mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-25 14:54:45 +02:00
Port Unix bash tests (#410)
Leverage upstream test infrastructure to run against windows openssh binaries.
This commit is contained in:
parent
9b327de3e7
commit
a49bdce666
@ -277,6 +277,12 @@ function Publish-Artifact
|
|||||||
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["UninstallTestResultsFile"]
|
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["UninstallTestResultsFile"]
|
||||||
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["TestSetupLogFile"]
|
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["TestSetupLogFile"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($Global:bash_tests_summary)
|
||||||
|
{
|
||||||
|
Add-Artifact -artifacts $artifacts -FileToAdd $Global:bash_tests_summary["BashTestSummaryFile"]
|
||||||
|
Add-Artifact -artifacts $artifacts -FileToAdd $Global:bash_tests_summary["BashTestLogFile"]
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($artifact in $artifacts)
|
foreach ($artifact in $artifacts)
|
||||||
{
|
{
|
||||||
@ -324,7 +330,7 @@ function Invoke-OpenSSHTests
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Write-Host "All Unit tests passed!"
|
Write-Host "All Unit tests passed!"
|
||||||
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
|
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run all E2E tests.
|
# Run all E2E tests.
|
||||||
@ -339,7 +345,7 @@ function Invoke-OpenSSHTests
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
$xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string)
|
$xml = [xml](Get-Content $OpenSSHTestInfo["E2ETestResultsFile"] | out-string)
|
||||||
if ([int]$xml.'test-results'.failures -gt 0)
|
if ([int]$xml.'test-results'.failures -gt 0)
|
||||||
{
|
{
|
||||||
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])."
|
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at $($OpenSSHTestInfo["E2ETestResultsFile"])."
|
||||||
Write-Warning $errorMessage
|
Write-Warning $errorMessage
|
||||||
@ -347,7 +353,31 @@ function Invoke-OpenSSHTests
|
|||||||
Set-BuildVariable TestPassed False
|
Set-BuildVariable TestPassed False
|
||||||
Write-Warning "Stop running further tests!"
|
Write-Warning "Stop running further tests!"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run UNIX bash tests.
|
||||||
|
Invoke-OpenSSHBashTests
|
||||||
|
if (-not $Global:bash_tests_summary)
|
||||||
|
{
|
||||||
|
$errorMessage = "Failed to start OpenSSH bash tests"
|
||||||
|
Write-Warning $errorMessage
|
||||||
|
Write-BuildMessage -Message $errorMessage -Category Error
|
||||||
|
Set-BuildVariable TestPassed False
|
||||||
|
Write-Warning "Stop running further tests!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Global:bash_tests_summary["TotalBashTestsFailed"] -ne 0)
|
||||||
|
{
|
||||||
|
$total_bash_failed_tests = $Global:bash_tests_summary["TotalBashTestsFailed"]
|
||||||
|
$total_bash_tests = $Global:bash_tests_summary["TotalBashTests"]
|
||||||
|
$errorMessage = "At least one of the bash tests failed. [$total_bash_failed_tests of $total_bash_tests]"
|
||||||
|
Write-Warning $errorMessage
|
||||||
|
Write-BuildMessage -Message $errorMessage -Category Error
|
||||||
|
Set-BuildVariable TestPassed False
|
||||||
|
Write-Warning "Stop running further tests!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Invoke-OpenSSHUninstallTest
|
Invoke-OpenSSHUninstallTest
|
||||||
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["UninstallTestResultsFile"])))
|
if (($OpenSSHTestInfo -eq $null) -or (-not (Test-Path $OpenSSHTestInfo["UninstallTestResultsFile"])))
|
||||||
|
@ -41,7 +41,7 @@ function Set-OpenSSHTestEnvironment
|
|||||||
param
|
param
|
||||||
(
|
(
|
||||||
[string] $OpenSSHBinPath,
|
[string] $OpenSSHBinPath,
|
||||||
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
|
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
|
||||||
[Switch] $DebugMode,
|
[Switch] $DebugMode,
|
||||||
[Switch] $NoAppVerifier,
|
[Switch] $NoAppVerifier,
|
||||||
[Switch] $PostmortemDebugging,
|
[Switch] $PostmortemDebugging,
|
||||||
@ -68,7 +68,6 @@ function Set-OpenSSHTestEnvironment
|
|||||||
$Global:OpenSSHTestInfo.Add("TestAccountPW", $OpenSSHTestAccountsPassword) # common password for all test accounts
|
$Global:OpenSSHTestInfo.Add("TestAccountPW", $OpenSSHTestAccountsPassword) # common password for all test accounts
|
||||||
$Global:OpenSSHTestInfo.Add("DebugMode", $DebugMode.IsPresent) # run openssh E2E in debug mode
|
$Global:OpenSSHTestInfo.Add("DebugMode", $DebugMode.IsPresent) # run openssh E2E in debug mode
|
||||||
|
|
||||||
|
|
||||||
$Script:EnableAppVerifier = -not ($NoAppVerifier.IsPresent)
|
$Script:EnableAppVerifier = -not ($NoAppVerifier.IsPresent)
|
||||||
if($Script:WindowsInBox = $true)
|
if($Script:WindowsInBox = $true)
|
||||||
{
|
{
|
||||||
@ -100,8 +99,7 @@ WARNING: Following changes will be made to OpenSSH configuration
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Install-OpenSSHTestDependencies
|
Install-OpenSSHTestDependencies
|
||||||
|
|
||||||
|
|
||||||
##### START: install sshd test service
|
##### START: install sshd test service
|
||||||
#delete service if exists
|
#delete service if exists
|
||||||
@ -164,15 +162,13 @@ WARNING: Following changes will be made to OpenSSH configuration
|
|||||||
}
|
}
|
||||||
Start-Service ssh-agent
|
Start-Service ssh-agent
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Prepare user config - known_hosts and ssh_config
|
#Prepare user config - known_hosts and ssh_config
|
||||||
$dotSshDirectoryPath = Join-Path $home .ssh
|
$dotSshDirectoryPath = Join-Path $home .ssh
|
||||||
if(-not (Test-Path $dotSshDirectoryPath -PathType Container))
|
if(-not (Test-Path $dotSshDirectoryPath -PathType Container))
|
||||||
{
|
{
|
||||||
New-Item -ItemType Directory -Path $dotSshDirectoryPath -Force -ErrorAction SilentlyContinue | out-null
|
New-Item -ItemType Directory -Path $dotSshDirectoryPath -Force -ErrorAction SilentlyContinue | out-null
|
||||||
}
|
}
|
||||||
|
|
||||||
$knowHostsFilePath = Join-Path $dotSshDirectoryPath known_hosts
|
$knowHostsFilePath = Join-Path $dotSshDirectoryPath known_hosts
|
||||||
if (-not (Test-Path $knowHostsFilePath -PathType Leaf)) {
|
if (-not (Test-Path $knowHostsFilePath -PathType Leaf)) {
|
||||||
Copy-Item (Join-Path $Script:E2ETestDataDirectory known_hosts) $knowHostsFilePath -Force
|
Copy-Item (Join-Path $Script:E2ETestDataDirectory known_hosts) $knowHostsFilePath -Force
|
||||||
@ -671,6 +667,38 @@ function Invoke-OpenSSHE2ETest
|
|||||||
Pop-Location
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Run UNIX bash tests using CYGWIN.
|
||||||
|
#>
|
||||||
|
function Invoke-OpenSSHBashTests
|
||||||
|
{
|
||||||
|
[string]$bashPath = [string]::Empty
|
||||||
|
# Check for cygwin
|
||||||
|
if (Test-Path $env:SystemDrive\cygwin\bin\sh.exe) {
|
||||||
|
$bashPath = "$env:SystemDrive\cygwin\bin\sh.exe"
|
||||||
|
} elseif (Test-Path $env:SystemDrive\cygwin64\bin\sh.exe) {
|
||||||
|
$bashPath = "$env:SystemDrive\cygwin64\bin\sh.exe"
|
||||||
|
} elseif (Test-Path $env:SystemDrive\tools\cygwin\bin\sh.exe) {
|
||||||
|
$bashPath = "$env:SystemDrive\tools\cygwin\bin\sh.exe"
|
||||||
|
} else {
|
||||||
|
# Install cygwin
|
||||||
|
Write-Host "Installing cygwin using chocolatey to $env:SystemDrive\cygwin folder"
|
||||||
|
choco install cygwin -y --params "/InstallDir:$env:SystemDrive\cygwin\ /NoStartMenu"
|
||||||
|
|
||||||
|
if (Test-Path $env:SystemDrive\cygwin\bin\sh.exe) {
|
||||||
|
$bashPath = "$env:SystemDrive\cygwin\bin\sh.exe"
|
||||||
|
} else {
|
||||||
|
Write-Error "Failed to install cygwin to $env:SystemDrive\cygwin folder" -ErrorAction Stop
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$bashTestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress"
|
||||||
|
|
||||||
|
&"$PSScriptRoot\bash_tests_iterator.ps1" -OpenSSHBinPath $Script:OpenSSHBinPath -BashTestsPath $bashTestDirectory -ShellPath $bashPath -ArtifactsDirectoryPath $bashTestDirectory
|
||||||
|
}
|
||||||
|
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Run openssh unit tests.
|
Run openssh unit tests.
|
||||||
@ -759,4 +787,4 @@ function Write-Log
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Export-ModuleMember -Function Set-BasicTestInfo, Set-OpenSSHTestEnvironment, Clear-OpenSSHTestEnvironment, Invoke-OpenSSHSetupTest, Invoke-OpenSSHUnitTest, Invoke-OpenSSHE2ETest, Invoke-OpenSSHUninstallTest
|
Export-ModuleMember -Function Set-BasicTestInfo, Set-OpenSSHTestEnvironment, Clear-OpenSSHTestEnvironment, Invoke-OpenSSHSetupTest, Invoke-OpenSSHUnitTest, Invoke-OpenSSHE2ETest, Invoke-OpenSSHUninstallTest, Invoke-OpenSSHBashTests
|
@ -1,276 +0,0 @@
|
|||||||
param (
|
|
||||||
# Path to openssh binaries
|
|
||||||
[Parameter(Mandatory=$true)] [string] $OpenSSHBinPath,
|
|
||||||
# Path of regress folder which has all the bash testcases.
|
|
||||||
[Parameter(Mandatory=$true)] [string] $BashTestsPath,
|
|
||||||
# Path to CYGWIN / WSL.
|
|
||||||
[Parameter(Mandatory=$true)] [string] $ShellPath,
|
|
||||||
# Individual bash test file (Ex - connect.sh)
|
|
||||||
[Parameter(Mandatory=$false)] [string[]] $TestFilePath,
|
|
||||||
[Parameter(Mandatory=$false)] [string] $ArtifactsPath=".",
|
|
||||||
[switch] $SkipCleanup,
|
|
||||||
[switch] $SkipInstallSSHD
|
|
||||||
)
|
|
||||||
|
|
||||||
# Resolve the relative paths
|
|
||||||
$OpenSSHBinPath=resolve-path $OpenSSHBinPath -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
$BashTestsPath=resolve-path $BashTestsPath -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
$ShellPath=resolve-path $ShellPath -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
$ArtifactsPath=resolve-path $ArtifactsPath -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
if ($TestFilePath) {
|
|
||||||
$TestFilePath=resolve-path $TestFilePath -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
# convert to bash format
|
|
||||||
$TestFilePath=$TestFilePath -replace "\\","/"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make sure config.h exists. It is used by bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
|
||||||
# first check in $BashTestsPath folder. If not then it's parent folder. If not then in the $OpenSSHBinPath
|
|
||||||
if(Test-Path "$BashTestsPath\config.h" -PathType Leaf) {
|
|
||||||
$configPath="$BashTestsPath\config.h"
|
|
||||||
} elseif(Test-Path "$BashTestsPath\..\config.h" -PathType Leaf) {
|
|
||||||
$configPath=resolve-path "$BashTestsPath\..\config.h" -ErrorAction Stop | select -ExpandProperty Path
|
|
||||||
} elseif(Test-Path "$OpenSSHBinPath\config.h" -PathType Leaf) {
|
|
||||||
$configPath="$OpenSSHBinPath\config.h"
|
|
||||||
} else {
|
|
||||||
Write-Error "Couldn't find config.h"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
# store user directory
|
|
||||||
$user_pwd=pwd | select -ExpandProperty Path
|
|
||||||
|
|
||||||
# If we are using a SKU with desired OpenSSH binaries then we can skip these steps.
|
|
||||||
if(!$SkipInstallSSHD) {
|
|
||||||
# Make sure install-sshd.ps1 exists.
|
|
||||||
if(!(Test-Path "$PSScriptRoot\install-sshd.ps1" -PathType Leaf)) {
|
|
||||||
Write-Error "$PSScriptRoot\install-sshd.ps1 doesn't exists"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
# Make sure uninstall-sshd.ps1 exists.
|
|
||||||
if(!(Test-Path "$PSScriptRoot\uninstall-sshd.ps1" -PathType Leaf)) {
|
|
||||||
Write-Error "$PSScriptRoot\uninstall-sshd.ps1 doesn't exists"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
#copy to binary folder and execute install-sshd.ps1
|
|
||||||
Copy-Item $PSScriptRoot\install-sshd.ps1 -Force $OpenSSHBinPath
|
|
||||||
Copy-Item $PSScriptRoot\uninstall-sshd.ps1 -Force $OpenSSHBinPath
|
|
||||||
|
|
||||||
# We need ssh-agent to be installed as service to run some bash tests.
|
|
||||||
& "$OpenSSHBinPath\install-sshd.ps1"
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
# set the default shell
|
|
||||||
$registryPath = "HKLM:\Software\OpenSSH"
|
|
||||||
$dfltShell = "DefaultShell"
|
|
||||||
# Fetch the user configured default shell.
|
|
||||||
$out=(Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
|
||||||
if($out) {
|
|
||||||
$user_default_shell = $out.$dfltShell
|
|
||||||
Write-Output "User configured default shell: $user_default_shell"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(Test-Path $registryPath)) {
|
|
||||||
# start and stop the sshd so that "HKLM:\Software\OpenSSH" registry path is created.
|
|
||||||
Start-Service sshd -ErrorAction Stop
|
|
||||||
Stop-Service sshd -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $ShellPath -Force
|
|
||||||
$out=(Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
|
||||||
if($out.$dfltShell -ne $ShellPath) {
|
|
||||||
Write-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $ShellPath"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prepend shell path to PATH. This is required to make the shell commands (like sleep, cat, etc) work properly.
|
|
||||||
$env:TEST_SHELL_PATH=$ShellPath -replace "\\","/"
|
|
||||||
$TEST_SHELL_DIR=split-path $ShellPath
|
|
||||||
if(!$env:path.StartsWith($TEST_SHELL_DIR, "CurrentCultureIgnoreCase"))
|
|
||||||
{
|
|
||||||
$env:path=$TEST_SHELL_DIR+";"+$env:path
|
|
||||||
}
|
|
||||||
|
|
||||||
$BashTestsPath=$BashTestsPath -replace "\\","/"
|
|
||||||
Push-location $BashTestsPath
|
|
||||||
|
|
||||||
# BUILDDIR: config.h location.
|
|
||||||
# BUILDDIR is used by bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
|
||||||
$BUILDDIR=resolve-path(split-path $configpath) | select -ExpandProperty Path
|
|
||||||
$tmp=&$ShellPath -c pwd
|
|
||||||
if ($tmp.StartsWith("/cygdrive/")) {
|
|
||||||
$shell_drv_fmt="/cygdrive/" # "/cygdrive/" - cygwin
|
|
||||||
$BUILDDIR=&$ShellPath -c "cygpath -u '$BUILDDIR'"
|
|
||||||
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "cygpath -u '$OpenSSHBinPath'"
|
|
||||||
$BashTestsPath=&$ShellPath -c "cygpath -u '$BashTestsPath'"
|
|
||||||
} elseif ($tmp.StartsWith("/mnt/")) {
|
|
||||||
$shell_drv_fmt="/mnt/" # "/mnt/" - WSL bash
|
|
||||||
$BUILDDIR=&$ShellPath -c "wslpath -u '$BUILDDIR'"
|
|
||||||
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "wslpath -u '$OpenSSHBinPath'"
|
|
||||||
$BashTestsPath=&$ShellPath -c "wslpath -u '$BashTestsPath'"
|
|
||||||
}
|
|
||||||
|
|
||||||
#set the environment variables.
|
|
||||||
$env:ShellPath=$ShellPath
|
|
||||||
$env:SSH_TEST_ENVIRONMENT=1
|
|
||||||
$env:TEST_SSH_TRACE="yes"
|
|
||||||
$env:TEST_SHELL="/bin/sh"
|
|
||||||
$env:TEST_SSH_PORT=22
|
|
||||||
$env:TEST_SSH_SSH=$OpenSSHBinPath_shell_fmt+"/ssh.exe"
|
|
||||||
$env:TEST_SSH_SSHD=$OpenSSHBinPath_shell_fmt+"/sshd.exe"
|
|
||||||
$env:TEST_SSH_SSHAGENT=$OpenSSHBinPath_shell_fmt+"/ssh-agent.exe"
|
|
||||||
$env:TEST_SSH_SSHADD=$OpenSSHBinPath_shell_fmt+"/ssh-add.exe"
|
|
||||||
$env:TEST_SSH_SSHKEYGEN=$OpenSSHBinPath_shell_fmt+"/ssh-keygen.exe"
|
|
||||||
$env:TEST_SSH_SSHKEYSCAN=$OpenSSHBinPath_shell_fmt+"/ssh-keyscan.exe"
|
|
||||||
$env:TEST_SSH_SFTP=$OpenSSHBinPath_shell_fmt+"/sftp.exe"
|
|
||||||
$env:TEST_SSH_SFTPSERVER=$OpenSSHBinPath_shell_fmt+"/sftp-server.exe"
|
|
||||||
$env:TEST_SSH_SCP=$OpenSSHBinPath_shell_fmt+"/scp.exe"
|
|
||||||
$env:BUILDDIR=$BUILDDIR
|
|
||||||
$env:TEST_WINDOWS_SSH=1
|
|
||||||
$user = &"$env:windir\system32\whoami.exe"
|
|
||||||
if($user.Contains($env:COMPUTERNAME.ToLower())) {
|
|
||||||
# for local accounts, skip COMPUTERNAME
|
|
||||||
$user = Split-Path $user -leaf
|
|
||||||
$env:TEST_SSH_USER=$user
|
|
||||||
} else {
|
|
||||||
# for domain user convert "domain\user" to "domain/user".
|
|
||||||
$user = $user -replace "\\","/"
|
|
||||||
$env:TEST_SSH_USER = $user
|
|
||||||
$env:TEST_SSH_USER_DOMAIN = Split-Path $user
|
|
||||||
}
|
|
||||||
|
|
||||||
# output to terminal
|
|
||||||
Write-Output "USER: $env:TEST_SSH_USER"
|
|
||||||
Write-Output "DOMAIN: $env:TEST_SSH_USER_DOMAIN"
|
|
||||||
Write-Output "OpenSSHBinPath: $OpenSSHBinPath_shell_fmt"
|
|
||||||
Write-Output "BUILDDIR: $BUILDDIR"
|
|
||||||
Write-Output "BashTestsPath: $BashTestsPath"
|
|
||||||
|
|
||||||
# remove, create the temp test directory
|
|
||||||
$temp_test_path="temp_test"
|
|
||||||
$null = Remove-Item -Recurse -Force $temp_test_path -ErrorAction SilentlyContinue
|
|
||||||
$null = New-Item -ItemType directory -Path $temp_test_path -ErrorAction Stop
|
|
||||||
|
|
||||||
# remove the summary, output files.
|
|
||||||
$test_summary="$ArtifactsPath\\bashtest_summary.txt"
|
|
||||||
$test_output="$ArtifactsPath\\bashtest_output.txt"
|
|
||||||
$null = Remove-Item -Force $test_summary -ErrorAction SilentlyContinue
|
|
||||||
$null = Remove-Item -Force $test_output -ErrorAction SilentlyContinue
|
|
||||||
[int]$total_tests = 0
|
|
||||||
[int]$total_tests_passed = 0
|
|
||||||
[int]$total_tests_failed = 0
|
|
||||||
[string]$failed_testcases = [string]::Empty
|
|
||||||
|
|
||||||
# These are the known failed testcases.
|
|
||||||
# agent.sh, krl.sh - User Cert authentication fails
|
|
||||||
# key-options.sh - pty testcases are failing (bug in conpty. conpty fails to launch cygwin bash)
|
|
||||||
# integrity.sh - It's dependent on regress\modpipe.exe, test is complicated. Need to debug more
|
|
||||||
# authinfo.sh - spawned conpty inherits all the environment variables from sshd.
|
|
||||||
# forward-control.sh - Need to debug more.
|
|
||||||
[string]$known_failed_testcases = "agent.sh key-options.sh forward-control.sh integrity.sh krl.sh authinfo.sh"
|
|
||||||
[string]$known_failed_testcases_skipped = [string]::Empty
|
|
||||||
|
|
||||||
$start_time = (Get-Date)
|
|
||||||
|
|
||||||
if($TestFilePath) {
|
|
||||||
# User can specify individual test file path.
|
|
||||||
$all_tests=$TestFilePath
|
|
||||||
} else {
|
|
||||||
# picking the gawk.exe from bash folder.
|
|
||||||
# TODO - check if gawk.exe is present in WSL.
|
|
||||||
$all_tests=gawk.exe 'sub(/.*LTESTS=/,""""){f=1} f{print $1; if (!/\\\\/) exit}' Makefile
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($test_case in $all_tests) {
|
|
||||||
if($TestFilePath) {
|
|
||||||
$TEST=$test_case
|
|
||||||
} else {
|
|
||||||
if(!$test_case.Contains(".sh")) {
|
|
||||||
$TEST=$BashTestsPath+"/"+$test_case+".sh"
|
|
||||||
} else {
|
|
||||||
$TEST=$BashTestsPath+"/"+$test_case
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$test_case_name = [System.IO.Path]::GetFileName($TEST)
|
|
||||||
if($known_failed_testcases.Contains($test_case_name))
|
|
||||||
{
|
|
||||||
Write-Output "Skip the known failed test:$test_case_name"
|
|
||||||
$known_failed_testcases_skipped = $known_failed_testcases_skipped + "$test_case_name "
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$msg="Executing $test_case_name " +[System.DateTime]::Now
|
|
||||||
Write-Output $msg
|
|
||||||
&$env:ShellPath -c "/usr/bin/sh $BashTestsPath/test-exec.sh $BashTestsPath/$temp_test_path $TEST" #>$null 2>&1
|
|
||||||
if($?)
|
|
||||||
{
|
|
||||||
$msg="$test_case_name PASSED " +[System.DateTime]::Now
|
|
||||||
Write-Output $msg
|
|
||||||
$total_tests_passed++
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$msg="$test_case_name FAILED " +[System.DateTime]::Now
|
|
||||||
Write-Output $msg
|
|
||||||
$total_tests_failed++
|
|
||||||
$failed_testcases=$failed_testcases + "$test_case_name "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$total_tests++
|
|
||||||
}
|
|
||||||
|
|
||||||
$end_time = (Get-Date)
|
|
||||||
|
|
||||||
# Create artifacts
|
|
||||||
"Start time: $start_time" | Out-File -FilePath $test_summary -Append
|
|
||||||
"End time: $end_time" | Out-File -FilePath $test_summary -Append
|
|
||||||
"Total execution time: " + (NEW-TIMESPAN -Start $start_time -End $end_time).ToString("hh\:mm\:ss") | Out-File -FilePath $test_summary -Append
|
|
||||||
"Tests executed: $total_tests" | Out-File -FilePath $test_summary -Append
|
|
||||||
"Tests passed: $total_tests_passed" | Out-File -FilePath $test_summary -Append
|
|
||||||
"Tests failed: $total_tests_failed" | Out-File -FilePath $test_summary -Append
|
|
||||||
"Failed tests: $failed_testcases" | Out-File -FilePath $test_summary -Append
|
|
||||||
"Skipped known failed tests: $known_failed_testcases_skipped" | Out-File -FilePath $test_summary -Append
|
|
||||||
|
|
||||||
Write-Output "Artifacts are saved to $ArtifactsPath"
|
|
||||||
|
|
||||||
#output the summary
|
|
||||||
Write-Output "================================="
|
|
||||||
cat $test_summary
|
|
||||||
Write-Output "================================="
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
# remove temp test directory
|
|
||||||
if (!$SkipCleanup)
|
|
||||||
{
|
|
||||||
# remove temp test folder
|
|
||||||
&$ShellPath -c "rm -rf $BashTestsPath/temp_test"
|
|
||||||
|
|
||||||
if(!$SkipInstallSSHD) {
|
|
||||||
# Uninstall the sshd, ssh-agent service
|
|
||||||
& "$PSScriptRoot\uninstall-sshd.ps1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the test environment variable
|
|
||||||
Remove-Item ENV:\SSH_TEST_ENVIRONMENT
|
|
||||||
|
|
||||||
# Revert to user configured default shell.
|
|
||||||
if($user_default_shell) {
|
|
||||||
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $user_default_shell -Force
|
|
||||||
$out=(Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
|
||||||
if($out.$dfltShell -eq $user_default_shell) {
|
|
||||||
Write-Output "Reverted user configured default shell to $user_default_shell"
|
|
||||||
} else {
|
|
||||||
Write-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $user_default_shell"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Remove-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Push-location $user_pwd
|
|
||||||
}
|
|
286
contrib/win32/openssh/bash_tests_iterator.ps1
Normal file
286
contrib/win32/openssh/bash_tests_iterator.ps1
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
param (
|
||||||
|
# Path to openssh binaries
|
||||||
|
[Parameter(Mandatory=$true)] [string] $OpenSSHBinPath,
|
||||||
|
# Path of regress folder which has all the bash testcases.
|
||||||
|
[Parameter(Mandatory=$true)] [string] $BashTestsPath,
|
||||||
|
# Path to CYGWIN / WSL.
|
||||||
|
[Parameter(Mandatory=$true)] [string] $ShellPath,
|
||||||
|
# Individual bash test file (Ex - connect.sh, scp.sh)
|
||||||
|
[Parameter(Mandatory=$false)] [string[]] $TestFilePath,
|
||||||
|
[Parameter(Mandatory=$false)] [string] $ArtifactsDirectoryPath=".",
|
||||||
|
[switch] $SkipCleanup,
|
||||||
|
[switch] $SkipInstallSSHD
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Continue'
|
||||||
|
|
||||||
|
# Resolve the relative paths
|
||||||
|
$OpenSSHBinPath = Resolve-Path $OpenSSHBinPath -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
$BashTestsPath = Resolve-Path $BashTestsPath -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
$ShellPath = Resolve-Path $ShellPath -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
$ArtifactsDirectoryPath = Resolve-Path $ArtifactsDirectoryPath -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
if ($TestFilePath) {
|
||||||
|
$TestFilePath = Resolve-Path $TestFilePath -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
# convert to bash format
|
||||||
|
$TestFilePath = $TestFilePath -replace "\\","/"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure config.h exists. It is used in some bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
||||||
|
# first check in $BashTestsPath folder. If not then it's parent folder. If not then in the $OpenSSHBinPath
|
||||||
|
if(Test-Path "$BashTestsPath\config.h" -PathType Leaf) {
|
||||||
|
$configPath = "$BashTestsPath\config.h"
|
||||||
|
} elseif(Test-Path "$BashTestsPath\..\config.h" -PathType Leaf) {
|
||||||
|
$configPath = Resolve-Path "$BashTestsPath\..\config.h" -ErrorAction Stop | select -ExpandProperty Path
|
||||||
|
} elseif(Test-Path "$OpenSSHBinPath\config.h" -PathType Leaf) {
|
||||||
|
$configPath = "$OpenSSHBinPath\config.h"
|
||||||
|
} else {
|
||||||
|
Write-Error "Couldn't find config.h"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_pwd = pwd | select -ExpandProperty Path
|
||||||
|
|
||||||
|
# If we are using a SKU with desired OpenSSH binaries then we can skip these steps.
|
||||||
|
if(!$SkipInstallSSHD) {
|
||||||
|
# Make sure install-sshd.ps1 exists.
|
||||||
|
# This is required only for ssh-agent related bash tests.
|
||||||
|
if(!(Test-Path "$PSScriptRoot\install-sshd.ps1" -PathType Leaf)) {
|
||||||
|
Write-Error "$PSScriptRoot\install-sshd.ps1 doesn't exists"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make sure uninstall-sshd.ps1 exists.
|
||||||
|
if(!(Test-Path "$PSScriptRoot\uninstall-sshd.ps1" -PathType Leaf)) {
|
||||||
|
Write-Error "$PSScriptRoot\uninstall-sshd.ps1 doesn't exists"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#copy to binary folder and execute install-sshd.ps1
|
||||||
|
Copy-Item $PSScriptRoot\install-sshd.ps1 -Force $OpenSSHBinPath
|
||||||
|
Copy-Item $PSScriptRoot\uninstall-sshd.ps1 -Force $OpenSSHBinPath
|
||||||
|
|
||||||
|
# We need ssh-agent to be installed as service to run some bash tests.
|
||||||
|
& "$OpenSSHBinPath\install-sshd.ps1"
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
# set the default shell
|
||||||
|
$registryPath = "HKLM:\Software\OpenSSH"
|
||||||
|
$dfltShell = "DefaultShell"
|
||||||
|
# Fetch the user configured default shell.
|
||||||
|
$out = (Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
||||||
|
if ($out) {
|
||||||
|
$user_default_shell = $out.$dfltShell
|
||||||
|
Write-Output "User configured default shell: $user_default_shell"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user_default_shell -ne $ShellPath)
|
||||||
|
{
|
||||||
|
if (!(Test-Path $registryPath)) {
|
||||||
|
# start and stop the sshd so that "HKLM:\Software\OpenSSH" registry path is created.
|
||||||
|
Start-Service sshd -ErrorAction Stop
|
||||||
|
Stop-Service sshd -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $ShellPath -Force
|
||||||
|
$out = (Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
||||||
|
if ($out.$dfltShell -ne $ShellPath) {
|
||||||
|
Write-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $ShellPath"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "Successfully set the default shell (HKLM:\Software\OpenSSH\DefaultShell) to $ShellPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prepend shell path to PATH. This is required to make the shell commands (like sleep, cat, etc) work properly.
|
||||||
|
$env:TEST_SHELL_PATH = $ShellPath -replace "\\","/"
|
||||||
|
$TEST_SHELL_DIR = split-path $ShellPath
|
||||||
|
if(!$env:path.StartsWith($TEST_SHELL_DIR, "CurrentCultureIgnoreCase"))
|
||||||
|
{
|
||||||
|
$env:path = $TEST_SHELL_DIR + ";" + $env:path
|
||||||
|
}
|
||||||
|
|
||||||
|
$BashTestsPath = $BashTestsPath -replace "\\","/"
|
||||||
|
Push-location $BashTestsPath
|
||||||
|
|
||||||
|
# BUILDDIR: config.h location.
|
||||||
|
# BUILDDIR is used by bashstests (Ex - sftp-glob.sh, cfgparse.sh)
|
||||||
|
$BUILDDIR = Resolve-Path(split-path $configpath) | select -ExpandProperty Path
|
||||||
|
$tmp = &$ShellPath -c pwd
|
||||||
|
if ($tmp.StartsWith("/cygdrive/")) {
|
||||||
|
$shell_drv_fmt = "/cygdrive/" # cygwin
|
||||||
|
$BUILDDIR = &$ShellPath -c "cygpath -u '$BUILDDIR'"
|
||||||
|
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "cygpath -u '$OpenSSHBinPath'"
|
||||||
|
$BashTestsPath = &$ShellPath -c "cygpath -u '$BashTestsPath'"
|
||||||
|
} elseif ($tmp.StartsWith("/mnt/")) {
|
||||||
|
$shell_drv_fmt = "/mnt/" # WSL bash
|
||||||
|
$BUILDDIR = &$ShellPath -c "wslpath -u '$BUILDDIR'"
|
||||||
|
$OpenSSHBinPath_shell_fmt=&$ShellPath -c "wslpath -u '$OpenSSHBinPath'"
|
||||||
|
$BashTestsPath = &$ShellPath -c "wslpath -u '$BashTestsPath'"
|
||||||
|
}
|
||||||
|
|
||||||
|
#set the environment variables.
|
||||||
|
$env:ShellPath = $ShellPath
|
||||||
|
$env:SSH_TEST_ENVIRONMENT = 1
|
||||||
|
$env:TEST_SSH_TRACE = "yes"
|
||||||
|
$env:TEST_SHELL = "/bin/sh"
|
||||||
|
$env:TEST_SSH_PORT = 22
|
||||||
|
$env:TEST_SSH_SSH = $OpenSSHBinPath_shell_fmt+"/ssh.exe"
|
||||||
|
$env:TEST_SSH_SSHD = $OpenSSHBinPath_shell_fmt+"/sshd.exe"
|
||||||
|
$env:TEST_SSH_SSHAGENT = $OpenSSHBinPath_shell_fmt+"/ssh-agent.exe"
|
||||||
|
$env:TEST_SSH_SSHADD = $OpenSSHBinPath_shell_fmt+"/ssh-add.exe"
|
||||||
|
$env:TEST_SSH_SSHKEYGEN = $OpenSSHBinPath_shell_fmt+"/ssh-keygen.exe"
|
||||||
|
$env:TEST_SSH_SSHKEYSCAN = $OpenSSHBinPath_shell_fmt+"/ssh-keyscan.exe"
|
||||||
|
$env:TEST_SSH_SFTP = $OpenSSHBinPath_shell_fmt+"/sftp.exe"
|
||||||
|
$env:TEST_SSH_SFTPSERVER = $OpenSSHBinPath_shell_fmt+"/sftp-server.exe"
|
||||||
|
$env:TEST_SSH_SCP = $OpenSSHBinPath_shell_fmt+"/scp.exe"
|
||||||
|
$env:BUILDDIR = $BUILDDIR
|
||||||
|
$env:TEST_WINDOWS_SSH = 1
|
||||||
|
$user = &"$env:windir\system32\whoami.exe"
|
||||||
|
if($user.Contains($env:COMPUTERNAME.ToLower())) {
|
||||||
|
# for local accounts, skip COMPUTERNAME
|
||||||
|
$user = Split-Path $user -leaf
|
||||||
|
$env:TEST_SSH_USER = $user
|
||||||
|
} else {
|
||||||
|
# for domain user convert "domain\user" to "domain/user".
|
||||||
|
$user = $user -replace "\\","/"
|
||||||
|
$env:TEST_SSH_USER = $user
|
||||||
|
$env:TEST_SSH_USER_DOMAIN = Split-Path $user
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "USER: $env:TEST_SSH_USER"
|
||||||
|
Write-Output "DOMAIN: $env:TEST_SSH_USER_DOMAIN"
|
||||||
|
Write-Output "OpenSSHBinPath: $OpenSSHBinPath_shell_fmt"
|
||||||
|
Write-Output "BUILDDIR: $BUILDDIR"
|
||||||
|
Write-Output "BashTestsPath: $BashTestsPath"
|
||||||
|
|
||||||
|
# remove, create the temp test directory
|
||||||
|
$temp_test_path = "temp_test"
|
||||||
|
$null = Remove-Item -Recurse -Force $temp_test_path -ErrorAction SilentlyContinue
|
||||||
|
$null = New-Item -ItemType directory -Path $temp_test_path -Force -ErrorAction Stop
|
||||||
|
|
||||||
|
# remove the summary, output files.
|
||||||
|
$bash_test_summary = "$ArtifactsDirectoryPath\bash_tests_summary.txt"
|
||||||
|
$bash_test_log_file = "$ArtifactsDirectoryPath\bash_tests_output.log"
|
||||||
|
$null = Remove-Item -Force $bash_test_summary -ErrorAction SilentlyContinue
|
||||||
|
$null = Remove-Item -Force $bash_test_log_file -ErrorAction SilentlyContinue
|
||||||
|
[int]$total_tests = 0
|
||||||
|
[int]$total_tests_passed = 0
|
||||||
|
[int]$total_tests_failed = 0
|
||||||
|
[string]$failed_testcases = [string]::Empty
|
||||||
|
|
||||||
|
# These are the known failed testcases.
|
||||||
|
$known_failed_testcases = @("agent.sh", "key-options.sh", "forward-control.sh", "integrity.sh", "krl.sh", "authinfo.sh")
|
||||||
|
$known_failed_testcases_skipped = @()
|
||||||
|
|
||||||
|
$start_time = (Get-Date)
|
||||||
|
|
||||||
|
if($TestFilePath) {
|
||||||
|
# User can specify individual test file path.
|
||||||
|
$all_tests = $TestFilePath
|
||||||
|
} else {
|
||||||
|
# picking the gawk.exe from bash folder.
|
||||||
|
# TODO - check if gawk.exe is present in WSL.
|
||||||
|
$all_tests = gawk.exe 'sub(/.*LTESTS=/,""""){f=1} f{print $1; if (!/\\\\/) exit}' Makefile
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output ""
|
||||||
|
|
||||||
|
foreach ($test_file in $all_tests) {
|
||||||
|
if ($TestFilePath) {
|
||||||
|
$TEST = $test_file
|
||||||
|
} else {
|
||||||
|
if (!$test_file.Contains(".sh")) {
|
||||||
|
$TEST = $BashTestsPath + "/" + $test_file + ".sh"
|
||||||
|
} else {
|
||||||
|
$TEST = $BashTestsPath + "/" + $test_file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$test_file_name = [System.IO.Path]::GetFileName($TEST)
|
||||||
|
if ($known_failed_testcases.Contains($test_file_name))
|
||||||
|
{
|
||||||
|
Write-Output "Skip the known failed test:$test_file_name [$($all_tests.IndexOf($test_file) + 1) of $($all_tests.count)]"
|
||||||
|
$known_failed_testcases_skipped += "$test_file_name"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$msg = "Run $test_file_name [$($all_tests.IndexOf($test_file) + 1) of $($all_tests.count)] " + [System.DateTime]::Now
|
||||||
|
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
|
||||||
|
|
||||||
|
&$env:ShellPath -c "/usr/bin/sh $BashTestsPath/test-exec.sh $BashTestsPath/$temp_test_path $TEST 2>&1" | Out-File -FilePath $bash_test_log_file -Append -ErrorAction Stop
|
||||||
|
if ($?)
|
||||||
|
{
|
||||||
|
$msg = "$test_file_name PASSED " + [System.DateTime]::Now
|
||||||
|
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
|
||||||
|
$total_tests_passed++
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$msg = "$test_file_name FAILED " + [System.DateTime]::Now
|
||||||
|
Write-Output $msg | Tee-Object -FilePath $bash_test_log_file -Append -ErrorAction Stop
|
||||||
|
$total_tests_failed++
|
||||||
|
$failed_testcases = $failed_testcases + "$test_file_name "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$total_tests++
|
||||||
|
}
|
||||||
|
|
||||||
|
$end_time = (Get-Date)
|
||||||
|
|
||||||
|
# Create artifacts
|
||||||
|
$Global:bash_tests_summary = [ordered]@{
|
||||||
|
"StartTime" = $start_time.ToString();
|
||||||
|
"EndTime" = $end_time.ToString();
|
||||||
|
"TotalExecutionTime" = (NEW-TIMESPAN -Start $start_time -End $end_time).ToString("hh\:mm\:ss");
|
||||||
|
"TotalBashTests" = $total_tests;
|
||||||
|
"TotalBashTestsPassed" = $total_tests_passed;
|
||||||
|
"TotalBashTestsFailed" = $total_tests_failed;
|
||||||
|
"TotalBashTestsSkipped" = $known_failed_testcases_skipped.Count;
|
||||||
|
"FailedBashTests" = $failed_testcases;
|
||||||
|
"SkippedBashTests" = $known_failed_testcases_skipped -join ', ';
|
||||||
|
"BashTestSummaryFile" = $bash_test_summary
|
||||||
|
"BashTestLogFile" = $bash_test_log_file
|
||||||
|
}
|
||||||
|
|
||||||
|
$Global:bash_tests_summary | ConvertTo-Json | Out-File -FilePath $bash_test_summary
|
||||||
|
|
||||||
|
#output the summary
|
||||||
|
Write-Output "`n============================================"
|
||||||
|
Get-Content -Raw $bash_test_summary
|
||||||
|
Write-Output "============================================`n"
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
# remove temp test directory
|
||||||
|
if (!$SkipCleanup)
|
||||||
|
{
|
||||||
|
# remove temp test folder
|
||||||
|
&$ShellPath -c "rm -rf $BashTestsPath/temp_test"
|
||||||
|
|
||||||
|
if(!$SkipInstallSSHD) {
|
||||||
|
# Uninstall the sshd, ssh-agent service
|
||||||
|
& "$PSScriptRoot\uninstall-sshd.ps1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the test environment variable
|
||||||
|
Remove-Item ENV:\SSH_TEST_ENVIRONMENT
|
||||||
|
|
||||||
|
# Revert to user configured default shell.
|
||||||
|
if($user_default_shell) {
|
||||||
|
Set-ItemProperty -Path $registryPath -Name $dfltShell -Value $user_default_shell -Force
|
||||||
|
$out=(Get-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue)
|
||||||
|
if($out.$dfltShell -eq $user_default_shell) {
|
||||||
|
Write-Output "Reverted user configured default shell to $user_default_shell"
|
||||||
|
} else {
|
||||||
|
Write-Output "Failed to set HKLM:\Software\OpenSSH\DefaultShell to $user_default_shell"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Remove-ItemProperty -Path $registryPath -Name $dfltShell -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Push-location $user_pwd
|
||||||
|
}
|
@ -1709,166 +1709,187 @@ build_exec_command(const char * command)
|
|||||||
return cmd_sp;
|
return cmd_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cmd is internally decoarated with a set of '"'
|
* cmd is internally decoarated with a set of '"'
|
||||||
* to account for any spaces within the commandline
|
* to account for any spaces within the commandline
|
||||||
* the double quotes and backslash is escaped if needed
|
* the double quotes and backslash is escaped if needed
|
||||||
* this decoration is done only when additional arguments are passed in argv
|
* this decoration is done only when additional arguments are passed in argv
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
build_commandline_string(const char* cmd, char *const argv[], BOOLEAN prepend_module_path)
|
build_commandline_string(const char* cmd, char *const argv[], BOOLEAN prepend_module_path)
|
||||||
{
|
{
|
||||||
char *cmdline, *t, *tmp = NULL, *path = NULL, *ret = NULL;
|
char *cmdline, *t, *tmp = NULL, *path = NULL, *ret = NULL;
|
||||||
char * const *t1;
|
char * const *t1;
|
||||||
DWORD cmdline_len = 0, path_len = 0;
|
DWORD cmdline_len = 0, path_len = 0;
|
||||||
int add_module_path = 0;
|
int add_module_path = 0;
|
||||||
|
|
||||||
|
if (!cmd) {
|
||||||
|
error("%s invalid argument cmd:%s", __func__, cmd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(path = _strdup(cmd))) {
|
||||||
|
error("failed to duplicate %s", cmd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_len = (DWORD)strlen(path);
|
||||||
|
|
||||||
|
if (is_bash_test_env()) {
|
||||||
|
memset(path, 0, path_len + 1);
|
||||||
|
bash_to_win_path(cmd, path, path_len + 1);
|
||||||
|
path_len = (DWORD)strlen(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_absolute_path(path) && prepend_module_path)
|
||||||
|
add_module_path = 1;
|
||||||
|
|
||||||
|
/* compute total cmdline len*/
|
||||||
|
if (add_module_path)
|
||||||
|
cmdline_len += (DWORD)strlen(__progdir) + 1 + (DWORD)strlen(path) + 1 + 2;
|
||||||
|
else
|
||||||
|
cmdline_len += (DWORD)strlen(path) + 1 + 2;
|
||||||
|
|
||||||
|
if (argv) {
|
||||||
|
t1 = argv;
|
||||||
|
while (*t1) {
|
||||||
|
char *p = *t1++;
|
||||||
|
for (int i = 0; i < (int)strlen(p); i++) {
|
||||||
|
if (p[i] == '\\') {
|
||||||
|
char * b = p + i;
|
||||||
|
int additional_backslash = 0;
|
||||||
|
int backslash_count = 0;
|
||||||
|
/*
|
||||||
|
Backslashes are interpreted literally, unless they immediately
|
||||||
|
precede a double quotation mark.
|
||||||
|
*/
|
||||||
|
while (b != NULL && *b == '\\') {
|
||||||
|
backslash_count++;
|
||||||
|
b++;
|
||||||
|
if (b != NULL && *b == '\"') {
|
||||||
|
additional_backslash = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmdline_len += backslash_count * (additional_backslash + 1);
|
||||||
|
i += backslash_count - 1;
|
||||||
|
}
|
||||||
|
else if (p[i] == '\"')
|
||||||
|
/* backslash will be added for every double quote.*/
|
||||||
|
cmdline_len += 2;
|
||||||
|
else
|
||||||
|
cmdline_len++;
|
||||||
|
}
|
||||||
|
cmdline_len += 1 + 2; /*for "around cmd arg and traling space*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cmdline = malloc(cmdline_len)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = cmdline;
|
||||||
|
|
||||||
|
*t++ = '\"';
|
||||||
|
if (add_module_path) {
|
||||||
|
/* add current module path to start if needed */
|
||||||
|
memcpy(t, __progdir, strlen(__progdir));
|
||||||
|
t += strlen(__progdir);
|
||||||
|
*t++ = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path[0] != '\"') {
|
||||||
|
/* If path is <executable_path> <arg> then we should add double quotes after <executable_path> i.e., "<executable_path>" <arg> should be passed to CreateProcess().
|
||||||
|
* Example - If path is C:\cygwin64\bin\bash.exe /cygdrive/e/openssh-portable-latestw_all/openssh-portable/regress/scp-ssh-wrapper.sh then
|
||||||
|
* we should pass "C:\cygwin64\bin\bash.exe" /cygdrive/e/openssh-portable-latestw_all/openssh-portable/regress/scp-ssh-wrapper.sh
|
||||||
|
* to the CreateProcess() otherwise CreateProcess() will fail with error code 2.
|
||||||
|
*/
|
||||||
|
if (strstr(path, ".exe") && (tmp = strstr(strstr(path, ".exe"), " ")))
|
||||||
|
{
|
||||||
|
size_t tmp_pos = tmp - path;
|
||||||
|
memcpy(t, path, tmp_pos);
|
||||||
|
t += tmp_pos;
|
||||||
|
*t++ = '\"';
|
||||||
|
memcpy(t, tmp, strlen(path) - tmp_pos);
|
||||||
|
t += (strlen(path) - tmp_pos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(t, path, path_len);
|
||||||
|
t += path_len;
|
||||||
|
*t++ = '\"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*path already contains "*/
|
||||||
|
memcpy(t, path + 1, path_len - 1);
|
||||||
|
t += path_len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = '\0';
|
||||||
|
t = cmdline + strlen(cmdline);
|
||||||
|
|
||||||
|
if (argv) {
|
||||||
|
t1 = argv;
|
||||||
|
while (*t1) {
|
||||||
|
*t++ = ' ';
|
||||||
|
char * p1 = *t1++;
|
||||||
|
BOOL add_quotes = FALSE;
|
||||||
|
/* leave as is if the command is surrounded by single quotes*/
|
||||||
|
if (p1[0] != '\'')
|
||||||
|
for (int i = 0; i < (int)strlen(p1); i++) {
|
||||||
|
if (p1[i] == ' ') {
|
||||||
|
add_quotes = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add_quotes)
|
||||||
|
*t++ = '\"';
|
||||||
|
for (int i = 0; i < (int)strlen(p1); i++) {
|
||||||
|
if (p1[i] == '\\') {
|
||||||
|
char * b = p1 + i;
|
||||||
|
int additional_backslash = 0;
|
||||||
|
int backslash_count = 0;
|
||||||
|
/*
|
||||||
|
* Backslashes are interpreted literally, unless they immediately
|
||||||
|
* precede a double quotation mark.
|
||||||
|
*/
|
||||||
|
while (b != NULL && *b == '\\') {
|
||||||
|
backslash_count++;
|
||||||
|
b++;
|
||||||
|
if (b != NULL && *b == '\"') {
|
||||||
|
additional_backslash = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += backslash_count - 1;
|
||||||
|
int escaped_backslash_count = backslash_count * (additional_backslash + 1);
|
||||||
|
while (escaped_backslash_count--)
|
||||||
|
*t++ = '\\';
|
||||||
|
}
|
||||||
|
else if (p1[i] == '\"') {
|
||||||
|
/* Add backslash for every double quote.*/
|
||||||
|
*t++ = '\\';
|
||||||
|
*t++ = '\"';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*t++ = p1[i];
|
||||||
|
}
|
||||||
|
if (add_quotes)
|
||||||
|
*t++ = '\"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*t = '\0';
|
||||||
|
ret = cmdline;
|
||||||
|
cmdline = NULL;
|
||||||
|
cleanup:
|
||||||
|
if (path)
|
||||||
|
free(path);
|
||||||
|
if (cmdline)
|
||||||
|
free(cmdline);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cmd) {
|
|
||||||
error("%s invalid argument cmd:%s", __func__, cmd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(path = _strdup(cmd))) {
|
|
||||||
error("failed to duplicate %s", cmd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_len = (DWORD)strlen(path);
|
|
||||||
|
|
||||||
if (is_bash_test_env()) {
|
|
||||||
memset(path, 0, path_len + 1);
|
|
||||||
bash_to_win_path(cmd, path, path_len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_absolute_path(path) && prepend_module_path)
|
|
||||||
add_module_path = 1;
|
|
||||||
|
|
||||||
/* compute total cmdline len*/
|
|
||||||
if (add_module_path)
|
|
||||||
cmdline_len += (DWORD)strlen(__progdir) + 1 + (DWORD)strlen(path) + 1 + 2;
|
|
||||||
else
|
|
||||||
cmdline_len += (DWORD)strlen(path) + 1 + 2;
|
|
||||||
|
|
||||||
if (argv) {
|
|
||||||
t1 = argv;
|
|
||||||
while (*t1) {
|
|
||||||
char *p = *t1++;
|
|
||||||
for (int i = 0; i < (int)strlen(p); i++) {
|
|
||||||
if (p[i] == '\\') {
|
|
||||||
char * b = p + i;
|
|
||||||
int additional_backslash = 0;
|
|
||||||
int backslash_count = 0;
|
|
||||||
/*
|
|
||||||
Backslashes are interpreted literally, unless they immediately
|
|
||||||
precede a double quotation mark.
|
|
||||||
*/
|
|
||||||
while (b != NULL && *b == '\\') {
|
|
||||||
backslash_count++;
|
|
||||||
b++;
|
|
||||||
if (b != NULL && *b == '\"') {
|
|
||||||
additional_backslash = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmdline_len += backslash_count * (additional_backslash + 1);
|
|
||||||
i += backslash_count - 1;
|
|
||||||
}
|
|
||||||
else if (p[i] == '\"')
|
|
||||||
/* backslash will be added for every double quote.*/
|
|
||||||
cmdline_len += 2;
|
|
||||||
else
|
|
||||||
cmdline_len++;
|
|
||||||
}
|
|
||||||
cmdline_len += 1 + 2; /*for "around cmd arg and traling space*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cmdline = malloc(cmdline_len)) == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
t = cmdline;
|
|
||||||
*t++ = '\"';
|
|
||||||
if (add_module_path) {
|
|
||||||
/* add current module path to start if needed */
|
|
||||||
memcpy(t, __progdir, strlen(__progdir));
|
|
||||||
t += strlen(__progdir);
|
|
||||||
*t++ = '\\';
|
|
||||||
}
|
|
||||||
if (path[0] != '\"') {
|
|
||||||
memcpy(t, path, path_len);
|
|
||||||
t += path_len;
|
|
||||||
*t++ = '\"';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*path already contains "*/
|
|
||||||
memcpy(t, path + 1, path_len - 1);
|
|
||||||
t += path_len - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = '\0';
|
|
||||||
t = cmdline + strlen(cmdline);
|
|
||||||
|
|
||||||
if (argv) {
|
|
||||||
t1 = argv;
|
|
||||||
while (*t1) {
|
|
||||||
*t++ = ' ';
|
|
||||||
char * p1 = *t1++;
|
|
||||||
BOOL add_quotes = FALSE;
|
|
||||||
/* leave as is if the command is surrounded by single quotes*/
|
|
||||||
if (p1[0] != '\'')
|
|
||||||
for (int i = 0; i < (int)strlen(p1); i++) {
|
|
||||||
if (p1[i] == ' ') {
|
|
||||||
add_quotes = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (add_quotes)
|
|
||||||
*t++ = '\"';
|
|
||||||
for (int i = 0; i < (int)strlen(p1); i++) {
|
|
||||||
if (p1[i] == '\\') {
|
|
||||||
char * b = p1 + i;
|
|
||||||
int additional_backslash = 0;
|
|
||||||
int backslash_count = 0;
|
|
||||||
/*
|
|
||||||
* Backslashes are interpreted literally, unless they immediately
|
|
||||||
* precede a double quotation mark.
|
|
||||||
*/
|
|
||||||
while (b != NULL && *b == '\\') {
|
|
||||||
backslash_count++;
|
|
||||||
b++;
|
|
||||||
if (b != NULL && *b == '\"') {
|
|
||||||
additional_backslash = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i += backslash_count - 1;
|
|
||||||
int escaped_backslash_count = backslash_count * (additional_backslash + 1);
|
|
||||||
while (escaped_backslash_count--)
|
|
||||||
*t++ = '\\';
|
|
||||||
}
|
|
||||||
else if (p1[i] == '\"') {
|
|
||||||
/* Add backslash for every double quote.*/
|
|
||||||
*t++ = '\\';
|
|
||||||
*t++ = '\"';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*t++ = p1[i];
|
|
||||||
}
|
|
||||||
if (add_quotes)
|
|
||||||
*t++ = '\"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*t = '\0';
|
|
||||||
ret = cmdline;
|
|
||||||
cmdline = NULL;
|
|
||||||
cleanup:
|
|
||||||
if (path)
|
|
||||||
free(path);
|
|
||||||
if (cmdline)
|
|
||||||
free(cmdline);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
BOOL
|
BOOL
|
||||||
is_bash_test_env()
|
is_bash_test_env()
|
||||||
{
|
{
|
||||||
|
@ -127,6 +127,11 @@ ReadThread(_In_ LPVOID lpParameter)
|
|||||||
pio->sync_read_status.error = GetLastError();
|
pio->sync_read_status.error = GetLastError();
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there is no data to be read then set the error to ERROR_HANDLE_EOF */
|
||||||
|
if (!pio->sync_read_status.transferred) {
|
||||||
|
pio->sync_read_status.error = ERROR_HANDLE_EOF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -1044,7 +1044,7 @@ char * build_commandline_string(const char* cmd, char *const argv[], BOOLEAN pre
|
|||||||
* spawned child will run as as_user if its not NULL
|
* spawned child will run as as_user if its not NULL
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDLE err, unsigned long flags, HANDLE* as_user, BOOLEAN prepend_module_path)
|
spawn_child_internal(const char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDLE err, unsigned long flags, HANDLE* as_user, BOOLEAN prepend_module_path)
|
||||||
{
|
{
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
@ -1262,7 +1262,7 @@ posix_spawn_internal(pid_t *pidp, const char *path, const posix_spawn_file_actio
|
|||||||
|
|
||||||
if (_putenv_s(POSIX_FD_STATE, fd_info) != 0)
|
if (_putenv_s(POSIX_FD_STATE, fd_info) != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
i = spawn_child_internal(argv[0], argv + 1, stdio_handles[STDIN_FILENO], stdio_handles[STDOUT_FILENO], stdio_handles[STDERR_FILENO], sc_flags, user_token, prepend_module_path);
|
i = spawn_child_internal(path, argv + 1, stdio_handles[STDIN_FILENO], stdio_handles[STDOUT_FILENO], stdio_handles[STDERR_FILENO], sc_flags, user_token, prepend_module_path);
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (pidp)
|
if (pidp)
|
||||||
|
@ -115,7 +115,6 @@ get_user_groups()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DWORD i = 0; i < group_buf->GroupCount; i++) {
|
for (DWORD i = 0; i < group_buf->GroupCount; i++) {
|
||||||
|
|
||||||
/* only bother with group thats are 'enabled' from a security perspective */
|
/* only bother with group thats are 'enabled' from a security perspective */
|
||||||
if ((group_buf->Groups[i].Attributes & SE_GROUP_ENABLED) == 0 ||
|
if ((group_buf->Groups[i].Attributes & SE_GROUP_ENABLED) == 0 ||
|
||||||
!IsValidSid(group_buf->Groups[i].Sid))
|
!IsValidSid(group_buf->Groups[i].Sid))
|
||||||
@ -278,6 +277,7 @@ int
|
|||||||
ga_match_pattern_list(const char *group_pattern)
|
ga_match_pattern_list(const char *group_pattern)
|
||||||
{
|
{
|
||||||
int i, found = 0;
|
int i, found = 0;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
/* group retrieval is expensive, optmizing the common case scenario - only one group with no wild cards and no negation */
|
/* group retrieval is expensive, optmizing the common case scenario - only one group with no wild cards and no negation */
|
||||||
if (!strchr(group_pattern, ',') && !strchr(group_pattern, '?') &&
|
if (!strchr(group_pattern, ',') && !strchr(group_pattern, '?') &&
|
||||||
@ -287,8 +287,15 @@ ga_match_pattern_list(const char *group_pattern)
|
|||||||
if (get_user_groups() == -1)
|
if (get_user_groups() == -1)
|
||||||
fatal("unable to retrieve group info for user %s", user_name);
|
fatal("unable to retrieve group info for user %s", user_name);
|
||||||
|
|
||||||
|
/* For domain groups we need special handling.
|
||||||
|
* We support both "domain\group_name" and "domain/group_name" formats.
|
||||||
|
*/
|
||||||
|
if (tmp = strstr(group_pattern, "/"))
|
||||||
|
*tmp = '\\';
|
||||||
|
|
||||||
for (i = 0; i < ngroups; i++) {
|
for (i = 0; i < ngroups; i++) {
|
||||||
switch (match_pattern_list(groups_byname[i], group_pattern, 0)) {
|
/* Group names are case insensitive */
|
||||||
|
switch (match_pattern_list(groups_byname[i], group_pattern, 1)) {
|
||||||
case -1:
|
case -1:
|
||||||
return 0; /* Negated match wins */
|
return 0; /* Negated match wins */
|
||||||
case 0:
|
case 0:
|
||||||
|
10
match.c
10
match.c
@ -177,8 +177,14 @@ match_usergroup_pattern_list(const char *string, const char *pattern)
|
|||||||
#ifdef HAVE_CYGWIN
|
#ifdef HAVE_CYGWIN
|
||||||
/* Windows usernames may be Unicode and are not case sensitive */
|
/* Windows usernames may be Unicode and are not case sensitive */
|
||||||
return cygwin_ug_match_pattern_list(string, pattern);
|
return cygwin_ug_match_pattern_list(string, pattern);
|
||||||
#elseif WINDOWS
|
#elif WINDOWS
|
||||||
if (match_pattern_list(ci->user, arg, 1) != 1)
|
/* We support both domain/username and domain\\username format */
|
||||||
|
char *tmp = NULL;
|
||||||
|
if (tmp = strstr(pattern, "/"))
|
||||||
|
*tmp = '\\';
|
||||||
|
|
||||||
|
/* Windows usernames are case insensitive */
|
||||||
|
return match_pattern_list(string, pattern, 1);
|
||||||
#else
|
#else
|
||||||
/* Case insensitive match */
|
/* Case insensitive match */
|
||||||
return match_pattern_list(string, pattern, 0);
|
return match_pattern_list(string, pattern, 0);
|
||||||
|
@ -26,8 +26,14 @@ timingsafe_bcmp(const void *b1, const void *b2, size_t n)
|
|||||||
const unsigned char *p1 = b1, *p2 = b2;
|
const unsigned char *p1 = b1, *p2 = b2;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
for (; n > 0; n--)
|
for (; n > 0; n--) {
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (*p1 == '\r' && *(p1 + 1) == '\n' && *p2 == '\n')
|
||||||
|
p1++;
|
||||||
|
#endif // WINDOWS
|
||||||
ret |= *p1++ ^ *p2++;
|
ret |= *p1++ ^ *p2++;
|
||||||
|
}
|
||||||
|
|
||||||
return (ret != 0);
|
return (ret != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ start_client()
|
|||||||
if test $n -gt 60; then
|
if test $n -gt 60; then
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
# We can't kill windows process from cygwin / wsl so use "stop-process"
|
# We can't kill windows process from cygwin / wsl so use "stop-process"
|
||||||
powershell.exe /c "stop-process -id $client_pid"
|
powershell.exe /c "stop-process -id $client_pid" >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
kill $client_pid
|
kill $client_pid
|
||||||
fi
|
fi
|
||||||
@ -39,8 +39,8 @@ stop_client()
|
|||||||
pid=`cat $pidfile`
|
pid=`cat $pidfile`
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
# We can't kill windows process from cygwin / wsl so use "stop-process"
|
# We can't kill windows process from cygwin / wsl so use "stop-process"
|
||||||
powershell.exe /c "stop-process -id $pid"
|
powershell.exe /c "stop-process -id $pid" >/dev/null 2>&1
|
||||||
powershell.exe /c "stop-process -name sleep"
|
powershell.exe /c "stop-process -name sleep" >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
if [ ! -z "$pid" ]; then
|
if [ ! -z "$pid" ]; then
|
||||||
kill $pid
|
kill $pid
|
||||||
@ -174,6 +174,9 @@ for i in $params; do
|
|||||||
trace "test spec $spec"
|
trace "test spec $spec"
|
||||||
result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \
|
result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \
|
||||||
awk '$1=="banner"{print $2}'`
|
awk '$1=="banner"{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
result=${result/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
if [ "$result" != "$expected" ]; then
|
if [ "$result" != "$expected" ]; then
|
||||||
fail "match $config expected $expected got $result"
|
fail "match $config expected $expected got $result"
|
||||||
fi
|
fi
|
||||||
|
@ -29,8 +29,12 @@ start_client()
|
|||||||
sleep 1
|
sleep 1
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
if test $n -gt 60; then
|
if test $n -gt 60; then
|
||||||
kill $client_pid
|
if [ "$os" == "windows" ]; then
|
||||||
fatal "timeout waiting for background ssh"
|
powershell.exe /c "stop-process -Id $client_pid -Force" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
kill $client_pid
|
||||||
|
fatal "timeout waiting for background ssh"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
return $r
|
return $r
|
||||||
@ -53,10 +57,14 @@ expect_client_fail()
|
|||||||
stop_client()
|
stop_client()
|
||||||
{
|
{
|
||||||
pid=`cat $pidfile`
|
pid=`cat $pidfile`
|
||||||
if [ ! -z "$pid" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
kill $pid
|
powershell.exe /c "stop-process -Id $pid -Force" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
if [ ! -z "$pid" ]; then
|
||||||
|
kill $pid
|
||||||
|
fi
|
||||||
|
wait
|
||||||
fi
|
fi
|
||||||
wait
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
tid="hostkey rotate"
|
tid="hostkey rotate"
|
||||||
|
|
||||||
# Need full names here since they are used in HostKeyAlgorithms
|
# Need full names here since they are used in HostKeyAlgorithms
|
||||||
HOSTKEY_TYPES="`${SSH} -Q key-plain`"
|
if [ "$os" == "windows" ]; then
|
||||||
|
HOSTKEY_TYPES=`${SSH} -Q key-plain | sed 's/\r$//'` # remove CR (carriage return)
|
||||||
|
else
|
||||||
|
HOSTKEY_TYPES=`${SSH} -Q key-plain`
|
||||||
|
fi
|
||||||
|
|
||||||
rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig
|
rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig
|
||||||
|
|
||||||
@ -21,9 +25,6 @@ trace "prepare hostkeys"
|
|||||||
nkeys=0
|
nkeys=0
|
||||||
all_algs=""
|
all_algs=""
|
||||||
for k in $HOSTKEY_TYPES; do
|
for k in $HOSTKEY_TYPES; do
|
||||||
if [ "$os" == "windows" ]; then
|
|
||||||
k=`echo $k | sed 's/\r$//'` # remove CR (carriage return)
|
|
||||||
fi
|
|
||||||
${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"
|
${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k"
|
||||||
echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig
|
echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig
|
||||||
nkeys=`expr $nkeys + 1`
|
nkeys=`expr $nkeys + 1`
|
||||||
|
@ -105,11 +105,11 @@ if [ "$os" == "windows" ]; then
|
|||||||
"powershell.exe /c \"!(Get-ChildItem $`windows_path $OBJ`/copy).IsReadOnly\" 1>/dev/null"
|
"powershell.exe /c \"!(Get-ChildItem $`windows_path $OBJ`/copy).IsReadOnly\" 1>/dev/null"
|
||||||
else
|
else
|
||||||
ro_test \
|
ro_test \
|
||||||
"setstat" \
|
"setstat" \
|
||||||
"chmod 0700 $COPY" \
|
"chmod 0700 $COPY" \
|
||||||
"touch $COPY; chmod 0400 $COPY" \
|
"touch $COPY; chmod 0400 $COPY" \
|
||||||
"test -x $COPY" \
|
"test -x $COPY" \
|
||||||
"test ! -x $COPY"
|
"test ! -x $COPY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ro_test \
|
ro_test \
|
||||||
|
@ -72,31 +72,55 @@ test "$f" = "no" || fail "clearallforwardings override"
|
|||||||
verbose "user first match"
|
verbose "user first match"
|
||||||
user=`awk '$1=="User" {print $2}' $OBJ/ssh_config`
|
user=`awk '$1=="User" {print $2}' $OBJ/ssh_config`
|
||||||
f=`${SSH} -GF $OBJ/ssh_config host | awk '/^user /{print $2}'`
|
f=`${SSH} -GF $OBJ/ssh_config host | awk '/^user /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
test "$f" = "$user" || fail "user from config, expected '$user' got '$f'"
|
test "$f" = "$user" || fail "user from config, expected '$user' got '$f'"
|
||||||
f=`${SSH} -GF $OBJ/ssh_config -o user=foo -l bar baz@host | awk '/^user /{print $2}'`
|
f=`${SSH} -GF $OBJ/ssh_config -o user=foo -l bar baz@host | awk '/^user /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
test "$f" = "foo" || fail "user first match -oUser, expected 'foo' got '$f' "
|
test "$f" = "foo" || fail "user first match -oUser, expected 'foo' got '$f' "
|
||||||
f=`${SSH} -GF $OBJ/ssh_config -lbar baz@host user=foo baz@host | awk '/^user /{print $2}'`
|
f=`${SSH} -GF $OBJ/ssh_config -lbar baz@host user=foo baz@host | awk '/^user /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
test "$f" = "bar" || fail "user first match -l, expected 'bar' got '$f'"
|
test "$f" = "bar" || fail "user first match -l, expected 'bar' got '$f'"
|
||||||
f=`${SSH} -GF $OBJ/ssh_config baz@host -o user=foo -l bar baz@host | awk '/^user /{print $2}'`
|
f=`${SSH} -GF $OBJ/ssh_config baz@host -o user=foo -l bar baz@host | awk '/^user /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
test "$f" = "baz" || fail "user first match user@host, expected 'baz' got '$f'"
|
test "$f" = "baz" || fail "user first match user@host, expected 'baz' got '$f'"
|
||||||
|
|
||||||
verbose "pubkeyacceptedkeytypes"
|
verbose "pubkeyacceptedkeytypes"
|
||||||
# Default set
|
# Default set
|
||||||
f=`${SSH} -GF none host | awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
f=`${SSH} -GF none host | awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*"
|
expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*"
|
||||||
expect_result_absent "$f" "ssh-dss"
|
expect_result_absent "$f" "ssh-dss"
|
||||||
# Explicit override
|
# Explicit override
|
||||||
f=`${SSH} -GF none -opubkeyacceptedkeytypes=ssh-ed25519 host | \
|
f=`${SSH} -GF none -opubkeyacceptedkeytypes=ssh-ed25519 host | \
|
||||||
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519"
|
expect_result_present "$f" "ssh-ed25519"
|
||||||
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
||||||
# Removal from default set
|
# Removal from default set
|
||||||
f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519-cert* host | \
|
f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519-cert* host | \
|
||||||
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519"
|
expect_result_present "$f" "ssh-ed25519"
|
||||||
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
||||||
f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519 host | \
|
f=`${SSH} -GF none -opubkeyacceptedkeytypes=-ssh-ed25519 host | \
|
||||||
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519-cert-v01.*"
|
expect_result_present "$f" "ssh-ed25519-cert-v01.*"
|
||||||
expect_result_absent "$f" "ssh-ed25519" "ssh-dss"
|
expect_result_absent "$f" "ssh-ed25519" "ssh-dss"
|
||||||
# Append to default set.
|
# Append to default set.
|
||||||
@ -104,10 +128,16 @@ expect_result_absent "$f" "ssh-ed25519" "ssh-dss"
|
|||||||
if [ "$dsa" = "1" ]; then
|
if [ "$dsa" = "1" ]; then
|
||||||
f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss-cert* host | \
|
f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss-cert* host | \
|
||||||
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*"
|
expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*"
|
||||||
expect_result_absent "$f" "ssh-dss"
|
expect_result_absent "$f" "ssh-dss"
|
||||||
f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss host | \
|
f=`${SSH} -GF none -opubkeyacceptedkeytypes=+ssh-dss host | \
|
||||||
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
awk '/^pubkeyacceptedkeytypes /{print $2}'`
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
f=${f/$'\r'/} # remove CR (carriage return)
|
||||||
|
fi
|
||||||
expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss"
|
||||||
expect_result_absent "$f" "ssh-dss-cert-v01.*"
|
expect_result_absent "$f" "ssh-dss-cert-v01.*"
|
||||||
fi
|
fi
|
||||||
|
@ -362,8 +362,15 @@ stop_sshd ()
|
|||||||
|
|
||||||
make_tmpdir ()
|
make_tmpdir ()
|
||||||
{
|
{
|
||||||
SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \
|
if [ "$os" == "windows" ]; then
|
||||||
fatal "failed to create temporary directory"
|
powershell.exe /c "New-Item -Path $OBJ\openssh-XXXXXXXX -ItemType Directory -Force" >/dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
fatal "failed to create temporary directory"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \
|
||||||
|
fatal "failed to create temporary directory"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# helper
|
# helper
|
||||||
@ -514,6 +521,7 @@ rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
|
|||||||
|
|
||||||
SSH_KEYTYPES=`$SSH -Q key-plain`
|
SSH_KEYTYPES=`$SSH -Q key-plain`
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
|
SSH_KEYTYPES=`echo $SSH_KEYTYPES | tr -d '\r','\n'` # remove \r\n
|
||||||
first_key_type=${SSH_KEYTYPES%% *}
|
first_key_type=${SSH_KEYTYPES%% *}
|
||||||
if [ "x$USER_DOMAIN" != "x" ]; then
|
if [ "x$USER_DOMAIN" != "x" ]; then
|
||||||
# For domain user, create folders
|
# For domain user, create folders
|
||||||
@ -529,9 +537,14 @@ if [ "$os" == "windows" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$os" == "windows" ]; then
|
||||||
|
OBJ_WIN_FORMAT=`windows_path $OBJ`
|
||||||
|
fi
|
||||||
|
|
||||||
for t in ${SSH_KEYTYPES}; do
|
for t in ${SSH_KEYTYPES}; do
|
||||||
# generate user key
|
# generate user key
|
||||||
trace "generating key type $t"
|
trace "generating key type $t"
|
||||||
|
|
||||||
if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
|
if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
|
||||||
rm -f $OBJ/$t
|
rm -f $OBJ/$t
|
||||||
${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\
|
${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\
|
||||||
@ -552,7 +565,7 @@ for t in ${SSH_KEYTYPES}; do
|
|||||||
$SUDO cp $OBJ/$t $OBJ/host.$t
|
$SUDO cp $OBJ/$t $OBJ/host.$t
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
# set the file permissions (ACLs) properly
|
# set the file permissions (ACLs) properly
|
||||||
powershell.exe /c "get-acl `windows_path $OBJ`/$t | set-acl `windows_path $OBJ`/host.$t"
|
powershell.exe /c "get-acl $OBJ_WIN_FORMAT/$t | set-acl $OBJ_WIN_FORMAT/host.$t"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
|
echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
|
||||||
@ -563,7 +576,7 @@ done
|
|||||||
|
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
# set the file permissions (ACLs) properly
|
# set the file permissions (ACLs) properly
|
||||||
powershell.exe /c "get-acl `windows_path $OBJ`/$first_key_type | set-acl `windows_path $OBJ`/authorized_keys_$USER"
|
powershell.exe /c "get-acl $OBJ_WIN_FORMAT/$first_key_type | set-acl $OBJ_WIN_FORMAT/authorized_keys_$USER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Activate Twisted Conch tests if the binary is present
|
# Activate Twisted Conch tests if the binary is present
|
||||||
@ -626,7 +639,7 @@ fi
|
|||||||
(
|
(
|
||||||
cat $OBJ/ssh_config
|
cat $OBJ/ssh_config
|
||||||
if [ "$os" == "windows" ]; then
|
if [ "$os" == "windows" ]; then
|
||||||
echo proxycommand `windows_path ${SSHD}` -i -f `windows_path $OBJ`/sshd_proxy
|
echo proxycommand `windows_path ${SSHD}` -i -f $OBJ_WIN_FORMAT/sshd_proxy
|
||||||
else
|
else
|
||||||
echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
|
echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
|
||||||
fi
|
fi
|
||||||
|
@ -364,7 +364,7 @@ test_build_commandline_string()
|
|||||||
ASSERT_STRING_EQ(out, "\"c:\\windows\\system32\\cmd.exe\" /c arg");
|
ASSERT_STRING_EQ(out, "\"c:\\windows\\system32\\cmd.exe\" /c arg");
|
||||||
free(out);
|
free(out);
|
||||||
out = build_commandline_string("cmd.exe /c ping.exe", NULL, FALSE);
|
out = build_commandline_string("cmd.exe /c ping.exe", NULL, FALSE);
|
||||||
ASSERT_STRING_EQ(out, "\"cmd.exe /c ping.exe\"");
|
ASSERT_STRING_EQ(out, "\"cmd.exe\" /c ping.exe");
|
||||||
sprintf_s(in, PATH_MAX, "\"%s\\%s\"", __progdir, "ssh-shellhost.exe\" -c \"arg1 arg2\"");
|
sprintf_s(in, PATH_MAX, "\"%s\\%s\"", __progdir, "ssh-shellhost.exe\" -c \"arg1 arg2\"");
|
||||||
out = build_commandline_string(in, NULL, TRUE);
|
out = build_commandline_string(in, NULL, TRUE);
|
||||||
ASSERT_STRING_EQ(out, in);
|
ASSERT_STRING_EQ(out, in);
|
||||||
|
@ -1181,7 +1181,12 @@ process_realpath(u_int32_t id)
|
|||||||
}
|
}
|
||||||
debug3("request %u: realpath", id);
|
debug3("request %u: realpath", id);
|
||||||
verbose("realpath \"%s\"", path);
|
verbose("realpath \"%s\"", path);
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (realpath(path, resolvedname) == NULL) {
|
||||||
|
#else
|
||||||
if (sftp_realpath(path, resolvedname) == NULL) {
|
if (sftp_realpath(path, resolvedname) == NULL) {
|
||||||
|
#endif // WINDOWS
|
||||||
send_status(id, errno_to_portable(errno));
|
send_status(id, errno_to_portable(errno));
|
||||||
} else {
|
} else {
|
||||||
Stat s;
|
Stat s;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user