summaryrefslogtreecommitdiff
path: root/auth2-pubkey.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
commitbaccdb349b31c47cd76fb63211f754ed33a9707e (patch)
treed03653f975fd4eb8bf71bb0c9d168614401202fa /auth2-pubkey.c
parent487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (diff)
parent9f82e5a9042f2d872e98f48a876fcab3e25dd9bb (diff)
Import openssh_6.8p1.orig.tar.gz
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r--auth2-pubkey.c82
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 */
707void
708auth2_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 */
722int
723auth2_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
683Authmethod method_pubkey = { 735Authmethod method_pubkey = {
684 "publickey", 736 "publickey",
685 userauth_pubkey, 737 userauth_pubkey,