diff --git a/openssh-6.1p1-required-authentications.patch b/openssh-6.1p1-required-authentications.patch index 6901708..bfc28ee 100644 --- a/openssh-6.1p1-required-authentications.patch +++ b/openssh-6.1p1-required-authentications.patch @@ -1,860 +1,22 @@ -diff -up openssh-6.1p1/auth.c.required-authentication openssh-6.1p1/auth.c ---- openssh-6.1p1/auth.c.required-authentication 2012-09-14 20:17:56.730488188 +0200 -+++ openssh-6.1p1/auth.c 2012-09-14 20:17:56.795488498 +0200 -@@ -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 authent - 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 authent - * 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: -@@ -696,3 +698,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 -up openssh-6.1p1/auth.h.required-authentication openssh-6.1p1/auth.h ---- openssh-6.1p1/auth.h.required-authentication 2011-05-29 13:39:38.000000000 +0200 -+++ openssh-6.1p1/auth.h 2012-09-14 20:17:56.796488502 +0200 -@@ -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 -up openssh-6.1p1/auth1.c.required-authentication openssh-6.1p1/auth1.c ---- openssh-6.1p1/auth1.c.required-authentication 2010-08-31 14:36:39.000000000 +0200 -+++ openssh-6.1p1/auth1.c 2012-09-14 20:17:56.798488515 +0200 -@@ -98,6 +98,55 @@ 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 +286,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 +294,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 +303,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 +322,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 +338,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 +348,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 +414,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 +452,7 @@ do_authloop(Authctxt *authctxt) - #endif - packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } -+ send_fail: - - packet_start(SSH_SMSG_FAILURE); - packet_send(); -diff -up openssh-6.1p1/auth2.c.required-authentication openssh-6.1p1/auth2.c ---- openssh-6.1p1/auth2.c.required-authentication 2011-12-19 00:52:51.000000000 +0100 -+++ openssh-6.1p1/auth2.c 2012-09-14 20:17:56.799488520 +0200 -@@ -215,7 +215,7 @@ input_userauth_request(int type, u_int32 - { - 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,22 +277,31 @@ input_userauth_request(int type, u_int32 - 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); -- } -- userauth_finish(authctxt, authenticated, method); -+ 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); -+ } - -+ } -+ xfree(active_methods); -+ userauth_finish(authctxt, authenticated, method, NULL); -+ - xfree(service); - xfree(user); - xfree(method); - } - - 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 - #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 - /* 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 - #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 -up openssh-6.1p1/auth2-gss.c.required-authentication openssh-6.1p1/auth2-gss.c ---- openssh-6.1p1/auth2-gss.c.required-authentication 2011-05-05 06:04:11.000000000 +0200 -+++ openssh-6.1p1/auth2-gss.c 2012-09-14 20:17:56.801488528 +0200 -@@ -163,7 +163,7 @@ input_gssapi_token(int type, u_int32_t p - } - 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, - 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 ple - 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 -up openssh-6.1p1/auth2-chall.c.required-authentication openssh-6.1p1/auth2-chall.c ---- openssh-6.1p1/auth2-chall.c.required-authentication 2009-01-28 06:13:39.000000000 +0100 -+++ openssh-6.1p1/auth2-chall.c 2012-09-14 20:17:56.802488532 +0200 -@@ -341,7 +341,8 @@ input_userauth_info_response(int type, u - auth2_challenge_start(authctxt); - } - } -- userauth_finish(authctxt, authenticated, method); -+ userauth_finish(authctxt, authenticated, "keyboard-interactive", -+ authctxt->kbdintctxt?kbdintctxt->device->name:NULL); - xfree(method); - } - -diff -up openssh-6.1p1/auth2-none.c.required-authentication openssh-6.1p1/auth2-none.c ---- openssh-6.1p1/auth2-none.c.required-authentication 2010-06-26 02:01:33.000000000 +0200 -+++ openssh-6.1p1/auth2-none.c 2012-09-14 20:17:56.803488537 +0200 -@@ -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 -up openssh-6.1p1/monitor.c.required-authentication openssh-6.1p1/monitor.c ---- openssh-6.1p1/monitor.c.required-authentication 2012-09-14 20:17:56.685487974 +0200 -+++ openssh-6.1p1/monitor.c 2012-09-14 20:17:56.806488552 +0200 -@@ -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 *_authctx - { - struct mon_table *ent; - int authenticated = 0; -+ char **req_auth; - - debug3("preauth child monitor started"); - -@@ -367,12 +369,14 @@ monitor_child_preauth(Authctxt *_authctx - - 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 *_authctx - /* 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 *_authctx - } - #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 *_authctx - } - } - #endif -+ if (*req_auth != NULL) -+ authenticated = 0; - } - - /* Drain any buffered messages from the child */ -@@ -860,6 +876,7 @@ mm_answer_authpassword(int sock, Buffer - 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, Buffe - 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 * - 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 * - 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 - (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); -@@ -1178,7 +1203,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); -@@ -1354,6 +1380,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(); - -@@ -1543,6 +1570,7 @@ mm_answer_rsa_keyallowed(int sock, Buffe - 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__); -@@ -1648,6 +1676,7 @@ mm_answer_rsa_response(int sock, Buffer - xfree(response); - - auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; -+ auth_submethod = NULL; - - /* reset state */ - BN_clear_free(ssh1_challenge); -@@ -2097,6 +2126,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); -@@ -2301,6 +2331,7 @@ mm_answer_jpake_check_confirm(int sock, - monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); - - auth_method = "jpake-01@openssh.com"; -+ auth_submethod = NULL; - return authenticated; - } - diff -up openssh-6.1p1/servconf.c.required-authentication openssh-6.1p1/servconf.c ---- openssh-6.1p1/servconf.c.required-authentication 2012-09-14 20:17:56.699488040 +0200 -+++ openssh-6.1p1/servconf.c 2012-09-14 20:19:49.179983651 +0200 -@@ -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->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 }, +--- openssh-6.1p1/servconf.c.required-authentication 2012-11-30 21:13:14.375382453 +0100 ++++ openssh-6.1p1/servconf.c 2012-11-30 21:33:56.972017545 +0100 +@@ -495,6 +495,8 @@ static struct { + { "authorizedkeyscommandrunas", sAuthorizedKeysCommandUser, SSHCFG_ALL }, + { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, + { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, ++ { "requiredauthentications1", sAuthenticationMethods, SSHCFG_ALL }, ++ { "requiredauthentications2", sAuthenticationMethods, SSHCFG_ALL }, { NULL, sBadOption, 0 } -@@ -1298,6 +1305,37 @@ process_server_config_line(ServerOptions - options->max_startups = options->max_startups_begin; - break; + }; -+ -+ case sRequiredAuthentications1: -+ if (*activep && options->required_auth1 == NULL) { -+ 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); -+ } -+ return 0; -+ -+ case sRequiredAuthentications2: -+ if (*activep && options->required_auth2 == NULL) { -+ 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); -+ } -+ return 0; -+ - case sMaxAuthTries: - intptr = &options->max_authtries; - goto parse_int; -@@ -1925,6 +1963,7 @@ dump_config(ServerOptions *o) - dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); - dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); - dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); -+ dump_cfg_string(sRequiredAuthentications2, o->required_auth2); +@@ -1560,6 +1562,9 @@ process_server_config_line(ServerOptions + return 0; - /* other arguments */ - for (i = 0; i < o->num_subsystems; i++) -diff -up openssh-6.1p1/servconf.h.required-authentication openssh-6.1p1/servconf.h ---- openssh-6.1p1/servconf.h.required-authentication 2012-07-31 04:21:34.000000000 +0200 -+++ openssh-6.1p1/servconf.h 2012-11-08 13:37:33.135918526 +0100 -@@ -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; -+ char *required_auth2; -+ - char *adm_forced_command; - - int use_pam; /* Enable auth via PAM */ -@@ -197,6 +200,8 @@ struct connection_info { - M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \ - M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ - M_CP_STRARRAYOPT(accept_env, num_accept_env); \ -+ M_CP_STROPT(required_auth1); \ -+ M_CP_STROPT(required_auth2); \ - } while (0) - - struct connection_info *get_connection_info(int, int); -diff -up openssh-6.1p1/sshd_config.5.required-authentication openssh-6.1p1/sshd_config.5 ---- openssh-6.1p1/sshd_config.5.required-authentication 2012-07-02 10:53:38.000000000 +0200 -+++ openssh-6.1p1/sshd_config.5 2012-11-08 13:28:34.669017468 +0100 -@@ -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,32 @@ 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) -+.Pp -+.Bl -item -offset indent -compact -+.It -+RequiredAuthentications1 method[,method...] -+.It -+RequiredAuthentications2 method[,method...] -+.El -+.Pp -+Example 1: -+.Bl -item -offset indent -compact -+RequiredAuthentications2 password,hostbased -+.El -+Example 2: -+.Bl -item -offset indent -compact -+RequiredAuthentications2 publickey,password -+.El -+.Pp -+Available methods: -+.Bl -item -offset indent -compact -+.It -+password, keyboard-interactive, publickey, hostbased, gssapi-keyex, gssapi-with-mic -+.El - .It Cm RhostsRSAAuthentication - Specifies whether rhosts or /etc/hosts.equiv authentication together - with successful RSA host authentication is allowed. + case sAuthenticationMethods: ++ if (strncasecmp(arg, "requiredauthentications", 23) == 0) ++ logit("%s line %d: Option %s is obsolete. Please use AuthenticationMethods", ++ filename, linenum, arg); + if (*activep && options->num_auth_methods == 0) { + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_auth_methods >= diff --git a/openssh.spec b/openssh.spec index 18dbfaf..869871c 100644 --- a/openssh.spec +++ b/openssh.spec @@ -208,6 +208,8 @@ Patch900: openssh-6.1p1-gssapi-canohost.patch Patch901: openssh-6.1p1-kuserok.patch #https://bugzilla.redhat.com/show_bug.cgi?id=841065 Patch902: openssh-6.1p1-man-moduli.patch +# obsolete RequiredAuthentications options +Patch903: openssh-6.1p1-required-authentications.patch #--- #https://bugzilla.mindrot.org/show_bug.cgi?id=1604 @@ -452,6 +454,7 @@ popd %patch900 -p1 -b .canohost %patch901 -p1 -b .kuserok %patch902 -p1 -b .man-moduli +%patch903 -p1 -b .required-authentication %if 0 # Nothing here yet