Skip to content

Commit 59d9124

Browse files
authored
support SSH2_AGENTC_ADD_ID_CONSTRAINED for [email protected] (#612)
* support SSH2_AGENTC_ADD_ID_CONSTRAINED by treating it as SSH2_AGENTC_ADD_IDENTITY This ignores the requested constraints: - SSH_AGENT_CONSTRAIN_LIFETIME - SSH_AGENT_CONSTRAIN_CONFIRM - SSH_AGENT_CONSTRAIN_MAXSIGN - SSH_AGENT_CONSTRAIN_EXTENSION SSH2_AGENTC_ADD_ID_CONSTRAINED is needed to support add U2F/Fido2 ssh keys to the agent from WSL ssh-add and KeePassXC ref PowerShell/Win32-OpenSSH#1961 * update buffer pointer to after comment string sshbuf_peek_string_direct doesn't update request offset pointer * parse agent constraint messages returns SSH_AGENT_FAILURE on unsupported constraint types, such as: * SSH_AGENT_CONSTRAIN_LIFETIME * SSH_AGENT_CONSTRAIN_CONFIRM * SSH_AGENT_CONSTRAIN_MAXSIGN returns SSH_AGENT_FAILURE on unsupported constrain extensions, such as: "[email protected]" accepts and ignores constrain extension "[email protected]" * reject non-internal skproviders & log
1 parent cdee736 commit 59d9124

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ process_request(struct agent_connection* con)
143143
r = process_unsupported_request(request, response, con);
144144
break;
145145
case SSH2_AGENTC_ADD_IDENTITY:
146+
case SSH2_AGENTC_ADD_ID_CONSTRAINED:
146147
r = process_add_identity(request, response, con);
147148
break;
148149
case SSH2_AGENTC_REQUEST_IDENTITIES:

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

+65-1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,64 @@ process_unsupported_request(struct sshbuf* request, struct sshbuf* response, str
224224
return r;
225225
}
226226

227+
static int
228+
parse_key_constraint_extension(struct sshbuf *m)
229+
{
230+
char *ext_name = NULL, *skprovider = NULL;
231+
int r;
232+
233+
if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) {
234+
error_fr(r, "parse constraint extension");
235+
goto out;
236+
}
237+
debug_f("constraint ext %s", ext_name);
238+
if (strcmp(ext_name, "[email protected]") == 0) {
239+
if ((r = sshbuf_get_cstring(m, &skprovider, NULL)) != 0) {
240+
error_fr(r, "parse %s", ext_name);
241+
goto out;
242+
}
243+
if (strcmp(skprovider, "internal") != 0) {
244+
error_f("unsupported sk-provider: %s", skprovider);
245+
r = SSH_ERR_FEATURE_UNSUPPORTED;
246+
goto out;
247+
}
248+
} else {
249+
error_f("unsupported constraint \"%s\"", ext_name);
250+
r = SSH_ERR_FEATURE_UNSUPPORTED;
251+
goto out;
252+
}
253+
/* success */
254+
r = 0;
255+
out:
256+
free(ext_name);
257+
return r;
258+
}
259+
260+
static int
261+
parse_key_constraints(struct sshbuf *m)
262+
{
263+
int r;
264+
u_char ctype;
265+
266+
while (sshbuf_len(m)) {
267+
if ((r = sshbuf_get_u8(m, &ctype)) != 0) {
268+
error("get constraint type returned %d", r);
269+
return r;
270+
}
271+
switch (ctype) {
272+
case SSH_AGENT_CONSTRAIN_EXTENSION:
273+
if ((r = parse_key_constraint_extension(m)) != 0)
274+
return r;
275+
break;
276+
default:
277+
error("Unknown constraint %d", ctype);
278+
return SSH_ERR_FEATURE_UNSUPPORTED;
279+
}
280+
}
281+
282+
return 0;
283+
}
284+
227285
int
228286
process_add_identity(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con)
229287
{
@@ -242,12 +300,18 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
242300
blob = sshbuf_ptr(request);
243301
if (sshkey_private_deserialize(request, &key) != 0 ||
244302
(blob_len = (sshbuf_ptr(request) - blob) & 0xffffffff) == 0 ||
245-
sshbuf_peek_string_direct(request, &comment, &comment_len) != 0) {
303+
sshbuf_get_cstring(request, &comment, &comment_len) != 0) {
246304
debug("key add request is invalid");
247305
request_invalid = 1;
248306
goto done;
249307
}
250308

309+
if ((r = parse_key_constraints(request)) != 0) {
310+
if (r != SSH_ERR_FEATURE_UNSUPPORTED)
311+
request_invalid = 1;
312+
goto done;
313+
}
314+
251315
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
252316
sa.nLength = sizeof(sa);
253317
if ((!ConvertStringSecurityDescriptorToSecurityDescriptorW(REG_KEY_SDDL, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength)) ||

0 commit comments

Comments
 (0)