[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