Skip to content

Commit fedeaca

Browse files
committed
5/12 C1
1 parent fcc3bdc commit fedeaca

File tree

4 files changed

+99
-19
lines changed

4 files changed

+99
-19
lines changed

contrib/win32/win32compat/ssh-agent/agent.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ init_listeners() {
6565
listeners[i].pipe_id = pipe_ids[i];
6666
listeners[i].type = pipe_types[i];
6767
listeners[i].pipe = INVALID_HANDLE_VALUE;
68-
listeners[i].sa.bInheritHandle = TRUE;
68+
listeners[i].sa.bInheritHandle = FALSE;
6969
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(pipe_sddls[i], SDDL_REVISION_1,
7070
&listeners[i].sa.lpSecurityDescriptor, &listeners[i].sa.nLength)) {
7171
debug("cannot convert sddl ERROR:%d", GetLastError());
@@ -111,7 +111,6 @@ iocp_work(LPVOID lpParam) {
111111
}
112112
}
113113

114-
115114
static void
116115
process_connection(HANDLE pipe, int type) {
117116
struct agent_connection* con;
@@ -124,7 +123,7 @@ process_connection(HANDLE pipe, int type) {
124123
con->type = type;
125124
if (CreateIoCompletionPort(pipe, ioc_port, (ULONG_PTR)con, 0) != ioc_port)
126125
fatal("failed to assign pipe to ioc_port");
127-
126+
128127
agent_connection_on_io(con, 0, &con->ol);
129128
return iocp_work(NULL);
130129
}
@@ -185,8 +184,10 @@ agent_listen_loop() {
185184
else if ((r > WAIT_OBJECT_0) && (r <= (WAIT_OBJECT_0 + NUM_LISTENERS))) {
186185
/* process incoming connection */
187186
HANDLE con = listeners[r - 1].pipe;
187+
DWORD client_pid = 0;
188188
listeners[r - 1].pipe = INVALID_HANDLE_VALUE;
189-
verbose("client connected on %ls", pipe_ids[r-1]);
189+
GetNamedPipeClientProcessId(con, &client_pid);
190+
verbose("client pid %d connected on %ls", client_pid, pipe_ids[r-1]);
190191
if (debug_mode) {
191192
process_connection(con, listeners[r - 1].type);
192193
agent_cleanup();
@@ -201,6 +202,7 @@ agent_listen_loop() {
201202
si.cb = sizeof(STARTUPINFOW);
202203
memset(&si, 0, sizeof(STARTUPINFOW));
203204
GetModuleFileNameW(NULL, module_path, MAX_PATH);
205+
SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
204206
if ((swprintf_s(path, MAX_PATH, L"%s %d %d", module_path, con, listeners[r - 1].type) == -1 ) ||
205207
(CreateProcessW(NULL, path, NULL, NULL, TRUE,
206208
DETACHED_PROCESS, NULL, NULL,
@@ -212,6 +214,7 @@ agent_listen_loop() {
212214
CloseHandle(pi.hProcess);
213215
CloseHandle(pi.hThread);
214216
}
217+
SetHandleInformation(con, HANDLE_FLAG_INHERIT, 0);
215218
CloseHandle(con);
216219
}
217220

contrib/win32/win32compat/ssh-agent/agent.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ struct agent_connection {
3131
WRITING,
3232
DONE
3333
} state;
34+
enum {
35+
UNKNOWN = 0,
36+
OTHER,
37+
LOCAL_SYSTEM,
38+
SSHD,
39+
NETWORK_SERVICE
40+
} client_type;
3441
enum agent_type type;
3542
};
3643

contrib/win32/win32compat/ssh-agent/connection.c

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,26 +114,81 @@ void agent_connection_disconnect(struct agent_connection* con) {
114114
DisconnectNamedPipe(con->connection);
115115
}
116116

117+
static int
118+
get_con_client_type(HANDLE pipe) {
119+
int r = -1;
120+
wchar_t *sshd_act = L"NT SERVICE\\SSHD", *ref_dom = NULL;
121+
PSID sshd_sid = NULL;
122+
char system_sid[SECURITY_MAX_SID_SIZE];
123+
char ns_sid[SECURITY_MAX_SID_SIZE];
124+
DWORD sshd_sid_len = 0, reg_dom_len = 0, info_len = 0, sid_size;
125+
SID_NAME_USE nuse;
126+
HANDLE token;
127+
TOKEN_USER* info = NULL;
128+
129+
if (ImpersonateNamedPipeClient(pipe) == FALSE)
130+
return -1;
131+
132+
if (LookupAccountNameW(NULL, sshd_act, NULL, &sshd_sid_len, NULL, &reg_dom_len, &nuse) == TRUE ||
133+
(sshd_sid = malloc(sshd_sid_len)) == NULL ||
134+
(ref_dom = (wchar_t*)malloc(reg_dom_len * 2)) == NULL ||
135+
LookupAccountNameW(NULL, sshd_act, sshd_sid, &sshd_sid_len, ref_dom, &reg_dom_len, &nuse) == FALSE ||
136+
OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE ||
137+
GetTokenInformation(token, TokenUser, NULL, 0, &info_len) == TRUE ||
138+
(info = (TOKEN_USER*)malloc(info_len)) == NULL ||
139+
GetTokenInformation(token, TokenUser, info, info_len, &info_len) == FALSE)
140+
goto done;
141+
142+
sid_size = SECURITY_MAX_SID_SIZE;
143+
if (CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size) == FALSE)
144+
goto done;
145+
sid_size = SECURITY_MAX_SID_SIZE;
146+
if (CreateWellKnownSid(WinNetworkServiceSid, NULL, ns_sid, &sid_size) == FALSE)
147+
goto done;
148+
149+
if (EqualSid(info->User.Sid, system_sid))
150+
r = LOCAL_SYSTEM;
151+
else if (EqualSid(info->User.Sid, sshd_sid))
152+
r = SSHD;
153+
else if (EqualSid(info->User.Sid, ns_sid))
154+
r = NETWORK_SERVICE;
155+
else
156+
r = OTHER;
157+
158+
debug("client type: %d", r);
159+
done:
160+
if (sshd_sid)
161+
free(sshd_sid);
162+
if (ref_dom)
163+
free(ref_dom);
164+
if (info)
165+
free(info);
166+
RevertToSelf();
167+
return r;
168+
}
169+
170+
117171
static int
118172
process_request(struct agent_connection* con) {
119-
int r;
173+
int r = -1;
120174
struct sshbuf *request = NULL, *response = NULL;
175+
176+
if (con->client_type == UNKNOWN)
177+
if ((con->client_type = get_con_client_type(con->connection)) == -1)
178+
goto done;
179+
121180

122181
request = sshbuf_from(con->io_buf.buf, con->io_buf.num_bytes);
123182
response = sshbuf_new();
124-
if ((request == NULL) || (response == NULL)) {
125-
r = ENOMEM;
183+
if ((request == NULL) || (response == NULL))
126184
goto done;
127-
}
128185

129186
if (con->type == KEY_AGENT)
130187
r = process_keyagent_request(request, response, con);
131188
else if (con->type == PUBKEY_AGENT)
132189
r = process_pubkeyagent_request(request, response, con);
133190
else if (con->type == PUBKEY_AUTH_AGENT)
134191
r = process_authagent_request(request, response, con);
135-
else
136-
r = EINVAL;
137192

138193
done:
139194
if (request)

contrib/win32/win32compat/ssh-agent/keyagent-request.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@ static int
4040
get_user_root(struct agent_connection* con, HKEY *root){
4141
int r = 0;
4242
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
43-
return ERROR_INTERNAL_ERROR;
43+
return -1;
4444

45-
r = RegOpenCurrentUser(KEY_ALL_ACCESS, root);
45+
if (con->client_type > OTHER)
46+
*root = HKEY_LOCAL_MACHINE;
47+
else if (RegOpenCurrentUser(KEY_ALL_ACCESS, root) != ERROR_SUCCESS)
48+
r = -1;
4649

4750
RevertToSelf();
4851
return r;
@@ -52,21 +55,27 @@ static int
5255
convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **eblob, DWORD *eblen, int encrypt) {
5356
int success = 0;
5457
DATA_BLOB in, out;
55-
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
56-
return -1;
58+
59+
if (con->client_type == OTHER)
60+
if (ImpersonateNamedPipeClient(con->connection) == FALSE)
61+
return -1;
5762

5863
in.cbData = blen;
5964
in.pbData = (char*)blob;
6065
out.cbData = 0;
6166
out.pbData = NULL;
6267

6368
if (encrypt) {
64-
if (!CryptProtectData(&in, NULL, NULL, 0, NULL, 0, &out))
69+
if (!CryptProtectData(&in, NULL, NULL, 0, NULL, 0, &out)) {
70+
debug("cannot encrypt data");
6571
goto done;
72+
}
6673
}
6774
else {
68-
if (!CryptUnprotectData(&in, NULL, NULL, 0, NULL, 0, &out))
75+
if (!CryptUnprotectData(&in, NULL, NULL, 0, NULL, 0, &out)) {
76+
debug("cannot decrypt data");
6977
goto done;
78+
}
7079
}
7180

7281
*eblob = malloc(out.cbData);
@@ -79,7 +88,8 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
7988
done:
8089
if (out.pbData)
8190
LocalFree(out.pbData);
82-
RevertToSelf();
91+
if (con->client_type == OTHER)
92+
RevertToSelf();
8393
return success? 0: -1;
8494
}
8595

@@ -182,9 +192,11 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
182192
(tmpbuf = sshbuf_from(keyblob, keyblob_len)) == NULL)
183193
goto done;
184194

185-
if ( sshkey_private_deserialize(tmpbuf, &prikey) != 0 ||
186-
sshkey_sign(prikey, sig, siglen, blob, blen, 0) != 0)
195+
if (sshkey_private_deserialize(tmpbuf, &prikey) != 0 ||
196+
sshkey_sign(prikey, sig, siglen, blob, blen, 0) != 0) {
197+
debug("cannot sign using retrieved key");
187198
goto done;
199+
}
188200

189201
success = 1;
190202

@@ -221,6 +233,7 @@ process_sign_request(struct sshbuf* request, struct sshbuf* response, struct age
221233
sshbuf_get_string_direct(request, &data, &dlen) != 0 ||
222234
sshbuf_get_u32(request, &flags) != 0 ||
223235
sshkey_from_blob(blob, blen, &key) != 0) {
236+
debug("sign request is invalid");
224237
request_invalid = 1;
225238
goto done;
226239
}
@@ -403,6 +416,8 @@ int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, st
403416

404417
if ((r = sshbuf_get_u8(request, &type)) != 0)
405418
return r;
419+
debug2("process key agent request type %d", type);
420+
406421
switch (type) {
407422
case SSH2_AGENTC_ADD_IDENTITY:
408423
return process_add_identity(request, response, con);

0 commit comments

Comments
 (0)