]> andersk Git - openssh.git/blobdiff - auth2.c
- (djm) Swapped tests for no_libsocket and no_libnsl in configure.in.
[openssh.git] / auth2.c
diff --git a/auth2.c b/auth2.c
index a0e6d577e27bce62cf5298c3a6a417f3ada05ec4..88fca2c9bb5734bd81847e211bdf8f5b6224ede5 100644 (file)
--- a/auth2.c
+++ b/auth2.c
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.23 2000/12/19 23:17:55 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.42 2001/02/13 22:49:40 markus Exp $");
 
-#ifdef HAVE_OSF_SIA
-# include <sia.h>
-# include <siad.h>
-#endif
-
-#include <openssl/dsa.h>
-#include <openssl/rsa.h>
 #include <openssl/evp.h>
 
+#include "ssh2.h"
 #include "xmalloc.h"
 #include "rsa.h"
-#include "ssh.h"
 #include "pty.h"
 #include "packet.h"
 #include "buffer.h"
+#include "log.h"
 #include "servconf.h"
 #include "compat.h"
 #include "channels.h"
 #include "bufaux.h"
-#include "ssh2.h"
 #include "auth.h"
 #include "session.h"
 #include "dispatch.h"
-#include "auth.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
-
+#include "pathnames.h"
 #include "uidswap.h"
 #include "auth-options.h"
 
@@ -63,10 +56,6 @@ extern int session_id2_len;
 #ifdef WITH_AIXAUTHENTICATE
 extern char *aixloginmsg;
 #endif
-#ifdef HAVE_OSF_SIA
-extern int saved_argc;
-extern char **saved_argv;
-#endif
 
 static Authctxt        *x_authctxt = NULL;
 static int one = 1;
@@ -84,7 +73,6 @@ void  input_service_request(int type, int plen, void *ctxt);
 void   input_userauth_request(int type, int plen, void *ctxt);
 void   protocol_error(int type, int plen, void *ctxt);
 
-
 /* helper */
 Authmethod     *authmethod_lookup(const char *name);
 struct passwd  *pwcopy(struct passwd *pw);
@@ -92,6 +80,7 @@ int   user_key_allowed(struct passwd *pw, Key *key);
 char   *authmethods_get(void);
 
 /* auth */
+void   userauth_banner(void);
 int    userauth_none(Authctxt *authctxt);
 int    userauth_passwd(Authctxt *authctxt);
 int    userauth_pubkey(Authctxt *authctxt);
@@ -104,12 +93,12 @@ Authmethod authmethods[] = {
        {"publickey",
                userauth_pubkey,
                &options.pubkey_authentication},
-       {"keyboard-interactive",
-               userauth_kbdint,
-               &options.kbd_interactive_authentication},
        {"password",
                userauth_passwd,
                &options.password_authentication},
+       {"keyboard-interactive",
+               userauth_kbdint,
+               &options.kbd_interactive_authentication},
        {NULL, NULL, NULL}
 };
 
@@ -120,21 +109,18 @@ Authmethod authmethods[] = {
 void
 do_authentication2()
 {
-       Authctxt *authctxt = xmalloc(sizeof(*authctxt));
-       memset(authctxt, 'a', sizeof(*authctxt));
-       authctxt->valid = 0;
-       authctxt->attempt = 0;
-       authctxt->success = 0;
+       Authctxt *authctxt = authctxt_new();
+
        x_authctxt = authctxt;          /*XXX*/
 
-#ifdef KRB4
-       /* turn off kerberos, not supported by SSH2 */
-       options.kerberos_authentication = 0;
-#endif
+       /* challenge-reponse is implemented via keyboard interactive */
+       if (options.challenge_reponse_authentication)
+               options.kbd_interactive_authentication = 1;
+
        dispatch_init(&protocol_error);
        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
        dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
-       do_authenticated2();
+       do_authenticated2(authctxt);
 }
 
 void
@@ -185,42 +171,42 @@ input_userauth_request(int type, int plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Authmethod *m = NULL;
-       char *user, *service, *method;
+       char *user, *service, *method, *style = NULL;
        int authenticated = 0;
 
        if (authctxt == NULL)
                fatal("input_userauth_request: no authctxt");
-       if (authctxt->attempt++ >= AUTH_FAIL_MAX) {
-#ifdef WITH_AIXAUTHENTICATE 
-               loginfailed(authctxt->user?authctxt->user:"NOUSER", 
-                       get_canonical_hostname(), "ssh");
-#endif /* WITH_AIXAUTHENTICATE */
-               packet_disconnect("too many failed userauth_requests");
-       }
 
        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", authctxt->attempt);
+       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+
+       if ((style = strchr(user, ':')) != NULL)
+               *style++ = 0;
 
-       if (authctxt->attempt == 1) { 
+       if (authctxt->attempt++ == 0) {
                /* setup auth context */
                struct passwd *pw = NULL;
-               setproctitle("%s", user);
                pw = getpwnam(user);
                if (pw && allowed_user(pw) && strcmp(service, "ssh-connection")==0) {
                        authctxt->pw = pwcopy(pw);
                        authctxt->valid = 1;
                        debug2("input_userauth_request: setting up authctxt for %s", user);
 #ifdef USE_PAM
-                       start_pam(pw);
+                       start_pam(pw->pw_name);
 #endif
                } else {
                        log("input_userauth_request: illegal user %s", user);
+#ifdef USE_PAM
+                       start_pam("NOUSER");
+#endif
                }
+               setproctitle("%s", pw ? user : "unknown");
                authctxt->user = xstrdup(user);
                authctxt->service = xstrdup(service);
+               authctxt->style = style ? xstrdup(style) : NULL; /* currently unused */
        } else if (authctxt->valid) {
                if (strcmp(user, authctxt->user) != 0 ||
                    strcmp(service, authctxt->service) != 0) {
@@ -229,85 +215,88 @@ input_userauth_request(int type, int plen, void *ctxt)
                        authctxt->valid = 0;
                }
        }
+       /* reset state */
+       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error);
+       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);
-       } else {
-               debug2("input_userauth_request: unsupported method %s", method);
-       }
-       if (!authctxt->valid && authenticated == 1) {
-               log("input_userauth_request: INTERNAL ERROR: authenticated invalid user %s service %s", user, method);
-               authenticated = 0;
        }
+       if (!authctxt->valid && authenticated)
+               fatal("INTERNAL ERROR: authenticated invalid user %s",
+                   authctxt->user);
 
        /* Special handling for root */
-       if (authenticated == 1 &&
-           authctxt->valid && authctxt->pw->pw_uid == 0 && !options.permit_root_login) {
+       if (authenticated && authctxt->pw->pw_uid == 0 &&
+           !auth_root_allowed(method))
                authenticated = 0;
-               log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname());
-       }
 
 #ifdef USE_PAM
-       if (authenticated && authctxt->user && !do_pam_account(authctxt->user, NULL))
+       if (authenticated && authctxt->user && !do_pam_account(authctxt->user,
+           NULL))
                authenticated = 0;
 #endif /* USE_PAM */
 
        /* Log before sending the reply */
-       userauth_log(authctxt, authenticated, method);
-       userauth_reply(authctxt, authenticated);
+       auth_log(authctxt, authenticated, method, " ssh2");
+
+       if (!authctxt->postponed)
+               userauth_reply(authctxt, authenticated);
 
        xfree(service);
        xfree(user);
        xfree(method);
 }
 
-
 void
-userauth_log(Authctxt *authctxt, int authenticated, char *method)
+userauth_banner(void)
 {
-       void (*authlog) (const char *fmt,...) = verbose;
-       char *user = NULL, *authmsg = NULL;
-
-       /* Raise logging level */
-       if (authenticated == 1 ||
-           !authctxt->valid ||
-           authctxt->attempt >= AUTH_FAIL_LOG ||
-           strcmp(method, "password") == 0)
-               authlog = log;
-
-       if (authenticated == 1) {
-               authmsg = "Accepted";
-       } else if (authenticated == 0) {
-               authmsg = "Failed";
-       } else {
-               authmsg = "Postponed";
-       }
-
-       if (authctxt->valid) {
-               user = authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user;
-       } else {
-               user = "NOUSER";
+       struct stat st;
+       char *banner = NULL;
+       off_t len, n;
+       int fd;
+
+       if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
+               return;
+       if ((fd = open(options.banner, O_RDONLY)) < 0) {
+               error("userauth_banner: open %s failed: %s",
+                   options.banner, strerror(errno));
+               return;
        }
-
-       authlog("%s %s for %.200s from %.200s port %d ssh2",
-           authmsg,
-           method,
-           user,
-           get_remote_ipaddr(),
-           get_remote_port());
+       if (fstat(fd, &st) < 0)
+               goto done;
+       len = st.st_size;
+       banner = xmalloc(len + 1);
+       if ((n = read(fd, banner, len)) < 0)
+               goto done;
+       banner[n] = '\0';
+       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);
+       close(fd);
+       return;
 }
 
-void   
+void
 userauth_reply(Authctxt *authctxt, int authenticated)
 {
+       char *methods;
+
        /* XXX todo: check if multiple auth methods are needed */
        if (authenticated == 1) {
 #ifdef WITH_AIXAUTHENTICATE
                /* We don't have a pty yet, so just label the line as "ssh" */
-               if (loginsuccess(authctxt->user?authctxt->user:"NOUSER", 
-                       get_canonical_hostname(), "ssh", &aixloginmsg) < 0)
+               if (loginsuccess(authctxt->user?authctxt->user:"NOUSER",
+                   get_canonical_hostname(options.reverse_mapping_check),
+                   "ssh", &aixloginmsg) < 0)
                        aixloginmsg = NULL;
 #endif /* WITH_AIXAUTHENTICATE */
                /* turn off userauth */
@@ -317,16 +306,16 @@ userauth_reply(Authctxt *authctxt, int authenticated)
                packet_write_wait();
                /* now we can break out */
                authctxt->success = 1;
-       } else if (authenticated == 0) {
-               char *methods = authmethods_get();
+       } else {
+               if (authctxt->failures++ > AUTH_FAIL_MAX)
+                       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);
-       } else {
-               /* do nothing, we did already send a reply */
        }
 }
 
@@ -338,10 +327,11 @@ userauth_none(Authctxt *authctxt)
        if (m != NULL)
                m->enabled = NULL;
        packet_done();
+       userauth_banner();
 
        if (authctxt->valid == 0)
                return(0);
-               
+
 #ifdef HAVE_CYGWIN
        if (check_nt_auth(1, authctxt->pw->pw_uid) == 0)
                return(0);
@@ -349,9 +339,7 @@ userauth_none(Authctxt *authctxt)
 #ifdef USE_PAM
        return auth_pam_password(authctxt->pw, "");
 #elif defined(HAVE_OSF_SIA)
-       return (sia_validate_user(NULL, saved_argc, saved_argv, 
-               get_canonical_hostname(), authctxt->user?authctxt->user:"NOUSER", 
-                       NULL, 0, NULL, "") == SIASUCCESS);
+       return 0;
 #else /* !HAVE_OSF_SIA && !USE_PAM */
        return auth_password(authctxt->pw, "");
 #endif /* USE_PAM */
@@ -376,9 +364,7 @@ userauth_passwd(Authctxt *authctxt)
 #ifdef USE_PAM
            auth_pam_password(authctxt->pw, password) == 1)
 #elif defined(HAVE_OSF_SIA)
-           sia_validate_user(NULL, saved_argc, saved_argv, 
-                       get_canonical_hostname(), authctxt->user?authctxt->user:"NOUSER", 
-                       NULL, 0, NULL, password) == SIASUCCESS)
+           auth_sia_password(authctxt->user, password) == 1)
 #else /* !USE_PAM && !HAVE_OSF_SIA */
            auth_password(authctxt->pw, password) == 1)
 #endif /* USE_PAM */
@@ -400,15 +386,13 @@ userauth_kbdint(Authctxt *authctxt)
        packet_done();
 
        debug("keyboard-interactive language %s devs %s", lang, devs);
+
+       if (options.challenge_reponse_authentication)
+               authenticated = auth2_challenge(authctxt, devs);
+
 #ifdef USE_PAM
        if (authenticated == 0)
                authenticated = auth2_pam(authctxt);
-#endif
-#ifdef SKEY
-       /* XXX hardcoded, we should look at devs */
-       if (authenticated == 0)
-               if (options.skey_authentication != 0)
-                       authenticated = auth2_skey(authctxt);
 #endif
        xfree(lang);
        xfree(devs);
@@ -508,7 +492,7 @@ userauth_pubkey(Authctxt *authctxt)
                                packet_put_string(pkblob, blen);
                                packet_send();
                                packet_write_wait();
-                               authenticated = -1;
+                               authctxt->postponed = 1;
                        }
                }
                if (authenticated != 1)
@@ -585,7 +569,7 @@ authmethod_lookup(const char *name)
 int
 user_key_allowed(struct passwd *pw, Key *key)
 {
-       char line[8192], file[1024];
+       char line[8192], file[MAXPATHLEN];
        int found_key = 0;
        FILE *f;
        u_long linenum = 0;
@@ -600,7 +584,7 @@ user_key_allowed(struct passwd *pw, Key *key)
 
        /* The authorized keys. */
        snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
-           SSH_USER_PERMITTED_KEYS2);
+           _PATH_SSH_USER_PERMITTED_KEYS2);
 
        /* Fail quietly if file does not exist */
        if (stat(file, &st) < 0) {
@@ -628,10 +612,10 @@ user_key_allowed(struct passwd *pw, Key *key)
                            key_type(key), pw->pw_name, file);
                        fail = 1;
                } else {
-                       /* Check path to SSH_USER_PERMITTED_KEYS */
+                       /* Check path to _PATH_SSH_USER_PERMITTED_KEYS */
                        int i;
                        static const char *check[] = {
-                               "", SSH_USER_DIR, NULL
+                               "", _PATH_SSH_USER_DIR, NULL
                        };
                        for (i = 0; check[i]; i++) {
                                snprintf(line, sizeof line, "%.500s/%.100s",
@@ -688,7 +672,7 @@ user_key_allowed(struct passwd *pw, Key *key)
                        }
                }
                if (key_equal(found, key) &&
-                   auth_parse_options(pw, options, linenum) == 1) {
+                   auth_parse_options(pw, options, file, linenum) == 1) {
                        found_key = 1;
                        debug("matching key found: file %s, line %ld",
                            file, linenum);
@@ -700,20 +684,3 @@ user_key_allowed(struct passwd *pw, Key *key)
        key_free(found);
        return found_key;
 }
-
-struct passwd *
-pwcopy(struct passwd *pw)
-{
-       struct passwd *copy = xmalloc(sizeof(*copy));
-       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;
-#ifdef HAVE_PW_CLASS_IN_PASSWD
-       copy->pw_class = xstrdup(pw->pw_class);
-#endif
-       copy->pw_dir = xstrdup(pw->pw_dir);
-       copy->pw_shell = xstrdup(pw->pw_shell);
-       return copy;
-}
This page took 0.051895 seconds and 4 git commands to generate.