Source snapshot from Powershell/openssh-portable:latestw_all

This commit is contained in:
Manoj Ampalam 2017-04-04 12:35:11 -07:00
parent f0fd5e0099
commit 8c43479844
100 changed files with 2907 additions and 1203 deletions

View File

@ -236,6 +236,8 @@ clean: regressclean
rm -f regress/unittests/sshkey/test_sshkey
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/conversion/*.o
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/kex/*.o
@ -262,6 +264,8 @@ distclean: regressclean
rm -f regress/unittests/sshkey/test_sshkey
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/conversion/*.o
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/kex/*.o
@ -426,6 +430,8 @@ regress-prep:
mkdir -p `pwd`/regress/unittests/sshkey
[ -d `pwd`/regress/unittests/bitmap ] || \
mkdir -p `pwd`/regress/unittests/bitmap
[ -d `pwd`/regress/unittests/conversion ] || \
mkdir -p `pwd`/regress/unittests/conversion
[ -d `pwd`/regress/unittests/hostkeys ] || \
mkdir -p `pwd`/regress/unittests/hostkeys
[ -d `pwd`/regress/unittests/kex ] || \
@ -503,6 +509,16 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
UNITTESTS_TEST_CONVERSION_OBJS=\
regress/unittests/conversion/tests.o
regress/unittests/conversion/test_conversion$(EXEEXT): \
${UNITTESTS_TEST_CONVERSION_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_CONVERSION_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS)
UNITTESTS_TEST_KEX_OBJS=\
regress/unittests/kex/tests.o \
regress/unittests/kex/test_kex.o
@ -558,13 +574,14 @@ regress-binaries: regress/modpipe$(EXEEXT) \
regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
regress/unittests/sshkey/test_sshkey$(EXEEXT) \
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
regress/unittests/conversion/test_conversion$(EXEEXT) \
regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \
regress/unittests/kex/test_kex$(EXEEXT) \
regress/unittests/match/test_match$(EXEEXT) \
regress/unittests/utf8/test_utf8$(EXEEXT) \
regress/misc/kexfuzz/kexfuzz$(EXEEXT)
tests interop-tests t-exec: regress-prep regress-binaries $(TARGETS)
tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS)
BUILDDIR=`pwd`; \
TEST_SSH_SCP="$${BUILDDIR}/scp"; \
TEST_SSH_SSH="$${BUILDDIR}/ssh"; \

2
README
View File

@ -1,4 +1,4 @@
See https://www.openssh.com/releasenotes.html#7.4p1 for the release notes.
See https://www.openssh.com/releasenotes.html#7.5p1 for the release notes.
Please read https://www.openssh.com/report.html for bug reporting
instructions and note that we do not use Github for bug reporting or

View File

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

View File

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

4
auth.c
View File

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

View File

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

View File

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

View File

@ -1486,6 +1486,7 @@ AC_ARG_WITH(ldns,
else
LIBS="$LIBS `$LDNSCONFIG --libs`"
CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
ldns=yes
fi
elif test "x$withval" != "xno" ; then
CPPFLAGS="$CPPFLAGS -I${withval}/include"
@ -1717,6 +1718,7 @@ AC_CHECK_FUNCS([ \
inet_ntoa \
inet_ntop \
innetgr \
llabs \
login_getcapbool \
md5_crypt \
memmove \
@ -2531,8 +2533,8 @@ if test "x$openssl" = "xyes" ; then
ssl_library_ver=`cat conftest.ssllibver`
# Check version is supported.
case "$ssl_library_ver" in
0090[[0-7]]*|009080[[0-5]]*)
AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")])
10000*|0*)
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
*) ;;
esac

View File

@ -63,7 +63,6 @@ sshd_config_configured=no
port_number=22
service_name=sshd
strictmodes=yes
privsep_used=yes
cygwin_value=""
user_account=
password_value=
@ -140,33 +139,21 @@ sshd_strictmodes() {
# ======================================================================
# Routine: sshd_privsep
# MODIFIES: privsep_used
# Try to create ssshd user account
# ======================================================================
sshd_privsep() {
local ret=0
if [ "${sshd_config_configured}" != "yes" ]
then
echo
csih_inform "Privilege separation is set to 'sandbox' by default since"
csih_inform "OpenSSH 6.1. This is unsupported by Cygwin and has to be set"
csih_inform "to 'yes' or 'no'."
csih_inform "However, using privilege separation requires a non-privileged account"
csih_inform "called 'sshd'."
csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
if csih_request "Should privilege separation be used?"
then
privsep_used=yes
if ! csih_create_unprivileged_user sshd
then
csih_error_recoverable "Couldn't create user 'sshd'!"
csih_error_recoverable "Privilege separation set to 'no' again!"
csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!"
csih_error_recoverable "Could not create user 'sshd'!"
csih_error_recoverable "You will not be able to run an sshd service"
csih_error_recoverable "under a privileged account successfully."
csih_error_recoverable "Make sure to create a non-privileged user 'sshd'"
csih_error_recoverable "manually before trying to run the service!"
let ++ret
privsep_used=no
fi
else
privsep_used=no
fi
fi
return $ret
@ -202,18 +189,6 @@ sshd_config_tweak() {
let ++ret
fi
fi
if [ "${sshd_config_configured}" != "yes" ]
then
/usr/bin/sed -i -e "
s/^#\?UsePrivilegeSeparation .*/UsePrivilegeSeparation ${privsep_used}/" \
${SYSCONFDIR}/sshd_config
if [ $? -ne 0 ]
then
csih_warning "Setting privilege separation failed!"
csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
let ++ret
fi
fi
return $ret
} # --- End of sshd_config_tweak --- #
@ -693,7 +668,7 @@ then
fi
fi
# handle sshd_config (and privsep)
# handle sshd_config
csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
then

View File

@ -1,4 +1,4 @@
%define ver 7.4p1
%define ver 7.5p1
%define rel 1
# OpenSSH privilege separation requires a user & group ID

View File

@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
Version: 7.4p1
Version: 7.5p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz

View File

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

View File

@ -0,0 +1,592 @@
Set-StrictMode -Version Latest
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -force -DisableNameChecking
[string] $script:platform = $env:PROCESSOR_ARCHITECTURE
[string] $script:vcPath = $null
[System.IO.DirectoryInfo] $script:OpenSSHRoot = $null
[System.IO.DirectoryInfo] $script:gitRoot = $null
[bool] $script:Verbose = $false
[string] $script:BuildLogFile = $null
<#
Called by Write-BuildMsg to write to the build log, if it exists.
#>
function Write-Log
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message
)
# write it to the log file, if present.
if (-not ([string]::IsNullOrEmpty($script:BuildLogFile)))
{
Add-Content -Path $script:BuildLogFile -Value $Message
}
}
<#
.Synopsis
Writes a build message.
.Parameter Message
The message to write.
.Parameter AsInfo
Writes a user message using Write-Information.
.Parameter AsVerbose
Writes a message using Write-Verbose and to the build log if -Verbose was specified to Start-DscBuild.
.Parameter AsWarning
Writes a message using Write-Warning and to the build log.
.Parameter AsError
Writes a message using Write-Error and to the build log.
.Parameter Silent
Writes the message only to the log.
.Parameter ErrorAction
Determines if the script is terminated when errors are written.
This parameter is ignored when -Silent is specified.
.Example
Write-BuildMsg -AsInfo 'Starting the build'
Writes an informational message to the log and to the user
.Example
Write-BuildMsg -AsError 'Terminating build' -Silent
Writes an error message only to the log
.Example
Write-BuildMsg -AsError 'Terminating build' -ErrorAction Stop
Writes an error message to the log and the user and terminates the build.
.Example
Write-BuildMsg -AsInfo 'Nuget is already installed' -Silent:(-not $script:Verbose)
Writes an informational message to the log. If -Verbose was specified, also
writes to message to the user.
#>
function Write-BuildMsg
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message,
[Parameter(ParameterSetName='Info')]
[switch] $AsInfo,
[Parameter(ParameterSetName='Verbose')]
[switch] $AsVerbose,
[Parameter(ParameterSetName='Warning')]
[switch] $AsWarning,
[Parameter(ParameterSetName='Error')]
[switch] $AsError,
[switch] $Silent
)
if ($AsVerbose)
{
if ($script:Verbose)
{
Write-Log -Message "VERBOSE: $message"
if (-not $Silent)
{
Write-Verbose -Message $message -Verbose
}
}
return
}
if ($AsInfo)
{
Write-Log -Message "INFO: $message"
if (-not $Silent)
{
Write-Information -MessageData $message -InformationAction Continue
}
return
}
if ($AsWarning)
{
Write-Log -Message "WARNING: $message"
if (-not $Silent)
{
Write-Warning -Message $message
}
return
}
if ($AsError)
{
Write-Log -Message "ERROR: $message"
if (-not $Silent)
{
Write-Error -Message $message
}
return
}
# if we reached here, no output type switch was specified.
Write-BuildMsg -AsError -ErrorAction Stop -Message 'Write-BuildMsg was called without selecting an output type.'
}
<#
.Synopsis
Verifies all tools and dependencies required for building Open SSH are installed on the machine.
#>
function Start-OpenSSHBootstrap
{
[bool] $silent = -not $script:Verbose
Set-StrictMode -Version Latest
Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
# Install chocolatey
$chocolateyPath = "$env:AllUsersProfile\chocolatey\bin"
if(Get-Command "choco" -ErrorAction SilentlyContinue)
{
Write-BuildMsg -AsVerbose -Message "Chocolatey is already installed. Skipping installation." -Silent:$silent
}
else
{
Write-BuildMsg -AsInfo -Message "Chocolatey not present. Installing chocolatey." -Silent:$silent
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:BuildLogFile
}
# Add git\cmd to the path
$gitCmdPath = "$env:ProgramFiles\git\cmd"
if (-not ($machinePath.ToLower().Contains($gitCmdPath.ToLower())))
{
Write-BuildMsg -AsVerbose -Message "Adding $gitCmdPath to Path environment variable" -Silent:$silent
$newMachineEnvironmentPath = "$gitCmdPath;$newMachineEnvironmentPath"
}
else
{
Write-BuildMsg -AsVerbose -Message "$gitCmdPath already present in Path environment variable" -Silent:$silent
}
$nativeMSBuildPath = "${env:ProgramFiles(x86)}\MSBuild\14.0\bin"
if($script:platform -ieq "AMD64")
{
$nativeMSBuildPath += "\amd64"
}
if (-not ($machinePath.ToLower().Contains($nativeMSBuildPath.ToLower())))
{
Write-BuildMsg -AsVerbose -Message "Adding $nativeMSBuildPath to Path environment variable" -Silent:$silent
$newMachineEnvironmentPath += ";$nativeMSBuildPath"
$env:Path += ";$nativeMSBuildPath"
}
else
{
Write-BuildMsg -AsVerbose -Message "$nativeMSBuildPath already present in Path environment variable" -Silent:$silent
}
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
# install nasm
$packageName = "nasm"
$nasmPath = "${env:ProgramFiles(x86)}\NASM"
if (-not (Test-Path -Path $nasmPath -PathType Container))
{
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName." -Silent:$silent
choco install $packageName -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
}
else
{
Write-BuildMsg -AsVerbose -Message "$packageName present. Skipping installation." -Silent:$silent
}
# Install Visual Studio 2015 Community
$packageName = "VisualStudio2015Community"
$VSPackageInstalled = Get-ItemProperty "HKLM:\software\WOW6432Node\Microsoft\VisualStudio\14.0\setup\vs" -ErrorAction SilentlyContinue
if ($null -eq $VSPackageInstalled)
{
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName."
$adminFilePath = "$script:OpenSSHRoot\contrib\win32\openssh\VSWithBuildTools.xml"
choco install $packageName -packageParameters "--AdminFile $adminFilePath" -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
}
else
{
Write-BuildMsg -AsVerbose -Message "$packageName present. Skipping installation." -Silent:$silent
}
# Install Windows 8.1 SDK
$packageName = "windows-sdk-8.1"
$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
if (-not (Test-Path -Path $sdkPath))
{
Write-BuildMsg -AsInfo -Message "Windows 8.1 SDK not present. Installing $packageName."
choco install $packageName -y --limitoutput --force 2>&1 >> $script:BuildLogFile
}
else
{
Write-BuildMsg -AsInfo -Message "$packageName present. Skipping installation." -Silent:$silent
}
# Require restarting PowerShell session
if ($null -eq $VSPackageInstalled)
{
Write-Host "To apply changes, please close this PowerShell window, open a new one and call Start-SSHBuild or Start-DscBootstrap again." -ForegroundColor Black -BackgroundColor Yellow
Write-Host -NoNewLine 'Press any key to close this PowerShell window...' -ForegroundColor Black -BackgroundColor Yellow
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
exit
}
# Ensure the VS C toolset is installed
if ($null -eq $env:VS140COMNTOOLS)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Cannot find Visual Studio 2015 Environment variable VS140COMNTOOlS"
}
$item = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc')
$script:vcPath = $item.FullName
Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" -Silent:$silent
if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at$script:vcPath, which means some required develop kits are missing on the machine."
}
}
function Clone-Win32OpenSSH
{
[bool] $silent = -not $script:Verbose
$win32OpenSSHPath = join-path $script:gitRoot "Win32-OpenSSH"
if (-not (Test-Path -Path $win32OpenSSHPath -PathType Container))
{
Write-BuildMsg -AsInfo -Message "clone repo Win32-OpenSSH" -Silent:$silent
Push-Location $gitRoot
git clone -q --recursive https://github.com/PowerShell/Win32-OpenSSH.git $win32OpenSSHPath
Pop-Location
}
Write-BuildMsg -AsInfo -Message "pull latest from repo Win32-OpenSSH" -Silent:$silent
Push-Location $win32OpenSSHPath
git fetch -q origin
git checkout -qf L1-Prod
Pop-Location
}
function Copy-OpenSSLSDK
{
[bool] $silent = -not $script:Verbose
$sourcePath = Join-Path $script:gitRoot "Win32-OpenSSH\contrib\win32\openssh\OpenSSLSDK"
Write-BuildMsg -AsInfo -Message "copying $sourcePath" -Silent:$silent
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
if($e -ne $null)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Copy OpenSSL from $sourcePath failed "
}
}
function Package-OpenSSH
{
[CmdletBinding(SupportsShouldProcess=$false)]
param
(
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Release"
)
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
$repositoryRoot = Get-Item -Path $repositoryRoot.FullName
$folderName = $NativeHostArch
if($NativeHostArch -ieq 'x86')
{
$folderName = "Win32"
}
$buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration)
$payload = "sshd.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe"
$payload += "sftp-server.exe", "scp.exe", "ssh-lsa.dll", "ssh-shellhost.exe", "ssh-keygen.exe"
$payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1"
$payload += "install-sshlsa.ps1", "uninstall-sshlsa.ps1"
$packageName = "OpenSSH-Win64"
if ($NativeHostArch -eq 'x86') {
$packageName = "OpenSSH-Win32"
}
$packageDir = Join-Path $buildDir $packageName
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
New-Item $packageDir -Type Directory | Out-Null
$symbolsDir = Join-Path $buildDir ($packageName + '_Symbols')
Remove-Item $symbolsDir -Recurse -Force -ErrorAction SilentlyContinue
New-Item $symbolsDir -Type Directory | Out-Null
foreach ($file in $payload) {
if ((-not(Test-Path (Join-Path $buildDir $file)))) {
Throw "Cannot find $file under $buildDir. Did you run Build-OpenSSH?"
}
Copy-Item (Join-Path $buildDir $file) $packageDir
if ($file.EndsWith(".exe")) {
$pdb = $file.Replace(".exe", ".pdb")
Copy-Item (Join-Path $buildDir $pdb) $symbolsDir
}
if ($file.EndsWith(".dll")) {
$pdb = $file.Replace(".dll", ".pdb")
Copy-Item (Join-Path $buildDir $pdb) $symbolsDir
}
}
Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
Compress-Archive -Path $packageDir -DestinationPath ($packageDir + '.zip')
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item ($symbolsDir + '.zip') -Force -ErrorAction SilentlyContinue
Compress-Archive -Path $symbolsDir -DestinationPath ($symbolsDir + '.zip')
Remove-Item $symbolsDir -Recurse -Force -ErrorAction SilentlyContinue
}
function Build-OpenSSH
{
[CmdletBinding(SupportsShouldProcess=$false)]
param
(
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Release"
)
Set-StrictMode -Version Latest
$script:BuildLogFile = $null
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
# Get openssh-portable root
$script:OpenSSHRoot = Get-Item -Path $repositoryRoot.FullName
$script:gitRoot = split-path $script:OpenSSHRoot
if($PSBoundParameters.ContainsKey("Verbose"))
{
$script:Verbose = ($PSBoundParameters['Verbose']).IsPresent
}
[bool] $silent = -not $script:Verbose
$script:BuildLogFile = Get-BuildLogFile -root $repositoryRoot.FullName -Configuration $Configuration -NativeHostArch $NativeHostArch
if (Test-Path -Path $script:BuildLogFile)
{
Remove-Item -Path $script:BuildLogFile -force
}
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)"
Start-OpenSSHBootstrap
Clone-Win32OpenSSH
Copy-OpenSSLSDK
$msbuildCmd = "msbuild.exe"
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
$cmdMsg = @("${solutionFile}", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/m", "/noconlog", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
& $msbuildCmd $cmdMsg
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Build failed for OpenSSH.`nExitCode: $error."
}
Write-BuildMsg -AsInfo -Message "SSH build passed." -Silent:$silent
}
function Get-BuildLogFile
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
[System.IO.DirectoryInfo] $root,
[ValidateSet('x86', 'x64')]
[string]$NativeHostArch = "x64",
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "Release"
)
return Join-Path -Path $root -ChildPath "contrib\win32\openssh\OpenSSH$($Configuration)$($NativeHostArch).log"
}
function Get-SolutionFile
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNull()]
[System.IO.DirectoryInfo] $root
)
return Join-Path -Path $root -ChildPath "contrib\win32\openssh\Win32-OpenSSH.sln"
}
<#
.Synopsis
Deploy all required files to build a package and create zip file.
#>
function Deploy-Win32OpenSSHBinaries
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if (-not (Test-Path -Path $OpenSSHDir -PathType Container))
{
$null = New-Item -Path $OpenSSHDir -ItemType Directory -Force -ErrorAction Stop
}
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -ieq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.exe,*.dll -Exclude *unittest*.* -Force -ErrorAction Stop
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "contrib\win32\openssh"
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHDir -Include *.ps1,sshd_config -Exclude AnalyzeCodeDiff.ps1 -Force -ErrorAction Stop
}
<#
.Synopsis
Deploy all required files to a location and install the binaries
#>
function Install-OpenSSH
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release', '')]
[string]$Configuration = "",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = "",
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
Deploy-Win32OpenSSHBinaries @PSBoundParameters
Push-Location $OpenSSHDir
& ( "$OpenSSHDir\install-sshd.ps1")
.\ssh-keygen.exe -A
& ( "$OpenSSHDir\install-sshlsa.ps1")
#machine will be reboot after Install-openssh anyway
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if (-not ($machinePath.ToLower().Contains($OpenSSHDir.ToLower())))
{
$newMachineEnvironmentPath = "$OpenSSHDir;$newMachineEnvironmentPath"
$env:Path = "$OpenSSHDir;$env:Path"
}
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
Start-Service sshd
Pop-Location
Write-Log -Message "OpenSSH installed!"
}
<#
.Synopsis
uninstalled sshd and sshla
#>
function UnInstall-OpenSSH
{
[CmdletBinding()]
param
(
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
Push-Location $OpenSSHDir
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
&( "$OpenSSHDir\uninstall-sshd.ps1")
&( "$OpenSSHDir\uninstall-sshlsa.ps1")
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}
# Update machine environment path
# machine will be reboot after Uninstall-OpenSSH
if ($newMachineEnvironmentPath -ne $machinePath)
{
[Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE')
}
Pop-Location
}
Export-ModuleMember -Function Build-OpenSSH, Get-BuildLogFile, Install-OpenSSH, UnInstall-OpenSSH, Package-OpenSSH

View File

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

View File

@ -0,0 +1,445 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -DisableNameChecking
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
# test environment parameters initialized with defaults
$E2ETestResultsFileName = "E2ETestResults.xml"
$UnitTestResultsFileName = "UnitTestResults.txt"
$TestSetupLogFileName = "TestSetupLog.txt"
$SSOUser = "sshtest_ssouser"
$PubKeyUser = "sshtest_pubkeyuser"
$PasswdUser = "sshtest_passwduser"
$OpenSSHTestAccountsPassword = "P@ssw0rd_1"
$OpenSSHTestAccounts = $Script:SSOUser, $Script:PubKeyUser, $Script:PasswdUser
$Script:TestDataPath = "$env:SystemDrive\OpenSSHTests"
$Script:E2ETestResultsFile = Join-Path $TestDataPath $E2ETestResultsFileName
$Script:UnitTestResultsFile = Join-Path $TestDataPath $UnitTestResultsFileName
$Script:TestSetupLogFile = Join-Path $TestDataPath $TestSetupLogFileName
$Script:E2ETestDirectory = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
<#
.Synopsis
Setup-OpenSSHTestEnvironment
TODO - split these steps into client and server side
#>
function Setup-OpenSSHTestEnvironment
{
[CmdletBinding()]
param
(
[switch] $Quiet,
[string] $OpenSSHBinPath,
[string] $TestDataPath = "$env:SystemDrive\OpenSSHTests",
[Boolean] $DebugMode = $false
)
if($Global:OpenSSHTestInfo -ne $null)
{
$Global:OpenSSHTestInfo.Clear()
$Global:OpenSSHTestInfo = $null
}
$Script:TestDataPath = $TestDataPath;
$Script:E2ETestResultsFile = Join-Path $TestDataPath "E2ETestResults.xml"
$Script:UnitTestResultsFile = Join-Path $TestDataPath "UnitTestResults.txt"
$Script:TestSetupLogFile = Join-Path $TestDataPath "TestSetupLog.txt"
$Script:UnitTestDirectory = Get-UnitTestDirectory
$Global:OpenSSHTestInfo = @{
"Target"= "localhost"; # test listener name
"Port"= "47002"; # test listener port
"SSOUser"= $SSOUser; # test user with single sign on capability
"PubKeyUser"= $PubKeyUser; # test user to be used with explicit key for key auth
"PasswdUser"= $PasswdUser; # common password for all test accounts
"TestAccountPW"= $OpenSSHTestAccountsPassword; # common password for all test accounts
"TestDataPath" = $TestDataPath; # openssh tests path
"TestSetupLogFile" = $Script:TestSetupLogFile; # openssh test setup log file
"E2ETestResultsFile" = $Script:E2ETestResultsFile; # openssh E2E test results file
"UnitTestResultsFile" = $Script:UnitTestResultsFile; # openssh unittest test results file
"E2ETestDirectory" = $Script:E2ETestDirectory # the directory of E2E tests
"UnitTestDirectory" = $Script:UnitTestDirectory # the directory of unit tests
"DebugMode" = $DebugMode # run openssh E2E in debug mode
}
#if user does not set path, pick it up
if([string]::IsNullOrEmpty($OpenSSHBinPath))
{
$sshcmd = get-command ssh.exe -ErrorAction Ignore
if($sshcmd -eq $null)
{
Throw "Cannot find ssh.exe. Please specify -OpenSSHBinPath to the OpenSSH installed location."
}
elseif($Quiet)
{
$dirToCheck = split-path $sshcmd.Path
$script:OpenSSHBinPath = $dirToCheck
}
else
{
$dirToCheck = split-path $sshcmd.Path
$message = "Do you want to test openssh installed at $($dirToCheck)? [Yes] Y; [No] N (default is `"Y`")"
$response = Read-Host -Prompt $message
if( ($response -eq "") -or ($response -ieq "Y") -or ($response -ieq "Yes") )
{
$script:OpenSSHBinPath = $dirToCheck
}
elseif( ($response -ieq "N") -or ($response -ieq "No") )
{
Write-Host "User decided not to pick up ssh.exe from $dirToCheck. Please specify -OpenSSHBinPath to the OpenSSH installed location."
return
}
else
{
Throw "User entered invalid option ($response). Please specify -OpenSSHBinPath to the OpenSSH installed location"
}
}
}
else
{
if (-not (Test-Path (Join-Path $OpenSSHBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $OpenSSHBinPath. Please specify -OpenSSHBinPathto the OpenSSH installed location"
}
else
{
$script:OpenSSHBinPath = $OpenSSHBinPath
}
}
$Global:OpenSSHTestInfo.Add("OpenSSHBinPath", $script:OpenSSHBinPath)
$warning = @"
WARNING: Following changes will be made to OpenSSH configuration
- sshd_config will be backed up as sshd_config.ori
- will be replaced with a test sshd_config
- $HOME\.ssh\known_hosts will be backed up as known_hosts.ori
- will be replaced with a test known_hosts
- sshd test listener will be on port 47002
- $HOME\.ssh\known_hosts will be modified with test host key entry
- test accounts - ssouser, pubkeyuser, and passwduser will be added
- Setup single signon for ssouser
- To cleanup - Run Cleanup-OpenSSHTestEnvironment
"@
if (-not $Quiet) {
Write-Warning $warning
$continue = Read-Host -Prompt "Do you want to continue with the above changes? [Yes] Y; [No] N (default is `"Y`")"
if( ($continue -eq "") -or ($continue -ieq "Y") -or ($continue -ieq "Yes") )
{
}
elseif( ($continue -ieq "N") -or ($continue -ieq "No") )
{
Write-Host "User decided not to make the changes."
return
}
else
{
Throw "User entered invalid option ($continue). Exit now."
}
}
Install-OpenSSHTestDependencies
if(-not (Test-path $TestDataPath -PathType Container))
{
New-Item -ItemType Directory -Path $TestDataPath -Force -ErrorAction SilentlyContinue | out-null
}
#Backup existing OpenSSH configuration
$backupConfigPath = Join-Path $script:OpenSSHBinPath sshd_config.ori
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
Copy-Item (Join-Path $script:OpenSSHBinPath sshd_config) $backupConfigPath -Force
}
# copy new sshd_config
Copy-Item (Join-Path $Script:E2ETestDirectory sshd_config) (Join-Path $script:OpenSSHBinPath sshd_config) -Force
Copy-Item "$($Script:E2ETestDirectory)\sshtest*hostkey*" $script:OpenSSHBinPath -Force
Restart-Service sshd -Force
#Backup existing known_hosts and replace with test version
#TODO - account for custom known_hosts locations
$knowHostsDirectoryPath = Join-Path $home .ssh
$knowHostsFilePath = Join-Path $knowHostsDirectoryPath known_hosts
if(-not (Test-Path $knowHostsDirectoryPath -PathType Container))
{
New-Item -ItemType Directory -Path $knowHostsDirectoryPath -Force -ErrorAction SilentlyContinue | out-null
}
if ((Test-Path $knowHostsFilePath -PathType Leaf) -and (-not (Test-Path (Join-Path $knowHostsDirectoryPath known_hosts.ori) -PathType Leaf))) {
Copy-Item $knowHostsFilePath (Join-Path $knowHostsDirectoryPath known_hosts.ori) -Force
}
Copy-Item (Join-Path $Script:E2ETestDirectory known_hosts) $knowHostsFilePath -Force
# create test accounts
#TODO - this is Windows specific. Need to be in PAL
foreach ($user in $OpenSSHTestAccounts)
{
try
{
$objUser = New-Object System.Security.Principal.NTAccount($user)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
}
catch
{
#only add the local user when it does not exists on the machine
net user $user $Script:OpenSSHTestAccountsPassword /ADD 2>&1 >> $Script:TestSetupLogFile
}
}
#setup single sign on for ssouser
#TODO - this is Windows specific. Need to be in PAL
$ssousersid = Get-UserSID -User sshtest_ssouser
$ssouserProfileRegistry = Join-Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $ssousersid
if (-not (Test-Path $ssouserProfileRegistry) ) {
#create profile
if (-not($env:DISPLAY)) { $env:DISPLAY = 1 }
$env:SSH_ASKPASS="$($env:ComSpec) /c echo $($OpenSSHTestAccountsPassword)"
cmd /c "ssh -p 47002 sshtest_ssouser@localhost echo %userprofile% > profile.txt"
if ($env:DISPLAY -eq 1) { Remove-Item env:\DISPLAY }
remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
}
$ssouserProfile = (Get-ItemProperty -Path $ssouserProfileRegistry -Name 'ProfileImagePath').ProfileImagePath
New-Item -ItemType Directory -Path (Join-Path $ssouserProfile .ssh) -Force -ErrorAction SilentlyContinue | out-null
$authorizedKeyPath = Join-Path $ssouserProfile .ssh\authorized_keys
$testPubKeyPath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519.pub
#workaround for the cariggage new line added by git
(Get-Content $testPubKeyPath -Raw).Replace("`r`n","`n") | Set-Content $testPubKeyPath -Force
Copy-Item $testPubKeyPath $authorizedKeyPath -Force -ErrorAction SilentlyContinue
$acl = get-acl $authorizedKeyPath
$ar = New-Object System.Security.AccessControl.FileSystemAccessRule("NT Service\sshd", "Read", "Allow")
$acl.SetAccessRule($ar)
Set-Acl $authorizedKeyPath $acl
$testPriKeypath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519
(Get-Content $testPriKeypath -Raw).Replace("`r`n","`n") | Set-Content $testPriKeypath -Force
cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile"
}
<#
.SYNOPSIS
This function installs the tools required by our tests
1) Pester for running the tests
2) sysinternals required by the tests on windows.
#>
function Install-OpenSSHTestDependencies
{
[CmdletBinding()]
param ()
# Install chocolatey
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
{
Write-Log -Message "Chocolatey not present. Installing chocolatey."
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $Script:TestSetupLogFile
}
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
if (-not ($isModuleAvailable))
{
Write-Log -Message "Installing Pester..."
choco install Pester -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
if ( -not (Test-Path "$env:ProgramData\chocolatey\lib\sysinternals\tools" ) ) {
Write-Log -Message "sysinternals not present. Installing sysinternals."
choco install sysinternals -y --force --limitoutput 2>&1 >> $Script:TestSetupLogFile
}
}
<#
.Synopsis
Get-UserSID
#>
function Get-UserSID
{
param
(
[string]$Domain,
[string]$User
)
if([string]::IsNullOrEmpty($Domain))
{
$objUser = New-Object System.Security.Principal.NTAccount($User)
}
else
{
$objUser = New-Object System.Security.Principal.NTAccount($Domain, $User)
}
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value
}
<#
.Synopsis
Cleanup-OpenSSHTestEnvironment
#>
function Cleanup-OpenSSHTestEnvironment
{
# .exe - Windows specific. TODO - PAL
if (-not (Test-Path (Join-Path $script:OpenSSHBinPath ssh.exe) -PathType Leaf))
{
Throw "Cannot find OpenSSH binaries under $script:OpenSSHBinPath. "
}
#Restore sshd_config
$backupConfigPath = Join-Path $Script:OpenSSHBinPath sshd_config.ori
if (Test-Path $backupConfigPath -PathType Leaf) {
Copy-Item $backupConfigPath (Join-Path $Script:OpenSSHBinPath sshd_config) -Force -ErrorAction SilentlyContinue
Remove-Item (Join-Path $Script:OpenSSHBinPath sshd_config.ori) -Force -ErrorAction SilentlyContinue
Remove-Item $Script:OpenSSHBinPath\sshtest*hostkey* -Force -ErrorAction SilentlyContinue
Restart-Service sshd
}
#Restore known_hosts
$originKnowHostsPath = Join-Path $home .ssh\known_hosts.ori
if (Test-Path $originKnowHostsPath)
{
Copy-Item $originKnowHostsPath (Join-Path $home .ssh\known_hosts) -Force -ErrorAction SilentlyContinue
Remove-Item $originKnowHostsPath -Force -ErrorAction SilentlyContinue
}
#Delete accounts
foreach ($user in $OpenSSHTestAccounts)
{
net user $user /delete
}
# remove registered keys
cmd /c "ssh-add -d (Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519) 2>&1 >> $Script:TestSetupLogFile"
if($Global:OpenSSHTestInfo -ne $null)
{
$Global:OpenSSHTestInfo.Clear()
$Global:OpenSSHTestInfo = $null
}
}
<#
.Synopsis
Get-UnitTestDirectory.
#>
function Get-UnitTestDirectory
{
[CmdletBinding()]
param
(
[ValidateSet('Debug', 'Release')]
[string]$Configuration = "Release",
[ValidateSet('x86', 'x64', '')]
[string]$NativeHostArch = ""
)
[string] $platform = $env:PROCESSOR_ARCHITECTURE
if(-not [String]::IsNullOrEmpty($NativeHostArch))
{
$folderName = $NativeHostArch
if($NativeHostArch -eq 'x86')
{
$folderName = "Win32"
}
}
else
{
if($platform -ieq "AMD64")
{
$folderName = "x64"
}
else
{
$folderName = "Win32"
}
}
if([String]::IsNullOrEmpty($Configuration))
{
if( $folderName -ieq "Win32" )
{
$RealConfiguration = "Debug"
}
else
{
$RealConfiguration = "Release"
}
}
else
{
$RealConfiguration = $Configuration
}
$unitTestdir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
$unitTestDir
}
<#
.Synopsis
Run OpenSSH pester tests.
#>
function Run-OpenSSHE2ETest
{
# Discover all CI tests and run them.
Push-Location $Script:E2ETestDirectory
Write-Log -Message "Running OpenSSH E2E tests..."
$testFolders = Get-ChildItem *.tests.ps1 -Recurse -Exclude SSHDConfig.tests.ps1, SSH.Tests.ps1 | ForEach-Object{ Split-Path $_.FullName} | Sort-Object -Unique
Invoke-Pester $testFolders -OutputFormat NUnitXml -OutputFile $Script:E2ETestResultsFile -Tag 'CI'
Pop-Location
}
<#
.Synopsis
Run openssh unit tests.
#>
function Run-OpenSSHUnitTest
{
# Discover all CI tests and run them.
Push-Location $Script:UnitTestDirectory
Write-Log -Message "Running OpenSSH unit tests..."
if (Test-Path $Script:UnitTestResultsFile)
{
$null = Remove-Item -Path $Script:UnitTestResultsFile -Force -ErrorAction SilentlyContinue
}
$testFolders = Get-ChildItem unittest-*.exe -Recurse -Exclude unittest-sshkey.exe,unittest-kex.exe |
ForEach-Object{ Split-Path $_.FullName} |
Sort-Object -Unique
$testfailed = $false
if ($testFolders -ne $null)
{
$testFolders | % {
Push-Location $_
$unittestFile = "$(Split-Path $_ -Leaf).exe"
Write-log "Running OpenSSH unit $unittestFile ..."
& .\$unittestFile >> $Script:UnitTestResultsFile
$errorCode = $LASTEXITCODE
if ($errorCode -ne 0)
{
$testfailed = $true
$errorMessage = "$($_.FullName) test failed for OpenSSH.`nExitCode: $errorCode. Detail test log is at $($Script:UnitTestResultsFile)."
Write-Warning $errorMessage
}
Pop-Location
}
}
Pop-Location
$testfailed
}
<#
Write-Log
#>
function Write-Log
{
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Message
)
if(-not (Test-Path (Split-Path $Script:TestSetupLogFile) -PathType Container))
{
$null = New-Item -ItemType Directory -Path (Split-Path $Script:TestSetupLogFile) -Force -ErrorAction SilentlyContinue | out-null
}
if (-not ([string]::IsNullOrEmpty($Script:TestSetupLogFile)))
{
Add-Content -Path $Script:TestSetupLogFile -Value $Message
}
}
Export-ModuleMember -Function Setup-OpenSSHTestEnvironment, Cleanup-OpenSSHTestEnvironment, Run-OpenSSHUnitTest, Run-OpenSSHE2ETest

View File

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

View File

@ -1681,13 +1681,12 @@
/* Windows specific macro added to workaround mysignal implementaion in bsd-misc.c */
#define HAVE_MYSIGNAL 1
#define PATH_MAX MAX_PATH
#define S_IFIFO 0x1000
#define HAVE_EXPLICIT_BZERO
#define HAVE_MBTOWC 1
#define HAVE_LLABS 1
#include <signal.h>
#include <io.h>

View File

@ -117,6 +117,10 @@
<PreBuildEvent>
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -141,6 +145,10 @@
<PreBuildEvent>
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@ -169,6 +177,10 @@
<PreBuildEvent>
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@ -197,6 +209,10 @@
<PreBuildEvent>
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -1,5 +1,6 @@
# @manojampalam - authored initial script
# @friism - Fixed issue with invalid SDDL on Set-Acl
# @manojampalam - removed ntrights.exe dependency
$scriptpath = $MyInvocation.MyCommand.Path
$scriptdir = Split-Path $scriptpath
@ -8,8 +9,71 @@ $sshdpath = Join-Path $scriptdir "sshd.exe"
$sshagentpath = Join-Path $scriptdir "ssh-agent.exe"
$logsdir = Join-Path $scriptdir "logs"
$account = "NT SERVICE\SSHD"
$ntrights = "ntrights.exe -u `"{0}`" +r SeAssignPrimaryTokenPrivilege" -f $account
$sshdAccount = "NT SERVICE\SSHD"
#Idea borrowed from http://sqldbamusings.blogspot.com/2012/03/powershell-adding-accounts-to-local.html
function Add-Privilege
{
param(
[string] $Account,
[ValidateSet("SeAssignPrimaryTokenPrivilege", "SeServiceLogonRight")]
[string] $Privilege
)
#Get $Account SID
$account_sid = $null
try
{
$ntprincipal = new-object System.Security.Principal.NTAccount "$Account"
$sid = $ntprincipal.Translate([System.Security.Principal.SecurityIdentifier])
$account_sid = $sid.Value.ToString()
}
catch
{
Throw 'Unable to resolve '+ $Account
}
#Prepare policy settings file to be applied
$settings_to_export = [System.IO.Path]::GetTempFileName()
"[Unicode]" | Set-Content $settings_to_export -Encoding Unicode
"Unicode=yes" | Add-Content $settings_to_export -Force -WhatIf:$false
"[Version]" | Add-Content $settings_to_export -Force -WhatIf:$false
"signature=`"`$CHICAGO`$`"" | Add-Content $settings_to_export -Force -WhatIf:$false
"Revision=1" | Add-Content $settings_to_export -Force -WhatIf:$false
"[Privilege Rights]" | Add-Content $settings_to_export -Force -WhatIf:$false
#Get Current policy settings
$imported_settings = [System.IO.Path]::GetTempFileName()
secedit.exe /export /areas USER_RIGHTS /cfg "$($imported_settings)" > $null
if (-not(Test-Path $imported_settings)) {
Throw "Unable to import current security policy settings"
}
#find current assigned accounts to $Privilege and add it to $settings_to_export
$current_settings = Get-Content $imported_settings -Encoding Unicode
$existing_setting = $null
foreach ($setting in $current_settings) {
if ($setting -like "$Privilege`*") {
$existing_setting = $setting
}
}
#Add $account_sid to list
if ($existing_setting -eq $null) {
$Privilege + " = *" + $account_sid | Add-Content $settings_to_export -Force -WhatIf:$false
}
else
{
$existing_setting + ",*" + $account_sid | Add-Content $settings_to_export -Force -WhatIf:$false
}
#export
secedit.exe /configure /db "secedit.sdb" /cfg "$($settings_to_export)" /areas USER_RIGHTS > $null
}
if (-not (Test-Path $sshdpath)) {
throw "sshd.exe is not present in script path"
@ -30,20 +94,18 @@ if (Get-Service ssh-agent -ErrorAction SilentlyContinue)
New-Service -Name ssh-agent -BinaryPathName $sshagentpath -Description "SSH Agent" -StartupType Manual | Out-Null
cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)'
New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Deamon" -StartupType Manual -DependsOn ssh-agent | Out-Null
sc.exe config sshd obj= $account
New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Daemon" -StartupType Manual -DependsOn ssh-agent | Out-Null
sc.exe config sshd obj= $sshdAccount
Push-Location
cd $scriptdir
cmd.exe /c $ntrights
Pop-Location
Add-Privilege -Account $sshdAccount -Privilege SeAssignPrimaryTokenPrivilege
Add-Privilege -Account $sshdAccount -Privilege SeServiceLogonRight
if(-not (test-path $logsdir -PathType Container))
{
$null = New-Item $logsdir -ItemType Directory -Force -ErrorAction Stop
}
$rights = [System.Security.AccessControl.FileSystemRights]"Read, Write"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($account, $rights, "ContainerInherit,ObjectInherit", "None", "Allow")
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($sshdAccount, $rights, "ContainerInherit,ObjectInherit", "None", "Allow")
$acl = Get-Acl -Path $logsdir
$Acl.SetAccessRule($accessRule)
Set-Acl -Path $logsdir -AclObject $acl

View File

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

View File

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

View File

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

View File

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

View File

@ -119,4 +119,4 @@ Subsystem sftp sftp-server.exe
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server
PubkeyAcceptedKeyTypes ssh-ed25519*
# PubkeyAcceptedKeyTypes ssh-ed25519*

Binary file not shown.

View File

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

View File

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

View File

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

View File

@ -38,10 +38,6 @@
#include "console.h"
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
#endif
HANDLE hOutputConsole = NULL;
DWORD dwSavedAttributes = 0;
WORD wStartingAttributes = 0;
@ -140,7 +136,7 @@ ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit)
SavedViewRect = csbi.srWindow;
debug("console doesn't support the ansi parsing");
} else {
ConMoveCurosorTop(csbi);
ConMoveCursorTop(csbi);
debug("console supports the ansi parsing");
}
@ -1082,9 +1078,20 @@ ConMoveVisibleWindow(int offset)
SMALL_RECT visibleWindowRect;
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo)) {
/* Check if applying the offset results in console buffer overflow.
* if yes, then scrolldown the console buffer.
*/
if ((consoleInfo.srWindow.Bottom + offset) >= (consoleInfo.dwSize.Y - 1)) {
for (int i = 0; i < offset; i++)
ConScrollDown(0, consoleInfo.dwSize.Y - 1);
if (GetConsoleScreenBufferInfo(hOutputConsole, &consoleInfo))
memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect));
} else {
memcpy(&visibleWindowRect, &consoleInfo.srWindow, sizeof(visibleWindowRect));
visibleWindowRect.Top += offset;
visibleWindowRect.Bottom += offset;
}
SetConsoleWindowInfo(hOutputConsole, TRUE, &visibleWindowRect);
}
@ -1552,10 +1559,48 @@ ConSaveWindowsState()
}
void
ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi)
ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi)
{
/* Windows server at first sends the "cls" after the connection is established.
* Since we don't want to loose any data on the console, we would like to scroll down
* the visible window.
*/
int offset = csbi.dwCursorPosition.Y - csbi.srWindow.Top;
ConMoveVisibleWindow(offset);
ConSaveViewRect();
}
HANDLE
get_console_handle(FILE *stream, DWORD * mode)
{
int file_num = 0, ret = 0;
intptr_t lHandle = 0;
HANDLE hFile = NULL;
DWORD type = 0;
file_num = (_fileno)(stream);
if (file_num == -1) {
return -1;
}
lHandle = _get_osfhandle(file_num);
if (lHandle == -1 && errno == EBADF) {
return -1;
}
type = GetFileType((HANDLE)lHandle);
if (type == FILE_TYPE_CHAR && file_num >= 0 && file_num <= 2) {
if (file_num == 0)
hFile = GetStdHandle(STD_INPUT_HANDLE);
else if (file_num == 1)
hFile = GetStdHandle(STD_OUTPUT_HANDLE);
else if (file_num == 2)
hFile = GetStdHandle(STD_ERROR_HANDLE);
if ((hFile != NULL) &&
(hFile != INVALID_HANDLE_VALUE) &&
(GetFileType(hFile) == FILE_TYPE_CHAR) &&
GetConsoleMode(hFile, mode))
return hFile;
}
return INVALID_HANDLE_VALUE;
}

View File

@ -79,6 +79,10 @@
#define false FALSE
#define bool BOOL
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
#endif
typedef void * SCREEN_HANDLE;
int ConEnterRawMode(DWORD OutputHandle, BOOL fSmartInit);
@ -137,5 +141,6 @@ void ConSaveWindowsState();
void ConMoveVisibleWindow(int offset);
int is_cursor_at_lastline_of_visible_window();
void ConGetCursorPosition(int *x, int *y);
void ConMoveCurosorTop(CONSOLE_SCREEN_BUFFER_INFO csbi);
void ConMoveCursorTop(CONSOLE_SCREEN_BUFFER_INFO csbi);
HANDLE get_console_handle(FILE *, DWORD *);
#endif

View File

@ -39,6 +39,7 @@
#include "inc\utf.h"
#include "inc\fcntl.h"
#include "misc_internal.h"
#include "debug.h"
/* internal read buffer size */
#define READ_BUFFER_SIZE 100*1024
@ -97,7 +98,7 @@ fileio_connect(struct w32_io* pio, char* name)
int ret = 0;
if (pio->handle != 0 && pio->handle != INVALID_HANDLE_VALUE) {
debug("fileio_connect called in unexpected state, pio = %p", pio);
debug3("fileio_connect called in unexpected state, pio = %p", pio);
errno = EOTHER;
ret = -1;
goto cleanup;
@ -114,13 +115,13 @@ fileio_connect(struct w32_io* pio, char* name)
/* TODO - support nonblocking connect */
/* wait until we have a server pipe instance to connect */
while (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) {
debug2("waiting for agent connection, retrying after 1 sec");
debug4("waiting for agent connection, retrying after 1 sec");
if ((ret = wait_for_any_event(NULL, 0, 1000) != 0) != 0)
goto cleanup;
}
if (h == INVALID_HANDLE_VALUE) {
debug("unable to connect to pipe %ls, error: %d", name_w, GetLastError());
debug3("unable to connect to pipe %ls, error: %d", name_w, GetLastError());
errno = errno_from_Win32LastError();
ret = -1;
goto cleanup;
@ -129,7 +130,7 @@ fileio_connect(struct w32_io* pio, char* name)
if (SetHandleInformation(h, HANDLE_FLAG_INHERIT,
pio->fd_flags & FD_CLOEXEC ? 0 : HANDLE_FLAG_INHERIT) == FALSE) {
errno = errno_from_Win32LastError();
debug("SetHandleInformation failed, error = %d, pio = %p", GetLastError(), pio);
debug3("SetHandleInformation failed, error = %d, pio = %p", GetLastError(), pio);
ret = -1;
goto cleanup;
}
@ -162,7 +163,7 @@ fileio_pipe(struct w32_io* pio[2])
if (pio == NULL) {
errno = EINVAL;
debug("pipe - ERROR invalid parameter");
debug3("pipe - ERROR invalid parameter");
return -1;
}
@ -170,7 +171,7 @@ fileio_pipe(struct w32_io* pio[2])
if (-1 == sprintf_s(pipe_name, PATH_MAX, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x",
GetCurrentProcessId(), pipe_counter++)) {
errno = EOTHER;
debug("pipe - ERROR sprintf_s %d", errno);
debug3("pipe - ERROR sprintf_s %d", errno);
goto error;
}
@ -179,31 +180,31 @@ fileio_pipe(struct w32_io* pio[2])
sec_attributes.nLength = 0;
/* create named pipe */
read_handle = CreateNamedPipeA(pipe_name,
PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
write_handle = CreateNamedPipeA(pipe_name,
PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_WAIT,
1,
4096,
4096,
0,
&sec_attributes);
if (read_handle == INVALID_HANDLE_VALUE) {
if (write_handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError();
debug("pipe - CreateNamedPipe() ERROR:%d", errno);
debug3("pipe - CreateNamedPipe() ERROR:%d", errno);
goto error;
}
/* connect to named pipe */
write_handle = CreateFileA(pipe_name,
GENERIC_WRITE,
read_handle = CreateFileA(pipe_name,
GENERIC_READ,
0,
&sec_attributes,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (write_handle == INVALID_HANDLE_VALUE) {
if (read_handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError();
debug("pipe - ERROR CreateFile() :%d", errno);
debug3("pipe - ERROR CreateFile() :%d", errno);
goto error;
}
@ -213,7 +214,7 @@ fileio_pipe(struct w32_io* pio[2])
if (!pio_read || !pio_write) {
errno = ENOMEM;
debug("pip - ERROR:%d", errno);
debug3("pip - ERROR:%d", errno);
goto error;
}
@ -252,21 +253,21 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
* O_RDONLY, O_WRONLY, or O_RDWR
*/
if ((rwflags != O_RDONLY) && (rwflags != O_WRONLY) && (rwflags != O_RDWR)) {
debug("open - flags ERROR: wrong rw flags: %d", flags);
debug3("open - flags ERROR: wrong rw flags: %d", flags);
errno = EINVAL;
return -1;
}
/*only following create and status flags currently supported*/
if (c_s_flags & ~(O_NONBLOCK | O_APPEND | O_CREAT | O_TRUNC | O_EXCL | O_BINARY)) {
debug("open - ERROR: Unsupported flags: %d", flags);
debug3("open - ERROR: Unsupported flags: %d", flags);
errno = ENOTSUP;
return -1;
}
/*validate mode*/
if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
debug("open - ERROR: unsupported mode: %d", mode);
debug3("open - ERROR: unsupported mode: %d", mode);
errno = ENOTSUP;
return -1;
}
@ -310,6 +311,8 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
return 0;
}
#define NULL_DEVICE "/dev/null"
/* open() implementation. Uses CreateFile to open file, console, device, etc */
struct w32_io*
fileio_open(const char *path_utf8, int flags, int mode)
@ -319,17 +322,21 @@ fileio_open(const char *path_utf8, int flags, int mode)
HANDLE handle;
wchar_t *path_utf16 = NULL;
debug2("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
debug4("open - pathname:%s, flags:%d, mode:%d", path_utf8, flags, mode);
/* check input params*/
if (path_utf8 == NULL) {
errno = EINVAL;
debug("open - ERROR:%d", errno);
debug3("open - ERROR:%d", errno);
return NULL;
}
/* if opening null device, point to Windows equivalent */
if (strncmp(path_utf8, NULL_DEVICE, strlen(NULL_DEVICE)) == 0)
path_utf8 = "NUL";
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
errno = ENOMEM;
debug("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
debug3("utf8_to_utf16 failed for file:%s error:%d", path_utf8, GetLastError());
return NULL;
}
@ -342,7 +349,7 @@ fileio_open(const char *path_utf8, int flags, int mode)
if (handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError();
debug("failed to open file:%s error:%d", path_utf8, GetLastError());
debug3("failed to open file:%s error:%d", path_utf8, GetLastError());
free(path_utf16);
return NULL;
}
@ -352,7 +359,7 @@ fileio_open(const char *path_utf8, int flags, int mode)
if (pio == NULL) {
CloseHandle(handle);
errno = ENOMEM;
debug("fileio_open(), failed to allocate memory error:%d", errno);
debug3("fileio_open(), failed to allocate memory error:%d", errno);
return NULL;
}
@ -369,7 +376,7 @@ VOID CALLBACK
ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfered, _Inout_ LPOVERLAPPED lpOverlapped)
{
struct w32_io* pio = (struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, read_overlapped));
debug2("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
debug4("ReadCB pio:%p, pending_state:%d, error:%d, received:%d",
pio, pio->read_details.pending, dwErrorCode, dwNumberOfBytesTransfered);
pio->read_details.error = dwErrorCode;
pio->read_details.remaining = dwNumberOfBytesTransfered;
@ -383,13 +390,13 @@ ReadCompletionRoutine(_In_ DWORD dwErrorCode, _In_ DWORD dwNumberOfBytesTransfer
int
fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
{
debug2("ReadFileEx io:%p", pio);
debug4("ReadFileEx io:%p", pio);
if (pio->read_details.buf == NULL) {
pio->read_details.buf = malloc(READ_BUFFER_SIZE);
if (!pio->read_details.buf) {
errno = ENOMEM;
debug2("ReadFileEx - ERROR: %d, io:%p", errno, pio);
debug4("ReadFileEx - ERROR: %d, io:%p", errno, pio);
return -1;
}
}
@ -404,7 +411,7 @@ fileio_ReadFileEx(struct w32_io* pio, unsigned int bytes_requested)
pio->read_details.pending = TRUE;
else {
errno = errno_from_Win32LastError();
debug("ReadFileEx() ERROR:%d, io:%p", GetLastError(), pio);
debug3("ReadFileEx() ERROR:%d, io:%p", GetLastError(), pio);
return -1;
}
@ -417,18 +424,18 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
{
int bytes_copied;
debug3("read - io:%p remaining:%d", pio, pio->read_details.remaining);
debug5("read - io:%p remaining:%d", pio, pio->read_details.remaining);
/* if read is pending */
if (pio->read_details.pending) {
if (w32_io_is_blocking(pio)) {
debug2("read - io is pending, blocking call made, io:%p", pio);
debug4("read - io is pending, blocking call made, io:%p", pio);
while (fileio_is_io_available(pio, TRUE) == FALSE) {
if (-1 == wait_for_any_event(NULL, 0, INFINITE))
return -1;
}
}
errno = EAGAIN;
debug2("read - io is already pending, io:%p", pio);
debug4("read - io is already pending, io:%p", pio);
return -1;
}
@ -442,14 +449,14 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
if ((FILETYPE(pio) == FILE_TYPE_PIPE)
&& (errno == ERROR_BROKEN_PIPE)) {
/* write end of the pipe closed */
debug("read - no more data, io:%p", pio);
debug3("read - no more data, io:%p", pio);
errno = 0;
return 0;
}
/* on W2012, ReadFileEx on file throws a synchronous EOF error*/
else if ((FILETYPE(pio) == FILE_TYPE_DISK)
&& (errno == ERROR_HANDLE_EOF)) {
debug("read - no more data, io:%p", pio);
debug3("read - no more data, io:%p", pio);
errno = 0;
return 0;
}
@ -468,7 +475,7 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
}
else if (pio->read_details.pending) {
errno = EAGAIN;
debug2("read - IO is pending, io:%p", pio);
debug4("read - IO is pending, io:%p", pio);
return -1;
}
}
@ -478,12 +485,12 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
/*write end of the pipe is closed or pipe broken or eof reached*/
if ((pio->read_details.error == ERROR_BROKEN_PIPE) ||
(pio->read_details.error == ERROR_HANDLE_EOF)) {
debug2("read - (2) no more data, io:%p", pio);
debug4("read - (2) no more data, io:%p", pio);
errno = 0;
pio->read_details.error = 0;
return 0;
}
debug("read - ERROR from cb :%d, io:%p", errno, pio);
debug3("read - ERROR from cb :%d, io:%p", errno, pio);
pio->read_details.error = 0;
return -1;
}
@ -492,7 +499,7 @@ fileio_read(struct w32_io* pio, void *dst, unsigned int max)
memcpy(dst, pio->read_details.buf + pio->read_details.completed, bytes_copied);
pio->read_details.remaining -= bytes_copied;
pio->read_details.completed += bytes_copied;
debug2("read - io:%p read: %d remaining: %d", pio, bytes_copied,
debug4("read - io:%p read: %d remaining: %d", pio, bytes_copied,
pio->read_details.remaining);
return bytes_copied;
}
@ -504,13 +511,13 @@ WriteCompletionRoutine(_In_ DWORD dwErrorCode,
{
struct w32_io* pio =
(struct w32_io*)((char*)lpOverlapped - offsetof(struct w32_io, write_overlapped));
debug2("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
debug4("WriteCB - pio:%p, pending_state:%d, error:%d, transferred:%d of remaining: %d",
pio, pio->write_details.pending, dwErrorCode, dwNumberOfBytesTransfered,
pio->write_details.remaining);
pio->write_details.error = dwErrorCode;
/* TODO - assert that remaining == dwNumberOfBytesTransfered */
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
debug("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio,
debug3("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio,
dwNumberOfBytesTransfered, pio->write_details.remaining);
DebugBreak();
}
@ -524,27 +531,28 @@ int
fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
{
int bytes_copied;
DWORD pipe_flags = 0, pipe_instances = 0;
debug2("write - io:%p", pio);
debug4("write - io:%p", pio);
if (pio->write_details.pending) {
if (w32_io_is_blocking(pio)) {
debug2("write - io pending, blocking call made, io:%p", pio);
debug4("write - io pending, blocking call made, io:%p", pio);
while (pio->write_details.pending)
if (wait_for_any_event(NULL, 0, INFINITE) == -1)
return -1;
} else {
errno = EAGAIN;
debug2("write - IO is already pending, io:%p", pio);
debug4("write - IO is already pending, io:%p", pio);
return -1;
}
}
if (pio->write_details.error) {
errno = errno_from_Win32Error(pio->write_details.error);
debug("write - ERROR:%d on prior unblocking write, io:%p", errno, pio);
debug3("write - ERROR:%d on prior unblocking write, io:%p", errno, pio);
pio->write_details.error = 0;
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
debug("write - ERROR:read end of the pipe closed, io:%p", pio);
debug3("write - ERROR:read end of the pipe closed, io:%p", pio);
errno = EPIPE;
}
return -1;
@ -554,7 +562,7 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
pio->write_details.buf = malloc(WRITE_BUFFER_SIZE);
if (pio->write_details.buf == NULL) {
errno = ENOMEM;
debug("write - ERROR:%d, io:%p", errno, pio);
debug3("write - ERROR:%d, io:%p", errno, pio);
return -1;
}
pio->write_details.buf_size = WRITE_BUFFER_SIZE;
@ -570,6 +578,39 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
}
else
return -1;
} else if ( FILETYPE(pio) == FILE_TYPE_PIPE &&
GetNamedPipeInfo(WINHANDLE(pio), &pipe_flags, NULL, NULL, &pipe_instances) &&
pipe_flags == PIPE_CLIENT_END && pipe_instances == 1) {
/*
* TODO - Figure out a better solution to this problem
* IO handle corresponding to this object (pio->handle) may be referring
* to something that isn't opened in overlapped mode. While all handles
* opened by this POSIX wrapper are opened in overlapped mode, other handles
* that are inherited (ex. via std i/o) are typically not.
* Ex. When we do this in Powershell
* $o = ssh.exe user@target hostname
* Powershell creates anonymous pipes (that do not support overlapped i.o)
* Calling asynchronous I/O APIs (WriteFileEx) for example will not work in
* those cases (the callback is never called and it typically manifests as a
* hang to end user
*
* This conditional logic is put in place to specifically handle Powershell
* redirection scenarios. Thinking behind these conditions
* - should be a pipe handle. console I/O is handled in termio.c, impacting file i/o
* scenarios not found yet.
* - pipe should be the client end. This is to skip pipes created internally in POSIX
* wrapper (by pipe() calls) - The write ends on these pipes are on server
* - pipe_instances == 1. This is to skip pipe handles created as part of Connect(AF_UNIX)
* sockets (that typically are created for unlimited instances).
* For such I/O we do a synchronous write.
*/
/* DebugBreak() */;
if (WriteFile(WINHANDLE(pio), pio->write_details.buf, bytes_copied, &bytes_copied, NULL) == FALSE) {
errno = errno_from_Win32LastError();
debug3("write - WriteFile() ERROR:%d, io:%p", GetLastError(), pio);
return -1;
}
return bytes_copied;
} else {
if (WriteFileEx(WINHANDLE(pio), pio->write_details.buf, bytes_copied,
&pio->write_overlapped, &WriteCompletionRoutine)) {
@ -579,10 +620,10 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
errno = errno_from_Win32LastError();
/* read end of the pipe closed ? */
if ((FILETYPE(pio) == FILE_TYPE_PIPE) && (errno == ERROR_BROKEN_PIPE)) {
debug("write - ERROR:read end of the pipe closed, io:%p", pio);
debug3("write - ERROR:read end of the pipe closed, io:%p", pio);
errno = EPIPE;
}
debug("write ERROR from cb(2):%d, io:%p", errno, pio);
debug3("write ERROR from cb(2):%d, io:%p", errno, pio);
return -1;
}
}
@ -604,11 +645,11 @@ fileio_write(struct w32_io* pio, const void *buf, unsigned int max)
/* if write has completed, pick up any error reported*/
if (!pio->write_details.pending && pio->write_details.error) {
errno = errno_from_Win32Error(pio->write_details.error);
debug("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio);
debug3("write - ERROR from cb:%d, io:%p", pio->write_details.error, pio);
pio->write_details.error = 0;
return -1;
}
debug2("write - reporting %d bytes written, io:%p", bytes_copied, pio);
debug4("write - reporting %d bytes written, io:%p", bytes_copied, pio);
return bytes_copied;
}
@ -618,7 +659,7 @@ int
fileio_fstat(struct w32_io* pio, struct _stat64 *buf)
{
int fd = _open_osfhandle((intptr_t)pio->handle, 0);
debug2("fstat - pio:%p", pio);
debug4("fstat - pio:%p", pio);
if (fd == -1) {
errno = EOTHER;
return -1;
@ -630,33 +671,31 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf)
int
fileio_stat(const char *path, struct _stat64 *buf)
{
wchar_t wpath[PATH_MAX];
wchar_t* wtmp = NULL;
struct w32_io* pio;
wchar_t* wpath = NULL;
int r = -1;
if ((wtmp = utf8_to_utf16(path)) == NULL)
if ((wpath = utf8_to_utf16(path)) == NULL)
fatal("failed to covert input arguments");
/* If we doesn't have sufficient permissions then _wstat4() is returning
* file not found so added fileio_open() which will set the errorno correctly (access denied)
r = _wstat64(wpath, buf);
/*
* If we doesn't have sufficient permissions then _wstat64() is returning "file not found"
* TODO - Replace the above call with GetFileAttributesEx
*/
if (NULL == (pio = fileio_open(path, O_RDONLY, 0)))
return -1;
fileio_close(pio);
wcscpy(&wpath[0], wtmp);
free(wtmp);
return _wstat64(wpath, buf);
cleanup:
if (wpath)
free(wpath);
return r;
}
long
fileio_lseek(struct w32_io* pio, long offset, int origin)
{
debug2("lseek - pio:%p", pio);
debug4("lseek - pio:%p", pio);
if (origin != SEEK_SET) {
debug("lseek - ERROR, origin is not supported %d", origin);
debug3("lseek - ERROR, origin is not supported %d", origin);
errno = ENOTSUP;
return -1;
}
@ -671,7 +710,7 @@ FILE*
fileio_fdopen(struct w32_io* pio, const char *mode)
{
int fd_flags = 0;
debug2("fdopen - io:%p", pio);
debug4("fdopen - io:%p", pio);
/* logic below doesn't work with overlapped file HANDLES */
if (mode[1] == '\0') {
@ -686,12 +725,12 @@ fileio_fdopen(struct w32_io* pio, const char *mode)
break;
default:
errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode);
debug3("fdopen - ERROR unsupported mode %s", mode);
return NULL;
}
} else {
errno = ENOTSUP;
debug("fdopen - ERROR unsupported mode %s", mode);
debug3("fdopen - ERROR unsupported mode %s", mode);
return NULL;
}
@ -699,7 +738,7 @@ fileio_fdopen(struct w32_io* pio, const char *mode)
if (fd == -1) {
errno = EOTHER;
debug("fdopen - ERROR:%d _open_osfhandle()", errno);
debug3("fdopen - ERROR:%d _open_osfhandle()", errno);
return NULL;
}
@ -732,7 +771,7 @@ fileio_on_select(struct w32_io* pio, BOOL rd)
int
fileio_close(struct w32_io* pio)
{
debug2("fileclose - pio:%p", pio);
debug4("fileclose - pio:%p", pio);
/* handle can be null on AF_UNIX sockets that are not yet connected */
if (WINHANDLE(pio) == 0 || WINHANDLE(pio) == INVALID_HANDLE_VALUE) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,34 +1,51 @@
/*
* Temporary Windows versions of functions implemented in utf8.c
* Windows versions of functions implemented in utf8.c
*/
#include <stdio.h>
#include <stdarg.h>
#include <Windows.h>
#include "console.h"
int
vfmprintf(FILE *f, const char *fmt, va_list list)
vfmprintf(FILE *stream, const char *fmt, va_list ap)
{
return vfprintf(f, fmt, list);
DWORD saved_mode = 0, new_mode = 0;
int ret;
HANDLE hFile;
hFile = get_console_handle(stream, &saved_mode);
if(hFile != INVALID_HANDLE_VALUE &&
((saved_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
new_mode = saved_mode & (~ENABLE_VIRTUAL_TERMINAL_PROCESSING);
SetConsoleMode(hFile, new_mode);
}
ret = vfprintf(stream, fmt, ap);
if (saved_mode != 0 && new_mode != saved_mode)
SetConsoleMode(hFile, saved_mode);
return ret;
}
int
mprintf(const char *fmt, ...)
{
int ret = 0;
va_list valist;
va_start(valist, fmt);
ret = vfmprintf(stdout, fmt, valist);
va_end(valist);
va_list ap;
va_start(ap, fmt);
ret = vfmprintf(stdout, fmt, ap);
va_end(ap);
return ret;
}
int
fmprintf(FILE *f, const char *fmt, ...)
fmprintf(FILE *stream, const char *fmt, ...)
{
int ret = 0;
va_list valist;
va_start(valist, fmt);
ret = vfmprintf(f, fmt, valist);
va_end(valist);
va_list ap;
va_start(ap, fmt);
ret = vfmprintf(stream, fmt, ap);
va_end(ap);
return ret;
}
@ -49,6 +66,5 @@ snmprintf(char *buf, size_t len, int *written, const char *fmt, ...)
void
msetlocale(void)
{
return;
}

View File

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

View File

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

View File

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

5
kex.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.130 2017/03/10 04:07:20 djm Exp $ */
/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -341,7 +341,6 @@ kex_reset_dispatch(struct ssh *ssh)
{
ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
}
static int
@ -431,6 +430,7 @@ kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
debug("SSH2_MSG_NEWKEYS received");
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
if ((r = sshpkt_get_end(ssh)) != 0)
return r;
if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
@ -545,6 +545,7 @@ kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
goto out;
kex->done = 0;
kex_reset_dispatch(ssh);
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
r = 0;
*kexp = kex;
out:

5
krl.c
View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $OpenBSD: krl.c,v 1.38 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: krl.c,v 1.39 2017/03/10 07:18:32 dtucker Exp $ */
#include "includes.h"
@ -1089,7 +1089,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
break;
case KRL_SECTION_SIGNATURE:
/* Handled above, but still need to stay in synch */
sshbuf_reset(sect);
sshbuf_free(sect);
sect = NULL;
if ((r = sshbuf_skip_string(copy)) != 0)
goto out;
@ -1288,6 +1288,7 @@ ssh_krl_file_contains_key(const char *path, const struct sshkey *key)
debug2("%s: checking KRL %s", __func__, path);
r = ssh_krl_check_key(krl, key);
out:
if (fd != -1)
close(fd);
sshbuf_free(krlbuf);
ssh_krl_free(krl);

8
log.c
View File

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

17
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.107 2016/11/30 00:28:31 dtucker Exp $ */
/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -310,7 +310,7 @@ a2tun(const char *s, int *remote)
long
convtime(const char *s)
{
long total, secs;
long total, secs, multiplier = 1;
const char *p;
char *endp;
@ -337,23 +337,28 @@ convtime(const char *s)
break;
case 'm':
case 'M':
secs *= MINUTES;
multiplier = MINUTES;
break;
case 'h':
case 'H':
secs *= HOURS;
multiplier = HOURS;
break;
case 'd':
case 'D':
secs *= DAYS;
multiplier = DAYS;
break;
case 'w':
case 'W':
secs *= WEEKS;
multiplier = WEEKS;
break;
default:
return -1;
}
if (secs >= LONG_MAX / multiplier)
return -1;
secs *= multiplier;
if (total >= LONG_MAX - secs)
return -1;
total += secs;
if (total < 0)
return -1;

View File

@ -307,3 +307,11 @@ mbtowc(wchar_t *pwc, const char *s, size_t n)
return 1;
}
#endif
#ifndef HAVE_LLABS
long long
llabs(long long j)
{
return (j < 0 ? -j : j);
}
#endif

View File

@ -135,4 +135,8 @@ void errx(int, const char *, ...) __attribute__((format(printf, 2, 3)));
void warn(const char *, ...) __attribute__((format(printf, 1, 2)));
#endif
#ifndef HAVE_LLABS
long long llabs(long long);
#endif
#endif /* _BSD_MISC_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */
/* $OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm Exp $ */
/*
* Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
@ -69,7 +69,7 @@ static long long scale_factors[] = {
#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
/** Convert the given input string "scaled" into numeric in "result".
/* Convert the given input string "scaled" into numeric in "result".
* Return 0 on success, -1 and errno set on error.
*/
int
@ -81,7 +81,7 @@ scan_scaled(char *scaled, long long *result)
long long scale_fact = 1, whole = 0, fpart = 0;
/* Skip leading whitespace */
while (isascii(*p) && isspace(*p))
while (isascii((unsigned char)*p) && isspace((unsigned char)*p))
++p;
/* Then at most one leading + or - */
@ -108,7 +108,8 @@ scan_scaled(char *scaled, long long *result)
* (but note that E for Exa might look like e to some!).
* Advance 'p' to end, to get scale factor.
*/
for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
for (; isascii((unsigned char)*p) &&
(isdigit((unsigned char)*p) || *p=='.'); ++p) {
if (*p == '.') {
if (fract_digits > 0) { /* oops, more than one '.' */
errno = EINVAL;
@ -124,6 +125,10 @@ scan_scaled(char *scaled, long long *result)
/* ignore extra fractional digits */
continue;
fract_digits++; /* for later scaling */
if (fpart >= LLONG_MAX / 10) {
errno = ERANGE;
return -1;
}
fpart *= 10;
fpart += i;
} else { /* normal digit */
@ -131,6 +136,10 @@ scan_scaled(char *scaled, long long *result)
errno = ERANGE;
return -1;
}
if (whole >= LLONG_MAX / 10) {
errno = ERANGE;
return -1;
}
whole *= 10;
whole += i;
}
@ -150,17 +159,22 @@ scan_scaled(char *scaled, long long *result)
/* Validate scale factor, and scale whole and fraction by it. */
for (i = 0; i < SCALE_LENGTH; i++) {
/** Are we there yet? */
/* Are we there yet? */
if (*p == scale_chars[i] ||
*p == tolower(scale_chars[i])) {
*p == tolower((unsigned char)scale_chars[i])) {
/* If it ends with alphanumerics after the scale char, bad. */
if (isalnum(*(p+1))) {
if (isalnum((unsigned char)*(p+1))) {
errno = EINVAL;
return -1;
}
scale_fact = scale_factors[i];
if (whole >= LLONG_MAX / scale_fact) {
errno = ERANGE;
return -1;
}
/* scale whole part */
whole *= scale_fact;
@ -181,7 +195,9 @@ scan_scaled(char *scaled, long long *result)
return 0;
}
}
errno = ERANGE;
/* Invalid unit or character */
errno = EINVAL;
return -1;
}
@ -196,7 +212,7 @@ fmt_scaled(long long number, char *result)
unsigned int i;
unit_type unit = NONE;
abval = (number < 0LL) ? -number : number; /* no long long_abs yet */
abval = llabs(number);
/* Not every negative long long has a positive representation.
* Also check for numbers that are just too darned big to format

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.246 2017/02/28 06:10:08 djm Exp $ */
/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1850,11 +1850,11 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
if (r != SSH_ERR_MAC_INVALID)
goto out;
logit("Corrupted MAC on input.");
if (need > PACKET_MAX_SIZE)
if (need + block_size > PACKET_MAX_SIZE)
return SSH_ERR_INTERNAL_ERROR;
return ssh_packet_start_discard(ssh, enc, mac,
sshbuf_len(state->incoming_packet),
PACKET_MAX_SIZE - need);
PACKET_MAX_SIZE - need - block_size);
}
/* Remove MAC from input buffer */
DBG(debug("MAC #%d ok", state->p_read.seqnr));

View File

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

View File

@ -222,6 +222,7 @@ unit:
$$V ${.OBJDIR}/unittests/sshkey/test_sshkey \
-d ${.CURDIR}/unittests/sshkey/testdata ; \
$$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \
$$V ${.OBJDIR}/unittests/conversion/test_conversion ; \
$$V ${.OBJDIR}/unittests/kex/test_kex ; \
$$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \
-d ${.CURDIR}/unittests/hostkeys/testdata ; \

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-file.sh,v 1.4 2016/12/16 02:48:55 djm Exp $
# $OpenBSD: cert-file.sh,v 1.5 2017/03/11 23:44:16 djm Exp $
# Placed in the Public Domain.
tid="ssh with certificates"
@ -17,24 +17,59 @@ ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key3 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key4 || \
fatal "ssh-keygen failed"
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key5 || \
fatal "ssh-keygen failed"
# Move the certificate to a different address to better control
# when it is offered.
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key1 ||
fail "couldn't sign user_key1 with user_ca_key1"
fatal "couldn't sign user_key1 with user_ca_key1"
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_1.pub
${SSHKEYGEN} -q -s $OBJ/user_ca_key2 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key1 ||
fail "couldn't sign user_key1 with user_ca_key2"
fatal "couldn't sign user_key1 with user_ca_key2"
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key3 ||
fatal "couldn't sign user_key3 with user_ca_key1"
rm $OBJ/user_key3.pub # to test use of private key w/o public half.
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
-z $$ -n ${USER} $OBJ/user_key4 ||
fatal "couldn't sign user_key4 with user_ca_key1"
rm $OBJ/user_key4 $OBJ/user_key4.pub # to test no matching pub/private key case.
trace 'try with identity files'
opts="-F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
opts2="$opts -i $OBJ/user_key1 -i $OBJ/user_key2"
echo "cert-authority $(cat $OBJ/user_ca_key1.pub)" > $OBJ/authorized_keys_$USER
# Make a clean config that doesn't have any pre-added identities.
cat $OBJ/ssh_proxy | grep -v IdentityFile > $OBJ/no_identity_config
# XXX: verify that certificate used was what we expect. Needs exposure of
# keys via enviornment variable or similar.
for p in ${SSH_PROTOCOLS}; do
# Key with no .pub should work - finding the equivalent *-cert.pub.
verbose "protocol $p: identity cert with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
# CertificateFile matching private key with no .pub file should work.
verbose "protocol $p: CertificateFile with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-oCertificateFile=$OBJ/user_key3-cert.pub \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
# Just keys should fail
verbose "protocol $p: plain keys"
${SSH} $opts2 somehost exit 5$p
r=$?
if [ $r -eq 5$p ]; then
@ -42,6 +77,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Keys with untrusted cert should fail.
verbose "protocol $p: untrusted cert"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
@ -50,6 +86,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Good cert with bad key should fail.
verbose "protocol $p: good cert, bad key"
opts3="$opts -i $OBJ/user_key2"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
@ -59,6 +96,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Keys with one trusted cert, should succeed.
verbose "protocol $p: single trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
@ -67,6 +105,7 @@ for p in ${SSH_PROTOCOLS}; do
fi
# Multiple certs and keys, with one trusted cert, should succeed.
verbose "protocol $p: multiple trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
@ -74,14 +113,6 @@ for p in ${SSH_PROTOCOLS}; do
if [ $r -ne 5$p ]; then
fail "ssh failed with multiple certs in protocol $p"
fi
#Keys with trusted certificate specified in config options, should succeed.
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
if [ $r -ne 5$p ]; then
fail "ssh failed with trusted cert in config in protocol $p"
fi
done
#next, using an agent in combination with the keys

View File

@ -10,7 +10,7 @@ start_sshd
base=33
last=$PORT
fwd=""
CTL=$OBJ/ctl-sock
CTL=/tmp/openssh.regress.ctl-sock.$$
for j in 0 1 2; do
for i in 0 1 2; do

View File

@ -1,13 +1,8 @@
# $OpenBSD: keytype.sh,v 1.4 2015/07/10 06:23:25 markus Exp $
# $OpenBSD: keytype.sh,v 1.5 2017/03/20 22:08:06 djm Exp $
# Placed in the Public Domain.
tid="login with different key types"
TIME=`which time 2>/dev/null`
if test ! -x "$TIME"; then
TIME=""
fi
cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
@ -26,8 +21,8 @@ for kt in $ktypes; do
rm -f $OBJ/key.$kt
bits=`echo ${kt} | awk -F- '{print $2}'`
type=`echo ${kt} | awk -F- '{print $1}'`
printf "keygen $type, $bits bits:\t"
${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\
verbose "keygen $type, $bits bits"
${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\
fail "ssh-keygen for type $type, $bits bits failed"
done
@ -63,8 +58,8 @@ for ut in $ktypes; do
) > $OBJ/known_hosts
cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER
for i in $tries; do
printf "userkey $ut, hostkey ${ht}:\t"
${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
verbose "userkey $ut, hostkey ${ht}"
${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
fail "ssh userkey $ut, hostkey $ht failed"
fi

View File

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

View File

@ -1,53 +1,45 @@
using module .\PlatformAbstractLayer.psm1

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

View File

@ -1,6 +1,4 @@
using module .\PlatformAbstractLayer.psm1
Describe "Tests for powershell over ssh" -Tags "Scenario" {
Describe "Tests for powershell over ssh" -Tags "Scenario" {
BeforeAll {
$defaultParamValues = $PSDefaultParameterValues.Clone()
#Skip on windows powershell. this feature only supported in powershell core from git

View File

@ -0,0 +1,42 @@
Run OpenSSH Pester Tests:
==================================
#### To setup the test environment before test run:
```powershell
Import-Module .\openssh-portable\contrib\win32\openssh\OpenSSHTestHelper.psm1 Force
Setup-OpenSSHTestEnvironment
```
`Setup-OpenSSHTestEnvironment` contains below parameters:
* `-OpenSSHBinPath`: Specify the location where ssh.exe should be picked up. If not specified, the function will prompt to user if he/she want to choose the first ssh.exe found in `$env:path` if exists.
* `-TestDataPath`: Specify the location where the test binaries deploy to. The default is `$env:SystemDrive\OpenSSHTests` if it not specified.
* `-Quiet`: If it is set, the function will do all the changes without prompting to user to confirm.
* `-DebugMode`: If it is set, the subsequent tests will be running in debug mode. User can modify by setting $OpenSSHTestInfo["DebugMode"] .
#### To run the test suites:
```powershell
Run-OpenSSHE2ETest
Run-OpenSSHUnitTest
```
#### To run a particular test, just run the script or the executatlbe directly
```powershell
C:\git\openssh-portable\regress\pesterTests\SCP.Tests.ps1
C:\git\openssh-portable\bin\x64\Release\unittest-bitmap\unittest-bitmap.exe
```
#### To verify / modify (Ex- DebugMode) the Test setup environment
```powershell
$OpenSSHTestInfo
$OpenSSHTestInfo["DebugMode"] = $true
```
#### To revert what's done in Setup-OpenSSHTestEnvironment:
```powershell
Cleanup-OpenSSHTestEnvironment
```

View File

@ -1,30 +1,39 @@
using module .\PlatformAbstractLayer.psm1

#covered -i -p -q -r -v -c -S -C
#todo: -F, -l and -P should be tested over the network
Describe "Tests for scp command" -Tags "CI" {
BeforeAll {
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
}
if(-not (Test-Path $OpenSSHTestInfo["TestDataPath"]))
{
$null = New-Item $OpenSSHTestInfo["TestDataPath"] -ItemType directory -Force -ErrorAction SilentlyContinue
}
$fileName1 = "test.txt"
$fileName2 = "test2.txt"
$SourceDirName = "SourceDir"
$SourceDir = Join-Path ${TestDrive} $SourceDirName
$SourceDir = Join-Path "$($OpenSSHTestInfo["TestDataPath"])\SCP" $SourceDirName
$SourceFilePath = Join-Path $SourceDir $fileName1
$DestinationDir = Join-Path ${TestDrive} "DestDir"
$DestinationDir = Join-Path "$($OpenSSHTestInfo["TestDataPath"])\SCP" "DestDir"
$DestinationFilePath = Join-Path $DestinationDir $fileName1
$NestedSourceDir= Join-Path $SourceDir "nested"
$NestedSourceFilePath = Join-Path $NestedSourceDir $fileName2
$null = New-Item $SourceDir -ItemType directory -Force
$null = New-Item $NestedSourceDir -ItemType directory -Force
$null = New-item -path $SourceFilePath -force
$null = New-item -path $NestedSourceFilePath -force
$null = New-Item $SourceDir -ItemType directory -Force -ErrorAction SilentlyContinue
$null = New-Item $NestedSourceDir -ItemType directory -Force -ErrorAction SilentlyContinue
$null = New-item -path $SourceFilePath -force -ErrorAction SilentlyContinue
$null = New-item -path $NestedSourceFilePath -force -ErrorAction SilentlyContinue
"Test content111" | Set-content -Path $SourceFilePath
"Test content in nested dir" | Set-content -Path $NestedSourceFilePath
$null = New-Item $DestinationDir -ItemType directory -Force
$null = New-Item $DestinationDir -ItemType directory -Force -ErrorAction SilentlyContinue
$sshcmd = (get-command ssh).Path
[Machine] $client = [Machine]::new([MachineRole]::Client)
[Machine] $server = [Machine]::new([MachineRole]::Server)
$client.SetupClient($server)
$server.SetupServer($client)
$server = $OpenSSHTestInfo["Target"]
$port = $OpenSSHTestInfo["Port"]
$ssouser = $OpenSSHTestInfo["SSOUser"]
$script:logNum = 0
$testData = @(
@ -32,31 +41,37 @@ Describe "Tests for scp command" -Tags "CI" {
Title = 'Simple copy local file to local file'
Source = $SourceFilePath
Destination = $DestinationFilePath
Options = "-P $port "
},
@{
Title = 'Simple copy local file to remote file'
Source = $SourceFilePath
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
Destination = "$($ssouser)@$($server):$DestinationFilePath"
Options = "-P $port -S $sshcmd"
},
@{
Title = 'Simple copy remote file to local file'
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
Source = "$($ssouser)@$($server):$SourceFilePath"
Destination = $DestinationFilePath
Options = "-P $port -p -c aes128-ctr -C"
},
@{
Title = 'Simple copy local file to local dir'
Source = $SourceFilePath
Destination = $DestinationDir
Options = "-P $port "
},
@{
Title = 'simple copy local file to remote dir'
Source = $SourceFilePath
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
Destination = "$($ssouser)@$($server):$DestinationDir"
Options = "-P $port -C -q"
},
@{
Title = 'simple copy remote file to local dir'
Source = "$($server.localAdminUserName)@$($server.MachineName):$SourceFilePath"
Source = "$($ssouser)@$($server):$SourceFilePath"
Destination = $DestinationDir
Options = "-P $port "
}
)
@ -64,28 +79,46 @@ Describe "Tests for scp command" -Tags "CI" {
@{
Title = 'copy from local dir to remote dir'
Source = $sourceDir
Destination = "$($server.localAdminUserName)@$($server.MachineName):$DestinationDir"
Destination = "$($ssouser)@$($server):$DestinationDir"
Options = "-P $port -r -p -c aes128-ctr"
},
<# @{
@{
Title = 'copy from local dir to local dir'
Source = $sourceDir
Destination = $DestinationDir
},#>
Options = "-r "
},
@{
Title = 'copy from remote dir to local dir'
Source = "$($server.localAdminUserName)@$($server.MachineName):$sourceDir"
Source = "$($ssouser)@$($server):$sourceDir"
Destination = $DestinationDir
Options = "-P $port -C -r -q"
}
)
# for the first time, delete the existing log files.
if ($OpenSSHTestInfo['DebugMode'])
{
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
}
function CheckTarget {
param([string]$target)
if(-not (Test-path $target))
{
Copy-Item .\logs\ssh-agent.log ".\logs\failedagent$script:logNum.log" -Force
Copy-Item .\logs\sshd.log ".\logs\failedsshd$script:logNum.log" -Force
if( $OpenSSHTestInfo["DebugMode"])
{
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\failedagent$script:logNum.log" -Force
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\failedsshd$script:logNum.log" -Force
$script:logNum++
# clear the ssh-agent, sshd logs so that next testcase will get fresh logs.
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
}
return $false
}
return $true
@ -93,12 +126,22 @@ Describe "Tests for scp command" -Tags "CI" {
}
AfterAll {
$client.CleanupClient()
$server.CleanupServer()
if($OpenSSHTestInfo -eq $null)
{
#do nothing
}
elseif( -not $OpenSSHTestInfo['DebugMode'])
{
if(-not [string]::IsNullOrEmpty($SourceDir))
{
Get-Item $SourceDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
if(-not [string]::IsNullOrEmpty($DestinationDir))
{
Get-Item $DestinationDir | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
}
BeforeAll {
$null = New-Item $DestinationDir -ItemType directory -Force -ErrorAction SilentlyContinue
@ -108,167 +151,47 @@ Describe "Tests for scp command" -Tags "CI" {
Get-ChildItem $DestinationDir -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
<#Context "SCP usage" {
It 'SCP usage' {
#TODO: usage output does not redirect to file
}
}#>
Context "Key is Secured in ssh-agent on server" {
BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$privateKeyFile = $client.clientPrivateKeyPaths[0]
}
BeforeEach {
if ($env:DebugMode)
It 'File copy: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination, $Options)
iex "scp $Options $Source $Destination"
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length ).Length -eq 0
$equal | Should Be $true
if($Options.contains("-p"))
{
Stop-Service ssh-agent -Force
Start-Sleep 2
Remove-Item .\logs\ssh-agent.log -Force -ErrorAction ignore
Remove-Item .\logs\sshd.log -Force -ErrorAction ignore
Start-Service sshd
}
}
AfterAll {
$Server.CleanupHostKeys()
}
It 'File copy with -i option and private key: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination)
.\scp -i $privateKeyFile $Source $Destination
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath).LastWriteTime.DateTime (Get-ChildItem -path $DestinationFilePath).LastWriteTime.DateTime ).Length -eq 0
$equal | Should Be $true
}
}
It 'Directory recursive copy with -i option and private key: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
It 'Directory recursive copy: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination, $Options)
.\scp -r -i $privateKeyFile $Source $Destination
iex "scp $Options $Source $Destination"
$LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
if($Options.contains("-p"))
{
$equal = @(Compare-Object (Get-Item -path $SourceDir).LastWriteTime.DateTime (Get-Item -path (join-path $DestinationDir $SourceDirName)).LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
}
Context "Single signon with keys -p -v -c option Secured in ssh-agent" {
BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$identifyFile = $client.clientPrivateKeyPaths[0]
#setup single signon
.\ssh-add.exe $identifyFile
}
AfterAll {
$Server.CleanupHostKeys()
#cleanup single signon
.\ssh-add.exe -D
}
It 'File copy with -S -v option (positive)' {
.\scp -S .\ssh.exe -v $SourceFilePath "$($server.localAdminUserName)@$($server.MachineName):$DestinationFilePath"
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
It 'File copy with -p -c option: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination)
.\scp -p -c aes128-ctr -C $Source $Destination
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
It 'Directory recursive copy with -r -p -c option: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -p -c aes128-ctr $Source $Destination
$LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
}
Context "Private key authentication with -i -C -q options. host keys are not secured on server" {
BeforeAll {
$identifyFile = $client.clientPrivateKeyPaths[0]
}
It 'File copy with -i -C -q options: <Title> ' -TestCases:$testData{
param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -C -q $Source $Destination
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
It 'Directory recursive copy with -i -C -r and -q options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -i $identifyFile -C -r -q $Source $Destination
$LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length).Length -eq 0
$equal | Should Be $true
}
}
Context "Password authentication" {
BeforeAll {
$client.AddPasswordSetting($server.localAdminPassword)
}
AfterAll {
$client.CleanupPasswordSetting()
}
It 'File copy with -p options: <Title> ' -TestCases:$testData {
param([string]$Title, $Source, $Destination)
.\scp -p $Source $Destination
$LASTEXITCODE | Should Be 0
#validate file content. DestPath is the path to the file.
CheckTarget -target $DestinationFilePath | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -path $SourceFilePath) (Get-ChildItem -path $DestinationFilePath) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
It 'Directory recursive copy with -p and -v options: <Title> ' -TestCases:$testData1 {
param([string]$Title, $Source, $Destination)
.\scp -r -p $Source $Destination
$LASTEXITCODE | Should Be 0
CheckTarget -target (join-path $DestinationDir $SourceDirName) | Should Be $true
$equal = @(Compare-Object (Get-Item -path $SourceDir ) (Get-Item -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir) (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ) -Property Name, Length, LastWriteTime.DateTime).Length -eq 0
if($Options.contains("-p"))
{
$equal = @(Compare-Object (Get-ChildItem -Recurse -path $SourceDir).LastWriteTime.DateTime (Get-ChildItem -Recurse -path (join-path $DestinationDir $SourceDirName) ).LastWriteTime.DateTime).Length -eq 0
$equal | Should Be $true
}
}

View File

@ -1,8 +1,16 @@
using module .\PlatformAbstractLayer.psm1
Describe "SFTP Testcases" -Tags "CI" {
Describe "SFTP Test Cases" -Tags "CI" {
BeforeAll {
$rootDirectory = $TestDrive
if($OpenSSHTestInfo -eq $null)
{
Throw "`$OpenSSHTestInfo is null. Please run Setup-OpenSSHTestEnvironment to setup test environment."
}
if(-not (Test-Path $OpenSSHTestInfo["TestDataPath"]))
{
$null = New-Item $OpenSSHTestInfo["TestDataPath"] -ItemType directory -Force -ErrorAction SilentlyContinue
}
$rootDirectory = "$($OpenSSHTestInfo["TestDataPath"])\SFTP"
$outputFileName = "output.txt"
$batchFileName = "sftp-batchcmds.txt"
@ -25,51 +33,48 @@ Describe "SFTP Testcases" -Tags "CI" {
$null = New-Item $tempFilePath -ItemType file -Force -value "temp file data"
$null = New-Item $tempUnicodeFilePath -ItemType file -Force -value "temp file data"
$expectedOutputDelimiter = "#DL$"
[Machine] $client = [Machine]::new([MachineRole]::Client)
[Machine] $server = [Machine]::new([MachineRole]::Server)
$client.SetupClient($server)
$server.SetupServer($client)
$server = $OpenSSHTestInfo["Target"]
$port = $OpenSSHTestInfo["Port"]
$ssouser = $OpenSSHTestInfo["SSOUser"]
$script:testId = 1
$testData1 = @(
@{
title = "put, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "put $tempFilePath $serverDirectory
ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempFileName)
},
@{
title = "get, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "get $tempFilePath $clientDirectory
ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempFileName)
},
@{
title = "mput, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "mput $tempFilePath $serverDirectory
ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempFileName)
},
@{
title = "mget, ls for non-unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "mget $tempFilePath $clientDirectory
ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempFileName)
},
@{
title = "mkdir, cd, pwd for non-unicode directory names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "cd $serverdirectory
mkdir server_test_dir
cd server_test_dir
@ -78,8 +83,8 @@ Describe "SFTP Testcases" -Tags "CI" {
},
@{
Title = "lmkdir, lcd, lpwd for non-unicode directory names"
LogonStr = "$($server.localAdminUserName)@$($server.MachineName)"
Options = '-i $identifyFile'
LogonStr = "$($ssouser)@$($server)"
Options = ''
Commands = "lcd $clientDirectory
lmkdir client_test_dir
lcd client_test_dir
@ -88,40 +93,40 @@ Describe "SFTP Testcases" -Tags "CI" {
},
@{
title = "put, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "put $tempUnicodeFilePath $serverDirectory
ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempUnicodeFileName)
},
@{
title = "get, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "get $tempUnicodeFilePath $clientDirectory
ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempUnicodeFileName)
},
@{
title = "mput, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "mput $tempUnicodeFilePath $serverDirectory
ls $serverDirectory"
expectedoutput = (join-path $serverdirectory $tempUnicodeFileName)
},
@{
title = "mget, ls for unicode file names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "mget $tempUnicodeFilePath $clientDirectory
ls $clientDirectory"
expectedoutput = (join-path $clientDirectory $tempUnicodeFileName)
},
@{
title = "mkdir, cd, pwd for unicode directory names"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile'
logonstr = "$($ssouser)@$($server)"
options = ''
commands = "cd $serverdirectory
mkdir server_test_dir_язык
cd server_test_dir_язык
@ -130,8 +135,8 @@ Describe "SFTP Testcases" -Tags "CI" {
},
@{
Title = "lmkdir, lcd, lpwd for unicode directory names"
LogonStr = "$($server.localAdminUserName)@$($server.MachineName)"
Options = '-i $identifyFile'
LogonStr = "$($ssouser)@$($server)"
Options = ''
Commands = "lcd $clientDirectory
lmkdir client_test_dir_язык
lcd client_test_dir_язык
@ -144,8 +149,8 @@ Describe "SFTP Testcases" -Tags "CI" {
$testData2 = @(
@{
title = "rm, rmdir, rename for unicode file, directory"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile -b $batchFilePath'
logonstr = "$($ssouser)@$($server)"
options = '-b $batchFilePath'
tmpFileName1 = $tempUnicodeFileName
tmpFilePath1 = $tempUnicodeFilePath
@ -159,8 +164,8 @@ Describe "SFTP Testcases" -Tags "CI" {
},
@{
title = "rm, rmdir, rename for non-unicode file, directory"
logonstr = "$($server.localadminusername)@$($server.machinename)"
options = '-i $identifyfile -b $batchFilePath'
logonstr = "$($ssouser)@$($server)"
options = '-b $batchFilePath'
tmpFileName1 = $tempFileName
tmpFilePath1 = $tempFilePath
@ -173,25 +178,38 @@ Describe "SFTP Testcases" -Tags "CI" {
tmpDirectoryPath2 = (join-path $serverDirectory "test_dir_2")
}
)
# for the first time, delete the existing log files.
if ($OpenSSHTestInfo['DebugMode'])
{
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction ignore
}
function CopyDebugLogs {
if($OpenSSHTestInfo["DebugMode"])
{
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent_$script:testId.log" -Force
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd_$script:testId.log" -Force
Copy-Item "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server_$script:testId.log" -Force
$script:testId++
# clear the ssh-agent, sshd logs so that next testcase will get fresh logs.
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\ssh-agent.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sshd.log" -Force -ErrorAction ignore
Clear-Content "$($OpenSSHTestInfo['OpenSSHBinPath'])\logs\sftp-server.log" -Force -ErrorAction ignore
}
}
}
AfterAll {
$client.CleanupClient()
$server.CleanupServer()
}
Context "Single signon" {
BeforeAll {
$Server.SecureHostKeys($server.PrivateHostKeyPaths)
$identifyFile = $client.clientPrivateKeyPaths[0]
.\ssh-add.exe $identifyFile #setup single signon
}
AfterAll {
$Server.CleanupHostKeys()
.\ssh-add.exe -D #cleanup single signon
if(!$OpenSSHTestInfo["DebugMode"])
{
Get-Item $rootDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
}
BeforeEach {
Get-ChildItem $serverDirectory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
@ -200,29 +218,31 @@ Describe "SFTP Testcases" -Tags "CI" {
Remove-Item $outputFilePath
}
AfterEach {
CopyDebugLogs
}
It '<Title>' -TestCases:$testData1 {
param([string]$Title, $LogonStr, $Options, $Commands, $ExpectedOutput, $SkipVerification = $false)
param([string]$Title, $LogonStr, $Options, $Commands, $ExpectedOutput)
Set-Content $batchFilePath -Encoding UTF8 -value $Commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) -b $batchFilePath $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) -b $batchFilePath $($LogonStr) > $outputFilePath")
iex $str
#validate file content.
$($ExpectedOutput).split($expectedOutputDelimiter) | foreach {
Test-Path ($_) | Should be $true
}
Test-Path $ExpectedOutput | Should be $true
}
It '<Title>' -TestCases:$testData2 {
param([string]$Title, $LogonStr, $Options, $tmpFileName1, $tmpFilePath1, $tmpFileName2, $tmpFilePath2, $tmpDirectoryName1, $tmpDirectoryPath1, $tmpDirectoryName2, $tmpDirectoryPath2, $SkipVerification = $false)
param([string]$Title, $LogonStr, $Options, $tmpFileName1, $tmpFilePath1, $tmpFileName2, $tmpFilePath2, $tmpDirectoryName1, $tmpDirectoryPath1, $tmpDirectoryName2, $tmpDirectoryPath2)
#rm (remove file)
$commands = "mkdir $tmpDirectoryPath1
put $tmpFilePath1 $tmpDirectoryPath1
ls $tmpDirectoryPath1"
Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) $($LogonStr) > $outputFilePath")
iex $str
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $true
$commands = "rm $tmpDirectoryPath1\*
@ -230,8 +250,8 @@ Describe "SFTP Testcases" -Tags "CI" {
pwd
"
Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) $($LogonStr) > $outputFilePath")
iex $str
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName1) | Should be $false
#rename file
@ -241,8 +261,8 @@ Describe "SFTP Testcases" -Tags "CI" {
ls $tmpDirectoryPath1
pwd"
Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) $($LogonStr) > $outputFilePath")
iex $str
Test-Path (join-path $tmpDirectoryPath1 $tmpFileName2) | Should be $true
#rename directory
@ -251,8 +271,8 @@ Describe "SFTP Testcases" -Tags "CI" {
rename $tmpDirectoryPath1 $tmpDirectoryPath2
ls $serverDirectory"
Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) $($LogonStr) > $outputFilePath")
iex $str
Test-Path $tmpDirectoryPath2 | Should be $true
#rmdir (remove directory)
@ -260,9 +280,8 @@ Describe "SFTP Testcases" -Tags "CI" {
$commands = "rmdir $tmpDirectoryPath2
ls $serverDirectory"
Set-Content $batchFilePath -Encoding UTF8 -value $commands
$str = $ExecutionContext.InvokeCommand.ExpandString(".\sftp $($Options) $($LogonStr) > $outputFilePath")
$client.RunCmd($str)
$str = $ExecutionContext.InvokeCommand.ExpandString("sftp -P $port $($Options) $($LogonStr) > $outputFilePath")
iex $str
Test-Path $tmpDirectoryPath2 | Should be $false
}
}
}

View File

@ -1,8 +1,6 @@
using module .\PlatformAbstractLayer.psm1
#covered -i -q -v -l -c -C
#covered -i -q -v -l -c -C
#todo: -S -F -V -e
Describe "Tests for ssh command" -Tags "CI" {
Describe "Tests for ssh command" -Tags "Scenario" {
BeforeAll {
$fileName = "test.txt"
$filePath = Join-Path ${TestDrive} $fileName

View File

@ -1,6 +1,4 @@
using module .\PlatformAbstractLayer.psm1
Describe "Tests of sshd_config" -Tags "CI" {
Describe "Tests of sshd_config" -Tags "Scenario" {
BeforeAll {
$fileName = "test.txt"
$filePath = Join-Path ${TestDrive} $fileName

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
# $OpenBSD: Makefile,v 1.7 2016/08/19 06:44:13 djm Exp $
REGRESS_FAIL_EARLY= yes
SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match
# $OpenBSD: Makefile,v 1.9 2017/03/14 01:20:29 dtucker Exp $
REGRESS_FAIL_EARLY?= yes
SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion
.include <bsd.subdir.mk>

View File

@ -0,0 +1,10 @@
# $OpenBSD: Makefile,v 1.1 2017/03/14 01:20:29 dtucker Exp $
PROG=test_conversion
SRCS=tests.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG}
.include <bsd.regress.mk>

View File

@ -0,0 +1,51 @@
/* $OpenBSD: tests.c,v 1.1 2017/03/14 01:20:29 dtucker Exp $ */
/*
* Regress test for conversions
*
* Placed in the public domain
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "../test_helper/test_helper.h"
#include "misc.h"
void
tests(void)
{
char buf[1024];
TEST_START("conversion_convtime");
ASSERT_LONG_EQ(convtime("0"), 0);
ASSERT_LONG_EQ(convtime("1"), 1);
ASSERT_LONG_EQ(convtime("1S"), 1);
/* from the examples in the comment above the function */
ASSERT_LONG_EQ(convtime("90m"), 5400);
ASSERT_LONG_EQ(convtime("1h30m"), 5400);
ASSERT_LONG_EQ(convtime("2d"), 172800);
ASSERT_LONG_EQ(convtime("1w"), 604800);
/* negative time is not allowed */
ASSERT_LONG_EQ(convtime("-7"), -1);
ASSERT_LONG_EQ(convtime("-9d"), -1);
/* overflow */
snprintf(buf, sizeof buf, "%llu", (unsigned long long)LONG_MAX + 1);
ASSERT_LONG_EQ(convtime(buf), -1);
/* overflow with multiplier */
snprintf(buf, sizeof buf, "%lluM", (unsigned long long)LONG_MAX/60 + 1);
ASSERT_LONG_EQ(convtime(buf), -1);
ASSERT_LONG_EQ(convtime("1000000000000000000000w"), -1);
TEST_DONE();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */
/* $OpenBSD: test_helper.c,v 1.7 2017/03/14 01:10:07 dtucker Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@ -441,6 +441,17 @@ assert_u_int(const char *file, int line, const char *a1, const char *a2,
test_die();
}
void
assert_long(const char *file, int line, const char *a1, const char *a2,
long aa1, long aa2, enum test_predicate pred)
{
TEST_CHECK(aa1, aa2, pred);
test_header(file, line, a1, a2, "LONG", pred);
fprintf(stderr, "%12s = %ld / 0x%lx\n", a1, aa1, aa1);
fprintf(stderr, "%12s = %ld / 0x%lx\n", a2, aa2, aa2);
test_die();
}
void
assert_long_long(const char *file, int line, const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */
/* $OpenBSD: test_helper.h,v 1.7 2017/03/14 01:10:07 dtucker Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@ -67,6 +67,9 @@ void assert_size_t(const char *file, int line,
void assert_u_int(const char *file, int line,
const char *a1, const char *a2,
u_int aa1, u_int aa2, enum test_predicate pred);
void assert_long(const char *file, int line,
const char *a1, const char *a2,
long aa1, long aa2, enum test_predicate pred);
void assert_long_long(const char *file, int line,
const char *a1, const char *a2,
long long aa1, long long aa2, enum test_predicate pred);
@ -110,6 +113,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_U_INT_EQ(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_LONG_EQ(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_LONG_LONG_EQ(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_EQ)
#define ASSERT_CHAR_EQ(a1, a2) \
@ -139,6 +144,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_U_INT_NE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_LONG_NE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_LONG_LONG_NE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_NE)
#define ASSERT_CHAR_NE(a1, a2) \
@ -166,6 +173,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_U_INT_LT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_LONG_LT(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_LONG_LONG_LT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LT)
#define ASSERT_CHAR_LT(a1, a2) \
@ -193,6 +202,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_U_INT_LE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_LONG_LE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_LONG_LONG_LE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_LE)
#define ASSERT_CHAR_LE(a1, a2) \
@ -220,6 +231,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_U_INT_GT(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_LONG_GT(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_LONG_LONG_GT(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GT)
#define ASSERT_CHAR_GT(a1, a2) \
@ -247,6 +260,8 @@ void assert_u64(const char *file, int line,
assert_size_t(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_U_INT_GE(a1, a2) \
assert_u_int(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_LONG_GE(a1, a2) \
assert_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_LONG_LONG_GE(a1, a2) \
assert_long_long(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE)
#define ASSERT_CHAR_GE(a1, a2) \

View File

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

View File

@ -50,6 +50,9 @@
#include <elf.h>
#include <asm/unistd.h>
#ifdef __s390__
#include <asm/zcrypt.h>
#endif
#include <errno.h>
#include <signal.h>
@ -73,19 +76,35 @@
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define ARG_LO_OFFSET 0
# define ARG_HI_OFFSET sizeof(uint32_t)
#elif __BYTE_ORDER == __BIG_ENDIAN
# define ARG_LO_OFFSET sizeof(uint32_t)
# define ARG_HI_OFFSET 0
#else
#error "Unknown endianness"
#endif
/* Simple helpers to avoid manual errors (but larger BPF programs). */
#define SC_DENY(_nr, _errno) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno))
#define SC_ALLOW(_nr) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 4), \
/* load first syscall argument */ \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \
/* load and test first syscall argument, low word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)])), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_arg_val), 0, 1), \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
((_arg_val) & 0xFFFFFFFF), 0, 3), \
/* load and test first syscall argument, high word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
(((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
@ -104,108 +123,122 @@ static const struct sock_filter preauth_insns[] = {
/* Syscalls to non-fatally deny */
#ifdef __NR_lstat
SC_DENY(lstat, EACCES),
SC_DENY(__NR_lstat, EACCES),
#endif
#ifdef __NR_lstat64
SC_DENY(lstat64, EACCES),
SC_DENY(__NR_lstat64, EACCES),
#endif
#ifdef __NR_fstat
SC_DENY(fstat, EACCES),
SC_DENY(__NR_fstat, EACCES),
#endif
#ifdef __NR_fstat64
SC_DENY(fstat64, EACCES),
SC_DENY(__NR_fstat64, EACCES),
#endif
#ifdef __NR_open
SC_DENY(open, EACCES),
SC_DENY(__NR_open, EACCES),
#endif
#ifdef __NR_openat
SC_DENY(openat, EACCES),
SC_DENY(__NR_openat, EACCES),
#endif
#ifdef __NR_newfstatat
SC_DENY(newfstatat, EACCES),
SC_DENY(__NR_newfstatat, EACCES),
#endif
#ifdef __NR_stat
SC_DENY(stat, EACCES),
SC_DENY(__NR_stat, EACCES),
#endif
#ifdef __NR_stat64
SC_DENY(stat64, EACCES),
SC_DENY(__NR_stat64, EACCES),
#endif
/* Syscalls to permit */
#ifdef __NR_brk
SC_ALLOW(brk),
SC_ALLOW(__NR_brk),
#endif
#ifdef __NR_clock_gettime
SC_ALLOW(clock_gettime),
SC_ALLOW(__NR_clock_gettime),
#endif
#ifdef __NR_close
SC_ALLOW(close),
SC_ALLOW(__NR_close),
#endif
#ifdef __NR_exit
SC_ALLOW(exit),
SC_ALLOW(__NR_exit),
#endif
#ifdef __NR_exit_group
SC_ALLOW(exit_group),
SC_ALLOW(__NR_exit_group),
#endif
#ifdef __NR_getpgid
SC_ALLOW(getpgid),
SC_ALLOW(__NR_getpgid),
#endif
#ifdef __NR_getpid
SC_ALLOW(getpid),
SC_ALLOW(__NR_getpid),
#endif
#ifdef __NR_getrandom
SC_ALLOW(getrandom),
SC_ALLOW(__NR_getrandom),
#endif
#ifdef __NR_gettimeofday
SC_ALLOW(gettimeofday),
SC_ALLOW(__NR_gettimeofday),
#endif
#ifdef __NR_madvise
SC_ALLOW(madvise),
SC_ALLOW(__NR_madvise),
#endif
#ifdef __NR_mmap
SC_ALLOW(mmap),
SC_ALLOW(__NR_mmap),
#endif
#ifdef __NR_mmap2
SC_ALLOW(mmap2),
SC_ALLOW(__NR_mmap2),
#endif
#ifdef __NR_mremap
SC_ALLOW(mremap),
SC_ALLOW(__NR_mremap),
#endif
#ifdef __NR_munmap
SC_ALLOW(munmap),
SC_ALLOW(__NR_munmap),
#endif
#ifdef __NR__newselect
SC_ALLOW(_newselect),
SC_ALLOW(__NR__newselect),
#endif
#ifdef __NR_poll
SC_ALLOW(poll),
SC_ALLOW(__NR_poll),
#endif
#ifdef __NR_pselect6
SC_ALLOW(pselect6),
SC_ALLOW(__NR_pselect6),
#endif
#ifdef __NR_read
SC_ALLOW(read),
SC_ALLOW(__NR_read),
#endif
#ifdef __NR_rt_sigprocmask
SC_ALLOW(rt_sigprocmask),
SC_ALLOW(__NR_rt_sigprocmask),
#endif
#ifdef __NR_select
SC_ALLOW(select),
SC_ALLOW(__NR_select),
#endif
#ifdef __NR_shutdown
SC_ALLOW(shutdown),
SC_ALLOW(__NR_shutdown),
#endif
#ifdef __NR_sigprocmask
SC_ALLOW(sigprocmask),
SC_ALLOW(__NR_sigprocmask),
#endif
#ifdef __NR_time
SC_ALLOW(time),
SC_ALLOW(__NR_time),
#endif
#ifdef __NR_write
SC_ALLOW(write),
SC_ALLOW(__NR_write),
#endif
#ifdef __NR_socketcall
SC_ALLOW_ARG(socketcall, 0, SYS_SHUTDOWN),
SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN),
#endif
#if defined(__NR_ioctl) && defined(__s390__)
/* Allow ioctls for ICA crypto card on s390 */
SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT),
#endif
#if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT)
/*
* On Linux x32, the clock_gettime VDSO falls back to the
* x86-64 syscall under some circumstances, e.g.
* https://bugs.debian.org/849923
*/
SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT),
#endif
/* Default deny */

43
scp.c
View File

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

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.305 2017/03/10 04:11:00 dtucker Exp $ */
/* $OpenBSD: servconf.c,v 1.306 2017/03/14 07:19:07 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -535,7 +535,7 @@ static struct {
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
{ "permittty", sPermitTTY, SSHCFG_ALL },
@ -1379,11 +1379,6 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->disable_forwarding;
goto parse_flag;
case sUsePrivilegeSeparation:
intptr = &use_privsep;
multistate_ptr = multistate_privsep;
goto parse_multistate;
case sAllowUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_allow_users >= MAX_ALLOW_USERS)
@ -2112,8 +2107,6 @@ fmt_intarg(ServerOpCodes code, int val)
return fmt_multistate_int(val, multistate_gatewayports);
case sCompression:
return fmt_multistate_int(val, multistate_compression);
case sUsePrivilegeSeparation:
return fmt_multistate_int(val, multistate_privsep);
case sAllowTcpForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
case sAllowStreamLocalForwarding:
@ -2289,7 +2282,6 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
/* string arguments */

View File

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

View File

@ -67,6 +67,13 @@ extern int showprogress;
/* Maximum depth to descend in directory trees */
#define MAX_DIR_DEPTH 64
/* Directory separator characters */
#ifdef HAVE_CYGWIN
# define SFTP_DIRECTORY_CHARS "/\\"
#else /* HAVE_CYGWIN */
# define SFTP_DIRECTORY_CHARS "/"
#endif /* HAVE_CYGWIN */
struct sftp_conn {
int fd_in;
int fd_out;
@ -619,7 +626,7 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
* These can be used to attack recursive ops
* (e.g. send '../../../../etc/passwd')
*/
if (strchr(filename, '/') != NULL) {
if (strpbrk(filename, SFTP_DIRECTORY_CHARS) != NULL) {
error("Server sent suspect path \"%s\" "
"during readdir of \"%s\"", filename, path);
} else if (dir) {

28
sftp.c
View File

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

View File

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

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.216 2017/01/04 02:21:43 djm Exp $ */
/* $OpenBSD: ssh-agent.c,v 1.218 2017/03/15 03:52:30 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -821,7 +821,7 @@ send:
static void
process_remove_smartcard_key(SocketEntry *e)
{
char *provider = NULL, *pin = NULL;
char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
int r, version, success = 0;
Identity *id, *nxt;
Idtab *tab;
@ -831,6 +831,13 @@ process_remove_smartcard_key(SocketEntry *e)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
free(pin);
if (realpath(provider, canonical_provider) == NULL) {
verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
provider, strerror(errno));
goto send;
}
debug("%s: remove %.100s", __func__, canonical_provider);
for (version = 1; version < 3; version++) {
tab = idtab_lookup(version);
for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
@ -838,18 +845,19 @@ process_remove_smartcard_key(SocketEntry *e)
/* Skip file--based keys */
if (id->provider == NULL)
continue;
if (!strcmp(provider, id->provider)) {
if (!strcmp(canonical_provider, id->provider)) {
TAILQ_REMOVE(&tab->idlist, id, next);
free_identity(id);
tab->nentries--;
}
}
}
if (pkcs11_del_provider(provider) == 0)
if (pkcs11_del_provider(canonical_provider) == 0)
success = 1;
else
error("process_remove_smartcard_key:"
" pkcs11_del_provider failed");
send:
free(provider);
send_status(e, success);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.254 2017/02/03 02:56:00 dtucker Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@ -1001,11 +1001,11 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
}
static const char *
identity_sign_encode(struct identity *id)
key_sign_encode(const struct sshkey *key)
{
struct ssh *ssh = active_state;
if (id->key->type == KEY_RSA) {
if (key->type == KEY_RSA) {
switch (ssh->kex->rsa_sha2) {
case 256:
return "rsa-sha2-256";
@ -1013,7 +1013,7 @@ identity_sign_encode(struct identity *id)
return "rsa-sha2-512";
}
}
return key_ssh_name(id->key);
return key_ssh_name(key);
}
static int
@ -1022,30 +1022,49 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
{
Key *prv;
int ret;
const char *alg;
alg = identity_sign_encode(id);
/* the agent supports this key */
if (id->agent_fd != -1)
if (id->key != NULL && id->agent_fd != -1)
return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
data, datalen, alg, compat);
data, datalen, key_sign_encode(id->key), compat);
/*
* we have already loaded the private key or
* the private key is stored in external hardware
*/
if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg,
compat));
if (id->key != NULL &&
(id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))
return (sshkey_sign(id->key, sigp, lenp, data, datalen,
key_sign_encode(id->key), compat));
/* load the private key from the file */
if ((prv = load_identity_file(id)) == NULL)
return SSH_ERR_KEY_NOT_FOUND;
ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat);
ret = sshkey_sign(prv, sigp, lenp, data, datalen,
key_sign_encode(prv), compat);
sshkey_free(prv);
return (ret);
}
static int
id_filename_matches(Identity *id, Identity *private_id)
{
const char *suffixes[] = { ".pub", "-cert.pub", NULL };
size_t len = strlen(id->filename), plen = strlen(private_id->filename);
size_t i, slen;
if (strcmp(id->filename, private_id->filename) == 0)
return 1;
for (i = 0; suffixes[i]; i++) {
slen = strlen(suffixes[i]);
if (len > slen && plen == len - slen &&
strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&
memcmp(id->filename, private_id->filename, plen) == 0)
return 1;
}
return 0;
}
static int
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
{
@ -1088,7 +1107,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
} else {
buffer_put_cstring(&b, authctxt->method->name);
buffer_put_char(&b, have_sig);
buffer_put_cstring(&b, identity_sign_encode(id));
buffer_put_cstring(&b, key_sign_encode(id->key));
}
buffer_put_string(&b, blob, bloblen);
@ -1108,6 +1127,24 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
break;
}
}
/*
* Exact key matches are preferred, but also allow
* filename matches for non-PKCS#11/agent keys that
* didn't load public keys. This supports the case
* of keeping just a private key file and public
* certificate on disk.
*/
if (!matched && !id->isprivate && id->agent_fd == -1 &&
(id->key->flags & SSHKEY_FLAG_EXT) == 0) {
TAILQ_FOREACH(private_id, &authctxt->keys, next) {
if (private_id->key == NULL &&
id_filename_matches(id, private_id)) {
id = private_id;
matched = 1;
break;
}
}
}
if (matched) {
debug2("%s: using private key \"%s\"%s for "
"certificate", __func__, id->filename,
@ -1186,7 +1223,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
packet_put_cstring(authctxt->method->name);
packet_put_char(have_sig);
if (!(datafellows & SSH_BUG_PKAUTH))
packet_put_cstring(identity_sign_encode(id));
packet_put_cstring(key_sign_encode(id->key));
packet_put_string(blob, bloblen);
free(blob);
packet_send();

13
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.483 2017/02/24 03:16:34 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1317,7 +1317,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
continue;
}
pid = spawn_child(path_utf8, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CREATE_NEW_PROCESS_GROUP);
pid = spawn_child(path_utf8, NULL, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CREATE_NEW_PROCESS_GROUP);
free(path_utf8);
close(*newsock);
}
@ -1755,6 +1755,15 @@ main(int ac, char **av)
continue;
key = key_load_private(options.host_key_files[i], "", NULL);
pubkey = key_load_public(options.host_key_files[i], NULL);
if ((pubkey != NULL && pubkey->type == KEY_RSA1) ||
(key != NULL && key->type == KEY_RSA1)) {
verbose("Ignoring RSA1 key %s",
options.host_key_files[i]);
key_free(key);
key_free(pubkey);
continue;
}
if (pubkey == NULL && key != NULL)
pubkey = key_demote(key);
sensitive_data.host_keys[i] = key;

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $
# $OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
@ -93,7 +93,6 @@ AuthorizedKeysFile .ssh/authorized_keys
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.242 2017/02/03 23:01:19 djm Exp $
.Dd $Mdocdate: February 3 2017 $
.\" $OpenBSD: sshd_config.5,v 1.243 2017/03/14 07:19:07 djm Exp $
.Dd $Mdocdate: March 14 2017 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -1494,28 +1494,6 @@ is enabled, you will not be able to run
as a non-root user.
The default is
.Cm no .
.It Cm UsePrivilegeSeparation
Specifies whether
.Xr sshd 8
separates privileges by creating an unprivileged child process
to deal with incoming network traffic.
After successful authentication, another process will be created that has
the privilege of the authenticated user.
The goal of privilege separation is to prevent privilege
escalation by containing any corruption within the unprivileged processes.
The argument must be
.Cm yes ,
.Cm no ,
or
.Cm sandbox .
If
.Cm UsePrivilegeSeparation
is set to
.Cm sandbox
then the pre-authentication unprivileged process is subject to additional
restrictions.
The default is
.Cm sandbox .
.It Cm VersionAddendum
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.

View File

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

View File

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

3
utf8.c
View File

@ -61,7 +61,7 @@ dangerous_locale(void) {
loc = nl_langinfo(CODESET);
return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 &&
strcmp(loc, "ANSI_X3.4-1968") != 0;
strcmp(loc, "ANSI_X3.4-1968") != 0 && strcmp(loc, "646") != 0;
}
static int
@ -332,4 +332,3 @@ msetlocale(void)
/* We can handle this locale */
setlocale(LC_CTYPE, "");
}

View File

@ -1,6 +1,6 @@
/* $OpenBSD: version.h,v 1.78 2016/12/19 04:55:51 djm Exp $ */
/* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */
#define SSH_VERSION "OpenSSH_7.4"
#define SSH_VERSION "OpenSSH_7.5"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE