Transfered patch enabling to work with cert and key stored in separate files
authorDaniel Kouřil <kouril@ics.muni.cz>
Fri, 8 Oct 2004 14:25:36 +0000 (14:25 +0000)
committerDaniel Kouřil <kouril@ics.muni.cz>
Fri, 8 Oct 2004 14:25:36 +0000 (14:25 +0000)
org.glite.lb.client/src/connection.c
org.glite.lb.client/src/producer.c
org.glite.lb.common/interface/lb_gss.h
org.glite.lb.common/src/lb_gss.c
org.glite.lb.common/test/test_gss.cpp
org.glite.lb.logger/src/interlogd.c
org.glite.lb.logger/src/logd.c
org.glite.lb.logger/src/recover.c
org.glite.lb.server/src/bkserverd.c

index ea7b4b8..54d2f9e 100644 (file)
@@ -129,10 +129,10 @@ int edg_wll_open(edg_wll_Context ctx)
         * struct specifying whether or not this connection shall be authenticated
         * to prevent from repeated calls to edg_wll_gss_acquire_cred_gsi() */
        if (!ctx->connPool[index].gsiCred && 
-           edg_wll_gss_acquire_cred_gsi(ctx->p_proxy_filename,
-                                        &ctx->connPool[index].gsiCred,
-                                        NULL,
-                                        &gss_stat)) {
+           edg_wll_gss_acquire_cred_gsi(
+              ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_cert_filename,
+              ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_key_filename,
+              &ctx->connPool[index].gsiCred, NULL, &gss_stat)) {
            edg_wll_SetErrorGss(ctx, "failed to load GSI credentials", &gss_stat);
            goto err;
        }
index aa15106..6d264ba 100644 (file)
@@ -51,8 +51,10 @@ static int edg_wll_DoLogEvent(
        fprintf(stderr,"Logging to host %s, port %d\n",
                        context->p_destination, context->p_dest_port);
 #endif
-       ret = edg_wll_gss_acquire_cred_gsi(context->p_proxy_filename, &cred,
-                                          &my_subject_name, &gss_stat);
+       ret = edg_wll_gss_acquire_cred_gsi(
+             context->p_proxy_filename ? context->p_proxy_filename : context->p_cert_filename,
+             context->p_proxy_filename ? context->p_proxy_filename : context->p_key_filename,
+             &cred, &my_subject_name, &gss_stat);
        /* Give up if unable to prescribed credentials, otherwise go on anonymously */
        if (ret && context->p_proxy_filename) {
                edg_wll_SetErrorGss(context, "failed to load GSI credentials", &gss_stat);
index af53f4c..047b718 100644 (file)
@@ -34,7 +34,8 @@ typedef struct _edg_wll_GssStatus {
  * anonymous servers as well. */
 
 int
-edg_wll_gss_acquire_cred_gsi(char *proxy_file,
+edg_wll_gss_acquire_cred_gsi(char *cert_file,
+                            char *key_file,
                             gss_cred_id_t *cred,
                             char **name,
                             edg_wll_GssStatus* gss_code);
index 7b2054f..a5642cb 100644 (file)
@@ -390,62 +390,164 @@ end:
    return ret;
 }
 
+static int
+create_proxy(char *cert_file, char *key_file, char **proxy_file)
+{
+   char buf[4096];
+   int in, out;
+   char *name = NULL;
+   int ret, len;
+
+   *proxy_file = NULL;
+
+   asprintf(&name, "%s/%d.lb.XXXXXX", P_tmpdir, getpid());
+
+   out = mkstemp(name);
+   if (out < 0)
+      return EDG_WLL_GSS_ERROR_ERRNO;
+
+   in = open(cert_file, O_RDONLY);
+   if (in < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+   while ((ret = read(in, buf, sizeof(buf))) > 0) {
+      len = write(out, buf, ret);
+      if (len != ret) {
+        ret = -1;
+        break;
+      }
+   }
+   close(in);
+   if (ret < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   in = open(key_file, O_RDONLY);
+   if (in < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+   while ((ret = read(in, buf, sizeof(buf))) > 0) {
+      len = write(out, buf, ret);
+      if (len != ret) {
+        ret = -1;
+        break;
+      }
+   }
+   close(in);
+   if (ret < 0) {
+      ret = EDG_WLL_GSS_ERROR_ERRNO;
+      goto end;
+   }
+
+   ret = 0;
+   *proxy_file = name;
+
+end:
+   close(out);
+   if (ret) {
+      unlink(name);
+      free(name);
+   }
+
+   return ret;
+}
+
+static int
+destroy_proxy(char *proxy_file)
+{
+   /* XXX we should erase the contents safely (i.e. overwrite with 0's) */
+   unlink(proxy_file);
+   return 0;
+}
+
 int
-edg_wll_gss_acquire_cred_gsi(char *proxy_file, gss_cred_id_t *cred,
+edg_wll_gss_acquire_cred_gsi(char *cert_file, char *key_file, gss_cred_id_t *cred,
                             char **name, edg_wll_GssStatus* gss_code)
 {
-   OM_uint32 major_status, minor_status, minor_status2;
+   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;
    OM_uint32 lifetime;
+   char *proxy_file = NULL;
+   int ret;
+
+   if ((cert_file == NULL && key_file != NULL) ||
+       (cert_file != NULL && key_file == NULL))
+      return EINVAL;
 
-   if (proxy_file == NULL) {
+   if (cert_file == NULL) {
       major_status = gss_acquire_cred(&minor_status, GSS_C_NO_NAME, 0,
                                      GSS_C_NO_OID_SET, GSS_C_BOTH,
                                      &gss_cred, NULL, NULL);
-      if (GSS_ERROR(major_status))
+      if (GSS_ERROR(major_status)) {
+        ret = EDG_WLL_GSS_ERROR_GSS;
         goto end;
+      }
    } else {
+      proxy_file = cert_file;
+      if (strcmp(cert_file, key_file) != 0 &&
+         (ret = create_proxy(cert_file, key_file, &proxy_file))) {
+        proxy_file = NULL;
+        goto end;
+      }
+      
       asprintf((char**)&buffer.value, "X509_USER_PROXY=%s", proxy_file);
       if (buffer.value == NULL) {
         errno = ENOMEM;
-        return EDG_WLL_GSS_ERROR_ERRNO;
+        ret = EDG_WLL_GSS_ERROR_ERRNO;
+        goto end;
       }
       buffer.length = strlen(proxy_file);
 
       major_status = gss_import_cred(&minor_status, &gss_cred, GSS_C_NO_OID, 1,
                                     &buffer, 0, NULL);
       free(buffer.value);
-      if (GSS_ERROR(major_status))
+      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))
+    if (GSS_ERROR(major_status)) {
+       ret = EDG_WLL_GSS_ERROR_GSS;
        goto end;
+    }
 
     if (lifetime == 0) {
        major_status = GSS_S_CREDENTIALS_EXPIRED;
        minor_status = 0; /* XXX */
+       ret = EDG_WLL_GSS_ERROR_GSS;
        goto end;
     }
 
     if (name) {
        major_status = gss_display_name(&minor_status, gss_name, &buffer, NULL);
-       if (GSS_ERROR(major_status))
+       if (GSS_ERROR(major_status)) {
+         ret = EDG_WLL_GSS_ERROR_GSS;
          goto end;
+       }
        *name = buffer.value;
        memset(&buffer, 0, sizeof(buffer));
     }
     
    *cred = gss_cred;
    gss_cred = GSS_C_NO_CREDENTIAL;
+   ret = 0;
 
 end:
+   if (cert_file && key_file && proxy_file && strcmp(cert_file, key_file) != 0) {
+      destroy_proxy(proxy_file);
+      free(proxy_file);
+   }
+
    if (gss_name != GSS_C_NO_NAME)
       gss_release_name(&minor_status2, &gss_name);
 
@@ -457,10 +559,10 @@ end:
         gss_code->major_status = major_status;
         gss_code->minor_status = minor_status;
       }
-      return EDG_WLL_GSS_ERROR_GSS;
+      ret = EDG_WLL_GSS_ERROR_GSS;
    }
 
-   return 0;
+   return ret;
 }
 
 int 
index 5080e81..97688c3 100644 (file)
@@ -62,14 +62,15 @@ void GSSTest::setUp(void) {
        struct sockaddr_in      a;
        socklen_t               alen = sizeof(a);
        char *                  cred_file = NULL;
+       char *                  key_file = NULL;
 
        timeout.tv_sec = 10;
        timeout.tv_usec = 0;
        
-       cred_file = getenv("X509_USER_PROXY");
+       key_file = cred_file = getenv("X509_USER_PROXY");
        CPPUNIT_ASSERT_MESSAGE("credential file", cred_file);
        
-       if (edg_wll_gss_acquire_cred_gsi(cred_file, &my_cred, &my_subject, &stat))
+       if (edg_wll_gss_acquire_cred_gsi(cred_file, key_file, &my_cred, &my_subject, &stat))
                CPPUNIT_ASSERT_MESSAGE("gss_acquire_cred", 0);
        
         sock = socket(PF_INET,SOCK_STREAM,0);
index efe13e7..dba2f0d 100644 (file)
@@ -223,7 +223,7 @@ main (int argc, char **argv)
      setenv("X509_CERT_DIR", CAcert_dir, 1);
 
   edg_wll_gss_watch_creds(cert_file,&cert_mtime);
-  ret = edg_wll_gss_acquire_cred_gsi(cert_file, &cred_handle, NULL, &gss_stat);
+  ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred_handle, NULL, &gss_stat);
   if (ret) {
      char *gss_err = NULL;
      char *str;
index c8c1bfe..1fe7582 100644 (file)
@@ -342,7 +342,7 @@ Copyright (c) 2002 CERN, INFN and CESNET on behalf of the EU DataGrid.\n");
 
    edg_wll_gss_watch_creds(cert_file,&cert_mtime);
    /* XXX DK: support noAuth */
-   ret = edg_wll_gss_acquire_cred_gsi(cert_file, &cred, &my_subject_name,
+   ret = edg_wll_gss_acquire_cred_gsi(cert_file, key_file, &cred, &my_subject_name,
                                      &gss_stat);
    if (ret) {
       /* XXX DK: call edg_wll_gss_get_error() */
@@ -394,7 +394,7 @@ Copyright (c) 2002 CERN, INFN and CESNET on behalf of the EU DataGrid.\n");
          gss_cred_id_t newcred;
          case 0: break;
          case 1:
-            ret = edg_wll_gss_acquire_cred_gsi(cert_file,&newcred,NULL,&gss_stat);
+            ret = edg_wll_gss_acquire_cred_gsi(cert_file,key_file,&newcred,NULL,&gss_stat);
             if (ret) {
                edg_wll_ll_log(LOG_WARNING, "Reloading credentials failed, continue with older\n");
             } else {
index 670c2f1..ed31186 100644 (file)
@@ -40,7 +40,7 @@ recover_thread(void *q)
                        OM_uint32 min_stat;
                        int ret;
 
-                       ret = edg_wll_gss_acquire_cred_gsi(cert_file, 
+                       ret = edg_wll_gss_acquire_cred_gsi(cert_file,key_file, 
                                &new_cred_handle, NULL, NULL);
                        if (new_cred_handle != GSS_C_NO_CREDENTIAL) {
                                gss_release_cred(&min_stat, &cred_handle);
index d20403b..811935a 100644 (file)
@@ -666,7 +666,7 @@ int main(int argc,char *argv[])
 
        if (cadir) setenv("X509_CERT_DIR",cadir,1);
        edg_wll_gss_watch_creds(cert,&cert_mtime);
-       if (edg_wll_gss_acquire_cred_gsi(cert, &mycred, &mysubj, &gss_code)) {
+       if (edg_wll_gss_acquire_cred_gsi(cert, key, &mycred, &mysubj, &gss_code)) {
           dprintf(("Running unauthenticated\n"));
        } else {
                int     i;
@@ -748,7 +748,7 @@ int main(int argc,char *argv[])
                switch (edg_wll_gss_watch_creds(cert,&cert_mtime)) {
                        case 0: break;
                        case 1: 
-                               ret = edg_wll_gss_acquire_cred_gsi(cert, &newcred, NULL, &gss_code);
+                               ret = edg_wll_gss_acquire_cred_gsi(cert, key, &newcred, NULL, &gss_code);
                                if (ret == 0) {
                                        dprintf(("reloading credentials"));
                                        gss_release_cred(&min_stat, &mycred);