1a04a10f8SKris Kennaway /* 2a04a10f8SKris Kennaway * Copyright (c) 2000 Markus Friedl. All rights reserved. 3a04a10f8SKris Kennaway * 4a04a10f8SKris Kennaway * Redistribution and use in source and binary forms, with or without 5a04a10f8SKris Kennaway * modification, are permitted provided that the following conditions 6a04a10f8SKris Kennaway * are met: 7a04a10f8SKris Kennaway * 1. Redistributions of source code must retain the above copyright 8a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer. 9a04a10f8SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 10a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer in the 11a04a10f8SKris Kennaway * documentation and/or other materials provided with the distribution. 12a04a10f8SKris Kennaway * 13a04a10f8SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14a04a10f8SKris Kennaway * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15a04a10f8SKris Kennaway * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16a04a10f8SKris Kennaway * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17a04a10f8SKris Kennaway * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18a04a10f8SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19a04a10f8SKris Kennaway * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20a04a10f8SKris Kennaway * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21a04a10f8SKris Kennaway * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22a04a10f8SKris Kennaway * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23a04a10f8SKris Kennaway */ 24c2d3a559SKris Kennaway 25a04a10f8SKris Kennaway #include "includes.h" 2621e764dfSDag-Erling Smørgrav RCSID("$OpenBSD: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $"); 275b400a39SDag-Erling Smørgrav RCSID("$FreeBSD$"); 28a04a10f8SKris Kennaway 299be00009SDag-Erling Smørgrav #include "canohost.h" 30ca3176e7SBrian Feldman #include "ssh2.h" 31a04a10f8SKris Kennaway #include "xmalloc.h" 32a04a10f8SKris Kennaway #include "packet.h" 33ca3176e7SBrian Feldman #include "log.h" 34a04a10f8SKris Kennaway #include "servconf.h" 35a04a10f8SKris Kennaway #include "compat.h" 36a04a10f8SKris Kennaway #include "auth.h" 37a04a10f8SKris Kennaway #include "dispatch.h" 38ca3176e7SBrian Feldman #include "pathnames.h" 3980628bacSDag-Erling Smørgrav #include "monitor_wrap.h" 40aa49c926SDag-Erling Smørgrav #include "buffer.h" 41a04a10f8SKris Kennaway 42cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 43cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h" 44cf2b5f3bSDag-Erling Smørgrav #endif 45cf2b5f3bSDag-Erling Smørgrav 46a04a10f8SKris Kennaway /* import */ 47a04a10f8SKris Kennaway extern ServerOptions options; 48ca3176e7SBrian Feldman extern u_char *session_id2; 49cf2b5f3bSDag-Erling Smørgrav extern u_int session_id2_len; 50aa49c926SDag-Erling Smørgrav extern Buffer loginmsg; 51a04a10f8SKris Kennaway 5280628bacSDag-Erling Smørgrav /* methods */ 5380628bacSDag-Erling Smørgrav 5480628bacSDag-Erling Smørgrav extern Authmethod method_none; 5580628bacSDag-Erling Smørgrav extern Authmethod method_pubkey; 5680628bacSDag-Erling Smørgrav extern Authmethod method_passwd; 5780628bacSDag-Erling Smørgrav extern Authmethod method_kbdint; 5880628bacSDag-Erling Smørgrav extern Authmethod method_hostbased; 59cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 60cf2b5f3bSDag-Erling Smørgrav extern Authmethod method_gssapi; 61cf2b5f3bSDag-Erling Smørgrav #endif 6280628bacSDag-Erling Smørgrav 6380628bacSDag-Erling Smørgrav Authmethod *authmethods[] = { 6480628bacSDag-Erling Smørgrav &method_none, 6580628bacSDag-Erling Smørgrav &method_pubkey, 66cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 67cf2b5f3bSDag-Erling Smørgrav &method_gssapi, 68cf2b5f3bSDag-Erling Smørgrav #endif 6980628bacSDag-Erling Smørgrav &method_passwd, 7080628bacSDag-Erling Smørgrav &method_kbdint, 7180628bacSDag-Erling Smørgrav &method_hostbased, 7280628bacSDag-Erling Smørgrav NULL 7309958426SBrian Feldman }; 7409958426SBrian Feldman 75a04a10f8SKris Kennaway /* protocol */ 76a04a10f8SKris Kennaway 77af12a3e7SDag-Erling Smørgrav static void input_service_request(int, u_int32_t, void *); 78af12a3e7SDag-Erling Smørgrav static void input_userauth_request(int, u_int32_t, void *); 79a04a10f8SKris Kennaway 80a04a10f8SKris Kennaway /* helper */ 81af12a3e7SDag-Erling Smørgrav static Authmethod *authmethod_lookup(const char *); 82af12a3e7SDag-Erling Smørgrav static char *authmethods_get(void); 8380628bacSDag-Erling Smørgrav int user_key_allowed(struct passwd *, Key *); 84a04a10f8SKris Kennaway 85a04a10f8SKris Kennaway /* 8609958426SBrian Feldman * loop until authctxt->success == TRUE 87a04a10f8SKris Kennaway */ 88a04a10f8SKris Kennaway 891ec0d754SDag-Erling Smørgrav void 901ec0d754SDag-Erling Smørgrav do_authentication2(Authctxt *authctxt) 91a04a10f8SKris Kennaway { 92af12a3e7SDag-Erling Smørgrav /* challenge-response is implemented via keyboard interactive */ 93af12a3e7SDag-Erling Smørgrav if (options.challenge_response_authentication) 94ca3176e7SBrian Feldman options.kbd_interactive_authentication = 1; 95ca3176e7SBrian Feldman 96af12a3e7SDag-Erling Smørgrav dispatch_init(&dispatch_protocol_error); 97a04a10f8SKris Kennaway dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 9809958426SBrian Feldman dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 99a04a10f8SKris Kennaway } 100a04a10f8SKris Kennaway 101af12a3e7SDag-Erling Smørgrav static void 102af12a3e7SDag-Erling Smørgrav input_service_request(int type, u_int32_t seq, void *ctxt) 103a04a10f8SKris Kennaway { 10409958426SBrian Feldman Authctxt *authctxt = ctxt; 105ca3176e7SBrian Feldman u_int len; 106f388f5efSDag-Erling Smørgrav int acceptit = 0; 107a04a10f8SKris Kennaway char *service = packet_get_string(&len); 108af12a3e7SDag-Erling Smørgrav packet_check_eom(); 109a04a10f8SKris Kennaway 11009958426SBrian Feldman if (authctxt == NULL) 11109958426SBrian Feldman fatal("input_service_request: no authctxt"); 11209958426SBrian Feldman 113a04a10f8SKris Kennaway if (strcmp(service, "ssh-userauth") == 0) { 11409958426SBrian Feldman if (!authctxt->success) { 115f388f5efSDag-Erling Smørgrav acceptit = 1; 116a04a10f8SKris Kennaway /* now we can handle user-auth requests */ 117a04a10f8SKris Kennaway dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); 118a04a10f8SKris Kennaway } 119a04a10f8SKris Kennaway } 120a04a10f8SKris Kennaway /* XXX all other service requests are denied */ 121a04a10f8SKris Kennaway 122f388f5efSDag-Erling Smørgrav if (acceptit) { 123a04a10f8SKris Kennaway packet_start(SSH2_MSG_SERVICE_ACCEPT); 124a04a10f8SKris Kennaway packet_put_cstring(service); 125a04a10f8SKris Kennaway packet_send(); 126a04a10f8SKris Kennaway packet_write_wait(); 127a04a10f8SKris Kennaway } else { 128a04a10f8SKris Kennaway debug("bad service request %s", service); 129a04a10f8SKris Kennaway packet_disconnect("bad service request %s", service); 130a04a10f8SKris Kennaway } 131a04a10f8SKris Kennaway xfree(service); 132a04a10f8SKris Kennaway } 133a04a10f8SKris Kennaway 134af12a3e7SDag-Erling Smørgrav static void 135af12a3e7SDag-Erling Smørgrav input_userauth_request(int type, u_int32_t seq, void *ctxt) 136a04a10f8SKris Kennaway { 13709958426SBrian Feldman Authctxt *authctxt = ctxt; 13809958426SBrian Feldman Authmethod *m = NULL; 139ca3176e7SBrian Feldman char *user, *service, *method, *style = NULL; 140a04a10f8SKris Kennaway int authenticated = 0; 1415b400a39SDag-Erling Smørgrav #ifdef HAVE_LOGIN_CAP 1425b400a39SDag-Erling Smørgrav login_cap_t *lc; 1435b400a39SDag-Erling Smørgrav const char *from_host, *from_ip; 1445b400a39SDag-Erling Smørgrav 145cf2b5f3bSDag-Erling Smørgrav from_host = get_canonical_hostname(options.use_dns); 1465b400a39SDag-Erling Smørgrav from_ip = get_remote_ipaddr(); 1475b400a39SDag-Erling Smørgrav #endif 148a04a10f8SKris Kennaway 14909958426SBrian Feldman if (authctxt == NULL) 15009958426SBrian Feldman fatal("input_userauth_request: no authctxt"); 151a04a10f8SKris Kennaway 15209958426SBrian Feldman user = packet_get_string(NULL); 15309958426SBrian Feldman service = packet_get_string(NULL); 15409958426SBrian Feldman method = packet_get_string(NULL); 155a04a10f8SKris Kennaway debug("userauth-request for user %s service %s method %s", user, service, method); 156ca3176e7SBrian Feldman debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 157a04a10f8SKris Kennaway 158ca3176e7SBrian Feldman if ((style = strchr(user, ':')) != NULL) 159ca3176e7SBrian Feldman *style++ = 0; 160ca3176e7SBrian Feldman 161ca3176e7SBrian Feldman if (authctxt->attempt++ == 0) { 16209958426SBrian Feldman /* setup auth context */ 16380628bacSDag-Erling Smørgrav authctxt->pw = PRIVSEP(getpwnamallow(user)); 1645962c0e9SDag-Erling Smørgrav authctxt->user = xstrdup(user); 16580628bacSDag-Erling Smørgrav if (authctxt->pw && strcmp(service, "ssh-connection")==0) { 16609958426SBrian Feldman authctxt->valid = 1; 16709958426SBrian Feldman debug2("input_userauth_request: setting up authctxt for %s", user); 16809958426SBrian Feldman #ifdef USE_PAM 169cf2b5f3bSDag-Erling Smørgrav if (options.use_pam) 1705962c0e9SDag-Erling Smørgrav PRIVSEP(start_pam(authctxt)); 17109958426SBrian Feldman #endif 17209958426SBrian Feldman } else { 17321e764dfSDag-Erling Smørgrav logit("input_userauth_request: invalid user %s", user); 174cf2b5f3bSDag-Erling Smørgrav authctxt->pw = fakepw(); 175989dd127SDag-Erling Smørgrav #ifdef USE_PAM 176cf2b5f3bSDag-Erling Smørgrav if (options.use_pam) 1775962c0e9SDag-Erling Smørgrav PRIVSEP(start_pam(authctxt)); 178989dd127SDag-Erling Smørgrav #endif 179aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 180aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_INVALID_USER)); 181aa49c926SDag-Erling Smørgrav #endif 182a04a10f8SKris Kennaway } 18321e764dfSDag-Erling Smørgrav setproctitle("%s%s", authctxt->valid ? user : "unknown", 18480628bacSDag-Erling Smørgrav use_privsep ? " [net]" : ""); 18509958426SBrian Feldman authctxt->service = xstrdup(service); 186af12a3e7SDag-Erling Smørgrav authctxt->style = style ? xstrdup(style) : NULL; 18780628bacSDag-Erling Smørgrav if (use_privsep) 18880628bacSDag-Erling Smørgrav mm_inform_authserv(service, style); 189af12a3e7SDag-Erling Smørgrav } else if (strcmp(user, authctxt->user) != 0 || 19009958426SBrian Feldman strcmp(service, authctxt->service) != 0) { 191af12a3e7SDag-Erling Smørgrav packet_disconnect("Change of username or service not allowed: " 192af12a3e7SDag-Erling Smørgrav "(%s,%s) -> (%s,%s)", 193af12a3e7SDag-Erling Smørgrav authctxt->user, authctxt->service, user, service); 194a04a10f8SKris Kennaway } 1955b400a39SDag-Erling Smørgrav 1965b400a39SDag-Erling Smørgrav #ifdef HAVE_LOGIN_CAP 1975b400a39SDag-Erling Smørgrav if (authctxt->pw != NULL) { 1985b400a39SDag-Erling Smørgrav lc = login_getpwclass(authctxt->pw); 1995b400a39SDag-Erling Smørgrav if (lc == NULL) 2005b400a39SDag-Erling Smørgrav lc = login_getclassbyname(NULL, authctxt->pw); 2015b400a39SDag-Erling Smørgrav if (!auth_hostok(lc, from_host, from_ip)) { 202cf2b5f3bSDag-Erling Smørgrav logit("Denied connection for %.200s from %.200s [%.200s].", 2035b400a39SDag-Erling Smørgrav authctxt->pw->pw_name, from_host, from_ip); 2045b400a39SDag-Erling Smørgrav packet_disconnect("Sorry, you are not allowed to connect."); 2055b400a39SDag-Erling Smørgrav } 2065b400a39SDag-Erling Smørgrav if (!auth_timeok(lc, time(NULL))) { 207cf2b5f3bSDag-Erling Smørgrav logit("LOGIN %.200s REFUSED (TIME) FROM %.200s", 2085b400a39SDag-Erling Smørgrav authctxt->pw->pw_name, from_host); 2095b400a39SDag-Erling Smørgrav packet_disconnect("Logins not available right now."); 2105b400a39SDag-Erling Smørgrav } 2115b400a39SDag-Erling Smørgrav login_close(lc); 2125b400a39SDag-Erling Smørgrav lc = NULL; 2135b400a39SDag-Erling Smørgrav } 2145b400a39SDag-Erling Smørgrav #endif /* HAVE_LOGIN_CAP */ 2155b400a39SDag-Erling Smørgrav 216ca3176e7SBrian Feldman /* reset state */ 217af12a3e7SDag-Erling Smørgrav auth2_challenge_stop(authctxt); 218cf2b5f3bSDag-Erling Smørgrav 219cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 220cf2b5f3bSDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 221cf2b5f3bSDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 222cf2b5f3bSDag-Erling Smørgrav #endif 223cf2b5f3bSDag-Erling Smørgrav 224ca3176e7SBrian Feldman authctxt->postponed = 0; 22503e72be8SBrian Feldman 226ca3176e7SBrian Feldman /* try to authenticate user */ 22709958426SBrian Feldman m = authmethod_lookup(method); 22809958426SBrian Feldman if (m != NULL) { 22909958426SBrian Feldman debug2("input_userauth_request: try method %s", method); 23009958426SBrian Feldman authenticated = m->userauth(authctxt); 23109958426SBrian Feldman } 232ca3176e7SBrian Feldman userauth_finish(authctxt, authenticated, method); 23309958426SBrian Feldman 23409958426SBrian Feldman xfree(service); 23509958426SBrian Feldman xfree(user); 23609958426SBrian Feldman xfree(method); 23709958426SBrian Feldman } 23809958426SBrian Feldman 239ca3176e7SBrian Feldman void 240ca3176e7SBrian Feldman userauth_finish(Authctxt *authctxt, int authenticated, char *method) 241ca3176e7SBrian Feldman { 242af12a3e7SDag-Erling Smørgrav char *methods; 243af12a3e7SDag-Erling Smørgrav 244ca3176e7SBrian Feldman if (!authctxt->valid && authenticated) 245ca3176e7SBrian Feldman fatal("INTERNAL ERROR: authenticated invalid user %s", 246ca3176e7SBrian Feldman authctxt->user); 247ca3176e7SBrian Feldman 248ca3176e7SBrian Feldman /* Special handling for root */ 249e73e9afaSDag-Erling Smørgrav if (authenticated && authctxt->pw->pw_uid == 0 && 250aa49c926SDag-Erling Smørgrav !auth_root_allowed(method)) { 251ca3176e7SBrian Feldman authenticated = 0; 252aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 253aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 254aa49c926SDag-Erling Smørgrav #endif 255aa49c926SDag-Erling Smørgrav } 256ca3176e7SBrian Feldman 257989dd127SDag-Erling Smørgrav #ifdef USE_PAM 258aa49c926SDag-Erling Smørgrav if (options.use_pam && authenticated) { 259aa49c926SDag-Erling Smørgrav if (!PRIVSEP(do_pam_account())) { 260aa49c926SDag-Erling Smørgrav /* if PAM returned a message, send it to the user */ 261aa49c926SDag-Erling Smørgrav if (buffer_len(&loginmsg) > 0) { 262aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, "\0", 1); 263aa49c926SDag-Erling Smørgrav userauth_send_banner(buffer_ptr(&loginmsg)); 264aa49c926SDag-Erling Smørgrav packet_write_wait(); 265aa49c926SDag-Erling Smørgrav } 266aa49c926SDag-Erling Smørgrav fatal("Access denied for user %s by PAM account " 267aa49c926SDag-Erling Smørgrav "configuration", authctxt->user); 268aa49c926SDag-Erling Smørgrav } 269aa49c926SDag-Erling Smørgrav } 270cf2b5f3bSDag-Erling Smørgrav #endif 271989dd127SDag-Erling Smørgrav 272f388f5efSDag-Erling Smørgrav #ifdef _UNICOS 273f388f5efSDag-Erling Smørgrav if (authenticated && cray_access_denied(authctxt->user)) { 274f388f5efSDag-Erling Smørgrav authenticated = 0; 275f388f5efSDag-Erling Smørgrav fatal("Access denied for user %s.",authctxt->user); 276f388f5efSDag-Erling Smørgrav } 277f388f5efSDag-Erling Smørgrav #endif /* _UNICOS */ 278f388f5efSDag-Erling Smørgrav 279ca3176e7SBrian Feldman /* Log before sending the reply */ 280ca3176e7SBrian Feldman auth_log(authctxt, authenticated, method, " ssh2"); 281ca3176e7SBrian Feldman 282af12a3e7SDag-Erling Smørgrav if (authctxt->postponed) 283af12a3e7SDag-Erling Smørgrav return; 284af12a3e7SDag-Erling Smørgrav 285af12a3e7SDag-Erling Smørgrav /* XXX todo: check if multiple auth methods are needed */ 286af12a3e7SDag-Erling Smørgrav if (authenticated == 1) { 287af12a3e7SDag-Erling Smørgrav /* turn off userauth */ 288af12a3e7SDag-Erling Smørgrav dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); 289af12a3e7SDag-Erling Smørgrav packet_start(SSH2_MSG_USERAUTH_SUCCESS); 290af12a3e7SDag-Erling Smørgrav packet_send(); 291af12a3e7SDag-Erling Smørgrav packet_write_wait(); 292af12a3e7SDag-Erling Smørgrav /* now we can break out */ 293af12a3e7SDag-Erling Smørgrav authctxt->success = 1; 294af12a3e7SDag-Erling Smørgrav } else { 295aa49c926SDag-Erling Smørgrav if (authctxt->failures++ > options.max_authtries) { 296aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 297aa49c926SDag-Erling Smørgrav PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 298aa49c926SDag-Erling Smørgrav #endif 299af12a3e7SDag-Erling Smørgrav packet_disconnect(AUTH_FAIL_MSG, authctxt->user); 300aa49c926SDag-Erling Smørgrav } 301af12a3e7SDag-Erling Smørgrav methods = authmethods_get(); 302af12a3e7SDag-Erling Smørgrav packet_start(SSH2_MSG_USERAUTH_FAILURE); 303af12a3e7SDag-Erling Smørgrav packet_put_cstring(methods); 304af12a3e7SDag-Erling Smørgrav packet_put_char(0); /* XXX partial success, unused */ 305af12a3e7SDag-Erling Smørgrav packet_send(); 306af12a3e7SDag-Erling Smørgrav packet_write_wait(); 307af12a3e7SDag-Erling Smørgrav xfree(methods); 308af12a3e7SDag-Erling Smørgrav } 309ca3176e7SBrian Feldman } 31009958426SBrian Feldman 31109958426SBrian Feldman #define DELIM "," 31209958426SBrian Feldman 313af12a3e7SDag-Erling Smørgrav static char * 31409958426SBrian Feldman authmethods_get(void) 315a04a10f8SKris Kennaway { 316af12a3e7SDag-Erling Smørgrav Buffer b; 31709958426SBrian Feldman char *list; 31880628bacSDag-Erling Smørgrav int i; 319a04a10f8SKris Kennaway 320af12a3e7SDag-Erling Smørgrav buffer_init(&b); 32180628bacSDag-Erling Smørgrav for (i = 0; authmethods[i] != NULL; i++) { 32280628bacSDag-Erling Smørgrav if (strcmp(authmethods[i]->name, "none") == 0) 32309958426SBrian Feldman continue; 32480628bacSDag-Erling Smørgrav if (authmethods[i]->enabled != NULL && 32580628bacSDag-Erling Smørgrav *(authmethods[i]->enabled) != 0) { 326af12a3e7SDag-Erling Smørgrav if (buffer_len(&b) > 0) 327af12a3e7SDag-Erling Smørgrav buffer_append(&b, ",", 1); 32880628bacSDag-Erling Smørgrav buffer_append(&b, authmethods[i]->name, 32980628bacSDag-Erling Smørgrav strlen(authmethods[i]->name)); 33009958426SBrian Feldman } 33109958426SBrian Feldman } 332af12a3e7SDag-Erling Smørgrav buffer_append(&b, "\0", 1); 333af12a3e7SDag-Erling Smørgrav list = xstrdup(buffer_ptr(&b)); 334af12a3e7SDag-Erling Smørgrav buffer_free(&b); 33509958426SBrian Feldman return list; 33609958426SBrian Feldman } 33709958426SBrian Feldman 338af12a3e7SDag-Erling Smørgrav static Authmethod * 33909958426SBrian Feldman authmethod_lookup(const char *name) 34009958426SBrian Feldman { 34180628bacSDag-Erling Smørgrav int i; 34280628bacSDag-Erling Smørgrav 34309958426SBrian Feldman if (name != NULL) 34480628bacSDag-Erling Smørgrav for (i = 0; authmethods[i] != NULL; i++) 34580628bacSDag-Erling Smørgrav if (authmethods[i]->enabled != NULL && 34680628bacSDag-Erling Smørgrav *(authmethods[i]->enabled) != 0 && 34780628bacSDag-Erling Smørgrav strcmp(name, authmethods[i]->name) == 0) 34880628bacSDag-Erling Smørgrav return authmethods[i]; 34980628bacSDag-Erling Smørgrav debug2("Unrecognized authentication method name: %s", 35080628bacSDag-Erling Smørgrav name ? name : "NULL"); 351a04a10f8SKris Kennaway return NULL; 352a04a10f8SKris Kennaway } 353