From 3db777a079717ba20569afef34f80bb733481860 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Tue, 27 Jun 2006 15:32:30 +0000 Subject: [PATCH] Add gridsite-ws back in --- org.gridsite.core/src/Makefile | 85 +++++- org.gridsite.core/src/delegation.h | 98 +++++- org.gridsite.core/src/grst-delegation.c | 414 ++++++++++++++----------- org.gridsite.core/src/gsoap-test.c | 2 + org.gridsite.core/src/htproxyput.c | 520 ++++++++++++-------------------- 5 files changed, 592 insertions(+), 527 deletions(-) create mode 100644 org.gridsite.core/src/gsoap-test.c diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index 5fc7d21..38de96f 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -52,6 +52,8 @@ ifndef MYLDFLAGS export MYLDFLAGS=-L. endif + + # # Build # @@ -219,8 +221,6 @@ showx509exts: showx509exts.c libgridsite.a -I/usr/kerberos/include \ -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm - - slashgrid: slashgrid.c libgridsite.so.$(VERSION) gcc -g -o slashgrid -lfuse -lpthread slashgrid.c \ @@ -252,7 +252,59 @@ xacmlexample: xacmlexample.c libgridsite.a gcc -g -o xacmlexample xacmlexample.c -I. -L. \ -I/usr/kerberos/include -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm +# +# Delegation machinery, including SOAP delegation portType. To build this +# you either need to use the gLite build environment and set REPOSITORY +# or install gSOAP and set GSOAPDIR to the directory containing +# soapcpp2 and stdsoap2.h (unless GSOAPDIR is set already) +# +ifndef GSOAPDIR + export GSOAPDIR=/usr +endif + +ifndef GRIDSITEDIR + export GRIDSITEDIR=/usr +endif + + +DelegationService.wsdl: delegation.h + $(GSOAPDIR)/bin/soapcpp2 -c delegation.h + +gridsite-delegation.cgi: grst-delegation.c delegation.h DelegationService.wsdl + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ + grst-delegation.c \ + -I/usr/kerberos/include -I. -I$(GSOAPDIR)/include \ + -I$(GRIDSITEDIR)/include \ + -DVERSION=\"$(VERSION)\" -L$(GSOAPDIR)/lib \ + -L$(GRIDSITEDIR)/lib \ + soapC.c soapServer.c -lgsoap \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm + +htproxyput: htproxyput.c delegation.h DelegationService.wsdl + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ + htproxyput.c \ + -I/usr/kerberos/include -I. \ + -g -DVERSION=\"$(VERSION)\" \ + -I$(GSOAPDIR)/include \ + -I$(GRIDSITEDIR)/include \ + -DWITH_OPENSSL -L$(GSOAPDIR)/lib \ + $(STDSOAP2) -L$(GRIDSITEDIR)/lib \ + soapC.c soapClient.c -lgsoapssl \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm + +# This target is used by make-gridsite-spec to test for gSOAP include+libs +gsoap-test: gsoap-test.c + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gsoap-test \ + gsoap-test.c \ + -I/usr/kerberos/include -I. \ + -g -DVERSION=\"$(VERSION)\" \ + -I$(GSOAPDIR)/include \ + -I$(GRIDSITEDIR)/include \ + -DWITH_OPENSSL -L$(GSOAPDIR)/lib \ + $(STDSOAP2) -L$(GRIDSITEDIR)/lib \ + -lgsoapssl -lz -lssl -lcrypto -lxml2 -lm + clean: # @@ -319,6 +371,31 @@ install-slashgrid: slashgrid mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/headers mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/blocks mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/tmp + +install-ws: gridsite-delegation.cgi htproxyput + mkdir -p $(prefix)/include \ + $(prefix)/lib \ + $(prefix)/bin \ + $(prefix)/sbin \ + $(prefix)/share/man/man1 \ + $(prefix)/share/man/man8 \ + $(prefix)/share/doc/gridsite-$(MINOR_VERSION) + for i in CHANGES README INSTALL LICENSE VERSION ; \ + do cp -f ../$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION)/$$i-services ; done + for i in CHANGES README INSTALL LICENSE VERSION ; \ + do cp -f ../$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION)/$$i-commands ; done + cp -f ../doc/*.1 ../doc/*.8 \ + ../doc/*.wsdl $(prefix)/share/doc/gridsite-$(MINOR_VERSION) + cp -f ../doc/*.1 $(prefix)/share/man/man1 + cp -f ../doc/*.8 $(prefix)/share/man/man8 + gzip -f $(prefix)/share/man/man1/*.1 + gzip -f $(prefix)/share/man/man8/*.8 + cp -f htproxyput $(prefix)/bin + ln -sf htproxyput $(prefix)/bin/htproxydestroy + ln -sf htproxyput $(prefix)/bin/htproxytime + ln -sf htproxyput $(prefix)/bin/htproxyunixtime + ln -sf htproxyput $(prefix)/bin/htproxyrenew + cp -f gridsite-delegation.cgi $(prefix)/sbin # # Distributions @@ -333,8 +410,8 @@ dist: ../dist/gridsite-$(PATCH_VERSION) cp -f Makefile grst*.c htcp.c slashgrid.c slashgrid.init \ urlencode.c findproxyfile.c gaclexample.c mod_gridsite.c \ - grst_admin.h mod_ssl-private.h \ - gsexec.c gsexec.h gridsite-copy.c \ + htproxyput.c grst_admin.h mod_ssl-private.h \ + gsexec.c gsexec.h gridsite-copy.c fuse-test.c gsoap-test.c \ roffit make-gridsite-spec \ Doxyfile doxygen.css doxyheader.html \ ../dist/gridsite-$(PATCH_VERSION)/src diff --git a/org.gridsite.core/src/delegation.h b/org.gridsite.core/src/delegation.h index e612498..01b462f 100644 --- a/org.gridsite.core/src/delegation.h +++ b/org.gridsite.core/src/delegation.h @@ -1,12 +1,86 @@ -//gsoap ns service name: delegation -//gsoap ns service style: rpc -//gsoap ns service encoding: encoded -//gsoap ns service namespace: http://www.gridsite.org/ns/delegation.wsdl -//gsoap ns service location: http://localhost/delegserver.cgi - -struct ns__putProxyResponse { } ; - -//gsoap ns schema namespace: urn:delegation -int ns__getProxyReq(char *delegationID, char **request); -int ns__putProxy(char *delegationID, char *proxy, - struct ns__putProxyResponse *unused); +//gsoap ns schema namespace: http://www.gridsite.org/namespaces/delegation-1 + +struct ns__DelegationExceptionType +{ + char *message; //nillable +}; + +struct ns__NewProxyReq +{ + char *proxyRequest; //nillable + char *delegationID; //nillable +}; + +struct _DelegationException +{ + struct ns__DelegationExceptionType *ns__DelegationException; +}; + +//gsoap ns service name: DelegationSoapBinding +//gsoap ns service type: Delegation +//gsoap ns service port: https://localhost/gridsite-delegation.cgi +//gsoap ns service namespace: http://www.gridsite.org/namespaces/delegation-1 + +/* *** getProxyReq method *** */ + +//gsoap ns service method-style: rpc +//gsoap ns service method-encoding: literal +//gsoap ns service method-action: "" +//gsoap ns service method-fault: getProxyReq _DelegationException + +int ns__getProxyReq(char *_delegationID, + struct ns__getProxyReqResponse { + char *getProxyReqReturn; } *); + +/* *** getNewProxyReq method *** */ + +//gsoap ns service method-style: getNewProxyReq rpc +//gsoap ns service method-encoding: getNewProxyReq literal +//gsoap ns service method-action: getNewProxyReq "" +//gsoap ns service method-fault: getNewProxyReq _DelegationException + +int ns__getNewProxyReq(struct ns__getNewProxyReqResponse { + struct ns__NewProxyReq *getNewProxyReqReturn; } *); + +/* *** renewProxyReq method *** */ + +//gsoap ns service method-style: renewProxyReq rpc +//gsoap ns service method-encoding: renewProxyReq literal +//gsoap ns service method-action: renewProxyReq "" +//gsoap ns service method-fault: renewProxyReq _DelegationException + +int ns__renewProxyReq(char *_delegationID, + struct ns__renewProxyReqResponse { + char *_renewProxyReqReturn; } *); + +/* *** putProxy method *** */ + +//gsoap ns service method-style: putProxy rpc +//gsoap ns service method-encoding: putProxy literal +//gsoap ns service method-action: putProxy "" +//gsoap ns service method-fault: putProxy _DelegationException + +int ns__putProxy(char *_delegationID, + char *_proxy, + struct ns__putProxyResponse { } *); + +/* *** getTerminationTime method *** */ + +//gsoap ns service method-style: getTerminationTime rpc +//gsoap ns service method-encoding: getTerminationTime literal +//gsoap ns service method-action: getTerminationTime "" +//gsoap ns service method-fault: getTerminationTime _DelegationException + +int ns__getTerminationTime(char *_delegationID, + struct ns__getTerminationTimeResponse { + time_t _getTerminationTimeReturn; } *); + +/* *** destroy method *** */ + +//gsoap ns service method-style: destroy rpc +//gsoap ns service method-encoding: destroy literal +//gsoap ns service method-action: destroy "" +//gsoap ns service method-fault: destroy _DelegationException + +int ns__destroy(char *_delegationID, + struct ns__destroyResponse { } *); diff --git a/org.gridsite.core/src/grst-delegation.c b/org.gridsite.core/src/grst-delegation.c index c8f8185..87f2278 100644 --- a/org.gridsite.core/src/grst-delegation.c +++ b/org.gridsite.core/src/grst-delegation.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-4, Andrew McNab, University of Manchester + Copyright (c) 2002-6, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -50,248 +50,298 @@ #include #include -#include -#include -#include -#include -#include -#include -#include - -#include -/* #include */ - -#include "gridsite.h" +#include #include "soapH.h" -#include "delegation.nsmap" +#include "DelegationSoapBinding.nsmap" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define GRST_KEYSIZE 512 #define GRST_PROXYCACHE "/../proxycache/" -#define GRST_SUPPORT_G_HTTPS -#ifdef GRST_SUPPORT_G_HTTPS -void GRSThttpError(char *status) +int main(int argn, char *argv[]) { - printf("Status: %s\n", status); - printf("Server-CGI: GridSite %s\n", VERSION); - printf("Content-Length: %d\n", 2 * strlen(status) + 58); - puts("Content-Type: text/html\n"); - - printf("%s\n", status); - printf("

%s

\n", status); - - exit(0); + char *docroot, *method, *request, *p, *client_dn, *user_dn, + *delegation_id, *reqtxt, *proxydir; + struct soap soap; + + method = getenv("REQUEST_METHOD"); + if (strcmp(method, "POST") == 0) + { + soap_init(&soap); + soap_serve(&soap); /* CGI application */ + return 0; + } + + puts("Status: 501 Method Not Implemented\n"); + return 0; } -int GRSTmethodPutProxy(char *delegation_id, char *user_dn) -/* return 0 on success; non-zero on error */ +char *get_dn(void) { - int c, len = 0, i; - char *docroot, *contentlen, *contenttype, *proxychain, *proxydir; - FILE *fp; - - if (((contenttype = getenv("CONTENT_TYPE")) == NULL) || - (strcmp(contenttype, "application/x-x509-user-cert-chain") != 0)) - return 2; + int i; + char *p, *s, *dn; + GRSTgaclCred *cred = NULL; + + for (i=0; ; ++i) + { + asprintf(&p, "GRST_CRED_%d", i); + s = getenv(p); + free(p); + + if (s == NULL) break; + + if ((cred = GRSTx509CompactToCred(s)) == NULL) break; + + if ((strcmp(cred->type, "person") == 0) && + (cred->firstname != NULL) && + (cred->firstname->name != NULL) && + (strcmp(cred->firstname->name, "dn") == 0) && + (cred->firstname->value != NULL)) + { + dn = strdup(cred->firstname->value); + GRSTgaclCredFree(cred); + return dn; + } + + GRSTgaclCredFree(cred); + } - contentlen = getenv("CONTENT_LENGTH"); - if (contentlen == NULL) return 2; - len = atoi(contentlen); + return NULL; +} + +int ns__getProxyReq(struct soap *soap, + char *delegation_id, + struct ns__getProxyReqResponse *response) +{ + int i; + char *p, *user_dn, *docroot, *proxydir, *request; + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; + if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = "_"; + delegation_id = GRSTx509MakeDelegationID(); + else for (i=0; delegation_id[i] != '\0'; ++i) + { + if (!isalnum(delegation_id[i]) && + (delegation_id[i] != '.') && + (delegation_id[i] != ',') && + (delegation_id[i] != '_')) + { + delegation_id = NULL; + break; + } + } docroot = getenv("DOCUMENT_ROOT"); asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - if ((user_dn == NULL) || (user_dn[0] == '\0') || - (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxychain) - != GRST_RET_OK)) + if ((user_dn != NULL) && + (user_dn[0] != '\0') && + (delegation_id != NULL) && + (GRSTx509MakeProxyRequest(&request, proxydir, + delegation_id, user_dn) == 0)) { - return GRST_RET_FAILED; - } + response->getProxyReqReturn = request; - free(proxydir); + free(user_dn); + return SOAP_OK; + } - return GRST_RET_OK; -} -#endif + free(user_dn); + return SOAP_ERR; +} -int main(int argn, char *argv[]) +int ns__getNewProxyReq(struct soap *soap, + struct ns__getNewProxyReqResponse *response) { - char *docroot, *method, *request, *p, *client_dn, *user_dn, - *delegation_id, *reqtxt, *proxydir; - struct soap soap; + char *p, *user_dn, *docroot, *proxydir, *request, *delegation_id; -chdir("/var/tmp"); + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; + + delegation_id = GRSTx509MakeDelegationID(); - method = getenv("REQUEST_METHOD"); - if (strcmp(method, "POST") == 0) - { - soap_init(&soap); - soap_serve(&soap); /* CGI application */ - return 0; - } - -#ifdef GRST_SUPPORT_G_HTTPS docroot = getenv("DOCUMENT_ROOT"); + asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - request = strdup(getenv("REQUEST_URI")); - p = index(request, '?'); - if (p != NULL) *p = '\0'; - - - /* non HTTP POST methods - ie special G-HTTPS methods */ - - delegation_id = getenv("HTTP_DELEGATION_ID"); - if ((delegation_id == NULL) || (*delegation_id == '\0')) delegation_id = "_"; - - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) + if ((user_dn != NULL) && + (user_dn[0] != '\0') && + (delegation_id != NULL) && + (GRSTx509MakeProxyRequest(&request, proxydir, + delegation_id, user_dn) == 0)) { - user_dn = strdup(client_dn); - - /* we assume here that mod_ssl has verified proxy chain already ... */ + response->getNewProxyReqReturn = malloc(sizeof(struct ns__NewProxyReq)); + response->getNewProxyReqReturn->proxyRequest = request; + response->getNewProxyReqReturn->delegationID = delegation_id; + + free(user_dn); + return SOAP_OK; + } - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; + free(user_dn); + return SOAP_ERR; +} + +int ns__putProxy(struct soap *soap, char *delegation_id, + char *proxy, + struct ns__putProxyResponse *response) +{ + int fd, c, len = 0, i; + char *docroot, *proxydir, *p, *user_dn; + + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; + + if ((delegation_id == NULL) || (*delegation_id == '\0')) + delegation_id = GRSTx509MakeDelegationID(); + else for (i=0; delegation_id[i] != '\0'; ++i) + { + if (!isalnum(delegation_id[i]) && + (delegation_id[i] != '.') && + (delegation_id[i] != ',') && + (delegation_id[i] != '_')) + { + delegation_id = NULL; + break; + } + } + + docroot = getenv("DOCUMENT_ROOT"); + asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; + if ((user_dn == NULL) || + (user_dn[0] == '\0') || + (delegation_id == NULL) || + (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxy) + != GRST_RET_OK)) + { + free(proxydir); + free(user_dn); + return SOAP_ERR; } + + free(proxydir); + free(user_dn); + return SOAP_OK; +} + +int ns__renewProxyReq(struct soap *soap, + char *delegation_id, + struct ns__renewProxyReqResponse *response) +{ + int i; + char *p, *user_dn, *docroot, *proxydir, *request; - if (user_dn == NULL) /* all methods require client auth */ - { - GRSThttpError("403 Forbidden"); - } - else if (strcmp(method, "GET-PROXY-REQ") == 0) + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; + + if (delegation_id == NULL) { - docroot = getenv("DOCUMENT_ROOT"); - asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); + free(user_dn); + return SOAP_ERR; + } - if (GRSTx509MakeProxyRequest(&reqtxt, proxydir, - delegation_id, user_dn) == 0) - { - puts("Status: 200 OK"); - puts("Content-Type: application/x-x509-cert-request"); - printf("Content-Length: %d\n\n", strlen(reqtxt)); - fputs(reqtxt, stdout); - free(proxydir); - return 0; - } - - puts("Status: 500 Internal Server Error\n"); - free(proxydir); - return 0; - } - else if (strcmp(method, "PUT-PROXY-CERT") == 0) - { - if (GRSTmethodPutProxy(delegation_id, user_dn) == 0) - { - puts("Status: 200 OK\n"); - return 0; - } - - puts("Status: 500 Internal Server Error\n"); - return 0; - } - else + for (i=0; delegation_id[i] != '\0'; ++i) + { + if (!isalnum(delegation_id[i]) && + (delegation_id[i] != '.') && + (delegation_id[i] != ',') && + (delegation_id[i] != '_')) + { + delegation_id = NULL; + break; + } + } + + if (*delegation_id == '\0') { - GRSThttpError("501 Method Not Implemented"); + free(user_dn); + return SOAP_ERR; } -#endif -} + + docroot = getenv("DOCUMENT_ROOT"); + asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); -int ns__getProxyReq(struct soap *soap, char *delegation_id, - char **request) -{ - char *p, *client_dn, *user_dn, *docroot, *proxydir; - - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) + if ((user_dn != NULL) && + (user_dn[0] != '\0') && + (delegation_id != NULL) && + (GRSTx509MakeProxyRequest(&request, proxydir, + delegation_id, user_dn) == 0)) { - user_dn = strdup(client_dn); + response->_renewProxyReqReturn = request; + + free(user_dn); + return SOAP_OK; + } - /* we assume here that mod_ssl has verified proxy chain already ... */ + free(user_dn); + return SOAP_ERR; +} - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; +int ns__getTerminationTime(struct soap *soap, + char *delegation_id, + struct ns__getTerminationTimeResponse *response) +{ + char *p, *user_dn, *docroot, *proxydir; + time_t start, finish; - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; - } + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; - if ((delegation_id == NULL) || (*delegation_id == '\0')) delegation_id = "_"; + delegation_id = GRSTx509MakeDelegationID(); docroot = getenv("DOCUMENT_ROOT"); asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - if ((user_dn != NULL) && (user_dn[0] != '\0') && - (GRSTx509MakeProxyRequest(request, proxydir, - delegation_id, user_dn) == 0)) + if ((user_dn != NULL) && + (user_dn[0] != '\0') && + (delegation_id != NULL) && + (GRSTx509ProxyGetTimes(proxydir, delegation_id, user_dn, + &start, &finish) == 0)) { + response->_getTerminationTimeReturn = finish; + + free(user_dn); return SOAP_OK; } - + + free(user_dn); return SOAP_ERR; -} +} -int ns__putProxy(struct soap *soap, char *delegation_id, - char *proxy, - struct ns__putProxyResponse *unused) -{ +int ns__destroy(struct soap *soap, + char *delegation_id, + struct ns__destroyResponse *response) +{ int fd, c, len = 0, i; char *docroot, *proxydir, *p, *client_dn, *user_dn; - user_dn = NULL; - client_dn = getenv("SSL_CLIENT_S_DN"); - if (client_dn != NULL) - { - user_dn = strdup(client_dn); - - /* we assume here that mod_ssl has verified proxy chain already ... */ - - p = strstr(user_dn, "/CN=proxy"); - if (p != NULL) *p = '\0'; - - p = strstr(user_dn, "/CN=limited proxy"); - if (p != NULL) *p = '\0'; - } + if ((user_dn = get_dn()) == NULL) return SOAP_ERR; if ((delegation_id == NULL) || (*delegation_id == '\0')) - delegation_id = "_"; + delegation_id = GRSTx509MakeDelegationID(); + else for (i=0; delegation_id[i] != '\0'; ++i) + { + if (!isalnum(delegation_id[i]) && + (delegation_id[i] != '.') && + (delegation_id[i] != ',') && + (delegation_id[i] != '_')) + { + delegation_id = NULL; + break; + } + } docroot = getenv("DOCUMENT_ROOT"); asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); - if ((user_dn == NULL) || (user_dn[0] == '\0') || - (GRSTx509CacheProxy(proxydir, delegation_id, user_dn, proxy) + if ((user_dn == NULL) || + (user_dn[0] == '\0') || + (delegation_id == NULL) || + (GRSTx509ProxyDestroy(proxydir, delegation_id, user_dn) != GRST_RET_OK)) { + free(proxydir); + free(user_dn); return SOAP_ERR; } + free(proxydir); + free(user_dn); return SOAP_OK; -} - +} diff --git a/org.gridsite.core/src/gsoap-test.c b/org.gridsite.core/src/gsoap-test.c new file mode 100644 index 0000000..8ece987 --- /dev/null +++ b/org.gridsite.core/src/gsoap-test.c @@ -0,0 +1,2 @@ +#include +main() { struct soap sp; soap_init(&sp); } diff --git a/org.gridsite.core/src/htproxyput.c b/org.gridsite.core/src/htproxyput.c index 834bea2..cf52474 100644 --- a/org.gridsite.core/src/htproxyput.c +++ b/org.gridsite.core/src/htproxyput.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-4, Andrew McNab, University of Manchester + Copyright (c) 2002-6, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -49,266 +49,26 @@ http://www.gridpp.ac.uk/authz/gridsite/ #include #include #include - -#include -#include -#include +#include #include #include #include -#include -#include -#include -#include - -#include -#include -#include - #include -#include "gridsite.h" - -#include "soapH.h" -#include "delegation.nsmap" - -#define USE_SOAP 0 -#define USE_G_HTTPS 1 -#define HTPROXY_PUT 0 - -int debugfunction(CURL *curl, curl_infotype type, char *s, size_t n, void *p) -{ - fwrite(s, sizeof(char), n, (FILE *) p); - - return 0; -} - -size_t parsegprheaders(void *ptr, size_t size, size_t nmemb, void *p) -{ - int i; - - if ((size * nmemb > 15) && - (strncmp((char *) ptr, "Delegation-ID: ", 15) == 0)) - { - *((char **) p) = malloc( size * nmemb - 14 ); - - memcpy(*((char **) p), &(((char *) ptr)[15]), size * nmemb - 15); - - for (i=0; i < size * nmemb - 15; ++i) - if (((*((char **) p))[i] == '\n') || ((*((char **) p))[i] == '\r')) - { - (*((char **) p))[i] = '\0'; /* drop trailing newline */ - break; - } - - (*((char **) p))[size * nmemb - 15] = '\0'; - } - - return size * nmemb; -} - -struct gprparams { char *req; size_t len; } ; - -size_t storegprbody(void *ptr, size_t size, size_t nmemb, void *p) -{ - ((struct gprparams *) p)->req = realloc( ((struct gprparams *) p)->req, - ((struct gprparams *) p)->len + size * nmemb + 1); - - memcpy( &((((struct gprparams *) p)->req)[((struct gprparams *) p)->len]), - ptr, size * nmemb); - - ((struct gprparams *) p)->len += size * nmemb; - - return size * nmemb; -} - -int GRSTgetProxyReq(CURL *curl, FILE *debugfp, char *delegid, char **reqtxt, - char *requrl, char *cert, char *key) -{ - char *delheader; - struct curl_slist *headerlist = NULL; - CURLcode res; - struct gprparams params; - - params.req = NULL; - params.len = 0; - - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) ¶ms); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, storegprbody); - - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, cert); - - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, key); - curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - -// curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parsegprheaders); -// curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *) delegid); - - curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/grid-security/certificates/"); - - curl_easy_setopt(curl, CURLOPT_URL, requrl); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET-PROXY-REQ"); - - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,0); - - asprintf(&delheader, "Delegation-ID: %s", delegid); - headerlist = curl_slist_append(headerlist, delheader); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - - if (debugfp != NULL) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGDATA, debugfp); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debugfunction); - } - - res = curl_easy_perform(curl); - - if (params.req != NULL) - { - params.req[params.len] = '\0'; - *reqtxt = params.req; - } - else *reqtxt = NULL; - - return (int) res; -} - -struct ppcparams{ char *cert; size_t len; }; - -size_t getppcbody(void *ptr, size_t size, size_t nmemb, void *p) -{ - size_t i; - - if (((struct ppcparams *) p)->len == 0) return 0; - - if (size * nmemb < ((struct ppcparams *) p)->len) i = size * nmemb; - else i = ((struct ppcparams *) p)->len; - - memcpy(ptr, ((struct ppcparams *) p)->cert, i); - - ((struct ppcparams *) p)->len -= i; - ((struct ppcparams *) p)->cert = &((((struct ppcparams *) p)->cert)[i+1]); - - return i; -} - -int GRSTputProxyCerts(CURL *curl, FILE *debugfp, char *delegid, char *certtxt, - char *requrl, char *cert, char *key) -{ - CURLcode res; - char *delheader; - long httpcode; - struct curl_slist *headerlist = NULL; - struct ppcparams params; - - params.cert = certtxt; - params.len = strlen(certtxt); - - curl_easy_setopt(curl, CURLOPT_READDATA, ¶ms); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, getppcbody); - curl_easy_setopt(curl, CURLOPT_INFILESIZE, strlen(certtxt)); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); - - curl_easy_setopt(curl, CURLOPT_NOBODY, 1); - - curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, cert); - - curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, key); -// curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - - curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/grid-security/certificates/"); - - curl_easy_setopt(curl, CURLOPT_URL, requrl); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT-PROXY-CERT"); - - headerlist = curl_slist_append(headerlist, - "Content-Type: application/x-x509-user-cert-chain"); - - asprintf(&delheader, "Delegation-ID: %s", delegid); - headerlist = curl_slist_append(headerlist, delheader); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - -curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); -curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); - - if (debugfp != NULL) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGDATA, debugfp); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, debugfunction); - } - - res = curl_easy_perform(curl); - - curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode); - - curl_slist_free_all(headerlist); - - free(delheader); - - return (int) res; -} - - -#if (LIBCURL_VERSION_NUM < 0x070908) -char *make_tmp_ca_roots(char *dir) -/* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory, - so we make a temporary file with the concatenated CA root certs: that - is, all the files in that directory which end in .0 */ -{ - int ofd, ifd, c; - size_t size; - char tmp_ca_roots[] = "/tmp/.ca-roots-XXXXXX", buffer[4096], *s; - DIR *rootsDIR; - struct dirent *root_ent; - - if ((rootsDIR = opendir(dir)) == NULL) return NULL; +#include - if ((ofd = mkstemp(tmp_ca_roots)) == -1) - { - closedir(rootsDIR); - return NULL; - } +#include - while ((root_ent = readdir(rootsDIR)) != NULL) - { - if ((root_ent->d_name[0] != '.') && - (strlen(root_ent->d_name) > 2) && - (strncmp(&(root_ent->d_name[strlen(root_ent->d_name)-2]), - ".0", 2) == 0)) - { - asprintf(&s, "%s/%s", dir, root_ent->d_name); - ifd = open(s, O_RDONLY); - free(s); +#include "DelegationSoapBinding.nsmap" - if (ifd != -1) - { - while ((size = read(ifd, buffer, sizeof(buffer))) > 0) - write(ofd, buffer, size); - - close(ifd); - } - } - } - - closedir(rootsDIR); - - if (close(ofd) == 0) return strdup(tmp_ca_roots); - - unlink(tmp_ca_roots); /* try to clean up if errors */ +#define HTPROXY_PUT 0 +#define HTPROXY_RENEW 1 +#define HTPROXY_DESTROY 2 +#define HTPROXY_TIME 3 +#define HTPROXY_UNIXTIME 4 - return NULL; -} -#endif - void printsyntax(char *argv0) { char *p; @@ -324,11 +84,18 @@ void printsyntax(char *argv0) int main(int argc, char *argv[]) { char *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, - *cert = NULL, *key = NULL, *capath = NULL, *keycert; + *cert = NULL, *key = NULL, *capath = NULL, *keycert, timestr[81], + *executable; struct ns__putProxyResponse *unused; - int option_index, c, protocol = USE_SOAP, noverify = 0, + struct tm *finish_tm; + int option_index, c, noverify = 0, method = HTPROXY_PUT, verbose = 0, fd, minutes; struct soap soap_get, soap_put; + struct ns__getProxyReqResponse getProxyReqResponse; + struct ns__getNewProxyReqResponse getNewProxyReqResponse; + struct ns__renewProxyReqResponse renewProxyReqResponse; + struct ns__destroyResponse destroyResponse; + struct ns__getTerminationTimeResponse getTerminationTimeResponse; FILE *ifp, *ofp; struct stat statbuf; struct passwd *userpasswd; @@ -336,14 +103,15 @@ int main(int argc, char *argv[]) {"cert", 1, 0, 0}, {"key", 1, 0, 0}, {"capath", 1, 0, 0}, - {"soap", 0, 0, 0}, - {"g-https", 0, 0, 0}, + {"destroy", 0, 0, 0}, + {"time", 0, 0, 0}, {"no-verify", 0, 0, 0}, {"valid", 1, 0, 0}, {"delegation-id",1, 0, 0}, {"put", 0, 0, 0}, + {"renew", 0, 0, 0}, + {"unixtime", 0, 0, 0}, {0, 0, 0, 0} }; - CURL *curl; if (argc == 1) { @@ -360,22 +128,40 @@ int main(int argc, char *argv[]) if (c == -1) break; else if (c == 0) { - if (option_index == 1) cert = optarg; - else if (option_index == 2) key = optarg; - else if (option_index == 3) capath = optarg; - else if (option_index == 4) protocol = USE_SOAP; - else if (option_index == 5) protocol = USE_G_HTTPS; - else if (option_index == 6) noverify = 1; - else if (option_index == 7) valid = optarg; - else if (option_index == 8) delegation_id = optarg; - else if (option_index == 9) method = HTPROXY_PUT; + if (option_index == 1) cert = optarg; + else if (option_index == 2) key = optarg; + else if (option_index == 3) capath = optarg; + else if (option_index == 4) method = HTPROXY_DESTROY; + else if (option_index == 5) method = HTPROXY_TIME; + else if (option_index == 6) noverify = 1; + else if (option_index == 7) valid = optarg; + else if (option_index == 8) delegation_id = optarg; + 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 (c == 'v') ++verbose; } if (optind + 1 != argc) { - fprintf(stderr, "Must specify a target URL!\n"); + fprintf(stderr, "Must specify a delegation service URL!\n"); + return 1; + } + + executable = rindex(argv[0], '/'); + if (executable != NULL) executable++; + else executable = argv[0]; + + if (strcmp(executable, "htproxydestroy") == 0) method = HTPROXY_DESTROY; + else if (strcmp(executable, "htproxyrenew") == 0) method = HTPROXY_RENEW; + else if (strcmp(executable, "htproxytime") == 0) method = HTPROXY_TIME; + else if (strcmp(executable, "htproxyunixtime") == 0) + method = HTPROXY_UNIXTIME; + + if ((method == HTPROXY_RENEW) && (delegation_id[0] == '\0')) + { + fprintf(stderr, "Must give a Delegation ID when renewing\n"); return 1; } @@ -430,73 +216,33 @@ int main(int argc, char *argv[]) if (verbose) fprintf(stderr, "key=%s\ncert=%s\ncapath=%s\n", key, cert, capath); -#if (LIBCURL_VERSION_NUM < 0x070908) - /* libcurl before 7.9.8 doesnt support CURLOPT_CAPATH and the directory */ - - if ((capath != NULL) && - (stat(capath, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) - { - tmp_ca_roots = make_tmp_ca_roots(capath); - capath = tmp_ca_roots; - } -#endif - - if (protocol == USE_G_HTTPS) + if (strcmp(key, cert) != 0) /* we have to concatenate for gSOAP */ { - if (verbose) fprintf(stderr, "Using G-HTTPS delegation protocol\n"); - - if (verbose) fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - -// curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, NULL); - - GRSTgetProxyReq(curl, stderr, delegation_id, &reqtxt, - argv[optind], cert, key); - - if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) - != GRST_RET_OK) - { - return 1; - } - - GRSTputProxyCerts(curl, stderr, delegation_id, certtxt, - argv[optind], cert, key); - - curl_easy_cleanup(curl); - curl_global_cleanup(); - - return 0; - } - else if (protocol == USE_SOAP) - { - if (strcmp(key, cert) != 0) /* we have to concatenate for gSOAP */ - { - keycert = strdup("/tmp/XXXXXX"); + keycert = strdup("/tmp/.XXXXXX"); - fd = mkstemp(keycert); - ofp = fdopen(fd, "w"); + fd = mkstemp(keycert); + ofp = fdopen(fd, "w"); - ifp = fopen(key, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); + ifp = fopen(key, "r"); + while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); + fclose(ifp); - ifp = fopen(cert, "r"); - while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); - fclose(ifp); + ifp = fopen(cert, "r"); + while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); + fclose(ifp); - fclose(ofp); + fclose(ofp); - if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert); - } - else keycert = key; + if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert); + } + else keycert = key; + if ((method == HTPROXY_PUT) || (method == HTPROXY_RENEW)) + { if (verbose) { fprintf(stderr, "Using SOAP delegation protocol\n"); fprintf(stderr, "Delegation-ID: %s\n", delegation_id); - fprintf(stderr, "Send getProxyReq to service\n"); } soap_init(&soap_get); @@ -513,18 +259,44 @@ int main(int argc, char *argv[]) return 1; } - soap_call_ns__getProxyReq(&soap_get, + if ((method == HTPROXY_RENEW) && (delegation_id[0] != '\0')) + { + if (verbose) fprintf(stderr, "Send renewProxyReq to service\n"); + + soap_call_ns__renewProxyReq(&soap_get, argv[optind], /* HTTPS url of service */ - "", /* no password on proxy */ + "http://www.gridsite.org/namespaces/delegation-1", delegation_id, - &reqtxt); + &renewProxyReqResponse); - if (soap_get.error) + if (soap_get.error) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + reqtxt = renewProxyReqResponse._renewProxyReqReturn; + } + else { - soap_print_fault(&soap_get, stderr); - return 1; + if (verbose) fprintf(stderr, "Send getNewProxyReq to service\n"); + + soap_call_ns__getNewProxyReq(&soap_get, + argv[optind], /* HTTPS url of service */ + "http://www.gridsite.org/namespaces/delegation-1", + &getNewProxyReqResponse); + + if (soap_get.error) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + reqtxt = getNewProxyReqResponse.getNewProxyReqReturn->proxyRequest; + delegation_id = + getNewProxyReqResponse.getNewProxyReqReturn->delegationID; } - + if (verbose) fprintf(stderr, "reqtxt:\n%s", reqtxt); if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) @@ -549,7 +321,9 @@ int main(int argc, char *argv[]) return 1; } - soap_call_ns__putProxy(&soap_put, argv[optind], "", delegation_id, + soap_call_ns__putProxy(&soap_put, argv[optind], + "http://www.gridsite.org/namespaces/delegation-1", + delegation_id, certtxt, unused); if (soap_put.error) { @@ -557,6 +331,94 @@ int main(int argc, char *argv[]) return 1; } + puts(delegation_id); + + return 0; + } + else if (method == HTPROXY_DESTROY) + { + if (verbose) + { + fprintf(stderr, "Using SOAP proxy destroy protocol\n"); + fprintf(stderr, "Delegation-ID: %s\n", delegation_id); + } + + soap_init(&soap_put); + + if (verbose) fprintf(stderr, "Send destroy to service:\n"); + + if (soap_ssl_client_context(&soap_put, + SOAP_SSL_DEFAULT, + keycert, + "", + NULL, + capath, + NULL)) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + soap_call_ns__destroy(&soap_put, argv[optind], + "http://www.gridsite.org/namespaces/delegation-1", + delegation_id, + &destroyResponse); + if (soap_put.error) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + return 0; + } + else if ((method == HTPROXY_TIME) || (method == HTPROXY_UNIXTIME)) + { + if (verbose) + { + fprintf(stderr, "Using SOAP proxy get expiration time protocol\n"); + fprintf(stderr, "Delegation-ID: %s\n", delegation_id); + } + + soap_init(&soap_put); + + if (verbose) fprintf(stderr, "Send get time to service:\n"); + + if (soap_ssl_client_context(&soap_put, + SOAP_SSL_DEFAULT, + keycert, + "", + NULL, + capath, + NULL)) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + soap_call_ns__getTerminationTime(&soap_put, argv[optind], + "http://www.gridsite.org/namespaces/delegation-1", + delegation_id, + &getTerminationTimeResponse); + if (soap_put.error) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + + if (method == HTPROXY_UNIXTIME) + printf("%ld\n", getTerminationTimeResponse._getTerminationTimeReturn); + else + { + finish_tm = + localtime(&(getTerminationTimeResponse._getTerminationTimeReturn)); + + strftime(timestr, sizeof(timestr), + "%a %b %e %H:%M:%S %Z %Y\n", finish_tm); + + fputs(timestr, stdout); + } + return 0; } -- 1.8.2.3