Bugzilla – Attachment 2178 Details for
Bug 983
Required authentication
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Fixes syntax error in 2177
0001-required-authentication-patch.patch (text/plain), 26.06 KB, created by
Paul Sery
on 2012-08-06 14:47:43 AEST
(
hide
)
Description:
Fixes syntax error in 2177
Filename:
MIME Type:
Creator:
Paul Sery
Created:
2012-08-06 14:47:43 AEST
Size:
26.06 KB
patch
obsolete
>From db70a0604eff31dc3919a42f24ef8efe00e5d1b0 Mon Sep 17 00:00:00 2001 >From: Petr Lautrbach <plautrba@redhat.com> >Date: Wed, 1 Aug 2012 13:40:22 +0200 >Subject: [PATCH] required authentication patch > >--- > auth.c | 62 ++++++++++++++++++++++++++++++++-- > auth.h | 12 +++++-- > auth1.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++--- > auth2-chall.c | 3 +- > auth2-gss.c | 6 ++-- > auth2-none.c | 2 +- > auth2.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++------ > monitor.c | 41 ++++++++++++++++++++--- > servconf.c | 34 +++++++++++++++++++ > servconf.h | 3 ++ > sshd_config.5 | 17 ++++++++++ > 11 files changed, 346 insertions(+), 32 deletions(-) > >diff --git a/auth.c b/auth.c >index a8cffd5..d399af5 100644 >--- a/auth.c >+++ b/auth.c >@@ -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, const char *method, >+ const char *submethod, const char *info) > { > void (*authlog) (const char *fmt,...) = verbose; > char *authmsg; >@@ -271,9 +272,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) > 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 +305,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: >@@ -695,3 +697,57 @@ fakepw(void) > > return (&fake); > } >+ >+int >+auth_method_in_list(const char *list, const char *method) >+{ >+ char *cp; >+ >+ cp = match_list(method, list, NULL); >+ if (cp != NULL) { >+ xfree(cp); >+ return 1; >+ } >+ >+ return 0; >+} >+ >+#define DELIM "," >+int >+auth_remove_from_list(char **list, const char *method) >+{ >+ char *oldlist, *cp, *newlist = NULL; >+ u_int len = 0, ret = 0; >+ >+ if (list == NULL || *list == NULL) >+ return (0); >+ >+ oldlist = *list; >+ len = strlen(oldlist) + 1; >+ newlist = xmalloc(len); >+ memset(newlist, '\0', len); >+ >+ /* Remove method from list, if present */ >+ for (;;) { >+ if ((cp = strsep(&oldlist, DELIM)) == NULL) >+ break; >+ if (*cp == '\0') >+ continue; >+ if (strcmp(cp, method) != 0) { >+ if (*newlist != '\0') >+ strlcat(newlist, DELIM, len); >+ strlcat(newlist, cp, len); >+ } else >+ ret++; >+ } >+ >+ /* Return NULL instead of empty list */ >+ if (*newlist == '\0') { >+ xfree(newlist); >+ newlist = NULL; >+ } >+ xfree(*list); >+ *list = newlist; >+ >+ return (ret); >+} >diff --git a/auth.h b/auth.h >index 0d786c4..466683b 100644 >--- a/auth.h >+++ b/auth.h >@@ -142,10 +142,11 @@ 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, 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); > >@@ -192,6 +193,11 @@ void auth_debug_send(void); > void auth_debug_reset(void); > > struct passwd *fakepw(void); >+int auth_method_in_list(const char *, const char *); >+int auth_remove_from_list(char **, const char *); >+ >+int auth1_check_required(const char *); >+int auth2_check_required(const char *); > > int sys_auth_passwd(Authctxt *, const char *); > >diff --git a/auth1.c b/auth1.c >index cc85aec..08a88f7 100644 >--- a/auth1.c >+++ b/auth1.c >@@ -98,6 +98,54 @@ static const struct AuthMethod1 > return (NULL); > } > >+static const struct AuthMethod1 * >+lookup_authmethod1_by_name(const char *name) >+{ >+ int i; >+ >+ for (i = 0; auth1_methods[i].name != NULL; i++) >+ if (strcmp(auth1_methods[i].name, name) == 0) >+ return (&(auth1_methods[i])); >+ >+ return NULL; >+} >+ >+#define DELIM "," >+int >+auth1_check_required(const char *list) >+{ >+ char *orig_methods, *methods, *cp; >+ static const struct AuthMethod1 *m; >+ int ret = 0; >+ >+ orig_methods = methods = xstrdup(list); >+ for(;;) { /* XXX maybe: while ((cp = ...) != NULL) ? */ >+ if ((cp = strsep(&methods, DELIM)) == NULL) >+ break; >+ debug2("auth1_check_required: method \"%s\"", cp); >+ if (*cp == '\0') { >+ debug("auth1_check_required: empty method"); >+ ret = -1; >+ } >+ if ((m = lookup_authmethod1_by_name(cp)) == NULL) { >+ debug("auth1_check_required: unknown method " >+ "\"%s\"", cp); >+ ret = -1; >+ break; >+ } >+ if (*(m->enabled) == 0) { >+ debug("auth1_check_required: method %s explicitly " >+ "disabled", cp); >+ ret = -1; >+ } >+ /* Activate method if it isn't already */ >+ if (*(m->enabled) == -1) >+ *(m->enabled) = 1; >+ } >+ xfree(orig_methods); >+ return (ret); >+} >+ > static char * > get_authname(int type) > { >@@ -237,6 +285,7 @@ do_authloop(Authctxt *authctxt) > { > int authenticated = 0; > char info[1024]; >+ const char *meth_name; > int prev = 0, type = 0; > const struct AuthMethod1 *meth; > >@@ -244,7 +293,7 @@ do_authloop(Authctxt *authctxt) > authctxt->valid ? "" : "invalid user ", authctxt->user); > > /* If the user has no password, accept authentication immediately. */ >- if (options.permit_empty_passwd && options.password_authentication && >+ if (options.permit_empty_passwd && options.password_authentication && options.password_authentication && > #ifdef KRB5 > (!options.kerberos_authentication || options.kerberos_or_local_passwd) && > #endif >@@ -253,7 +302,7 @@ do_authloop(Authctxt *authctxt) > if (options.use_pam && (PRIVSEP(do_pam_account()))) > #endif > { >- auth_log(authctxt, 1, "without authentication", ""); >+ auth_log(authctxt, 1, "without authentication", NULL, ""); > return; > } > } >@@ -272,6 +321,7 @@ do_authloop(Authctxt *authctxt) > /* Get a packet from the client. */ > prev = type; > type = packet_read(); >+ meth_name = get_authname(type); > > /* > * If we started challenge-response authentication but the >@@ -287,8 +337,8 @@ do_authloop(Authctxt *authctxt) > if (authctxt->failures >= options.max_authtries) > goto skip; > if ((meth = lookup_authmethod1(type)) == NULL) { >- logit("Unknown message during authentication: " >- "type %d", type); >+ logit("Unknown message during authentication: type %d", >+ type); > goto skip; > } > >@@ -297,6 +347,17 @@ do_authloop(Authctxt *authctxt) > goto skip; > } > >+ /* >+ * Skip methods not in required list, until all the required >+ * ones are done >+ */ >+ if (options.required_auth1 != NULL && >+ !auth_method_in_list(options.required_auth1, meth_name)) { >+ debug("Skipping method \"%s\" until required " >+ "authentication completed", meth_name); >+ goto skip; >+ } >+ > authenticated = meth->method(authctxt, info, sizeof(info)); > if (authenticated == -1) > continue; /* "postponed" */ >@@ -352,7 +413,29 @@ do_authloop(Authctxt *authctxt) > > skip: > /* Log before sending the reply */ >- auth_log(authctxt, authenticated, get_authname(type), info); >+ auth_log(authctxt, authenticated, meth_name, NULL, info); >+ >+ /* Loop until the required authmethods are done */ >+ if (authenticated && options.required_auth1 != NULL) { >+ if (auth_remove_from_list(&options.required_auth1, >+ meth_name) == 0) >+ fatal("INTERNAL ERROR: authenticated method " >+ "\"%s\" not in required list \"%s\"", >+ meth_name, options.required_auth1); >+ debug2("do_authloop: required list now: %s", >+ options.required_auth1 == NULL ? >+ "DONE" : options.required_auth1); >+ if (options.required_auth1 == NULL) >+ return; >+ authenticated = 0; >+ /* >+ * Disable method so client can't authenticate with it >+ * after the required authentications are complete. >+ */ >+ *(meth->enabled) = 0; >+ packet_send_debug("Further authentication required"); >+ goto send_fail; >+ } > > if (client_user != NULL) { > xfree(client_user); >@@ -368,6 +451,7 @@ do_authloop(Authctxt *authctxt) > #endif > packet_disconnect(AUTH_FAIL_MSG, authctxt->user); > } >+ send_fail: > > packet_start(SSH_SMSG_FAILURE); > packet_send(); >diff --git a/auth2-chall.c b/auth2-chall.c >index e6dbffe..8a653ae 100644 >--- a/auth2-chall.c >+++ b/auth2-chall.c >@@ -341,7 +341,8 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) > auth2_challenge_start(authctxt); > } > } >- userauth_finish(authctxt, authenticated, method); >+ userauth_finish(authctxt, authenticated, "keyboard-interactive", >+ authctxt->kbdintctxt?kbdintctxt->device->name:NULL); > xfree(method); > } > >diff --git a/auth2-gss.c b/auth2-gss.c >index 0d59b21..338c748 100644 >--- a/auth2-gss.c >+++ b/auth2-gss.c >@@ -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-none.c b/auth2-none.c >index c8c6c74..4113e5a 100644 >--- a/auth2-none.c >+++ b/auth2-none.c >@@ -61,7 +61,7 @@ userauth_none(Authctxt *authctxt) > { > none_enabled = 0; > packet_check_eom(); >- if (options.permit_empty_passwd && options.password_authentication) >+ if (options.permit_empty_passwd && options.password_authentication && options.required_auth2 == NULL) > return (PRIVSEP(auth_password(authctxt, ""))); > return (0); > } >diff --git a/auth2.c b/auth2.c >index b66bef6..5d76349 100644 >--- a/auth2.c >+++ b/auth2.c >@@ -215,7 +215,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) > { > Authctxt *authctxt = ctxt; > Authmethod *m = NULL; >- char *user, *service, *method, *style = NULL; >+ char *user, *service, *method, *active_methods, *style = NULL; > int authenticated = 0; > > if (authctxt == NULL) >@@ -277,12 +277,18 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) > authctxt->server_caused_failure = 0; > > /* try to authenticate user */ >- m = authmethod_lookup(method); >- if (m != NULL && authctxt->failures < options.max_authtries) { >- debug2("input_userauth_request: try method %s", method); >- authenticated = m->userauth(authctxt); >+ active_methods = authmethods_get(); >+ if (strcmp(method, "none") == 0 || >+ auth_method_in_list(active_methods, method)) { >+ m = authmethod_lookup(method); >+ if (m != NULL) { >+ debug2("input_userauth_request: try method %s", method); >+ authenticated = m->userauth(authctxt); >+ } >+ > } >- userauth_finish(authctxt, authenticated, method); >+ xfree(active_methods); >+ userauth_finish(authctxt, authenticated, method, NULL); > > xfree(service); > xfree(user); >@@ -290,9 +296,12 @@ 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; >+ Authmethod *m = NULL; >+ u_int partial = 0; > > if (!authctxt->valid && authenticated) > fatal("INTERNAL ERROR: authenticated invalid user %s", >@@ -330,12 +339,42 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) > #endif /* _UNICOS */ > > /* Log before sending the reply */ >- auth_log(authctxt, authenticated, method, " ssh2"); >+ auth_log(authctxt, authenticated, method, submethod, " ssh2"); > > if (authctxt->postponed) > return; > >- /* XXX todo: check if multiple auth methods are needed */ >+ /* Handle RequiredAuthentications2: loop until required methods done */ >+ if (authenticated && options.required_auth2 != NULL) { >+ if ((m = authmethod_lookup(method)) == NULL) >+ fatal("INTERNAL ERROR: authenticated method " >+ "\"%s\" unknown", method); >+ if (auth_remove_from_list(&options.required_auth2, method) == 0) >+ fatal("INTERNAL ERROR: authenticated method " >+ "\"%s\" not in required list \"%s\"", >+ method, options.required_auth2); >+ debug2("userauth_finish: required list now: %s", >+ options.required_auth2 == NULL ? >+ "DONE" : options.required_auth2); >+ /* >+ * if authenticated and no more required methods >+ * then declare success >+ */ >+ if ( authenticated && options.required_auth2 == NULL ) { >+ debug2("userauth_finish: authenticated and no more required methods"); >+ } else { >+ /* >+ * Disable method so client can't authenticate with it after >+ * the required authentications are complete. >+ */ >+ if (m->enabled != NULL) >+ *(m->enabled) = 0; >+ authenticated = 0; >+ partial = 1; >+ goto send_fail; >+ } >+ } >+ > if (authenticated == 1) { > /* turn off userauth */ > dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); >@@ -345,7 +384,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) > /* now we can break out */ > authctxt->success = 1; > } else { >- > /* Allow initial try of "none" auth without failure penalty */ > if (!authctxt->server_caused_failure && > (authctxt->attempt > 1 || strcmp(method, "none") != 0)) >@@ -356,10 +394,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) > #endif > packet_disconnect(AUTH_FAIL_MSG, authctxt->user); > } >+ send_fail: > methods = authmethods_get(); > 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); >@@ -373,6 +412,9 @@ authmethods_get(void) > char *list; > int i; > >+ if (options.required_auth2 != NULL) >+ return xstrdup(options.required_auth2); >+ > buffer_init(&b); > for (i = 0; authmethods[i] != NULL; i++) { > if (strcmp(authmethods[i]->name, "none") == 0) >@@ -407,3 +449,43 @@ authmethod_lookup(const char *name) > return NULL; > } > >+#define DELIM "," >+ >+int >+auth2_check_required(const char *list) >+{ >+ char *orig_methods, *methods, *cp; >+ struct Authmethod *m; >+ int i, ret = 0; >+ >+ orig_methods = methods = xstrdup(list); >+ for(;;) { >+ if ((cp = strsep(&methods, DELIM)) == NULL) >+ break; >+ debug2("auth2_check_required: method \"%s\"", cp); >+ if (*cp == '\0') { >+ debug("auth2_check_required: empty method"); >+ ret = -1; >+ } >+ for (i = 0; authmethods[i] != NULL; i++) >+ if (strcmp(cp, authmethods[i]->name) == 0) >+ break; >+ if ((m = authmethods[i]) == NULL) { >+ debug("auth2_check_required: unknown method " >+ "\"%s\"", cp); >+ ret = -1; >+ break; >+ } >+ if (m->enabled == NULL || *(m->enabled) == 0) { >+ debug("auth2_check_required: method %s explicitly " >+ "disabled", cp); >+ ret = -1; >+ } >+ /* Activate method if it isn't already */ >+ if (m->enabled != NULL && *(m->enabled) == -1) >+ *(m->enabled) = 1; >+ } >+ xfree(orig_methods); >+ return (ret); >+} >+ >diff --git a/monitor.c b/monitor.c >index e9802a3..799d4ae 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -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; >@@ -353,6 +354,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > { > struct mon_table *ent; > int authenticated = 0; >+ char **req_auth; > > debug3("preauth child monitor started"); > >@@ -367,12 +369,14 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > > if (compat20) { > mon_dispatch = mon_dispatch_proto20; >+ req_auth = &options.required_auth2; > > /* Permit requests for moduli and signatures */ > monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); > monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); > } else { > mon_dispatch = mon_dispatch_proto15; >+ req_auth = &options.required_auth1; > > monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); > } >@@ -380,6 +384,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > /* The first few requests do not require asynchronous access */ > while (!authenticated) { > auth_method = "unknown"; >+ auth_submethod = NULL; > authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); > if (authenticated) { > if (!(ent->flags & MON_AUTHDECIDE)) >@@ -401,10 +406,19 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > } > #endif > } >+ /* Loop until the required authmethods are done */ >+ if (authenticated && *req_auth != NULL) { >+ if (auth_remove_from_list(req_auth, auth_method) == 0) >+ fatal("INTERNAL ERROR: authenticated method " >+ "\"%s\" not in required list \"%s\"", >+ auth_method, *req_auth); >+ debug2("monitor_child_preauth: required list now: %s", >+ *req_auth == NULL ? "DONE" : *req_auth); >+ } > > if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { > auth_log(authctxt, authenticated, auth_method, >- compat20 ? " ssh2" : ""); >+ auth_submethod, compat20 ? " ssh2" : ""); > if (!authenticated) > authctxt->failures++; > } >@@ -417,6 +431,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > } > } > #endif >+ if (*req_auth != NULL) >+ authenticated = 0; > } > > /* Drain any buffered messages from the child */ >@@ -860,6 +876,7 @@ mm_answer_authpassword(int sock, Buffer *m) > auth_method = "none"; > else > auth_method = "password"; >+ auth_submethod = NULL; > > /* Causes monitor loop to terminate if authenticated */ > return (authenticated); >@@ -919,6 +936,7 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) > mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); > > auth_method = "bsdauth"; >+ auth_submethod = NULL; > > return (authok != 0); > } >@@ -968,6 +986,7 @@ mm_answer_skeyrespond(int sock, Buffer *m) > mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); > > auth_method = "skey"; >+ auth_submethod = NULL; > > return (authok != 0); > } >@@ -1057,7 +1076,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); > } >@@ -1086,7 +1106,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); >@@ -1100,7 +1121,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 >@@ -1136,6 +1158,7 @@ mm_answer_keyallowed(int sock, Buffer *m) > allowed = options.pubkey_authentication && > user_key_allowed(authctxt->pw, key); > auth_method = "publickey"; >+ auth_submethod = NULL; > if (options.pubkey_authentication && allowed != 1) > auth_clear_options(); > break; >@@ -1144,6 +1167,7 @@ mm_answer_keyallowed(int sock, Buffer *m) > hostbased_key_allowed(authctxt->pw, > cuser, chost, key); > auth_method = "hostbased"; >+ auth_submethod = NULL; > break; > case MM_RSAHOSTKEY: > key->type = KEY_RSA1; /* XXX */ >@@ -1153,6 +1177,7 @@ mm_answer_keyallowed(int sock, Buffer *m) > if (options.rhosts_rsa_authentication && allowed != 1) > auth_clear_options(); > auth_method = "rsa"; >+ auth_submethod = NULL; > break; > default: > fatal("%s: unknown key type %d", __func__, type); >@@ -1174,7 +1199,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, auth_method, auth_submethod, >+ compat20 ? " ssh2" : ""); > xfree(blob); > xfree(cuser); > xfree(chost); >@@ -1353,6 +1379,7 @@ mm_answer_keyverify(int sock, Buffer *m) > xfree(data); > > auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased"; >+ auth_submethod = NULL; > > monitor_reset_key_state(); > >@@ -1542,6 +1569,7 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m) > debug3("%s entering", __func__); > > auth_method = "rsa"; >+ auth_submethod = NULL; > if (options.rsa_authentication && authctxt->valid) { > if ((client_n = BN_new()) == NULL) > fatal("%s: BN_new", __func__); >@@ -1647,6 +1675,7 @@ mm_answer_rsa_response(int sock, Buffer *m) > xfree(response); > > auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; >+ auth_submethod = NULL; > > /* reset state */ > BN_clear_free(ssh1_challenge); >@@ -2096,6 +2125,7 @@ mm_answer_gss_userok(int sock, Buffer *m) > mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); > > auth_method = "gssapi-with-mic"; >+ auth_submethod = NULL; > > /* Monitor loop will terminate if authenticated */ > return (authenticated); >@@ -2300,6 +2330,7 @@ mm_answer_jpake_check_confirm(int sock, Buffer *m) > monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); > > auth_method = "jpake-01@openssh.com"; >+ auth_submethod = NULL; > return authenticated; > } > >diff --git a/servconf.c b/servconf.c >index ee2e531..ac7528d 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -43,6 +43,8 @@ > #include "key.h" > #include "kex.h" > #include "mac.h" >+#include "hostfile.h" >+#include "auth.h" > #include "match.h" > #include "channels.h" > #include "groupaccess.h" >@@ -132,6 +134,8 @@ initialize_server_options(ServerOptions *options) > options->num_authkeys_files = 0; > options->num_accept_env = 0; > options->permit_tun = -1; >+ options->required_auth1 = NULL; >+ options->required_auth2 = NULL; > options->num_permitted_opens = -1; > options->adm_forced_command = NULL; > options->chroot_directory = NULL; >@@ -324,6 +328,7 @@ typedef enum { > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, >+ sRequiredAuthentications1, sRequiredAuthentications2, > sMatch, sPermitOpen, sForceCommand, sChrootDirectory, > sUsePrivilegeSeparation, sAllowAgentForwarding, > sZeroKnowledgePasswordAuthentication, sHostCertificate, >@@ -452,6 +457,8 @@ static struct { > { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, > { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, > { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, >+ { "requiredauthentications1", sRequiredAuthentications1, SSHCFG_ALL }, >+ { "requiredauthentications2", sRequiredAuthentications2, SSHCFG_ALL }, > { "ipqos", sIPQoS, SSHCFG_ALL }, > { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, > { NULL, sBadOption, 0 } >@@ -1298,6 +1305,33 @@ process_server_config_line(ServerOptions *options, char *line, > options->max_startups = options->max_startups_begin; > break; > >+ >+ case sRequiredAuthentications1: >+ charptr = &options->required_auth1; >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%.200s line %d: Missing argument.", >+ filename, linenum); >+ if (auth1_check_required(arg) != 0) >+ fatal("%.200s line %d: Invalid required authentication " >+ "list", filename, linenum); >+ if (*charptr == NULL) >+ *charptr = xstrdup(arg); >+ break; >+ >+ case sRequiredAuthentications2: >+ charptr = &options->required_auth2; >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%.200s line %d: Missing argument.", >+ filename, linenum); >+ if (auth2_check_required(arg) != 0) >+ fatal("%.200s line %d: Invalid required authentication " >+ "list", filename, linenum); >+ if (*charptr == NULL) >+ *charptr = xstrdup(arg); >+ break; >+ > case sMaxAuthTries: > intptr = &options->max_authtries; > goto parse_int; >diff --git a/servconf.h b/servconf.h >index 096d596..c609152 100644 >--- a/servconf.h >+++ b/servconf.h >@@ -154,6 +154,9 @@ typedef struct { > u_int num_authkeys_files; /* Files containing public keys */ > char *authorized_keys_files[MAX_AUTHKEYS_FILES]; > >+ char *required_auth1; /* Required, but not sufficient */ >+ char *required_auth2; >+ > char *adm_forced_command; > > int use_pam; /* Enable auth via PAM */ >diff --git a/sshd_config.5 b/sshd_config.5 >index 314ecfb..32043bb 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -731,6 +731,8 @@ Available keywords are > .Cm PermitOpen , > .Cm PermitRootLogin , > .Cm PermitTunnel , >+.Cm RequiredAuthentications1, >+.Cm RequiredAuthentications2, > .Cm PubkeyAuthentication , > .Cm RhostsRSAAuthentication , > .Cm RSAAuthentication , >@@ -931,6 +933,21 @@ Specifies a list of revoked public keys. > Keys listed in this file will be refused for public key authentication. > Note that if this file is not readable, then public key authentication will > be refused for all users. >+.It Cm RequiredAuthentications[12] >+ Specifies required methods of authentications that has to succeed before authorizing the connection. >+ (RequiredAuthentication1 for Protocol version 1, and RequiredAuthentication2 for v2) >+ >+ RequiredAuthentications1 method[,method...] >+ RequiredAuthentications2 method[,method...] >+ >+.Pp >+Example 1: >+ >+ RequiredAuthentications2 password,hostbased >+ >+Example 2: >+ RequiredAuthentications2 publickey,password >+ > .It Cm RhostsRSAAuthentication > Specifies whether rhosts or /etc/hosts.equiv authentication together > with successful RSA host authentication is allowed. >-- >1.7.10.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 983
:
807
|
941
|
1121
|
1122
|
1123
|
1455
|
1518
|
1521
|
1567
|
1667
|
1768
|
1955
|
1999
|
2079
|
2084
|
2096
|
2138
|
2177
| 2178 |
2192
|
2196