From c1680168e4035be32fb06fb1e1853a2b0607378d Mon Sep 17 00:00:00 2001 From: Manoj Ampalam Date: Fri, 18 Aug 2017 13:23:47 -0700 Subject: [PATCH] Source snapshot from Powershell/openssh-portable:latestw_all --- appveyor.yml | 2 +- contrib/win32/openssh/OpenSSHTestHelper.psm1 | 90 +++- contrib/win32/openssh/config.h.vs | 2 - contrib/win32/openssh/config.vcxproj | 58 +-- contrib/win32/openssh/install-sshd.ps1 | 5 +- contrib/win32/openssh/uninstall-sshd.ps1 | 7 +- .../win32/openssh/unittest-hostkeys.vcxproj | 8 +- contrib/win32/openssh/unittest-sshkey.vcxproj | 8 +- contrib/win32/openssh/version.rc | Bin 4066 -> 4066 bytes contrib/win32/win32compat/ansiprsr.c | 6 +- contrib/win32/win32compat/console.c | 96 ++-- contrib/win32/win32compat/console.h | 12 +- contrib/win32/win32compat/fileio.c | 13 +- contrib/win32/win32compat/misc.c | 56 ++- contrib/win32/win32compat/misc_internal.h | 3 +- contrib/win32/win32compat/pwd.c | 45 +- contrib/win32/win32compat/shell-host.c | 429 ++++++++++++------ contrib/win32/win32compat/signal.c | 8 +- contrib/win32/win32compat/socketio.c | 37 +- .../win32/win32compat/ssh-agent/agent-main.c | 1 + .../win32/win32compat/ssh-agent/agentconfig.c | 25 +- .../win32compat/ssh-agent/authagent-request.c | 20 +- .../win32/win32compat/ssh-agent/connection.c | 6 +- .../win32compat/ssh-agent/keyagent-request.c | 6 +- contrib/win32/win32compat/termio.c | 46 +- contrib/win32/win32compat/tncon.c | 11 +- contrib/win32/win32compat/tncon.h | 3 +- contrib/win32/win32compat/tnnet.c | 28 +- contrib/win32/win32compat/w32-sshfileperm.c | 17 +- contrib/win32/win32compat/w32log.c | 35 +- contrib/win32/win32compat/win32-utf8.c | 3 +- contrib/win32/win32compat/win32_dirent.c | 17 +- contrib/win32/win32compat/win32_sshtty.c | 14 +- contrib/win32/win32compat/wmain_common.c | 9 +- contrib/win32/win32compat/wmain_sshd.c | 1 + regress/pesterTests/KeyUtils.Tests.ps1 | 41 +- .../pesterTests/Userkey_fileperm.Tests.ps1 | 9 +- regress/unittests/win32compat/file_tests.c | 4 +- sftp.c | 3 +- 39 files changed, 810 insertions(+), 374 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c713ebf..b5f33f8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.0.17.0.{build} +version: 0.0.19.0.{build} image: Visual Studio 2015 branches: diff --git a/contrib/win32/openssh/OpenSSHTestHelper.psm1 b/contrib/win32/openssh/OpenSSHTestHelper.psm1 index bd1a341..a2a8a97 100644 --- a/contrib/win32/openssh/OpenSSHTestHelper.psm1 +++ b/contrib/win32/openssh/OpenSSHTestHelper.psm1 @@ -20,6 +20,8 @@ $Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName $Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName $Script:E2ETestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests" $Script:WindowsInBox = $false +$Script:EnableAppVerifier = $true +$Script:PostmortemDebugging = $false <# .Synopsis @@ -32,8 +34,10 @@ function Set-OpenSSHTestEnvironment param ( [string] $OpenSSHBinPath, - [string] $TestDataPath = "$env:SystemDrive\OpenSSHTests", - [Boolean] $DebugMode = $false + [string] $TestDataPath = "$env:SystemDrive\OpenSSHTests", + [Boolean] $DebugMode = $false, + [Switch] $NoAppVerifier, + [Switch] $PostmortemDebugging ) if($PSBoundParameters.ContainsKey("Verbose")) @@ -51,7 +55,11 @@ function Set-OpenSSHTestEnvironment $Script:UnitTestResultsFile = Join-Path $TestDataPath "UnitTestResults.txt" $Script:TestSetupLogFile = Join-Path $TestDataPath "TestSetupLog.txt" $Script:UnitTestDirectory = Get-UnitTestDirectory - + $Script:EnableAppVerifier = -not ($NoAppVerifier.IsPresent) + if($Script:EnableAppVerifier) + { + $Script:PostmortemDebugging = $PostmortemDebugging.IsPresent + } $Global:OpenSSHTestInfo = @{ "Target"= "localhost"; # test listener name @@ -67,6 +75,8 @@ function Set-OpenSSHTestEnvironment "E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests "UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests "DebugMode" = $DebugMode # run openssh E2E in debug mode + "EnableAppVerifier" = $Script:EnableAppVerifier + "PostmortemDebugging" = $Script:PostmortemDebugging } #if user does not set path, pick it up @@ -237,6 +247,24 @@ WARNING: Following changes will be made to OpenSSH configuration cmd /c "ssh-add -D 2>&1 >> $Script:TestSetupLogFile" Repair-UserKeyPermission -FilePath $testPriKeypath -confirm:$false cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile" + + #Enable AppVerifier + if($EnableAppVerifier) + { + # clear all applications in application verifier first + & $env:windir\System32\appverif.exe -disable * -for * | out-null + Get-ChildItem "$($script:OpenSSHBinPath)\*.exe" | % { + & $env:windir\System32\appverif.exe -verify $_.Name | out-null + } + + if($Script:PostmortemDebugging -and (Test-path $Script:WindbgPath)) + { + # enable Postmortem debugger + New-ItemProperty "HKLM:Software\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Debugger -Type String -Value "`"$Script:WindbgPath`" -p %ld -e %ld -g" -Force -ErrorAction SilentlyContinue | Out-Null + New-ItemProperty "HKLM:Software\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Auto -Type String -Value "1" -Force -ErrorAction SilentlyContinue | Out-Null + } + } + Backup-OpenSSHTestInfo } #TODO - this is Windows specific. Need to be in PAL @@ -294,6 +322,31 @@ function Install-OpenSSHTestDependencies Write-Log -Message "Installing Pester..." choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile } + + if($Script:PostmortemDebugging -or (($OpenSSHTestInfo -ne $null) -and ($OpenSSHTestInfo["PostmortemDebugging"]))) + { + $folderName = "x86" + $pathroot = $env:ProgramFiles + if($env:PROCESSOR_ARCHITECTURE -ieq "AMD64") + { + $folderName = "x64" + $pathroot = ${env:ProgramFiles(x86)} + } + $Script:WindbgPath = "$pathroot\Windows Kits\8.1\Debuggers\$folderName\windbg.exe" + if(-not (Test-Path $Script:WindbgPath)) + { + $Script:WindbgPath = "$pathroot\Windows Kits\10\Debuggers\$folderName\windbg.exe" + if(-not (Test-Path $Script:WindbgPath)) + { + choco install windbg -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile + } + } + } + + if(($Script:EnableAppVerifier -or (($OpenSSHTestInfo -ne $null) -and ($OpenSSHTestInfo["EnableAppVerifier"]))) -and (-not (Test-path $env:windir\System32\appverif.exe))) + { + choco install appverifier -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile + } } function Install-OpenSSHUtilsModule @@ -313,12 +366,12 @@ function Install-OpenSSHUtilsModule } $modulePath = Join-Path -Path $env:ProgramFiles -ChildPath WindowsPowerShell\Modules - if(-not (Test-Path $targetDirectory -PathType Container)) + if(-not (Test-Path "$targetDirectory" -PathType Container)) { - New-Item -ItemType Directory -Path $targetDirectory -Force -ErrorAction SilentlyContinue | out-null + New-Item -ItemType Directory -Path "$targetDirectory" -Force -ErrorAction SilentlyContinue | out-null } - Copy-item $manifestFile -Destination $targetDirectory -Force -ErrorAction SilentlyContinue | out-null - Copy-item $moduleFile -Destination $targetDirectory -Force -ErrorAction SilentlyContinue | out-null + Copy-item "$manifestFile" -Destination "$targetDirectory" -Force -ErrorAction SilentlyContinue | out-null + Copy-item "$moduleFile" -Destination "$targetDirectory" -Force -ErrorAction SilentlyContinue | out-null if ($PSVersionTable.PSVersion.Major -lt 4) { @@ -396,6 +449,18 @@ function Clear-OpenSSHTestEnvironment Get-ChildItem "$sshBinPath\sshtest*hostkey*.pub"| % { ssh-add-hostkey.ps1 -Delete_key $_.FullName } + + if($Global:OpenSSHTestInfo["EnableAppVerifier"] -and (Test-path $env:windir\System32\appverif.exe)) + { + # clear all applications in application verifier + & $env:windir\System32\appverif.exe -disable * -for * | out-null + } + + if($Global:OpenSSHTestInfo["PostmortemDebugging"]) + { + Remove-ItemProperty "HKLM:Software\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Debugger -ErrorAction SilentlyContinue -Force | Out-Null + Remove-ItemProperty "HKLM:Software\Microsoft\Windows NT\CurrentVersion\AeDebug" -Name Auto -ErrorAction SilentlyContinue -Force | Out-Null + } Remove-Item $sshBinPath\sshtest*hostkey* -Force -ErrorAction SilentlyContinue #Restore sshd_config @@ -442,7 +507,7 @@ function Clear-OpenSSHTestEnvironment { Write-Log -Message "Uninstalling Module OpenSSHUtils..." Uninstall-OpenSSHUtilsModule - } + } } <# @@ -506,13 +571,18 @@ function Get-UnitTestDirectory Run OpenSSH pester tests. #> function Invoke-OpenSSHE2ETest -{ +{ + [CmdletBinding()] + param + ( + [ValidateSet('CI', 'Scenario')] + [string]$pri = "CI") # Discover all CI tests and run them. Import-Module pester -force -global Push-Location $Script:E2ETestDirectory Write-Log -Message "Running OpenSSH E2E tests..." $testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique) - Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag 'CI' + Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag $pri -PassThru Pop-Location } diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs index e049e33..69bdc87 100644 --- a/contrib/win32/openssh/config.h.vs +++ b/contrib/win32/openssh/config.h.vs @@ -189,11 +189,9 @@ /* Define to 1 if you have the `arc4random' function. */ /* #undef HAVE_ARC4RANDOM */ -#define HAVE_ARC4RANDOM 1 /* Define to 1 if you have the `arc4random_buf' function. */ /* #undef HAVE_ARC4RANDOM_BUF */ -#define HAVE_ARC4RANDOM_BUF 1 /* Define to 1 if you have the `arc4random_uniform' function. */ /* #undef HAVE_ARC4RANDOM_UNIFORM */ diff --git a/contrib/win32/openssh/config.vcxproj b/contrib/win32/openssh/config.vcxproj index 67e9187..fbf48b0 100644 --- a/contrib/win32/openssh/config.vcxproj +++ b/contrib/win32/openssh/config.vcxproj @@ -112,18 +112,18 @@ $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories) - powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' + powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h" Generate crtheaders.h and config.h - copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir) -copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir) -copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir) -If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir)) + copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)" +copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)" +copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)" +If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)") Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, OpenSSHUtils.psd1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory @@ -145,18 +145,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories) - powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' + powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h" Generate crtheaders.h and config.h - copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir) -copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir) -copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir) -If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir)) + copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)" +copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)" +copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)" +If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)") Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, OpenSSHUtils.psd1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory @@ -182,18 +182,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories) - powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' + powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h" Generate crtheaders.h and config.h - copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir) -copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir) -copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir) -If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir)) + copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)" +copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)" +copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)" +If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)") Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, OpenSSHUtils.psd1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory @@ -219,18 +219,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories) - powershell.exe -Executionpolicy Bypass "$(SolutionDir)config.ps1" -Config_h_vs '$(SolutionDir)config.h.vs' -Config_h '$(OpenSSH-Src-Path)config.h' -VCIncludePath '$(VC_IncludePath)' -OutCRTHeader '$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h' + powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h" Generate crtheaders.h and config.h - copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir) -copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir) -copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir) -copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir) -If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir)) + copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)" +copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)" +copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)" +copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)" +If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)") Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, OpenSSHUtils.psd1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, ssh-add-hostkey.ps1, and sshd_config (if not already present) to build directory @@ -240,4 +240,4 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir)) - \ No newline at end of file + diff --git a/contrib/win32/openssh/install-sshd.ps1 b/contrib/win32/openssh/install-sshd.ps1 index f7b0df1..6052bae 100644 --- a/contrib/win32/openssh/install-sshd.ps1 +++ b/contrib/win32/openssh/install-sshd.ps1 @@ -255,13 +255,13 @@ if (-not (Test-Path $sshdpath)) { if (Get-Service sshd -ErrorAction SilentlyContinue) { Stop-Service sshd - sc.exe delete sshd 1> null + sc.exe delete sshd 1>$null } if (Get-Service ssh-agent -ErrorAction SilentlyContinue) { Stop-Service ssh-agent - sc.exe delete ssh-agent 1> null + sc.exe delete ssh-agent 1>$null } New-Service -Name ssh-agent -BinaryPathName $sshagentpath -Description "SSH Agent" -StartupType Manual | Out-Null @@ -272,6 +272,7 @@ sc.exe config sshd obj= $sshdAccount sc.exe privs sshd SeAssignPrimaryTokenPrivilege Add-Privilege -Account $sshdSid -Privilege SeAssignPrimaryTokenPrivilege +Add-Privilege -Account $sshdSid -Privilege SeServiceLogonRight if(-not (test-path $logsdir -PathType Container)) { diff --git a/contrib/win32/openssh/uninstall-sshd.ps1 b/contrib/win32/openssh/uninstall-sshd.ps1 index 8f0cd90..7ccff62 100644 --- a/contrib/win32/openssh/uninstall-sshd.ps1 +++ b/contrib/win32/openssh/uninstall-sshd.ps1 @@ -1,7 +1,7 @@ if (Get-Service sshd -ErrorAction SilentlyContinue) { Stop-Service sshd - sc.exe delete sshd 1> null + sc.exe delete sshd 1>$null Write-Host -ForegroundColor Green "sshd successfully uninstalled" } else { @@ -11,12 +11,9 @@ else { if (Get-Service ssh-agent -ErrorAction SilentlyContinue) { Stop-Service ssh-agent - sc.exe delete ssh-agent 1>null + sc.exe delete ssh-agent 1>$null Write-Host -ForegroundColor Green "ssh-agent successfully uninstalled" } else { Write-Host -ForegroundColor Yellow "ssh-agent service is not installed" } - - - diff --git a/contrib/win32/openssh/unittest-hostkeys.vcxproj b/contrib/win32/openssh/unittest-hostkeys.vcxproj index 870afc5..ca3eefd 100644 --- a/contrib/win32/openssh/unittest-hostkeys.vcxproj +++ b/contrib/win32/openssh/unittest-hostkeys.vcxproj @@ -123,7 +123,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)" @@ -149,7 +149,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)" @@ -177,7 +177,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)" @@ -206,7 +206,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)" diff --git a/contrib/win32/openssh/unittest-sshkey.vcxproj b/contrib/win32/openssh/unittest-sshkey.vcxproj index 1f26481..d643165 100644 --- a/contrib/win32/openssh/unittest-sshkey.vcxproj +++ b/contrib/win32/openssh/unittest-sshkey.vcxproj @@ -123,7 +123,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)" @@ -149,7 +149,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)" @@ -177,7 +177,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)" @@ -206,7 +206,7 @@ targetos.manifest - xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir) + xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)" diff --git a/contrib/win32/openssh/version.rc b/contrib/win32/openssh/version.rc index b43900b189bf78f38d5f31e376e60ad550bd221c..bfe76721a19e60801bfd8adb10cc7b23bae95fc1 100644 GIT binary patch delta 44 ucmaDP|44qr6b?qq$x}Iu87()T diff --git a/contrib/win32/win32compat/ansiprsr.c b/contrib/win32/win32compat/ansiprsr.c index 6845749..a3bfaa5 100644 --- a/contrib/win32/win32compat/ansiprsr.c +++ b/contrib/win32/win32compat/ansiprsr.c @@ -473,12 +473,12 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char case '^': /* Private message */ /* while not stop */ while (pszCurrent && pszCurrent < pszBufferEnd && - _strnicmp((const char *)pszCurrent, (const char *)VT_ST, strlen((const char *)VT_ST))) { + _strnicmp((const char *)pszCurrent, (const char *)VT_ST, strnlen((const char *)VT_ST, sizeof(VT_ST)))) { if (pszCurrent && pszCurrent < pszBufferEnd && - _strnicmp((const char *)pszCurrent, (const char *)VT_ST, strlen((const char *)VT_ST))) + _strnicmp((const char *)pszCurrent, (const char *)VT_ST, strnlen((const char *)VT_ST, sizeof(VT_ST)))) pszCurrent++; } - pszCurrent += strlen((const char *)VT_ST) - 1; + pszCurrent += strnlen((const char *)VT_ST, sizeof(VT_ST)) - 1; fcompletion = 1; break; diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c index fdd51d2..bb574ae 100644 --- a/contrib/win32/win32compat/console.c +++ b/contrib/win32/win32compat/console.c @@ -42,7 +42,8 @@ #include "ansiprsr.h" HANDLE hOutputConsole = NULL; -DWORD dwSavedAttributes = 0; +DWORD stdin_dwSavedAttributes = 0; +DWORD stdout_dwSavedAttributes = 0; WORD wStartingAttributes = 0; int ScreenX; @@ -72,8 +73,8 @@ int in_raw_mode = 0; char *consoleTitle = "OpenSSH SSH client"; /* Used to enter the raw mode */ -int -ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) +void +ConEnterRawMode() { DWORD dwAttributes = 0; DWORD dwRet = 0; @@ -81,22 +82,22 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) CONSOLE_SCREEN_BUFFER_INFO csbi; static bool bFirstConInit = true; - hOutputConsole = GetStdHandle(OutputHandle); + hOutputConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (hOutputConsole == INVALID_HANDLE_VALUE) { dwRet = GetLastError(); error("GetStdHandle on OutputHandle failed with %d\n", dwRet); - return dwRet; + return; } - if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &dwSavedAttributes)) { + if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &stdin_dwSavedAttributes)) { dwRet = GetLastError(); error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); - return dwRet; + return; } SetConsoleTitle(consoleTitle); - dwAttributes = dwSavedAttributes; + dwAttributes = stdin_dwSavedAttributes; dwAttributes &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT); dwAttributes |= ENABLE_WINDOW_INPUT; @@ -104,17 +105,17 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) { /* Windows NT */ dwRet = GetLastError(); error("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet); - return dwRet; + return; } - if (!GetConsoleMode(hOutputConsole, &dwAttributes)) { + if (!GetConsoleMode(hOutputConsole, &stdout_dwSavedAttributes)) { dwRet = GetLastError(); error("GetConsoleMode on hOutputConsole failed with %d\n", dwRet); - return dwRet; - + return; } - dwAttributes |= (DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING; + dwAttributes = stdout_dwSavedAttributes; + dwAttributes |= (DWORD)ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; char *envValue = NULL; _dupenv_s(&envValue, NULL, "SSH_TERM_CONHOST_PARSER"); @@ -140,7 +141,7 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) SavedViewRect = csbi.srWindow; debug("console doesn't support the ansi parsing"); } else { - ConMoveCursorTop(csbi); + ConSaveViewRect(); debug("console supports the ansi parsing"); } @@ -150,26 +151,18 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit) ScrollBottom = ConVisibleWindowHeight(); in_raw_mode = 1; - - return 0; } /* Used to Uninitialize the Console */ -int +void ConExitRawMode() { - CONSOLE_SCREEN_BUFFER_INFO consoleInfo; - in_raw_mode = 0; - if (hOutputConsole == NULL || !GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) - return 0; - - SetConsoleMode(hOutputConsole, dwSavedAttributes); - - return 0; + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), stdin_dwSavedAttributes); + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), stdout_dwSavedAttributes); } /* Used to exit the raw mode */ -int +void ConUnInitWithRestore() { DWORD dwWritten; @@ -177,19 +170,19 @@ ConUnInitWithRestore() CONSOLE_SCREEN_BUFFER_INFO consoleInfo; if (hOutputConsole == NULL) - return 0; + return; if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) - return 0; + return; - SetConsoleMode(hOutputConsole, dwSavedAttributes); + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), stdin_dwSavedAttributes); + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), stdout_dwSavedAttributes); Coord = consoleInfo.dwCursorPosition; Coord.X = 0; DWORD dwNumChar = (consoleInfo.dwSize.Y - consoleInfo.dwCursorPosition.Y) * consoleInfo.dwSize.X; FillConsoleOutputCharacter(hOutputConsole, ' ', dwNumChar, Coord, &dwWritten); FillConsoleOutputAttribute(hOutputConsole, wStartingAttributes, dwNumChar, Coord, &dwWritten); SetConsoleTextAttribute(hOutputConsole, wStartingAttributes); - return 0; } BOOL @@ -524,12 +517,12 @@ ConWriteString(char* pszString, int cbString) if ((needed = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, NULL, 0)) == 0 || (utf16 = malloc(needed * sizeof(wchar_t))) == NULL || (cnt = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, utf16, needed)) == 0) { - Result = (DWORD)printf(pszString); + Result = (DWORD)printf_s(pszString); } else { if (hOutputConsole) WriteConsoleW(hOutputConsole, utf16, cnt, &Result, 0); else - Result = (DWORD)wprintf(utf16); + Result = (DWORD)wprintf_s(utf16); } if (utf16) @@ -546,7 +539,7 @@ ConTranslateAndWriteString(char* pszString, int cbString) if (hOutputConsole) WriteConsole(hOutputConsole, pszString, cbString, &Result, 0); else - Result = (DWORD)printf(pszString); + Result = (DWORD)printf_s(pszString); return Result; } @@ -836,7 +829,11 @@ Con_printf(const char *Format, ...) memset(temp, '\0', sizeof(temp)); va_start(va_data, Format); - len = vsnprintf(temp, sizeof(temp), Format, va_data); + len = vsnprintf_s(temp, sizeof(temp), _TRUNCATE, Format, va_data); + if (len == -1) { + error("Error from vsnprintf_s!"); + return -1; + } ConWriteConsole(temp, len); va_end(va_data); @@ -1080,6 +1077,7 @@ ConMoveVisibleWindow(int offset) { CONSOLE_SCREEN_BUFFER_INFO consoleInfo; SMALL_RECT visibleWindowRect; + errno_t r = 0; memset(&visibleWindowRect, 0, sizeof(SMALL_RECT)); if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) { @@ -1090,14 +1088,19 @@ ConMoveVisibleWindow(int offset) for (int i = 0; i < offset; i++) ConScrollDown(0, consoleInfo.dwSize.Y - 1); - if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) - memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect)); - else { + if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo) == FALSE) { error("GetConsoleScreenBufferInfo failed with %d", GetLastError()); return; } + if ((r = memcpy_s(&visibleWindowRect, sizeof(visibleWindowRect), &consoleInfo.srWindow, sizeof(visibleWindowRect))) != 0) { + error("memcpy_s failed with error: %d.", r); + return; + } } else { - memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect)); + if ((r = memcpy_s(&visibleWindowRect, sizeof(visibleWindowRect), &consoleInfo.srWindow, sizeof(visibleWindowRect))) != 0) { + error("memcpy_s failed with error: %d.", r); + return; + } visibleWindowRect.Top += offset; visibleWindowRect.Bottom += offset; } @@ -1571,16 +1574,17 @@ ConSaveWindowsState() } void -ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi) +ConMoveCursorTopOfVisibleWindow() { - /* Windows server at first sends the "cls" after the connection is established. - * Since we don't want to loose any data on the console, we would like to scroll down - * the visible window. - */ - int offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top; - ConMoveVisibleWindow(offset); + CONSOLE_SCREEN_BUFFER_INFO csbi; + int offset; - ConSaveViewRect(); + if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi)) { + offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top; + ConMoveVisibleWindow(offset); + + ConSaveViewRect(); + } } HANDLE diff --git a/contrib/win32/win32compat/console.h b/contrib/win32/win32compat/console.h index 46c73bf..9d44e5b 100644 --- a/contrib/win32/win32compat/console.h +++ b/contrib/win32/win32compat/console.h @@ -83,11 +83,15 @@ #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 #endif +#ifndef DISABLE_NEWLINE_AUTO_RETURN +#define DISABLE_NEWLINE_AUTO_RETURN 0x8 +#endif + typedef void * SCREEN_HANDLE; -int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit); -int ConUnInitWithRestore(); -int ConExitRawMode(); +void ConEnterRawMode(); +void ConUnInitWithRestore(); +void ConExitRawMode(); BOOL ConIsRedirected(HANDLE hInput); HANDLE GetConsoleOutputHandle(); HANDLE GetConsoleInputHandle(); @@ -141,6 +145,6 @@ void ConSaveWindowsState(); void ConMoveVisibleWindow(int offset); int is_cursor_at_lastline_of_visible_window(); void ConGetCursorPosition(int *x, int *y); -void ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi); +void ConMoveCursorTopOfVisibleWindow(); HANDLE get_console_handle(FILE *, DWORD *); #endif diff --git a/contrib/win32/win32compat/fileio.c b/contrib/win32/win32compat/fileio.c index c876adb..03ac241 100644 --- a/contrib/win32/win32compat/fileio.c +++ b/contrib/win32/win32compat/fileio.c @@ -532,6 +532,7 @@ int fileio_read(struct w32_io* pio, void *dst, size_t max_bytes) { int bytes_copied; + errno_t r = 0; debug5("read - io:%p remaining:%d", pio, pio->read_details.remaining); @@ -605,7 +606,10 @@ fileio_read(struct w32_io* pio, void *dst, size_t max_bytes) } bytes_copied = min((DWORD)max_bytes, pio->read_details.remaining); - memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied); + if ((r = memcpy_s(dst, max_bytes, pio->read_details.buf + pio->read_details.completed, bytes_copied)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } pio->read_details.remaining -= bytes_copied; pio->read_details.completed += bytes_copied; debug4("read - io:%p read: %d remaining: %d", pio, bytes_copied, @@ -641,6 +645,7 @@ fileio_write(struct w32_io* pio, const void *buf, size_t max_bytes) { int bytes_copied; DWORD pipe_flags = 0, pipe_instances = 0; + errno_t r = 0; debug4("write - io:%p", pio); if (pio->write_details.pending) { @@ -678,7 +683,10 @@ fileio_write(struct w32_io* pio, const void *buf, size_t max_bytes) } bytes_copied = min((int)max_bytes, pio->write_details.buf_size); - memcpy(pio->write_details.buf, buf, bytes_copied); + if((r = memcpy_s(pio->write_details.buf, max_bytes, buf, bytes_copied)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } if (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) { if (syncio_initiate_write(pio, bytes_copied) == 0) { @@ -726,7 +734,6 @@ fileio_write(struct w32_io* pio, const void *buf, size_t max_bytes) } debug4("write - reporting %d bytes written, io:%p", bytes_copied, pio); return bytes_copied; - } /* fstat() implemetation */ diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c index 144589d..5b76466 100644 --- a/contrib/win32/win32compat/misc.c +++ b/contrib/win32/win32compat/misc.c @@ -244,6 +244,7 @@ w32_fopen_utf8(const char *path, const char *mode) char utf8_bom[] = { 0xEF,0xBB,0xBF }; char first3_bytes[3]; int status = 1; + errno_t r = 0; if (mode[1] != '\0') { errno = ENOTSUP; @@ -257,8 +258,12 @@ w32_fopen_utf8(const char *path, const char *mode) } /* if opening null device, point to Windows equivalent */ - if (0 == strncmp(path, NULL_DEVICE, strlen(NULL_DEVICE)+1)) - wcsncpy_s(wpath, PATH_MAX, L"NUL", 3); + if (0 == strncmp(path, NULL_DEVICE, strlen(NULL_DEVICE)+1)) { + if ((r = wcsncpy_s(wpath, PATH_MAX, L"NUL", 3)) != 0) { + debug3("wcsncpy_s failed with error: %d.", r); + return NULL; + } + } else status = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX); @@ -308,6 +313,7 @@ char* wchar_t* str_w = NULL; char *ret = NULL, *str_tmp = NULL, *cp = NULL; int actual_read = 0; + errno_t r = 0; if (h != NULL && h != INVALID_HANDLE_VALUE && GetFileType(h) == FILE_TYPE_CHAR) { @@ -338,7 +344,10 @@ char* if((actual_read + strlen(str_tmp)) >= n) break; - memcpy(cp, str_tmp, strlen(str_tmp)); + if ((r = memcpy_s(cp, n - actual_read, str_tmp, strlen(str_tmp))) != 0) { + debug3("memcpy_s failed with error: %d.", r); + goto cleanup; + } actual_read += (int)strlen(str_tmp); cp += strlen(str_tmp); @@ -766,7 +775,8 @@ w32_getcwd(char *buffer, int maxlen) return NULL; } - strcpy_s(buffer, maxlen, putf8); + if (strcpy_s(buffer, maxlen, putf8)) + return NULL; free(putf8); return buffer; @@ -807,7 +817,8 @@ w32_stat(const char *path, struct w32_stat *buf) int readlink(const char *path, char *link, int linklen) { - strcpy_s(link, linklen, sanitized_path(path)); + if(strcpy_s(link, linklen, sanitized_path(path))) + return -1; return 0; } @@ -850,6 +861,7 @@ convertToForwardslash(char *str) char * realpath(const char *path, char resolved[PATH_MAX]) { + errno_t r = 0; if (!path || !resolved) return NULL; char tempPath[PATH_MAX]; @@ -860,10 +872,16 @@ realpath(const char *path, char resolved[PATH_MAX]) return NULL; } - if ((path_len >= 2) && (path[0] == '/') && path[1] && (path[2] == ':')) - strncpy_s(resolved, PATH_MAX, path + 1, path_len); /* skip the first '/' */ - else - strncpy_s(resolved, PATH_MAX, path, path_len + 1); + if ((path_len >= 2) && (path[0] == '/') && path[1] && (path[2] == ':')) { + if((r = strncpy_s(resolved, PATH_MAX, path + 1, path_len)) != 0 ) /* skip the first '/' */ { + debug3("memcpy_s failed with error: %d.", r); + return NULL; + } + } + else if(( r = strncpy_s(resolved, PATH_MAX, path, path_len + 1)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return NULL; + } if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { /* make "x:" as "x:\\" */ resolved[2] = '\\'; @@ -876,8 +894,10 @@ realpath(const char *path, char resolved[PATH_MAX]) convertToForwardslash(tempPath); resolved[0] = '/'; /* will be our first slash in /x:/users/test1 format */ - if (strncpy_s(resolved+1, PATH_MAX - 1, tempPath, sizeof(tempPath) - 1) != 0) + if ((r = strncpy_s(resolved+1, PATH_MAX - 1, tempPath, sizeof(tempPath) - 1)) != 0) { + debug3("memcpy_s failed with error: %d.", r); return NULL; + } return resolved; } @@ -887,11 +907,15 @@ sanitized_path(const char *path) if(!path) return NULL; static char newPath[PATH_MAX] = { '\0', }; + errno_t r = 0; if (path[0] == '/' && path[1]) { if (path[2] == ':') { if (path[3] == '\0') { /* make "/x:" as "x:\\" */ - strncpy_s(newPath, sizeof(PATH_MAX), path + 1, strlen(path) - 1); + if((r = strncpy_s(newPath, sizeof(newPath), path + 1, strlen(path) - 1)) != 0 ) { + debug3("memcpy_s failed with error: %d.", r); + return NULL; + } newPath[2] = '\\'; newPath[3] = '\0'; @@ -993,7 +1017,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) } else if (ch == '\b') { /* backspace */ if (current_index > 0) { if (flags & RPP_ECHO_ON) - printf("%c \b", ch); + printf_s("%c \b", ch); current_index--; /* overwrite last character */ } @@ -1012,7 +1036,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) outBuf[current_index++] = ch; if(flags & RPP_ECHO_ON) - printf("%c", ch); + printf_s("%c", ch); } } @@ -1021,3 +1045,9 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags) return outBuf; } + +void invalid_parameter_handler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) +{ + debug3("Invalid parameter in function: %ls. File: %ls Line: %d.", function, file, line); + debug3("Expression: %s", expression); +} diff --git a/contrib/win32/win32compat/misc_internal.h b/contrib/win32/win32compat/misc_internal.h index abf818a..a416f21 100644 --- a/contrib/win32/win32compat/misc_internal.h +++ b/contrib/win32/win32compat/misc_internal.h @@ -30,4 +30,5 @@ void convertToForwardslash(char *str); int errno_from_Win32Error(int); void unix_time_to_file_time(ULONG, LPFILETIME); void file_time_to_unix_time(const LPFILETIME, time_t *); -int file_attr_to_st_mode(wchar_t * path, DWORD attributes); \ No newline at end of file +int file_attr_to_st_mode(wchar_t * path, DWORD attributes); +void invalid_parameter_handler(const wchar_t *, const wchar_t *, const wchar_t *, unsigned int, uintptr_t); \ No newline at end of file diff --git a/contrib/win32/win32compat/pwd.c b/contrib/win32/win32compat/pwd.c index 1740be9..e60096b 100644 --- a/contrib/win32/win32compat/pwd.c +++ b/contrib/win32/win32compat/pwd.c @@ -51,15 +51,23 @@ static char* pw_shellpath = NULL; int initialize_pw() { + errno_t r = 0; + char* program_dir = w32_programdir(); + size_t program_dir_len = strlen(program_dir); + size_t shell_host_len = strlen(SHELL_HOST); if (pw_shellpath == NULL) { - if ((pw_shellpath = malloc(strlen(w32_programdir()) + strlen(SHELL_HOST) + 1)) == NULL) + if ((pw_shellpath = malloc(program_dir_len + shell_host_len + 1)) == NULL) fatal("initialize_pw - out of memory"); else { char* head = pw_shellpath; - memcpy(head, w32_programdir(), strlen(w32_programdir())); - head += strlen(w32_programdir()); - memcpy(head, SHELL_HOST, strlen(SHELL_HOST)); - head += strlen(SHELL_HOST); + if ((r= memcpy_s(head, program_dir_len + shell_host_len + 1, w32_programdir(), program_dir_len)) != 0) { + fatal("memcpy_s failed with error: %d.", r); + } + head += program_dir_len; + if ((r = memcpy_s(head, shell_host_len + 1, SHELL_HOST, shell_host_len)) != 0) { + fatal("memcpy_s failed with error: %d.", r); + } + head += shell_host_len; *head = '\0'; } } @@ -102,7 +110,8 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) HKEY reg_key = 0; int tmp_len = PATH_MAX; PDOMAIN_CONTROLLER_INFOW pdc = NULL; - DWORD dsStatus, uname_upn_len = 0;; + DWORD dsStatus, uname_upn_len = 0, uname_len = 0, udom_len = 0; + errno_t r = 0; errno = 0; reset_pw(); @@ -154,7 +163,7 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) } /* if one of below fails, set profile path to Windows directory */ - if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX || + if (swprintf_s(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == -1 || 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) if (GetWindowsDirectoryW(profile_home, PATH_MAX) == 0) { @@ -170,21 +179,29 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) errno = ENOMEM; goto done; } - - uname_upn_len = (DWORD) strlen(uname_utf8) + 1; - if (udom_utf8) - uname_upn_len += (DWORD)strlen(udom_utf8) + 1; + uname_len = (DWORD)strlen(uname_utf8); + uname_upn_len = uname_len + 1; + if (udom_utf8) { + udom_len = (DWORD)strlen(udom_utf8); + uname_upn_len += udom_len + 1; + } if ((uname_upn = malloc(uname_upn_len)) == NULL) { errno = ENOMEM; goto done; } - memcpy(uname_upn, uname_utf8, strlen(uname_utf8) + 1); + if ((r = memcpy_s(uname_upn, uname_upn_len, uname_utf8, uname_len + 1)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + goto done; + } if (udom_utf8) { /* TODO - get domain FQDN */ - uname_upn[strlen(uname_utf8)] = '@'; - memcpy(uname_upn + strlen(uname_utf8) + 1, udom_utf8, strlen(udom_utf8) + 1); + uname_upn[uname_len] = '@'; + if ((r = memcpy_s(uname_upn + uname_len + 1, udom_len + 1, udom_utf8, udom_len + 1)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + goto done; + } } pw.pw_name = uname_upn; uname_upn = NULL; diff --git a/contrib/win32/win32compat/shell-host.c b/contrib/win32/win32compat/shell-host.c index 019a657..621099e 100644 --- a/contrib/win32/win32compat/shell-host.c +++ b/contrib/win32/win32compat/shell-host.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include "misc_internal.h" #include "inc\utf.h" @@ -53,6 +55,33 @@ #define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 #endif +#define VK_A 0x41 +#define VK_B 0x42 +#define VK_C 0x43 +#define VK_D 0x44 +#define VK_E 0x45 +#define VK_F 0x46 +#define VK_G 0x47 +#define VK_H 0x48 +#define VK_I 0x49 +#define VK_J 0x4A +#define VK_K 0x4B +#define VK_L 0x4C +#define VK_M 0x4D +#define VK_N 0x4E +#define VK_O 0x4F +#define VK_P 0x50 +#define VK_Q 0x51 +#define VK_R 0x52 +#define VK_S 0x53 +#define VK_T 0x54 +#define VK_U 0x55 +#define VK_V 0x56 +#define VK_W 0x57 +#define VK_X 0x58 +#define VK_Y 0x59 +#define VK_Z 0x5A + typedef BOOL(WINAPI *__t_SetCurrentConsoleFontEx)( _In_ HANDLE hConsoleOutput, _In_ BOOL bMaximumWindow, @@ -90,48 +119,83 @@ struct key_translation { int vk; wchar_t out; int in_key_len; + DWORD ctrlState; } key_translation; -/* All the substrings (Ex- "\x1b") should be in the end, otherwise ProcessIncomingKeys() will not work as expected */ +/* All the substrings should be in the end, otherwise ProcessIncomingKeys() will not work as expected */ struct key_translation keys[] = { - { L"\r", VK_RETURN, L'\r' , 0}, - { L"\b", VK_BACK, L'\b' , 0}, - { L"\x7f", VK_BACK, L'\b' , 0}, - { L"\t", VK_TAB, L'\t' , 0}, - { L"\x1b[A", VK_UP, 0 , 0}, - { L"\x1b[B", VK_DOWN, 0 , 0}, - { L"\x1b[C", VK_RIGHT, 0 , 0}, - { L"\x1b[D", VK_LEFT, 0 , 0}, - { L"\x1b[F", VK_END, 0 , 0 }, /* KeyPad END */ - { L"\x1b[H", VK_HOME, 0 , 0 }, /* KeyPad HOME */ - { L"\x1b[Z", 0, 0 , 0 }, /* ignore Shift+TAB */ - { L"\x1b[1~", VK_HOME, 0 , 0}, - { L"\x1b[2~", VK_INSERT, 0 , 0}, - { L"\x1b[3~", VK_DELETE, 0 , 0}, - { L"\x1b[4~", VK_END, 0 , 0}, - { L"\x1b[5~", VK_PRIOR, 0 , 0}, - { L"\x1b[6~", VK_NEXT, 0 , 0}, - { L"\x1b[11~", VK_F1, 0 , 0}, - { L"\x1b[12~", VK_F2, 0 , 0}, - { L"\x1b[13~", VK_F3, 0 , 0}, - { L"\x1b[14~", VK_F4, 0 , 0}, - { L"\x1b[15~", VK_F5, 0 , 0}, - { L"\x1b[17~", VK_F6, 0 , 0}, - { L"\x1b[18~", VK_F7, 0 , 0}, - { L"\x1b[19~", VK_F8, 0 , 0}, - { L"\x1b[20~", VK_F9, 0 , 0}, - { L"\x1b[21~", VK_F10, 0 , 0}, - { L"\x1b[23~", VK_F11, 0 , 0}, - { L"\x1b[24~", VK_F12, 0 , 0}, - { L"\x1bOP", VK_F1, 0 , 0 }, - { L"\x1bOQ", VK_F2, 0 , 0 }, - { L"\x1bOR", VK_F3, 0 , 0 }, - { L"\x1bOS", VK_F4, 0 , 0 }, - { L"\x1b", VK_ESCAPE, L'\x1b' , 0} + { L"\r", VK_RETURN, L'\r' , 0 , 0}, + { L"\n", VK_RETURN, L'\r' , 0 , 0 }, + { L"\b", VK_BACK, L'\b' , 0 , 0 }, + { L"\x7f", VK_BACK, L'\b' , 0 , 0 }, + { L"\t", VK_TAB, L'\t' , 0 , 0}, + { L"\x1b[A", VK_UP, 0 , 0 , 0}, + { L"\x1b[B", VK_DOWN, 0 , 0 , 0}, + { L"\x1b[C", VK_RIGHT, 0 , 0 , 0}, + { L"\x1b[D", VK_LEFT, 0 , 0 , 0}, + { L"\x1b[F", VK_END, 0 , 0 , 0}, /* KeyPad END */ + { L"\x1b[H", VK_HOME, 0 , 0 , 0}, /* KeyPad HOME */ + { L"\x1b[Z", 0, 0 , 0 , 0}, /* ignore Shift+TAB */ + { L"\x1b[1~", VK_HOME, 0 , 0 , 0}, + { L"\x1b[2~", VK_INSERT, 0 , 0 , 0}, + { L"\x1b[3~", VK_DELETE, 0 , 0 , 0}, + { L"\x1b[4~", VK_END, 0 , 0 , 0}, + { L"\x1b[5~", VK_PRIOR, 0 , 0 , 0}, + { L"\x1b[6~", VK_NEXT, 0 , 0 , 0}, + { L"\x1b[11~", VK_F1, 0 , 0 , 0}, + { L"\x1b[12~", VK_F2, 0 , 0 , 0}, + { L"\x1b[13~", VK_F3, 0 , 0 , 0}, + { L"\x1b[14~", VK_F4, 0 , 0 , 0}, + { L"\x1b[15~", VK_F5, 0 , 0 , 0}, + { L"\x1b[17~", VK_F6, 0 , 0 , 0}, + { L"\x1b[18~", VK_F7, 0 , 0 , 0}, + { L"\x1b[19~", VK_F8, 0 , 0 , 0}, + { L"\x1b[20~", VK_F9, 0 , 0 , 0}, + { L"\x1b[21~", VK_F10, 0 , 0 , 0}, + { L"\x1b[23~", VK_F11, 0 , 0 , 0}, + { L"\x1b[24~", VK_F12, 0 , 0 , 0}, + { L"\x1bOA", VK_UP, 0 , 0 , 0}, + { L"\x1bOB", VK_DOWN, 0 , 0 , 0}, + { L"\x1bOC", VK_RIGHT, 0 , 0 , 0}, + { L"\x1bOD", VK_LEFT, 0 , 0 , 0}, + { L"\x1bOF", VK_END, 0 , 0 , 0}, /* KeyPad END */ + { L"\x1bOH", VK_HOME, 0 , 0 , 0}, /* KeyPad HOME */ + { L"\x1bOP", VK_F1, 0 , 0 , 0}, + { L"\x1bOQ", VK_F2, 0 , 0 , 0}, + { L"\x1bOR", VK_F3, 0 , 0 , 0}, + { L"\x1bOS", VK_F4, 0 , 0 , 0}, + { L"\x1b?", VK_OEM_2, L'?' , 0 , SHIFT_PRESSED | LEFT_ALT_PRESSED}, + { L"\x1", VK_A, L'\x1' , 0 , LEFT_CTRL_PRESSED}, + { L"\x2", VK_B, L'\x2' , 0 , LEFT_CTRL_PRESSED}, + //{ L"\x3", VK_C, L'\x3' , 0 , LEFT_CTRL_PRESSED}, /* Control + C is handled differently */ + { L"\x4", VK_D, L'\x4' , 0 , LEFT_CTRL_PRESSED}, + { L"\x5", VK_E, L'\x5' , 0 , LEFT_CTRL_PRESSED}, + { L"\x6", VK_F, L'\x6' , 0 , LEFT_CTRL_PRESSED}, + { L"\x7", VK_G, L'\x7' , 0 , LEFT_CTRL_PRESSED}, + { L"\x8", VK_H, L'\x8' , 0 , LEFT_CTRL_PRESSED}, + { L"\x9", VK_I, L'\x9' , 0 , LEFT_CTRL_PRESSED}, + { L"\xA", VK_J, L'\xA' , 0 , LEFT_CTRL_PRESSED}, + { L"\xB", VK_K, L'\xB' , 0 , LEFT_CTRL_PRESSED}, + { L"\xC", VK_L, L'\xC' , 0 , LEFT_CTRL_PRESSED}, + { L"\xD", VK_M, L'\xD' , 0 , LEFT_CTRL_PRESSED}, + { L"\xE", VK_N, L'\xE' , 0 , LEFT_CTRL_PRESSED}, + { L"\xF", VK_O, L'\xF' , 0 , LEFT_CTRL_PRESSED}, + { L"\x10", VK_P, L'\x10' , 0 , LEFT_CTRL_PRESSED}, + { L"\x11", VK_Q, L'\x11' , 0 , LEFT_CTRL_PRESSED}, + { L"\x12", VK_R, L'\x12' , 0 , LEFT_CTRL_PRESSED}, + { L"\x13", VK_S, L'\x13' , 0 , LEFT_CTRL_PRESSED}, + { L"\x14", VK_T, L'\x14' , 0 , LEFT_CTRL_PRESSED}, + { L"\x15", VK_U, L'\x15' , 0 , LEFT_CTRL_PRESSED}, + { L"\x16", VK_V, L'\x16' , 0 , LEFT_CTRL_PRESSED}, + { L"\x17", VK_W, L'\x17' , 0 , LEFT_CTRL_PRESSED}, + { L"\x18", VK_X, L'\x18' , 0 , LEFT_CTRL_PRESSED}, + { L"\x19", VK_Y, L'\x19' , 0 , LEFT_CTRL_PRESSED}, + { L"\x1A", VK_Z, L'\x1A' , 0 , LEFT_CTRL_PRESSED} }; static SHORT lastX = 0; static SHORT lastY = 0; +static wchar_t system32_path[PATH_MAX]; static wchar_t cmd_exe_path[PATH_MAX]; SHORT currentLine = 0; @@ -201,60 +265,149 @@ ConSRWidth() return consoleBufferInfo.srWindow.Right; } +void +my_invalid_parameter_handler(const wchar_t* expression, const wchar_t* function, + const wchar_t* file, unsigned int line, uintptr_t pReserved) +{ + wprintf_s(L"Invalid parameter in function: %s. File: %s Line: %d\n", function, file, line); + wprintf_s(L"Expression: %s\n", expression); +} + +struct key_translation * +FindKeyTransByMask(wchar_t prefix, const wchar_t * value, int vlen, wchar_t suffix) +{ + struct key_translation *k = NULL; + for (int i = 0; i < ARRAYSIZE(keys); i++) { + k = &keys[i]; + if (k->in_key_len < vlen + 2) continue; + if (k->in[0] != L'\033') continue; + if (k->in[1] != prefix) continue; + if (k->in[vlen + 2] != suffix) continue; + + if (vlen <= 1 && value[0] == k->in[2]) + return k; + if (vlen > 1 && wcsncmp(&k->in[2], value, vlen) == 0) + return k; + } + + return NULL; +} + +int +GetVirtualKeyByMask(wchar_t prefix, const wchar_t * value, int vlen, wchar_t suffix) +{ + struct key_translation * pk = FindKeyTransByMask(prefix, value, vlen, suffix); + return pk ? pk->vk : 0; +} + /* * This function will handle the console keystrokes. */ -void -SendKeyStroke(HANDLE hInput, int keyStroke, wchar_t character) +void +SendKeyStrokeEx(HANDLE hInput, int vKey, wchar_t character, DWORD ctrlState, BOOL keyDown) { DWORD wr = 0; INPUT_RECORD ir; ir.EventType = KEY_EVENT; - ir.Event.KeyEvent.bKeyDown = TRUE; - ir.Event.KeyEvent.wRepeatCount = 1; - ir.Event.KeyEvent.wVirtualKeyCode = keyStroke; - ir.Event.KeyEvent.wVirtualScanCode = 0; - ir.Event.KeyEvent.dwControlKeyState = 0; + ir.Event.KeyEvent.bKeyDown = keyDown; + ir.Event.KeyEvent.wRepeatCount = 0; + ir.Event.KeyEvent.wVirtualKeyCode = vKey; + ir.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyA(vKey, MAPVK_VK_TO_VSC); + ir.Event.KeyEvent.dwControlKeyState = ctrlState; ir.Event.KeyEvent.uChar.UnicodeChar = character; WriteConsoleInputW(hInput, &ir, 1, &wr); +} - ir.Event.KeyEvent.bKeyDown = FALSE; - WriteConsoleInputW(hInput, &ir, 1, &wr); +void +SendKeyStroke(HANDLE hInput, int keyStroke, wchar_t character, DWORD ctrlState) +{ + SendKeyStrokeEx(hInput, keyStroke, character, ctrlState, TRUE); + SendKeyStrokeEx(hInput, keyStroke, character, ctrlState, FALSE); } void initialize_keylen() { for(int i = 0; i < ARRAYSIZE(keys); i++) - keys[i].in_key_len = (int) wcslen(keys[i].in); + keys[i].in_key_len = (int) wcsnlen(keys[i].in, _countof(keys[i].in)); +} + +int +ProcessCtrlSequence(wchar_t *buf, int buf_len) +{ + int vkey = 0; + /* Decode special keys when pressed CTRL key */ + if (buf[0] == L'\033' && buf[1] == L'[' && buf[buf_len - 3] == L';' && buf[buf_len - 2] == L'5') { + if (buf[buf_len - 1] == L'~') { + /* VK_DELETE, VK_PGDN, VK_PGUP */ + if (!vkey && buf_len == 6) + vkey = GetVirtualKeyByMask(L'[', &buf[2], 1, L'~'); + + /* VK_F1 ... VK_F12 */ + if (!vkey && buf_len == 7) + vkey = GetVirtualKeyByMask(L'[', &buf[2], 2, L'~'); + } else { + /* VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN */ + if (!vkey && buf_len == 6 && buf[2] == L'1') + vkey = GetVirtualKeyByMask(L'[', &buf[5], 1, 0); + + /* VK_F1 ... VK_F4 */ + if (!vkey && buf_len == 6 && buf[2] == L'1' && isalpha(buf[5])) + vkey = GetVirtualKeyByMask(L'O', &buf[5], 1, 0); + } + if (vkey) + SendKeyStroke(child_in, vkey, 0, LEFT_CTRL_PRESSED); + } + + return vkey; } void ProcessIncomingKeys(char * ansikey) { + int buf_len = 0; + const int MAX_CTRL_SEQ_LEN = 7; + const wchar_t *ESC_SEQ = L"\x1b"; wchar_t *buf = utf8_to_utf16(ansikey); - + if (!buf) { - printf("\nFailed to deserialize the client data, error:%d\n", GetLastError()); + printf_s("\nFailed to deserialize the client data, error:%d\n", GetLastError()); exit(255); } loop: - while (buf && (wcslen(buf) > 0)) { + while (buf && ((buf_len=(int)wcslen(buf)) > 0)) { for (int j = 0; j < ARRAYSIZE(keys); j++) { - if ( (wcslen(buf) >= keys[j].in_key_len) && (wcsncmp(buf, keys[j].in, keys[j].in_key_len) == 0) ) { - SendKeyStroke(child_in, keys[j].vk, keys[j].out); + if ( (buf_len >= keys[j].in_key_len) && (wcsncmp(buf, keys[j].in, keys[j].in_key_len) == 0) ) { + SendKeyStroke(child_in, keys[j].vk, keys[j].out, keys[j].ctrlState); buf += keys[j].in_key_len; goto loop; } } + /* Decode special keys when pressed CTRL key. CTRL sequences can be of size 6 or 7. */ + if ((buf_len >= MAX_CTRL_SEQ_LEN) && ProcessCtrlSequence(buf, MAX_CTRL_SEQ_LEN)) { + buf += MAX_CTRL_SEQ_LEN; + goto loop; + } + + if ((buf_len >= (MAX_CTRL_SEQ_LEN - 1)) && ProcessCtrlSequence(buf, MAX_CTRL_SEQ_LEN - 1)) { + buf += (MAX_CTRL_SEQ_LEN - 1); + goto loop; + } + + if(wcsncmp(buf, ESC_SEQ, wcslen(ESC_SEQ)) == 0) { + SendKeyStroke(child_in, VK_ESCAPE, L'\x1b', 0); + buf += wcslen(ESC_SEQ); + goto loop; + } + if (*buf == L'\x3') /*Ctrl+C - Raise Ctrl+C*/ GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); else - SendKeyStroke(child_in, 0, *buf); + SendKeyStroke(child_in, 0, *buf, 0); buf++; } @@ -321,11 +474,11 @@ void SendSetCursor(HANDLE hInput, int X, int Y) { DWORD wr = 0; - DWORD out = 0; + int out = 0; char formatted_output[255]; out = _snprintf_s(formatted_output, sizeof(formatted_output), _TRUNCATE, "\033[%d;%dH", Y, X); - if (bUseAnsiEmulation) + if (out > 0 && bUseAnsiEmulation) WriteFile(hInput, formatted_output, out, &wr, NULL); } @@ -333,15 +486,15 @@ void SendVerticalScroll(HANDLE hInput, int lines) { DWORD wr = 0; - DWORD out = 0; + int out = 0; char formatted_output[255]; LONG vn = abs(lines); /* Not supporting the [S at the moment. */ if (lines > 0) { - out = snprintf(formatted_output, sizeof(formatted_output), "\033[%dT", vn); + out = _snprintf_s(formatted_output, sizeof(formatted_output), _TRUNCATE, "\033[%dT", vn); - if (bUseAnsiEmulation) + if (out > 0 && bUseAnsiEmulation) WriteFile(hInput, formatted_output, out, &wr, NULL); } } @@ -350,12 +503,12 @@ void SendHorizontalScroll(HANDLE hInput, int cells) { DWORD wr = 0; - DWORD out = 0; + int out = 0; char formatted_output[255]; - out = snprintf(formatted_output, sizeof(formatted_output), "\033[%dG", cells); + out = _snprintf_s(formatted_output, sizeof(formatted_output), _TRUNCATE, "\033[%dG", cells); - if (bUseAnsiEmulation) + if (out > 0 && bUseAnsiEmulation) WriteFile(hInput, formatted_output, out, &wr, NULL); } @@ -460,10 +613,13 @@ SendBuffer(HANDLE hInput, CHAR_INFO *buffer, DWORD bufferSize) } void -CalculateAndSetCursor(HANDLE hInput, UINT x, UINT y) +CalculateAndSetCursor(HANDLE hInput, short x, short y, BOOL scroll) { + if (scroll && y > currentLine) + for (short n = currentLine; n < y; n++) + SendLF(hInput); - SendSetCursor(pipe_out, x + 1, y + 1); + SendSetCursor(hInput, x + 1, y + 1); currentLine = y; } @@ -486,16 +642,16 @@ SizeWindow(HANDLE hInput) matchingFont.FontWeight = FW_NORMAL; wcscpy_s(matchingFont.FaceName, LF_FACESIZE, L"Consolas"); - bSuccess = __SetCurrentConsoleFontEx(child_out, FALSE, &matchingFont); + bSuccess = __SetCurrentConsoleFontEx(hInput, FALSE, &matchingFont); /* This information is the live screen */ ZeroMemory(&consoleInfo, sizeof(consoleInfo)); consoleInfo.cbSize = sizeof(consoleInfo); - bSuccess = GetConsoleScreenBufferInfoEx(child_out, &consoleInfo); + bSuccess = GetConsoleScreenBufferInfoEx(hInput, &consoleInfo); /* Get the largest size we can size the console window to */ - coordScreen = GetLargestConsoleWindowSize(child_out); + coordScreen = GetLargestConsoleWindowSize(hInput); /* Define the new console window size and scroll position */ if (inputSi.dwXCountChars == 0 || inputSi.dwYCountChars == 0) { @@ -507,18 +663,18 @@ SizeWindow(HANDLE hInput) srWindowRect.Bottom = min((SHORT)inputSi.dwYCountChars, coordScreen.Y) - 1; srWindowRect.Left = srWindowRect.Top = (SHORT)0; - /* Define the new console buffer size to be the maximum possible */ - coordScreen.X = 100; + /* Define the new console buffer history to be the maximum possible */ + coordScreen.X = srWindowRect.Right + 1; /* buffer width must be equ window width */ coordScreen.Y = 9999; - if (SetConsoleWindowInfo(child_out, TRUE, &srWindowRect)) - bSuccess = SetConsoleScreenBufferSize(child_out, coordScreen); + if (SetConsoleWindowInfo(hInput, TRUE, &srWindowRect)) + bSuccess = SetConsoleScreenBufferSize(hInput, coordScreen); else { - if (SetConsoleScreenBufferSize(child_out, coordScreen)) - bSuccess = SetConsoleWindowInfo(child_out, TRUE, &srWindowRect); + if (SetConsoleScreenBufferSize(hInput, coordScreen)) + bSuccess = SetConsoleWindowInfo(hInput, TRUE, &srWindowRect); } - bSuccess = GetConsoleScreenBufferInfoEx(child_out, &consoleInfo); + bSuccess = GetConsoleScreenBufferInfoEx(hInput, &consoleInfo); } DWORD WINAPI @@ -543,20 +699,25 @@ ProcessEvent(void *p) HWND hwnd; LONG idObject; LONG idChild; + CHAR_INFO pBuffer[MAX_EXPECTED_BUFFER_SIZE] = {0,}; + DWORD bufferSize; + SMALL_RECT readRect; + COORD coordBufSize; + COORD coordBufCoord; if (!p) return ERROR_INVALID_PARAMETER; consoleEvent* current = (consoleEvent *)p; - if (current) { - event = current->event; - hwnd = current->hwnd; - idObject = current->idObject; - idChild = current->idChild; - } else + if (!current) return ERROR_INVALID_PARAMETER; + event = current->event; + hwnd = current->hwnd; + idObject = current->idObject; + idChild = current->idChild; + if (event < EVENT_CONSOLE_CARET || event > EVENT_CONSOLE_LAYOUT) return ERROR_INVALID_PARAMETER; @@ -586,14 +747,15 @@ ProcessEvent(void *p) lastX = co.X; lastY = co.Y; - SendSetCursor(pipe_out, lastX + 1, lastY + 1); + if (lastX == 0 && lastY > currentLine) + CalculateAndSetCursor(pipe_out, lastX, lastY, TRUE); + else + SendSetCursor(pipe_out, lastX + 1, lastY + 1); break; } case EVENT_CONSOLE_UPDATE_REGION: { - SMALL_RECT readRect; - readRect.Top = HIWORD(idObject); readRect.Left = LOWORD(idObject); readRect.Bottom = HIWORD(idChild); @@ -617,8 +779,7 @@ ProcessEvent(void *p) } } - /* Figure out the buffer size */ - COORD coordBufSize; + /* Figure out the buffer size */ coordBufSize.Y = readRect.Bottom - readRect.Top + 1; coordBufSize.X = readRect.Right - readRect.Left + 1; @@ -632,7 +793,7 @@ ProcessEvent(void *p) return ERROR_INVALID_PARAMETER; /* Compute buffer size */ - DWORD bufferSize = coordBufSize.X * coordBufSize.Y; + bufferSize = coordBufSize.X * coordBufSize.Y; if (bufferSize > MAX_EXPECTED_BUFFER_SIZE) { if (!bStartup) { SendClearScreen(pipe_out); @@ -641,38 +802,22 @@ ProcessEvent(void *p) } return ERROR_SUCCESS; } - - /* Create the screen scrape buffer */ - CHAR_INFO *pBuffer = (PCHAR_INFO)malloc(sizeof(CHAR_INFO) * bufferSize); - if (!pBuffer) - return ERROR_INSUFFICIENT_BUFFER; - - /* The top left destination cell of the temporary buffer is row 0, col 0 */ - COORD coordBufCoord; + + /* The top left destination cell of the temporary buffer is row 0, col 0 */ coordBufCoord.X = 0; coordBufCoord.Y = 0; /* Copy the block from the screen buffer to the temp. buffer */ - if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) { - DWORD dwError = GetLastError(); - - free(pBuffer); - return dwError; - } - - if (readRect.Top > currentLine) - for (SHORT n = currentLine; n < readRect.Top; n++) - SendLF(pipe_out); + if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) + return GetLastError(); /* Set cursor location based on the reported location from the message */ - CalculateAndSetCursor(pipe_out, readRect.Left, readRect.Top); + CalculateAndSetCursor(pipe_out, readRect.Left, readRect.Top, TRUE); /* Send the entire block */ SendBuffer(pipe_out, pBuffer, bufferSize); lastViewPortY = ViewPortY; - lastLineLength = readRect.Left; - - free(pBuffer); + lastLineLength = readRect.Left; break; } @@ -683,38 +828,27 @@ ProcessEvent(void *p) wX = LOWORD(idObject); wY = HIWORD(idObject); - SMALL_RECT readRect; readRect.Top = wY; readRect.Bottom = wY; readRect.Left = wX; readRect.Right = ConSRWidth(); /* Set cursor location based on the reported location from the message */ - CalculateAndSetCursor(pipe_out, wX, wY); - - COORD coordBufSize; + CalculateAndSetCursor(pipe_out, wX, wY, TRUE); + coordBufSize.Y = readRect.Bottom - readRect.Top + 1; coordBufSize.X = readRect.Right - readRect.Left + 1; + bufferSize = coordBufSize.X * coordBufSize.Y; /* The top left destination cell of the temporary buffer is row 0, col 0 */ - COORD coordBufCoord; coordBufCoord.X = 0; coordBufCoord.Y = 0; - int pBufferSize = coordBufSize.X * coordBufSize.Y; - /* Send the one character. Note that a CR doesn't end up here */ - CHAR_INFO *pBuffer = (PCHAR_INFO)malloc(sizeof(CHAR_INFO) * pBufferSize); - if (!pBuffer) - return ERROR_INSUFFICIENT_BUFFER; /* Copy the block from the screen buffer to the temp. buffer */ - if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) { - DWORD dwError = GetLastError(); - free(pBuffer); - return dwError; - } + if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) + return GetLastError(); - SendBuffer(pipe_out, pBuffer, pBufferSize); - free(pBuffer); + SendBuffer(pipe_out, pBuffer, bufferSize); break; } @@ -951,13 +1085,16 @@ cleanup: wchar_t * w32_cmd_path() { - ZeroMemory(cmd_exe_path, PATH_MAX); - if (!GetSystemDirectory(cmd_exe_path, sizeof(cmd_exe_path))) { - printf("GetSystemDirectory failed"); + errno_t r = 0; + if ((r = wcsncpy_s(cmd_exe_path, _countof(cmd_exe_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)) != 0) { + printf_s("wcsncpy_s failed with error: %d.", r); exit(255); } - wcscat_s(cmd_exe_path, sizeof(cmd_exe_path), L"\\cmd.exe"); + if ((r = wcscat_s(cmd_exe_path, _countof(cmd_exe_path), L"\\cmd.exe")) != 0) { + printf_s("wcscat_s failed with error: %d.", r); + exit(255); + } return cmd_exe_path; } @@ -972,18 +1109,25 @@ start_with_pty(wchar_t *command) DWORD dwStatus; HANDLE hEventHook = NULL; HMODULE hm_kernel32 = NULL, hm_user32 = NULL; + wchar_t kernel32_dll_path[PATH_MAX]={0,}, user32_dll_path[PATH_MAX]={0,}; if(cmd == NULL) { - printf("ssh-shellhost is out of memory"); + printf_s("ssh-shellhost is out of memory"); exit(255); } - - if ((hm_kernel32 = LoadLibraryW(L"kernel32.dll")) == NULL || - (hm_user32 = LoadLibraryW(L"user32.dll")) == NULL || + + GOTO_CLEANUP_ON_ERR(wcsncpy_s(kernel32_dll_path, _countof(kernel32_dll_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)); + GOTO_CLEANUP_ON_ERR(wcscat_s(kernel32_dll_path, _countof(kernel32_dll_path), L"\\kernel32.dll")); + + GOTO_CLEANUP_ON_ERR(wcsncpy_s(user32_dll_path, _countof(user32_dll_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)); + GOTO_CLEANUP_ON_ERR(wcscat_s(user32_dll_path, _countof(user32_dll_path), L"\\user32.dll")); + + if ((hm_kernel32 = LoadLibraryW(kernel32_dll_path)) == NULL || + (hm_user32 = LoadLibraryW(user32_dll_path)) == NULL || (__SetCurrentConsoleFontEx = (__t_SetCurrentConsoleFontEx)GetProcAddress(hm_kernel32, "SetCurrentConsoleFontEx")) == NULL || (__UnhookWinEvent = (__t_UnhookWinEvent)GetProcAddress(hm_user32, "UnhookWinEvent")) == NULL || (__SetWinEventHook = (__t_SetWinEventHook)GetProcAddress(hm_user32, "SetWinEventHook")) == NULL) { - printf("cannot support a pseudo terminal. \n"); + printf_s("cannot support a pseudo terminal. \n"); return -1; } @@ -1130,7 +1274,7 @@ start_withno_pty(wchar_t *command) DWORD rd = 0, wr = 0, i = 0; if (cmd == NULL) { - printf("ssh-shellhost is out of memory"); + printf_s("ssh-shellhost is out of memory"); exit(255); } @@ -1310,13 +1454,10 @@ cleanup: return child_exit_code; } -#include -#include - static void* xmalloc(size_t size) { void* ptr; if ((ptr = malloc(size)) == NULL) { - printf("out of memory"); + printf_s("out of memory"); exit(EXIT_FAILURE); } return ptr; @@ -1387,7 +1528,7 @@ static void setup_session_user_vars() path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2); GetEnvironmentVariableW(L"PATH", path_value, required); path_value[required - 1] = L';'; - memcpy(path_value + required, to_apply, (wcslen(to_apply) + 1) * 2); + GOTO_CLEANUP_ON_ERR(memcpy_s(path_value + required, (wcslen(to_apply) + 1) * 2, to_apply, (wcslen(to_apply) + 1) * 2)); to_apply = path_value; } @@ -1395,6 +1536,7 @@ static void setup_session_user_vars() if (to_apply) SetEnvironmentVariableW(name, to_apply); } +cleanup: if (reg_key) RegCloseKey(reg_key); if (data) @@ -1414,13 +1556,14 @@ wmain(int ac, wchar_t **av) int pty_requested = 0; wchar_t *cmd = NULL, *cmd_b64 = NULL; + _set_invalid_parameter_handler(my_invalid_parameter_handler); if ((ac == 1) || (ac == 2 && wcscmp(av[1], L"-nopty"))) { pty_requested = 1; cmd_b64 = ac == 2? av[1] : NULL; } else if (ac <= 3 && wcscmp(av[1], L"-nopty") == 0) cmd_b64 = ac == 3? av[2] : NULL; else { - printf("ssh-shellhost received unexpected input arguments"); + printf_s("ssh-shellhost received unexpected input arguments"); return -1; } @@ -1432,7 +1575,7 @@ wmain(int ac, wchar_t **av) if ((cmd_b64_utf8 = utf16_to_utf8(cmd_b64)) == NULL || /* strlen(b64) should be sufficient for decoded length */ (cmd_utf8 = malloc(strlen(cmd_b64_utf8))) == NULL) { - printf("ssh-shellhost - out of memory"); + printf_s("ssh-shellhost - out of memory"); return -1; } @@ -1440,13 +1583,19 @@ wmain(int ac, wchar_t **av) if (b64_pton(cmd_b64_utf8, cmd_utf8, strlen(cmd_b64_utf8)) == -1 || (cmd = utf8_to_utf16(cmd_utf8)) == NULL) { - printf("ssh-shellhost encountered an internal error while decoding base64 cmdline"); + printf_s("ssh-shellhost encountered an internal error while decoding base64 cmdline"); return -1; } free(cmd_b64_utf8); free(cmd_utf8); } + ZeroMemory(system32_path, _countof(system32_path)); + if (!GetSystemDirectory(system32_path, _countof(system32_path))) { + printf_s("GetSystemDirectory failed"); + exit(255); + } + if (pty_requested) return start_with_pty(cmd); else diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index d049903..02c8011 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -254,6 +254,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) HANDLE all_events[MAXIMUM_WAIT_OBJECTS]; DWORD num_all_events; DWORD live_children = children.num_children - children.num_zombies; + errno_t r = 0; num_all_events = num_events + live_children; @@ -263,8 +264,11 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds) return -1; } - memcpy(all_events, children.handles, live_children * sizeof(HANDLE)); - memcpy(all_events + live_children, events, num_events * sizeof(HANDLE)); + if ((r = memcpy_s(all_events, MAXIMUM_WAIT_OBJECTS * sizeof(HANDLE), children.handles, live_children * sizeof(HANDLE)) != 0) || + ( r = memcpy_s(all_events + live_children, (MAXIMUM_WAIT_OBJECTS - live_children) * sizeof(HANDLE), events, num_events * sizeof(HANDLE)) != 0)) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } debug5("wait() on %d events and %d children", num_events, live_children); /* TODO - implement signal catching and handling */ diff --git a/contrib/win32/win32compat/socketio.c b/contrib/win32/win32compat/socketio.c index 7920c40..290f92c 100644 --- a/contrib/win32/win32compat/socketio.c +++ b/contrib/win32/win32compat/socketio.c @@ -359,6 +359,7 @@ int socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) { BOOL completed = FALSE; + errno_t r = 0; debug5("recv - io:%p state:%d", pio, pio->internal.state); if ((buf == NULL) || (len == 0)) { @@ -388,13 +389,16 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) debug4("recv - io is already pending, io:%p", pio); return -1; } - } + } /* if we have some buffer copy it and return #bytes copied */ if (pio->read_details.remaining) { int num_bytes_copied = min((int)len, pio->read_details.remaining); - memcpy(buf, pio->read_details.buf + pio->read_details.completed, - num_bytes_copied); + if ((r = memcpy_s(buf, len, pio->read_details.buf + pio->read_details.completed, + num_bytes_copied)) != 0) { + debug4("memcpy_s failed with error: %d.", r); + return -1; + } pio->read_details.remaining -= num_bytes_copied; pio->read_details.completed += num_bytes_copied; debug5("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p", @@ -465,7 +469,10 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) if (pio->read_details.remaining) { int num_bytes_copied = min((int)len, pio->read_details.remaining); - memcpy(buf, pio->read_details.buf, num_bytes_copied); + if ((r = memcpy_s(buf, len, pio->read_details.buf, num_bytes_copied)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } pio->read_details.remaining -= num_bytes_copied; pio->read_details.completed = num_bytes_copied; debug4("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p", @@ -506,6 +513,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) { int ret = 0; WSABUF wsabuf; + errno_t r = 0; debug5("send - io:%p state:%d", pio, pio->internal.state); @@ -558,7 +566,10 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags) wsabuf.buf = pio->write_details.buf; wsabuf.len = min(wsabuf.len, (int)len); - memcpy(wsabuf.buf, buf, wsabuf.len); + if ((r = memcpy_s(wsabuf.buf, wsabuf.len, buf, wsabuf.len)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } /* TODO - implement flags support if needed */ ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, &WSASendCompletionRoutine); @@ -659,6 +670,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) struct acceptEx_context* context; struct sockaddr *local_address, *remote_address; int local_address_len, remote_address_len; + errno_t r = 0; debug5("accept - io:%p", pio); /* start io if not already started */ @@ -718,7 +730,10 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) sizeof(SOCKADDR_STORAGE) + 16, &local_address, &local_address_len, &remote_address, &remote_address_len); if (remote_address_len) { - memcpy(addr, remote_address, remote_address_len); + if((r = memcpy_s(addr, remote_address_len, remote_address, remote_address_len)) != 0) { + debug3("memcpy_s failed with error: %d.", r); + goto on_error; + } *addrlen = remote_address_len; } } @@ -1018,7 +1033,10 @@ w32_getaddrinfo(const char *node_utf8, const char *service_utf8, ret = EAI_MEMORY; goto done; } - memcpy(*cur, *cur_w, sizeof(struct addrinfo)); + if (memcpy_s(*cur, sizeof(struct addrinfo), *cur_w, sizeof(struct addrinfo))) { + ret = EAI_MEMORY; + goto done; + } (*cur)->ai_next = NULL; if (((*cur_w)->ai_canonname && ((*cur)->ai_canonname = utf16_to_utf8((*cur_w)->ai_canonname)) == NULL) || ((*cur_w)->ai_addrlen && ((*cur)->ai_addr = malloc((*cur_w)->ai_addrlen)) == NULL)) { @@ -1027,7 +1045,10 @@ w32_getaddrinfo(const char *node_utf8, const char *service_utf8, } if ((*cur_w)->ai_addrlen) - memcpy((*cur)->ai_addr, (*cur_w)->ai_addr, (*cur_w)->ai_addrlen); + if (memcpy_s((*cur)->ai_addr, (*cur_w)->ai_addrlen, (*cur_w)->ai_addr, (*cur_w)->ai_addrlen)) { + ret = EAI_MEMORY; + goto done; + } cur_w = &(*cur_w)->ai_next; cur = &(*cur)->ai_next; } diff --git a/contrib/win32/win32compat/ssh-agent/agent-main.c b/contrib/win32/win32compat/ssh-agent/agent-main.c index eda3a49..f3fee97 100644 --- a/contrib/win32/win32compat/ssh-agent/agent-main.c +++ b/contrib/win32/win32compat/ssh-agent/agent-main.c @@ -98,6 +98,7 @@ ctrl_c_handler(_In_ DWORD dwCtrlType) int wmain(int argc, wchar_t **argv) { + _set_invalid_parameter_handler(invalid_parameter_handler); w32posix_initialize(); /* this exits() on failure*/ load_config(); diff --git a/contrib/win32/win32compat/ssh-agent/agentconfig.c b/contrib/win32/win32compat/ssh-agent/agentconfig.c index dddada9..cd45f43 100644 --- a/contrib/win32/win32compat/ssh-agent/agentconfig.c +++ b/contrib/win32/win32compat/ssh-agent/agentconfig.c @@ -57,7 +57,7 @@ static char *config_file_name = _PATH_SERVER_CONFIG_FILE; int auth_sock = -1; int -auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key) +auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key) { return 0; } @@ -79,7 +79,7 @@ mm_is_monitor(void) { return 0; } -int +int mm_user_key_allowed(struct passwd *pw, Key *k, int i) { return 0; @@ -96,7 +96,7 @@ kexgex_server(struct ssh * sh) { return -1; } -static int +static int GetCurrentModulePath(wchar_t *path, int pathSize) { if (GetModuleFileNameW(NULL, path, pathSize)) { @@ -105,7 +105,7 @@ GetCurrentModulePath(wchar_t *path, int pathSize) for (i = 0; path[i]; i++) { if (path[i] == L'/' || path[i] == L'\\') - lastSlashPos = i; + lastSlashPos = i; } path[lastSlashPos] = 0; @@ -114,20 +114,27 @@ GetCurrentModulePath(wchar_t *path, int pathSize) return -1; } -int +int load_config() { wchar_t basePath[PATH_MAX] = { 0 }; wchar_t path[PATH_MAX] = { 0 }; wchar_t* config_file = L"/sshd_config"; + errno_t r = 0; if (GetCurrentModulePath(basePath, PATH_MAX) == -1) return -1; - if (wcslen(basePath) + wcslen(config_file) + 1 > PATH_MAX) + if (wcsnlen_s(basePath, PATH_MAX) + wcslen(config_file) + 1 > PATH_MAX) fatal("unexpected config file path length"); - - wcsncpy_s(path, PATH_MAX, basePath, PATH_MAX); - wcsncat_s(path, PATH_MAX, L"/sshd_config", PATH_MAX - wcslen(basePath)); + + if(( r = wcsncpy_s(path, PATH_MAX, basePath, wcsnlen_s(basePath, PATH_MAX))) != 0) { + debug3("memcpy_s failed with error: %d.", r); + return -1; + } + if (( r = wcsncat_s(path, PATH_MAX, L"/sshd_config", PATH_MAX - wcsnlen_s(basePath, PATH_MAX))) != 0) { + debug3("wcscat_s failed with error: %d.", r); + return -1; + } if ((config_file_name = utf16_to_utf8(path)) == NULL) return -1; diff --git a/contrib/win32/win32compat/ssh-agent/authagent-request.c b/contrib/win32/win32compat/ssh-agent/authagent-request.c index 3aafdf8..cf681d9 100644 --- a/contrib/win32/win32compat/ssh-agent/authagent-request.c +++ b/contrib/win32/win32compat/ssh-agent/authagent-request.c @@ -160,7 +160,8 @@ generate_user_token(wchar_t* user_cpn) { s4u_logon->ClientUpn.Length = (USHORT)wcslen(user_cpn) * 2; s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length; s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1); - memcpy(s4u_logon->ClientUpn.Buffer, user_cpn, s4u_logon->ClientUpn.Length + 2); + if (memcpy_s(s4u_logon->ClientUpn.Buffer, s4u_logon->ClientUpn.Length + 2, user_cpn, s4u_logon->ClientUpn.Length + 2)) + goto done; s4u_logon->ClientRealm.Length = 0; s4u_logon->ClientRealm.MaximumLength = 0; s4u_logon->ClientRealm.Buffer = 0; @@ -178,14 +179,17 @@ generate_user_token(wchar_t* user_cpn) { s4u_logon->UserPrincipalName.Length = (USHORT)wcslen(user_cpn) * 2; s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length; s4u_logon->UserPrincipalName.Buffer = (WCHAR*)(s4u_logon + 1); - memcpy(s4u_logon->UserPrincipalName.Buffer, user_cpn, s4u_logon->UserPrincipalName.Length + 2); + if(memcpy_s(s4u_logon->UserPrincipalName.Buffer, s4u_logon->UserPrincipalName.Length + 2, user_cpn, s4u_logon->UserPrincipalName.Length + 2)) + goto done; s4u_logon->DomainName.Length = 2; s4u_logon->DomainName.MaximumLength = 2; s4u_logon->DomainName.Buffer = ((WCHAR*)s4u_logon->UserPrincipalName.Buffer) + wcslen(user_cpn) + 1; - memcpy(s4u_logon->DomainName.Buffer, L".", 4); + if(memcpy_s(s4u_logon->DomainName.Buffer, 4, L".", 4)) + goto done; } - memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName)); + if(memcpy_s(sourceContext.SourceName, TOKEN_SOURCE_LENGTH, "sshagent", sizeof(sourceContext.SourceName))) + goto done; if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE) goto done; @@ -273,7 +277,13 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response, if ((token = generate_user_token(user_utf16)) == 0) { error("unable to generate token for user %ls", user_utf16); - goto done; + /* work around for https://github.com/PowerShell/Win32-OpenSSH/issues/727 by doing a fake login */ + LogonUserW(L"FakeUser", L"FakeDomain", L"FakePasswd", + LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, &token); + if ((token = generate_user_token(user_utf16)) == 0) { + error("unable to generate token on 2nd attempt for user %ls", user_utf16); + goto done; + } } diff --git a/contrib/win32/win32compat/ssh-agent/connection.c b/contrib/win32/win32compat/ssh-agent/connection.c index ecb71e2..2ef51a1 100644 --- a/contrib/win32/win32compat/ssh-agent/connection.c +++ b/contrib/win32/win32compat/ssh-agent/connection.c @@ -143,6 +143,7 @@ process_request(struct agent_connection* con) int r = -1; struct sshbuf *request = NULL, *response = NULL; u_char type; + errno_t err = 0; request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes); response = sshbuf_new(); @@ -185,7 +186,10 @@ done: ZeroMemory(&con->io_buf, sizeof(con->io_buf)); if (r == 0) { POKE_U32(con->io_buf.buf, (u_int32_t)sshbuf_len(response)); - memcpy(con->io_buf.buf + 4, sshbuf_ptr(response), sshbuf_len(response)); + if ((err = memcpy_s(con->io_buf.buf + 4, sizeof(con->io_buf.buf) - 4, sshbuf_ptr(response), sshbuf_len(response))) != 0) { + debug("memcpy_s failed with error: %d.", err); + r = -1; + } con->io_buf.num_bytes = (DWORD)sshbuf_len(response) + 4; } diff --git a/contrib/win32/win32compat/ssh-agent/keyagent-request.c b/contrib/win32/win32compat/ssh-agent/keyagent-request.c index 18c0506..9714bcf 100644 --- a/contrib/win32/win32compat/ssh-agent/keyagent-request.c +++ b/contrib/win32/win32compat/ssh-agent/keyagent-request.c @@ -72,6 +72,7 @@ static int convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **eblob, DWORD *eblen, int encrypt) { int success = 0; DATA_BLOB in, out; + errno_t r = 0; if (con->client_type <= ADMIN_USER) if (ImpersonateLoggedOnUser(con->client_impersonation_token) == FALSE) @@ -98,7 +99,10 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char ** if (*eblob == NULL) goto done; - memcpy(*eblob, out.pbData, out.cbData); + if((r = memcpy_s(*eblob, out.cbData, out.pbData, out.cbData)) != 0) { + debug("memcpy_s failed with error: %d.", r); + goto done; + } *eblen = out.cbData; success = 1; done: diff --git a/contrib/win32/win32compat/termio.c b/contrib/win32/win32compat/termio.c index 786c0fe..5494bef 100644 --- a/contrib/win32/win32compat/termio.c +++ b/contrib/win32/win32compat/termio.c @@ -50,6 +50,7 @@ #define TERM_IO_BUF_SIZE 2048 extern int in_raw_mode; +BOOL isFirstTime = TRUE; struct io_status { DWORD to_transfer; @@ -84,16 +85,51 @@ ReadThread(_In_ LPVOID lpParameter) debug5("TermRead thread, io:%p", pio); memset(&read_status, 0, sizeof(read_status)); if (FILETYPE(pio) == FILE_TYPE_CHAR) { - while (nBytesReturned == 0) { - nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio), - pio->read_details.buf, pio->read_details.buf_size); + if (in_raw_mode) { + while (nBytesReturned == 0) { + nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio), + pio->read_details.buf, pio->read_details.buf_size); + } + read_status.transferred = nBytesReturned; + } else { + if (isFirstTime) { + isFirstTime = false; + + DWORD dwAttributes; + if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &dwAttributes)) + error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", GetLastError()); + + dwAttributes |= (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); + + if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) + error("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", GetLastError()); + } + + if (!ReadFile(WINHANDLE(pio), pio->read_details.buf, + pio->read_details.buf_size, &read_status.transferred, NULL)) { + read_status.error = GetLastError(); + debug("ReadThread - ReadFile failed %d, io:%p", GetLastError(), pio); + return -1; + } + + char *p = NULL; + if (p = strstr(pio->read_details.buf, "\r\n")) + *p++ = '\n'; + else if (p = strstr(pio->read_details.buf, "\r")) + *p++ = '\n'; + + if (p) { + *p = '\0'; + pio->read_details.buf_size = (DWORD)strlen(pio->read_details.buf); + read_status.transferred = pio->read_details.buf_size; + } } - read_status.transferred = nBytesReturned; } else { if (!ReadFile(WINHANDLE(pio), pio->read_details.buf, pio->read_details.buf_size, &read_status.transferred, NULL)) { read_status.error = GetLastError(); debug("ReadThread - ReadFile failed %d, io:%p", GetLastError(), pio); + return -1; } } if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) { @@ -221,7 +257,7 @@ syncio_close(struct w32_io* pio) /* If io is pending, let worker threads exit. */ if (pio->read_details.pending) { /* For console - the read thread is blocked so terminate it. */ - if (FILETYPE(pio) == FILE_TYPE_CHAR) + if (FILETYPE(pio) == FILE_TYPE_CHAR && in_raw_mode) TerminateThread(pio->read_overlapped.hEvent, 0); else WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE); diff --git a/contrib/win32/win32compat/tncon.c b/contrib/win32/win32compat/tncon.c index 6d171c8..b9c5bd9 100644 --- a/contrib/win32/win32compat/tncon.c +++ b/contrib/win32/win32compat/tncon.c @@ -155,7 +155,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) switch (InputRecord.Event.KeyEvent.uChar.UnicodeChar) { case 0xd: if (pParams->nReceiveCRLF == ENUM_LF) - NetWriteString2(pParams->Socket, "\r", 1, 0); + NetWriteString2(pParams->Socket, "\n", 1, 0); else NetWriteString2(pParams->Socket, "\r\n", 2, 0); break; @@ -190,6 +190,12 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_DELETE: NetWriteString2(pParams->Socket, (char *)REMOVE_KEY, 4, 0); break; + case VK_PRIOR: /* page up */ + NetWriteString2(pParams->Socket, (char *)PREV_KEY, 4, 0); + break; + case VK_NEXT: /* page down */ + NetWriteString2(pParams->Socket, (char *)NEXT_KEY, 4, 0); + break; case VK_BACK: NetWriteString2(pParams->Socket, (char *)BACKSPACE_KEY, 1, 0); break; @@ -202,6 +208,9 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen) case VK_ESCAPE: NetWriteString2(pParams->Socket, (char *)ESCAPE_KEY, 1, 0); break; + case VK_OEM_2: + NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_Q, 2, 0); + break; case VK_SHIFT: case VK_CONTROL: case VK_CAPITAL: diff --git a/contrib/win32/win32compat/tncon.h b/contrib/win32/win32compat/tncon.h index c36c02b..d58f596 100644 --- a/contrib/win32/win32compat/tncon.h +++ b/contrib/win32/win32compat/tncon.h @@ -54,7 +54,8 @@ #define PREV_KEY "\x1b[5~" #define NEXT_KEY "\x1b[6~" #define SHIFT_TAB_KEY "\x1b[~" -#define ESCAPE_KEY "\x1b" +#define SHIFT_ALT_Q "\x1b?" +#define ESCAPE_KEY "\x1b" #define BACKSPACE_KEY "\b" // VT100 Function Key's diff --git a/contrib/win32/win32compat/tnnet.c b/contrib/win32/win32compat/tnnet.c index 39b0fc8..5c53ebe 100644 --- a/contrib/win32/win32compat/tnnet.c +++ b/contrib/win32/win32compat/tnnet.c @@ -41,6 +41,8 @@ #define dwBuffer 4096 extern BOOL isAnsiParsingRequired; +extern bool gbVTAppMode; +BOOL isFirstPacket = TRUE; /* * Server will always be returning a sequence of ANSI control characters which the client @@ -51,14 +53,34 @@ extern BOOL isAnsiParsingRequired; void processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, size_t *resplen) { - unsigned char* pszNewHead = NULL; - unsigned char* pszHead = NULL; - unsigned char* pszTail = NULL; + unsigned char *pszNewHead = NULL; + unsigned char *pszHead = NULL; + unsigned char *pszTail = NULL; + const char *applicationModeSeq = "\x1b[?1h"; + const int applicationModeSeqLen = (int)strlen(applicationModeSeq); + const char *normalModeSeq = "\x1b[?1l"; + const int normalModeSeqLen = (int)strlen(normalModeSeq); + const char *clsSeq = "\x1b[2J"; if (len == 0) return; if (false == isAnsiParsingRequired) { + if(isFirstPacket) { + isFirstPacket = FALSE; + /* Windows server at first sends the "cls" after the connection is established. + * There is a bug in the conhost which causes the visible window data to loose so to + * mitigate that issue we need to first move the visible window so that the cursor is at the top of the visible window. + */ + if (strstr(buf, clsSeq)) + ConMoveCursorTopOfVisibleWindow(); + } + + if(len >= applicationModeSeqLen && strstr(buf, applicationModeSeq)) + gbVTAppMode = true; + else if(len >= normalModeSeqLen && strstr(buf, normalModeSeq)) + gbVTAppMode = false; + /* Console has the capability to parse so pass the raw buffer to console directly */ ConRestoreViewRect(); /* Restore the visible window, otherwise WriteConsoleW() gets messy */ wchar_t* t = utf8_to_utf16(buf); diff --git a/contrib/win32/win32compat/w32-sshfileperm.c b/contrib/win32/win32compat/w32-sshfileperm.c index 44d3f3c..9382092 100644 --- a/contrib/win32/win32compat/w32-sshfileperm.c +++ b/contrib/win32/win32compat/w32-sshfileperm.c @@ -56,7 +56,7 @@ check_secure_file_permission(const char *name, struct passwd * pw) BOOL is_valid_sid = FALSE, is_valid_acl = FALSE; struct passwd * pwd = pw; char *bad_user = NULL; - int ret = 0; + int ret = 0; if (pwd == NULL) if ((pwd = getpwuid(0)) == NULL) @@ -160,20 +160,23 @@ cleanup: /*TODO: optimize to get sshd sid first and then call EqualSid*/ static BOOL is_sshd_account(PSID user_sid) { - wchar_t user_name[UNCLEN], full_name[UNCLEN + DNLEN + 2]; + wchar_t user_name[UNCLEN] = { 0 }, full_name[UNCLEN + DNLEN + 2] = { 0 }; DWORD name_length = UNCLEN, domain_name_length = 0, full_name_len = UNCLEN + DNLEN + 2; SID_NAME_USE sid_type = SidTypeInvalid; BOOL ret = FALSE; - + errno_t r = 0; + if (LookupAccountSidLocalW(user_sid, user_name, &name_length, full_name, &full_name_len, &sid_type) == FALSE) { debug3("LookupAccountSidLocalW() failed with error: %d. ", GetLastError()); errno = ENOENT; return FALSE; - } - domain_name_length = wcslen(full_name); + } + domain_name_length = wcsnlen(full_name, _countof(full_name)); full_name[domain_name_length] = L'\\'; - wmemcpy(full_name + domain_name_length + 1, user_name, wcslen(user_name)+1); + if ((r = wmemcpy_s(full_name + domain_name_length + 1, _countof(full_name) - domain_name_length -1, user_name, wcsnlen_s(user_name, UNCLEN) + 1)) != 0) { + debug3("wmemcpy_s failed with error: %d.", r); + return FALSE; + } return (wcsicmp(full_name, SSHD_ACCOUNT) == 0); } - diff --git a/contrib/win32/win32compat/w32log.c b/contrib/win32/win32compat/w32log.c index 3483bea..ae5fd40 100644 --- a/contrib/win32/win32compat/w32log.c +++ b/contrib/win32/win32compat/w32log.c @@ -39,7 +39,7 @@ #define MSGBUFSIZ 1024 static int logfd = -1; -/* +/* * open a log file using the name of executable under logs folder * Ex. if called from c:\windows\system32\openssh\sshd.exe * logfile - c:\windows\system32\openssh\logs\sshd.log @@ -51,30 +51,30 @@ openlog(char *ident, unsigned int option, int facility) if (logfd != -1 || ident == NULL) return; - wchar_t path[PATH_MAX], log_file[PATH_MAX + 12]; + wchar_t path[PATH_MAX] = { 0 }, log_file[PATH_MAX + 12] = { 0 }; + errno_t r = 0; if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0) return; - path[PATH_MAX - 1] = '\0'; + path[PATH_MAX - 1] = L'\0'; - if (wcsnlen(path, MAX_PATH) > MAX_PATH - wcslen(logs_dir) ) + if (wcsnlen(path, MAX_PATH) > MAX_PATH - wcslen(logs_dir)) return; /* split path root and module */ { - wchar_t* tail = path + wcslen(path), *p; + wchar_t* tail = path + wcsnlen(path, MAX_PATH); while (tail > path && *tail != L'\\' && *tail != L'/') tail--; - memcpy(log_file, path, (tail - path) * sizeof(wchar_t)); - p = log_file + (tail - path); - memcpy(p, logs_dir, wcslen(logs_dir) * sizeof(wchar_t)); - p += 6; - memcpy(p, tail + 1, (wcslen(tail + 1) - 3) * sizeof(wchar_t)); - p += wcslen(tail + 1) - 3; - memcpy(p, L"log\0", 8); + if (((r = wcsncat_s(log_file, PATH_MAX + 12, path, tail - path)) != 0 ) || + (r = wcsncat_s(log_file, PATH_MAX + 12, logs_dir, 6) != 0 )|| + (r = wcsncat_s(log_file, PATH_MAX + 12, tail + 1, wcslen(tail + 1) - 3) != 0 ) || + (r = wcsncat_s(log_file, PATH_MAX + 12, L"log", 3) != 0 )) + return; } + errno_t err = _wsopen_s(&logfd, log_file, O_WRONLY | O_CREAT | O_APPEND, SH_DENYNO, S_IREAD | S_IWRITE); if (logfd != -1) @@ -98,10 +98,13 @@ syslog(int priority, const char *format, const char *formatBuffer) return; GetLocalTime(&st); - r = snprintf(msgbufTimestamp, sizeof(msgbufTimestamp), "%d %02d:%02d:%02d:%03d %s\n", + r = _snprintf_s(msgbufTimestamp, sizeof(msgbufTimestamp), _TRUNCATE, "%d %02d:%02d:%02d:%03d %s\n", GetCurrentProcessId(), st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, formatBuffer); - msgbufTimestamp[sizeof(msgbufTimestamp) - 1] = '\0'; - if (r > 0 && r < sizeof(msgbufTimestamp)) - _write(logfd, msgbufTimestamp, (unsigned int)strlen(msgbufTimestamp)); + if (r == -1) { + _write(logfd, "_snprintf_s failed.", 30); + return; + } + msgbufTimestamp[strnlen(msgbufTimestamp, MSGBUFSIZ)] = '\0'; + _write(logfd, msgbufTimestamp, (unsigned int)strnlen(msgbufTimestamp, MSGBUFSIZ)); } \ No newline at end of file diff --git a/contrib/win32/win32compat/win32-utf8.c b/contrib/win32/win32compat/win32-utf8.c index 3ca38da..1610e82 100644 --- a/contrib/win32/win32compat/win32-utf8.c +++ b/contrib/win32/win32compat/win32-utf8.c @@ -55,8 +55,7 @@ snmprintf(char *buf, size_t len, int *written, const char *fmt, ...) int ret; va_list valist; va_start(valist, fmt); - if ((ret = vsnprintf(buf, len, fmt, valist)) >= len) - ret = len; + ret = vsnprintf_s(buf, len, _TRUNCATE, fmt, valist); va_end(valist); if (written != NULL && ret != -1) *written = ret; diff --git a/contrib/win32/win32compat/win32_dirent.c b/contrib/win32/win32compat/win32_dirent.c index c6488f0..dfa3ffd 100644 --- a/contrib/win32/win32compat/win32_dirent.c +++ b/contrib/win32/win32compat/win32_dirent.c @@ -84,7 +84,9 @@ openrootdir(const char *name) } memset(pdir, 0, sizeof(DIR)); pdir->hFile = 0; - memcpy(&pdir->c_file, &c_file, sizeof(c_file)); + if (memcpy_s(&pdir->c_file, sizeof(c_file), &c_file, sizeof(c_file))) { + return NULL; + } pdir->first = 1; return pdir; @@ -138,7 +140,10 @@ opendir(const char *name) memset(pdir, 0, sizeof(DIR)); pdir->hFile = hFile; - memcpy(&pdir->c_file, &c_file, sizeof(c_file)); + if (memcpy_s(&pdir->c_file, sizeof(c_file), &c_file, sizeof(c_file))) { + _findclose(hFile); + return NULL; + } pdir->first = 1; return pdir; @@ -236,7 +241,9 @@ readdir(void *avp) for (;;) { if (dirp->first) { - memcpy(&c_file, &dirp->c_file, sizeof(c_file)); + if (memcpy_s(&c_file, sizeof(c_file), &dirp->c_file, sizeof(c_file))) { + return NULL; + } dirp->first = 0; } else if (_wfindnext(dirp->hFile, &c_file) != 0) return NULL; @@ -249,7 +256,9 @@ readdir(void *avp) return NULL; } - strncpy_s(pdirentry.d_name, PATH_MAX, tmp, strlen(tmp) + 1); + if (strncpy_s(pdirentry.d_name, PATH_MAX, tmp, strlen(tmp) + 1)) { + return NULL; + } free(tmp); pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */ diff --git a/contrib/win32/win32compat/win32_sshtty.c b/contrib/win32/win32compat/win32_sshtty.c index 84e80ca..ab5f2f8 100644 --- a/contrib/win32/win32compat/win32_sshtty.c +++ b/contrib/win32/win32compat/win32_sshtty.c @@ -4,27 +4,17 @@ #include #include "..\..\..\sshpty.h" - static struct termios _saved_tio; static int _in_raw_mode = 0; - /* * TTY raw mode routines for Windows */ -int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit); -int ConExitRawMode(void); - struct termios term_settings; -/* - * TODO - clean this up for Windows, ConInit should return previous terminal - * settings that need to be stored in term_settings - */ - struct termios * - get_saved_tio(void) { +get_saved_tio(void) { memset(&term_settings, 0, sizeof(term_settings)); return &term_settings; } @@ -36,5 +26,5 @@ leave_raw_mode(int quiet) { void enter_raw_mode(int quiet) { - ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE); + ConEnterRawMode(); } diff --git a/contrib/win32/win32compat/wmain_common.c b/contrib/win32/win32compat/wmain_common.c index b78d8cf..7362333 100644 --- a/contrib/win32/win32compat/wmain_common.c +++ b/contrib/win32/win32compat/wmain_common.c @@ -40,8 +40,8 @@ main(int, char **); int wmain(int argc, wchar_t **wargv) { char** argv = NULL; - int i,r; - + int i, r; + _set_invalid_parameter_handler(invalid_parameter_handler); if (argc) { if ((argv = malloc(argc * sizeof(char*))) == NULL) fatal("out of memory"); @@ -53,9 +53,12 @@ wmain(int argc, wchar_t **wargv) { if (getenv("SSH_AUTH_SOCK") == NULL) _putenv("SSH_AUTH_SOCK=\\\\.\\pipe\\openssh-ssh-agent"); + if (getenv("TERM") == NULL) + _putenv("TERM=xterm-256color"); + w32posix_initialize(); r = main(argc, argv); - w32posix_done(); + w32posix_done(); return r; } diff --git a/contrib/win32/win32compat/wmain_sshd.c b/contrib/win32/win32compat/wmain_sshd.c index 5e75d01..514c144 100644 --- a/contrib/win32/win32compat/wmain_sshd.c +++ b/contrib/win32/win32compat/wmain_sshd.c @@ -100,6 +100,7 @@ static VOID WINAPI service_handler(DWORD dwControl) int sshd_main(int argc, wchar_t **wargv) { char** argv = NULL; int i, r; + _set_invalid_parameter_handler(invalid_parameter_handler); if (argc) { if ((argv = malloc(argc * sizeof(char*))) == NULL) diff --git a/regress/pesterTests/KeyUtils.Tests.ps1 b/regress/pesterTests/KeyUtils.Tests.ps1 index d4f33e2..f51645f 100644 --- a/regress/pesterTests/KeyUtils.Tests.ps1 +++ b/regress/pesterTests/KeyUtils.Tests.ps1 @@ -18,7 +18,15 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" { } $keypassphrase = "testpassword" - $keytypes = @("rsa","dsa","ecdsa","ed25519") + $WindowsInBox = $OpenSSHTestInfo["WindowsInBox"] + if($WindowsInBox) + { + $keytypes = @("ed25519") + } + else + { + $keytypes = @("rsa","dsa","ecdsa","ed25519") + } $ssouser = $OpenSSHTestInfo["SSOUser"] @@ -117,8 +125,15 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" { foreach($type in $keytypes) { $keyPath = Join-Path $testDir "id_$type" - remove-item $keyPath -ErrorAction SilentlyContinue - ssh-keygen -t $type -P $keypassphrase -f $keyPath + remove-item $keyPath -ErrorAction SilentlyContinue + if($OpenSSHTestInfo["WindowsInBox"]) + { + ssh-keygen -t $type -P $keypassphrase -f $keyPath -Z aes128-ctr + } + else + { + ssh-keygen -t $type -P $keypassphrase -f $keyPath + } ValidateKeyFile -FilePath $keyPath ValidateKeyFile -FilePath "$keyPath.pub" } @@ -224,7 +239,15 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" { $keyFileName = "sshadd_userPermTestkey_ed25519" $keyFilePath = Join-Path $testDir $keyFileName Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue - ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase + if($OpenSSHTestInfo["WindowsInBox"]) + { + ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase -Z aes128-ctr + } + else + { + ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase + } + #set up SSH_ASKPASS Add-PasswordSetting -Pass $keypassphrase $tI=1 @@ -331,7 +354,7 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" { } Context "$tC - ssh-keyscan test cases" { - BeforeAll { + BeforeAll { $tI=1 $port = $OpenSSHTestInfo["Port"] Remove-item (join-path $testDir "$tC.$tI.out.txt") -force -ErrorAction SilentlyContinue @@ -341,23 +364,23 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" { } AfterAll{$tC++} - It "$tC.$tI - ssh-keyscan with default arguments" { + It "$tC.$tI - ssh-keyscan with default arguments" -Skip:$WindowsInBox { cmd /c "ssh-keyscan -p $port 127.0.0.1 2>&1 > $outputFile" $outputFile | Should Contain '.*ssh-rsa.*' } - It "$tC.$tI - ssh-keyscan with -p" { + It "$tC.$tI - ssh-keyscan with -p" -Skip:$WindowsInBox { cmd /c "ssh-keyscan -p $port 127.0.0.1 2>&1 > $outputFile" $outputFile | Should Contain '.*ssh-rsa.*' } - It "$tC.$tI - ssh-keyscan with -f" { + It "$tC.$tI - ssh-keyscan with -f" -Skip:$WindowsInBox { Set-Content -Path tmp.txt -Value "127.0.0.1" cmd /c "ssh-keyscan -p $port -f tmp.txt 2>&1 > $outputFile" $outputFile | Should Contain '.*ssh-rsa.*' } - It "$tC.$tI - ssh-keyscan with -f -t" { + It "$tC.$tI - ssh-keyscan with -f -t" -Skip:$WindowsInBox { Set-Content -Path tmp.txt -Value "127.0.0.1" cmd /c "ssh-keyscan -p $port -f tmp.txt -t rsa,dsa 2>&1 > $outputFile" $outputFile | Should Contain '.*ssh-rsa.*' diff --git a/regress/pesterTests/Userkey_fileperm.Tests.ps1 b/regress/pesterTests/Userkey_fileperm.Tests.ps1 index 7e013b9..0ea561d 100644 --- a/regress/pesterTests/Userkey_fileperm.Tests.ps1 +++ b/regress/pesterTests/Userkey_fileperm.Tests.ps1 @@ -50,7 +50,14 @@ Describe "Tests for user Key file permission" -Tags "CI" { $keyFileName = "sshtest_userPermTestkey_ed25519" $keyFilePath = Join-Path $testDir $keyFileName Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue - ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase + if($OpenSSHTestInfo["WindowsInBox"]) + { + ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase -Z aes128-ctr + } + else + { + ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase + } $pubKeyUserProfilePath = Join-Path $pubKeyUserProfile .ssh if(-not (Test-Path $pubKeyUserProfilePath -PathType Container)) { diff --git a/regress/unittests/win32compat/file_tests.c b/regress/unittests/win32compat/file_tests.c index 72cdaaf..c959383 100644 --- a/regress/unittests/win32compat/file_tests.c +++ b/regress/unittests/win32compat/file_tests.c @@ -88,8 +88,8 @@ void file_simple_fileio() int f; struct stat st; { - f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC); - ASSERT_INT_EQ(f, -1); + //f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC); + //ASSERT_INT_EQ(f, -1); } { f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); diff --git a/sftp.c b/sftp.c index b89ae9d..6b1eefb 100644 --- a/sftp.c +++ b/sftp.c @@ -2518,7 +2518,8 @@ main(int argc, char **argv) usage(); userhost = xstrdup(argv[optind]); - file2 = argv[optind+1]; + if(argc > optind + 1) + file2 = argv[optind+1]; if ((host = strrchr(userhost, '@')) == NULL) host = userhost;