mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-24 22:45:17 +02:00
Source snapshot from Powershell/openssh-portable:latestw_all
This commit is contained in:
parent
0a83df7d22
commit
dbbe15ac80
@ -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
2
auth.c
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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>
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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.
55
contrib/win32/win32compat/lsa_missingdefs.h
Normal file
55
contrib/win32/win32compat/lsa_missingdefs.h
Normal 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
|
||||
);
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
@ -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) {
|
||||
|
@ -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())) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
"as,
|
||||
&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)
|
@ -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;
|
||||
|
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
#>
|
||||
}
|
||||
}
|
||||
|
5
regress/pesterTests/testdata/SSHD_Config
vendored
5
regress/pesterTests/testdata/SSHD_Config
vendored
@ -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
2
sftp.c
@ -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;
|
||||
|
@ -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);
|
||||
|
28
sshconnect.c
28
sshconnect.c
@ -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
10
sshd.c
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user