mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-22 21:45:09 +02:00
5/12 C1
This commit is contained in:
parent
fcc3bdcd0a
commit
fedeacacf5
@ -65,7 +65,7 @@ init_listeners() {
|
||||
listeners[i].pipe_id = pipe_ids[i];
|
||||
listeners[i].type = pipe_types[i];
|
||||
listeners[i].pipe = INVALID_HANDLE_VALUE;
|
||||
listeners[i].sa.bInheritHandle = TRUE;
|
||||
listeners[i].sa.bInheritHandle = FALSE;
|
||||
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(pipe_sddls[i], SDDL_REVISION_1,
|
||||
&listeners[i].sa.lpSecurityDescriptor, &listeners[i].sa.nLength)) {
|
||||
debug("cannot convert sddl ERROR:%d", GetLastError());
|
||||
@ -111,7 +111,6 @@ iocp_work(LPVOID lpParam) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
process_connection(HANDLE pipe, int type) {
|
||||
struct agent_connection* con;
|
||||
@ -124,7 +123,7 @@ process_connection(HANDLE pipe, int type) {
|
||||
con->type = type;
|
||||
if (CreateIoCompletionPort(pipe, ioc_port, (ULONG_PTR)con, 0) != ioc_port)
|
||||
fatal("failed to assign pipe to ioc_port");
|
||||
|
||||
|
||||
agent_connection_on_io(con, 0, &con->ol);
|
||||
return iocp_work(NULL);
|
||||
}
|
||||
@ -185,8 +184,10 @@ agent_listen_loop() {
|
||||
else if ((r > WAIT_OBJECT_0) && (r <= (WAIT_OBJECT_0 + NUM_LISTENERS))) {
|
||||
/* process incoming connection */
|
||||
HANDLE con = listeners[r - 1].pipe;
|
||||
DWORD client_pid = 0;
|
||||
listeners[r - 1].pipe = INVALID_HANDLE_VALUE;
|
||||
verbose("client connected on %ls", pipe_ids[r-1]);
|
||||
GetNamedPipeClientProcessId(con, &client_pid);
|
||||
verbose("client pid %d connected on %ls", client_pid, pipe_ids[r-1]);
|
||||
if (debug_mode) {
|
||||
process_connection(con, listeners[r - 1].type);
|
||||
agent_cleanup();
|
||||
@ -201,6 +202,7 @@ agent_listen_loop() {
|
||||
si.cb = sizeof(STARTUPINFOW);
|
||||
memset(&si, 0, sizeof(STARTUPINFOW));
|
||||
GetModuleFileNameW(NULL, module_path, MAX_PATH);
|
||||
SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
||||
if ((swprintf_s(path, MAX_PATH, L"%s %d %d", module_path, con, listeners[r - 1].type) == -1 ) ||
|
||||
(CreateProcessW(NULL, path, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS, NULL, NULL,
|
||||
@ -212,6 +214,7 @@ agent_listen_loop() {
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
SetHandleInformation(con, HANDLE_FLAG_INHERIT, 0);
|
||||
CloseHandle(con);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,13 @@ struct agent_connection {
|
||||
WRITING,
|
||||
DONE
|
||||
} state;
|
||||
enum {
|
||||
UNKNOWN = 0,
|
||||
OTHER,
|
||||
LOCAL_SYSTEM,
|
||||
SSHD,
|
||||
NETWORK_SERVICE
|
||||
} client_type;
|
||||
enum agent_type type;
|
||||
};
|
||||
|
||||
|
@ -114,17 +114,74 @@ void agent_connection_disconnect(struct agent_connection* con) {
|
||||
DisconnectNamedPipe(con->connection);
|
||||
}
|
||||
|
||||
static int
|
||||
get_con_client_type(HANDLE pipe) {
|
||||
int r = -1;
|
||||
wchar_t *sshd_act = L"NT SERVICE\\SSHD", *ref_dom = NULL;
|
||||
PSID sshd_sid = NULL;
|
||||
char system_sid[SECURITY_MAX_SID_SIZE];
|
||||
char ns_sid[SECURITY_MAX_SID_SIZE];
|
||||
DWORD sshd_sid_len = 0, reg_dom_len = 0, info_len = 0, sid_size;
|
||||
SID_NAME_USE nuse;
|
||||
HANDLE token;
|
||||
TOKEN_USER* info = NULL;
|
||||
|
||||
if (ImpersonateNamedPipeClient(pipe) == FALSE)
|
||||
return -1;
|
||||
|
||||
if (LookupAccountNameW(NULL, sshd_act, NULL, &sshd_sid_len, NULL, ®_dom_len, &nuse) == TRUE ||
|
||||
(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 ||
|
||||
OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE ||
|
||||
GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE ||
|
||||
(info = (TOKEN_USER*)malloc(info_len)) == NULL ||
|
||||
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;
|
||||
|
||||
if (EqualSid(info->User.Sid, system_sid))
|
||||
r = LOCAL_SYSTEM;
|
||||
else if (EqualSid(info->User.Sid, sshd_sid))
|
||||
r = SSHD;
|
||||
else if (EqualSid(info->User.Sid, ns_sid))
|
||||
r = NETWORK_SERVICE;
|
||||
else
|
||||
r = OTHER;
|
||||
|
||||
debug("client type: %d", r);
|
||||
done:
|
||||
if (sshd_sid)
|
||||
free(sshd_sid);
|
||||
if (ref_dom)
|
||||
free(ref_dom);
|
||||
if (info)
|
||||
free(info);
|
||||
RevertToSelf();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
process_request(struct agent_connection* con) {
|
||||
int r;
|
||||
int r = -1;
|
||||
struct sshbuf *request = NULL, *response = NULL;
|
||||
|
||||
if (con->client_type == UNKNOWN)
|
||||
if ((con->client_type = get_con_client_type(con->connection)) == -1)
|
||||
goto done;
|
||||
|
||||
|
||||
request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes);
|
||||
response = sshbuf_new();
|
||||
if ((request == NULL) || (response == NULL)) {
|
||||
r = ENOMEM;
|
||||
if ((request == NULL) || (response == NULL))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (con->type == KEY_AGENT)
|
||||
r = process_keyagent_request(request, response, con);
|
||||
@ -132,8 +189,6 @@ process_request(struct agent_connection* con) {
|
||||
r = process_pubkeyagent_request(request, response, con);
|
||||
else if (con->type == PUBKEY_AUTH_AGENT)
|
||||
r = process_authagent_request(request, response, con);
|
||||
else
|
||||
r = EINVAL;
|
||||
|
||||
done:
|
||||
if (request)
|
||||
|
@ -40,9 +40,12 @@ static int
|
||||
get_user_root(struct agent_connection* con, HKEY *root){
|
||||
int r = 0;
|
||||
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
return -1;
|
||||
|
||||
r = RegOpenCurrentUser(KEY_ALL_ACCESS, root);
|
||||
if (con->client_type > OTHER)
|
||||
*root = HKEY_LOCAL_MACHINE;
|
||||
else if (RegOpenCurrentUser(KEY_ALL_ACCESS, root) != ERROR_SUCCESS)
|
||||
r = -1;
|
||||
|
||||
RevertToSelf();
|
||||
return r;
|
||||
@ -52,8 +55,10 @@ static int
|
||||
convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **eblob, DWORD *eblen, int encrypt) {
|
||||
int success = 0;
|
||||
DATA_BLOB in, out;
|
||||
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
|
||||
return -1;
|
||||
|
||||
if (con->client_type == OTHER)
|
||||
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
|
||||
return -1;
|
||||
|
||||
in.cbData = blen;
|
||||
in.pbData = (char*)blob;
|
||||
@ -61,12 +66,16 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
|
||||
out.pbData = NULL;
|
||||
|
||||
if (encrypt) {
|
||||
if (!CryptProtectData(&in, NULL, NULL, 0, NULL, 0, &out))
|
||||
if (!CryptProtectData(&in, NULL, NULL, 0, NULL, 0, &out)) {
|
||||
debug("cannot encrypt data");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!CryptUnprotectData(&in, NULL, NULL, 0, NULL, 0, &out))
|
||||
if (!CryptUnprotectData(&in, NULL, NULL, 0, NULL, 0, &out)) {
|
||||
debug("cannot decrypt data");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
*eblob = malloc(out.cbData);
|
||||
@ -79,7 +88,8 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
|
||||
done:
|
||||
if (out.pbData)
|
||||
LocalFree(out.pbData);
|
||||
RevertToSelf();
|
||||
if (con->client_type == OTHER)
|
||||
RevertToSelf();
|
||||
return success? 0: -1;
|
||||
}
|
||||
|
||||
@ -182,9 +192,11 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
|
||||
(tmpbuf = sshbuf_from(keyblob, keyblob_len)) == NULL)
|
||||
goto done;
|
||||
|
||||
if ( sshkey_private_deserialize(tmpbuf, &prikey) != 0 ||
|
||||
sshkey_sign(prikey, sig, siglen, blob, blen, 0) != 0)
|
||||
if (sshkey_private_deserialize(tmpbuf, &prikey) != 0 ||
|
||||
sshkey_sign(prikey, sig, siglen, blob, blen, 0) != 0) {
|
||||
debug("cannot sign using retrieved key");
|
||||
goto done;
|
||||
}
|
||||
|
||||
success = 1;
|
||||
|
||||
@ -221,6 +233,7 @@ process_sign_request(struct sshbuf* request, struct sshbuf* response, struct age
|
||||
sshbuf_get_string_direct(request, &data, &dlen) != 0 ||
|
||||
sshbuf_get_u32(request, &flags) != 0 ||
|
||||
sshkey_from_blob(blob, blen, &key) != 0) {
|
||||
debug("sign request is invalid");
|
||||
request_invalid = 1;
|
||||
goto done;
|
||||
}
|
||||
@ -403,6 +416,8 @@ int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, st
|
||||
|
||||
if ((r = sshbuf_get_u8(request, &type)) != 0)
|
||||
return r;
|
||||
debug2("process key agent request type %d", type);
|
||||
|
||||
switch (type) {
|
||||
case SSH2_AGENTC_ADD_IDENTITY:
|
||||
return process_add_identity(request, response, con);
|
||||
|
Loading…
x
Reference in New Issue
Block a user