mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-23 14:04:59 +02:00
Source snapshot from Powershell/openssh-portable:latestw_cwb
This commit is contained in:
parent
a4b577b5a0
commit
e85070d50e
3
INSTALL
3
INSTALL
@ -1,3 +1,4 @@
|
||||
1. Prerequisites
|
||||
----------------
|
||||
|
||||
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 ""
|
||||
|
||||
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
|
||||
|
||||
|
14
appveyor.yml
14
appveyor.yml
@ -11,12 +11,12 @@ init:
|
||||
|
||||
build_script:
|
||||
- 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
|
||||
|
||||
after_build:
|
||||
- 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
|
||||
- ps: Write-Verbose "Restart computer ..."
|
||||
- ps: Restart-Computer -ComputerName localhost -Force
|
||||
@ -25,19 +25,19 @@ after_build:
|
||||
|
||||
before_test:
|
||||
- ps: |
|
||||
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1
|
||||
Install-TestDependencies
|
||||
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppVeyor.psm1 -WarningAction SilentlyContinue
|
||||
Install-TestDependencies
|
||||
|
||||
test_script:
|
||||
- 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:
|
||||
- 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
|
||||
|
||||
on_finish:
|
||||
- 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
|
||||
|
@ -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.
|
||||
*
|
||||
@ -783,6 +783,9 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
|
||||
|
||||
ok = process_principals(f, NULL, pw, cert);
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0)
|
||||
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);
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0)
|
||||
goto out;
|
||||
|
||||
|
@ -1,6 +1,26 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Import-Module $PSScriptRoot\build.psm1
|
||||
$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
|
||||
Function Set-BuildVariable
|
||||
@ -53,7 +73,7 @@ function Invoke-AppVeyorFull
|
||||
Install-TestDependencies
|
||||
& "$env:ProgramFiles\PowerShell\6.0.0.12\powershell.exe" -Command {Import-Module $($repoRoot.FullName)\contrib\win32\openssh\AppVeyor.psm1;Run-OpenSSHTests -uploadResults}
|
||||
Run-OpenSSHTests
|
||||
Publish-Artifact
|
||||
Publish-Artifact
|
||||
}
|
||||
finally {
|
||||
if($APPVEYOR_SCHEDULED_BUILD -and $env:APPVEYOR_SCHEDULED_BUILD)
|
||||
@ -66,10 +86,8 @@ function Invoke-AppVeyorFull
|
||||
# Implements the AppVeyor 'build_script' step
|
||||
function Invoke-AppVeyorBuild
|
||||
{
|
||||
Start-SSHBuild -Configuration Release -NativeHostArch x64 -Verbose
|
||||
Start-SSHBuild -Configuration Debug -NativeHostArch x64 -Verbose
|
||||
Start-SSHBuild -Configuration Release -NativeHostArch x86 -Verbose
|
||||
Start-SSHBuild -Configuration Debug -NativeHostArch x86 -Verbose
|
||||
Start-SSHBuild -Configuration Release -NativeHostArch x64
|
||||
Start-SSHBuild -Configuration Debug -NativeHostArch x86
|
||||
}
|
||||
|
||||
<#
|
||||
@ -83,8 +101,8 @@ function Invoke-MSIEXEC
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $InstallFile
|
||||
)
|
||||
|
||||
Write-Verbose "Installing $InstallFile..."
|
||||
|
||||
Write-Log -Message "Installing $InstallFile..."
|
||||
$arguments = @(
|
||||
"/i"
|
||||
"`"$InstallFile`""
|
||||
@ -93,10 +111,10 @@ function Invoke-MSIEXEC
|
||||
)
|
||||
$process = Start-Process -FilePath msiexec.exe -ArgumentList $arguments -Wait -PassThru
|
||||
if ($process.ExitCode -eq 0){
|
||||
Write-Output "$InstallFile has been successfully installed"
|
||||
Write-Log -Message "$InstallFile has been successfully installed."
|
||||
}
|
||||
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
|
||||
@ -108,13 +126,13 @@ function Invoke-MSIEXEC
|
||||
#>
|
||||
function Install-PSCoreFromGithub
|
||||
{
|
||||
$downloadLocation = Download-PSCoreMSI
|
||||
|
||||
Write-Output "Installing PSCore ..."
|
||||
$downloadLocation = Download-PSCoreMSI
|
||||
|
||||
Write-Log -Message "Installing PSCore ..."
|
||||
if(-not [string]::IsNullOrEmpty($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
|
||||
{
|
||||
$osversion = [String][Environment]::OSVersion.Version
|
||||
Write-Host "osversion:$osversion"
|
||||
|
||||
if($osversion.StartsWith("6"))
|
||||
{
|
||||
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
|
||||
{
|
||||
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"))
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
if([string]::IsNullOrEmpty($url))
|
||||
{
|
||||
Write-Output "url is empty"
|
||||
{
|
||||
Write-Log -Message "url is empty"
|
||||
return ''
|
||||
}
|
||||
$parsed = $url.Substring($url.LastIndexOf("/") + 1)
|
||||
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"
|
||||
if(-not (Test-path $downloadLocation -PathType Leaf))
|
||||
@ -196,16 +214,15 @@ function Install-TestDependencies
|
||||
|
||||
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
|
||||
if (-not ($isModuleAvailable))
|
||||
{
|
||||
Write-Output 'Installing Pester...'
|
||||
choco install Pester -y --force
|
||||
{
|
||||
Write-Log -Message "Installing Pester..."
|
||||
choco install Pester -y --force --limitoutput
|
||||
}
|
||||
|
||||
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
|
||||
Write-Output "sysinternals not present. Installing sysinternals."
|
||||
choco install sysinternals -y
|
||||
}
|
||||
Write-Output "Installing pscore..."
|
||||
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
|
||||
Write-Log -Message "sysinternals not present. Installing sysinternals."
|
||||
choco install sysinternals -y --force --limitoutput
|
||||
}
|
||||
Install-PSCoreFromGithub
|
||||
}
|
||||
<#
|
||||
@ -219,8 +236,8 @@ function Install-OpenSSH
|
||||
(
|
||||
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
|
||||
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = "Debug",
|
||||
[ValidateSet('Debug', 'Release', '')]
|
||||
[string]$Configuration = "",
|
||||
|
||||
[ValidateSet('x86', 'x64', '')]
|
||||
[string]$NativeHostArch = ""
|
||||
@ -272,8 +289,8 @@ function Build-Win32OpenSSHPackage
|
||||
(
|
||||
[string] $OpenSSHDir = "$env:SystemDrive\OpenSSH",
|
||||
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = "Debug",
|
||||
[ValidateSet('Debug', 'Release', '')]
|
||||
[string]$Configuration = "",
|
||||
|
||||
[ValidateSet('x86', 'x64', '')]
|
||||
[string]$NativeHostArch = ""
|
||||
@ -281,32 +298,49 @@ function Build-Win32OpenSSHPackage
|
||||
|
||||
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))
|
||||
{
|
||||
$folderName = $NativeHostArch
|
||||
if($NativeHostArch -eq 'x86')
|
||||
if($NativeHostArch -ieq 'x86')
|
||||
{
|
||||
$folderName = "Win32"
|
||||
$folderName = "Win32"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($platform -ieq "AMD64")
|
||||
{
|
||||
$folderName = "x64"
|
||||
$folderName = "x64"
|
||||
}
|
||||
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
|
||||
$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
|
||||
$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
|
||||
@ -314,8 +348,8 @@ function Build-Win32OpenSSHPackage
|
||||
$packageName = "rktools.2003"
|
||||
$rktoolsPath = "${env:ProgramFiles(x86)}\Windows Resource Kits\Tools\ntrights.exe"
|
||||
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
|
||||
}
|
||||
|
||||
@ -327,7 +361,7 @@ function Build-Win32OpenSSHPackage
|
||||
$packageFolder = $env:APPVEYOR_BUILD_FOLDER
|
||||
}
|
||||
|
||||
$package = "$packageFolder\Win32OpenSSH$Configuration$folderName.zip"
|
||||
$package = "$packageFolder\Win32OpenSSH$RealConfiguration$folderName.zip"
|
||||
$allPackage = "$packageFolder\Win32OpenSSH*.zip"
|
||||
if (Test-Path $allPackage)
|
||||
{
|
||||
@ -349,8 +383,8 @@ function Deploy-OpenSSHTests
|
||||
(
|
||||
[string] $OpenSSHTestDir = "$env:SystemDrive\OpenSSH",
|
||||
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = "Debug",
|
||||
[ValidateSet('Debug', 'Release', '')]
|
||||
[string]$Configuration = "",
|
||||
|
||||
[ValidateSet('x86', 'x64', '')]
|
||||
[string]$NativeHostArch = ""
|
||||
@ -358,7 +392,7 @@ function Deploy-OpenSSHTests
|
||||
|
||||
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
|
||||
@ -381,6 +415,22 @@ function Deploy-OpenSSHTests
|
||||
$folderName = "Win32"
|
||||
}
|
||||
}
|
||||
|
||||
if([String]::IsNullOrEmpty($Configuration))
|
||||
{
|
||||
if( $folderName -ieq "Win32" )
|
||||
{
|
||||
$RealConfiguration = "Debug"
|
||||
}
|
||||
else
|
||||
{
|
||||
$RealConfiguration = "Release"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$RealConfiguration = $Configuration
|
||||
}
|
||||
|
||||
|
||||
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
|
||||
@ -388,9 +438,8 @@ function Deploy-OpenSSHTests
|
||||
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
|
||||
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1 -Force -ErrorAction Stop
|
||||
|
||||
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$Configuration"
|
||||
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Exclude ssh-agent.exe, sshd.exe -Force -ErrorAction Stop
|
||||
|
||||
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
|
||||
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)
|
||||
{
|
||||
Write-Output "Adding $buildLog to local artifacts"
|
||||
{
|
||||
$null = $artifacts.Add($buildLog)
|
||||
Write-Output "Adding $buildLog to local artifacts- completed"
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -449,14 +496,10 @@ function Add-Artifact
|
||||
|
||||
$files = Get-ChildItem -Path $FileToAdd -ErrorAction Ignore
|
||||
if ($files -ne $null)
|
||||
{
|
||||
|
||||
{
|
||||
$files | % {
|
||||
Write-Output "Adding $($_.FullName) to local artifacts"
|
||||
$null = $artifacts.Add($_.FullName)
|
||||
Write-Output "Adding $($_.FullName) to local artifacts- completed"
|
||||
}
|
||||
|
||||
$null = $artifacts.Add($_.FullName)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -480,13 +523,11 @@ function Publish-Artifact
|
||||
}
|
||||
|
||||
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
|
||||
#Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName -Configuration Release -NativeHostArch x86)
|
||||
#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)
|
||||
# Get the build.log file for each build configuration
|
||||
Add-BuildLog -artifacts $artifacts -buildLog (Get-BuildLogFile -root $repoRoot.FullName)
|
||||
|
||||
foreach ($artifact in $artifacts)
|
||||
{
|
||||
@ -505,11 +546,11 @@ function Run-OpenSSHPesterTest
|
||||
param($testRoot, $outputXml)
|
||||
|
||||
# Discover all CI tests and run them.
|
||||
Push-Location $testRoot
|
||||
Write-Output "Running OpenSSH Pester tests..."
|
||||
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'
|
||||
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $outputXml -Tag 'CI'
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
@ -522,8 +563,8 @@ function Run-OpenSSHUnitTest
|
||||
param($testRoot, $unitTestOutputFile)
|
||||
|
||||
# Discover all CI tests and run them.
|
||||
Push-Location $testRoot
|
||||
Write-Output "Running OpenSSH unit tests..."
|
||||
Push-Location $testRoot
|
||||
Write-Log -Message "Running OpenSSH unit tests..."
|
||||
if (Test-Path $unitTestOutputFile)
|
||||
{
|
||||
Remove-Item -Path $unitTestOutputFile -Force -ErrorAction SilentlyContinue
|
||||
@ -534,13 +575,13 @@ function Run-OpenSSHUnitTest
|
||||
if ($unitTestFiles -ne $null)
|
||||
{
|
||||
$unitTestFiles | % {
|
||||
Write-Output "Running OpenSSH unit $($_.FullName)..."
|
||||
Write-Log -Message "Running OpenSSH unit $($_.FullName)..."
|
||||
& $_.FullName >> $unitTestOutputFile
|
||||
$errorCode = $LASTEXITCODE
|
||||
if ($errorCode -ne 0)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -133,15 +133,14 @@ function Write-BuildMsg
|
||||
Verifies all tools and dependencies required for building Open SSH are installed on the machine.
|
||||
#>
|
||||
function Start-SSHBootstrap
|
||||
{
|
||||
{
|
||||
[bool] $silent = -not $script:Verbose
|
||||
|
||||
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')
|
||||
$newMachineEnvironmentPath = $machinePath
|
||||
|
||||
# NOTE: Unless -Verbose is specified, most informational output will only go to the log file.
|
||||
[bool] $silent = -not $script:Verbose
|
||||
$newMachineEnvironmentPath = $machinePath
|
||||
|
||||
# Install chocolatey
|
||||
$chocolateyPath = "$env:AllUsersProfile\chocolatey\bin"
|
||||
@ -151,18 +150,18 @@ function Start-SSHBootstrap
|
||||
}
|
||||
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'))
|
||||
|
||||
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"
|
||||
$env:Path += ";$chocolateyPath"
|
||||
}
|
||||
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"
|
||||
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"
|
||||
}
|
||||
else
|
||||
@ -186,7 +185,7 @@ function Start-SSHBootstrap
|
||||
|
||||
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"
|
||||
$env:Path += ";$nativeMSBuildPath"
|
||||
}
|
||||
@ -207,8 +206,8 @@ function Start-SSHBootstrap
|
||||
|
||||
if (-not (Test-Path -Path $nasmPath -PathType Container))
|
||||
{
|
||||
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName."
|
||||
choco install $packageName -y --force --execution-timeout 10000
|
||||
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." -Silent:$silent
|
||||
choco install $packageName -y --force --limitoutput --execution-timeout 10000
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -221,9 +220,9 @@ function Start-SSHBootstrap
|
||||
|
||||
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"
|
||||
choco install $packageName -packageParameters "--AdminFile $adminFilePath" -y --force --execution-timeout 10000
|
||||
choco install $packageName -packageParameters "--AdminFile $adminFilePath" -y --force --limitoutput --execution-timeout 10000
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -236,8 +235,8 @@ function Start-SSHBootstrap
|
||||
|
||||
if (-not (Test-Path -Path $sdkPath))
|
||||
{
|
||||
Write-BuildMsg -AsInfo -Message "Windows 8.1 SDK not present. Installing $packageName."
|
||||
choco install $packageName -y --force
|
||||
Write-BuildMsg -AsInfo -Message "Windows 8.1 SDK not present. Installing $packageName." -Silent:$silent
|
||||
choco install $packageName -y --limitoutput --force
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -262,7 +261,7 @@ function Start-SSHBootstrap
|
||||
$item = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc')
|
||||
|
||||
$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)
|
||||
{
|
||||
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
|
||||
{
|
||||
{
|
||||
[bool] $silent = -not $script:Verbose
|
||||
|
||||
$win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
|
||||
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
|
||||
git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath
|
||||
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
|
||||
git fetch -q origin
|
||||
git checkout -qf L1-Prod
|
||||
@ -287,9 +288,11 @@ function Clone-Win32OpenSSH
|
||||
}
|
||||
|
||||
function Copy-OpenSSLSDK
|
||||
{
|
||||
{
|
||||
[bool] $silent = -not $script:Verbose
|
||||
|
||||
$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
|
||||
if($e -ne $null)
|
||||
{
|
||||
@ -306,7 +309,7 @@ function Start-SSHBuild
|
||||
[string]$NativeHostArch = "x64",
|
||||
|
||||
[ValidateSet('Debug', 'Release', '')]
|
||||
[string]$Configuration = "Debug"
|
||||
[string]$Configuration = "Release"
|
||||
)
|
||||
Set-StrictMode -Version Latest
|
||||
$script:BuildLogFile = $null
|
||||
@ -321,16 +324,16 @@ function Start-SSHBuild
|
||||
if($PSBoundParameters.ContainsKey("Verbose"))
|
||||
{
|
||||
$script:Verbose = ($PSBoundParameters['Verbose']).IsPresent
|
||||
}
|
||||
}
|
||||
[bool] $silent = -not $script:Verbose
|
||||
|
||||
$script:BuildLogFile = Get-BuildLogFile -root $repositoryRoot.FullName -Configuration $Configuration -NativeHostArch $NativeHostArch
|
||||
if (Test-Path -Path $script:BuildLogFile)
|
||||
{
|
||||
Remove-Item -Path $script:BuildLogFile
|
||||
}
|
||||
|
||||
Write-BuildMsg -AsInfo -Message "Starting Open SSH build."
|
||||
Write-BuildMsg -AsInfo -Message "Build Log: $($script:BuildLogFile)"
|
||||
|
||||
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)"
|
||||
|
||||
Start-SSHBootstrap
|
||||
|
||||
@ -338,20 +341,19 @@ function Start-SSHBuild
|
||||
Copy-OpenSSLSDK
|
||||
$msbuildCmd = "msbuild.exe"
|
||||
$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
|
||||
$errorCode = $LASTEXITCODE
|
||||
|
||||
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
|
||||
@ -366,10 +368,10 @@ function Get-BuildLogFile
|
||||
[string]$NativeHostArch = "x64",
|
||||
|
||||
[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
|
||||
@ -414,4 +416,4 @@ function Get-RepositoryRoot
|
||||
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.
@ -37,6 +37,7 @@
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include "inc\utf.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
/* internal read buffer size */
|
||||
#define READ_BUFFER_SIZE 100*1024
|
||||
@ -76,7 +77,7 @@ int
|
||||
fileio_pipe(struct w32_io* pio[2]) {
|
||||
HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
|
||||
struct w32_io *pio_read = NULL, *pio_write = NULL;
|
||||
char pipe_name[MAX_PATH];
|
||||
char pipe_name[PATH_MAX];
|
||||
SECURITY_ATTRIBUTES sec_attributes;
|
||||
|
||||
if (pio == NULL) {
|
||||
@ -86,7 +87,7 @@ fileio_pipe(struct w32_io* pio[2]) {
|
||||
}
|
||||
|
||||
/* 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++)) {
|
||||
errno = EOTHER;
|
||||
debug("pipe - ERROR sprintf_s %d", errno);
|
||||
@ -564,15 +565,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
|
||||
|
||||
int
|
||||
fileio_stat(const char *path, struct _stat64 *buf) {
|
||||
wchar_t wpath[MAX_PATH];
|
||||
wchar_t* wtmp = NULL;
|
||||
wchar_t wpath[PATH_MAX];
|
||||
wchar_t* wtmp = NULL;
|
||||
|
||||
if ((wtmp = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
wcscpy(&wpath[0], wtmp);
|
||||
free(wtmp);
|
||||
if ((wtmp = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
wcscpy(&wpath[0], wtmp);
|
||||
free(wtmp);
|
||||
|
||||
return _wstat64(wpath, buf);
|
||||
return _wstat64(wpath, buf);
|
||||
}
|
||||
|
||||
long
|
||||
@ -597,8 +598,6 @@ fileio_fdopen(struct w32_io* pio, const char *mode) {
|
||||
debug2("fdopen - io:%p", pio);
|
||||
|
||||
/* logic below doesn't work with overlapped file HANDLES */
|
||||
errno = ENOTSUP;
|
||||
return NULL;
|
||||
|
||||
if (mode[1] == '\0') {
|
||||
switch (*mode) {
|
||||
|
@ -10,10 +10,11 @@
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include "..\misc_internal.h"
|
||||
|
||||
struct dirent {
|
||||
int d_ino; /* Inode number */
|
||||
char d_name[256]; /* Null-terminated filename */
|
||||
char d_name[PATH_MAX]; /* Null-terminated filename */
|
||||
};
|
||||
|
||||
typedef struct DIR_ DIR;
|
||||
|
@ -154,6 +154,8 @@ explicit_bzero(void *b, size_t len);
|
||||
/* string.h overrides */
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
char *w32_strerror(int);
|
||||
#define strerror w32_strerror
|
||||
|
||||
/* stdio.h overrides */
|
||||
#define fopen w32_fopen_utf8
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <NTSecPkg.h>
|
||||
#include <ntstatus.h>
|
||||
#include <stdio.h>
|
||||
#include "..\misc_internal.h"
|
||||
|
||||
#define Unsigned unsigned
|
||||
#define Char char
|
||||
@ -264,7 +265,7 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
|
||||
UNICODE_STRING *flatName = NULL;
|
||||
UCHAR *userAuth = NULL;
|
||||
ULONG userAuthSize;
|
||||
wchar_t homeDir[MAX_PATH];
|
||||
wchar_t homeDir[PATH_MAX];
|
||||
TOKEN_SOURCE tokenSource;
|
||||
|
||||
HANDLE token = NULL;
|
||||
@ -292,9 +293,9 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
|
||||
*authority, &token, logonId,
|
||||
*accountName, subStat));
|
||||
|
||||
NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile));
|
||||
*profileSize = MAX_PATH;
|
||||
NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t),
|
||||
NTFAIL(LsaApi.AllocateClientBuffer(request, PATH_MAX * sizeof(wchar_t), profile));
|
||||
*profileSize = PATH_MAX;
|
||||
NTFAIL(LsaApi.CopyToClientBuffer(request, PATH_MAX * sizeof(wchar_t),
|
||||
*profile, homeDir));
|
||||
|
||||
PLSA_TOKEN_INFORMATION_V1 outTokenInfo;
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include <time.h>
|
||||
#include <Shlwapi.h>
|
||||
#include "misc_internal.h"
|
||||
#include "inc\dlfcn.h"
|
||||
#include "inc\dirent.h"
|
||||
|
||||
int usleep(unsigned int useconds)
|
||||
{
|
||||
@ -114,51 +116,6 @@ explicit_bzero(void *b, size_t len) {
|
||||
SecureZeroMemory(b, len);
|
||||
}
|
||||
|
||||
int statvfs(const char *path, struct statvfs *buf) {
|
||||
DWORD sectorsPerCluster;
|
||||
DWORD bytesPerSector;
|
||||
DWORD freeClusters;
|
||||
DWORD totalClusters;
|
||||
|
||||
if (GetDiskFreeSpace(path, §orsPerCluster, &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) {
|
||||
return LoadLibraryA(filename);
|
||||
}
|
||||
@ -178,7 +135,7 @@ FARPROC dlsym(HMODULE handle, const char *symbol) {
|
||||
*/
|
||||
FILE*
|
||||
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;
|
||||
char utf8_bom[] = { 0xEF,0xBB,0xBF };
|
||||
char first3_bytes[3];
|
||||
@ -188,7 +145,7 @@ w32_fopen_utf8(const char *path, const char *mode) {
|
||||
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) {
|
||||
errno = EFAULT;
|
||||
debug("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError());
|
||||
@ -480,10 +437,16 @@ strmode(mode_t mode, char *p)
|
||||
}
|
||||
|
||||
int
|
||||
w32_chmod(const char *pathname, mode_t mode) {
|
||||
/* TODO - implement this */
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
w32_chmod(const char *pathname, mode_t mode) {
|
||||
int ret;
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(pathname));
|
||||
if (resolvedPathName_utf16 == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ret = _wchmod(resolvedPathName_utf16, mode);
|
||||
free(resolvedPathName_utf16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@ -493,20 +456,55 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group) {
|
||||
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
|
||||
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;
|
||||
|
||||
FILETIME acttime, modtime;
|
||||
wchar_t *resolvedPathName_utf16 = utf8_to_utf16(sanitized_path(filename));
|
||||
if (resolvedPathName_utf16 == NULL) {
|
||||
errno = ENOMEM;
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
@ -535,6 +533,28 @@ w32_rename(const char *old_name, const char *new_name) {
|
||||
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);
|
||||
free(resolvedOldPathName_utf16);
|
||||
free(resolvedNewPathName_utf16);
|
||||
@ -587,10 +607,10 @@ w32_chdir(const char *dirname_utf8) {
|
||||
|
||||
char *
|
||||
w32_getcwd(char *buffer, int maxlen) {
|
||||
wchar_t wdirname[MAX_PATH];
|
||||
wchar_t wdirname[PATH_MAX];
|
||||
char* putf8 = NULL;
|
||||
|
||||
_wgetcwd(&wdirname[0], MAX_PATH);
|
||||
_wgetcwd(&wdirname[0], PATH_MAX);
|
||||
|
||||
if ((putf8 = utf16_to_utf8(&wdirname[0])) == NULL)
|
||||
fatal("failed to convert input arguments");
|
||||
@ -609,8 +629,17 @@ w32_mkdir(const char *path_utf8, unsigned short mode) {
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
|
||||
|
||||
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
|
||||
* path to produce a canonicalized absolute pathname.
|
||||
*/
|
||||
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
|
||||
* path to produce a canonicalized absolute pathname.
|
||||
*/
|
||||
char *
|
||||
realpath(const char *path, char resolved[MAX_PATH]) {
|
||||
char tempPath[MAX_PATH];
|
||||
realpath(const char *path, char resolved[PATH_MAX]) {
|
||||
char tempPath[PATH_MAX];
|
||||
|
||||
if (*path == '/' && *(path + 2) == ':')
|
||||
if ((path[0] == '/') && path[1] && (path[2] == ':')) {
|
||||
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
|
||||
else
|
||||
} else {
|
||||
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;
|
||||
|
||||
convertToForwardslash(tempPath);
|
||||
@ -670,6 +705,27 @@ realpath(const char *path, char resolved[MAX_PATH]) {
|
||||
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
|
||||
// data is 16KB, plus there's a header.
|
||||
#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_HSM (0xC0000004L) // 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 {
|
||||
ULONG ReparseTag;
|
||||
@ -778,4 +833,107 @@ ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) {
|
||||
|
||||
CloseHandle(fileHandle);
|
||||
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, §orsPerCluster, &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 */
|
@ -1,3 +1,4 @@
|
||||
#define PATH_MAX MAX_PATH
|
||||
|
||||
/* 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 *);
|
@ -39,6 +39,7 @@
|
||||
#include "inc\pwd.h"
|
||||
#include "inc\grp.h"
|
||||
#include "inc\utf.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
static struct passwd pw;
|
||||
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;
|
||||
LPBYTE user_info = 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;
|
||||
int tmp_len = MAX_PATH;
|
||||
int tmp_len = PATH_MAX;
|
||||
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
||||
|
||||
errno = 0;
|
||||
@ -141,10 +142,10 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
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, ®_key) != 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 ||
|
||||
(pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL) {
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <Strsafe.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include "misc_internal.h"
|
||||
|
||||
#define MAX_CONSOLE_COLUMNS 9999
|
||||
#define MAX_CONSOLE_ROWS 9999
|
||||
@ -136,6 +137,7 @@ HANDLE pipe_in = INVALID_HANDLE_VALUE;
|
||||
HANDLE pipe_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE pipe_err = INVALID_HANDLE_VALUE;
|
||||
HANDLE child = INVALID_HANDLE_VALUE;
|
||||
DWORD child_exit_code = 0;
|
||||
HANDLE hConsoleBuffer = INVALID_HANDLE_VALUE;
|
||||
|
||||
HANDLE monitor_thread = INVALID_HANDLE_VALUE;
|
||||
@ -497,6 +499,7 @@ void SizeWindow(HANDLE hInput) {
|
||||
|
||||
DWORD WINAPI MonitorChild(_In_ LPVOID lpParameter) {
|
||||
WaitForSingleObject(child, INFINITE);
|
||||
GetExitCodeProcess(child, &child_exit_code);
|
||||
PostThreadMessage(hostThreadId, WM_APPEXIT, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -1066,15 +1069,15 @@ int start_with_pty(int ac, wchar_t **av) {
|
||||
/*TODO - pick this up from system32*/
|
||||
cmd[0] = L'\0';
|
||||
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--;
|
||||
av++;
|
||||
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) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
|
||||
ac--;
|
||||
av++;
|
||||
}
|
||||
@ -1088,8 +1091,7 @@ int start_with_pty(int ac, wchar_t **av) {
|
||||
Sleep(20);
|
||||
while (!AttachConsole(pi.dwProcessId))
|
||||
{
|
||||
DWORD exit_code;
|
||||
if (GetExitCodeProcess(pi.hProcess, &exit_code) && exit_code != STILL_ACTIVE)
|
||||
if (GetExitCodeProcess(pi.hProcess, &child_exit_code) && child_exit_code != STILL_ACTIVE)
|
||||
break;
|
||||
Sleep(100);
|
||||
}
|
||||
@ -1129,7 +1131,7 @@ cleanup:
|
||||
|
||||
FreeConsole();
|
||||
|
||||
return 0;
|
||||
return child_exit_code;
|
||||
}
|
||||
|
||||
HANDLE child_pipe_read;
|
||||
@ -1138,6 +1140,7 @@ DWORD WINAPI MonitorChild_nopty(
|
||||
_In_ LPVOID lpParameter
|
||||
) {
|
||||
WaitForSingleObject(child, INFINITE);
|
||||
GetExitCodeProcess(child, &child_exit_code);
|
||||
CloseHandle(pipe_in);
|
||||
//printf("XXXX CHILD PROCESS DEAD XXXXX");
|
||||
return 0;
|
||||
@ -1180,14 +1183,14 @@ int start_withno_pty(int ac, wchar_t **av) {
|
||||
|
||||
/*TODO - pick this up from system32*/
|
||||
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;
|
||||
av += 2;
|
||||
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) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
|
||||
ac--;
|
||||
av++;
|
||||
}
|
||||
@ -1282,7 +1285,7 @@ cleanup:
|
||||
TerminateProcess(child, 0);
|
||||
if (monitor_thread != INVALID_HANDLE_VALUE)
|
||||
WaitForSingleObject(monitor_thread, INFINITE);
|
||||
return 0;
|
||||
return child_exit_code;
|
||||
}
|
||||
|
||||
int wmain(int ac, wchar_t **av) {
|
||||
|
@ -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)) {
|
||||
//woken up by event signalled
|
||||
/* 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);
|
||||
sw_child_to_zombie(ret - WAIT_OBJECT_0);
|
||||
}
|
||||
|
@ -11,12 +11,17 @@ int sw_kill(int pid, int sig);
|
||||
/* child processes */
|
||||
#define MAX_CHILDREN 50
|
||||
struct _children {
|
||||
/*
|
||||
* array of handles and process_ids.
|
||||
* intial (num_children - num_zombies) are alive
|
||||
* rest are zombies
|
||||
*/
|
||||
HANDLE handles[MAX_CHILDREN];
|
||||
DWORD process_id[MAX_CHILDREN];
|
||||
/* total children */
|
||||
DWORD num_children;
|
||||
/* #zombies */
|
||||
/* (num_chileren - zombies) are live children */
|
||||
/* (num_children - zombies) are live children */
|
||||
DWORD num_zombies;
|
||||
};
|
||||
|
||||
|
@ -101,7 +101,7 @@ sw_remove_child_at_index(DWORD index) {
|
||||
|
||||
int
|
||||
sw_child_to_zombie(DWORD index) {
|
||||
DWORD last_non_zombie, last_child, zombie_pid;
|
||||
DWORD last_non_zombie, zombie_pid;
|
||||
HANDLE zombie_handle;
|
||||
|
||||
debug("zombie'ing child at index %d, %d zombies of %d", index,
|
||||
@ -112,17 +112,17 @@ sw_child_to_zombie(DWORD index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
zombie_pid = children.process_id[index];
|
||||
zombie_handle = children.handles[index];
|
||||
last_non_zombie = children.num_children - children.num_zombies - 1;
|
||||
last_child = children.num_children - 1;
|
||||
|
||||
children.handles[index] = children.handles[last_non_zombie];
|
||||
children.process_id[index] = children.process_id[last_non_zombie];
|
||||
|
||||
children.handles[last_non_zombie] = children.handles[index];
|
||||
children.process_id[last_non_zombie] = children.process_id[index];
|
||||
|
||||
|
||||
if (last_non_zombie != index) {
|
||||
/* swap */
|
||||
zombie_pid = children.process_id[index];
|
||||
zombie_handle = children.handles[index];
|
||||
children.handles[index] = children.handles[last_non_zombie];
|
||||
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++;
|
||||
return 0;
|
||||
}
|
||||
@ -185,10 +185,13 @@ int waitpid(int pid, int *status, int options) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
process = children.handles[index];
|
||||
ret = WaitForSingleObject(process, INFINITE);
|
||||
if (ret != WAIT_OBJECT_0)
|
||||
DebugBreak();//fatal
|
||||
/* wait if process is still alive */
|
||||
if (index < children.num_children - children.num_zombies) {
|
||||
process = children.handles[index];
|
||||
ret = WaitForSingleObject(process, INFINITE);
|
||||
if (ret != WAIT_OBJECT_0)
|
||||
DebugBreak();//fatal
|
||||
}
|
||||
|
||||
ret_id = children.process_id[index];
|
||||
GetExitCodeProcess(process, &exit_code);
|
||||
@ -200,6 +203,15 @@ int waitpid(int pid, int *status, int options) {
|
||||
}
|
||||
|
||||
/* 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;
|
||||
if (options & WNOHANG)
|
||||
timeout = 0;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "agent.h"
|
||||
#include <sddl.h>
|
||||
#include <UserEnv.h>
|
||||
#include "..\misc_internal.h"
|
||||
#define BUFSIZE 5 * 1024
|
||||
|
||||
static HANDLE ioc_port = NULL;
|
||||
@ -179,15 +180,15 @@ agent_listen_loop() {
|
||||
}
|
||||
else {
|
||||
/* 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;
|
||||
STARTUPINFOW si;
|
||||
|
||||
si.cb = 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);
|
||||
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,
|
||||
DETACHED_PROCESS, NULL, NULL,
|
||||
&si, &pi) == FALSE)) {
|
||||
|
@ -87,15 +87,15 @@ int GetCurrentModulePath(wchar_t *path, int pathSize)
|
||||
}
|
||||
|
||||
int load_config() {
|
||||
wchar_t basePath[MAX_PATH] = { 0 };
|
||||
wchar_t path[MAX_PATH] = { 0 };
|
||||
wchar_t basePath[PATH_MAX] = { 0 };
|
||||
wchar_t path[PATH_MAX] = { 0 };
|
||||
|
||||
/* TODO - account for UNICODE paths*/
|
||||
if (GetCurrentModulePath(basePath, MAX_PATH) == -1)
|
||||
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
|
||||
return -1;
|
||||
|
||||
wcsncpy(path, basePath, MAX_PATH);
|
||||
wcsncat(path, L"/sshd_config", MAX_PATH);
|
||||
wcsncpy(path, basePath, PATH_MAX);
|
||||
wcsncat(path, L"/sshd_config", PATH_MAX);
|
||||
|
||||
if ((config_file_name = utf16_to_utf8(path)) == NULL)
|
||||
return -1;
|
||||
|
@ -318,7 +318,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
||||
|
||||
if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, token, &wuser_home) != S_OK ||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include "inc\syslog.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
#define MSGBUFSIZ 1024
|
||||
static int logfd = -1;
|
||||
|
||||
void openlog(char *ident, unsigned int option, int facility) {
|
||||
if ((logfd == -1) && (ident != NULL)) {
|
||||
wchar_t path[MAX_PATH], log_file[MAX_PATH + 12];
|
||||
if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0)
|
||||
return;
|
||||
path[MAX_PATH - 1] = '\0';
|
||||
/* split path root and module */
|
||||
{
|
||||
wchar_t* tail = path + wcslen(path), *p;
|
||||
while (tail > path && *tail != L'\\' && *tail != L'/')
|
||||
tail--;
|
||||
void
|
||||
openlog(char *ident, unsigned int option, int facility) {
|
||||
if (logfd != -1 || ident == NULL)
|
||||
return;
|
||||
|
||||
wchar_t path[PATH_MAX], log_file[PATH_MAX + 12];
|
||||
if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
|
||||
|
||||
memcpy(log_file, path, (tail - path) * sizeof(wchar_t));
|
||||
p = log_file + (tail - path);
|
||||
memcpy(p, L"\\logs\\", 12);
|
||||
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);
|
||||
return;
|
||||
path[PATH_MAX - 1] = '\0';
|
||||
|
||||
/* split path root and module */
|
||||
{
|
||||
wchar_t* tail = path + wcslen(path), *p;
|
||||
while (tail > path && *tail != L'\\' && *tail != L'/')
|
||||
tail--;
|
||||
|
||||
memcpy(log_file, path, (tail - path) * sizeof(wchar_t));
|
||||
p = log_file + (tail - path);
|
||||
memcpy(p, L"\\logs\\", 12);
|
||||
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) {
|
||||
//NOOP
|
||||
void
|
||||
closelog(void) {
|
||||
/*NOOP*/
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,7 +27,7 @@ DIR * opendir(const char *name)
|
||||
struct _wfinddata_t c_file;
|
||||
intptr_t hFile;
|
||||
DIR *pdir;
|
||||
wchar_t searchstr[MAX_PATH];
|
||||
wchar_t searchstr[PATH_MAX];
|
||||
wchar_t* wname = NULL;
|
||||
int needed;
|
||||
|
||||
@ -37,7 +37,7 @@ DIR * opendir(const char *name)
|
||||
}
|
||||
|
||||
// add *.* for Windows _findfirst() search pattern
|
||||
swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname);
|
||||
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
|
||||
free(wname);
|
||||
|
||||
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. */
|
||||
struct dirent *readdir(void *avp)
|
||||
{
|
||||
struct dirent *pdirentry;
|
||||
static struct dirent pdirentry;
|
||||
struct _wfinddata_t c_file;
|
||||
DIR *dirp = (DIR *)avp;
|
||||
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 )
|
||||
continue;
|
||||
|
||||
if ((pdirentry = malloc(sizeof(struct dirent))) == NULL ||
|
||||
(tmp = utf16_to_utf8(c_file.name)) == NULL) {
|
||||
|
||||
if ((tmp = utf16_to_utf8(c_file.name)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(pdirentry->d_name, tmp, strlen(tmp) + 1);
|
||||
strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
|
||||
free(tmp);
|
||||
|
||||
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
|
||||
return pdirentry ;
|
||||
}
|
||||
pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero
|
||||
return &pdirentry ;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// end of dirent functions in Windows
|
||||
|
@ -112,8 +112,12 @@ int sshd_main(int argc, wchar_t **wargv) {
|
||||
w32posix_initialize();
|
||||
if (getenv("SSHD_REMSOC"))
|
||||
is_child = 1;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ Class Machine
|
||||
[string] $ClientKeyDirectory
|
||||
[string] $knownHostOfCurrentUser
|
||||
[string] $OpenSSHdir = $PSScriptRoot
|
||||
[string] $ToolsPath = "$env:ProgramData\chocolatey\lib\sysinternals\tools"
|
||||
[string] $ToolsPath = "$env:ProgramData\chocolatey\lib\sysinternals\tools"
|
||||
|
||||
Machine() {
|
||||
$this.Platform = Set-Platform
|
||||
@ -106,13 +106,13 @@ Class Machine
|
||||
}
|
||||
|
||||
[void] InitializeClient() {
|
||||
$this.ClientKeyDirectory = join-path ($env:USERPROFILE) ".ssh"
|
||||
$this.ClientKeyDirectory = join-path $PSScriptRoot "clientkeys"
|
||||
if(-not (Test-path $this.ClientKeyDirectory -PathType Container))
|
||||
{
|
||||
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"
|
||||
|
||||
@ -131,8 +131,7 @@ Class Machine
|
||||
$this.clientPrivateKeyPaths += $keyPath
|
||||
$this.clientPublicKeyPaths += "$keyPath.pub"
|
||||
$str = ".\ssh-keygen -t $key -P """" -f $keyPath"
|
||||
$this.RunCmd($str)
|
||||
|
||||
$this.RunCmd($str)
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,16 +210,27 @@ Class Machine
|
||||
}
|
||||
}
|
||||
|
||||
[void] CleanupServer() {
|
||||
Remove-Item -Path $this.localAdminAuthorizedKeyPath -Force -ea silentlycontinue
|
||||
[void] CleanupServer() {
|
||||
$sshPath = split-path $this.localAdminAuthorizedKeyPath -Parent
|
||||
if(Test-Path $sshPath -PathType Container )
|
||||
{
|
||||
Remove-item -path $sshPath -force -Recurse
|
||||
}
|
||||
|
||||
if ( $this.Platform -eq [PlatformType]::Windows )
|
||||
{
|
||||
$this.CleanupLocalAccountTokenFilterPolicy()
|
||||
}
|
||||
}
|
||||
|
||||
[void] CleanupClient() {
|
||||
Remove-Item -Path "$this.clientKeyPath\*" -Force -ea silentlycontinue
|
||||
[void] CleanupClient() {
|
||||
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) {
|
||||
@ -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
|
||||
[void] SetLocalAccountTokenFilterPolicy($setting) {
|
||||
$path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\system"
|
||||
@ -308,6 +331,7 @@ Class Machine
|
||||
$shell_app = $null
|
||||
}
|
||||
|
||||
#this does not work when "using module"; works fine when import the module
|
||||
[void] DownloadPStools()
|
||||
{
|
||||
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
|
||||
|
@ -98,31 +98,30 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
It 'SCP usage' {
|
||||
#TODO: usage output does not redirect to file
|
||||
}
|
||||
}#>
|
||||
|
||||
#this context only run on windows
|
||||
}#>
|
||||
|
||||
Context "Key is Secured in ssh-agent on server" {
|
||||
BeforeAll {
|
||||
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
|
||||
$identifyFile = $client.clientPrivateKeyPaths[0]
|
||||
$privateKeyFile = $client.clientPrivateKeyPaths[0]
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
$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)
|
||||
.\scp -i $identifyFile $Source $Destination
|
||||
.\scp -i $privateKeyFile $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).Length -eq 0
|
||||
$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)
|
||||
|
||||
.\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 | 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 | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#this context only run on windows
|
||||
|
||||
Context "Single signon with keys -p -v -c option Secured in ssh-agent" {
|
||||
BeforeAll {
|
||||
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
|
||||
@ -149,27 +147,27 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
.\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"
|
||||
#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 | 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)
|
||||
|
||||
.\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.
|
||||
$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 -r -p -v option: <Title> ' -TestCases:$testData1 {
|
||||
It 'Directory recursive copy with -r -p -v option: <Title> ' -TestCases:$testData1 {
|
||||
param([string]$Title, $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 = @(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 {
|
||||
$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)
|
||||
|
||||
.\scp -i $identifyFile -C -q $Source $Destination
|
||||
@ -191,16 +189,45 @@ Describe "Tests for scp command" -Tags "CI" {
|
||||
$equal | Should Be $true
|
||||
}
|
||||
|
||||
|
||||
It 'Directory recursive Copy with -i 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)
|
||||
|
||||
.\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 | 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 | 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,5 +135,28 @@ Describe "Tests for ssh command" -Tags "CI" {
|
||||
#validate file content.
|
||||
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
11
scp.c
@ -595,12 +595,17 @@ main(int argc, char **argv)
|
||||
#ifdef WINDOWS
|
||||
/*
|
||||
* To support both Windows and Unix style paths
|
||||
* convert '\\' to '/' in rest of arguments
|
||||
* convert '\\' to '/' in path portion of rest arguments
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
convertToForwardslash(argv[i]);
|
||||
char *p;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if(p = colon(argv[i]))
|
||||
convertToForwardslash(p);
|
||||
else
|
||||
convertToForwardslash(argv[i]);
|
||||
}
|
||||
}
|
||||
#endif /* WINDOWS */
|
||||
|
||||
|
@ -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>
|
||||
*
|
||||
@ -587,6 +587,8 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
|
||||
|
||||
if ((r = sshbuf_get_u32(msg, &count)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (count > SSHBUF_SIZE_MAX)
|
||||
fatal("%s: nonsensical number of entries", __func__);
|
||||
if (count == 0)
|
||||
break;
|
||||
debug3("Received %d SSH2_FXP_NAME responses", count);
|
||||
|
16
sftp.c
16
sftp.c
@ -320,12 +320,16 @@ static void
|
||||
local_do_shell(const char *args)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
/* execute via system call in Windows*/
|
||||
if (!*args) {
|
||||
/* TODO - support unicode ComSpec */
|
||||
/* execute via system call in Windows*/
|
||||
if (!*args) {
|
||||
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 */
|
||||
int status;
|
||||
char *shell;
|
||||
@ -1513,7 +1517,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
* convert '\\' to '/' in Windows styled paths.
|
||||
* else they get treated as escape sequence in makeargv
|
||||
*/
|
||||
convertToForwardslash(cmd);
|
||||
convertToForwardslash((char *)cmd);
|
||||
#endif
|
||||
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
|
||||
&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*/
|
||||
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);
|
||||
}
|
||||
|
@ -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>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@ -89,7 +89,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_PKCS11_WHITELIST
|
||||
# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*"
|
||||
# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
|
@ -221,7 +221,11 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
|
||||
fatal("Key must at least be 1024 bits");
|
||||
else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
|
||||
fatal("Invalid ECDSA key length - valid lengths are "
|
||||
#ifdef OPENSSL_HAS_NISTP521
|
||||
"256, 384 or 521 bits");
|
||||
#else
|
||||
"256 or 384 bits");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user