mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
Added support for AuthorizedKeysCommand and AuthorizedPrincipalsCommand (#409)
This commit is contained in:
parent
754f7b4885
commit
7ae6defce8
26
auth.c
26
auth.c
@ -527,7 +527,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strict_modes && check_secure_file_permission(file, pw) != 0) {
|
if (strict_modes && check_secure_file_permission(file, pw, 0) != 0) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
logit("Authentication refused.");
|
logit("Authentication refused.");
|
||||||
auth_debug_add("Ignored %s", file_type);
|
auth_debug_add("Ignored %s", file_type);
|
||||||
@ -925,11 +925,20 @@ subprocess(const char *tag, struct passwd *pw, const char *command,
|
|||||||
restore_uid();
|
restore_uid();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (check_secure_file_permission(av[0], pw, 1) != 0) {
|
||||||
|
error("Permissions on %s:\"%s\" are too open", tag, av[0]);
|
||||||
|
restore_uid();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
|
if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
|
||||||
error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
|
error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
|
||||||
restore_uid();
|
restore_uid();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Prepare to keep the child's stdout if requested */
|
/* Prepare to keep the child's stdout if requested */
|
||||||
if (pipe(p) == -1) {
|
if (pipe(p) == -1) {
|
||||||
error("%s: pipe: %s", tag, strerror(errno));
|
error("%s: pipe: %s", tag, strerror(errno));
|
||||||
@ -938,6 +947,20 @@ subprocess(const char *tag, struct passwd *pw, const char *command,
|
|||||||
}
|
}
|
||||||
restore_uid();
|
restore_uid();
|
||||||
|
|
||||||
|
#ifdef FORK_NOT_SUPPORTED
|
||||||
|
{
|
||||||
|
posix_spawn_file_actions_t actions;
|
||||||
|
pid = -1;
|
||||||
|
|
||||||
|
if (posix_spawn_file_actions_init(&actions) != 0 ||
|
||||||
|
posix_spawn_file_actions_adddup2(&actions, p[1], STDOUT_FILENO) != 0)
|
||||||
|
fatal("posix_spawn initialization failed");
|
||||||
|
else if (__posix_spawn_asuser((pid_t*)&pid, av[0], &actions, NULL, av, NULL, pw->pw_name) != 0)
|
||||||
|
fatal("posix_spawn: %s", strerror(errno));
|
||||||
|
|
||||||
|
posix_spawn_file_actions_destroy(&actions);
|
||||||
|
}
|
||||||
|
#else
|
||||||
switch ((pid = fork())) {
|
switch ((pid = fork())) {
|
||||||
case -1: /* error */
|
case -1: /* error */
|
||||||
error("%s: fork: %s", tag, strerror(errno));
|
error("%s: fork: %s", tag, strerror(errno));
|
||||||
@ -1004,6 +1027,7 @@ subprocess(const char *tag, struct passwd *pw, const char *command,
|
|||||||
default: /* parent */
|
default: /* parent */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
close(p[1]);
|
close(p[1]);
|
||||||
if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
|
if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
|
||||||
|
@ -311,6 +311,12 @@ check_principals_line(struct ssh *ssh, char *cp, const struct sshkey_cert *cert,
|
|||||||
while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
|
while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
|
||||||
*ep-- = '\0';
|
*ep-- = '\0';
|
||||||
|
|
||||||
|
#ifdef SUPPORT_CRLF
|
||||||
|
/* account for \r at line end */
|
||||||
|
if (*ep == '\r')
|
||||||
|
*ep-- = '\0';
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the line has internal whitespace then assume it has
|
* If the line has internal whitespace then assume it has
|
||||||
* key options.
|
* key options.
|
||||||
|
@ -154,7 +154,7 @@ sshkey_perm_ok(int fd, const char *filename)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS /*implement permission checks on Windows*/
|
#ifdef WINDOWS /*implement permission checks on Windows*/
|
||||||
if(check_secure_file_permission(filename, NULL) != 0) {
|
if(check_secure_file_permission(filename, NULL, 0) != 0) {
|
||||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||||
|
@ -906,31 +906,64 @@ fileio_lseek(struct w32_io* pio, unsigned __int64 offset, int origin)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* fdopen() to be used on pipe handles */
|
||||||
* fdopen implementation - use with caution
|
static FILE*
|
||||||
* this implementation deviates from POSIX spec the following way
|
fileio_fdopen_pipe(struct w32_io* pio, const char *mode)
|
||||||
* - the underlying file descriptor is closed automatically
|
{
|
||||||
* hence no further POSIX io operations (read, write, close, etc) on the
|
int fd_flags = 0;
|
||||||
* underlying file descriptor are supported
|
FILE* ret;
|
||||||
*/
|
debug4("fdopen - io:%p", pio);
|
||||||
FILE*
|
|
||||||
fileio_fdopen(struct w32_io* pio, const char *mode)
|
if (mode[1] == '\0') {
|
||||||
|
switch (*mode) {
|
||||||
|
case 'r':
|
||||||
|
fd_flags = _O_RDONLY;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
fd_flags = _O_APPEND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = ENOTSUP;
|
||||||
|
debug3("fdopen - ERROR unsupported mode %s", mode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
debug3("fdopen - ERROR unsupported mode %s", mode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = _open_osfhandle((intptr_t)pio->handle, fd_flags);
|
||||||
|
|
||||||
|
if (fd == -1 || (ret = _fdopen(fd, mode)) == NULL) {
|
||||||
|
errno = EOTHER;
|
||||||
|
debug3("fdopen - ERROR:%d _open_osfhandle()", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overwrite underlying win32 handle - its expected to be closed via fclose
|
||||||
|
// and close pio
|
||||||
|
pio->handle = NULL;
|
||||||
|
int w32_close(int);
|
||||||
|
w32_close(pio->table_index);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fdopen() to be used on file handles */
|
||||||
|
static FILE*
|
||||||
|
fileio_fdopen_disk(struct w32_io* pio, const char *mode)
|
||||||
{
|
{
|
||||||
wchar_t *file_path, *wmode = NULL;
|
wchar_t *file_path, *wmode = NULL;
|
||||||
FILE* ret = NULL;
|
FILE* ret = NULL;
|
||||||
DWORD type = 0;
|
|
||||||
|
|
||||||
debug4("fdopen - io:%p", pio);
|
debug4("fdopen - io:%p", pio);
|
||||||
|
|
||||||
if ((wmode = utf8_to_utf16(mode)) == NULL)
|
if ((wmode = utf8_to_utf16(mode)) == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* for non-disk files, just return the descriptor */
|
|
||||||
type = GetFileType(pio->handle);
|
|
||||||
if (type != FILE_TYPE_DISK) {
|
|
||||||
return _fdopen(pio->table_index, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
file_path = get_final_path_by_handle(pio->handle);
|
file_path = get_final_path_by_handle(pio->handle);
|
||||||
if (!file_path)
|
if (!file_path)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -950,6 +983,31 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fdopen implementation - use with caution
|
||||||
|
* this implementation deviates from POSIX spec the following way
|
||||||
|
* - the underlying file descriptor is closed automatically
|
||||||
|
* hence no further POSIX io operations (read, write, close, etc) on the
|
||||||
|
* underlying file descriptor are supported
|
||||||
|
*/
|
||||||
|
FILE*
|
||||||
|
fileio_fdopen(struct w32_io* pio, const char *mode)
|
||||||
|
{
|
||||||
|
DWORD type = 0;
|
||||||
|
|
||||||
|
debug4("fdopen - io:%p", pio);
|
||||||
|
|
||||||
|
type = GetFileType(pio->handle);
|
||||||
|
if (type == FILE_TYPE_DISK) {
|
||||||
|
return fileio_fdopen_disk(pio, mode);
|
||||||
|
} else if (type == FILE_TYPE_PIPE) {
|
||||||
|
return fileio_fdopen_pipe(pio, mode);
|
||||||
|
} else {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fileio_on_select(struct w32_io* pio, BOOL rd)
|
fileio_on_select(struct w32_io* pio, BOOL rd)
|
||||||
{
|
{
|
||||||
|
@ -45,15 +45,14 @@
|
|||||||
* Check the owner of the file is one of these types: Local Administrators groups, system account, current user account
|
* Check the owner of the file is one of these types: Local Administrators groups, system account, current user account
|
||||||
* Check the users have access permission to the file don't voilate the following rules:
|
* Check the users have access permission to the file don't voilate the following rules:
|
||||||
1. no user other than local administrators group, system account, and pwd user have write permission on the file
|
1. no user other than local administrators group, system account, and pwd user have write permission on the file
|
||||||
2. sshd account can only have read permission
|
|
||||||
* Returns 0 on success and -1 on failure
|
* Returns 0 on success and -1 on failure
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
check_secure_file_permission(const char *input_path, struct passwd * pw)
|
check_secure_file_permission(const char *input_path, struct passwd * pw, int read_ok)
|
||||||
{
|
{
|
||||||
PSECURITY_DESCRIPTOR pSD = NULL;
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
||||||
wchar_t * path_utf16 = NULL;
|
wchar_t * path_utf16 = NULL;
|
||||||
PSID owner_sid = NULL, user_sid = NULL;
|
PSID owner_sid = NULL, user_sid = NULL, ti_sid = NULL;
|
||||||
PACL dacl = NULL;
|
PACL dacl = NULL;
|
||||||
DWORD error_code = ERROR_SUCCESS;
|
DWORD error_code = ERROR_SUCCESS;
|
||||||
BOOL is_valid_sid = FALSE, is_valid_acl = FALSE;
|
BOOL is_valid_sid = FALSE, is_valid_acl = FALSE;
|
||||||
@ -68,6 +67,8 @@ check_secure_file_permission(const char *input_path, struct passwd * pw)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ti_sid = get_sid("NT SERVICE\\TrustedInstaller");
|
||||||
|
|
||||||
/*Get the owner sid of the file.*/
|
/*Get the owner sid of the file.*/
|
||||||
if ((error_code = GetNamedSecurityInfoW(path_utf16, SE_FILE_OBJECT,
|
if ((error_code = GetNamedSecurityInfoW(path_utf16, SE_FILE_OBJECT,
|
||||||
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
@ -83,8 +84,9 @@ check_secure_file_permission(const char *input_path, struct passwd * pw)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) &&
|
if (!IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) &&
|
||||||
!IsWellKnownSid(owner_sid, WinLocalSystemSid) &&
|
!IsWellKnownSid(owner_sid, WinLocalSystemSid) &&
|
||||||
!EqualSid(owner_sid, user_sid)) {
|
!EqualSid(owner_sid, user_sid) &&
|
||||||
|
!(ti_sid && EqualSid(owner_sid, ti_sid))) {
|
||||||
debug3("Bad owner on %S", path_utf16);
|
debug3("Bad owner on %S", path_utf16);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -92,7 +94,6 @@ check_secure_file_permission(const char *input_path, struct passwd * pw)
|
|||||||
/*
|
/*
|
||||||
iterate all aces of the file to find out if there is voilation of the following rules:
|
iterate all aces of the file to find out if there is voilation of the following rules:
|
||||||
1. no others than administrators group, system account, and current user account have write permission on the file
|
1. no others than administrators group, system account, and current user account have write permission on the file
|
||||||
2. sshd account can only have read permission
|
|
||||||
*/
|
*/
|
||||||
for (DWORD i = 0; i < dacl->AceCount; i++) {
|
for (DWORD i = 0; i < dacl->AceCount; i++) {
|
||||||
PVOID current_ace = NULL;
|
PVOID current_ace = NULL;
|
||||||
@ -118,8 +119,12 @@ check_secure_file_permission(const char *input_path, struct passwd * pw)
|
|||||||
|
|
||||||
/*no need to check administrators group, pwd user account, and system account*/
|
/*no need to check administrators group, pwd user account, and system account*/
|
||||||
if (IsWellKnownSid(current_trustee_sid, WinBuiltinAdministratorsSid) ||
|
if (IsWellKnownSid(current_trustee_sid, WinBuiltinAdministratorsSid) ||
|
||||||
IsWellKnownSid(current_trustee_sid, WinLocalSystemSid) ||
|
IsWellKnownSid(current_trustee_sid, WinLocalSystemSid) ||
|
||||||
EqualSid(current_trustee_sid, user_sid)) {
|
EqualSid(current_trustee_sid, user_sid) ||
|
||||||
|
(ti_sid && EqualSid(current_trustee_sid, ti_sid))) {
|
||||||
|
continue;
|
||||||
|
} else if (read_ok && (current_access_mask & (FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA)) == 0 ) {
|
||||||
|
/* if read is allowed, allow ACES that do not give write access*/
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -159,6 +164,8 @@ cleanup:
|
|||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
if (user_sid)
|
if (user_sid)
|
||||||
free(user_sid);
|
free(user_sid);
|
||||||
|
if (ti_sid)
|
||||||
|
free(ti_sid);
|
||||||
if(path_utf16)
|
if(path_utf16)
|
||||||
free(path_utf16);
|
free(path_utf16);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1810,7 +1810,7 @@ read_config_file_depth(const char *filename, struct passwd *pw,
|
|||||||
implementation on windows to make sure the config file is owned by a user, administrators group, or LOCALSYSTEM account
|
implementation on windows to make sure the config file is owned by a user, administrators group, or LOCALSYSTEM account
|
||||||
and nobody else except Administrators group, LOCALSYSTEM, and file owner account has the write permission
|
and nobody else except Administrators group, LOCALSYSTEM, and file owner account has the write permission
|
||||||
*/
|
*/
|
||||||
if (check_secure_file_permission(filename, pw) != 0)
|
if (check_secure_file_permission(filename, pw, 1) != 0)
|
||||||
fatal("Bad owner or permissions on %s", filename);
|
fatal("Bad owner or permissions on %s", filename);
|
||||||
#else
|
#else
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
57
regress/pesterTests/AuthorizedKeysCommand.Tests.ps1
Normal file
57
regress/pesterTests/AuthorizedKeysCommand.Tests.ps1
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
|
||||||
|
Import-Module $PSScriptRoot\CommonUtils.psm1 -Force
|
||||||
|
$tC = 1
|
||||||
|
$tI = 0
|
||||||
|
$suite = "authorizedKeysCommand"
|
||||||
|
|
||||||
|
Describe "E2E scenarios for AuthorizedKeysCommand" -Tags "CI" {
|
||||||
|
BeforeAll {
|
||||||
|
if($OpenSSHTestInfo -eq $null)
|
||||||
|
{
|
||||||
|
Throw "`$OpenSSHTestInfo is null. Please run Set-OpenSSHTestEnvironment to set test environments."
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = $OpenSSHTestInfo["Target"]
|
||||||
|
$port = 47004
|
||||||
|
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
|
||||||
|
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
||||||
|
$sshdconfig = Join-Path $Global:OpenSSHTestInfo["ServiceConfigDir"] sshd_config
|
||||||
|
|
||||||
|
$testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite
|
||||||
|
if(-not (Test-Path $testDir))
|
||||||
|
{
|
||||||
|
$null = New-Item $testDir -ItemType directory -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeEach {
|
||||||
|
$stderrFile=Join-Path $testDir "$tC.$tI.stderr.txt"
|
||||||
|
$stdoutFile=Join-Path $testDir "$tC.$tI.stdout.txt"
|
||||||
|
$logFile = Join-Path $testDir "$tC.$tI.log.txt"
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterEach {$tI++;}
|
||||||
|
|
||||||
|
Context "$tC - basic test cases" {
|
||||||
|
|
||||||
|
BeforeAll {$tI=1}
|
||||||
|
AfterAll{$tC++}
|
||||||
|
|
||||||
|
It "$tC.$tI - keys command with %k argument" {
|
||||||
|
#override authorizedkeysfile location to an unknown location, so AuthorizedKeysCommand gets executed
|
||||||
|
$kcOutFile = Join-Path $testDir "$tC.$tI.kcout.txt"
|
||||||
|
Remove-Item -Force $kcOutFile -ErrorAction SilentlyContinue
|
||||||
|
$sshdArgs = "-d -f $sshdconfig -E $logFile -o `"AuthorizedKeysFile .fake/authorized_keys`""
|
||||||
|
$sshdArgs += " -o `"AuthorizedKeysCommand=$env:windir\system32\cmd.exe /c echo ssh-ed25519 %k & whoami > $kcOutFile`""
|
||||||
|
$sshdArgs += " -o `"AuthorizedKeysCommandUser=$ssouser`""
|
||||||
|
$sshdArgs += " -o PasswordAuthentication=no"
|
||||||
|
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments $sshdArgs -Port $port
|
||||||
|
$o = ssh -p $port test_target echo 1234
|
||||||
|
Stop-SSHDTestDaemon -Port $port
|
||||||
|
$o | Should Be "1234"
|
||||||
|
#check the command is run as AuthorizedKeysCommandUser
|
||||||
|
(gc $kcOutFile).Contains($ssouser) | Should Be $true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,9 @@ Describe "E2E scenarios for certificate authentication" -Tags "CI" {
|
|||||||
$port = $OpenSSHTestInfo["Port"]
|
$port = $OpenSSHTestInfo["Port"]
|
||||||
$pkuser = $OpenSSHTestInfo["PubKeyUser"]
|
$pkuser = $OpenSSHTestInfo["PubKeyUser"]
|
||||||
$cakey = $OpenSSHTestInfo["CA_Private_Key"]
|
$cakey = $OpenSSHTestInfo["CA_Private_Key"]
|
||||||
|
$opensshbinpath = $OpenSSHTestInfo['OpenSSHBinPath']
|
||||||
|
$ssouser = $OpenSSHTestInfo["SSOUser"]
|
||||||
|
$sshdconfig = Join-Path $Global:OpenSSHTestInfo["ServiceConfigDir"] sshd_config
|
||||||
|
|
||||||
$testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite
|
$testDir = Join-Path $OpenSSHTestInfo["TestDataPath"] $suite
|
||||||
if(-not (Test-Path $testDir))
|
if(-not (Test-Path $testDir))
|
||||||
@ -61,6 +64,28 @@ Describe "E2E scenarios for certificate authentication" -Tags "CI" {
|
|||||||
$o | Should Be "1234"
|
$o | Should Be "1234"
|
||||||
Remove-PasswordSetting
|
Remove-PasswordSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "$tC.$tI - authenticate using certificate via AuthorizedPrincipalsCommand" {
|
||||||
|
$pcOutFile = Join-Path $testDir "$tC.$tI.pcout.txt"
|
||||||
|
$logFile = Join-Path $testDir "$tC.$tI.log.txt"
|
||||||
|
Remove-Item -Force $pcOutFile -ErrorAction SilentlyContinue
|
||||||
|
$sshdArgs = "-d -f $sshdconfig -E $logFile -o `"AuthorizedKeysFile .fake/authorized_keys`""
|
||||||
|
$sshdArgs += " -o `"AuthorizedPrincipalsCommand=$env:windir\system32\cmd.exe /c echo otheruser& echo $pkuser& whoami > $pcOutFile`""
|
||||||
|
$sshdArgs += " -o `"AuthorizedPrincipalsCommandUser=$ssouser`""
|
||||||
|
$sshdArgs += " -o PasswordAuthentication=no"
|
||||||
|
|
||||||
|
Start-SSHDTestDaemon -WorkDir $opensshbinpath -Arguments $sshdArgs -Port 47004
|
||||||
|
|
||||||
|
#set up SSH_ASKPASS for key passphrase
|
||||||
|
Add-PasswordSetting -Pass $keypassphrase
|
||||||
|
$o = ssh -i $user_key -p 47004 $pkuser@$server echo 2345
|
||||||
|
Remove-PasswordSetting
|
||||||
|
|
||||||
|
Stop-SSHDTestDaemon -Port 47004
|
||||||
|
$o | Should Be "2345"
|
||||||
|
#check the command is run as AuthorizedPrincipalsCommandUser
|
||||||
|
(gc $pcOutFile).Contains($ssouser) | Should Be $true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ Describe "Tests for ssh config" -Tags "CI" {
|
|||||||
|
|
||||||
It "$tC.$tI-User SSHConfig-ReadConfig negative (others has permission)" {
|
It "$tC.$tI-User SSHConfig-ReadConfig negative (others has permission)" {
|
||||||
#setup
|
#setup
|
||||||
Repair-FilePermission -Filepath $userConfigFile -Owners $currentUserSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid -ReadAccessNeeded $objUserSid -confirm:$false
|
Repair-FilePermission -Filepath $userConfigFile -Owners $currentUserSid -FullAccessNeeded $adminsSid,$systemSid,$currentUserSid,$objUserSid -confirm:$false
|
||||||
|
|
||||||
#Run
|
#Run
|
||||||
cmd /c "ssh test_target echo 1234 2> $logPath"
|
cmd /c "ssh test_target echo 1234 2> $logPath"
|
||||||
|
@ -5,5 +5,6 @@
|
|||||||
[localhost]:47002 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
|
[localhost]:47002 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
|
||||||
[localhost]:47002 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU+NcQ5NuRutQJoZVjDmP/vE6IYZOaE59FTUjaoZkuPl4prdOPgqAnCwSy9XtnfzPm/oe62SyYIHgj8wRzhqjMU8g8aGqfv9ryF+hpNXZrFYXIdkdxnubzfb4e70RRRoTH8P5vuY8sAn0FIRlV/3EDkSKBFy2W3InMTO6l8gbkzzkgbn1GLvH06QJVdb2PcHksSn7dJBVHWASYi3TJWWu4muI+ZNfothujxAHqjKTJuJ9apDZIc0tnkPmlifRmolSUS4OAH2KWZ+5Gwaj7gsB8bk4QuA+QCT60OCcuzCcy4FBuXvvXkM9MBe/P2KZjVLAn86SriRtoE4RI+9R9S7DV sshtest_hostkey_rsa
|
[localhost]:47002 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU+NcQ5NuRutQJoZVjDmP/vE6IYZOaE59FTUjaoZkuPl4prdOPgqAnCwSy9XtnfzPm/oe62SyYIHgj8wRzhqjMU8g8aGqfv9ryF+hpNXZrFYXIdkdxnubzfb4e70RRRoTH8P5vuY8sAn0FIRlV/3EDkSKBFy2W3InMTO6l8gbkzzkgbn1GLvH06QJVdb2PcHksSn7dJBVHWASYi3TJWWu4muI+ZNfothujxAHqjKTJuJ9apDZIc0tnkPmlifRmolSUS4OAH2KWZ+5Gwaj7gsB8bk4QuA+QCT60OCcuzCcy4FBuXvvXkM9MBe/P2KZjVLAn86SriRtoE4RI+9R9S7DV sshtest_hostkey_rsa
|
||||||
[localhost]:47003 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
|
[localhost]:47003 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
|
||||||
|
[localhost]:47004 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMtJMxwn+iJU0X4+EC7PSj/cfcMbdP6ahhodtXx+6RHv sshtest_hostkey_ed25519
|
||||||
###OpenSSHE2ETests
|
###OpenSSHE2ETests
|
||||||
|
|
||||||
|
@ -2044,7 +2044,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||||||
linenum);
|
linenum);
|
||||||
len = strspn(cp, WHITESPACE);
|
len = strspn(cp, WHITESPACE);
|
||||||
if (*activep && options->authorized_keys_command == NULL) {
|
if (*activep && options->authorized_keys_command == NULL) {
|
||||||
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
|
if (!path_absolute(cp + len) && strcasecmp(cp + len, "none") != 0)
|
||||||
fatal("%.200s line %d: AuthorizedKeysCommand "
|
fatal("%.200s line %d: AuthorizedKeysCommand "
|
||||||
"must be an absolute path",
|
"must be an absolute path",
|
||||||
filename, linenum);
|
filename, linenum);
|
||||||
@ -2070,7 +2070,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||||||
len = strspn(cp, WHITESPACE);
|
len = strspn(cp, WHITESPACE);
|
||||||
if (*activep &&
|
if (*activep &&
|
||||||
options->authorized_principals_command == NULL) {
|
options->authorized_principals_command == NULL) {
|
||||||
if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0)
|
if (!path_absolute(cp + len) && strcasecmp(cp + len, "none") != 0)
|
||||||
fatal("%.200s line %d: "
|
fatal("%.200s line %d: "
|
||||||
"AuthorizedPrincipalsCommand must be "
|
"AuthorizedPrincipalsCommand must be "
|
||||||
"an absolute path", filename, linenum);
|
"an absolute path", filename, linenum);
|
||||||
|
@ -25,5 +25,5 @@
|
|||||||
#ifndef _SSH_FILE_PERM_H
|
#ifndef _SSH_FILE_PERM_H
|
||||||
#define _SSH_FILE_PERM_H
|
#define _SSH_FILE_PERM_H
|
||||||
|
|
||||||
int check_secure_file_permission(const char *, struct passwd *);
|
int check_secure_file_permission(const char *, struct passwd *, int);
|
||||||
#endif /* _SSH_FILE_PERM_H */
|
#endif /* _SSH_FILE_PERM_H */
|
Loading…
x
Reference in New Issue
Block a user