From 327e73a23a6b5c6bc0bf8a2c9da750f2ff495e59 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Thu, 7 Dec 2006 13:46:59 +0000 Subject: [PATCH] Sync --- org.gridsite.core/doc/htproxyput.1 | 12 +++ org.gridsite.core/doc/mod_gridsite.8 | 9 ++ org.gridsite.core/src/Makefile | 20 +++- org.gridsite.core/src/grst_admin_file.c | 30 +++--- org.gridsite.core/src/grst_gacl.c | 21 ++++ org.gridsite.core/src/grst_x509.c | 98 +++++++---------- org.gridsite.core/src/make-gridsite-spec | 8 +- org.gridsite.core/src/mod_gridsite.c | 177 ++++++++++++++++++++++++++++--- org.gridsite.core/src/slashgrid.c | 39 +++++-- 9 files changed, 304 insertions(+), 110 deletions(-) diff --git a/org.gridsite.core/doc/htproxyput.1 b/org.gridsite.core/doc/htproxyput.1 index 3d2bf04..a917054 100644 --- a/org.gridsite.core/doc/htproxyput.1 +++ b/org.gridsite.core/doc/htproxyput.1 @@ -6,12 +6,19 @@ .B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew [options] Service-URL +.B htproxyinfo +[options] + .SH DESCRIPTION .B htproxyput is a client to perform GSI proxy delegations using the GridSite/gLite delegation Web Service portType. The gridsite-delegation(8) CGI program is the complementary server-side implementation. +.B htproxyinfo +examines a local copy of a GSI proxy, and outputs a summary of its X.509 and +VOMS contents. + .SH OPTIONS .IP "-v/--verbose" Turn on debugging information. @@ -39,6 +46,11 @@ Delegate an updated version of an existing proxy. The Delegation ID be given when using this option. Calling the program as htproxyrenew has the same effect. +.IP "--info" +Examine a local proxy file, and output a summary of the X.509 certificates +and VOMS attributes it contains. Calling the program as htproxyinfo has the +same effect. + .IP "--cert and --key " Path to the PEM-encoded X.509 or GSI Proxy user certificate and key to use for HTTPS diff --git a/org.gridsite.core/doc/mod_gridsite.8 b/org.gridsite.core/doc/mod_gridsite.8 index cfbea3f..4299e34 100644 --- a/org.gridsite.core/doc/mod_gridsite.8 +++ b/org.gridsite.core/doc/mod_gridsite.8 @@ -182,6 +182,15 @@ HTTPS requests following a session restart. Format to use when writing .gacl files. (Both formats are automatically recognised when reading.) (Default: GACL) +.IP "GridSiteACLPath path" +Specify the absolute or relative (to ServerRoot) path of the ACL file +governing this section of the server's URL space. This can be applied to +virtual URL spaces provided by other modules, such as DAV or SVN, using +the Apache container. If the path contains %0, it is replaced +by this virtual server's hostname. If it contains %1, %2, ... it is replaced +with the 1st, 2nd, ... component of the request's URI, separated by slashes +and counting from immediately after the initial slash. + .IP "GridSiteExecMethod nosetuid|suexec|X509DN|directory" Execution strategy for CGI scripts and executables. For options other than nosetuid, suexec (or gsexec renamed suexec) must installed. For diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index 95f2cbd..2d0e8bf 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -297,9 +297,7 @@ htproxyput: htproxyput.c delegation.h DelegationService.wsdl libgridsite.so.$(VE -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm # This target is used by make-gridsite-spec to test for gSOAP include+libs -gsoap-test: gridsite-delegation.cgi - -gsoap-test-xxx: gsoap-test.c +gsoap-test: gsoap-test.c gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gsoap-test \ gsoap-test.c \ -I/usr/kerberos/include -I. \ @@ -310,6 +308,15 @@ gsoap-test-xxx: gsoap-test.c $(STDSOAP2) -L$(GRIDSITEDIR)/lib \ -lgsoapssl -lz -lssl -lcrypto -lxml2 -lm +gridsite-srm.cgi: gridsite-srm.c libgridsite.so.$(VERSION) + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-srm.cgi \ + gridsite-srm.c \ + -I/usr/kerberos/include -I.\ + -I$(GRIDSITEDIR)/include \ + -DVERSION=\"$(VERSION)\" -L. \ + -L$(GRIDSITEDIR)/lib \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm + clean: # @@ -379,6 +386,10 @@ install-lib: install-slashgrid: slashgrid cp -f slashgrid $(prefix)/sbin cp -f slashgrid.init $(RPM_BUILD_ROOT)/etc/rc.d/init.d/slashgrid + cp -f ../doc/slashgrid.8.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ + cp -f ../doc/slashgrid.8 $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ + cp -f ../doc/slashgrid.8 $(prefix)/share/man/man8 + gzip -f $(prefix)/share/man/man8/slashgrid.8 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 @@ -393,7 +404,7 @@ install-ws: gridsite-delegation.cgi htproxyput $(prefix)/share/doc/gridsite-$(MINOR_VERSION) cp -f ../doc/*.wsdl $(prefix)/share/doc/gridsite-$(MINOR_VERSION) for i in htproxyput.1 htproxytime.1 htproxyrenew.1 htproxydestroy.1 \ - htproxyunixtime.1 ; do \ + htproxyunixtime.1 htproxyinfo.1 ; do \ cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \ cp -f ../doc/$$i $(prefix)/share/man/man1 ; \ @@ -408,6 +419,7 @@ install-ws: gridsite-delegation.cgi htproxyput ln -sf htproxyput $(prefix)/bin/htproxytime ln -sf htproxyput $(prefix)/bin/htproxyunixtime ln -sf htproxyput $(prefix)/bin/htproxyrenew + ln -sf htproxyput $(prefix)/bin/htproxyinfo cp -f gridsite-delegation.cgi $(prefix)/sbin # diff --git a/org.gridsite.core/src/grst_admin_file.c b/org.gridsite.core/src/grst_admin_file.c index b4d47f5..cf85f5d 100644 --- a/org.gridsite.core/src/grst_admin_file.c +++ b/org.gridsite.core/src/grst_admin_file.c @@ -836,8 +836,9 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file) { - int fd; + int c; char *dir_path_file; + FILE *fp; struct stat statbuf; if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden"); @@ -849,19 +850,20 @@ void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, strcpy(dir_path_file, dir_path); strcat(dir_path_file, "/"); strcat(dir_path_file, file); - - fd = open(dir_path_file, O_RDONLY); - if (fd == -1) GRSThttpError("500 Internal server error"); - - if ((fstat(fd, &statbuf) != 0) || + + if ((stat(dir_path_file, &statbuf) != 0) || !S_ISREG(statbuf.st_mode)) GRSThttpError("403 Forbidden"); + fp = fopen(dir_path_file, "r"); + if (fp == NULL) GRSThttpError("500 Internal server error"); + printf("Status: 200 OK\nContent-Type: text/html\nContent-Length: %d\n\n", statbuf.st_size); - fflush(stdout); + while ((c = fgetc(fp)) != EOF) putchar(c); - sendfile(1, fd, 0, statbuf.st_size); + fflush(stdout); + fclose(fp); } void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, @@ -1463,7 +1465,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, } else /* regular directory, not DN Lists */ { - d_name = namelist[n]->d_name; + d_name = namelist[n]->d_name; GRSThttpPrintf(&bp, "%s" @@ -1475,7 +1477,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintf(&bp, "" "History", - dir_uri, admin_file, d_name); + dir_uri, admin_file, GRSThttpUrlEncode(d_name)); p = rindex(namelist[n]->d_name, '.'); @@ -1486,27 +1488,27 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintf(&bp, "" "List\n", - dir_uri, admin_file, d_name); + dir_uri, admin_file, GRSThttpUrlEncode(d_name)); else if ((p != NULL) && (strstr(editable, &p[1]) != NULL) && GRSTgaclPermHasWrite(perm)) GRSThttpPrintf(&bp, "" "Edit\n", - dir_uri, admin_file, d_name); + dir_uri, admin_file, GRSThttpUrlEncode(d_name)); else GRSThttpPrintf(&bp, " "); if (GRSTgaclPermHasWrite(perm)) GRSThttpPrintf(&bp, "" - "Delete\n", dir_uri, admin_file, d_name); + "Delete\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name)); else GRSThttpPrintf(&bp, " \n"); if (GRSTgaclPermHasWrite(perm)) GRSThttpPrintf(&bp, "" - "Rename\n", dir_uri, admin_file, d_name); + "Rename\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name)); else GRSThttpPrintf(&bp, " "); } diff --git a/org.gridsite.core/src/grst_gacl.c b/org.gridsite.core/src/grst_gacl.c index db1dbdb..c2c4ecd 100644 --- a/org.gridsite.core/src/grst_gacl.c +++ b/org.gridsite.core/src/grst_gacl.c @@ -928,6 +928,25 @@ int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred) return 0; } + if (strcmp(cred->type, "level") == 0) + { + if ((user->firstcred == NULL) || + ((user->firstcred)->firstname == NULL)) return 0; + + for (crediter=user->firstcred; + crediter != NULL; + crediter = crediter->next) + if (strcmp(crediter->type, "level") == 0) + { + if (atoi(user->firstcred->firstname->value) + >= atoi(crediter->firstname->value)) return 1; + + return 0; + } + + return 0; + } + for (crediter=user->firstcred; crediter != NULL; crediter = crediter->next) { if (strcmp(crediter->type, cred->type) != 0) continue; @@ -950,11 +969,13 @@ int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred) if (GRSTx509NameCmp(usernamevalue->value, crednamevalue->value) != 0) break; } +/* else if (strcmp(cred->type, "level") == 0) { if (atoi(usernamevalue->value) < atoi(crednamevalue->value)) break; } +*/ else if (strcmp(usernamevalue->value, crednamevalue->value) != 0) break; diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c index 53a7500..3251813 100644 --- a/org.gridsite.core/src/grst_x509.c +++ b/org.gridsite.core/src/grst_x509.c @@ -1,4 +1,4 @@ -/*5~ +/* Copyright (c) 2002-6, Andrew McNab, University of Manchester All rights reserved. @@ -382,7 +382,6 @@ static int GRSTx509VerifyVomsSig(time_t *time1_time, time_t *time2_time, static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, time_t time1_time, time_t time2_time, X509_EXTENSION *ex, - int chain_errors, char *ucuserdn, char *vomsdir) { #define MAXTAG 500 @@ -396,7 +395,7 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, dn_coords[200], fqan_coords[200], time1_coords[200], time2_coords[200]; long asn1length; - int lasttag=-1, itag, i, acnumber = 1; + int lasttag=-1, itag, i, acnumber = 1, chain_errors = 0; struct GRSTasn1TagList taglist[MAXTAG+1]; time_t actime1 = 0, actime2 = 0, time_now; GRSTx509Cert *new_grst_cert; @@ -409,6 +408,8 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, for (acnumber = 1; ; ++acnumber) /* go through ACs one by one */ { + chain_errors = 0; + snprintf(dn_coords, sizeof(dn_coords), GRST_ASN1_COORDS_USER_DN, acnumber); if (GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), dn_coords, asn1string, taglist, lasttag) != GRST_RET_OK) @@ -482,24 +483,13 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, return GRST_RET_OK; } -/// Load and check X.509 chain, include Proxy Certificates and VOMS Attributes +/// Check certificate chain for GSI proxy acceptability. /** - * Returns GRST_RET_OK if valid; GRST_xxx errors otherwise. + * Returns GRST_RET_OK if valid; OpenSSL X509 errors otherwise. * - * This function fills the GridSite linked list **chain with summaries - * of the X.509 certificates, and any VOMS attributes they contain - * - * o If the root CA cert is not present, it is added from the capath - * directory of hashed-DN. - * o The chain list starts from the CA end. - * o Certs are included even if they are invalid, but are flagged in their - * errors field (0 = OK) - * o If lastcert is not NULL, then it is included at the end of the chain. - * o If capath is not NULL, then it is used as a source of CA root - * certificates. (If capath is NULL, or a root cert in capath cannot - * be found, then all EEC/PC/AC certs are flagged with BAD CHAIN errors.) - * o If vomsdir is not NULL, it used as the top of a hierarchy of VOMS - * cert directories. (VOMS ACs are ignored if vomsdir is NULL.) + * The GridSite version handles old and new style Globus proxies, and + * proxies derived from user certificates issued with "X509v3 Basic + * Constraints: CA:FALSE" (eg UK e-Science CA) * * TODO: we do not yet check ProxyCertInfo and ProxyCertPolicy extensions * (although via GRSTx509KnownCriticalExts() we can accept them.) @@ -552,36 +542,30 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain, return GRST_RET_FAILED; } - if (capath != NULL) - { - cert = sk_X509_value(certstack, depth - 1); - subjecthash = X509_NAME_hash(X509_get_subject_name(cert)); - issuerhash = X509_NAME_hash(X509_get_issuer_name(cert)); - asprintf(&cacertpath, "%s/%.8x.0", capath, issuerhash); + cert = sk_X509_value(certstack, depth - 1); + subjecthash = X509_NAME_hash(X509_get_subject_name(cert)); + issuerhash = X509_NAME_hash(X509_get_issuer_name(cert)); + asprintf(&cacertpath, "%s/%.8x.0", capath, issuerhash); - GRSTerrorLog(GRST_LOG_DEBUG, "Look for CA root file %s", cacertpath); + GRSTerrorLog(GRST_LOG_DEBUG, "Look for CA root file %s", cacertpath); - fp = fopen(cacertpath, "r"); - free(cacertpath); + fp = fopen(cacertpath, "r"); + free(cacertpath); - if (fp == NULL) chain_errors |= GRST_CERT_BAD_CHAIN; - else - { - cacert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - if (cacert != NULL) - GRSTerrorLog(GRST_LOG_DEBUG, " Loaded CA root cert from file"); - } + if (fp == NULL) chain_errors |= GRST_CERT_BAD_CHAIN; + else + { + cacert = PEM_read_X509(fp, NULL, NULL, NULL); + fclose(fp); + if (cacert != NULL) + GRSTerrorLog(GRST_LOG_DEBUG, " Loaded CA root cert from file"); } - - if (cacert == NULL) - chain_errors |= GRST_CERT_BAD_CHAIN; /* never good without CA */ *chain = malloc(sizeof(GRSTx509Chain)); bzero(*chain, sizeof(GRSTx509Chain)); /* Check the client chain */ - for (i = depth - (((subjecthash == issuerhash) || (cacert == NULL)) ? 1 : 0); + for (i = depth - ((subjecthash == issuerhash) ? 1 : 0); i >= ((lastcert == NULL) ? 0 : -1); --i) /* loop through client-presented chain starting at CA end */ @@ -607,17 +591,13 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain, if (i < 0) cert = lastcert; else if (i == depth) cert = cacert; /* the self-signed CA from the store*/ - else if ((i == depth - 1) && - (subjecthash == issuerhash) && - (cacert != NULL)) + else if ((i == depth - 1) && (subjecthash == issuerhash)) cert = cacert; /* ie claims to be a copy of a self-signed CA */ else cert = sk_X509_value(certstack, i); if (cert != NULL) { - if ((i == depth - 1) && - (subjecthash != issuerhash) && - (cacert != NULL)) + if ((i == depth - 1) && (subjecthash != issuerhash)) { /* if first cert does not claim to be a self-signed copy of a CA root cert in the store, we check the signature */ @@ -630,9 +610,7 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain, if (ret != X509_V_OK) new_grst_cert->errors |= GRST_CERT_BAD_SIG; } - else if ((i == depth - 2) && - (subjecthash == issuerhash) && - (cacert != NULL)) + else if ((i == depth - 2) && (subjecthash == issuerhash)) { /* first cert claimed to be a self-signed copy of a CA root cert in the store, we check the signature of the second @@ -753,26 +731,22 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain, if (strncmp(proxy_part_DN, "/CN=limited proxy", 17) == 0) prevIsLimited = 1; /* ready for next cert ... */ - if (vomsdir != NULL) - { - for (j=0; j < X509_get_ext_count(cert); ++j) - { - ex = X509_get_ext(cert, j); - OBJ_obj2txt(s, sizeof(s), - X509_EXTENSION_get_object(ex), 1); + for (j=0; j < X509_get_ext_count(cert); ++j) + { + ex = X509_get_ext(cert, j); + OBJ_obj2txt(s,sizeof(s),X509_EXTENSION_get_object(ex),1); - if (strcmp(s, GRST_VOMS_OID) == 0) /* VOMS ext */ - { - GRSTx509ChainVomsAdd(&grst_cert, + if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */ + { + GRSTx509ChainVomsAdd(&grst_cert, new_grst_cert->start, new_grst_cert->finish, ex, - chain_errors, ucuserdn, vomsdir); - } } - } + } + } } diff --git a/org.gridsite.core/src/make-gridsite-spec b/org.gridsite.core/src/make-gridsite-spec index 21bac26..3b81780 100755 --- a/org.gridsite.core/src/make-gridsite-spec +++ b/org.gridsite.core/src/make-gridsite-spec @@ -12,13 +12,13 @@ if [ $? = 0 ] ; then have_fuse=1 ; fi # test to see if gsoap-devel (or stdsoap2.h and libgsoapssl) is installed # -cat <gsoap-test-xxx.c +cat <gsoap-test.c #include #ifdef SOAP_BEGIN main() { return; } #endif EOF -make GSOAPDIR=$GSOAPDIR STDSOAP2=$STDSOAP2 gsoap-test +make GSOAPDIR=$GSOAPDIR STDSOAP2=$STDSOAP2 gridsite-delegation.cgi if [ $? = 0 ] ; then have_gsoap=1 ; fi cat <gridsite.spec @@ -245,6 +245,7 @@ mkdir -p /grid %attr(0744, root, root) %{prefix}/sbin/slashgrid %attr(0744, root, root) /etc/rc.d/init.d/slashgrid %attr(0700, root, root) /var/spool/slashgrid +%attr(-, root, root) %{prefix}/share/man/man8/slashgrid.8.gz EOF fi @@ -281,16 +282,19 @@ See http://www.gridsite.org/ for details. %attr(-, root, root) %{prefix}/bin/htproxytime %attr(-, root, root) %{prefix}/bin/htproxyunixtime %attr(-, root, root) %{prefix}/bin/htproxyrenew +%attr(-, root, root) %{prefix}/bin/htproxyinfo %attr(-, root, root) %{prefix}/share/man/man1/htproxyput.1.gz %attr(-, root, root) %{prefix}/share/man/man1/htproxydestroy.1.gz %attr(-, root, root) %{prefix}/share/man/man1/htproxytime.1.gz %attr(-, root, root) %{prefix}/share/man/man1/htproxyunixtime.1.gz %attr(-, root, root) %{prefix}/share/man/man1/htproxyrenew.1.gz +%attr(-, root, root) %{prefix}/share/man/man1/htproxyinfo.1.gz %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyput.1 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxydestroy.1 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxytime.1 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyunixtime.1 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyrenew.1 +%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyinfo.1 EOF fi diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index 7d04a77..16febab 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -147,6 +147,7 @@ typedef struct char *footfile; int gridhttp; char *aclformat; + char *aclpath; char *execmethod; char *delegationuri; ap_unix_identity_t execugid; @@ -1532,6 +1533,7 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path) conf->gridhttp = 0; /* GridSiteGridHTTP on/off */ conf->aclformat = apr_pstrdup(p, "GACL"); /* GridSiteACLFormat gacl/xacml */ + conf->aclpath = NULL; /* GridSiteACLPath acl-path */ conf->delegationuri = NULL; /* GridSiteDelegationURI URI-value */ conf->execmethod = NULL; /* GridSiteExecMethod nosetuid/suexec/X509DN/directory */ @@ -1566,6 +1568,7 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path) conf->footfile = NULL; /* GridSiteFootFile file name */ conf->gridhttp = UNSET; /* GridSiteGridHTTP on/off */ conf->aclformat = NULL; /* GridSiteACLFormat gacl/xacml */ + conf->aclpath = NULL; /* GridSiteACLPath acl-path */ conf->delegationuri = NULL; /* GridSiteDelegationURI URI-value */ conf->execmethod = NULL; /* GridSiteExecMethod */ conf->execugid.uid = UNSET; /* GridSiteUserGroup User Group */ @@ -1648,6 +1651,9 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, if (direct->aclformat != NULL) conf->aclformat = direct->aclformat; else conf->aclformat = server->aclformat; + if (direct->aclpath != NULL) conf->aclpath = direct->aclpath; + else conf->aclpath = server->aclpath; + if (direct->delegationuri != NULL) conf->delegationuri = direct->delegationuri; else conf->delegationuri = server->delegationuri; @@ -1845,7 +1851,10 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, ((mod_gridsite_dir_cfg *) cfg)->aclformat = apr_pstrdup(a->pool, parm); } - + else if (strcasecmp(a->cmd->name, "GridSiteACLPath") == 0) + { + ((mod_gridsite_dir_cfg *) cfg)->aclpath = apr_pstrdup(a->pool, parm); + } else if (strcasecmp(a->cmd->name, "GridSiteDelegationURI") == 0) { if (*parm != '/') return "GridSiteDelegationURI must begin with /"; @@ -2054,6 +2063,8 @@ static const command_rec mod_gridsite_cmds[] = AP_INIT_TAKE1("GridSiteACLFormat", mod_gridsite_take1_cmds, NULL, OR_FILEINFO, "format to save access control lists in"), + AP_INIT_TAKE1("GridSiteACLPath", mod_gridsite_take1_cmds, + NULL, OR_FILEINFO, "explicit location of access control file"), AP_INIT_TAKE1("GridSiteDelegationURI", mod_gridsite_take1_cmds, NULL, OR_FILEINFO, "URI of the delegation service CGI"), @@ -2079,7 +2090,11 @@ static const command_rec mod_gridsite_cmds[] = static int mod_gridsite_check_user_id(request_rec *r) { apr_table_unset(r->headers_in, "User-Distinguished-Name"); +#if 0 + apr_table_unset(r->headers_in, "User-Distinguished-Name-2"); +#endif apr_table_unset(r->headers_in, "Nist-LoA"); + apr_table_unset(r->headers_in, "LoA"); apr_table_unset(r->headers_in, "VOMS-Attribute"); return DECLINED; /* ie carry on processing request */ @@ -2287,6 +2302,79 @@ void GRST_save_ssl_creds(conn_rec *conn, } } +static char *get_aclpath_component(request_rec *r, int n) +/* + Get the nth component of REQUEST_URI, or component 0 + which is the server name. + +*/ +{ + int ii, i, nn; + + if (n == 0) return r->server->server_hostname; + + if (r->uri == NULL) return NULL; /* some kind of internal error? */ + + i = 1; /* start of first component */ + nn = 1; + + for (ii=1; r->uri[ii] != '\0'; ++ii) /* look for this component */ + { + if (r->uri[ii] == '/') /* end of a component */ + { + if (nn == n) break; + + ++nn; + i = ii + 1; + } + else if ((r->uri[ii] == '.') && (r->uri[ii+1] == '.')) + { + return NULL; /* can this happen? dont allow anyway */ + } + } + + if (nn != n) return NULL; /* no component for this number */ + + return apr_psprintf(r->pool, "%.*s", ii - i, &(r->uri[i])); +} + +static char *make_aclpath(request_rec *r, char *format) +{ + int i, n; + char *formatted, *p; + + formatted = apr_pstrdup(r->pool, format); + + while (1) + { + for (i=0; (formatted[i] != '\0') && (formatted[i] != '%'); ++i) ; + + if (formatted[i] == '\0') break; + + if ((formatted[i] == '%') && (formatted[i+1] == '%')) + { + ++i; + continue; + } + + if (sscanf(&formatted[i+1], "%d", &n) != 1) + { + return NULL; /* not %% or %0,%1,... */ + } + + formatted[i] = '\0'; + + for (i++; isdigit(formatted[i]); ++i) ; + + if ((p = get_aclpath_component(r, n)) == NULL) return NULL; + + formatted = apr_pstrcat(r->pool, formatted, p, &formatted[i],NULL); + i += strlen(p); + } + + return ap_server_root_relative(r->pool, formatted); +} + static int mod_gridsite_perm_handler(request_rec *r) /* Do authentication/authorization here rather than in the normal module @@ -2301,7 +2389,8 @@ static int mod_gridsite_perm_handler(request_rec *r) *remotehost, s[99], *grst_cred_i, *cookies, *file, *https, *gridauthpasscode = NULL, *cookiefile, oneline[1025], *key_i, *destination = NULL, *destination_uri = NULL, *querytmp, - *destination_prefix = NULL, *destination_translated = NULL; + *destination_prefix = NULL, *destination_translated = NULL, + *aclpath = NULL; char *vomsAttribute = NULL, *loa; const char *content_type; time_t now, notbefore, notafter; @@ -2334,13 +2423,27 @@ static int mod_gridsite_perm_handler(request_rec *r) a Shibboleth Identity Provider.*/ /* Get DN from a Shibboleth attribute */ + dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name"); +#if 0 + if ((dn == NULL) || (*dn == '\0')) + dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name-2"); +#endif + + if ((dn != NULL) && (*dn == '\0')) dn = NULL; + if (dn != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "DN: %s", dn); -#if 0 + /* Get the NIST LoA attribute */ loa = (char *) apr_table_get(r->headers_in, "nist-loa"); - if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Nist-LoA: %d", loa); -#endif + + if ((loa == NULL) || (*loa == '\0')) + loa = (char *) apr_table_get(r->headers_in, "loa"); + + if ((loa != NULL) && (*loa == '\0')) loa = NULL; + + if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "nist-loa: %s", loa); + /* Set up user credential based on the DN and LoA attributes */ if (dn != NULL) @@ -2349,20 +2452,21 @@ static int mod_gridsite_perm_handler(request_rec *r) GRSTgaclCredAddValue(cred, "dn", dn); user = GRSTgaclUserNew(cred); cred = GRSTgaclCredNew("level"); -#if 0 - GRSTgaclCredAddValue(cred, "nist-loa", loa); -#endif - GRSTgaclCredAddValue(cred, "nist-loa", "2"); /* hardcoded for now */ + + if (loa != NULL) GRSTgaclCredAddValue(cred, "nist-loa", loa); + else GRSTgaclCredAddValue(cred, "nist-loa", "2"); + GRSTgaclUserAddCred(user, cred); } + + /* Set up user credential based on VOMS Attribute from Shibboleth? */ vomsAttribute = (char *) apr_table_get(r->headers_in, "VOMS-Attribute"); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "VOMS-Attribute: %s", vomsAttribute); - - /* Set up user credential based on VOMS Attribute */ if (vomsAttribute != NULL) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "VOMS-Attribute: %s", vomsAttribute); + cred = GRSTgaclCredNew("voms"); GRSTgaclCredAddValue(cred, "fqan", vomsAttribute); if (user == NULL) user = GRSTgaclUserNew(cred); @@ -2376,13 +2480,14 @@ static int mod_gridsite_perm_handler(request_rec *r) sslconn = (SSLConnRec *) ap_get_module_config(r->connection->conn_config, &ssl_module); - if ((sslconn != NULL) && + if ((user == NULL) && + (sslconn != NULL) && (sslconn->ssl != NULL) && (sslconn->ssl->session != NULL) && (r->connection->notes != NULL) && (apr_table_get(r->connection->notes, "GRST_save_ssl_creds") == NULL)) { - if (GRST_load_ssl_creds(sslconn->ssl, r->connection) == GRST_RET_OK) + if (GRST_load_ssl_creds(sslconn->ssl, r->connection) == GRST_RET_OK) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Restored SSL session data from session cache file"); } @@ -2453,6 +2558,9 @@ static int mod_gridsite_perm_handler(request_rec *r) if ((destination = (char *) apr_table_get(r->headers_in, "Destination")) != NULL) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Destination header found, value=%s", destination); + destination_prefix = apr_psprintf(r->pool, "https://%s:%d/", r->server->server_hostname, (int) r->server->port); @@ -2501,7 +2609,24 @@ static int mod_gridsite_perm_handler(request_rec *r) } else { - acl = GRSTgaclAclLoadforFile(r->filename); + if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL) + { + aclpath = make_aclpath(r,((mod_gridsite_dir_cfg *) cfg)->aclpath); + + if (aclpath != NULL) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Examine ACL file %s (from ACL path %s)", + aclpath, ((mod_gridsite_dir_cfg *) cfg)->aclpath); + + acl = GRSTgaclAclLoadFile(aclpath); + } + else ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Failed to make ACL file from ACL path %s, URI %s)", + ((mod_gridsite_dir_cfg *) cfg)->aclpath, r->uri); + } + else acl = GRSTgaclAclLoadforFile(r->filename); + if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user); GRSTgaclAclFree(acl); @@ -2674,6 +2799,10 @@ static int mod_gridsite_perm_handler(request_rec *r) apr_table_setn(env, "GRST_ACL_FORMAT", ((mod_gridsite_dir_cfg *) cfg)->aclformat); + if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL) + apr_table_setn(env, "GRST_ACL_PATH", + ((mod_gridsite_dir_cfg *) cfg)->aclpath); + if (((mod_gridsite_dir_cfg *) cfg)->delegationuri != NULL) apr_table_setn(env, "GRST_DELEGATION_URI", ((mod_gridsite_dir_cfg *) cfg)->delegationuri); @@ -2763,7 +2892,21 @@ static int mod_gridsite_perm_handler(request_rec *r) (((r->method_number == M_PUT) || (r->method_number == M_DELETE)) && - !GRSTgaclPermHasAdmin(perm) && file_is_acl) + !GRSTgaclPermHasAdmin(perm) && file_is_acl) || + + /* for WebDAV/Subversion */ + + (((r->method_number == M_PROPFIND) || + (r->method_number == M_REPORT)) && + !GRSTgaclPermHasRead(perm)) || + + (((r->method_number == M_CHECKOUT) || + (r->method_number == M_MERGE) || + (r->method_number == M_MKACTIVITY) || + (r->method_number == M_MKCOL) || + (r->method_number == M_LOCK) || + (r->method_number == M_UNLOCK)) && + !GRSTgaclPermHasWrite(perm)) ) retcode = HTTP_FORBIDDEN; } diff --git a/org.gridsite.core/src/slashgrid.c b/org.gridsite.core/src/slashgrid.c index de86328..8ae240c 100644 --- a/org.gridsite.core/src/slashgrid.c +++ b/org.gridsite.core/src/slashgrid.c @@ -91,7 +91,7 @@ #endif #ifndef CURLOPT_READDATA -#define CURLOPT_READDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE #endif #ifndef CURLE_HTTP_RETURNED_ERROR @@ -599,12 +599,18 @@ int perform_request(struct grst_request *request_data, curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYHOST, 2); } + curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata); + if (request_data->method == GRST_SLASH_GET) { curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, NULL); curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 1); curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD, 0); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1); } else if ((request_data->method == GRST_SLASH_PUT) || (request_data->method == GRST_SLASH_TRUNC)) @@ -622,6 +628,7 @@ int perform_request(struct grst_request *request_data, curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1); } else if (request_data->method == GRST_SLASH_MOVE) { @@ -629,6 +636,7 @@ int perform_request(struct grst_request *request_data, curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "MOVE"); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1); } else /* default or GRST_SLASH_HEAD */ { @@ -636,6 +644,7 @@ int perform_request(struct grst_request *request_data, curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY, 1); curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0); curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD, 0); + curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1); } curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEHEADER, request_data); @@ -647,11 +656,12 @@ int perform_request(struct grst_request *request_data, if (debugmode) curl_easy_setopt(handles[i].curl_handle, CURLOPT_DEBUGDATA, &i); +/* Move to higher up curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction); curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata); curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction); curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata); - +*/ if ((request_data->start >= 0) && (request_data->finish >= request_data->start)) { @@ -1433,7 +1443,7 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context)); if (debugmode) syslog(LOG_DEBUG, - "in slashgrid_getattr, rawpath=%s, UID=%d\n", + "in slashgrid_getattr, rawpath=%s UID=%d\n", rawpath, fuse_ctx.uid); memset(stbuf, 0, sizeof(struct stat)); @@ -1566,10 +1576,14 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) free(path); return 0; } + + if (debugmode) syslog(LOG_DEBUG, "Get details for %s over network\n", url); bzero(&request_data, sizeof(struct grst_request)); request_data.writefunction = null_callback; request_data.writedata = NULL; + request_data.readfunction = null_callback; + request_data.readdata = NULL; request_data.errorbuffer = errorbuffer; request_data.url = url; request_data.method = GRST_SLASH_HEAD; @@ -1578,6 +1592,9 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) thiserror = perform_request(&request_data, &fuse_ctx); + if (debugmode) syslog(LOG_DEBUG, "perform_request returns error=%d (%s)\n", + thiserror, errorbuffer); + if ((thiserror != 0) || (request_data.retcode < 200) || (request_data.retcode > 301)) @@ -2333,6 +2350,7 @@ int slashgrid_statfs(const char *path, struct statfs *fs) void *slashgrid_init(void) { FILE *fp; + struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY }; if ((fp = fopen(GRST_SLASH_PIDFILE, "w")) != NULL) { @@ -2340,6 +2358,12 @@ void *slashgrid_init(void) fclose(fp); } + if (debugmode) + { + chdir("/var/tmp"); /* fuse changes to / in demonize: undo this */ + setrlimit(RLIMIT_CORE, &unlimited); + } + return NULL; } @@ -2386,7 +2410,6 @@ int main(int argc, char *argv[]) "-s", "-d" }; int i, ret, fuse_argc = 4; /* by default, ignore the final 2 args */ struct passwd *pw; - struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY }; for (i=1; i < argc; ++i) { @@ -2449,7 +2472,7 @@ int main(int argc, char *argv[]) openlog("slashgrid", 0, LOG_DAEMON); - umount("/grid"); /* in case of a crash, but will fail if still busy */ + umount("/grid"); /* in case of previous crash - will fail if still busy */ for (i=0; i < GRST_SLASH_MAX_HANDLES; ++i) { @@ -2459,12 +2482,6 @@ int main(int argc, char *argv[]) handles[i].last_used = 0; } - if (debugmode) - { - chdir("/var/tmp"); - setrlimit(RLIMIT_CORE, &unlimited); - } - // GRSTerrorLogFunc = slashgrid_logfunc; GRSTgaclInit(); -- 1.8.2.3