]> andersk Git - openssh.git/blobdiff - auth2.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / auth2.c
diff --git a/auth2.c b/auth2.c
index 6bcc5652787fbac9e67e5205bee4291bb3331d3a..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.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.91 2002/05/13 02:37:39 itojun Exp $");
 
-#include <openssl/evp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
 
-#include "ssh2.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 "sshpty.h"
+#include "ssh2.h"
 #include "packet.h"
-#include "buffer.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "compat.h"
-#include "channels.h"
-#include "bufaux.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
-#include "session.h"
 #include "dispatch.h"
-#include "key.h"
-#include "cipher.h"
-#include "kex.h"
 #include "pathnames.h"
-#include "uidswap.h"
-#include "auth-options.h"
-#include "hostfile.h"
-#include "canohost.h"
-#include "match.h"
+#include "buffer.h"
+
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
-#include "atomicio.h"
 
 /* import */
 extern ServerOptions options;
 extern u_char *session_id2;
-extern int session_id2_len;
-
-Authctxt *x_authctxt = NULL;
-static int one = 1;
+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
 
-typedef struct Authmethod Authmethod;
-struct Authmethod {
-       char    *name;
-       int     (*userauth)(Authctxt *authctxt);
-       int     *enabled;
+Authmethod *authmethods[] = {
+       &method_none,
+       &method_pubkey,
+#ifdef GSSAPI
+       &method_gssapi,
+#endif
+#ifdef JPAKE
+       &method_jpake,
+#endif
+       &method_passwd,
+       &method_kbdint,
+       &method_hostbased,
+       NULL
 };
 
 /* protocol */
@@ -76,68 +98,90 @@ static void input_userauth_request(int, u_int32_t, void *);
 /* helper */
 static Authmethod *authmethod_lookup(const char *);
 static char *authmethods_get(void);
-int user_key_allowed(struct passwd *, Key *);
-int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
-
-/* auth */
-static void userauth_banner(void);
-static int userauth_none(Authctxt *);
-static int userauth_passwd(Authctxt *);
-static int userauth_pubkey(Authctxt *);
-static int userauth_hostbased(Authctxt *);
-static int userauth_kbdint(Authctxt *);
-
-Authmethod authmethods[] = {
-       {"none",
-               userauth_none,
-               &one},
-       {"publickey",
-               userauth_pubkey,
-               &options.pubkey_authentication},
-       {"password",
-               userauth_passwd,
-               &options.password_authentication},
-       {"keyboard-interactive",
-               userauth_kbdint,
-               &options.kbd_interactive_authentication},
-       {"hostbased",
-               userauth_hostbased,
-               &options.hostbased_authentication},
-       {NULL, NULL, NULL}
-};
 
-/*
- * loop until authctxt->success == TRUE
- */
+char *
+auth2_read_banner(void)
+{
+       struct stat st;
+       char *banner = NULL;
+       size_t len, n;
+       int fd;
 
-Authctxt *
-do_authentication2(void)
+       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);
+       }
+
+       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
+userauth_send_banner(const char *msg)
+{
+       if (datafellows & SSH_BUG_BANNER)
+               return;
+
+       packet_start(SSH2_MSG_USERAUTH_BANNER);
+       packet_put_cstring(msg);
+       packet_put_cstring("");         /* language, unused */
+       packet_send();
+       debug("%s: sent", __func__);
+}
+
+static void
+userauth_banner(void)
 {
-       Authctxt *authctxt = authctxt_new();
+       char *banner = NULL;
+
+       if (options.banner == NULL ||
+           strcasecmp(options.banner, "none") == 0 ||
+           (datafellows & SSH_BUG_BANNER) != 0)
+               return;
 
-       x_authctxt = authctxt;          /*XXX*/
+       if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+               goto done;
+       userauth_send_banner(banner);
 
-       /* challenge-response is implemented via keyboard interactive */
-       if (options.challenge_response_authentication)
-               options.kbd_interactive_authentication = 1;
-       if (options.pam_authentication_via_kbd_int)
-               options.kbd_interactive_authentication = 1;
-       if (use_privsep)
-               options.pam_authentication_via_kbd_int = 0;
+done:
+       if (banner)
+               xfree(banner);
+}
 
+/*
+ * loop until authctxt->success == TRUE
+ */
+void
+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);
-
-       return (authctxt);
 }
 
+/*ARGSUSED*/
 static void
 input_service_request(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        u_int len;
-       int accept = 0;
+       int acceptit = 0;
        char *service = packet_get_string(&len);
        packet_check_eom();
 
@@ -146,14 +190,14 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
 
        if (strcmp(service, "ssh-userauth") == 0) {
                if (!authctxt->success) {
-                       accept = 1;
+                       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();
@@ -165,6 +209,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
        xfree(service);
 }
 
+/*ARGSUSED*/
 static void
 input_userauth_request(int type, u_int32_t seq, void *ctxt)
 {
@@ -188,25 +233,28 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        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);
-#ifdef USE_PAM
-                       PRIVSEP(start_pam(authctxt->pw->pw_name));
-#endif
                } else {
-                       log("input_userauth_request: illegal user %s", user);
-#ifdef USE_PAM
-                       PRIVSEP(start_pam("NOUSER"));
+                       logit("input_userauth_request: invalid user %s", user);
+                       authctxt->pw = fakepw();
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_INVALID_USER));
 #endif
                }
-               setproctitle("%s%s", authctxt->pw ? user : "unknown",
+#ifdef USE_PAM
+               if (options.use_pam)
+                       PRIVSEP(start_pam(authctxt));
+#endif
+               setproctitle("%s%s", authctxt->valid ? user : "unknown",
                    use_privsep ? " [net]" : "");
-               authctxt->user = xstrdup(user);
                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: "
@@ -215,11 +263,21 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        }
        /* reset state */
        auth2_challenge_stop(authctxt);
+#ifdef JPAKE
+       auth2_jpake_stop(authctxt);
+#endif
+
+#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
+
        authctxt->postponed = 0;
 
        /* try to authenticate user */
        m = authmethod_lookup(method);
-       if (m != NULL) {
+       if (m != NULL && authctxt->failures < options.max_authtries) {
                debug2("input_userauth_request: try method %s", method);
                authenticated = m->userauth(authctxt);
        }
@@ -241,14 +299,34 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
 
        /* Special handling for root */
        if (authenticated && authctxt->pw->pw_uid == 0 &&
-           !auth_root_allowed(method))
+           !auth_root_allowed(method)) {
                authenticated = 0;
+#ifdef SSH_AUDIT_EVENTS
+               PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+#endif
+       }
 
 #ifdef USE_PAM
-       if (!use_privsep && authenticated && authctxt->user && 
-           !do_pam_account(authctxt->user, NULL))
+       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();
+                       }
+                       fatal("Access denied for user %s by PAM account "
+                           "configuration", authctxt->user);
+               }
+       }
+#endif
+
+#ifdef _UNICOS
+       if (authenticated && cray_access_denied(authctxt->user)) {
                authenticated = 0;
-#endif /* USE_PAM */
+               fatal("Access denied for user %s.",authctxt->user);
+       }
+#endif /* _UNICOS */
 
        /* Log before sending the reply */
        auth_log(authctxt, authenticated, method, " ssh2");
@@ -266,12 +344,14 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                /* now we can break out */
                authctxt->success = 1;
        } else {
-               if (authctxt->failures++ > AUTH_FAIL_MAX) {
-#ifdef WITH_AIXAUTHENTICATE
-                       loginfailed(authctxt->user,
-                           get_canonical_hostname(options.verify_reverse_mapping),
-                           "ssh");
-#endif /* WITH_AIXAUTHENTICATE */
+
+               /* 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();
@@ -284,352 +364,23 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
        }
 }
 
-char *
-auth2_read_banner(void)
-{
-       struct stat st;
-       char *banner = NULL;
-       off_t len, n;
-       int fd;
-
-       if ((fd = open(options.banner, O_RDONLY)) == -1)
-               return (NULL);
-       if (fstat(fd, &st) == -1) {
-               close(fd);
-               return (NULL);
-       }
-       len = st.st_size;
-       banner = xmalloc(len + 1);
-       n = atomicio(read, fd, banner, len);
-       close(fd);
-
-       if (n != len) {
-               free(banner);
-               return (NULL);
-       }
-       banner[n] = '\0';
-       
-       return (banner);
-}
-
-static void
-userauth_banner(void)
-{
-       char *banner = NULL;
-
-       if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
-               return;
-
-       if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
-               goto done;
-
-       packet_start(SSH2_MSG_USERAUTH_BANNER);
-       packet_put_cstring(banner);
-       packet_put_cstring("");         /* language, unused */
-       packet_send();
-       debug("userauth_banner: sent");
-done:
-       if (banner)
-               xfree(banner);
-       return;
-}
-
-static int
-userauth_none(Authctxt *authctxt)
-{
-       /* disable method "none", only allowed one time */
-       Authmethod *m = authmethod_lookup("none");
-       if (m != NULL)
-               m->enabled = NULL;
-       packet_check_eom();
-       userauth_banner();
-
-       if (authctxt->valid == 0)
-               return(0);
-
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(1, authctxt->pw) == 0)
-               return(0);
-#endif
-       return PRIVSEP(auth_password(authctxt, ""));
-}
-
-static int
-userauth_passwd(Authctxt *authctxt)
-{
-       char *password;
-       int authenticated = 0;
-       int change;
-       u_int len;
-       change = packet_get_char();
-       if (change)
-               log("password change not supported");
-       password = packet_get_string(&len);
-       packet_check_eom();
-       if (authctxt->valid &&
-#ifdef HAVE_CYGWIN
-           check_nt_auth(1, authctxt->pw) &&
-#endif
-           PRIVSEP(auth_password(authctxt, password)) == 1)
-               authenticated = 1;
-       memset(password, 0, len);
-       xfree(password);
-       return authenticated;
-}
-
-static int
-userauth_kbdint(Authctxt *authctxt)
-{
-       int authenticated = 0;
-       char *lang, *devs;
-
-       lang = packet_get_string(NULL);
-       devs = packet_get_string(NULL);
-       packet_check_eom();
-
-       debug("keyboard-interactive devs %s", devs);
-
-       if (options.challenge_response_authentication)
-               authenticated = auth2_challenge(authctxt, devs);
-
-#ifdef USE_PAM
-       if (authenticated == 0 && options.pam_authentication_via_kbd_int)
-               authenticated = auth2_pam(authctxt);
-#endif
-       xfree(devs);
-       xfree(lang);
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw) == 0)
-               return(0);
-#endif
-       return authenticated;
-}
-
-static int
-userauth_pubkey(Authctxt *authctxt)
-{
-       Buffer b;
-       Key *key = NULL;
-       char *pkalg;
-       u_char *pkblob, *sig;
-       u_int alen, blen, slen;
-       int have_sig, pktype;
-       int authenticated = 0;
-
-       if (!authctxt->valid) {
-               debug2("userauth_pubkey: disabled because of invalid user");
-               return 0;
-       }
-       have_sig = packet_get_char();
-       if (datafellows & SSH_BUG_PKAUTH) {
-               debug2("userauth_pubkey: SSH_BUG_PKAUTH");
-               /* no explicit pkalg given */
-               pkblob = packet_get_string(&blen);
-               buffer_init(&b);
-               buffer_append(&b, pkblob, blen);
-               /* so we have to extract the pkalg from the pkblob */
-               pkalg = buffer_get_string(&b, &alen);
-               buffer_free(&b);
-       } else {
-               pkalg = packet_get_string(&alen);
-               pkblob = packet_get_string(&blen);
-       }
-       pktype = key_type_from_name(pkalg);
-       if (pktype == KEY_UNSPEC) {
-               /* this is perfectly legal */
-               log("userauth_pubkey: unsupported public key algorithm: %s",
-                   pkalg);
-               goto done;
-       }
-       key = key_from_blob(pkblob, blen);
-       if (key == NULL) {
-               error("userauth_pubkey: cannot decode key: %s", pkalg);
-               goto done;
-       }
-       if (key->type != pktype) {
-               error("userauth_pubkey: type mismatch for decoded key "
-                   "(received %d, expected %d)", key->type, pktype);
-               goto done;
-       }
-       if (have_sig) {
-               sig = packet_get_string(&slen);
-               packet_check_eom();
-               buffer_init(&b);
-               if (datafellows & SSH_OLD_SESSIONID) {
-                       buffer_append(&b, session_id2, session_id2_len);
-               } else {
-                       buffer_put_string(&b, session_id2, session_id2_len);
-               }
-               /* reconstruct packet */
-               buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
-               buffer_put_cstring(&b, authctxt->user);
-               buffer_put_cstring(&b,
-                   datafellows & SSH_BUG_PKSERVICE ?
-                   "ssh-userauth" :
-                   authctxt->service);
-               if (datafellows & SSH_BUG_PKAUTH) {
-                       buffer_put_char(&b, have_sig);
-               } else {
-                       buffer_put_cstring(&b, "publickey");
-                       buffer_put_char(&b, have_sig);
-                       buffer_put_cstring(&b, pkalg);
-               }
-               buffer_put_string(&b, pkblob, blen);
-#ifdef DEBUG_PK
-               buffer_dump(&b);
-#endif
-               /* test for correct signature */
-               authenticated = 0;
-               if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
-                   PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
-                               buffer_len(&b))) == 1)
-                       authenticated = 1;
-               buffer_clear(&b);
-               xfree(sig);
-       } else {
-               debug("test whether pkalg/pkblob are acceptable");
-               packet_check_eom();
-
-               /* XXX fake reply and always send PK_OK ? */
-               /*
-                * XXX this allows testing whether a user is allowed
-                * to login: if you happen to have a valid pubkey this
-                * message is sent. the message is NEVER sent at all
-                * if a user is not allowed to login. is this an
-                * issue? -markus
-                */
-               if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
-                       packet_start(SSH2_MSG_USERAUTH_PK_OK);
-                       packet_put_string(pkalg, alen);
-                       packet_put_string(pkblob, blen);
-                       packet_send();
-                       packet_write_wait();
-                       authctxt->postponed = 1;
-               }
-       }
-       if (authenticated != 1)
-               auth_clear_options();
-done:
-       debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
-       if (key != NULL)
-               key_free(key);
-       xfree(pkalg);
-       xfree(pkblob);
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw) == 0)
-               return(0);
-#endif
-       return authenticated;
-}
-
-static int
-userauth_hostbased(Authctxt *authctxt)
-{
-       Buffer b;
-       Key *key = NULL;
-       char *pkalg, *cuser, *chost, *service;
-       u_char *pkblob, *sig;
-       u_int alen, blen, slen;
-       int pktype;
-       int authenticated = 0;
-
-       if (!authctxt->valid) {
-               debug2("userauth_hostbased: disabled because of invalid user");
-               return 0;
-       }
-       pkalg = packet_get_string(&alen);
-       pkblob = packet_get_string(&blen);
-       chost = packet_get_string(NULL);
-       cuser = packet_get_string(NULL);
-       sig = packet_get_string(&slen);
-
-       debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
-           cuser, chost, pkalg, slen);
-#ifdef DEBUG_PK
-       debug("signature:");
-       buffer_init(&b);
-       buffer_append(&b, sig, slen);
-       buffer_dump(&b);
-       buffer_free(&b);
-#endif
-       pktype = key_type_from_name(pkalg);
-       if (pktype == KEY_UNSPEC) {
-               /* this is perfectly legal */
-               log("userauth_hostbased: unsupported "
-                   "public key algorithm: %s", pkalg);
-               goto done;
-       }
-       key = key_from_blob(pkblob, blen);
-       if (key == NULL) {
-               error("userauth_hostbased: cannot decode key: %s", pkalg);
-               goto done;
-       }
-       if (key->type != pktype) {
-               error("userauth_hostbased: type mismatch for decoded key "
-                   "(received %d, expected %d)", key->type, pktype);
-               goto done;
-       }
-       service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
-           authctxt->service;
-       buffer_init(&b);
-       buffer_put_string(&b, session_id2, session_id2_len);
-       /* reconstruct packet */
-       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
-       buffer_put_cstring(&b, authctxt->user);
-       buffer_put_cstring(&b, service);
-       buffer_put_cstring(&b, "hostbased");
-       buffer_put_string(&b, pkalg, alen);
-       buffer_put_string(&b, pkblob, blen);
-       buffer_put_cstring(&b, chost);
-       buffer_put_cstring(&b, cuser);
-#ifdef DEBUG_PK
-       buffer_dump(&b);
-#endif
-       /* test for allowed key and correct signature */
-       authenticated = 0;
-       if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
-           PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
-                       buffer_len(&b))) == 1)
-               authenticated = 1;
-
-       buffer_clear(&b);
-done:
-       debug2("userauth_hostbased: authenticated %d", authenticated);
-       if (key != NULL)
-               key_free(key);
-       xfree(pkalg);
-       xfree(pkblob);
-       xfree(cuser);
-       xfree(chost);
-       xfree(sig);
-       return authenticated;
-}
-
-/* get current user */
-
-struct passwd*
-auth_get_user(void)
-{
-       return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
-}
-
-#define        DELIM   ","
-
 static char *
 authmethods_get(void)
 {
-       Authmethod *method = NULL;
        Buffer b;
        char *list;
+       int i;
 
        buffer_init(&b);
-       for (method = authmethods; method->name != NULL; method++) {
-               if (strcmp(method->name, "none") == 0)
+       for (i = 0; authmethods[i] != NULL; i++) {
+               if (strcmp(authmethods[i]->name, "none") == 0)
                        continue;
-               if (method->enabled != NULL && *(method->enabled) != 0) {
+               if (authmethods[i]->enabled != NULL &&
+                   *(authmethods[i]->enabled) != 0) {
                        if (buffer_len(&b) > 0)
                                buffer_append(&b, ",", 1);
-                       buffer_append(&b, method->name, strlen(method->name));
+                       buffer_append(&b, authmethods[i]->name,
+                           strlen(authmethods[i]->name));
                }
        }
        buffer_append(&b, "\0", 1);
@@ -641,174 +392,16 @@ authmethods_get(void)
 static Authmethod *
 authmethod_lookup(const char *name)
 {
-       Authmethod *method = NULL;
+       int i;
+
        if (name != NULL)
-               for (method = authmethods; method->name != NULL; method++)
-                       if (method->enabled != NULL &&
-                           *(method->enabled) != 0 &&
-                           strcmp(name, method->name) == 0)
-                               return method;
-       debug2("Unrecognized authentication method name: %s", name ? 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;
 }
 
-/* return 1 if user allows given key */
-static int
-user_key_allowed2(struct passwd *pw, Key *key, char *file)
-{
-       char line[8192];
-       int found_key = 0;
-       FILE *f;
-       u_long linenum = 0;
-       struct stat st;
-       Key *found;
-       char *fp;
-
-       if (pw == NULL)
-               return 0;
-
-       /* Temporarily use the user's uid. */
-       temporarily_use_uid(pw);
-
-       debug("trying public key file %s", file);
-
-       /* 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 &&
-           secure_filename(f, file, pw, line, sizeof(line)) != 0) {
-               fclose(f);
-               log("Authentication refused: %s", line);
-               restore_uid();
-               return 0;
-       }
-
-       found_key = 0;
-       found = key_new(key->type);
-
-       while (fgets(line, sizeof(line), f)) {
-               char *cp, *options = NULL;
-               linenum++;
-               /* Skip leading whitespace, empty and comment lines. */
-               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
-                       ;
-               if (!*cp || *cp == '\n' || *cp == '#')
-                       continue;
-
-               if (key_read(found, &cp) != 1) {
-                       /* no key?  check if there are options for this key */
-                       int quoted = 0;
-                       debug2("user_key_allowed: check options: '%s'", cp);
-                       options = cp;
-                       for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
-                               if (*cp == '\\' && cp[1] == '"')
-                                       cp++;   /* Skip both */
-                               else if (*cp == '"')
-                                       quoted = !quoted;
-                       }
-                       /* Skip remaining whitespace. */
-                       for (; *cp == ' ' || *cp == '\t'; cp++)
-                               ;
-                       if (key_read(found, &cp) != 1) {
-                               debug2("user_key_allowed: advance: '%s'", cp);
-                               /* still no key?  advance to next line*/
-                               continue;
-                       }
-               }
-               if (key_equal(found, key) &&
-                   auth_parse_options(pw, options, file, linenum) == 1) {
-                       found_key = 1;
-                       debug("matching key found: file %s, line %lu",
-                           file, linenum);
-                       fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
-                       verbose("Found matching %s key: %s",
-                           key_type(found), fp);
-                       xfree(fp);
-                       break;
-               }
-       }
-       restore_uid();
-       fclose(f);
-       key_free(found);
-       if (!found_key)
-               debug2("key not found");
-       return found_key;
-}
-
-/* check whether given key is in .ssh/authorized_keys* */
-int
-user_key_allowed(struct passwd *pw, Key *key)
-{
-       int success;
-       char *file;
-
-       file = authorized_keys_file(pw);
-       success = user_key_allowed2(pw, key, file);
-       xfree(file);
-       if (success)
-               return success;
-
-       /* try suffix "2" for backward compat, too */
-       file = authorized_keys_file2(pw);
-       success = user_key_allowed2(pw, key, file);
-       xfree(file);
-       return success;
-}
-
-/* return 1 if given hostkey is allowed */
-int
-hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
-    Key *key)
-{
-       const char *resolvedname, *ipaddr, *lookup;
-       HostStatus host_status;
-       int len;
-
-       resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
-       ipaddr = get_remote_ipaddr();
-
-       debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
-           chost, resolvedname, ipaddr);
-
-       if (options.hostbased_uses_name_from_packet_only) {
-               if (auth_rhosts2(pw, cuser, chost, chost) == 0)
-                       return 0;
-               lookup = chost;
-       } else {
-               if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
-                       debug2("stripping trailing dot from chost %s", chost);
-                       chost[len - 1] = '\0';
-               }
-               if (strcasecmp(resolvedname, chost) != 0)
-                       log("userauth_hostbased mismatch: "
-                           "client sends %s, but we resolve %s to %s",
-                           chost, ipaddr, resolvedname);
-               if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
-                       return 0;
-               lookup = resolvedname;
-       }
-       debug2("userauth_hostbased: access allowed by auth_rhosts2");
-
-       host_status = check_key_in_hostfiles(pw, key, lookup,
-           _PATH_SSH_SYSTEM_HOSTFILE,
-           options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
-
-       /* backward compat if no key has been found. */
-       if (host_status == HOST_NEW)
-               host_status = check_key_in_hostfiles(pw, key, lookup,
-                   _PATH_SSH_SYSTEM_HOSTFILE2,
-                   options.ignore_user_known_hosts ? NULL :
-                   _PATH_SSH_USER_HOSTFILE2);
-
-       return (host_status == HOST_OK);
-}
This page took 5.035202 seconds and 4 git commands to generate.