From ccf0eabc48be41e528c0045887542246010fe42c Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Thu, 29 Jun 2006 08:48:28 +0000 Subject: [PATCH] Sync --- org.gridsite.core/src/grst_x509.c | 77 +++++++++++++++++++++++++++++- org.gridsite.core/src/htproxyput.c | 91 +++++++++++++++++++++++++++++++----- org.gridsite.core/src/mod_gridsite.c | 33 +++++++++---- 3 files changed, 179 insertions(+), 22 deletions(-) diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c index 31a89c9..fe2905a 100644 --- a/org.gridsite.core/src/grst_x509.c +++ b/org.gridsite.core/src/grst_x509.c @@ -1121,13 +1121,88 @@ static void mkdir_printf(mode_t mode, char *fmt, ...) free(path); } +/// Create a X.509 request for a GSI proxy and its private key +/** + * Returns GRST_RET_OK on success, non-zero otherwise. Request string + * and private key are PEM encoded strings + */ + +int GRSTx509CreateProxyRequest(char **reqtxt, char **keytxt, char *ocspurl) +{ + int i; + char *ptr; + size_t ptrlen; + RSA *keypair; + X509_NAME *subject; + X509_NAME_ENTRY *ent; + EVP_PKEY *pkey; + X509_REQ *certreq; + BIO *reqmem, *keymem; + const EVP_MD *digest; + struct stat statbuf; + + /* create key pair and put it in a PEM string */ + + if ((keypair = RSA_generate_key(GRST_KEYSIZE, 65537, NULL, NULL)) == NULL) + return 1; + + keymem = BIO_new(BIO_s_mem()); + if (!PEM_write_bio_RSAPrivateKey(keymem, keypair, NULL, NULL, 0, NULL, NULL)) + { + BIO_free(keymem); + return 3; + } + + ptrlen = BIO_get_mem_data(keymem, &ptr); + + *keytxt = malloc(ptrlen + 1); + memcpy(*keytxt, ptr, ptrlen); + (*keytxt)[ptrlen] = '\0'; + + BIO_free(keymem); + + /* now create the certificate request */ + + certreq = X509_REQ_new(); + + OpenSSL_add_all_algorithms(); + + pkey = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(pkey, keypair); + + X509_REQ_set_pubkey(certreq, pkey); + + subject = X509_NAME_new(); + ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("organizationName"), + MBSTRING_ASC, "Dummy", -1); + X509_NAME_add_entry (subject, ent, -1, 0); + X509_REQ_set_subject_name (certreq, subject); + + digest = EVP_md5(); + X509_REQ_sign(certreq, pkey, digest); + + reqmem = BIO_new(BIO_s_mem()); + PEM_write_bio_X509_REQ(reqmem, certreq); + ptrlen = BIO_get_mem_data(reqmem, &ptr); + + *reqtxt = malloc(ptrlen + 1); + memcpy(*reqtxt, ptr, ptrlen); + (*reqtxt)[ptrlen] = '\0'; + + BIO_free(reqmem); + + X509_REQ_free(certreq); + + return 0; +} + /// Make and store a X.509 request for a GSI proxy /** * Returns GRST_RET_OK on success, non-zero otherwise. Request string * is PEM encoded, and the key is stored in the temporary cache under * proxydir */ - + int GRSTx509MakeProxyRequest(char **reqtxt, char *proxydir, char *delegation_id, char *user_dn) { diff --git a/org.gridsite.core/src/htproxyput.c b/org.gridsite.core/src/htproxyput.c index cf52474..d1f0d87 100644 --- a/org.gridsite.core/src/htproxyput.c +++ b/org.gridsite.core/src/htproxyput.c @@ -55,6 +55,10 @@ http://www.gridpp.ac.uk/authz/gridsite/ #include #include +#include +#include +#include + #include #include @@ -68,6 +72,7 @@ http://www.gridpp.ac.uk/authz/gridsite/ #define HTPROXY_DESTROY 2 #define HTPROXY_TIME 3 #define HTPROXY_UNIXTIME 4 +#define HTPROXY_MAKE 5 void printsyntax(char *argv0) { @@ -85,10 +90,10 @@ int main(int argc, char *argv[]) { char *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, *cert = NULL, *key = NULL, *capath = NULL, *keycert, timestr[81], - *executable; + *executable, *keytxt, *proxychain, *ptr; struct ns__putProxyResponse *unused; struct tm *finish_tm; - int option_index, c, noverify = 0, + int option_index, c, noverify = 0, i, method = HTPROXY_PUT, verbose = 0, fd, minutes; struct soap soap_get, soap_put; struct ns__getProxyReqResponse getProxyReqResponse; @@ -97,6 +102,10 @@ int main(int argc, char *argv[]) struct ns__destroyResponse destroyResponse; struct ns__getTerminationTimeResponse getTerminationTimeResponse; FILE *ifp, *ofp; + STACK_OF(X509) *x509_certstack; + X509 *x509_cert; + BIO *certmem; + long ptrlen; struct stat statbuf; struct passwd *userpasswd; struct option long_options[] = { {"verbose", 0, 0, 'v'}, @@ -111,6 +120,7 @@ int main(int argc, char *argv[]) {"put", 0, 0, 0}, {"renew", 0, 0, 0}, {"unixtime", 0, 0, 0}, + {"make", 0, 0, 0}, {0, 0, 0, 0} }; if (argc == 1) @@ -139,16 +149,11 @@ int main(int argc, char *argv[]) else if (option_index == 9) method = HTPROXY_PUT; else if (option_index == 10) method = HTPROXY_RENEW; else if (option_index == 11) method = HTPROXY_UNIXTIME; + else if (option_index == 12) method = HTPROXY_MAKE; } else if (c == 'v') ++verbose; } - if (optind + 1 != argc) - { - fprintf(stderr, "Must specify a delegation service URL!\n"); - return 1; - } - executable = rindex(argv[0], '/'); if (executable != NULL) executable++; else executable = argv[0]; @@ -158,6 +163,13 @@ int main(int argc, char *argv[]) else if (strcmp(executable, "htproxytime") == 0) method = HTPROXY_TIME; else if (strcmp(executable, "htproxyunixtime") == 0) method = HTPROXY_UNIXTIME; + else if (strcmp(executable, "htproxymake") == 0) method = HTPROXY_MAKE; + + if ((method != HTPROXY_MAKE) && (optind + 1 != argc)) + { + fprintf(stderr, "Must specify a delegation service URL!\n"); + return 1; + } if ((method == HTPROXY_RENEW) && (delegation_id[0] == '\0')) { @@ -177,12 +189,14 @@ int main(int argc, char *argv[]) else if ((cert != NULL) && (key == NULL)) key = cert; else if ((cert == NULL) && (key == NULL)) { - cert = getenv("X509_USER_PROXY"); + if (method != HTPROXY_MAKE) cert = getenv("X509_USER_PROXY"); + if (cert != NULL) key = cert; else { - asprintf(&(cert), "/tmp/x509up_u%d", geteuid()); - + if (method != HTPROXY_MAKE) + asprintf(&(cert), "/tmp/x509up_u%d", geteuid()); + /* one fine day, we will check the proxy file for expiry too to avoid suprises when we try to use it ... */ @@ -421,6 +435,61 @@ int main(int argc, char *argv[]) return 0; } + else if (method == HTPROXY_MAKE) + { + if (GRSTx509CreateProxyRequest(&reqtxt, &keytxt, NULL) != GRST_RET_OK) + { + fprintf(stderr, "Failed to create internal proxy cert request\n"); + return 1; + } + + if (GRSTx509MakeProxyCert(&proxychain, NULL, reqtxt, cert, key, minutes) + != GRST_RET_OK) + { + fprintf(stderr, "Failed to sign internal proxy cert request\n"); + return 2; + } + + if (GRSTx509StringToChain(&x509_certstack, proxychain) != GRST_RET_OK) + { + fprintf(stderr, "Failed to convert internal proxy chain\n"); + return 3; + } + + if (x509_cert = sk_X509_value(x509_certstack, 0)) + { + certmem = BIO_new(BIO_s_mem()); + if (PEM_write_bio_X509(certmem, x509_cert) == 1) + { + ptrlen = BIO_get_mem_data(certmem, &ptr); + fwrite(ptr, 1, ptrlen, stdout); + } + + BIO_free(certmem); + } + + fputs(keytxt, stdout); + + for (i=1; i <= sk_X509_num(x509_certstack) - 1; ++i) + /* loop through the proxy chain starting at 2nd most recent proxy */ + { + if (x509_cert = sk_X509_value(x509_certstack, i)) + { + certmem = BIO_new(BIO_s_mem()); + if (PEM_write_bio_X509(certmem, x509_cert) == 1) + { + ptrlen = BIO_get_mem_data(certmem, &ptr); + fwrite(ptr, 1, ptrlen, stdout); + } + + BIO_free(certmem); + } + } + + sk_X509_free(x509_certstack); + + return 0; + } /* weirdness */ } diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index 8c8fb7e..4fb177b 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -823,11 +823,10 @@ int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf) int http_put_method(request_rec *r, mod_gridsite_dir_cfg *conf) { - char buf[2048]; + char buf[2048], *filename; size_t block_length, length_sent; int retcode, stat_ret; apr_file_t *fp; - apr_int32_t open_flag; struct stat statbuf; int has_range = 0, is_done = 0; apr_off_t range_start, range_end, range_length, length_to_send; @@ -872,23 +871,29 @@ int http_put_method(request_rec *r, mod_gridsite_dir_cfg *conf) else return OK; } - open_flag = APR_WRITE | APR_CREATE | APR_BUFFERED; + filename = r->filename; + + if (apr_file_open(&fp, filename, APR_WRITE | APR_CREATE | APR_BUFFERED, + conf->diskmode, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; } - else open_flag = APR_WRITE | APR_CREATE | APR_BUFFERED | APR_TRUNCATE; + else /* use temporary file if not a partial transfer */ + { + filename = apr_psprintf(r->pool, "%s.tmpXXXXXX", r->filename); - if (apr_file_open(&fp, r->filename, open_flag, - conf->diskmode, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; - + if (apr_file_mktemp(&fp, filename, + APR_CREATE | APR_WRITE | APR_BUFFERED | APR_EXCL, r->pool) + != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; + } + /* we force the permissions, rather than accept any existing ones */ - apr_file_perms_set(r->filename, conf->diskmode); + apr_file_perms_set(filename, conf->diskmode); if (has_range) { if (apr_file_seek(fp, APR_SET, &range_start) != 0) { retcode = HTTP_INTERNAL_SERVER_ERROR; - //break; return retcode; } @@ -925,7 +930,15 @@ int http_put_method(request_rec *r, mod_gridsite_dir_cfg *conf) ap_set_content_type(r, "text/html"); } - if (apr_file_close(fp) != 0) return HTTP_INTERNAL_SERVER_ERROR; + if ((apr_file_close(fp) != 0) || (retcode == HTTP_INTERNAL_SERVER_ERROR)) + { + if (strcmp(filename, r->filename) != 0) remove(filename); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if ((strcmp(filename, r->filename) != 0) && + (apr_file_rename(filename, r->filename, r->pool) != 0)) + return HTTP_FORBIDDEN; /* best guess as to the problem ... */ if ((retcode == OK) && (stat_ret != 0)) { -- 1.8.2.3