Bugzilla – Attachment 807 Details for
Bug 983
Required authentication
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to add RequiredAuthentications{1,2} options to sshd_config
requiredauth3.diff (text/plain), 25.07 KB, created by
Damien Miller
on 2005-02-09 15:13:28 AEDT
(
hide
)
Description:
Patch to add RequiredAuthentications{1,2} options to sshd_config
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2005-02-09 15:13:28 AEDT
Size:
25.07 KB
patch
obsolete
>Here is the latest version of the required authentication patch for OpenSSH, >i.e specified auth methods that must be passed before authentication may >complete (required, but not sufficient). Markus Friedl mentioned that you >were interested. > >I'm still not sure what to do about the configuration options, so that >part may change. > >-d > > >Index: auth.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth.c,v >retrieving revision 1.57 >diff -u -p -r1.57 auth.c >--- auth.c 22 Jan 2005 08:17:59 -0000 1.57 >+++ auth.c 2 Feb 2005 11:20:21 -0000 >@@ -156,7 +156,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; >@@ -173,9 +174,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(), >@@ -187,7 +189,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: >@@ -483,4 +485,58 @@ fakepw(void) > fake.pw_shell = "/nonexist"; > > 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); > } >Index: auth.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth.h,v >retrieving revision 1.50 >diff -u -p -r1.50 auth.h >--- auth.h 23 May 2004 23:59:53 -0000 1.50 >+++ auth.h 2 Feb 2005 11:20:21 -0000 >@@ -125,9 +125,9 @@ void krb5_cleanup_proc(Authctxt *authctx > void do_authentication(Authctxt *); > void do_authentication2(Authctxt *); > >-void auth_log(Authctxt *, int, char *, char *); >-void userauth_finish(Authctxt *, int, char *); >-int auth_root_allowed(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 *); > > char *auth2_read_banner(void); > >@@ -169,6 +169,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 *); > > #define AUTH_FAIL_MSG "Too many authentication failures for %.100s" > >Index: auth1.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth1.c,v >retrieving revision 1.59 >diff -u -p -r1.59 auth1.c >--- auth1.c 28 Jul 2004 09:40:29 -0000 1.59 >+++ auth1.c 2 Feb 2005 11:20:21 -0000 >@@ -29,28 +29,78 @@ RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/ > /* import */ > extern ServerOptions options; > >-/* >- * convert ssh auth msg type into description >- */ >-static char * >-get_authname(int type) >+struct Authmethod1 { >+ int type; >+ char *name; >+ int *enabled; >+}; >+ >+static struct Authmethod1 auth1_methods[] = { >+ { SSH_CMSG_AUTH_PASSWORD, "password", &options.password_authentication }, >+ { SSH_CMSG_AUTH_RSA, "rsa", &options.rsa_authentication }, >+ { SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa", &options.rhosts_rsa_authentication }, >+ { SSH_CMSG_AUTH_TIS, "challenge-response", &options.challenge_response_authentication }, >+ { SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response", &options.challenge_response_authentication }, >+ { -1, NULL } >+}; >+ >+static struct Authmethod1 * >+get_authmethod1_by_type(int type) >+{ >+ int i; >+ >+ for (i = 0; auth1_methods[i].name != NULL; i++) >+ if (auth1_methods[i].type == type) >+ return &auth1_methods[i]; >+ >+ return NULL; >+} >+ >+static struct Authmethod1 * >+get_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) > { >- static char buf[1024]; >- switch (type) { >- case SSH_CMSG_AUTH_PASSWORD: >- return "password"; >- case SSH_CMSG_AUTH_RSA: >- return "rsa"; >- case SSH_CMSG_AUTH_RHOSTS_RSA: >- return "rhosts-rsa"; >- case SSH_CMSG_AUTH_RHOSTS: >- return "rhosts"; >- case SSH_CMSG_AUTH_TIS: >- case SSH_CMSG_AUTH_TIS_RESPONSE: >- return "challenge-response"; >+ char *orig_methods, *methods, *cp; >+ struct Authmethod1 *m; >+ int ret = 0; >+ >+ orig_methods = methods = xstrdup(list); >+ for(;;) { >+ 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 = get_authmethod1_by_name(cp)) == NULL) { >+ debug("auth1_check_required: unknown method " >+ "\"%s\"", cp); >+ ret = -1; >+ } >+ 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; > } >- snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); >- return buf; >+ xfree(orig_methods); >+ return (ret); > } > > /* >@@ -64,22 +114,23 @@ do_authloop(Authctxt *authctxt) > u_int bits; > Key *client_host_key; > BIGNUM *n; >- char *client_user, *password; >+ char *client_user, *password, *challenge, *response, meth_name[64]; > char info[1024]; > u_int dlen; > u_int ulen; > int type = 0; >+ struct Authmethod1 *meth; > > debug("Attempting authentication for %s%.100s.", > authctxt->valid ? "" : "invalid user ", authctxt->user); > > /* If the user has no password, accept authentication immediately. */ >- if (options.password_authentication && >+ if (options.required_auth1 == NULL && options.password_authentication && > #ifdef KRB5 > (!options.kerberos_authentication || options.kerberos_or_local_passwd) && > #endif > PRIVSEP(auth_password(authctxt, ""))) { >- auth_log(authctxt, 1, "without authentication", ""); >+ auth_log(authctxt, 1, "without authentication", NULL, ""); > return; > } > >@@ -97,13 +148,39 @@ do_authloop(Authctxt *authctxt) > /* Get a packet from the client. */ > type = packet_read(); > >+ /* >+ * Any unknown messages will be ignored (and failure >+ * returned) during authentication. >+ */ >+ if ((meth = get_authmethod1_by_type(type)) == NULL) { >+ logit("Unknown message during authentication: type %d", >+ type); >+ snprintf(meth_name, sizeof meth_name, >+ "bad-auth-msg-%d", type); >+ goto skip_method; >+ } >+ strlcpy(meth_name, meth->name, sizeof meth_name); >+ >+ /* Skip disabled methods */ >+ if (!*(meth->enabled)) { >+ verbose("%s authentication disabled", meth_name); >+ goto skip_method; >+ } >+ >+ /* >+ * 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_method; >+ } >+ > /* Process the packet. */ > switch (type) { > case SSH_CMSG_AUTH_RHOSTS_RSA: >- if (!options.rhosts_rsa_authentication) { >- verbose("Rhosts with RSA authentication disabled."); >- break; >- } > /* > * Get client user name. Note that we just have to > * trust the client; root on the client machine can >@@ -132,10 +209,6 @@ do_authloop(Authctxt *authctxt) > break; > > case SSH_CMSG_AUTH_RSA: >- if (!options.rsa_authentication) { >- verbose("RSA authentication disabled."); >- break; >- } > /* RSA authentication requested. */ > if ((n = BN_new()) == NULL) > fatal("do_authloop: BN_new failed"); >@@ -146,10 +219,6 @@ do_authloop(Authctxt *authctxt) > break; > > case SSH_CMSG_AUTH_PASSWORD: >- if (!options.password_authentication) { >- verbose("Password authentication disabled."); >- break; >- } > /* > * Read user password. It is in plain text, but was > * transmitted over the encrypted channel so it is >@@ -167,38 +236,30 @@ do_authloop(Authctxt *authctxt) > > case SSH_CMSG_AUTH_TIS: > debug("rcvd SSH_CMSG_AUTH_TIS"); >- if (options.challenge_response_authentication == 1) { >- char *challenge = get_challenge(authctxt); >- if (challenge != NULL) { >- debug("sending challenge '%s'", challenge); >- packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); >- packet_put_cstring(challenge); >- xfree(challenge); >- packet_send(); >- packet_write_wait(); >- continue; >- } >+ challenge = get_challenge(authctxt); >+ if (challenge != NULL) { >+ debug("sending challenge '%s'", challenge); >+ packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); >+ packet_put_cstring(challenge); >+ xfree(challenge); >+ packet_send(); >+ packet_write_wait(); >+ continue; > } > break; > case SSH_CMSG_AUTH_TIS_RESPONSE: > debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE"); >- if (options.challenge_response_authentication == 1) { >- char *response = packet_get_string(&dlen); >- packet_check_eom(); >- authenticated = verify_response(authctxt, response); >- memset(response, 'r', dlen); >- xfree(response); >- } >+ response = packet_get_string(&dlen); >+ packet_check_eom(); >+ authenticated = verify_response(authctxt, response); >+ memset(response, 'r', dlen); >+ xfree(response); > break; > > default: >- /* >- * Any unknown messages will be ignored (and failure >- * returned) during authentication. >- */ >- logit("Unknown message during authentication: type %d", type); >- break; >+ fatal("INTERNAL ERROR: unrecognised method %d", type); > } >+ skip_method: > #ifdef BSD_AUTH > if (authctxt->as) { > auth_close(authctxt->as); >@@ -211,11 +272,31 @@ do_authloop(Authctxt *authctxt) > > /* Special handling for root */ > if (authenticated && authctxt->pw->pw_uid == 0 && >- !auth_root_allowed(get_authname(type))) >+ !auth_root_allowed(meth_name)) > authenticated = 0; > > /* 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) != 1) >+ 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); >+ 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 (authenticated) > return; >@@ -223,6 +304,7 @@ do_authloop(Authctxt *authctxt) > if (authctxt->failures++ > options.max_authtries) > packet_disconnect(AUTH_FAIL_MSG, authctxt->user); > >+ send_fail: > packet_start(SSH_SMSG_FAILURE); > packet_send(); > packet_write_wait(); >Index: auth2-chall.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth2-chall.c,v >retrieving revision 1.22 >diff -u -p -r1.22 auth2-chall.c >--- auth2-chall.c 19 Jan 2005 13:11:47 -0000 1.22 >+++ auth2-chall.c 2 Feb 2005 11:20:21 -0000 >@@ -243,9 +243,9 @@ input_userauth_info_response(int type, u > { > Authctxt *authctxt = ctxt; > KbdintAuthctxt *kbdintctxt; >- int i, authenticated = 0, res, len; >+ int i, authenticated = 0, res; > u_int nresp; >- char **response = NULL, *method; >+ char **response = NULL; > > if (authctxt == NULL) > fatal("input_userauth_info_response: no authctxt"); >@@ -292,12 +292,6 @@ input_userauth_info_response(int type, u > break; > } > >- len = strlen("keyboard-interactive") + 2 + >- strlen(kbdintctxt->device->name); >- method = xmalloc(len); >- snprintf(method, len, "keyboard-interactive/%s", >- kbdintctxt->device->name); >- > if (!authctxt->postponed) { > if (authenticated) { > auth2_challenge_stop(authctxt); >@@ -307,8 +301,8 @@ input_userauth_info_response(int type, u > auth2_challenge_start(authctxt); > } > } >- userauth_finish(authctxt, authenticated, method); >- xfree(method); >+ userauth_finish(authctxt, authenticated, "keyboard-interactive", >+ kbdintctxt->device->name); > } > > void >Index: auth2-gss.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth2-gss.c,v >retrieving revision 1.8 >diff -u -p -r1.8 auth2-gss.c >--- auth2-gss.c 21 Jun 2004 17:36:31 -0000 1.8 >+++ auth2-gss.c 2 Feb 2005 11:20:21 -0000 >@@ -155,7 +155,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); >@@ -243,7 +243,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 >@@ -283,7 +283,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 = { >Index: auth2-none.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth2-none.c,v >retrieving revision 1.7 >diff -u -p -r1.7 auth2-none.c >--- auth2-none.c 11 May 2004 19:01:43 -0000 1.7 >+++ auth2-none.c 2 Feb 2005 11:20:21 -0000 >@@ -101,7 +101,7 @@ userauth_none(Authctxt *authctxt) > none_enabled = 0; > packet_check_eom(); > userauth_banner(); >- if (options.password_authentication) >+ if (options.password_authentication && options.required_auth2 == NULL) > return (PRIVSEP(auth_password(authctxt, ""))); > return (0); > } >Index: auth2.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth2.c,v >retrieving revision 1.107 >diff -u -p -r1.107 auth2.c >--- auth2.c 28 Jul 2004 09:40:29 -0000 1.107 >+++ auth2.c 2 Feb 2005 11:20:21 -0000 >@@ -132,7 +132,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) >@@ -181,12 +181,17 @@ input_userauth_request(int type, u_int32 > authctxt->postponed = 0; > > /* try to authenticate user */ >- m = authmethod_lookup(method); >- if (m != NULL) { >- 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); >@@ -194,9 +199,12 @@ input_userauth_request(int type, u_int32 > } > > 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", >@@ -208,12 +216,34 @@ userauth_finish(Authctxt *authctxt, int > authenticated = 0; > > /* 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) != 1) >+ 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); >+ /* >+ * 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); >@@ -225,10 +255,11 @@ userauth_finish(Authctxt *authctxt, int > } else { > if (authctxt->failures++ > options.max_authtries) > 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); >@@ -244,6 +275,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) >@@ -276,4 +310,41 @@ authmethod_lookup(const char *name) > debug2("Unrecognized authentication method name: %s", > name ? name : "NULL"); > return NULL; >+} >+ >+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; >+ } >+ 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) == -1) >+ *(m->enabled) = 1; >+ } >+ xfree(orig_methods); >+ return (ret); > } >Index: monitor.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/monitor.c,v >retrieving revision 1.62 >diff -u -p -r1.62 monitor.c >--- monitor.c 30 Jan 2005 11:18:08 -0000 1.62 >+++ monitor.c 2 Feb 2005 11:20:23 -0000 >@@ -253,7 +253,8 @@ void > monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) > { > struct mon_table *ent; >- int authenticated = 0; >+ int no_increment, authenticated = 0; >+ char **req_auth; > > debug3("preauth child monitor started"); > >@@ -262,18 +263,21 @@ 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); > } > > /* The first few requests do not require asynchronous access */ > while (!authenticated) { >+ no_increment = 0; > authenticated = monitor_read(pmonitor, mon_dispatch, &ent); > if (authenticated) { > if (!(ent->flags & MON_AUTHDECIDE)) >@@ -283,11 +287,22 @@ monitor_child_preauth(Authctxt *_authctx > !auth_root_allowed(auth_method)) > authenticated = 0; > } >+ /* Loop until the required authmethods are done */ >+ if (authenticated && *req_auth != NULL) { >+ if (auth_remove_from_list(req_auth, auth_method) != 1) >+ 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); >+ authenticated = 0; >+ no_increment = 1; >+ } > > if (ent->flags & MON_AUTHDECIDE) { >- auth_log(authctxt, authenticated, auth_method, >+ auth_log(authctxt, authenticated, auth_method, NULL, > compat20 ? " ssh2" : ""); >- if (!authenticated) >+ if (!authenticated && !no_increment) > authctxt->failures++; > } > } >Index: servconf.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/servconf.c,v >retrieving revision 1.138 >diff -u -p -r1.138 servconf.c >--- servconf.c 23 Dec 2004 23:11:00 -0000 1.138 >+++ servconf.c 2 Feb 2005 11:20:23 -0000 >@@ -22,6 +22,7 @@ RCSID("$OpenBSD: servconf.c,v 1.138 2004 > #include "cipher.h" > #include "kex.h" > #include "mac.h" >+#include "auth.h" > > static void add_listen_addr(ServerOptions *, char *, u_short); > static void add_one_listen_addr(ServerOptions *, char *, u_short); >@@ -96,6 +97,8 @@ initialize_server_options(ServerOptions > options->authorized_keys_file = NULL; > options->authorized_keys_file2 = NULL; > options->num_accept_env = 0; >+ options->required_auth1 = NULL; >+ options->required_auth2 = NULL; > > /* Needs to be accessable in many places */ > use_privsep = -1; >@@ -248,7 +251,8 @@ typedef enum { > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, >- sUsePrivilegeSeparation, >+ sRequiredAuthentications1, sRequiredAuthentications2, >+ sUsePrivilegeSeparation, > sDeprecated, sUnsupported > } ServerOpCodes; > >@@ -338,6 +342,8 @@ static struct { > { "authorizedkeysfile2", sAuthorizedKeysFile2 }, > { "useprivilegeseparation", sUsePrivilegeSeparation}, > { "acceptenv", sAcceptEnv }, >+ { "requiredauthentications1", sRequiredAuthentications1 }, >+ { "requiredauthentications2", sRequiredAuthentications2 }, > { NULL, sBadOption } > }; > >@@ -853,6 +859,33 @@ parse_flag: > filename, linenum); > else > options->max_startups = options->max_startups_begin; >+ break; >+ >+ >+ case sRequiredAuthentications1: >+ charptr = &options->required_auth1; >+ arg = strdelim(&cp); >+ if (auth1_check_required(arg) != 0) >+ fatal("%.200s line %d: Invalid required authentication " >+ "list", filename, linenum); >+ if (!arg || *arg == '\0') >+ fatal("%.200s line %d: Missing argument.", >+ filename, linenum); >+ if (*charptr == NULL) >+ *charptr = xstrdup(arg); >+ break; >+ >+ case sRequiredAuthentications2: >+ charptr = &options->required_auth2; >+ arg = strdelim(&cp); >+ if (auth2_check_required(arg) != 0) >+ fatal("%.200s line %d: Invalid required authentication " >+ "list", filename, linenum); >+ if (!arg || *arg == '\0') >+ fatal("%.200s line %d: Missing argument.", >+ filename, linenum); >+ if (*charptr == NULL) >+ *charptr = xstrdup(arg); > break; > > case sMaxAuthTries: >Index: servconf.h >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/servconf.h,v >retrieving revision 1.71 >diff -u -p -r1.71 servconf.h >--- servconf.h 23 Dec 2004 23:11:00 -0000 1.71 >+++ servconf.h 2 Feb 2005 11:20:23 -0000 >@@ -133,6 +133,9 @@ typedef struct { > > char *authorized_keys_file; /* File containing public keys */ > char *authorized_keys_file2; >+ >+ char *required_auth1; /* Required, but not sufficient */ >+ char *required_auth2; > } ServerOptions; > > void initialize_server_options(ServerOptions *);
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