diff options
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index df12c2c60..815ea0f25 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.94 2019/09/06 04:53:27 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.99 2020/02/06 22:30:54 naddy Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -68,6 +68,7 @@ | |||
68 | #include "ssherr.h" | 68 | #include "ssherr.h" |
69 | #include "channels.h" /* XXX for session.h */ | 69 | #include "channels.h" /* XXX for session.h */ |
70 | #include "session.h" /* XXX for child_set_env(); refactor? */ | 70 | #include "session.h" /* XXX for child_set_env(); refactor? */ |
71 | #include "sk-api.h" | ||
71 | 72 | ||
72 | /* import */ | 73 | /* import */ |
73 | extern ServerOptions options; | 74 | extern ServerOptions options; |
@@ -96,8 +97,9 @@ userauth_pubkey(struct ssh *ssh) | |||
96 | u_char *pkblob = NULL, *sig = NULL, have_sig; | 97 | u_char *pkblob = NULL, *sig = NULL, have_sig; |
97 | size_t blen, slen; | 98 | size_t blen, slen; |
98 | int r, pktype; | 99 | int r, pktype; |
99 | int authenticated = 0; | 100 | int req_presence = 0, authenticated = 0; |
100 | struct sshauthopt *authopts = NULL; | 101 | struct sshauthopt *authopts = NULL; |
102 | struct sshkey_sig_details *sig_details = NULL; | ||
101 | 103 | ||
102 | if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 || | 104 | if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 || |
103 | (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || | 105 | (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || |
@@ -213,9 +215,31 @@ userauth_pubkey(struct ssh *ssh) | |||
213 | PRIVSEP(sshkey_verify(key, sig, slen, | 215 | PRIVSEP(sshkey_verify(key, sig, slen, |
214 | sshbuf_ptr(b), sshbuf_len(b), | 216 | sshbuf_ptr(b), sshbuf_len(b), |
215 | (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, | 217 | (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, |
216 | ssh->compat)) == 0) { | 218 | ssh->compat, &sig_details)) == 0) { |
217 | authenticated = 1; | 219 | authenticated = 1; |
218 | } | 220 | } |
221 | if (authenticated == 1 && sig_details != NULL) { | ||
222 | auth2_record_info(authctxt, "signature count = %u", | ||
223 | sig_details->sk_counter); | ||
224 | debug("%s: sk_counter = %u, sk_flags = 0x%02x", | ||
225 | __func__, sig_details->sk_counter, | ||
226 | sig_details->sk_flags); | ||
227 | req_presence = (options.pubkey_auth_options & | ||
228 | PUBKEYAUTH_TOUCH_REQUIRED) || | ||
229 | !authopts->no_require_user_presence; | ||
230 | if (req_presence && (sig_details->sk_flags & | ||
231 | SSH_SK_USER_PRESENCE_REQD) == 0) { | ||
232 | error("public key %s signature for %s%s from " | ||
233 | "%.128s port %d rejected: user presence " | ||
234 | "(authenticator touch) requirement " | ||
235 | "not met ", key_s, | ||
236 | authctxt->valid ? "" : "invalid user ", | ||
237 | authctxt->user, ssh_remote_ipaddr(ssh), | ||
238 | ssh_remote_port(ssh)); | ||
239 | authenticated = 0; | ||
240 | goto done; | ||
241 | } | ||
242 | } | ||
219 | auth2_record_key(authctxt, authenticated, key); | 243 | auth2_record_key(authctxt, authenticated, key); |
220 | } else { | 244 | } else { |
221 | debug("%s: test pkalg %s pkblob %s%s%s", | 245 | debug("%s: test pkalg %s pkblob %s%s%s", |
@@ -266,6 +290,7 @@ done: | |||
266 | free(key_s); | 290 | free(key_s); |
267 | free(ca_s); | 291 | free(ca_s); |
268 | free(sig); | 292 | free(sig); |
293 | sshkey_sig_details_free(sig_details); | ||
269 | return authenticated; | 294 | return authenticated; |
270 | } | 295 | } |
271 | 296 | ||
@@ -436,7 +461,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, | |||
436 | * NB. all returns later this function should go via "out" to | 461 | * NB. all returns later this function should go via "out" to |
437 | * ensure the original SIGCHLD handler is restored properly. | 462 | * ensure the original SIGCHLD handler is restored properly. |
438 | */ | 463 | */ |
439 | osigchld = signal(SIGCHLD, SIG_DFL); | 464 | osigchld = ssh_signal(SIGCHLD, SIG_DFL); |
440 | 465 | ||
441 | /* Prepare and verify the user for the command */ | 466 | /* Prepare and verify the user for the command */ |
442 | username = percent_expand(options.authorized_principals_command_user, | 467 | username = percent_expand(options.authorized_principals_command_user, |
@@ -524,7 +549,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, | |||
524 | out: | 549 | out: |
525 | if (f != NULL) | 550 | if (f != NULL) |
526 | fclose(f); | 551 | fclose(f); |
527 | signal(SIGCHLD, osigchld); | 552 | ssh_signal(SIGCHLD, osigchld); |
528 | for (i = 0; i < ac; i++) | 553 | for (i = 0; i < ac; i++) |
529 | free(av[i]); | 554 | free(av[i]); |
530 | free(av); | 555 | free(av); |
@@ -874,7 +899,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, | |||
874 | * NB. all returns later this function should go via "out" to | 899 | * NB. all returns later this function should go via "out" to |
875 | * ensure the original SIGCHLD handler is restored properly. | 900 | * ensure the original SIGCHLD handler is restored properly. |
876 | */ | 901 | */ |
877 | osigchld = signal(SIGCHLD, SIG_DFL); | 902 | osigchld = ssh_signal(SIGCHLD, SIG_DFL); |
878 | 903 | ||
879 | /* Prepare and verify the user for the command */ | 904 | /* Prepare and verify the user for the command */ |
880 | username = percent_expand(options.authorized_keys_command_user, | 905 | username = percent_expand(options.authorized_keys_command_user, |
@@ -963,7 +988,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, | |||
963 | out: | 988 | out: |
964 | if (f != NULL) | 989 | if (f != NULL) |
965 | fclose(f); | 990 | fclose(f); |
966 | signal(SIGCHLD, osigchld); | 991 | ssh_signal(SIGCHLD, osigchld); |
967 | for (i = 0; i < ac; i++) | 992 | for (i = 0; i < ac; i++) |
968 | free(av[i]); | 993 | free(av[i]); |
969 | free(av); | 994 | free(av); |