Fix agent to recognize calls from sshd service (#149)
https://github.com/PowerShell/Win32-OpenSSH/issues/734
This commit is contained in:
parent
2060a413d5
commit
4df71693c2
|
@ -82,13 +82,7 @@ function Adjust-HostKeyFileACL
|
|||
("Everyone", "Read", "None", "None", "Allow")
|
||||
$myACL.AddAccessRule($everyoneAce)
|
||||
}
|
||||
else
|
||||
{
|
||||
#this only is needed when the private host keys are not registered with agent
|
||||
$sshdAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
|
||||
("NT service\sshd", "Read", "None", "None", "Allow")
|
||||
$myACL.AddAccessRule($sshdAce)
|
||||
}
|
||||
|
||||
Set-Acl -Path $FilePath -AclObject $myACL
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,14 @@ WARNING: Following changes will be made to OpenSSH configuration
|
|||
(Get-Content $_.FullName -Raw).Replace("`r`n","`n") | Set-Content $_.FullName -Force
|
||||
Adjust-HostKeyFileACL -FilePath $_.FullName
|
||||
}
|
||||
|
||||
#register host keys with agent
|
||||
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
|
||||
if (-not ($_.Name.EndsWith(".pub"))) {
|
||||
$cmd = "cmd /c `"$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec -accepteula -nobanner -s -w $($script:OpenSSHBinPath) ssh-add $_ 2> tmp.txt`""
|
||||
iex $cmd
|
||||
}
|
||||
}
|
||||
Restart-Service sshd -Force
|
||||
|
||||
#Backup existing known_hosts and replace with test version
|
||||
|
@ -305,6 +313,13 @@ function Cleanup-OpenSSHTestEnvironment
|
|||
Throw "Cannot find OpenSSH binaries under $script:OpenSSHBinPath. "
|
||||
}
|
||||
|
||||
#unregister test host keys from agent
|
||||
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*.pub"| % {
|
||||
$cmd = "cmd /c `"$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec -accepteula -nobanner -s -w $($script:OpenSSHBinPath) ssh-add -d $_ 2> tmp.txt`""
|
||||
iex $cmd
|
||||
}
|
||||
|
||||
|
||||
#Restore sshd_config
|
||||
$backupConfigPath = Join-Path $Script:OpenSSHBinPath sshd_config.ori
|
||||
if (Test-Path $backupConfigPath -PathType Leaf) {
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
*/
|
||||
|
||||
#include "agent.h"
|
||||
#include "..\misc_internal.h"
|
||||
|
||||
#pragma warning(push, 3)
|
||||
|
||||
int scm_start_service(DWORD, LPWSTR*);
|
||||
|
||||
|
@ -133,7 +135,6 @@ wmain(int argc, wchar_t **argv)
|
|||
/* - just start ssh-agent service if needed */
|
||||
{
|
||||
SC_HANDLE sc_handle, svc_handle;
|
||||
DWORD err;
|
||||
|
||||
if ((sc_handle = OpenSCManagerW(NULL, NULL, SERVICE_START)) == NULL ||
|
||||
(svc_handle = OpenServiceW(sc_handle, L"ssh-agent", SERVICE_START)) == NULL) {
|
||||
|
@ -168,3 +169,4 @@ scm_start_service(DWORD num, LPWSTR* args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
|
@ -110,9 +110,7 @@ agent_listen_loop()
|
|||
if (GetLastError() == ERROR_PIPE_CONNECTED) {
|
||||
debug("Client has already connected");
|
||||
SetEvent(ol.hEvent);
|
||||
}
|
||||
|
||||
if (GetLastError() != ERROR_IO_PENDING) {
|
||||
} else if (GetLastError() != ERROR_IO_PENDING) {
|
||||
debug("ConnectNamedPipe failed ERROR: %d", GetLastError());
|
||||
SetEvent(event_stop_agent);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#define __attribute__(A)
|
||||
#include "log.h"
|
||||
#define MAX_MESSAGE_SIZE 256 * 1024
|
||||
|
||||
#define SSH_ROOT L"SOFTWARE\\SSH"
|
||||
|
@ -25,10 +27,13 @@ struct agent_connection {
|
|||
WRITING,
|
||||
DONE
|
||||
} state;
|
||||
enum {
|
||||
enum { /* retain this order */
|
||||
UNKNOWN = 0,
|
||||
USER, /* client is running as some user */
|
||||
MACHINE /* clinet is running as machine - System, NS or LS */
|
||||
NONADMIN_USER, /* client is running as a nonadmin user */
|
||||
ADMIN_USER, /* client is running as admin */
|
||||
SSHD_SERVICE, /* client is sshd service */
|
||||
SYSTEM, /* client is running as System */
|
||||
SERVICE, /* client is running as LS or NS */
|
||||
} client_type;
|
||||
HANDLE auth_token;
|
||||
HANDLE hProfile;
|
||||
|
|
|
@ -48,13 +48,15 @@
|
|||
|
||||
#include <utf.h>
|
||||
|
||||
#pragma warning(push, 3)
|
||||
|
||||
Buffer cfg;
|
||||
ServerOptions options;
|
||||
struct passwd *privsep_pw = NULL;
|
||||
static char *config_file_name = _PATH_SERVER_CONFIG_FILE;
|
||||
int auth_sock = -1;
|
||||
|
||||
int
|
||||
int
|
||||
auth2_methods_valid(const char * c, int i) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -97,12 +99,16 @@ int
|
|||
load_config() {
|
||||
wchar_t basePath[PATH_MAX] = { 0 };
|
||||
wchar_t path[PATH_MAX] = { 0 };
|
||||
|
||||
wchar_t* config_file = L"/sshd_config";
|
||||
|
||||
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
|
||||
return -1;
|
||||
|
||||
wcsncpy(path, basePath, PATH_MAX);
|
||||
wcsncat(path, L"/sshd_config", PATH_MAX);
|
||||
if (wcslen(basePath) + wcslen(config_file) + 1 > PATH_MAX)
|
||||
fatal("unexpected config file path length");
|
||||
|
||||
wcsncpy_s(path, PATH_MAX, basePath, PATH_MAX);
|
||||
wcsncat_s(path, PATH_MAX, L"/sshd_config", PATH_MAX - wcslen(basePath));
|
||||
|
||||
if ((config_file_name = utf16_to_utf8(path)) == NULL)
|
||||
return -1;
|
||||
|
@ -129,4 +135,6 @@ pubkey_allowed(struct sshkey* pubkey, HANDLE user_token) {
|
|||
return 0;
|
||||
|
||||
return user_key_allowed(pw, pubkey, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
|
@ -40,6 +40,11 @@
|
|||
#include "key.h"
|
||||
#include "inc\utf.h"
|
||||
|
||||
#pragma warning(push, 3)
|
||||
|
||||
int
|
||||
pubkey_allowed(struct sshkey*, HANDLE);
|
||||
|
||||
static void
|
||||
InitLsaString(LSA_STRING *lsa_string, const char *str)
|
||||
{
|
||||
|
@ -47,7 +52,7 @@ InitLsaString(LSA_STRING *lsa_string, const char *str)
|
|||
memset(lsa_string, 0, sizeof(LSA_STRING));
|
||||
else {
|
||||
lsa_string->Buffer = (char *)str;
|
||||
lsa_string->Length = strlen(str);
|
||||
lsa_string->Length = (USHORT)strlen(str);
|
||||
lsa_string->MaximumLength = lsa_string->Length + 1;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +151,7 @@ generate_user_token(wchar_t* user_cpn) {
|
|||
s4u_logon = (KERB_S4U_LOGON*)logon_info;
|
||||
s4u_logon->MessageType = KerbS4ULogon;
|
||||
s4u_logon->Flags = 0;
|
||||
s4u_logon->ClientUpn.Length = wcslen(user_cpn) * 2;
|
||||
s4u_logon->ClientUpn.Length = (USHORT)wcslen(user_cpn) * 2;
|
||||
s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
|
||||
s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1);
|
||||
memcpy(s4u_logon->ClientUpn.Buffer, user_cpn, s4u_logon->ClientUpn.Length + 2);
|
||||
|
@ -164,7 +169,7 @@ generate_user_token(wchar_t* user_cpn) {
|
|||
s4u_logon = (MSV1_0_S4U_LOGON*)logon_info;
|
||||
s4u_logon->MessageType = MsV1_0S4ULogon;
|
||||
s4u_logon->Flags = 0;
|
||||
s4u_logon->UserPrincipalName.Length = wcslen(user_cpn) * 2;
|
||||
s4u_logon->UserPrincipalName.Length = (USHORT)wcslen(user_cpn) * 2;
|
||||
s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length;
|
||||
s4u_logon->UserPrincipalName.Buffer = (WCHAR*)(s4u_logon + 1);
|
||||
memcpy(s4u_logon->UserPrincipalName.Buffer, user_cpn, s4u_logon->UserPrincipalName.Length + 2);
|
||||
|
@ -184,7 +189,7 @@ generate_user_token(wchar_t* user_cpn) {
|
|||
Network,
|
||||
auth_package_id,
|
||||
logon_info,
|
||||
logon_info_size,
|
||||
(ULONG)logon_info_size,
|
||||
NULL,
|
||||
&sourceContext,
|
||||
(PVOID*)&pProfile,
|
||||
|
@ -208,14 +213,39 @@ done:
|
|||
return token;
|
||||
}
|
||||
|
||||
static HANDLE
|
||||
duplicate_token_for_client(struct agent_connection* con, HANDLE t) {
|
||||
ULONG client_pid;
|
||||
HANDLE client_proc = NULL, dup_t = NULL;
|
||||
|
||||
/* Should the token match client's session id?
|
||||
ULONG client_sessionId;
|
||||
if (GetNamedPipeClientSessionId(con->pipe_handle, &client_sessionId) == FALSE ||
|
||||
SetTokenInformation(t, TokenSessionId, &client_sessionId, sizeof(client_sessionId)) == FALSE) {
|
||||
error("unable to set token session id, error: %d", GetLastError());
|
||||
goto done;
|
||||
}*/
|
||||
|
||||
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
|
||||
((client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
|
||||
DuplicateHandle(GetCurrentProcess(), t, client_proc, &dup_t, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS) == FALSE ) {
|
||||
error("failed to duplicate user token");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (client_proc)
|
||||
CloseHandle(client_proc);
|
||||
return dup_t;
|
||||
}
|
||||
|
||||
/* TODO - SecureZeroMemory password */
|
||||
int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
|
||||
char *user = NULL, *domain = NULL, *pwd = NULL;
|
||||
size_t user_len, pwd_len;
|
||||
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *pwd_utf16 = NULL, *tmp;
|
||||
int r = -1;
|
||||
HANDLE token = 0, dup_token, client_proc = 0;
|
||||
ULONG client_pid;
|
||||
HANDLE token = 0, dup_token;
|
||||
|
||||
if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
|
||||
sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
|
||||
|
@ -243,13 +273,11 @@ int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
|
||||
((client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
|
||||
(FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
|
||||
(sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) {
|
||||
debug("failed to duplicate user token");
|
||||
if ((dup_token = duplicate_token_for_client(con, token)) == NULL)
|
||||
goto done;
|
||||
|
||||
if (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
con->auth_token = token;
|
||||
LoadProfile(con, user_utf16, udom_utf16);
|
||||
|
@ -267,8 +295,6 @@ done:
|
|||
free(user_utf16);
|
||||
if (pwd_utf16)
|
||||
free(pwd_utf16);
|
||||
if (client_proc)
|
||||
CloseHandle(client_proc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -278,11 +304,10 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
|||
char *key_blob, *user, *sig, *blob;
|
||||
size_t key_blob_len, user_len, sig_len, blob_len;
|
||||
struct sshkey *key = NULL;
|
||||
HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
|
||||
HANDLE token = NULL, dup_token = NULL;
|
||||
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *tmp;
|
||||
PWSTR wuser_home = NULL;
|
||||
ULONG client_pid;
|
||||
LUID_AND_ATTRIBUTES priv_to_delete[1];
|
||||
|
||||
|
||||
user = NULL;
|
||||
if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
|
||||
|
@ -301,7 +326,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
|||
}
|
||||
|
||||
if ((token = generate_user_token(user_utf16)) == 0) {
|
||||
debug("unable to generate token for user %ls", user_utf16);
|
||||
error("unable to generate token for user %ls", user_utf16);
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -311,18 +336,16 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (key_verify(key, sig, sig_len, blob, blob_len) != 1) {
|
||||
if (key_verify(key, sig, (u_int)sig_len, blob, (u_int)blob_len) != 1) {
|
||||
debug("signature verification failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
|
||||
( (client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
|
||||
(FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
|
||||
(sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) {
|
||||
debug("failed to authorize user");
|
||||
if ((dup_token = duplicate_token_for_client(con, token)) == NULL)
|
||||
goto done;
|
||||
|
||||
if (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
con->auth_token = token;
|
||||
token = NULL;
|
||||
|
@ -346,8 +369,6 @@ done:
|
|||
sshkey_free(key);
|
||||
if (wuser_home)
|
||||
CoTaskMemFree(wuser_home);
|
||||
if (client_proc)
|
||||
CloseHandle(client_proc);
|
||||
if (token)
|
||||
CloseHandle(token);
|
||||
return r;
|
||||
|
@ -361,6 +382,12 @@ int process_authagent_request(struct sshbuf* request, struct sshbuf* response, s
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* allow only admins and NT Service\sshd to send auth requests */
|
||||
if (con->client_type != SSHD_SERVICE && con->client_type != ADMIN_USER) {
|
||||
error("cannot authenticate: client process is not admin or sshd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(opn, PUBKEY_AUTH_REQUEST, opn_len) == 0)
|
||||
return process_pubkeyauth_request(request, response, con);
|
||||
else if (memcmp(opn, PASSWD_AUTH_REQUEST, opn_len) == 0)
|
||||
|
@ -369,4 +396,6 @@ int process_authagent_request(struct sshbuf* request, struct sshbuf* response, s
|
|||
debug("unknown auth request: %s", opn);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
|
@ -31,6 +31,8 @@
|
|||
#include "agent.h"
|
||||
#include "agent-request.h"
|
||||
|
||||
#pragma warning(push, 3)
|
||||
|
||||
int process_request(struct agent_connection*);
|
||||
|
||||
#define ABORT_CONNECTION_RETURN(c) do { \
|
||||
|
@ -114,20 +116,41 @@ agent_connection_disconnect(struct agent_connection* con)
|
|||
DisconnectNamedPipe(con->pipe_handle);
|
||||
}
|
||||
|
||||
static char*
|
||||
con_type_to_string(struct agent_connection* con) {
|
||||
switch (con->client_type) {
|
||||
case UNKNOWN:
|
||||
return "unknown";
|
||||
case NONADMIN_USER:
|
||||
return "restricted user";
|
||||
case ADMIN_USER:
|
||||
return "administrator";
|
||||
case SSHD_SERVICE:
|
||||
return "sshd service";
|
||||
case SYSTEM:
|
||||
return "system";
|
||||
case SERVICE:
|
||||
return "service";
|
||||
default:
|
||||
return "unexpected";
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_con_client_type(struct agent_connection* con)
|
||||
{
|
||||
int r = -1;
|
||||
char system_sid[SECURITY_MAX_SID_SIZE];
|
||||
char ns_sid[SECURITY_MAX_SID_SIZE];
|
||||
char ls_sid[SECURITY_MAX_SID_SIZE];
|
||||
char sid[SECURITY_MAX_SID_SIZE];
|
||||
wchar_t *sshd_act = L"NT SERVICE\\SSHD", *ref_dom = NULL;
|
||||
DWORD reg_dom_len = 0, info_len = 0, sid_size;
|
||||
DWORD sshd_sid_len = 0;
|
||||
PSID sshd_sid = NULL;
|
||||
SID_NAME_USE nuse;
|
||||
HANDLE token;
|
||||
TOKEN_USER* info = NULL;
|
||||
HANDLE pipe = con->pipe_handle;
|
||||
BOOL isMember = FALSE;
|
||||
|
||||
if (ImpersonateNamedPipeClient(pipe) == FALSE)
|
||||
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
|
||||
return -1;
|
||||
|
||||
if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE ||
|
||||
|
@ -136,26 +159,76 @@ get_con_client_type(struct agent_connection* con)
|
|||
GetTokenInformation(token, TokenUser, info, info_len, &info_len) == FALSE)
|
||||
goto done;
|
||||
|
||||
sid_size = SECURITY_MAX_SID_SIZE;
|
||||
if (CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size) == FALSE)
|
||||
goto done;
|
||||
sid_size = SECURITY_MAX_SID_SIZE;
|
||||
if (CreateWellKnownSid(WinNetworkServiceSid, NULL, ns_sid, &sid_size) == FALSE)
|
||||
goto done;
|
||||
sid_size = SECURITY_MAX_SID_SIZE;
|
||||
if (CreateWellKnownSid(WinLocalServiceSid, NULL, ls_sid, &sid_size) == FALSE)
|
||||
/* check if its localsystem */
|
||||
if (IsWellKnownSid(info->User.Sid, WinLocalSystemSid)) {
|
||||
con->client_type = SYSTEM;
|
||||
r = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (EqualSid(info->User.Sid, system_sid) ||
|
||||
EqualSid(info->User.Sid, ls_sid) ||
|
||||
EqualSid(info->User.Sid, ns_sid))
|
||||
con->client_type = MACHINE;
|
||||
else
|
||||
con->client_type = USER;
|
||||
/* check if its SSHD service */
|
||||
{
|
||||
/* Does NT Service/SSHD exist */
|
||||
LookupAccountNameW(NULL, sshd_act, NULL, &sshd_sid_len, NULL, ®_dom_len, &nuse);
|
||||
|
||||
if (GetLastError() == ERROR_NONE_MAPPED)
|
||||
debug3("Cannot look up SSHD account, its likely not installed");
|
||||
else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||
error("LookupAccountNameW on SSHD account failed with %d", GetLastError());
|
||||
goto done;
|
||||
} else {
|
||||
if ((sshd_sid = malloc(sshd_sid_len)) == NULL ||
|
||||
(ref_dom = (wchar_t*)malloc(reg_dom_len * 2)) == NULL ||
|
||||
LookupAccountNameW(NULL, sshd_act, sshd_sid, &sshd_sid_len, ref_dom, ®_dom_len, &nuse) == FALSE)
|
||||
goto done;
|
||||
|
||||
debug2("client type: %s", con->client_type == MACHINE? "machine" : "user");
|
||||
if (EqualSid(info->User.Sid, sshd_sid)) {
|
||||
con->client_type = SSHD_SERVICE;
|
||||
r = 0;
|
||||
goto done;
|
||||
}
|
||||
if (CheckTokenMembership(token, sshd_sid, &isMember) == FALSE)
|
||||
goto done;
|
||||
if (isMember) {
|
||||
con->client_type = SSHD_SERVICE;
|
||||
r = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if its LS or NS */
|
||||
if (IsWellKnownSid(info->User.Sid, WinNetworkServiceSid) ||
|
||||
IsWellKnownSid(info->User.Sid, WinLocalServiceSid)) {
|
||||
con->client_type = SERVICE;
|
||||
r = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* check if its admin */
|
||||
{
|
||||
sid_size = SECURITY_MAX_SID_SIZE;
|
||||
if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, sid, &sid_size) == FALSE)
|
||||
goto done;
|
||||
if (CheckTokenMembership(token, sid, &isMember) == FALSE)
|
||||
goto done;
|
||||
if (isMember) {
|
||||
con->client_type = ADMIN_USER;
|
||||
r = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* none of above */
|
||||
con->client_type = NONADMIN_USER;
|
||||
r = 0;
|
||||
done:
|
||||
debug("client type: %s", con_type_to_string(con));
|
||||
|
||||
if (sshd_sid)
|
||||
free(sshd_sid);
|
||||
if (ref_dom)
|
||||
free(ref_dom);
|
||||
if (info)
|
||||
free(info);
|
||||
RevertToSelf();
|
||||
|
@ -214,13 +287,15 @@ done:
|
|||
|
||||
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
|
||||
if (r == 0) {
|
||||
POKE_U32(con->io_buf.buf, sshbuf_len(response));
|
||||
POKE_U32(con->io_buf.buf, (u_int32_t)sshbuf_len(response));
|
||||
memcpy(con->io_buf.buf + 4, sshbuf_ptr(response), sshbuf_len(response));
|
||||
con->io_buf.num_bytes = sshbuf_len(response) + 4;
|
||||
con->io_buf.num_bytes = (DWORD)sshbuf_len(response) + 4;
|
||||
}
|
||||
|
||||
if (response)
|
||||
sshbuf_free(response);
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
|
@ -33,6 +33,8 @@
|
|||
#include "agent-request.h"
|
||||
#include <sddl.h>
|
||||
|
||||
#pragma warning(push, 3)
|
||||
|
||||
#define MAX_KEY_LENGTH 255
|
||||
#define MAX_VALUE_NAME 16383
|
||||
|
||||
|
@ -48,7 +50,7 @@ get_user_root(struct agent_connection* con, HKEY *root)
|
|||
LONG ret;
|
||||
*root = HKEY_LOCAL_MACHINE;
|
||||
|
||||
if (con->client_type == USER) {
|
||||
if (con->client_type <= ADMIN_USER) {
|
||||
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
|
||||
return -1;
|
||||
*root = NULL;
|
||||
|
@ -71,7 +73,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
|
|||
int success = 0;
|
||||
DATA_BLOB in, out;
|
||||
|
||||
if (con->client_type == USER)
|
||||
if (con->client_type <= ADMIN_USER)
|
||||
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
|
||||
return -1;
|
||||
|
||||
|
@ -102,7 +104,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
|
|||
done:
|
||||
if (out.pbData)
|
||||
LocalFree(out.pbData);
|
||||
if (con->client_type == USER)
|
||||
if (con->client_type <= ADMIN_USER)
|
||||
RevertToSelf();
|
||||
return success? 0: -1;
|
||||
}
|
||||
|
@ -123,6 +125,7 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
|
|||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
/* parse input request */
|
||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
blob = sshbuf_ptr(request);
|
||||
if (sshkey_private_deserialize(request, &key) != 0 ||
|
||||
(blob_len = (sshbuf_ptr(request) - blob) & 0xffffffff) == 0 ||
|
||||
|
@ -142,9 +145,9 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
|
|||
RegCreateKeyExW(user_root, SSH_KEYS_ROOT, 0, 0, 0, KEY_WRITE | KEY_WOW64_64KEY, &sa, ®, NULL) != 0 ||
|
||||
RegCreateKeyExA(reg, thumbprint, 0, 0, 0, KEY_WRITE | KEY_WOW64_64KEY, &sa, &sub, NULL) != 0 ||
|
||||
RegSetValueExW(sub, NULL, 0, REG_BINARY, eblob, eblob_len) != 0 ||
|
||||
RegSetValueExW(sub, L"pub", 0, REG_BINARY, pubkey_blob, pubkey_blob_len) != 0 ||
|
||||
RegSetValueExW(sub, L"pub", 0, REG_BINARY, pubkey_blob, (DWORD)pubkey_blob_len) != 0 ||
|
||||
RegSetValueExW(sub, L"type", 0, REG_DWORD, (BYTE*)&key->type, 4) != 0 ||
|
||||
RegSetValueExW(sub, L"comment", 0, REG_BINARY, comment, comment_len) != 0 ) {
|
||||
RegSetValueExW(sub, L"comment", 0, REG_BINARY, comment, (DWORD)comment_len) != 0 ) {
|
||||
debug("failed to add key to store");
|
||||
goto done;
|
||||
}
|
||||
|
@ -450,4 +453,6 @@ int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, st
|
|||
debug("unknown key agent request %d", type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
3
sshd.c
3
sshd.c
|
@ -1677,7 +1677,8 @@ main(int ac, char **av)
|
|||
* For windows, enable logging right away to capture failures while loading private host keys.
|
||||
* On Unix, logging at configured level is not done until private host keys are loaded. Why??
|
||||
*/
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
||||
if (!debug_flag)
|
||||
log_init(__progname, options.log_level, options.log_facility, log_stderr);
|
||||
#endif // WINDOWS
|
||||
|
||||
/* challenge-response is implemented via keyboard interactive */
|
||||
|
|
Loading…
Reference in New Issue