Source snapshot from Powershell/openssh-portable:latestw_all

This commit is contained in:
Yanbing Wang 2018-02-28 17:13:27 -08:00
parent 0a83df7d22
commit dbbe15ac80
29 changed files with 794 additions and 348 deletions

View File

@ -231,7 +231,7 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
#elif defined(WINDOWS)
HANDLE password_auth_token = NULL;
HANDLE process_custom_lsa_auth(char*, const char*, char*);
HANDLE process_custom_lsa_auth(const char*, const char*, const char*);
void
sys_auth_passwd_lsa(Authctxt *authctxt, const char *password)
@ -253,8 +253,7 @@ sys_auth_passwd_lsa(Authctxt *authctxt, const char *password)
lsa_auth_pkg = utf16_to_utf8(lsa_auth_pkg_w);
if (!lsa_auth_pkg)
fatal("utf16_to_utf8 failed to convert lsa_auth_pkg_w:%ls", lsa_auth_pkg_w);
debug("Authenticating using LSA Auth Package:%ls", lsa_auth_pkg_w);
password_auth_token = process_custom_lsa_auth(authctxt->pw->pw_name, password, lsa_auth_pkg);
}
}

2
auth.c
View File

@ -430,7 +430,7 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
#ifdef WINDOWS
/* Return if the path is absolute. If not, prepend the '%h\\' */
if ((strlen(file) > 1) && (file[1] == ':'))
if(is_absolute_path(file))
return (file);
i = snprintf(ret, sizeof(ret), "%s\\%s", pw->pw_dir, file);

View File

@ -3950,8 +3950,6 @@ channel_disable_adm_local_opens(struct ssh *ssh)
void
channel_clear_permitted_opens(struct ssh *ssh)
{
if(ssh == NULL)
return;
struct ssh_channels *sc = ssh->chanctxt;
sc->permitted_opens = xrecallocarray(sc->permitted_opens,

View File

@ -197,7 +197,8 @@ function Start-OpenSSHBootstrap
Write-BuildMsg -AsVerbose -Message "$gitCmdPath already present in Path environment variable" -Silent:$silent
}
$nativeMSBuildPath = Get-VS2015BuildToolPath
$VS2015Path = Get-VS2015BuildToolPath
$VS2017Path = Get-VS2017BuildToolPath
# Update machine environment path
if ($newMachineEnvironmentPath -ne $machinePath)
@ -206,9 +207,24 @@ function Start-OpenSSHBootstrap
}
$vcVars = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
$packageName = "vcbuildtools"
If (($nativeMSBuildPath -eq $null) -or (-not (Test-Path $VcVars)) -or (-not (Test-Path $sdkPath))) {
$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
#use vs2017 build tool if exists
if($VS2017Path -ne $null)
{
If (-not (Test-Path $sdkPath))
{
$packageName = "windows-sdk-8.1"
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
choco install $packageName -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
}
if(-not (Test-Path $VcVars))
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "VC++ 2015.3 v140 toolset are not installed."
}
}
elseIf (($VS2015Path -eq $null) -or (-not (Test-Path $VcVars)) -or (-not (Test-Path $sdkPath))) {
$packageName = "vcbuildtools"
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
choco install $packageName -ia "/InstallSelectableItems VisualCppBuildTools_ATLMFC_SDK;VisualCppBuildTools_NETFX_SDK;Win81SDK_CppBuildSKUV1" -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
$errorCode = $LASTEXITCODE
@ -234,9 +250,9 @@ function Start-OpenSSHBootstrap
Write-BuildMsg -AsError -ErrorAction Stop -Message "User choose not to restart the machine to apply the changes."
}
}
else
elseif($errorCode -ne 0)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "$packageName installation failed with error code $errorCode"
Write-BuildMsg -AsError -ErrorAction Stop -Message "$packageName installation failed with error code $errorCode."
}
}
else
@ -244,14 +260,11 @@ function Start-OpenSSHBootstrap
Write-BuildMsg -AsVerbose -Message 'VC++ 2015 Build Tools already present.'
}
if($NativeHostArch.ToLower().Startswith('arm'))
{
$nativeMSBuildPath = Get-VS2017BuildToolPath
If ($nativeMSBuildPath -eq $null)
{
#todo, install vs 2017 build tools
Write-BuildMsg -AsError -ErrorAction Stop -Message "The required msbuild 15.0 is not installed on the machine."
}
if($NativeHostArch.ToLower().Startswith('arm') -and ($VS2017Path -eq $null))
{
#todo, install vs 2017 build tools
Write-BuildMsg -AsError -ErrorAction Stop -Message "The required msbuild 15.0 is not installed on the machine."
}
if($OneCore -or ($NativeHostArch.ToLower().Startswith('arm')))
@ -268,7 +281,7 @@ function Start-OpenSSHBootstrap
# 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"
Write-BuildMsg -AsError -ErrorAction Stop -Message "Cannot find Visual Studio 2015 Environment variable VS140COMNTOOlS."
}
$item = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc')
@ -314,7 +327,7 @@ function Copy-LibreSSLSDK
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
if($e -ne $null)
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "Copy LibreSSLSDK from $sourcePath to $PSScriptRoot failed"
Write-BuildMsg -AsError -ErrorAction Stop -Message "Copy LibreSSLSDK from $sourcePath to $PSScriptRoot failed."
}
}
@ -330,7 +343,8 @@ function Start-OpenSSHPackage
[string]$Configuration = "Release",
# Copy payload to DestinationPath instead of packaging
[string]$DestinationPath = ""
[string]$DestinationPath = "",
[switch]$NoOpenSSL
)
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
@ -390,7 +404,10 @@ function Start-OpenSSHPackage
#copy libcrypto dll
$libreSSLSDKPath = Join-Path $PSScriptRoot $script:libreSSLSDKStr
Copy-Item -Path $(Join-Path $libreSSLSDKPath "$NativeHostArch\libcrypto.dll") -Destination $packageDir -Force -ErrorAction Stop
if (-not $NoOpenSSL.IsPresent)
{
Copy-Item -Path $(Join-Path $libreSSLSDKPath "$NativeHostArch\libcrypto.dll") -Destination $packageDir -Force -ErrorAction Stop
}
if ($DestinationPath -ne "") {
if (Test-Path $DestinationPath) {
@ -400,7 +417,7 @@ function Start-OpenSSHPackage
New-Item -ItemType Directory $DestinationPath -Force | Out-Null
}
Copy-Item -Path $packageDir\* -Destination $DestinationPath -Force -Recurse
Write-BuildMsg -AsInfo -Message "Copied payload to $DestinationPath"
Write-BuildMsg -AsInfo -Message "Copied payload to $DestinationPath."
}
else {
Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
@ -411,7 +428,7 @@ function Start-OpenSSHPackage
}
else
{
Write-BuildMsg -AsInfo -Message "Packaged Payload not compressed."
Write-BuildMsg -AsInfo -Message "Packaged Payload not compressed."
}
}
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
@ -470,7 +487,7 @@ function Start-OpenSSHBuild
Remove-Item -Path $script:BuildLogFile -force
}
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)"
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)."
Start-OpenSSHBootstrap -OneCore:$OneCore
@ -523,17 +540,25 @@ function Start-OpenSSHBuild
$xml.Project.PropertyGroup.WindowsSDKVersion = $win10SDKVer.ToString()
$xml.Project.PropertyGroup.AdditionalDependentLibs = 'onecore.lib'
$xml.Project.PropertyGroup.MinimalCoreWin = 'true'
#Use onecore libcrypto binaries
$xml.Project.PropertyGroup."LibreSSL-x86-Path" = '$(SolutionDir)\LibreSSLSDK\onecore\x86\'
$xml.Project.PropertyGroup."LibreSSL-x64-Path" = '$(SolutionDir)\LibreSSLSDK\onecore\x64\'
$xml.Project.PropertyGroup."LibreSSL-arm-Path" = '$(SolutionDir)\LibreSSLSDK\onecore\arm\'
$xml.Project.PropertyGroup."LibreSSL-arm64-Path" = '$(SolutionDir)\LibreSSLSDK\onecore\arm64\'
$xml.Save($PathTargets)
}
$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")
if($NativeHostArch.ToLower().Startswith('arm'))
$cmdMsg = @("${solutionFile}", "/t:Rebuild", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/m", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
if($silent)
{
$msbuildCmd = Get-VS2017BuildToolPath
$cmdMsg += "/noconlog"
}
else
$msbuildCmd = Get-VS2017BuildToolPath
if($msbuildCmd -eq $null)
{
$msbuildCmd = Get-VS2015BuildToolPath
}

View File

@ -162,8 +162,14 @@ WARNING: Following changes will be made to OpenSSH configuration
New-Item -ItemType Directory -Path $TestDataPath -Force -ErrorAction SilentlyContinue | out-null
}
#Backup existing OpenSSH configuration
if(-not (Test-Path $OpenSSHConfigPath -pathType Container))
{
#starting the service will create ssh config folder
start-service sshd
}
$backupConfigPath = Join-Path $OpenSSHConfigPath sshd_config.ori
#Backup existing OpenSSH configuration
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
Copy-Item (Join-Path $OpenSSHConfigPath sshd_config) $backupConfigPath -Force
}
@ -244,7 +250,7 @@ WARNING: Following changes will be made to OpenSSH configuration
$authorizedKeyPath = Join-Path $ssouserProfile .ssh\authorized_keys
$testPubKeyPath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519.pub
Copy-Item $testPubKeyPath $authorizedKeyPath -Force -ErrorAction SilentlyContinue
Repair-AuthorizedKeyPermission -FilePath $authorizedKeyPath -confirm:$false
Repair-AuthorizedKeyPermission -FilePath $authorizedKeyPath -confirm:$false
copy-item (Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519) $Global:OpenSSHTestInfo["TestDataPath"]
$testPriKeypath = Join-Path $Global:OpenSSHTestInfo["TestDataPath"] sshtest_userssokey_ed25519

View File

@ -1565,7 +1565,7 @@
#define _PATH_PASSWD_PROG "/usr/bin/passwd"
/* Specify location of ssh.pid */
#define _PATH_SSH_PIDDIR "."
/* #undef _PATH_SSH_PIDDIR */
/* Define if we don't have struct __res_state in resolv.h */
#define __res_state state
@ -1693,6 +1693,7 @@
#define _PATH_PRIVSEP_CHROOT_DIR "."
#define SSHDIR "__PROGRAMDATA__\\ssh"
#define _PATH_SSH_PIDDIR SSHDIR
#define _PATH_SFTP_SERVER "sftp-server.exe"
#define _PATH_SSH_PROGRAM "ssh.exe"
#define _PATH_LS "dir"

View File

@ -12,7 +12,7 @@
<UseOpenSSL>true</UseOpenSSL>
<SSLLib>libcrypto.lib;</SSLLib>
<WindowsSDKVersion>8.1</WindowsSDKVersion>
<AdditionalDependentLibs>bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Netapi32.lib;Rpcrt4.lib</AdditionalDependentLibs>
<AdditionalDependentLibs>bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Netapi32.lib;Rpcrt4.lib;ntdll.lib</AdditionalDependentLibs>
<MinimalCoreWin>false</MinimalCoreWin>
</PropertyGroup>
</Project>

View File

@ -1,96 +0,0 @@
<#
Author: manoj.ampalam@microsoft.com
Description: ssh-add.exe like Powershell utility to do host key management.
Input parameter mimic ssh-add.exe cmdline arguments.
Host keys on Windows need to be registered as SYSTEM (i.e ssh-add.exe would
need to run as SYSTEM while talking to ssh-agent). This typically requires
an external utility like psexec.
This script tries to use the Task scheduler option:
- registers a task scheduler task to run ssh-add.exe operation as SYSTEM
- actual output of ssh-add.exe is written to file (both stdout and stderr)
- Dumps the file contents to console
#>
# see https://linux.die.net/man/1/ssh-add for what the arguments mean
[CmdletBinding(DefaultParameterSetName='Add_key')]
Param(
[Parameter(ParameterSetName="List_fingerprints")]
[switch]$List_fingerprints, #ssh-add -l
[Parameter(ParameterSetName="List_pubkeys")]
[switch]$List_pubkeys, #ssh-add -L
[Parameter(ParameterSetName="Delete_key")]
[switch]$Delete_key, #ssh-add -d
[Parameter(ParameterSetName="Delete_all")]
[switch]$Delete_all, #ssh-add -D
[Parameter(Mandatory, Position=0, ParameterSetName="Delete_key")]
[Parameter(Mandatory, Position=0, ParameterSetName="Add_key")]
[ValidateNotNullOrEmpty()]
[string]$key
)
$ssh_add_cmd = get-command ssh-add.exe -ErrorAction Ignore
if($ssh_add_cmd -eq $null)
{
Throw "Cannot find ssh-add.exe."
}
#create ssh-add cmdlinet
$ssh_add_cmd_str = $ssh_add_cmd.Path
if ($List_fingerprints) { $ssh_add_cmd_str += " -l" }
elseif ($List_pubkeys) { $ssh_add_cmd_str += " -L" }
elseif ($Delete_key) { $ssh_add_cmd_str += " -d $key" }
elseif ($Delete_all) { $ssh_add_cmd_str += " -D" }
else
{
if ( ($key.Length -gt 0) -and (-not($key.Contains("host"))) ) {
Do {
$input = Read-Host -Prompt "Are you sure the provided key is a host key? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
if (-not($result.ToLower().Startswith('y'))) { exit }
}
$ssh_add_cmd_str += " $key"
}
#globals
$taskfolder = "\OpenSSHUtils\hostkey_tasks\"
$taskname = "hostkey_task"
$ssh_add_output = Join-Path (pwd).Path "ssh-add-hostkey-tmp.txt"
$task_argument = "/c `"$ssh_add_cmd_str > $ssh_add_output 2>&1 `""
#create TaskScheduler task
$ac = New-ScheduledTaskAction -Execute "cmd.exe" -Argument $task_argument -WorkingDirectory (pwd).path
$task = Register-ScheduledTask -TaskName $taskname -User System -Action $ac -TaskPath $taskfolder -Force
#run the task
if (Test-Path $ssh_add_output) {Remove-Item $ssh_add_output -Force}
Start-ScheduledTask -TaskPath $taskfolder -TaskName $taskname
#if still running, wait a little while for task to complete
$num = 0
while ((Get-ScheduledTask -TaskName $taskname -TaskPath $taskfolder).State -eq "Running")
{
sleep 1
$num++
if($num -gt 20) { break }
}
if (-not(Test-Path $ssh_add_output)) {throw "cannot find task output file. Something went WRONG!!! "}
#dump output to console
Get-Content $ssh_add_output
#cleanup task and output file
Remove-Item $ssh_add_output -Force
Unregister-ScheduledTask -TaskPath $taskfolder -TaskName $taskname -Confirm:$false

View File

@ -11,10 +11,10 @@
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
@ -39,7 +39,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
# For this to work you will also need host keys in %windir%/programdata/openssh/config/ssh_known_hosts
# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication

Binary file not shown.

View File

@ -0,0 +1,55 @@
/*
* Missing public definitions from Ntsecapi.h
*/
typedef enum _LSA_SID_NAME_MAPPING_OPERATION_TYPE {
LsaSidNameMappingOperation_Add,
LsaSidNameMappingOperation_Remove,
LsaSidNameMappingOperation_AddMultiple,
} LSA_SID_NAME_MAPPING_OPERATION_TYPE, *PLSA_SID_NAME_MAPPING_OPERATION_TYPE;
typedef enum _LSA_SID_NAME_MAPPING_OPERATION_ERROR {
LsaSidNameMappingOperation_Success,
LsaSidNameMappingOperation_NonMappingError,
LsaSidNameMappingOperation_NameCollision,
LsaSidNameMappingOperation_SidCollision,
LsaSidNameMappingOperation_DomainNotFound,
LsaSidNameMappingOperation_DomainSidPrefixMismatch,
LsaSidNameMappingOperation_MappingNotFound,
} LSA_SID_NAME_MAPPING_OPERATION_ERROR, *PLSA_SID_NAME_MAPPING_OPERATION_ERROR;
typedef struct _LSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT {
UNICODE_STRING DomainName;
UNICODE_STRING AccountName;
PSID Sid;
ULONG Flags;
} LSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT, *PLSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT;
typedef struct _LSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT {
UNICODE_STRING DomainName;
UNICODE_STRING AccountName;
} LSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT, *PLSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT;
typedef union _LSA_SID_NAME_MAPPING_OPERATION_INPUT {
LSA_SID_NAME_MAPPING_OPERATION_ADD_INPUT AddInput;
LSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT RemoveInput;
} LSA_SID_NAME_MAPPING_OPERATION_INPUT, *PLSA_SID_NAME_MAPPING_OPERATION_INPUT;
typedef struct _LSA_SID_NAME_MAPPING_OPERATION_GENERIC_OUTPUT {
LSA_SID_NAME_MAPPING_OPERATION_ERROR ErrorCode;
} LSA_SID_NAME_MAPPING_OPERATION_GENERIC_OUTPUT, *PLSA_SID_NAME_MAPPING_OPERATION_GENERIC_OUTPUT;
typedef LSA_SID_NAME_MAPPING_OPERATION_GENERIC_OUTPUT LSA_SID_NAME_MAPPING_OPERATION_ADD_OUTPUT, *PLSA_SID_NAME_MAPPING_OPERATION_ADD_OUTPUT;
typedef LSA_SID_NAME_MAPPING_OPERATION_GENERIC_OUTPUT LSA_SID_NAME_MAPPING_OPERATION_REMOVE_OUTPUT, *PLSA_SID_NAME_MAPPING_OPERATION_REMOVE_OUTPUT;
typedef union _LSA_SID_NAME_MAPPING_OPERATION_OUTPUT {
LSA_SID_NAME_MAPPING_OPERATION_ADD_OUTPUT AddOutput;
LSA_SID_NAME_MAPPING_OPERATION_REMOVE_OUTPUT RemoveOutput;
} LSA_SID_NAME_MAPPING_OPERATION_OUTPUT, *PLSA_SID_NAME_MAPPING_OPERATION_OUTPUT;
NTSTATUS WINAPI LsaManageSidNameMapping(
LSA_SID_NAME_MAPPING_OPERATION_TYPE OpType,
PLSA_SID_NAME_MAPPING_OPERATION_INPUT OpInput,
PLSA_SID_NAME_MAPPING_OPERATION_OUTPUT *OpOutput
);

View File

@ -1460,9 +1460,86 @@ int
is_absolute_path(char *path)
{
int retVal = 0;
if (*path == '/' || *path == '\\' || (*path != '\0' && path[1] == ':') ||
if(*path == '\"') /* skip double quote if path is "c:\abc" */
path++;
if (*path == '/' || *path == '\\' || (*path != '\0' && isalpha(*path) && path[1] == ':') ||
((strlen(path) >= strlen(PROGRAM_DATA)) && (memcmp(path, PROGRAM_DATA, strlen(PROGRAM_DATA)) == 0)))
retVal = 1;
return retVal;
}
/* return -1 - in case of failure, 0 - success */
int
create_directory_withsddl(char *path, char *sddl)
{
struct stat st;
if (stat(path, &st) < 0) {
PSECURITY_DESCRIPTOR pSD = NULL;
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
wchar_t *path_w = utf8_to_utf16(path);
if (!path_w) {
error("%s utf8_to_utf16() has failed to convert string:%s", __func__, path);
return -1;
}
wchar_t *sddl_w = utf8_to_utf16(sddl);
if (!sddl_w) {
error("%s utf8_to_utf16() has failed to convert string:%s", __func__, sddl);
return -1;
}
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl_w, SDDL_REVISION, &pSD, NULL) == FALSE) {
error("ConvertStringSecurityDescriptorToSecurityDescriptorW failed with error code %d", GetLastError());
return -1;
}
if (IsValidSecurityDescriptor(pSD) == FALSE) {
error("IsValidSecurityDescriptor return FALSE");
return -1;
}
sa.lpSecurityDescriptor = pSD;
if (!CreateDirectoryW(path_w, &sa)) {
error("Failed to create directory:%ls error:%d", path_w, GetLastError());
return -1;
}
}
return 0;
}
/* return -1 - in case of failure, 0 - success */
int
copy_file(char *source, char *destination)
{
if (!source || !destination) return 0;
struct stat st;
if ((stat(source, &st) >= 0) && (stat(destination, &st) < 0)) {
wchar_t *source_w = utf8_to_utf16(source);
if (!source_w) {
error("%s utf8_to_utf16() has failed to convert string:%s", __func__, source_w);
return -1;
}
wchar_t *destination_w = utf8_to_utf16(destination);
if (!destination_w) {
error("%s utf8_to_utf16() has failed to convert string:%s", __func__, destination_w);
return -1;
}
if (!CopyFileW(source_w, destination_w, FALSE)) {
error("Failed to copy %ls to %ls, error:%d", source_w, destination_w, GetLastError());
return -1;
}
}
return 0;
}

View File

@ -2,7 +2,7 @@
#include <VersionHelpers.h>
#define PATH_MAX MAX_PATH
#define SSH_REGISTRY_ROOT L"SOFTWARE\\OpenSSH"
#define GOTO_CLEANUP_IF(_cond_,_err_) do { \
if ((_cond_)) { \
hr = _err_; \
@ -40,3 +40,5 @@ int get_machine_domain_name(wchar_t *domain, int size);
char* get_program_data_path();
HANDLE get_user_token(char* user);
int load_user_profile(HANDLE user_token, char* user);
int copy_file(char *source, char *destination);
int create_directory_withsddl(char *path, char *sddl);

View File

@ -111,6 +111,8 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
int tmp_len = PATH_MAX;
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
DWORD dsStatus, uname_upn_len = 0, uname_len = 0, udom_len = 0;
wchar_t wmachine_name[MAX_COMPUTERNAME_LENGTH + 1];
DWORD wmachine_name_len = MAX_COMPUTERNAME_LENGTH + 1;
errno_t r = 0;
errno = 0;
@ -135,6 +137,14 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
udom_utf16 = NULL;
}
if (udom_utf16) {
/* this should never fail */
GetComputerNameW(wmachine_name, &wmachine_name_len);
/* If this is a local account (domain part and computer name are the same), strip out domain */
if (_wcsicmp(udom_utf16, wmachine_name) == 0)
udom_utf16 = NULL;
}
if (user_sid == NULL) {
NET_API_STATUS status;
if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {

View File

@ -1790,7 +1790,7 @@ wmain(int ac, wchar_t **av)
}
memset(&job_info, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_BREAKAWAY_OK;
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info)) ||
!AssignProcessToJobObject(job, GetCurrentProcess())) {

View File

@ -1,11 +1,11 @@
#include <Windows.h>
#include <stdio.h>
#include "Debug.h"
#include "misc_internal.h"
#define MAX_MESSAGE_SIZE 256 * 1024
#define SSH_ROOT L"SOFTWARE\\OpenSSH"
#define SSH_AGENT_ROOT SSH_ROOT L"\\Agent"
#define SSH_AGENT_ROOT SSH_REGISTRY_ROOT L"\\Agent"
#define SSH_KEYS_KEY L"Keys"
#define SSH_KEYS_ROOT SSH_AGENT_ROOT L"\\" SSH_KEYS_KEY

View File

@ -37,6 +37,7 @@
#include "inc\fcntl.h"
#include "inc\sys\un.h"
#include "inc\utf.h"
#include "inc\stdio.h"
#include "w32fd.h"
#include "signal_internal.h"
@ -953,16 +954,14 @@ spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDL
int add_module_path = 0, ret = -1;
/* should module path be added */
do {
if (!cmd)
break;
t = cmd;
if (*t == '\"')
t++;
if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
break;
if (!cmd) {
error("%s invalid argument cmd:%s", __func__, cmd);
return -1;
}
t = cmd;
if (!is_absolute_path(t))
add_module_path = 1;
} while (0);
/* compute total cmdline len*/
if (add_module_path)
@ -1040,6 +1039,7 @@ spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDL
}
else {
errno = GetLastError();
error("%s failed error:%d", (as_user?"CreateProcessAsUserW":"CreateProcessW"), GetLastError());
goto cleanup;
}

View File

@ -35,11 +35,16 @@
#include <Ntsecapi.h>
#include <ntstatus.h>
#include <Shlobj.h>
#include <LM.h>
#include "inc\utf.h"
#include "logonuser.h"
#include <Ntsecapi.h>
#include <Strsafe.h>
#include <sddl.h>
#include <ntstatus.h>
#include "misc_internal.h"
#include "lsa_missingdefs.h"
#include "Debug.h"
#pragma warning(push, 3)
@ -116,7 +121,7 @@ done:
#define MAX_PW_LEN 64
static HANDLE
generate_user_token(wchar_t* user_cpn) {
generate_s4u_user_token(wchar_t* user_cpn) {
HANDLE lsa_handle = 0, token = 0;
LSA_OPERATIONAL_MODE mode;
ULONG auth_package_id;
@ -223,14 +228,14 @@ done:
}
HANDLE
process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
process_custom_lsa_auth(const char* user, const char* pwd, const char* lsa_pkg)
{
wchar_t *userw = NULL, *pwdw = NULL, *domw = NULL, *tmp, *providerw = NULL;
wchar_t *providerw = NULL;
HANDLE token = NULL, lsa_handle = NULL;
LSA_OPERATIONAL_MODE mode;
ULONG auth_package_id, logon_info_size = 0;
NTSTATUS ret, subStatus;
wchar_t *logon_info = NULL;
wchar_t *logon_info_w = NULL;
LSA_STRING logon_process_name, lsa_auth_package_name, originName;
TOKEN_SOURCE sourceContext;
PVOID pProfile = NULL;
@ -238,19 +243,34 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
QUOTA_LIMITS quotas;
DWORD cbProfile;
int retVal = -1;
char *domain = NULL, *logon_info = NULL, user_name[UNLEN] = { 0, }, *tmp = NULL;
debug("LSA auth request, user:%s lsa_pkg:%s ", user, lsa_pkg);
debug3("LSA auth request, user:%s lsa_pkg:%s ", user, lsa_pkg);
if ((userw = utf8_to_utf16(user)) == NULL ||
(pwdw = utf8_to_utf16(pwd)) == NULL) {
debug("out of memory");
goto done;
logon_info_size = (ULONG)(strlen(user) + strlen(pwd) + 2); // 1 - ";", 1 - "\0"
strcpy_s(user_name, _countof(user_name), user);
if (tmp = strstr(user_name, "@")) {
domain = tmp + 1;
*tmp = '\0';
logon_info_size++; // 1 - ";"
}
/* split user and domain */
if ((tmp = wcschr(userw, L'@')) != NULL) {
domw = tmp + 1;
*tmp = L'\0';
logon_info = malloc(logon_info_size);
if(!logon_info)
fatal("%s out of memory", __func__);
strcpy_s(logon_info, logon_info_size, user_name);
strcat_s(logon_info, logon_info_size, ";");
strcat_s(logon_info, logon_info_size, pwd);
if (domain) {
strcat_s(logon_info, logon_info_size, ";");
strcat_s(logon_info, logon_info_size, domain);
}
if (NULL == (logon_info_w = utf8_to_utf16(logon_info))) {
error("utf8_to_utf16 failed to convert %s", logon_info);
goto done;
}
/* call into LSA provider , get and duplicate token */
@ -268,30 +288,19 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
goto done;
}
logon_info_size = (ULONG)((wcslen(userw) + wcslen(pwdw) + wcslen(domw) + 3) * sizeof(wchar_t));
logon_info = (wchar_t *)malloc(logon_info_size);
if (NULL == logon_info)
fatal("%s:out of memory", __func__);
wcscpy_s(logon_info, logon_info_size, userw);
wcscat_s(logon_info, logon_info_size, L";");
wcscat_s(logon_info, logon_info_size, pwdw);
wcscat_s(logon_info, logon_info_size, L";");
wcscat_s(logon_info, logon_info_size, domw);
memcpy(sourceContext.SourceName, "sshd", sizeof(sourceContext.SourceName));
if (!AllocateLocallyUniqueId(&sourceContext.SourceIdentifier)) {
error("AllocateLocallyUniqueId failed, error:%d", GetLastError());
goto done;
}
}
if ((ret = LsaLogonUser(lsa_handle,
&originName,
Network,
auth_package_id,
logon_info,
logon_info_size,
logon_info_w,
logon_info_size * sizeof(wchar_t),
NULL,
&sourceContext,
&pProfile,
@ -299,8 +308,8 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
&logonId,
&token,
&quotas,
&subStatus)) != STATUS_SUCCESS) {
if(ret == STATUS_ACCOUNT_RESTRICTION)
&subStatus)) != STATUS_SUCCESS) {
if (ret == STATUS_ACCOUNT_RESTRICTION)
error("LsaLogonUser failed, error:%x subStatus:%ld", ret, subStatus);
else
error("LsaLogonUser failed error:%x", ret);
@ -308,23 +317,23 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
goto done;
}
debug3("LSA auth request is successful for user:%s ", user);
retVal = 0;
done:
/* delete allocated memory*/
if (lsa_handle)
LsaDeregisterLogonProcess(lsa_handle);
if (logon_info)
free(logon_info);
if (pProfile)
LsaFreeReturnBuffer(pProfile);
if (userw)
free(userw);
if (pwdw)
free(pwdw);
if (logon_info)
free(logon_info);
if (logon_info_w)
free(logon_info_w);
return token;
}
HANDLE generate_sshd_virtual_token();
HANDLE
get_user_token(char* user) {
HANDLE token = NULL;
@ -335,12 +344,18 @@ get_user_token(char* user) {
goto done;
}
if ((token = generate_user_token(user_utf16)) == 0) {
if (wcscmp(user_utf16, L"sshd") == 0) {
if ((token = generate_sshd_virtual_token()) != 0)
goto done;
debug3("unable to generate sshd virtual token, falling back to s4u");
}
if ((token = generate_s4u_user_token(user_utf16)) == 0) {
error("unable to generate token for user %ls", user_utf16);
/* work around for https://github.com/PowerShell/Win32-OpenSSH/issues/727 by doing a fake login */
LogonUserExExWHelper(L"FakeUser", L"FakeDomain", L"FakePasswd",
LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, NULL, &token, NULL, NULL, NULL, NULL);
if ((token = generate_user_token(user_utf16)) == 0) {
if ((token = generate_s4u_user_token(user_utf16)) == 0) {
error("unable to generate token on 2nd attempt for user %ls", user_utf16);
goto done;
}
@ -378,4 +393,209 @@ done:
return r;
}
/* *** virtual account token generation logic ***/
char* LSAMappingErrorDetails[] = {
"LsaSidNameMappingOperation_Success",
"LsaSidNameMappingOperation_NonMappingError",
"LsaSidNameMappingOperation_NameCollision",
"LsaSidNameMappingOperation_SidCollision",
"LsaSidNameMappingOperation_DomainNotFound",
"LsaSidNameMappingOperation_DomainSidPrefixMismatch",
"LsaSidNameMappingOperation_MappingNotFound"
};
#define VIRTUALUSER_DOMAIN L"VIRTUAL USERS"
#define VIRTUALUSER_GROUP_NAME L"ALL VIRTUAL USERS"
/* returns 0 on success -1 on failure */
int
AddSidMappingToLsa(PUNICODE_STRING domain_name,
PUNICODE_STRING account_name,
PSID sid)
{
LSA_SID_NAME_MAPPING_OPERATION_INPUT input = { 0 };
PLSA_SID_NAME_MAPPING_OPERATION_OUTPUT p_output = NULL;
LSA_SID_NAME_MAPPING_OPERATION_ERROR op_result =
LsaSidNameMappingOperation_NonMappingError;
NTSTATUS status = STATUS_SUCCESS;
int ret = 0;
input.AddInput.DomainName = *domain_name;
if (account_name)
input.AddInput.AccountName = *account_name;
input.AddInput.Sid = sid;
status = LsaManageSidNameMapping(LsaSidNameMappingOperation_Add,
&input,
&p_output);
if (status != STATUS_SUCCESS) {
ret = -1;
if (p_output) {
op_result = p_output->AddOutput.ErrorCode;
if (op_result == LsaSidNameMappingOperation_NameCollision || op_result == LsaSidNameMappingOperation_SidCollision)
ret = 0; /* OK as it failed due to collision */
else
error("LsaManageSidNameMapping failed with : %s \n", LSAMappingErrorDetails[op_result]);
}
else
error("LsaManageSidNameMapping failed with ntstatus: %d \n", status);
}
/* TODO - Free p_output */
/*if (p_output)
LsaFreeMemory(p_output);*/
return ret;
}
int RemoveVirtualAccountLSAMapping(PUNICODE_STRING domain_name,
PUNICODE_STRING account_name)
{
int ret = 0;
LSA_SID_NAME_MAPPING_OPERATION_INPUT input = { 0 };
PLSA_SID_NAME_MAPPING_OPERATION_OUTPUT p_output = NULL;
PLSA_SID_NAME_MAPPING_OPERATION_REMOVE_INPUT remove_input = &input.RemoveInput;
remove_input->DomainName = *domain_name;
if (account_name)
remove_input->AccountName = *account_name;
NTSTATUS status = LsaManageSidNameMapping(LsaSidNameMappingOperation_Remove,
&input,
&p_output);
if (status != STATUS_SUCCESS)
ret = -1;
/* TODO - Free p_output */
/*if (p_output)
LsaFreeMemory(p_output);*/
return ret;
}
void
InitUnicodeString(PUNICODE_STRING dest, PCWSTR source)
{
dest->Buffer = source;
dest->Length = wcslen(source) * sizeof(wchar_t);
dest->MaximumLength = dest->Length + 2;
}
HANDLE generate_sshd_virtual_token()
{
SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
UNICODE_STRING domain, group, account;
WCHAR va_name[32]; /* enough to accomodate sshd_123457890 */
PSID sid_domain = NULL, sid_group = NULL, sid_user = NULL;
HANDLE va_token = 0, va_token_restricted = 0;
StringCchPrintfW(va_name, 32, L"%s_%d", L"sshd", GetCurrentProcessId());
InitUnicodeString(&domain, VIRTUALUSER_DOMAIN);
InitUnicodeString(&group, VIRTUALUSER_GROUP_NAME);
InitUnicodeString(&account, va_name);
/* Initialize SIDs */
/* domain SID - S-1-5-111 */
if (!(AllocateAndInitializeSid(&nt_authority,
1,
111,
0,
0,
0,
0,
0,
0,
0,
&sid_domain)))
goto cleanup;
/* group SID - S-1-5-111-0 */
if (!(AllocateAndInitializeSid(&nt_authority,
2,
111,
0,
0,
0,
0,
0,
0,
0,
&sid_group)))
goto cleanup;
/*
* account SID
* this is derived from higher RIDs in sshd service account SID to ensure there are no conflicts
* S-1-5-80-3847866527-469524349-687026318-516638107-1125189541 (Well Known group: NT SERVICE\sshd)
* Ex account SID - S-1-5-111-3847866527-469524349-687026318-516638107-1125189541-123
*/
if (!(AllocateAndInitializeSid(&nt_authority,
7,
111,
3847866527,
469524349,
687026318,
516638107,
1125189541,
GetCurrentProcessId(),
0,
&sid_user)))
goto cleanup;
/* Map the domain SID */
if (AddSidMappingToLsa(&domain, NULL, sid_domain) != 0)
goto cleanup;
/* Map the group SID */
if (AddSidMappingToLsa(&domain, &group, sid_group) != 0)
goto cleanup;
/* Map the user SID */
if (AddSidMappingToLsa(&domain, &account, sid_user) != 0)
goto cleanup;
/* Logon virtual and create token */
if (!LogonUserExExWHelper(
va_name,
VIRTUALUSER_DOMAIN,
L"",
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_VIRTUAL,
NULL,
&va_token,
NULL,
NULL,
NULL,
NULL)) {
debug3("LogonUserExExW failed with %d \n", GetLastError());
goto cleanup;
}
/* remove all privileges */
if (!CreateRestrictedToken(va_token, DISABLE_MAX_PRIVILEGE, 0, NULL, 0, NULL, 0, NULL, &va_token_restricted ))
debug3("CreateRestrictedToken failed with %d \n", GetLastError());
CloseHandle(va_token);
cleanup:
RemoveVirtualAccountLSAMapping(&domain, &account);
if (sid_domain)
FreeSid(sid_domain);
if (sid_user)
FreeSid(sid_user);
if (sid_group)
FreeSid(sid_group);
return va_token_restricted;
}
#pragma warning(pop)

View File

@ -35,6 +35,8 @@
#include <Windows.h>
#include <wchar.h>
#include <Lm.h>
#include <sddl.h>
#include "inc\utf.h"
#include "misc_internal.h"
@ -99,7 +101,7 @@ static VOID WINAPI service_handler(DWORD dwControl)
#define SSH_HOSTKEY_GEN_CMDLINE L"ssh-keygen -A"
static void
prereq_setup()
generate_host_keys()
{
TOKEN_USER* info = NULL;
DWORD info_len = 0, dwError = 0;
@ -127,7 +129,7 @@ prereq_setup()
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_flags = UF_SCRIPT | UF_DONT_EXPIRE_PASSWD;
ui.usri1_script_path = NULL;
NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError);
@ -151,14 +153,96 @@ cleanup:
free(info);
}
/*
* 1) Create %programdata%\ssh - Administrator group(F), system(F), authorized users(RX).
* 2) Create %programdata%\ssh\logs - Administrator group(F), system(F)
* 3) copy <binary_location>\sshd_config_default to %programdata%\ssh\sshd_config
*/
static void
create_prgdata_ssh_folder()
{
/* create ssh cfg folder */
char ssh_cfg_dir[PATH_MAX] = { 0, };
strcpy_s(ssh_cfg_dir, _countof(ssh_cfg_dir), get_program_data_path());
strcat_s(ssh_cfg_dir, _countof(ssh_cfg_dir), "\\ssh");
if (create_directory_withsddl(ssh_cfg_dir, "O:BAD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;AU)") < 0) {
printf("failed to create %s", ssh_cfg_dir);
exit(255);
}
/* create logs folder */
char logs_dir[PATH_MAX] = { 0, };
strcat_s(logs_dir, _countof(logs_dir), ssh_cfg_dir);
strcat_s(logs_dir, _countof(logs_dir), "\\logs");
if (create_directory_withsddl(logs_dir, "O:BAD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)") < 0) {
printf("failed to create %s", logs_dir);
exit(255);
}
/* COPY sshd_config_default to %programData%\openssh\sshd_config */
char sshd_config_path[PATH_MAX] = { 0, };
strcat_s(sshd_config_path, _countof(sshd_config_path), ssh_cfg_dir);
strcat_s(sshd_config_path, _countof(sshd_config_path), "\\sshd_config");
struct stat st;
if (stat(sshd_config_path, &st) < 0) {
char sshd_config_default_path[PATH_MAX] = { 0, };
strcat_s(sshd_config_default_path, _countof(sshd_config_default_path), w32_programdir());
strcat_s(sshd_config_default_path, _countof(sshd_config_default_path), "\\sshd_config_default");
if (copy_file(sshd_config_default_path, sshd_config_path) < 0) {
printf("Failed to copy %s to %s, error:%d", sshd_config_default_path, sshd_config_path, GetLastError());
exit(255);
}
}
}
/* Create HKLM\Software\OpenSSH windows registry key */
static void
create_openssh_registry_key()
{
HKEY ssh_registry_root = NULL;
wchar_t* sddl_str;
SECURITY_ATTRIBUTES sa;
int r;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(sa);
/*
* SDDL - FullAcess to System and Builtin/Admins and restricted access to Authenticated users
* 0x12019b - FILE_GENERIC_READ/WRITE minus FILE_CREATE_PIPE_INSTANCE
*/
sddl_str = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x12019b;;;AU)";
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl_str, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength)) {
printf("cannot convert sddl ERROR:%d", GetLastError());
return;
}
if ((r = RegCreateKeyExW(HKEY_LOCAL_MACHINE, SSH_REGISTRY_ROOT, 0, 0, 0, KEY_WRITE, &sa, &ssh_registry_root, 0)) == ERROR_SUCCESS)
RegCloseKey(ssh_registry_root);
else
printf("cannot create ssh root reg key, ERROR:%d", r);
}
static void
prereq_setup()
{
create_prgdata_ssh_folder();
generate_host_keys();
create_openssh_registry_key();
}
int sshd_main(int argc, wchar_t **wargv) {
char** argv = NULL;
int i, r;
_set_invalid_parameter_handler(invalid_parameter_handler);
if (argc) {
if ((argv = malloc(argc * sizeof(char*))) == NULL)
fatal("out of memory");
if ((argv = malloc(argc * sizeof(char*))) == NULL) {
printf("out of memory");
exit(255);
}
for (i = 0; i < argc; i++)
argv[i] = utf16_to_utf8(wargv[i]);
}
@ -177,7 +261,7 @@ int wmain(int argc, wchar_t **wargv) {
wchar_t* path_utf16;
argc_original = argc;
wargv_original = wargv;
/* change current directory to sshd.exe root */
if ( (path_utf16 = utf8_to_utf16(w32_programdir())) == NULL)
return -1;

View File

@ -17,42 +17,22 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
}
$fileName = "test.txt"
$logName = "sshdlog.txt"
$sshLogName = "test.txt"
$sshdLogName = "sshdlog.txt"
$server = $OpenSSHTestInfo["Target"]
$port = 47003
$ssouser = $OpenSSHTestInfo["SSOUser"]
$PwdUser = $OpenSSHTestInfo["PasswdUser"]
$ssouserProfile = $OpenSSHTestInfo["SSOUserProfile"]
Remove-Item -Path (Join-Path $testDir "*$fileName") -Force -ErrorAction SilentlyContinue
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
Remove-Item -Path (Join-Path $testDir "*$sshLogName") -Force -ErrorAction SilentlyContinue
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
#suppress the firewall blocking dialogue on win7
netsh advfirewall firewall add rule name="sshd" program="$($OpenSSHTestInfo['OpenSSHBinPath'])\sshd.exe" protocol=any action=allow dir=in
}
$Taskfolder = "\OpenSSHTestTasks\"
$Taskname = "StartTestDaemon"
function Start-SSHD-TestDaemon
{
param([string] $Arguments)
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
$ac = New-ScheduledTaskAction -Execute (join-path $opensshbinpath "sshd") -WorkingDirectory $opensshbinpath -Argument $Arguments
$task = Register-ScheduledTask -TaskName $Taskname -User system -Action $ac -TaskPath $Taskfolder -Force
Start-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
}
function Stop-SSHD-TestDaemon
{
Stop-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
#stop-scheduledTask does not wait for worker process to end. Kill it if still running. Logic below assume sshd service is running
$svcpid = ((tasklist /svc | select-string -Pattern ".+sshd").ToString() -split "\s+")[1]
(gps sshd).id | foreach { if ((-not($_ -eq $svcpid))) {Stop-Process $_ -Force} }
}
}
}
AfterEach { $tI++ }
@ -78,11 +58,13 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
$authorizedkeyPath = Join-Path $ssouserProfile .testssh\authorized_keys
$Source = Join-Path $ssouserProfile .ssh\authorized_keys
$testknownhosts = Join-path $PSScriptRoot testdata\test_known_hosts
Copy-Item $Source $ssouserSSHProfilePath -Force -ErrorAction Stop
Copy-Item $Source $ssouserSSHProfilePath -Force -ErrorAction Stop
Repair-AuthorizedKeyPermission -Filepath $authorizedkeyPath -confirm:$false
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
if(-not $skip)
{
Stop-SSHDTestDaemon
}
#add wrong password so ssh does not prompt password if failed with authorized keys
Add-PasswordSetting -Pass "WrongPass"
$tI=1
@ -102,73 +84,73 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
}
BeforeEach {
$filePath = Join-Path $testDir "$tC.$tI.$fileName"
$logPath = Join-Path $testDir "$tC.$tI.$logName"
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
$sshlog = Join-Path $testDir "$tC.$tI.$sshLogName"
$sshdlog = Join-Path $testDir "$tC.$tI.$sshdLogName"
if(-not $skip)
{
Stop-SSHDTestDaemon
}
}
It "$tC.$tI-authorized_keys-positive(pwd user is the owner and running process can access to the file)" {
It "$tC.$tI-authorized_keys-positive(pwd user is the owner and running process can access to the file)" -skip:$skip {
#setup to have ssouser as owner and grant ssouser read and write, admins group, and local system full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owners $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by local system)" {
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by local system)" -skip:$skip {
#setup to have system as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $systemSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd does not have explict ACE)" {
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd does not have explict ACE)" -skip:$skip {
#setup to have admin group as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
}
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd have explict ACE)" {
It "$tC.$tI-authorized_keys-positive(authorized_keys is owned by admins group and pwd have explict ACE)" -skip:$skip {
#setup to have admin group as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
$o | Should Be "1234"
Stop-SSHDTestDaemon
$o | Should Be "1234"
}
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other admin user)" {
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other admin user)" -skip:$skip {
#setup to have current user (admin user) as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $currentUserSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "Authentication refused."
Stop-SSHDTestDaemon
$sshlog | Should Contain "Permission denied"
$sshdlog | Should Contain "Authentication refused."
}
It "$tC.$tI-authorized_keys-negative(other account can access private key file)" {
It "$tC.$tI-authorized_keys-negative(other account can access private key file)" -skip:$skip {
#setup to have current user as owner and grant it full control
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
@ -177,24 +159,26 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
Set-FilePermission -FilePath $authorizedkeyPath -User $objPwdUserSid -Perm "Read"
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "Authentication refused."
Start-SSHDTestDaemon -workDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHDTestDaemon
$sshlog | Should Contain "Permission denied"
$sshdlog | Should Contain "Authentication refused."
}
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other non-admin user)" {
It "$tC.$tI-authorized_keys-negative(authorized_keys is owned by other non-admin user)" -skip:$skip {
#setup to have PwdUser as owner and grant it full control
$objPwdUserSid = Get-UserSid -User $PwdUser
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objPwdUserSid -FullAccessNeeded $adminsSid,$systemSid,$objPwdUser -confirm:$false
#Run
Start-SSHD-TestDaemon -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $logPath"
ssh -p $port -E $FilePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -p $port -o `"AuthorizedKeysFile .testssh/authorized_keys`" -E $sshdlog"
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "Authentication refused."
Stop-SSHDTestDaemon
$sshlog | Should Contain "Permission denied"
$sshdlog | Should Contain "Authentication refused."
}
}
}

View File

@ -105,4 +105,52 @@ function Remove-PasswordSetting
{
if ($env:DISPLAY -eq 1) { Remove-Item env:\DISPLAY }
Remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
}
$Taskfolder = "\OpenSSHTestTasks\"
$Taskname = "StartTestDaemon"
function Start-SSHDTestDaemon
{
param(
[string] $Arguments,
[string] $Workdir)
$ac = New-ScheduledTaskAction -Execute (join-path $workdir "sshd") -WorkingDirectory $workdir -Argument $Arguments
$task = Register-ScheduledTask -TaskName $Taskname -User system -Action $ac -TaskPath $Taskfolder -Force
Start-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
$svcpid = ((tasklist /svc | select-string -Pattern ".+sshd").ToString() -split "\s+")[1]
#sleep for 1 seconds for process to ready to listener
$num = 0
while((Get-Process sshd | Where-Object {$_.Id -ne $svcpid}) -eq $null)
{
start-sleep 1
$num++
if($num -gt 30) { break }
}
}
function Stop-SSHDTestDaemon
{
$task = Get-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname -ErrorAction SilentlyContinue
if($task)
{
if($task.State -eq "Running")
{
Stop-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
}
Unregister-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname -Confirm:$false
}
#if still running, wait a little while for task to complete
#stop-scheduledTask does not wait for worker process to end. Kill it if still running. Logic below assume sshd service is running
$svcpid = ((tasklist /svc | select-string -Pattern ".+sshd").ToString() -split "\s+")[1]
Get-Process sshd -ErrorAction SilentlyContinue | Where-Object {$_.Id -ne $svcpid} | Stop-Process -Force -ErrorAction SilentlyContinue
$num = 0
while((Get-Process sshd | Where-Object {$_.Id -ne $svcpid}))
{
# sshd process is still running; wait 1 more seconds"
start-sleep 1
$num++
if($num -gt 30) { break }
}
}

View File

@ -106,7 +106,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
It "$tC.$tI - test version" {
iex "cmd /c `"ssh -V 2> $stderrFile`""
$stderrFile | Should Contain "OpenSSH_"
$stderrFile | Should Contain "OpenSSH_for_Windows"
}
It "$tC.$tI - test help" {
@ -147,7 +147,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
$o | Should Be "1234"
}
It "$tC.$tI - stdin from PS object" {
It "$tC.$tI - stdin from PS object" -skip:$skip {
# execute this script that dumps the length of input data, on the remote end
$str = "begin {} process { Write-Output `$input.Length} end { }"
$EncodedText =[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))
@ -157,7 +157,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
$o | Should Be "8"
}
It "$tC.$tI - stream file in and out" {
It "$tC.$tI - stream file in and out" -skip:$skip {
# prep a file of size > 10KB (https://github.com/PowerShell/Win32-OpenSSH/issues/908 was caught with such file size)
$str = ""
(1..100) | foreach {$str += "1234567890"}
@ -191,7 +191,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
Remove-ItemProperty -Path $dfltShellRegPath -Name $dfltShellCmdOptionRegKeyName -ErrorAction SilentlyContinue
}
It "$tC.$tI - default shell as powershell" {
It "$tC.$tI - default shell as powershell" -skip:$skip {
$shell_path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).path
if($shell_path -ne $null) {
ConfigureDefaultShell -default_shell_path $shell_path -default_shell_cmd_option_val "/c"

View File

@ -14,39 +14,20 @@ Describe "Tests of sshd_config" -Tags "CI" {
if( -not (Test-path $testDir -PathType Container))
{
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
}
}
$fileName = "test.txt"
$logName = "sshdlog.txt"
$sshLogName = "test.txt"
$sshdLogName = "sshdlog.txt"
$server = $OpenSSHTestInfo["Target"]
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
$port = 47003
Remove-Item -Path (Join-Path $testDir "*$fileName") -Force -ErrorAction SilentlyContinue
Remove-Item -Path (Join-Path $testDir "*$sshLogName") -Force -ErrorAction SilentlyContinue
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ContextName = $env:COMPUTERNAME
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Machine
$PrincipalContext = new-object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList @($ContextType, $ContextName)
$IdentityType = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
$Taskfolder = "\OpenSSHTestTasks\"
$Taskname = "StartTestDaemon"
function Start-SSHD-TestDaemon
{
param([string] $Arguments)
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
$ac = New-ScheduledTaskAction -Execute (join-path $opensshbinpath "sshd") -WorkingDirectory $opensshbinpath -Argument $Arguments
$task = Register-ScheduledTask -TaskName $Taskname -User system -Action $ac -TaskPath $Taskfolder -Force
Start-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
}
function Stop-SSHD-TestDaemon
{
Stop-ScheduledTask -TaskPath $Taskfolder -TaskName $Taskname
#stop-scheduledTask does not wait for worker process to end. Kill it if still running. Logic below assume sshd service is running
$svcpid = ((tasklist /svc | select-string -Pattern ".+sshd").ToString() -split "\s+")[1]
(gps sshd).id | foreach { if ((-not($_ -eq $svcpid))) {Stop-Process $_ -Force} }
}
$IdentityType = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
function Add-LocalUser
{
@ -133,6 +114,10 @@ Describe "Tests of sshd_config" -Tags "CI" {
}
$platform = Get-Platform
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
if(-not $skip)
{
Stop-SSHDTestDaemon
}
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
#suppress the firewall blocking dialogue on win7
@ -142,7 +127,7 @@ Describe "Tests of sshd_config" -Tags "CI" {
AfterEach { $tI++ }
AfterAll {
AfterAll {
$PrincipalContext.Dispose()
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
{
@ -190,8 +175,12 @@ Describe "Tests of sshd_config" -Tags "CI" {
}
BeforeEach {
$filePath = Join-Path $testDir "$tC.$tI.$fileName"
$logPath = Join-Path $testDir "$tC.$tI.$logName"
$sshlog = Join-Path $testDir "$tC.$tI.$sshLogName"
$sshdlog = Join-Path $testDir "$tC.$tI.$sshdLogName"
if(-not $skip)
{
Stop-SSHDTestDaemon
}
}
AfterAll {
@ -199,148 +188,162 @@ Describe "Tests of sshd_config" -Tags "CI" {
$tC++
}
It "$tC.$tI-User with full name in the list of AllowUsers" {
It "$tC.$tI-User with full name in the list of AllowUsers" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $allowUser1 -Password $password -GroupName $allowGroup1
$o = ssh -p $port $allowUser1@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
Remove-UserFromLocalGroup -UserName $allowUser1 -GroupName $allowGroup1
}
It "$tC.$tI-User with * wildcard" {
It "$tC.$tI-User with * wildcard" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $allowUser2 -Password $password -GroupName $allowGroup1
$o = ssh -p $port $allowUser2@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
Remove-UserFromLocalGroup -UserName $allowUser2 -GroupName $allowGroup1
}
It "$tC.$tI-User with ? wildcard" {
It "$tC.$tI-User with ? wildcard" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $allowUser3 -Password $password -GroupName $allowGroup1
$o = ssh -p $port $allowUser3@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
Stop-SSHD-TestDaemon
Stop-SSHDTestDaemon
$o | Should Be "1234"
Remove-UserFromLocalGroup -UserName $allowUser3 -GroupName $allowGroup1
}
It "$tC.$tI-User with full name in the list of AllowUsers but not in any AllowGroups" {
It "$tC.$tI-User with full name in the list of AllowUsers but not in any AllowGroups" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-LocalUser -UserName $allowUser4 -Password $password
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $allowUser4@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $allowUser4@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because not in any group"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because not in any group"
}
It "$tC.$tI-User with full name in the list of DenyUsers" {
It "$tC.$tI-User with full name in the list of DenyUsers" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $denyUser1 -Password $password -GroupName $allowGroup1
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $denyUser1@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $denyUser1@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because listed in DenyUsers"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because listed in DenyUsers"
Remove-UserFromLocalGroup -UserName $denyUser1 -GroupName $allowGroup1
}
It "$tC.$tI-User with * wildcard in the list of DenyUsers" {
It "$tC.$tI-User with * wildcard in the list of DenyUsers" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $denyUser2 -Password $password -GroupName $allowGroup1
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $denyUser2@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $denyUser2@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because listed in DenyUsers"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because listed in DenyUsers"
Remove-UserFromLocalGroup -UserName $denyUser2 -GroupName $allowGroup1
}
It "$tC.$tI-User with ? wildcard in the list of DenyUsers" {
It "$tC.$tI-User with ? wildcard in the list of DenyUsers" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $denyUser3 -Password $password -GroupName $allowGroup1
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $denyUser3@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $denyUser3@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because not listed in AllowUsers"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because not listed in AllowUsers"
Remove-UserFromLocalGroup -UserName $denyUser3 -GroupName $allowGroup1
}
It "$tC.$tI-User is listed in the list of AllowUsers but also in a full name DenyGroups and AllowGroups" {
It "$tC.$tI-User is listed in the list of AllowUsers but also in a full name DenyGroups and AllowGroups" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $localuser1 -Password $password -GroupName $allowGroup1
Add-UserToLocalGroup -UserName $localuser1 -Password $password -GroupName $denyGroup1
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $localuser1@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $localuser1@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
Remove-UserFromLocalGroup -UserName $localuser1 -GroupName $allowGroup1
Remove-UserFromLocalGroup -UserName $localuser1 -GroupName $denyGroup1
}
It "$tC.$tI-User is listed in the list of AllowUsers but also in a wildcard * DenyGroups" {
It "$tC.$tI-User is listed in the list of AllowUsers but also in a wildcard * DenyGroups" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $localuser2 -Password $password -GroupName $denyGroup2
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $localuser2@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $localuser2@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
Remove-UserFromLocalGroup -UserName $localuser2 -GroupName $denyGroup2
}
It "$tC.$tI-User is listed in the list of AllowUsers but also in a wildcard ? DenyGroups" {
It "$tC.$tI-User is listed in the list of AllowUsers but also in a wildcard ? DenyGroups" -skip:$skip {
#Run
Start-SSHD-TestDaemon -Arguments "-d -f $sshdConfigPath -E $logPath"
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
Add-UserToLocalGroup -UserName $localuser3 -Password $password -GroupName $denyGroup3
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $localuser3@$server echo 1234
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $localuser3@$server echo 1234
$LASTEXITCODE | Should Not Be 0
Stop-SSHD-TestDaemon
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
Stop-SSHDTestDaemon
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
Remove-UserFromLocalGroup -UserName $localuser3 -GroupName $denyGroup3
}
It "$tC.$tI - Match User block with ForceCommand" -skip:$skip {
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments "-d -f $sshdConfigPath -E $sshdlog"
$matchuser = "matchuser"
Add-UserToLocalGroup -UserName $matchuser -Password $password -GroupName $allowGroup1
$o = ssh -p $port -T -o "UserKnownHostsFile $testknownhosts" $matchuser@$server randomcommand
# Match block's ForceCommand returns output of "whoami & set SSH_ORIGINAL_COMMAND"
$o[0].Contains($matchuser) | Should Be $true
$o[1].Contains("randomcommand") | Should Be $true
Stop-SSHDTestDaemon
Remove-UserFromLocalGroup -UserName $matchuser -GroupName $allowGroup1
}
#>
}
}

View File

@ -113,6 +113,9 @@ Subsystem sftp sftp-server.exe -l DEBUG3
PubkeyAcceptedKeyTypes ssh-ed25519*
DenyUsers denyuser1 deny*2 denyuse?3,
AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin
AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin matchuser
DenyGroups denygroup1 denygr*p2 deny?rou?3
AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm*
Match User matchuser
ForceCommand cmd.exe /c "whoami & set SSH_ORIGINAL_COMMAND"

2
sftp.c
View File

@ -397,7 +397,7 @@ make_absolute(char *p, const char *pwd)
* Need to follow up with community if this makes sense in common code
*/
char *s1, *s2;
if (p && p[0] != '/' && (p[0] == '\0' || p[1] != ':')) {
if (!is_absolute_path(p)) {
abs_str = path_append(pwd, p);
free(p);
p = abs_str;

View File

@ -1544,9 +1544,16 @@ do_change_comment(struct passwd *pw)
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
fatal("Could not save your public key in %s", identity_file);
#ifdef WINDOWS
/* Windows POSIX adpater does not support fdopen() on open(file)*/
close(fd);
if ((f = fopen(identity_file, "w")) == NULL)
fatal("fopen %s failed: %s", identity_file, strerror(errno));
#else /* !WINDOWS */
f = fdopen(fd, "w");
if (f == NULL)
fatal("fdopen %s failed: %s", identity_file, strerror(errno));
#endif /* !WINDOWS */
if ((r = sshkey_write(public, f)) != 0)
fatal("write key failed: %s", ssh_err(r));
sshkey_free(public);

View File

@ -199,10 +199,6 @@ static int
ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
const char *proxy_command)
{
#ifdef WINDOWS
fatal("Proxy connect is not supported in Windows yet");
return 0;
#else /* !WINDOWS */
char *command_string;
int pin[2], pout[2];
pid_t pid;
@ -220,6 +216,28 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
host, port);
debug("Executing proxy command: %.500s", command_string);
#ifdef FORK_NOT_SUPPORTED
{
posix_spawn_file_actions_t actions;
char* spawn_argv[2];
/*
* expand_proxy_command prefixes cmdline with "exec "
*/
spawn_argv[0] = command_string + 5;
spawn_argv[1] = NULL;
pid = -1;
if (posix_spawn_file_actions_init(&actions) != 0 ||
posix_spawn_file_actions_adddup2(&actions, pin[0], STDIN_FILENO) != 0 ||
posix_spawn_file_actions_adddup2(&actions, pout[1], STDOUT_FILENO) != 0)
fatal("posix_spawn initialization failed");
else if (posix_spawn(&pid, spawn_argv[0], &actions, NULL, spawn_argv, NULL) != 0)
fatal("posix_spawn: %s", strerror(errno));
posix_spawn_file_actions_destroy(&actions);
}
#else
/* Fork and execute the proxy command. */
if ((pid = fork()) == 0) {
char *argv[10];
@ -254,6 +272,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
perror(argv[0]);
exit(1);
}
#endif
/* Parent. */
if (pid < 0)
fatal("fork failed: %.100s", strerror(errno));
@ -272,7 +291,6 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
return -1; /* ssh_packet_set_connection logs error */
return 0;
#endif /* !WINDOWS */
}
void

10
sshd.c
View File

@ -742,7 +742,9 @@ privsep_preauth(Authctxt *authctxt)
#ifdef FORK_NOT_SUPPORTED
if (privsep_auth_child) {
authctxt->pw = w32_getpwuid(1);
struct passwd* me = getpwuid(geteuid());
/* this re-does the user specific config */
authctxt->pw = getpwnamallow(xstrdup(me->pw_name));
authctxt->valid = 1;
return 1;
}
@ -774,7 +776,7 @@ privsep_preauth(Authctxt *authctxt)
else {
char** argv = privsep_child_cmdline(0);
if (__posix_spawn_asuser(&pid, argv[0], &actions, NULL, argv, NULL, SSH_PRIVSEP_USER) != 0)
error("posix_spawn failed");
error("%s, posix_spawn failed", __func__);
posix_spawn_file_actions_destroy(&actions);
}
close(pmonitor->m_recvfd);
@ -880,7 +882,7 @@ privsep_postauth(Authctxt *authctxt)
else {
char** argv = privsep_child_cmdline(1);
if (__posix_spawn_asuser(&pmonitor->m_pid, argv[0], &actions, NULL, argv, NULL, authctxt->pw->pw_name) != 0)
error("posix_spawn failed");
error("%s, posix_spawn failed", __func__);
posix_spawn_file_actions_destroy(&actions);
}
@ -1545,7 +1547,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
error("posix_spawn initialization failed");
else {
if (posix_spawn(&pid, rexec_argv[0], &actions, &attributes, rexec_argv, NULL) != 0)
error("posix_spawn failed");
error("%s, posix_spawn failed", __func__);
posix_spawn_file_actions_destroy(&actions);
posix_spawnattr_destroy(&attributes);
}

View File

@ -1,6 +1,6 @@
/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
#define SSH_VERSION "OpenSSH_7.6"
#define SSH_VERSION "OpenSSH_for_Windows_7.6"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE