mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-27 07:54:50 +02:00
Source snapshot from Powershell/openssh-portable:latestw_all
This commit is contained in:
parent
993c15663a
commit
c1680168e4
@ -1,4 +1,4 @@
|
|||||||
version: 0.0.17.0.{build}
|
version: 0.0.19.0.{build}
|
||||||
image: Visual Studio 2015
|
image: Visual Studio 2015
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
|
@ -20,6 +20,8 @@ $Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName
|
|||||||
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
|
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
|
||||||
$Script:E2ETestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
|
$Script:E2ETestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
|
||||||
$Script:WindowsInBox = $false
|
$Script:WindowsInBox = $false
|
||||||
|
$Script:EnableAppVerifier = $true
|
||||||
|
$Script:PostmortemDebugging = $false
|
||||||
|
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
@ -33,7 +35,9 @@ function Set-OpenSSHTestEnvironment
|
|||||||
(
|
(
|
||||||
[string] $OpenSSHBinPath,
|
[string] $OpenSSHBinPath,
|
||||||
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
|
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
|
||||||
[Boolean] $DebugMode = $false
|
[Boolean] $DebugMode = $false,
|
||||||
|
[Switch] $NoAppVerifier,
|
||||||
|
[Switch] $PostmortemDebugging
|
||||||
)
|
)
|
||||||
|
|
||||||
if($PSBoundParameters.ContainsKey("Verbose"))
|
if($PSBoundParameters.ContainsKey("Verbose"))
|
||||||
@ -51,7 +55,11 @@ function Set-OpenSSHTestEnvironment
|
|||||||
$Script:UnitTestResultsFile = Join-Path $TestDataPath "UnitTestResults.txt"
|
$Script:UnitTestResultsFile = Join-Path $TestDataPath "UnitTestResults.txt"
|
||||||
$Script:TestSetupLogFile = Join-Path $TestDataPath "TestSetupLog.txt"
|
$Script:TestSetupLogFile = Join-Path $TestDataPath "TestSetupLog.txt"
|
||||||
$Script:UnitTestDirectory = Get-UnitTestDirectory
|
$Script:UnitTestDirectory = Get-UnitTestDirectory
|
||||||
|
$Script:EnableAppVerifier = -not ($NoAppVerifier.IsPresent)
|
||||||
|
if($Script:EnableAppVerifier)
|
||||||
|
{
|
||||||
|
$Script:PostmortemDebugging = $PostmortemDebugging.IsPresent
|
||||||
|
}
|
||||||
|
|
||||||
$Global:OpenSSHTestInfo = @{
|
$Global:OpenSSHTestInfo = @{
|
||||||
"Target"= "localhost"; # test listener name
|
"Target"= "localhost"; # test listener name
|
||||||
@ -67,6 +75,8 @@ function Set-OpenSSHTestEnvironment
|
|||||||
"E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests
|
"E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests
|
||||||
"UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests
|
"UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests
|
||||||
"DebugMode" = $DebugMode # run openssh E2E in debug mode
|
"DebugMode" = $DebugMode # run openssh E2E in debug mode
|
||||||
|
"EnableAppVerifier" = $Script:EnableAppVerifier
|
||||||
|
"PostmortemDebugging" = $Script:PostmortemDebugging
|
||||||
}
|
}
|
||||||
|
|
||||||
#if user does not set path, pick it up
|
#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"
|
cmd /c "ssh-add -D 2>&1 >> $Script:TestSetupLogFile"
|
||||||
Repair-UserKeyPermission -FilePath $testPriKeypath -confirm:$false
|
Repair-UserKeyPermission -FilePath $testPriKeypath -confirm:$false
|
||||||
cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile"
|
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
|
Backup-OpenSSHTestInfo
|
||||||
}
|
}
|
||||||
#TODO - this is Windows specific. Need to be in PAL
|
#TODO - this is Windows specific. Need to be in PAL
|
||||||
@ -294,6 +322,31 @@ function Install-OpenSSHTestDependencies
|
|||||||
Write-Log -Message "Installing Pester..."
|
Write-Log -Message "Installing Pester..."
|
||||||
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
|
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
|
function Install-OpenSSHUtilsModule
|
||||||
@ -313,12 +366,12 @@ function Install-OpenSSHUtilsModule
|
|||||||
}
|
}
|
||||||
|
|
||||||
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath WindowsPowerShell\Modules
|
$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 "$manifestFile" -Destination "$targetDirectory" -Force -ErrorAction SilentlyContinue | out-null
|
||||||
Copy-item $moduleFile -Destination $targetDirectory -Force -ErrorAction SilentlyContinue | out-null
|
Copy-item "$moduleFile" -Destination "$targetDirectory" -Force -ErrorAction SilentlyContinue | out-null
|
||||||
|
|
||||||
if ($PSVersionTable.PSVersion.Major -lt 4)
|
if ($PSVersionTable.PSVersion.Major -lt 4)
|
||||||
{
|
{
|
||||||
@ -397,6 +450,18 @@ function Clear-OpenSSHTestEnvironment
|
|||||||
ssh-add-hostkey.ps1 -Delete_key $_.FullName
|
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
|
Remove-Item $sshBinPath\sshtest*hostkey* -Force -ErrorAction SilentlyContinue
|
||||||
#Restore sshd_config
|
#Restore sshd_config
|
||||||
$backupConfigPath = Join-Path $sshBinPath sshd_config.ori
|
$backupConfigPath = Join-Path $sshBinPath sshd_config.ori
|
||||||
@ -507,12 +572,17 @@ function Get-UnitTestDirectory
|
|||||||
#>
|
#>
|
||||||
function Invoke-OpenSSHE2ETest
|
function Invoke-OpenSSHE2ETest
|
||||||
{
|
{
|
||||||
|
[CmdletBinding()]
|
||||||
|
param
|
||||||
|
(
|
||||||
|
[ValidateSet('CI', 'Scenario')]
|
||||||
|
[string]$pri = "CI")
|
||||||
# Discover all CI tests and run them.
|
# Discover all CI tests and run them.
|
||||||
Import-Module pester -force -global
|
Import-Module pester -force -global
|
||||||
Push-Location $Script:E2ETestDirectory
|
Push-Location $Script:E2ETestDirectory
|
||||||
Write-Log -Message "Running OpenSSH E2E tests..."
|
Write-Log -Message "Running OpenSSH E2E tests..."
|
||||||
$testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique)
|
$testFolders = @(Get-ChildItem *.tests.ps1 -Recurse | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique)
|
||||||
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag 'CI'
|
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag $pri -PassThru
|
||||||
Pop-Location
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,11 +189,9 @@
|
|||||||
|
|
||||||
/* Define to 1 if you have the `arc4random' function. */
|
/* Define to 1 if you have the `arc4random' function. */
|
||||||
/* #undef HAVE_ARC4RANDOM */
|
/* #undef HAVE_ARC4RANDOM */
|
||||||
#define HAVE_ARC4RANDOM 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `arc4random_buf' function. */
|
/* Define to 1 if you have the `arc4random_buf' function. */
|
||||||
/* #undef HAVE_ARC4RANDOM_BUF */
|
/* #undef HAVE_ARC4RANDOM_BUF */
|
||||||
#define HAVE_ARC4RANDOM_BUF 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `arc4random_uniform' function. */
|
/* Define to 1 if you have the `arc4random_uniform' function. */
|
||||||
/* #undef HAVE_ARC4RANDOM_UNIFORM */
|
/* #undef HAVE_ARC4RANDOM_UNIFORM */
|
||||||
|
@ -112,18 +112,18 @@
|
|||||||
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>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'</Command>
|
<Command>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"</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Message>Generate crtheaders.h and config.h</Message>
|
<Message>Generate crtheaders.h and config.h</Message>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
|
<Command>copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
|
copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir)
|
copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)"
|
||||||
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
|
If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)")</Command>
|
||||||
<Message>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</Message>
|
<Message>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</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -145,18 +145,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
|
|||||||
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>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'</Command>
|
<Command>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"</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Message>Generate crtheaders.h and config.h</Message>
|
<Message>Generate crtheaders.h and config.h</Message>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
|
<Command>copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
|
copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir)
|
copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)"
|
||||||
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
|
If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)")</Command>
|
||||||
<Message>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</Message>
|
<Message>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</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -182,18 +182,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
|
|||||||
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>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'</Command>
|
<Command>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"</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Message>Generate crtheaders.h and config.h</Message>
|
<Message>Generate crtheaders.h and config.h</Message>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
|
<Command>copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
|
copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir)
|
copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)"
|
||||||
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
|
If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)")</Command>
|
||||||
<Message>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</Message>
|
<Message>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</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -219,18 +219,18 @@ If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</C
|
|||||||
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Command>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'</Command>
|
<Command>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"</Command>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PreBuildEvent>
|
<PreBuildEvent>
|
||||||
<Message>Generate crtheaders.h and config.h</Message>
|
<Message>Generate crtheaders.h and config.h</Message>
|
||||||
</PreBuildEvent>
|
</PreBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
|
<Command>copy /Y "$(SolutionDir)install-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
|
copy /Y "$(SolutionDir)uninstall-ssh*ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)OpenSSHUtils.ps*1 $(OutDir)
|
copy /Y "$(SolutionDir)OpenSSHUtils.ps*1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)Fix*FilePermissions.ps1" "$(OutDir)"
|
||||||
copy /Y $(SolutionDir)ssh-add-hostkey.ps1 $(OutDir)
|
copy /Y "$(SolutionDir)ssh-add-hostkey.ps1" "$(OutDir)"
|
||||||
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
|
If NOT exist "$(OutDir)\sshd_config" (copy "$(SolutionDir)sshd_config" "$(OutDir)")</Command>
|
||||||
<Message>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</Message>
|
<Message>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</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@ -255,13 +255,13 @@ if (-not (Test-Path $sshdpath)) {
|
|||||||
if (Get-Service sshd -ErrorAction SilentlyContinue)
|
if (Get-Service sshd -ErrorAction SilentlyContinue)
|
||||||
{
|
{
|
||||||
Stop-Service sshd
|
Stop-Service sshd
|
||||||
sc.exe delete sshd 1> null
|
sc.exe delete sshd 1>$null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
|
if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
|
||||||
{
|
{
|
||||||
Stop-Service ssh-agent
|
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
|
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
|
sc.exe privs sshd SeAssignPrimaryTokenPrivilege
|
||||||
|
|
||||||
Add-Privilege -Account $sshdSid -Privilege SeAssignPrimaryTokenPrivilege
|
Add-Privilege -Account $sshdSid -Privilege SeAssignPrimaryTokenPrivilege
|
||||||
|
Add-Privilege -Account $sshdSid -Privilege SeServiceLogonRight
|
||||||
|
|
||||||
if(-not (test-path $logsdir -PathType Container))
|
if(-not (test-path $logsdir -PathType Container))
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
if (Get-Service sshd -ErrorAction SilentlyContinue)
|
if (Get-Service sshd -ErrorAction SilentlyContinue)
|
||||||
{
|
{
|
||||||
Stop-Service sshd
|
Stop-Service sshd
|
||||||
sc.exe delete sshd 1> null
|
sc.exe delete sshd 1>$null
|
||||||
Write-Host -ForegroundColor Green "sshd successfully uninstalled"
|
Write-Host -ForegroundColor Green "sshd successfully uninstalled"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -11,12 +11,9 @@ else {
|
|||||||
if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
|
if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
|
||||||
{
|
{
|
||||||
Stop-Service ssh-agent
|
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"
|
Write-Host -ForegroundColor Green "ssh-agent successfully uninstalled"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host -ForegroundColor Yellow "ssh-agent service is not installed"
|
Write-Host -ForegroundColor Yellow "ssh-agent service is not installed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@ -149,7 +149,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -177,7 +177,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@ -206,7 +206,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\hostkeys\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -123,7 +123,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@ -149,7 +149,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -177,7 +177,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@ -206,7 +206,7 @@
|
|||||||
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
|
||||||
</Manifest>
|
</Manifest>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>xcopy /Y $(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\* $(OutDir)</Command>
|
<Command>xcopy /Y "$(ProjectDir)..\..\..\regress\unittests\sshkey\testdata\*" "$(OutDir)"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Binary file not shown.
@ -473,12 +473,12 @@ ParseANSI(unsigned char * pszBuffer, unsigned char * pszBufferEnd, unsigned char
|
|||||||
case '^': /* Private message */
|
case '^': /* Private message */
|
||||||
/* while not stop */
|
/* while not stop */
|
||||||
while (pszCurrent && pszCurrent < pszBufferEnd &&
|
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 &&
|
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++;
|
||||||
}
|
}
|
||||||
pszCurrent += strlen((const char *)VT_ST) - 1;
|
pszCurrent += strnlen((const char *)VT_ST, sizeof(VT_ST)) - 1;
|
||||||
fcompletion = 1;
|
fcompletion = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -42,7 +42,8 @@
|
|||||||
#include "ansiprsr.h"
|
#include "ansiprsr.h"
|
||||||
|
|
||||||
HANDLE hOutputConsole = NULL;
|
HANDLE hOutputConsole = NULL;
|
||||||
DWORD dwSavedAttributes = 0;
|
DWORD stdin_dwSavedAttributes = 0;
|
||||||
|
DWORD stdout_dwSavedAttributes = 0;
|
||||||
WORD wStartingAttributes = 0;
|
WORD wStartingAttributes = 0;
|
||||||
|
|
||||||
int ScreenX;
|
int ScreenX;
|
||||||
@ -72,8 +73,8 @@ int in_raw_mode = 0;
|
|||||||
char *consoleTitle = "OpenSSH SSH client";
|
char *consoleTitle = "OpenSSH SSH client";
|
||||||
|
|
||||||
/* Used to enter the raw mode */
|
/* Used to enter the raw mode */
|
||||||
int
|
void
|
||||||
ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
|
ConEnterRawMode()
|
||||||
{
|
{
|
||||||
DWORD dwAttributes = 0;
|
DWORD dwAttributes = 0;
|
||||||
DWORD dwRet = 0;
|
DWORD dwRet = 0;
|
||||||
@ -81,22 +82,22 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
|
|||||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
static bool bFirstConInit = true;
|
static bool bFirstConInit = true;
|
||||||
|
|
||||||
hOutputConsole = GetStdHandle(OutputHandle);
|
hOutputConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
if (hOutputConsole == INVALID_HANDLE_VALUE) {
|
if (hOutputConsole == INVALID_HANDLE_VALUE) {
|
||||||
dwRet = GetLastError();
|
dwRet = GetLastError();
|
||||||
error("GetStdHandle on OutputHandle failed with %d\n", dwRet);
|
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();
|
dwRet = GetLastError();
|
||||||
error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
|
error("GetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
|
||||||
return dwRet;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConsoleTitle(consoleTitle);
|
SetConsoleTitle(consoleTitle);
|
||||||
|
|
||||||
dwAttributes = dwSavedAttributes;
|
dwAttributes = stdin_dwSavedAttributes;
|
||||||
dwAttributes &= ~(ENABLE_LINE_INPUT |
|
dwAttributes &= ~(ENABLE_LINE_INPUT |
|
||||||
ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
|
ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
|
||||||
dwAttributes |= ENABLE_WINDOW_INPUT;
|
dwAttributes |= ENABLE_WINDOW_INPUT;
|
||||||
@ -104,17 +105,17 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
|
|||||||
if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) { /* Windows NT */
|
if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), dwAttributes)) { /* Windows NT */
|
||||||
dwRet = GetLastError();
|
dwRet = GetLastError();
|
||||||
error("SetConsoleMode on STD_INPUT_HANDLE failed with %d\n", dwRet);
|
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();
|
dwRet = GetLastError();
|
||||||
error("GetConsoleMode on hOutputConsole failed with %d\n", dwRet);
|
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;
|
char *envValue = NULL;
|
||||||
_dupenv_s(&envValue, NULL, "SSH_TERM_CONHOST_PARSER");
|
_dupenv_s(&envValue, NULL, "SSH_TERM_CONHOST_PARSER");
|
||||||
@ -140,7 +141,7 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
|
|||||||
SavedViewRect = csbi.srWindow;
|
SavedViewRect = csbi.srWindow;
|
||||||
debug("console doesn't support the ansi parsing");
|
debug("console doesn't support the ansi parsing");
|
||||||
} else {
|
} else {
|
||||||
ConMoveCursorTop(csbi);
|
ConSaveViewRect();
|
||||||
debug("console supports the ansi parsing");
|
debug("console supports the ansi parsing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,26 +151,18 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
|
|||||||
ScrollBottom = ConVisibleWindowHeight();
|
ScrollBottom = ConVisibleWindowHeight();
|
||||||
|
|
||||||
in_raw_mode = 1;
|
in_raw_mode = 1;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used to Uninitialize the Console */
|
/* Used to Uninitialize the Console */
|
||||||
int
|
void
|
||||||
ConExitRawMode()
|
ConExitRawMode()
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), stdin_dwSavedAttributes);
|
||||||
in_raw_mode = 0;
|
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), stdout_dwSavedAttributes);
|
||||||
if (hOutputConsole == NULL || !GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
SetConsoleMode(hOutputConsole, dwSavedAttributes);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used to exit the raw mode */
|
/* Used to exit the raw mode */
|
||||||
int
|
void
|
||||||
ConUnInitWithRestore()
|
ConUnInitWithRestore()
|
||||||
{
|
{
|
||||||
DWORD dwWritten;
|
DWORD dwWritten;
|
||||||
@ -177,19 +170,19 @@ ConUnInitWithRestore()
|
|||||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
||||||
|
|
||||||
if (hOutputConsole == NULL)
|
if (hOutputConsole == NULL)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
if (!GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
|
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 = consoleInfo.dwCursorPosition;
|
||||||
Coord.X = 0;
|
Coord.X = 0;
|
||||||
DWORD dwNumChar = (consoleInfo.dwSize.Y - consoleInfo.dwCursorPosition.Y) * consoleInfo.dwSize.X;
|
DWORD dwNumChar = (consoleInfo.dwSize.Y - consoleInfo.dwCursorPosition.Y) * consoleInfo.dwSize.X;
|
||||||
FillConsoleOutputCharacter(hOutputConsole, ' ', dwNumChar, Coord, &dwWritten);
|
FillConsoleOutputCharacter(hOutputConsole, ' ', dwNumChar, Coord, &dwWritten);
|
||||||
FillConsoleOutputAttribute(hOutputConsole, wStartingAttributes, dwNumChar, Coord, &dwWritten);
|
FillConsoleOutputAttribute(hOutputConsole, wStartingAttributes, dwNumChar, Coord, &dwWritten);
|
||||||
SetConsoleTextAttribute(hOutputConsole, wStartingAttributes);
|
SetConsoleTextAttribute(hOutputConsole, wStartingAttributes);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
@ -524,12 +517,12 @@ ConWriteString(char* pszString, int cbString)
|
|||||||
if ((needed = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, NULL, 0)) == 0 ||
|
if ((needed = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, NULL, 0)) == 0 ||
|
||||||
(utf16 = malloc(needed * sizeof(wchar_t))) == NULL ||
|
(utf16 = malloc(needed * sizeof(wchar_t))) == NULL ||
|
||||||
(cnt = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, utf16, needed)) == 0) {
|
(cnt = MultiByteToWideChar(CP_UTF8, 0, pszString, cbString, utf16, needed)) == 0) {
|
||||||
Result = (DWORD)printf(pszString);
|
Result = (DWORD)printf_s(pszString);
|
||||||
} else {
|
} else {
|
||||||
if (hOutputConsole)
|
if (hOutputConsole)
|
||||||
WriteConsoleW(hOutputConsole, utf16, cnt, &Result, 0);
|
WriteConsoleW(hOutputConsole, utf16, cnt, &Result, 0);
|
||||||
else
|
else
|
||||||
Result = (DWORD)wprintf(utf16);
|
Result = (DWORD)wprintf_s(utf16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utf16)
|
if (utf16)
|
||||||
@ -546,7 +539,7 @@ ConTranslateAndWriteString(char* pszString, int cbString)
|
|||||||
if (hOutputConsole)
|
if (hOutputConsole)
|
||||||
WriteConsole(hOutputConsole, pszString, cbString, &Result, 0);
|
WriteConsole(hOutputConsole, pszString, cbString, &Result, 0);
|
||||||
else
|
else
|
||||||
Result = (DWORD)printf(pszString);
|
Result = (DWORD)printf_s(pszString);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -836,7 +829,11 @@ Con_printf(const char *Format, ...)
|
|||||||
|
|
||||||
memset(temp, '\0', sizeof(temp));
|
memset(temp, '\0', sizeof(temp));
|
||||||
va_start(va_data, Format);
|
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);
|
ConWriteConsole(temp, len);
|
||||||
va_end(va_data);
|
va_end(va_data);
|
||||||
|
|
||||||
@ -1080,6 +1077,7 @@ ConMoveVisibleWindow(int offset)
|
|||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
||||||
SMALL_RECT visibleWindowRect;
|
SMALL_RECT visibleWindowRect;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
memset(&visibleWindowRect, 0, sizeof(SMALL_RECT));
|
memset(&visibleWindowRect, 0, sizeof(SMALL_RECT));
|
||||||
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
|
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
|
||||||
@ -1090,14 +1088,19 @@ ConMoveVisibleWindow(int offset)
|
|||||||
for (int i = 0; i < offset; i++)
|
for (int i = 0; i < offset; i++)
|
||||||
ConScrollDown(0, consoleInfo.dwSize.Y - 1);
|
ConScrollDown(0, consoleInfo.dwSize.Y - 1);
|
||||||
|
|
||||||
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
|
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo) == FALSE) {
|
||||||
memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect));
|
|
||||||
else {
|
|
||||||
error("GetConsoleScreenBufferInfo failed with %d", GetLastError());
|
error("GetConsoleScreenBufferInfo failed with %d", GetLastError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((r = memcpy_s(&visibleWindowRect, sizeof(visibleWindowRect), &consoleInfo.srWindow, sizeof(visibleWindowRect))) != 0) {
|
||||||
|
error("memcpy_s failed with error: %d.", r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} 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.Top += offset;
|
||||||
visibleWindowRect.Bottom += offset;
|
visibleWindowRect.Bottom += offset;
|
||||||
}
|
}
|
||||||
@ -1571,17 +1574,18 @@ ConSaveWindowsState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi)
|
ConMoveCursorTopOfVisibleWindow()
|
||||||
{
|
{
|
||||||
/* Windows server at first sends the "cls" after the connection is established.
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
* Since we don't want to loose any data on the console, we would like to scroll down
|
int offset;
|
||||||
* the visible window.
|
|
||||||
*/
|
if (GetConsoleScreenBufferInfo(hOutputConsole, &csbi)) {
|
||||||
int offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top;
|
offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top;
|
||||||
ConMoveVisibleWindow(offset);
|
ConMoveVisibleWindow(offset);
|
||||||
|
|
||||||
ConSaveViewRect();
|
ConSaveViewRect();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
get_console_handle(FILE *stream, DWORD * mode)
|
get_console_handle(FILE *stream, DWORD * mode)
|
||||||
|
@ -83,11 +83,15 @@
|
|||||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
|
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DISABLE_NEWLINE_AUTO_RETURN
|
||||||
|
#define DISABLE_NEWLINE_AUTO_RETURN 0x8
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef void * SCREEN_HANDLE;
|
typedef void * SCREEN_HANDLE;
|
||||||
|
|
||||||
int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
|
void ConEnterRawMode();
|
||||||
int ConUnInitWithRestore();
|
void ConUnInitWithRestore();
|
||||||
int ConExitRawMode();
|
void ConExitRawMode();
|
||||||
BOOL ConIsRedirected(HANDLE hInput);
|
BOOL ConIsRedirected(HANDLE hInput);
|
||||||
HANDLE GetConsoleOutputHandle();
|
HANDLE GetConsoleOutputHandle();
|
||||||
HANDLE GetConsoleInputHandle();
|
HANDLE GetConsoleInputHandle();
|
||||||
@ -141,6 +145,6 @@ void ConSaveWindowsState();
|
|||||||
void ConMoveVisibleWindow(int offset);
|
void ConMoveVisibleWindow(int offset);
|
||||||
int is_cursor_at_lastline_of_visible_window();
|
int is_cursor_at_lastline_of_visible_window();
|
||||||
void ConGetCursorPosition(int *x, int *y);
|
void ConGetCursorPosition(int *x, int *y);
|
||||||
void ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi);
|
void ConMoveCursorTopOfVisibleWindow();
|
||||||
HANDLE get_console_handle(FILE *, DWORD *);
|
HANDLE get_console_handle(FILE *, DWORD *);
|
||||||
#endif
|
#endif
|
||||||
|
@ -532,6 +532,7 @@ int
|
|||||||
fileio_read(struct w32_io* pio, void *dst, size_t max_bytes)
|
fileio_read(struct w32_io* pio, void *dst, size_t max_bytes)
|
||||||
{
|
{
|
||||||
int bytes_copied;
|
int bytes_copied;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
debug5("read - io:%p remaining:%d", pio, pio->read_details.remaining);
|
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);
|
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.remaining -= bytes_copied;
|
||||||
pio->read_details.completed += bytes_copied;
|
pio->read_details.completed += bytes_copied;
|
||||||
debug4("read - io:%p read: %d remaining: %d", pio, 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;
|
int bytes_copied;
|
||||||
DWORD pipe_flags = 0, pipe_instances = 0;
|
DWORD pipe_flags = 0, pipe_instances = 0;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
debug4("write - io:%p", pio);
|
debug4("write - io:%p", pio);
|
||||||
if (pio->write_details.pending) {
|
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);
|
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 (pio->type == NONSOCK_SYNC_FD || FILETYPE(pio) == FILE_TYPE_CHAR) {
|
||||||
if (syncio_initiate_write(pio, bytes_copied) == 0) {
|
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);
|
debug4("write - reporting %d bytes written, io:%p", bytes_copied, pio);
|
||||||
return bytes_copied;
|
return bytes_copied;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fstat() implemetation */
|
/* fstat() implemetation */
|
||||||
|
@ -244,6 +244,7 @@ w32_fopen_utf8(const char *path, const char *mode)
|
|||||||
char utf8_bom[] = { 0xEF,0xBB,0xBF };
|
char utf8_bom[] = { 0xEF,0xBB,0xBF };
|
||||||
char first3_bytes[3];
|
char first3_bytes[3];
|
||||||
int status = 1;
|
int status = 1;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (mode[1] != '\0') {
|
if (mode[1] != '\0') {
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
@ -257,8 +258,12 @@ w32_fopen_utf8(const char *path, const char *mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if opening null device, point to Windows equivalent */
|
/* if opening null device, point to Windows equivalent */
|
||||||
if (0 == strncmp(path, NULL_DEVICE, strlen(NULL_DEVICE)+1))
|
if (0 == strncmp(path, NULL_DEVICE, strlen(NULL_DEVICE)+1)) {
|
||||||
wcsncpy_s(wpath, PATH_MAX, L"NUL", 3);
|
if ((r = wcsncpy_s(wpath, PATH_MAX, L"NUL", 3)) != 0) {
|
||||||
|
debug3("wcsncpy_s failed with error: %d.", r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
status = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX);
|
status = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX);
|
||||||
|
|
||||||
@ -308,6 +313,7 @@ char*
|
|||||||
wchar_t* str_w = NULL;
|
wchar_t* str_w = NULL;
|
||||||
char *ret = NULL, *str_tmp = NULL, *cp = NULL;
|
char *ret = NULL, *str_tmp = NULL, *cp = NULL;
|
||||||
int actual_read = 0;
|
int actual_read = 0;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (h != NULL && h != INVALID_HANDLE_VALUE
|
if (h != NULL && h != INVALID_HANDLE_VALUE
|
||||||
&& GetFileType(h) == FILE_TYPE_CHAR) {
|
&& GetFileType(h) == FILE_TYPE_CHAR) {
|
||||||
@ -338,7 +344,10 @@ char*
|
|||||||
|
|
||||||
if((actual_read + strlen(str_tmp)) >= n)
|
if((actual_read + strlen(str_tmp)) >= n)
|
||||||
break;
|
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);
|
actual_read += (int)strlen(str_tmp);
|
||||||
cp += strlen(str_tmp);
|
cp += strlen(str_tmp);
|
||||||
|
|
||||||
@ -766,7 +775,8 @@ w32_getcwd(char *buffer, int maxlen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy_s(buffer, maxlen, putf8);
|
if (strcpy_s(buffer, maxlen, putf8))
|
||||||
|
return NULL;
|
||||||
free(putf8);
|
free(putf8);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -807,7 +817,8 @@ w32_stat(const char *path, struct w32_stat *buf)
|
|||||||
int
|
int
|
||||||
readlink(const char *path, char *link, int linklen)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -850,6 +861,7 @@ convertToForwardslash(char *str)
|
|||||||
char *
|
char *
|
||||||
realpath(const char *path, char resolved[PATH_MAX])
|
realpath(const char *path, char resolved[PATH_MAX])
|
||||||
{
|
{
|
||||||
|
errno_t r = 0;
|
||||||
if (!path || !resolved) return NULL;
|
if (!path || !resolved) return NULL;
|
||||||
|
|
||||||
char tempPath[PATH_MAX];
|
char tempPath[PATH_MAX];
|
||||||
@ -860,10 +872,16 @@ realpath(const char *path, char resolved[PATH_MAX])
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((path_len >= 2) && (path[0] == '/') && path[1] && (path[2] == ':'))
|
if ((path_len >= 2) && (path[0] == '/') && path[1] && (path[2] == ':')) {
|
||||||
strncpy_s(resolved, PATH_MAX, path + 1, path_len); /* skip the first '/' */
|
if((r = strncpy_s(resolved, PATH_MAX, path + 1, path_len)) != 0 ) /* skip the first '/' */ {
|
||||||
else
|
debug3("memcpy_s failed with error: %d.", r);
|
||||||
strncpy_s(resolved, PATH_MAX, path, path_len + 1);
|
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:\\" */
|
if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { /* make "x:" as "x:\\" */
|
||||||
resolved[2] = '\\';
|
resolved[2] = '\\';
|
||||||
@ -876,8 +894,10 @@ realpath(const char *path, char resolved[PATH_MAX])
|
|||||||
convertToForwardslash(tempPath);
|
convertToForwardslash(tempPath);
|
||||||
|
|
||||||
resolved[0] = '/'; /* will be our first slash in /x:/users/test1 format */
|
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 NULL;
|
||||||
|
}
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,11 +907,15 @@ sanitized_path(const char *path)
|
|||||||
if(!path) return NULL;
|
if(!path) return NULL;
|
||||||
|
|
||||||
static char newPath[PATH_MAX] = { '\0', };
|
static char newPath[PATH_MAX] = { '\0', };
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (path[0] == '/' && path[1]) {
|
if (path[0] == '/' && path[1]) {
|
||||||
if (path[2] == ':') {
|
if (path[2] == ':') {
|
||||||
if (path[3] == '\0') { /* make "/x:" as "x:\\" */
|
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[2] = '\\';
|
||||||
newPath[3] = '\0';
|
newPath[3] = '\0';
|
||||||
|
|
||||||
@ -993,7 +1017,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags)
|
|||||||
} else if (ch == '\b') { /* backspace */
|
} else if (ch == '\b') { /* backspace */
|
||||||
if (current_index > 0) {
|
if (current_index > 0) {
|
||||||
if (flags & RPP_ECHO_ON)
|
if (flags & RPP_ECHO_ON)
|
||||||
printf("%c \b", ch);
|
printf_s("%c \b", ch);
|
||||||
|
|
||||||
current_index--; /* overwrite last character */
|
current_index--; /* overwrite last character */
|
||||||
}
|
}
|
||||||
@ -1012,7 +1036,7 @@ readpassphrase(const char *prompt, char *outBuf, size_t outBufLen, int flags)
|
|||||||
|
|
||||||
outBuf[current_index++] = ch;
|
outBuf[current_index++] = ch;
|
||||||
if(flags & RPP_ECHO_ON)
|
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;
|
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);
|
||||||
|
}
|
||||||
|
@ -31,3 +31,4 @@ int errno_from_Win32Error(int);
|
|||||||
void unix_time_to_file_time(ULONG, LPFILETIME);
|
void unix_time_to_file_time(ULONG, LPFILETIME);
|
||||||
void file_time_to_unix_time(const LPFILETIME, time_t *);
|
void file_time_to_unix_time(const LPFILETIME, time_t *);
|
||||||
int file_attr_to_st_mode(wchar_t * path, DWORD attributes);
|
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);
|
@ -51,15 +51,23 @@ static char* pw_shellpath = NULL;
|
|||||||
int
|
int
|
||||||
initialize_pw()
|
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 == 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");
|
fatal("initialize_pw - out of memory");
|
||||||
else {
|
else {
|
||||||
char* head = pw_shellpath;
|
char* head = pw_shellpath;
|
||||||
memcpy(head, w32_programdir(), strlen(w32_programdir()));
|
if ((r= memcpy_s(head, program_dir_len + shell_host_len + 1, w32_programdir(), program_dir_len)) != 0) {
|
||||||
head += strlen(w32_programdir());
|
fatal("memcpy_s failed with error: %d.", r);
|
||||||
memcpy(head, SHELL_HOST, strlen(SHELL_HOST));
|
}
|
||||||
head += strlen(SHELL_HOST);
|
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';
|
*head = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +110,8 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
|
|||||||
HKEY reg_key = 0;
|
HKEY reg_key = 0;
|
||||||
int tmp_len = PATH_MAX;
|
int tmp_len = PATH_MAX;
|
||||||
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
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;
|
errno = 0;
|
||||||
reset_pw();
|
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 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 ||
|
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)
|
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
|
||||||
if (GetWindowsDirectoryW(profile_home, PATH_MAX) == 0) {
|
if (GetWindowsDirectoryW(profile_home, PATH_MAX) == 0) {
|
||||||
@ -170,21 +179,29 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
|
|||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
uname_len = (DWORD)strlen(uname_utf8);
|
||||||
uname_upn_len = (DWORD) strlen(uname_utf8) + 1;
|
uname_upn_len = uname_len + 1;
|
||||||
if (udom_utf8)
|
if (udom_utf8) {
|
||||||
uname_upn_len += (DWORD)strlen(udom_utf8) + 1;
|
udom_len = (DWORD)strlen(udom_utf8);
|
||||||
|
uname_upn_len += udom_len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((uname_upn = malloc(uname_upn_len)) == NULL) {
|
if ((uname_upn = malloc(uname_upn_len)) == NULL) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
goto done;
|
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) {
|
if (udom_utf8) {
|
||||||
/* TODO - get domain FQDN */
|
/* TODO - get domain FQDN */
|
||||||
uname_upn[strlen(uname_utf8)] = '@';
|
uname_upn[uname_len] = '@';
|
||||||
memcpy(uname_upn + strlen(uname_utf8) + 1, udom_utf8, strlen(udom_utf8) + 1);
|
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;
|
pw.pw_name = uname_upn;
|
||||||
uname_upn = NULL;
|
uname_upn = NULL;
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include <Strsafe.h>
|
#include <Strsafe.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <Shlobj.h>
|
||||||
|
#include <Sddl.h>
|
||||||
#include "misc_internal.h"
|
#include "misc_internal.h"
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
|
|
||||||
@ -53,6 +55,33 @@
|
|||||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||||
#endif
|
#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)(
|
typedef BOOL(WINAPI *__t_SetCurrentConsoleFontEx)(
|
||||||
_In_ HANDLE hConsoleOutput,
|
_In_ HANDLE hConsoleOutput,
|
||||||
_In_ BOOL bMaximumWindow,
|
_In_ BOOL bMaximumWindow,
|
||||||
@ -90,48 +119,83 @@ struct key_translation {
|
|||||||
int vk;
|
int vk;
|
||||||
wchar_t out;
|
wchar_t out;
|
||||||
int in_key_len;
|
int in_key_len;
|
||||||
|
DWORD ctrlState;
|
||||||
} key_translation;
|
} 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[] = {
|
struct key_translation keys[] = {
|
||||||
{ L"\r", VK_RETURN, L'\r' , 0},
|
{ L"\r", VK_RETURN, L'\r' , 0 , 0},
|
||||||
{ L"\b", VK_BACK, L'\b' , 0},
|
{ L"\n", VK_RETURN, L'\r' , 0 , 0 },
|
||||||
{ L"\x7f", VK_BACK, L'\b' , 0},
|
{ L"\b", VK_BACK, L'\b' , 0 , 0 },
|
||||||
{ L"\t", VK_TAB, L'\t' , 0},
|
{ L"\x7f", VK_BACK, L'\b' , 0 , 0 },
|
||||||
{ L"\x1b[A", VK_UP, 0 , 0},
|
{ L"\t", VK_TAB, L'\t' , 0 , 0},
|
||||||
{ L"\x1b[B", VK_DOWN, 0 , 0},
|
{ L"\x1b[A", VK_UP, 0 , 0 , 0},
|
||||||
{ L"\x1b[C", VK_RIGHT, 0 , 0},
|
{ L"\x1b[B", VK_DOWN, 0 , 0 , 0},
|
||||||
{ L"\x1b[D", VK_LEFT, 0 , 0},
|
{ L"\x1b[C", VK_RIGHT, 0 , 0 , 0},
|
||||||
{ L"\x1b[F", VK_END, 0 , 0 }, /* KeyPad END */
|
{ L"\x1b[D", VK_LEFT, 0 , 0 , 0},
|
||||||
{ L"\x1b[H", VK_HOME, 0 , 0 }, /* KeyPad HOME */
|
{ L"\x1b[F", VK_END, 0 , 0 , 0}, /* KeyPad END */
|
||||||
{ L"\x1b[Z", 0, 0 , 0 }, /* ignore Shift+TAB */
|
{ L"\x1b[H", VK_HOME, 0 , 0 , 0}, /* KeyPad HOME */
|
||||||
{ L"\x1b[1~", VK_HOME, 0 , 0},
|
{ L"\x1b[Z", 0, 0 , 0 , 0}, /* ignore Shift+TAB */
|
||||||
{ L"\x1b[2~", VK_INSERT, 0 , 0},
|
{ L"\x1b[1~", VK_HOME, 0 , 0 , 0},
|
||||||
{ L"\x1b[3~", VK_DELETE, 0 , 0},
|
{ L"\x1b[2~", VK_INSERT, 0 , 0 , 0},
|
||||||
{ L"\x1b[4~", VK_END, 0 , 0},
|
{ L"\x1b[3~", VK_DELETE, 0 , 0 , 0},
|
||||||
{ L"\x1b[5~", VK_PRIOR, 0 , 0},
|
{ L"\x1b[4~", VK_END, 0 , 0 , 0},
|
||||||
{ L"\x1b[6~", VK_NEXT, 0 , 0},
|
{ L"\x1b[5~", VK_PRIOR, 0 , 0 , 0},
|
||||||
{ L"\x1b[11~", VK_F1, 0 , 0},
|
{ L"\x1b[6~", VK_NEXT, 0 , 0 , 0},
|
||||||
{ L"\x1b[12~", VK_F2, 0 , 0},
|
{ L"\x1b[11~", VK_F1, 0 , 0 , 0},
|
||||||
{ L"\x1b[13~", VK_F3, 0 , 0},
|
{ L"\x1b[12~", VK_F2, 0 , 0 , 0},
|
||||||
{ L"\x1b[14~", VK_F4, 0 , 0},
|
{ L"\x1b[13~", VK_F3, 0 , 0 , 0},
|
||||||
{ L"\x1b[15~", VK_F5, 0 , 0},
|
{ L"\x1b[14~", VK_F4, 0 , 0 , 0},
|
||||||
{ L"\x1b[17~", VK_F6, 0 , 0},
|
{ L"\x1b[15~", VK_F5, 0 , 0 , 0},
|
||||||
{ L"\x1b[18~", VK_F7, 0 , 0},
|
{ L"\x1b[17~", VK_F6, 0 , 0 , 0},
|
||||||
{ L"\x1b[19~", VK_F8, 0 , 0},
|
{ L"\x1b[18~", VK_F7, 0 , 0 , 0},
|
||||||
{ L"\x1b[20~", VK_F9, 0 , 0},
|
{ L"\x1b[19~", VK_F8, 0 , 0 , 0},
|
||||||
{ L"\x1b[21~", VK_F10, 0 , 0},
|
{ L"\x1b[20~", VK_F9, 0 , 0 , 0},
|
||||||
{ L"\x1b[23~", VK_F11, 0 , 0},
|
{ L"\x1b[21~", VK_F10, 0 , 0 , 0},
|
||||||
{ L"\x1b[24~", VK_F12, 0 , 0},
|
{ L"\x1b[23~", VK_F11, 0 , 0 , 0},
|
||||||
{ L"\x1bOP", VK_F1, 0 , 0 },
|
{ L"\x1b[24~", VK_F12, 0 , 0 , 0},
|
||||||
{ L"\x1bOQ", VK_F2, 0 , 0 },
|
{ L"\x1bOA", VK_UP, 0 , 0 , 0},
|
||||||
{ L"\x1bOR", VK_F3, 0 , 0 },
|
{ L"\x1bOB", VK_DOWN, 0 , 0 , 0},
|
||||||
{ L"\x1bOS", VK_F4, 0 , 0 },
|
{ L"\x1bOC", VK_RIGHT, 0 , 0 , 0},
|
||||||
{ L"\x1b", VK_ESCAPE, L'\x1b' , 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 lastX = 0;
|
||||||
static SHORT lastY = 0;
|
static SHORT lastY = 0;
|
||||||
|
static wchar_t system32_path[PATH_MAX];
|
||||||
static wchar_t cmd_exe_path[PATH_MAX];
|
static wchar_t cmd_exe_path[PATH_MAX];
|
||||||
|
|
||||||
SHORT currentLine = 0;
|
SHORT currentLine = 0;
|
||||||
@ -201,60 +265,149 @@ ConSRWidth()
|
|||||||
return consoleBufferInfo.srWindow.Right;
|
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.
|
* This function will handle the console keystrokes.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SendKeyStroke(HANDLE hInput, int keyStroke, wchar_t character)
|
SendKeyStrokeEx(HANDLE hInput, int vKey, wchar_t character, DWORD ctrlState, BOOL keyDown)
|
||||||
{
|
{
|
||||||
DWORD wr = 0;
|
DWORD wr = 0;
|
||||||
INPUT_RECORD ir;
|
INPUT_RECORD ir;
|
||||||
|
|
||||||
ir.EventType = KEY_EVENT;
|
ir.EventType = KEY_EVENT;
|
||||||
ir.Event.KeyEvent.bKeyDown = TRUE;
|
ir.Event.KeyEvent.bKeyDown = keyDown;
|
||||||
ir.Event.KeyEvent.wRepeatCount = 1;
|
ir.Event.KeyEvent.wRepeatCount = 0;
|
||||||
ir.Event.KeyEvent.wVirtualKeyCode = keyStroke;
|
ir.Event.KeyEvent.wVirtualKeyCode = vKey;
|
||||||
ir.Event.KeyEvent.wVirtualScanCode = 0;
|
ir.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyA(vKey, MAPVK_VK_TO_VSC);
|
||||||
ir.Event.KeyEvent.dwControlKeyState = 0;
|
ir.Event.KeyEvent.dwControlKeyState = ctrlState;
|
||||||
ir.Event.KeyEvent.uChar.UnicodeChar = character;
|
ir.Event.KeyEvent.uChar.UnicodeChar = character;
|
||||||
|
|
||||||
WriteConsoleInputW(hInput, &ir, 1, &wr);
|
WriteConsoleInputW(hInput, &ir, 1, &wr);
|
||||||
|
}
|
||||||
|
|
||||||
ir.Event.KeyEvent.bKeyDown = FALSE;
|
void
|
||||||
WriteConsoleInputW(hInput, &ir, 1, &wr);
|
SendKeyStroke(HANDLE hInput, int keyStroke, wchar_t character, DWORD ctrlState)
|
||||||
|
{
|
||||||
|
SendKeyStrokeEx(hInput, keyStroke, character, ctrlState, TRUE);
|
||||||
|
SendKeyStrokeEx(hInput, keyStroke, character, ctrlState, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initialize_keylen()
|
initialize_keylen()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ARRAYSIZE(keys); i++)
|
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
|
void
|
||||||
ProcessIncomingKeys(char * ansikey)
|
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);
|
wchar_t *buf = utf8_to_utf16(ansikey);
|
||||||
|
|
||||||
if (!buf) {
|
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);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
while (buf && (wcslen(buf) > 0)) {
|
while (buf && ((buf_len=(int)wcslen(buf)) > 0)) {
|
||||||
for (int j = 0; j < ARRAYSIZE(keys); j++) {
|
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) ) {
|
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);
|
SendKeyStroke(child_in, keys[j].vk, keys[j].out, keys[j].ctrlState);
|
||||||
buf += keys[j].in_key_len;
|
buf += keys[j].in_key_len;
|
||||||
goto loop;
|
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*/
|
if (*buf == L'\x3') /*Ctrl+C - Raise Ctrl+C*/
|
||||||
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
|
||||||
else
|
else
|
||||||
SendKeyStroke(child_in, 0, *buf);
|
SendKeyStroke(child_in, 0, *buf, 0);
|
||||||
|
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
@ -321,11 +474,11 @@ void
|
|||||||
SendSetCursor(HANDLE hInput, int X, int Y)
|
SendSetCursor(HANDLE hInput, int X, int Y)
|
||||||
{
|
{
|
||||||
DWORD wr = 0;
|
DWORD wr = 0;
|
||||||
DWORD out = 0;
|
int out = 0;
|
||||||
char formatted_output[255];
|
char formatted_output[255];
|
||||||
|
|
||||||
out = _snprintf_s(formatted_output, sizeof(formatted_output), _TRUNCATE, "\033[%d;%dH", Y, X);
|
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);
|
WriteFile(hInput, formatted_output, out, &wr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,15 +486,15 @@ void
|
|||||||
SendVerticalScroll(HANDLE hInput, int lines)
|
SendVerticalScroll(HANDLE hInput, int lines)
|
||||||
{
|
{
|
||||||
DWORD wr = 0;
|
DWORD wr = 0;
|
||||||
DWORD out = 0;
|
int out = 0;
|
||||||
char formatted_output[255];
|
char formatted_output[255];
|
||||||
|
|
||||||
LONG vn = abs(lines);
|
LONG vn = abs(lines);
|
||||||
/* Not supporting the [S at the moment. */
|
/* Not supporting the [S at the moment. */
|
||||||
if (lines > 0) {
|
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);
|
WriteFile(hInput, formatted_output, out, &wr, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,12 +503,12 @@ void
|
|||||||
SendHorizontalScroll(HANDLE hInput, int cells)
|
SendHorizontalScroll(HANDLE hInput, int cells)
|
||||||
{
|
{
|
||||||
DWORD wr = 0;
|
DWORD wr = 0;
|
||||||
DWORD out = 0;
|
int out = 0;
|
||||||
char formatted_output[255];
|
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);
|
WriteFile(hInput, formatted_output, out, &wr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,10 +613,13 @@ SendBuffer(HANDLE hInput, CHAR_INFO *buffer, DWORD bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
currentLine = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,16 +642,16 @@ SizeWindow(HANDLE hInput)
|
|||||||
matchingFont.FontWeight = FW_NORMAL;
|
matchingFont.FontWeight = FW_NORMAL;
|
||||||
wcscpy_s(matchingFont.FaceName, LF_FACESIZE, L"Consolas");
|
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 */
|
/* This information is the live screen */
|
||||||
ZeroMemory(&consoleInfo, sizeof(consoleInfo));
|
ZeroMemory(&consoleInfo, sizeof(consoleInfo));
|
||||||
consoleInfo.cbSize = 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 */
|
/* 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 */
|
/* Define the new console window size and scroll position */
|
||||||
if (inputSi.dwXCountChars == 0 || inputSi.dwYCountChars == 0) {
|
if (inputSi.dwXCountChars == 0 || inputSi.dwYCountChars == 0) {
|
||||||
@ -507,18 +663,18 @@ SizeWindow(HANDLE hInput)
|
|||||||
srWindowRect.Bottom = min((SHORT)inputSi.dwYCountChars, coordScreen.Y) - 1;
|
srWindowRect.Bottom = min((SHORT)inputSi.dwYCountChars, coordScreen.Y) - 1;
|
||||||
srWindowRect.Left = srWindowRect.Top = (SHORT)0;
|
srWindowRect.Left = srWindowRect.Top = (SHORT)0;
|
||||||
|
|
||||||
/* Define the new console buffer size to be the maximum possible */
|
/* Define the new console buffer history to be the maximum possible */
|
||||||
coordScreen.X = 100;
|
coordScreen.X = srWindowRect.Right + 1; /* buffer width must be equ window width */
|
||||||
coordScreen.Y = 9999;
|
coordScreen.Y = 9999;
|
||||||
|
|
||||||
if (SetConsoleWindowInfo(child_out, TRUE, &srWindowRect))
|
if (SetConsoleWindowInfo(hInput, TRUE, &srWindowRect))
|
||||||
bSuccess = SetConsoleScreenBufferSize(child_out, coordScreen);
|
bSuccess = SetConsoleScreenBufferSize(hInput, coordScreen);
|
||||||
else {
|
else {
|
||||||
if (SetConsoleScreenBufferSize(child_out, coordScreen))
|
if (SetConsoleScreenBufferSize(hInput, coordScreen))
|
||||||
bSuccess = SetConsoleWindowInfo(child_out, TRUE, &srWindowRect);
|
bSuccess = SetConsoleWindowInfo(hInput, TRUE, &srWindowRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
bSuccess = GetConsoleScreenBufferInfoEx(child_out, &consoleInfo);
|
bSuccess = GetConsoleScreenBufferInfoEx(hInput, &consoleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI
|
DWORD WINAPI
|
||||||
@ -543,19 +699,24 @@ ProcessEvent(void *p)
|
|||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
LONG idObject;
|
LONG idObject;
|
||||||
LONG idChild;
|
LONG idChild;
|
||||||
|
CHAR_INFO pBuffer[MAX_EXPECTED_BUFFER_SIZE] = {0,};
|
||||||
|
DWORD bufferSize;
|
||||||
|
SMALL_RECT readRect;
|
||||||
|
COORD coordBufSize;
|
||||||
|
COORD coordBufCoord;
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
consoleEvent* current = (consoleEvent *)p;
|
consoleEvent* current = (consoleEvent *)p;
|
||||||
|
|
||||||
if (current) {
|
if (!current)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
event = current->event;
|
event = current->event;
|
||||||
hwnd = current->hwnd;
|
hwnd = current->hwnd;
|
||||||
idObject = current->idObject;
|
idObject = current->idObject;
|
||||||
idChild = current->idChild;
|
idChild = current->idChild;
|
||||||
} else
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (event < EVENT_CONSOLE_CARET || event > EVENT_CONSOLE_LAYOUT)
|
if (event < EVENT_CONSOLE_CARET || event > EVENT_CONSOLE_LAYOUT)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
@ -586,14 +747,15 @@ ProcessEvent(void *p)
|
|||||||
lastX = co.X;
|
lastX = co.X;
|
||||||
lastY = co.Y;
|
lastY = co.Y;
|
||||||
|
|
||||||
|
if (lastX == 0 && lastY > currentLine)
|
||||||
|
CalculateAndSetCursor(pipe_out, lastX, lastY, TRUE);
|
||||||
|
else
|
||||||
SendSetCursor(pipe_out, lastX + 1, lastY + 1);
|
SendSetCursor(pipe_out, lastX + 1, lastY + 1);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVENT_CONSOLE_UPDATE_REGION:
|
case EVENT_CONSOLE_UPDATE_REGION:
|
||||||
{
|
{
|
||||||
SMALL_RECT readRect;
|
|
||||||
|
|
||||||
readRect.Top = HIWORD(idObject);
|
readRect.Top = HIWORD(idObject);
|
||||||
readRect.Left = LOWORD(idObject);
|
readRect.Left = LOWORD(idObject);
|
||||||
readRect.Bottom = HIWORD(idChild);
|
readRect.Bottom = HIWORD(idChild);
|
||||||
@ -618,7 +780,6 @@ ProcessEvent(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out the buffer size */
|
/* Figure out the buffer size */
|
||||||
COORD coordBufSize;
|
|
||||||
coordBufSize.Y = readRect.Bottom - readRect.Top + 1;
|
coordBufSize.Y = readRect.Bottom - readRect.Top + 1;
|
||||||
coordBufSize.X = readRect.Right - readRect.Left + 1;
|
coordBufSize.X = readRect.Right - readRect.Left + 1;
|
||||||
|
|
||||||
@ -632,7 +793,7 @@ ProcessEvent(void *p)
|
|||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* Compute buffer size */
|
/* Compute buffer size */
|
||||||
DWORD bufferSize = coordBufSize.X * coordBufSize.Y;
|
bufferSize = coordBufSize.X * coordBufSize.Y;
|
||||||
if (bufferSize > MAX_EXPECTED_BUFFER_SIZE) {
|
if (bufferSize > MAX_EXPECTED_BUFFER_SIZE) {
|
||||||
if (!bStartup) {
|
if (!bStartup) {
|
||||||
SendClearScreen(pipe_out);
|
SendClearScreen(pipe_out);
|
||||||
@ -642,38 +803,22 @@ ProcessEvent(void *p)
|
|||||||
return ERROR_SUCCESS;
|
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 */
|
/* The top left destination cell of the temporary buffer is row 0, col 0 */
|
||||||
COORD coordBufCoord;
|
|
||||||
coordBufCoord.X = 0;
|
coordBufCoord.X = 0;
|
||||||
coordBufCoord.Y = 0;
|
coordBufCoord.Y = 0;
|
||||||
|
|
||||||
/* Copy the block from the screen buffer to the temp. buffer */
|
/* Copy the block from the screen buffer to the temp. buffer */
|
||||||
if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) {
|
if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect))
|
||||||
DWORD dwError = GetLastError();
|
return GetLastError();
|
||||||
|
|
||||||
free(pBuffer);
|
|
||||||
return dwError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readRect.Top > currentLine)
|
|
||||||
for (SHORT n = currentLine; n < readRect.Top; n++)
|
|
||||||
SendLF(pipe_out);
|
|
||||||
|
|
||||||
/* Set cursor location based on the reported location from the message */
|
/* 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 */
|
/* Send the entire block */
|
||||||
SendBuffer(pipe_out, pBuffer, bufferSize);
|
SendBuffer(pipe_out, pBuffer, bufferSize);
|
||||||
lastViewPortY = ViewPortY;
|
lastViewPortY = ViewPortY;
|
||||||
lastLineLength = readRect.Left;
|
lastLineLength = readRect.Left;
|
||||||
|
|
||||||
free(pBuffer);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVENT_CONSOLE_UPDATE_SIMPLE:
|
case EVENT_CONSOLE_UPDATE_SIMPLE:
|
||||||
@ -683,38 +828,27 @@ ProcessEvent(void *p)
|
|||||||
wX = LOWORD(idObject);
|
wX = LOWORD(idObject);
|
||||||
wY = HIWORD(idObject);
|
wY = HIWORD(idObject);
|
||||||
|
|
||||||
SMALL_RECT readRect;
|
|
||||||
readRect.Top = wY;
|
readRect.Top = wY;
|
||||||
readRect.Bottom = wY;
|
readRect.Bottom = wY;
|
||||||
readRect.Left = wX;
|
readRect.Left = wX;
|
||||||
readRect.Right = ConSRWidth();
|
readRect.Right = ConSRWidth();
|
||||||
|
|
||||||
/* Set cursor location based on the reported location from the message */
|
/* Set cursor location based on the reported location from the message */
|
||||||
CalculateAndSetCursor(pipe_out, wX, wY);
|
CalculateAndSetCursor(pipe_out, wX, wY, TRUE);
|
||||||
|
|
||||||
COORD coordBufSize;
|
|
||||||
coordBufSize.Y = readRect.Bottom - readRect.Top + 1;
|
coordBufSize.Y = readRect.Bottom - readRect.Top + 1;
|
||||||
coordBufSize.X = readRect.Right - readRect.Left + 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 */
|
/* The top left destination cell of the temporary buffer is row 0, col 0 */
|
||||||
COORD coordBufCoord;
|
|
||||||
coordBufCoord.X = 0;
|
coordBufCoord.X = 0;
|
||||||
coordBufCoord.Y = 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 */
|
/* Copy the block from the screen buffer to the temp. buffer */
|
||||||
if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect)) {
|
if (!ReadConsoleOutput(child_out, pBuffer, coordBufSize, coordBufCoord, &readRect))
|
||||||
DWORD dwError = GetLastError();
|
return GetLastError();
|
||||||
free(pBuffer);
|
|
||||||
return dwError;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendBuffer(pipe_out, pBuffer, pBufferSize);
|
SendBuffer(pipe_out, pBuffer, bufferSize);
|
||||||
free(pBuffer);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -951,13 +1085,16 @@ cleanup:
|
|||||||
wchar_t *
|
wchar_t *
|
||||||
w32_cmd_path()
|
w32_cmd_path()
|
||||||
{
|
{
|
||||||
ZeroMemory(cmd_exe_path, PATH_MAX);
|
errno_t r = 0;
|
||||||
if (!GetSystemDirectory(cmd_exe_path, sizeof(cmd_exe_path))) {
|
if ((r = wcsncpy_s(cmd_exe_path, _countof(cmd_exe_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1)) != 0) {
|
||||||
printf("GetSystemDirectory failed");
|
printf_s("wcsncpy_s failed with error: %d.", r);
|
||||||
exit(255);
|
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;
|
return cmd_exe_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,18 +1109,25 @@ start_with_pty(wchar_t *command)
|
|||||||
DWORD dwStatus;
|
DWORD dwStatus;
|
||||||
HANDLE hEventHook = NULL;
|
HANDLE hEventHook = NULL;
|
||||||
HMODULE hm_kernel32 = NULL, hm_user32 = 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) {
|
if(cmd == NULL) {
|
||||||
printf("ssh-shellhost is out of memory");
|
printf_s("ssh-shellhost is out of memory");
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hm_kernel32 = LoadLibraryW(L"kernel32.dll")) == NULL ||
|
GOTO_CLEANUP_ON_ERR(wcsncpy_s(kernel32_dll_path, _countof(kernel32_dll_path), system32_path, wcsnlen(system32_path, _countof(system32_path)) + 1));
|
||||||
(hm_user32 = LoadLibraryW(L"user32.dll")) == NULL ||
|
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 ||
|
(__SetCurrentConsoleFontEx = (__t_SetCurrentConsoleFontEx)GetProcAddress(hm_kernel32, "SetCurrentConsoleFontEx")) == NULL ||
|
||||||
(__UnhookWinEvent = (__t_UnhookWinEvent)GetProcAddress(hm_user32, "UnhookWinEvent")) == NULL ||
|
(__UnhookWinEvent = (__t_UnhookWinEvent)GetProcAddress(hm_user32, "UnhookWinEvent")) == NULL ||
|
||||||
(__SetWinEventHook = (__t_SetWinEventHook)GetProcAddress(hm_user32, "SetWinEventHook")) == 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1274,7 @@ start_withno_pty(wchar_t *command)
|
|||||||
DWORD rd = 0, wr = 0, i = 0;
|
DWORD rd = 0, wr = 0, i = 0;
|
||||||
|
|
||||||
if (cmd == NULL) {
|
if (cmd == NULL) {
|
||||||
printf("ssh-shellhost is out of memory");
|
printf_s("ssh-shellhost is out of memory");
|
||||||
exit(255);
|
exit(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,13 +1454,10 @@ cleanup:
|
|||||||
return child_exit_code;
|
return child_exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Shlobj.h>
|
|
||||||
#include <Sddl.h>
|
|
||||||
|
|
||||||
static void* xmalloc(size_t size) {
|
static void* xmalloc(size_t size) {
|
||||||
void* ptr;
|
void* ptr;
|
||||||
if ((ptr = malloc(size)) == NULL) {
|
if ((ptr = malloc(size)) == NULL) {
|
||||||
printf("out of memory");
|
printf_s("out of memory");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
@ -1387,7 +1528,7 @@ static void setup_session_user_vars()
|
|||||||
path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2);
|
path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2);
|
||||||
GetEnvironmentVariableW(L"PATH", path_value, required);
|
GetEnvironmentVariableW(L"PATH", path_value, required);
|
||||||
path_value[required - 1] = L';';
|
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;
|
to_apply = path_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,6 +1536,7 @@ static void setup_session_user_vars()
|
|||||||
if (to_apply)
|
if (to_apply)
|
||||||
SetEnvironmentVariableW(name, to_apply);
|
SetEnvironmentVariableW(name, to_apply);
|
||||||
}
|
}
|
||||||
|
cleanup:
|
||||||
if (reg_key)
|
if (reg_key)
|
||||||
RegCloseKey(reg_key);
|
RegCloseKey(reg_key);
|
||||||
if (data)
|
if (data)
|
||||||
@ -1414,13 +1556,14 @@ wmain(int ac, wchar_t **av)
|
|||||||
int pty_requested = 0;
|
int pty_requested = 0;
|
||||||
wchar_t *cmd = NULL, *cmd_b64 = NULL;
|
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"))) {
|
if ((ac == 1) || (ac == 2 && wcscmp(av[1], L"-nopty"))) {
|
||||||
pty_requested = 1;
|
pty_requested = 1;
|
||||||
cmd_b64 = ac == 2? av[1] : NULL;
|
cmd_b64 = ac == 2? av[1] : NULL;
|
||||||
} else if (ac <= 3 && wcscmp(av[1], L"-nopty") == 0)
|
} else if (ac <= 3 && wcscmp(av[1], L"-nopty") == 0)
|
||||||
cmd_b64 = ac == 3? av[2] : NULL;
|
cmd_b64 = ac == 3? av[2] : NULL;
|
||||||
else {
|
else {
|
||||||
printf("ssh-shellhost received unexpected input arguments");
|
printf_s("ssh-shellhost received unexpected input arguments");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,7 +1575,7 @@ wmain(int ac, wchar_t **av)
|
|||||||
if ((cmd_b64_utf8 = utf16_to_utf8(cmd_b64)) == NULL ||
|
if ((cmd_b64_utf8 = utf16_to_utf8(cmd_b64)) == NULL ||
|
||||||
/* strlen(b64) should be sufficient for decoded length */
|
/* strlen(b64) should be sufficient for decoded length */
|
||||||
(cmd_utf8 = malloc(strlen(cmd_b64_utf8))) == NULL) {
|
(cmd_utf8 = malloc(strlen(cmd_b64_utf8))) == NULL) {
|
||||||
printf("ssh-shellhost - out of memory");
|
printf_s("ssh-shellhost - out of memory");
|
||||||
return -1;
|
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 ||
|
if (b64_pton(cmd_b64_utf8, cmd_utf8, strlen(cmd_b64_utf8)) == -1 ||
|
||||||
(cmd = utf8_to_utf16(cmd_utf8)) == NULL) {
|
(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;
|
return -1;
|
||||||
}
|
}
|
||||||
free(cmd_b64_utf8);
|
free(cmd_b64_utf8);
|
||||||
free(cmd_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)
|
if (pty_requested)
|
||||||
return start_with_pty(cmd);
|
return start_with_pty(cmd);
|
||||||
else
|
else
|
||||||
|
@ -254,6 +254,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
|
|||||||
HANDLE all_events[MAXIMUM_WAIT_OBJECTS];
|
HANDLE all_events[MAXIMUM_WAIT_OBJECTS];
|
||||||
DWORD num_all_events;
|
DWORD num_all_events;
|
||||||
DWORD live_children = children.num_children - children.num_zombies;
|
DWORD live_children = children.num_children - children.num_zombies;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
num_all_events = num_events + live_children;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(all_events, children.handles, live_children * sizeof(HANDLE));
|
if ((r = memcpy_s(all_events, MAXIMUM_WAIT_OBJECTS * sizeof(HANDLE), children.handles, live_children * sizeof(HANDLE)) != 0) ||
|
||||||
memcpy(all_events + live_children, events, num_events * sizeof(HANDLE));
|
( 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);
|
debug5("wait() on %d events and %d children", num_events, live_children);
|
||||||
/* TODO - implement signal catching and handling */
|
/* TODO - implement signal catching and handling */
|
||||||
|
@ -359,6 +359,7 @@ int
|
|||||||
socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
|
socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
|
||||||
{
|
{
|
||||||
BOOL completed = FALSE;
|
BOOL completed = FALSE;
|
||||||
|
errno_t r = 0;
|
||||||
debug5("recv - io:%p state:%d", pio, pio->internal.state);
|
debug5("recv - io:%p state:%d", pio, pio->internal.state);
|
||||||
|
|
||||||
if ((buf == NULL) || (len == 0)) {
|
if ((buf == NULL) || (len == 0)) {
|
||||||
@ -393,8 +394,11 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
|
|||||||
/* if we have some buffer copy it and return #bytes copied */
|
/* if we have some buffer copy it and return #bytes copied */
|
||||||
if (pio->read_details.remaining) {
|
if (pio->read_details.remaining) {
|
||||||
int num_bytes_copied = min((int)len, 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,
|
if ((r = memcpy_s(buf, len, pio->read_details.buf + pio->read_details.completed,
|
||||||
num_bytes_copied);
|
num_bytes_copied)) != 0) {
|
||||||
|
debug4("memcpy_s failed with error: %d.", r);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
pio->read_details.remaining -= num_bytes_copied;
|
pio->read_details.remaining -= num_bytes_copied;
|
||||||
pio->read_details.completed += num_bytes_copied;
|
pio->read_details.completed += num_bytes_copied;
|
||||||
debug5("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p",
|
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) {
|
if (pio->read_details.remaining) {
|
||||||
int num_bytes_copied = min((int)len, 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.remaining -= num_bytes_copied;
|
||||||
pio->read_details.completed = num_bytes_copied;
|
pio->read_details.completed = num_bytes_copied;
|
||||||
debug4("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p",
|
debug4("recv - (2) returning %d bytes from completed IO, remaining:%d, io:%p",
|
||||||
@ -506,6 +513,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
WSABUF wsabuf;
|
WSABUF wsabuf;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
debug5("send - io:%p state:%d", pio, pio->internal.state);
|
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.buf = pio->write_details.buf;
|
||||||
|
|
||||||
wsabuf.len = min(wsabuf.len, (int)len);
|
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 */
|
/* TODO - implement flags support if needed */
|
||||||
ret = WSASend(pio->sock, &wsabuf, 1, NULL, 0, &pio->write_overlapped, &WSASendCompletionRoutine);
|
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 acceptEx_context* context;
|
||||||
struct sockaddr *local_address, *remote_address;
|
struct sockaddr *local_address, *remote_address;
|
||||||
int local_address_len, remote_address_len;
|
int local_address_len, remote_address_len;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
debug5("accept - io:%p", pio);
|
debug5("accept - io:%p", pio);
|
||||||
/* start io if not already started */
|
/* 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,
|
sizeof(SOCKADDR_STORAGE) + 16, &local_address,
|
||||||
&local_address_len, &remote_address, &remote_address_len);
|
&local_address_len, &remote_address, &remote_address_len);
|
||||||
if (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;
|
*addrlen = remote_address_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1018,7 +1033,10 @@ w32_getaddrinfo(const char *node_utf8, const char *service_utf8,
|
|||||||
ret = EAI_MEMORY;
|
ret = EAI_MEMORY;
|
||||||
goto done;
|
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;
|
(*cur)->ai_next = NULL;
|
||||||
if (((*cur_w)->ai_canonname && ((*cur)->ai_canonname = utf16_to_utf8((*cur_w)->ai_canonname)) == 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)) {
|
((*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)
|
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_w = &(*cur_w)->ai_next;
|
||||||
cur = &(*cur)->ai_next;
|
cur = &(*cur)->ai_next;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ ctrl_c_handler(_In_ DWORD dwCtrlType)
|
|||||||
int
|
int
|
||||||
wmain(int argc, wchar_t **argv)
|
wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
|
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||||
w32posix_initialize();
|
w32posix_initialize();
|
||||||
/* this exits() on failure*/
|
/* this exits() on failure*/
|
||||||
load_config();
|
load_config();
|
||||||
|
@ -119,15 +119,22 @@ load_config() {
|
|||||||
wchar_t basePath[PATH_MAX] = { 0 };
|
wchar_t basePath[PATH_MAX] = { 0 };
|
||||||
wchar_t path[PATH_MAX] = { 0 };
|
wchar_t path[PATH_MAX] = { 0 };
|
||||||
wchar_t* config_file = L"/sshd_config";
|
wchar_t* config_file = L"/sshd_config";
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
|
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
|
||||||
return -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");
|
fatal("unexpected config file path length");
|
||||||
|
|
||||||
wcsncpy_s(path, PATH_MAX, basePath, PATH_MAX);
|
if(( r = wcsncpy_s(path, PATH_MAX, basePath, wcsnlen_s(basePath, PATH_MAX))) != 0) {
|
||||||
wcsncat_s(path, PATH_MAX, L"/sshd_config", PATH_MAX - wcslen(basePath));
|
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)
|
if ((config_file_name = utf16_to_utf8(path)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -160,7 +160,8 @@ generate_user_token(wchar_t* user_cpn) {
|
|||||||
s4u_logon->ClientUpn.Length = (USHORT)wcslen(user_cpn) * 2;
|
s4u_logon->ClientUpn.Length = (USHORT)wcslen(user_cpn) * 2;
|
||||||
s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
|
s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
|
||||||
s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1);
|
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.Length = 0;
|
||||||
s4u_logon->ClientRealm.MaximumLength = 0;
|
s4u_logon->ClientRealm.MaximumLength = 0;
|
||||||
s4u_logon->ClientRealm.Buffer = 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.Length = (USHORT)wcslen(user_cpn) * 2;
|
||||||
s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length;
|
s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length;
|
||||||
s4u_logon->UserPrincipalName.Buffer = (WCHAR*)(s4u_logon + 1);
|
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.Length = 2;
|
||||||
s4u_logon->DomainName.MaximumLength = 2;
|
s4u_logon->DomainName.MaximumLength = 2;
|
||||||
s4u_logon->DomainName.Buffer = ((WCHAR*)s4u_logon->UserPrincipalName.Buffer) + wcslen(user_cpn) + 1;
|
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)
|
if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE)
|
||||||
goto done;
|
goto done;
|
||||||
@ -273,8 +277,14 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
|||||||
|
|
||||||
if ((token = generate_user_token(user_utf16)) == 0) {
|
if ((token = generate_user_token(user_utf16)) == 0) {
|
||||||
error("unable to generate token for user %ls", user_utf16);
|
error("unable to generate token for user %ls", user_utf16);
|
||||||
|
/* 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;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pubkey_allowed(key, token) != 1) {
|
if (pubkey_allowed(key, token) != 1) {
|
||||||
|
@ -143,6 +143,7 @@ process_request(struct agent_connection* con)
|
|||||||
int r = -1;
|
int r = -1;
|
||||||
struct sshbuf *request = NULL, *response = NULL;
|
struct sshbuf *request = NULL, *response = NULL;
|
||||||
u_char type;
|
u_char type;
|
||||||
|
errno_t err = 0;
|
||||||
|
|
||||||
request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes);
|
request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes);
|
||||||
response = sshbuf_new();
|
response = sshbuf_new();
|
||||||
@ -185,7 +186,10 @@ done:
|
|||||||
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
|
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
POKE_U32(con->io_buf.buf, (u_int32_t)sshbuf_len(response));
|
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;
|
con->io_buf.num_bytes = (DWORD)sshbuf_len(response) + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ static int
|
|||||||
convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **eblob, DWORD *eblen, int encrypt) {
|
convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **eblob, DWORD *eblen, int encrypt) {
|
||||||
int success = 0;
|
int success = 0;
|
||||||
DATA_BLOB in, out;
|
DATA_BLOB in, out;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (con->client_type <= ADMIN_USER)
|
if (con->client_type <= ADMIN_USER)
|
||||||
if (ImpersonateLoggedOnUser(con->client_impersonation_token) == FALSE)
|
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)
|
if (*eblob == NULL)
|
||||||
goto done;
|
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;
|
*eblen = out.cbData;
|
||||||
success = 1;
|
success = 1;
|
||||||
done:
|
done:
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#define TERM_IO_BUF_SIZE 2048
|
#define TERM_IO_BUF_SIZE 2048
|
||||||
|
|
||||||
extern int in_raw_mode;
|
extern int in_raw_mode;
|
||||||
|
BOOL isFirstTime = TRUE;
|
||||||
|
|
||||||
struct io_status {
|
struct io_status {
|
||||||
DWORD to_transfer;
|
DWORD to_transfer;
|
||||||
@ -84,16 +85,51 @@ ReadThread(_In_ LPVOID lpParameter)
|
|||||||
debug5("TermRead thread, io:%p", pio);
|
debug5("TermRead thread, io:%p", pio);
|
||||||
memset(&read_status, 0, sizeof(read_status));
|
memset(&read_status, 0, sizeof(read_status));
|
||||||
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
|
if (FILETYPE(pio) == FILE_TYPE_CHAR) {
|
||||||
|
if (in_raw_mode) {
|
||||||
while (nBytesReturned == 0) {
|
while (nBytesReturned == 0) {
|
||||||
nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio),
|
nBytesReturned = ReadConsoleForTermEmul(WINHANDLE(pio),
|
||||||
pio->read_details.buf, pio->read_details.buf_size);
|
pio->read_details.buf, pio->read_details.buf_size);
|
||||||
}
|
}
|
||||||
read_status.transferred = nBytesReturned;
|
read_status.transferred = nBytesReturned;
|
||||||
} else {
|
} 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,
|
if (!ReadFile(WINHANDLE(pio), pio->read_details.buf,
|
||||||
pio->read_details.buf_size, &read_status.transferred, NULL)) {
|
pio->read_details.buf_size, &read_status.transferred, NULL)) {
|
||||||
read_status.error = GetLastError();
|
read_status.error = GetLastError();
|
||||||
debug("ReadThread - ReadFile failed %d, io:%p", GetLastError(), pio);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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)) {
|
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 io is pending, let worker threads exit. */
|
||||||
if (pio->read_details.pending) {
|
if (pio->read_details.pending) {
|
||||||
/* For console - the read thread is blocked so terminate it. */
|
/* 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);
|
TerminateThread(pio->read_overlapped.hEvent, 0);
|
||||||
else
|
else
|
||||||
WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE);
|
WaitForSingleObject(pio->read_overlapped.hEvent, INFINITE);
|
||||||
|
@ -155,7 +155,7 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
|||||||
switch (InputRecord.Event.KeyEvent.uChar.UnicodeChar) {
|
switch (InputRecord.Event.KeyEvent.uChar.UnicodeChar) {
|
||||||
case 0xd:
|
case 0xd:
|
||||||
if (pParams->nReceiveCRLF == ENUM_LF)
|
if (pParams->nReceiveCRLF == ENUM_LF)
|
||||||
NetWriteString2(pParams->Socket, "\r", 1, 0);
|
NetWriteString2(pParams->Socket, "\n", 1, 0);
|
||||||
else
|
else
|
||||||
NetWriteString2(pParams->Socket, "\r\n", 2, 0);
|
NetWriteString2(pParams->Socket, "\r\n", 2, 0);
|
||||||
break;
|
break;
|
||||||
@ -190,6 +190,12 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
|||||||
case VK_DELETE:
|
case VK_DELETE:
|
||||||
NetWriteString2(pParams->Socket, (char *)REMOVE_KEY, 4, 0);
|
NetWriteString2(pParams->Socket, (char *)REMOVE_KEY, 4, 0);
|
||||||
break;
|
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:
|
case VK_BACK:
|
||||||
NetWriteString2(pParams->Socket, (char *)BACKSPACE_KEY, 1, 0);
|
NetWriteString2(pParams->Socket, (char *)BACKSPACE_KEY, 1, 0);
|
||||||
break;
|
break;
|
||||||
@ -202,6 +208,9 @@ ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
|||||||
case VK_ESCAPE:
|
case VK_ESCAPE:
|
||||||
NetWriteString2(pParams->Socket, (char *)ESCAPE_KEY, 1, 0);
|
NetWriteString2(pParams->Socket, (char *)ESCAPE_KEY, 1, 0);
|
||||||
break;
|
break;
|
||||||
|
case VK_OEM_2:
|
||||||
|
NetWriteString2(pParams->Socket, (char *)SHIFT_ALT_Q, 2, 0);
|
||||||
|
break;
|
||||||
case VK_SHIFT:
|
case VK_SHIFT:
|
||||||
case VK_CONTROL:
|
case VK_CONTROL:
|
||||||
case VK_CAPITAL:
|
case VK_CAPITAL:
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#define PREV_KEY "\x1b[5~"
|
#define PREV_KEY "\x1b[5~"
|
||||||
#define NEXT_KEY "\x1b[6~"
|
#define NEXT_KEY "\x1b[6~"
|
||||||
#define SHIFT_TAB_KEY "\x1b[~"
|
#define SHIFT_TAB_KEY "\x1b[~"
|
||||||
|
#define SHIFT_ALT_Q "\x1b?"
|
||||||
#define ESCAPE_KEY "\x1b"
|
#define ESCAPE_KEY "\x1b"
|
||||||
#define BACKSPACE_KEY "\b"
|
#define BACKSPACE_KEY "\b"
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#define dwBuffer 4096
|
#define dwBuffer 4096
|
||||||
|
|
||||||
extern BOOL isAnsiParsingRequired;
|
extern BOOL isAnsiParsingRequired;
|
||||||
|
extern bool gbVTAppMode;
|
||||||
|
BOOL isFirstPacket = TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Server will always be returning a sequence of ANSI control characters which the client
|
* Server will always be returning a sequence of ANSI control characters which the client
|
||||||
@ -54,11 +56,31 @@ processBuffer(HANDLE handle, char *buf, size_t len, unsigned char **respbuf, siz
|
|||||||
unsigned char *pszNewHead = NULL;
|
unsigned char *pszNewHead = NULL;
|
||||||
unsigned char *pszHead = NULL;
|
unsigned char *pszHead = NULL;
|
||||||
unsigned char *pszTail = 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)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (false == isAnsiParsingRequired) {
|
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 */
|
/* Console has the capability to parse so pass the raw buffer to console directly */
|
||||||
ConRestoreViewRect(); /* Restore the visible window, otherwise WriteConsoleW() gets messy */
|
ConRestoreViewRect(); /* Restore the visible window, otherwise WriteConsoleW() gets messy */
|
||||||
wchar_t* t = utf8_to_utf16(buf);
|
wchar_t* t = utf8_to_utf16(buf);
|
||||||
|
@ -160,10 +160,11 @@ cleanup:
|
|||||||
/*TODO: optimize to get sshd sid first and then call EqualSid*/
|
/*TODO: optimize to get sshd sid first and then call EqualSid*/
|
||||||
static BOOL
|
static BOOL
|
||||||
is_sshd_account(PSID user_sid) {
|
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;
|
DWORD name_length = UNCLEN, domain_name_length = 0, full_name_len = UNCLEN + DNLEN + 2;
|
||||||
SID_NAME_USE sid_type = SidTypeInvalid;
|
SID_NAME_USE sid_type = SidTypeInvalid;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
errno_t r = 0;
|
||||||
|
|
||||||
if (LookupAccountSidLocalW(user_sid, user_name, &name_length, full_name, &full_name_len, &sid_type) == FALSE)
|
if (LookupAccountSidLocalW(user_sid, user_name, &name_length, full_name, &full_name_len, &sid_type) == FALSE)
|
||||||
{
|
{
|
||||||
@ -171,9 +172,11 @@ is_sshd_account(PSID user_sid) {
|
|||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
domain_name_length = wcslen(full_name);
|
domain_name_length = wcsnlen(full_name, _countof(full_name));
|
||||||
full_name[domain_name_length] = L'\\';
|
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);
|
return (wcsicmp(full_name, SSHD_ACCOUNT) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,30 +51,30 @@ openlog(char *ident, unsigned int option, int facility)
|
|||||||
if (logfd != -1 || ident == NULL)
|
if (logfd != -1 || ident == NULL)
|
||||||
return;
|
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)
|
if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
/* split path root and module */
|
/* 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'/')
|
while (tail > path && *tail != L'\\' && *tail != L'/')
|
||||||
tail--;
|
tail--;
|
||||||
|
|
||||||
memcpy(log_file, path, (tail - path) * sizeof(wchar_t));
|
if (((r = wcsncat_s(log_file, PATH_MAX + 12, path, tail - path)) != 0 ) ||
|
||||||
p = log_file + (tail - path);
|
(r = wcsncat_s(log_file, PATH_MAX + 12, logs_dir, 6) != 0 )||
|
||||||
memcpy(p, logs_dir, wcslen(logs_dir) * sizeof(wchar_t));
|
(r = wcsncat_s(log_file, PATH_MAX + 12, tail + 1, wcslen(tail + 1) - 3) != 0 ) ||
|
||||||
p += 6;
|
(r = wcsncat_s(log_file, PATH_MAX + 12, L"log", 3) != 0 ))
|
||||||
memcpy(p, tail + 1, (wcslen(tail + 1) - 3) * sizeof(wchar_t));
|
return;
|
||||||
p += wcslen(tail + 1) - 3;
|
|
||||||
memcpy(p, L"log\0", 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
errno_t err = _wsopen_s(&logfd, log_file, O_WRONLY | O_CREAT | O_APPEND, SH_DENYNO, S_IREAD | S_IWRITE);
|
errno_t err = _wsopen_s(&logfd, log_file, O_WRONLY | O_CREAT | O_APPEND, SH_DENYNO, S_IREAD | S_IWRITE);
|
||||||
|
|
||||||
if (logfd != -1)
|
if (logfd != -1)
|
||||||
@ -98,10 +98,13 @@ syslog(int priority, const char *format, const char *formatBuffer)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
GetLocalTime(&st);
|
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,
|
GetCurrentProcessId(), st.wHour, st.wMinute, st.wSecond,
|
||||||
st.wMilliseconds, formatBuffer);
|
st.wMilliseconds, formatBuffer);
|
||||||
msgbufTimestamp[sizeof(msgbufTimestamp) - 1] = '\0';
|
if (r == -1) {
|
||||||
if (r > 0 && r < sizeof(msgbufTimestamp))
|
_write(logfd, "_snprintf_s failed.", 30);
|
||||||
_write(logfd, msgbufTimestamp, (unsigned int)strlen(msgbufTimestamp));
|
return;
|
||||||
|
}
|
||||||
|
msgbufTimestamp[strnlen(msgbufTimestamp, MSGBUFSIZ)] = '\0';
|
||||||
|
_write(logfd, msgbufTimestamp, (unsigned int)strnlen(msgbufTimestamp, MSGBUFSIZ));
|
||||||
}
|
}
|
@ -55,8 +55,7 @@ snmprintf(char *buf, size_t len, int *written, const char *fmt, ...)
|
|||||||
int ret;
|
int ret;
|
||||||
va_list valist;
|
va_list valist;
|
||||||
va_start(valist, fmt);
|
va_start(valist, fmt);
|
||||||
if ((ret = vsnprintf(buf, len, fmt, valist)) >= len)
|
ret = vsnprintf_s(buf, len, _TRUNCATE, fmt, valist);
|
||||||
ret = len;
|
|
||||||
va_end(valist);
|
va_end(valist);
|
||||||
if (written != NULL && ret != -1)
|
if (written != NULL && ret != -1)
|
||||||
*written = ret;
|
*written = ret;
|
||||||
|
@ -84,7 +84,9 @@ openrootdir(const char *name)
|
|||||||
}
|
}
|
||||||
memset(pdir, 0, sizeof(DIR));
|
memset(pdir, 0, sizeof(DIR));
|
||||||
pdir->hFile = 0;
|
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;
|
pdir->first = 1;
|
||||||
|
|
||||||
return pdir;
|
return pdir;
|
||||||
@ -138,7 +140,10 @@ opendir(const char *name)
|
|||||||
|
|
||||||
memset(pdir, 0, sizeof(DIR));
|
memset(pdir, 0, sizeof(DIR));
|
||||||
pdir->hFile = hFile;
|
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;
|
pdir->first = 1;
|
||||||
|
|
||||||
return pdir;
|
return pdir;
|
||||||
@ -236,7 +241,9 @@ readdir(void *avp)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (dirp->first) {
|
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;
|
dirp->first = 0;
|
||||||
} else if (_wfindnext(dirp->hFile, &c_file) != 0)
|
} else if (_wfindnext(dirp->hFile, &c_file) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -249,7 +256,9 @@ readdir(void *avp)
|
|||||||
return NULL;
|
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);
|
free(tmp);
|
||||||
|
|
||||||
pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */
|
pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */
|
||||||
|
@ -4,25 +4,15 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include "..\..\..\sshpty.h"
|
#include "..\..\..\sshpty.h"
|
||||||
|
|
||||||
static struct termios _saved_tio;
|
static struct termios _saved_tio;
|
||||||
static int _in_raw_mode = 0;
|
static int _in_raw_mode = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TTY raw mode routines for Windows
|
* TTY raw mode routines for Windows
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
|
|
||||||
int ConExitRawMode(void);
|
|
||||||
|
|
||||||
struct termios term_settings;
|
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 *
|
struct termios *
|
||||||
get_saved_tio(void) {
|
get_saved_tio(void) {
|
||||||
memset(&term_settings, 0, sizeof(term_settings));
|
memset(&term_settings, 0, sizeof(term_settings));
|
||||||
@ -36,5 +26,5 @@ leave_raw_mode(int quiet) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
enter_raw_mode(int quiet) {
|
enter_raw_mode(int quiet) {
|
||||||
ConEnterRawMode(STD_OUTPUT_HANDLE, TRUE);
|
ConEnterRawMode();
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ int
|
|||||||
wmain(int argc, wchar_t **wargv) {
|
wmain(int argc, wchar_t **wargv) {
|
||||||
char** argv = NULL;
|
char** argv = NULL;
|
||||||
int i, r;
|
int i, r;
|
||||||
|
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if ((argv = malloc(argc * sizeof(char*))) == NULL)
|
if ((argv = malloc(argc * sizeof(char*))) == NULL)
|
||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
@ -53,6 +53,9 @@ wmain(int argc, wchar_t **wargv) {
|
|||||||
if (getenv("SSH_AUTH_SOCK") == NULL)
|
if (getenv("SSH_AUTH_SOCK") == NULL)
|
||||||
_putenv("SSH_AUTH_SOCK=\\\\.\\pipe\\openssh-ssh-agent");
|
_putenv("SSH_AUTH_SOCK=\\\\.\\pipe\\openssh-ssh-agent");
|
||||||
|
|
||||||
|
if (getenv("TERM") == NULL)
|
||||||
|
_putenv("TERM=xterm-256color");
|
||||||
|
|
||||||
w32posix_initialize();
|
w32posix_initialize();
|
||||||
|
|
||||||
r = main(argc, argv);
|
r = main(argc, argv);
|
||||||
|
@ -100,6 +100,7 @@ static VOID WINAPI service_handler(DWORD dwControl)
|
|||||||
int sshd_main(int argc, wchar_t **wargv) {
|
int sshd_main(int argc, wchar_t **wargv) {
|
||||||
char** argv = NULL;
|
char** argv = NULL;
|
||||||
int i, r;
|
int i, r;
|
||||||
|
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if ((argv = malloc(argc * sizeof(char*))) == NULL)
|
if ((argv = malloc(argc * sizeof(char*))) == NULL)
|
||||||
|
@ -18,7 +18,15 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$keypassphrase = "testpassword"
|
$keypassphrase = "testpassword"
|
||||||
|
$WindowsInBox = $OpenSSHTestInfo["WindowsInBox"]
|
||||||
|
if($WindowsInBox)
|
||||||
|
{
|
||||||
|
$keytypes = @("ed25519")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$keytypes = @("rsa","dsa","ecdsa","ed25519")
|
$keytypes = @("rsa","dsa","ecdsa","ed25519")
|
||||||
|
}
|
||||||
|
|
||||||
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
||||||
|
|
||||||
@ -118,7 +126,14 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
|
|||||||
{
|
{
|
||||||
$keyPath = Join-Path $testDir "id_$type"
|
$keyPath = Join-Path $testDir "id_$type"
|
||||||
remove-item $keyPath -ErrorAction SilentlyContinue
|
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
|
ssh-keygen -t $type -P $keypassphrase -f $keyPath
|
||||||
|
}
|
||||||
ValidateKeyFile -FilePath $keyPath
|
ValidateKeyFile -FilePath $keyPath
|
||||||
ValidateKeyFile -FilePath "$keyPath.pub"
|
ValidateKeyFile -FilePath "$keyPath.pub"
|
||||||
}
|
}
|
||||||
@ -224,7 +239,15 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
|
|||||||
$keyFileName = "sshadd_userPermTestkey_ed25519"
|
$keyFileName = "sshadd_userPermTestkey_ed25519"
|
||||||
$keyFilePath = Join-Path $testDir $keyFileName
|
$keyFilePath = Join-Path $testDir $keyFileName
|
||||||
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
|
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
|
||||||
|
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
|
ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase
|
||||||
|
}
|
||||||
|
|
||||||
#set up SSH_ASKPASS
|
#set up SSH_ASKPASS
|
||||||
Add-PasswordSetting -Pass $keypassphrase
|
Add-PasswordSetting -Pass $keypassphrase
|
||||||
$tI=1
|
$tI=1
|
||||||
@ -341,23 +364,23 @@ Describe "E2E scenarios for ssh key management" -Tags "CI" {
|
|||||||
}
|
}
|
||||||
AfterAll{$tC++}
|
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"
|
cmd /c "ssh-keyscan -p $port 127.0.0.1 2>&1 > $outputFile"
|
||||||
$outputFile | Should Contain '.*ssh-rsa.*'
|
$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"
|
cmd /c "ssh-keyscan -p $port 127.0.0.1 2>&1 > $outputFile"
|
||||||
$outputFile | Should Contain '.*ssh-rsa.*'
|
$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"
|
Set-Content -Path tmp.txt -Value "127.0.0.1"
|
||||||
cmd /c "ssh-keyscan -p $port -f tmp.txt 2>&1 > $outputFile"
|
cmd /c "ssh-keyscan -p $port -f tmp.txt 2>&1 > $outputFile"
|
||||||
$outputFile | Should Contain '.*ssh-rsa.*'
|
$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"
|
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"
|
cmd /c "ssh-keyscan -p $port -f tmp.txt -t rsa,dsa 2>&1 > $outputFile"
|
||||||
$outputFile | Should Contain '.*ssh-rsa.*'
|
$outputFile | Should Contain '.*ssh-rsa.*'
|
||||||
|
@ -50,7 +50,14 @@ Describe "Tests for user Key file permission" -Tags "CI" {
|
|||||||
$keyFileName = "sshtest_userPermTestkey_ed25519"
|
$keyFileName = "sshtest_userPermTestkey_ed25519"
|
||||||
$keyFilePath = Join-Path $testDir $keyFileName
|
$keyFilePath = Join-Path $testDir $keyFileName
|
||||||
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
|
Remove-Item -path "$keyFilePath*" -Force -ErrorAction SilentlyContinue
|
||||||
|
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
|
ssh-keygen.exe -t ed25519 -f $keyFilePath -P $keypassphrase
|
||||||
|
}
|
||||||
|
|
||||||
$pubKeyUserProfilePath = Join-Path $pubKeyUserProfile .ssh
|
$pubKeyUserProfilePath = Join-Path $pubKeyUserProfile .ssh
|
||||||
if(-not (Test-Path $pubKeyUserProfilePath -PathType Container)) {
|
if(-not (Test-Path $pubKeyUserProfilePath -PathType Container)) {
|
||||||
|
@ -88,8 +88,8 @@ void file_simple_fileio()
|
|||||||
int f;
|
int f;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
{
|
{
|
||||||
f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC);
|
//f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
ASSERT_INT_EQ(f, -1);
|
//ASSERT_INT_EQ(f, -1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
f = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
1
sftp.c
1
sftp.c
@ -2518,6 +2518,7 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
userhost = xstrdup(argv[optind]);
|
userhost = xstrdup(argv[optind]);
|
||||||
|
if(argc > optind + 1)
|
||||||
file2 = argv[optind+1];
|
file2 = argv[optind+1];
|
||||||
|
|
||||||
if ((host = strrchr(userhost, '@')) == NULL)
|
if ((host = strrchr(userhost, '@')) == NULL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user