[Pvfs2-cvs] commit by sampson in pvfs2/src/client/windows/client-service: cert.c config.c

CVS commit program cvs at parl.clemson.edu
Thu May 12 17:39:25 EDT 2011


Update of /projects/cvsroot/pvfs2/src/client/windows/client-service
In directory parlweb1:/tmp/cvs-serv9292/src/client/windows/client-service

Modified Files:
      Tag: windows-client
	cert.c config.c 
Log Message:
Windows certificate processing


Index: cert.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/client/windows/client-service/Attic/cert.c,v
diff -p -u -r1.1.2.4 -r1.1.2.5
--- cert.c	11 May 2011 21:36:11 -0000	1.1.2.4
+++ cert.c	12 May 2011 21:39:25 -0000	1.1.2.5
@@ -10,6 +10,7 @@
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/x509_vfy.h>
 
 #include "cert.h"
@@ -54,14 +55,130 @@ static unsigned long load_cert_from_file
     return 0;
 }
 
+
+static int get_proxy_auth_ex_data_idx(void)
+{
+    static volatile int idx = -1;
+    if (idx < 0)
+    {
+        CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
+        if (idx < 0)
+        {
+            idx = X509_STORE_CTX_get_ex_new_index(0,
+                                                  "for verify callback",
+                                                  NULL,NULL,NULL);
+        }
+        CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
+    }
+
+    return idx;
+}
+
+/* parse the credential string uid/gid from credstr */
+static int parse_credentials(char *credstr, PVFS_uid *uid, PVFS_gid *gid)
+{
+    char *p, uidstr[16], gidstr[16];
+    int i, ret = 0;
+
+    uidstr[0] = gidstr[0] = '\0';
+    i = 0;
+    p = credstr;
+    while (*p && *p != '/' && i < 15)
+    {
+        if (isdigit(*p))
+        {
+            uidstr[i++] = *p++;
+        }
+        else 
+        {
+            /* error */
+            ret = 1;
+            break;
+        }
+    }
+    uidstr[i] = '\0';
+    if (ret == 0)
+    {
+        if (*p == '/')
+            p++;
+        i = 0;
+        while(*p && i < 15)
+        {
+            if (isdigit(*p))
+            {
+                gidstr[i++] = *p++;
+            }
+            else 
+            {
+                ret = 1;
+                break;
+            }
+        }
+        gidstr[i] = '\0';
+    }
+
+    if (ret == 0)
+    {
+        *uid = atoi(uidstr);
+        *gid = atoi(gidstr);
+    }
+
+    return ret;
+}
+
+static int verify_callback(int ok, X509_STORE_CTX *ctx)
+{
+    X509 *xs;
+    PROXY_CERT_INFO_EXTENSION *pci;
+    char *credstr;
+    PVFS_credentials *credentials;
+    int ret;
+
+    /* prior verifies have succeeded */
+    if (ok == 1) 
+    {
+        /* parse the credential string uid/gid from the policy */
+        xs = ctx->current_cert;
+        if (xs->ex_flags & EXFLAG_PROXY)
+        {
+            pci = (PROXY_CERT_INFO_EXTENSION *) 
+                    X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL);
+
+            credstr = (char *) pci->proxyPolicy->policy->data;
+            if (pci->proxyPolicy->policy->length > 0)
+            {
+                credentials = (PVFS_credentials *) X509_STORE_CTX_get_ex_data(
+                                 ctx, get_proxy_auth_ex_data_idx());
+                ret = parse_credentials(credstr, &credentials->uid, 
+                                        &credentials->gid);
+                if (ret != 0)
+                {
+                    DbgPrint("Could not parse credential string: %s\n", credstr);
+                }
+            }
+            else
+            {
+                DbgPrint("Could not load policy\n");
+            }
+
+            PROXY_CERT_INFO_EXTENSION_free(pci);
+        }
+    }
+    
+    return ok;
+}
+
 /* verify certificate */
 static unsigned long verify_cert(X509 *cert, 
-                                 X509 *ca_cert)
+                                 X509 *ca_cert,
+                                 STACK_OF(X509) *chain,
+                                 PVFS_credentials *credentials)
 {
     X509_STORE *trust_store;
     X509_STORE_CTX *ctx;
     int ret;
     unsigned long err;
+    int (*save_verify_cb)(int ok, X509_STORE_CTX *ctx);
 
     /* add CA cert to trusted store */
     trust_store = X509_STORE_new();
@@ -77,13 +194,18 @@ static unsigned long verify_cert(X509 *c
     if (ctx == NULL)
         goto verify_cert_exit;
 
-    ret = X509_STORE_CTX_init(ctx, trust_store, cert, NULL);
+    ret = X509_STORE_CTX_init(ctx, trust_store, cert, chain);
     if (!ret)
         goto verify_cert_exit;
 
-    /* TODO: verify proxy cert */
-    /* verify the cert */
-    X509_verify_cert(ctx);
+    /* verify the cert and get credentials */
+    save_verify_cb = ctx->verify_cb;
+    X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
+    X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), credentials);
+    X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
+    ret = X509_verify_cert(ctx);
+
+    X509_STORE_CTX_set_verify_cb(ctx, save_verify_cb);
     
 verify_cert_exit:
     err = ERR_get_error();
@@ -107,7 +229,7 @@ static unsigned int get_profile_dir(char
                                     char *profile_dir)
 {
     USER_INFO_4 user_info;
-    LPCWSTR wuserid;
+    LPWSTR wuserid;
     int ret;
     char *mbstr;
 
@@ -117,7 +239,7 @@ static unsigned int get_profile_dir(char
         return -1;
 
     /* get user information */
-    ret = NetUserGetInfo(NULL, wuserid, 4, &user_info);
+    ret = NetUserGetInfo(NULL, wuserid, 4, (LPBYTE *) &user_info);
 
     if (ret == 0)
     {
@@ -144,13 +266,16 @@ static unsigned int get_cert_credentials
                                          char *ca_path,
                                          PVFS_credentials *credentials)
 {
-    char cert_path[MAX_PATH];
-    char *temp;
-    X509 *cert, *ca_cert;
-    int ret;
+    char cert_dir[MAX_PATH], cert_path[MAX_PATH],
+         cert_pattern[MAX_PATH];
+    HANDLE h_find;
+    WIN32_FIND_DATA find_data;
+    X509 *cert, *chain_cert, *ca_cert;
+    STACK_OF(X509) *chain;
+    int ret, i;
 
     if (userid == NULL || credentials == NULL ||
-        ca_path)
+        ca_path == NULL)
         return -1;
 
     /* checked for cached credentials */
@@ -168,24 +293,23 @@ static unsigned int get_cert_credentials
 
     /* credentials not in cache... */
 
-    /* locate the certificate and CA */
+    /* locate the certificates and CA */
     if (cert_dir_prefix != NULL)
     {
-        if ((strlen(cert_dir_prefix) + strlen(userid) + 10) > MAX_PATH)
+        if ((strlen(cert_dir_prefix) + strlen(userid) + 8) > MAX_PATH)
         {
             DbgPrint("User %s: path to cert too long\n", userid);
             return -1;
         }
 
-        /* cert file is cert.pem in directory of user name */
-        strcpy(cert_path, cert_dir_prefix);
-        strcat(cert_path, userid);
-        strcat(cert_path, "\\cert.pem");
+        /* cert dir is cert_dir_prefix\userid */
+        strcpy(cert_dir, cert_dir_prefix);
+        strcat(cert_dir, userid);
     }
     else
     {
         /* get profile directory */
-        ret = get_profile_dir(userid, cert_path);
+        ret = get_profile_dir(userid, cert_dir);
         if (ret != 0)
         {
             DbgPrint("User %s: could not locate profile dir: %d\n", userid,
@@ -193,27 +317,68 @@ static unsigned int get_cert_credentials
             return ret;
         }
         
-        if (strlen(cert_path) + 9 >= MAX_PATH)
+        if (strlen(cert_dir) + 7 > MAX_PATH)
         {
             DbgPrint("User %s: profile dir too long\n", userid);
             return -1;
         }
+    }
+    
+    /* load certs */
+    chain = sk_X509_new_null();
 
-        strcat(cert_path, "\\cert.pem");
+    strcpy(cert_pattern, cert_dir);
+    strcat(cert_pattern, "cert.*");
+    h_find = FindFirstFile(cert_pattern, &find_data);
+    if (h_find == INVALID_HANDLE_VALUE)
+    {
+        DbgPrint("User %s: no certificates\n", userid);
+        return -1;
     }
 
-    /* verify the certificate */
-    ret = load_cert_from_file(cert_path, &cert);
+    do {
+       strcpy(cert_path, cert_dir);
+       strcat(cert_path, find_data.cFileName);
+        /* load proxy cert */
+        if (!stricmp(find_data.cFileName, "cert.0"))
+        {
+            ret = load_cert_from_file(cert_path, &cert);
+        }
+        else
+        {
+            /* load intermediate certs (including user cert) */
+            ret = load_cert_from_file(cert_path, &chain_cert);
+            if (ret == 0)
+                sk_X509_push(chain, chain_cert);
+        }
+        if (ret != 0)
+        {
+            DbgPrint("Error loading cert %s: %d\n", cert_path, ret);
+        }
+    } while (ret == 0 && FindNextFile(h_find, &find_data));
+
+    FindClose(h_find);
+    
     if (ret != 0)
-        return ret;
+        goto get_cert_credentials_exit;
 
+    /* load CA cert */
     ret = load_cert_from_file(ca_path, &ca_cert);
     if (ret != 0)
     {
-        X509_free(cert);
-        return ret;
+        DbgPrint("Error loading CA cert %s: %d\n", cert_path, ret);
+        goto get_cert_credentials_exit;
     }
-    
+
     /* read and cache credentials from certificate */
+    ret = verify_cert(cert, ca_cert, chain, credentials);
 
-}
\ No newline at end of file
+
+get_cert_credentials_exit:
+    /* free chain */
+    while (sk_X509_num(chain) > 0)
+        sk_X509_pop_free(chain, X509_free);
+    sk_X509_free(chain);
+
+    return ret;
+}

Index: config.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/client/windows/client-service/Attic/config.c,v
diff -p -u -r1.1.2.4 -r1.1.2.5
--- config.c	3 May 2011 14:54:48 -0000	1.1.2.4
+++ config.c	12 May 2011 21:39:25 -0000	1.1.2.5
@@ -224,8 +224,6 @@ int get_config(PORANGEFS_OPTIONS options
                 {
                     strncpy(options->ca_path, line + 8, MAX_PATH-2);
                     options->ca_path[MAX_PATH-2] = '\0';
-                    if (options->ca_path[strlen(options->ca_path)-1] != '\\')
-                        strcat(options->ca_path, "\\");
                 }
                 else
                 {



More information about the Pvfs2-cvs mailing list