$ErrorActionPreference = 'Stop' $root = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path . (Join-Path $root 'scripts/deploy-auth.ps1') $session = $null $server = $null $tunnel = $null $username = 'test_' + [Guid]::NewGuid().ToString('N') try { $password = [Guid]::NewGuid().ToString('N') + '测试 !$`"' $session = Start-CaiwuDeploymentAuth -Server '127.0.0.1' -SshUser $username -Password (ConvertTo-SecureString $password -AsPlainText -Force) $info = [Diagnostics.ProcessStartInfo]::new() $info.FileName = (Get-Command python).Source $info.ArgumentList.Add((Join-Path $PSScriptRoot 'deploy-auth-server.py')) $info.UseShellExecute = $false $info.CreateNoWindow = $true $info.RedirectStandardInput = $true $info.StandardInputEncoding = [Text.UTF8Encoding]::new($false) $info.Environment['PYTHONIOENCODING'] = 'utf-8' $info.RedirectStandardOutput = $true $info.RedirectStandardError = $true $server = [Diagnostics.Process]::Start($info) $server.StandardInput.WriteLine($password) $server.StandardInput.Flush() $port = $server.StandardOutput.ReadLine() if ($port -notmatch '^\d+$') { throw 'SSH fixture did not start' } $options = $session.Options + @('-o', "UserKnownHostsFile=$($session.Directory)/known_hosts") $target = "${username}@127.0.0.1" & ssh @options -p $port $target true if ($LASTEXITCODE -ne 0) { throw 'Password SSH failed' } Stop-CaiwuDeploymentAuth $session $session = Start-CaiwuDeploymentAuth -Server '127.0.0.1' -SshUser $username & ssh @options -p $port $target true if ($LASTEXITCODE -ne 0) { throw 'Saved password reuse failed' } $upload = Join-Path $session.Directory 'fixture.txt' 'fixture' | Set-Content -LiteralPath $upload & scp @options -P $port $upload "${target}:/fixture.txt" if ($LASTEXITCODE -ne 0) { throw 'Password SFTP upload failed' } $listener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0) $listener.Start(); $localPort = ([Net.IPEndPoint]$listener.LocalEndpoint).Port; $listener.Stop() $info = [Diagnostics.ProcessStartInfo]::new() $info.FileName = (Get-Command ssh).Source $info.UseShellExecute = $false $info.CreateNoWindow = $true foreach ($argument in ($options + @('-p', $port, '-N', '-o', 'ExitOnForwardFailure=yes', '-L', "127.0.0.1:${localPort}:127.0.0.1:1234", $target))) { $info.ArgumentList.Add($argument) } $tunnel = [Diagnostics.Process]::Start($info) Start-Sleep -Seconds 2 $client = [Net.Sockets.TcpClient]::new('127.0.0.1', $localPort) $stream = $client.GetStream(); $stream.ReadTimeout = 5000 $bytes = [Text.Encoding]::UTF8.GetBytes('probe'); $stream.Write($bytes, 0, $bytes.Length) $received = New-Object byte[] 5 $count = $stream.Read($received, 0, 5) $client.Dispose() if ([Text.Encoding]::UTF8.GetString($received, 0, $count) -ne 'probe') { throw 'Password tunnel failed' } if ((Get-Content -LiteralPath $env:CAIWU_DEPLOY_PASSWORD_CACHE -Raw).Contains($password)) { throw 'Plaintext persisted' } 'wrong-fixture-password' | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Set-Content -LiteralPath $env:CAIWU_DEPLOY_PASSWORD_CACHE & ssh @options -p $port $target true 2>$null if ($LASTEXITCODE -eq 0) { throw 'Invalid password accepted' } $existingKey = Join-Path $session.Directory 'fake-key' 'fixture' | Set-Content -LiteralPath $existingKey $keySession = Start-CaiwuDeploymentAuth -Server '127.0.0.1' -SshUser $username -KeyPath $existingKey if ($keySession.Options -notcontains 'BatchMode=yes' -or $keySession.Directory) { throw 'Key compatibility failed' } Write-Host 'PASS: supplied password SSH, saved-login reuse, SFTP upload, background tunnel, encrypted storage, rejected wrong password, optional key compatibility' } finally { if ($tunnel) { if (-not $tunnel.HasExited) { $tunnel.Kill() }; $tunnel.Dispose() } if ($server) { if (-not $server.HasExited) { $server.Kill() }; $server.Dispose() } Stop-CaiwuDeploymentAuth $session # Only this test-created identity directory may be removed. if ($session -and (Split-Path -Leaf $session.Directory) -eq "${username}@127.0.0.1") { $expected = Join-Path ([Environment]::GetFolderPath('LocalApplicationData')) "CaiWuXiTong/deploy-credentials/${username}@127.0.0.1" if ([IO.Path]::GetFullPath($session.Directory) -ne [IO.Path]::GetFullPath($expected)) { throw 'Unexpected test cleanup path' } Remove-Item -LiteralPath $session.Directory -Recurse -Force } }