Spin up ssh-sk-helper in user context when called from ssh-agent (#560)

This commit is contained in:
bagajjal 2022-02-01 18:46:19 -08:00 committed by GitHub
parent f82b197a3e
commit 0d88c342a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 99 additions and 44 deletions

View File

@ -90,7 +90,7 @@ wevtutil im `"$etwman`"
$agentDesc = "Agent to hold private keys used for public key authentication."
New-Service -Name ssh-agent -DisplayName "OpenSSH Authentication Agent" -BinaryPathName `"$sshagentpath`" -Description $agentDesc -StartupType Manual | Out-Null
sc.exe sdset ssh-agent "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RP;;;AU)"
sc.exe privs ssh-agent SeImpersonatePrivilege
sc.exe privs ssh-agent SeAssignPrimaryTokenPrivilege/SeTcbPrivilege/SeBackupPrivilege/SeRestorePrivilege/SeImpersonatePrivilege
$sshdDesc = "SSH protocol based service to provide secure encrypted communications between two untrusted hosts over an insecure network."
New-Service -Name sshd -DisplayName "OpenSSH SSH Server" -BinaryPathName `"$sshdpath`" -Description $sshdDesc -StartupType Manual | Out-Null

View File

@ -41,6 +41,7 @@ struct passwd *w32_getpwuid(uid_t uid);
struct passwd *w32_getpwnam(const char *username);
struct passwd *getpwent(void);
void endpwent(void);
char *get_username(const PSID sid);
#define getpwuid w32_getpwuid
#define getpwnam w32_getpwnam

View File

@ -330,6 +330,21 @@ cleanup:
return ret;
}
char *
get_username(const PSID sid)
{
if (!sid) {
error_f("sid is NULL");
return NULL;
}
struct passwd *p = get_passwd(NULL, sid);
if (p && p->pw_name)
return strdup(p->pw_name);
else
return NULL;
}
struct passwd*
w32_getpwnam(const char *user_utf8)
{

View File

@ -121,6 +121,9 @@ wmain(int argc, wchar_t **argv)
fix_cwd();
if (!StartServiceCtrlDispatcherW(dispatch_table)) {
if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/*
* agent is not spawned by SCM
* Its either started in debug mode or a worker child

View File

@ -32,8 +32,12 @@
#include <sddl.h>
#include <UserEnv.h>
#include "..\misc_internal.h"
#include <pwd.h>
#define BUFSIZE 5 * 1024
char* sshagent_con_username;
static HANDLE ioc_port = NULL;
static BOOL debug_mode = FALSE;
@ -189,6 +193,11 @@ agent_cleanup_connection(struct agent_connection* con)
free(con);
CloseHandle(ioc_port);
ioc_port = NULL;
if(sshagent_con_username) {
free(sshagent_con_username);
sshagent_con_username = NULL;
}
}
void
@ -289,6 +298,13 @@ get_con_client_info(struct agent_connection* con)
goto done;
}
// Get username
sshagent_con_username= get_username(info->User.Sid);
if (sshagent_con_username)
debug_f("sshagent_con_username: %s", sshagent_con_username);
else
error_f("Failed to get the userName");
/* check if its admin */
{
sid_size = SECURITY_MAX_SID_SIZE;

View File

@ -118,10 +118,14 @@ generate_s4u_user_token(wchar_t* user_cpn, int impersonation) {
/* trusted mode - used for impersonation */
LSA_OPERATIONAL_MODE mode;
InitLsaString(&logon_process_name, "sshd");
if ((ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode)) != STATUS_SUCCESS)
InitLsaString(&logon_process_name, __progname);
if ((ret = LsaRegisterLogonProcess(&logon_process_name, &lsa_handle, &mode)) != STATUS_SUCCESS) {
ULONG winError = LsaNtStatusToWinError(ret);
error_f("LsaRegisterLogonProcess failed with error:%d", winError);
goto done;
}
}
else {
/* untrusted mode - used for information lookup */
if (LsaConnectUntrusted(&lsa_handle) != STATUS_SUCCESS)

View File

@ -424,10 +424,16 @@ Describe "Setup Tests" -Tags "Setup" {
}
It "$tC.$tI - Validate RequiredPrivileges of ssh-agent" {
$expected = @("SeAssignPrimaryTokenPrivilege", "SeTcbPrivilege", "SeBackupPrivilege", "SeRestorePrivilege", "SeImpersonatePrivilege")
$a = sc.exe qprivs ssh-agent 256
$p = @($a | % { if($_ -match "Se[\w]+Privilege" ) {$start = $_.IndexOf("Se");$_.Substring($start, $_.length-$start)}})
$p.count | Should Be 1
$p[0] | Should Be "SeImpersonatePrivilege"
$expected | % {
$p -contains $_ | Should be $true
}
$p | % {
$expected -contains $_ | Should be $true
}
}
It "$tC.$tI - Validate RequiredPrivileges of sshd" {

View File

@ -44,6 +44,7 @@
/* #define DEBUG_SK 1 */
#ifdef WINDOWS
extern char *sshagent_con_username = NULL;
static char module_path[PATH_MAX + 1];
static char *
@ -167,10 +168,19 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
av[0] = helper;
av[1] = verbosity;
av[2] = NULL;
if (sshagent_con_username) {
debug_f("sshagent_con_username:%s", sshagent_con_username);
if (__posix_spawn_asuser((pid_t *)&pid, av[0], &actions, NULL, av, NULL, sshagent_con_username) != 0) {
error_f("__posix_spawn_asuser failed for username:%s", sshagent_con_username);
goto out;
}
} else {
if (posix_spawnp((pid_t *)&pid, av[0], &actions, NULL, av, NULL) != 0) {
error_f("posix_spawnp failed");
goto out;
}
}
r = 0;
#else
if ((pid = fork()) == -1) {