]> andersk Git - openssh.git/blobdiff - auth2.c
- djm@cvs.openbsd.org 2010/01/12 01:36:08
[openssh.git] / auth2.c
diff --git a/auth2.c b/auth2.c
index e77358a3b3efad831a4584f080fb75d0a45bf698..5d54685596c848a7bb0d59722353dafb9ebdf9cd 100644 (file)
--- a/auth2.c
+++ b/auth2.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -9,11 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Markus Friedl.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.5 2000/05/01 23:13:39 djm Exp $");
 
-#include <openssl/dsa.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
 
+#include "atomicio.h"
 #include "xmalloc.h"
-#include "rsa.h"
-#include "ssh.h"
-#include "pty.h"
+#include "ssh2.h"
 #include "packet.h"
+#include "log.h"
 #include "buffer.h"
-#include "cipher.h"
 #include "servconf.h"
 #include "compat.h"
-#include "channels.h"
-#include "bufaux.h"
-#include "ssh2.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
-#include "session.h"
 #include "dispatch.h"
-#include "auth.h"
-#include "key.h"
-#include "kex.h"
+#include "pathnames.h"
+#include "buffer.h"
 
-#include "dsa.h"
-#include "uidswap.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
 
 /* import */
 extern ServerOptions options;
-extern unsigned char *session_id2;
-extern int session_id2_len;
+extern u_char *session_id2;
+extern u_int session_id2_len;
+extern Buffer loginmsg;
+
+/* methods */
+
+extern Authmethod method_none;
+extern Authmethod method_pubkey;
+extern Authmethod method_passwd;
+extern Authmethod method_kbdint;
+extern Authmethod method_hostbased;
+#ifdef GSSAPI
+extern Authmethod method_gssapi;
+#endif
+#ifdef JPAKE
+extern Authmethod method_jpake;
+#endif
 
-/* protocol */
+Authmethod *authmethods[] = {
+       &method_none,
+       &method_pubkey,
+#ifdef GSSAPI
+       &method_gssapi,
+#endif
+#ifdef JPAKE
+       &method_jpake,
+#endif
+       &method_passwd,
+       &method_kbdint,
+       &method_hostbased,
+       NULL
+};
 
-void   input_service_request(int type, int plen);
-void   input_userauth_request(int type, int plen);
-void   protocol_error(int type, int plen);
+/* protocol */
 
-/* auth */
-int    ssh2_auth_none(struct passwd *pw);
-int    ssh2_auth_password(struct passwd *pw);
-int    ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen);
+static void input_service_request(int, u_int32_t, void *);
+static void input_userauth_request(int, u_int32_t, void *);
 
 /* helper */
-struct passwd*  auth_set_user(char *u, char *s);
-int    user_dsa_key_allowed(struct passwd *pw, Key *key);
-
-typedef struct Authctxt Authctxt;
-struct Authctxt {
-       char *user;
-       char *service;
-       struct passwd pw;
-       int valid;
-};
-static Authctxt        *authctxt = NULL;
-static int userauth_success = 0;
-
-/*
- * loop until userauth_success == TRUE
- */
+static Authmethod *authmethod_lookup(const char *);
+static char *authmethods_get(void);
 
-void
-do_authentication2()
+char *
+auth2_read_banner(void)
 {
-       /* turn off skey/kerberos, not supported by SSH2 */
-#ifdef SKEY
-       options.skey_authentication = 0;
-#endif
-#ifdef KRB4
-       options.kerberos_authentication = 0;
-#endif
+       struct stat st;
+       char *banner = NULL;
+       size_t len, n;
+       int fd;
+
+       if ((fd = open(options.banner, O_RDONLY)) == -1)
+               return (NULL);
+       if (fstat(fd, &st) == -1) {
+               close(fd);
+               return (NULL);
+       }
+       if (st.st_size > 1*1024*1024) {
+               close(fd);
+               return (NULL);
+       }
 
-       dispatch_init(&protocol_error);
-       dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
-       dispatch_run(DISPATCH_BLOCK, &userauth_success);
-       do_authenticated2();
+       len = (size_t)st.st_size;               /* truncate */
+       banner = xmalloc(len + 1);
+       n = atomicio(read, fd, banner, len);
+       close(fd);
+
+       if (n != len) {
+               xfree(banner);
+               return (NULL);
+       }
+       banner[n] = '\0';
+
+       return (banner);
 }
 
 void
-protocol_error(int type, int plen)
+userauth_send_banner(const char *msg)
 {
-       log("auth: protocol error: type %d plen %d", type, plen);
-       packet_start(SSH2_MSG_UNIMPLEMENTED);
-       packet_put_int(0);
+       if (datafellows & SSH_BUG_BANNER)
+               return;
+
+       packet_start(SSH2_MSG_USERAUTH_BANNER);
+       packet_put_cstring(msg);
+       packet_put_cstring("");         /* language, unused */
        packet_send();
-       packet_write_wait();
+       debug("%s: sent", __func__);
 }
 
+static void
+userauth_banner(void)
+{
+       char *banner = NULL;
+
+       if (options.banner == NULL ||
+           strcasecmp(options.banner, "none") == 0 ||
+           (datafellows & SSH_BUG_BANNER) != 0)
+               return;
+
+       if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+               goto done;
+       userauth_send_banner(banner);
+
+done:
+       if (banner)
+               xfree(banner);
+}
+
+/*
+ * loop until authctxt->success == TRUE
+ */
 void
-input_service_request(int type, int plen)
+do_authentication2(Authctxt *authctxt)
+{
+       dispatch_init(&dispatch_protocol_error);
+       dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
+       dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
+}
+
+/*ARGSUSED*/
+static void
+input_service_request(int type, u_int32_t seq, void *ctxt)
 {
-       unsigned int len;
-       int accept = 0;
+       Authctxt *authctxt = ctxt;
+       u_int len;
+       int acceptit = 0;
        char *service = packet_get_string(&len);
-       packet_done();
+       packet_check_eom();
+
+       if (authctxt == NULL)
+               fatal("input_service_request: no authctxt");
 
        if (strcmp(service, "ssh-userauth") == 0) {
-               if (!userauth_success) {
-                       accept = 1;
+               if (!authctxt->success) {
+                       acceptit = 1;
                        /* now we can handle user-auth requests */
                        dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
                }
        }
        /* XXX all other service requests are denied */
 
-       if (accept) {
+       if (acceptit) {
                packet_start(SSH2_MSG_SERVICE_ACCEPT);
                packet_put_cstring(service);
                packet_send();
@@ -145,323 +209,199 @@ input_service_request(int type, int plen)
        xfree(service);
 }
 
-void
-input_userauth_request(int type, int plen)
+/*ARGSUSED*/
+static void
+input_userauth_request(int type, u_int32_t seq, void *ctxt)
 {
-       static void (*authlog) (const char *fmt,...) = verbose;
-       static int attempt = 0;
-       unsigned int len, rlen;
+       Authctxt *authctxt = ctxt;
+       Authmethod *m = NULL;
+       char *user, *service, *method, *style = NULL;
        int authenticated = 0;
-       char *raw, *user, *service, *method, *authmsg = NULL;
-       struct passwd *pw;
-
-       if (++attempt == AUTH_FAIL_MAX)
-               packet_disconnect("too many failed userauth_requests");
-
-       raw = packet_get_raw(&rlen);
-       if (plen != rlen)
-               fatal("plen != rlen");
-       user = packet_get_string(&len);
-       service = packet_get_string(&len);
-       method = packet_get_string(&len);
-       debug("userauth-request for user %s service %s method %s", user, service, method);
 
-       /* XXX we only allow the ssh-connection service */
-       pw = auth_set_user(user, service);
-       if (pw && strcmp(service, "ssh-connection")==0) {
-               if (strcmp(method, "none") == 0) {
-                       authenticated = ssh2_auth_none(pw);
-               } else if (strcmp(method, "password") == 0) {
-                       authenticated = ssh2_auth_password(pw);
-               } else if (strcmp(method, "publickey") == 0) {
-                       authenticated = ssh2_auth_pubkey(pw, raw, rlen);
+       if (authctxt == NULL)
+               fatal("input_userauth_request: no authctxt");
+
+       user = packet_get_string(NULL);
+       service = packet_get_string(NULL);
+       method = packet_get_string(NULL);
+       debug("userauth-request for user %s service %s method %s", user, service, method);
+       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+
+       if ((style = strchr(user, ':')) != NULL)
+               *style++ = 0;
+
+       if (authctxt->attempt++ == 0) {
+               /* setup auth context */
+               authctxt->pw = PRIVSEP(getpwnamallow(user));
+               authctxt->user = xstrdup(user);
+               if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+                       authctxt->valid = 1;
+                       debug2("input_userauth_request: setting up authctxt for %s", user);
+               } else {
+                       logit("input_userauth_request: invalid user %s", user);
+                       authctxt->pw = fakepw();
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_INVALID_USER));
+#endif
                }
+#ifdef USE_PAM
+               if (options.use_pam)
+                       PRIVSEP(start_pam(authctxt));
+#endif
+               setproctitle("%s%s", authctxt->valid ? user : "unknown",
+                   use_privsep ? " [net]" : "");
+               authctxt->service = xstrdup(service);
+               authctxt->style = style ? xstrdup(style) : NULL;
+               if (use_privsep)
+                       mm_inform_authserv(service, style);
+               userauth_banner();
+       } else if (strcmp(user, authctxt->user) != 0 ||
+           strcmp(service, authctxt->service) != 0) {
+               packet_disconnect("Change of username or service not allowed: "
+                   "(%s,%s) -> (%s,%s)",
+                   authctxt->user, authctxt->service, user, service);
        }
-       if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
-               authenticated = 0;
-               log("ROOT LOGIN REFUSED FROM %.200s",
-                   get_canonical_hostname());
-       }
+       /* reset state */
+       auth2_challenge_stop(authctxt);
+#ifdef JPAKE
+       auth2_jpake_stop(authctxt);
+#endif
 
-#ifdef USE_PAM
-               if (authenticated && !do_pam_account(pw->pw_name, NULL))
-                       authenticated = 0;
-#endif /* USE_PAM */
+#ifdef GSSAPI
+       /* XXX move to auth2_gssapi_stop() */
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+#endif
 
-       /* XXX todo: check if multiple auth methods are needed */
-       if (authenticated == 1) {
-               authmsg = "Accepted";
-               /* turn off userauth */
-               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
-               packet_start(SSH2_MSG_USERAUTH_SUCCESS);
-               packet_send();
-               packet_write_wait();
-               /* now we can break out */
-               userauth_success = 1;
-       } else if (authenticated == 0) {
-               authmsg = "Failed";
-               packet_start(SSH2_MSG_USERAUTH_FAILURE);
-               packet_put_cstring("publickey,password");       /* XXX dynamic */
-               packet_put_char(0);                             /* XXX partial success, unused */
-               packet_send();
-               packet_write_wait();
-       } else {
-               authmsg = "Postponed";
+       authctxt->postponed = 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);
        }
-       /* Raise logging level */
-       if (authenticated == 1||
-           attempt == AUTH_FAIL_LOG ||
-           strcmp(method, "password") == 0)
-               authlog = log;
-
-       authlog("%s %s for %.200s from %.200s port %d ssh2",
-               authmsg,
-               method,
-               pw && pw->pw_uid == 0 ? "ROOT" : user,
-               get_remote_ipaddr(),
-               get_remote_port());
+       userauth_finish(authctxt, authenticated, method);
 
        xfree(service);
        xfree(user);
        xfree(method);
 }
 
-int
-ssh2_auth_none(struct passwd *pw)
-{
-       packet_done();
-#ifdef USE_PAM
-       return auth_pam_password(pw, "");
-#else /* USE_PAM */
-       return auth_password(pw, "");
-#endif /* USE_PAM */
-}
-int
-ssh2_auth_password(struct passwd *pw)
-{
-       char *password;
-       int authenticated = 0;
-       int change;
-       unsigned int len;
-       change = packet_get_char();
-       if (change)
-               log("password change not supported");
-       password = packet_get_string(&len);
-       packet_done();
-       if (options.password_authentication &&
-#ifdef USE_PAM
-           auth_pam_password(pw, password) == 1)
-#else /* USE_PAM */
-           auth_password(pw, password) == 1)
-#endif /* USE_PAM */
-               authenticated = 1;
-       memset(password, 0, len);
-       xfree(password);
-       return authenticated;
-}
-int
-ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
+void
+userauth_finish(Authctxt *authctxt, int authenticated, char *method)
 {
-       Buffer b;
-       Key *key;
-       char *pkalg, *pkblob, *sig;
-       unsigned int alen, blen, slen;
-       int have_sig;
-       int authenticated = 0;
+       char *methods;
 
-       if (options.rsa_authentication == 0) {
-               debug("pubkey auth disabled");
-               return 0;
-       }
-       have_sig = packet_get_char();
-       pkalg = packet_get_string(&alen);
-       if (strcmp(pkalg, KEX_DSS) != 0) {
-               xfree(pkalg);
-               log("bad pkalg %s", pkalg);     /*XXX*/
-               return 0;
-       }
-       pkblob = packet_get_string(&blen);
-       key = dsa_key_from_blob(pkblob, blen);
-       if (key != NULL) {
-               if (have_sig) {
-                       sig = packet_get_string(&slen);
-                       packet_done();
-                       buffer_init(&b);
-                       buffer_append(&b, session_id2, session_id2_len);
-                       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
-                       if (slen + 4 > rlen)
-                               fatal("bad rlen/slen");
-                       buffer_append(&b, raw, rlen - slen - 4);
-#ifdef DEBUG_DSS
-                       buffer_dump(&b);
+       if (!authctxt->valid && authenticated)
+               fatal("INTERNAL ERROR: authenticated invalid user %s",
+                   authctxt->user);
+
+       /* Special handling for root */
+       if (authenticated && authctxt->pw->pw_uid == 0 &&
+           !auth_root_allowed(method)) {
+               authenticated = 0;
+#ifdef SSH_AUDIT_EVENTS
+               PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
 #endif
-                       /* test for correct signature */
-                       if (user_dsa_key_allowed(pw, key) &&
-                           dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
-                               authenticated = 1;
-                       buffer_clear(&b);
-                       xfree(sig);
-               } else {
-                       packet_done();
-                       debug("test key...");
-                       /* test whether pkalg/pkblob are acceptable */
-                       /* XXX fake reply and always send PK_OK ? */
-                       if (user_dsa_key_allowed(pw, key)) {
-                               packet_start(SSH2_MSG_USERAUTH_PK_OK);
-                               packet_put_string(pkalg, alen);
-                               packet_put_string(pkblob, blen);
-                               packet_send();
+       }
+
+#ifdef USE_PAM
+       if (options.use_pam && authenticated) {
+               if (!PRIVSEP(do_pam_account())) {
+                       /* if PAM returned a message, send it to the user */
+                       if (buffer_len(&loginmsg) > 0) {
+                               buffer_append(&loginmsg, "\0", 1);
+                               userauth_send_banner(buffer_ptr(&loginmsg));
                                packet_write_wait();
-                               authenticated = -1;
                        }
+                       fatal("Access denied for user %s by PAM account "
+                           "configuration", authctxt->user);
                }
-               key_free(key);
        }
-       xfree(pkalg);
-       xfree(pkblob);
-       return authenticated;
-}
+#endif
 
-/* set and get current user */
+#ifdef _UNICOS
+       if (authenticated && cray_access_denied(authctxt->user)) {
+               authenticated = 0;
+               fatal("Access denied for user %s.",authctxt->user);
+       }
+#endif /* _UNICOS */
 
-struct passwd*
-auth_get_user(void)
-{
-       return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
-}
+       /* Log before sending the reply */
+       auth_log(authctxt, authenticated, method, " ssh2");
 
-struct passwd*
-auth_set_user(char *u, char *s)
-{
-       struct passwd *pw, *copy;
-
-       if (authctxt == NULL) {
-               authctxt = xmalloc(sizeof(*authctxt));
-               authctxt->valid = 0;
-               authctxt->user = xstrdup(u);
-               authctxt->service = xstrdup(s);
-               setproctitle("%s", u);
-               pw = getpwnam(u);
-               if (!pw || !allowed_user(pw)) {
-                       log("auth_set_user: illegal user %s", u);
-                       return NULL;
-               }
-#ifdef USE_PAM
-               start_pam(pw);
-#endif
-               copy = &authctxt->pw;
-               memset(copy, 0, sizeof(*copy));
-               copy->pw_name = xstrdup(pw->pw_name);
-               copy->pw_passwd = xstrdup(pw->pw_passwd);
-               copy->pw_uid = pw->pw_uid;
-               copy->pw_gid = pw->pw_gid;
-               copy->pw_dir = xstrdup(pw->pw_dir);
-               copy->pw_shell = xstrdup(pw->pw_shell);
-               authctxt->valid = 1;
+       if (authctxt->postponed)
+               return;
+
+       /* XXX todo: check if multiple auth methods are needed */
+       if (authenticated == 1) {
+               /* turn off userauth */
+               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
+               packet_start(SSH2_MSG_USERAUTH_SUCCESS);
+               packet_send();
+               packet_write_wait();
+               /* now we can break out */
+               authctxt->success = 1;
        } else {
-               if (strcmp(u, authctxt->user) != 0 ||
-                   strcmp(s, authctxt->service) != 0) {
-                       log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
-                           u, s, authctxt->user, authctxt->service);
-                       return NULL;
+
+               /* Allow initial try of "none" auth without failure penalty */
+               if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
+                       authctxt->failures++;
+               if (authctxt->failures >= options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
+                       packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
                }
+               methods = authmethods_get();
+               packet_start(SSH2_MSG_USERAUTH_FAILURE);
+               packet_put_cstring(methods);
+               packet_put_char(0);     /* XXX partial success, unused */
+               packet_send();
+               packet_write_wait();
+               xfree(methods);
        }
-       return auth_get_user();
 }
 
-/* return 1 if user allows given key */
-int
-user_dsa_key_allowed(struct passwd *pw, Key *key)
+static char *
+authmethods_get(void)
 {
-       char line[8192], file[1024];
-       int found_key = 0;
-       unsigned int bits = -1;
-       FILE *f;
-       unsigned long linenum = 0;
-       struct stat st;
-       Key *found;
-
-       /* Temporarily use the user's uid. */
-       temporarily_use_uid(pw->pw_uid);
-
-       /* The authorized keys. */
-       snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
-           SSH_USER_PERMITTED_KEYS2);
+       Buffer b;
+       char *list;
+       int i;
 
-       /* Fail quietly if file does not exist */
-       if (stat(file, &st) < 0) {
-               /* Restore the privileged uid. */
-               restore_uid();
-               return 0;
-       }
-       /* Open the file containing the authorized keys. */
-       f = fopen(file, "r");
-       if (!f) {
-               /* Restore the privileged uid. */
-               restore_uid();
-               return 0;
-       }
-       if (options.strict_modes) {
-               int fail = 0;
-               char buf[1024];
-               /* Check open file in order to avoid open/stat races */
-               if (fstat(fileno(f), &st) < 0 ||
-                   (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-                   (st.st_mode & 022) != 0) {
-                       snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: "
-                           "bad ownership or modes for '%s'.", pw->pw_name, file);
-                       fail = 1;
-               } else {
-                       /* Check path to SSH_USER_PERMITTED_KEYS */
-                       int i;
-                       static const char *check[] = {
-                               "", SSH_USER_DIR, NULL
-                       };
-                       for (i = 0; check[i]; i++) {
-                               snprintf(line, sizeof line, "%.500s/%.100s",
-                                   pw->pw_dir, check[i]);
-                               if (stat(line, &st) < 0 ||
-                                   (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-                                   (st.st_mode & 022) != 0) {
-                                       snprintf(buf, sizeof buf,
-                                           "DSA authentication refused for %.100s: "
-                                           "bad ownership or modes for '%s'.",
-                                           pw->pw_name, line);
-                                       fail = 1;
-                                       break;
-                               }
-                       }
-               }
-               if (fail) {
-                       log(buf);
-                       fclose(f);
-                       restore_uid();
-                       return 0;
-               }
-       }
-       found_key = 0;
-       found = key_new(KEY_DSA);
-
-       while (fgets(line, sizeof(line), f)) {
-               char *cp;
-               linenum++;
-               /* Skip leading whitespace, empty and comment lines. */
-               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
-                       ;
-               if (!*cp || *cp == '\n' || *cp == '#')
+       buffer_init(&b);
+       for (i = 0; authmethods[i] != NULL; i++) {
+               if (strcmp(authmethods[i]->name, "none") == 0)
                        continue;
-               bits = key_read(found, &cp);
-               if (bits == 0)
-                       continue;
-               if (key_equal(found, key)) {
-                       found_key = 1;
-                       debug("matching key found: file %s, line %ld",
-                           file, linenum);
-                       break;
+               if (authmethods[i]->enabled != NULL &&
+                   *(authmethods[i]->enabled) != 0) {
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, authmethods[i]->name,
+                           strlen(authmethods[i]->name));
                }
        }
-       restore_uid();
-       fclose(f);
-       key_free(found);
-       return found_key;
+       buffer_append(&b, "\0", 1);
+       list = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
+       return list;
 }
+
+static Authmethod *
+authmethod_lookup(const char *name)
+{
+       int i;
+
+       if (name != NULL)
+               for (i = 0; authmethods[i] != NULL; i++)
+                       if (authmethods[i]->enabled != NULL &&
+                           *(authmethods[i]->enabled) != 0 &&
+                           strcmp(name, authmethods[i]->name) == 0)
+                               return authmethods[i];
+       debug2("Unrecognized authentication method name: %s",
+           name ? name : "NULL");
+       return NULL;
+}
+
This page took 0.059488 seconds and 4 git commands to generate.