From a6e3f01d1e230b8acfdd6b4cf3096459d2a325e0 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 4 Nov 2012 23:21:40 +1100 Subject: - djm@cvs.openbsd.org 2012/11/04 11:09:15 [auth.h auth1.c auth2.c monitor.c servconf.c servconf.h sshd.c] [sshd_config.5] Support multiple required authentication via an AuthenticationMethods option. This option lists one or more comma-separated lists of authentication method names. Successful completion of all the methods in any list is required for authentication to complete; feedback and ok markus@ --- auth2.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 200 insertions(+), 18 deletions(-) (limited to 'auth2.c') diff --git a/auth2.c b/auth2.c index b66bef64c..8114ec863 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.125 2012/11/04 11:09:15 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -96,8 +96,10 @@ static void input_service_request(int, u_int32_t, void *); static void input_userauth_request(int, u_int32_t, void *); /* helper */ -static Authmethod *authmethod_lookup(const char *); -static char *authmethods_get(void); +static Authmethod *authmethod_lookup(Authctxt *, const char *); +static char *authmethods_get(Authctxt *authctxt); +static int method_allowed(Authctxt *, const char *); +static int list_starts_with(const char *, const char *); char * auth2_read_banner(void) @@ -255,6 +257,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) if (use_privsep) mm_inform_authserv(service, style); userauth_banner(); + if (auth2_setup_methods_lists(authctxt) != 0) + packet_disconnect("no authentication methods enabled"); } else if (strcmp(user, authctxt->user) != 0 || strcmp(service, authctxt->service) != 0) { packet_disconnect("Change of username or service not allowed: " @@ -277,7 +281,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->server_caused_failure = 0; /* try to authenticate user */ - m = authmethod_lookup(method); + m = authmethod_lookup(authctxt, method); if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); @@ -293,6 +297,7 @@ void userauth_finish(Authctxt *authctxt, int authenticated, char *method) { char *methods; + int partial = 0; if (!authctxt->valid && authenticated) fatal("INTERNAL ERROR: authenticated invalid user %s", @@ -335,7 +340,13 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) if (authctxt->postponed) return; - /* XXX todo: check if multiple auth methods are needed */ + if (authenticated && options.num_auth_methods != 0) { + if (!auth2_update_methods_lists(authctxt, method)) { + authenticated = 0; + partial = 1; + } + } + if (authenticated == 1) { /* turn off userauth */ dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); @@ -356,34 +367,61 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) #endif packet_disconnect(AUTH_FAIL_MSG, authctxt->user); } - methods = authmethods_get(); + methods = authmethods_get(authctxt); + debug3("%s: failure partial=%d next methods=\"%s\"", __func__, + partial, methods); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); - packet_put_char(0); /* XXX partial success, unused */ + packet_put_char(partial); packet_send(); packet_write_wait(); xfree(methods); } } +/* + * Checks whether method is allowed by at least one AuthenticationMethods + * methods list. Returns 1 if allowed, or no methods lists configured. + * 0 otherwise. + */ +static int +method_allowed(Authctxt *authctxt, const char *method) +{ + u_int i; + + /* + * NB. authctxt->num_auth_methods might be zero as a result of + * auth2_setup_methods_lists(), so check the configuration. + */ + if (options.num_auth_methods == 0) + return 1; + for (i = 0; i < authctxt->num_auth_methods; i++) { + if (list_starts_with(authctxt->auth_methods[i], method)) + return 1; + } + return 0; +} + static char * -authmethods_get(void) +authmethods_get(Authctxt *authctxt) { Buffer b; char *list; - int i; + u_int i; buffer_init(&b); for (i = 0; authmethods[i] != NULL; i++) { if (strcmp(authmethods[i]->name, "none") == 0) continue; - if (authmethods[i]->enabled != NULL && - *(authmethods[i]->enabled) != 0) { - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - buffer_append(&b, authmethods[i]->name, - strlen(authmethods[i]->name)); - } + if (authmethods[i]->enabled == NULL || + *(authmethods[i]->enabled) == 0) + continue; + if (!method_allowed(authctxt, authmethods[i]->name)) + continue; + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + buffer_append(&b, authmethods[i]->name, + strlen(authmethods[i]->name)); } buffer_append(&b, "\0", 1); list = xstrdup(buffer_ptr(&b)); @@ -392,7 +430,7 @@ authmethods_get(void) } static Authmethod * -authmethod_lookup(const char *name) +authmethod_lookup(Authctxt *authctxt, const char *name) { int i; @@ -400,10 +438,154 @@ authmethod_lookup(const char *name) for (i = 0; authmethods[i] != NULL; i++) if (authmethods[i]->enabled != NULL && *(authmethods[i]->enabled) != 0 && - strcmp(name, authmethods[i]->name) == 0) + strcmp(name, authmethods[i]->name) == 0 && + method_allowed(authctxt, authmethods[i]->name)) return authmethods[i]; debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); return NULL; } +/* + * Check a comma-separated list of methods for validity. Is need_enable is + * non-zero, then also require that the methods are enabled. + * Returns 0 on success or -1 if the methods list is invalid. + */ +int +auth2_methods_valid(const char *_methods, int need_enable) +{ + char *methods, *omethods, *method; + u_int i, found; + int ret = -1; + + if (*_methods == '\0') { + error("empty authentication method list"); + return -1; + } + omethods = methods = xstrdup(_methods); + while ((method = strsep(&methods, ",")) != NULL) { + for (found = i = 0; !found && authmethods[i] != NULL; i++) { + if (strcmp(method, authmethods[i]->name) != 0) + continue; + if (need_enable) { + if (authmethods[i]->enabled == NULL || + *(authmethods[i]->enabled) == 0) { + error("Disabled method \"%s\" in " + "AuthenticationMethods list \"%s\"", + method, _methods); + goto out; + } + } + found = 1; + break; + } + if (!found) { + error("Unknown authentication method \"%s\" in list", + method); + goto out; + } + } + ret = 0; + out: + free(omethods); + return ret; +} + +/* + * Prune the AuthenticationMethods supplied in the configuration, removing + * any methods lists that include disabled methods. Note that this might + * leave authctxt->num_auth_methods == 0, even when multiple required auth + * has been requested. For this reason, all tests for whether multiple is + * enabled should consult options.num_auth_methods directly. + */ +int +auth2_setup_methods_lists(Authctxt *authctxt) +{ + u_int i; + + if (options.num_auth_methods == 0) + return 0; + debug3("%s: checking methods", __func__); + authctxt->auth_methods = xcalloc(options.num_auth_methods, + sizeof(*authctxt->auth_methods)); + authctxt->num_auth_methods = 0; + for (i = 0; i < options.num_auth_methods; i++) { + if (auth2_methods_valid(options.auth_methods[i], 1) != 0) { + logit("Authentication methods list \"%s\" contains " + "disabled method, skipping", + options.auth_methods[i]); + continue; + } + debug("authentication methods list %d: %s", + authctxt->num_auth_methods, options.auth_methods[i]); + authctxt->auth_methods[authctxt->num_auth_methods++] = + xstrdup(options.auth_methods[i]); + } + if (authctxt->num_auth_methods == 0) { + error("No AuthenticationMethods left after eliminating " + "disabled methods"); + return -1; + } + return 0; +} + +static int +list_starts_with(const char *methods, const char *method) +{ + size_t l = strlen(method); + + if (strncmp(methods, method, l) != 0) + return 0; + if (methods[l] != ',' && methods[l] != '\0') + return 0; + return 1; +} + +/* + * Remove method from the start of a comma-separated list of methods. + * Returns 0 if the list of methods did not start with that method or 1 + * if it did. + */ +static int +remove_method(char **methods, const char *method) +{ + char *omethods = *methods; + size_t l = strlen(method); + + if (!list_starts_with(omethods, method)) + return 0; + *methods = xstrdup(omethods + l + (omethods[l] == ',' ? 1 : 0)); + free(omethods); + return 1; +} + +/* + * Called after successful authentication. Will remove the successful method + * from the start of each list in which it occurs. If it was the last method + * in any list, then authentication is deemed successful. + * Returns 1 if the method completed any authentication list or 0 otherwise. + */ +int +auth2_update_methods_lists(Authctxt *authctxt, const char *method) +{ + u_int i, found = 0; + + debug3("%s: updating methods list after \"%s\"", __func__, method); + for (i = 0; i < authctxt->num_auth_methods; i++) { + if (!remove_method(&(authctxt->auth_methods[i]), method)) + continue; + found = 1; + if (*authctxt->auth_methods[i] == '\0') { + debug2("authentication methods list %d complete", i); + return 1; + } + debug3("authentication methods list %d remaining: \"%s\"", + i, authctxt->auth_methods[i]); + } + /* This should not happen, but would be bad if it did */ + if (!found) + fatal("%s: method not in AuthenticationMethods", __func__); + return 0; +} + + -- cgit v1.2.3 From 15b05cfa17592da7470d7bd4b2de063188697471 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 3 Dec 2012 09:53:20 +1100 Subject: - djm@cvs.openbsd.org 2012/12/02 20:34:10 [auth.c auth.h auth1.c auth2-chall.c auth2-gss.c auth2-jpake.c auth2.c] [monitor.c monitor.h] Fixes logging of partial authentication when privsep is enabled Previously, we recorded "Failed xxx" since we reset authenticated before calling auth_log() in auth2.c. This adds an explcit "Partial" state. Add a "submethod" to auth_log() to report which submethod is used for keyboard-interactive. Fix multiple authentication when one of the methods is keyboard-interactive. ok markus@ --- ChangeLog | 14 +++++++++++ auth.c | 12 ++++++--- auth.h | 10 +++++--- auth1.c | 8 +++--- auth2-chall.c | 12 ++++----- auth2-gss.c | 8 +++--- auth2-jpake.c | 4 +-- auth2.c | 37 ++++++++++++++------------- monitor.c | 25 +++++++++++++------ monitor.h | 80 +++++++++++++++++++++++++++++++---------------------------- 10 files changed, 123 insertions(+), 87 deletions(-) (limited to 'auth2.c') diff --git a/ChangeLog b/ChangeLog index cee038727..9ed715925 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,20 @@ - djm@cvs.openbsd.org 2012/11/14 02:32:15 [ssh-keygen.c] allow the full range of unsigned serial numbers; 'fine' deraadt@ + - djm@cvs.openbsd.org 2012/12/02 20:34:10 + [auth.c auth.h auth1.c auth2-chall.c auth2-gss.c auth2-jpake.c auth2.c] + [monitor.c monitor.h] + Fixes logging of partial authentication when privsep is enabled + Previously, we recorded "Failed xxx" since we reset authenticated before + calling auth_log() in auth2.c. This adds an explcit "Partial" state. + + Add a "submethod" to auth_log() to report which submethod is used + for keyboard-interactive. + + Fix multiple authentication when one of the methods is + keyboard-interactive. + + ok markus@ 20121107 - (djm) OpenBSD CVS Sync diff --git a/auth.c b/auth.c index b5e1eefa0..7bc6f4021 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.97 2012/10/30 21:29:54 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.98 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -251,7 +251,8 @@ allowed_user(struct passwd * pw) } void -auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) +auth_log(Authctxt *authctxt, int authenticated, int partial, + const char *method, const char *submethod, const char *info) { void (*authlog) (const char *fmt,...) = verbose; char *authmsg; @@ -268,12 +269,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) if (authctxt->postponed) authmsg = "Postponed"; + else if (partial) + authmsg = "Partial"; else authmsg = authenticated ? "Accepted" : "Failed"; - authlog("%s %s for %s%.100s from %.200s port %d%s", + authlog("%s %s%s%s for %s%.100s from %.200s port %d%s", authmsg, method, + submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", authctxt->user, get_remote_ipaddr(), @@ -303,7 +307,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) * Check whether root logins are disallowed. */ int -auth_root_allowed(char *method) +auth_root_allowed(const char *method) { switch (options.permit_root_login) { case PERMIT_YES: diff --git a/auth.h b/auth.h index 8920c7dae..c6fe84722 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.71 2012/11/04 11:09:15 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.72 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -148,10 +148,12 @@ void disable_forwarding(void); void do_authentication(Authctxt *); void do_authentication2(Authctxt *); -void auth_log(Authctxt *, int, char *, char *); -void userauth_finish(Authctxt *, int, char *); +void auth_log(Authctxt *, int, int, const char *, const char *, + const char *); +void userauth_finish(Authctxt *, int, const char *, const char *); +int auth_root_allowed(const char *); + void userauth_send_banner(const char *); -int auth_root_allowed(char *); char *auth2_read_banner(void); int auth2_methods_valid(const char *, int); diff --git a/auth1.c b/auth1.c index fb37fadfe..6eea8d81e 100644 --- a/auth1.c +++ b/auth1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth1.c,v 1.76 2012/11/04 11:09:15 djm Exp $ */ +/* $OpenBSD: auth1.c,v 1.77 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -253,7 +253,8 @@ do_authloop(Authctxt *authctxt) if (options.use_pam && (PRIVSEP(do_pam_account()))) #endif { - auth_log(authctxt, 1, "without authentication", ""); + auth_log(authctxt, 1, 0, "without authentication", + NULL, ""); return; } } @@ -352,7 +353,8 @@ do_authloop(Authctxt *authctxt) skip: /* Log before sending the reply */ - auth_log(authctxt, authenticated, get_authname(type), info); + auth_log(authctxt, authenticated, 0, get_authname(type), + NULL, info); if (client_user != NULL) { xfree(client_user); diff --git a/auth2-chall.c b/auth2-chall.c index e6dbffe22..8fdb33498 100644 --- a/auth2-chall.c +++ b/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.35 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -283,7 +283,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) KbdintAuthctxt *kbdintctxt; int authenticated = 0, res; u_int i, nresp; - char **response = NULL, *method; + char *devicename = NULL, **response = NULL; if (authctxt == NULL) fatal("input_userauth_info_response: no authctxt"); @@ -329,9 +329,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) /* Failure! */ break; } - - xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name); - + devicename = kbdintctxt->device->name; if (!authctxt->postponed) { if (authenticated) { auth2_challenge_stop(authctxt); @@ -341,8 +339,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) auth2_challenge_start(authctxt); } } - userauth_finish(authctxt, authenticated, method); - xfree(method); + userauth_finish(authctxt, authenticated, "keyboard-interactive", + devicename); } void diff --git a/auth2-gss.c b/auth2-gss.c index 0d59b2177..93d576bfb 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.18 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -163,7 +163,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt) } authctxt->postponed = 0; dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - userauth_finish(authctxt, 0, "gssapi-with-mic"); + userauth_finish(authctxt, 0, "gssapi-with-mic", NULL); } else { if (send_tok.length != 0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); @@ -251,7 +251,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); - userauth_finish(authctxt, authenticated, "gssapi-with-mic"); + userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); } static void @@ -291,7 +291,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); - userauth_finish(authctxt, authenticated, "gssapi-with-mic"); + userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); } Authmethod method_gssapi = { diff --git a/auth2-jpake.c b/auth2-jpake.c index a460e8216..ed0eba47b 100644 --- a/auth2-jpake.c +++ b/auth2-jpake.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */ +/* $OpenBSD: auth2-jpake.c,v 1.5 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. * @@ -556,7 +556,7 @@ input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt) authctxt->postponed = 0; jpake_free(authctxt->jpake_ctx); authctxt->jpake_ctx = NULL; - userauth_finish(authctxt, authenticated, method_jpake.name); + userauth_finish(authctxt, authenticated, method_jpake.name, NULL); } #endif /* JPAKE */ diff --git a/auth2.c b/auth2.c index 8114ec863..e367a1045 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.125 2012/11/04 11:09:15 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.126 2012/12/02 20:34:09 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -286,7 +286,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); } - userauth_finish(authctxt, authenticated, method); + userauth_finish(authctxt, authenticated, method, NULL); xfree(service); xfree(user); @@ -294,7 +294,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } void -userauth_finish(Authctxt *authctxt, int authenticated, char *method) +userauth_finish(Authctxt *authctxt, int authenticated, const char *method, + const char *submethod) { char *methods; int partial = 0; @@ -302,6 +303,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) if (!authctxt->valid && authenticated) fatal("INTERNAL ERROR: authenticated invalid user %s", authctxt->user); + if (authenticated && authctxt->postponed) + fatal("INTERNAL ERROR: authenticated and postponed"); /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && @@ -312,6 +315,19 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) #endif } + if (authenticated && options.num_auth_methods != 0) { + if (!auth2_update_methods_lists(authctxt, method)) { + authenticated = 0; + partial = 1; + } + } + + /* Log before sending the reply */ + auth_log(authctxt, authenticated, partial, method, submethod, " ssh2"); + + if (authctxt->postponed) + return; + #ifdef USE_PAM if (options.use_pam && authenticated) { if (!PRIVSEP(do_pam_account())) { @@ -330,23 +346,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; - fatal("Access denied for user %s.",authctxt->user); + fatal("Access denied for user %s.", authctxt->user); } #endif /* _UNICOS */ - /* Log before sending the reply */ - auth_log(authctxt, authenticated, method, " ssh2"); - - if (authctxt->postponed) - return; - - if (authenticated && options.num_auth_methods != 0) { - if (!auth2_update_methods_lists(authctxt, method)) { - authenticated = 0; - partial = 1; - } - } - if (authenticated == 1) { /* turn off userauth */ dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); diff --git a/monitor.c b/monitor.c index 0adbf3a65..1cfc48757 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.118 2012/11/04 11:09:15 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.119 2012/12/02 20:34:10 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -199,6 +199,7 @@ static int key_blobtype = MM_NOKEY; static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; +static char *auth_submethod = NULL; static u_int session_id2_len = 0; static u_char *session_id2 = NULL; static pid_t monitor_child_pid; @@ -352,7 +353,7 @@ void monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) { struct mon_table *ent; - int authenticated = 0; + int authenticated = 0, partial = 0; debug3("preauth child monitor started"); @@ -379,7 +380,9 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) /* The first few requests do not require asynchronous access */ while (!authenticated) { + partial = 0; auth_method = "unknown"; + auth_submethod = NULL; authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); /* Special handling for multiple required authentications */ @@ -393,6 +396,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) debug3("%s: method %s: partial", __func__, auth_method); authenticated = 0; + partial = 1; } } @@ -417,7 +421,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) #endif } if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { - auth_log(authctxt, authenticated, auth_method, + auth_log(authctxt, authenticated, partial, + auth_method, auth_submethod, compat20 ? " ssh2" : ""); if (!authenticated) authctxt->failures++; @@ -943,7 +948,7 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); if (compat20) - auth_method = "keyboard-interactive"; + auth_method = "keyboard-interactive"; /* XXX auth_submethod */ else auth_method = "bsdauth"; @@ -1084,7 +1089,8 @@ mm_answer_pam_query(int sock, Buffer *m) xfree(prompts); if (echo_on != NULL) xfree(echo_on); - auth_method = "keyboard-interactive/pam"; + auth_method = "keyboard-interactive"; + auth_submethod = "pam"; mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); return (0); } @@ -1113,7 +1119,8 @@ mm_answer_pam_respond(int sock, Buffer *m) buffer_clear(m); buffer_put_int(m, ret); mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); - auth_method = "keyboard-interactive/pam"; + auth_method = "keyboard-interactive"; + auth_submethod = "pam"; if (ret == 0) sshpam_authok = sshpam_ctxt; return (0); @@ -1127,7 +1134,8 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) (sshpam_device.free_ctx)(sshpam_ctxt); buffer_clear(m); mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); - auth_method = "keyboard-interactive/pam"; + auth_method = "keyboard-interactive"; + auth_submethod = "pam"; return (sshpam_authok == sshpam_ctxt); } #endif @@ -1201,7 +1209,8 @@ mm_answer_keyallowed(int sock, Buffer *m) hostbased_chost = chost; } else { /* Log failed attempt */ - auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : ""); + auth_log(authctxt, 0, 0, auth_method, NULL, + compat20 ? " ssh2" : ""); xfree(blob); xfree(cuser); xfree(chost); diff --git a/monitor.h b/monitor.h index 5e7d552fb..2caa46933 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.16 2011/06/17 21:44:31 djm Exp $ */ +/* $OpenBSD: monitor.h,v 1.17 2012/12/02 20:34:10 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -28,44 +28,48 @@ #ifndef _MONITOR_H_ #define _MONITOR_H_ +/* Please keep *_REQ_* values on even numbers and *_ANS_* on odd numbers */ enum monitor_reqtype { - MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, - MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, - MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, - MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, - MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, - MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD, - MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY, - MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND, - MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY, - MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND, - MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED, - MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY, - MONITOR_REQ_KEYEXPORT, - MONITOR_REQ_PTY, MONITOR_ANS_PTY, - MONITOR_REQ_PTYCLEANUP, - MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY, - MONITOR_REQ_SESSID, - MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, - MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, - MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, - MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, - MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, - MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, - MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC, - MONITOR_REQ_PAM_START, - MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, - MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, - MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, - MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, - MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, - MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND, - MONITOR_REQ_TERM, - MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, - MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, - MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2, - MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM, - MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM, + MONITOR_REQ_MODULI = 0, MONITOR_ANS_MODULI = 1, + MONITOR_REQ_FREE = 2, + MONITOR_REQ_AUTHSERV = 4, + MONITOR_REQ_SIGN = 6, MONITOR_ANS_SIGN = 7, + MONITOR_REQ_PWNAM = 8, MONITOR_ANS_PWNAM = 9, + MONITOR_REQ_AUTH2_READ_BANNER = 10, MONITOR_ANS_AUTH2_READ_BANNER = 11, + MONITOR_REQ_AUTHPASSWORD = 12, MONITOR_ANS_AUTHPASSWORD = 13, + MONITOR_REQ_BSDAUTHQUERY = 14, MONITOR_ANS_BSDAUTHQUERY = 15, + MONITOR_REQ_BSDAUTHRESPOND = 16, MONITOR_ANS_BSDAUTHRESPOND = 17, + MONITOR_REQ_SKEYQUERY = 18, MONITOR_ANS_SKEYQUERY = 19, + MONITOR_REQ_SKEYRESPOND = 20, MONITOR_ANS_SKEYRESPOND = 21, + MONITOR_REQ_KEYALLOWED = 22, MONITOR_ANS_KEYALLOWED = 23, + MONITOR_REQ_KEYVERIFY = 24, MONITOR_ANS_KEYVERIFY = 25, + MONITOR_REQ_KEYEXPORT = 26, + MONITOR_REQ_PTY = 28, MONITOR_ANS_PTY = 29, + MONITOR_REQ_PTYCLEANUP = 30, + MONITOR_REQ_SESSKEY = 32, MONITOR_ANS_SESSKEY = 33, + MONITOR_REQ_SESSID = 34, + MONITOR_REQ_RSAKEYALLOWED = 36, MONITOR_ANS_RSAKEYALLOWED = 37, + MONITOR_REQ_RSACHALLENGE = 38, MONITOR_ANS_RSACHALLENGE = 39, + MONITOR_REQ_RSARESPONSE = 40, MONITOR_ANS_RSARESPONSE = 41, + MONITOR_REQ_GSSSETUP = 42, MONITOR_ANS_GSSSETUP = 43, + MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45, + MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, + MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, + MONITOR_REQ_TERM = 50, + MONITOR_REQ_JPAKE_STEP1 = 52, MONITOR_ANS_JPAKE_STEP1 = 53, + MONITOR_REQ_JPAKE_GET_PWDATA = 54, MONITOR_ANS_JPAKE_GET_PWDATA = 55, + MONITOR_REQ_JPAKE_STEP2 = 56, MONITOR_ANS_JPAKE_STEP2 = 57, + MONITOR_REQ_JPAKE_KEY_CONFIRM = 58, MONITOR_ANS_JPAKE_KEY_CONFIRM = 59, + MONITOR_REQ_JPAKE_CHECK_CONFIRM = 60, MONITOR_ANS_JPAKE_CHECK_CONFIRM = 61, + + MONITOR_REQ_PAM_START = 100, + MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, + MONITOR_REQ_PAM_INIT_CTX = 104, MONITOR_ANS_PAM_INIT_CTX = 105, + MONITOR_REQ_PAM_QUERY = 106, MONITOR_ANS_PAM_QUERY = 107, + MONITOR_REQ_PAM_RESPOND = 108, MONITOR_ANS_PAM_RESPOND = 109, + MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, + MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, + }; struct mm_master; -- cgit v1.2.3