mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
support SSH2_AGENTC_ADD_ID_CONSTRAINED for sk-provider@openssh.com (#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: "restrict-destination-v00@openssh.com" accepts and ignores constrain extension "sk-provider@openssh.com" * reject non-internal skproviders & log
This commit is contained in:
parent
cdee73645a
commit
59d91246b4
@ -143,6 +143,7 @@ process_request(struct agent_connection* con)
|
|||||||
r = process_unsupported_request(request, response, con);
|
r = process_unsupported_request(request, response, con);
|
||||||
break;
|
break;
|
||||||
case SSH2_AGENTC_ADD_IDENTITY:
|
case SSH2_AGENTC_ADD_IDENTITY:
|
||||||
|
case SSH2_AGENTC_ADD_ID_CONSTRAINED:
|
||||||
r = process_add_identity(request, response, con);
|
r = process_add_identity(request, response, con);
|
||||||
break;
|
break;
|
||||||
case SSH2_AGENTC_REQUEST_IDENTITIES:
|
case SSH2_AGENTC_REQUEST_IDENTITIES:
|
||||||
|
@ -224,6 +224,64 @@ process_unsupported_request(struct sshbuf* request, struct sshbuf* response, str
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_key_constraint_extension(struct sshbuf *m)
|
||||||
|
{
|
||||||
|
char *ext_name = NULL, *skprovider = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) {
|
||||||
|
error_fr(r, "parse constraint extension");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
debug_f("constraint ext %s", ext_name);
|
||||||
|
if (strcmp(ext_name, "sk-provider@openssh.com") == 0) {
|
||||||
|
if ((r = sshbuf_get_cstring(m, &skprovider, NULL)) != 0) {
|
||||||
|
error_fr(r, "parse %s", ext_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (strcmp(skprovider, "internal") != 0) {
|
||||||
|
error_f("unsupported sk-provider: %s", skprovider);
|
||||||
|
r = SSH_ERR_FEATURE_UNSUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_f("unsupported constraint \"%s\"", ext_name);
|
||||||
|
r = SSH_ERR_FEATURE_UNSUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* success */
|
||||||
|
r = 0;
|
||||||
|
out:
|
||||||
|
free(ext_name);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_key_constraints(struct sshbuf *m)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
u_char ctype;
|
||||||
|
|
||||||
|
while (sshbuf_len(m)) {
|
||||||
|
if ((r = sshbuf_get_u8(m, &ctype)) != 0) {
|
||||||
|
error("get constraint type returned %d", r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
switch (ctype) {
|
||||||
|
case SSH_AGENT_CONSTRAIN_EXTENSION:
|
||||||
|
if ((r = parse_key_constraint_extension(m)) != 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unknown constraint %d", ctype);
|
||||||
|
return SSH_ERR_FEATURE_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
process_add_identity(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con)
|
process_add_identity(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con)
|
||||||
{
|
{
|
||||||
@ -242,12 +300,18 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
|
|||||||
blob = sshbuf_ptr(request);
|
blob = sshbuf_ptr(request);
|
||||||
if (sshkey_private_deserialize(request, &key) != 0 ||
|
if (sshkey_private_deserialize(request, &key) != 0 ||
|
||||||
(blob_len = (sshbuf_ptr(request) - blob) & 0xffffffff) == 0 ||
|
(blob_len = (sshbuf_ptr(request) - blob) & 0xffffffff) == 0 ||
|
||||||
sshbuf_peek_string_direct(request, &comment, &comment_len) != 0) {
|
sshbuf_get_cstring(request, &comment, &comment_len) != 0) {
|
||||||
debug("key add request is invalid");
|
debug("key add request is invalid");
|
||||||
request_invalid = 1;
|
request_invalid = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((r = parse_key_constraints(request)) != 0) {
|
||||||
|
if (r != SSH_ERR_FEATURE_UNSUPPORTED)
|
||||||
|
request_invalid = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||||
sa.nLength = sizeof(sa);
|
sa.nLength = sizeof(sa);
|
||||||
if ((!ConvertStringSecurityDescriptorToSecurityDescriptorW(REG_KEY_SDDL, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength)) ||
|
if ((!ConvertStringSecurityDescriptorToSecurityDescriptorW(REG_KEY_SDDL, SDDL_REVISION_1, &sa.lpSecurityDescriptor, &sa.nLength)) ||
|
||||||
|
Loading…
x
Reference in New Issue
Block a user