mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-27 07:54:50 +02:00
Source snapshot from Powershell/openssh-portable:latestw_all
This commit is contained in:
parent
0a83df7d22
commit
dbbe15ac80
@ -231,7 +231,7 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
|
|||||||
|
|
||||||
#elif defined(WINDOWS)
|
#elif defined(WINDOWS)
|
||||||
HANDLE password_auth_token = NULL;
|
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
|
void
|
||||||
sys_auth_passwd_lsa(Authctxt *authctxt, const char *password)
|
sys_auth_passwd_lsa(Authctxt *authctxt, const char *password)
|
||||||
@ -254,7 +254,6 @@ sys_auth_passwd_lsa(Authctxt *authctxt, const char *password)
|
|||||||
if (!lsa_auth_pkg)
|
if (!lsa_auth_pkg)
|
||||||
fatal("utf16_to_utf8 failed to convert lsa_auth_pkg_w:%ls", lsa_auth_pkg_w);
|
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);
|
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
|
#ifdef WINDOWS
|
||||||
/* Return if the path is absolute. If not, prepend the '%h\\' */
|
/* Return if the path is absolute. If not, prepend the '%h\\' */
|
||||||
if ((strlen(file) > 1) && (file[1] == ':'))
|
if(is_absolute_path(file))
|
||||||
return (file);
|
return (file);
|
||||||
|
|
||||||
i = snprintf(ret, sizeof(ret), "%s\\%s", pw->pw_dir, 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
|
void
|
||||||
channel_clear_permitted_opens(struct ssh *ssh)
|
channel_clear_permitted_opens(struct ssh *ssh)
|
||||||
{
|
{
|
||||||
if(ssh == NULL)
|
|
||||||
return;
|
|
||||||
struct ssh_channels *sc = ssh->chanctxt;
|
struct ssh_channels *sc = ssh->chanctxt;
|
||||||
|
|
||||||
sc->permitted_opens = xrecallocarray(sc->permitted_opens,
|
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
|
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
|
# Update machine environment path
|
||||||
if ($newMachineEnvironmentPath -ne $machinePath)
|
if ($newMachineEnvironmentPath -ne $machinePath)
|
||||||
@ -207,8 +208,23 @@ function Start-OpenSSHBootstrap
|
|||||||
|
|
||||||
$vcVars = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
|
$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"
|
$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
|
||||||
$packageName = "vcbuildtools"
|
#use vs2017 build tool if exists
|
||||||
If (($nativeMSBuildPath -eq $null) -or (-not (Test-Path $VcVars)) -or (-not (Test-Path $sdkPath))) {
|
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 ..."
|
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
|
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
|
$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."
|
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
|
else
|
||||||
@ -244,14 +260,11 @@ function Start-OpenSSHBootstrap
|
|||||||
Write-BuildMsg -AsVerbose -Message 'VC++ 2015 Build Tools already present.'
|
Write-BuildMsg -AsVerbose -Message 'VC++ 2015 Build Tools already present.'
|
||||||
}
|
}
|
||||||
|
|
||||||
if($NativeHostArch.ToLower().Startswith('arm'))
|
if($NativeHostArch.ToLower().Startswith('arm') -and ($VS2017Path -eq $null))
|
||||||
{
|
{
|
||||||
$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."
|
||||||
#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')))
|
if($OneCore -or ($NativeHostArch.ToLower().Startswith('arm')))
|
||||||
@ -268,7 +281,7 @@ function Start-OpenSSHBootstrap
|
|||||||
# Ensure the VS C toolset is installed
|
# Ensure the VS C toolset is installed
|
||||||
if ($null -eq $env:VS140COMNTOOLS)
|
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')
|
$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
|
Copy-Item -Container -Path $sourcePath -Destination $PSScriptRoot -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable e
|
||||||
if($e -ne $null)
|
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",
|
[string]$Configuration = "Release",
|
||||||
|
|
||||||
# Copy payload to DestinationPath instead of packaging
|
# Copy payload to DestinationPath instead of packaging
|
||||||
[string]$DestinationPath = ""
|
[string]$DestinationPath = "",
|
||||||
|
[switch]$NoOpenSSL
|
||||||
)
|
)
|
||||||
|
|
||||||
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
|
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
|
||||||
@ -390,7 +404,10 @@ function Start-OpenSSHPackage
|
|||||||
|
|
||||||
#copy libcrypto dll
|
#copy libcrypto dll
|
||||||
$libreSSLSDKPath = Join-Path $PSScriptRoot $script:libreSSLSDKStr
|
$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 ($DestinationPath -ne "") {
|
||||||
if (Test-Path $DestinationPath) {
|
if (Test-Path $DestinationPath) {
|
||||||
@ -400,7 +417,7 @@ function Start-OpenSSHPackage
|
|||||||
New-Item -ItemType Directory $DestinationPath -Force | Out-Null
|
New-Item -ItemType Directory $DestinationPath -Force | Out-Null
|
||||||
}
|
}
|
||||||
Copy-Item -Path $packageDir\* -Destination $DestinationPath -Force -Recurse
|
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 {
|
else {
|
||||||
Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
|
Remove-Item ($packageDir + '.zip') -Force -ErrorAction SilentlyContinue
|
||||||
@ -411,7 +428,7 @@ function Start-OpenSSHPackage
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Write-BuildMsg -AsInfo -Message "Packaged Payload not compressed."
|
Write-BuildMsg -AsInfo -Message "Packaged Payload not compressed."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
@ -470,7 +487,7 @@ function Start-OpenSSHBuild
|
|||||||
Remove-Item -Path $script:BuildLogFile -force
|
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
|
Start-OpenSSHBootstrap -OneCore:$OneCore
|
||||||
|
|
||||||
@ -523,17 +540,25 @@ function Start-OpenSSHBuild
|
|||||||
$xml.Project.PropertyGroup.WindowsSDKVersion = $win10SDKVer.ToString()
|
$xml.Project.PropertyGroup.WindowsSDKVersion = $win10SDKVer.ToString()
|
||||||
$xml.Project.PropertyGroup.AdditionalDependentLibs = 'onecore.lib'
|
$xml.Project.PropertyGroup.AdditionalDependentLibs = 'onecore.lib'
|
||||||
$xml.Project.PropertyGroup.MinimalCoreWin = 'true'
|
$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)
|
$xml.Save($PathTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
$solutionFile = Get-SolutionFile -root $repositoryRoot.FullName
|
$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")
|
$cmdMsg = @("${solutionFile}", "/t:Rebuild", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/m", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic")
|
||||||
|
if($silent)
|
||||||
if($NativeHostArch.ToLower().Startswith('arm'))
|
|
||||||
{
|
{
|
||||||
$msbuildCmd = Get-VS2017BuildToolPath
|
$cmdMsg += "/noconlog"
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
$msbuildCmd = Get-VS2017BuildToolPath
|
||||||
|
if($msbuildCmd -eq $null)
|
||||||
{
|
{
|
||||||
$msbuildCmd = Get-VS2015BuildToolPath
|
$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
|
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
|
$backupConfigPath = Join-Path $OpenSSHConfigPath sshd_config.ori
|
||||||
|
#Backup existing OpenSSH configuration
|
||||||
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
|
if (-not (Test-Path $backupConfigPath -PathType Leaf)) {
|
||||||
Copy-Item (Join-Path $OpenSSHConfigPath sshd_config) $backupConfigPath -Force
|
Copy-Item (Join-Path $OpenSSHConfigPath sshd_config) $backupConfigPath -Force
|
||||||
}
|
}
|
||||||
|
@ -1565,7 +1565,7 @@
|
|||||||
#define _PATH_PASSWD_PROG "/usr/bin/passwd"
|
#define _PATH_PASSWD_PROG "/usr/bin/passwd"
|
||||||
|
|
||||||
/* Specify location of ssh.pid */
|
/* 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 if we don't have struct __res_state in resolv.h */
|
||||||
#define __res_state state
|
#define __res_state state
|
||||||
@ -1693,6 +1693,7 @@
|
|||||||
|
|
||||||
#define _PATH_PRIVSEP_CHROOT_DIR "."
|
#define _PATH_PRIVSEP_CHROOT_DIR "."
|
||||||
#define SSHDIR "__PROGRAMDATA__\\ssh"
|
#define SSHDIR "__PROGRAMDATA__\\ssh"
|
||||||
|
#define _PATH_SSH_PIDDIR SSHDIR
|
||||||
#define _PATH_SFTP_SERVER "sftp-server.exe"
|
#define _PATH_SFTP_SERVER "sftp-server.exe"
|
||||||
#define _PATH_SSH_PROGRAM "ssh.exe"
|
#define _PATH_SSH_PROGRAM "ssh.exe"
|
||||||
#define _PATH_LS "dir"
|
#define _PATH_LS "dir"
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<UseOpenSSL>true</UseOpenSSL>
|
<UseOpenSSL>true</UseOpenSSL>
|
||||||
<SSLLib>libcrypto.lib;</SSLLib>
|
<SSLLib>libcrypto.lib;</SSLLib>
|
||||||
<WindowsSDKVersion>8.1</WindowsSDKVersion>
|
<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>
|
<MinimalCoreWin>false</MinimalCoreWin>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</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 0.0.0.0
|
||||||
#ListenAddress ::
|
#ListenAddress ::
|
||||||
|
|
||||||
#HostKey /etc/ssh/ssh_host_rsa_key
|
#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
|
||||||
#HostKey /etc/ssh/ssh_host_dsa_key
|
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
|
||||||
#HostKey /etc/ssh/ssh_host_ecdsa_key
|
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
|
||||||
#HostKey /etc/ssh/ssh_host_ed25519_key
|
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key
|
||||||
|
|
||||||
# Ciphers and keying
|
# Ciphers and keying
|
||||||
#RekeyLimit default none
|
#RekeyLimit default none
|
||||||
@ -39,7 +39,7 @@ AuthorizedKeysFile .ssh/authorized_keys
|
|||||||
|
|
||||||
#AuthorizedPrincipalsFile none
|
#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
|
#HostbasedAuthentication no
|
||||||
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
||||||
# HostbasedAuthentication
|
# 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)
|
is_absolute_path(char *path)
|
||||||
{
|
{
|
||||||
int retVal = 0;
|
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)))
|
((strlen(path) >= strlen(PROGRAM_DATA)) && (memcmp(path, PROGRAM_DATA, strlen(PROGRAM_DATA)) == 0)))
|
||||||
retVal = 1;
|
retVal = 1;
|
||||||
|
|
||||||
return retVal;
|
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>
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
#define PATH_MAX MAX_PATH
|
#define PATH_MAX MAX_PATH
|
||||||
|
#define SSH_REGISTRY_ROOT L"SOFTWARE\\OpenSSH"
|
||||||
#define GOTO_CLEANUP_IF(_cond_,_err_) do { \
|
#define GOTO_CLEANUP_IF(_cond_,_err_) do { \
|
||||||
if ((_cond_)) { \
|
if ((_cond_)) { \
|
||||||
hr = _err_; \
|
hr = _err_; \
|
||||||
@ -40,3 +40,5 @@ int get_machine_domain_name(wchar_t *domain, int size);
|
|||||||
char* get_program_data_path();
|
char* get_program_data_path();
|
||||||
HANDLE get_user_token(char* user);
|
HANDLE get_user_token(char* user);
|
||||||
int load_user_profile(HANDLE 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;
|
int tmp_len = PATH_MAX;
|
||||||
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
||||||
DWORD dsStatus, uname_upn_len = 0, uname_len = 0, udom_len = 0;
|
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_t r = 0;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@ -135,6 +137,14 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
|
|||||||
udom_utf16 = NULL;
|
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) {
|
if (user_sid == NULL) {
|
||||||
NET_API_STATUS status;
|
NET_API_STATUS status;
|
||||||
if ((status = NetUserGetInfo(udom_utf16, uname_utf16, 23, &user_info)) != NERR_Success) {
|
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));
|
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)) ||
|
if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info)) ||
|
||||||
!AssignProcessToJobObject(job, GetCurrentProcess())) {
|
!AssignProcessToJobObject(job, GetCurrentProcess())) {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
#define MAX_MESSAGE_SIZE 256 * 1024
|
#define MAX_MESSAGE_SIZE 256 * 1024
|
||||||
|
|
||||||
#define SSH_ROOT L"SOFTWARE\\OpenSSH"
|
#define SSH_AGENT_ROOT SSH_REGISTRY_ROOT L"\\Agent"
|
||||||
#define SSH_AGENT_ROOT SSH_ROOT L"\\Agent"
|
|
||||||
#define SSH_KEYS_KEY L"Keys"
|
#define SSH_KEYS_KEY L"Keys"
|
||||||
#define SSH_KEYS_ROOT SSH_AGENT_ROOT L"\\" SSH_KEYS_KEY
|
#define SSH_KEYS_ROOT SSH_AGENT_ROOT L"\\" SSH_KEYS_KEY
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "inc\fcntl.h"
|
#include "inc\fcntl.h"
|
||||||
#include "inc\sys\un.h"
|
#include "inc\sys\un.h"
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
|
#include "inc\stdio.h"
|
||||||
|
|
||||||
#include "w32fd.h"
|
#include "w32fd.h"
|
||||||
#include "signal_internal.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;
|
int add_module_path = 0, ret = -1;
|
||||||
|
|
||||||
/* should module path be added */
|
/* should module path be added */
|
||||||
do {
|
if (!cmd) {
|
||||||
if (!cmd)
|
error("%s invalid argument cmd:%s", __func__, cmd);
|
||||||
break;
|
return -1;
|
||||||
t = cmd;
|
}
|
||||||
if (*t == '\"')
|
|
||||||
t++;
|
t = cmd;
|
||||||
if (t[0] == '\0' || t[0] == '\\' || t[0] == '.' || t[1] == ':')
|
if (!is_absolute_path(t))
|
||||||
break;
|
|
||||||
add_module_path = 1;
|
add_module_path = 1;
|
||||||
} while (0);
|
|
||||||
|
|
||||||
/* compute total cmdline len*/
|
/* compute total cmdline len*/
|
||||||
if (add_module_path)
|
if (add_module_path)
|
||||||
@ -1040,6 +1039,7 @@ spawn_child_internal(char* cmd, char *const argv[], HANDLE in, HANDLE out, HANDL
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errno = GetLastError();
|
errno = GetLastError();
|
||||||
|
error("%s failed error:%d", (as_user?"CreateProcessAsUserW":"CreateProcessW"), GetLastError());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,16 @@
|
|||||||
#include <Ntsecapi.h>
|
#include <Ntsecapi.h>
|
||||||
#include <ntstatus.h>
|
#include <ntstatus.h>
|
||||||
#include <Shlobj.h>
|
#include <Shlobj.h>
|
||||||
|
#include <LM.h>
|
||||||
|
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
#include "logonuser.h"
|
#include "logonuser.h"
|
||||||
#include <Ntsecapi.h>
|
#include <Ntsecapi.h>
|
||||||
|
#include <Strsafe.h>
|
||||||
|
#include <sddl.h>
|
||||||
#include <ntstatus.h>
|
#include <ntstatus.h>
|
||||||
#include "misc_internal.h"
|
#include "misc_internal.h"
|
||||||
|
#include "lsa_missingdefs.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
|
||||||
#pragma warning(push, 3)
|
#pragma warning(push, 3)
|
||||||
@ -116,7 +121,7 @@ done:
|
|||||||
#define MAX_PW_LEN 64
|
#define MAX_PW_LEN 64
|
||||||
|
|
||||||
static HANDLE
|
static HANDLE
|
||||||
generate_user_token(wchar_t* user_cpn) {
|
generate_s4u_user_token(wchar_t* user_cpn) {
|
||||||
HANDLE lsa_handle = 0, token = 0;
|
HANDLE lsa_handle = 0, token = 0;
|
||||||
LSA_OPERATIONAL_MODE mode;
|
LSA_OPERATIONAL_MODE mode;
|
||||||
ULONG auth_package_id;
|
ULONG auth_package_id;
|
||||||
@ -223,14 +228,14 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
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;
|
HANDLE token = NULL, lsa_handle = NULL;
|
||||||
LSA_OPERATIONAL_MODE mode;
|
LSA_OPERATIONAL_MODE mode;
|
||||||
ULONG auth_package_id, logon_info_size = 0;
|
ULONG auth_package_id, logon_info_size = 0;
|
||||||
NTSTATUS ret, subStatus;
|
NTSTATUS ret, subStatus;
|
||||||
wchar_t *logon_info = NULL;
|
wchar_t *logon_info_w = NULL;
|
||||||
LSA_STRING logon_process_name, lsa_auth_package_name, originName;
|
LSA_STRING logon_process_name, lsa_auth_package_name, originName;
|
||||||
TOKEN_SOURCE sourceContext;
|
TOKEN_SOURCE sourceContext;
|
||||||
PVOID pProfile = NULL;
|
PVOID pProfile = NULL;
|
||||||
@ -238,19 +243,34 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
|
|||||||
QUOTA_LIMITS quotas;
|
QUOTA_LIMITS quotas;
|
||||||
DWORD cbProfile;
|
DWORD cbProfile;
|
||||||
int retVal = -1;
|
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 ||
|
logon_info_size = (ULONG)(strlen(user) + strlen(pwd) + 2); // 1 - ";", 1 - "\0"
|
||||||
(pwdw = utf8_to_utf16(pwd)) == NULL) {
|
strcpy_s(user_name, _countof(user_name), user);
|
||||||
debug("out of memory");
|
if (tmp = strstr(user_name, "@")) {
|
||||||
goto done;
|
domain = tmp + 1;
|
||||||
|
*tmp = '\0';
|
||||||
|
logon_info_size++; // 1 - ";"
|
||||||
}
|
}
|
||||||
|
|
||||||
/* split user and domain */
|
logon_info = malloc(logon_info_size);
|
||||||
if ((tmp = wcschr(userw, L'@')) != NULL) {
|
if(!logon_info)
|
||||||
domw = tmp + 1;
|
fatal("%s out of memory", __func__);
|
||||||
*tmp = L'\0';
|
|
||||||
|
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 */
|
/* call into LSA provider , get and duplicate token */
|
||||||
@ -268,17 +288,6 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
|
|||||||
goto done;
|
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));
|
memcpy(sourceContext.SourceName, "sshd", sizeof(sourceContext.SourceName));
|
||||||
|
|
||||||
if (!AllocateLocallyUniqueId(&sourceContext.SourceIdentifier)) {
|
if (!AllocateLocallyUniqueId(&sourceContext.SourceIdentifier)) {
|
||||||
@ -290,8 +299,8 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
|
|||||||
&originName,
|
&originName,
|
||||||
Network,
|
Network,
|
||||||
auth_package_id,
|
auth_package_id,
|
||||||
logon_info,
|
logon_info_w,
|
||||||
logon_info_size,
|
logon_info_size * sizeof(wchar_t),
|
||||||
NULL,
|
NULL,
|
||||||
&sourceContext,
|
&sourceContext,
|
||||||
&pProfile,
|
&pProfile,
|
||||||
@ -300,7 +309,7 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
|
|||||||
&token,
|
&token,
|
||||||
"as,
|
"as,
|
||||||
&subStatus)) != STATUS_SUCCESS) {
|
&subStatus)) != STATUS_SUCCESS) {
|
||||||
if(ret == STATUS_ACCOUNT_RESTRICTION)
|
if (ret == STATUS_ACCOUNT_RESTRICTION)
|
||||||
error("LsaLogonUser failed, error:%x subStatus:%ld", ret, subStatus);
|
error("LsaLogonUser failed, error:%x subStatus:%ld", ret, subStatus);
|
||||||
else
|
else
|
||||||
error("LsaLogonUser failed error:%x", ret);
|
error("LsaLogonUser failed error:%x", ret);
|
||||||
@ -308,23 +317,23 @@ process_custom_lsa_auth(char* user, const char* pwd, char* lsa_pkg)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug3("LSA auth request is successful for user:%s ", user);
|
||||||
retVal = 0;
|
retVal = 0;
|
||||||
done:
|
done:
|
||||||
/* delete allocated memory*/
|
|
||||||
if (lsa_handle)
|
if (lsa_handle)
|
||||||
LsaDeregisterLogonProcess(lsa_handle);
|
LsaDeregisterLogonProcess(lsa_handle);
|
||||||
if (logon_info)
|
|
||||||
free(logon_info);
|
|
||||||
if (pProfile)
|
if (pProfile)
|
||||||
LsaFreeReturnBuffer(pProfile);
|
LsaFreeReturnBuffer(pProfile);
|
||||||
if (userw)
|
if (logon_info)
|
||||||
free(userw);
|
free(logon_info);
|
||||||
if (pwdw)
|
if (logon_info_w)
|
||||||
free(pwdw);
|
free(logon_info_w);
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE generate_sshd_virtual_token();
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
get_user_token(char* user) {
|
get_user_token(char* user) {
|
||||||
HANDLE token = NULL;
|
HANDLE token = NULL;
|
||||||
@ -335,12 +344,18 @@ get_user_token(char* user) {
|
|||||||
goto done;
|
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);
|
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 */
|
/* work around for https://github.com/PowerShell/Win32-OpenSSH/issues/727 by doing a fake login */
|
||||||
LogonUserExExWHelper(L"FakeUser", L"FakeDomain", L"FakePasswd",
|
LogonUserExExWHelper(L"FakeUser", L"FakeDomain", L"FakePasswd",
|
||||||
LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, NULL, &token, NULL, NULL, NULL, NULL);
|
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);
|
error("unable to generate token on 2nd attempt for user %ls", user_utf16);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -378,4 +393,209 @@ done:
|
|||||||
return r;
|
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)
|
#pragma warning(pop)
|
@ -35,6 +35,8 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <Lm.h>
|
#include <Lm.h>
|
||||||
|
#include <sddl.h>
|
||||||
|
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
#include "misc_internal.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"
|
#define SSH_HOSTKEY_GEN_CMDLINE L"ssh-keygen -A"
|
||||||
static void
|
static void
|
||||||
prereq_setup()
|
generate_host_keys()
|
||||||
{
|
{
|
||||||
TOKEN_USER* info = NULL;
|
TOKEN_USER* info = NULL;
|
||||||
DWORD info_len = 0, dwError = 0;
|
DWORD info_len = 0, dwError = 0;
|
||||||
@ -127,7 +129,7 @@ prereq_setup()
|
|||||||
ui.usri1_priv = USER_PRIV_USER;
|
ui.usri1_priv = USER_PRIV_USER;
|
||||||
ui.usri1_home_dir = NULL;
|
ui.usri1_home_dir = NULL;
|
||||||
ui.usri1_comment = NULL;
|
ui.usri1_comment = NULL;
|
||||||
ui.usri1_flags = UF_SCRIPT;
|
ui.usri1_flags = UF_SCRIPT | UF_DONT_EXPIRE_PASSWD;
|
||||||
ui.usri1_script_path = NULL;
|
ui.usri1_script_path = NULL;
|
||||||
|
|
||||||
NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError);
|
NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError);
|
||||||
@ -151,14 +153,96 @@ cleanup:
|
|||||||
free(info);
|
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) {
|
int sshd_main(int argc, wchar_t **wargv) {
|
||||||
char** argv = NULL;
|
char** argv = NULL;
|
||||||
int i, r;
|
int i, r;
|
||||||
_set_invalid_parameter_handler(invalid_parameter_handler);
|
_set_invalid_parameter_handler(invalid_parameter_handler);
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
if ((argv = malloc(argc * sizeof(char*))) == NULL)
|
if ((argv = malloc(argc * sizeof(char*))) == NULL) {
|
||||||
fatal("out of memory");
|
printf("out of memory");
|
||||||
|
exit(255);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
argv[i] = utf16_to_utf8(wargv[i]);
|
argv[i] = utf16_to_utf8(wargv[i]);
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,15 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
|
|||||||
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
|
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileName = "test.txt"
|
$sshLogName = "test.txt"
|
||||||
$logName = "sshdlog.txt"
|
$sshdLogName = "sshdlog.txt"
|
||||||
$server = $OpenSSHTestInfo["Target"]
|
$server = $OpenSSHTestInfo["Target"]
|
||||||
$port = 47003
|
$port = 47003
|
||||||
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
||||||
$PwdUser = $OpenSSHTestInfo["PasswdUser"]
|
$PwdUser = $OpenSSHTestInfo["PasswdUser"]
|
||||||
$ssouserProfile = $OpenSSHTestInfo["SSOUserProfile"]
|
$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
|
$platform = Get-Platform
|
||||||
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
|
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
|
||||||
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
|
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
|
||||||
@ -32,27 +33,6 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
|
|||||||
#suppress the firewall blocking dialogue on win7
|
#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
|
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++ }
|
AfterEach { $tI++ }
|
||||||
@ -79,10 +59,12 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
|
|||||||
$Source = Join-Path $ssouserProfile .ssh\authorized_keys
|
$Source = Join-Path $ssouserProfile .ssh\authorized_keys
|
||||||
$testknownhosts = Join-path $PSScriptRoot testdata\test_known_hosts
|
$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
|
Repair-AuthorizedKeyPermission -Filepath $authorizedkeyPath -confirm:$false
|
||||||
|
if(-not $skip)
|
||||||
|
{
|
||||||
|
Stop-SSHDTestDaemon
|
||||||
|
}
|
||||||
|
|
||||||
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
|
|
||||||
#add wrong password so ssh does not prompt password if failed with authorized keys
|
#add wrong password so ssh does not prompt password if failed with authorized keys
|
||||||
Add-PasswordSetting -Pass "WrongPass"
|
Add-PasswordSetting -Pass "WrongPass"
|
||||||
$tI=1
|
$tI=1
|
||||||
@ -102,73 +84,73 @@ Describe "Tests for authorized_keys file permission" -Tags "CI" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BeforeEach {
|
BeforeEach {
|
||||||
$filePath = Join-Path $testDir "$tC.$tI.$fileName"
|
$sshlog = Join-Path $testDir "$tC.$tI.$sshLogName"
|
||||||
$logPath = Join-Path $testDir "$tC.$tI.$logName"
|
$sshdlog = Join-Path $testDir "$tC.$tI.$sshdLogName"
|
||||||
Get-Process -Name sshd -ErrorAction SilentlyContinue | Where-Object {$_.SessionID -ne 0} | Stop-process -force -ErrorAction SilentlyContinue
|
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
|
#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
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owners $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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
|
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$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
|
#setup to have system as owner and grant it full control
|
||||||
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $systemSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $systemSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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
|
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$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
|
#setup to have admin group as owner and grant it full control
|
||||||
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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
|
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$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
|
#setup to have admin group as owner and grant it full control
|
||||||
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $adminsSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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
|
$o = ssh -p $port $ssouser@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$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
|
#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
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $currentUserSid -FullAccessNeeded $adminsSid,$systemSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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"
|
||||||
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
||||||
$LASTEXITCODE | Should Not Be 0
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "Authentication refused."
|
$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
|
#setup to have current user as owner and grant it full control
|
||||||
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objUserSid -FullAccessNeeded $adminsSid,$systemSid,$objUserSid -confirm:$false
|
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"
|
Set-FilePermission -FilePath $authorizedkeyPath -User $objPwdUserSid -Perm "Read"
|
||||||
|
|
||||||
#Run
|
#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"
|
||||||
ssh -p $port -E $filePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
||||||
$LASTEXITCODE | Should Not Be 0
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "Authentication refused."
|
$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
|
#setup to have PwdUser as owner and grant it full control
|
||||||
$objPwdUserSid = Get-UserSid -User $PwdUser
|
$objPwdUserSid = Get-UserSid -User $PwdUser
|
||||||
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objPwdUserSid -FullAccessNeeded $adminsSid,$systemSid,$objPwdUser -confirm:$false
|
Repair-FilePermission -Filepath $authorizedkeyPath -Owner $objPwdUserSid -FullAccessNeeded $adminsSid,$systemSid,$objPwdUser -confirm:$false
|
||||||
|
|
||||||
#Run
|
#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"
|
||||||
ssh -p $port -E $FilePath -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
ssh -p $port -E $sshlog -o "UserKnownHostsFile $testknownhosts" $ssouser@$server echo 1234
|
||||||
$LASTEXITCODE | Should Not Be 0
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "Authentication refused."
|
$sshlog | Should Contain "Permission denied"
|
||||||
|
$sshdlog | Should Contain "Authentication refused."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,3 +106,51 @@ function Remove-PasswordSetting
|
|||||||
if ($env:DISPLAY -eq 1) { Remove-Item env:\DISPLAY }
|
if ($env:DISPLAY -eq 1) { Remove-Item env:\DISPLAY }
|
||||||
Remove-item "env:SSH_ASKPASS" -ErrorAction SilentlyContinue
|
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" {
|
It "$tC.$tI - test version" {
|
||||||
iex "cmd /c `"ssh -V 2> $stderrFile`""
|
iex "cmd /c `"ssh -V 2> $stderrFile`""
|
||||||
$stderrFile | Should Contain "OpenSSH_"
|
$stderrFile | Should Contain "OpenSSH_for_Windows"
|
||||||
}
|
}
|
||||||
|
|
||||||
It "$tC.$tI - test help" {
|
It "$tC.$tI - test help" {
|
||||||
@ -147,7 +147,7 @@ Describe "E2E scenarios for ssh client" -Tags "CI" {
|
|||||||
$o | Should Be "1234"
|
$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
|
# execute this script that dumps the length of input data, on the remote end
|
||||||
$str = "begin {} process { Write-Output `$input.Length} end { }"
|
$str = "begin {} process { Write-Output `$input.Length} end { }"
|
||||||
$EncodedText =[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))
|
$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"
|
$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)
|
# prep a file of size > 10KB (https://github.com/PowerShell/Win32-OpenSSH/issues/908 was caught with such file size)
|
||||||
$str = ""
|
$str = ""
|
||||||
(1..100) | foreach {$str += "1234567890"}
|
(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
|
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
|
$shell_path = (Get-Command powershell.exe -ErrorAction SilentlyContinue).path
|
||||||
if($shell_path -ne $null) {
|
if($shell_path -ne $null) {
|
||||||
ConfigureDefaultShell -default_shell_path $shell_path -default_shell_cmd_option_val "/c"
|
ConfigureDefaultShell -default_shell_path $shell_path -default_shell_cmd_option_val "/c"
|
||||||
|
@ -16,37 +16,18 @@ Describe "Tests of sshd_config" -Tags "CI" {
|
|||||||
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
|
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
$fileName = "test.txt"
|
$sshLogName = "test.txt"
|
||||||
$logName = "sshdlog.txt"
|
$sshdLogName = "sshdlog.txt"
|
||||||
$server = $OpenSSHTestInfo["Target"]
|
$server = $OpenSSHTestInfo["Target"]
|
||||||
|
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
|
||||||
$port = 47003
|
$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
|
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
|
||||||
$ContextName = $env:COMPUTERNAME
|
$ContextName = $env:COMPUTERNAME
|
||||||
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Machine
|
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Machine
|
||||||
$PrincipalContext = new-object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList @($ContextType, $ContextName)
|
$PrincipalContext = new-object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList @($ContextType, $ContextName)
|
||||||
$IdentityType = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName
|
$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} }
|
|
||||||
}
|
|
||||||
|
|
||||||
function Add-LocalUser
|
function Add-LocalUser
|
||||||
{
|
{
|
||||||
@ -133,6 +114,10 @@ Describe "Tests of sshd_config" -Tags "CI" {
|
|||||||
}
|
}
|
||||||
$platform = Get-Platform
|
$platform = Get-Platform
|
||||||
$skip = ($platform -eq [PlatformType]::Windows) -and ($PSVersionTable.PSVersion.Major -le 2)
|
$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))
|
if(($platform -eq [PlatformType]::Windows) -and ($psversiontable.BuildVersion.Major -le 6))
|
||||||
{
|
{
|
||||||
#suppress the firewall blocking dialogue on win7
|
#suppress the firewall blocking dialogue on win7
|
||||||
@ -190,8 +175,12 @@ Describe "Tests of sshd_config" -Tags "CI" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BeforeEach {
|
BeforeEach {
|
||||||
$filePath = Join-Path $testDir "$tC.$tI.$fileName"
|
$sshlog = Join-Path $testDir "$tC.$tI.$sshLogName"
|
||||||
$logPath = Join-Path $testDir "$tC.$tI.$logName"
|
$sshdlog = Join-Path $testDir "$tC.$tI.$sshdLogName"
|
||||||
|
if(-not $skip)
|
||||||
|
{
|
||||||
|
Stop-SSHDTestDaemon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AfterAll {
|
AfterAll {
|
||||||
@ -199,148 +188,162 @@ Describe "Tests of sshd_config" -Tags "CI" {
|
|||||||
$tC++
|
$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
|
#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
|
Add-UserToLocalGroup -UserName $allowUser1 -Password $password -GroupName $allowGroup1
|
||||||
|
|
||||||
$o = ssh -p $port $allowUser1@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
$o = ssh -p $port $allowUser1@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$o | Should Be "1234"
|
||||||
Remove-UserFromLocalGroup -UserName $allowUser1 -GroupName $allowGroup1
|
Remove-UserFromLocalGroup -UserName $allowUser1 -GroupName $allowGroup1
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
It "$tC.$tI-User with * wildcard" {
|
It "$tC.$tI-User with * wildcard" -skip:$skip {
|
||||||
#Run
|
#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
|
Add-UserToLocalGroup -UserName $allowUser2 -Password $password -GroupName $allowGroup1
|
||||||
|
|
||||||
$o = ssh -p $port $allowUser2@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
$o = ssh -p $port $allowUser2@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$o | Should Be "1234"
|
||||||
Remove-UserFromLocalGroup -UserName $allowUser2 -GroupName $allowGroup1
|
Remove-UserFromLocalGroup -UserName $allowUser2 -GroupName $allowGroup1
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
It "$tC.$tI-User with ? wildcard" {
|
It "$tC.$tI-User with ? wildcard" -skip:$skip {
|
||||||
#Run
|
#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
|
Add-UserToLocalGroup -UserName $allowUser3 -Password $password -GroupName $allowGroup1
|
||||||
|
|
||||||
$o = ssh -p $port $allowUser3@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
$o = ssh -p $port $allowUser3@$server -o "UserKnownHostsFile $testknownhosts" echo 1234
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$o | Should Be "1234"
|
$o | Should Be "1234"
|
||||||
Remove-UserFromLocalGroup -UserName $allowUser3 -GroupName $allowGroup1
|
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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because not in any group"
|
$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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because listed in DenyUsers"
|
$sshdlog | Should Contain "not allowed because listed in DenyUsers"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $denyUser1 -GroupName $allowGroup1
|
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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because listed in DenyUsers"
|
$sshdlog | Should Contain "not allowed because listed in DenyUsers"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $denyUser2 -GroupName $allowGroup1
|
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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because not listed in AllowUsers"
|
$sshdlog | Should Contain "not allowed because not listed in AllowUsers"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $denyUser3 -GroupName $allowGroup1
|
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
|
#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 $allowGroup1
|
||||||
Add-UserToLocalGroup -UserName $localuser1 -Password $password -GroupName $denyGroup1
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
|
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $localuser1 -GroupName $allowGroup1
|
Remove-UserFromLocalGroup -UserName $localuser1 -GroupName $allowGroup1
|
||||||
Remove-UserFromLocalGroup -UserName $localuser1 -GroupName $denyGroup1
|
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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
|
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $localuser2 -GroupName $denyGroup2
|
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
|
#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
|
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
|
$LASTEXITCODE | Should Not Be 0
|
||||||
Stop-SSHD-TestDaemon
|
Stop-SSHDTestDaemon
|
||||||
$logPath | Should Contain "not allowed because a group is listed in DenyGroups"
|
$sshdlog | Should Contain "not allowed because a group is listed in DenyGroups"
|
||||||
|
|
||||||
Remove-UserFromLocalGroup -UserName $localuser3 -GroupName $denyGroup3
|
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*
|
PubkeyAcceptedKeyTypes ssh-ed25519*
|
||||||
|
|
||||||
DenyUsers denyuser1 deny*2 denyuse?3,
|
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
|
DenyGroups denygroup1 denygr*p2 deny?rou?3
|
||||||
AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm*
|
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
|
* Need to follow up with community if this makes sense in common code
|
||||||
*/
|
*/
|
||||||
char *s1, *s2;
|
char *s1, *s2;
|
||||||
if (p && p[0] != '/' && (p[0] == '\0' || p[1] != ':')) {
|
if (!is_absolute_path(p)) {
|
||||||
abs_str = path_append(pwd, p);
|
abs_str = path_append(pwd, p);
|
||||||
free(p);
|
free(p);
|
||||||
p = abs_str;
|
p = abs_str;
|
||||||
|
@ -1544,9 +1544,16 @@ do_change_comment(struct passwd *pw)
|
|||||||
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
fatal("Could not save your public key in %s", identity_file);
|
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");
|
f = fdopen(fd, "w");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
fatal("fdopen %s failed: %s", identity_file, strerror(errno));
|
fatal("fdopen %s failed: %s", identity_file, strerror(errno));
|
||||||
|
#endif /* !WINDOWS */
|
||||||
if ((r = sshkey_write(public, f)) != 0)
|
if ((r = sshkey_write(public, f)) != 0)
|
||||||
fatal("write key failed: %s", ssh_err(r));
|
fatal("write key failed: %s", ssh_err(r));
|
||||||
sshkey_free(public);
|
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,
|
ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
|
||||||
const char *proxy_command)
|
const char *proxy_command)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
fatal("Proxy connect is not supported in Windows yet");
|
|
||||||
return 0;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
char *command_string;
|
char *command_string;
|
||||||
int pin[2], pout[2];
|
int pin[2], pout[2];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -220,6 +216,28 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
|
|||||||
host, port);
|
host, port);
|
||||||
debug("Executing proxy command: %.500s", command_string);
|
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. */
|
/* Fork and execute the proxy command. */
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
char *argv[10];
|
char *argv[10];
|
||||||
@ -254,6 +272,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
|
|||||||
perror(argv[0]);
|
perror(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* Parent. */
|
/* Parent. */
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
fatal("fork failed: %.100s", strerror(errno));
|
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 -1; /* ssh_packet_set_connection logs error */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
10
sshd.c
10
sshd.c
@ -742,7 +742,9 @@ privsep_preauth(Authctxt *authctxt)
|
|||||||
|
|
||||||
#ifdef FORK_NOT_SUPPORTED
|
#ifdef FORK_NOT_SUPPORTED
|
||||||
if (privsep_auth_child) {
|
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;
|
authctxt->valid = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -774,7 +776,7 @@ privsep_preauth(Authctxt *authctxt)
|
|||||||
else {
|
else {
|
||||||
char** argv = privsep_child_cmdline(0);
|
char** argv = privsep_child_cmdline(0);
|
||||||
if (__posix_spawn_asuser(&pid, argv[0], &actions, NULL, argv, NULL, SSH_PRIVSEP_USER) != 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);
|
posix_spawn_file_actions_destroy(&actions);
|
||||||
}
|
}
|
||||||
close(pmonitor->m_recvfd);
|
close(pmonitor->m_recvfd);
|
||||||
@ -880,7 +882,7 @@ privsep_postauth(Authctxt *authctxt)
|
|||||||
else {
|
else {
|
||||||
char** argv = privsep_child_cmdline(1);
|
char** argv = privsep_child_cmdline(1);
|
||||||
if (__posix_spawn_asuser(&pmonitor->m_pid, argv[0], &actions, NULL, argv, NULL, authctxt->pw->pw_name) != 0)
|
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);
|
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");
|
error("posix_spawn initialization failed");
|
||||||
else {
|
else {
|
||||||
if (posix_spawn(&pid, rexec_argv[0], &actions, &attributes, rexec_argv, NULL) != 0)
|
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_spawn_file_actions_destroy(&actions);
|
||||||
posix_spawnattr_destroy(&attributes);
|
posix_spawnattr_destroy(&attributes);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
|
/* $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_PORTABLE "p1"
|
||||||
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user