diff options
author | Colin Watson <cjwatson@debian.org> | 2015-08-19 14:23:50 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2015-08-19 14:23:50 +0100 |
commit | baccdb349b31c47cd76fb63211f754ed33a9707e (patch) | |
tree | d03653f975fd4eb8bf71bb0c9d168614401202fa /auth2-pubkey.c | |
parent | 487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (diff) | |
parent | 9f82e5a9042f2d872e98f48a876fcab3e25dd9bb (diff) |
Import openssh_6.8p1.orig.tar.gz
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index f3ca96592..d943efa1e 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.41 2014/07/15 15:54:14 millert Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.47 2015/02/17 00:14:05 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include <string.h> | 41 | #include <string.h> |
42 | #include <time.h> | 42 | #include <time.h> |
43 | #include <unistd.h> | 43 | #include <unistd.h> |
44 | #include <limits.h> | ||
44 | 45 | ||
45 | #include "xmalloc.h" | 46 | #include "xmalloc.h" |
46 | #include "ssh.h" | 47 | #include "ssh.h" |
@@ -122,6 +123,17 @@ userauth_pubkey(Authctxt *authctxt) | |||
122 | "signature scheme"); | 123 | "signature scheme"); |
123 | goto done; | 124 | goto done; |
124 | } | 125 | } |
126 | if (auth2_userkey_already_used(authctxt, key)) { | ||
127 | logit("refusing previously-used %s key", key_type(key)); | ||
128 | goto done; | ||
129 | } | ||
130 | if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, | ||
131 | strlen(options.pubkey_key_types), 0) != 1) { | ||
132 | logit("%s: key type %s not in PubkeyAcceptedKeyTypes", | ||
133 | __func__, sshkey_ssh_name(key)); | ||
134 | goto done; | ||
135 | } | ||
136 | |||
125 | if (have_sig) { | 137 | if (have_sig) { |
126 | sig = packet_get_string(&slen); | 138 | sig = packet_get_string(&slen); |
127 | packet_check_eom(); | 139 | packet_check_eom(); |
@@ -159,8 +171,12 @@ userauth_pubkey(Authctxt *authctxt) | |||
159 | authenticated = 0; | 171 | authenticated = 0; |
160 | if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && | 172 | if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && |
161 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | 173 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), |
162 | buffer_len(&b))) == 1) | 174 | buffer_len(&b))) == 1) { |
163 | authenticated = 1; | 175 | authenticated = 1; |
176 | /* Record the successful key to prevent reuse */ | ||
177 | auth2_record_userkey(authctxt, key); | ||
178 | key = NULL; /* Don't free below */ | ||
179 | } | ||
164 | buffer_free(&b); | 180 | buffer_free(&b); |
165 | free(sig); | 181 | free(sig); |
166 | } else { | 182 | } else { |
@@ -212,17 +228,20 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) | |||
212 | } | 228 | } |
213 | 229 | ||
214 | if (key_is_cert(key)) { | 230 | if (key_is_cert(key)) { |
215 | fp = key_fingerprint(key->cert->signature_key, | 231 | fp = sshkey_fingerprint(key->cert->signature_key, |
216 | SSH_FP_MD5, SSH_FP_HEX); | 232 | options.fingerprint_hash, SSH_FP_DEFAULT); |
217 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", | 233 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", |
218 | key_type(key), key->cert->key_id, | 234 | key_type(key), key->cert->key_id, |
219 | (unsigned long long)key->cert->serial, | 235 | (unsigned long long)key->cert->serial, |
220 | key_type(key->cert->signature_key), fp, | 236 | key_type(key->cert->signature_key), |
237 | fp == NULL ? "(null)" : fp, | ||
221 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 238 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
222 | free(fp); | 239 | free(fp); |
223 | } else { | 240 | } else { |
224 | fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | 241 | fp = sshkey_fingerprint(key, options.fingerprint_hash, |
225 | auth_info(authctxt, "%s %s%s%s", key_type(key), fp, | 242 | SSH_FP_DEFAULT); |
243 | auth_info(authctxt, "%s %s%s%s", key_type(key), | ||
244 | fp == NULL ? "(null)" : fp, | ||
226 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 245 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
227 | free(fp); | 246 | free(fp); |
228 | } | 247 | } |
@@ -365,8 +384,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
365 | continue; | 384 | continue; |
366 | if (!key_is_cert_authority) | 385 | if (!key_is_cert_authority) |
367 | continue; | 386 | continue; |
368 | fp = key_fingerprint(found, SSH_FP_MD5, | 387 | if ((fp = sshkey_fingerprint(found, |
369 | SSH_FP_HEX); | 388 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
389 | continue; | ||
370 | debug("matching CA found: file %s, line %lu, %s %s", | 390 | debug("matching CA found: file %s, line %lu, %s %s", |
371 | file, linenum, key_type(found), fp); | 391 | file, linenum, key_type(found), fp); |
372 | /* | 392 | /* |
@@ -405,11 +425,13 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | |||
405 | continue; | 425 | continue; |
406 | if (key_is_cert_authority) | 426 | if (key_is_cert_authority) |
407 | continue; | 427 | continue; |
408 | found_key = 1; | 428 | if ((fp = sshkey_fingerprint(found, |
409 | fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | 429 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
430 | continue; | ||
410 | debug("matching key found: file %s, line %lu %s %s", | 431 | debug("matching key found: file %s, line %lu %s %s", |
411 | file, linenum, key_type(found), fp); | 432 | file, linenum, key_type(found), fp); |
412 | free(fp); | 433 | free(fp); |
434 | found_key = 1; | ||
413 | break; | 435 | break; |
414 | } | 436 | } |
415 | } | 437 | } |
@@ -431,11 +453,12 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
431 | if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) | 453 | if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) |
432 | return 0; | 454 | return 0; |
433 | 455 | ||
434 | ca_fp = key_fingerprint(key->cert->signature_key, | 456 | if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, |
435 | SSH_FP_MD5, SSH_FP_HEX); | 457 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
458 | return 0; | ||
436 | 459 | ||
437 | if (key_in_file(key->cert->signature_key, | 460 | if (sshkey_in_file(key->cert->signature_key, |
438 | options.trusted_user_ca_keys, 1) != 1) { | 461 | options.trusted_user_ca_keys, 1, 0) != 0) { |
439 | debug2("%s: CA %s %s is not listed in %s", __func__, | 462 | debug2("%s: CA %s %s is not listed in %s", __func__, |
440 | key_type(key->cert->signature_key), ca_fp, | 463 | key_type(key->cert->signature_key), ca_fp, |
441 | options.trusted_user_ca_keys); | 464 | options.trusted_user_ca_keys); |
@@ -680,6 +703,35 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
680 | return success; | 703 | return success; |
681 | } | 704 | } |
682 | 705 | ||
706 | /* Records a public key in the list of previously-successful keys */ | ||
707 | void | ||
708 | auth2_record_userkey(Authctxt *authctxt, struct sshkey *key) | ||
709 | { | ||
710 | struct sshkey **tmp; | ||
711 | |||
712 | if (authctxt->nprev_userkeys >= INT_MAX || | ||
713 | (tmp = reallocarray(authctxt->prev_userkeys, | ||
714 | authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL) | ||
715 | fatal("%s: reallocarray failed", __func__); | ||
716 | authctxt->prev_userkeys = tmp; | ||
717 | authctxt->prev_userkeys[authctxt->nprev_userkeys] = key; | ||
718 | authctxt->nprev_userkeys++; | ||
719 | } | ||
720 | |||
721 | /* Checks whether a key has already been used successfully for authentication */ | ||
722 | int | ||
723 | auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key) | ||
724 | { | ||
725 | u_int i; | ||
726 | |||
727 | for (i = 0; i < authctxt->nprev_userkeys; i++) { | ||
728 | if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) { | ||
729 | return 1; | ||
730 | } | ||
731 | } | ||
732 | return 0; | ||
733 | } | ||
734 | |||
683 | Authmethod method_pubkey = { | 735 | Authmethod method_pubkey = { |
684 | "publickey", | 736 | "publickey", |
685 | userauth_pubkey, | 737 | userauth_pubkey, |