Source snapshot from Powershell/openssh-portable:latestw_cwb

This commit is contained in:
Manoj Ampalam 2017-01-15 16:46:39 -08:00
parent a4b577b5a0
commit e85070d50e
31 changed files with 692 additions and 332 deletions

View File

@ -1,3 +1,4 @@
1. Prerequisites
---------------- ----------------
A C compiler. Any C89 or better compiler should work. Where supported, A C compiler. Any C89 or better compiler should work. Where supported,
@ -231,7 +232,7 @@ manually using the following commands:
ssh-keygen -t [type] -f /etc/ssh/ssh_host_key -N "" ssh-keygen -t [type] -f /etc/ssh/ssh_host_key -N ""
for each of the types you wish to generate (rsa, dsa or ecdsaa) or for each of the types you wish to generate (rsa, dsa or ecdsa) or
ssh-keygen -A ssh-keygen -A

View File

@ -11,12 +11,12 @@ init:
build_script: build_script:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
Invoke-AppVeyorBuild Invoke-AppVeyorBuild
after_build: after_build:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
Install-OpenSSH Install-OpenSSH
- ps: Write-Verbose "Restart computer ..." - ps: Write-Verbose "Restart computer ..."
- ps: Restart-Computer -ComputerName localhost -Force - ps: Restart-Computer -ComputerName localhost -Force
@ -25,19 +25,19 @@ after_build:
before_test: before_test:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
Install-TestDependencies Install-TestDependencies
test_script: test_script:
- cmd: | - cmd: |
"%ProgramFiles%\PowerShell\6.0.0.12\powershell.exe" -Command "Import-Module \"%APPVEYOR_BUILD_FOLDER%\contrib\win32\openssh\AppVeyor.psm1\";Run-OpenSSHTests" "%ProgramFiles%\PowerShell\6.0.0.14\powershell.exe" -Command "Import-Module \"%APPVEYOR_BUILD_FOLDER%\contrib\win32\openssh\AppVeyor.psm1\" -WarningAction SilentlyContinue;Run-OpenSSHTests"
after_test: after_test:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
Upload-OpenSSHTestResults Upload-OpenSSHTestResults
on_finish: on_finish:
- ps: | - ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
Publish-Artifact Publish-Artifact

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth2-pubkey.c,v 1.60 2016/11/30 02:57:40 djm Exp $ */ /* $OpenBSD: auth2-pubkey.c,v 1.61 2016/12/30 22:08:02 djm Exp $ */
/* /*
* Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2000 Markus Friedl. All rights reserved.
* *
@ -783,6 +783,9 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
ok = process_principals(f, NULL, pw, cert); ok = process_principals(f, NULL, pw, cert);
fclose(f);
f = NULL;
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0)
goto out; goto out;
@ -1106,6 +1109,9 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
ok = check_authkeys_file(f, options.authorized_keys_command, key, pw); ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
fclose(f);
f = NULL;
if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0)
goto out; goto out;

View File

@ -1,6 +1,26 @@
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\build.psm1 Import-Module $PSScriptRoot\build.psm1
$repoRoot = Get-RepositoryRoot $repoRoot = Get-RepositoryRoot
$script:logFile = join-path $repoRoot.FullName "appveyorlog.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 # Sets a build variable
Function Set-BuildVariable Function Set-BuildVariable
@ -53,7 +73,7 @@ function Invoke-AppVeyorFull
Install-TestDependencies Install-TestDependencies
& "$env:ProgramFiles\PowerShell\6.0.0.12\powershell.exe" -Command {Import-Module $($repoRoot.FullName)\contrib\win32\openssh\AppVeyor.psm1;Run-OpenSSHTests -uploadResults} & "$env:ProgramFiles\PowerShell\6.0.0.12\powershell.exe" -Command {Import-Module $($repoRoot.FullName)\contrib\win32\openssh\AppVeyor.psm1;Run-OpenSSHTests -uploadResults}
Run-OpenSSHTests Run-OpenSSHTests
Publish-Artifact Publish-Artifact
} }
finally { finally {
if($APPVEYOR_SCHEDULED_BUILD -and $env:APPVEYOR_SCHEDULED_BUILD) if($APPVEYOR_SCHEDULED_BUILD -and $env:APPVEYOR_SCHEDULED_BUILD)
@ -66,10 +86,8 @@ function Invoke-AppVeyorFull
# Implements the AppVeyor 'build_script' step # Implements the AppVeyor 'build_script' step
function Invoke-AppVeyorBuild function Invoke-AppVeyorBuild
{ {
Start-SSHBuild -Configuration Release -NativeHostArch x64 -Verbose Start-SSHBuild -Configuration Release -NativeHostArch x64
Start-SSHBuild -Configuration Debug -NativeHostArch x64 -Verbose Start-SSHBuild -Configuration Debug -NativeHostArch x86
Start-SSHBuild -Configuration Release -NativeHostArch x86 -Verbose
Start-SSHBuild -Configuration Debug -NativeHostArch x86 -Verbose
} }
<# <#
@ -83,8 +101,8 @@ function Invoke-MSIEXEC
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
[string] $InstallFile [string] $InstallFile
) )
Write-Verbose "Installing $InstallFile..." Write-Log -Message "Installing $InstallFile..."
$arguments = @( $arguments = @(
"/i" "/i"
"`"$InstallFile`"" "`"$InstallFile`""
@ -93,10 +111,10 @@ function Invoke-MSIEXEC
) )
$process = Start-Process -FilePath msiexec.exe -ArgumentList $arguments -Wait -PassThru $process = Start-Process -FilePath msiexec.exe -ArgumentList $arguments -Wait -PassThru
if ($process.ExitCode -eq 0){ if ($process.ExitCode -eq 0){
Write-Output "$InstallFile has been successfully installed" Write-Log -Message "$InstallFile has been successfully installed."
} }
else { else {
Write-Output "installer exit code $($process.ExitCode) for file $($InstallFile)" Write-Log -Message "installer exit code $($process.ExitCode) for file $($InstallFile)"
} }
return $process.ExitCode return $process.ExitCode
@ -108,13 +126,13 @@ function Invoke-MSIEXEC
#> #>
function Install-PSCoreFromGithub function Install-PSCoreFromGithub
{ {
$downloadLocation = Download-PSCoreMSI $downloadLocation = Download-PSCoreMSI
Write-Output "Installing PSCore ..." Write-Log -Message "Installing PSCore ..."
if(-not [string]::IsNullOrEmpty($downloadLocation)) if(-not [string]::IsNullOrEmpty($downloadLocation))
{ {
$processExitCode = Invoke-MSIEXEC -InstallFile $downloadLocation $processExitCode = Invoke-MSIEXEC -InstallFile $downloadLocation
Write-Output "Process exitcode: $processExitCode" Write-Log -Message "Process exitcode: $processExitCode"
} }
} }
@ -125,27 +143,27 @@ function Install-PSCoreFromGithub
function Get-PSCoreMSIDownloadURL function Get-PSCoreMSIDownloadURL
{ {
$osversion = [String][Environment]::OSVersion.Version $osversion = [String][Environment]::OSVersion.Version
Write-Host "osversion:$osversion"
if($osversion.StartsWith("6")) if($osversion.StartsWith("6"))
{ {
if ($($env:PROCESSOR_ARCHITECTURE).Contains('64')) if ($($env:PROCESSOR_ARCHITECTURE).Contains('64'))
{ {
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.12/PowerShell_6.0.0.12-alpha.12-win81-x64.msi' return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win81-x64.msi'
} }
else else
{ {
return '' 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")) elseif ($osversion.Contains("10.0"))
{ {
if ($($env:PROCESSOR_ARCHITECTURE).Contains('64')) if ($($env:PROCESSOR_ARCHITECTURE).Contains('64'))
{ {
return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.12/PowerShell_6.0.0.12-alpha.12-win10-x64.msi' return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win10-x64.msi'
} }
else else
{ {
return '' return 'https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/PowerShell_6.0.0.14-alpha.14-win7-x86.msi'
} }
} }
} }
@ -158,14 +176,14 @@ function Download-PSCoreMSI
{ {
$url = Get-PSCoreMSIDownloadURL $url = Get-PSCoreMSIDownloadURL
if([string]::IsNullOrEmpty($url)) if([string]::IsNullOrEmpty($url))
{ {
Write-Output "url is empty" Write-Log -Message "url is empty"
return '' return ''
} }
$parsed = $url.Substring($url.LastIndexOf("/") + 1) $parsed = $url.Substring($url.LastIndexOf("/") + 1)
if(-not (Test-path "$env:SystemDrive\PScore" -PathType Container)) if(-not (Test-path "$env:SystemDrive\PScore" -PathType Container))
{ {
New-Item -ItemType Directory -Force -Path "$env:SystemDrive\PScore" | out-null $null = New-Item -ItemType Directory -Force -Path "$env:SystemDrive\PScore" | out-null
} }
$downloadLocation = "$env:SystemDrive\PScore\$parsed" $downloadLocation = "$env:SystemDrive\PScore\$parsed"
if(-not (Test-path $downloadLocation -PathType Leaf)) if(-not (Test-path $downloadLocation -PathType Leaf))
@ -196,16 +214,15 @@ function Install-TestDependencies
$isModuleAvailable = Get-Module 'Pester' -ListAvailable $isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable)) if (-not ($isModuleAvailable))
{ {
Write-Output 'Installing Pester...' Write-Log -Message "Installing Pester..."
choco install Pester -y --force choco install Pester -y --force --limitoutput
} }
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) { if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
Write-Output "sysinternals not present. Installing sysinternals." Write-Log -Message "sysinternals not present. Installing sysinternals."
choco install sysinternals -y choco install sysinternals -y --force --limitoutput
} }
Write-Output "Installing pscore..."
Install-PSCoreFromGithub Install-PSCoreFromGithub
} }
<# <#
@ -219,8 +236,8 @@ function Install-OpenSSH
( (
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH", [string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release')] [ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Debug", [string]$Configuration = "",
[ValidateSet('x86', 'x64', '')] [ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "" [string]$NativeHostArch = ""
@ -272,8 +289,8 @@ function Build-Win32OpenSSHPackage
( (
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH", [string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release')] [ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Debug", [string]$Configuration = "",
[ValidateSet('x86', 'x64', '')] [ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "" [string]$NativeHostArch = ""
@ -281,32 +298,49 @@ function Build-Win32OpenSSHPackage
if (-not (Test-Path -Path $OpenSSHDir -PathType Container)) if (-not (Test-Path -Path $OpenSSHDir -PathType Container))
{ {
New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop $null = New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop
} }
[string] $platform = $env:PROCESSOR_ARCHITECTURE [string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch)) if(-not [String]::IsNullOrEmpty($NativeHostArch))
{ {
$folderName = $NativeHostArch $folderName = $NativeHostArch
if($NativeHostArch -eq 'x86') if($NativeHostArch -ieq 'x86')
{ {
$folderName = "Win32" $folderName = "Win32"
} }
} }
else else
{ {
if($platform -ieq "AMD64") if($platform -ieq "AMD64")
{ {
$folderName = "x64" $folderName = "x64"
} }
else else
{ {
$folderName = "Win32" $folderName = "Win32"
} }
} }
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$Configuration" $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "contrib\win32\openssh" $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 Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.ps1,sshd_config -Exclude AnalyzeCodeDiff.ps1 -Force -ErrorAction Stop
@ -314,8 +348,8 @@ function Build-Win32OpenSSHPackage
$packageName = "rktools.2003" $packageName = "rktools.2003"
$rktoolsPath = "${env:ProgramFiles(x86)}\Windows Resource Kits\Tools\ntrights.exe" $rktoolsPath = "${env:ProgramFiles(x86)}\Windows Resource Kits\Tools\ntrights.exe"
if (-not (Test-Path -Path $rktoolsPath)) if (-not (Test-Path -Path $rktoolsPath))
{ {
Write-Information -MessageData "$packageName not present. Installing $packageName." Write-Log -Message "$packageName not present. Installing $packageName."
choco install $packageName -y --force choco install $packageName -y --force
} }
@ -327,7 +361,7 @@ function Build-Win32OpenSSHPackage
$packageFolder = $env:APPVEYOR_BUILD_FOLDER $packageFolder = $env:APPVEYOR_BUILD_FOLDER
} }
$package = "$packageFolder\Win32OpenSSH$Configuration$folderName.zip" $package = "$packageFolder\Win32OpenSSH$RealConfiguration$folderName.zip"
$allPackage = "$packageFolder\Win32OpenSSH*.zip" $allPackage = "$packageFolder\Win32OpenSSH*.zip"
if (Test-Path $allPackage) if (Test-Path $allPackage)
{ {
@ -349,8 +383,8 @@ function Deploy-OpenSSHTests
( (
[string] $OpenSSHTestDir = "$env:SystemDrive\OpenSSH", [string] $OpenSSHTestDir = "$env:SystemDrive\OpenSSH",
[ValidateSet('Debug', 'Release')] [ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Debug", [string]$Configuration = "",
[ValidateSet('x86', 'x64', '')] [ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "" [string]$NativeHostArch = ""
@ -358,7 +392,7 @@ function Deploy-OpenSSHTests
if (-not (Test-Path -Path $OpenSSHTestDir -PathType Container)) if (-not (Test-Path -Path $OpenSSHTestDir -PathType Container))
{ {
New-Item -Path $OpenSSHTestDir -ItemType Directory -Force -ErrorAction Stop $null = New-Item -Path $OpenSSHTestDir -ItemType Directory -Force -ErrorAction Stop
} }
[string] $platform = $env:PROCESSOR_ARCHITECTURE [string] $platform = $env:PROCESSOR_ARCHITECTURE
@ -381,6 +415,22 @@ function Deploy-OpenSSHTests
$folderName = "Win32" $folderName = "Win32"
} }
} }
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
@ -388,9 +438,8 @@ function Deploy-OpenSSHTests
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests" $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1 -Force -ErrorAction Stop Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1 -Force -ErrorAction Stop
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$Configuration" $sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Exclude ssh-agent.exe, sshd.exe -Force -ErrorAction Stop Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Exclude ssh-agent.exe, sshd.exe -Force -ErrorAction Stop
} }
@ -419,10 +468,8 @@ function Add-BuildLog
) )
if (Test-Path -Path $buildLog) if (Test-Path -Path $buildLog)
{ {
Write-Output "Adding $buildLog to local artifacts"
$null = $artifacts.Add($buildLog) $null = $artifacts.Add($buildLog)
Write-Output "Adding $buildLog to local artifacts- completed"
} }
else else
{ {
@ -449,14 +496,10 @@ function Add-Artifact
$files = Get-ChildItem -Path $FileToAdd -ErrorAction Ignore $files = Get-ChildItem -Path $FileToAdd -ErrorAction Ignore
if ($files -ne $null) if ($files -ne $null)
{ {
$files | % { $files | % {
Write-Output "Adding $($_.FullName) to local artifacts" $null = $artifacts.Add($_.FullName)
$null = $artifacts.Add($_.FullName) }
Write-Output "Adding $($_.FullName) to local artifacts- completed"
}
} }
else else
{ {
@ -480,13 +523,11 @@ function Publish-Artifact
} }
Add-Artifact -artifacts $artifacts -FileToAdd "$packageFolder\Win32OpenSSH*.zip" Add-Artifact -artifacts $artifacts -FileToAdd "$packageFolder\Win32OpenSSH*.zip"
Add-Artifact -artifacts $artifacts -FileToAdd "$packageFolder\OpenSSH\UnitTestResults.txt" Add-Artifact -artifacts $artifacts -FileToAdd "$env:SystemDrive\OpenSSH\UnitTestResults.txt"
Add-Artifact -artifacts $artifacts -FileToAdd "$script:logFile"
# Get the build.log file for each build configuration # Get the build.log file for each build configuration
#Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Release -NativeHostArch x86) Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName)
#Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Debug -NativeHostArch x86)
#Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Release -NativeHostArch x64)
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Debug -NativeHostArch x64)
foreach ($artifact in $artifacts) foreach ($artifact in $artifacts)
{ {
@ -505,11 +546,11 @@ function Run-OpenSSHPesterTest
param($testRoot, $outputXml) param($testRoot, $outputXml)
# Discover all CI tests and run them. # Discover all CI tests and run them.
Push-Location $testRoot Push-Location $testRoot
Write-Output "Running OpenSSH Pester tests..." Write-Log -Message "Running OpenSSH Pester tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique $testFolders = Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $outputXml -Tag 'CI' Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $outputXml -Tag 'CI'
Pop-Location Pop-Location
} }
@ -522,8 +563,8 @@ function Run-OpenSSHUnitTest
param($testRoot, $unitTestOutputFile) param($testRoot, $unitTestOutputFile)
# Discover all CI tests and run them. # Discover all CI tests and run them.
Push-Location $testRoot Push-Location $testRoot
Write-Output "Running OpenSSH unit tests..." Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $unitTestOutputFile) if (Test-Path $unitTestOutputFile)
{ {
Remove-Item -Path $unitTestOutputFile -Force -ErrorAction SilentlyContinue Remove-Item -Path $unitTestOutputFile -Force -ErrorAction SilentlyContinue
@ -534,13 +575,13 @@ function Run-OpenSSHUnitTest
if ($unitTestFiles -ne $null) if ($unitTestFiles -ne $null)
{ {
$unitTestFiles | % { $unitTestFiles | % {
Write-Output "Running OpenSSH unit $($_.FullName)..." Write-Log -Message "Running OpenSSH unit $($_.FullName)..."
& $_.FullName >> $unitTestOutputFile & $_.FullName >> $unitTestOutputFile
$errorCode = $LASTEXITCODE $errorCode = $LASTEXITCODE
if ($errorCode -ne 0) if ($errorCode -ne 0)
{ {
$testFailed = $true $testFailed = $true
Write-Output "$($_.FullName) test failed for OpenSSH.`nExitCode: $error" Write-Log -Message "$($_.FullName) test failed for OpenSSH.`nExitCode: $error"
} }
} }
@ -614,6 +655,5 @@ function Upload-OpenSSHTestResults
if ($env:APPVEYOR_JOB_ID) if ($env:APPVEYOR_JOB_ID)
{ {
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile))
} }
} }

View File

@ -133,15 +133,14 @@ function Write-BuildMsg
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-SSHBootstrap
{ {
[bool] $silent = -not $script:Verbose
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath $newMachineEnvironmentPath = $machinePath
# NOTE: Unless -Verbose is specified, most informational output will only go to the log file.
[bool] $silent = -not $script:Verbose
# Install chocolatey # Install chocolatey
$chocolateyPath = "$env:AllUsersProfile\chocolatey\bin" $chocolateyPath = "$env:AllUsersProfile\chocolatey\bin"
@ -151,18 +150,18 @@ function Start-SSHBootstrap
} }
else else
{ {
Write-BuildMsg -AsInfo -Message "Chocolatey not present. Installing chocolatey." Write-BuildMsg -AsInfo -Message "Chocolatey not present. Installing chocolatey." -Silent:$silent
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower()))) if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower())))
{ {
Write-BuildMsg -AsVerbose -Message "Adding $chocolateyPath to Path environment variable" Write-BuildMsg -AsVerbose -Message "Adding $chocolateyPath to Path environment variable" -Silent:$silent
$newMachineEnvironmentPath += ";$chocolateyPath" $newMachineEnvironmentPath += ";$chocolateyPath"
$env:Path += ";$chocolateyPath" $env:Path += ";$chocolateyPath"
} }
else else
{ {
Write-BuildMsg -AsVerbose -Message "$chocolateyPath already present in Path environment variable" Write-BuildMsg -AsVerbose -Message "$chocolateyPath already present in Path environment variable" -Silent:$silent
} }
} }
@ -170,7 +169,7 @@ function Start-SSHBootstrap
$gitCmdPath = "$env:ProgramFiles\git\cmd" $gitCmdPath = "$env:ProgramFiles\git\cmd"
if (-not ($machinePath.ToLower().Contains($gitCmdPath.ToLower()))) if (-not ($machinePath.ToLower().Contains($gitCmdPath.ToLower())))
{ {
Write-BuildMsg -AsVerbose -Message "Adding $gitCmdPath to Path environment variable" Write-BuildMsg -AsVerbose -Message "Adding $gitCmdPath to Path environment variable" -Silent:$silent
$newMachineEnvironmentPath = "$gitCmdPath;$newMachineEnvironmentPath" $newMachineEnvironmentPath = "$gitCmdPath;$newMachineEnvironmentPath"
} }
else else
@ -186,7 +185,7 @@ function Start-SSHBootstrap
if (-not ($machinePath.ToLower().Contains($nativeMSBuildPath.ToLower()))) if (-not ($machinePath.ToLower().Contains($nativeMSBuildPath.ToLower())))
{ {
Write-BuildMsg -AsVerbose -Message "Adding $nativeMSBuildPath to Path environment variable" Write-BuildMsg -AsVerbose -Message "Adding $nativeMSBuildPath to Path environment variable" -Silent:$silent
$newMachineEnvironmentPath += ";$nativeMSBuildPath" $newMachineEnvironmentPath += ";$nativeMSBuildPath"
$env:Path += ";$nativeMSBuildPath" $env:Path += ";$nativeMSBuildPath"
} }
@ -207,8 +206,8 @@ function Start-SSHBootstrap
if (-not (Test-Path -Path $nasmPath -PathType Container)) if (-not (Test-Path -Path $nasmPath -PathType Container))
{ {
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." -Silent:$silent
choco install $packageName -y --force --execution-timeout 10000 choco install $packageName -y --force --limitoutput --execution-timeout 10000
} }
else else
{ {
@ -221,9 +220,9 @@ function Start-SSHBootstrap
if ($null -eq $VSPackageInstalled) if ($null -eq $VSPackageInstalled)
{ {
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." -Silent:$silent
$adminFilePath = "$script:OpenSSHRoot\contrib\win32\openssh\VSWithBuildTools.xml" $adminFilePath = "$script:OpenSSHRoot\contrib\win32\openssh\VSWithBuildTools.xml"
choco install $packageName -packageParameters "--AdminFile $adminFilePath" -y --force --execution-timeout 10000 choco install $packageName -packageParameters "--AdminFile $adminFilePath" -y --force --limitoutput --execution-timeout 10000
} }
else else
{ {
@ -236,8 +235,8 @@ function Start-SSHBootstrap
if (-not (Test-Path -Path $sdkPath)) if (-not (Test-Path -Path $sdkPath))
{ {
Write-BuildMsg -AsInfo -Message "Windows 8.1 SDK not present. Installing $packageName." Write-BuildMsg -AsInfo -Message "Windows 8.1 SDK not present. Installing $packageName." -Silent:$silent
choco install $packageName -y --force choco install $packageName -y --limitoutput --force
} }
else else
{ {
@ -262,7 +261,7 @@ function Start-SSHBootstrap
$item = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc') $item = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc')
$script:vcPath = $item.FullName $script:vcPath = $item.FullName
Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" -Silent:$silent
if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false) if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false)
{ {
Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at" + $script:vcPath Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at" + $script:vcPath
@ -270,16 +269,18 @@ function Start-SSHBootstrap
} }
function Clone-Win32OpenSSH function Clone-Win32OpenSSH
{ {
[bool] $silent = -not $script:Verbose
$win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH" $win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
if (-not (Test-Path -Path $win32OpenSSHPath -PathType Container)) if (-not (Test-Path -Path $win32OpenSSHPath -PathType Container))
{ {
Write-BuildMsg -AsInfo -Message "clone repo Win32-OpenSSH" Write-BuildMsg -AsInfo -Message "clone repo Win32-OpenSSH" -Silent:$silent
Push-Location $gitRoot Push-Location $gitRoot
git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath
Pop-Location Pop-Location
} }
Write-BuildMsg -AsInfo -Message "pull latest from repo Win32-OpenSSH" Write-BuildMsg -AsInfo -Message "pull latest from repo Win32-OpenSSH" -Silent:$silent
Push-Location $win32OpenSSHPath Push-Location $win32OpenSSHPath
git fetch -q origin git fetch -q origin
git checkout -qf L1-Prod git checkout -qf L1-Prod
@ -287,9 +288,11 @@ function Clone-Win32OpenSSH
} }
function Copy-OpenSSLSDK function Copy-OpenSSLSDK
{ {
[bool] $silent = -not $script:Verbose
$sourcePath = Join-Path $script:gitRoot "Win32-OpenSSH\contrib\win32\openssh\OpenSSLSDK" $sourcePath = Join-Path $script:gitRoot "Win32-OpenSSH\contrib\win32\openssh\OpenSSLSDK"
Write-BuildMsg -AsInfo -Message "copying $sourcePath" Write-BuildMsg -AsInfo -Message "copying $sourcePath" -Silent:$silent
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
if($e -ne $null) if($e -ne $null)
{ {
@ -306,7 +309,7 @@ function Start-SSHBuild
[string]$NativeHostArch = "x64", [string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')] [ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Debug" [string]$Configuration = "Release"
) )
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$script:BuildLogFile = $null $script:BuildLogFile = $null
@ -321,16 +324,16 @@ function Start-SSHBuild
if($PSBoundParameters.ContainsKey("Verbose")) if($PSBoundParameters.ContainsKey("Verbose"))
{ {
$script:Verbose = ($PSBoundParameters['Verbose']).IsPresent $script:Verbose = ($PSBoundParameters['Verbose']).IsPresent
} }
[bool] $silent = -not $script:Verbose
$script:BuildLogFile = Get-BuildLogFile -root $repositoryRoot.FullName -Configuration $Configuration -NativeHostArch $NativeHostArch $script:BuildLogFile = Get-BuildLogFile -root $repositoryRoot.FullName -Configuration $Configuration -NativeHostArch $NativeHostArch
if (Test-Path -Path $script:BuildLogFile) if (Test-Path -Path $script:BuildLogFile)
{ {
Remove-Item -Path $script:BuildLogFile Remove-Item -Path $script:BuildLogFile
} }
Write-BuildMsg -AsInfo -Message "Starting Open SSH build." Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)"
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
Start-SSHBootstrap Start-SSHBootstrap
@ -338,20 +341,19 @@ function Start-SSHBuild
Copy-OpenSSLSDK Copy-OpenSSLSDK
$msbuildCmd = "msbuild.exe" $msbuildCmd = "msbuild.exe"
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName $solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic") $cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/noconlog", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
#$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
Write-Information -MessageData $msbuildCmd
Write-Information -MessageData $cmdMsg
& $msbuildCmd $cmdMsg & $msbuildCmd $cmdMsg
$errorCode = $LASTEXITCODE $errorCode = $LASTEXITCODE
if ($errorCode -ne 0) if ($errorCode -ne 0)
{ {
Write-BuildMsg -AsError -ErrorAction Stop -Message "Build failed for OpenSSH.`nExitCode: $error" Write-BuildMsg -AsError -ErrorAction Stop -Message "Build failed for OpenSSH.`nExitCode: $error."
} }
Write-BuildMsg -AsVerbose -Message "Finished Open SSH build." Write-BuildMsg -AsInfo -Message "SSH build passed."
} }
function Get-BuildLogFile function Get-BuildLogFile
@ -366,10 +368,10 @@ function Get-BuildLogFile
[string]$NativeHostArch = "x64", [string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')] [ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Debug" [string]$Configuration = "Release"
) )
return Join-Path -Path $root -ChildPath "contrib\win32\openssh\OpenSSH$($Configuration)$($NativeHostArch).log" return Join-Path -Path $root -ChildPath "contrib\win32\openssh\OpenSSH$($Configuration)$($NativeHostArch).log"
} }
function Get-SolutionFile function Get-SolutionFile
@ -414,4 +416,4 @@ function Get-RepositoryRoot
throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository") throw new-object System.IO.DirectoryNotFoundException("Could not find the root of the GIT repository")
} }
Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile, Clone-Win32OpenSSH, Copy-OpenSSLSDK Export-ModuleMember -Function Start-SSHBuild, Get-RepositoryRoot, Get-BuildLogFile, Clone-Win32OpenSSH, Copy-OpenSSLSDK, Write-BuildMsg

Binary file not shown.

View File

@ -37,6 +37,7 @@
#include <errno.h> #include <errno.h>
#include <stddef.h> #include <stddef.h>
#include "inc\utf.h" #include "inc\utf.h"
#include "misc_internal.h"
/* internal read buffer size */ /* internal read buffer size */
#define READ_BUFFER_SIZE 100*1024 #define READ_BUFFER_SIZE 100*1024
@ -76,7 +77,7 @@ int
fileio_pipe(struct w32_io* pio[2]) { fileio_pipe(struct w32_io* pio[2]) {
HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE; HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
struct w32_io *pio_read = NULL, *pio_write = NULL; struct w32_io *pio_read = NULL, *pio_write = NULL;
char pipe_name[MAX_PATH]; char pipe_name[PATH_MAX];
SECURITY_ATTRIBUTES sec_attributes; SECURITY_ATTRIBUTES sec_attributes;
if (pio == NULL) { if (pio == NULL) {
@ -86,7 +87,7 @@ fileio_pipe(struct w32_io* pio[2]) {
} }
/* create name for named pipe */ /* create name for named pipe */
if (-1 == sprintf_s(pipe_name, MAX_PATH, "\\\\.\\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); debug("pipe - ERROR sprintf_s %d", errno);
@ -564,15 +565,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
int int
fileio_stat(const char *path, struct _stat64 *buf) { fileio_stat(const char *path, struct _stat64 *buf) {
wchar_t wpath[MAX_PATH]; wchar_t wpath[PATH_MAX];
wchar_t* wtmp = NULL; wchar_t* wtmp = NULL;
if ((wtmp = utf8_to_utf16(path)) == NULL) if ((wtmp = utf8_to_utf16(path)) == NULL)
fatal("failed to covert input arguments"); fatal("failed to covert input arguments");
wcscpy(&wpath[0], wtmp); wcscpy(&wpath[0], wtmp);
free(wtmp); free(wtmp);
return _wstat64(wpath, buf); return _wstat64(wpath, buf);
} }
long long
@ -597,8 +598,6 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
debug2("fdopen - io:%p", pio); debug2("fdopen - io:%p", pio);
/* logic below doesn't work with overlapped file HANDLES */ /* logic below doesn't work with overlapped file HANDLES */
errno = ENOTSUP;
return NULL;
if (mode[1] == '\0') { if (mode[1] == '\0') {
switch (*mode) { switch (*mode) {

View File

@ -10,10 +10,11 @@
#include <direct.h> #include <direct.h>
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
#include "..\misc_internal.h"
struct dirent { struct dirent {
int d_ino; /* Inode number */ int d_ino; /* Inode number */
char d_name[256]; /* Null-terminated filename */ char d_name[PATH_MAX]; /* Null-terminated filename */
}; };
typedef struct DIR_ DIR; typedef struct DIR_ DIR;

View File

@ -154,6 +154,8 @@ explicit_bzero(void *b, size_t len);
/* string.h overrides */ /* string.h overrides */
#define strcasecmp _stricmp #define strcasecmp _stricmp
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
char *w32_strerror(int);
#define strerror w32_strerror
/* stdio.h overrides */ /* stdio.h overrides */
#define fopen w32_fopen_utf8 #define fopen w32_fopen_utf8

View File

@ -38,6 +38,7 @@
#include <NTSecPkg.h> #include <NTSecPkg.h>
#include <ntstatus.h> #include <ntstatus.h>
#include <stdio.h> #include <stdio.h>
#include "..\misc_internal.h"
#define Unsigned unsigned #define Unsigned unsigned
#define Char char #define Char char
@ -264,7 +265,7 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
UNICODE_STRING *flatName = NULL; UNICODE_STRING *flatName = NULL;
UCHAR *userAuth = NULL; UCHAR *userAuth = NULL;
ULONG userAuthSize; ULONG userAuthSize;
wchar_t homeDir[MAX_PATH]; wchar_t homeDir[PATH_MAX];
TOKEN_SOURCE tokenSource; TOKEN_SOURCE tokenSource;
HANDLE token = NULL; HANDLE token = NULL;
@ -292,9 +293,9 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
*authority, &token, logonId, *authority, &token, logonId,
*accountName, subStat)); *accountName, subStat));
NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile)); NTFAIL(LsaApi.AllocateClientBuffer(request, PATH_MAX * sizeof(wchar_t), profile));
*profileSize = MAX_PATH; *profileSize = PATH_MAX;
NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t), NTFAIL(LsaApi.CopyToClientBuffer(request, PATH_MAX * sizeof(wchar_t),
*profile, homeDir)); *profile, homeDir));
PLSA_TOKEN_INFORMATION_V1 outTokenInfo; PLSA_TOKEN_INFORMATION_V1 outTokenInfo;

View File

@ -37,6 +37,8 @@
#include <time.h> #include <time.h>
#include <Shlwapi.h> #include <Shlwapi.h>
#include "misc_internal.h" #include "misc_internal.h"
#include "inc\dlfcn.h"
#include "inc\dirent.h"
int usleep(unsigned int useconds) int usleep(unsigned int useconds)
{ {
@ -114,51 +116,6 @@ explicit_bzero(void *b, size_t len) {
SecureZeroMemory(b, len); SecureZeroMemory(b, len);
} }
int statvfs(const char *path, struct statvfs *buf) {
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD freeClusters;
DWORD totalClusters;
if (GetDiskFreeSpace(path, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE)
{
debug3("path : [%s]", path);
debug3("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug3("bytesPerSector : [%lu]", bytesPerSector);
debug3("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector);
debug3("freeClusters : [%lu]", freeClusters);
debug3("totalClusters : [%lu]", totalClusters);
buf->f_bsize = sectorsPerCluster * bytesPerSector;
buf->f_frsize = sectorsPerCluster * bytesPerSector;
buf->f_blocks = totalClusters;
buf->f_bfree = freeClusters;
buf->f_bavail = freeClusters;
buf->f_files = -1;
buf->f_ffree = -1;
buf->f_favail = -1;
buf->f_fsid = 0;
buf->f_flag = 0;
buf->f_namemax = MAX_PATH - 1;
return 0;
}
else
{
debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n",
path, GetLastError());
return -1;
}
}
int fstatvfs(int fd, struct statvfs *buf) {
errno = ENOTSUP;
return -1;
}
#include "inc\dlfcn.h"
HMODULE dlopen(const char *filename, int flags) { HMODULE dlopen(const char *filename, int flags) {
return LoadLibraryA(filename); return LoadLibraryA(filename);
} }
@ -178,7 +135,7 @@ FARPROC dlsym(HMODULE handle, const char *symbol) {
*/ */
FILE* FILE*
w32_fopen_utf8(const char *path, const char *mode) { w32_fopen_utf8(const char *path, const char *mode) {
wchar_t wpath[MAX_PATH], wmode[5]; wchar_t wpath[PATH_MAX], wmode[5];
FILE* f; FILE* f;
char utf8_bom[] = { 0xEF,0xBB,0xBF }; char utf8_bom[] = { 0xEF,0xBB,0xBF };
char first3_bytes[3]; char first3_bytes[3];
@ -188,7 +145,7 @@ w32_fopen_utf8(const char *path, const char *mode) {
return NULL; return NULL;
} }
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH) == 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()); debug("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError());
@ -480,10 +437,16 @@ strmode(mode_t mode, char *p)
} }
int int
w32_chmod(const char *pathname, mode_t mode) { w32_chmod(const char *pathname, mode_t mode) {
/* TODO - implement this */ int ret;
errno = EOPNOTSUPP; wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(pathname));
return -1; if (resolvedPathName_utf16 == NULL) {
errno = ENOMEM;
return -1;
}
ret = _wchmod(resolvedPathName_utf16, mode);
free(resolvedPathName_utf16);
return ret;
} }
int int
@ -493,20 +456,55 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
return -1; return -1;
} }
static void
unix_time_to_file_time(ULONG t, LPFILETIME pft) {
ULONGLONG ull;
ull = UInt32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ull;
pft->dwHighDateTime = (DWORD)(ull >> 32);
}
static int
settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime) {
HANDLE handle;
handle = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (handle == INVALID_HANDLE_VALUE) {
/* TODO - convert Win32 error to errno */
errno = GetLastError();
debug("w32_settimes - CreateFileW ERROR:%d", errno);
return -1;
}
if (SetFileTime(handle, cretime, acttime, modtime) == 0) {
errno = GetLastError();
debug("w32_settimes - SetFileTime ERROR:%d", errno);
CloseHandle(handle);
return -1;
}
CloseHandle(handle);
return 0;
}
int int
w32_utimes(const char *filename, struct timeval *tvp) { w32_utimes(const char *filename, struct timeval *tvp) {
struct utimbuf ub;
ub.actime = tvp[0].tv_sec;
ub.modtime = tvp[1].tv_sec;
int ret; int ret;
FILETIME acttime, modtime;
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename)); wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
if (resolvedPathName_utf16 == NULL) { if (resolvedPathName_utf16 == NULL) {
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
memset(&acttime, 0, sizeof(FILETIME));
memset(&modtime, 0, sizeof(FILETIME));
ret = _wutime(resolvedPathName_utf16, &ub); unix_time_to_file_time((ULONG)tvp[0].tv_sec, &acttime);
unix_time_to_file_time((ULONG)tvp[1].tv_sec, &modtime);
ret = settimes(resolvedPathName_utf16, NULL, &acttime, &modtime);
free(resolvedPathName_utf16); free(resolvedPathName_utf16);
return ret; return ret;
} }
@ -535,6 +533,28 @@ w32_rename(const char *old_name, const char *new_name) {
return -1; return -1;
} }
/*
* To be consistent with linux rename(),
* 1) if the new_name is file, then delete it so that _wrename will succeed.
* 2) if the new_name is directory and it is empty then delete it so that _wrename will succeed.
*/
struct _stat64 st;
if (fileio_stat(sanitized_path(new_name), &st) != -1) {
if(((st.st_mode & _S_IFMT) == _S_IFREG)) {
w32_unlink(new_name);
} else {
DIR *dirp = opendir(new_name);
if (NULL != dirp) {
struct dirent *dp = readdir(dirp);
closedir(dirp);
if (dp == NULL) {
w32_rmdir(new_name);
}
}
}
}
int returnStatus = _wrename(resolvedOldPathName_utf16, resolvedNewPathName_utf16); int returnStatus = _wrename(resolvedOldPathName_utf16, resolvedNewPathName_utf16);
free(resolvedOldPathName_utf16); free(resolvedOldPathName_utf16);
free(resolvedNewPathName_utf16); free(resolvedNewPathName_utf16);
@ -587,10 +607,10 @@ w32_chdir(const char *dirname_utf8) {
char * char *
w32_getcwd(char *buffer, int maxlen) { w32_getcwd(char *buffer, int maxlen) {
wchar_t wdirname[MAX_PATH]; wchar_t wdirname[PATH_MAX];
char* putf8 = NULL; char* putf8 = NULL;
_wgetcwd(&wdirname[0], MAX_PATH); _wgetcwd(&wdirname[0], PATH_MAX);
if ((putf8 = utf16_to_utf8(&wdirname[0])) == NULL) if ((putf8 = utf16_to_utf8(&wdirname[0])) == NULL)
fatal("failed to convert input arguments"); fatal("failed to convert input arguments");
@ -609,8 +629,17 @@ w32_mkdir(const char *path_utf8, unsigned short mode) {
return -1; return -1;
} }
int returnStatus = _wmkdir(path_utf16); int returnStatus = _wmkdir(path_utf16);
if (returnStatus < 0) {
free(path_utf16);
return -1;
}
mode_t curmask = _umask(0);
_umask(curmask);
returnStatus = _wchmod(path_utf16, mode & ~curmask & (_S_IREAD | _S_IWRITE));
free(path_utf16); free(path_utf16);
return returnStatus; return returnStatus;
} }
@ -648,19 +677,25 @@ convertToForwardslash(char *str) {
} }
/* /*
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by * This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
* path to produce a canonicalized absolute pathname. * path to produce a canonicalized absolute pathname.
*/ */
char * char *
realpath(const char *path, char resolved[MAX_PATH]) { realpath(const char *path, char resolved[PATH_MAX]) {
char tempPath[MAX_PATH]; char tempPath[PATH_MAX];
if (*path == '/' && *(path + 2) == ':') if ((path[0] == '/') && path[1] && (path[2] == ':')) {
strncpy(resolved, path + 1, strlen(path)); // skip the first '/' strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
else } else {
strncpy(resolved, path, strlen(path) + 1); strncpy(resolved, path, strlen(path) + 1);
}
if (_fullpath(tempPath, resolved, MAX_PATH) == NULL) if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { // make "x:" as "x:\\"
resolved[2] = '\\';
resolved[3] = '\0';
}
if (_fullpath(tempPath, resolved, PATH_MAX) == NULL)
return NULL; return NULL;
convertToForwardslash(tempPath); convertToForwardslash(tempPath);
@ -670,6 +705,27 @@ realpath(const char *path, char resolved[MAX_PATH]) {
return resolved; return resolved;
} }
char*
sanitized_path(const char *path) {
static char newPath[PATH_MAX] = { '\0', };
if (path[0] == '/' && path[1]) {
if (path[2] == ':') {
if (path[3] == '\0') { // make "/x:" as "x:\\"
strncpy(newPath, path + 1, strlen(path) - 1);
newPath[2] = '\\';
newPath[3] = '\0';
return newPath;
} else {
return (char *)(path + 1); // skip the first "/"
}
}
}
return (char *)path;
}
// Maximum reparse buffer info size. The max user defined reparse // Maximum reparse buffer info size. The max user defined reparse
// data is 16KB, plus there's a header. // data is 16KB, plus there's a header.
#define MAX_REPARSE_SIZE 17000 #define MAX_REPARSE_SIZE 17000
@ -677,8 +733,7 @@ realpath(const char *path, char resolved[MAX_PATH]) {
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt ntifs #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt ntifs
#define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt ntifs #define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt ntifs
#define IO_REPARSE_TAG_SIS (0x80000007L) // winnt ntifs #define IO_REPARSE_TAG_SIS (0x80000007L) // winnt ntifs
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8 #define REPARSE_MOUNTPOINT_HEADER_SIZE 8
typedef struct _REPARSE_DATA_BUFFER { typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag; ULONG ReparseTag;
@ -778,4 +833,107 @@ ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) {
CloseHandle(fileHandle); CloseHandle(fileHandle);
return TRUE; return TRUE;
} }
int statvfs(const char *path, struct statvfs *buf) {
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD freeClusters;
DWORD totalClusters;
wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path));
if (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE)
{
debug3("path : [%s]", path);
debug3("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug3("bytesPerSector : [%lu]", bytesPerSector);
debug3("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector);
debug3("freeClusters : [%lu]", freeClusters);
debug3("totalClusters : [%lu]", totalClusters);
buf->f_bsize = sectorsPerCluster * bytesPerSector;
buf->f_frsize = sectorsPerCluster * bytesPerSector;
buf->f_blocks = totalClusters;
buf->f_bfree = freeClusters;
buf->f_bavail = freeClusters;
buf->f_files = -1;
buf->f_ffree = -1;
buf->f_favail = -1;
buf->f_fsid = 0;
buf->f_flag = 0;
buf->f_namemax = PATH_MAX - 1;
free(path_utf16);
return 0;
}
else
{
debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n",
path, GetLastError());
free(path_utf16);
return -1;
}
}
int fstatvfs(int fd, struct statvfs *buf) {
errno = ENOTSUP;
return -1;
}
/* w32_strerror start */
/* Windows CRT defines error string messages only till 43 in errno.h*/
/* This is an extended list that defines messages for EADDRINUSE through EWOULDBLOCK*/
char* _sys_errlist_ext[] = {
"Address already in use", // EADDRINUSE 100
"Address not available", // EADDRNOTAVAIL 101
"Address family not supported", // EAFNOSUPPORT 102
"Connection already in progress", // EALREADY 103
"Bad message", // EBADMSG 104
"Operation canceled", // ECANCELED 105
"Connection aborted", // ECONNABORTED 106
"Connection refused", // ECONNREFUSED 107
"Connection reset", // ECONNRESET 108
"Destination address required", // EDESTADDRREQ 109
"Host is unreachable", // EHOSTUNREACH 110
"Identifier removed", // EIDRM 111
"Operation in progress", // EINPROGRESS 112
"Socket is connected", // EISCONN 113
"Too many levels of symbolic links", // ELOOP 114
"Message too long", // EMSGSIZE 115
"Network is down", // ENETDOWN 116
"Connection aborted by network", // ENETRESET 117
"Network unreachable", // ENETUNREACH 118
"No buffer space available", // ENOBUFS 119
"No message is available on the STREAM head read queue", // ENODATA 120
"Link has been severed", // ENOLINK 121
"No message of the desired type", // ENOMSG 122
"Protocol not available", // ENOPROTOOPT 123
"No STREAM resources", // ENOSR 124
"Not a STREAM", // ENOSTR 125
"The socket is not connected", // ENOTCONN 126
"enotecoverable", // ENOTRECOVERABLE 127
"Not a socket", // ENOTSOCK 128
"Operation not supported", // ENOTSUP 129
"Operation not supported on socket", // EOPNOTSUPP 130
"eother", // EOTHER 131
"Value too large to be stored in data type", // EOVERFLOW 132
"eownerdead", // EOWNERDEAD 133
"Protocol error", // EPROTO 134
"Protocol not supported", // EPROTONOSUPPORT 135
"Protocol wrong type for socket", // EPROTOTYPE 136
"Timer expired", // ETIME 137
"Connection timed out", // ETIMEDOUT 138
"Text file busy", // ETXTBSY 139
"Operation would block" // EWOULDBLOCK 140
};
char *
w32_strerror(int errnum) {
if (errnum >= EADDRINUSE && errnum <= EWOULDBLOCK)
return _sys_errlist_ext[errnum - EADDRINUSE];
return strerror(errnum);
}
/* w32_strerror end */

View File

@ -1,3 +1,4 @@
#define PATH_MAX MAX_PATH
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */ /* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
#define sanitized_path(p) (((p)[0] == '/' && (p)[1] != '\0' && (p)[2] == ':')? (p)+1 : (p)) char * sanitized_path(const char *);

View File

@ -39,6 +39,7 @@
#include "inc\pwd.h" #include "inc\pwd.h"
#include "inc\grp.h" #include "inc\grp.h"
#include "inc\utf.h" #include "inc\utf.h"
#include "misc_internal.h"
static struct passwd pw; static struct passwd pw;
static char* pw_shellpath = NULL; static char* pw_shellpath = NULL;
@ -87,9 +88,9 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
char *uname_utf8 = NULL, *pw_home_utf8 = NULL; char *uname_utf8 = NULL, *pw_home_utf8 = NULL;
LPBYTE user_info = NULL; LPBYTE user_info = NULL;
LPWSTR user_sid_local = NULL; LPWSTR user_sid_local = NULL;
wchar_t reg_path[MAX_PATH], profile_home[MAX_PATH]; wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
HKEY reg_key = 0; HKEY reg_key = 0;
int tmp_len = MAX_PATH; int tmp_len = PATH_MAX;
PDOMAIN_CONTROLLER_INFOW pdc = NULL; PDOMAIN_CONTROLLER_INFOW pdc = NULL;
errno = 0; errno = 0;
@ -141,10 +142,10 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
user_sid = user_sid_local; user_sid = user_sid_local;
} }
if (swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == MAX_PATH || if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 || RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, &reg_key) != 0 ||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0) RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
GetWindowsDirectoryW(profile_home, MAX_PATH); GetWindowsDirectoryW(profile_home, PATH_MAX);
if ((uname_utf8 = _strdup(user_utf8)) == NULL || if ((uname_utf8 = _strdup(user_utf8)) == NULL ||
(pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL) { (pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL) {

View File

@ -35,6 +35,7 @@
#include <Strsafe.h> #include <Strsafe.h>
#include <stdio.h> #include <stdio.h>
#include <io.h> #include <io.h>
#include "misc_internal.h"
#define MAX_CONSOLE_COLUMNS 9999 #define MAX_CONSOLE_COLUMNS 9999
#define MAX_CONSOLE_ROWS 9999 #define MAX_CONSOLE_ROWS 9999
@ -136,6 +137,7 @@ HANDLE pipe_in = INVALID_HANDLE_VALUE;
HANDLE pipe_out = INVALID_HANDLE_VALUE; HANDLE pipe_out = INVALID_HANDLE_VALUE;
HANDLE pipe_err = INVALID_HANDLE_VALUE; HANDLE pipe_err = INVALID_HANDLE_VALUE;
HANDLE child = INVALID_HANDLE_VALUE; HANDLE child = INVALID_HANDLE_VALUE;
DWORD child_exit_code = 0;
HANDLE hConsoleBuffer = INVALID_HANDLE_VALUE; HANDLE hConsoleBuffer = INVALID_HANDLE_VALUE;
HANDLE monitor_thread = INVALID_HANDLE_VALUE; HANDLE monitor_thread = INVALID_HANDLE_VALUE;
@ -497,6 +499,7 @@ void SizeWindow(HANDLE hInput) {
DWORD WINAPI MonitorChild(_In_ LPVOID lpParameter) { DWORD WINAPI MonitorChild(_In_ LPVOID lpParameter) {
WaitForSingleObject(child, INFINITE); WaitForSingleObject(child, INFINITE);
GetExitCodeProcess(child, &child_exit_code);
PostThreadMessage(hostThreadId, WM_APPEXIT, 0, 0); PostThreadMessage(hostThreadId, WM_APPEXIT, 0, 0);
return 0; return 0;
} }
@ -1066,15 +1069,15 @@ int start_with_pty(int ac, wchar_t **av) {
/*TODO - pick this up from system32*/ /*TODO - pick this up from system32*/
cmd[0] = L'\0'; cmd[0] = L'\0';
if (ac) if (ac)
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L"cmd.exe"));
ac--; ac--;
av++; av++;
if (ac) if (ac)
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" /c"));
while (ac) { while (ac) {
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" ")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av)); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
ac--; ac--;
av++; av++;
} }
@ -1088,8 +1091,7 @@ int start_with_pty(int ac, wchar_t **av) {
Sleep(20); Sleep(20);
while (!AttachConsole(pi.dwProcessId)) while (!AttachConsole(pi.dwProcessId))
{ {
DWORD exit_code; if (GetExitCodeProcess(pi.hProcess, &child_exit_code) && child_exit_code != STILL_ACTIVE)
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
break; break;
Sleep(100); Sleep(100);
} }
@ -1129,7 +1131,7 @@ cleanup:
FreeConsole(); FreeConsole();
return 0; return child_exit_code;
} }
HANDLE child_pipe_read; HANDLE child_pipe_read;
@ -1138,6 +1140,7 @@ DWORD WINAPI MonitorChild_nopty(
_In_ LPVOID lpParameter _In_ LPVOID lpParameter
) { ) {
WaitForSingleObject(child, INFINITE); WaitForSingleObject(child, INFINITE);
GetExitCodeProcess(child, &child_exit_code);
CloseHandle(pipe_in); CloseHandle(pipe_in);
//printf("XXXX CHILD PROCESS DEAD XXXXX"); //printf("XXXX CHILD PROCESS DEAD XXXXX");
return 0; return 0;
@ -1180,14 +1183,14 @@ int start_withno_pty(int ac, wchar_t **av) {
/*TODO - pick this up from system32*/ /*TODO - pick this up from system32*/
cmd[0] = L'\0'; cmd[0] = L'\0';
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L"cmd.exe"));
ac -= 2; ac -= 2;
av += 2; av += 2;
if (ac) if (ac)
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" /c"));
while (ac) { while (ac) {
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" ")); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av)); GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
ac--; ac--;
av++; av++;
} }
@ -1282,7 +1285,7 @@ cleanup:
TerminateProcess(child, 0); TerminateProcess(child, 0);
if (monitor_thread != INVALID_HANDLE_VALUE) if (monitor_thread != INVALID_HANDLE_VALUE)
WaitForSingleObject(monitor_thread, INFINITE); WaitForSingleObject(monitor_thread, INFINITE);
return 0; return child_exit_code;
} }
int wmain(int ac, wchar_t **av) { int wmain(int ac, wchar_t **av) {

View File

@ -258,7 +258,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) { if ((ret >= WAIT_OBJECT_0) && (ret <= WAIT_OBJECT_0 + num_all_events - 1)) {
//woken up by event signalled //woken up by event signalled
/* is this due to a child process going down*/ /* is this due to a child process going down*/
if (children.num_children && ((ret - WAIT_OBJECT_0) < children.num_children)) { if (live_children && ((ret - WAIT_OBJECT_0) < live_children)) {
sigaddset(&pending_signals, W32_SIGCHLD); sigaddset(&pending_signals, W32_SIGCHLD);
sw_child_to_zombie(ret - WAIT_OBJECT_0); sw_child_to_zombie(ret - WAIT_OBJECT_0);
} }

View File

@ -11,12 +11,17 @@ int sw_kill(int pid, int sig);
/* child processes */ /* child processes */
#define MAX_CHILDREN 50 #define MAX_CHILDREN 50
struct _children { struct _children {
/*
* array of handles and process_ids.
* intial (num_children - num_zombies) are alive
* rest are zombies
*/
HANDLE handles[MAX_CHILDREN]; HANDLE handles[MAX_CHILDREN];
DWORD process_id[MAX_CHILDREN]; DWORD process_id[MAX_CHILDREN];
/* total children */ /* total children */
DWORD num_children; DWORD num_children;
/* #zombies */ /* #zombies */
/* (num_chileren - zombies) are live children */ /* (num_children - zombies) are live children */
DWORD num_zombies; DWORD num_zombies;
}; };

View File

@ -101,7 +101,7 @@ sw_remove_child_at_index(DWORD index) {
int int
sw_child_to_zombie(DWORD index) { sw_child_to_zombie(DWORD index) {
DWORD last_non_zombie, last_child, 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, debug("zombie'ing child at index %d, %d zombies of %d", index,
@ -112,17 +112,17 @@ sw_child_to_zombie(DWORD index) {
return -1; return -1;
} }
zombie_pid = children.process_id[index];
zombie_handle = children.handles[index];
last_non_zombie = children.num_children - children.num_zombies - 1; last_non_zombie = children.num_children - children.num_zombies - 1;
last_child = children.num_children - 1;
if (last_non_zombie != index) {
children.handles[index] = children.handles[last_non_zombie]; /* swap */
children.process_id[index] = children.process_id[last_non_zombie]; zombie_pid = children.process_id[index];
zombie_handle = children.handles[index];
children.handles[last_non_zombie] = children.handles[index]; children.handles[index] = children.handles[last_non_zombie];
children.process_id[last_non_zombie] = children.process_id[index]; children.process_id[index] = children.process_id[last_non_zombie];
children.handles[last_non_zombie] = zombie_handle;
children.process_id[last_non_zombie] = zombie_pid;
}
children.num_zombies++; children.num_zombies++;
return 0; return 0;
} }
@ -185,10 +185,13 @@ int waitpid(int pid, int *status, int options) {
return -1; return -1;
} }
process = children.handles[index]; /* wait if process is still alive */
ret = WaitForSingleObject(process, INFINITE); if (index < children.num_children - children.num_zombies) {
if (ret != WAIT_OBJECT_0) process = children.handles[index];
DebugBreak();//fatal ret = WaitForSingleObject(process, INFINITE);
if (ret != WAIT_OBJECT_0)
DebugBreak();//fatal
}
ret_id = children.process_id[index]; ret_id = children.process_id[index];
GetExitCodeProcess(process, &exit_code); GetExitCodeProcess(process, &exit_code);
@ -200,6 +203,15 @@ int waitpid(int pid, int *status, int options) {
} }
/* pid = -1*/ /* pid = -1*/
/* are there any existing zombies */
if (children.num_zombies) {
/* return one of them */
ret_id = children.process_id[children.num_children - 1];
sw_remove_child_at_index(children.num_children - 1);
return ret_id;
}
/* all children are alive. wait for one of them to exit */
timeout = INFINITE; timeout = INFINITE;
if (options & WNOHANG) if (options & WNOHANG)
timeout = 0; timeout = 0;

View File

@ -31,6 +31,7 @@
#include "agent.h" #include "agent.h"
#include <sddl.h> #include <sddl.h>
#include <UserEnv.h> #include <UserEnv.h>
#include "..\misc_internal.h"
#define BUFSIZE 5 * 1024 #define BUFSIZE 5 * 1024
static HANDLE ioc_port = NULL; static HANDLE ioc_port = NULL;
@ -179,15 +180,15 @@ agent_listen_loop() {
} }
else { else {
/* spawn a child to take care of this*/ /* spawn a child to take care of this*/
wchar_t path[MAX_PATH], module_path[MAX_PATH]; wchar_t path[PATH_MAX], module_path[PATH_MAX];
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFOW si; STARTUPINFOW si;
si.cb = sizeof(STARTUPINFOW); si.cb = sizeof(STARTUPINFOW);
memset(&si, 0, sizeof(STARTUPINFOW)); memset(&si, 0, sizeof(STARTUPINFOW));
GetModuleFileNameW(NULL, module_path, MAX_PATH); GetModuleFileNameW(NULL, module_path, PATH_MAX);
SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
if ((swprintf_s(path, MAX_PATH, L"%s %d", module_path, (int)(intptr_t)con) == -1 ) || if ((swprintf_s(path, PATH_MAX, L"%s %d", module_path, (int)(intptr_t)con) == -1 ) ||
(CreateProcessW(NULL, path, NULL, NULL, TRUE, (CreateProcessW(NULL, path, NULL, NULL, TRUE,
DETACHED_PROCESS, NULL, NULL, DETACHED_PROCESS, NULL, NULL,
&si, &pi) == FALSE)) { &si, &pi) == FALSE)) {

View File

@ -87,15 +87,15 @@ int GetCurrentModulePath(wchar_t *path, int pathSize)
} }
int load_config() { int load_config() {
wchar_t basePath[MAX_PATH] = { 0 }; wchar_t basePath[PATH_MAX] = { 0 };
wchar_t path[MAX_PATH] = { 0 }; wchar_t path[PATH_MAX] = { 0 };
/* TODO - account for UNICODE paths*/ /* TODO - account for UNICODE paths*/
if (GetCurrentModulePath(basePath, MAX_PATH) == -1) if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
return -1; return -1;
wcsncpy(path, basePath, MAX_PATH); wcsncpy(path, basePath, PATH_MAX);
wcsncat(path, L"/sshd_config", MAX_PATH); wcsncat(path, L"/sshd_config", PATH_MAX);
if ((config_file_name = utf16_to_utf8(path)) == NULL) if ((config_file_name = utf16_to_utf8(path)) == NULL)
return -1; return -1;

View File

@ -318,7 +318,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK || if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK ||
pubkey_allowed(key, wuser, wuser_home) != 1) { pubkey_allowed(key, wuser, wuser_home) != 1) {
debug("given public key is not mapped to user %ls (profile:%ls)", wuser, wuser_home); debug("unable to verify public key for user %ls (profile:%ls)", wuser, wuser_home);
goto done; goto done;
} }

View File

@ -1,43 +1,79 @@
/*
* Copyright (c) 2016 Microsoft Corp.
* All rights reserved
*
* Implementation of sys log for windows:
* openlog(), closelog, syslog
*
* 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.
*/
#include <Windows.h> #include <Windows.h>
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "inc\syslog.h" #include "inc\syslog.h"
#include "misc_internal.h"
#define MSGBUFSIZ 1024 #define MSGBUFSIZ 1024
static int logfd = -1; static int logfd = -1;
void openlog(char *ident, unsigned int option, int facility) { void
if ((logfd == -1) && (ident != NULL)) { openlog(char *ident, unsigned int option, int facility) {
wchar_t path[MAX_PATH], log_file[MAX_PATH + 12]; if (logfd != -1 || ident == NULL)
if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0) return;
return;
path[MAX_PATH - 1] = '\0'; wchar_t path[PATH_MAX], log_file[PATH_MAX + 12];
/* split path root and module */ if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
{
wchar_t* tail = path + wcslen(path), *p;
while (tail > path && *tail != L'\\' && *tail != L'/')
tail--;
memcpy(log_file, path, (tail - path) * sizeof(wchar_t)); return;
p = log_file + (tail - path); path[PATH_MAX - 1] = '\0';
memcpy(p, L"\\logs\\", 12);
p += 6; /* split path root and module */
memcpy(p, tail + 1, (wcslen(tail + 1) - 3) * sizeof(wchar_t)); {
p += wcslen(tail + 1) - 3; wchar_t* tail = path + wcslen(path), *p;
memcpy(p, L"log\0", 8); while (tail > path && *tail != L'\\' && *tail != L'/')
} tail--;
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND,
S_IREAD | S_IWRITE); memcpy(log_file, path, (tail - path) * sizeof(wchar_t));
if (logfd != -1) p = log_file + (tail - path);
SetHandleInformation((HANDLE)_get_osfhandle(logfd), memcpy(p, L"\\logs\\", 12);
HANDLE_FLAG_INHERIT, 0); p += 6;
memcpy(p, tail + 1, (wcslen(tail + 1) - 3) * sizeof(wchar_t));
p += wcslen(tail + 1) - 3;
memcpy(p, L"log\0", 8);
} }
logfd = _wopen(log_file, O_WRONLY | O_CREAT | O_APPEND,
S_IREAD | S_IWRITE);
if (logfd != -1)
SetHandleInformation((HANDLE)_get_osfhandle(logfd),
HANDLE_FLAG_INHERIT, 0);
} }
void closelog(void) { void
//NOOP closelog(void) {
/*NOOP*/
} }
void void

View File

@ -27,7 +27,7 @@ DIR * opendir(const char *name)
struct _wfinddata_t c_file; struct _wfinddata_t c_file;
intptr_t hFile; intptr_t hFile;
DIR *pdir; DIR *pdir;
wchar_t searchstr[MAX_PATH]; wchar_t searchstr[PATH_MAX];
wchar_t* wname = NULL; wchar_t* wname = NULL;
int needed; int needed;
@ -37,7 +37,7 @@ DIR * opendir(const char *name)
} }
// add *.* for Windows _findfirst() search pattern // add *.* for Windows _findfirst() search pattern
swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname); swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
free(wname); free(wname);
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L) if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L)
@ -77,7 +77,7 @@ int closedir(DIR *dirp)
by a later readdir call on the same DIR stream. */ by a later readdir call on the same DIR stream. */
struct dirent *readdir(void *avp) struct dirent *readdir(void *avp)
{ {
struct dirent *pdirentry; static struct dirent pdirentry;
struct _wfinddata_t c_file; struct _wfinddata_t c_file;
DIR *dirp = (DIR *)avp; DIR *dirp = (DIR *)avp;
char *tmp = NULL; char *tmp = NULL;
@ -92,19 +92,18 @@ struct dirent *readdir(void *avp)
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0 ) if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0 )
continue; continue;
if ((pdirentry = malloc(sizeof(struct dirent))) == NULL || if ((tmp = utf16_to_utf8(c_file.name)) == NULL) {
(tmp = utf16_to_utf8(c_file.name)) == NULL) {
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
strncpy(pdirentry->d_name, tmp, strlen(tmp) + 1); strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
free(tmp); free(tmp);
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero
return pdirentry ; return &pdirentry ;
} }
} }
// return last part of a path. The last path being a filename. // return last part of a path. The last path being a filename.
@ -123,4 +122,3 @@ char *basename(char *path)
return path; // path does not have a slash return path; // path does not have a slash
} }
// end of dirent functions in Windows

View File

@ -112,8 +112,12 @@ int sshd_main(int argc, wchar_t **wargv) {
w32posix_initialize(); w32posix_initialize();
if (getenv("SSHD_REMSOC")) if (getenv("SSHD_REMSOC"))
is_child = 1; is_child = 1;
/* change current directory to sshd.exe root */ /* change current directory to sshd.exe root */
_wchdir(utf8_to_utf16(w32_programdir())); wchar_t* path_utf16 = utf8_to_utf16(w32_programdir());
_wchdir(path_utf16);
free(path_utf16);
return main(argc, argv); return main(argc, argv);
} }

View File

@ -85,7 +85,7 @@ Class Machine
[string] $ClientKeyDirectory [string] $ClientKeyDirectory
[string] $knownHostOfCurrentUser [string] $knownHostOfCurrentUser
[string] $OpenSSHdir = $PSScriptRoot [string] $OpenSSHdir = $PSScriptRoot
[string] $ToolsPath = "$env:ProgramData\chocolatey\lib\sysinternals\tools" [string] $ToolsPath = "$env:ProgramData\chocolatey\lib\sysinternals\tools"
Machine() { Machine() {
$this.Platform = Set-Platform $this.Platform = Set-Platform
@ -106,13 +106,13 @@ Class Machine
} }
[void] InitializeClient() { [void] InitializeClient() {
$this.ClientKeyDirectory = join-path ($env:USERPROFILE) ".ssh" $this.ClientKeyDirectory = join-path $PSScriptRoot "clientkeys"
if(-not (Test-path $this.ClientKeyDirectory -PathType Container)) if(-not (Test-path $this.ClientKeyDirectory -PathType Container))
{ {
New-Item -Path $this.ClientKeyDirectory -ItemType Directory -Force -ErrorAction silentlycontinue New-Item -Path $this.ClientKeyDirectory -ItemType Directory -Force -ErrorAction silentlycontinue
} }
Remove-Item -Path "$($this.ClientKeyDirectory)\*" -Force -ea silentlycontinue Remove-Item -Path "$($this.ClientKeyDirectory)\*" -Force -ea silentlycontinue
$this.knownHostOfCurrentUser = join-path ($env:USERPROFILE) ".ssh/known_hosts" $this.knownHostOfCurrentUser = join-path ($env:USERPROFILE) ".ssh/known_hosts"
@ -131,8 +131,7 @@ Class Machine
$this.clientPrivateKeyPaths += $keyPath $this.clientPrivateKeyPaths += $keyPath
$this.clientPublicKeyPaths += "$keyPath.pub" $this.clientPublicKeyPaths += "$keyPath.pub"
$str = ".\ssh-keygen -t $key -P """" -f $keyPath" $str = ".\ssh-keygen -t $key -P """" -f $keyPath"
$this.RunCmd($str) $this.RunCmd($str)
} }
} }
@ -211,16 +210,27 @@ Class Machine
} }
} }
[void] CleanupServer() { [void] CleanupServer() {
Remove-Item -Path $this.localAdminAuthorizedKeyPath -Force -ea silentlycontinue $sshPath = split-path $this.localAdminAuthorizedKeyPath -Parent
if(Test-Path $sshPath -PathType Container )
{
Remove-item -path $sshPath -force -Recurse
}
if ( $this.Platform -eq [PlatformType]::Windows ) if ( $this.Platform -eq [PlatformType]::Windows )
{ {
$this.CleanupLocalAccountTokenFilterPolicy() $this.CleanupLocalAccountTokenFilterPolicy()
} }
} }
[void] CleanupClient() { [void] CleanupClient() {
Remove-Item -Path "$this.clientKeyPath\*" -Force -ea silentlycontinue Remove-item -path $($this.ClientKeyDirectory) -force -Recurse -ea silentlycontinue
$sshPath = split-path $this.knownHostOfCurrentUser -Parent
if(Test-Path $sshPath -PathType Container )
{
Remove-item -path $sshPath -force -Recurse
}
$this.CleanupPasswordSetting()
} }
[void] RunCmd($Str) { [void] RunCmd($Str) {
@ -248,6 +258,19 @@ Class Machine
} }
} }
[void] AddPasswordSetting([string] $pass) {
if ($this.Platform -eq [PlatformType]::Windows) {
$env:SSH_ASKPASS="$($env:ComSpec) /c echo $pass"
}
}
[void] CleanupPasswordSetting() {
if ($this.Platform -eq [PlatformType]::Windows -and (Test-Path env:SSH_ASKPASS))
{
remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
}
}
#Set LocalAccountTokenFilterPolicy #Set LocalAccountTokenFilterPolicy
[void] SetLocalAccountTokenFilterPolicy($setting) { [void] SetLocalAccountTokenFilterPolicy($setting) {
$path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\system" $path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\system"
@ -308,6 +331,7 @@ Class Machine
$shell_app = $null $shell_app = $null
} }
#this does not work when "using module"; works fine when import the module
[void] DownloadPStools() [void] DownloadPStools()
{ {
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')

View File

@ -98,31 +98,30 @@ Describe "Tests for scp command" -Tags "CI" {
It 'SCP usage' { It 'SCP usage' {
#TODO: usage output does not redirect to file #TODO: usage output does not redirect to file
} }
}#> }#>
#this context only run on windows
Context "Key is Secured in ssh-agent on server" { Context "Key is Secured in ssh-agent on server" {
BeforeAll { BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths) $Server.SecureHostKeys($server.PrivateHostKeyPaths)
$identifyFile = $client.clientPrivateKeyPaths[0] $privateKeyFile = $client.clientPrivateKeyPaths[0]
} }
AfterAll { AfterAll {
$Server.CleanupHostKeys() $Server.CleanupHostKeys()
} }
It 'File Copy with -i option: <Title> ' -TestCases:$testData { It 'File copy with -i option and private key: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile $Source $Destination .\scp -i $privateKeyFile $Source $Destination
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
It 'Directory recursive Copy with -i option: <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 $identifyFile $Source $Destination .\scp -r -i $privateKeyFile $Source $Destination
$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
$equal | Should Be $true $equal | Should Be $true
@ -130,10 +129,9 @@ 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).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
} }
#this context only run on windows
Context "Single signon with keys -p -v -c option Secured in ssh-agent" { Context "Single signon with keys -p -v -c option Secured in ssh-agent" {
BeforeAll { BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths) $Server.SecureHostKeys($server.PrivateHostKeyPaths)
@ -149,27 +147,27 @@ Describe "Tests for scp command" -Tags "CI" {
.\ssh-add.exe -D .\ssh-add.exe -D
} }
It 'File Copy with -S option (positive)' { It 'File copy with -S option (positive)' {
.\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath" .\scp -S .\ssh.exe $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
It 'File Copy with -p -c -v option: <Title> ' -TestCases:$testData { It 'File copy with -p -c -v option: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -p -c aes128-ctr -v -C $Source $Destination .\scp -p -c aes128-ctr -v -C $Source $Destination
#validate file content. DestPath is the path to the file. #validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
It 'Directory recursive Copy with -r -p -v option: <Title> ' -TestCases:$testData1 { It 'Directory recursive copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -r -p -c aes128-ctr -v $Source $Destination .\scp -r -p -c aes128-ctr -v $Source $Destination
$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, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
$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
@ -177,12 +175,12 @@ Describe "Tests for scp command" -Tags "CI" {
} }
} }
Context "Key based authentication with -i -C -q options. host keys are not secured on server" { Context "Private key authentication with -i -C -q options. host keys are not secured on server" {
BeforeAll { BeforeAll {
$identifyFile = $client.clientPrivateKeyPaths[0] $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 -i $identifyFile -C -q $Source $Destination
@ -191,16 +189,45 @@ Describe "Tests for scp command" -Tags "CI" {
$equal | Should Be $true $equal | Should Be $true
} }
It 'Directory recursive copy with -i -C -r and -q options: <Title> ' -TestCases:$testData1 {
It 'Directory recursive Copy with -i and -q options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination) param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -r -q $Source $Destination .\scp -i $identifyFile -C -r -q $Source $Destination
$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
$equal | Should Be $true $equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0 $equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true $equal | Should Be $true
} }
} }
Context "Password authentication" {
BeforeAll {
$client.AddPasswordSetting($server.localAdminPassword)
}
AfterAll {
$client.CleanupPasswordSetting()
}
It 'File copy with -p options: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination)
.\scp -p $Source $Destination
#validate file content. DestPath is the path to the file.
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
It 'Directory recursive copy with -p and -v options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -p $Source $Destination
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
$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
}
}
} }

View File

@ -135,5 +135,28 @@ Describe "Tests for ssh command" -Tags "CI" {
#validate file content. #validate file content.
Get-Content $filePath | Should be $server.MachineName Get-Content $filePath | Should be $server.MachineName
} }
} }
Context "password authentication" {
BeforeAll {
$client.AddPasswordSetting($server.localAdminPassword)
Remove-Item -Path $filePath -Force -ea silentlycontinue
}
AfterAll {
$client.CleanupPasswordSetting()
}
AfterEach {
Remove-Item -Path $filePath -Force -ea silentlycontinue
}
It '<Title>' -TestCases:$testData {
param([string]$Title, $LogonStr, $Options)
$str = ".\ssh $($Options) $($LogonStr) hostname > $filePath"
$client.RunCmd($str)
#validate file content.
Get-Content $filePath | Should be $server.MachineName
}
}
} }

11
scp.c
View File

@ -595,12 +595,17 @@ main(int argc, char **argv)
#ifdef WINDOWS #ifdef WINDOWS
/* /*
* To support both Windows and Unix style paths * To support both Windows and Unix style paths
* convert '\\' to '/' in rest of arguments * convert '\\' to '/' in path portion of rest arguments
*/ */
{ {
int i; int i;
for (i = 0; i < argc; i++) char *p;
convertToForwardslash(argv[i]); for (i = 0; i < argc; i++) {
if(p = colon(argv[i]))
convertToForwardslash(p);
else
convertToForwardslash(argv[i]);
}
} }
#endif /* WINDOWS */ #endif /* WINDOWS */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.c,v 1.125 2016/09/12 01:22:38 deraadt Exp $ */ /* $OpenBSD: sftp-client.c,v 1.126 2017/01/03 05:46:51 djm Exp $ */
/* /*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
* *
@ -587,6 +587,8 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
if ((r = sshbuf_get_u32(msg, &count)) != 0) if ((r = sshbuf_get_u32(msg, &count)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (count > SSHBUF_SIZE_MAX)
fatal("%s: nonsensical number of entries", __func__);
if (count == 0) if (count == 0)
break; break;
debug3("Received %d SSH2_FXP_NAME responses", count); debug3("Received %d SSH2_FXP_NAME responses", count);

16
sftp.c
View File

@ -320,12 +320,16 @@ static void
local_do_shell(const char *args) local_do_shell(const char *args)
{ {
#ifdef WINDOWS #ifdef WINDOWS
/* execute via system call in Windows*/ /* execute via system call in Windows*/
if (!*args) { if (!*args) {
/* TODO - support unicode ComSpec */
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
} else {
convertToBackslash((char *) args);
} }
system(args); // execute the shell or cmd given
wchar_t* path_utf16 = utf8_to_utf16(args);
_wsystem(path_utf16); // execute the shell or cmd given
free(path_utf16);
#else /* !WINDOWS */ #else /* !WINDOWS */
int status; int status;
char *shell; char *shell;
@ -1513,7 +1517,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
* convert '\\' to '/' in Windows styled paths. * convert '\\' to '/' in Windows styled paths.
* else they get treated as escape sequence in makeargv * else they get treated as escape sequence in makeargv
*/ */
convertToForwardslash(cmd); convertToForwardslash((char *)cmd);
#endif #endif
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag, cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2); &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
@ -2334,7 +2338,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
/* disable inheritance on local pipe ends*/ /* disable inheritance on local pipe ends*/
fcntl(pout[1], F_SETFD, FD_CLOEXEC); fcntl(pout[1], F_SETFD, FD_CLOEXEC);
fcntl(pin[0], F_SETFD, FD_CLOEXEC); fcntl(pin[0], F_SETFD, FD_CLOEXEC);
sshpid = spawn_child(full_cmd, c_in, c_out, STDERR_FILENO, 0); sshpid = spawn_child(full_cmd, c_in, c_out, STDERR_FILENO, 0);
free(full_cmd); free(full_cmd);
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.215 2016/11/30 03:07:37 djm Exp $ */ /* $OpenBSD: ssh-agent.c,v 1.216 2017/01/04 02:21:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -89,7 +89,7 @@
#endif #endif
#ifndef DEFAULT_PKCS11_WHITELIST #ifndef DEFAULT_PKCS11_WHITELIST
# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" # define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
#endif #endif
typedef enum { typedef enum {

View File

@ -221,7 +221,11 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
fatal("Key must at least be 1024 bits"); fatal("Key must at least be 1024 bits");
else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
fatal("Invalid ECDSA key length - valid lengths are " fatal("Invalid ECDSA key length - valid lengths are "
#ifdef OPENSSL_HAS_NISTP521
"256, 384 or 521 bits"); "256, 384 or 521 bits");
#else
"256 or 384 bits");
#endif
#endif #endif
} }