From b78bd084d8cbbe23392dd082be7ecd7af7b53b2b Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Mon, 15 Nov 2004 15:49:51 +0000 Subject: [PATCH] Import 1.1.3 --- org.gridsite.core/CHANGES | 36 +- org.gridsite.core/INSTALL | 2 +- org.gridsite.core/README | 4 +- org.gridsite.core/VERSION | 4 +- org.gridsite.core/doc/README.htcp-bin | 13 + org.gridsite.core/doc/build-apache2.sh | 6 +- org.gridsite.core/doc/config.html | 2 +- org.gridsite.core/doc/findproxyfile.1 | 63 +++ org.gridsite.core/doc/gacl.html | 2 +- org.gridsite.core/doc/htcp.1 | 15 +- org.gridsite.core/doc/httpd-fileserver.conf | 6 +- org.gridsite.core/doc/httpd-webserver.conf | 6 +- org.gridsite.core/doc/index.html | 6 +- org.gridsite.core/doc/install.html | 10 +- org.gridsite.core/doc/urlencode.1 | 8 +- org.gridsite.core/interface/gridsite-gacl.h | 80 +-- org.gridsite.core/interface/gridsite.h | 94 ++-- org.gridsite.core/src/Makefile | 81 ++- org.gridsite.core/src/delegation.h | 12 + org.gridsite.core/src/doxyheader.html | 2 +- org.gridsite.core/src/findproxyfile.c | 122 +++++ org.gridsite.core/src/gaclexample.c | 6 +- org.gridsite.core/src/gridsite.spec | 8 +- org.gridsite.core/src/grst-delegation.c | 295 +++++++++++ org.gridsite.core/src/grst_admin.h | 6 +- org.gridsite.core/src/grst_admin_file.c | 6 +- org.gridsite.core/src/grst_admin_gacl.c | 8 +- org.gridsite.core/src/grst_admin_main.c | 8 +- org.gridsite.core/src/grst_gacl.c | 38 +- org.gridsite.core/src/grst_x509.c | 768 ++++++++++++++++++++++++---- org.gridsite.core/src/htcp.c | 166 +++++- org.gridsite.core/src/htproxyput.c | 565 ++++++++++++++++++++ org.gridsite.core/src/mod_gridsite.c | 540 ++++++++++++++++++- org.gridsite.core/src/mod_ssl-private.h | 6 +- org.gridsite.core/src/proxyput-example.c | 131 +++++ org.gridsite.core/src/urlencode.c | 6 +- 36 files changed, 2812 insertions(+), 319 deletions(-) create mode 100644 org.gridsite.core/doc/README.htcp-bin create mode 100644 org.gridsite.core/doc/findproxyfile.1 create mode 100644 org.gridsite.core/src/delegation.h create mode 100644 org.gridsite.core/src/findproxyfile.c create mode 100644 org.gridsite.core/src/grst-delegation.c create mode 100644 org.gridsite.core/src/htproxyput.c create mode 100644 org.gridsite.core/src/proxyput-example.c diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES index c7c17d5..e46eee6 100644 --- a/org.gridsite.core/CHANGES +++ b/org.gridsite.core/CHANGES @@ -1,5 +1,39 @@ +* Mon Nov 15 2004 Andrew McNab +- Back out of (most of) redone VOMS support for committing + to JRA1 CVS. +* Thu Oct 19 2004 Andrew McNab +- ==== GridSite version 1.1.3 ==== +* Thu Oct 19 2004 Andrew McNab +- Fix Bug #5203 from Martijn Steenbakkers + by fixing GACLparseEntry in gridsite-gacl.h +- Change to C style comments (mostly) in gridsite.h and + gridsite-gacl.h (fixes part of Bug #4222 from + ) +- Fix Bug #4225 from in + GRSTgaclCredsFree() +- Add GRSTx509CachedProxyFind() and findproxyfile + command to allow proxies to be found in proxy cache +- Change GRSTx509StoreProxy() to GRSTx509CacheProxy() for + consistency with this and GRSTx509CachedProxyKeyFind() +* Wed Oct 18 2004 Andrew McNab +- ==== GridSite version 1.1.2 ==== +* Tue Oct 19 2004 Andrew McNab +- Copy code from delegation prototype into grst_x509.c + and include htproxyput.c and grst-delegation.c + optional targets (which depend on gSOAP.) +* Wed Oct 13 2004 Andrew McNab +- Include per-file patch to GRSTgaclFileFindAclname: + .gacl:FILENAME controls FILENAME if it exists. +* Tue Jul 27 2004 Andrew McNab +- ==== GridSite version 1.1.1 ==== +* Tue Jul 27 2004 Andrew McNab +- Include HTTP Downgrade support in htcp +* Sat Jul 24 2004 Andrew McNab +- Include HTTP Downgrade support in mod_gridsite. * Thu Jul 22 2004 Andrew McNab -- ==== GridSite version 1.0.4 ==== +- Begin development version 1.1.x +* Thu Jul 22 2004 Andrew McNab +- ==== GridSite version 1.1.0 ==== * Mon Jul 19 2004 Andrew McNab - Changes in line with EGEE SCM - most importantly the top level directory becomes org.gridsite.core diff --git a/org.gridsite.core/INSTALL b/org.gridsite.core/INSTALL index 68e150a..3da6cde 100644 --- a/org.gridsite.core/INSTALL +++ b/org.gridsite.core/INSTALL @@ -4,7 +4,7 @@ BUILDING/INSTALLING GRIDSITE For more detailed instructions, see the install.html file, either in the ./doc subdirectory in the sources, in the directory gridsite-VERSION/html of the docs directory when GridSite is -installed, or http://www.gridpp.ac.uk/gridsite/1.0.x/install.html +installed, or http://www.gridsite.org/1.1.x/install.html GridSite is currently only supported on Linux, but should be trivially portable to other Unix platforms where the GNU build diff --git a/org.gridsite.core/README b/org.gridsite.core/README index 5fbb1db..62730a6 100644 --- a/org.gridsite.core/README +++ b/org.gridsite.core/README @@ -1,3 +1,3 @@ See INSTALL for build and installation instructions, and -http://www.gridpp.ac.uk/gridsite/ for configuration and -usage guides. +the Documentation section of http://www.gridsite.org/ +for configuration and usage guides. diff --git a/org.gridsite.core/VERSION b/org.gridsite.core/VERSION index 10c4a0f..372ce91 100644 --- a/org.gridsite.core/VERSION +++ b/org.gridsite.core/VERSION @@ -1,4 +1,4 @@ MAJOR_VERSION=1 -MINOR_VERSION=1.0 -PATCH_VERSION=1.0.4 +MINOR_VERSION=1.1 +PATCH_VERSION=1.1.3 VERSION=$(PATCH_VERSION) diff --git a/org.gridsite.core/doc/README.htcp-bin b/org.gridsite.core/doc/README.htcp-bin new file mode 100644 index 0000000..ac546fc --- /dev/null +++ b/org.gridsite.core/doc/README.htcp-bin @@ -0,0 +1,13 @@ +Binaries (and links) are in ./bin; man pages are in ./man/man1 + +Install by copying binaries/links onto your path, or by copying htcp +and making symbolic links to htcp from htls, htll, htrm and htmkdir. + +All the .1 man pages should be copied to a suitable ./man/man1 +directory on your man path. + +If you just want to install htcp in /usr/local, then unpacking this +tgz file in /usr/local should do the trick. (Delete this README when +you're finished!) + +For more about htcp see http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/build-apache2.sh b/org.gridsite.core/doc/build-apache2.sh index f1246d4..507be31 100644 --- a/org.gridsite.core/doc/build-apache2.sh +++ b/org.gridsite.core/doc/build-apache2.sh @@ -29,9 +29,9 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # -#----------------------------------------------------------------------------- -# For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ -#----------------------------------------------------------------------------- +#--------------------------------------------------------------- +# For more information about GridSite: http://www.gridsite.org/ +#--------------------------------------------------------------- # # This script takes an Apache .tar.gz as the single command line argument, # unpacks the file, modifies the httpd.spec it contains to work without diff --git a/org.gridsite.core/doc/config.html b/org.gridsite.core/doc/config.html index 6e747e2..825bf49 100644 --- a/org.gridsite.core/doc/config.html +++ b/org.gridsite.core/doc/config.html @@ -4,7 +4,7 @@

This Guide is intended for webmasters setting up -GridSite with an Apache 2.0 +GridSite with an Apache 2.0 webserver. We assume you have root access to the server machine to do this. There is a separate Admin Guide for people administrating areas of GridSite diff --git a/org.gridsite.core/doc/findproxyfile.1 b/org.gridsite.core/doc/findproxyfile.1 new file mode 100644 index 0000000..ae2f944 --- /dev/null +++ b/org.gridsite.core/doc/findproxyfile.1 @@ -0,0 +1,63 @@ +.TH findproxyfile 1 "October 2004" findproxyfile "FINDPROXYFILE Manual" +.SH NAME +.B findproxyfile +\- returns full path to GSI Proxy file +.SH SYNOPSIS +.B findproxyfile +[--proxycache=PATH] [--delegation-id=ID] [--user-dn=DN] [--outsidecache] +.SH DESCRIPTION +.B findproxyfile +returns full path to a GSI Proxy file, either in the proxy cache maintained +by the GridSite G-HTTPS and delegation portType functions, or in other +standard places. + +If a User DN is given +.B findproxyfile +uses the value of the +.B --proxycache +argument, the GRST_PROXY_PATH or the +compile time default to detemine the location of the proxy cache directory. +The directory is searched for a proxy having the given User DN and +Delegation ID. (If no Delegation ID is specificed, then the default value is +used.) + +If +.B findproxyfile +does not find a proxy or if a User DN is not given, but +.B --outsidecache +was given, then the environment variable X509_USER_PROXY and the standard +location /tmp/x509up_uUID are searched as well. + +.SH OPTIONS + +.IP "--proxycache=PATH" +Give the path of the proxy cache directory explicitly, overriding the +default and the GRST_PROXY_PATH environment variable if present. + +.IP "--delegation-id=ID" +The optional delegation ID is search for in the proxy cache in addition to +the User DN. If absent, the default Delegation ID value is searched for. + +.IP "--user-dn=DN" +The DN of the full user certificate associated with the proxy to be searched +for in the proxy cache. (This is not the DN of any proxy earlier in the +chain: it is a the DN of a certificate issued by a recognised CA.) + +.IP "--outsidecache" +If a User DN is not given, or a proxy not found in the cache, then search +for a proxy using X509_USER_PROXY environment variable and file name of +form /tmp/x509up_uUID as well. + +.SH RETURN VALUE +If a proxy is found, its full path is output on standard out. + +.SH EXIT CODES +0 is returned on succcess. Non-zero otherwise. + +.SH BUGS +In this version, no attempt is made to verify or validate the proxies. + +.SH AUTHOR +Andrew McNab + +findproxyfile is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/gacl.html b/org.gridsite.core/doc/gacl.html index 12e58c7..40efdd2 100644 --- a/org.gridsite.core/doc/gacl.html +++ b/org.gridsite.core/doc/gacl.html @@ -4,7 +4,7 @@

GACL is the authorization policy language used by -GridSite GACL allows +GridSite GACL allows policies to be written in terms of common Grid credentials: X.509 identities, GSI proxies, VOMS attribute certificates and lists of X.509 identities. diff --git a/org.gridsite.core/doc/htcp.1 b/org.gridsite.core/doc/htcp.1 index 05b0718..984aaaf 100644 --- a/org.gridsite.core/doc/htcp.1 +++ b/org.gridsite.core/doc/htcp.1 @@ -1,4 +1,4 @@ -.TH htcp 1 "December 2003" htcp "HTCP Manual" +.TH htcp 1 "July 2004" htcp "HTCP Manual" .SH NAME .B htcp, htrm, htls, htll, htmkdir \- get, put, delete or list HTTP/HTTPS files or directories @@ -84,6 +84,15 @@ This is useful for testing sites before their certificate is set up properly, but leaves you vulnerable to "man in the middle" attacks by hostile servers masquerading as your target. +.IP "--downgrade-size " +Try to use HTTP-Downgrade for HTTPS URLs. Compatible servers will perform +authentication and authorization on the HTTPS connection and then redirect +to HTTP for the GET or PUT file transfer. htcp makes the HTTP request using +the GRID_AUTH_ONETIME single-use passcode obtained via HTTPS. The downgrade +option will be ignored for directory operations, HTTP URLs, or if the file +size is less than the value given. If a downgraded transfer isn't possible, +a normal HTTPS data transfer will be done. + .SH FILES .IP /tmp/x509up_uID Default GSI Proxy file for Unix UID equal to ID. @@ -127,9 +136,9 @@ Recursive copying. Server-side wildcards. Parallel streams. Error recovery. Not enough beta testing (hint hint...) .SH AUTHOR -Andrew McNab +Andrew McNab -htcp is part of GridSite: http://www.gridpp.ac.uk/gridsite/ +htcp is part of GridSite: http://www.gridsite.org/ .SH "SEE ALSO" .BR scp(1), .BR curl(1), diff --git a/org.gridsite.core/doc/httpd-fileserver.conf b/org.gridsite.core/doc/httpd-fileserver.conf index 1b197e7..9bd51e2 100644 --- a/org.gridsite.core/doc/httpd-fileserver.conf +++ b/org.gridsite.core/doc/httpd-fileserver.conf @@ -1,9 +1,9 @@ ############################################################################## -## GridSite httpd-fileserver.conf - Andrew McNab +## GridSite httpd-fileserver.conf - Andrew McNab ## ## Example configuration file for GridSite as an HTTP(S) fileserver. ## -## For GridSite documentation, see http://www.gridpp.ac.uk/gridsite/ +## For GridSite documentation, see http://www.gridsite.org/ ## ## This file should be renamed /etc/httpd/conf/httpd.conf and Apache ## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. @@ -130,6 +130,8 @@ SSLCertificateFile /etc/grid-security/hostcert.pem SSLCertificateKeyFile /etc/grid-security/hostkey.pem SSLCACertificatePath /etc/grid-security/certificates #SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE +SSLSessionCache dbm:/var/cache/mod_ssl/scache +SSLSessionCacheTimeout 300 SSLVerifyClient optional SSLVerifyDepth 10 SSLOptions +ExportCertData +StdEnvVars diff --git a/org.gridsite.core/doc/httpd-webserver.conf b/org.gridsite.core/doc/httpd-webserver.conf index 0662f15..da332a0 100644 --- a/org.gridsite.core/doc/httpd-webserver.conf +++ b/org.gridsite.core/doc/httpd-webserver.conf @@ -1,10 +1,10 @@ ############################################################################## -## GridSite httpd-webserver.conf - Andrew McNab +## GridSite httpd-webserver.conf - Andrew McNab ## ## Example configuration file for GridSite as a Web Server ## (that is, primarily for interactive use with a browser.) ## -## For GridSite documentation, see http://www.gridpp.ac.uk/gridsite/ +## For GridSite documentation, see http://www.gridsite.org/ ## ## This file should be renamed /etc/httpd/conf/httpd.conf and Apache ## restarted to use Apache2/GridSite as a webserver. @@ -160,6 +160,8 @@ SSLCertificateFile /etc/grid-security/hostcert.pem SSLCertificateKeyFile /etc/grid-security/hostkey.pem SSLCACertificatePath /etc/grid-security/certificates #SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE +SSLSessionCache dbm:/var/cache/mod_ssl/scache +SSLSessionCacheTimeout 300 SSLVerifyClient optional SSLVerifyDepth 10 SSLOptions +ExportCertData +StdEnvVars diff --git a/org.gridsite.core/doc/index.html b/org.gridsite.core/doc/index.html index 11aaa86..a93f2cb 100644 --- a/org.gridsite.core/doc/index.html +++ b/org.gridsite.core/doc/index.html @@ -1,9 +1,9 @@ -GridSite 1.0.x Documentation +GridSite 1.1.x Documentation -

GridSite 1.0.x Documentation

+

GridSite 1.1.x Documentation

-GridSite +GridSite is a set of extensions to the Apache 2.0 webserver, which support Grid security based on X.509 certificates. Since GridSite applies access control within Apache itself, via mod_gridsite, Grid authorization and diff --git a/org.gridsite.core/doc/install.html b/org.gridsite.core/doc/install.html index 6755b1e..91a60d2 100644 --- a/org.gridsite.core/doc/install.html +++ b/org.gridsite.core/doc/install.html @@ -20,8 +20,8 @@ to the Config Guide.

We currently distribute GridSite RPMs for RedHat Linux versions 9 and 7.3 from our download area at - -https://www.gridpp.ac.uk/gridsite/download/ + +https://www.gridsite.org/download/

RedHat 9: @@ -72,8 +72,8 @@ RedHat Linux releases 7.x onwards, for instance.)

Our download area at - -https://www.gridpp.ac.uk/gridsite/download/ includes a tar-ball + +https://www.gridsite.org/download/ includes a tar-ball distribution of the sources, which can be unpacked and used to build GridSite from source. (Bleeding-edge developers can get the current snapshot of the same files from our CVS area.) @@ -140,7 +140,7 @@ the Makefile and the scriptlets in the included SPEC files are a good starting point for building Apache by hand yourself. The complexities of this are outside of the scope of this Guide, but you are welcome to ask for assistance on the -GridSite +GridSite Discussion List, although www.apache.org is a better starting point for purely Apache problems. diff --git a/org.gridsite.core/doc/urlencode.1 b/org.gridsite.core/doc/urlencode.1 index 47d2b91..fe84405 100644 --- a/org.gridsite.core/doc/urlencode.1 +++ b/org.gridsite.core/doc/urlencode.1 @@ -14,8 +14,8 @@ That is, characters A-Z a-z 0-9 . _ and - are passed through unmodified, but all other characters are represented as %HH, where HH is their two-digit upper-case hexadecimal ASCII representation. -For example, the URL http://www.gridpp.ac.uk/gridsite/ becomes -http%3A%2F%2Fwww.gridpp.ac.uk%2Fgridsite%2F +For example, the URL http://www.gridpp.ac.uk/ becomes +http%3A%2F%2Fwww.gridpp.ac.uk%2F .B urlencode converts each character in all the strings given on the command line. If @@ -41,6 +41,6 @@ with the exception that + is converted to space. Not enough beta testing (hint hint...) .SH AUTHOR -Andrew McNab +Andrew McNab -urlencode is part of GridSite: http://www.gridpp.ac.uk/gridsite/ +urlencode is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/interface/gridsite-gacl.h b/org.gridsite.core/interface/gridsite-gacl.h index 2eec2fa..f739c00 100644 --- a/org.gridsite.core/interface/gridsite-gacl.h +++ b/org.gridsite.core/interface/gridsite-gacl.h @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ #ifndef HEADER_GACL_H #define HEADER_GACL_H @@ -76,113 +76,113 @@ extern GACLperm gacl_perm_vals[]; #define GACLinit() GRSTgaclInit() #define GACLnewCred(x) GRSTgaclCredNew((x)) -//GACLcred *GACLnewCred(char *); +/* GACLcred *GACLnewCred(char *); */ #define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) -//int GACLaddToCred(GACLcred *, char *, char *); +/* int GACLaddToCred(GACLcred *, char *, char *); */ #define GACLfreeCred(x) GRSTgaclCredFree((x)) -//int GACLfreeCred(GACLcred *); +/* int GACLfreeCred(GACLcred *); */ #define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) -//int GACLaddCred(GACLentry *, GACLcred *); +/* int GACLaddCred(GACLentry *, GACLcred *); */ #define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) -//int GACLdelCred(GACLentry *, GACLcred *); +/* int GACLdelCred(GACLentry *, GACLcred *); */ #define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) -// int GACLprintCred(GACLcred *, FILE *); +/* int GACLprintCred(GACLcred *, FILE *); */ #define GACLnewEntry() GRSTgaclEntryNew() -// GACLentry *GACLnewEntry(void); +/* GACLentry *GACLnewEntry(void); */ #define GACLfreeEntry(x) GRSTgaclEntryFree((x)) -// int GACLfreeEntry(GACLentry *); +/* int GACLfreeEntry(GACLentry *); */ #define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) -// int GACLaddEntry(GACLacl *, GACLentry *); +/* int GACLaddEntry(GACLacl *, GACLentry *); */ #define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) -// int GACLprintEntry(GACLentry *, FILE *); +/* int GACLprintEntry(GACLentry *, FILE *); */ #define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) -//int GACLprintPerm(GACLperm, FILE *); +/* int GACLprintPerm(GACLperm, FILE *); */ #define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) -// int GACLallowPerm(GACLentry *, GACLperm); +/* int GACLallowPerm(GACLentry *, GACLperm); */ #define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) -//int GACLunallowPerm(GACLentry *, GACLperm); +/* int GACLunallowPerm(GACLentry *, GACLperm); */ #define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) -// int GACLdenyPerm(GACLentry *, GACLperm); +/* int GACLdenyPerm(GACLentry *, GACLperm); */ #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) -// int GACLundenyPerm(GACLentry *, GACLperm); +/* int GACLundenyPerm(GACLentry *, GACLperm); */ #define GACLpermToChar(x) GRSTgaclPermToChar((x)) -// char *GACLpermToChar(GACLperm); +/* char *GACLpermToChar(GACLperm); */ #define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) -// GACLperm GACLcharToPerm(char *); +/* GACLperm GACLcharToPerm(char *); */ #define GACLnewAcl() GRSTgaclAclNew() -// GACLacl *GACLnewAcl(void); +/* GACLacl *GACLnewAcl(void); */ #define GACLfreeAcl(x) GRSTgaclAclFree((x)) -// int GACLfreeAcl(GACLacl *); +/* int GACLfreeAcl(GACLacl *); */ #define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) -// int GACLprintAcl(GACLacl *, FILE *); +/* int GACLprintAcl(GACLacl *, FILE *); */ #define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) -// int GACLsaveAcl(char *, GACLacl *); +/* int GACLsaveAcl(char *, GACLacl *); */ #define GACLloadAcl(x) GRSTgaclAclLoadFile((x)) -// GACLacl *GACLloadAcl(char *); +/* GACLacl *GACLloadAcl(char *); */ #define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) -// char *GACLfindAclForFile(char *); +/* char *GACLfindAclForFile(char *); */ #define GACLloadAclForFile(x) GRSTgaclAclLoadforFile((x)) -// GACLacl *GACLloadAclForFile(char *); +/* GACLacl *GACLloadAclForFile(char *); */ #define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) -// int GACLisAclFile(char *); +/* int GACLisAclFile(char *); */ #define GACLnewUser(x) GRSTgaclUserNew((x)) -// GACLuser *GACLnewUser(GACLcred *); +/* GACLuser *GACLnewUser(GACLcred *); */ #define GACLfreeUser(x) GRSTgaclUserFree((x)) -// int GACLfreeUser(GACLuser *); +/* int GACLfreeUser(GACLuser *); */ #define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) -// int GACLuserAddCred(GACLuser *, GACLcred *); +/* int GACLuserAddCred(GACLuser *, GACLcred *); */ #define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) -// int GACLuserHasCred(GACLuser *, GACLcred *); +/* int GACLuserHasCred(GACLuser *, GACLcred *); */ #define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) -// GACLcred *GACLuserFindCredType(GACLuser *, char *); +/* GACLcred *GACLuserFindCredType(GACLuser *, char *); */ #define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) -// int GACLtestDnList(char *, GACLuser *); +/* int GACLtestDnList(char *, GACLuser *); */ #define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) -// GACLperm GACLtestUserAcl(GACLacl *, GACLuser *); +/* GACLperm GACLtestUserAcl(GACLacl *, GACLuser *); */ #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) -// GACLperm GACLtestExclAcl(GACLacl *, GACLuser *); +/* GACLperm GACLtestExclAcl(GACLacl *, GACLuser *); */ #define GACLurlEncode(x) GRSThttpUrlEncode((x)) -// char *GACLurlEncode(char *); +/* char *GACLurlEncode(char *); */ #define GACLmildUrlEncode(x) GRSThttpUrlMildencode((x)) -// char *GACLmildUrlEncode(char *); +/* char *GACLmildUrlEncode(char *); */ -GACLparseEntry *GRSTgaclEntryParse(xmlNodePtr cur); -// special function for legacy EDG LB service +GACLentry *GRSTgaclEntryParse(xmlNodePtr cur); +/* special function for legacy EDG LB service */ diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h index 9742d15..7f614f5 100644 --- a/org.gridsite.core/interface/gridsite.h +++ b/org.gridsite.core/interface/gridsite.h @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ #ifndef HEADER_SSL_H #include @@ -67,10 +67,12 @@ #define GRST_VOMS_OID "1.3.6.1.4.1.8005.100.100.1" #define GRST_VOMS_DIR "/etc/grid-security/vomsdir" + + typedef struct { char *name; char *value; - struct _GRSTgaclNamevalue *next; } GRSTgaclNamevalue; - + void *next; } GRSTgaclNamevalue; + typedef struct { char *type; int delegation; GRSTgaclNamevalue *firstname; @@ -117,120 +119,120 @@ typedef struct { GRSTgaclCred *firstcred; int GRSTgaclInit(void); -// #define GACLnewCred(x) GRSTgaclCredNew((x)) +/* #define GACLnewCred(x) GRSTgaclCredNew((x)) */ GRSTgaclCred *GRSTgaclCredNew(char *); -// #define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) +/* #define GACLaddToCred(x,y,z) GRSTgaclCredAddValue((x),(y),(z)) */ int GRSTgaclCredAddValue(GRSTgaclCred *, char *, char *); #define GRSTgaclCredSetDelegation(cred, level) ((cred)->delegation = (level)) #define GRSTgaclCredGetDelegation(cred) ((cred)->delegation) -//#define GACLfreeCred(x) GRSTgaclCredFree((x)) +/* #define GACLfreeCred(x) GRSTgaclCredFree((x)) */ int GRSTgaclCredFree(GRSTgaclCred *); -// #define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) +/* #define GACLaddCred(x,y) GRSTgaclEntryAddCred((x),(y)) */ int GRSTgaclEntryAddCred(GRSTgaclEntry *, GRSTgaclCred *); -// #define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) +/* #define GACLdelCred(x,y) GRSTgaclEntryDelCred((x),(y)) */ int GRSTgaclEntryDelCred(GRSTgaclEntry *, GRSTgaclCred *); -// #define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) +/* #define GACLprintCred(x,y) GRSTgaclCredPrint((x),(y)) */ int GRSTgaclCredCredPrint(GRSTgaclCred *, FILE *); -// #define GACLnewEntry(x) GRSTgaclEntryNew((x)) +/* #define GACLnewEntry(x) GRSTgaclEntryNew((x)) */ GRSTgaclEntry *GRSTgaclEntryNew(void); -// #define GACLfreeEntry(x) GRSTgaclEntryFree((x)) +/* #define GACLfreeEntry(x) GRSTgaclEntryFree((x)) */ int GRSTgaclEntryFree(GRSTgaclEntry *); -// #define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) +/* #define GACLaddEntry(x,y) GRSTgaclAclAddEntry((x),(y)) */ int GRSTgaclAclAddEntry(GRSTgaclAcl *, GRSTgaclEntry *); -// #define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) +/* #define GACLprintEntry(x,y) GRSTgaclEntryPrint((x),(y)) */ int GRSTgaclEntryPrint(GRSTgaclEntry *, FILE *); -// #define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) +/* #define GACLprintPerm(x,y) GRSTgaclPermPrint((x),(y)) */ int GRSTgaclPermPrint(GRSTgaclPerm, FILE *); -// #define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) +/* #define GACLallowPerm(x,y) GRSTgaclEntryAllowPerm((x),(y)) */ int GRSTgaclEntryAllowPerm(GRSTgaclEntry *, GRSTgaclPerm); -// #define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) +/* #define GACLunallowPerm(x,y) GRSTgaclEntryUnallowPerm((x),(y)) */ int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *, GRSTgaclPerm); -// #define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) +/* #define GACLdenyPerm(x,y) GRSTgaclEntryDenyPerm((x),(y)) */ int GRSTgaclEntryDenyPerm(GRSTgaclEntry *, GRSTgaclPerm); -// #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) +/* #define GACLundenyPerm(x,y) GRSTgaclEntryUndenyPerm((x),(y)) */ int GRSTgaclUndenyPerm(GRSTgaclEntry *, GRSTgaclPerm); -// #define GACLpermToChar(x) GRSTgaclPermToChar((x)) +/* #define GACLpermToChar(x) GRSTgaclPermToChar((x)) */ char *GRSTgaclPermToChar(GRSTgaclPerm); -// #define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) +/* #define GACLcharToPerm(x) GRSTgaclPermFromChar((x)) */ GRSTgaclPerm GRSTgaclPermFromChar(char *); -// #define GACLnewAcl(x) GRSTgaclAclNew((x)) +/* #define GACLnewAcl(x) GRSTgaclAclNew((x)) */ GRSTgaclAcl *GRSTgaclAclNew(void); -// #define GACLfreeAcl(x) GRSTgaclAclFree((x)) +/* #define GACLfreeAcl(x) GRSTgaclAclFree((x)) */ int GRSTgaclAclFree(GRSTgaclAcl *); -// #define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) +/* #define GACLprintAcl(x,y) GRSTgaclAclPrint((x),(y)) */ int GRSTgaclAclPrint(GRSTgaclAcl *, FILE *); -// #define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) +/* #define GACLsaveAcl(x,y) GRSTgaclAclSave((y),(x)) */ int GRSTgaclAclSave(GRSTgaclAcl *, char *); -// #define GACLloadAcl(x) GRSTgaclFileLoadAcl((x)) +/* #define GACLloadAcl(x) GRSTgaclFileLoadAcl((x)) */ GRSTgaclAcl *GRSTgaclAclLoadFile(char *); -// #define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) +/* #define GACLfindAclForFile(x) GRSTgaclFileFindAclname((x)) */ char *GRSTgaclFileFindAclname(char *); -// #define GACLloadAclForFile(x) GRSTgaclFileLoadAcl((x)) +/* #define GACLloadAclForFile(x) GRSTgaclFileLoadAcl((x)) */ GRSTgaclAcl *GRSTgaclAclLoadforFile(char *); -// #define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) +/* #define GACLisAclFile(x) GRSTgaclFileIsAcl((x)) */ int GRSTgaclFileIsAcl(char *); -// #define GACLnewUser(x) GRSTgaclUserNew((x)) +/* #define GACLnewUser(x) GRSTgaclUserNew((x)) */ GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *); -// #define GACLfreeUser(x) GRSTgaclUserFree((x)) +/* #define GACLfreeUser(x) GRSTgaclUserFree((x)) */ int GRSTgaclUserFree(GRSTgaclUser *); -// #define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) +/* #define GACLuserAddCred(x,y) GRSTgaclUserAddCred((x),(y)) */ int GRSTgaclUserAddCred(GRSTgaclUser *, GRSTgaclCred *); -// #define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) +/* #define GACLuserHasCred(x,y) GRSTgaclUserHasCred((x),(y)) */ int GRSTgaclUserHasCred(GRSTgaclUser *, GRSTgaclCred *); int GRSTgaclUserSetDNlists(GRSTgaclUser *, char *); -// #define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) +/* #define GACLuserFindCredType(x,y) GRSTgaclUserFindCredtype((x),(y)) */ GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *, char *); -// #define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) +/* #define GACLtestDnList(x,y) GRSTgaclDNlistHasUser((x),(y)) */ int GRSTgaclDNlistHasUser(char *, GRSTgaclUser *); -// #define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) +/* #define GACLtestUserAcl(x,y) GRSTgaclAclTestUser((x),(y)) */ GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *, GRSTgaclUser *); -// #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) +/* #define GACLtestExclAcl(x,y) GRSTgaclAclTestexclUser((x),(y)) */ GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *, GRSTgaclUser *); char *GRSThttpUrlDecode(char *); -// #define GACLurlEncode(x) GRSThttpUrlEncode((x)) +/* #define GACLurlEncode(x) GRSThttpUrlEncode((x)) */ char *GRSThttpUrlEncode(char *); -// #define GACLmildUrlEncode(x) GRSThttpMildUrlEncode((x)) +/* #define GACLmildUrlEncode(x) GRSThttpMildUrlEncode((x)) */ char *GRSThttpUrlMildencode(char *); int GRSTx509NameCmp(char *, char *); @@ -242,13 +244,15 @@ int GRSTx509IsCA(X509 *); int GRSTx509CheckChain(int *, X509_STORE_CTX *); int GRSTx509VerifyCallback(int, X509_STORE_CTX *); -int GRSTx509CheckVomsSig(unsigned char *, unsigned int, - unsigned char *, unsigned int, - char *, char *, char *); -int GRSTx509GetVomsCreds(int *, int, size_t, char *, X509 *, X509 *, char *); +int GRSTx509GetVomsCreds(int *, int, size_t, char *, X509 *, STACK_OF(X509) *, char *); GRSTgaclCred *GRSTx509CompactToCred(char *); int GRSTx509CompactCreds(int *, int, size_t, char *, STACK_OF(X509) *, char *); - +char *GRSTx509CachedProxyFind(char *, char *, char *); +char *GRSTx509FindProxyFileName(void); +int GRSTx509MakeProxyCert(char **, FILE *, char *, char *, char *, int); +char *GRSTx509CachedProxyKeyFind(char *, char *, char *); +int GRSTx509MakeProxyRequest(char **, char *, char *, char *); +int GRSTx509CacheProxy(char *, char *, char *, char *); #define GRST_HEADFILE "gridsitehead.txt" #define GRST_FOOTFILE "gridsitefoot.txt" diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index a2bba0b..2971a33 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -28,9 +28,9 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # -#----------------------------------------------------------------------------- -# For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ -#----------------------------------------------------------------------------- +#--------------------------------------------------------------- +# For more information about GridSite: http://www.gridsite.org/ +#--------------------------------------------------------------- include ../VERSION @@ -41,15 +41,16 @@ export MYRPMDIR=$(shell pwd)/../RPMTMP endif ifndef prefix -export prefix=/home/dimeglio/gridsite +export prefix=/usr/local endif ifndef MYCFLAGS -export MYCFLAGS=-I. -I../interface -I/usr/include/httpd -I/usr/include/apr-0 +export MYCFLAGS=-I. -I../interface -I/usr/include/httpd -I/usr/include/apr-0 -I/opt/glite/include endif ifndef MYLDFLAGS export MYLDFLAGS=-L. +# export MYLDFLAGS=-L. -L/opt/glite/lib -lvomsc endif # @@ -57,7 +58,7 @@ endif # build: libgridsite.so.$(VERSION) libgridsite.a htcp mod_gridsite.so \ - urlencode real-gridsite-admin.cgi apidoc + urlencode findproxyfile real-gridsite-admin.cgi libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_http.o gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ @@ -87,9 +88,10 @@ htcp: htcp.c gcc -DVERSION=\"$(PATCH_VERSION)\" -I. -o htcp htcp.c \ `curl-config --cflags` `curl-config --libs` -mod_gridsite.so: mod_gridsite.c mod_ssl-private.h +mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a gcc $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ -I/usr/include/openssl -I/usr/kerberos/include \ + -I/usr/include/libxml2 \ -DVERSION=\"$(VERSION)\" -o mod_gridsite.so \ mod_gridsite.c $(MYLDFLAGS) -lxml2 -lm -lz -lgridsite @@ -102,20 +104,69 @@ real-gridsite-admin.cgi: grst_admin_main.c grst_admin_gacl.c \ -I/usr/include/openssl -I/usr/kerberos/include \ -DVERSION=\"$(VERSION)\" -lgridsite -lssl -lcrypto -lxml2 -lz -lm -apidoc: ../interface/gridsite.h grst_x509.c grst_gacl.c grst_http.c \ - Doxyfile doxygen.css +findproxyfile: findproxyfile.c libgridsite.a + gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ + -o findproxyfile findproxyfile.c -L. \ + -I/usr/include/openssl -I/usr/kerberos/include -lgridsite \ + -lssl -lcrypto -lxml2 -lz -lm + +apidoc: doxygen Doxyfile gaclexample: gaclexample.c libgridsite.a gcc -o gaclexample gaclexample.c -I. -L. \ -I/usr/include/openssl -I/usr/kerberos/include -lgridsite \ - -lxml2 -lz -lm + -lssl -lcrypto -lxml2 -lz -lm + +# +# Delegation machinery, including SOAP delegation portType. To build this +# you need to install gSOAP and set GSOAPDIR to the directory containing +# soapcpp2 and stdsoap2.h +# + +GSOAPDIR=/usr/local/lib/gsoap + +delegation.wsdl: delegation.h + $(GSOAPDIR)/soapcpp2 -c delegation.h + +libstdsoap2.a: $(GSOAPDIR)/stdsoap2.c + gcc -c -DWITH_OPENSSL $(GSOAPDIR)/stdsoap2.c + ar src libstdsoap2.a stdsoap2.o + +gridsite-delegation.cgi: grst-delegation.c delegation.h delegation.wsdl \ + libstdsoap2.a soapC.c soapServer.c + gcc $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ + grst-delegation.c \ + -I/usr/include/openssl -I/usr/kerberos/include -I$(GSOAPDIR) \ + -DVERSION=\"$(VERSION)\" \ + soapC.c soapServer.c libstdsoap2.a \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm + +htproxyput: htproxyput.c delegation.h delegation.wsdl \ + soapC.c soapServer.c libstdsoap2.a + gcc $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ + htproxyput.c \ + -I/usr/include/openssl -I/usr/kerberos/include \ + -g -DVERSION=\"$(VERSION)\" \ + -I$(GSOAPDIR) -DWITH_OPENSSL \ + soapC.c soapClient.c libstdsoap2.a \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm + +proxyput-example: proxyput-example.c delegation.h delegation.wsdl \ + soapC.c soapServer.c libstdsoap2.a + gcc $(MYCFLAGS) $(MYLDFLAGS) -o proxyput-example \ + proxyput-example.c \ + -I/usr/include/openssl -I/usr/kerberos/include \ + -g -DVERSION=\"$(VERSION)\" \ + -I$(GSOAPDIR) -DWITH_OPENSSL \ + soapC.c soapClient.c libstdsoap2.a \ + -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm # # Install # -install: +install: apidoc mkdir -p $(prefix)/include \ $(prefix)/lib \ $(prefix)/bin \ @@ -126,6 +177,7 @@ install: cp -f ../interface/gridsite.h $(prefix)/include cp -f ../interface/gridsite-gacl.h $(prefix)/include cp -f urlencode $(prefix)/bin + cp -f findproxyfile $(prefix)/bin cp -f libgridsite.a $(prefix)/lib cp -f real-gridsite-admin.cgi $(prefix)/sbin cp -f libgridsite.so.$(PATCH_VERSION) $(prefix)/lib @@ -143,7 +195,7 @@ install: cp -f ../doc/*.html ../doc/*.conf ../doc/*.1 ../doc/*.sh \ $(prefix)/share/doc/gridsite-$(VERSION) cp -f ../doc/*.1 $(prefix)/share/man/man1 - gzip -f $(prefix)/share/man/man1/*.1 + gzip $(prefix)/share/man/man1/*.1 cd ../doc ; for i in *.1 ; do ../src/roffit < $$i \ > $(prefix)/share/doc/gridsite-$(VERSION)/$$i.html ; done cp -f htcp $(prefix)/bin @@ -164,7 +216,10 @@ dist: ../gridsite-$(PATCH_VERSION)/interface cp -f ../VERSION ../README ../LICENSE ../CHANGES ../INSTALL \ ../gridsite-$(PATCH_VERSION) - cp -f Makefile *.c *.h roffit gridsite.spec \ + cp -f Makefile grst*.c htproxyput.c proxyput-example.c htcp.c \ + urlencode.c findproxyfile.c gaclexample.c mod_gridsite.c \ + delegation.h grst_admin.h mod_ssl-private.h \ + roffit gridsite.spec \ Doxyfile doxygen.css doxyheader.html \ ../gridsite-$(PATCH_VERSION)/src cp -f ../doc/*.html ../doc/*.1 ../doc/*.conf ../doc/*.sh \ diff --git a/org.gridsite.core/src/delegation.h b/org.gridsite.core/src/delegation.h new file mode 100644 index 0000000..e612498 --- /dev/null +++ b/org.gridsite.core/src/delegation.h @@ -0,0 +1,12 @@ +//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); diff --git a/org.gridsite.core/src/doxyheader.html b/org.gridsite.core/src/doxyheader.html index ad33993..af78b52 100644 --- a/org.gridsite.core/src/doxyheader.html +++ b/org.gridsite.core/src/doxyheader.html @@ -1 +1 @@ -

GridSite Version 0.9.1 +

GridSite Version 1.1.x diff --git a/org.gridsite.core/src/findproxyfile.c b/org.gridsite.core/src/findproxyfile.c new file mode 100644 index 0000000..4485cc5 --- /dev/null +++ b/org.gridsite.core/src/findproxyfile.c @@ -0,0 +1,122 @@ +/* + Copyright (c) 2002-4, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef VERSION +#define VERSION "0.0.0" +#endif + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include + +#include "gridsite.h" + +void printsyntax(char *argv0) +{ + char *p; + + p = rindex(argv0, '/'); + if (p != NULL) ++p; + else p = argv0; + + fprintf(stderr, "%s [--outsidecache] [--proxycache=PATH] " + "[--delegation-id=DELEGATION-ID] [--user-dn=USER-DN]\n" + "(Version: %s)\n", p, VERSION); +} + +#define GRST_PROXY_CACHE "/var/www/proxycache" + +int main(int argc, char *argv[]) +{ + char *delegation_id = "_", *proxycache = "", *user_dn = "", + *proxyfile = NULL; + int c, outsidecache = 0, verbose = 0, option_index; + struct option long_options[] = { {"verbose", 0, 0, 'v'}, + {"outsidecache", 0, 0, 0}, + {"proxycache", 1, 0, 0}, + {"delegation-id", 1, 0, 0}, + {"user-dn", 1, 0, 0}, + {0, 0, 0, 0} }; + + if (argc == 1) + { + printsyntax(argv[0]); + return 0; + } + + while (1) + { + option_index = 0; + + c = getopt_long(argc, argv, "v", long_options, &option_index); + + if (c == -1) break; + else if (c == 0) + { + if (option_index == 1) outsidecache = 1; + else if (option_index == 2) proxycache = optarg; + else if (option_index == 3) delegation_id = optarg; + else if (option_index == 4) user_dn = optarg; + } + else if (c == 'v') ++verbose; + } + + if (*user_dn != '\0') /* try to find in proxy cache */ + { + if ((proxycache == NULL) || (*proxycache == '\0')) + proxycache = getenv("GRST_PROXY_CACHE"); + + if ((proxycache == NULL) || (*proxycache == '\0')) + proxycache = GRST_PROXY_CACHE; + + proxyfile = GRSTx509CachedProxyFind(proxycache, delegation_id, user_dn); + } + + if (((proxyfile == NULL) || (*proxyfile == '\0')) && outsidecache) + { + proxyfile = GRSTx509FindProxyFileName(); + } + + if ((proxyfile != NULL) && (*proxyfile != '\0')) + { + puts(proxyfile); + return 0; + } + + fputs("No proxy file found\n", stderr); + + return 1; +} diff --git a/org.gridsite.core/src/gaclexample.c b/org.gridsite.core/src/gaclexample.c index 4cab5bc..5ad29b7 100644 --- a/org.gridsite.core/src/gaclexample.c +++ b/org.gridsite.core/src/gaclexample.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ /* Example program using GACL diff --git a/org.gridsite.core/src/gridsite.spec b/org.gridsite.core/src/gridsite.spec index a6633d3..c2bbe80 100644 --- a/org.gridsite.core/src/gridsite.spec +++ b/org.gridsite.core/src/gridsite.spec @@ -6,11 +6,11 @@ Copyright: Modified BSD Group: System Environment/Daemons Source: %{name}-%{version}.src.tar.gz Prefix: %(echo ${MYPREFIX:-/usr}) -URL: http://www.gridpp.ac.uk/gridsite/ +URL: http://www.gridsite.org/ Vendor: GridPP #Requires: libxml2,curl-ssl,mod_ssl #Buildrequires: libxml2-devel,curl-ssl-devel,httpd-devel -Packager: Andrew McNab +Packager: Andrew McNab %description GridSite adds GSI, VOMS and GACL support to Apache 2.0 (mod_gridsite), @@ -18,7 +18,7 @@ a library for manipulating these technologies (libgridsite), and CGI programs for interactive management of HTTP(S) servers (gridsite-admin.cgi) See %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version} and -http://www.gridpp.ac.uk/gridsite/ for details. +http://www.gridsite.org/ for details. %package -n htcp Group: Applications/Internet @@ -55,6 +55,7 @@ rm -f %(echo ${MYPREFIX:-/usr})/share/doc/gridsite %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so.%{version} %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/lib/libgridsite.so %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/urlencode +%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/bin/findproxyfile %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/doc/gridsite-%{version} %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/urlencode.1.gz %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/include/gridsite.h @@ -74,3 +75,4 @@ rm -f %(echo ${MYPREFIX:-/usr})/share/doc/gridsite %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htls.1.gz %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htll.1.gz %attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/htmkdir.1.gz +%attr(-, root, root) %(echo ${MYPREFIX:-/usr})/share/man/man1/findproxyfile.1.gz diff --git a/org.gridsite.core/src/grst-delegation.c b/org.gridsite.core/src/grst-delegation.c new file mode 100644 index 0000000..2a8a9b2 --- /dev/null +++ b/org.gridsite.core/src/grst-delegation.c @@ -0,0 +1,295 @@ +/* + Copyright (c) 2002-4, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/*---------------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridpp.ac.uk/authz/gridsite/ * + *---------------------------------------------------------------------------*/ + +#ifndef VERSION +#define VERSION "0.0.1" +#endif + +#define _GNU_SOURCE +#include + +#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" + +#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) +{ + 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); +} + +int GRSTmethodPutProxy(char *delegation_id, char *user_dn) +/* return 0 on success; non-zero on error */ +{ + 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; + + contentlen = getenv("CONTENT_LENGTH"); + if (contentlen == NULL) return 2; + len = atoi(contentlen); + + if ((delegation_id == NULL) || (*delegation_id == '\0')) + delegation_id = "_"; + + 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)) + { + return GRST_RET_FAILED; + } + + free(proxydir); + + return GRST_RET_OK; +} +#endif + +int main(int argn, char *argv[]) +{ + 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; + } + +#ifdef GRST_SUPPORT_G_HTTPS + docroot = getenv("DOCUMENT_ROOT"); + + 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) + { + 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 == NULL) /* all methods require client auth */ + { + GRSThttpError("403 Forbidden"); + } + else if (strcmp(method, "GET-PROXY-REQ") == 0) + { + docroot = getenv("DOCUMENT_ROOT"); + asprintf(&proxydir, "%s/%s", docroot, GRST_PROXYCACHE); + + 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 + { + GRSThttpError("501 Method Not Implemented"); + } +#endif +} + +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) + { + 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 ((delegation_id == NULL) || (*delegation_id == '\0')) delegation_id = "_"; + + 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)) + { + return SOAP_OK; + } + + return SOAP_ERR; +} + +int ns__putProxy(struct soap *soap, char *delegation_id, + char *proxy, + struct ns__putProxyResponse *unused) +{ + 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 ((delegation_id == NULL) || (*delegation_id == '\0')) + delegation_id = "_"; + + 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) + != GRST_RET_OK)) + { + return SOAP_ERR; + } + + return SOAP_OK; +} + diff --git a/org.gridsite.core/src/grst_admin.h b/org.gridsite.core/src/grst_admin.h index 4da3d11..cddc415 100644 --- a/org.gridsite.core/src/grst_admin.h +++ b/org.gridsite.core/src/grst_admin.h @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/gridsite/ * - *---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridsite.org/ * + *------------------------------------------------------------------*/ void GRSThttpError(char *); void adminfooter(GRSThttpBody *, char *, char *, char *, char *); diff --git a/org.gridsite.core/src/grst_admin_file.c b/org.gridsite.core/src/grst_admin_file.c index fed6c42..f89a004 100644 --- a/org.gridsite.core/src/grst_admin_file.c +++ b/org.gridsite.core/src/grst_admin_file.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/gridsite/ * - *---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridsite.org/ * + *------------------------------------------------------------------*/ #ifndef VERSION #define VERSION "x.x.x" diff --git a/org.gridsite.core/src/grst_admin_gacl.c b/org.gridsite.core/src/grst_admin_gacl.c index ba5ba1e..2a40b28 100644 --- a/org.gridsite.core/src/grst_admin_gacl.c +++ b/org.gridsite.core/src/grst_admin_gacl.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*---------------------------------------------------------------------------* -* This program is part of GridSite: http://www.gridpp.ac.uk/authz/gridsite/ * -*---------------------------------------------------------------------------*/ +/*-----------------------------------------------------------* +* This program is part of GridSite: http://www.gridsite.org/ * +*------------------------------------------------------------*/ #include #include @@ -84,7 +84,7 @@ void revert_acl(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, /*****************************************/ void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file){ - /* Shows the contents of the ACL. Gives edit 'buttons' if (int admin) == 1*/ + // Shows the contents of the ACL. Gives edit 'buttons' if (int admin) == 1 GRSTgaclAcl *acl; GRSTgaclEntry *entry; GRSTgaclCred *cred; diff --git a/org.gridsite.core/src/grst_admin_main.c b/org.gridsite.core/src/grst_admin_main.c index 9390dd1..d884bf5 100644 --- a/org.gridsite.core/src/grst_admin_main.c +++ b/org.gridsite.core/src/grst_admin_main.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/gridsite/ * - *---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridsite.org/ * + *------------------------------------------------------------------*/ #ifndef VERSION #define VERSION "x.x.x" @@ -115,7 +115,7 @@ void adminfooter(GRSThttpBody *bp, char *dn, char *help_uri, char *dir_uri, if ((getenv("GRST_NO_LINK") == NULL) && (getenv("REDIRECT_GRST_NO_LINK") == NULL)) GRSThttpPrintf(bp, "Built with " - "GridSite %s\n", + "GridSite %s\n", VERSION); GRSThttpPrintf(bp, "\n"); diff --git a/org.gridsite.core/src/grst_gacl.c b/org.gridsite.core/src/grst_gacl.c index 3c99002..13b46c8 100644 --- a/org.gridsite.core/src/grst_gacl.c +++ b/org.gridsite.core/src/grst_gacl.c @@ -28,9 +28,9 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more information about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ #include #include @@ -187,7 +187,7 @@ static int GRSTgaclCredsFree(GRSTgaclCred *firstcred) if (firstcred->next != NULL) GRSTgaclCredsFree(firstcred->next); - return GRSTgaclCredsFree(firstcred); + return GRSTgaclCredFree(firstcred); } static int GRSTgaclCredInsert(GRSTgaclCred *firstcred, GRSTgaclCred *newcred) @@ -691,18 +691,36 @@ char *GRSTgaclFileFindAclname(char *pathandfile) (for directories, the ACL file is in the directory itself), or NULL if none can be found. */ { - char *path, *p; + int len; + char *path, *file, *p; struct stat statbuf; + + len = strlen(pathandfile); + if (len == 0) return NULL; - path = malloc(strlen(pathandfile) + sizeof(GRST_ACL_FILE) + 1); + path = malloc(len + sizeof(GRST_ACL_FILE) + 2); strcpy(path, pathandfile); - if (stat(path, &statbuf) == 0) + if ((stat(path, &statbuf) == 0) && + S_ISDIR(statbuf.st_mode) && + (path[len-1] != '/')) { - if (!S_ISDIR(statbuf.st_mode)) /* can strip this / off straightaway */ + strcat(path, "/"); + ++len; + } + + if (path[len-1] != '/') + { + p = rindex(pathandfile, '/'); + if (p != NULL) { - p = rindex(path, '/'); - if (p != NULL) *p = '\0'; + file = &p[1]; + p = rindex(path, '/'); + sprintf(p, "/%s:%s", GRST_ACL_FILE, file); + + if (stat(path, &statbuf) == 0) return path; + + *p = '\0'; /* otherwise strip off any filename */ } } diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c index 797786d..37b60e6 100644 --- a/org.gridsite.core/src/grst_x509.c +++ b/org.gridsite.core/src/grst_x509.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-3, Andrew McNab, University of Manchester + Copyright (c) 2002-4, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -28,23 +28,50 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------------------------------------------------------------------ - For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ - ------------------------------------------------------------------------ + --------------------------------------------------------------- + For more information about GridSite: http://www.gridsite.org/ + --------------------------------------------------------------- */ +#define _GNU_SOURCE + #include -#include #include -#include +#include +#include +#include #include #include -#include +#include +#include +#include + +#include +#include + #include #include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef GRST_VOMS_SUPPORT +#include +#endif #include "gridsite.h" +#define GRST_KEYSIZE 512 +#define GRST_PROXYCACHE "/../proxycache/" +#define GRST_MAX_CHAIN_LEN 9 + /// Compare X509 Distinguished Name strings int GRSTx509NameCmp(char *a, char *b) /** @@ -370,100 +397,6 @@ int GRSTx509VerifyCallback (int ok, X509_STORE_CTX *ctx) // else return GRST_RET_FAILED; } -/// Check VOMS signature -/** - * Return GRST_RET_OK if signature starting at *sig matches *data and is - * from VOMS *vo; return GRST_RET_FAILED otherwise. - */ - -int GRSTx509CheckVomsSig(unsigned char *sig, unsigned int siglen, - unsigned char *data, unsigned int datalen, - char *vomsdir, char *vo, char *vomsdn) -{ - int ret = 0; - char *certfilename, *certdn; - FILE *fp; - DIR *vomsDIR; - struct dirent *certdirent; - X509 *cert; - EVP_PKEY *pubkey; - EVP_MD_CTX ctx; - struct stat statbuf; - time_t now; - - time(&now); - - vomsDIR = opendir(vomsdir); - if (vomsDIR == NULL) - { - return GRST_RET_NO_SUCH_FILE; - } - - while ((certdirent = readdir(vomsDIR)) != NULL) - { - certfilename = malloc(strlen(vomsdir) + - strlen(certdirent->d_name) + 2); - - strcpy(certfilename, vomsdir); - strcat(certfilename, "/"); - strcat(certfilename, certdirent->d_name); - - if ((stat(certfilename, &statbuf) != 0) || S_ISDIR(statbuf.st_mode)) - { - free(certfilename); - continue; - } - - fp = fopen(certfilename, "r"); - free(certfilename); - - if (fp == NULL) continue; - - cert = PEM_read_X509(fp, NULL, NULL, NULL); - fclose(fp); - - if (cert == NULL) continue; - - certdn = X509_NAME_oneline(X509_get_subject_name(cert),NULL,0); - - if ((now < - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notBefore(cert))) ) || - (now > - GRSTasn1TimeToTimeT(ASN1_STRING_data(X509_get_notAfter( cert))) ) || - (GRSTx509NameCmp(certdn, vomsdn) != 0)) - { - X509_free(cert); - continue; - } - - pubkey = X509_extract_key(cert); - - if (pubkey != NULL) - { -// EVP_MD_CTX_init(&ctx); - EVP_VerifyInit(&ctx, EVP_sha1()); - EVP_VerifyUpdate(&ctx, (unsigned char *) data, datalen); - - ret=EVP_VerifyFinal(&ctx, (unsigned char *) sig, siglen, pubkey); - -// EVP_MD_CTX_cleanup(&ctx); - } - - closedir(vomsDIR); /* we're finished now, one way or the other */ - - X509_free(cert); - - /* since we matched cert names and times, we always return */ - - if (ret == 1) return GRST_RET_OK; - else return GRST_RET_BAD_SIGNATURE; - } - - closedir(vomsDIR); - - return GRST_RET_CERT_NOT_FOUND; /* didnt find a matching VOMS cert */ -} - /// Get the VOMS attributes in the extensions to the given cert /* * Puts any VOMS credentials found into the Compact Creds string array @@ -471,10 +404,16 @@ int GRSTx509CheckVomsSig(unsigned char *sig, unsigned int siglen, */ int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, - char *creds, X509 *cert, X509 *usercert, + char *creds, X509 *cert, STACK_OF(X509) *certstack, char *vomsdir) { - int i, j; +#ifndef GRST_VOMS_SUPPORT + return GRST_RET_OK; +} +#else + +/* + int j; unsigned int siglen=-1, datalength=-1, dataoffset = -1; char s[80]; unsigned char *charstr, *p, *time1 = NULL, *time2 = NULL, *vo = NULL, @@ -485,6 +424,51 @@ int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, ASN1_STRING *asn1str; time_t now, time1_time = 0, time2_time = 0, uctime1_time, uctime2_time; +*/ + + + struct vomsdata *vd; + int i, j, vomserror; + + vd = VOMS_Init(NULL, NULL); + + if (VOMS_Retrieve(cert, certstack, RECURSE_CHAIN, vd, &vomserror) && + (vd->data != NULL)) + { + for (i = 0; vd->data[i] != NULL; ++i) + { + if (vd->data[i]->fqan != NULL) + for (j = 0; vd->data[i]->fqan[j] != NULL; ++j) + { + if (*lastcred >= maxcreds - 1) + { + VOMS_Destroy(vd); + return GRST_RET_OK; + } + + ++(*lastcred); + + snprintf(&creds[*lastcred * (credlen + 1)], + credlen+1, + "VOMS %010lu %010lu 0 %s", + GRSTasn1TimeToTimeT(vd->data[i]->date1), + GRSTasn1TimeToTimeT(vd->data[i]->date2), + vd->data[i]->fqan[j]); + } + } + } + else + { + FILE *fp = fopen("/tmp/getvoms.log", "w"); + fprintf(fp, "%d\n", vomserror); + fclose(fp); + } + + VOMS_Destroy(vd); + return GRST_RET_OK; +} + +#if 0 time(&now); @@ -622,9 +606,8 @@ int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, ++p; } } - - if ( - (now >= time1_time) && +/* + if ((now >= time1_time) && (now <= time2_time) && (signature != NULL) && (data != NULL) && @@ -635,7 +618,9 @@ int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, (GRSTx509CheckVomsSig(signature, siglen, &((ASN1_STRING_data(asn1str))[dataoffset]), datalength, vomsdir, vo, - server) == GRST_RET_OK)) while (1) + server) == GRST_RET_OK)) + while (1) +*/ { if (strncmp(p, "GROUP:", sizeof("GROUP:") - 1) == 0) { @@ -713,6 +698,9 @@ int GRSTx509GetVomsCreds(int *lastcred, int maxcreds, size_t credlen, return GRST_RET_OK; } +#endif + +#endif /// Turn a Compact Cred line into a GRSTgaclCred object /** @@ -839,8 +827,572 @@ int GRSTx509CompactCreds(int *lastcred, int maxcreds, size_t credlen, strcpy(&creds[*lastcred * (credlen + 1)], credtemp); GRSTx509GetVomsCreds(lastcred, maxcreds, credlen, creds, - gsiproxycert, usercert, vomsdir); + gsiproxycert, certstack, vomsdir); } return GRST_RET_OK; } + +/// Find proxy file name of the current user +/** + * Return a string with the proxy file name or NULL if not present. + * This function does not check if the proxy has expired. + */ + +char *GRSTx509FindProxyFileName(void) +{ + char *p; + + p = getenv("X509_USER_PROXY"); + + if (p != NULL) return strdup(p); + + p = malloc(sizeof("/tmp/x509up_uXYYYXXXYYY")); + + sprintf(p, "/tmp/x509up_u%d", getuid()); + + return p; +} + +static void mpcerror(FILE *debugfp, char *msg) +{ + if (debugfp != NULL) + { + fputs(msg, debugfp); + ERR_print_errors_fp(debugfp); + } +} + +/// Make a GSI Proxy chain from a request, certificate and private key +/** + * The proxy chain is returned in *proxychain. If debugfp is non-NULL, + * errors are output to that file pointer. The proxy will expired in + * the given number of minutes starting from the current time. + */ + +int GRSTx509MakeProxyCert(char **proxychain, FILE *debugfp, + char *reqtxt, char *cert, char *key, int minutes) +{ + char *ptr, *certchain; + int i, subjAltName_pos, ncerts; + long serial = 1, ptrlen; + EVP_PKEY *pkey, *CApkey; + const EVP_MD *digest; + X509 *certs[GRST_MAX_CHAIN_LEN]; + X509_REQ *req; + X509_NAME *name, *CAsubject, *newsubject; + X509_NAME_ENTRY *ent; + X509V3_CTX ctx; + X509_EXTENSION *subjAltName; + STACK_OF (X509_EXTENSION) * req_exts; + FILE *fp; + BIO *reqmem, *certmem; + + /* read in the request */ + reqmem = BIO_new(BIO_s_mem()); + BIO_puts(reqmem, reqtxt); + + if (!(req = PEM_read_bio_X509_REQ(reqmem, NULL, NULL, NULL))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error reading request from BIO memory\n"); + BIO_free(reqmem); + return GRST_RET_FAILED; + } + + BIO_free(reqmem); + + /* verify signature on the request */ + if (!(pkey = X509_REQ_get_pubkey (req))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error getting public key from request\n"); + return GRST_RET_FAILED; + } + + if (X509_REQ_verify(req, pkey) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error verifying signature on certificate\n"); + return GRST_RET_FAILED; + } + + /* read in the signing certificate */ + if (!(fp = fopen(cert, "r"))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error opening signing certificate file\n"); + return GRST_RET_FAILED; + } + + for (ncerts = 1; ncerts < GRST_MAX_CHAIN_LEN; ++ncerts) + if (!(certs[ncerts] = PEM_read_X509(fp, NULL, NULL, NULL))) break; + + if (ncerts == 1) /* zeroth cert with be new proxy cert */ + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error reading signing certificate file\n"); + return GRST_RET_FAILED; + } + + fclose(fp); + + CAsubject = X509_get_subject_name(certs[1]); + + /* read in the CA private key */ + if (!(fp = fopen(key, "r"))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error reading signing private key file\n"); + return GRST_RET_FAILED; + } + + if (!(CApkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error reading signing private key in file\n"); + return GRST_RET_FAILED; + } + + fclose(fp); + + /* get subject name */ + if (!(name = X509_REQ_get_subject_name (req))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error getting subject name from request\n"); + return GRST_RET_FAILED; + } + + /* create new certificate */ + if (!(certs[0] = X509_new ())) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error creating X509 object\n"); + return GRST_RET_FAILED; + } + + /* set version number for the certificate (X509v3) and the serial number + need 3 = v4 for GSI proxy?? */ + if (X509_set_version (certs[0], 3L) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting certificate version\n"); + return GRST_RET_FAILED; + } + + ASN1_INTEGER_set (X509_get_serialNumber (certs[0]), serial++); + + if (!(name = X509_get_subject_name(certs[1]))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error getting subject name from CA certificate\n"); + return GRST_RET_FAILED; + } + + if (X509_set_issuer_name (certs[0], name) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting issuer name of certificate\n"); + return GRST_RET_FAILED; + } + + /* set issuer and subject name of the cert from the req and the CA */ + ent = X509_NAME_ENTRY_create_by_NID(NULL, OBJ_txt2nid("commonName"), + MBSTRING_ASC, "proxy", -1); + + newsubject = X509_NAME_dup(CAsubject); + + X509_NAME_add_entry(newsubject, ent, -1, 0); + + if (X509_set_subject_name(certs[0], newsubject) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting subject name of certificate\n"); + return GRST_RET_FAILED; + } + + /* set public key in the certificate */ + if (X509_set_pubkey(certs[0], pkey) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting public key of the certificate\n"); + return GRST_RET_FAILED; + } + +// need to set validity within limits of earlier certificates in the chain + + /* set duration for the certificate */ + if (!(X509_gmtime_adj (X509_get_notBefore(certs[0]), 0))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting beginning time of the certificate\n"); + return GRST_RET_FAILED; + } + + if (!(X509_gmtime_adj (X509_get_notAfter(certs[0]), 60 * minutes))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error setting ending time of the certificate\n"); + return GRST_RET_FAILED; + } + + /* sign the certificate with the signing private key */ + if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_RSA) + digest = EVP_md5(); + else + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error checking signing private key for a valid digest\n"); + return GRST_RET_FAILED; + } + + if (!(X509_sign (certs[0], CApkey, digest))) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error signing certificate\n"); + return GRST_RET_FAILED; + } + + /* store the completed certificate chain */ + + certchain = strdup(""); + + for (i=0; i < ncerts; ++i) + { + certmem = BIO_new(BIO_s_mem()); + + if (PEM_write_bio_X509(certmem, certs[i]) != 1) + { + mpcerror(debugfp, + "GRSTx509MakeProxyCert(): error writing certificate to memory BIO\n"); + return GRST_RET_FAILED; + } + + ptrlen = BIO_get_mem_data(certmem, &ptr); + + certchain = realloc(certchain, strlen(certchain) + ptrlen + 1); + + strncat(certchain, ptr, ptrlen); + + BIO_free(certmem); + } + + *proxychain = certchain; + + return GRST_RET_OK; +} + +/// Find a proxy file in the proxy cache +/** + * Returns the full path and file name of proxy file associated + * with given delegation ID and user DN. + */ + +char *GRSTx509CachedProxyFind(char *proxydir, char *delegation_id, + char *user_dn) +/* + Return a pointer to a malloc'd string with the full path of the + proxy file corresponding to the given delegation_id, or NULL + 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); + + return proxyfile; +} + +/// Find a temporary proxy private key file in the proxy cache +/** + * Returns the full path and file name of the private key file associated + * with given delegation ID and user DN. + */ + +char *GRSTx509CachedProxyKeyFind(char *proxydir, char *delegation_id, + char *user_dn) +/* + Return a pointer to a malloc'd string with the full path of the + private proxy key corresponding to the given delegation_id, or NULL + 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; +} + +/// 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 proxydir as temporary file + * with a filename like .XXXXXX + */ + +int GRSTx509MakeProxyRequest(char **reqtxt, char *proxydir, + char *delegation_id, char *user_dn) +{ + int i, fd; + char *docroot, *reqfile, *prvkeyfile, *ptr; + size_t ptrlen; + FILE *fp; + RSA *keypair; + X509_NAME *subject; + X509_NAME_ENTRY *ent; + EVP_PKEY *pkey; + X509_REQ *certreq; + BIO *reqmem; + const EVP_MD *digest; + struct stat statbuf; + + if ((keypair = RSA_generate_key(GRST_KEYSIZE, 3, NULL, NULL)) == NULL) + return 1; + asprintf(&prvkeyfile, "%s/.XXXXXX", proxydir); + + fd = mkstemp(prvkeyfile); + + if ((fp = fdopen(fd, "w")) == NULL) return 1; + + fprintf(fp, "%s\n%s\n", delegation_id, user_dn); + + if (!PEM_write_RSAPrivateKey(fp, keypair, NULL, NULL, 0, NULL, NULL)) + return 1; + + if (fclose(fp) != 0) return 1; + + /* now create the certificate request */ + + certreq = X509_REQ_new(); + if (certreq == NULL) return 1; + + 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; +} + +/// Store a GSI proxy chain in the proxy cache, along with the private key +/** + * Returns GRST_RET_OK on success, non-zero otherwise. The existing + * private key with the same delegation ID and user DN is appended to + * make a valid proxy file, and the temporary private key file deleted. + */ + +int GRSTx509CacheProxy(char *proxydir, char *delegation_id, + char *user_dn, char *proxychain) +{ + int fd, c, len = 0, i; + char *cert, *upcertfile, *prvkeyfile, *p; + FILE *ifp, *ofp; + + prvkeyfile = GRSTx509CachedProxyKeyFind(proxydir, delegation_id, user_dn); + + if (prvkeyfile == NULL) + { + free(proxydir); + return GRST_RET_FAILED; + } + + if ((ifp = fopen(prvkeyfile, "r")) == NULL) + { + free(prvkeyfile); + free(proxydir); + return GRST_RET_FAILED; + } + + if (asprintf(&upcertfile, "%s/XXXXXX", proxydir) == -1) + return GRST_RET_FAILED; + + if ((fd = mkstemp(upcertfile)) == -1) + { + fclose(ifp); + free(prvkeyfile); + free(upcertfile); + return GRST_RET_FAILED; + } + + if ((ofp = fdopen(fd, "w")) == NULL) + { + close(fd); + fclose(ifp); + free(prvkeyfile); + free(upcertfile); + return GRST_RET_FAILED; + } + + fprintf(ofp, "%s\n%s\n", delegation_id, user_dn); + + fputs(proxychain, ofp); /* write out certificates */ + + while ((c = fgetc(ifp)) != EOF) fputc(c, ofp); /* append proxy private key */ + + if (fclose(ifp) != 0) return GRST_RET_FAILED; + if (fclose(ofp) != 0) return GRST_RET_FAILED; + + unlink(prvkeyfile); + + free(prvkeyfile); + free(upcertfile); + +/* should also check validity of proxy cert to avoid suprises? */ + + return GRST_RET_OK; +} diff --git a/org.gridsite.core/src/htcp.c b/org.gridsite.core/src/htcp.c index 8f0ba7f..3275806 100644 --- a/org.gridsite.core/src/htcp.c +++ b/org.gridsite.core/src/htcp.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-3, Andrew McNab, University of Manchester + Copyright (c) 2002-4, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ #ifndef VERSION #define VERSION "0.0.0" @@ -85,6 +85,7 @@ struct grst_stream_data { char *source; char *errorbuf; int noverify; int anonymous; + long long downgrade; int verbose; } ; struct grst_index_blob { char *text; @@ -97,19 +98,21 @@ struct grst_dir_list { char *filename; time_t modified; int modified_set; } ; -struct grst_header_data { int retcode; +struct grst_header_data { int retcode; char *location; + char *gridauthonetime; size_t length; int length_set; time_t modified; - int modified_set; } ; + int modified_set; + struct grst_stream_data *common_data; } ; size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p) /* Find the values of the return code, Content-Length, Last-Modified and Location headers */ { float f; - char *s; + char *s, *q; size_t realsize; struct tm modified_tm; struct grst_header_data *header_data; @@ -124,7 +127,22 @@ size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p) header_data->length_set = 1; else if (sscanf(s, "HTTP/%f %d ", &f, &(header_data->retcode)) == 2) ; else if (strncmp(s, "Location: ", 10) == 0) - header_data->location = strdup(&s[10]); + { + header_data->location = strdup(&s[10]); + + if (header_data->common_data->verbose > 0) + fprintf(stderr, "Received Location: %s\n", header_data->location); + } + else if (strncmp(s, "Set-Cookie: GRID_AUTH_ONETIME=", 30) == 0) + { + header_data->gridauthonetime = strdup(&s[12]); + q = index(header_data->gridauthonetime, ';'); + if (q != NULL) *q = '\0'; + + if (header_data->common_data->verbose > 0) + fprintf(stderr, "Received Grid Auth Cookie: %s\n", + header_data->gridauthonetime); + } else if (strncmp(s, "Last-Modified: ", 15) == 0) { /* follow RFC 2616: first try RFC 822 (kosher), then RFC 850 and @@ -196,9 +214,20 @@ int do_copies(char *sources[], char *destination, CURL *easyhandle; struct stat statbuf; struct grst_header_data header_data; + struct curl_slist *dgheader_slist = NULL, *nodgheader_slist = NULL; easyhandle = curl_easy_init(); + if (common_data->downgrade >= (long long) 0) + { + asprintf(&p, "HTTP-Downgrade-Size: %lld", common_data->downgrade); + dgheader_slist = curl_slist_append(dgheader_slist, p); + free(p); + + nodgheader_slist = curl_slist_append(nodgheader_slist, + "HTTP-Downgrade-Size:"); + } + curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); if (common_data->verbose > 1) curl_easy_setopt(easyhandle, CURLOPT_VERBOSE, 1); @@ -245,6 +274,18 @@ int do_copies(char *sources[], char *destination, curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, common_data->fp); curl_easy_setopt(easyhandle, CURLOPT_URL, sources[isrc]); + + if ((common_data->downgrade >= (long long) 0) && + (strncmp(sources[isrc], "https://", 8) == 0)) + { + if (common_data->verbose > 0) + fprintf(stderr, "Add HTTP-Downgrade-Size: %lld header\n", + common_data->downgrade); + + curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,dgheader_slist); + } + else + curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nodgheader_slist); } else if (common_data->method == HTCP_PUT) { @@ -270,25 +311,82 @@ int do_copies(char *sources[], char *destination, curl_easy_setopt(easyhandle, CURLOPT_URL, thisdestination); curl_easy_setopt(easyhandle, CURLOPT_INFILESIZE, statbuf.st_size); curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1); + + if (((long long) statbuf.st_size >= common_data->downgrade) && + (strncmp(thisdestination, "https://", 8) == 0)) + curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,dgheader_slist); + else + curl_easy_setopt(easyhandle,CURLOPT_HTTPHEADER,nodgheader_slist); } - header_data.retcode = 0; + header_data.retcode = 0; + header_data.location = NULL; + header_data.gridauthonetime = NULL; + header_data.common_data = common_data; thiserror = curl_easy_perform(easyhandle); + fclose(common_data->fp); + + if ((common_data->downgrade >= (long long) 0) && + (thiserror == 0) && + (header_data.retcode == 302) && + (header_data.location != NULL) && + (strncmp(header_data.location, "http://", 7) == 0) && + (header_data.gridauthonetime != NULL)) + { + if (common_data->verbose > 0) + fprintf(stderr, "... Found (%d)\nHTTP-Downgrade to %s\n", + header_data.retcode, header_data.location); + + /* try again with new URL and all the previous CURL options */ + + if (common_data->method == HTCP_GET) + { + common_data->fp = fopen(thisdestination, "w"); + if (common_data->fp == NULL) + { + fprintf(stderr, "... failed to open destination source " + "file %s\n", thisdestination); + anyerror = 99; + if (isdirdest) free(thisdestination); + continue; + } + } + else if (common_data->method == HTCP_PUT) + { + common_data->fp = fopen(sources[isrc], "r"); + if (common_data->fp == NULL) + { + fprintf(stderr, "... failed to open source file %s\n", + sources[isrc]); + anyerror = 99; + if (isdirdest) free(thisdestination); + continue; + } + } + + header_data.retcode = 0; + curl_easy_setopt(easyhandle, CURLOPT_URL, header_data.location); + curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, nodgheader_slist); + curl_easy_setopt(easyhandle, CURLOPT_COOKIE, + header_data.gridauthonetime); + thiserror = curl_easy_perform(easyhandle); + + fclose(common_data->fp); + } + if ((thiserror != 0) || (header_data.retcode < 200) || (header_data.retcode >= 300)) { fprintf(stderr, "... curl error: %s (%d), HTTP error: %d\n", common_data->errorbuf, thiserror, header_data.retcode); - + if (thiserror != 0) anyerror = thiserror; else anyerror = header_data.retcode; } else if (common_data->verbose > 0) fprintf(stderr, "... OK (%d)\n", header_data.retcode); - - fclose(common_data->fp); if (isdirdest) free(thisdestination); } @@ -304,6 +402,8 @@ int do_deletes(char *sources[], struct grst_stream_data *common_data) CURL *easyhandle; struct grst_header_data header_data; + header_data.common_data = common_data; + easyhandle = curl_easy_init(); curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); @@ -354,6 +454,8 @@ int do_mkdirs(char *sources[], struct grst_stream_data *common_data) CURL *easyhandle; struct grst_header_data header_data; + header_data.common_data = common_data; + easyhandle = curl_easy_init(); curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); @@ -520,7 +622,8 @@ struct grst_dir_list *index_to_dir_list(char *text, char *source) { allocated += 256; list = (struct grst_dir_list *) - malloc(allocated * sizeof(struct grst_dir_list)); + realloc((void *) list, + allocated * sizeof(struct grst_dir_list)); } list[used].filename = NULL; @@ -631,6 +734,8 @@ int do_listings(char *sources[], struct grst_stream_data *common_data, time(&now); + header_data.common_data = common_data; + easyhandle = curl_easy_init(); curl_easy_setopt(easyhandle, CURLOPT_USERAGENT, common_data->useragent); @@ -671,6 +776,7 @@ int do_listings(char *sources[], struct grst_stream_data *common_data, curl_easy_setopt(easyhandle, CURLOPT_NOBODY, 1); } + header_data.gridauthonetime = NULL; header_data.length_set = 0; header_data.modified_set = 0; header_data.retcode = 0; @@ -719,6 +825,7 @@ int do_listings(char *sources[], struct grst_stream_data *common_data, asprintf(&s, "%s%s", sources[isrc], list[i].filename); curl_easy_setopt(easyhandle, CURLOPT_URL, s); + header_data.gridauthonetime = NULL; header_data.length_set = 0; header_data.modified_set = 0; header_data.retcode = 0; @@ -859,7 +966,7 @@ void printsyntax(char *argv0) "from remote servers using HTTP or HTTPS, or to put or delete files or\n" "directories onto remote servers using HTTPS. htcp is similar to scp(1)\n" "but uses HTTP/HTTPS rather than ssh as its transfer protocol.\n" -"See the htcp(1) or http://www.gridpp.ac.uk/gridsite/ for details.\n" +"See the htcp(1) or http://www.gridsite.org/ for details.\n" "(Version: %s)\n", p, p, VERSION); } @@ -870,19 +977,20 @@ int main(int argc, char *argv[]) struct stat statbuf; struct grst_stream_data common_data; struct passwd *userpasswd; - struct option long_options[] = { {"verbose", 0, 0, 'v'}, - {"cert", 1, 0, 0}, - {"key", 1, 0, 0}, - {"capath", 1, 0, 0}, - {"delete", 0, 0, 0}, - {"list", 0, 0, 0}, - {"long-list", 0, 0, 0}, - {"mkdir", 0, 0, 0}, - {"no-verify", 0, 0, 0}, - {"anon", 0, 0, 0}, -// {"streams", 1, 0, 0}, -// {"blocksize", 1, 0, 0}, -// {"recursive", 0, 0, 0}, + struct option long_options[] = { {"verbose", 0, 0, 'v'}, + {"cert", 1, 0, 0}, + {"key", 1, 0, 0}, + {"capath", 1, 0, 0}, + {"delete", 0, 0, 0}, + {"list", 0, 0, 0}, + {"long-list", 0, 0, 0}, + {"mkdir", 0, 0, 0}, + {"no-verify", 0, 0, 0}, + {"anon", 0, 0, 0}, + {"downgrade-size", 1, 0, 0}, +// {"streams", 1, 0, 0}, +// {"blocksize", 1, 0, 0}, +// {"recursive", 0, 0, 0}, {0, 0, 0, 0} }; #if (LIBCURL_VERSION_NUM < 0x070908) @@ -901,10 +1009,11 @@ int main(int argc, char *argv[]) common_data.method = 0; common_data.errorbuf = malloc(CURL_ERROR_SIZE); asprintf(&(common_data.useragent), - "htcp/%s (http://www.gridpp.ac.uk/gridsite/)", VERSION); + "htcp/%s (http://www.gridsite.org/)", VERSION); common_data.verbose = 0; common_data.noverify = 0; common_data.anonymous = 0; + common_data.downgrade = (long long) -1; while (1) { @@ -924,6 +1033,7 @@ int main(int argc, char *argv[]) else if (option_index == 7) common_data.method = HTCP_MKDIR; else if (option_index == 8) common_data.noverify = 1; else if (option_index == 9) common_data.anonymous = 1; + else if (option_index ==10) common_data.downgrade = atoll(optarg); } else if (c == 'v') ++(common_data.verbose); } diff --git a/org.gridsite.core/src/htproxyput.c b/org.gridsite.core/src/htproxyput.c new file mode 100644 index 0000000..834bea2 --- /dev/null +++ b/org.gridsite.core/src/htproxyput.c @@ -0,0 +1,565 @@ +/* + Copyright (c) 2002-4, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + +Build with: + +gcc -lcurl -lssl -lcrypto -o grst-proxy-put grst-proxy-put.c libgridsite.a + +http://www.gridpp.ac.uk/authz/gridsite/ + +*/ + +#ifndef VERSION +#define VERSION "0.0.0" +#endif + +#define _GNU_SOURCE + +#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; + + if ((ofd = mkstemp(tmp_ca_roots)) == -1) + { + closedir(rootsDIR); + return NULL; + } + + 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); + + 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 */ + + return NULL; +} +#endif + +void printsyntax(char *argv0) +{ + char *p; + + p = rindex(argv0, '/'); + if (p != NULL) ++p; + else p = argv0; + + fprintf(stderr, "%s [options] URL\n" + "(Version: %s)\n", p, VERSION); +} + +int main(int argc, char *argv[]) +{ + char *delegation_id = "", *reqtxt, *certtxt, *valid = NULL, + *cert = NULL, *key = NULL, *capath = NULL, *keycert; + struct ns__putProxyResponse *unused; + int option_index, c, protocol = USE_SOAP, noverify = 0, + method = HTPROXY_PUT, verbose = 0, fd, minutes; + struct soap soap_get, soap_put; + FILE *ifp, *ofp; + struct stat statbuf; + struct passwd *userpasswd; + struct option long_options[] = { {"verbose", 0, 0, 'v'}, + {"cert", 1, 0, 0}, + {"key", 1, 0, 0}, + {"capath", 1, 0, 0}, + {"soap", 0, 0, 0}, + {"g-https", 0, 0, 0}, + {"no-verify", 0, 0, 0}, + {"valid", 1, 0, 0}, + {"delegation-id",1, 0, 0}, + {"put", 0, 0, 0}, + {0, 0, 0, 0} }; + CURL *curl; + + if (argc == 1) + { + printsyntax(argv[0]); + return 0; + } + + while (1) + { + option_index = 0; + + c = getopt_long(argc, argv, "v", long_options, &option_index); + + 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; + } + else if (c == 'v') ++verbose; + } + + if (optind + 1 != argc) + { + fprintf(stderr, "Must specify a target URL!\n"); + return 1; + } + + if (valid == NULL) minutes = 60 * 12; + else minutes = atoi(valid); + + if (verbose) fprintf(stderr, "Proxy valid for %d minutes\n", minutes); + + ERR_load_crypto_strings (); + OpenSSL_add_all_algorithms(); + + if ((cert == NULL) && (key != NULL)) cert = key; + else if ((cert != NULL) && (key == NULL)) key = cert; + else if ((cert == NULL) && (key == NULL)) + { + cert = getenv("X509_USER_PROXY"); + if (cert != NULL) key = cert; + else + { + 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 ... */ + + if (stat(cert, &statbuf) == 0) key = cert; + else + { + cert = getenv("X509_USER_CERT"); + key = getenv("X509_USER_KEY"); + + userpasswd = getpwuid(geteuid()); + + if ((cert == NULL) && + (userpasswd != NULL) && + (userpasswd->pw_dir != NULL)) + asprintf(&(cert), "%s/.globus/usercert.pem", + userpasswd->pw_dir); + + if ((key == NULL) && + (userpasswd != NULL) && + (userpasswd->pw_dir != NULL)) + asprintf(&(key), "%s/.globus/userkey.pem", + userpasswd->pw_dir); + + } + } + } + + if (capath == NULL) capath = getenv("X509_CERT_DIR"); + if (capath == NULL) capath = "/etc/grid-security/certificates"; + + 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 (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"); + + fd = mkstemp(keycert); + ofp = fdopen(fd, "w"); + + 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); + + fclose(ofp); + + if (verbose) fprintf(stderr, "Created %s key/cert file\n", keycert); + } + else keycert = key; + + 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); + + if (soap_ssl_client_context(&soap_get, + SOAP_SSL_DEFAULT, + keycert, + "", + NULL, + capath, + NULL)) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + soap_call_ns__getProxyReq(&soap_get, + argv[optind], /* HTTPS url of service */ + "", /* no password on proxy */ + delegation_id, + &reqtxt); + + if (soap_get.error) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + if (verbose) fprintf(stderr, "reqtxt:\n%s", reqtxt); + + if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, cert, key, minutes) + != GRST_RET_OK) + { + return 1; + } + + soap_init(&soap_put); + + if (verbose) fprintf(stderr, "Send putProxy to service:\n%s\n", certtxt); + + 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__putProxy(&soap_put, argv[optind], "", delegation_id, + certtxt, unused); + if (soap_put.error) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + return 0; + } + + /* weirdness */ +} + diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index 05ae8ff..78d853c 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/gridsite/ * - *---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridsite.org/ * + *------------------------------------------------------------------*/ #ifndef VERSION #define VERSION "x.x.x" @@ -56,11 +56,16 @@ #include #include #include +#include #include #include - +#include #include +#include +#include + + #include "mod_ssl-private.h" #include "gridsite.h" @@ -91,8 +96,257 @@ typedef struct char *editable; char *headfile; char *footfile; + int downgrade; + char *authcookiesdir; + int soap2cgi; } mod_gridsite_cfg; /* per-directory config choices */ + +typedef struct +{ + xmlDocPtr doc; +// char *outbuffer; +} soap2cgi_ctx; /* store per-request context for Soap2cgi in/out filters */ + +static const char Soap2cgiFilterName[]="Soap2cgiFilter"; + +static void mod_gridsite_soap2cgi_insert(request_rec *r) +{ + mod_gridsite_cfg *conf; + soap2cgi_ctx *ctx; + + conf = (mod_gridsite_cfg *) ap_get_module_config(r->per_dir_config, + &gridsite_module); + + if (conf->soap2cgi) + { + ctx = (soap2cgi_ctx *) malloc(sizeof(soap2cgi_ctx)); + ctx->doc = NULL; + + ap_add_output_filter(Soap2cgiFilterName, ctx, r, r->connection); + + ap_add_input_filter(Soap2cgiFilterName, NULL, r, r->connection); + } +} + +xmlNodePtr find_one_child(xmlNodePtr parent_node, char *name) +{ + xmlNodePtr cur; + + for (cur = parent_node->children; cur != NULL; cur = cur->next) + { + if ((cur->type == XML_ELEMENT_NODE) && + (strcmp(cur->name, name) == 0)) return cur; + } + + return NULL; +} + +int add_one_node(xmlDocPtr doc, char *line) +{ + char *p, *name, *aftername, *attrname = NULL, *value = NULL; + xmlNodePtr cur, cur_child; + + cur = xmlDocGetRootElement(doc); + + p = index(line, '='); + if (p == NULL) return 1; + + *p = '\0'; + value = &p[1]; + + name = line; + + while (1) /* go through each .-deliminated segment of line[] */ + { + if ((p = index(name, '.')) != NULL) + { + *p = '\0'; + aftername = &p[1]; + } + else aftername = &name[strlen(name)]; + + if ((p = index(name, '_')) != NULL) + { + *p = '\0'; + attrname = &p[1]; + } + + cur_child = find_one_child(cur, name); + + if (cur_child == NULL) + cur_child = xmlNewChild(cur, NULL, name, NULL); + + cur = cur_child; + + name = aftername; + + if (attrname != NULL) + { + xmlSetProp(cur, attrname, value); + return 0; + } + + if (*name == '\0') + { + xmlNodeSetContent(cur, value); + return 0; + } + } +} + +static apr_status_t mod_gridsite_soap2cgi_out(ap_filter_t *f, + apr_bucket_brigade *bbIn) +{ + char *p, *name, *outbuffer; + request_rec *r = f->r; + conn_rec *c = r->connection; + apr_bucket *bucketIn, *pbktEOS; + apr_bucket_brigade *bbOut; + + const char *data; + apr_size_t len; + char *buf; + apr_size_t n; + apr_bucket *pbktOut; + + soap2cgi_ctx *ctx; + xmlNodePtr root_node = NULL; + xmlBufferPtr buff; + + ctx = (soap2cgi_ctx *) f->ctx; + +// LIBXML_TEST_VERSION; + + bbOut = apr_brigade_create(r->pool, c->bucket_alloc); + + if (ctx->doc == NULL) + { + ctx->doc = xmlNewDoc("1.0"); + + root_node = xmlNewNode(NULL, "Envelope"); + xmlDocSetRootElement(ctx->doc, root_node); + + xmlNewChild(root_node, NULL, "Header", NULL); + xmlNewChild(root_node, NULL, "Body", NULL); + } + + apr_brigade_pflatten(bbIn, &outbuffer, &len, r->pool); + + /* split up buffer and feed each line to add_one_node() */ + + name = outbuffer; + + while (*name != '\0') + { + p = index(name, '\n'); + if (p != NULL) + { + *p = '\0'; + ++p; + } + else p = &name[strlen(name)]; /* point to final NUL */ + + add_one_node(ctx->doc, name); + + name = p; + } + + APR_BRIGADE_FOREACH(bucketIn, bbIn) + { + if (APR_BUCKET_IS_EOS(bucketIn)) + { + /* write out XML tree we have built */ + + buff = xmlBufferCreate(); + xmlNodeDump(buff, ctx->doc, root_node, 0, 0); + +// TODO: simplify/reduce number of copies or libxml vs APR buffers? + + buf = (char *) xmlBufferContent(buff); + + pbktOut = apr_bucket_heap_create(buf, strlen(buf), NULL, + c->bucket_alloc); + + APR_BRIGADE_INSERT_TAIL(bbOut, pbktOut); + + xmlBufferFree(buff); + + pbktEOS = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bbOut, pbktEOS); + + continue; + } + } + + return ap_pass_brigade(f->next, bbOut); +} + +static apr_status_t mod_gridsite_soap2cgi_in(ap_filter_t *f, + apr_bucket_brigade *pbbOut, + ap_input_mode_t eMode, + apr_read_type_e eBlock, + apr_off_t nBytes) +{ + request_rec *r = f->r; + conn_rec *c = r->connection; +// CaseFilterInContext *pCtx; + apr_status_t ret; + +#ifdef NEVERDEFINED + + ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); + + if (!(pCtx = f->ctx)) { + f->ctx = pCtx = apr_palloc(r->pool, sizeof *pCtx); + pCtx->pbbTmp = apr_brigade_create(r->pool, c->bucket_alloc); + } + + if (APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { + ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); + + if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS) + return ret; + } + + while(!APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { + apr_bucket *pbktIn = APR_BRIGADE_FIRST(pCtx->pbbTmp); + apr_bucket *pbktOut; + const char *data; + apr_size_t len; + char *buf; + int n; + + /* It is tempting to do this... + * APR_BUCKET_REMOVE(pB); + * APR_BRIGADE_INSERT_TAIL(pbbOut,pB); + * and change the case of the bucket data, but that would be wrong + * for a file or socket buffer, for example... + */ + + if(APR_BUCKET_IS_EOS(pbktIn)) { + APR_BUCKET_REMOVE(pbktIn); + APR_BRIGADE_INSERT_TAIL(pbbOut, pbktIn); + break; + } + + ret=apr_bucket_read(pbktIn, &data, &len, eBlock); + if(ret != APR_SUCCESS) + return ret; + + buf = malloc(len); + for(n=0 ; n < len ; ++n) + buf[n] = apr_toupper(data[n]); + + pbktOut = apr_bucket_heap_create(buf, len, 0, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut); + apr_bucket_delete(pbktIn); + } +#endif + + return APR_SUCCESS; +} + char *make_admin_footer(request_rec *r, mod_gridsite_cfg *conf, int isdirectory) /* @@ -236,7 +490,7 @@ char *make_admin_footer(request_rec *r, mod_gridsite_cfg *conf, if (conf->gridsitelink) { temp = apr_psprintf(r->pool, - ". Built with " + ". Built with " "GridSite %s\n", VERSION); out = apr_pstrcat(r->pool, out, temp, NULL); } @@ -511,10 +765,11 @@ int html_dir_list(request_rec *r, mod_gridsite_cfg *conf) if (S_ISDIR(statbuf.st_mode)) temp = apr_psprintf(r->pool, - "%s/" + "" + "%s/" "%ld%s\n", - namelist[n]->d_name, statbuf.st_mtime, + namelist[n]->d_name, statbuf.st_size, statbuf.st_mtime, namelist[n]->d_name, statbuf.st_size, modified); else temp = apr_psprintf(r->pool, @@ -604,6 +859,81 @@ int html_dir_list(request_rec *r, mod_gridsite_cfg *conf) return OK; } +int http_downgrade(request_rec *r, mod_gridsite_cfg *conf) +{ + int i; + char *httpurl, *filetemplate, *cookievalue, *envname_i, + *grst_cred_i, expires_str[APR_RFC822_DATE_LEN]; + apr_uint64_t gridauthcookie; + apr_table_t *env; + apr_time_t expires_time; + apr_file_t *fp; + + /* create random cookie and gridauthcookie file */ + + if (apr_generate_random_bytes((char *) &gridauthcookie, + sizeof(gridauthcookie)) + != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; + + filetemplate = apr_psprintf(r->pool, "%s/%016llxXXXXXX", + ap_server_root_relative(r->pool, + conf->authcookiesdir), + gridauthcookie); + + if (apr_file_mktemp(&fp, + filetemplate, + APR_CREATE | APR_WRITE | APR_EXCL, + r->pool) + != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR; + + expires_time = apr_time_now() + apr_time_from_sec(300); + /* onetime cookies are valid for only 5 mins! */ + + apr_file_printf(fp, "expires=%lu\ndomain=%s\npath=%s\nonetime=yes\n", + (time_t) apr_time_sec(expires_time), r->hostname, r->uri); + + for (i=0; ; ++i) + { + envname_i = apr_psprintf(r->pool, "GRST_CRED_%d", i); + if (grst_cred_i = (char *) + apr_table_get(r->connection->notes, envname_i)) + { + apr_file_printf(fp, "%s=%s\n", envname_i, grst_cred_i); + } + else break; /* GRST_CRED_i are numbered consecutively */ + } + + if (apr_file_close(fp) != APR_SUCCESS) + { + apr_file_remove(filetemplate, r->pool); /* try to clean up */ + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* send redirection header back to client */ + + cookievalue = rindex(filetemplate, '/'); + if (cookievalue != NULL) ++cookievalue; + else cookievalue = filetemplate; + + apr_rfc822_date(expires_str, expires_time); + + apr_table_add(r->headers_out, + apr_pstrdup(r->pool, "Set-Cookie"), + apr_psprintf(r->pool, + "GRID_AUTH_ONETIME=%s; " + "expires=%s; " + "domain=%s; " + "path=%s", + cookievalue, expires_str, r->hostname, r->uri)); + + httpurl = apr_pstrcat(r->pool, "http://", r->hostname, + ap_escape_uri(r->pool, r->uri), NULL); + apr_table_setn(r->headers_out, apr_pstrdup(r->pool, "Location"), httpurl); + + r->status = HTTP_MOVED_TEMPORARILY; + return OK; +} + int http_put_method(request_rec *r, mod_gridsite_cfg *conf) { char buf[2048]; @@ -630,7 +960,7 @@ int http_put_method(request_rec *r, mod_gridsite_cfg *conf) if (apr_file_open(&fp, r->filename, APR_WRITE | APR_CREATE | APR_BUFFERED, APR_UREAD | APR_UWRITE, r->pool) != 0) return HTTP_INTERNAL_SERVER_ERROR; -// need to add Range: support at some point too +// TODO: need to add Range: support at some point too retcode = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); if (retcode == OK) @@ -697,10 +1027,26 @@ static int mod_gridsite_nondir_handler(request_rec *r, mod_gridsite_cfg *conf) and GET inside ghost directories. */ { - /* *** is this a write method? only possible if GridSiteAuth on *** */ + char *downgradesize; + apr_off_t numericsize; + + /* *** is this a write method or HTTP downgrade? + only possible if GridSiteAuth on *** */ if (conf->auth) { + if ((conf->downgrade) && + ((downgradesize = (char *) apr_table_get(r->headers_in, + "HTTP-Downgrade-Size")) != NULL) && + ((numericsize = (apr_off_t) atoll(downgradesize)) >= 0) && + +// TODO: what if we're pointing at a CGI or some dynamic content??? + (((r->method_number == M_GET) && (r->finfo.size >= numericsize)) + || (r->method_number == M_PUT)) && + + (strcasecmp(apr_table_get(r->subprocess_env, "HTTPS"), "on") == 0)) + return http_downgrade(r, conf); + if ((r->method_number == M_PUT) && (conf->methods != NULL) && (strstr(conf->methods, " PUT " ) != NULL)) @@ -1113,6 +1459,11 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path) conf->headfile = apr_pstrdup(p, GRST_HEADFILE); conf->footfile = apr_pstrdup(p, GRST_FOOTFILE); /* GridSiteHeadFile and GridSiteFootFile file name */ + + conf->downgrade = 0; /* GridSiteDowngrade on/off */ + conf->authcookiesdir = apr_pstrdup(p, "gridauthcookies"); + /* GridSiteAuthCookiesDir dir-path */ + conf->soap2cgi = 0; /* GridSiteSoap2cgi on/off */ } else { @@ -1132,8 +1483,11 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path) conf->unzip = NULL; /* GridSiteUnzip file-path */ conf->methods = NULL; /* GridSiteMethods methods */ conf->editable = NULL; /* GridSiteEditable types */ - conf->headfile = NULL; /* GridSiteHeadFile file name */ - conf->footfile = NULL; /* GridSiteFootFile file name */ + conf->headfile = NULL; /* GridSiteHeadFile file name */ + conf->footfile = NULL; /* GridSiteFootFile file name */ + conf->downgrade = UNSET; /* GridSiteDowngrade on/off */ + conf->authcookiesdir= NULL; /* GridSiteAuthCookiesDir dir-path */ + conf->soap2cgi = UNSET; /* GridSiteSoap2cgi on/off */ } return conf; @@ -1204,6 +1558,16 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, if (direct->footfile != NULL) conf->footfile = direct->footfile; else conf->footfile = server->footfile; + if (direct->downgrade != UNSET) conf->downgrade = direct->downgrade; + else conf->downgrade = server->downgrade; + + if (direct->authcookiesdir != NULL) + conf->authcookiesdir = direct->authcookiesdir; + else conf->authcookiesdir = server->authcookiesdir; + + if (direct->soap2cgi != UNSET) conf->soap2cgi = direct->soap2cgi; + else conf->soap2cgi = server->soap2cgi; + return conf; } @@ -1307,6 +1671,14 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, ((mod_gridsite_cfg *) cfg)->indexheader = apr_pstrdup(a->pool, parm); } + else if (strcasecmp(a->cmd->name, "GridSiteAuthCookiesDir") == 0) + { + if (index(parm, '/') != NULL) + return "/ not permitted in GridSiteAuthCookiesDir"; + + ((mod_gridsite_cfg *) cfg)->authcookiesdir = + apr_pstrdup(a->pool, parm); + } return NULL; } @@ -1334,12 +1706,24 @@ static const char *mod_gridsite_flag_cmds(cmd_parms *a, void *cfg, { ((mod_gridsite_cfg *) cfg)->gridsitelink = flag; } + else if (strcasecmp(a->cmd->name, "GridSiteDowngrade") == 0) + { +// TODO: return error if try this on non-HTTPS virtual server + + ((mod_gridsite_cfg *) cfg)->downgrade = flag; + } + else if (strcasecmp(a->cmd->name, "GridSiteSoap2cgi") == 0) + { + ((mod_gridsite_cfg *) cfg)->soap2cgi = flag; + } return NULL; } static const command_rec mod_gridsite_cmds[] = { +// TODO: need to check and document valid contexts for each command! + AP_INIT_FLAG("GridSiteAuth", mod_gridsite_flag_cmds, NULL, OR_FILEINFO, "on or off"), AP_INIT_FLAG("GridSiteEnvs", mod_gridsite_flag_cmds, @@ -1379,6 +1763,13 @@ static const command_rec mod_gridsite_cmds[] = AP_INIT_TAKE1("GridSiteIndexHeader", mod_gridsite_take1_cmds, NULL, OR_FILEINFO, "filename of directory header"), + AP_INIT_FLAG("GridSiteDowngrade", mod_gridsite_flag_cmds, + NULL, OR_FILEINFO, "on or off"), + AP_INIT_TAKE1("GridSiteAuthCookiesDir", mod_gridsite_take1_cmds, + NULL, OR_FILEINFO, "directory with Grid Auth Cookies"), + + AP_INIT_FLAG("GridSiteSoap2cgi", mod_gridsite_flag_cmds, + NULL, OR_FILEINFO, "on or off"), {NULL} }; @@ -1391,6 +1782,9 @@ static int mod_gridsite_first_fixups(request_rec *r) conf = (mod_gridsite_cfg *) ap_get_module_config(r->per_dir_config, &gridsite_module); + /* we handle DN Lists as regular files, even if they also match + directory names */ + if ((conf != NULL) && (conf->dnlistsuri != NULL) && (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0) && @@ -1412,10 +1806,13 @@ static int mod_gridsite_perm_handler(request_rec *r) { int retcode = DECLINED, i, n; char *dn, *p, envname[14], *grst_cred_0 = NULL, *dir_path, - *remotehost, s[99], *grst_cred_i, *file; + *remotehost, s[99], *grst_cred_i, *file, *cookies, + *gridauthonetime, *cookiefile, oneline[1025], *key_i; const char *content_type; time_t now, notbefore, notafter; apr_table_t *env; + apr_finfo_t cookiefile_info; + apr_file_t *fp; GRSTgaclCred *cred = NULL, *cred_0 = NULL; GRSTgaclUser *user = NULL; GRSTgaclPerm perm = GRST_PERM_NONE; @@ -1430,13 +1827,104 @@ static int mod_gridsite_perm_handler(request_rec *r) if ((cfg->auth == 0) && (cfg->envs == 0)) return DECLINED; /* if not turned on, look invisible */ - + env = r->subprocess_env; - if (r->connection->notes != NULL) - grst_cred_0 = (char *) apr_table_get(r->connection->notes, "GRST_CRED_0"); + if ((p = (char *) apr_table_get(r->headers_in, "Cookie")) != NULL) + { + cookies = apr_pstrcat(r->pool, " ", p, NULL); + gridauthonetime = strstr(cookies, " GRID_AUTH_ONETIME="); + + if (gridauthonetime != NULL) + { + for (p = &gridauthonetime[19]; (*p != '\0') && (*p != ';'); ++p) + if (!isalnum(*p)) *p = '_'; + + cookiefile = apr_psprintf(r->pool, "%s/%s", + ap_server_root_relative(r->pool, + cfg->authcookiesdir), + &gridauthonetime[19]); + + if ((apr_stat(&cookiefile_info , cookiefile, + APR_FINFO_TYPE, r->pool) == APR_SUCCESS) && + (cookiefile_info.filetype == APR_REG) && + (apr_file_open(&fp, cookiefile, APR_READ, 0, r->pool) + == APR_SUCCESS)) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Open Grid Auth Cookie file %s", cookiefile); + + while (apr_file_gets(oneline, + sizeof(oneline), fp) == APR_SUCCESS) + { + p = index(oneline, '\n'); + if (p != NULL) *p = '\0'; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "%s: %s", cookiefile, oneline); + + if ((strncmp(oneline, "expires=", 8) == 0) && + (apr_time_from_sec(atoll(&oneline[8])) < + apr_time_now())) + break; + else if ((strncmp(oneline, "domain=", 7) == 0) && + (strcmp(&oneline[7], r->hostname) != 0)) + break; /* exact needed in the version */ + else if ((strncmp(oneline, "path=", 5) == 0) && + (strcmp(&oneline[5], r->uri) != 0)) + break; + else if (strncmp(oneline, "onetime=yes", 11) == 0) + apr_file_remove(cookiefile, r->pool); + else if (strncmp(oneline, "GRST_CRED_", 10) == 0) + { + grst_cred_i = index(oneline, '='); + if (grst_cred_i == NULL) continue; + *grst_cred_i = '\0'; + ++grst_cred_i; + + i = atoi(&oneline[10]); + cred = GRSTx509CompactToCred(grst_cred_i); + + if (cred == NULL) continue; + + if ((i == 0) && (user == NULL)) + { + if (GRSTgaclCredGetDelegation(cred) + <= ((mod_gridsite_cfg *) cfg)->gsiproxylimit) + { + user = GRSTgaclUserNew(cred); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, + 0, r->server, + "Using identity %s from " + "GRID_AUTH_ONETIME", + grst_cred_i); + + if (((mod_gridsite_cfg *) cfg)->envs) + apr_table_setn(env, oneline, grst_cred_i); + } + } + else if ((i > 0) && (user != NULL)) + { + GRSTgaclUserAddCred(user, cred); + + if (((mod_gridsite_cfg *) cfg)->envs) + apr_table_set(env,oneline,grst_cred_i); + } + } + } + + apr_file_close(fp); + } + } + } + + /* do we need/have per-connection (SSL) cred variable(s)? */ - if (grst_cred_0 != NULL) /* do we have per-connection cred variable(s)? */ + if ((user == NULL) && + (r->connection->notes != NULL) && + ((grst_cred_0 = (char *) + apr_table_get(r->connection->notes, "GRST_CRED_0")) != NULL)) { if (((mod_gridsite_cfg *) cfg)->envs) apr_table_setn(env, "GRST_CRED_0", grst_cred_0); @@ -1446,6 +1934,9 @@ static int mod_gridsite_perm_handler(request_rec *r) (GRSTgaclCredGetDelegation(cred_0) <= ((mod_gridsite_cfg *) cfg)->gsiproxylimit)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Using identity %s from SSL/TLS", grst_cred_0); + user = GRSTgaclUserNew(cred_0); /* check for VOMS GRST_CRED_i too */ @@ -1830,6 +2321,19 @@ static int mod_gridsite_handler(request_rec *r) static void register_hooks(apr_pool_t *p) { + /* set up the Soap2cgi input and output filters */ + + ap_hook_insert_filter(mod_gridsite_soap2cgi_insert, NULL, NULL, + APR_HOOK_MIDDLE); + + ap_register_output_filter(Soap2cgiFilterName, mod_gridsite_soap2cgi_out, + NULL, AP_FTYPE_RESOURCE); + +// ap_register_input_filter(Soap2cgiFilterName, mod_gridsite_soap2cgi_in, +// NULL, AP_FTYPE_RESOURCE); + + /* config and handler stuff */ + ap_hook_post_config(mod_gridsite_server_post_config, NULL, NULL, APR_HOOK_LAST); ap_hook_child_init(mod_gridsite_child_init, NULL, NULL, APR_HOOK_MIDDLE); @@ -1838,7 +2342,7 @@ static void register_hooks(apr_pool_t *p) ap_hook_fixups(mod_gridsite_perm_handler,NULL,NULL,APR_HOOK_REALLY_LAST); - ap_hook_handler(mod_gridsite_handler, NULL, NULL, APR_HOOK_FIRST); + ap_hook_handler(mod_gridsite_handler, NULL, NULL, APR_HOOK_FIRST); } module AP_MODULE_DECLARE_DATA gridsite_module = diff --git a/org.gridsite.core/src/mod_ssl-private.h b/org.gridsite.core/src/mod_ssl-private.h index bcf759a..2a60edf 100644 --- a/org.gridsite.core/src/mod_ssl-private.h +++ b/org.gridsite.core/src/mod_ssl-private.h @@ -49,9 +49,9 @@ * limitations under the License. */ -/*---------------------------------------------------------------------------* - * This program is part of GridSite: http://www.gridpp.ac.uk/gridsite/ * - *---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------* + * This program is part of GridSite: http://www.gridsite.org/ * + *------------------------------------------------------------------*/ /* diff --git a/org.gridsite.core/src/proxyput-example.c b/org.gridsite.core/src/proxyput-example.c new file mode 100644 index 0000000..f0fe834 --- /dev/null +++ b/org.gridsite.core/src/proxyput-example.c @@ -0,0 +1,131 @@ +/* + Copyright (c) 2002-4, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + Change the hard-coded defaults below to your set up. +*/ + +#define LOCALPROXY "/tmp/x509up" +#define DELEGATIONURL "https://testing.hep.man.ac.uk/gridsite-delegation.cgi" +#define CAPATH "/etc/grid-security/certificates" +#define DELEGATIONID "1234567890" +#define EXPIREMINUTES 60 + +#ifndef VERSION +#define VERSION "0.0.0" +#endif + +#define _GNU_SOURCE + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "gridsite.h" + +#include "soapH.h" +#include "delegation.nsmap" + +int main(int argc, char *argv[]) +{ + char *reqtxt, *certtxt; + struct ns__putProxyResponse *unused; + struct soap soap_get, soap_put; + + ERR_load_crypto_strings (); + OpenSSL_add_all_algorithms(); + + soap_init(&soap_get); + + if (soap_ssl_client_context(&soap_get, + SOAP_SSL_DEFAULT, + LOCALPROXY, + "", + NULL, + CAPATH, + NULL)) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + soap_call_ns__getProxyReq(&soap_get, + DELEGATIONURL, /* HTTPS url of service */ + "", /* no password on proxy */ + DELEGATIONID, + &reqtxt); + + if (soap_get.error) + { + soap_print_fault(&soap_get, stderr); + return 1; + } + + if (GRSTx509MakeProxyCert(&certtxt, stderr, reqtxt, + LOCALPROXY, LOCALPROXY, EXPIREMINUTES) + != GRST_RET_OK) + { + return 1; + } + + soap_init(&soap_put); + + if (soap_ssl_client_context(&soap_put, + SOAP_SSL_DEFAULT, + LOCALPROXY, + "", + NULL, + CAPATH, + NULL)) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + soap_call_ns__putProxy(&soap_put, DELEGATIONURL, "", DELEGATIONID, + certtxt, unused); + if (soap_put.error) + { + soap_print_fault(&soap_put, stderr); + return 1; + } + + return 0; +} + diff --git a/org.gridsite.core/src/urlencode.c b/org.gridsite.core/src/urlencode.c index 8890689..bea36a9 100644 --- a/org.gridsite.core/src/urlencode.c +++ b/org.gridsite.core/src/urlencode.c @@ -29,9 +29,9 @@ POSSIBILITY OF SUCH DAMAGE. */ -/*------------------------------------------------------------------------* - * For more about GridSite: http://www.gridpp.ac.uk/gridsite/ * - *------------------------------------------------------------------------*/ +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ #include #include -- 1.8.2.3