Bugzilla – Attachment 1123 Details for
Bug 983
Required authentication
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Fix a null pointer deref when given an invalid method name.
openbsd-ssh-requiredauth6.patch (text/plain), 20.87 KB, created by
Darren Tucker
on 2006-04-17 23:43:50 AEST
(
hide
)
Description:
Fix a null pointer deref when given an invalid method name.
Filename:
MIME Type:
Creator:
Darren Tucker
Created:
2006-04-17 23:43:50 AEST
Size:
20.87 KB
patch
obsolete
>Index: auth.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/auth.c,v >retrieving revision 1.67 >diff -u -p -r1.67 auth.c >--- auth.c 2006/03/30 11:40:21 1.67 >+++ auth.c 2006/04/17 13:38:06 >@@ -163,7 +163,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; >@@ -183,9 +184,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(), >@@ -197,7 +199,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: >@@ -467,4 +469,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.52 >diff -u -p -r1.52 auth.h >--- auth.h 2006/03/25 22:22:42 1.52 >+++ auth.h 2006/04/17 13:38:06 >@@ -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); > >@@ -168,6 +168,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.66 >diff -u -p -r1.66 auth1.c >--- auth1.c 2006/03/25 13:17:01 1.66 >+++ auth1.c 2006/04/17 13:38:06 >@@ -80,6 +80,53 @@ 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; >+ } >+ 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) > { >@@ -221,6 +268,7 @@ do_authloop(Authctxt *authctxt) > { > int authenticated = 0; > char info[1024]; >+ const char *meth_name; > int type = 0; > const struct AuthMethod1 *meth; > >@@ -228,12 +276,12 @@ do_authloop(Authctxt *authctxt) > 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; > } > >@@ -250,9 +298,10 @@ do_authloop(Authctxt *authctxt) > > /* Get a packet from the client. */ > type = packet_read(); >+ meth_name = get_authname(type); > if ((meth = lookup_authmethod1(type)) == NULL) { >- logit("Unknown message during authentication: " >- "type %d", type); >+ logit("Unknown message during authentication: type %d", >+ type); > goto skip; > } > >@@ -261,6 +310,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" */ >@@ -282,7 +342,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) != 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); >+ 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 (authenticated) > return; >@@ -290,6 +372,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.27 >diff -u -p -r1.27 auth2-chall.c >--- auth2-chall.c 2006/03/25 13:17:01 1.27 >+++ auth2-chall.c 2006/04/17 13:38:06 >@@ -242,9 +242,9 @@ input_userauth_info_response(int type, u > { > Authctxt *authctxt = ctxt; > KbdintAuthctxt *kbdintctxt; >- int authenticated = 0, res, len; >+ int authenticated = 0, res; > u_int i, nresp; >- char **response = NULL, *method; >+ char **response = NULL; > > if (authctxt == NULL) > fatal("input_userauth_info_response: no authctxt"); >@@ -291,12 +291,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); >@@ -306,8 +300,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.14 >diff -u -p -r1.14 auth2-gss.c >--- auth2-gss.c 2006/03/25 22:22:42 1.14 >+++ auth2-gss.c 2006/04/17 13:38:06 >@@ -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.10 >diff -u -p -r1.10 auth2-none.c >--- auth2-none.c 2006/03/25 13:17:01 1.10 >+++ auth2-none.c 2006/04/17 13:38:06 >@@ -104,7 +104,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.110 >diff -u -p -r1.110 auth2.c >--- auth2.c 2006/03/25 13:17:01 1.110 >+++ auth2.c 2006/04/17 13:38:06 >@@ -134,7 +134,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) >@@ -183,12 +183,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); >@@ -196,9 +201,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", >@@ -210,12 +218,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; >+ >+ /* 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; >+ } > >- /* XXX todo: check if multiple auth methods are needed */ > if (authenticated == 1) { > /* turn off userauth */ > dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); >@@ -227,10 +257,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); >@@ -246,6 +277,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) >@@ -278,4 +312,42 @@ 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; >+ 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) == -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.77 >diff -u -p -r1.77 monitor.c >--- monitor.c 2006/03/30 11:40:21 1.77 >+++ monitor.c 2006/04/17 13:38:07 >@@ -260,7 +260,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"); > >@@ -269,12 +270,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); > } >@@ -282,6 +285,7 @@ monitor_child_preauth(Authctxt *_authctx > /* The first few requests do not require asynchronous access */ > while (!authenticated) { > auth_method = "unknown"; >+ no_increment = 0; > authenticated = monitor_read(pmonitor, mon_dispatch, &ent); > if (authenticated) { > if (!(ent->flags & MON_AUTHDECIDE)) >@@ -291,11 +295,23 @@ 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); >+ if (*req_auth != NULL) >+ authenticated = 0; >+ no_increment = 1; >+ } > > if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { >- auth_log(authctxt, authenticated, auth_method, >+ auth_log(authctxt, authenticated, auth_method, NULL, > compat20 ? " ssh2" : ""); >- if (!authenticated) >+ if (!authenticated && !no_increment) > authctxt->failures++; > } > } >@@ -825,7 +841,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, NULL, >+ compat20 ? " ssh2" : ""); > xfree(blob); > xfree(cuser); > xfree(chost); >Index: servconf.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/servconf.c,v >retrieving revision 1.150 >diff -u -p -r1.150 servconf.c >--- servconf.c 2006/03/25 13:17:02 1.150 >+++ servconf.c 2006/04/17 13:38:07 >@@ -22,6 +22,7 @@ > #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); >@@ -97,6 +98,8 @@ initialize_server_options(ServerOptions > options->authorized_keys_file2 = NULL; > options->num_accept_env = 0; > options->permit_tun = -1; >+ options->required_auth1 = NULL; >+ options->required_auth2 = NULL; > > /* Needs to be accessable in many places */ > use_privsep = -1; >@@ -251,6 +254,7 @@ typedef enum { > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, >+ sRequiredAuthentications1, sRequiredAuthentications2, > sUsePrivilegeSeparation, > sDeprecated, sUnsupported > } ServerOpCodes; >@@ -342,6 +346,8 @@ static struct { > { "useprivilegeseparation", sUsePrivilegeSeparation}, > { "acceptenv", sAcceptEnv }, > { "permittunnel", sPermitTunnel }, >+ { "requiredauthentications1", sRequiredAuthentications1 }, >+ { "requiredauthentications2", sRequiredAuthentications2 }, > { NULL, sBadOption } > }; > >@@ -883,6 +889,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.73 >diff -u -p -r1.73 servconf.h >--- servconf.h 2006/03/25 22:22:43 1.73 >+++ servconf.h 2006/04/17 13:38:07 >@@ -135,6 +135,9 @@ typedef struct { > char *authorized_keys_file2; > > int permit_tun; >+ >+ 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