version 1.281, 2021/12/19 22:11:39 |
version 1.282, 2021/12/19 22:13:33 |
|
|
* request, checking its contents for consistency and matching the embedded |
* request, checking its contents for consistency and matching the embedded |
* key against the one that is being used for signing. |
* key against the one that is being used for signing. |
* Note: does not modify msg buffer. |
* Note: does not modify msg buffer. |
* Optionally extract the username and session ID from the request. |
* Optionally extract the username, session ID and/or hostkey from the request. |
*/ |
*/ |
static int |
static int |
parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key, |
parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key, |
char **userp, struct sshbuf **sess_idp) |
char **userp, struct sshbuf **sess_idp, struct sshkey **hostkeyp) |
{ |
{ |
struct sshbuf *b = NULL, *sess_id = NULL; |
struct sshbuf *b = NULL, *sess_id = NULL; |
char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL; |
char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL; |
int r; |
int r; |
u_char t, sig_follows; |
u_char t, sig_follows; |
struct sshkey *mkey = NULL; |
struct sshkey *mkey = NULL, *hostkey = NULL; |
|
|
if (userp != NULL) |
if (userp != NULL) |
*userp = NULL; |
*userp = NULL; |
if (sess_idp != NULL) |
if (sess_idp != NULL) |
*sess_idp = NULL; |
*sess_idp = NULL; |
|
if (hostkeyp != NULL) |
|
*hostkeyp = NULL; |
if ((b = sshbuf_fromb(msg)) == NULL) |
if ((b = sshbuf_fromb(msg)) == NULL) |
fatal_f("sshbuf_fromb"); |
fatal_f("sshbuf_fromb"); |
|
|
|
|
r = SSH_ERR_INVALID_FORMAT; |
r = SSH_ERR_INVALID_FORMAT; |
goto out; |
goto out; |
} |
} |
if (strcmp(method, "publickey") != 0) { |
if (strcmp(method, "publickey-hostbound-v00@openssh.com") == 0) { |
|
if ((r = sshkey_froms(b, &hostkey)) != 0) |
|
goto out; |
|
} else if (strcmp(method, "publickey") != 0) { |
r = SSH_ERR_INVALID_FORMAT; |
r = SSH_ERR_INVALID_FORMAT; |
goto out; |
goto out; |
} |
} |
|
|
*sess_idp = sess_id; |
*sess_idp = sess_id; |
sess_id = NULL; |
sess_id = NULL; |
} |
} |
|
if (hostkeyp != NULL) { |
|
*hostkeyp = hostkey; |
|
hostkey = NULL; |
|
} |
out: |
out: |
sshbuf_free(b); |
sshbuf_free(b); |
sshbuf_free(sess_id); |
sshbuf_free(sess_id); |
|
|
free(method); |
free(method); |
free(pkalg); |
free(pkalg); |
sshkey_free(mkey); |
sshkey_free(mkey); |
|
sshkey_free(hostkey); |
return r; |
return r; |
} |
} |
|
|
|
|
static int |
static int |
check_websafe_message_contents(struct sshkey *key, struct sshbuf *data) |
check_websafe_message_contents(struct sshkey *key, struct sshbuf *data) |
{ |
{ |
if (parse_userauth_request(data, key, NULL, NULL) == 0) { |
if (parse_userauth_request(data, key, NULL, NULL, NULL) == 0) { |
debug_f("signed data matches public key userauth request"); |
debug_f("signed data matches public key userauth request"); |
return 1; |
return 1; |
} |
} |
|
|
"to sign on unbound connection"); |
"to sign on unbound connection"); |
goto send; |
goto send; |
} |
} |
if (parse_userauth_request(data, key, &user, &sid) != 0) { |
if (parse_userauth_request(data, key, &user, &sid, NULL) != 0) { |
logit_f("refusing use of destination-constrained key " |
logit_f("refusing use of destination-constrained key " |
"to sign an unidentified signature"); |
"to sign an unidentified signature"); |
goto send; |
goto send; |