Groupaccess support (https://github.com/PowerShell/Win32-OpenSSH/issues/463)
This commit is contained in:
parent
c4a9f83682
commit
8e9236b03b
|
@ -244,7 +244,6 @@ int sys_auth_passwd(Authctxt *authctxt, const char *password)
|
||||||
if (sshbuf_put_u8(msg, SSH_AGENT_AUTHENTICATE) != 0 ||
|
if (sshbuf_put_u8(msg, SSH_AGENT_AUTHENTICATE) != 0 ||
|
||||||
sshbuf_put_cstring(msg, PASSWD_AUTH_REQUEST) != 0 ||
|
sshbuf_put_cstring(msg, PASSWD_AUTH_REQUEST) != 0 ||
|
||||||
sshbuf_put_cstring(msg, authctxt->pw->pw_name) != 0 ||
|
sshbuf_put_cstring(msg, authctxt->pw->pw_name) != 0 ||
|
||||||
sshbuf_put_cstring(msg, authctxt->pw->pw_domain) != 0 ||
|
|
||||||
sshbuf_put_cstring(msg, password) != 0 ||
|
sshbuf_put_cstring(msg, password) != 0 ||
|
||||||
ssh_request_reply(auth_sock, msg, msg) != 0 ||
|
ssh_request_reply(auth_sock, msg, msg) != 0 ||
|
||||||
sshbuf_get_u32(msg, &token) != 0) {
|
sshbuf_get_u32(msg, &token) != 0) {
|
||||||
|
|
|
@ -196,7 +196,6 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
(r = sshkey_to_blob(key, &blob, &blen)) != 0 ||
|
(r = sshkey_to_blob(key, &blob, &blen)) != 0 ||
|
||||||
(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
|
(r = sshbuf_put_string(msg, blob, blen)) != 0 ||
|
||||||
(r = sshbuf_put_cstring(msg, authctxt->pw->pw_name)) != 0 ||
|
(r = sshbuf_put_cstring(msg, authctxt->pw->pw_name)) != 0 ||
|
||||||
(r = sshbuf_put_cstring(msg, authctxt->pw->pw_domain)) != 0 ||
|
|
||||||
(r = sshbuf_put_string(msg, sig, slen)) != 0 ||
|
(r = sshbuf_put_string(msg, sig, slen)) != 0 ||
|
||||||
(r = sshbuf_put_string(msg, buffer_ptr(&b), buffer_len(&b))) != 0 ||
|
(r = sshbuf_put_string(msg, buffer_ptr(&b), buffer_len(&b))) != 0 ||
|
||||||
(r = ssh_request_reply(auth_sock, msg, msg)) != 0 ||
|
(r = ssh_request_reply(auth_sock, msg, msg)) != 0 ||
|
||||||
|
|
|
@ -3,7 +3,6 @@ Import-Module $PSScriptRoot\build.psm1 -Force -DisableNameChecking
|
||||||
$repoRoot = Get-RepositoryRoot
|
$repoRoot = Get-RepositoryRoot
|
||||||
$script:logFile = join-path $repoRoot.FullName "appveyor.log"
|
$script:logFile = join-path $repoRoot.FullName "appveyor.log"
|
||||||
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
|
$script:messageFile = join-path $repoRoot.FullName "BuildMessage.log"
|
||||||
$testfailed = $false
|
|
||||||
|
|
||||||
<#
|
<#
|
||||||
Called by Write-BuildMsg to write to the build log, if it exists.
|
Called by Write-BuildMsg to write to the build log, if it exists.
|
||||||
|
@ -234,13 +233,20 @@ function Download-PSCoreMSI
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
This function installs the tools required by our tests
|
This function installs the tools required by our tests
|
||||||
1) Pester for running the tests
|
1) Pester for running the tests
|
||||||
2) sysinternals required by the tests on windows.
|
2) sysinternals required by the tests on windows.
|
||||||
#>
|
#>
|
||||||
function Install-TestDependencies
|
function Install-TestDependencies
|
||||||
{
|
{
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param ()
|
param ()
|
||||||
|
|
||||||
|
# Install chocolatey
|
||||||
|
if(-not (Get-Command "choco" -ErrorAction SilentlyContinue))
|
||||||
|
{
|
||||||
|
Write-Log -Message "Chocolatey not present. Installing chocolatey."
|
||||||
|
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:logFile
|
||||||
|
}
|
||||||
|
|
||||||
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
|
$isModuleAvailable = Get-Module 'Pester' -ListAvailable
|
||||||
if (-not ($isModuleAvailable))
|
if (-not ($isModuleAvailable))
|
||||||
{
|
{
|
||||||
|
@ -360,18 +366,18 @@ function Build-Win32OpenSSHPackage
|
||||||
$folderName = $NativeHostArch
|
$folderName = $NativeHostArch
|
||||||
if($NativeHostArch -ieq 'x86')
|
if($NativeHostArch -ieq 'x86')
|
||||||
{
|
{
|
||||||
$folderName = "Win32"
|
$folderName = "Win32"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if($platform -ieq "AMD64")
|
if($platform -ieq "AMD64")
|
||||||
{
|
{
|
||||||
$folderName = "x64"
|
$folderName = "x64"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$folderName = "Win32"
|
$folderName = "Win32"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +436,7 @@ function Build-Win32OpenSSHPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
Add-Type -assemblyname System.IO.Compression.FileSystem
|
Add-Type -assemblyname System.IO.Compression.FileSystem
|
||||||
[System.IO.Compression.ZipFile]::CreateFromDirectory($OpenSSHDir, $package)
|
[System.IO.Compression.ZipFile]::CreateFromDirectory($OpenSSHDir, $package)
|
||||||
}
|
}
|
||||||
|
|
||||||
<#
|
<#
|
||||||
|
@ -494,43 +500,15 @@ function Deploy-OpenSSHTests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
|
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
|
||||||
|
#copy all pester tests
|
||||||
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
|
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "regress\pesterTests"
|
||||||
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1 -Force -ErrorAction Stop
|
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Include *.ps1,*.psm1, sshd_config -Force -ErrorAction Stop
|
||||||
|
#copy all unit tests.
|
||||||
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
|
$sourceDir = Join-Path $repositoryRoot.FullName -ChildPath "bin\$folderName\$RealConfiguration"
|
||||||
Copy-Item -Path "$sourceDir\*" -Destination $OpenSSHTestDir -Exclude ssh-agent.exe, sshd.exe -Force -ErrorAction Stop
|
Copy-Item -Path "$sourceDir\unittest-*" -Destination $OpenSSHTestDir -Force -ErrorAction Stop
|
||||||
|
#restart the service to use the test copy of sshd_config
|
||||||
|
Restart-Service sshd
|
||||||
$sshdConfigFile = "$OpenSSHTestDir\sshd_config"
|
|
||||||
if (-not (Test-Path -Path $sshdConfigFile -PathType Leaf))
|
|
||||||
{
|
|
||||||
Write-BuildMessage "Installation dependencies: $OpenSSHTestDir\sshd_config is missing in the folder" -Category Error
|
|
||||||
throw "$OpenSSHTestDir\sshd_config is missing in the folder"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($env:DebugMode)
|
|
||||||
{
|
|
||||||
$strToReplace = "#LogLevel INFO"
|
|
||||||
(Get-Content $sshdConfigFile).Replace($strToReplace,"LogLevel Debug3") | Set-Content $sshdConfigFile
|
|
||||||
}
|
|
||||||
if(-not ($env:psPath))
|
|
||||||
{
|
|
||||||
$psCorePath = GetLocalPSCorePath
|
|
||||||
Set-BuildVariable -Name psPath -Value $psCorePath
|
|
||||||
}
|
|
||||||
|
|
||||||
$strToReplace = "Subsystem sftp sftp-server.exe"
|
|
||||||
if($env:psPath)
|
|
||||||
{
|
|
||||||
$strNewsubSystem = @"
|
|
||||||
Subsystem sftp sftp-server.exe
|
|
||||||
Subsystem powershell $env:psPath
|
|
||||||
"@
|
|
||||||
}
|
|
||||||
|
|
||||||
(Get-Content $sshdConfigFile).Replace($strToReplace, $strNewsubSystem) | Set-Content $sshdConfigFile
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -152,17 +152,6 @@ function Start-SSHBootstrap
|
||||||
{
|
{
|
||||||
Write-BuildMsg -AsInfo -Message "Chocolatey not present. Installing chocolatey." -Silent:$silent
|
Write-BuildMsg -AsInfo -Message "Chocolatey not present. Installing chocolatey." -Silent:$silent
|
||||||
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:BuildLogFile
|
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) 2>&1 >> $script:BuildLogFile
|
||||||
|
|
||||||
if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower())))
|
|
||||||
{
|
|
||||||
Write-BuildMsg -AsVerbose -Message "Adding $chocolateyPath to Path environment variable" -Silent:$silent
|
|
||||||
$newMachineEnvironmentPath += ";$chocolateyPath"
|
|
||||||
$env:Path += ";$chocolateyPath"
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write-BuildMsg -AsVerbose -Message "$chocolateyPath already present in Path environment variable" -Silent:$silent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add git\cmd to the path
|
# Add git\cmd to the path
|
||||||
|
@ -231,7 +220,7 @@ function Start-SSHBootstrap
|
||||||
|
|
||||||
# Install Windows 8.1 SDK
|
# Install Windows 8.1 SDK
|
||||||
$packageName = "windows-sdk-8.1"
|
$packageName = "windows-sdk-8.1"
|
||||||
$sdkPath = "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\register_app.vbs"
|
$sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
|
||||||
|
|
||||||
if (-not (Test-Path -Path $sdkPath))
|
if (-not (Test-Path -Path $sdkPath))
|
||||||
{
|
{
|
||||||
|
@ -264,7 +253,7 @@ function Start-SSHBootstrap
|
||||||
Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" -Silent:$silent
|
Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" -Silent:$silent
|
||||||
if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false)
|
if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false)
|
||||||
{
|
{
|
||||||
Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at" + $script:vcPath
|
Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at$script:vcPath, which means some required develop kits are missing on the machine."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,7 @@
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\ssh-pubkey\ssh-pubkeydefs.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\ssh-pubkey\ssh-pubkeydefs.h" />
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agent-request.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agent-request.h" />
|
||||||
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agent.h" />
|
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agent.h" />
|
||||||
|
<ClInclude Include="$(OpenSSH-Src-Path)groupaccess.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\auth.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\auth.c" />
|
||||||
|
@ -212,8 +213,9 @@
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agentconfig.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\agentconfig.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\connection.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\connection.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\keyagent-request.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\ssh-agent\keyagent-request.c" />
|
||||||
<ClCompile Include="..\..\..\auth-options.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)auth-options.c" />
|
||||||
<ClCompile Include="..\..\..\auth2-pubkey.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)auth2-pubkey.c" />
|
||||||
|
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="version.rc" />
|
<ResourceCompile Include="version.rc" />
|
||||||
|
|
|
@ -248,6 +248,7 @@
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)sshlogin.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)sshpty.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)sshpty.c" />
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c" />
|
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c" />
|
||||||
|
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="version.rc" />
|
<ResourceCompile Include="version.rc" />
|
||||||
|
|
|
@ -150,6 +150,9 @@
|
||||||
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c">
|
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_sshd.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(OpenSSH-Src-Path)groupaccess.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="version.rc">
|
<ResourceCompile Include="version.rc">
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
struct passwd {
|
struct passwd {
|
||||||
char *pw_name; /* user's login name */
|
char *pw_name; /* user's login name */
|
||||||
char *pw_domain; /* user's domain name */
|
|
||||||
char *pw_passwd; /* password? */
|
char *pw_passwd; /* password? */
|
||||||
char *pw_gecos; /* ??? */
|
char *pw_gecos; /* ??? */
|
||||||
uid_t pw_uid; /* numerical user ID */
|
uid_t pw_uid; /* numerical user ID */
|
||||||
|
|
|
@ -90,31 +90,6 @@ innetgr(const char *netgroup, const char *host, const char *user, const char *do
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* groupaccess.c*/
|
|
||||||
int
|
|
||||||
ga_init(const char *user, gid_t base)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ga_match(char * const *groups, int n)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ga_match_pattern_list(const char *group_pattern)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ga_free(void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
chroot(const char *path)
|
chroot(const char *path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,13 +82,10 @@ reset_pw()
|
||||||
free(pw.pw_name);
|
free(pw.pw_name);
|
||||||
if (pw.pw_dir)
|
if (pw.pw_dir)
|
||||||
free(pw.pw_dir);
|
free(pw.pw_dir);
|
||||||
if (pw.pw_domain)
|
|
||||||
free(pw.pw_domain);
|
|
||||||
if (pw.pw_sid)
|
if (pw.pw_sid)
|
||||||
free(pw.pw_sid);
|
free(pw.pw_sid);
|
||||||
pw.pw_name = NULL;
|
pw.pw_name = NULL;
|
||||||
pw.pw_dir = NULL;
|
pw.pw_dir = NULL;
|
||||||
pw.pw_domain = NULL;
|
|
||||||
pw.pw_sid = NULL;
|
pw.pw_sid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,14 +94,14 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
|
||||||
{
|
{
|
||||||
struct passwd *ret = NULL;
|
struct passwd *ret = NULL;
|
||||||
wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
|
wchar_t *user_utf16 = NULL, *uname_utf16, *udom_utf16, *tmp;
|
||||||
char *uname_utf8 = NULL, *udom_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8 = NULL;
|
char *uname_utf8 = NULL, *uname_upn = NULL, *udom_utf8 = NULL, *pw_home_utf8 = NULL, *user_sid_utf8 = NULL;
|
||||||
LPBYTE user_info = NULL;
|
LPBYTE user_info = NULL;
|
||||||
LPWSTR user_sid_local = NULL;
|
LPWSTR user_sid_local = NULL;
|
||||||
wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
|
wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
|
||||||
HKEY reg_key = 0;
|
HKEY reg_key = 0;
|
||||||
int tmp_len = PATH_MAX;
|
int tmp_len = PATH_MAX;
|
||||||
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
||||||
DWORD dsStatus;
|
DWORD dsStatus, uname_upn_len = 0;;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
reset_pw();
|
reset_pw();
|
||||||
|
@ -169,10 +166,23 @@ get_passwd(const char *user_utf8, LPWSTR user_sid)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.pw_name = uname_utf8;
|
uname_upn_len = strlen(uname_utf8) + 1;
|
||||||
uname_utf8 = NULL;
|
if (udom_utf8)
|
||||||
pw.pw_domain = udom_utf8;
|
uname_upn_len += strlen(udom_utf8) + 1;
|
||||||
udom_utf8 = NULL;
|
|
||||||
|
if ((uname_upn = malloc(uname_upn_len)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(uname_upn, uname_utf8, strlen(uname_utf8) + 1);
|
||||||
|
if (udom_utf8) {
|
||||||
|
/* TODO - get domain FQDN */
|
||||||
|
uname_upn[strlen(uname_utf8)] = '@';
|
||||||
|
memcpy(uname_upn + strlen(uname_utf8) + 1, udom_utf8, strlen(udom_utf8) + 1);
|
||||||
|
}
|
||||||
|
pw.pw_name = uname_upn;
|
||||||
|
uname_upn = NULL;
|
||||||
pw.pw_dir = pw_home_utf8;
|
pw.pw_dir = pw_home_utf8;
|
||||||
pw_home_utf8 = NULL;
|
pw_home_utf8 = NULL;
|
||||||
pw.pw_sid = user_sid_utf8;
|
pw.pw_sid = user_sid_utf8;
|
||||||
|
@ -184,6 +194,8 @@ done:
|
||||||
free(user_utf16);
|
free(user_utf16);
|
||||||
if (uname_utf8)
|
if (uname_utf8)
|
||||||
free(uname_utf8);
|
free(uname_utf8);
|
||||||
|
if (uname_upn)
|
||||||
|
free(uname_upn);
|
||||||
if (udom_utf8)
|
if (udom_utf8)
|
||||||
free(udom_utf8);
|
free(udom_utf8);
|
||||||
if (pw_home_utf8)
|
if (pw_home_utf8)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "agent.h"
|
#include "agent.h"
|
||||||
#include "agent-request.h"
|
#include "agent-request.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "inc\utf.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
InitLsaString(LSA_STRING *lsa_string, const char *str)
|
InitLsaString(LSA_STRING *lsa_string, const char *str)
|
||||||
|
@ -105,7 +106,7 @@ LoadProfile(struct agent_connection* con, wchar_t* user, wchar_t* domain) {
|
||||||
#define MAX_PW_LEN 64
|
#define MAX_PW_LEN 64
|
||||||
|
|
||||||
static HANDLE
|
static HANDLE
|
||||||
generate_user_token(wchar_t* user, wchar_t* domain) {
|
generate_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;
|
||||||
|
@ -120,7 +121,7 @@ generate_user_token(wchar_t* user, wchar_t* domain) {
|
||||||
DWORD cbProfile;
|
DWORD cbProfile;
|
||||||
BOOL domain_user;
|
BOOL domain_user;
|
||||||
|
|
||||||
domain_user = (*domain != L'\0') ? TRUE : FALSE;
|
domain_user = wcschr(user_cpn, L'@')? TRUE : FALSE;
|
||||||
|
|
||||||
InitLsaString(&logon_process_name, "ssh-agent");
|
InitLsaString(&logon_process_name, "ssh-agent");
|
||||||
if (domain_user)
|
if (domain_user)
|
||||||
|
@ -137,10 +138,6 @@ generate_user_token(wchar_t* user, wchar_t* domain) {
|
||||||
|
|
||||||
if (domain_user) {
|
if (domain_user) {
|
||||||
KERB_S4U_LOGON *s4u_logon;
|
KERB_S4U_LOGON *s4u_logon;
|
||||||
wchar_t user_cpn[MAX_USER_LEN + 1 + MAX_FQDN_LEN + 1];
|
|
||||||
memcpy(user_cpn, user, wcslen(user) * 2);
|
|
||||||
user_cpn[wcslen(user)] = L'@';
|
|
||||||
memcpy(user_cpn + wcslen(user) + 1, domain, wcslen(domain) * 2 + 2);
|
|
||||||
logon_info_size = sizeof(KERB_S4U_LOGON);
|
logon_info_size = sizeof(KERB_S4U_LOGON);
|
||||||
logon_info_size += (wcslen(user_cpn) * 2 + 2);
|
logon_info_size += (wcslen(user_cpn) * 2 + 2);
|
||||||
logon_info = malloc(logon_info_size);
|
logon_info = malloc(logon_info_size);
|
||||||
|
@ -157,11 +154,11 @@ generate_user_token(wchar_t* user, wchar_t* domain) {
|
||||||
s4u_logon->ClientRealm.MaximumLength = 0;
|
s4u_logon->ClientRealm.MaximumLength = 0;
|
||||||
s4u_logon->ClientRealm.Buffer = 0;
|
s4u_logon->ClientRealm.Buffer = 0;
|
||||||
} else {
|
} else {
|
||||||
logon_info_size = (wcslen(user) + 1)*sizeof(wchar_t);
|
logon_info_size = (wcslen(user_cpn) + 1)*sizeof(wchar_t);
|
||||||
logon_info = malloc(logon_info_size);
|
logon_info = malloc(logon_info_size);
|
||||||
if (logon_info == NULL)
|
if (logon_info == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
memcpy(logon_info, user, logon_info_size);
|
memcpy(logon_info, user_cpn, logon_info_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName));
|
memcpy(sourceContext.SourceName,"sshagent", sizeof(sourceContext.SourceName));
|
||||||
|
@ -201,36 +198,35 @@ done:
|
||||||
/* TODO - SecureZeroMemory password */
|
/* TODO - SecureZeroMemory password */
|
||||||
int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
|
int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
|
||||||
char *user = NULL, *domain = NULL, *pwd = NULL;
|
char *user = NULL, *domain = NULL, *pwd = NULL;
|
||||||
wchar_t userW_buf[MAX_USER_LEN], domainW_buf[MAX_FQDN_LEN], pwdW_buf[MAX_PW_LEN];
|
size_t user_len, pwd_len;
|
||||||
wchar_t *userW = userW_buf, *domW = domainW_buf, *pwdW = pwdW_buf, *tmp;
|
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *pwd_utf16 = NULL, *tmp;
|
||||||
size_t user_len = 0, domain_len = 0, pwd_len = 0, dom_len = 0;
|
|
||||||
int r = -1;
|
int r = -1;
|
||||||
HANDLE token = 0, dup_token, client_proc = 0;
|
HANDLE token = 0, dup_token, client_proc = 0;
|
||||||
ULONG client_pid;
|
ULONG client_pid;
|
||||||
|
|
||||||
if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
|
if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
|
||||||
sshbuf_get_cstring(request, &domain, &domain_len) != 0 ||
|
|
||||||
sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
|
sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
|
||||||
user_len == 0 ||
|
user_len == 0 ||
|
||||||
pwd_len == 0 ||
|
pwd_len == 0 ||
|
||||||
user_len > MAX_USER_LEN ||
|
user_len > MAX_USER_LEN + MAX_FQDN_LEN ||
|
||||||
domain_len > MAX_FQDN_LEN ||
|
|
||||||
pwd_len > MAX_PW_LEN) {
|
pwd_len > MAX_PW_LEN) {
|
||||||
debug("bad password auth request");
|
debug("bad password auth request");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
userW[0] = L'\0';
|
if ((user_utf16 = utf8_to_utf16(user)) == NULL ||
|
||||||
domW[0] = L'\0';
|
(pwd_utf16 = utf8_to_utf16(pwd)) == NULL) {
|
||||||
if ((MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, userW, MAX_USER_LEN) == 0) ||
|
debug("out of memory");
|
||||||
(domain_len != 0 && MultiByteToWideChar(CP_UTF8, 0, domain, domain_len + 1, domW, MAX_FQDN_LEN) == 0) ||
|
|
||||||
(MultiByteToWideChar(CP_UTF8, 0, pwd, pwd_len + 1, pwdW, MAX_PW_LEN) == 0)) {
|
|
||||||
debug("unable to convert user (%s) or password to UTF-16", user);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogonUserW(userW, domW, pwdW, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token) == FALSE) {
|
if ((tmp = wcschr(user_utf16, L'@') ) != NULL ) {
|
||||||
debug("failed to logon user");
|
udom_utf16 = tmp + 1;
|
||||||
|
*tmp = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LogonUserW(user_utf16, udom_utf16, pwd_utf16, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token) == FALSE) {
|
||||||
|
debug("failed to logon user: %ls domain: %ls", user_utf16, udom_utf16);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +239,7 @@ int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response
|
||||||
}
|
}
|
||||||
|
|
||||||
con->auth_token = token;
|
con->auth_token = token;
|
||||||
LoadProfile(con, userW, domW);
|
LoadProfile(con, user_utf16, udom_utf16);
|
||||||
r = 0;
|
r = 0;
|
||||||
done:
|
done:
|
||||||
/* TODO Fix this hacky protocol*/
|
/* TODO Fix this hacky protocol*/
|
||||||
|
@ -254,6 +250,10 @@ done:
|
||||||
free(user);
|
free(user);
|
||||||
if (pwd)
|
if (pwd)
|
||||||
free(pwd);
|
free(pwd);
|
||||||
|
if (user_utf16)
|
||||||
|
free(user_utf16);
|
||||||
|
if (pwd_utf16)
|
||||||
|
free(pwd_utf16);
|
||||||
if (client_proc)
|
if (client_proc)
|
||||||
CloseHandle(client_proc);
|
CloseHandle(client_proc);
|
||||||
|
|
||||||
|
@ -262,22 +262,19 @@ done:
|
||||||
|
|
||||||
int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
|
int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
|
||||||
int r = -1;
|
int r = -1;
|
||||||
char *key_blob, *user, *domain, *usernameWithDomain, *sig, *blob;
|
char *key_blob, *user, *sig, *blob;
|
||||||
size_t key_blob_len, user_len, domain_len, sig_len, blob_len;
|
size_t key_blob_len, user_len, sig_len, blob_len;
|
||||||
struct sshkey *key = NULL;
|
struct sshkey *key = NULL;
|
||||||
HANDLE token = NULL, restricted_token = NULL, dup_token = NULL, client_proc = NULL;
|
HANDLE token = NULL, restricted_token = NULL, dup_token = NULL, client_proc = NULL;
|
||||||
wchar_t wuser[MAX_USER_LEN], wdomain[MAX_FQDN_LEN];
|
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *tmp;
|
||||||
PWSTR wuser_home = NULL;
|
PWSTR wuser_home = NULL;
|
||||||
ULONG client_pid;
|
ULONG client_pid;
|
||||||
LUID_AND_ATTRIBUTES priv_to_delete[1];
|
LUID_AND_ATTRIBUTES priv_to_delete[1];
|
||||||
|
|
||||||
user = NULL;
|
user = NULL;
|
||||||
domain = NULL;
|
|
||||||
if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
|
if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
|
||||||
sshbuf_get_cstring(request, &user, &user_len) != 0 ||
|
sshbuf_get_cstring(request, &user, &user_len) != 0 ||
|
||||||
sshbuf_get_cstring(request, &domain, &domain_len) != 0 ||
|
|
||||||
user_len > MAX_USER_LEN ||
|
user_len > MAX_USER_LEN ||
|
||||||
domain_len > MAX_FQDN_LEN ||
|
|
||||||
sshbuf_get_string_direct(request, &sig, &sig_len) != 0 ||
|
sshbuf_get_string_direct(request, &sig, &sig_len) != 0 ||
|
||||||
sshbuf_get_string_direct(request, &blob, &blob_len) != 0 ||
|
sshbuf_get_string_direct(request, &blob, &blob_len) != 0 ||
|
||||||
sshkey_from_blob(key_blob, key_blob_len, &key) != 0) {
|
sshkey_from_blob(key_blob, key_blob_len, &key) != 0) {
|
||||||
|
@ -285,12 +282,13 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
wuser[0] = L'\0';
|
if ((user_utf16 = utf8_to_utf16(user)) == NULL) {
|
||||||
wdomain[0] = L'\0';
|
debug("out of memory");
|
||||||
if (MultiByteToWideChar(CP_UTF8, 0, user, user_len + 1, wuser, MAX_USER_LEN) == 0 ||
|
goto done;
|
||||||
(domain_len != 0 && MultiByteToWideChar(CP_UTF8, 0, domain, domain_len + 1, wdomain, MAX_FQDN_LEN) == 0) ||
|
}
|
||||||
(token = generate_user_token(wuser, wdomain)) == 0) {
|
|
||||||
debug("unable to generate token for user %ls", wuser);
|
if ((token = generate_user_token(user_utf16)) == 0) {
|
||||||
|
debug("unable to generate token for user %ls", user_utf16);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +300,8 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, restricted_token, &wuser_home) != S_OK ||
|
if (SHGetKnownFolderPath(&FOLDERID_Profile, 0, restricted_token, &wuser_home) != S_OK ||
|
||||||
pubkey_allowed(key, wuser, wuser_home) != 1) {
|
pubkey_allowed(key, user_utf16, wuser_home) != 1) {
|
||||||
debug("unable to verify public key for user %ls (profile:%ls)", wuser, wuser_home);
|
debug("unable to verify public key for user %ls (profile:%ls)", user_utf16, wuser_home);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +320,11 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
||||||
|
|
||||||
con->auth_token = restricted_token;
|
con->auth_token = restricted_token;
|
||||||
restricted_token = NULL;
|
restricted_token = NULL;
|
||||||
LoadProfile(con, wuser, wdomain);
|
if ((tmp = wcschr(user_utf16, L'@')) != NULL) {
|
||||||
|
udom_utf16 = tmp + 1;
|
||||||
|
*tmp = L'\0';
|
||||||
|
}
|
||||||
|
LoadProfile(con, user_utf16, udom_utf16);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
done:
|
done:
|
||||||
|
@ -332,6 +334,8 @@ done:
|
||||||
|
|
||||||
if (user)
|
if (user)
|
||||||
free(user);
|
free(user);
|
||||||
|
if (user_utf16)
|
||||||
|
free(user_utf16);
|
||||||
if (key)
|
if (key)
|
||||||
sshkey_free(key);
|
sshkey_free(key);
|
||||||
if (wuser_home)
|
if (wuser_home)
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#ifdef WINDOWS
|
||||||
|
#include <lm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "groupaccess.h"
|
#include "groupaccess.h"
|
||||||
|
@ -49,6 +52,82 @@ static char **groups_byname;
|
||||||
int
|
int
|
||||||
ga_init(const char *user, gid_t base)
|
ga_init(const char *user, gid_t base)
|
||||||
{
|
{
|
||||||
|
#ifdef WINDOWS
|
||||||
|
DWORD i = 0, j = 0;
|
||||||
|
LPLOCALGROUP_USERS_INFO_0 local_groups_info = NULL, tmp_groups_info;
|
||||||
|
wchar_t *user_utf16 = NULL, *full_name_utf16 = NULL, *udom_utf16 = NULL, *tmp;
|
||||||
|
char *group_utf8 = NULL;
|
||||||
|
DWORD entries_read = 0, total_entries = 0, full_name_len = 0, index = 0;
|
||||||
|
NET_API_STATUS nStatus;
|
||||||
|
|
||||||
|
if (ngroups > 0)
|
||||||
|
ga_free();
|
||||||
|
|
||||||
|
user_utf16 = utf8_to_utf16(user);
|
||||||
|
if ((user_utf16 = utf8_to_utf16(user)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
full_name_len = wcslen(user_utf16) + 1;
|
||||||
|
if ((full_name_utf16 = malloc(full_name_len * sizeof(wchar_t))) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tmp = wcschr(user_utf16, L'@')) != NULL) {
|
||||||
|
udom_utf16 = tmp + 1;
|
||||||
|
*tmp = L'\0';
|
||||||
|
index = wcslen(udom_utf16) + 1;
|
||||||
|
wmemcpy(full_name_utf16, udom_utf16, index);
|
||||||
|
full_name_utf16[wcslen(udom_utf16)] = L'\\';
|
||||||
|
}
|
||||||
|
wmemcpy(full_name_utf16 + index, user_utf16, wcslen(user_utf16) + 1);
|
||||||
|
|
||||||
|
nStatus = NetUserGetLocalGroups(NULL,
|
||||||
|
full_name_utf16,
|
||||||
|
0,
|
||||||
|
LG_INCLUDE_INDIRECT,
|
||||||
|
(LPBYTE *)&local_groups_info,
|
||||||
|
MAX_PREFERRED_LENGTH,
|
||||||
|
&entries_read,
|
||||||
|
&total_entries);
|
||||||
|
|
||||||
|
if (NERR_Success != nStatus) {
|
||||||
|
error("NetUserGetLocalGroups() failed with error: %u",
|
||||||
|
nStatus);
|
||||||
|
errno = ENOENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries_read != total_entries) {
|
||||||
|
error("NetUserGetLocalGroups(): entries_read (%u) is not equal to "
|
||||||
|
"total_entries (%u) for user %.100s", entries_read, total_entries, user);
|
||||||
|
errno = ENOENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tmp_groups_info = local_groups_info) != NULL) {
|
||||||
|
groups_byname = xcalloc(entries_read, sizeof(*groups_byname));
|
||||||
|
for (i = 0, j = 0; i < total_entries; i++)
|
||||||
|
{
|
||||||
|
if ((group_utf8 = utf16_to_utf8(tmp_groups_info->lgrui0_name)) == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
groups_byname[j++] = group_utf8;
|
||||||
|
tmp_groups_info++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if(user_utf16 != NULL)
|
||||||
|
free(user_utf16);
|
||||||
|
if(full_name_utf16 != NULL)
|
||||||
|
free(full_name_utf16);
|
||||||
|
if (local_groups_info != NULL)
|
||||||
|
NetApiBufferFree(local_groups_info);
|
||||||
|
|
||||||
|
#else /* !WINDOWS */
|
||||||
gid_t *groups_bygid;
|
gid_t *groups_bygid;
|
||||||
int i, j;
|
int i, j;
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
|
@ -70,7 +149,9 @@ ga_init(const char *user, gid_t base)
|
||||||
if ((gr = getgrgid(groups_bygid[i])) != NULL)
|
if ((gr = getgrgid(groups_bygid[i])) != NULL)
|
||||||
groups_byname[j++] = xstrdup(gr->gr_name);
|
groups_byname[j++] = xstrdup(gr->gr_name);
|
||||||
free(groups_bygid);
|
free(groups_bygid);
|
||||||
|
#endif /* !WINDOWS */
|
||||||
return (ngroups = j);
|
return (ngroups = j);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
5
misc.c
5
misc.c
|
@ -226,11 +226,6 @@ pwcopy(struct passwd *pw)
|
||||||
copy->pw_dir = xstrdup(pw->pw_dir);
|
copy->pw_dir = xstrdup(pw->pw_dir);
|
||||||
copy->pw_shell = xstrdup(pw->pw_shell);
|
copy->pw_shell = xstrdup(pw->pw_shell);
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* copy additionaly pw entries for Windows */
|
|
||||||
if (pw->pw_domain != NULL)
|
|
||||||
copy->pw_domain = xstrdup(pw->pw_domain);
|
|
||||||
else
|
|
||||||
copy->pw_domain = NULL;
|
|
||||||
copy->pw_sid = xstrdup(pw->pw_sid);
|
copy->pw_sid = xstrdup(pw->pw_sid);
|
||||||
#endif /* WINDOWS */
|
#endif /* WINDOWS */
|
||||||
|
|
||||||
|
|
|
@ -75,9 +75,11 @@ Class Machine
|
||||||
[string] $localAdminUserName = "localadmin"
|
[string] $localAdminUserName = "localadmin"
|
||||||
[string] $localAdminPassword = "Bull_dog1"
|
[string] $localAdminPassword = "Bull_dog1"
|
||||||
[string] $localAdminAuthorizedKeyPath
|
[string] $localAdminAuthorizedKeyPath
|
||||||
|
[string] $sshdConfigFile = (join-path $PSScriptRoot "sshd_config")
|
||||||
|
[string] $backupFileName = (join-path $PSScriptRoot "sshd_backup")
|
||||||
[System.Security.SecureString] $password
|
[System.Security.SecureString] $password
|
||||||
$preLatfpSetting
|
$preLatfpSetting
|
||||||
$localUserprofilePath
|
[string] $localUserprofilePath
|
||||||
|
|
||||||
#Members on client role
|
#Members on client role
|
||||||
[string []] $clientPrivateKeyPaths
|
[string []] $clientPrivateKeyPaths
|
||||||
|
@ -177,6 +179,47 @@ Class Machine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[void] SetupSingleSignon([string] $identifyFile) {
|
||||||
|
.\ssh-add.exe $identifyFile
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] CleanupSingleSignon([string] $identifyFile) {
|
||||||
|
.\ssh-add.exe -d $identifyFile
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] AddItemInSSHDConfig([string] $key, [string] $value) {
|
||||||
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
|
Get-Content $this.sshdConfigFile | % {
|
||||||
|
if($_.StartsWith($key)) {
|
||||||
|
"#$_"
|
||||||
|
}
|
||||||
|
else {$_}
|
||||||
|
} | Set-Content $this.sshdConfigFile
|
||||||
|
Add-Content -Path $this.sshdConfigFile -Value "`r`n$key $value"
|
||||||
|
|
||||||
|
Restart-Service sshd
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] BackupSSHDConfig() {
|
||||||
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
|
if(Test-path $this.backupFileName) {
|
||||||
|
Remove-Item -Path $this.backupFileName -Force
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item $this.sshdConfigFile $this.backupFileName -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RestoreSSHDConfig() {
|
||||||
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
|
Copy-Item $this.backupFileName $this.sshdConfigFile -Force
|
||||||
|
Remove-Item -Path $this.backupFileName -Force
|
||||||
|
Restart-Service sshd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[void] SetupServerRemoting([Protocol] $protocol) {
|
[void] SetupServerRemoting([Protocol] $protocol) {
|
||||||
if ($this.Platform -eq [PlatformType]::Windows)
|
if ($this.Platform -eq [PlatformType]::Windows)
|
||||||
{
|
{
|
||||||
|
@ -240,6 +283,56 @@ Class Machine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[void] AddLocalUser($UserName, $password) {
|
||||||
|
$a = Get-LocalUser -Name $UserName -ErrorAction Ignore
|
||||||
|
if ($a -eq $null)
|
||||||
|
{
|
||||||
|
$pass = ConvertTo-SecureString -String $this.localAdminPassword -AsPlainText -Force
|
||||||
|
$a = New-LocalUser -Name $UserName -Password $pass -AccountNeverExpires -PasswordNeverExpires -UserMayNotChangePassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] AddLocalGroup($groupName) {
|
||||||
|
$g = Get-LocalGroup -Name $groupName -ErrorAction Ignore
|
||||||
|
if ($g -eq $null)
|
||||||
|
{
|
||||||
|
$g = New-LocalGroup -Name $groupName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] AddUserToLocalGroup($UserName, $password, $groupName) {
|
||||||
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
|
$this.AddLocalUser($UserName, $password)
|
||||||
|
$this.AddLocalGroup($groupName)
|
||||||
|
|
||||||
|
if((Get-LocalGroupMember -Name $groupName -Member $UserName -ErrorAction Ignore ) -eq $null)
|
||||||
|
{
|
||||||
|
Add-LocalGroupMember -Name $groupName -Member $UserName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#Todo add local user and add it to a user group on linux
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] RemoveUserFromLocalGroup($UserName, $groupName) {
|
||||||
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
|
if((Get-LocalGroupMember -Name $groupName -Member $UserName -ErrorAction Ignore ) -eq $null)
|
||||||
|
{
|
||||||
|
Remove-LocalGroupMember -Name $groupName -Member $UserName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#Todo add local user and add it to a user group on linux
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void] ClenaupLocalGroup($groupName) {
|
||||||
|
$g = Get-LocalGroup -Name $groupName -ErrorAction Ignore
|
||||||
|
if ($g -eq $null)
|
||||||
|
{
|
||||||
|
$g | Remove-LocalGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[void] AddAdminUser($UserName, $password) {
|
[void] AddAdminUser($UserName, $password) {
|
||||||
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
if ( $this.Platform -eq [PlatformType]::Windows ) {
|
||||||
$a = Get-LocalUser -Name $UserName -ErrorAction Ignore
|
$a = Get-LocalUser -Name $UserName -ErrorAction Ignore
|
||||||
|
@ -253,8 +346,7 @@ Class Machine
|
||||||
Add-LocalGroupMember -SID s-1-5-32-544 -Member $a
|
Add-LocalGroupMember -SID s-1-5-32-544 -Member $a
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#Todo add local user and add it to administrators group on linux
|
#Todo add local user and add it to a administrators on linux
|
||||||
#Todo: get $localUserprofilePath
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
using module .\PlatformAbstractLayer.psm1
|
||||||
|
|
||||||
|
Describe "Tests of sshd_config" -Tags "CI" {
|
||||||
|
BeforeAll {
|
||||||
|
$fileName = "test.txt"
|
||||||
|
$filePath = Join-Path ${TestDrive} $fileName
|
||||||
|
|
||||||
|
[Machine] $client = [Machine]::new([MachineRole]::Client)
|
||||||
|
[Machine] $server = [Machine]::new([MachineRole]::Server)
|
||||||
|
$client.SetupClient($server)
|
||||||
|
$server.SetupServer($client)
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterAll {
|
||||||
|
$client.CleanupClient()
|
||||||
|
$server.CleanupServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
<#
|
||||||
|
Settings in the sshd_config:
|
||||||
|
|
||||||
|
DenyUsers denyuser1 denyu*2 denyuse?3,
|
||||||
|
AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin
|
||||||
|
DenyGroups denygroup1 denygr*p2 deny?rou?3
|
||||||
|
AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm*
|
||||||
|
#>
|
||||||
|
Context "Tests of AllowGroups, AllowUsers, DenyUsers, DenyGroups" {
|
||||||
|
BeforeAll {
|
||||||
|
Remove-Item -Path $filePath -Force -ea silentlycontinue
|
||||||
|
$password = "Bull_dog1"
|
||||||
|
|
||||||
|
$allowUser1 = "allowuser1"
|
||||||
|
$allowUser2 = "allowuser2"
|
||||||
|
$allowUser3 = "allowuser3"
|
||||||
|
$allowUser4 = "allowuser4"
|
||||||
|
|
||||||
|
$denyUser1 = "denyuser1"
|
||||||
|
$denyUser2 = "denyuser2"
|
||||||
|
$denyUser3 = "denyuser3"
|
||||||
|
|
||||||
|
$localuser1 = "localuser1"
|
||||||
|
$localuser2 = "localuser2"
|
||||||
|
$localuser3 = "localuser3"
|
||||||
|
|
||||||
|
$allowGroup1 = "allowgroup1"
|
||||||
|
$allowGroup2 = "allowgroup2"
|
||||||
|
$allowGroup3 = "allowgroup3"
|
||||||
|
|
||||||
|
$denyGroup1 = "denygroup1"
|
||||||
|
$denyGroup2 = "denygroup2"
|
||||||
|
$denyGroup3 = "denygroup3"
|
||||||
|
$client.AddPasswordSetting($password)
|
||||||
|
}
|
||||||
|
AfterEach {
|
||||||
|
Remove-Item -Path $filePath -Force -ea ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterAll {
|
||||||
|
$client.CleanupPasswordSetting()
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with full name in the list of AllowUsers' {
|
||||||
|
$server.AddUserToLocalGroup($allowUser1, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($allowUser1)@$($server.MachineName) hostname > $filePath")
|
||||||
|
Get-Content $filePath | Should be $server.MachineName
|
||||||
|
$server.RemoveUserFromLocalGroup($allowUser1, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with * wildcard' {
|
||||||
|
$server.AddUserToLocalGroup($allowUser2, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($allowUser2)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Be 0
|
||||||
|
Get-Content $filePath | Should be $server.MachineName
|
||||||
|
$server.RemoveUserFromLocalGroup($allowUser2, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with ? wildcard' {
|
||||||
|
$server.AddUserToLocalGroup($allowUser3, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($allowUser3)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Be 0
|
||||||
|
Get-Content $filePath | Should be $server.MachineName
|
||||||
|
$server.RemoveUserFromLocalGroup($allowUser3, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with full name in the list of AllowUsers but not in any AllowGroups' {
|
||||||
|
$server.AddLocalUser($allowUser4, $password)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($allowUser4)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with full name in the list of DenyUsers' {
|
||||||
|
$server.AddUserToLocalGroup($denyUser1, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($denyUser1)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($denyUser1, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with * wildcard in the list of DenyUsers' {
|
||||||
|
$server.AddUserToLocalGroup($denyUser2, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$str = ".\ssh $($denyUser2)@$($server.MachineName) hostname > $filePath"
|
||||||
|
$client.RunCmd(".\ssh $($denyUser2)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($denyUser2, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User with ? wildcard in the list of DenyUsers' {
|
||||||
|
$server.AddUserToLocalGroup($denyUser3, $password, $allowGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($denyUser3)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($denyUser3, $allowGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User is listed in the list of AllowUsers but also in a full name DenyGroups and AllowGroups' {
|
||||||
|
$server.AddUserToLocalGroup($localuser1, $password, $allowGroup1)
|
||||||
|
$server.AddUserToLocalGroup($localuser1, $password, $denyGroup1)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($localuser1)@$($server.MachineName) hostname > $filePath")
|
||||||
|
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($localuser1, $allowGroup1)
|
||||||
|
$server.RemoveUserFromLocalGroup($localuser1, $denyGroup1)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User is listed in the list of AllowUsers but also in a wildcard * DenyGroups' {
|
||||||
|
$server.AddUserToLocalGroup($localuser2, $password, $denyGroup2)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($localuser2)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($localuser2, $denyGroup2)
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'User is listed in the list of AllowUsers but also in a wildcard ? DenyGroups' {
|
||||||
|
$server.AddUserToLocalGroup($localuser3, $password, $denyGroup3)
|
||||||
|
|
||||||
|
$client.RunCmd(".\ssh $($localuser3)@$($server.MachineName) hostname > $filePath")
|
||||||
|
$LASTEXITCODE | Should Not Be 0
|
||||||
|
Get-Content $filePath | Should BeNullOrEmpty
|
||||||
|
|
||||||
|
$server.RemoveUserFromLocalGroup($localuser3, $denyGroup3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
# $OpenBSD: sshd_config,v 1.84 2011/05/23 03:30:07 djm Exp $
|
||||||
|
|
||||||
|
# This is the sshd server system-wide configuration file. See
|
||||||
|
# sshd_config(5) for more information.
|
||||||
|
|
||||||
|
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
# The strategy used for options in the default sshd_config shipped with
|
||||||
|
# OpenSSH is to specify options with their default value where
|
||||||
|
# possible, but leave them commented. Uncommented options override the
|
||||||
|
# default value.
|
||||||
|
|
||||||
|
#Port 22
|
||||||
|
#AddressFamily any
|
||||||
|
#ListenAddress 0.0.0.0
|
||||||
|
#ListenAddress ::
|
||||||
|
|
||||||
|
# The default requires explicit activation of protocol 1
|
||||||
|
#Protocol 2
|
||||||
|
|
||||||
|
# HostKey for protocol version 1
|
||||||
|
#HostKey /etc/ssh/ssh_host_key
|
||||||
|
# HostKeys for protocol version 2
|
||||||
|
#HostKey /etc/ssh/ssh_host_rsa_key
|
||||||
|
#HostKey /etc/ssh/ssh_host_dsa_key
|
||||||
|
#HostKey /etc/ssh/ssh_host_ecdsa_key
|
||||||
|
|
||||||
|
# Lifetime and size of ephemeral version 1 server key
|
||||||
|
#KeyRegenerationInterval 1h
|
||||||
|
#ServerKeyBits 1024
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
# obsoletes QuietMode and FascistLogging
|
||||||
|
#SyslogFacility AUTH
|
||||||
|
LogLevel DEBUG3
|
||||||
|
|
||||||
|
# Authentication:
|
||||||
|
|
||||||
|
#LoginGraceTime 2m
|
||||||
|
#PermitRootLogin yes
|
||||||
|
#StrictModes yes
|
||||||
|
#MaxAuthTries 6
|
||||||
|
#MaxSessions 10
|
||||||
|
|
||||||
|
#RSAAuthentication yes
|
||||||
|
#PubkeyAuthentication yes
|
||||||
|
|
||||||
|
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
|
||||||
|
# but this is overridden so installations will only check .ssh/authorized_keys
|
||||||
|
AuthorizedKeysFile .ssh/authorized_keys
|
||||||
|
|
||||||
|
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
||||||
|
#RhostsRSAAuthentication no
|
||||||
|
# similar for protocol version 2
|
||||||
|
#HostbasedAuthentication no
|
||||||
|
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
||||||
|
# RhostsRSAAuthentication and HostbasedAuthentication
|
||||||
|
#IgnoreUserKnownHosts no
|
||||||
|
# Don't read the user's ~/.rhosts and ~/.shosts files
|
||||||
|
#IgnoreRhosts yes
|
||||||
|
|
||||||
|
# To disable tunneled clear text passwords, change to no here!
|
||||||
|
#PasswordAuthentication yes
|
||||||
|
#PermitEmptyPasswords no
|
||||||
|
|
||||||
|
# Change to no to disable s/key passwords
|
||||||
|
#ChallengeResponseAuthentication yes
|
||||||
|
|
||||||
|
# Kerberos options
|
||||||
|
#KerberosAuthentication no
|
||||||
|
#KerberosOrLocalPasswd yes
|
||||||
|
#KerberosTicketCleanup yes
|
||||||
|
#KerberosGetAFSToken no
|
||||||
|
|
||||||
|
# GSSAPI options
|
||||||
|
#GSSAPIAuthentication no
|
||||||
|
#GSSAPICleanupCredentials yes
|
||||||
|
|
||||||
|
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||||
|
# and session processing. If this is enabled, PAM authentication will
|
||||||
|
# be allowed through the ChallengeResponseAuthentication and
|
||||||
|
# PasswordAuthentication. Depending on your PAM configuration,
|
||||||
|
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||||
|
# the setting of "PermitRootLogin without-password".
|
||||||
|
# If you just want the PAM account and session checks to run without
|
||||||
|
# PAM authentication, then enable this but set PasswordAuthentication
|
||||||
|
# and ChallengeResponseAuthentication to 'no'.
|
||||||
|
#UsePAM no
|
||||||
|
|
||||||
|
#AllowAgentForwarding yes
|
||||||
|
#AllowTcpForwarding yes
|
||||||
|
#GatewayPorts no
|
||||||
|
#X11Forwarding no
|
||||||
|
#X11DisplayOffset 10
|
||||||
|
#X11UseLocalhost yes
|
||||||
|
#PrintMotd yes
|
||||||
|
#PrintLastLog yes
|
||||||
|
#TCPKeepAlive yes
|
||||||
|
#UseLogin no
|
||||||
|
#UsePrivilegeSeparation yes
|
||||||
|
#PermitUserEnvironment no
|
||||||
|
#Compression delayed
|
||||||
|
#ClientAliveInterval 0
|
||||||
|
#ClientAliveCountMax 3
|
||||||
|
#UseDNS yes
|
||||||
|
#PidFile /var/run/sshd.pid
|
||||||
|
#MaxStartups 10
|
||||||
|
#PermitTunnel no
|
||||||
|
#ChrootDirectory none
|
||||||
|
|
||||||
|
# no default banner path
|
||||||
|
#Banner none
|
||||||
|
|
||||||
|
# override default of no subsystems
|
||||||
|
Subsystem sftp sftp-server.exe
|
||||||
|
|
||||||
|
# Example of overriding settings on a per-user basis
|
||||||
|
#Match User anoncvs
|
||||||
|
# X11Forwarding no
|
||||||
|
# AllowTcpForwarding no
|
||||||
|
# ForceCommand cvs server
|
||||||
|
PubkeyAcceptedKeyTypes ssh-ed25519*
|
||||||
|
|
||||||
|
DenyUsers denyuser1 deny*2 denyuse?3,
|
||||||
|
AllowUsers allowuser1 allowu*r2 allow?se?3 allowuser4 localuser1 localu*r2 loc?lu?er3 localadmin
|
||||||
|
DenyGroups denygroup1 denygr*p2 deny?rou?3
|
||||||
|
AllowGroups allowgroup1 allowg*2 allowg?ou?3 Adm*
|
Loading…
Reference in New Issue