]> andersk Git - gssapi-openssh.git/blobdiff - openssh/auth2.c
merging OPENSSH_5_2P1_SIMON_20090726_HPN13V6 to trunk:
[gssapi-openssh.git] / openssh / auth2.c
index c6c983a3784b7b53ef250411e7b1bddeaae84203..1cd3e10364ee7df583ae46718936e226999d6112 100644 (file)
@@ -70,8 +70,10 @@ extern Authmethod method_passwd;
 extern Authmethod method_kbdint;
 extern Authmethod method_hostbased;
 #ifdef GSSAPI
+extern Authmethod method_external;
 extern Authmethod method_gsskeyex;
 extern Authmethod method_gssapi;
+extern Authmethod method_gssapi_compat;
 #endif
 #ifdef JPAKE
 extern Authmethod method_jpake;
@@ -85,7 +87,9 @@ Authmethod *authmethods[] = {
        &method_pubkey,
 #ifdef GSSAPI
        &method_gsskeyex,
+       &method_external,
        &method_gssapi,
+       &method_gssapi_compat,
 #endif
 #ifdef JPAKE
        &method_jpake,
@@ -230,10 +234,32 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        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);
+
+#ifdef GSSAPI
+       if (user[0] == '\0') {
+           debug("received empty username for %s", method);
+           if (strcmp(method, "external-keyx") == 0 ||
+               strcmp(method, "gssapi-keyex") == 0) {
+               char *lname = NULL;
+               PRIVSEP(ssh_gssapi_localname(&lname));
+               if (lname && lname[0] != '\0') {
+                   xfree(user);
+                   user = lname;
+                   debug("set username to %s from gssapi context", user);
+               } else {
+                   debug("failed to set username from gssapi context");
+                   packet_send_debug("failed to set username from gssapi context");
+               }
+           }
+       }
+#endif
+
+       debug("userauth-request for user %s service %s method %s",
+             user[0] ? user : "<implicit>", service, method);
        if (!log_flag) {
                logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
-                     get_remote_ipaddr(), get_remote_port(), user);
+                     get_remote_ipaddr(), get_remote_port(),
+              user[0] ? user : "<implicit>");
                log_flag = 1;
        }
        debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
@@ -241,11 +267,32 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        if ((style = strchr(user, ':')) != NULL)
                *style++ = 0;
 
-       if (authctxt->attempt++ == 0) {
-               /* setup auth context */
+       /* If first time or username changed or empty username,
+          setup/reset authentication context. */
+       if ((authctxt->attempt++ == 0) ||
+           (strcmp(user, authctxt->user) != 0) ||
+           (strcmp(user, "") == 0)) {
+               if (authctxt->user) {
+                   xfree(authctxt->user);
+                   authctxt->user = NULL;
+               }
+               authctxt->valid = 0;
+        authctxt->user = xstrdup(user);
+        if (strcmp(service, "ssh-connection") != 0) {
+            packet_disconnect("Unsupported service %s", service);
+        }
+#ifdef GSSAPI
+               /* If we're going to set the username based on the
+                  GSSAPI context later, then wait until then to
+                  verify it. Just put in placeholders for now. */
+               if ((strcmp(user, "") == 0) &&
+                   ((strcmp(method, "gssapi") == 0) ||
+                    (strcmp(method, "gssapi-with-mic") == 0))) {
+                       authctxt->pw = fakepw();
+               } else {
+#endif
                authctxt->pw = PRIVSEP(getpwnamallow(user));
-               authctxt->user = xstrdup(user);
-               if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+               if (authctxt->pw) {
                        authctxt->valid = 1;
                        debug2("input_userauth_request: setting up authctxt for %s", user);
                } else {
@@ -255,20 +302,25 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
                        PRIVSEP(audit_event(SSH_INVALID_USER));
 #endif
                }
+#ifdef GSSAPI
+               } /* endif for setting username based on GSSAPI context */
+#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: "
+               if (authctxt->attempt == 1) {
+            authctxt->service = xstrdup(service);
+            authctxt->style = style ? xstrdup(style) : NULL;
+            if (use_privsep)
+                mm_inform_authserv(service, style);
+            userauth_banner();
+               }
+       }
+       if (strcmp(service, authctxt->service) != 0) {
+               packet_disconnect("Change of service not allowed: "
                    "(%s,%s) -> (%s,%s)",
                    authctxt->user, authctxt->service, user, service);
        }
@@ -356,7 +408,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                /* now we can break out */
                authctxt->success = 1;
        } else {
-
+               /* Dont count server configuration issues against the client */
                /* Allow initial try of "none" auth without failure penalty */
                if (!authctxt->server_caused_failure &&
                    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
This page took 0.038766 seconds and 4 git commands to generate.