]> andersk Git - gssapi-openssh.git/commitdiff
changes for gssapi mechglue support:
authorjbasney <jbasney>
Thu, 26 Sep 2002 16:17:41 +0000 (16:17 +0000)
committerjbasney <jbasney>
Thu, 26 Sep 2002 16:17:41 +0000 (16:17 +0000)
- rename get_gssapi_cred() to get_gsi_cred() and get_gss_our_name() to
  get_gsi_name() and try to force the GSI mechanism, because these functions
  (for getting the grid-mapfile name for implicit username mapping) are
  GSI specific; this needs more work
- fix debug messages to not assume only one gssapi mechanism
- only tell server about those gssapi oids for which we have valid creds
- prefer GSI over Kerberos GSSAPI mech, because we can only choose one
  and we can always do regular (non-GSSAPI) Kerberos auth later

openssh/sshconnect1.c

index 605658ba367a4a5a85f92107906c7b402bcc0341..03b401d511b315030b55ab7b9c99e3ddbd6dcb88 100644 (file)
@@ -998,17 +998,19 @@ static void display_gssapi_status(msg, maj_stat, min_stat)
 }
 
 #ifdef GSI
-int get_gssapi_cred()
+int get_gsi_cred()
 {
   OM_uint32 maj_stat;
   OM_uint32 min_stat;
-
-
+  gss_OID_set oidset;
+  
   debug("calling gss_acquire_cred");
+  gss_create_empty_oid_set(&min_stat,&oidset);
+  gss_add_oid_set_member(&min_stat,&supported_mechs[GSI].oid,&oidset);
   maj_stat = gss_acquire_cred(&min_stat,
                               GSS_C_NO_NAME,
                               GSS_C_INDEFINITE,
-                              GSS_C_NO_OID_SET,
+                              oidset,
                               GSS_C_INITIATE,
                               &gss_cred,
                               NULL,
@@ -1024,7 +1026,7 @@ int get_gssapi_cred()
   return 1;     /* Success */
 }
 
-char * get_gss_our_name()
+char * get_gsi_name()
 {
   OM_uint32 maj_stat;
   OM_uint32 min_stat;
@@ -1077,17 +1079,17 @@ int try_gssapi_authentication(char *host, Options *options)
   gss_ctx_id_t gss_context;
   gss_OID_desc mech_oid;
   gss_OID name_type;
-  gss_OID_set my_mechs;
-  int my_mech_num;
+  gss_OID_set gss_mechs, my_mechs;
+  int my_mech_num, i, present;
   OM_uint32 maj_stat;
   OM_uint32 min_stat;
   int ret_stat = 0;                             /* 1 == success */
   OM_uint32 req_flags = 0;
   OM_uint32 ret_flags;
   int type;
-  char *gssapi_auth_type = NULL;
   char *xhost;
   unsigned int slen;
+  Gssctxt *ctx = NULL;
 
   /* Make a copy of the host name, in case it was returned by a
    * previous call to gethostbyname(). */      
@@ -1109,25 +1111,6 @@ int try_gssapi_authentication(char *host, Options *options)
   /* Do mutual authentication */
   req_flags |= GSS_C_MUTUAL_FLAG;
 
-#ifdef KRB5
-
-  gssapi_auth_type = "GSSAPI/Kerberos 5";
-
-#endif
-
-#ifdef GSI
-
-  gssapi_auth_type = "GSSAPI/GLOBUS";
-
-#endif /* GSI */
-
-  if (gssapi_auth_type == NULL) {
-      debug("No GSSAPI type defined during compile");
-      goto cleanup;
-  }
-
-  debug("Attempting %s authentication", gssapi_auth_type);
-
   service_name = (char *) xmalloc(strlen("host") +
                                  strlen(xhost) +
                                  2 /* 1 for '@', 1 for NUL */);
@@ -1143,26 +1126,11 @@ int try_gssapi_authentication(char *host, Options *options)
 
   /* Forward credentials? */
 
-#ifdef KRB5
-  if (options->kerberos_tgt_passing) {
-      debug("Forwarding Kerberos credentials");
-      req_flags |= GSS_C_DELEG_FLAG;
-  }
-#endif /* KRB5 */
-
 #ifdef GSSAPI
   if(options->gss_deleg_creds) {
-    debug("Forwarding X509 proxy certificate");
+    debug("Delegating GSSAPI credentials");
     req_flags |= GSS_C_DELEG_FLAG;
   }
-#ifdef GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG
-  /* Forward limited credentials, overrides gss_deleg_creds */
-  if(options->gss_globus_deleg_limited_proxy) {
-    debug("Forwarding limited X509 proxy certificate");
-    req_flags |= (GSS_C_DELEG_FLAG | GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG);
-  }
-#endif /* GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG */
-
 #endif /* GSSAPI */
 
   debug("req_flags = %u", (unsigned int)req_flags);
@@ -1180,23 +1148,67 @@ int try_gssapi_authentication(char *host, Options *options)
     goto cleanup;
   }
 
-  maj_stat = gss_indicate_mechs(&min_stat, &my_mechs);
+  maj_stat = gss_indicate_mechs(&min_stat, &gss_mechs);
 
   if (maj_stat != GSS_S_COMPLETE) {
     display_gssapi_status("indicating mechs", maj_stat, min_stat);
     goto cleanup;
   }
 
+  /* The GSSAPI supports the mechs in gss_mechs, but which ones do
+     we have credentials for?  We only get one try, so we don't want
+     to propose a mechanism we know is going to fail. */
+  maj_stat = gss_create_empty_oid_set(&min_stat, &my_mechs);
+  for (i=0; supported_mechs[i].name != NULL; i++) {
+      maj_stat = gss_test_oid_set_member(&min_stat, &supported_mechs[i].oid,
+                                        gss_mechs, &present);
+      if (present) {
+         if (!GSS_ERROR(ssh_gssapi_client_ctx(&ctx, &supported_mechs[i].oid,
+                                              host))) {
+             maj_stat = gss_add_oid_set_member(&min_stat,
+                                               &supported_mechs[i].oid,
+                                               &my_mechs);
+             debug("GSSAPI mechanism %s supported", supported_mechs[i].name);
+         } else {
+             debug("no credentials for GSSAPI mechanism %s",
+                   supported_mechs[i].name);
+         }
+      } else {
+         debug("GSSAPI mechanism %s not supported", supported_mechs[i].name);
+      }
+  }
+
   /*
    * Send over a packet to the daemon, letting it know we're doing
    * GSSAPI and our mech_oid(s).
    */
-  debug("Sending mech oid to server");
+  debug("Sending mech oid(s) to server");
   packet_start(SSH_CMSG_AUTH_GSSAPI);
   packet_put_int(my_mechs->count); /* Number of mechs we're sending */
-  for (my_mech_num = 0; my_mech_num < my_mechs->count; my_mech_num++)
+#ifdef GSI
+  /* Send GSI before Kerberos, because if GSI fails, we can always fall
+     back and try regular Kerberos authentication with our Kerberos cred. */
+  maj_stat = gss_test_oid_set_member(&min_stat, &supported_mechs[GSI].oid,
+                                    my_mechs, &present);
+  if (present) {
+      packet_put_string(supported_mechs[GSI].oid.elements,
+                        supported_mechs[GSI].oid.length);
+  }
+#endif
+  for (my_mech_num = 0; my_mech_num < my_mechs->count; my_mech_num++) {
+#ifdef GSI
+      /* Skip GSI.  We already sent it above. */
+      if ((my_mechs->elements[my_mech_num].length ==
+          supported_mechs[GSI].oid.length) &&
+         memcmp(my_mechs->elements[my_mech_num].elements,
+                supported_mechs[GSI].oid.elements,
+                my_mechs->elements[my_mech_num].length) == 0) {
+         continue;
+      }
+#endif
       packet_put_string(my_mechs->elements[my_mech_num].elements,
                         my_mechs->elements[my_mech_num].length);
+  }
   packet_send();
   packet_write_wait();
 
@@ -1321,7 +1333,7 @@ int try_gssapi_authentication(char *host, Options *options)
   /* Success */
   ret_stat = 1;
 
-  debug("%s authentication successful", gssapi_auth_type);
+  debug("GSSAPI authentication successful");
 
   /*
    * Read hash of host and server keys and make sure it
@@ -1649,14 +1661,14 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
    */
   if ((supported_authentications & (1 << SSH_AUTH_GSSAPI)) &&
       options.gss_authentication) {
-    if (get_gssapi_cred()) {
+    if (get_gsi_cred()) {
       char * retname;
       char * newname;
 
 
       save_server_user = server_user;
 
-      retname = get_gss_our_name();
+      retname = get_gsi_name();
 
       if (retname) {
         debug("passing gssapi name '%s'", retname);
@@ -1675,12 +1687,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
           }
         }
       }
-    } else {
-      /*
-       * If we couldn't successfully get our GSSAPI credentials then
-       * turn off gssapi authentication
-       */
-      options.gss_authentication = 0;
     }
     debug("server_user %s", server_user);
   }
This page took 0.042122 seconds and 5 git commands to generate.