mirror of https://github.com/wolfSSL/wolfssh.git
wolfsshd: Cover -D option parsing on Windows in CI
The Windows StartSSHD() path rebuilds argv from GetCommandLineW(). A regression there left -D foreground mode walking the raw wide command line, so -f and -p were ignored and the daemon used its built-in defaults. Nothing in CI caught that. Add sshd_dash_d_test.ps1: it starts wolfsshd with -D and a config file at a non-default path whose Port line differs from the -p value, then checks the listener binds the -p port and not the config port. That holds only when -D mode parsed both -f and -p. Run it from the Windows build job next to the existing LoginGraceTime check.pull/1247/head
parent
ea30c9fd9d
commit
39fec50df2
|
|
@ -88,6 +88,12 @@ jobs:
|
|||
timeout-minutes: 2
|
||||
run: .\sshd_login_grace_test.ps1 -SshdExe "$env:SSHD_PATH"
|
||||
|
||||
- name: Test wolfsshd -D option parsing on Windows
|
||||
working-directory: ${{ github.workspace }}\wolfssh\apps\wolfsshd\test
|
||||
shell: pwsh
|
||||
timeout-minutes: 2
|
||||
run: .\sshd_dash_d_test.ps1 -SshdExe "$env:SSHD_PATH"
|
||||
|
||||
# Build and run the self-contained unit tests with the MSVC AddressSanitizer.
|
||||
# This is the only job that executes wolfSSH tests under a sanitizer on
|
||||
# Windows, where the USE_WINDOWS_API console code (e.g. wolfSSH_DoOSC) is
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env pwsh
|
||||
#
|
||||
# Windows regression test for wolfsshd -D (foreground) option parsing.
|
||||
#
|
||||
# On Windows, StartSSHD() rebuilds argv from GetCommandLineW(); a bug in that
|
||||
# path left -D (foreground) mode parsing the raw wide command line, so -f and
|
||||
# -p were silently ignored and the daemon fell back to its compiled-in
|
||||
# defaults. This test starts wolfsshd with -D and a config file at a
|
||||
# non-default path whose Port line differs from the -p value, then checks that
|
||||
# the listener comes up on the -p port. That only happens if -D mode parsed
|
||||
# both -f (to find the config) and -p (to override the config's Port).
|
||||
#
|
||||
# No Windows user account or authorized key is required: the check is that the
|
||||
# daemon binds the requested port, not that a session authenticates.
|
||||
#
|
||||
# Usage:
|
||||
# pwsh sshd_dash_d_test.ps1 -SshdExe <path-to-wolfsshd.exe> [-Port N] [-ConfPort N]
|
||||
# (SshdExe also accepts the SSHD_PATH environment variable.)
|
||||
|
||||
param(
|
||||
[string]$SshdExe = $env:SSHD_PATH,
|
||||
[int]$Port = 22335,
|
||||
[int]$ConfPort = 22336
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$exitCode = 1
|
||||
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..\..\..")).Path
|
||||
$keyPath = (Resolve-Path (Join-Path $repoRoot "keys\server-key.pem")).Path
|
||||
$confFile = Join-Path $scriptDir "sshd_config_test_dash_d"
|
||||
$authFile = Join-Path $scriptDir "authorized_keys_test_dash_d"
|
||||
|
||||
if (-not $SshdExe -or -not (Test-Path $SshdExe)) {
|
||||
Write-Host "ERROR: wolfsshd.exe not found (pass -SshdExe or set SSHD_PATH)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($Port -eq $ConfPort) {
|
||||
Write-Host "ERROR: -Port and -ConfPort must differ so the test can tell them apart"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# The config's Port is deliberately not the port we probe. If -p is parsed it
|
||||
# wins (wolfsshd only reads the config Port when none was given on the command
|
||||
# line), so a listener on $Port proves the -p override took effect.
|
||||
@"
|
||||
Port $ConfPort
|
||||
Protocol 2
|
||||
PermitRootLogin yes
|
||||
PasswordAuthentication yes
|
||||
UseDNS no
|
||||
HostKey $keyPath
|
||||
AuthorizedKeysFile $authFile
|
||||
"@ | Out-File -FilePath $confFile -Encoding ASCII
|
||||
|
||||
"" | Out-File -FilePath $authFile -Encoding ASCII
|
||||
|
||||
# -D selects the non-service (foreground) path on Windows.
|
||||
$sshd = Start-Process -FilePath $SshdExe `
|
||||
-ArgumentList "-D", "-f", "`"$confFile`"", "-p", "$Port" `
|
||||
-NoNewWindow -PassThru
|
||||
|
||||
try {
|
||||
$up = $false
|
||||
for ($i = 0; $i -lt 20; $i++) {
|
||||
if ($sshd.HasExited) {
|
||||
throw "wolfsshd exited early (code $($sshd.ExitCode)); -D option parsing likely failed"
|
||||
}
|
||||
try {
|
||||
$probe = New-Object System.Net.Sockets.TcpClient
|
||||
$probe.Connect("127.0.0.1", $Port)
|
||||
$probe.Close()
|
||||
$up = $true
|
||||
break
|
||||
}
|
||||
catch {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
if (-not $up) {
|
||||
throw "wolfsshd did not listen on the -p port $Port; -D did not honor -f/-p"
|
||||
}
|
||||
|
||||
# The config Port must not have been used: nothing should answer there.
|
||||
$confBound = $false
|
||||
try {
|
||||
$probe = New-Object System.Net.Sockets.TcpClient
|
||||
$probe.Connect("127.0.0.1", $ConfPort)
|
||||
$probe.Close()
|
||||
$confBound = $true
|
||||
}
|
||||
catch {
|
||||
# expected: no listener on the config Port
|
||||
}
|
||||
if ($confBound) {
|
||||
throw "wolfsshd listened on the config Port $ConfPort; -p override was not applied"
|
||||
}
|
||||
|
||||
Write-Host "PASS: -D mode parsed -f and -p (listening on $Port, not $ConfPort)"
|
||||
$exitCode = 0
|
||||
}
|
||||
catch {
|
||||
Write-Host "FAIL: $_"
|
||||
$exitCode = 1
|
||||
}
|
||||
finally {
|
||||
if ($sshd -and -not $sshd.HasExited) {
|
||||
Stop-Process -Id $sshd.Id -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Remove-Item -Path $confFile, $authFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
exit $exitCode
|
||||
Loading…
Reference in New Issue