From 55513261a9a38c12af21ef7a8ad845de7d7b9768 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Thu, 22 Jun 2006 10:20:25 +0000 Subject: [PATCH] Sync --- org.gridsite.core/CHANGES | 3 + org.gridsite.core/src/grst_x509.c | 330 ++++++++++++++------------------------ 2 files changed, 120 insertions(+), 213 deletions(-) diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES index 9a05619..3fc6d60 100644 --- a/org.gridsite.core/CHANGES +++ b/org.gridsite.core/CHANGES @@ -1,3 +1,6 @@ +* Thu Jun 22 2006 Andrew McNab +- Backport fixes to grst_x509.c from 1.3.x for + delegation utility functions used by findproxyfile * Mon Jun 05 2006 Andrew McNab - ==== GridSite version 1.2.3 ==== * Mon Jun 05 2006 Andrew McNab diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c index f3c0aa5..31a89c9 100644 --- a/org.gridsite.core/src/grst_x509.c +++ b/org.gridsite.core/src/grst_x509.c @@ -76,7 +76,8 @@ int GRSTx509NameCmp(char *a, char *b) * would ideally be done with OIDs/values. In particular, we equate * "/Email=" == "/emailAddress=" to deal with this important change * between OpenSSL 0.9.6 and 0.9.7. - * Other than that, it is currently the same as ordinary strcmp(3). + * Other than that, it is currently the same as ordinary strcasecmp(3) + * (for consistency with EDG/LCG/EGEE gridmapdir case insensitivity.) */ { int ret; @@ -96,7 +97,7 @@ int GRSTx509NameCmp(char *a, char *b) p[1] = 'E'; } - ret = strcmp(aa, bb); + ret = strcasecmp(aa, bb); free(aa); free(bb); @@ -1053,75 +1054,22 @@ char *GRSTx509CachedProxyFind(char *proxydir, char *delegation_id, if not found. */ { - int ret, len; - char *filename = NULL, *line, *p, *proxyfile = NULL; - DIR *proxyDIR; - FILE *fp; - struct dirent *ent; - struct stat entstat; - - if ((proxyDIR = opendir(proxydir)) == NULL) return NULL; - - len = strlen(delegation_id); - if (strlen(user_dn) > len) len = strlen(user_dn); - - if ((line = malloc(len + 2)) == NULL) return NULL; - - while ((ent = readdir(proxyDIR)) != NULL) - { - if (ent->d_name[0] != '.') /* private keys begin with . */ - { - if (asprintf(&filename, "%s/%s", proxydir, ent->d_name) == -1) - break; - if ((stat(filename, &entstat) != 0) - || !S_ISREG(entstat.st_mode)) - { - free(filename); - continue; - } - - fp = fopen(filename, "r"); - if (fp != NULL) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - if (strcmp(line, delegation_id) == 0) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - - if (strcmp(line, user_dn) == 0) - { - proxyfile = filename; - fclose(fp); - break; - } - } - } - } - } - } - - fclose(fp); - } - - free(filename); - } - } - - closedir(proxyDIR); - free(line); - + char *user_dn_enc, *proxyfile; + struct stat statbuf; + + user_dn_enc = GRSThttpUrlEncode(user_dn); + + asprintf(&proxyfile, "%s/%s/%s/userproxy.pem", + proxydir, user_dn_enc, delegation_id); + + free(user_dn_enc); + + if ((stat(proxyfile, &statbuf) != 0) || !S_ISREG(statbuf.st_mode)) + { + free(proxyfile); + return NULL; + } + return proxyfile; } @@ -1139,76 +1087,23 @@ char *GRSTx509CachedProxyKeyFind(char *proxydir, char *delegation_id, if not found. */ { - int ret, len; - char *filename = NULL, *line, *p, *keyfile = NULL; - DIR *proxyDIR; - FILE *fp; - struct dirent *ent; - struct stat entstat; - - if ((proxyDIR = opendir(proxydir)) == NULL) return NULL; - - len = strlen(delegation_id); - if (strlen(user_dn) > len) len = strlen(user_dn); - - if ((line = malloc(len + 2)) == NULL) return NULL; - - while ((ent = readdir(proxyDIR)) != NULL) - { - if (ent->d_name[0] == '.') /* private keys begin with . */ - { - if (asprintf(&filename, "%s/%s", proxydir, ent->d_name) == -1) - break; - if ((stat(filename, &entstat) != 0) - || !S_ISREG(entstat.st_mode)) - { - free(filename); - continue; - } - - fp = fopen(filename, "r"); - if (fp != NULL) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - if (strcmp(line, delegation_id) == 0) - { - if (fgets(line, len + 2, fp) != NULL) - { - p = index(line, '\n'); - - if (p != NULL) - { - *p = '\0'; - - if (strcmp(line, user_dn) == 0) - { - keyfile = filename; - fclose(fp); - break; - } - } - } - } - } - } - - fclose(fp); - } - - free(filename); - } - } - - closedir(proxyDIR); - free(line); - - return keyfile; + char *user_dn_enc, *prvkeyfile; + struct stat statbuf; + + user_dn_enc = GRSThttpUrlEncode(user_dn); + + asprintf(&prvkeyfile, "%s/cache/%s/%s/userkey.pem", + proxydir, user_dn_enc, delegation_id); + + free(user_dn_enc); + + if ((stat(prvkeyfile, &statbuf) != 0) || !S_ISREG(statbuf.st_mode)) + { + free(prvkeyfile); + return NULL; + } + + return prvkeyfile; } static void mkdir_printf(mode_t mode, char *fmt, ...) @@ -1339,23 +1234,9 @@ int GRSTx509ProxyDestroy(char *proxydir, char *delegation_id, char *user_dn) user_dn_enc = GRSThttpUrlEncode(user_dn); - /* private key */ - - asprintf(&filename, "%s/%s/%s/userkey.pem", - proxydir, user_dn_enc, delegation_id); - - if (filename == NULL) - { - free(user_dn_enc); - return GRST_RET_FAILED; - } - - if (unlink(filename) != 0) ret = GRST_RET_NO_SUCH_FILE; - free(filename); - - /* cert chain */ + /* proxy file */ - asprintf(&filename, "%s/%s/%s/usercert.pem", + asprintf(&filename, "%s/%s/%s/userproxy.pem", proxydir, user_dn_enc, delegation_id); if (filename == NULL) @@ -1400,10 +1281,8 @@ int GRSTx509ProxyGetTimes(char *proxydir, char *delegation_id, char *user_dn, if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; user_dn_enc = GRSThttpUrlEncode(user_dn); - - /* cert chain */ - asprintf(&filename, "%s/%s/%s/usercert.pem", + asprintf(&filename, "%s/%s/%s/userproxy.pem", proxydir, user_dn_enc, delegation_id); free(user_dn_enc); @@ -1415,7 +1294,7 @@ int GRSTx509ProxyGetTimes(char *proxydir, char *delegation_id, char *user_dn, if (fp == NULL) return GRST_RET_NO_SUCH_FILE; - cert = PEM_read_X509(fp, NULL, NULL, NULL); + cert = PEM_read_X509(fp, NULL, NULL, NULL); /* first cert is X.509 PC */ fclose(fp); @@ -1521,6 +1400,7 @@ char *GRSTx509MakeDelegationID(void) return delegation_id; } +#if 0 /// Return the short file name for the given delegation_id and user_dn /** * Returns a malloc'd string with the short file name (no paths) that @@ -1608,6 +1488,7 @@ char *GRSTx509MakeProxyFileName(char *delegation_id, return strdup(filename); } +#endif /// Store a GSI proxy chain in the proxy cache, along with the private key /** @@ -1620,85 +1501,108 @@ int GRSTx509CacheProxy(char *proxydir, char *delegation_id, char *user_dn, char *proxychain) { int c, len = 0, i, ret; - char *user_dn_enc, *upcertfile, *upcertpath, *userkeyfile, *cachekeyfile, - *p, *ptr; + char *user_dn_enc, *p, *ptr, *prvkeyfile, *proxyfile; + STACK_OF(X509) *certstack; + BIO *certmem; + X509 *cert; + long ptrlen; FILE *ifp, *ofp; if (strcmp(user_dn, "cache") == 0) return GRST_RET_FAILED; - user_dn_enc = GRSThttpUrlEncode(user_dn); - - /* create directories if necessary */ - - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/%s", proxydir, user_dn_enc); - mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, - "%s/%s/%s", proxydir, user_dn_enc, delegation_id); + /* find the existing private key file */ - /* move the new proxy private key */ - - asprintf(&cachekeyfile, "%s/cache/%s/%s/userkey.pem", - proxydir, user_dn_enc, delegation_id); + prvkeyfile = GRSTx509CachedProxyKeyFind(proxydir, delegation_id, user_dn); - if (cachekeyfile == NULL) + if (prvkeyfile == NULL) { - free(user_dn_enc); return GRST_RET_FAILED; } - - asprintf(&userkeyfile, "%s/%s/%s/userkey.pem", - proxydir, user_dn_enc, delegation_id); - if (userkeyfile == NULL) + /* open it ready for later */ + + if ((ifp = fopen(prvkeyfile, "r")) == NULL) { - free(cachekeyfile); - free(user_dn_enc); + free(prvkeyfile); return GRST_RET_FAILED; } - ret = rename(cachekeyfile, userkeyfile); - chmod(userkeyfile, S_IRUSR | S_IWUSR); + /* get the X509 stack */ - free(cachekeyfile); - free(userkeyfile); - - if (ret != 0) + if (GRSTx509StringToChain(&certstack, proxychain) != GRST_RET_OK) { - free(user_dn_enc); + fclose(ifp); + free(prvkeyfile); return GRST_RET_FAILED; } - /* write out the proxy certificate chain */ + /* create directories if necessary, and set proxy filename */ + + user_dn_enc = GRSThttpUrlEncode(user_dn); - asprintf(&upcertfile, "%s/%s/%s/usercert.pem", + mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, + "%s/%s", proxydir, user_dn_enc); + mkdir_printf(S_IRUSR | S_IWUSR | S_IXUSR, + "%s/%s/%s", proxydir, user_dn_enc, delegation_id); + + asprintf(&proxyfile, "%s/%s/%s/userproxy.pem", proxydir, user_dn_enc, delegation_id); + + free(user_dn_enc); + + /* set up to write proxy file */ + + ofp = fopen(proxyfile, "w"); + chmod(proxyfile, S_IRUSR | S_IWUSR); + free(proxyfile); - if (upcertfile == NULL) - { - free(user_dn_enc); - return GRST_RET_FAILED; - } - - ofp = fopen(upcertfile, "w"); if (ofp == NULL) { - free(user_dn_enc); - free(upcertfile); + fclose(ifp); + free(prvkeyfile); return GRST_RET_FAILED; } - - chmod(upcertfile, S_IRUSR | S_IWUSR); - free(user_dn_enc); - free(upcertfile); + /* write out the most recent proxy by itself */ - if ((fwrite(proxychain, sizeof (char), strlen(proxychain), ofp) != - strlen(proxychain)) || (fclose(ofp) != 0)) - { - return GRST_RET_FAILED; + if (cert = sk_X509_value(certstack, 0)) + { + certmem = BIO_new(BIO_s_mem()); + if (PEM_write_bio_X509(certmem, cert) == 1) + { + ptrlen = BIO_get_mem_data(certmem, &ptr); + fwrite(ptr, 1, ptrlen, ofp); + } + + BIO_free(certmem); } - -/* should also check validity of proxy cert to avoid suprises? */ - + + /* insert proxy private key, read from private key file */ + + while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); + unlink(prvkeyfile); + free(prvkeyfile); + + for (i=1; i <= sk_X509_num(certstack) - 1; ++i) + /* loop through the proxy chain starting at 2nd most recent proxy */ + { + if (cert = sk_X509_value(certstack, i)) + { + certmem = BIO_new(BIO_s_mem()); + if (PEM_write_bio_X509(certmem, cert) == 1) + { + ptrlen = BIO_get_mem_data(certmem, &ptr); + fwrite(ptr, 1, ptrlen, ofp); + } + + BIO_free(certmem); + } + } + + sk_X509_free(certstack); + + if (fclose(ifp) != 0) return GRST_RET_FAILED; + if (fclose(ofp) != 0) return GRST_RET_FAILED; + return GRST_RET_OK; -} +} -- 1.8.2.3