summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
committerColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
commite6547182a54f0f268ee36e7c99319eeddffbaff2 (patch)
tree417527229ad3f3764ba71ea383f478a168895087 /auth2.c
parented6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff)
parent71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff)
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'auth2.c')
-rw-r--r--auth2.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/auth2.c b/auth2.c
index e0034229a..ab8795895 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.145 2018/03/03 03:15:51 djm Exp $ */ 1/* $OpenBSD: auth2.c,v 1.149 2018/07/11 18:53:29 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -41,28 +41,30 @@
41#include "ssh2.h" 41#include "ssh2.h"
42#include "packet.h" 42#include "packet.h"
43#include "log.h" 43#include "log.h"
44#include "buffer.h" 44#include "sshbuf.h"
45#include "misc.h" 45#include "misc.h"
46#include "servconf.h" 46#include "servconf.h"
47#include "compat.h" 47#include "compat.h"
48#include "key.h" 48#include "sshkey.h"
49#include "hostfile.h" 49#include "hostfile.h"
50#include "auth.h" 50#include "auth.h"
51#include "dispatch.h" 51#include "dispatch.h"
52#include "pathnames.h" 52#include "pathnames.h"
53#include "buffer.h" 53#include "sshbuf.h"
54#include "ssherr.h"
54 55
55#ifdef GSSAPI 56#ifdef GSSAPI
56#include "ssh-gss.h" 57#include "ssh-gss.h"
57#endif 58#endif
58#include "monitor_wrap.h" 59#include "monitor_wrap.h"
59#include "ssherr.h" 60#include "ssherr.h"
61#include "digest.h"
60 62
61/* import */ 63/* import */
62extern ServerOptions options; 64extern ServerOptions options;
63extern u_char *session_id2; 65extern u_char *session_id2;
64extern u_int session_id2_len; 66extern u_int session_id2_len;
65extern Buffer loginmsg; 67extern struct sshbuf *loginmsg;
66 68
67/* methods */ 69/* methods */
68 70
@@ -210,6 +212,43 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
210 return 0; 212 return 0;
211} 213}
212 214
215#define MIN_FAIL_DELAY_SECONDS 0.005
216static double
217user_specific_delay(const char *user)
218{
219 char b[512];
220 size_t len = ssh_digest_bytes(SSH_DIGEST_SHA512);
221 u_char *hash = xmalloc(len);
222 double delay;
223
224 (void)snprintf(b, sizeof b, "%llu%s",
225 (unsigned long long)options.timing_secret, user);
226 if (ssh_digest_memory(SSH_DIGEST_SHA512, b, strlen(b), hash, len) != 0)
227 fatal("%s: ssh_digest_memory", __func__);
228 /* 0-4.2 ms of delay */
229 delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000;
230 freezero(hash, len);
231 debug3("%s: user specific delay %0.3lfms", __func__, delay/1000);
232 return MIN_FAIL_DELAY_SECONDS + delay;
233}
234
235static void
236ensure_minimum_time_since(double start, double seconds)
237{
238 struct timespec ts;
239 double elapsed = monotime_double() - start, req = seconds, remain;
240
241 /* if we've already passed the requested time, scale up */
242 while ((remain = seconds - elapsed) < 0.0)
243 seconds *= 2;
244
245 ts.tv_sec = remain;
246 ts.tv_nsec = (remain - ts.tv_sec) * 1000000000;
247 debug3("%s: elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)",
248 __func__, elapsed*1000, remain*1000, req*1000);
249 nanosleep(&ts, NULL);
250}
251
213/*ARGSUSED*/ 252/*ARGSUSED*/
214static int 253static int
215input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) 254input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
@@ -218,6 +257,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
218 Authmethod *m = NULL; 257 Authmethod *m = NULL;
219 char *user, *service, *method, *style = NULL; 258 char *user, *service, *method, *style = NULL;
220 int authenticated = 0; 259 int authenticated = 0;
260 double tstart = monotime_double();
221 261
222 if (authctxt == NULL) 262 if (authctxt == NULL)
223 fatal("input_userauth_request: no authctxt"); 263 fatal("input_userauth_request: no authctxt");
@@ -286,6 +326,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
286 debug2("input_userauth_request: try method %s", method); 326 debug2("input_userauth_request: try method %s", method);
287 authenticated = m->userauth(ssh); 327 authenticated = m->userauth(ssh);
288 } 328 }
329 if (!authctxt->authenticated)
330 ensure_minimum_time_since(tstart,
331 user_specific_delay(authctxt->user));
289 userauth_finish(ssh, authenticated, method, NULL); 332 userauth_finish(ssh, authenticated, method, NULL);
290 333
291 free(service); 334 free(service);
@@ -336,11 +379,15 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
336 379
337#ifdef USE_PAM 380#ifdef USE_PAM
338 if (options.use_pam && authenticated) { 381 if (options.use_pam && authenticated) {
382 int r;
383
339 if (!PRIVSEP(do_pam_account())) { 384 if (!PRIVSEP(do_pam_account())) {
340 /* if PAM returned a message, send it to the user */ 385 /* if PAM returned a message, send it to the user */
341 if (buffer_len(&loginmsg) > 0) { 386 if (sshbuf_len(loginmsg) > 0) {
342 buffer_append(&loginmsg, "\0", 1); 387 if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
343 userauth_send_banner(buffer_ptr(&loginmsg)); 388 fatal("%s: buffer error: %s",
389 __func__, ssh_err(r));
390 userauth_send_banner(sshbuf_ptr(loginmsg));
344 packet_write_wait(); 391 packet_write_wait();
345 } 392 }
346 fatal("Access denied for user %s by PAM account " 393 fatal("Access denied for user %s by PAM account "
@@ -409,11 +456,12 @@ auth2_method_allowed(Authctxt *authctxt, const char *method,
409static char * 456static char *
410authmethods_get(Authctxt *authctxt) 457authmethods_get(Authctxt *authctxt)
411{ 458{
412 Buffer b; 459 struct sshbuf *b;
413 char *list; 460 char *list;
414 u_int i; 461 int i, r;
415 462
416 buffer_init(&b); 463 if ((b = sshbuf_new()) == NULL)
464 fatal("%s: sshbuf_new failed", __func__);
417 for (i = 0; authmethods[i] != NULL; i++) { 465 for (i = 0; authmethods[i] != NULL; i++) {
418 if (strcmp(authmethods[i]->name, "none") == 0) 466 if (strcmp(authmethods[i]->name, "none") == 0)
419 continue; 467 continue;
@@ -423,14 +471,13 @@ authmethods_get(Authctxt *authctxt)
423 if (!auth2_method_allowed(authctxt, authmethods[i]->name, 471 if (!auth2_method_allowed(authctxt, authmethods[i]->name,
424 NULL)) 472 NULL))
425 continue; 473 continue;
426 if (buffer_len(&b) > 0) 474 if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "",
427 buffer_append(&b, ",", 1); 475 authmethods[i]->name)) != 0)
428 buffer_append(&b, authmethods[i]->name, 476 fatal("%s: buffer error: %s", __func__, ssh_err(r));
429 strlen(authmethods[i]->name));
430 } 477 }
431 if ((list = sshbuf_dup_string(&b)) == NULL) 478 if ((list = sshbuf_dup_string(b)) == NULL)
432 fatal("%s: sshbuf_dup_string failed", __func__); 479 fatal("%s: sshbuf_dup_string failed", __func__);
433 buffer_free(&b); 480 sshbuf_free(b);
434 return list; 481 return list;
435} 482}
436 483