add krb5 counterpart for acquire_cred
authorMichal Voců <michal@ruk.cuni.cz>
Wed, 8 Aug 2012 15:26:46 +0000 (15:26 +0000)
committerMichal Voců <michal@ruk.cuni.cz>
Wed, 8 Aug 2012 15:26:46 +0000 (15:26 +0000)
org.glite.lbjp-common.gss/interface/glite_gss.h
org.glite.lbjp-common.gss/src/glite_gss.c

index caa66cb..672990b 100644 (file)
@@ -87,6 +87,11 @@ edg_wll_gss_acquire_cred_gsi(const char *cert_file,
                             edg_wll_GssStatus* gss_code);
 
 int
+edg_wll_gss_acquire_cred_krb5(const char *cert_file,
+                             edg_wll_GssCred *cred,
+                             edg_wll_GssStatus* gss_code);
+
+int
 edg_wll_gss_release_cred(edg_wll_GssCred *cred,
                         edg_wll_GssStatus* gss_code);
 
index 038f539..f272501 100644 (file)
@@ -840,6 +840,111 @@ end:
 
    return ret;
 }
+
+
+int
+edg_wll_gss_acquire_cred_krb5(const char *cert_file, edg_wll_GssCred *cred,
+                             edg_wll_GssStatus* gss_code)
+{
+   OM_uint32 major_status = 0, minor_status, minor_status2;
+   gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
+   gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+   gss_name_t gss_name = GSS_C_NO_NAME;
+   gss_OID_set_desc mechs;
+   gss_OID_set avail_mechs = NULL;
+   OM_uint32 lifetime;
+   char *proxy_file = NULL;
+   char *name = NULL;
+   int ret, mech_available;
+
+   *cred = NULL;
+
+   major_status = gss_indicate_mechs(&minor_status, &avail_mechs);
+   /* ignore error */
+
+   major_status = gss_test_oid_set_member(&minor_status, get_oid("krb5"),
+                                         avail_mechs, &mech_available);
+   if (!GSS_ERROR(major_status) && !mech_available) {
+          ret = 0;
+          lifetime = 0;
+          goto end1;
+   }
+
+   mechs.count = 1;
+   mechs.elements = get_oid("krb5");
+      
+   major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0,
+                                  &mechs, GSS_C_BOTH,
+                                  &gss_cred, NULL, NULL);
+   if (GSS_ERROR(major_status)) {
+          ret = EDG_WLL_GSS_ERROR_GSS;
+          goto end;
+   }
+
+  /* gss_import_cred() doesn't check validity of credential loaded, so let's
+    * verify it now */
+    major_status = gss_inquire_cred(&minor_status, gss_cred, &gss_name,
+                                   &lifetime, NULL, NULL);
+    if (GSS_ERROR(major_status)) {
+       ret = EDG_WLL_GSS_ERROR_GSS;
+       goto end;
+    }
+
+    /* Must cast to time_t since OM_uint32 is unsinged and hence we couldn't
+     * detect negative values. */
+    if ((time_t) lifetime <= 0) {
+       major_status = GSS_S_CREDENTIALS_EXPIRED;
+       minor_status = 0; /* XXX */
+       ret = EDG_WLL_GSS_ERROR_GSS;
+       goto end;
+    }
+
+   major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL);
+   if (GSS_ERROR(major_status)) {
+      ret = EDG_WLL_GSS_ERROR_GSS;
+      goto end;
+   }
+   name = buffer.value;
+   memset(&buffer, 0, sizeof(buffer));
+    
+end1:
+
+   *cred = calloc(1, sizeof(**cred));
+   if (*cred == NULL) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      free(name);
+      goto end;
+   }
+
+   (*cred)->gss_cred = gss_cred;
+   gss_cred = GSS_C_NO_CREDENTIAL;
+   (*cred)->lifetime = lifetime;
+   (*cred)->name = name;
+
+   ret = 0;
+
+end:
+   if (gss_name != GSS_C_NO_NAME)
+      gss_release_name(&minor_status2, &gss_name);
+
+   if (gss_cred != GSS_C_NO_CREDENTIAL)
+      gss_release_cred(&minor_status2, &gss_cred);
+
+   if (avail_mechs)
+       gss_release_oid_set(&minor_status2, &avail_mechs);
+
+   if (GSS_ERROR(major_status)) {
+      if (gss_code) {
+        gss_code->major_status = major_status;
+        gss_code->minor_status = minor_status;
+      }
+      ret = EDG_WLL_GSS_ERROR_GSS;
+   }
+
+   return ret;
+}
+
+
 /* XXX XXX This is black magic. "Sometimes" server refuses the client with SSL
  * alert "certificate expired" even if it is not true. In this case the server
  * slave terminates (which helps, usually), and we can reconnect transparently.