summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2017-06-24 06:34:38 +0000
committerDamien Miller <djm@mindrot.org>2017-06-24 16:56:11 +1000
commit8f574959272ac7fe9239c4f5d10fd913f8920ab0 (patch)
tree51ab66a6011af6459e0d4ca15a4b4b78368607a1 /auth2.c
parente2004d4bb7eb01c663dd3a3e7eb224f1ccdc9bba (diff)
upstream commit
refactor authentication logging optionally record successful auth methods and public credentials used in a file accessible to user sessions feedback and ok markus@ Upstream-ID: 090b93036967015717b9a54fd0467875ae9d32fb
Diffstat (limited to 'auth2.c')
-rw-r--r--auth2.c133
1 files changed, 132 insertions, 1 deletions
diff --git a/auth2.c b/auth2.c
index cb4c2fd5d..862e09960 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.142 2017/05/31 07:00:13 markus Exp $ */ 1/* $OpenBSD: auth2.c,v 1.143 2017/06/24 06:34:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,6 +30,7 @@
30#include <sys/uio.h> 30#include <sys/uio.h>
31 31
32#include <fcntl.h> 32#include <fcntl.h>
33#include <limits.h>
33#include <pwd.h> 34#include <pwd.h>
34#include <stdarg.h> 35#include <stdarg.h>
35#include <string.h> 36#include <string.h>
@@ -55,6 +56,7 @@
55#include "ssh-gss.h" 56#include "ssh-gss.h"
56#endif 57#endif
57#include "monitor_wrap.h" 58#include "monitor_wrap.h"
59#include "ssherr.h"
58 60
59/* import */ 61/* import */
60extern ServerOptions options; 62extern ServerOptions options;
@@ -277,6 +279,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
277 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 279 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
278#endif 280#endif
279 281
282 auth2_authctxt_reset_info(authctxt);
280 authctxt->postponed = 0; 283 authctxt->postponed = 0;
281 authctxt->server_caused_failure = 0; 284 authctxt->server_caused_failure = 0;
282 285
@@ -327,6 +330,10 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
327 /* Log before sending the reply */ 330 /* Log before sending the reply */
328 auth_log(authctxt, authenticated, partial, method, submethod); 331 auth_log(authctxt, authenticated, partial, method, submethod);
329 332
333 /* Update information exposed to session */
334 if (authenticated || partial)
335 auth2_update_session_info(authctxt, method, submethod);
336
330 if (authctxt->postponed) 337 if (authctxt->postponed)
331 return; 338 return;
332 339
@@ -624,4 +631,128 @@ auth2_update_methods_lists(Authctxt *authctxt, const char *method,
624 return 0; 631 return 0;
625} 632}
626 633
634/* Reset method-specific information */
635void auth2_authctxt_reset_info(Authctxt *authctxt)
636{
637 sshkey_free(authctxt->auth_method_key);
638 free(authctxt->auth_method_info);
639 authctxt->auth_method_key = NULL;
640 authctxt->auth_method_info = NULL;
641}
642
643/* Record auth method-specific information for logs */
644void
645auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
646{
647 va_list ap;
648 int i;
649
650 free(authctxt->auth_method_info);
651 authctxt->auth_method_info = NULL;
652
653 va_start(ap, fmt);
654 i = vasprintf(&authctxt->auth_method_info, fmt, ap);
655 va_end(ap);
656
657 if (i < 0 || authctxt->auth_method_info == NULL)
658 fatal("%s: vasprintf failed", __func__);
659}
660
661/*
662 * Records a public key used in authentication. This is used for logging
663 * and to ensure that the same key is not subsequently accepted again for
664 * multiple authentication.
665 */
666void
667auth2_record_key(Authctxt *authctxt, int authenticated,
668 const struct sshkey *key)
669{
670 struct sshkey **tmp, *dup;
671 int r;
672
673 if ((r = sshkey_demote(key, &dup)) != 0)
674 fatal("%s: copy key: %s", __func__, ssh_err(r));
675 sshkey_free(authctxt->auth_method_key);
676 authctxt->auth_method_key = dup;
677
678 if (!authenticated)
679 return;
680
681 /* If authenticated, make sure we don't accept this key again */
682 if ((r = sshkey_demote(key, &dup)) != 0)
683 fatal("%s: copy key: %s", __func__, ssh_err(r));
684 if (authctxt->nprev_keys >= INT_MAX ||
685 (tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
686 authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL)
687 fatal("%s: reallocarray failed", __func__);
688 authctxt->prev_keys = tmp;
689 authctxt->prev_keys[authctxt->nprev_keys] = dup;
690 authctxt->nprev_keys++;
691
692}
693
694/* Checks whether a key has already been previously used for authentication */
695int
696auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key)
697{
698 u_int i;
699 char *fp;
700
701 for (i = 0; i < authctxt->nprev_keys; i++) {
702 if (sshkey_equal_public(key, authctxt->prev_keys[i])) {
703 fp = sshkey_fingerprint(authctxt->prev_keys[i],
704 options.fingerprint_hash, SSH_FP_DEFAULT);
705 debug3("%s: key already used: %s %s", __func__,
706 sshkey_type(authctxt->prev_keys[i]),
707 fp == NULL ? "UNKNOWN" : fp);
708 free(fp);
709 return 1;
710 }
711 }
712 return 0;
713}
714
715/*
716 * Updates authctxt->session_info with details of authentication. Should be
717 * whenever an authentication method succeeds.
718 */
719void
720auth2_update_session_info(Authctxt *authctxt, const char *method,
721 const char *submethod)
722{
723 int r;
724
725 if (authctxt->session_info == NULL) {
726 if ((authctxt->session_info = sshbuf_new()) == NULL)
727 fatal("%s: sshbuf_new", __func__);
728 }
729
730 /* Append method[/submethod] */
731 if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
732 method, submethod == NULL ? "" : "/",
733 submethod == NULL ? "" : submethod)) != 0)
734 fatal("%s: append method: %s", __func__, ssh_err(r));
735
736 /* Append key if present */
737 if (authctxt->auth_method_key != NULL) {
738 if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
739 (r = sshkey_format_text(authctxt->auth_method_key,
740 authctxt->session_info)) != 0)
741 fatal("%s: append key: %s", __func__, ssh_err(r));
742 }
743
744 if (authctxt->auth_method_info != NULL) {
745 /* Ensure no ambiguity here */
746 if (strchr(authctxt->auth_method_info, '\n') != NULL)
747 fatal("%s: auth_method_info contains \\n", __func__);
748 if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
749 (r = sshbuf_putf(authctxt->session_info, "%s",
750 authctxt->auth_method_info)) != 0) {
751 fatal("%s: append method info: %s",
752 __func__, ssh_err(r));
753 }
754 }
755 if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
756 fatal("%s: append: %s", __func__, ssh_err(r));
757}
627 758