latestw + Test Infra upgrades

Includes
- CR changes for upstream PR
- Fix in spawn_child logic
- Test Infra upgrades
This commit is contained in:
Yanbing 2017-03-24 12:35:52 -07:00 committed by Manoj Ampalam
parent 78995b5a42
commit 425bc4033f
60 changed files with 2006 additions and 1507 deletions

View File

@ -11,12 +11,12 @@ init:
build_script: build_script:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Invoke-AppVeyorBuild Invoke-AppVeyorBuild
after_build: after_build:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Install-OpenSSH Install-OpenSSH
- ps: Write-Verbose "Restart computer ..." - ps: Write-Verbose "Restart computer ..."
- ps: Restart-Computer -Force - ps: Restart-Computer -Force
@ -25,23 +25,22 @@ after_build:
before_test: before_test:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Install-TestDependencies Install-OpenSSHTestDependencies
Deploy-OpenSSHTests Deploy-OpenSSHTests
Setup-OpenSSHTestEnvironment -Quiet
test_script: test_script:
- cmd: |
"%ProgramFiles%\PowerShell\6.0.0.14\powershell.exe" -Command "Import-Module \"%APPVEYOR_BUILD_FOLDER%\contrib\win32\openssh\AppVeyor.psm1\" -DisableNameChecking;Run-OpenSSHPesterTest"
- ps: | - ps: |
Check-PesterTestResult Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Run-OpenSSHUnitTest Run-OpenSSHTests
after_test: after_test:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Upload-OpenSSHTestResults Upload-OpenSSHTestResults
on_finish: on_finish:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -DisableNameChecking Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Publish-Artifact Publish-Artifact

View File

@ -227,15 +227,16 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
#elif defined(WINDOWS) #elif defined(WINDOWS)
/* /*
* Authenticate on Windows - Pass credentials to ssh-agent and retrieve token * Authenticate on Windows - Pass credentials to ssh-agent and retrieve token
* upon succesful authentication * upon successful authentication
* TODO - password is sent in plain text over IPC. Consider implications.
*/ */
extern int auth_sock;
int sys_auth_passwd(Authctxt *authctxt, const char *password) int sys_auth_passwd(Authctxt *authctxt, const char *password)
{ {
struct sshbuf *msg = NULL;
size_t blen = 0; size_t blen = 0;
DWORD token = 0; DWORD token = 0;
struct sshbuf *msg = NULL; extern int auth_sock;
int r; int r = 0;
msg = sshbuf_new(); msg = sshbuf_new();
if (!msg) if (!msg)

4
auth.c
View File

@ -490,7 +490,7 @@ auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
uid_t uid, char *err, size_t errlen) uid_t uid, char *err, size_t errlen)
{ {
#ifdef WINDOWS #ifdef WINDOWS
error("auth_secure_path should not be called in Windows"); error("auth_secure_path should not be called in Windows yet");
return -1; return -1;
#else /* !WINDOWS */ #else /* !WINDOWS */
char buf[PATH_MAX], homedir[PATH_MAX]; char buf[PATH_MAX], homedir[PATH_MAX];
@ -579,7 +579,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
FILE *f; FILE *f;
#ifdef WINDOWS #ifdef WINDOWS
/* Windows POSIX adpater does not support fdopen() on open(file)*/ /* Windows POSIX adapter does not support fdopen() on open(file)*/
if ((f = fopen(file, "r")) == NULL) { if ((f = fopen(file, "r")) == NULL) {
debug("Could not open %s '%s': %s", file_type, file, debug("Could not open %s '%s': %s", file_type, file,
strerror(errno)); strerror(errno));

View File

@ -178,14 +178,14 @@ userauth_pubkey(Authctxt *authctxt)
authenticated = 0; authenticated = 0;
#ifdef WINDOWS #ifdef WINDOWS
/* Pass key challenge material to ssh-agent to retrieve token upon succesful authentication */ /* Pass key challenge material to ssh-agent to retrieve token upon successful authentication */
{ {
extern int auth_sock; struct sshbuf *msg = NULL;
int r;
u_char *blob = NULL; u_char *blob = NULL;
size_t blen = 0; size_t blen = 0;
DWORD token = 0; DWORD token = 0;
struct sshbuf *msg = NULL; extern int auth_sock;
int r = 0;
while (1) { while (1) {
msg = sshbuf_new(); msg = sshbuf_new();
@ -246,11 +246,7 @@ userauth_pubkey(Authctxt *authctxt)
* if a user is not allowed to login. is this an * if a user is not allowed to login. is this an
* issue? -markus * issue? -markus
*/ */
#ifdef WINDOWS /* key validation in done in agent for Windows */
{
#else /* !WINDOWS */
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) { if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
#endif /* !WINDOWS */
packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen); packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen); packet_put_string(pkblob, blen);

View File

@ -113,7 +113,6 @@ ssh_get_authentication_socket(int *fdp)
errno = oerrno; errno = oerrno;
return SSH_ERR_SYSTEM_ERROR; return SSH_ERR_SYSTEM_ERROR;
} }
if (fdp != NULL) if (fdp != NULL)
*fdp = sock; *fdp = sock;
else else

View File

@ -0,0 +1,268 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHBuildHelper.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHTestHelper.psm1 -Force -DisableNameChecking
$repoRoot = Get-RepositoryRoot
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
# Sets a build variable
Function Write-BuildMessage
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message,
$Category,
[string] $Details)
if($env:AppVeyor)
{
Add-AppveyorMessage @PSBoundParameters
}
# write it to the log file, if present.
if (-not ([string]::IsNullOrEmpty($script:messageFile)))
{
Add-Content -Path $script:messageFile -Value "$Category--$Message"
}
}
# Sets a build variable
Function Set-BuildVariable
{
param(
[Parameter(Mandatory=$true)]
[string]
$Name,
[Parameter(Mandatory=$true)]
[string]
$Value
)
if($env:AppVeyor -and (Get-Command Set-AppveyorBuildVariable -ErrorAction Ignore) -ne $null)
{
Set-AppveyorBuildVariable @PSBoundParameters
}
elseif($env:AppVeyor)
{
appveyor SetVariable -Name $Name -Value $Value
}
else
{
Set-Item env:$Name -Value $Value
}
}
# Emulates running all of AppVeyor but locally
# should not be used on AppVeyor
function Invoke-AppVeyorFull
{
param(
[switch] $APPVEYOR_SCHEDULED_BUILD,
[switch] $CleanRepo
)
if($CleanRepo)
{
Clear-PSRepo
}
if($env:APPVEYOR)
{
throw "This function is to simulate appveyor, but not to be run from appveyor!"
}
if($APPVEYOR_SCHEDULED_BUILD)
{
$env:APPVEYOR_SCHEDULED_BUILD = 'True'
}
try {
Set-OpenSSHTestParams
Invoke-AppVeyorBuild
Install-OpenSSH
Install-OpenSSHTestDependencies
Deploy-OpenSSHTests
Setup-OpenSSHTestEnvironment
Run-OpenSSHTests
Publish-Artifact
}
finally {
if($APPVEYOR_SCHEDULED_BUILD -and $env:APPVEYOR_SCHEDULED_BUILD)
{
Remove-Item env:APPVEYOR_SCHEDULED_BUILD
}
}
}
# Implements the AppVeyor 'build_script' step
function Invoke-AppVeyorBuild
{
Set-BuildVariable TestPassed True
Build-OpenSSH -Configuration Release -NativeHostArch x64
Build-OpenSSH -Configuration Debug -NativeHostArch x86
Write-BuildMessage -Message "OpenSSH binaries build success!" -Category Information
}
<#
.Synopsis
Adds a build log to the list of published artifacts.
.Description
If a build log exists, it is renamed to reflect the associated CLR runtime then added to the list of
artifacts to publish. If it doesn't exist, a warning is written and the file is skipped.
The rename is needed since publishing overwrites the artifact if it already exists.
.Parameter artifacts
An array list to add the fully qualified build log path
.Parameter buildLog
The build log file produced by the build.
#>
function Add-BuildLog
{
param
(
[ValidateNotNull()]
[System.Collections.ArrayList] $artifacts,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $buildLog
)
if (Test-Path -Path $buildLog)
{
$null = $artifacts.Add($buildLog)
}
else
{
Write-Warning "Skip publishing build log. $buildLog does not exist"
}
}
<#
.Synopsis
Publishes package build artifacts.
.Parameter artifacts
An array list to add the fully qualified build log path
.Parameter FileToAdd
Path to the file
#>
function Add-Artifact
{
param
(
[ValidateNotNull()]
[System.Collections.ArrayList] $artifacts,
[string] $FileToAdd
)
if (($FileToAdd -ne $null ) -and (Test-Path $FileToAdd -PathType Leaf))
{
$null = $artifacts.Add($FileToAdd)
}
else
{
Write-Host "Skip publishing package artifacts. $FileToAdd does not exist"
}
}
<#
.Synopsis
After build and test run completes, upload all artifacts from the build machine.
#>
function Publish-Artifact
{
Write-Host -ForegroundColor Yellow "Publishing project artifacts"
[System.Collections.ArrayList] $artifacts = [System.Collections.ArrayList]::new()
# Get the build.log file for each build configuration
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName)
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["UnitTestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["E2ETestResultsFile"]
Add-Artifact -artifacts $artifacts -FileToAdd $Global:OpenSSHTestInfo["TestSetupLogFile"]
foreach ($artifact in $artifacts)
{
Write-Host "Publishing $artifact as Appveyor artifact"
# NOTE: attempt to publish subsequent artifacts even if the current one fails
# TODO - Fix this
# Push-AppveyorArtifact $artifact -ErrorAction Continue
}
}
<#
.Synopsis
Runs the tests for this repo
#>
function Run-OpenSSHTests
{
Write-Host "Start running unit tests"
$unitTestFailed = Run-OpenSSHUnitTest
if($unitTestFailed)
{
Write-Host "At least one of the unit tests failed!" -ForegroundColor Yellow
Write-BuildMessage "At least one of the unit tests failed!" -Category Error
Set-BuildVariable TestPassed False
}
else
{
Write-Host "All Unit tests passed!"
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
}
# Run all pester tests.
<#Run-OpenSSHPesterTest
if (-not (Test-Path $global:PesterTestResultsFile))
{
Write-Warning "Test result file $global:PesterTestResultsFile not found after tests."
Write-BuildMessage -Message "Test result file $global:PesterTestResultsFile not found after tests." -Category Error
Set-BuildVariable TestPassed False
}
$xml = [xml](Get-Content -raw $global:PesterTestResultsFile)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at $($global:PesterTestResultsFile)."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
# Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success.
if ($Error.Count -gt 0)
{
Write-BuildMessage -Message "Tests Should clean $Error after success." -Category Warning
}#>
}
<#
.Synopsis
upload OpenSSH pester test results.
#>
function Upload-OpenSSHTestResults
{
if ($env:APPVEYOR_JOB_ID)
{
$resultFile = Resolve-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"] -ErrorAction Ignore
if( (Test-Path $Global:OpenSSHTestInfo["E2ETestResultsFile"]) -and $resultFile)
{
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resultFile)
Write-BuildMessage -Message "Test results uploaded!" -Category Information
}
}
if ($env:DebugMode)
{
Remove-Item $env:DebugMode
}
if($env:TestPassed -ieq 'True')
{
Write-BuildMessage -Message "The checkin validation success!" -Category Information
}
else
{
Write-BuildMessage -Message "The checkin validation failed!" -Category Error
throw "The checkin validation failed!"
}
}

View File

@ -1,5 +1,6 @@
 Set-StrictMode -Version Latest
Set-StrictMode -Version Latest
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -force -DisableNameChecking
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE [string] $script:platform = $env:PROCESSOR_ARCHITECTURE
[string] $script:vcPath = $null [string] $script:vcPath = $null
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null [System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
@ -132,7 +133,7 @@ function Write-BuildMsg
.Synopsis .Synopsis
Verifies all tools and dependencies required for building Open SSH are installed on the machine. Verifies all tools and dependencies required for building Open SSH are installed on the machine.
#> #>
function Start-SSHBootstrap function Start-OpenSSHBootstrap
{ {
[bool] $silent = -not $script:Verbose [bool] $silent = -not $script:Verbose
@ -140,7 +141,7 @@ function Start-SSHBootstrap
Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath $newMachineEnvironmentPath = $machinePath
# Install chocolatey # Install chocolatey
$chocolateyPath = "$env:AllUsersProfile\chocolatey\bin" $chocolateyPath = "$env:AllUsersProfile\chocolatey\bin"
@ -289,7 +290,7 @@ function Copy-OpenSSLSDK
} }
} }
function Start-SSHBuild function Build-OpenSSH
{ {
[CmdletBinding(SupportsShouldProcess=$false)] [CmdletBinding(SupportsShouldProcess=$false)]
param param
@ -309,7 +310,6 @@ function Start-SSHBuild
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName $script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
$script:gitRoot = split-path $script:OpenSSHRoot $script:gitRoot = split-path $script:OpenSSHRoot
if($PSBoundParameters.ContainsKey("Verbose")) if($PSBoundParameters.ContainsKey("Verbose"))
{ {
$script:Verbose = ($PSBoundParameters['Verbose']).IsPresent $script:Verbose = ($PSBoundParameters['Verbose']).IsPresent
@ -324,7 +324,7 @@ function Start-SSHBuild
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)" Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)"
Start-SSHBootstrap Start-OpenSSHBootstrap
Clone-Win32OpenSSH Clone-Win32OpenSSH
Copy-OpenSSLSDK Copy-OpenSSLSDK
@ -373,34 +373,176 @@ function Get-SolutionFile
} }
<# <#
.Synopsis .Synopsis
Finds the root of the git repository Deploy all required files to build a package and create zip file.
.Outputs
A System.IO.DirectoryInfo for the location of the root.
.Inputs
None
.Notes
FileNotFoundException is thrown if the current directory does not contain a CMakeLists.txt file.
#> #>
function Get-RepositoryRoot function Deploy-Win32OpenSSHBinaries
{ {
Set-StrictMode -Version Latest [CmdletBinding()]
$currentDir = (Get-Item -Path $PSCommandPath).Directory param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
while ($null -ne $currentDir.Parent) if (-not (Test-Path -Path $OpenSSHDir -PathType Container))
{ {
$path = Join-Path -Path $currentDir.FullName -ChildPath '.git' $null = New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop
if (Test-Path -Path $path)
{
return $currentDir
}
$currentDir = $currentDir.Parent
} }
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository") [string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -ieq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "contrib\win32\openssh"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.ps1,sshd_config -Exclude AnalyzeCodeDiff.ps1 -Force -ErrorAction Stop
$packageName = "rktools.2003"
$rktoolsPath = "${env:ProgramFiles(x86)}\Windows Resource Kits\Tools\ntrights.exe"
if (-not (Test-Path -Path $rktoolsPath))
{
Write-Log -Message "$packageName not present. Installing $packageName."
choco install $packageName -y --force 2>&1 >> $script:BuildLogFile
if (-not (Test-Path -Path $rktoolsPath))
{
choco install $packageName -y --force 2>&1 >> $script:BuildLogFile
if (-not (Test-Path -Path $rktoolsPath))
{
throw "failed to download $packageName"
}
}
}
Copy-Item -Path $rktoolsPath -Destination $OpenSSHDir -Force -ErrorAction Stop
} }
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile, Clone-Win32OpenSSH, Copy-OpenSSLSDK, Write-BuildMsg <#
.Synopsis
Deploy all required files to a location and install the binaries
#>
function Install-OpenSSH
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
Deploy-Win32OpenSSHBinaries @PSBoundParameters
Push-Location $OpenSSHDir
& ( "$OpenSSHDir\install-sshd.ps1")
.\ssh-keygen.exe -A
& ( "$OpenSSHDir\install-sshlsa.ps1")
#machine will be reboot after Install-openssh anyway
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if (-not ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())))
{
$newMachineEnvironmentPath = "$OpenSSHDir;$newMachineEnvironmentPath"
$env:Path = "$OpenSSHDir;$env:Path"
}
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
Start-Service sshd
Pop-Location
Write-Log -Message "OpenSSH installed!"
}
<#
.Synopsis
uninstalled sshd and sshla
#>
function UnInstall-OpenSSH
{
[CmdletBinding()]
param
(
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
Push-Location $OpenSSHDir
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
&( "$OpenSSHDir\uninstall-sshd.ps1")
&( "$OpenSSHDir\uninstall-sshlsa.ps1")
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}
# Update machine environment path
# machine will be reboot after Uninstall-OpenSSH
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Pop-Location
}
Export-ModuleMember -Function Build-OpenSSH, Get-BuildLogFile, Install-OpenSSH, UnInstall-OpenSSH

View File

@ -0,0 +1,31 @@
<#
.Synopsis
Finds the root of the git repository
.Outputs
A System.IO.DirectoryInfo for the location of the root.
.Inputs
None
.Notes
FileNotFoundException is thrown if the current directory does not contain a CMakeLists.txt file.
#>
function Get-RepositoryRoot
{
$currentDir = (Get-Item -Path $PSCommandPath).Directory
while ($null -ne $currentDir.Parent)
{
$path = Join-Path -Path $currentDir.FullName -ChildPath '.git'
if (Test-Path -Path $path)
{
return $currentDir
}
$currentDir = $currentDir.Parent
}
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository")
}
Export-ModuleMember -Function Get-RepositoryRoot

View File

@ -0,0 +1,456 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -DisableNameChecking
# state object used by all tests, initialized in Setup-OpenSSHTetEnvironment
$Global:OpenSSHTestInfo = @{}
<# Hash Table definitions
#test listener name
$Global:OpenSSHTestInfo["Target"]
# test listener port
$Global:OpenSSHTestInfo["Port"]
# test user with single sign on capability
$Global:OpenSSHTestInfo["SSOUser"]
# test user to be used with explicit key for key auth
$Global:OpenSSHTestInfo["PubKeyUser"]
# test user for passwd based auth
$Global:OpenSSHTestInfo["PasswdUser"]
# common password for all test accounts
$Global:OpenSSHTestInfo["TestAccountPW"]
# openssh bin path
$Global:OpenSSHTestInfo["OpenSSHDir"]
# openssh tests path
$Global:OpenSSHTestInfo["OpenSSHTestDir"]
# openssh test setup log file
$Global:OpenSSHTestInfo["TestSetupLogFile"]
# openssh E2E test results file
$Global:OpenSSHTestInfo["E2ETestResultsFile"]
# openssh unittest test results file
$Global:OpenSSHTestInfo["UnitTestResultsFile"]
#>
# test environment parameters initialized with defaults
$Script:OpenSSHDir = "$env:SystemDrive\OpenSSH"
$Script:OpenSSHTestDir = "$env:SystemDrive\OpenSSHTests"
$Script:E2ETestResultsFile = Join-Path $Script:OpenSSHTestDir "E2ETestResultsFile.xml"
$Script:UnitTestResultsFile = Join-Path $Script:OpenSSHTestDir "UnitTestResults.txt"
$Script:TestSetupLogFile = Join-Path $Script:OpenSSHTestDir "TestSetupLog.txt"
$Script:SSOUser = "sshtest_ssouser"
$Script:PubKeyUser = "sshtest_pubkeyuser"
$Script:PasswdUser = "sshtest_passwduser"
$Script:OpenSSHTestAccountsPassword = "P@ssw0rd_1"
$Script:OpenSSHTestAccounts = $Script:SSOUser, $Script:PubKeyUser, $Script:PasswdUser
function Set-OpenSSHTestParams
{
param
(
[string] $OpenSSHDir = $Script:OpenSSHDir,
[string] $OpenSSHTestDir = $Script:OpenSSHTestDir,
[string] $E2ETestResultsFile = $Script:E2ETestResultsFile,
[string] $UnitTestResultsFile = $Script:UnitTestResultsFile,
[string] $TestSetupLogFile = $Script:TestSetupLogFile
)
$Script:OpenSSHDir = $OpenSSHDir
$Script:OpenSSHTestDir = $OpenSSHTestDir
$Script:E2ETestResultsFile = $E2ETestResultsFile
$Script:UnitTestResultsFile = $UnitTestResultsFile
$Script:TestSetupLogFile = $TestSetupLogFile
}
function Dump-OpenSSHTestParams
{
$out = @"
OpenSSHDir: $Script:OpenSSHDir
OpenSSHTestDir: $Script:OpenSSHTestDir
E2ETestResultsFile: $Script:E2ETestResultsFile
UnitTestResultsFile: $Script:UnitTestResultsFile
TestSetupLogFile: $Script:TestSetupLogFile
"@
Write-Host $out
}
<#
.SYNOPSIS
This function installs the tools required by our tests
1) Pester for running the tests
2) sysinternals required by the tests on windows.
#>
function Install-OpenSSHTestDependencies
{
[CmdletBinding()]
param ()
# Install chocolatey
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
{
Write-Log -Message "Chocolatey not present. Installing chocolatey."
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $Script:TestSetupLogFile
}
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable))
{
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
Write-Log -Message "sysinternals not present. Installing sysinternals."
choco install sysinternals -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
}
<#
.Synopsis
Setup-OpenSSHTestEnvironment
TODO - split these steps into client and server side
#>
function Setup-OpenSSHTestEnvironment
{
[CmdletBinding()]
param
(
[switch] $Quiet
)
$warning = @"
WARNING: Following changes will be made to OpenSSH configuration
- sshd_config will be backed up as sshd_config.ori
- will be replaced with a test sshd_config
- $env:USERPROFILE\.ssh\known_hosts will be backed up as known_hosts.ori
- will be replaced with a test known_hosts
- sshd test listener will be on port 47002
- $env:USERPROFILE\.ssh\known_hosts will be modified with test host key entry
- test accounts - ssouser, pubkeyuser and passwduser will be added
- To cleanup - Run Cleanup-OpenSSHTestEnvironment
"@
if (-not $Quiet) {
Write-Warning $warning
}
if (-not (Test-Path (Join-Path $Script:OpenSSHDir ssh.exe) -PathType Leaf))
{
Throw "cannot find OpenSSH binaries under $Script:OpenSSHDir Try Set-OpenSSHTestParams"
}
$sshcmd = get-command ssh.exe -ErrorAction Ignore
if($sshcmd -eq $null) {
Throw 'Cannot find ssh.exe. Make sure OpenSSH binary path is in %PATH%'
}
#ensure ssh.exe is being picked from $Script:OpenSSHDir. Multiple versions may exist
if ( (Split-Path $sshcmd.Source) -ine "$Script:OpenSSHDir" ) {
Throw "ssh.exe is being picked from $($sshcmd.Source) instead of $Script:OpenSSHDir. "
}
if (-not (Test-Path $Script:OpenSSHTestDir -PathType Container )) {
Throw "$Script:OpenSSHTestDir does not exist. Run Deploy-OpenSSHTests to deploy tests."
}
if ((Get-ChildItem $Script:OpenSSHTestDir).Count -eq 0) {
Throw "Nothing found in $Script:OpenSSHTestDir. Run Deploy-OpenSSHTests to deploy tests"
}
#Backup existing OpenSSH configuration
$backupConfigPath = Join-Path $Script:OpenSSHDir sshd_config.ori
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
Copy-Item (Join-Path $Script:OpenSSHDir sshd_config) $backupConfigPath -Force
}
# copy new sshd_config
Copy-Item (Join-Path $Script:OpenSSHTestDir sshd_config) (Join-Path $Script:OpenSSHDir sshd_config) -Force
Copy-Item $Script:OpenSSHTestDir\sshtest*hostkey* $Script:OpenSSHDir -Force
Restart-Service sshd -Force
#Backup existing known_hosts and replace with test version
#TODO - account for custom known_hosts locations
$knowHostsDirectoryPath = Join-Path $home .ssh
$knowHostsFilePath = Join-Path $knowHostsDirectoryPath known_hosts
if(-not (Test-Path $knowHostsDirectoryPath -PathType Container))
{
New-Item -ItemType Directory -Path $knowHostsDirectoryPath -Force -ErrorAction SilentlyContinue | out-null
}
if (Test-Path $knowHostsFilePath -PathType Leaf) {
Copy-Item $knowHostsFilePath (Join-Path $knowHostsDirectoryPath known_hosts.ori) -Force
}
Copy-Item (Join-Path $Script:OpenSSHTestDir known_hosts) $knowHostsFilePath -Force
# create test accounts
#TODO - this is Windows specific. Need to be in PAL
foreach ($user in $Script:OpenSSHTestAccounts)
{
net user $user $Script:OpenSSHTestAccountsPassword /ADD 2>&1 >> $Script:TestSetupLogFile
}
#setup single sign on for ssouser
#TODO - this is Windows specific. Need to be in PAL
$ssousersid = Get-UserSID -User sshtest_ssouser
$ssouserProfileRegistry = Join-Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $ssousersid
if (-not (Test-Path $ssouserProfileRegistry) ) {
#create profile
if (-not($env:DISPLAY)) { $env:DISPLAY = 1 }
$env:SSH_ASKPASS="$($env:ComSpec) /c echo $($Script:OpenSSHTestAccountsPassword)"
cmd /c "ssh -p 47002 sshtest_ssouser@localhost echo %userprofile% > profile.txt"
if ($env:DISPLAY -eq 1) { Remove-Item env:\DISPLAY }
remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
}
$ssouserProfile = (Get-ItemProperty -Path $ssouserProfileRegistry -Name 'ProfileImagePath').ProfileImagePath
New-Item -ItemType Directory -Path (Join-Path $ssouserProfile .ssh) -Force -ErrorAction SilentlyContinue | out-null
$authorizedKeyPath = Join-Path $ssouserProfile .ssh\authorized_keys
$testPubKeyPath = Join-Path $Script:OpenSSHTestDir sshtest_userssokey_ed25519.pub
(Get-Content $testPubKeyPath -Raw).Replace("`r`n","`n") | Set-Content $testPubKeyPath -Force
Copy-Item $testPubKeyPath $authorizedKeyPath -Force -ErrorAction SilentlyContinue
$acl = get-acl $authorizedKeyPath
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule("NT Service\sshd", "Read", "Allow")
$acl.SetAccessRule($ar)
Set-Acl $authorizedKeyPath $acl
$testPriKeypath = Join-Path $Script:OpenSSHTestDir sshtest_userssokey_ed25519
(Get-Content $testPriKeypath -Raw).Replace("`r`n","`n") | Set-Content $testPriKeypath -Force
cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile"
$Global:OpenSSHTestInfo = @{}
# test listener name
$Global:OpenSSHTestInfo.Add("Target","localhost")
# test listener port
$Global:OpenSSHTestInfo.Add("Port", "47002")
# test user with single sign on capability
$Global:OpenSSHTestInfo.Add("SSOUser", $Script:SSOUser)
# test user to be used with explicit key for key auth
$Global:OpenSSHTestInfo.Add("PubKeyUser", $Script:PubKeyUser)
# test user for passwd based auth
$Global:OpenSSHTestInfo.Add("PasswdUser", $Script:PasswdUser)
# common password for all test accounts
$Global:OpenSSHTestInfo.Add("TestAccountPW", $Script:OpenSSHTestAccountsPassword)
# openssh bin path
$Global:OpenSSHTestInfo.Add("OpenSSHDir", $Script:OpenSSHDir)
# openssh tests path
$Global:OpenSSHTestInfo.Add("OpenSSHTestDir", $Script:OpenSSHTestDir)
# openssh test setup log file
$Global:OpenSSHTestInfo.Add("TestSetupLogFile", $Script:TestSetupLogFile)
# openssh E2E test results file
$Global:OpenSSHTestInfo.Add("E2ETestResultsFile", $Script:E2ETestResultsFile)
# openssh unittest test results file
$Global:OpenSSHTestInfo.Add("UnitTestResultsFile", $Script:UnitTestResultsFile)
}
<#
.Synopsis
Get-UserSID
#>
function Get-UserSID
{
param
(
[string]$Domain,
[string]$User
)
if([string]::IsNullOrEmpty($Domain))
{
$objUser = New-Object System.Security.Principal.NTAccount($User)
}
else
{
$objUser = New-Object System.Security.Principal.NTAccount($Domain, $User)
}
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value
}
<#
.Synopsis
Cleanup-OpenSSHTestEnvironment
#>
function Cleanup-OpenSSHTestEnvironment
{
# .exe - Windows specific. TODO - PAL
if (-not (Test-Path (Join-Path $Script:OpenSSHDir ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $($Script:OpenSSHDir). Try -OpenSSHDir parameter"
}
#Restore sshd_config
$backupConfigPath = Join-Path $Script:OpenSSHDir sshd_config.ori
if (Test-Path $backupConfigPath -PathType Leaf) {
Copy-Item $backupConfigPath (Join-Path $Script:OpenSSHDir sshd_config) -Force -ErrorAction SilentlyContinue
Remove-Item (Join-Path $Script:OpenSSHDir sshd_config.ori) -Force -ErrorAction SilentlyContinue
Remove-Item $Script:OpenSSHDir\sshtest*hostkey* -Force -ErrorAction SilentlyContinue
Restart-Service sshd
}
#Restore known_hosts
$originKnowHostsPath = Join-Path $home .ssh\known_hosts.ori
if (Test-Path $originKnowHostsPath)
{
Copy-Item $originKnowHostsPath (Join-Path $home .ssh\known_hosts) -Force -ErrorAction SilentlyContinue
Remove-Item $originKnowHostsPath -Force -ErrorAction SilentlyContinue
}
#Delete accounts
foreach ($user in $Script:OpenSSHTestAccounts)
{
net user $user /delete
}
# remove registered keys
cmd /c "ssh-add -d (Join-Path $Script:OpenSSHTestDir sshtest_userssokey_ed25519) 2>&1 >> $Script:TestSetupLogFile"
$Global:OpenSSHTestInfo = $null
}
<#
.Synopsis
After build and test run completes, upload all artifacts from the build machine.
#>
function Deploy-OpenSSHTests
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
if (-not (Test-Path -Path $Script:OpenSSHTestDir -PathType Container))
{
$null = New-Item -Path $Script:OpenSSHTestDir -ItemType Directory -Force -ErrorAction Stop
}
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -eq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
#copy all pester tests
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
Copy-Item -Path "$sourceDir\*" -Destination $Script:OpenSSHTestDir -Include *.ps1,*.psm1, sshd_config, known_hosts, sshtest_* -Force -ErrorAction Stop
#copy all unit tests.
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination "$($Script:OpenSSHTestDir)\" -Container -Include unittest-* -Recurse -Force -ErrorAction Stop
}
<#
.Synopsis
Run OpenSSH pester tests.
#>
function Run-OpenSSHPesterTest
{
# Discover all CI tests and run them.
Push-Location $Script:OpenSSHTestDir
Write-Log -Message "Running OpenSSH Pester tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse -Exclude SSHDConfig.tests.ps1, SSH.Tests.ps1 | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag 'CI'
Pop-Location
}
<#
.Synopsis
Run openssh unit tests.
#>
function Run-OpenSSHUnitTest
{
# Discover all CI tests and run them.
Push-Location $Script:OpenSSHTestDir
Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $Script:UnitTestResultsFile)
{
$null = Remove-Item -Path $Script:UnitTestResultsFile -Force -ErrorAction SilentlyContinue
}
$testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
ForEach-Object{ Split-Path $_.FullName} |
Sort-Object -Unique
$testfailed = $false
if ($testFolders -ne $null)
{
$testFolders | % {
Push-Location $_
$unittestFile = "$(Split-Path $_ -Leaf).exe"
Write-log "Running OpenSSH unit $unittestFile ..."
& .\$unittestFile >> $Script:UnitTestResultsFile
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
$testfailed = $true
$errorMessage = "$($_.FullName) test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at $($Script:UnitTestResultsFile)."
Write-Warning $errorMessage
}
Pop-Location
}
}
Pop-Location
$testfailed
}
<#
Write-Log
#>
function Write-Log
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message
)
if(-not (Test-Path (Split-Path $Script:TestSetupLogFile) -PathType Container))
{
$null = New-Item -ItemType Directory -Path (Split-Path $Script:TestSetupLogFile) -Force -ErrorAction SilentlyContinue | out-null
}
if (-not ([string]::IsNullOrEmpty($Script:TestSetupLogFile)))
{
Add-Content -Path $Script:TestSetupLogFile -Value $Message
}
}
Export-ModuleMember -Function Set-OpenSSHTestParams, Dump-OpenSSHTestParams, Install-OpenSSHTestDependencies, Setup-OpenSSHTestEnvironment, Cleanup-OpenSSHTestEnvironment, Deploy-OpenSSHTests, Run-OpenSSHUnitTest, Run-OpenSSHPesterTest

View File

@ -126,14 +126,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-win32compat", "uni
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0} {0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-utf8", "unittest-utf8.vcxproj", "{114CAA59-46C0-4B87-BA86-C1946A68101D}"
ProjectSection(ProjectDependencies) = postProject
{05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7}
{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}
{DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174}
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-hostkeys", "unittest-hostkeys.vcxproj", "{890C6129-286F-4CD8-8252-FB8D3B4E6E1B}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-hostkeys", "unittest-hostkeys.vcxproj", "{890C6129-286F-4CD8-8252-FB8D3B4E6E1B}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7} {05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7}
@ -314,14 +306,6 @@ Global
{BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x64.Build.0 = Release|x64 {BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x64.Build.0 = Release|x64
{BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x86.ActiveCfg = Release|Win32 {BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x86.ActiveCfg = Release|Win32
{BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x86.Build.0 = Release|Win32 {BF295BA9-4BF8-43F8-8CBF-FAE84815466C}.Release|x86.Build.0 = Release|Win32
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Debug|x64.ActiveCfg = Debug|x64
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Debug|x64.Build.0 = Debug|x64
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Debug|x86.ActiveCfg = Debug|Win32
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Debug|x86.Build.0 = Debug|Win32
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Release|x64.ActiveCfg = Release|x64
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Release|x64.Build.0 = Release|x64
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Release|x86.ActiveCfg = Release|Win32
{114CAA59-46C0-4B87-BA86-C1946A68101D}.Release|x86.Build.0 = Release|Win32
{890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x64.ActiveCfg = Debug|x64 {890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x64.ActiveCfg = Debug|x64
{890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x64.Build.0 = Debug|x64 {890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x64.Build.0 = Debug|x64
{890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x86.ActiveCfg = Debug|Win32 {890C6129-286F-4CD8-8252-FB8D3B4E6E1B}.Debug|x86.ActiveCfg = Debug|Win32
@ -369,7 +353,6 @@ Global
{8EC56B06-5A9A-4D6D-804D-037FE26FD43E} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {8EC56B06-5A9A-4D6D-804D-037FE26FD43E} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{CD9740CE-C96E-49B3-823F-012E09D17806} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {CD9740CE-C96E-49B3-823F-012E09D17806} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{BF295BA9-4BF8-43F8-8CBF-FAE84815466C} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {BF295BA9-4BF8-43F8-8CBF-FAE84815466C} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{114CAA59-46C0-4B87-BA86-C1946A68101D} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{890C6129-286F-4CD8-8252-FB8D3B4E6E1B} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {890C6129-286F-4CD8-8252-FB8D3B4E6E1B} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{FC568FF0-60F2-4B2E-AF62-FD392EDBA1B9} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {FC568FF0-60F2-4B2E-AF62-FD392EDBA1B9} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{484A8CDE-B949-4BDA-B447-74685C8E032F} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4} {484A8CDE-B949-4BDA-B447-74685C8E032F} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}

View File

@ -1,764 +0,0 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\build.psm1 -Force -DisableNameChecking
$repoRoot = Get-RepositoryRoot
$script:logFile = join-path $repoRoot.FullName "appveyor.log"
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
<#
Called by Write-BuildMsg to write to the build log, if it exists.
#>
function Write-Log
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message
)
# write it to the log file, if present.
if (-not ([string]::IsNullOrEmpty($script:logFile)))
{
Add-Content -Path $script:logFile -Value $Message
}
}
# Sets a build variable
Function Write-BuildMessage
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message,
$Category,
[string] $Details)
if($env:AppVeyor)
{
Add-AppveyorMessage @PSBoundParameters
}
# write it to the log file, if present.
if (-not ([string]::IsNullOrEmpty($script:messageFile)))
{
Add-Content -Path $script:messageFile -Value "$Category--$Message"
}
}
# Sets a build variable
Function Set-BuildVariable
{
param(
[Parameter(Mandatory=$true)]
[string]
$Name,
[Parameter(Mandatory=$true)]
[string]
$Value
)
if($env:AppVeyor -and (Get-Command Set-AppveyorBuildVariable -ErrorAction Ignore) -ne $null)
{
Set-AppveyorBuildVariable @PSBoundParameters
}
elseif($env:AppVeyor)
{
appveyor SetVariable -Name $Name -Value $Value
}
else
{
Set-Item env:$Name -Value $Value
}
}
# Emulates running all of AppVeyor but locally
# should not be used on AppVeyor
function Invoke-AppVeyorFull
{
param(
[switch] $APPVEYOR_SCHEDULED_BUILD,
[switch] $CleanRepo
)
if($CleanRepo)
{
Clear-PSRepo
}
if($env:APPVEYOR)
{
throw "This function is to simulate appveyor, but not to be run from appveyor!"
}
if($APPVEYOR_SCHEDULED_BUILD)
{
$env:APPVEYOR_SCHEDULED_BUILD = 'True'
}
try {
Invoke-AppVeyorBuild
Install-OpenSSH
Install-TestDependencies
Run-OpenSSHTests
Publish-Artifact
}
finally {
if($APPVEYOR_SCHEDULED_BUILD -and $env:APPVEYOR_SCHEDULED_BUILD)
{
Remove-Item env:APPVEYOR_SCHEDULED_BUILD
}
}
}
# Implements the AppVeyor 'build_script' step
function Invoke-AppVeyorBuild
{
Set-BuildVariable TestPassed True
Start-SSHBuild -Configuration Release -NativeHostArch x64
Start-SSHBuild -Configuration Debug -NativeHostArch x86
Write-BuildMessage -Message "OpenSSH binaries build success!" -Category Information
}
<#
.Synopsis
This function invokes msiexec.exe to install PSCore on the AppVeyor build machine
#>
function Invoke-MSIEXEC
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $InstallFile
)
Write-Log -Message "Installing $InstallFile..."
$arguments = @(
"/i"
"`"$InstallFile`""
"/qn"
"/norestart"
)
$process = Start-Process -FilePath msiexec.exe -ArgumentList $arguments -Wait -PassThru
if ($process.ExitCode -eq 0){
Write-Log -Message "$InstallFile has been successfully installed."
}
else {
Write-Log -Message "installer exit code $($process.ExitCode) for file $($InstallFile)"
}
return $process.ExitCode
}
<#
.Synopsis
This function installs PSCore MSI on the AppVeyor build machine
#>
function Install-PSCoreFromGithub
{
$downloadLocation = Download-PSCoreMSI
Write-Log -Message "Installing PSCore ..."
if(-not [string]::IsNullOrEmpty($downloadLocation))
{
$processExitCode = Invoke-MSIEXEC -InstallFile $downloadLocation
Write-Log -Message "Process exitcode: $processExitCode"
}
}
<#
.Synopsis
Retuns MSI location for PSCore for Win10, Windows 8.1 and 2012 R2
#>
function Get-PSCoreMSIDownloadURL
{
$osversion = [String][Environment]::OSVersion.Version
if($osversion.StartsWith("6"))
{
if ($($env:PROCESSOR_ARCHITECTURE).Contains('64'))
{
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win81-x64.msi'
}
else
{
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win7-x86.msi'
}
}
elseif ($osversion.Contains("10.0"))
{
if ($($env:PROCESSOR_ARCHITECTURE).Contains('64'))
{
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win10-x64.msi'
}
else
{
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win7-x86.msi'
}
}
}
<#
.Synopsis
This functions downloads MSI and returns the path where the file is downloaded.
#>
function Download-PSCoreMSI
{
$url = Get-PSCoreMSIDownloadURL
if([string]::IsNullOrEmpty($url))
{
Write-Log -Message "url is empty"
return ''
}
$parsed = $url.Substring($url.LastIndexOf("/") + 1)
if(-not (Test-path "$env:SystemDrive\PScore" -PathType Container))
{
$null = New-Item -ItemType Directory -Force -Path "$env:SystemDrive\PScore" | out-null
}
$downloadLocation = "$env:SystemDrive\PScore\$parsed"
if(-not (Test-path $downloadLocation -PathType Leaf))
{
Invoke-WebRequest -Uri $url -OutFile $downloadLocation -ErrorVariable v
}
if ($v)
{
Write-BuildMessage -Message "Failed to download PSCore MSI package from $url" -Category Error
throw "Failed to download PSCore MSI package from $url"
}
else
{
return $downloadLocation
}
}
<#
.SYNOPSIS
This function installs the tools required by our tests
1) Pester for running the tests
2) sysinternals required by the tests on windows.
#>
function Install-TestDependencies
{
[CmdletBinding()]
param ()
# Install chocolatey
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
{
Write-Log -Message "Chocolatey not present. Installing chocolatey."
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:logFile
}
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable))
{
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $script:logFile
}
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
Write-Log -Message "sysinternals not present. Installing sysinternals."
choco install sysinternals -y --force --limitoutput 2>&1 >> $script:logFile
}
<#if ( (-not (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\8.1\Debuggers\" )) -and (-not (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\10\Debuggers\" ))) {
Write-Log -Message "debugger not present. Installing windbg."
choco install windbg --force --limitoutput -y 2>&1 >> $script:logFile
}#>
Install-PSCoreFromGithub
$psCorePath = GetLocalPSCorePath
Set-BuildVariable -Name psPath -Value $psCorePath
Write-BuildMessage -Message "All testDependencies installed!" -Category Information
}
<#
.Synopsis
Get the path to the installed powershell score
#>
function GetLocalPSCorePath {
$psPath = Get-ChildItem "$env:ProgramFiles\PowerShell\*\powershell.exe" -Recurse -ErrorAction SilentlyContinue
if($psPath.Count -eq 0)
{
""
}
else
{
$psPath[-1].FullName
}
}
<#
.Synopsis
Deploy all required files to a location and install the binaries
#>
function Install-OpenSSH
{
[CmdletBinding()]
param
(
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
Build-Win32OpenSSHPackage @PSBoundParameters
Push-Location $OpenSSHDir
& ( "$OpenSSHDir\install-sshd.ps1")
.\ssh-keygen.exe -A
Start-Service ssh-agent
&( "$OpenSSHDir\install-sshlsa.ps1")
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
Start-Service sshd
Pop-Location
Write-BuildMessage -Message "OpenSSH installed!" -Category Information
}
<#
.Synopsis
uninstalled sshd and sshla
#>
function UnInstall-OpenSSH
{
[CmdletBinding()]
param
(
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
Push-Location $OpenSSHDir
Stop-Service sshd
&( "$OpenSSHDir\uninstall-sshd.ps1")
&( "$OpenSSHDir\uninstall-sshlsa.ps1")
Pop-Location
}
<#
.Synopsis
Deploy all required files to build a package and create zip file.
#>
function Build-Win32OpenSSHPackage
{
[CmdletBinding()]
param
(
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
if (-not (Test-Path -Path $OpenSSHDir -PathType Container))
{
$null = New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop
}
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -ieq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "contrib\win32\openssh"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.ps1,sshd_config -Exclude AnalyzeCodeDiff.ps1 -Force -ErrorAction Stop
$packageName = "rktools.2003"
$rktoolsPath = "${env:ProgramFiles(x86)}\Windows Resource Kits\Tools\ntrights.exe"
if (-not (Test-Path -Path $rktoolsPath))
{
Write-Log -Message "$packageName not present. Installing $packageName."
choco install $packageName -y --force 2>&1 >> $script:logFile
if (-not (Test-Path -Path $rktoolsPath))
{
choco install $packageName -y --force 2>&1 >> $script:logFile
if (-not (Test-Path -Path $rktoolsPath))
{
Write-BuildMessage "Installation dependencies: failed to download $packageName. try again please." -Category Error
throw "failed to download $packageName"
}
}
}
Copy-Item -Path $rktoolsPath -Destination $OpenSSHDir -Force -ErrorAction Stop
$packageFolder = $env:SystemDrive
if ($env:APPVEYOR_BUILD_FOLDER)
{
$packageFolder = $env:APPVEYOR_BUILD_FOLDER
}
$package = "$packageFolder\Win32OpenSSH$RealConfiguration$folderName.zip"
$allPackage = "$packageFolder\Win32OpenSSH*.zip"
if (Test-Path $allPackage)
{
Remove-Item -Path $allPackage -Force -ErrorAction SilentlyContinue
}
Add-Type -assemblyname System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory($OpenSSHDir, $package)
}
<#
.Synopsis
After build and test run completes, upload all artifacts from the build machine.
#>
function Deploy-OpenSSHTests
{
[CmdletBinding()]
param
(
[string] $OpenSSHTestDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
if (-not (Test-Path -Path $OpenSSHTestDir -PathType Container))
{
$null = New-Item -Path $OpenSSHTestDir -ItemType Directory -Force -ErrorAction Stop
}
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -eq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
#copy all pester tests
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1, sshd_config -Force -ErrorAction Stop
#copy all unit tests.
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination "$OpenSSHTestDir\" -Container -Include unittest-* -Recurse -Force -ErrorAction Stop
#restart the service to use the test copy of sshd_config
Restart-Service sshd
}
<#
.Synopsis
Adds a build log to the list of published artifacts.
.Description
If a build log exists, it is renamed to reflect the associated CLR runtime then added to the list of
artifacts to publish. If it doesn't exist, a warning is written and the file is skipped.
The rename is needed since publishing overwrites the artifact if it already exists.
.Parameter artifacts
An array list to add the fully qualified build log path
.Parameter buildLog
The build log file produced by the build.
#>
function Add-BuildLog
{
param
(
[ValidateNotNull()]
[System.Collections.ArrayList] $artifacts,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $buildLog
)
if (Test-Path -Path $buildLog)
{
$null = $artifacts.Add($buildLog)
}
else
{
Write-Warning "Skip publishing build log. $buildLog does not exist"
}
}
<#
.Synopsis
Publishes package build artifacts.
.Parameter artifacts
An array list to add the fully qualified build log path
.Parameter packageFile
Path to the package
#>
function Add-Artifact
{
param
(
[ValidateNotNull()]
[System.Collections.ArrayList] $artifacts,
[string] $FileToAdd
)
$files = Get-ChildItem -Path $FileToAdd -ErrorAction Ignore
if ($files -ne $null)
{
$files | % {
$null = $artifacts.Add($_.FullName)
}
}
else
{
Write-Log -Message "Skip publishing package artifacts. $FileToAdd does not exist"
}
}
<#
.Synopsis
After build and test run completes, upload all artifacts from the build machine.
#>
function Publish-Artifact
{
Write-Host -ForegroundColor Yellow "Publishing project artifacts"
[System.Collections.ArrayList] $artifacts = [System.Collections.ArrayList]::new()
$packageFolder = $env:SystemDrive
if ($env:APPVEYOR_BUILD_FOLDER)
{
$packageFolder = $env:APPVEYOR_BUILD_FOLDER
}
Add-Artifact -artifacts $artifacts -FileToAdd "$packageFolder\Win32OpenSSH*.zip"
Add-Artifact -artifacts $artifacts -FileToAdd "$env:SystemDrive\OpenSSH\UnitTestResults.txt"
Add-Artifact -artifacts $artifacts -FileToAdd "$env:SystemDrive\OpenSSH\TestError.txt"
# Get the build.log file for each build configuration
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName)
Add-Artifact -artifacts $artifacts -FileToAdd "$script:logFile"
Add-Artifact -artifacts $artifacts -FileToAdd "$script:messageFile"
foreach ($artifact in $artifacts)
{
Write-Log -Message "Publishing $artifact as Appveyor artifact"
# NOTE: attempt to publish subsequent artifacts even if the current one fails
Push-AppveyorArtifact $artifact -ErrorAction "Continue"
}
}
<#
.Synopsis
Run OpenSSH pester tests.
#>
function Run-OpenSSHPesterTest
{
param($testRoot = "$env:SystemDrive\OpenSSH",
$outputXml = "$env:SystemDrive\OpenSSH\TestResults.xml")
# Discover all CI tests and run them.
Push-Location $testRoot
Write-Log -Message "Running OpenSSH Pester tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $outputXml -Tag 'CI'
Pop-Location
}
function Check-PesterTestResult
{
param($outputXml = "$env:SystemDrive\OpenSSH\TestResults.xml")
if (-not (Test-Path $outputXml))
{
Write-Warning "$($xml.'test-results'.failures) tests in regress\pesterTests failed"
Write-BuildMessage -Message "Test result file $outputXml not found after tests." -Category Error
Set-BuildVariable TestPassed False
}
$xml = [xml](Get-Content -raw $outputXml)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at TestResults.xml."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
# Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success.
if ($Error.Count -gt 0)
{
Write-BuildMessage -Message "Tests Should clean $Error after success." -Category Warning
$Error| Out-File "$testInstallFolder\TestError.txt" -Append
}
}
<#
.Synopsis
Run unit tests.
#>
function Run-OpenSSHUnitTest
{
param($testRoot = "$env:SystemDrive\OpenSSH",
$unitTestOutputFile = "$env:SystemDrive\OpenSSH\UnitTestResults.txt")
# Discover all CI tests and run them.
Push-Location $testRoot
Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $unitTestOutputFile)
{
Remove-Item -Path $unitTestOutputFile -Force -ErrorAction SilentlyContinue
}
$testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
ForEach-Object{ Split-Path $_.FullName} |
Sort-Object -Unique
$testfailed = $false
if ($testFolders -ne $null)
{
$testFolders | % {
Push-Location $_
$unittestFile = "$(Split-Path $_ -Leaf).exe"
Write-Output "Running OpenSSH unit $unittestFile ..."
& .\$unittestFile >> $unitTestOutputFile
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
$testfailed = $true
$errorMessage = "$($_.FullName) test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at UnitTestResults.txt."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
Pop-Location
}
if(-not $testfailed)
{
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
}
}
Pop-Location
}
<#
.Synopsis
Runs the tests for this repo
.Parameter testResultsFile
The name of the xml file to write pester results.
The default value is '.\testResults.xml'
.Example
.\RunTests.ps1
Runs the tests and creates the default 'testResults.xml'
#>
function Run-OpenSSHTests
{
[CmdletBinding()]
param
(
[string] $testResultsFile = "$env:SystemDrive\OpenSSH\TestResults.xml",
[string] $unitTestResultsFile = "$env:SystemDrive\OpenSSH\UnitTestResults.txt",
[string] $testInstallFolder = "$env:SystemDrive\OpenSSH"
)
Deploy-OpenSSHTests -OpenSSHTestDir $testInstallFolder
Run-OpenSSHUnitTest -testRoot $testInstallFolder -unitTestOutputFile $unitTestResultsFile
# Run all pester tests.
Run-OpenSSHPesterTest -testRoot $testInstallFolder -outputXml $testResultsFile
}
function Upload-OpenSSHTestResults
{
[CmdletBinding()]
param
(
[string] $testResultsFile = "$env:SystemDrive\OpenSSH\TestResults.xml"
)
if ($env:APPVEYOR_JOB_ID)
{
$resultFile = Resolve-Path $testResultsFile -ErrorAction Ignore
if($resultFile)
{
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", $resultFile)
Write-BuildMessage -Message "Test results uploaded!" -Category Information
}
}
if ($env:DebugMode)
{
Remove-Item $env:DebugMode
}
if($env:TestPassed -ieq 'True')
{
Write-BuildMessage -Message "The checkin validation success!" -Category Information
}
else
{
Write-BuildMessage -Message "The checkin validation failed!" -Category Error
throw "The checkin validation failed!"
}
}
Export-ModuleMember -Function Set-BuildVariable, Invoke-AppVeyorBuild, Install-OpenSSH, Install-TestDependencies, GetLocalPSCorePath, Upload-OpenSSHTestResults, Run-OpenSSHTests, Publish-Artifact, Start-SSHBuild, Deploy-OpenSSHTests, Run-OpenSSHUnitTest,Run-OpenSSHPesterTest,Check-PesterTestResult

View File

@ -290,7 +290,6 @@
<ClInclude Include="$(OpenSSH-Src-Path)uuencode.h" /> <ClInclude Include="$(OpenSSH-Src-Path)uuencode.h" />
<ClInclude Include="$(OpenSSH-Src-Path)version.h" /> <ClInclude Include="$(OpenSSH-Src-Path)version.h" />
<ClInclude Include="$(OpenSSH-Src-Path)xmalloc.h" /> <ClInclude Include="$(OpenSSH-Src-Path)xmalloc.h" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)clientloop.c" /> <ClCompile Include="$(OpenSSH-Src-Path)clientloop.c" />
@ -299,7 +298,8 @@
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshtty.c" /> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="version.rc" /> <ResourceCompile Include="version.rc" />

View File

@ -305,10 +305,10 @@
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c"> <ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshtty.c"> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c"> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>

View File

@ -222,6 +222,7 @@
<ClCompile Include="$(OpenSSH-Src-Path)auth2-passwd.c" /> <ClCompile Include="$(OpenSSH-Src-Path)auth2-passwd.c" />
<ClCompile Include="$(OpenSSH-Src-Path)auth2-pubkey.c" /> <ClCompile Include="$(OpenSSH-Src-Path)auth2-pubkey.c" />
<ClCompile Include="$(OpenSSH-Src-Path)auth2.c" /> <ClCompile Include="$(OpenSSH-Src-Path)auth2.c" />
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c" />
<ClCompile Include="$(OpenSSH-Src-Path)gss-serv-krb5.c" /> <ClCompile Include="$(OpenSSH-Src-Path)gss-serv-krb5.c" />
<ClCompile Include="$(OpenSSH-Src-Path)gss-serv.c" /> <ClCompile Include="$(OpenSSH-Src-Path)gss-serv.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexdhs.c" /> <ClCompile Include="$(OpenSSH-Src-Path)kexdhs.c" />
@ -244,9 +245,8 @@
<ClCompile Include="$(OpenSSH-Src-Path)sftp-common.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sftp-common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshd.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sshd.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c" /> <ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshpty.c" /> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshpty.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c" /> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c" />
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="version.rc" /> <ResourceCompile Include="version.rc" />

View File

@ -144,15 +144,15 @@
<ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c"> <ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshpty.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c"> <ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c"> <ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshpty.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="version.rc"> <ResourceCompile Include="version.rc">

View File

@ -204,8 +204,9 @@
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\sys\types.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\sys\types.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\ctype.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\ctype.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\stdlib.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\stdlib.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\debug.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.h" />
<ClInclude Include="..\win32compat\tnnet.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -139,8 +139,9 @@
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\ctype.h"> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\ctype.h">
<Filter>inc</Filter> <Filter>inc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\debug.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\console.h" />
<ClInclude Include="..\win32compat\tnnet.h" /> <ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\tnnet.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="inc"> <Filter Include="inc">

View File

@ -1,39 +1,10 @@
/* #pragma once
* Author: NoMachine <developers@nomachine.com>
*
* Copyright (c) 2009, 2011 NoMachine
* All rights reserved
*
* Support functions and system calls' replacements needed to let the
* software run on Win32 based operating systems.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef Debug_H /* Enable the following for verbose logging */
#define Debug_H #if (0)
#define debug4 debug2
#define FAIL(CONDITION) if (CONDITION) goto fail #define debug5 debug3
#else
#define NTFAIL(NTFUNC) if((ntStat = (NTFUNC))) goto fail #define debug4(a,...)
#define debug5(a,...)
#endif #endif

View File

@ -39,6 +39,7 @@
#include "inc\utf.h" #include "inc\utf.h"
#include "inc\fcntl.h" #include "inc\fcntl.h"
#include "misc_internal.h" #include "misc_internal.h"
#include "debug.h"
/* internal read buffer size */ /* internal read buffer size */
#define READ_BUFFER_SIZE 100*1024 #define READ_BUFFER_SIZE 100*1024
@ -97,7 +98,7 @@ fileio_connect(struct w32_io* pio, char* name)
int ret = 0; int ret = 0;
if (pio->handle != 0 && pio->handle != INVALID_HANDLE_VALUE) { if (pio->handle != 0 && pio->handle != INVALID_HANDLE_VALUE) {
debug("fileio_connect called in unexpected state, pio = %p", pio); debug3("fileio_connect called in unexpected state, pio = %p", pio);
errno = EOTHER; errno = EOTHER;
ret = -1; ret = -1;
goto cleanup; goto cleanup;
@ -114,13 +115,13 @@ fileio_connect(struct w32_io* pio, char* name)
/* TODO - support nonblocking connect */ /* TODO - support nonblocking connect */
/* wait until we have a server pipe instance to connect */ /* wait until we have a server pipe instance to connect */
while (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) { while (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) {
debug2("waiting for agent connection, retrying after 1 sec"); debug4("waiting for agent connection, retrying after 1 sec");
if ((ret = wait_for_any_event(NULL, 0, 1000) != 0) != 0) if ((ret = wait_for_any_event(NULL, 0, 1000) != 0) != 0)
goto cleanup; goto cleanup;
} }
if (h == INVALID_HANDLE_VALUE) { if (h == INVALID_HANDLE_VALUE) {
debug("unable to connect to pipe %ls, error: %d", name_w, GetLastError()); debug3("unable to connect to pipe %ls, error: %d", name_w, GetLastError());
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
ret = -1; ret = -1;
goto cleanup; goto cleanup;
@ -129,7 +130,7 @@ fileio_connect(struct w32_io* pio, char* name)
if (SetHandleInformation(h, HANDLE_FLAG_INHERIT, if (SetHandleInformation(h, HANDLE_FLAG_INHERIT,
pio->fd_flags & FD_CLOEXEC ? 0 : HANDLE_FLAG_INHERIT) == FALSE) { pio->fd_flags & FD_CLOEXEC ? 0 : HANDLE_FLAG_INHERIT) == FALSE) {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("SetHandleInformation failed, error = %d, pio = %p", GetLastError(), pio); debug3("SetHandleInformation failed, error = %d, pio = %p", GetLastError(), pio);
ret = -1; ret = -1;
goto cleanup; goto cleanup;
} }
@ -162,7 +163,7 @@ fileio_pipe(struct w32_io* pio[2])
if (pio == NULL) { if (pio == NULL) {
errno = EINVAL; errno = EINVAL;
debug("pipe - ERROR invalid parameter"); debug3("pipe - ERROR invalid parameter");
return -1; return -1;
} }
@ -170,7 +171,7 @@ fileio_pipe(struct w32_io* pio[2])
if (-1 == sprintf_s(pipe_name, PATH_MAX, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x", if (-1 == sprintf_s(pipe_name, PATH_MAX, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x",
GetCurrentProcessId(), pipe_counter++)) { GetCurrentProcessId(), pipe_counter++)) {
errno = EOTHER; errno = EOTHER;
debug("pipe - ERROR sprintf_s %d", errno); debug3("pipe - ERROR sprintf_s %d", errno);
goto error; goto error;
} }
@ -189,7 +190,7 @@ fileio_pipe(struct w32_io* pio[2])
&sec_attributes); &sec_attributes);
if (read_handle == INVALID_HANDLE_VALUE) { if (read_handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("pipe - CreateNamedPipe() ERROR:%d", errno); debug3("pipe - CreateNamedPipe() ERROR:%d", errno);
goto error; goto error;
} }
@ -203,7 +204,7 @@ fileio_pipe(struct w32_io* pio[2])
NULL); NULL);
if (write_handle == INVALID_HANDLE_VALUE) { if (write_handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("pipe - ERROR CreateFile() :%d", errno); debug3("pipe - ERROR CreateFile() :%d", errno);
goto error; goto error;
} }
@ -213,7 +214,7 @@ fileio_pipe(struct w32_io* pio[2])
if (!pio_read || !pio_write) { if (!pio_read || !pio_write) {
errno = ENOMEM; errno = ENOMEM;
debug("pip - ERROR:%d", errno); debug3("pip - ERROR:%d", errno);
goto error; goto error;
} }
@ -252,21 +253,21 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
* O_RDONLY, O_WRONLY, or O_RDWR * O_RDONLY, O_WRONLY, or O_RDWR
*/ */
if ((rwflags != O_RDONLY) && (rwflags != O_WRONLY) && (rwflags != O_RDWR)) { if ((rwflags != O_RDONLY) && (rwflags != O_WRONLY) && (rwflags != O_RDWR)) {
debug("open - flags ERROR: wrong rw flags: %d", flags); debug3("open - flags ERROR: wrong rw flags: %d", flags);
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
/*only following create and status flags currently supported*/ /*only following create and status flags currently supported*/
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) { if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) {
debug("open - ERROR: Unsupported flags: %d", flags); debug3("open - ERROR: Unsupported flags: %d", flags);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
/*validate mode*/ /*validate mode*/
if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) { if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
debug("open - ERROR: unsupported mode: %d", mode); debug3("open - ERROR: unsupported mode: %d", mode);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
@ -319,17 +320,17 @@ fileio_open(const char *path_utf8, int flags, int mode)
HANDLE handle; HANDLE handle;
wchar_t *path_utf16 = NULL; wchar_t *path_utf16 = NULL;
debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode); debug4("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
/* check input params*/ /* check input params*/
if (path_utf8 == NULL) { if (path_utf8 == NULL) {
errno = EINVAL; errno = EINVAL;
debug("open - ERROR:%d", errno); debug3("open - ERROR:%d", errno);
return NULL; return NULL;
} }
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) { if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
errno = ENOMEM; errno = ENOMEM;
debug("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError()); debug3("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
return NULL; return NULL;
} }
@ -342,7 +343,7 @@ fileio_open(const char *path_utf8, int flags, int mode)
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("failed to open file:%s error:%d", path_utf8, GetLastError()); debug3("failed to open file:%s error:%d", path_utf8, GetLastError());
free(path_utf16); free(path_utf16);
return NULL; return NULL;
} }
@ -352,7 +353,7 @@ fileio_open(const char *path_utf8, int flags, int mode)
if (pio == NULL) { if (pio == NULL) {
CloseHandle(handle); CloseHandle(handle);
errno = ENOMEM; errno = ENOMEM;
debug("fileio_open(), failed to allocate memory error:%d", errno); debug3("fileio_open(), failed to allocate memory error:%d", errno);
return NULL; return NULL;
} }
@ -369,7 +370,7 @@ VOID CALLBACK
ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped) ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
{ {
struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d", debug4("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered); pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
pio->read_details.error = dwErrorCode; pio->read_details.error = dwErrorCode;
pio->read_details.remaining = dwNumberOfBytesTransfered; pio->read_details.remaining = dwNumberOfBytesTransfered;
@ -383,13 +384,13 @@ ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfer
int int
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested) fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
{ {
debug2("ReadFileEx io:%p", pio); debug4("ReadFileEx io:%p", pio);
if (pio->read_details.buf == NULL) { if (pio->read_details.buf == NULL) {
pio->read_details.buf = malloc(READ_BUFFER_SIZE); pio->read_details.buf = malloc(READ_BUFFER_SIZE);
if (!pio->read_details.buf) { if (!pio->read_details.buf) {
errno = ENOMEM; errno = ENOMEM;
debug2("ReadFileEx - ERROR: %d, io:%p", errno, pio); debug4("ReadFileEx - ERROR: %d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -404,7 +405,7 @@ fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
pio->read_details.pending = TRUE; pio->read_details.pending = TRUE;
else { else {
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
debug("ReadFileEx() ERROR:%d, io:%p", GetLastError(), pio); debug3("ReadFileEx() ERROR:%d, io:%p", GetLastError(), pio);
return -1; return -1;
} }
@ -417,18 +418,18 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
{ {
int bytes_copied; int bytes_copied;
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining); debug5("read - io:%p remaining:%d", pio, pio->read_details.remaining);
/* if read is pending */ /* if read is pending */
if (pio->read_details.pending) { if (pio->read_details.pending) {
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
debug2("read - io is pending, blocking call made, io:%p", pio); debug4("read - io is pending, blocking call made, io:%p", pio);
while (fileio_is_io_available(pio, TRUE) == FALSE) { while (fileio_is_io_available(pio, TRUE) == FALSE) {
if (-1 == wait_for_any_event(NULL, 0, INFINITE)) if (-1 == wait_for_any_event(NULL, 0, INFINITE))
return -1; return -1;
} }
} }
errno = EAGAIN; errno = EAGAIN;
debug2("read - io is already pending, io:%p", pio); debug4("read - io is already pending, io:%p", pio);
return -1; return -1;
} }
@ -442,14 +443,14 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
if ((FILETYPE(pio) == FILE_TYPE_PIPE) if ((FILETYPE(pio) == FILE_TYPE_PIPE)
&& (errno == ERROR_BROKEN_PIPE)) { && (errno == ERROR_BROKEN_PIPE)) {
/* write end of the pipe closed */ /* write end of the pipe closed */
debug("read - no more data, io:%p", pio); debug3("read - no more data, io:%p", pio);
errno = 0; errno = 0;
return 0; return 0;
} }
/* on W2012, ReadFileEx on file throws a synchronous EOF error*/ /* on W2012, ReadFileEx on file throws a synchronous EOF error*/
else if ((FILETYPE(pio) == FILE_TYPE_DISK) else if ((FILETYPE(pio) == FILE_TYPE_DISK)
&& (errno == ERROR_HANDLE_EOF)) { && (errno == ERROR_HANDLE_EOF)) {
debug("read - no more data, io:%p", pio); debug3("read - no more data, io:%p", pio);
errno = 0; errno = 0;
return 0; return 0;
} }
@ -468,7 +469,7 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
} }
else if (pio->read_details.pending) { else if (pio->read_details.pending) {
errno = EAGAIN; errno = EAGAIN;
debug2("read - IO is pending, io:%p", pio); debug4("read - IO is pending, io:%p", pio);
return -1; return -1;
} }
} }
@ -478,12 +479,12 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
/*write end of the pipe is closed or pipe broken or eof reached*/ /*write end of the pipe is closed or pipe broken or eof reached*/
if ((pio->read_details.error == ERROR_BROKEN_PIPE) || if ((pio->read_details.error == ERROR_BROKEN_PIPE) ||
(pio->read_details.error == ERROR_HANDLE_EOF)) { (pio->read_details.error == ERROR_HANDLE_EOF)) {
debug2("read - (2) no more data, io:%p", pio); debug4("read - (2) no more data, io:%p", pio);
errno = 0; errno = 0;
pio->read_details.error = 0; pio->read_details.error = 0;
return 0; return 0;
} }
debug("read - ERROR from cb :%d, io:%p", errno, pio); debug3("read - ERROR from cb :%d, io:%p", errno, pio);
pio->read_details.error = 0; pio->read_details.error = 0;
return -1; return -1;
} }
@ -492,7 +493,7 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied); memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied);
pio->read_details.remaining -= bytes_copied; pio->read_details.remaining -= bytes_copied;
pio->read_details.completed += bytes_copied; pio->read_details.completed += bytes_copied;
debug2("read - io:%p read: %d remaining: %d", pio, bytes_copied, debug4("read - io:%p read: %d remaining: %d", pio, bytes_copied,
pio->read_details.remaining); pio->read_details.remaining);
return bytes_copied; return bytes_copied;
} }
@ -504,13 +505,13 @@ WriteCompletionRoutine(_In_ DWORD dwErrorCode,
{ {
struct w32_io* pio = struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d", debug4("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
pio, pio->write_details.pending, dwErrorCode, dwNumberOfBytesTransfered, pio, pio->write_details.pending, dwErrorCode, dwNumberOfBytesTransfered,
pio->write_details.remaining); pio->write_details.remaining);
pio->write_details.error = dwErrorCode; pio->write_details.error = dwErrorCode;
/* TODO - assert that remaining == dwNumberOfBytesTransfered */ /* TODO - assert that remaining == dwNumberOfBytesTransfered */
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) { if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
debug("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio, debug3("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio,
dwNumberOfBytesTransfered, pio->write_details.remaining); dwNumberOfBytesTransfered, pio->write_details.remaining);
DebugBreak(); DebugBreak();
} }
@ -525,26 +526,26 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
{ {
int bytes_copied; int bytes_copied;
debug2("write - io:%p", pio); debug4("write - io:%p", pio);
if (pio->write_details.pending) { if (pio->write_details.pending) {
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
debug2("write - io pending, blocking call made, io:%p", pio); debug4("write - io pending, blocking call made, io:%p", pio);
while (pio->write_details.pending) while (pio->write_details.pending)
if (wait_for_any_event(NULL, 0, INFINITE) == -1) if (wait_for_any_event(NULL, 0, INFINITE) == -1)
return -1; return -1;
} else { } else {
errno = EAGAIN; errno = EAGAIN;
debug2("write - IO is already pending, io:%p", pio); debug4("write - IO is already pending, io:%p", pio);
return -1; return -1;
} }
} }
if (pio->write_details.error) { if (pio->write_details.error) {
errno = errno_from_Win32Error(pio->write_details.error); errno = errno_from_Win32Error(pio->write_details.error);
debug("write - ERROR:%d on prior unblocking write, io:%p", errno, pio); debug3("write - ERROR:%d on prior unblocking write, io:%p", errno, pio);
pio->write_details.error = 0; pio->write_details.error = 0;
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) { if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
debug("write - ERROR:read end of the pipe closed, io:%p", pio); debug3("write - ERROR:read end of the pipe closed, io:%p", pio);
errno = EPIPE; errno = EPIPE;
} }
return -1; return -1;
@ -554,7 +555,7 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
pio->write_details.buf = malloc(WRITE_BUFFER_SIZE); pio->write_details.buf = malloc(WRITE_BUFFER_SIZE);
if (pio->write_details.buf == NULL) { if (pio->write_details.buf == NULL) {
errno = ENOMEM; errno = ENOMEM;
debug("write - ERROR:%d, io:%p", errno, pio); debug3("write - ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
pio->write_details.buf_size = WRITE_BUFFER_SIZE; pio->write_details.buf_size = WRITE_BUFFER_SIZE;
@ -579,10 +580,10 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
errno = errno_from_Win32LastError(); errno = errno_from_Win32LastError();
/* read end of the pipe closed ? */ /* read end of the pipe closed ? */
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) { if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
debug("write - ERROR:read end of the pipe closed, io:%p", pio); debug3("write - ERROR:read end of the pipe closed, io:%p", pio);
errno = EPIPE; errno = EPIPE;
} }
debug("write ERROR from cb(2):%d, io:%p", errno, pio); debug3("write ERROR from cb(2):%d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -604,11 +605,11 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
/* if write has completed, pick up any error reported*/ /* if write has completed, pick up any error reported*/
if (!pio->write_details.pending && pio->write_details.error) { if (!pio->write_details.pending && pio->write_details.error) {
errno = errno_from_Win32Error(pio->write_details.error); errno = errno_from_Win32Error(pio->write_details.error);
debug("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio); debug3("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio);
pio->write_details.error = 0; pio->write_details.error = 0;
return -1; return -1;
} }
debug2("write - reporting %d bytes written, io:%p", bytes_copied, pio); debug4("write - reporting %d bytes written, io:%p", bytes_copied, pio);
return bytes_copied; return bytes_copied;
} }
@ -618,7 +619,7 @@ int
fileio_fstat(struct w32_io* pio, struct _stat64 *buf) fileio_fstat(struct w32_io* pio, struct _stat64 *buf)
{ {
int fd = _open_osfhandle((intptr_t)pio->handle, 0); int fd = _open_osfhandle((intptr_t)pio->handle, 0);
debug2("fstat - pio:%p", pio); debug4("fstat - pio:%p", pio);
if (fd == -1) { if (fd == -1) {
errno = EOTHER; errno = EOTHER;
return -1; return -1;
@ -654,9 +655,9 @@ fileio_stat(const char *path, struct _stat64 *buf)
long long
fileio_lseek(struct w32_io* pio, long offset, int origin) fileio_lseek(struct w32_io* pio, long offset, int origin)
{ {
debug2("lseek - pio:%p", pio); debug4("lseek - pio:%p", pio);
if (origin != SEEK_SET) { if (origin != SEEK_SET) {
debug("lseek - ERROR, origin is not supported %d", origin); debug3("lseek - ERROR, origin is not supported %d", origin);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
@ -671,7 +672,7 @@ FILE*
fileio_fdopen(struct w32_io* pio, const char *mode) fileio_fdopen(struct w32_io* pio, const char *mode)
{ {
int fd_flags = 0; int fd_flags = 0;
debug2("fdopen - io:%p", pio); debug4("fdopen - io:%p", pio);
/* logic below doesn't work with overlapped file HANDLES */ /* logic below doesn't work with overlapped file HANDLES */
if (mode[1] == '\0') { if (mode[1] == '\0') {
@ -686,12 +687,12 @@ fileio_fdopen(struct w32_io* pio, const char *mode)
break; break;
default: default:
errno = ENOTSUP; errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode); debug3("fdopen - ERROR unsupported mode %s", mode);
return NULL; return NULL;
} }
} else { } else {
errno = ENOTSUP; errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode); debug3("fdopen - ERROR unsupported mode %s", mode);
return NULL; return NULL;
} }
@ -699,7 +700,7 @@ fileio_fdopen(struct w32_io* pio, const char *mode)
if (fd == -1) { if (fd == -1) {
errno = EOTHER; errno = EOTHER;
debug("fdopen - ERROR:%d _open_osfhandle()", errno); debug3("fdopen - ERROR:%d _open_osfhandle()", errno);
return NULL; return NULL;
} }
@ -732,7 +733,7 @@ fileio_on_select(struct w32_io* pio, BOOL rd)
int int
fileio_close(struct w32_io* pio) fileio_close(struct w32_io* pio)
{ {
debug2("fileclose - pio:%p", pio); debug4("fileclose - pio:%p", pio);
/* handle can be null on AF_UNIX sockets that are not yet connected */ /* handle can be null on AF_UNIX sockets that are not yet connected */
if (WINHANDLE(pio) == 0 || WINHANDLE(pio) == INVALID_HANDLE_VALUE) { if (WINHANDLE(pio) == 0 || WINHANDLE(pio) == INVALID_HANDLE_VALUE) {

View File

@ -81,4 +81,21 @@ char *crypt(const char *key, const char *salt);
int link(const char *oldpath, const char *newpath); int link(const char *oldpath, const char *newpath);
int readlink(const char *path, char *link, int linklen); int readlink(const char *path, char *link, int linklen);
int spawn_child(char* cmd, int in, int out, int err, unsigned long flags); int spawn_child(char* cmd, char** argv, int in, int out, int err, unsigned long flags);
/*
* readpassphrase.h definitions
* cannot create a separate header due to the way
* its included in openbsdcompat.h
*/
#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */
#define RPP_ECHO_ON 0x01 /* Leave echo on. */
#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */
#define RPP_FORCELOWER 0x04 /* Force input to lower case. */
#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */
#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */
char * readpassphrase(const char *, char *, size_t, int);

View File

@ -33,6 +33,7 @@
#include <time.h> #include <time.h>
#include <Shlwapi.h> #include <Shlwapi.h>
#include "inc\unistd.h"
#include "inc\sys\stat.h" #include "inc\sys\stat.h"
#include "inc\sys\statvfs.h" #include "inc\sys\statvfs.h"
#include "inc\sys\time.h" #include "inc\sys\time.h"
@ -44,6 +45,7 @@
#include "inc\fcntl.h" #include "inc\fcntl.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "signal_internal.h" #include "signal_internal.h"
#include "debug.h"
static char* s_programdir = NULL; static char* s_programdir = NULL;
@ -249,7 +251,7 @@ w32_fopen_utf8(const char *path, const char *mode)
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX) == 0 || if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX) == 0 ||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) { MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) {
errno = EFAULT; errno = EFAULT;
debug("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError()); debug3("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError());
return NULL; return NULL;
} }
@ -402,15 +404,26 @@ w32_ioctl(int d, int request, ...)
} }
} }
/*
* spawn a child process
* - specified by cmd with agruments argv
* - with std handles set to in, out, err
* - flags are passed to CreateProcess call
*
* cmd will be internally decoarated with a set of '"'
* to account for any spaces within the commandline
* this decoration is done only when additional arguments are passed in argv
*/
int int
spawn_child(char* cmd, int in, int out, int err, DWORD flags) spawn_child(char* cmd, char** argv, int in, int out, int err, DWORD flags)
{ {
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFOW si; STARTUPINFOW si;
BOOL b; BOOL b;
char *abs_cmd, *t; char *cmdline, *t, **t1;
wchar_t * cmd_utf16; DWORD cmdline_len = 0;
int add_module_path = 0; wchar_t * cmdline_utf16;
int add_module_path = 0, ret = -1;
/* should module path be added */ /* should module path be added */
do { do {
@ -424,31 +437,57 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags)
add_module_path = 1; add_module_path = 1;
} while (0); } while (0);
/* add current module path to start if needed */ /* compute total cmdline len*/
if (add_module_path) { if (add_module_path)
char* ctr; cmdline_len += strlen(w32_programdir()) + 1 + strlen(cmd) + 1 + 2;
abs_cmd = malloc(strlen(w32_programdir()) + 1 + strlen(cmd) + 1); else
if (abs_cmd == NULL) { cmdline_len += strlen(cmd) + 1 + 2;
errno = ENOMEM;
return -1;
}
ctr = abs_cmd;
memcpy(ctr, w32_programdir(), strlen(w32_programdir()));
ctr += strlen(w32_programdir());
*ctr++ = '\\';
memcpy(ctr, cmd, strlen(cmd) + 1);
} else
abs_cmd = cmd;
debug("spawning %s", abs_cmd); if (argv) {
t1 = argv;
if ((cmd_utf16 = utf8_to_utf16(abs_cmd)) == NULL) { while (*t1)
errno = ENOMEM; cmdline_len += strlen(*t1++) + 1 + 2;
return -1;
} }
if (abs_cmd != cmd) if ((cmdline = malloc(cmdline_len)) == NULL) {
free(abs_cmd); errno = ENOMEM;
goto cleanup;
}
/* add current module path to start if needed */
t = cmdline;
if (argv && argv[0])
*t++ = '\"';
if (add_module_path) {
memcpy(t, w32_programdir(), strlen(w32_programdir()));
t += strlen(w32_programdir());
*t++ = '\\';
}
memcpy(t, cmd, strlen(cmd));
t += strlen(cmd);
if (argv && argv[0])
*t++ = '\"';
if (argv) {
t1 = argv;
while (*t1) {
*t++ = ' ';
*t++ = '\"';
memcpy(t, *t1, strlen(*t1));
t += strlen(*t1);
*t++ = '\"';
t1++;
}
}
*t = '\0';
if ((cmdline_utf16 = utf8_to_utf16(cmdline)) == NULL) {
errno = ENOMEM;
goto cleanup;
}
memset(&si, 0, sizeof(STARTUPINFOW)); memset(&si, 0, sizeof(STARTUPINFOW));
si.cb = sizeof(STARTUPINFOW); si.cb = sizeof(STARTUPINFOW);
@ -457,22 +496,29 @@ spawn_child(char* cmd, int in, int out, int err, DWORD flags)
si.hStdError = w32_fd_to_handle(err); si.hStdError = w32_fd_to_handle(err);
si.dwFlags = STARTF_USESTDHANDLES; si.dwFlags = STARTF_USESTDHANDLES;
b = CreateProcessW(NULL, cmd_utf16, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi); debug3("spawning %ls", cmdline_utf16);
b = CreateProcessW(NULL, cmdline_utf16, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
if (b) { if (b) {
if (register_child(pi.hProcess, pi.dwProcessId) == -1) { if (register_child(pi.hProcess, pi.dwProcessId) == -1) {
TerminateProcess(pi.hProcess, 0); TerminateProcess(pi.hProcess, 0);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
pi.dwProcessId = -1; goto cleanup;
} }
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
} else { } else {
errno = GetLastError(); errno = GetLastError();
pi.dwProcessId = -1; goto cleanup;
} }
free(cmd_utf16); ret = pi.dwProcessId;
return pi.dwProcessId; cleanup:
if (cmdline)
free(cmdline);
if (cmdline_utf16)
free(cmdline_utf16);
return ret;
} }
void void
@ -618,13 +664,13 @@ settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
/* TODO - convert Win32 error to errno */ /* TODO - convert Win32 error to errno */
errno = GetLastError(); errno = GetLastError();
debug("w32_settimes - CreateFileW ERROR:%d", errno); debug3("w32_settimes - CreateFileW ERROR:%d", errno);
return -1; return -1;
} }
if (SetFileTime(handle, cretime, acttime, modtime) == 0) { if (SetFileTime(handle, cretime, acttime, modtime) == 0) {
errno = GetLastError(); errno = GetLastError();
debug("w32_settimes - SetFileTime ERROR:%d", errno); debug3("w32_settimes - SetFileTime ERROR:%d", errno);
CloseHandle(handle); CloseHandle(handle);
return -1; return -1;
} }
@ -953,12 +999,12 @@ statvfs(const char *path, struct statvfs *buf)
wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path)); wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path));
if (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector, if (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE) { &freeClusters, &totalClusters) == TRUE) {
debug3("path : [%s]", path); debug5("path : [%s]", path);
debug3("sectorsPerCluster : [%lu]", sectorsPerCluster); debug5("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug3("bytesPerSector : [%lu]", bytesPerSector); debug5("bytesPerSector : [%lu]", bytesPerSector);
debug3("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector); debug5("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector);
debug3("freeClusters : [%lu]", freeClusters); debug5("freeClusters : [%lu]", freeClusters);
debug3("totalClusters : [%lu]", totalClusters); debug5("totalClusters : [%lu]", totalClusters);
buf->f_bsize = sectorsPerCluster * bytesPerSector; buf->f_bsize = sectorsPerCluster * bytesPerSector;
buf->f_frsize = sectorsPerCluster * bytesPerSector; buf->f_frsize = sectorsPerCluster * bytesPerSector;
@ -975,7 +1021,7 @@ statvfs(const char *path, struct statvfs *buf)
free(path_utf16); free(path_utf16);
return 0; return 0;
} else { } else {
debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n", path, GetLastError()); debug5("ERROR: Cannot get free space for [%s]. Error code is : %d.\n", path, GetLastError());
free(path_utf16); free(path_utf16);
return -1; return -1;
@ -996,3 +1042,58 @@ w32_strerror(int errnum)
return _sys_errlist_ext[errnum - EADDRINUSE]; return _sys_errlist_ext[errnum - EADDRINUSE];
return strerror(errnum); return strerror(errnum);
} }
/*
* Temporary implementation of readpassphrase.
* TODO - this needs to be reimplemented as per
* https://linux.die.net/man/3/readpassphrase
*/
char *
readpassphrase(const char *prompt, char *out, size_t out_len, int flags) {
char *askpass = NULL;
char *ret = NULL;
DWORD mode;
size_t len = 0;
int retr = 0;
/* prompt user */
wchar_t* wtmp = utf8_to_utf16(prompt);
if (wtmp == NULL)
fatal("unable to alloc memory");
_cputws(wtmp);
free(wtmp);
len = retr = 0;
while (_kbhit())
_getch();
while (len < out_len) {
out[len] = (unsigned char)_getch();
if (out[len] == '\r') {
if (_kbhit()) /* read linefeed if its there */
_getch();
break;
}
else if (out[len] == '\n') {
break;
}
else if (out[len] == '\b') { /* backspace */
if (len > 0)
len--; /* overwrite last character */
}
else if (out[len] == '\003') {
/* exit on Ctrl+C */
fatal("");
}
else {
len++; /* keep reading in the loop */
}
}
out[len] = '\0'; /* get rid of the cr/lf */
_cputs("\n"); /*show a newline as we do not echo password or the line */
return out;
}

View File

@ -41,6 +41,7 @@
#include "inc\grp.h" #include "inc\grp.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "misc_internal.h" #include "misc_internal.h"
#include "debug.h"
static struct passwd pw; static struct passwd pw;
static char* pw_shellpath = NULL; static char* pw_shellpath = NULL;
@ -128,7 +129,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
if (user_sid == NULL) { if (user_sid == NULL) {
NET_API_STATUS status; NET_API_STATUS status;
if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) { if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {
debug("NetUserGetInfo() failed with error: %d for user: %ls and domain: %ls \n", status, uname_utf16, udom_utf16); debug3("NetUserGetInfo() failed with error: %d for user: %ls and domain: %ls \n", status, uname_utf16, udom_utf16);
if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) != ERROR_SUCCESS) { if ((dsStatus = DsGetDcNameW(NULL, udom_utf16, NULL, NULL, DS_DIRECTORY_SERVICE_PREFERRED, &pdc)) != ERROR_SUCCESS) {
error("DsGetDcNameW() failed with error: %d \n", dsStatus); error("DsGetDcNameW() failed with error: %d \n", dsStatus);
@ -137,14 +138,14 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
} }
if ((status = NetUserGetInfo(pdc->DomainControllerName, uname_utf16, 23, &user_info)) != NERR_Success) { if ((status = NetUserGetInfo(pdc->DomainControllerName, uname_utf16, 23, &user_info)) != NERR_Success) {
debug("NetUserGetInfo() with domainController: %ls failed with error: %d \n", pdc->DomainControllerName, status); debug3("NetUserGetInfo() with domainController: %ls failed with error: %d \n", pdc->DomainControllerName, status);
errno = ENOENT; errno = ENOENT;
goto done; goto done;
} }
} }
if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) { if (ConvertSidToStringSidW(((LPUSER_INFO_23)user_info)->usri23_user_sid, &user_sid_local) == FALSE) {
debug("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError()); debug3("NetUserGetInfo() Succeded but ConvertSidToStringSidW() failed with error: %d\n", GetLastError());
errno = ENOENT; errno = ENOENT;
goto done; goto done;
} }

View File

@ -32,6 +32,7 @@
#include "w32fd.h" #include "w32fd.h"
#include "signal_internal.h" #include "signal_internal.h"
#include "inc\signal.h" #include "inc\signal.h"
#include "debug.h"
#undef signal #undef signal
#undef raise #undef raise
@ -56,28 +57,28 @@ extern struct _children children;
static VOID CALLBACK static VOID CALLBACK
sigint_APCProc(_In_ ULONG_PTR dwParam) sigint_APCProc(_In_ ULONG_PTR dwParam)
{ {
debug3("SIGINT APCProc()"); debug5("SIGINT APCProc()");
sigaddset(&pending_signals, W32_SIGINT); sigaddset(&pending_signals, W32_SIGINT);
} }
static VOID CALLBACK static VOID CALLBACK
sigterm_APCProc(_In_ ULONG_PTR dwParam) sigterm_APCProc(_In_ ULONG_PTR dwParam)
{ {
debug3("SIGTERM APCProc()"); debug5("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGTERM); sigaddset(&pending_signals, W32_SIGTERM);
} }
static VOID CALLBACK static VOID CALLBACK
sigtstp_APCProc(_In_ ULONG_PTR dwParam) sigtstp_APCProc(_In_ ULONG_PTR dwParam)
{ {
debug3("SIGTSTP APCProc()"); debug5("SIGTSTP APCProc()");
sigaddset(&pending_signals, W32_SIGTSTP); sigaddset(&pending_signals, W32_SIGTSTP);
} }
BOOL WINAPI BOOL WINAPI
native_sig_handler(DWORD dwCtrlType) native_sig_handler(DWORD dwCtrlType)
{ {
debug("Native Ctrl+C handler, CtrlType %d", dwCtrlType); debug3("Native Ctrl+C handler, CtrlType %d", dwCtrlType);
switch (dwCtrlType) { switch (dwCtrlType) {
case CTRL_C_EVENT: case CTRL_C_EVENT:
QueueUserAPC(sigint_APCProc, main_thread, (ULONG_PTR)NULL); QueueUserAPC(sigint_APCProc, main_thread, (ULONG_PTR)NULL);
@ -100,7 +101,7 @@ native_sig_handler(DWORD dwCtrlType)
static VOID CALLBACK static VOID CALLBACK
sigwinch_APCProc(_In_ ULONG_PTR dwParam) sigwinch_APCProc(_In_ ULONG_PTR dwParam)
{ {
debug3("SIGTERM APCProc()"); debug5("SIGTERM APCProc()");
sigaddset(&pending_signals, W32_SIGWINCH); sigaddset(&pending_signals, W32_SIGWINCH);
} }
@ -128,7 +129,7 @@ sighandler_t
w32_signal(int signum, sighandler_t handler) w32_signal(int signum, sighandler_t handler)
{ {
sighandler_t prev; sighandler_t prev;
debug2("signal() sig:%d, handler:%p", signum, handler); debug4("signal() sig:%d, handler:%p", signum, handler);
if (signum >= W32_SIGMAX) { if (signum >= W32_SIGMAX) {
errno = EINVAL; errno = EINVAL;
return W32_SIG_ERR; return W32_SIG_ERR;
@ -144,7 +145,7 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
{ {
/* this is only used by sshd to block SIGCHLD while doing waitpid() */ /* this is only used by sshd to block SIGCHLD while doing waitpid() */
/* our implementation of waidpid() is never interrupted, so no need to implement this for now*/ /* our implementation of waidpid() is never interrupted, so no need to implement this for now*/
debug3("sigprocmask() how:%d"); debug5("sigprocmask() how:%d");
return 0; return 0;
} }
@ -153,7 +154,7 @@ w32_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
int int
w32_raise(int sig) w32_raise(int sig)
{ {
debug("raise sig:%d", sig); debug3("raise sig:%d", sig);
if (sig == W32_SIGSEGV) if (sig == W32_SIGSEGV)
return raise(SIGSEGV); /* raise native exception handler*/ return raise(SIGSEGV); /* raise native exception handler*/
@ -191,7 +192,7 @@ sw_process_pending_signals()
sigset_t pending_tmp = pending_signals; sigset_t pending_tmp = pending_signals;
BOOL sig_int = FALSE; /* has any signal actually interrupted */ BOOL sig_int = FALSE; /* has any signal actually interrupted */
debug3("process_signals()"); debug5("process_signals()");
int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP, W32_SIGWINCH }; int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP, W32_SIGWINCH };
/* check for expected signals*/ /* check for expected signals*/
@ -199,7 +200,7 @@ sw_process_pending_signals()
sigdelset(&pending_tmp, exp[i]); sigdelset(&pending_tmp, exp[i]);
if (pending_tmp) { if (pending_tmp) {
/* unexpected signals queued up */ /* unexpected signals queued up */
debug("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp); debug3("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp);
errno = ENOTSUP; errno = ENOTSUP;
DebugBreak(); DebugBreak();
return -1; return -1;
@ -228,7 +229,7 @@ sw_process_pending_signals()
DebugBreak(); DebugBreak();
if (sig_int) { if (sig_int) {
debug("process_queued_signals: WARNING - A signal has interrupted and was processed"); debug3("process_queued_signals: WARNING - A signal has interrupted and was processed");
errno = EINTR; errno = EINTR;
return -1; return -1;
} }
@ -257,7 +258,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
num_all_events = num_events + live_children; num_all_events = num_events + live_children;
if (num_all_events > MAXIMUM_WAIT_OBJECTS) { if (num_all_events > MAXIMUM_WAIT_OBJECTS) {
debug("wait() - ERROR max events reached"); debug3("wait() - ERROR max events reached");
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
@ -265,7 +266,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
memcpy(all_events, children.handles, live_children * sizeof(HANDLE)); memcpy(all_events, children.handles, live_children * sizeof(HANDLE));
memcpy(all_events + live_children, events, num_events * sizeof(HANDLE)); memcpy(all_events + live_children, events, num_events * sizeof(HANDLE));
debug3("wait() on %d events and %d children", num_events, live_children); debug5("wait() on %d events and %d children", num_events, live_children);
/* TODO - implement signal catching and handling */ /* TODO - implement signal catching and handling */
if (num_all_events) { if (num_all_events) {
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, milli_seconds, TRUE); DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE, milli_seconds, TRUE);
@ -284,7 +285,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
return 0; return 0;
} else { /* some other error*/ } else { /* some other error*/
errno = EOTHER; errno = EOTHER;
debug("ERROR: unxpected wait end: %d", ret); debug3("ERROR: unxpected wait end: %d", ret);
return -1; return -1;
} }
} else { } else {
@ -296,7 +297,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
return 0; return 0;
} else { /* some other error */ } else { /* some other error */
errno = EOTHER; errno = EOTHER;
debug("ERROR: unxpected SleepEx error: %d", ret); debug3("ERROR: unxpected SleepEx error: %d", ret);
return -1; return -1;
} }
} }

View File

@ -30,6 +30,7 @@
#include "signal_internal.h" #include "signal_internal.h"
#include "inc\signal.h" #include "inc\signal.h"
#include "debug.h"
struct _timer_info timer_info; struct _timer_info timer_info;
extern sigset_t pending_signals; extern sigset_t pending_signals;
@ -49,7 +50,7 @@ w32_alarm(unsigned int sec)
ULONGLONG sec_passed; ULONGLONG sec_passed;
int ret = 0; int ret = 0;
debug3("alarm() %d secs", sec); debug5("alarm() %d secs", sec);
errno = 0; errno = 0;
/* cancel any live timer if seconds is 0*/ /* cancel any live timer if seconds is 0*/
if (sec == 0) { if (sec == 0) {
@ -63,7 +64,7 @@ w32_alarm(unsigned int sec)
due.QuadPart *= sec; due.QuadPart *= sec;
/* this call resets the timer if it is already active */ /* this call resets the timer if it is already active */
if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) { if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) {
debug("alram() - ERROR SetWaitableTimer() %d", GetLastError()); debug3("alram() - ERROR SetWaitableTimer() %d", GetLastError());
return 0;; return 0;;
} }

View File

@ -30,6 +30,7 @@
#include "signal_internal.h" #include "signal_internal.h"
#include "inc\sys\wait.h" #include "inc\sys\wait.h"
#include "debug.h"
struct _children children; struct _children children;
@ -38,7 +39,7 @@ register_child(HANDLE child, DWORD pid)
{ {
DWORD first_zombie_index; DWORD first_zombie_index;
debug("Register child %p pid %d, %d zombies of %d", child, pid, debug3("Register child %p pid %d, %d zombies of %d", child, pid,
children.num_zombies, children.num_children); children.num_zombies, children.num_children);
if (children.num_children == MAX_CHILDREN) { if (children.num_children == MAX_CHILDREN) {
errno = ENOMEM; errno = ENOMEM;
@ -65,7 +66,7 @@ int
sw_remove_child_at_index(DWORD index) sw_remove_child_at_index(DWORD index)
{ {
DWORD last_non_zombie; DWORD last_non_zombie;
debug("Unregister child at index %d, %d zombies of %d", index, debug3("Unregister child at index %d, %d zombies of %d", index,
children.num_zombies, children.num_children); children.num_zombies, children.num_children);
if ((index >= children.num_children) || (children.num_children == 0)) { if ((index >= children.num_children) || (children.num_children == 0)) {
@ -103,7 +104,7 @@ sw_child_to_zombie(DWORD index)
DWORD last_non_zombie, zombie_pid; DWORD last_non_zombie, zombie_pid;
HANDLE zombie_handle; HANDLE zombie_handle;
debug("zombie'ing child at index %d, %d zombies of %d", index, debug3("zombie'ing child at index %d, %d zombies of %d", index,
children.num_zombies, children.num_children); children.num_zombies, children.num_children);
if (index >= children.num_children) { if (index >= children.num_children) {
@ -152,7 +153,7 @@ waitpid(int pid, int *status, int options)
DWORD index, ret, ret_id, exit_code, timeout = 0; DWORD index, ret, ret_id, exit_code, timeout = 0;
HANDLE process = NULL; HANDLE process = NULL;
debug3("waitpid - pid:%d, options:%d", pid, options); debug5("waitpid - pid:%d, options:%d", pid, options);
if (options & (~WNOHANG)) { if (options & (~WNOHANG)) {
errno = ENOTSUP; errno = ENOTSUP;
DebugBreak(); DebugBreak();

View File

@ -36,6 +36,7 @@
#include <stddef.h> #include <stddef.h>
#include "w32fd.h" #include "w32fd.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "debug.h"
#define INTERNAL_SEND_BUFFER_SIZE 70*1024 //70KB #define INTERNAL_SEND_BUFFER_SIZE 70*1024 //70KB
#define INTERNAL_RECV_BUFFER_SIZE 70*1024 //70KB #define INTERNAL_RECV_BUFFER_SIZE 70*1024 //70KB
@ -103,7 +104,7 @@ int
socketio_acceptEx(struct w32_io* pio) socketio_acceptEx(struct w32_io* pio)
{ {
struct acceptEx_context *context; struct acceptEx_context *context;
debug3("acceptEx - io:%p", pio); debug5("acceptEx - io:%p", pio);
context = (struct acceptEx_context *)pio->internal.context; context = (struct acceptEx_context *)pio->internal.context;
ResetEvent(pio->read_overlapped.hEvent); ResetEvent(pio->read_overlapped.hEvent);
@ -111,7 +112,7 @@ socketio_acceptEx(struct w32_io* pio)
context->accept_socket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); context->accept_socket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
if (context->accept_socket == INVALID_SOCKET) { if (context->accept_socket == INVALID_SOCKET) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("acceptEx - socket() ERROR:%d, io:%p", errno, pio); debug3("acceptEx - socket() ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -130,7 +131,7 @@ socketio_acceptEx(struct w32_io* pio)
/* if overlapped io is in progress, we are good */ /* if overlapped io is in progress, we are good */
if (WSAGetLastError() != ERROR_IO_PENDING) { if (WSAGetLastError() != ERROR_IO_PENDING) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("acceptEx - AcceptEx() ERROR:%d, io:%p", errno, pio); debug3("acceptEx - AcceptEx() ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -147,7 +148,7 @@ CALLBACK WSARecvCompletionRoutine(IN DWORD dwError,
{ {
struct w32_io* pio = struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped)); (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
debug2("WSARecvCompletionCB - io:%p, pending_state:%d, flags:%d, error:%d, received:%d", debug4("WSARecvCompletionCB - io:%p, pending_state:%d, flags:%d, error:%d, received:%d",
pio, pio->read_details.pending, dwFlags, dwError, cbTransferred); pio, pio->read_details.pending, dwFlags, dwError, cbTransferred);
if (!dwError && !cbTransferred) if (!dwError && !cbTransferred)
dwError = ERROR_GRACEFUL_DISCONNECT; dwError = ERROR_GRACEFUL_DISCONNECT;
@ -166,7 +167,7 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed)
WSABUF wsabuf; WSABUF wsabuf;
DWORD recv_flags = 0; DWORD recv_flags = 0;
debug3("WSARecv - pio: %p", pio); debug5("WSARecv - pio: %p", pio);
if (completed) if (completed)
*completed = FALSE; *completed = FALSE;
@ -176,7 +177,7 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed)
wsabuf.buf = malloc(wsabuf.len); wsabuf.buf = malloc(wsabuf.len);
if (!wsabuf.buf) { if (!wsabuf.buf) {
errno = ENOMEM; errno = ENOMEM;
debug("WSARecv - ERROR:%d, io:%p", errno, pio); debug3("WSARecv - ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -189,17 +190,17 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed)
if (ret == 0) { if (ret == 0) {
pio->read_details.pending = TRUE; pio->read_details.pending = TRUE;
/* receive has completed but APC is pending to be scheduled */ /* receive has completed but APC is pending to be scheduled */
debug2("WSARecv - WSARecv() returned 0, io:%p", pio); debug4("WSARecv - WSARecv() returned 0, io:%p", pio);
if (completed) if (completed)
*completed = TRUE; *completed = TRUE;
} else { /* (ret == SOCKET_ERROR) */ } else { /* (ret == SOCKET_ERROR) */
if (WSAGetLastError() == WSA_IO_PENDING) { if (WSAGetLastError() == WSA_IO_PENDING) {
/* io is initiated and pending */ /* io is initiated and pending */
debug2("WSARecv - reported IO pending"); debug4("WSARecv - reported IO pending");
pio->read_details.pending = TRUE; pio->read_details.pending = TRUE;
} else { } else {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno); debug3("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno);
return -1; return -1;
} }
} }
@ -214,7 +215,7 @@ socketio_socket(int domain, int type, int protocol)
struct w32_io *pio = (struct w32_io*)malloc(sizeof(struct w32_io)); struct w32_io *pio = (struct w32_io*)malloc(sizeof(struct w32_io));
if (!pio) { if (!pio) {
errno = ENOMEM; errno = ENOMEM;
debug("socket - ERROR:%d, io:%p", errno, pio); debug3("socket - ERROR:%d, io:%p", errno, pio);
return NULL; return NULL;
} }
@ -223,7 +224,7 @@ socketio_socket(int domain, int type, int protocol)
if (pio->sock == INVALID_SOCKET) { if (pio->sock == INVALID_SOCKET) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
free(pio); free(pio);
debug("socket - socket() ERROR:%d, io:%p", errno, pio); debug3("socket - socket() ERROR:%d, io:%p", errno, pio);
return NULL; return NULL;
} }
@ -235,7 +236,7 @@ socketio_socket(int domain, int type, int protocol)
int ret = (expr); \ int ret = (expr); \
if (ret == SOCKET_ERROR) { \ if (ret == SOCKET_ERROR) { \
errno = errno_from_WSALastError(); \ errno = errno_from_WSALastError(); \
debug("%s - ERROR:%d", __FUNCTION__, errno); \ debug3("%s - ERROR:%d", __FUNCTION__, errno); \
} \ } \
return ret; \ return ret; \
} while (0) } while (0)
@ -248,7 +249,7 @@ socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optv
(optname == TCP_NODELAY) || (optname == IPV6_V6ONLY)) (optname == TCP_NODELAY) || (optname == IPV6_V6ONLY))
SET_ERRNO_ON_ERROR(setsockopt(pio->sock, level, optname, optval, optlen)); SET_ERRNO_ON_ERROR(setsockopt(pio->sock, level, optname, optval, optlen));
else { else {
debug("setsockop - ERROR: unsupported optname:%d io:%p", optname, pio); debug3("setsockop - ERROR: unsupported optname:%d io:%p", optname, pio);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
@ -283,7 +284,7 @@ socketio_listen(struct w32_io* pio, int backlog)
if (SOCKET_ERROR == listen(pio->sock, backlog)) { if (SOCKET_ERROR == listen(pio->sock, backlog)) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("listen - listen() ERROR:%d io:%p", errno, pio); debug3("listen - listen() ERROR:%d io:%p", errno, pio);
return -1; return -1;
} }
@ -296,7 +297,7 @@ socketio_listen(struct w32_io* pio, int backlog)
context = (struct acceptEx_context*)malloc(sizeof(struct acceptEx_context)); context = (struct acceptEx_context*)malloc(sizeof(struct acceptEx_context));
if (context == NULL) { if (context == NULL) {
errno = ENOMEM; errno = ENOMEM;
debug("listen - ERROR:%d, io:%p", errno, pio); debug3("listen - ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
memset(context, 0, sizeof(struct acceptEx_context)); memset(context, 0, sizeof(struct acceptEx_context));
@ -307,7 +308,7 @@ socketio_listen(struct w32_io* pio, int backlog)
&dwBytes, NULL, NULL)) { &dwBytes, NULL, NULL)) {
free(context); free(context);
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("listen - Ioctl1 ERROR:%d, io:%p", errno, pio); debug3("listen - Ioctl1 ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -318,7 +319,7 @@ socketio_listen(struct w32_io* pio, int backlog)
&dwBytes, NULL, NULL)) { &dwBytes, NULL, NULL)) {
free(context); free(context);
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("listen - Ioctl2 ERROR:%d, io:%p", errno, pio); debug3("listen - Ioctl2 ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -326,7 +327,7 @@ socketio_listen(struct w32_io* pio, int backlog)
if ((pio->read_overlapped.hEvent) == NULL) { if ((pio->read_overlapped.hEvent) == NULL) {
free(context); free(context);
errno = ENOMEM; errno = ENOMEM;
debug("listen - CreateEvent() ERROR:%d, io:%p", errno, pio); debug3("listen - CreateEvent() ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -350,16 +351,16 @@ int
socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
{ {
BOOL completed = FALSE; BOOL completed = FALSE;
debug3("recv - io:%p", pio); debug5("recv - io:%p", pio);
if ((buf == NULL) || (len == 0)) { if ((buf == NULL) || (len == 0)) {
errno = EINVAL; errno = EINVAL;
debug("recv - ERROR: invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); debug3("recv - ERROR: invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio);
return -1; return -1;
} }
if (flags != 0) { if (flags != 0) {
errno = ENOTSUP; errno = ENOTSUP;
debug("recv - ERROR: flags are not currently supported, io:%p", pio); debug3("recv - ERROR: flags are not currently supported, io:%p", pio);
return -1; return -1;
} }
@ -368,14 +369,14 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
if (pio->read_details.pending) { if (pio->read_details.pending) {
/* if recv is now in blocking mode, wait for data to be available */ /* if recv is now in blocking mode, wait for data to be available */
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
debug2("recv - io is pending, call is blocking, io:%p", pio); debug4("recv - io is pending, call is blocking, io:%p", pio);
while (socketio_is_io_available(pio, TRUE) == FALSE) { while (socketio_is_io_available(pio, TRUE) == FALSE) {
if (0 != wait_for_any_event(NULL, 0, INFINITE)) if (0 != wait_for_any_event(NULL, 0, INFINITE))
return -1; return -1;
} }
} else { } else {
errno = EAGAIN; errno = EAGAIN;
debug2("recv - io is already pending, io:%p", pio); debug4("recv - io is already pending, io:%p", pio);
return -1; return -1;
} }
} }
@ -387,7 +388,7 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
num_bytes_copied); num_bytes_copied);
pio->read_details.remaining -= num_bytes_copied; pio->read_details.remaining -= num_bytes_copied;
pio->read_details.completed += num_bytes_copied; pio->read_details.completed += num_bytes_copied;
debug2("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", debug4("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p",
num_bytes_copied, pio->read_details.remaining, pio); num_bytes_copied, pio->read_details.remaining, pio);
return num_bytes_copied; return num_bytes_copied;
} }
@ -395,12 +396,12 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
/* if there was an error on async call, return */ /* if there was an error on async call, return */
if (pio->read_details.error) { if (pio->read_details.error) {
if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) {
debug2("recv - connection closed, io:%p", pio); debug4("recv - connection closed, io:%p", pio);
/* connection is closed */ /* connection is closed */
return 0; return 0;
} else { } else {
errno = errno_from_WSAError(pio->read_details.error); errno = errno_from_WSAError(pio->read_details.error);
debug("recv - from CB ERROR:%d, io:%p", pio->read_details.error, pio); debug3("recv - from CB ERROR:%d, io:%p", pio->read_details.error, pio);
pio->read_details.error = 0; pio->read_details.error = 0;
return -1; return -1;
} }
@ -411,19 +412,19 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
if (completed) { if (completed) {
/* Let APC be scheduled */ /* Let APC be scheduled */
debug2("recv - Letting APC to execute, io:%p", pio); debug4("recv - Letting APC to execute, io:%p", pio);
SleepEx(0, TRUE); SleepEx(0, TRUE);
if (pio->read_details.pending) { if (pio->read_details.pending) {
/* this shouldn't be happening */ /* this shouldn't be happening */
errno = EOTHER; errno = EOTHER;
debug("recv - ERROR: Unexpected IO state, io:%p", pio); debug3("recv - ERROR: Unexpected IO state, io:%p", pio);
return -1; return -1;
} }
} }
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
/* wait until io is done */ /* wait until io is done */
debug3("recv - socket in blocking mode, io:%p", pio); debug5("recv - socket in blocking mode, io:%p", pio);
while (socketio_is_io_available(pio, TRUE) == FALSE) { while (socketio_is_io_available(pio, TRUE) == FALSE) {
if (0 != wait_for_any_event(NULL, 0, INFINITE)) if (0 != wait_for_any_event(NULL, 0, INFINITE))
return -1; return -1;
@ -431,7 +432,7 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
} else { } else {
if (socketio_is_io_available(pio, TRUE) == FALSE) { if (socketio_is_io_available(pio, TRUE) == FALSE) {
errno = EAGAIN; errno = EAGAIN;
debug2("recv - IO is pending, io:%p", pio); debug4("recv - IO is pending, io:%p", pio);
return -1; return -1;
} }
} }
@ -443,12 +444,12 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
if (pio->read_details.error) { if (pio->read_details.error) {
if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) { if (pio->read_details.error == ERROR_GRACEFUL_DISCONNECT) {
/* connection is closed */ /* connection is closed */
debug2("recv - connection closed(2), io:%p", pio); debug4("recv - connection closed(2), io:%p", pio);
return 0; return 0;
} else { } else {
errno = errno_from_WSAError(pio->read_details.error); errno = errno_from_WSAError(pio->read_details.error);
pio->read_details.error = 0; pio->read_details.error = 0;
debug("recv - from CB(2) ERROR:%d, io:%p", errno, pio); debug3("recv - from CB(2) ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -458,13 +459,13 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
memcpy(buf, pio->read_details.buf, num_bytes_copied); memcpy(buf, pio->read_details.buf, num_bytes_copied);
pio->read_details.remaining -= num_bytes_copied; pio->read_details.remaining -= num_bytes_copied;
pio->read_details.completed = num_bytes_copied; pio->read_details.completed = num_bytes_copied;
debug2("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p", debug4("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p",
num_bytes_copied, pio->read_details.remaining, pio); num_bytes_copied, pio->read_details.remaining, pio);
return num_bytes_copied; return num_bytes_copied;
} else { } else {
/* this should not happen */ /* this should not happen */
errno = EOTHER; errno = EOTHER;
debug("recv - (2) ERROR:Unexpected IO state, io:%p", pio); debug3("recv - (2) ERROR:Unexpected IO state, io:%p", pio);
return -1; return -1;
} }
} }
@ -476,13 +477,13 @@ CALLBACK WSASendCompletionRoutine(IN DWORD dwError,
IN DWORD dwFlags) IN DWORD dwFlags)
{ {
struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped)); struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
debug2("WSASendCB - io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d", debug4("WSASendCB - io:%p, pending_state:%d, error:%d, sent:%d of remaining:%d",
pio, pio->write_details.pending, dwError, cbTransferred, pio, pio->write_details.pending, dwError, cbTransferred,
pio->write_details.remaining); pio->write_details.remaining);
pio->write_details.error = dwError; pio->write_details.error = dwError;
/* TODO - assert that remaining == cbTransferred */ /* TODO - assert that remaining == cbTransferred */
if ((dwError == 0) && (pio->write_details.remaining != cbTransferred)) { if ((dwError == 0) && (pio->write_details.remaining != cbTransferred)) {
debug("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio, debug3("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio,
cbTransferred, pio->write_details.remaining); cbTransferred, pio->write_details.remaining);
DebugBreak(); DebugBreak();
} }
@ -497,16 +498,16 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
int ret = 0; int ret = 0;
WSABUF wsabuf; WSABUF wsabuf;
debug2("send - io:%p", pio); debug4("send - io:%p", pio);
if ((buf == NULL) || (len == 0)) { if ((buf == NULL) || (len == 0)) {
errno = EINVAL; errno = EINVAL;
debug("send - ERROR invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio); debug3("send - ERROR invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio);
return -1; return -1;
} }
if (flags != 0) { if (flags != 0) {
errno = ENOTSUP; errno = ENOTSUP;
debug("send - ERROR: flags are not currently supported, io:%p", pio); debug3("send - ERROR: flags are not currently supported, io:%p", pio);
return -1; return -1;
} }
@ -514,20 +515,20 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
/* if io is already pending */ /* if io is already pending */
if (pio->write_details.pending) { if (pio->write_details.pending) {
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
debug2("send - io is pending, call is blocking, io:%p", pio); debug4("send - io is pending, call is blocking, io:%p", pio);
while (pio->write_details.pending) while (pio->write_details.pending)
if (wait_for_any_event(NULL, 0, INFINITE) == -1) if (wait_for_any_event(NULL, 0, INFINITE) == -1)
return -1; return -1;
} else { } else {
errno = EAGAIN; errno = EAGAIN;
debug2("send - IO currently pending, EAGAIN, io:%p", pio); debug4("send - IO currently pending, EAGAIN, io:%p", pio);
return -1; return -1;
} }
} }
if (pio->write_details.error) { if (pio->write_details.error) {
errno = errno_from_WSAError(pio->write_details.error); errno = errno_from_WSAError(pio->write_details.error);
debug("ERROR:%d, io:%p", errno, pio); debug3("ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -537,7 +538,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
wsabuf.buf = malloc(wsabuf.len); wsabuf.buf = malloc(wsabuf.len);
if (!wsabuf.buf) { if (!wsabuf.buf) {
errno = ENOMEM; errno = ENOMEM;
debug("send - ERROR:%d, io:%p", errno, pio); debug3("send - ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -554,13 +555,13 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
if (ret == 0) { if (ret == 0) {
/* send has completed and APC is scheduled, let it run */ /* send has completed and APC is scheduled, let it run */
debug2("send - WSASend() returned 0, APC scheduled io:%p", pio); debug4("send - WSASend() returned 0, APC scheduled io:%p", pio);
pio->write_details.pending = TRUE; pio->write_details.pending = TRUE;
pio->write_details.remaining = wsabuf.len; pio->write_details.remaining = wsabuf.len;
SleepEx(0, TRUE); SleepEx(0, TRUE);
if ((pio->write_details.pending) || (pio->write_details.remaining != 0)) { if ((pio->write_details.pending) || (pio->write_details.remaining != 0)) {
errno = EOTHER; errno = EOTHER;
debug("send - ERROR: Unexpected IO state, io:%p", pio); debug3("send - ERROR: Unexpected IO state, io:%p", pio);
return -1; return -1;
} }
@ -569,12 +570,12 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
} else { } else {
if (WSAGetLastError() == WSA_IO_PENDING) { if (WSAGetLastError() == WSA_IO_PENDING) {
/* io is initiated and pending */ /* io is initiated and pending */
debug2("send - WSASend reported IO pending, io:%p", pio); debug4("send - WSASend reported IO pending, io:%p", pio);
pio->write_details.pending = TRUE; pio->write_details.pending = TRUE;
pio->write_details.remaining = wsabuf.len; pio->write_details.remaining = wsabuf.len;
if (w32_io_is_blocking(pio)) { if (w32_io_is_blocking(pio)) {
/* wait until io is done */ /* wait until io is done */
debug3("send - waiting as socket is in blocking mode, io:%p", pio); debug5("send - waiting as socket is in blocking mode, io:%p", pio);
while (pio->write_details.pending) while (pio->write_details.pending)
if (wait_for_any_event(NULL, 0, INFINITE) == -1) { if (wait_for_any_event(NULL, 0, INFINITE) == -1) {
/* if interrupted but send has completed, we are good*/ /* if interrupted but send has completed, we are good*/
@ -584,11 +585,11 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
} }
} }
debug3("send - returning %d, io:%p", wsabuf.len, pio); debug5("send - returning %d, io:%p", wsabuf.len, pio);
return wsabuf.len; return wsabuf.len;
} else { } else {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("send - WSASend() ERROR:%d, io:%p", errno, pio); debug3("send - WSASend() ERROR:%d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -605,13 +606,13 @@ socketio_shutdown(struct w32_io* pio, int how)
int int
socketio_close(struct w32_io* pio) socketio_close(struct w32_io* pio)
{ {
debug2("close - io:%p", pio); debug4("close - io:%p", pio);
closesocket(pio->sock); closesocket(pio->sock);
/* wait for pending io to abort */ /* wait for pending io to abort */
SleepEx(0, TRUE); SleepEx(0, TRUE);
if (((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) && if (((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) &&
(pio->read_details.pending || pio->write_details.pending)) { (pio->read_details.pending || pio->write_details.pending)) {
debug2("close - IO is still pending on closed socket. read:%d, write:%d, io:%p", debug4("close - IO is still pending on closed socket. read:%d, write:%d, io:%p",
pio->read_details.pending, pio->write_details.pending, pio); pio->read_details.pending, pio->write_details.pending, pio);
DebugBreak(); DebugBreak();
} }
@ -649,7 +650,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
struct sockaddr *local_address, *remote_address; struct sockaddr *local_address, *remote_address;
int local_address_len, remote_address_len; int local_address_len, remote_address_len;
debug3("accept - io:%p", pio); debug5("accept - io:%p", pio);
/* start io if not already started */ /* start io if not already started */
if (pio->read_details.pending == FALSE) { if (pio->read_details.pending == FALSE) {
if (socketio_acceptEx(pio) != 0) if (socketio_acceptEx(pio) != 0)
@ -666,7 +667,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
/* if i/o is not ready */ /* if i/o is not ready */
if (FALSE == socketio_is_io_available(pio, TRUE)) { if (FALSE == socketio_is_io_available(pio, TRUE)) {
errno = EAGAIN; errno = EAGAIN;
debug2("accept is pending, io:%p", pio); debug4("accept is pending, io:%p", pio);
return NULL; return NULL;
} }
} }
@ -677,21 +678,21 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
if (pio->read_details.error) { if (pio->read_details.error) {
errno = errno_from_WSAError(pio->read_details.error); errno = errno_from_WSAError(pio->read_details.error);
debug("accept - ERROR: async io completed with error: %d, io:%p", errno, pio); debug3("accept - ERROR: async io completed with error: %d, io:%p", errno, pio);
goto on_error; goto on_error;
} }
if (0 != setsockopt(context->accept_socket, SOL_SOCKET, if (0 != setsockopt(context->accept_socket, SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) { SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("accept - ERROR: setsockopt failed:%d, io:%p", errno, pio); debug3("accept - ERROR: setsockopt failed:%d, io:%p", errno, pio);
goto on_error; goto on_error;
} }
accept_io = (struct w32_io*)malloc(sizeof(struct w32_io)); accept_io = (struct w32_io*)malloc(sizeof(struct w32_io));
if (!accept_io) { if (!accept_io) {
errno = ENOMEM; errno = ENOMEM;
debug("accept - ERROR:%d, io:%p", errno, pio); debug3("accept - ERROR:%d, io:%p", errno, pio);
goto on_error; goto on_error;
} }
memset(accept_io, 0, sizeof(struct w32_io)); memset(accept_io, 0, sizeof(struct w32_io));
@ -699,7 +700,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
accept_io->sock = context->accept_socket; accept_io->sock = context->accept_socket;
accept_io->internal.state = SOCK_ACCEPTED; accept_io->internal.state = SOCK_ACCEPTED;
context->accept_socket = INVALID_SOCKET; context->accept_socket = INVALID_SOCKET;
debug2("accept io:%p", accept_io); debug4("accept io:%p", accept_io);
if ((addr != NULL) && (addrlen != NULL)) { if ((addr != NULL) && (addrlen != NULL)) {
context->lpfnGuidGetAcceptExSockaddrs(context->lpOutputBuf, 0, context->lpfnGuidGetAcceptExSockaddrs(context->lpOutputBuf, 0,
@ -735,7 +736,7 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen)
GUID connectex_guid = WSAID_CONNECTEX; GUID connectex_guid = WSAID_CONNECTEX;
LPFN_CONNECTEX ConnectEx; LPFN_CONNECTEX ConnectEx;
debug3("connectex - io:%p", pio); debug5("connectex - io:%p", pio);
if (name->sa_family == AF_INET6) { if (name->sa_family == AF_INET6) {
ZeroMemory(&tmp_addr6, sizeof(tmp_addr6)); ZeroMemory(&tmp_addr6, sizeof(tmp_addr6));
tmp_addr6.sin6_family = AF_INET6; tmp_addr6.sin6_family = AF_INET6;
@ -750,13 +751,13 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen)
tmp_addr_len = sizeof(tmp_addr4); tmp_addr_len = sizeof(tmp_addr4);
} else { } else {
errno = ENOTSUP; errno = ENOTSUP;
debug("connectex - ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio); debug3("connectex - ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio);
return -1; return -1;
} }
if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) { if (SOCKET_ERROR == bind(pio->sock, tmp_addr, (int)tmp_addr_len)) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("connectex - ERROR: bind failed :%d, io:%p", WSAGetLastError(), pio); debug3("connectex - ERROR: bind failed :%d, io:%p", WSAGetLastError(), pio);
return -1; return -1;
} }
@ -765,14 +766,14 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen)
&ConnectEx, sizeof(ConnectEx), &ConnectEx, sizeof(ConnectEx),
&tmp_bytes, NULL, NULL)) { &tmp_bytes, NULL, NULL)) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("connectex - ioctl ERROR:%d, io:%p", WSAGetLastError(), pio); debug3("connectex - ioctl ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1; return -1;
} }
if ((!pio->write_overlapped.hEvent) if ((!pio->write_overlapped.hEvent)
&& ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) { && ((pio->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)) {
errno = ENOMEM; errno = ENOMEM;
debug("connectex - ERROR CreateEvent failed:%d, io:%p", errno, pio); debug3("connectex - ERROR CreateEvent failed:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -786,7 +787,7 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen)
CloseHandle(pio->write_overlapped.hEvent); CloseHandle(pio->write_overlapped.hEvent);
pio->write_overlapped.hEvent = 0; pio->write_overlapped.hEvent = 0;
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("connectex - ERROR ConnectEx() :%d, io:%p", errno, pio); debug3("connectex - ERROR ConnectEx() :%d, io:%p", errno, pio);
return -1; return -1;
} }
} }
@ -801,7 +802,7 @@ int
socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen) socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen)
{ {
debug3("connect - io:%p", pio); debug5("connect - io:%p", pio);
if (pio->write_details.pending == FALSE) { if (pio->write_details.pending == FALSE) {
if (-1 == socketio_connectex(pio, name, namelen)) if (-1 == socketio_connectex(pio, name, namelen))
return -1; return -1;
@ -817,7 +818,7 @@ socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen)
/* if i/o is not ready */ /* if i/o is not ready */
if (FALSE == socketio_is_io_available(pio, TRUE)) { if (FALSE == socketio_is_io_available(pio, TRUE)) {
errno = EINPROGRESS; errno = EINPROGRESS;
debug2("connect - in progress, io:%p", pio); debug4("connect - in progress, io:%p", pio);
return -1; return -1;
} }
} }
@ -828,16 +829,16 @@ socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen)
int int
socketio_finish_connect(struct w32_io* pio) socketio_finish_connect(struct w32_io* pio)
{ {
debug3("finish_connect, io:%p", pio); debug5("finish_connect, io:%p", pio);
if (pio->write_details.error) { if (pio->write_details.error) {
errno = errno_from_WSAError(pio->write_details.error); errno = errno_from_WSAError(pio->write_details.error);
debug("finish_connect - ERROR: async io completed with error: %d, io:%p", errno, pio); debug3("finish_connect - ERROR: async io completed with error: %d, io:%p", errno, pio);
return -1; return -1;
} }
if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) { if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) {
errno = errno_from_WSALastError(); errno = errno_from_WSALastError();
debug("finish_connect - ERROR: setsockopt failed:%d, io:%p", errno, pio); debug3("finish_connect - ERROR: setsockopt failed:%d, io:%p", errno, pio);
return -1; return -1;
} }
@ -896,7 +897,7 @@ void
socketio_on_select(struct w32_io* pio, BOOL rd) socketio_on_select(struct w32_io* pio, BOOL rd)
{ {
enum w32_io_sock_state sock_state = pio->internal.state; enum w32_io_sock_state sock_state = pio->internal.state;
debug2("on_select - io:%p type:%d rd:%d", pio, pio->type, rd); debug4("on_select - io:%p type:%d rd:%d", pio, pio->type, rd);
/* nothing to do for writes (that includes connect) */ /* nothing to do for writes (that includes connect) */
if (!rd) if (!rd)

View File

@ -63,6 +63,12 @@ mm_is_monitor(void) {
return 0; return 0;
} }
int
mm_user_key_allowed(struct passwd *pw, Key *k, int i)
{
return 0;
}
int kexgex_server(struct ssh * sh) { int kexgex_server(struct ssh * sh) {
return -1; return -1;
} }

View File

@ -39,6 +39,7 @@
#include "w32fd.h" #include "w32fd.h"
#include "tncon.h" #include "tncon.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "debug.h"
#include "tnnet.h" #include "tnnet.h"
#define TERM_IO_BUF_SIZE 2048 #define TERM_IO_BUF_SIZE 2048
@ -57,7 +58,7 @@ static VOID CALLBACK
ReadAPCProc(_In_ ULONG_PTR dwParam) ReadAPCProc(_In_ ULONG_PTR dwParam)
{ {
struct w32_io* pio = (struct w32_io*)dwParam; struct w32_io* pio = (struct w32_io*)dwParam;
debug3("TermRead CB - io:%p, bytes: %d, pending: %d, error: %d", pio, read_status.transferred, debug5("TermRead CB - io:%p, bytes: %d, pending: %d, error: %d", pio, read_status.transferred,
pio->read_details.pending, read_status.error); pio->read_details.pending, read_status.error);
pio->read_details.error = read_status.error; pio->read_details.error = read_status.error;
pio->read_details.remaining = read_status.transferred; pio->read_details.remaining = read_status.transferred;
@ -75,7 +76,7 @@ ReadConsoleThread(_In_ LPVOID lpParameter)
int nBytesReturned = 0; int nBytesReturned = 0;
struct w32_io* pio = (struct w32_io*)lpParameter; struct w32_io* pio = (struct w32_io*)lpParameter;
debug3("TermRead thread, io:%p", pio); debug5("TermRead thread, io:%p", pio);
memset(&read_status, 0, sizeof(read_status)); memset(&read_status, 0, sizeof(read_status));
while (nBytesReturned == 0) { while (nBytesReturned == 0) {
nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio), nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio),
@ -83,7 +84,7 @@ ReadConsoleThread(_In_ LPVOID lpParameter)
} }
read_status.transferred = nBytesReturned; read_status.transferred = nBytesReturned;
if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) { if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) {
debug("TermRead thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio); debug3("TermRead thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
pio->read_details.pending = FALSE; pio->read_details.pending = FALSE;
pio->read_details.error = GetLastError(); pio->read_details.error = GetLastError();
DebugBreak(); DebugBreak();
@ -98,7 +99,7 @@ termio_initiate_read(struct w32_io* pio)
{ {
HANDLE read_thread; HANDLE read_thread;
debug3("TermRead initiate io:%p", pio); debug5("TermRead initiate io:%p", pio);
if (pio->read_details.buf_size == 0) { if (pio->read_details.buf_size == 0) {
pio->read_details.buf = malloc(TERM_IO_BUF_SIZE); pio->read_details.buf = malloc(TERM_IO_BUF_SIZE);
if (pio->read_details.buf == NULL) { if (pio->read_details.buf == NULL) {
@ -111,7 +112,7 @@ termio_initiate_read(struct w32_io* pio)
read_thread = CreateThread(NULL, 0, ReadConsoleThread, pio, 0, NULL); read_thread = CreateThread(NULL, 0, ReadConsoleThread, pio, 0, NULL);
if (read_thread == NULL) { if (read_thread == NULL) {
errno = errno_from_Win32Error(GetLastError()); errno = errno_from_Win32Error(GetLastError());
debug("TermRead initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio); debug3("TermRead initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
return -1; return -1;
} }
@ -125,7 +126,7 @@ static VOID CALLBACK
WriteAPCProc(_In_ ULONG_PTR dwParam) WriteAPCProc(_In_ ULONG_PTR dwParam)
{ {
struct w32_io* pio = (struct w32_io*)dwParam; struct w32_io* pio = (struct w32_io*)dwParam;
debug3("TermWrite CB - io:%p, bytes: %d, pending: %d, error: %d", pio, write_status.transferred, debug5("TermWrite CB - io:%p, bytes: %d, pending: %d, error: %d", pio, write_status.transferred,
pio->write_details.pending, write_status.error); pio->write_details.pending, write_status.error);
pio->write_details.error = write_status.error; pio->write_details.error = write_status.error;
pio->write_details.remaining -= write_status.transferred; pio->write_details.remaining -= write_status.transferred;
@ -146,8 +147,8 @@ WriteThread(_In_ LPVOID lpParameter)
char *respbuf = NULL; char *respbuf = NULL;
size_t resplen = 0; size_t resplen = 0;
DWORD dwSavedAttributes = ENABLE_PROCESSED_INPUT; DWORD dwSavedAttributes = ENABLE_PROCESSED_INPUT;
debug3("TermWrite thread, io:%p", pio); debug5("TermWrite thread, io:%p", pio);
pio->write_details.buf[write_status.to_transfer] = '\0'; pio->write_details.buf[write_status.to_transfer] = '\0';
if (0 == in_raw_mode) { if (0 == in_raw_mode) {
@ -162,7 +163,7 @@ WriteThread(_In_ LPVOID lpParameter)
write_status.transferred = write_status.to_transfer; write_status.transferred = write_status.to_transfer;
if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) { if (0 == QueueUserAPC(WriteAPCProc, main_thread, (ULONG_PTR)pio)) {
debug("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio); debug3("TermWrite thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
pio->write_details.pending = FALSE; pio->write_details.pending = FALSE;
pio->write_details.error = GetLastError(); pio->write_details.error = GetLastError();
DebugBreak(); DebugBreak();
@ -176,13 +177,13 @@ int
termio_initiate_write(struct w32_io* pio, DWORD num_bytes) termio_initiate_write(struct w32_io* pio, DWORD num_bytes)
{ {
HANDLE write_thread; HANDLE write_thread;
debug3("TermWrite initiate io:%p", pio); debug5("TermWrite initiate io:%p", pio);
memset(&write_status, 0, sizeof(write_status)); memset(&write_status, 0, sizeof(write_status));
write_status.to_transfer = num_bytes; write_status.to_transfer = num_bytes;
write_thread = CreateThread(NULL, 0, WriteThread, pio, 0, NULL); write_thread = CreateThread(NULL, 0, WriteThread, pio, 0, NULL);
if (write_thread == NULL) { if (write_thread == NULL) {
errno = errno_from_Win32Error(GetLastError()); errno = errno_from_Win32Error(GetLastError());
debug("TermWrite initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio); debug3("TermWrite initiate - ERROR CreateThread %d, io:%p", GetLastError(), pio);
return -1; return -1;
} }
@ -195,7 +196,7 @@ termio_initiate_write(struct w32_io* pio, DWORD num_bytes)
int int
termio_close(struct w32_io* pio) termio_close(struct w32_io* pio)
{ {
debug2("termio_close - pio:%p", pio); debug4("termio_close - pio:%p", pio);
HANDLE h; HANDLE h;
CancelIoEx(WINHANDLE(pio), NULL); CancelIoEx(WINHANDLE(pio), NULL);
/* If io is pending, let write worker threads exit. The read thread is blocked so terminate it.*/ /* If io is pending, let write worker threads exit. The read thread is blocked so terminate it.*/

View File

@ -48,6 +48,7 @@
#include "Shlwapi.h" #include "Shlwapi.h"
#include <sys\utime.h> #include <sys\utime.h>
#include "misc_internal.h" #include "misc_internal.h"
#include "debug.h"
/* internal table that stores the fd to w32_io mapping*/ /* internal table that stores the fd to w32_io mapping*/
struct w32fd_table { struct w32fd_table {
@ -99,7 +100,7 @@ fd_table_get_min_index()
min_index += 8; min_index += 8;
if (min_index >= MAX_FDS) { if (min_index >= MAX_FDS) {
errno = EMFILE; errno = EMFILE;
debug("ERROR: MAX_FDS limit reached"); debug3("ERROR: MAX_FDS limit reached");
return -1; return -1;
} }
} }
@ -180,11 +181,10 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
} }
#define CHECK_FD(fd) do { \ #define CHECK_FD(fd) do { \
debug3("%s fd:%d", __FUNCTION__, fd); \
errno = 0; \ errno = 0; \
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { \ if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { \
errno = EBADF; \ errno = EBADF; \
debug("%s ERROR: bad fd: %d", __FUNCTION__, fd); \ debug3("%s ERROR: bad fd: %d", __FUNCTION__, fd); \
return -1; \ return -1; \
} \ } \
} while (0) } while (0)
@ -193,7 +193,7 @@ w32_io_on_select(struct w32_io* pio, BOOL rd)
errno = 0; \ errno = 0; \
if (pio->type != SOCK_FD) { \ if (pio->type != SOCK_FD) { \
errno = ENOTSOCK; \ errno = ENOTSOCK; \
debug("%s ERROR: not sock :%d", __FUNCTION__, pio->type); \ debug3("%s ERROR: not sock :%d", __FUNCTION__, pio->type); \
return -1; \ return -1; \
} \ } \
} while (0) } while (0)
@ -221,7 +221,7 @@ w32_socket(int domain, int type, int protocol)
} }
fd_table_set(pio, min_index); fd_table_set(pio, min_index);
debug("socket:%d, socktype:%d, io:%p, fd:%d ", pio->sock, type, pio, min_index); debug3("socket:%d, socktype:%d, io:%p, fd:%d ", pio->sock, type, pio, min_index);
return min_index; return min_index;
} }
@ -242,7 +242,7 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
pio->type = SOCK_FD; pio->type = SOCK_FD;
fd_table_set(pio, min_index); fd_table_set(pio, min_index);
debug("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index); debug3("socket:%d, io:%p, fd:%d ", pio->sock, pio, min_index);
return min_index; return min_index;
} }
@ -329,7 +329,7 @@ w32_send(int fd, const void *buf, size_t len, int flags)
int int
w32_shutdown(int fd, int how) w32_shutdown(int fd, int how)
{ {
debug2("shutdown - fd:%d how:%d", fd, how); debug4("shutdown - fd:%d how:%d", fd, how);
CHECK_FD(fd); CHECK_FD(fd);
CHECK_SOCK_IO(fd_table.w32_ios[fd]); CHECK_SOCK_IO(fd_table.w32_ios[fd]);
return socketio_shutdown(fd_table.w32_ios[fd], how); return socketio_shutdown(fd_table.w32_ios[fd], how);
@ -339,7 +339,7 @@ int
w32_socketpair(int domain, int type, int protocol, int sv[2]) w32_socketpair(int domain, int type, int protocol, int sv[2])
{ {
errno = ENOTSUP; errno = ENOTSUP;
debug("socketpair - ERROR not supported"); debug3("socketpair - ERROR not supported");
return -1; return -1;
} }
@ -371,7 +371,7 @@ w32_pipe(int *pfds)
fd_table_set(pio[1], write_index); fd_table_set(pio[1], write_index);
pfds[0] = read_index; pfds[0] = read_index;
pfds[1] = write_index; pfds[1] = write_index;
debug("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d", debug3("pipe - r-h:%d,io:%p,fd:%d w-h:%d,io:%p,fd:%d",
pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index); pio[0]->handle, pio[0], read_index, pio[1]->handle, pio[1], write_index);
return 0; return 0;
@ -393,8 +393,8 @@ w32_open(const char *pathname, int flags, ...)
pio->type = NONSOCK_FD; pio->type = NONSOCK_FD;
fd_table_set(pio, min_index); fd_table_set(pio, min_index);
debug("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index); debug3("open - handle:%p, io:%p, fd:%d", pio->handle, pio, min_index);
debug3("open - path:%s", pathname); debug5("open - path:%s", pathname);
return min_index; return min_index;
} }
@ -473,7 +473,7 @@ w32_fdopen(int fd, const char *mode)
errno = 0; errno = 0;
if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) { if ((fd < 0) || (fd > MAX_FDS - 1) || fd_table.w32_ios[fd] == NULL) {
errno = EBADF; errno = EBADF;
debug("fdopen - ERROR bad fd: %d", fd); debug3("fdopen - ERROR bad fd: %d", fd);
return NULL; return NULL;
} }
return fileio_fdopen(fd_table.w32_ios[fd], mode); return fileio_fdopen(fd_table.w32_ios[fd], mode);
@ -490,7 +490,7 @@ w32_close(int fd)
pio = fd_table.w32_ios[fd]; pio = fd_table.w32_ios[fd];
debug("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd, debug3("close - io:%p, type:%d, fd:%d, table_index:%d", pio, pio->type, fd,
pio->table_index); pio->table_index);
fd_table_clear(pio->table_index); fd_table_clear(pio->table_index);
@ -510,7 +510,7 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags)
{ {
DWORD shi_flags; DWORD shi_flags;
if (flags & ~FD_CLOEXEC) { if (flags & ~FD_CLOEXEC) {
debug("fcntl - ERROR unsupported flags %d, io:%p", flags, pio); debug3("fcntl - ERROR unsupported flags %d, io:%p", flags, pio);
errno = ENOTSUP; errno = ENOTSUP;
return -1; return -1;
} }
@ -523,7 +523,7 @@ w32_io_process_fd_flags(struct w32_io* pio, int flags)
* UF_UNIX sockets that are not connected yet * UF_UNIX sockets that are not connected yet
*/ */
if (GetLastError() != ERROR_INVALID_HANDLE) { if (GetLastError() != ERROR_INVALID_HANDLE) {
debug("fcntl - SetHandleInformation failed %d, io:%p", debug3("fcntl - SetHandleInformation failed %d, io:%p",
GetLastError(), pio); GetLastError(), pio);
errno = EOTHER; errno = EOTHER;
return -1; return -1;
@ -559,7 +559,7 @@ w32_fcntl(int fd, int cmd, ... /* arg */)
break; break;
default: default:
errno = EINVAL; errno = EINVAL;
debug("fcntl - ERROR not supported cmd:%d", cmd); debug3("fcntl - ERROR not supported cmd:%d", cmd);
ret = -1; ret = -1;
break; break;
} }
@ -589,20 +589,20 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if (fds > MAX_FDS) { if (fds > MAX_FDS) {
errno = EINVAL; errno = EINVAL;
debug("select - ERROR: invalid fds: %d", fds); debug3("select - ERROR: invalid fds: %d", fds);
return -1; return -1;
} }
if (!readfds && !writefds) { if (!readfds && !writefds) {
errno = EINVAL; errno = EINVAL;
debug("select - ERROR: null fd_sets"); debug3("select - ERROR: null fd_sets");
return -1; return -1;
} }
/* TODO - see if this needs to be supported */ /* TODO - see if this needs to be supported */
/* if (exceptfds) { /* if (exceptfds) {
errno = EOPNOTSUPP; errno = EOPNOTSUPP;
debug("select - ERROR: exceptfds not supported"); debug3("select - ERROR: exceptfds not supported");
DebugBreak(); DebugBreak();
return -1; return -1;
} */ } */
@ -626,11 +626,11 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
/* if none of input fds are set return error */ /* if none of input fds are set return error */
if (in_set_fds == 0) { if (in_set_fds == 0) {
errno = EINVAL; errno = EINVAL;
debug("select - ERROR: empty fd_sets"); debug3("select - ERROR: empty fd_sets");
return -1; return -1;
} }
debug3("Total in fds:%d", in_set_fds); debug5("Total in fds:%d", in_set_fds);
/* /*
* start async io on selected fds if needed and pick up any events * start async io on selected fds if needed and pick up any events
* that select needs to listen on * that select needs to listen on
@ -641,7 +641,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if ((fd_table.w32_ios[i]->type == SOCK_FD) && if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
(fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) { (fd_table.w32_ios[i]->internal.state == SOCK_LISTENING)) {
if (num_events == SELECT_EVENT_LIMIT) { if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events breach"); debug3("select - ERROR: max #events breach");
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
@ -654,7 +654,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if ((fd_table.w32_ios[i]->type == SOCK_FD) && if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
(fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) { (fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)) {
if (num_events == SELECT_EVENT_LIMIT) { if (num_events == SELECT_EVENT_LIMIT) {
debug("select - ERROR: max #events reached for select"); debug3("select - ERROR: max #events reached for select");
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
@ -695,7 +695,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
if (timeout != NULL) { if (timeout != NULL) {
if (timeout_ms < ticks_spent) { if (timeout_ms < ticks_spent) {
debug("select - timing out"); debug3("select - timing out");
break; break;
} }
time_rem = timeout_ms - (ticks_spent & 0xffffffff); time_rem = timeout_ms - (ticks_spent & 0xffffffff);
@ -725,7 +725,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
} }
if (out_ready_fds == 0) if (out_ready_fds == 0)
debug3("select - wait ended without any IO completion, looping again"); debug5("select - wait ended without any IO completion, looping again");
} }
/* clear out fds that are not ready yet */ /* clear out fds that are not ready yet */
@ -754,7 +754,7 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
FD_CLR(i, writefds); FD_CLR(i, writefds);
} }
debug3("select - returning %d", out_ready_fds); debug5("select - returning %d", out_ready_fds);
return out_ready_fds; return out_ready_fds;
} }
@ -768,7 +768,7 @@ w32_dup(int oldfd)
CHECK_FD(oldfd); CHECK_FD(oldfd);
if (oldfd > STDERR_FILENO) { if (oldfd > STDERR_FILENO) {
errno = EOPNOTSUPP; errno = EOPNOTSUPP;
debug("dup - ERROR: supports only std io, fd:%d", oldfd); debug3("dup - ERROR: supports only std io, fd:%d", oldfd);
return -1; return -1;
} }
@ -778,13 +778,13 @@ w32_dup(int oldfd)
src = GetStdHandle(fd_table.w32_ios[oldfd]->std_handle); src = GetStdHandle(fd_table.w32_ios[oldfd]->std_handle);
if (src == INVALID_HANDLE_VALUE) { if (src == INVALID_HANDLE_VALUE) {
errno = EINVAL; errno = EINVAL;
debug("dup - ERROR: unable to get underlying handle for std fd:%d", oldfd); debug3("dup - ERROR: unable to get underlying handle for std fd:%d", oldfd);
return -1; return -1;
} }
if (!DuplicateHandle(GetCurrentProcess(), src, GetCurrentProcess(), &target, 0, TRUE, DUPLICATE_SAME_ACCESS)) { if (!DuplicateHandle(GetCurrentProcess(), src, GetCurrentProcess(), &target, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
errno = EOTHER; errno = EOTHER;
debug("dup - ERROR: DuplicatedHandle() :%d", GetLastError()); debug3("dup - ERROR: DuplicatedHandle() :%d", GetLastError());
return -1; return -1;
} }
@ -792,7 +792,7 @@ w32_dup(int oldfd)
if (pio == NULL) { if (pio == NULL) {
CloseHandle(target); CloseHandle(target);
errno = ENOMEM; errno = ENOMEM;
debug("dup - ERROR: %d", errno); debug3("dup - ERROR: %d", errno);
return -1; return -1;
} }
@ -808,7 +808,7 @@ w32_dup2(int oldfd, int newfd)
{ {
CHECK_FD(oldfd); CHECK_FD(oldfd);
errno = EOPNOTSUPP; errno = EOPNOTSUPP;
debug("dup2 - ERROR: not implemented yet"); debug3("dup2 - ERROR: not implemented yet");
return -1; return -1;
} }

View File

@ -0,0 +1,58 @@
/*
* Windows version of sshpty* routines in sshpty.c
*/
#include <Windows.h>
#include "..\..\..\sshpty.h"
/*
* Windows versions of pty_*. Some of them are NO-OPs and should go
* away when pty logic is refactored and abstracted out
*
*/
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
/*
* Simple console screen implementation in Win32 to give a
* Unix like pty for interactive sessions
*/
*ttyfd = 0;
*ptyfd = 0;
strlcpy(namebuf, "console", namebuflen);
return 1;
}
void
pty_release(const char *tty) {
/* NO-OP */
}
void
pty_make_controlling_tty(int *ttyfd, const char *tty) {
/* NO-OP */
}
void
pty_change_window_size(int ptyfd, u_int row, u_int col,
u_int xpixel, u_int ypixel) {
COORD coord;
coord.X = col;
coord.Y = 9999;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void
pty_setowner(struct passwd *pw, const char *tty) {
/* NO-OP */
}
void
disconnect_controlling_tty(void) {
/* NO-OP */
}

View File

@ -0,0 +1,40 @@
/*
* Windows version of sshtty* routines implemented in sshtty.c
*/
#include <Windows.h>
#include "..\..\..\sshpty.h"
static struct termios _saved_tio;
static int _in_raw_mode = 0;
/*
* TTY raw mode routines for Windows
*/
int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
int ConExitRawMode(void);
struct termios term_settings;
/*
* TODO - clean this up for Windows, ConInit should return previous terminal
* settings that need to be stored in term_settings
*/
struct termios *
get_saved_tio(void) {
memset(&term_settings, 0, sizeof(term_settings));
return &term_settings;
}
void
leave_raw_mode(int quiet) {
ConExitRawMode();
}
void
enter_raw_mode(int quiet) {
ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE);
}

View File

@ -53,21 +53,21 @@ int
ga_init(const char *user, gid_t base) ga_init(const char *user, gid_t base)
{ {
#ifdef WINDOWS #ifdef WINDOWS
DWORD i = 0, j = 0;
LPLOCALGROUP_USERS_INFO_0 local_groups_info = NULL, tmp_groups_info; LPLOCALGROUP_USERS_INFO_0 local_groups_info = NULL, tmp_groups_info;
wchar_t *user_utf16 = NULL, *full_name_utf16 = NULL, *udom_utf16 = NULL, *tmp; wchar_t *user_utf16 = NULL, *full_name_utf16 = NULL, *udom_utf16 = NULL, *tmp;
char *group_utf8 = NULL; char *group_utf8 = NULL;
DWORD i = 0, j = 0;
DWORD entries_read = 0, total_entries = 0, full_name_len = 0, index = 0; DWORD entries_read = 0, total_entries = 0, full_name_len = 0, index = 0;
NET_API_STATUS nStatus; NET_API_STATUS nStatus;
if (ngroups > 0) if (ngroups > 0)
ga_free(); ga_free();
user_utf16 = utf8_to_utf16(user);
if ((user_utf16 = utf8_to_utf16(user)) == NULL) { if ((user_utf16 = utf8_to_utf16(user)) == NULL) {
errno = ENOMEM; errno = ENOMEM;
goto done; goto done;
} }
full_name_len = wcslen(user_utf16) + 1; full_name_len = wcslen(user_utf16) + 1;
if ((full_name_utf16 = malloc(full_name_len * sizeof(wchar_t))) == NULL) { if ((full_name_utf16 = malloc(full_name_len * sizeof(wchar_t))) == NULL) {
errno = ENOMEM; errno = ENOMEM;
@ -151,7 +151,6 @@ done:
free(groups_bygid); free(groups_bygid);
#endif /* !WINDOWS */ #endif /* !WINDOWS */
return (ngroups = j); return (ngroups = j);
} }
/* /*

8
log.c
View File

@ -455,15 +455,7 @@ do_log(LogLevel level, const char *fmt, va_list args)
} else if (log_on_stderr) { } else if (log_on_stderr) {
snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n", snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n",
(int)sizeof msgbuf - 3, fmtbuf); (int)sizeof msgbuf - 3, fmtbuf);
#ifdef WINDOWS
/*
* In Windows, write is implemented as part of POSIX compat layer
* that itself may "log" resulting in a infinite recursion loop
*/
_write(STDERR_FILENO, msgbuf, strlen(msgbuf));
#else /* !WINDOWS */
(void)write(log_stderr_fd, msgbuf, strlen(msgbuf)); (void)write(log_stderr_fd, msgbuf, strlen(msgbuf));
#endif /* !WINDOWS */
} else { } else {
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);

View File

@ -69,7 +69,7 @@ ssh_askpass(char *askpass, const char *msg)
#ifdef WINDOWS #ifdef WINDOWS
/* spawd child for Windows */ /* spawd child for Windows */
fcntl(p[0], F_SETFD, FD_CLOEXEC); fcntl(p[0], F_SETFD, FD_CLOEXEC);
pid = spawn_child(askpass, p[1], p[1], STDERR_FILENO, 0); pid = spawn_child(askpass, NULL, p[1], p[1], STDERR_FILENO, 0);
if (pid < 0) { if (pid < 0) {
#else /* !WINDOWS */ #else /* !WINDOWS */
if ((pid = fork()) < 0) { if ((pid = fork()) < 0) {
@ -125,71 +125,6 @@ ssh_askpass(char *askpass, const char *msg)
char * char *
read_passphrase(const char *prompt, int flags) read_passphrase(const char *prompt, int flags)
{ {
#ifdef WINDOWS
/* TODO - do flags apply on Windows? */
char *askpass = NULL;
char *ret = NULL;
char buf[1024] = { 0 };
DWORD mode;
size_t len = 0;
int retr = 0;
if (getenv(SSH_ASKPASS_ENV)) {
askpass = getenv(SSH_ASKPASS_ENV);
if ((ret = ssh_askpass(askpass, prompt)) == NULL)
return xstrdup("");
return ret;
}
/* prompt user */
wchar_t* wtmp = utf8_to_utf16(prompt);
if (wtmp == NULL)
fatal("unable to alloc memory");
_cputws(wtmp);
free(wtmp);
len = retr = 0;
int bufsize = sizeof(buf);
while (_kbhit())
_getch();
while (len < bufsize) {
buf[len] = (unsigned char)_getch();
if (buf[len] == '\r') {
if (_kbhit()) /* read linefeed if its there */
_getch();
break;
}
else if (buf[len] == '\n') {
break;
}
else if (buf[len] == '\b') { /* backspace */
if (len > 0)
len--; /* overwrite last character */
}
else if (buf[len] == '\003') {
/* exit on Ctrl+C */
fatal("");
}
else {
len++; /* keep reading in the loop */
}
}
buf[len] = '\0'; /* get rid of the cr/lf */
_cputs("\n"); /*show a newline as we do not echo password or the line */
ret = xstrdup(buf);
memset(buf, 'x', sizeof(buf));
return ret;
#else /* !WINDOWS */
char *askpass = NULL, *ret, buf[1024]; char *askpass = NULL, *ret, buf[1024];
int rppflags, use_askpass = 0, ttyfd; int rppflags, use_askpass = 0, ttyfd;
@ -236,7 +171,6 @@ read_passphrase(const char *prompt, int flags)
ret = xstrdup(buf); ret = xstrdup(buf);
explicit_bzero(buf, sizeof(buf)); explicit_bzero(buf, sizeof(buf));
return ret; return ret;
#endif /* !WINDOWS */
} }
int int

View File

@ -0,0 +1,385 @@

# test environment parametes initialized with defaults
$script:OpenSSHDir = "$env:SystemDrive\OpenSSH"
$script:OpenSSHTestDir = "$env:SystemDrive\OpenSSHTests"
$script:PesterTestResultsFile = Join-Path $script:OpenSSHTestDir "PesterTestResults.xml"
$script:UnitTestResultsFile = Join-Path $script:OpenSSHTestDir "UnitTestResults.txt"
$script:TestSetupLogFile = Join-Path $script:OpenSSHTestDir "TestSetupLog.txt"
function Set-OpenSSHTestParams
{
param
(
[string] $OpenSSHDir = $script:OpenSSHDir,
[string] $OpenSSHTestDir = $script:OpenSSHTestDir,
[string] $PesterTestResultsFile = $script:PesterTestResultsFile,
[string] $UnitTestResultsFile = $script:UnitTestResultsFile,
[string] $TestSetupLogFile = $script:TestSetupLogFile
)
$script:OpenSSHDir = $OpenSSHDir
$script:OpenSSHTestDir = $OpenSSHTestDir
$script:PesterTestResultsFile = $PesterTestResultsFile
$script:UnitTestResultsFile = $UnitTestResultsFile
$script:TestSetupLogFile = $TestSetupLogFile
}
function Dump-OpenSSHTestParams
{
Write-Host "OpenSSHDir: " $script:OpenSSHDir
Write-Host "OpenSSHTestDir: " $script:OpenSSHTestDir
Write-Host "PesterTestResultsFile: " $script:PesterTestResultsFile
Write-Host "UnitTestResultsFile: " $script:UnitTestResultsFile
Write-Host "TestSetupLogFile: " $script:TestSetupLogFile
}
<#
.SYNOPSIS
This function installs the tools required by our tests
1) Pester for running the tests
2) sysinternals required by the tests on windows.
#>
function Install-OpenSSHTestDependencies
{
[CmdletBinding()]
param ()
# Install chocolatey
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
{
Write-Log -Message "Chocolatey not present. Installing chocolatey."
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:TestSetupLogFile
}
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable))
{
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $script:TestSetupLogFile
}
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
Write-Log -Message "sysinternals not present. Installing sysinternals."
choco install sysinternals -y --force --limitoutput 2>&1 >> $script:TestSetupLogFile
}
<#if ( (-not (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\8.1\Debuggers\" )) -and (-not (Test-Path "${env:ProgramFiles(x86)}\Windows Kits\10\Debuggers\" ))) {
Write-Log -Message "debugger not present. Installing windbg."
choco install windbg --force --limitoutput -y 2>&1 >> $script:TestSetupLogFile
}
Install-PSCoreFromGithub
$psCorePath = GetLocalPSCorePath
Set-BuildVariable -Name psPath -Value $psCorePath
#>
Write-BuildMessage -Message "All testDependencies installed!" -Category Information
}
$testaccounts = "sshtest_ssouser", "sshtest_pubkeyuser", "sshtest_passwduser"
$testaccountPassword = "P@ssw0rd_1" | ConvertTo-SecureString -AsPlainText -Force
<#
.Synopsis
Setup-OpenSSHTestEnvironment
#>
function Setup-OpenSSHTestEnvironment
{
[CmdletBinding()]
param
(
[bool] $Quiet = $false
)
if ($Quiet -eq $false) {
Write-Host 'WARNING: Following changes will be made to OpenSSH configuration'
Write-Host ' - sshd_config will be backed up as sshd_config.ori'
Write-Host ' - will be replaced with a test sshd_config'
Write-Host ' - %user%\.ssh\known_hosts will be backed up as known_hosts.ori'
Write-Host ' - will be replaced with a test known_hosts'
Write-Host ' - sshd test listener will be on port 47002'
Write-Host ' - %userprofile%\.ssh\known_hosts will be modified with test host key entry'
Write-Host ' - test accounts - ssouser, pubkeyuser and passwduser will be added'
Write-Host 'To cleanup - Run Cleanup-OpenSSHTestEnvironment'
}
if (-not(Test-Path(Join-Path $OpenSSHDir ssh.exe)))
{
Throw 'cannot find OpenSSH binaries under ' + $OpenSSHDir + '. Try -OpenSSHDir parameter'
}
try
{
$sshcmd = get-command ssh.exe
}
catch [System.Exception]
{
Throw 'Cannot find ssh.exe. Make sure OpenSSH binary path is in %PATH%'
}
# TODO - ensure ssh.exe is being picked from $OpenSSHDir. Multiple versions may exist
if (-not(Test-Path($OpenSSHTestDir))) {
Throw $OpenSSHTestDir +' does not exist. Try setting -OpenSSHTestDir parameter'
}
if ((Get-ChildItem $OpenSSHTestDir).Count -eq 0) {
Throw 'Nothing found in ' + $OpenSSHTestDir
}
#Backup existing OpenSSH configuration
if (-not(Test-Path (Join-Path $OpenSSHDir sshd_config.ori))) {
Copy-Item (Join-Path $OpenSSHDir sshd_config) (Join-Path $OpenSSHDir sshd_config.ori)
}
# copy new sshd_config
Stop-Service sshd
Stop-Service ssh-agent
Copy-Item (Join-Path $OpenSSHTestDir sshd_config) (Join-Path $OpenSSHDir sshd_config)
Copy-Item $OpenSSHTestDir\sshtest*hostkey* $OpenSSHDir
Start-Service sshd
#Backup existing known_hosts and replace with test version
#TODO - account for custom known_hosts locations
if (Test-Path (Join-Path $home .ssh\known_hosts)) {
Copy-Item (Join-Path $home .ssh\known_hosts) (Join-Path $home .ssh\known_hosts.ori)
}
Copy-Item (Join-Path $OpenSSHTestDir known_hosts) (Join-Path $home .ssh\known_hosts)
# create test accounts
foreach ($user in $testaccounts) {
New-LocalUser -Name $user -Password $testaccountPassword -ErrorAction SilentlyContinue
}
#setup single sign on for ssouser
#TODO - this is Windows specific. Need to be in PAL
$ssouser = Get-LocalUser sshtest_ssouser
$ssouserProfileRegistry = Join-Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' $ssouser.SID
if (-not(Test-Path $ssouserProfileRegistry)) {
#create profile
if (-not($env:DISPLAY)) {$env:DISPLAY=1}
$env:SSH_ASKPASS="$($env:ComSpec) /c echo P@ssw0rd_1"
ssh -p 47002 sshtest_ssouser@localhost whoami
if ($env:DISPLAY -eq 1) {Remove-Item env:\DISPLAY}
remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
}
$ssouserProfile = (Get-ItemProperty -Path $ssouserProfileRegistry -Name 'ProfileImagePath').ProfileImagePath
mkdir -Path (Join-Path $ssouserProfile .ssh) -ErrorAction SilentlyContinue
Copy-Item (Join-Path $OpenSSHTestDir sshtest_userssokey_ed25519.pub) (Join-Path $ssouserProfile .ssh\authorized_keys)
$acl = get-acl (Join-Path $ssouserProfile .ssh\authorized_keys)
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule("NT Service\sshd", "Read", "Allow")
$acl.SetAccessRule($ar)
Set-Acl (Join-Path $ssouserProfile .ssh\authorized_keys) $acl
$ssouserpubkey = Join-Path $OpenSSHTestDir sshtest_userssokey_ed25519
ssh-add $ssouserpubkey
#TODO - scp tests need an admin user. This restriction should be removed
net localgroup Administrators sshtest_ssouser /add
}
<#
.Synopsis
Cleanup-OpenSSHTestEnvironment
#>
function Cleanup-OpenSSHTestEnvironment
{
[CmdletBinding()]
param
()
# .exe - Windows specific. TODO - PAL
if (-not(Test-Path(Join-Path $OpenSSHDir ssh.exe)))
{
Throw 'cannot find OpenSSH binaries under ' + $OpenSSHDir + '. Try -OpenSSHDir parameter'
}
#Restore sshd_config
if (Test-Path (Join-Path $OpenSSHDir sshd_config.ori)) {
Stop-Service sshd
Stop-Service ssh-agent
Copy-Item (Join-Path $OpenSSHDir sshd_config.ori) (Join-Path $OpenSSHDir sshd_config)
Remove-Item (Join-Path $OpenSSHDir sshd_config.ori) -Force
Remove-Item $OpenSSHDir\sshtest*hostkey* -Force
Start-Service sshd
}
#Restore known_hosts
if (Test-Path (Join-Path $home .ssh\known_hosts.ori)) {
Copy-Item (Join-Path $home .ssh\known_hosts.ori) (Join-Path $home .ssh\known_hosts)
Remove-Item (Join-Path $home .ssh\known_hosts.ori) -Force
}
# delete accounts
foreach ($user in $testaccounts) {
Remove-LocalUser -Name $user -ErrorAction SilentlyContinue
}
# remove registered keys
$ssouserpubkey = Join-Path $OpenSSHTestDir sshtest_userssokey_ed25519
ssh-add -d $ssouserpubkey
}
<#
.Synopsis
After build and test run completes, upload all artifacts from the build machine.
#>
function Deploy-OpenSSHTests
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
if (-not (Test-Path -Path $OpenSSHTestDir -PathType Container))
{
$null = New-Item -Path $OpenSSHTestDir -ItemType Directory -Force -ErrorAction Stop
}
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -eq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
#copy all pester tests
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1, sshd_config, known_hosts, sshtest_* -Force -ErrorAction Stop
#copy all unit tests.
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination "$OpenSSHTestDir\" -Container -Include unittest-* -Recurse -Force -ErrorAction Stop
#restart the service to use the test copy of sshd_config
Restart-Service sshd
}
<#
.Synopsis
Run OpenSSH pester tests.
#>
function Run-OpenSSHPesterTest
{
# Discover all CI tests and run them.
Push-Location $OpenSSHTestDir
Write-Log -Message "Running OpenSSH Pester tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse -Exclude SSHDConfig.tests.ps1, SSH.Tests.ps1 | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $PesterTestResultsFile -Tag 'CI'
Pop-Location
}
function Check-OpenSSHPesterTestResult
{
if (-not (Test-Path $PesterTestResultsFile))
{
Write-Warning "$($xml.'test-results'.failures) tests in regress\pesterTests failed"
Write-BuildMessage -Message "Test result file $PesterTestResultsFile not found after tests." -Category Error
Set-BuildVariable TestPassed False
}
$xml = [xml](Get-Content -raw $PesterTestResultsFile)
if ([int]$xml.'test-results'.failures -gt 0)
{
$errorMessage = "$($xml.'test-results'.failures) tests in regress\pesterTests failed. Detail test log is at TestResults.xml."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
# Writing out warning when the $Error.Count is non-zero. Tests Should clean $Error after success.
if ($Error.Count -gt 0)
{
Write-BuildMessage -Message "Tests Should clean $Error after success." -Category Warning
$Error| Out-File "$testInstallFolder\TestError.txt" -Append
}
}
<#
.Synopsis
Run unit tests.
#>
function Run-OpenSSHUnitTest
{
# Discover all CI tests and run them.
Push-Location $OpenSSHTestDir
Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $unitTestOutputFile)
{
Remove-Item -Path $UnitTestResultsFile -Force -ErrorAction SilentlyContinue
}
$testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
ForEach-Object{ Split-Path $_.FullName} |
Sort-Object -Unique
$testfailed = $false
if ($testFolders -ne $null)
{
$testFolders | % {
Push-Location $_
$unittestFile = "$(Split-Path $_ -Leaf).exe"
Write-Output "Running OpenSSH unit $unittestFile ..."
& .\$unittestFile >> $UnitTestResultsFile
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
$testfailed = $true
$errorMessage = "$($_.FullName) test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at UnitTestResults.txt."
Write-Warning $errorMessage
Write-BuildMessage -Message $errorMessage -Category Error
Set-BuildVariable TestPassed False
}
Pop-Location
}
if(-not $testfailed)
{
Write-BuildMessage -Message "All Unit tests passed!" -Category Information
}
}
Pop-Location
}
Export-ModuleMember -Function Set-OpenSSHTestParams, Dump-OpenSSHTestParams, Install-OpenSSHTestDependencies, Setup-OpenSSHTestEnvironment, Cleanup-OpenSSHTestEnvironment, Deploy-OpenSSHTests, Run-OpenSSHUnitTest, Run-OpenSSHPesterTest, Check-OpenSSHPesterTestResult

View File

@ -64,7 +64,7 @@ function Is-CoreCLR {
Class Machine Class Machine
{ {
[string] $MachineName = $env:COMPUTERNAME [string] $MachineName = "localhost"
[MachineRole] $Role = [MachineRole]::Client [MachineRole] $Role = [MachineRole]::Client
[PlatformType] $Platform [PlatformType] $Platform
[boolean] $IsCoreCLR [boolean] $IsCoreCLR
@ -72,8 +72,9 @@ Class Machine
#Members on server role #Members on server role
[string []] $PublicHostKeyPaths [string []] $PublicHostKeyPaths
[string []] $PrivateHostKeyPaths [string []] $PrivateHostKeyPaths
[string] $localAdminUserName = "localadmin" [string] $ssouser = "sshtest_ssouser"
[string] $localAdminPassword = "Bull_dog1" [string] $passwduser = "sshtest_passwduser"
[string] $passwduser_pw = "P@ssw0rd_1"
[string] $localAdminAuthorizedKeyPath [string] $localAdminAuthorizedKeyPath
[string] $sshdConfigFile = (join-path $PSScriptRoot "sshd_config") [string] $sshdConfigFile = (join-path $PSScriptRoot "sshd_config")
[string] $backupFileName = (join-path $PSScriptRoot "sshd_backup") [string] $backupFileName = (join-path $PSScriptRoot "sshd_backup")
@ -92,19 +93,19 @@ Class Machine
Machine() { Machine() {
$this.Platform = Set-Platform $this.Platform = Set-Platform
$this.IsCoreCLR = Is-CoreCLR $this.IsCoreCLR = Is-CoreCLR
$this.InitializeClient() #$this.InitializeClient()
$this.InitializeServer() #$this.InitializeServer()
} }
Machine ([MachineRole] $r) { Machine ([MachineRole] $r) {
$this.Platform = Set-Platform $this.Platform = Set-Platform
$this.IsCoreCLR = Is-CoreCLR $this.IsCoreCLR = Is-CoreCLR
$this.Role = $r $this.Role = $r
if($this.Role -eq [MachineRole]::Client) { #if($this.Role -eq [MachineRole]::Client) {
$this.InitializeClient() # $this.InitializeClient()
} else { #} else {
$this.InitializeServer() # $this.InitializeServer()
} #}
} }
[void] InitializeClient() { [void] InitializeClient() {
@ -127,14 +128,6 @@ Class Machine
} }
} }
foreach($key in @("ed25519")) #@("rsa","dsa","ecdsa","ed25519")
{
$keyPath = "$($this.ClientKeyDirectory)\id_$key"
$this.clientPrivateKeyPaths += $keyPath
$this.clientPublicKeyPaths += "$keyPath.pub"
$str = ".\ssh-keygen -t $key -P """" -f $keyPath"
$this.RunCmd($str)
}
} }
[void] InitializeServer() { [void] InitializeServer() {
@ -157,13 +150,6 @@ Class Machine
} }
$this.localAdminAuthorizedKeyPath = join-path $($this.localUserprofilePath) ".ssh/authorized_keys" $this.localAdminAuthorizedKeyPath = join-path $($this.localUserprofilePath) ".ssh/authorized_keys"
Remove-Item -Path $($this.localAdminAuthorizedKeyPath) -Force -ea silentlycontinue Remove-Item -Path $($this.localAdminAuthorizedKeyPath) -Force -ea silentlycontinue
#Generate all host keys
.\ssh-keygen -A
$this.PublicHostKeyPaths = @("$psscriptroot\ssh_host_ed25519_key.pub")
# @("$psscriptroot\ssh_host_rsa_key.pub","$psscriptroot\ssh_host_dsa_key.pub","$psscriptroot\ssh_host_ecdsa_key.pub","$psscriptroot\ssh_host_ed25519_key.pub")
$this.PrivateHostKeyPaths = @("$psscriptroot\ssh_host_ed25519_key")
# @("$psscriptroot\ssh_host_rsa_key","$psscriptroot\ssh_host_dsa_key","$psscriptroot\ssh_host_ecdsa_key","$psscriptroot\ssh_host_ed25519_key")
} }
[void] SetupClient([Machine] $server) { [void] SetupClient([Machine] $server) {
@ -251,6 +237,11 @@ Class Machine
{ {
$this.SetKeys($null, $publicKeyPath, $($this.localAdminAuthorizedKeyPath)) $this.SetKeys($null, $publicKeyPath, $($this.localAdminAuthorizedKeyPath))
} }
# Provide Read Access to NT Service\sshd
$acl = get-acl $($this.localAdminAuthorizedKeyPath)
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule("NT Service\sshd", "Read", "Allow")
$acl.SetAccessRule($ar)
Set-Acl $($this.localAdminAuthorizedKeyPath) $acl
} }
[void] CleanupServer() { [void] CleanupServer() {
@ -351,7 +342,8 @@ Class Machine
} }
[void] AddPasswordSetting([string] $pass) { [void] AddPasswordSetting([string] $pass) {
if ($this.Platform -eq [PlatformType]::Windows) { if ($this.Platform -eq [PlatformType]::Windows) {
if (-not($env:DISPLAY)) {$env:DISPLAY=1}
$env:SSH_ASKPASS="$($env:ComSpec) /c echo $pass" $env:SSH_ASKPASS="$($env:ComSpec) /c echo $pass"
} }
} }
@ -359,6 +351,7 @@ Class Machine
[void] CleanupPasswordSetting() { [void] CleanupPasswordSetting() {
if ($this.Platform -eq [PlatformType]::Windows -and (Test-Path env:SSH_ASKPASS)) if ($this.Platform -eq [PlatformType]::Windows -and (Test-Path env:SSH_ASKPASS))
{ {
if ($env:DISPLAY -eq 1) {Remove-Item env:\DISPLAY}
remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
} }
} }

View File

@ -1,53 +1,43 @@
using module .\PlatformAbstractLayer.psm1 
Describe "Tests for portforwarding" -Tags "CI" { Describe "Tests for portforwarding" -Tags "CI" {
BeforeAll { BeforeAll {
$fileName = "test.txt" $fileName = "test.txt"
$filePath = Join-Path ${TestDrive} $fileName $filePath = Join-Path ${TestDrive} $fileName
$logName = "log.txt"
[Machine] $client = [Machine]::new([MachineRole]::Client) $logPath = Join-Path ${TestDrive} $logName
[Machine] $server = [Machine]::new([MachineRole]::Server) $server = $OpenSSHTestInfo["Target"]
$client.SetupClient($server) $port = $OpenSSHTestInfo["Port"]
$server.SetupServer($client) $ssouser = $OpenSSHTestInfo["SSOUser"]
$server.SecureHostKeys($server.PrivateHostKeyPaths)
$server.SetupServerRemoting([Protocol]::WSMAN)
#setup single signon
.\ssh-add.exe $client.clientPrivateKeyPaths[0]
Remove-Item -Path $filePath -Force -ea silentlycontinue
$testData = @( $testData = @(
@{ @{
Title = "Local port forwarding" Title = "Local port forwarding"
Options = "-L 5432:127.0.0.1:47001" Options = "-L 5432:127.0.0.1:47001"
Port = 5432 FwdedPort = 5432
}, },
@{ @{
Title = "Remote port forwarding" Title = "Remote port forwarding"
Options = "-R 5432:127.0.0.1:47001" Options = "-R 5432:127.0.0.1:47001"
Port = 5432 FwdedPort = 5432
} }
) )
} }
AfterAll { AfterAll {
#cleanup single signon
.\ssh-add.exe -D
$Server.CleanupHostKeys()
$client.CleanupClient()
$server.CleanupServer()
} }
AfterEach { AfterEach {
Remove-Item -Path $filePath -Force -ea silentlycontinue Remove-Item -Path $filePath -Force -ea silentlycontinue
Remove-Item -Path $logPath -Force -ea silentlycontinue
} }
It '<Title>' -TestCases:$testData { It '<Title>' -TestCases:$testData {
param([string]$Title, $Options, $port) param([string]$Title, $Options, $FwdedPort)
$str = ".\ssh $($Options) $($server.localAdminUserName)@$($server.MachineName) powershell.exe Test-WSMan -computer 127.0.0.1 -port $port > $filePath" $str = "ssh -p $($port) -E $logPath $($Options) $($ssouser)@$($server) powershell.exe Test-WSMan -computer 127.0.0.1 -port $FwdedPort > $filePath"
$client.RunCmd($str) # TODO - move this to PAL
cmd /c $str
#validate file content. #validate file content.
$content = Get-Content $filePath $content = Get-Content $filePath
$content -like "wsmid*" | Should Not Be $null $content -like "wsmid*" | Should Not Be $null

View File

@ -1,5 +1,4 @@
using module .\PlatformAbstractLayer.psm1 
#covered -i -p -q -r -v -c -S -C #covered -i -p -q -r -v -c -S -C
#todo: -F, -l and -P should be tested over the network #todo: -F, -l and -P should be tested over the network
Describe "Tests for scp command" -Tags "CI" { Describe "Tests for scp command" -Tags "CI" {
@ -21,10 +20,9 @@ Describe "Tests for scp command" -Tags "CI" {
"Test content in nested dir" | Set-content -Path $NestedSourceFilePath "Test content in nested dir" | Set-content -Path $NestedSourceFilePath
$null = New-Item $DestinationDir -ItemType directory -Force $null = New-Item $DestinationDir -ItemType directory -Force
[Machine] $client = [Machine]::new([MachineRole]::Client) $server = $OpenSSHTestInfo["Target"]
[Machine] $server = [Machine]::new([MachineRole]::Server) $port = $OpenSSHTestInfo["Port"]
$client.SetupClient($server) $ssouser = $OpenSSHTestInfo["SSOUser"]
$server.SetupServer($client)
$script:logNum = 0 $script:logNum = 0
$testData = @( $testData = @(
@ -36,11 +34,11 @@ Describe "Tests for scp command" -Tags "CI" {
@{ @{
Title = 'Simple copy local file to remote file' Title = 'Simple copy local file to remote file'
Source = $SourceFilePath Source = $SourceFilePath
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath" Destination = "$($ssouser)@$($server):$DestinationFilePath"
}, },
@{ @{
Title = 'Simple copy remote file to local file' Title = 'Simple copy remote file to local file'
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath" Source = "$($ssouser)@$($server):$SourceFilePath"
Destination = $DestinationFilePath Destination = $DestinationFilePath
}, },
@{ @{
@ -51,11 +49,11 @@ Describe "Tests for scp command" -Tags "CI" {
@{ @{
Title = 'simple copy local file to remote dir' Title = 'simple copy local file to remote dir'
Source = $SourceFilePath Source = $SourceFilePath
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir" Destination = "$($ssouser)@$($server):$DestinationDir"
}, },
@{ @{
Title = 'simple copy remote file to local dir' Title = 'simple copy remote file to local dir'
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath" Source = "$($ssouser)@$($server):$SourceFilePath"
Destination = $DestinationDir Destination = $DestinationDir
} }
) )
@ -64,7 +62,7 @@ Describe "Tests for scp command" -Tags "CI" {
@{ @{
Title = 'copy from local dir to remote dir' Title = 'copy from local dir to remote dir'
Source = $sourceDir Source = $sourceDir
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir" Destination = "$($ssouser)@$($server):$DestinationDir"
}, },
<# @{ <# @{
Title = 'copy from local dir to local dir' Title = 'copy from local dir to local dir'
@ -73,7 +71,7 @@ Describe "Tests for scp command" -Tags "CI" {
},#> },#>
@{ @{
Title = 'copy from remote dir to local dir' Title = 'copy from remote dir to local dir'
Source = "$($server.localAdminUserName)@$($server.MachineName):$sourceDir" Source = "$($ssouser)@$($server):$sourceDir"
Destination = $DestinationDir Destination = $DestinationDir
} }
) )
@ -93,9 +91,6 @@ Describe "Tests for scp command" -Tags "CI" {
} }
AfterAll { AfterAll {
$client.CleanupClient()
$server.CleanupServer()
Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
} }
@ -114,16 +109,15 @@ Describe "Tests for scp command" -Tags "CI" {
} }
}#> }#>
Context "Key is Secured in ssh-agent on server" { Context "SCP -i option" {
BeforeAll { BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$privateKeyFile = $client.clientPrivateKeyPaths[0]
} }
BeforeEach { BeforeEach {
if ($env:DebugMode) if ($env:DebugMode)
{ {
Stop-Service ssh-agent -Force Stop-Service ssh-agent -Force
Start-Sleep 2 Start-Sleep 2
# Fix this - pick up logs from ssh installation dir, not test directory
Remove-Item .\logs\ssh-agent.log -Force -ErrorAction ignore Remove-Item .\logs\ssh-agent.log -Force -ErrorAction ignore
Remove-Item .\logs\sshd.log -Force -ErrorAction ignore Remove-Item .\logs\sshd.log -Force -ErrorAction ignore
Start-Service sshd Start-Service sshd
@ -131,12 +125,11 @@ Describe "Tests for scp command" -Tags "CI" {
} }
AfterAll { AfterAll {
$Server.CleanupHostKeys()
} }
It 'File copy with -i option and private key: <Title> ' -TestCases:$testData { It 'File copy with -i option: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -i $privateKeyFile $Source $Destination scp -P $port $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
@ -148,7 +141,7 @@ Describe "Tests for scp command" -Tags "CI" {
It 'Directory recursive copy with -i option and private key: <Title> ' -TestCases:$testData1 { It 'Directory recursive copy with -i option and private key: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -r -i $privateKeyFile $Source $Destination scp -P $port -r $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
@ -160,23 +153,16 @@ Describe "Tests for scp command" -Tags "CI" {
} }
} }
Context "Single signon with keys -p -v -c option Secured in ssh-agent" { Context "SCP -p -v -c options" {
BeforeAll { BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$identifyFile = $client.clientPrivateKeyPaths[0]
#setup single signon
.\ssh-add.exe $identifyFile
} }
AfterAll { AfterAll {
$Server.CleanupHostKeys()
#cleanup single signon
.\ssh-add.exe -D
} }
It 'File copy with -S -v option (positive)' { It 'File copy with -S option (positive)' {
.\scp -S .\ssh.exe -v $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath" $sshcmd = (get-command ssh).Path
scp -P $port -S $sshcmd $SourceFilePath "$($ssouser)@$($server):$DestinationFilePath"
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true CheckTarget -target $DestinationFilePath | Should Be $true
@ -184,10 +170,11 @@ Describe "Tests for scp command" -Tags "CI" {
$equal | Should Be $true $equal | Should Be $true
} }
It 'File copy with -p -c option: <Title> ' -TestCases:$testData { It 'File copy with -p -c option: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -p -c aes128-ctr -C $Source $Destination scp -P $port -p -c aes128-ctr -C $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true CheckTarget -target $DestinationFilePath | Should Be $true
@ -198,7 +185,7 @@ Describe "Tests for scp command" -Tags "CI" {
It 'Directory recursive copy with -r -p -c option: <Title> ' -TestCases:$testData1 { It 'Directory recursive copy with -r -p -c option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -r -p -c aes128-ctr $Source $Destination scp -P $port -r -p -c aes128-ctr $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0 $equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
@ -209,15 +196,14 @@ Describe "Tests for scp command" -Tags "CI" {
} }
} }
Context "Private key authentication with -i -C -q options. host keys are not secured on server" { Context "SCP -i -C -q options" {
BeforeAll { BeforeAll {
$identifyFile = $client.clientPrivateKeyPaths[0]
} }
It 'File copy with -i -C -q options: <Title> ' -TestCases:$testData{ It 'File copy with -i -C -q options: <Title> ' -TestCases:$testData{
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -C -q $Source $Destination scp -P $port -C -q $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true CheckTarget -target $DestinationFilePath | Should Be $true
@ -228,7 +214,7 @@ Describe "Tests for scp command" -Tags "CI" {
It 'Directory recursive copy with -i -C -r and -q options: <Title> ' -TestCases:$testData1 { It 'Directory recursive copy with -i -C -r and -q options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -C -r -q $Source $Destination scp -P $port -C -r -q $Source $Destination
$LASTEXITCODE | Should Be 0 $LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 $equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
@ -239,6 +225,7 @@ Describe "Tests for scp command" -Tags "CI" {
} }
} }
<# No need to test Password auth for scp. Remove these if they are not adding any value from scp side
Context "Password authentication" { Context "Password authentication" {
BeforeAll { BeforeAll {
$client.AddPasswordSetting($server.localAdminPassword) $client.AddPasswordSetting($server.localAdminPassword)
@ -271,5 +258,6 @@ Describe "Tests for scp command" -Tags "CI" {
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
} }
#>
} }

View File

@ -29,14 +29,12 @@ Describe "SFTP Testcases" -Tags "CI" {
[Machine] $client = [Machine]::new([MachineRole]::Client) [Machine] $client = [Machine]::new([MachineRole]::Client)
[Machine] $server = [Machine]::new([MachineRole]::Server) [Machine] $server = [Machine]::new([MachineRole]::Server)
$client.SetupClient($server)
$server.SetupServer($client)
$testData1 = @( $testData1 = @(
@{ @{
title = "put, ls for non-unicode file names" title = "put, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "put $tempFilePath $serverDirectory commands = "put $tempFilePath $serverDirectory
ls $serverDirectory" ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempFileName) expectedoutput = (join-path $serverdirectory $tempFileName)
@ -44,32 +42,32 @@ Describe "SFTP Testcases" -Tags "CI" {
}, },
@{ @{
title = "get, ls for non-unicode file names" title = "get, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "get $tempFilePath $clientDirectory commands = "get $tempFilePath $clientDirectory
ls $clientDirectory" ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempFileName) expectedoutput = (join-path $clientDirectory $tempFileName)
}, },
@{ @{
title = "mput, ls for non-unicode file names" title = "mput, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "mput $tempFilePath $serverDirectory commands = "mput $tempFilePath $serverDirectory
ls $serverDirectory" ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempFileName) expectedoutput = (join-path $serverdirectory $tempFileName)
}, },
@{ @{
title = "mget, ls for non-unicode file names" title = "mget, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "mget $tempFilePath $clientDirectory commands = "mget $tempFilePath $clientDirectory
ls $clientDirectory" ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempFileName) expectedoutput = (join-path $clientDirectory $tempFileName)
}, },
@{ @{
title = "mkdir, cd, pwd for non-unicode directory names" title = "mkdir, cd, pwd for non-unicode directory names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "cd $serverdirectory commands = "cd $serverdirectory
mkdir server_test_dir mkdir server_test_dir
cd server_test_dir cd server_test_dir
@ -78,8 +76,8 @@ Describe "SFTP Testcases" -Tags "CI" {
}, },
@{ @{
Title = "lmkdir, lcd, lpwd for non-unicode directory names" Title = "lmkdir, lcd, lpwd for non-unicode directory names"
LogonStr = "$($server.localAdminUserName)@$($server.MachineName)" LogonStr = "$($server.ssouser)@$($server.MachineName)"
Options = '-i $identifyFile' Options = ''
Commands = "lcd $clientDirectory Commands = "lcd $clientDirectory
lmkdir client_test_dir lmkdir client_test_dir
lcd client_test_dir lcd client_test_dir
@ -88,40 +86,40 @@ Describe "SFTP Testcases" -Tags "CI" {
}, },
@{ @{
title = "put, ls for unicode file names" title = "put, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "put $tempUnicodeFilePath $serverDirectory commands = "put $tempUnicodeFilePath $serverDirectory
ls $serverDirectory" ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) expectedoutput = (join-path $serverdirectory $tempUnicodeFileName)
}, },
@{ @{
title = "get, ls for unicode file names" title = "get, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "get $tempUnicodeFilePath $clientDirectory commands = "get $tempUnicodeFilePath $clientDirectory
ls $clientDirectory" ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) expectedoutput = (join-path $clientDirectory $tempUnicodeFileName)
}, },
@{ @{
title = "mput, ls for unicode file names" title = "mput, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "mput $tempUnicodeFilePath $serverDirectory commands = "mput $tempUnicodeFilePath $serverDirectory
ls $serverDirectory" ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempUnicodeFileName) expectedoutput = (join-path $serverdirectory $tempUnicodeFileName)
}, },
@{ @{
title = "mget, ls for unicode file names" title = "mget, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "mget $tempUnicodeFilePath $clientDirectory commands = "mget $tempUnicodeFilePath $clientDirectory
ls $clientDirectory" ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempUnicodeFileName) expectedoutput = (join-path $clientDirectory $tempUnicodeFileName)
}, },
@{ @{
title = "mkdir, cd, pwd for unicode directory names" title = "mkdir, cd, pwd for unicode directory names"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile' options = ''
commands = "cd $serverdirectory commands = "cd $serverdirectory
mkdir server_test_dir_язык mkdir server_test_dir_язык
cd server_test_dir_язык cd server_test_dir_язык
@ -130,8 +128,8 @@ Describe "SFTP Testcases" -Tags "CI" {
}, },
@{ @{
Title = "lmkdir, lcd, lpwd for unicode directory names" Title = "lmkdir, lcd, lpwd for unicode directory names"
LogonStr = "$($server.localAdminUserName)@$($server.MachineName)" LogonStr = "$($server.ssouser)@$($server.MachineName)"
Options = '-i $identifyFile' Options = ''
Commands = "lcd $clientDirectory Commands = "lcd $clientDirectory
lmkdir client_test_dir_язык lmkdir client_test_dir_язык
lcd client_test_dir_язык lcd client_test_dir_язык
@ -144,8 +142,8 @@ Describe "SFTP Testcases" -Tags "CI" {
$testData2 = @( $testData2 = @(
@{ @{
title = "rm, rmdir, rename for unicode file, directory" title = "rm, rmdir, rename for unicode file, directory"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile -b $batchFilePath' options = 'b $batchFilePath'
tmpFileName1 = $tempUnicodeFileName tmpFileName1 = $tempUnicodeFileName
tmpFilePath1 = $tempUnicodeFilePath tmpFilePath1 = $tempUnicodeFilePath
@ -159,8 +157,8 @@ Describe "SFTP Testcases" -Tags "CI" {
}, },
@{ @{
title = "rm, rmdir, rename for non-unicode file, directory" title = "rm, rmdir, rename for non-unicode file, directory"
logonstr = "$($server.localadminusername)@$($server.machinename)" logonstr = "$($server.ssouser)@$($server.machinename)"
options = '-i $identifyfile -b $batchFilePath' options = '-b $batchFilePath'
tmpFileName1 = $tempFileName tmpFileName1 = $tempFileName
tmpFilePath1 = $tempFilePath tmpFilePath1 = $tempFilePath
@ -176,20 +174,12 @@ Describe "SFTP Testcases" -Tags "CI" {
} }
AfterAll { AfterAll {
$client.CleanupClient()
$server.CleanupServer()
} }
Context "Single signon" { Context "SFTP Test Cases" {
BeforeAll { BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$identifyFile = $client.clientPrivateKeyPaths[0]
.\ssh-add.exe $identifyFile #setup single signon
} }
AfterAll { AfterAll {
$Server.CleanupHostKeys()
.\ssh-add.exe -D #cleanup single signon
Get-Item $rootDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue Get-Item $rootDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
} }
@ -204,7 +194,8 @@ Describe "SFTP Testcases" -Tags "CI" {
param([string]$Title, $LogonStr, $Options, $Commands, $ExpectedOutput, $SkipVerification = $false) param([string]$Title, $LogonStr, $Options, $Commands, $ExpectedOutput, $SkipVerification = $false)
Set-Content $batchFilePath -Encoding UTF8 -value $Commands Set-Content $batchFilePath -Encoding UTF8 -value $Commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) -b $batchFilePath $($LogonStr) > $outputFilePath") Write-Host "sftp -P 47002 $($Options) -b $batchFilePath $($LogonStr) > $outputFilePath"
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) -b $batchFilePath $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
#validate file content. #validate file content.
@ -221,7 +212,7 @@ Describe "SFTP Testcases" -Tags "CI" {
put $tmpFilePath1 $tmpDirectoryPath1 put $tmpFilePath1 $tmpDirectoryPath1
ls $tmpDirectoryPath1" ls $tmpDirectoryPath1"
Set-Content $batchFilePath -Encoding UTF8 -value $commands Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath") $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $true Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $true
@ -230,7 +221,7 @@ Describe "SFTP Testcases" -Tags "CI" {
pwd pwd
" "
Set-Content $batchFilePath -Encoding UTF8 -value $commands Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath") $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $false Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $false
@ -241,7 +232,7 @@ Describe "SFTP Testcases" -Tags "CI" {
ls $tmpDirectoryPath1 ls $tmpDirectoryPath1
pwd" pwd"
Set-Content $batchFilePath -Encoding UTF8 -value $commands Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath") $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName2) | Should be $true Test-Path (join-path $tmpDirectoryPath1 $tmpFileName2) | Should be $true
@ -251,7 +242,7 @@ Describe "SFTP Testcases" -Tags "CI" {
rename $tmpDirectoryPath1 $tmpDirectoryPath2 rename $tmpDirectoryPath1 $tmpDirectoryPath2
ls $serverDirectory" ls $serverDirectory"
Set-Content $batchFilePath -Encoding UTF8 -value $commands Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath") $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
Test-Path $tmpDirectoryPath2 | Should be $true Test-Path $tmpDirectoryPath2 | Should be $true
@ -260,7 +251,7 @@ Describe "SFTP Testcases" -Tags "CI" {
$commands = "rmdir $tmpDirectoryPath2 $commands = "rmdir $tmpDirectoryPath2
ls $serverDirectory" ls $serverDirectory"
Set-Content $batchFilePath -Encoding UTF8 -value $commands Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath") $str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P 47002 $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str) $client.RunCmd($str)
Test-Path $tmpDirectoryPath2 | Should be $false Test-Path $tmpDirectoryPath2 | Should be $false
} }

View File

@ -10,7 +10,7 @@
# possible, but leave them commented. Uncommented options override the # possible, but leave them commented. Uncommented options override the
# default value. # default value.
#Port 22 Port 47002
#AddressFamily any #AddressFamily any
#ListenAddress 0.0.0.0 #ListenAddress 0.0.0.0
#ListenAddress :: #ListenAddress ::
@ -21,9 +21,10 @@
# HostKey for protocol version 1 # HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key #HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2 # HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key HostKey sshtest_hostkey_rsa
#HostKey /etc/ssh/ssh_host_dsa_key HostKey sshtest_hostkey_dsa
#HostKey /etc/ssh/ssh_host_ecdsa_key HostKey sshtest_hostkey_ecdsa
HostKey sshtest_hostkey_ed25519
# Lifetime and size of ephemeral version 1 server key # Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h #KeyRegenerationInterval 1h
@ -121,7 +122,7 @@ Subsystem sftp sftp-server.exe
# ForceCommand cvs server # ForceCommand cvs server
PubkeyAcceptedKeyTypes ssh-ed25519* PubkeyAcceptedKeyTypes ssh-ed25519*
DenyUsers denyuser1 deny*2 denyuse?3, #DenyUsers denyuser1 deny*2 denyuse?3,
AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin #AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin
DenyGroups denygroup1 denygr*p2 deny?rou?3 #DenyGroups denygroup1 denygr*p2 deny?rou?3
AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm* #AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm*

View File

@ -0,0 +1,4 @@
[localhost]:47002 ssh-dss AAAAB3NzaC1kc3MAAACBAIyVGPwSzaCedtroufmFrwXGVPzYUMHPePvlduORG2+1VmLkP2Yw+U6MHRnaDyDriCulhnmwIueGxhH+t0HKbGK0j7XpGnwgmFOBIg5gJwQTDJ+gX+qC2ju55WB0Gkkwl+xktnAFSqmj8ttSzUBhh1ksh5A6oW+NKjwEVH8tQExFAAAAFQC0YldxCDQbTuDO04EVgA0OMpDIvwAAAIBXWRzpoyQWNoB18DGbY9zupGhfwuKGmnlj2mY0aYxY3qu1+9ciQOBrwYJlf4dEJbirwp2XmKzHZ6LFrkLQptVcD1wDkG/a/wMRvh+tbxlq45S3Eh0oNj1cobhUlFm9m5PM2HW1LccbOAEBUG/L4Vcj1Ag4n639H0fwDRL+rwOpjgAAAIBh/fSBidBGsQITgg45wwDszk7AAhngNm+jbiea8dbgYP6wpT6dJdg3pYwKT0V/PdXTSDi16kkoMkbUsMZyxyFJf/TtmCtBnon55yL9+H5dtcOBF8BXR7KzQX1E1n0eIL9jZ0Q4BspkB4LKQXhxRnrNJlv/oopxXua/GCMW17xxuA== sshtest_hostkey_dsa
[localhost]:47002 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHF2eWwgnaUSLNNN0ilxiT916uMa6lusMB31AxfkDGArh4xCWL0e3F/gRifRephM0cD2dSh8Ji6VnjkhvZptjEw= sshtest_hostkey_ecdsa
[localhost]:47002 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
[localhost]:47002 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU+NcQ5NuRutQJoZVjDmP/vE6IYZOaE59FTUjaoZkuPl4prdOPgqAnCwSy9XtnfzPm/oe62SyYIHgj8wRzhqjMU8g8aGqfv9ryF+hpNXZrFYXIdkdxnubzfb4e70RRRoTH8P5vuY8sAn0FIRlV/3EDkSKBFy2W3InMTO6l8gbkzzkgbn1GLvH06QJVdb2PcHksSn7dJBVHWASYi3TJWWu4muI+ZNfothujxAHqjKTJuJ9apDZIc0tnkPmlifRmolSUS4OAH2KWZ+5Gwaj7gsB8bk4QuA+QCT60OCcuzCcy4FBuXvvXkM9MBe/P2KZjVLAn86SriRtoE4RI+9R9S7DV sshtest_hostkey_rsa

View File

@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQCMlRj8Es2gnnba6Ln5ha8FxlT82FDBz3j75XbjkRtvtVZi5D9m
MPlOjB0Z2g8g64grpYZ5sCLnhsYR/rdBymxitI+16Rp8IJhTgSIOYCcEEwyfoF/q
gto7ueVgdBpJMJfsZLZwBUqpo/LbUs1AYYdZLIeQOqFvjSo8BFR/LUBMRQIVALRi
V3EINBtO4M7TgRWADQ4ykMi/AoGAV1kc6aMkFjaAdfAxm2Pc7qRoX8Lihpp5Y9pm
NGmMWN6rtfvXIkDga8GCZX+HRCW4q8Kdl5isx2eixa5C0KbVXA9cA5Bv2v8DEb4f
rW8ZauOUtxIdKDY9XKG4VJRZvZuTzNh1tS3HGzgBAVBvy+FXI9QIOJ+t/R9H8A0S
/q8DqY4CgYBh/fSBidBGsQITgg45wwDszk7AAhngNm+jbiea8dbgYP6wpT6dJdg3
pYwKT0V/PdXTSDi16kkoMkbUsMZyxyFJf/TtmCtBnon55yL9+H5dtcOBF8BXR7Kz
QX1E1n0eIL9jZ0Q4BspkB4LKQXhxRnrNJlv/oopxXua/GCMW17xxuAIVAIy08ce7
877PESiaI4iDWj36uuWV
-----END DSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-dss AAAAB3NzaC1kc3MAAACBAIyVGPwSzaCedtroufmFrwXGVPzYUMHPePvlduORG2+1VmLkP2Yw+U6MHRnaDyDriCulhnmwIueGxhH+t0HKbGK0j7XpGnwgmFOBIg5gJwQTDJ+gX+qC2ju55WB0Gkkwl+xktnAFSqmj8ttSzUBhh1ksh5A6oW+NKjwEVH8tQExFAAAAFQC0YldxCDQbTuDO04EVgA0OMpDIvwAAAIBXWRzpoyQWNoB18DGbY9zupGhfwuKGmnlj2mY0aYxY3qu1+9ciQOBrwYJlf4dEJbirwp2XmKzHZ6LFrkLQptVcD1wDkG/a/wMRvh+tbxlq45S3Eh0oNj1cobhUlFm9m5PM2HW1LccbOAEBUG/L4Vcj1Ag4n639H0fwDRL+rwOpjgAAAIBh/fSBidBGsQITgg45wwDszk7AAhngNm+jbiea8dbgYP6wpT6dJdg3pYwKT0V/PdXTSDi16kkoMkbUsMZyxyFJf/TtmCtBnon55yL9+H5dtcOBF8BXR7KzQX1E1n0eIL9jZ0Q4BspkB4LKQXhxRnrNJlv/oopxXua/GCMW17xxuA== sshtest_hostkey_dsa

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICAT5BC1AJpeOsRQaettNtqw6rzKlHDgtGvqnYZuU8YOoAoGCCqGSM49
AwEHoUQDQgAEcXZ5bCCdpRIs003SKXGJP3Xq4xrqW6wwHfUDF+QMYCuHjEJYvR7c
X+BGJ9F6mEzRwPZ1KHwmLpWeOSG9mm2MTA==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHF2eWwgnaUSLNNN0ilxiT916uMa6lusMB31AxfkDGArh4xCWL0e3F/gRifRephM0cD2dSh8Ji6VnjkhvZptjEw= sshtest_hostkey_ecdsa

View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDLSTMcJ/oiVNF+PhAuz0o/3H3DG3T+moYaHbV8fukR7wAAAKACW4cWAluH
FgAAAAtzc2gtZWQyNTUxOQAAACDLSTMcJ/oiVNF+PhAuz0o/3H3DG3T+moYaHbV8fukR7w
AAAEDIU6PKvxw+6hgpQmTOOFeUasWnsYU3gricJCNrEHu2FstJMxwn+iJU0X4+EC7PSj/c
fcMbdP6ahhodtXx+6RHvAAAAF3NzaHRlc3RfaG9zdGtleV9lZDI1NTE5AQIDBAUG
-----END OPENSSH PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA1PjXEOTbkbrUCaGVYw5j/7xOiGGTmhOfRU1I2qGZLj5eKa3T
j4KgJwsEsvV7Z38z5v6HutksmCB4I/MEc4aozFPIPGhqn7/a8hfoaTV2axWFyHZH
cZ7m832+Hu9EUUaEx/D+b7mPLAJ9BSEZVf9xA5EigRctltyJzEzupfIG5M85IG59
Ri7x9OkCVXW9j3B5LEp+3SQVR1gEmIt0yVlruJriPmTX6LYbo8QB6oykybifWqQ2
SHNLZ5D5pYn0ZqJUlEuDgB9ilmfuRsGo+4LAfG5OELgPkAk+tDgnLswnMuBQbl77
15DPTAXvz9imY1SwJ/Okq4kbaBOESPvUfUuw1QIDAQABAoIBAGdEafRVJGqbbulk
om0vsyl0A5h5x/pz/Uy7VtI8fWxA7aPEF8uEiWelHhgwlC/xLBeb3/CoEcmKJPc5
hTUHXJ4HGhbAgsMHYoD1OsqZE9yEySQUxju/0zjKBgA2AKhwSz4wCw/dqCCs7DYq
gICEpiYWn+Z8eKyoL2ETBL0OiG01c4oZ8Qd1WrNPNAOA8uX2avCIawiGqfI5hRR2
UIpmTNsh8SbA7hMqI47JlLvmfAdKOvug09f36Yhx63RuXWy0AHqz3HcTe4K4tzlP
M+DnKDgHQkx8R5j/Q9Dv6ZlKn85FatIWftjd9e4Zsjx2lCKXBFIyn3EM1aiCaRAS
iIFJh4ECgYEA6nBShG3z6bLbBNEWPq2xqmq6uJDD7dg6glK5alDDKwCmurfQYxyY
HD/1YcIlf+kC4qUCrREgYlheH3xRbzT0yomtci015iC8R8ZZgGNqZO52HxhQVWdN
i08vsJmUnrq0WFyXS0OysnPCEPLbHBoFVbJWEDTgKxLOwbYMEyp7IHECgYEA6I8Z
tRE3AMbdYvN8+hjq5fcrsRZvkbddYa3DLYImii09s84p82MEskFd+dcTs6ViX2Qn
wFgdASCi0FBblKca6ZxgwMHoEEiWgx6zndayeU2wDGWCbHlVXkpnCPb7O+YoMKhy
XtDDfVZ0n0Cu+W6dlbVxWyP0uQ8RrE25Po/QSKUCgYAGCrkFsrO7jSF54U2ade2D
P9bqFMkH4y+21hzzMXumKxEg9MXJGB6Pc9KGH3PJ9R5e6vPDtBJKlo5ub0zF+e5p
Hd07eRDPin5vtxvtZCKE0WR37q97U/s6oOLQwVSENrmZIWHAzdDYKoWQ3EFrWvxS
NhNjvYkdcxGjCmcLQ2gC8QKBgD4IFZpXmi1J3jmLqxVm2hk3Id9dlarvlyf72mjk
I3WN9bxlTIlQKyuFBhUjSm0Luz6oj3XdyvbHBsa7+IGhRSt0+9XOoyDcy9DzuoNq
hjaXA1N7LBvVDXFWNT+N6Zujm6rG86LY2pwvGHJ2JXYBDGWnfTILWDaYj2U/Yh8O
60bFAoGAVnm3EVlak5mbDpSpyzqnglVKgZ+mz+4ODcF+qK4415QtAua8Je8Frcje
3dYJtP5c5Xm+wE5Lmr+yZUAxup5oC5NAmtvLwK8DLPjfZIBtF7qBf08am8e8HnZw
PzFks7iwv86eqgvTwBdE6QmaBzvEPLSmSI93uRz3q/S+16j50Pk=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU+NcQ5NuRutQJoZVjDmP/vE6IYZOaE59FTUjaoZkuPl4prdOPgqAnCwSy9XtnfzPm/oe62SyYIHgj8wRzhqjMU8g8aGqfv9ryF+hpNXZrFYXIdkdxnubzfb4e70RRRoTH8P5vuY8sAn0FIRlV/3EDkSKBFy2W3InMTO6l8gbkzzkgbn1GLvH06QJVdb2PcHksSn7dJBVHWASYi3TJWWu4muI+ZNfothujxAHqjKTJuJ9apDZIc0tnkPmlifRmolSUS4OAH2KWZ+5Gwaj7gsB8bk4QuA+QCT60OCcuzCcy4FBuXvvXkM9MBe/P2KZjVLAn86SriRtoE4RI+9R9S7DV sshtest_hostkey_rsa

View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACArxdmtP2DtTFvNp+4N4vlEP2tBmG7QtG4qfNUKlYmxRQAAAKAX+9lZF/vZ
WQAAAAtzc2gtZWQyNTUxOQAAACArxdmtP2DtTFvNp+4N4vlEP2tBmG7QtG4qfNUKlYmxRQ
AAAEBkZYPXRU9wu7OCcBia+eKvWOtDKpZRibjGQMTdBlCn5CvF2a0/YO1MW82n7g3i+UQ/
a0GYbtC0bip81QqVibFFAAAAGnNzaHRlc3RfdXNlcnNzb2tleV9lZDI1NTE5AQID
-----END OPENSSH PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICvF2a0/YO1MW82n7g3i+UQ/a0GYbtC0bip81QqVibFF sshtest_userssokey_ed25519

View File

@ -56,11 +56,6 @@ tests(void)
{ {
char *loc; char *loc;
#ifdef WINDOWS
TEST_START("not applicable to Windows yet");
TEST_DONE();
return;
#endif
TEST_START("utf8_setlocale"); TEST_START("utf8_setlocale");
loc = setlocale(LC_CTYPE, "en_US.UTF-8"); loc = setlocale(LC_CTYPE, "en_US.UTF-8");
ASSERT_PTR_NE(loc, NULL); ASSERT_PTR_NE(loc, NULL);

47
scp.c
View File

@ -292,29 +292,11 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
addargs(&args, "%s", host); addargs(&args, "%s", host);
addargs(&args, "%s", cmd); addargs(&args, "%s", cmd);
{ fcntl(pout[0], F_SETFD, FD_CLOEXEC);
char* full_cmd; fcntl(pin[1], F_SETFD, FD_CLOEXEC);
size_t cmdlen = 0;
char** list = args.list;
cmdlen = 1; /* null term */ do_cmd_pid = spawn_child(args.list[0], args.list + 1, pin[0], pout[1], STDERR_FILENO, 0);
while (*list)
cmdlen += strlen(*list++) + 1;
full_cmd = xmalloc(cmdlen);
full_cmd[0] = '\0';
list = args.list;
while (*list) {
strcat(full_cmd, *list++);
strcat(full_cmd, " ");
}
fcntl(pout[0], F_SETFD, FD_CLOEXEC);
fcntl(pin[1], F_SETFD, FD_CLOEXEC);
do_cmd_pid = spawn_child(full_cmd, pin[0], pout[1], STDERR_FILENO, 0);
free(full_cmd);
}
#else /* !WINDOWS */ #else /* !WINDOWS */
do_cmd_pid = fork(); do_cmd_pid = fork();
#endif /* !WINDOWS */ #endif /* !WINDOWS */
@ -382,26 +364,8 @@ do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout)
addargs(&args, "%s", host); addargs(&args, "%s", host);
addargs(&args, "%s", cmd); addargs(&args, "%s", cmd);
{ pid = spawn_child(args.list[0], args.list + 1, fdin, fdout, STDERR_FILENO, 0);
char* full_cmd;
size_t cmdlen = 0;
char** list = args.list;
cmdlen = 1; /* null term */
while (*list)
cmdlen += strlen(*list++) + 1;
full_cmd = xmalloc(cmdlen);
full_cmd[0] = '\0';
list = args.list;
while (*list) {
strcat(full_cmd, *list++);
strcat(full_cmd, " ");
}
pid = spawn_child(full_cmd, fdin, fdout, STDERR_FILENO, 0);
free(full_cmd);
}
#else /* !WINDOWS */ #else /* !WINDOWS */
pid = fork(); pid = fork();
#endif /* !WINDOWS */ #endif /* !WINDOWS */
@ -1512,4 +1476,3 @@ lostconn(int signo)
else else
exit(1); exit(1);
} }

View File

@ -183,7 +183,7 @@ static int
auth_input_request_forwarding(struct passwd * pw) auth_input_request_forwarding(struct passwd * pw)
{ {
#ifdef WINDOWS #ifdef WINDOWS
packet_send_debug("Agent forwarding not supported yet in Windows"); packet_send_debug("Agent forwarding not supported in Windows yet");
return 0; return 0;
#else /* !WINDOWS */ #else /* !WINDOWS */
Channel *nc; Channel *nc;
@ -2377,9 +2377,9 @@ static int
session_env_req(Session *s) session_env_req(Session *s)
{ {
char *name, *val; char *name, *val;
u_int name_chars, val_len, i; u_int name_len, val_len, i;
name = packet_get_cstring(&name_chars); name = packet_get_cstring(&name_len);
val = packet_get_cstring(&val_len); val = packet_get_cstring(&val_len);
packet_check_eom(); packet_check_eom();

34
sftp.c
View File

@ -2163,12 +2163,11 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
free(dir); free(dir);
} }
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0); setvbuf(infile, NULL, _IOLBF, 0);
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) { for (;;) {
char *cp; char *cp;
@ -2256,32 +2255,11 @@ connect_to_server(char *path, char **args, int *in, int *out)
#ifdef WINDOWS #ifdef WINDOWS
/* fork replacement on Windows */ /* fork replacement on Windows */
{ /* disable inheritance on local pipe ends*/
size_t cmdlen = 0; fcntl(pout[1], F_SETFD, FD_CLOEXEC);
int i = 0; fcntl(pin[0], F_SETFD, FD_CLOEXEC);
char* full_cmd;
cmdlen = strlen(path) + 1;
for (i = 1; args[i]; i++)
cmdlen += strlen(args[i]) + 1 + 2;
full_cmd = xmalloc(cmdlen);
full_cmd[0] = '\0';
strcat(full_cmd, path);
for (i = 1; args[i]; i++) {
strcat(full_cmd, " \"");
strcat(full_cmd, args[i]);
strcat(full_cmd, "\"");
}
/* disable inheritance on local pipe ends*/
fcntl(pout[1], F_SETFD, FD_CLOEXEC);
fcntl(pin[0], F_SETFD, FD_CLOEXEC);
sshpid = spawn_child(full_cmd, c_in, c_out, STDERR_FILENO, 0);
free(full_cmd);
}
sshpid = spawn_child(path, args + 1, c_in, c_out, STDERR_FILENO, 0);
if (sshpid == -1) if (sshpid == -1)
#else /* !WINDOWS */ #else /* !WINDOWS */
if ((sshpid = fork()) == -1) if ((sshpid = fork()) == -1)

View File

@ -492,12 +492,7 @@ main(int argc, char **argv)
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
#endif #endif
#ifdef WINDOWS
/* Min buffer size allowed in Windows is 2*/
setvbuf(stdout, NULL, _IOLBF, 2);
#else
setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stdout, NULL, _IOLBF, 0);
#endif
/* First, get a connection to the authentication agent. */ /* First, get a connection to the authentication agent. */
switch (r = ssh_get_authentication_socket(&agent_fd)) { switch (r = ssh_get_authentication_socket(&agent_fd)) {

6
sshd.c
View File

@ -1317,7 +1317,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
continue; continue;
} }
pid = spawn_child(path_utf8, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CREATE_NEW_PROCESS_GROUP); pid = spawn_child(path_utf8, NULL, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CREATE_NEW_PROCESS_GROUP);
free(path_utf8); free(path_utf8);
close(*newsock); close(*newsock);
} }
@ -1747,9 +1747,9 @@ main(int ac, char **av)
error("Could not connect to agent \"%s\": %s", error("Could not connect to agent \"%s\": %s",
options.host_key_agent, ssh_err(r)); options.host_key_agent, ssh_err(r));
} }
#ifdef WINDOWS /* Windows version always needs and has agent running */ #ifdef WINDOWS /* Windows version always needs and has agent running */
have_agent = 1; have_agent = 1;
#endif #endif
for (i = 0; i < options.num_host_key_files; i++) { for (i = 0; i < options.num_host_key_files; i++) {
if (options.host_key_files[i] == NULL) if (options.host_key_files[i] == NULL)
continue; continue;

View File

@ -53,57 +53,6 @@
# endif # endif
#endif #endif
#ifdef WINDOWS
/*
* Windows versions of pty_*. Some of them are NO-OPs and should go
* away when pty logic is refactored and abstracted out
*
*/
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
/*
* Simple console screen implementation in Win32 to give a
* Unix like pty for interactive sessions
*/
*ttyfd = 0;
*ptyfd = 0;
strlcpy(namebuf, "console", namebuflen);
return 1;
}
void
pty_release(const char *tty) {
/* NO-OP */
}
void
pty_make_controlling_tty(int *ttyfd, const char *tty) {
/* NO-OP */
}
void
pty_change_window_size(int ptyfd, u_int row, u_int col,
u_int xpixel, u_int ypixel) {
COORD coord;
coord.X = col;
coord.Y = 9999;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void
pty_setowner(struct passwd *pw, const char *tty) {
/* NO-OP */
}
void
disconnect_controlling_tty(void) {
/* NO-OP */
}
#else
/* /*
* Allocates and opens a pty. Returns 0 if no pty could be allocated, or * Allocates and opens a pty. Returns 0 if no pty could be allocated, or
* nonzero if a pty was successfully allocated. On success, open file * nonzero if a pty was successfully allocated. On success, open file
@ -303,4 +252,3 @@ disconnect_controlling_tty(void)
} }
#endif /* TIOCNOTTY */ #endif /* TIOCNOTTY */
} }
#endif

View File

@ -47,37 +47,6 @@
static struct termios _saved_tio; static struct termios _saved_tio;
static int _in_raw_mode = 0; static int _in_raw_mode = 0;
#ifdef WINDOWS
/*
* TTY raw mode routines for Windows
*/
int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
int ConExitRawMode(void);
struct termios term_settings;
/*
* TODO - clean this up for Windows, ConInit should return previous terminal
* settings that need to be stored in term_settings
*/
struct termios *
get_saved_tio(void) {
memset(&term_settings, 0, sizeof(term_settings));
return &term_settings;
}
void
leave_raw_mode(int quiet) {
ConExitRawMode();
}
void
enter_raw_mode(int quiet) {
ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE);
}
#else /* !WINDOWS */
struct termios * struct termios *
get_saved_tio(void) get_saved_tio(void)
{ {
@ -125,4 +94,3 @@ enter_raw_mode(int quiet)
} else } else
_in_raw_mode = 1; _in_raw_mode = 1;
} }
#endif /* !WINDOWS */

1
utf8.c
View File

@ -332,4 +332,3 @@ msetlocale(void)
/* We can handle this locale */ /* We can handle this locale */
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
} }