CaiWuXiTong/tests/scripts/deploy-password-auth.ps1

74 lines
4.5 KiB
PowerShell

$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
}
}