summaryrefslogtreecommitdiff
path: root/auth2-pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r--auth2-pubkey.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 04b70e362..2b0486222 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.43 2014/12/21 22:27:56 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.44 2014/12/22 07:51:30 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,10 @@ 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 }
125 if (have_sig) { 130 if (have_sig) {
126 sig = packet_get_string(&slen); 131 sig = packet_get_string(&slen);
127 packet_check_eom(); 132 packet_check_eom();
@@ -159,8 +164,12 @@ userauth_pubkey(Authctxt *authctxt)
159 authenticated = 0; 164 authenticated = 0;
160 if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && 165 if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
161 PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), 166 PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
162 buffer_len(&b))) == 1) 167 buffer_len(&b))) == 1) {
163 authenticated = 1; 168 authenticated = 1;
169 /* Record the successful key to prevent reuse */
170 auth2_record_userkey(authctxt, key);
171 key = NULL; /* Don't free below */
172 }
164 buffer_free(&b); 173 buffer_free(&b);
165 free(sig); 174 free(sig);
166 } else { 175 } else {
@@ -682,6 +691,35 @@ user_key_allowed(struct passwd *pw, Key *key)
682 return success; 691 return success;
683} 692}
684 693
694/* Records a public key in the list of previously-successful keys */
695void
696auth2_record_userkey(Authctxt *authctxt, struct sshkey *key)
697{
698 struct sshkey **tmp;
699
700 if (authctxt->nprev_userkeys >= INT_MAX ||
701 (tmp = reallocarray(authctxt->prev_userkeys,
702 authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL)
703 fatal("%s: reallocarray failed", __func__);
704 authctxt->prev_userkeys = tmp;
705 authctxt->prev_userkeys[authctxt->nprev_userkeys] = key;
706 authctxt->nprev_userkeys++;
707}
708
709/* Checks whether a key has already been used successfully for authentication */
710int
711auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key)
712{
713 u_int i;
714
715 for (i = 0; i < authctxt->nprev_userkeys; i++) {
716 if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) {
717 return 1;
718 }
719 }
720 return 0;
721}
722
685Authmethod method_pubkey = { 723Authmethod method_pubkey = {
686 "publickey", 724 "publickey",
687 userauth_pubkey, 725 userauth_pubkey,