From b40822b55eb984db1b941cd2417497e0cacf9c52 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Thu, 29 Sep 2005 19:34:30 +0000 Subject: [PATCH] SiteCast in mod_gridsite --- org.gridsite.core/CHANGES | 8 + org.gridsite.core/VERSION | 2 +- org.gridsite.core/doc/httpd-fileserver.conf | 19 +- org.gridsite.core/doc/httpd-webserver.conf | 16 +- org.gridsite.core/interface/gridsite.h | 41 +- org.gridsite.core/project/version.properties | 2 +- org.gridsite.core/src/Makefile | 65 ++-- org.gridsite.core/src/grst_htcp.c | 307 +++++++++++++++ org.gridsite.core/src/htcp | Bin 23375 -> 31631 bytes org.gridsite.core/src/mod_gridsite.c | 560 +++++++++++++++++++++++++-- 10 files changed, 943 insertions(+), 77 deletions(-) create mode 100644 org.gridsite.core/src/grst_htcp.c diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES index e68d642..beef484 100644 --- a/org.gridsite.core/CHANGES +++ b/org.gridsite.core/CHANGES @@ -1,3 +1,11 @@ +* Thu Sep 29 2005 Andrew McNab +- Add SiteCast support to mod_gridsite (file location + discovery via UDP multicast of HTCP messages.) +* Wed Sep 21 2005 Andrew McNab +- Add ports 777 and 488 to example httpd.conf files in + docs. See http://www.gridsite.org/wiki/IP_Ports +* Tue Sep 13 2005 Andrew McNab +- ==== GridSite version 1.1.12 ==== * Tue Sep 13 2005 Andrew McNab - Fix bug #10031 submitted by Fabrizio Pacini (invalid free in diff --git a/org.gridsite.core/VERSION b/org.gridsite.core/VERSION index 2e3c1a3..9429197 100644 --- a/org.gridsite.core/VERSION +++ b/org.gridsite.core/VERSION @@ -1,4 +1,4 @@ MAJOR_VERSION=1 MINOR_VERSION=1.1 -PATCH_VERSION=1.1.11 +PATCH_VERSION=1.1.12 VERSION=$(PATCH_VERSION) diff --git a/org.gridsite.core/doc/httpd-fileserver.conf b/org.gridsite.core/doc/httpd-fileserver.conf index eddad08..a14a559 100644 --- a/org.gridsite.core/doc/httpd-fileserver.conf +++ b/org.gridsite.core/doc/httpd-fileserver.conf @@ -1,10 +1,14 @@ ############################################################################## ## GridSite httpd-fileserver.conf - Andrew McNab ## -## Example configuration file for GridSite as an HTTP(S) fileserver. -## ## For GridSite documentation, see http://www.gridsite.org/ ## +## Example configuration file for GridSite as an HTTP(S) fileserver, +## listening on ports 80/777 (HTTP) and 443/488 (HTTPS) +## +## (777/488 is to allow firewalls to distinguish between Grid and +## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) +## ## This file should be renamed /etc/httpd/conf/httpd.conf and Apache ## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. ## @@ -67,6 +71,7 @@ ## ## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use ## a Globus GSI Proxy created with grid-proxy-init.) +## ############################################################################## ServerRoot "/etc/httpd" @@ -105,11 +110,12 @@ ErrorLog logs/httpd-gridsite-errors HostnameLookups On ###################################################################### -# Plain unauthenticated HTTP on port 80 +# Plain unauthenticated HTTP on ports 80 and 777 ###################################################################### Listen 80 - +Listen 777 + GridSiteIndexes on @@ -120,13 +126,14 @@ Listen 80 ###################################################################### -# Secured and possibly authenticated HTTPS on port 443 +# Secured and possibly authenticated HTTPS on ports 443 and 488 ###################################################################### Listen 443 +Listen 488 SSLSessionCacheTimeout 300 SSLSessionCache dbm:/var/cache/mod_ssl/scache # This version of GridSite is NOT compatible with the SHM SSL cache!!! - + SSLEngine on SSLCertificateFile /etc/grid-security/hostcert.pem diff --git a/org.gridsite.core/doc/httpd-webserver.conf b/org.gridsite.core/doc/httpd-webserver.conf index 57adb5d..59b7487 100644 --- a/org.gridsite.core/doc/httpd-webserver.conf +++ b/org.gridsite.core/doc/httpd-webserver.conf @@ -1,10 +1,14 @@ ############################################################################## ## GridSite httpd-webserver.conf - Andrew McNab ## +## For GridSite documentation, see http://www.gridsite.org/ +## ## Example configuration file for GridSite as a Web Server ## (that is, primarily for interactive use with a browser.) +## Listening is on ports 80/777 (HTTP) and 443/488 (HTTPS). ## -## For GridSite documentation, see http://www.gridsite.org/ +## (777/488 is to allow firewalls to distinguish between Grid and +## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) ## ## This file should be renamed /etc/httpd/conf/httpd.conf and Apache ## restarted to use Apache2/GridSite as a webserver. @@ -113,11 +117,12 @@ ErrorLog logs/httpd-gridsite-errors HostnameLookups On ###################################################################### -# Plain unauthenticated HTTP on port 80 +# Plain unauthenticated HTTP on ports 80 and 777 ###################################################################### Listen 80 - +Listen 777 + ## This is used to serve the Manage Directory links in footers, ## and to allow you to edit files and ACLs via your browser. @@ -150,13 +155,14 @@ ScriptAlias /real-gridsite-admin.cgi /usr/sbin/real-gridsite-admin.cgi ###################################################################### -# Secured and possibly authenticated HTTPS on port 443 +# Secured and possibly authenticated HTTPS on ports 443 and 488 ###################################################################### Listen 443 +Listen 488 SSLSessionCacheTimeout 300 SSLSessionCache dbm:/var/cache/mod_ssl/scache # This version of GridSite is NOT compatible with the SHM SSL cache!!! - + SSLEngine on SSLCertificateFile /etc/grid-security/hostcert.pem diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h index e252019..9e6b302 100644 --- a/org.gridsite.core/interface/gridsite.h +++ b/org.gridsite.core/interface/gridsite.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-3, Andrew McNab, University of Manchester + Copyright (c) 2002-5, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -124,6 +124,39 @@ struct GRSTasn1TagList { char treecoords[GRST_ASN1_MAXCOORDLEN+1]; int length; int tag; } ; +#define GRST_HTTP_PORT 777 +#define GRST_HTTPS_PORT 488 +#define GRST_HTCP_PORT 777 + +#define GRSThtcpNOPop 0 +#define GRSThtcpTSTop 1 + +typedef struct { unsigned char length_msb; + unsigned char length_lsb; + char text[1]; } GRSThtcpCountstr; + +#define GRSThtcpCountstrLen(string) (256*((string)->length_msb) + (string)->length_lsb) + +typedef struct { unsigned char total_length_msb; + unsigned char total_length_lsb; + unsigned char version_msb; + unsigned char version_lsb; + unsigned char data_length_msb; + unsigned char data_length_lsb; + unsigned int response : 4; + unsigned int opcode : 4; + unsigned int rr : 1; + unsigned int f1 : 1; + unsigned int reserved : 6; + unsigned int trans_id; /* must be 4 bytes */ + GRSThtcpCountstr *method; + GRSThtcpCountstr *uri; + GRSThtcpCountstr *version; + GRSThtcpCountstr *req_hdrs; + GRSThtcpCountstr *resp_hdrs; + GRSThtcpCountstr *entity_hdrs; + GRSThtcpCountstr *cache_hdrs; } GRSThtcpMessage; + int GRSTgaclInit(void); /* #define GACLnewCred(x) GRSTgaclCredNew((x)) */ @@ -285,3 +318,9 @@ int GRSTasn1ParseDump(BIO *, unsigned char *, long, struct GRSTasn1TagList taglist[], int, int *); int GRSTasn1GetX509Name(char *, int, char *, char *, struct GRSTasn1TagList taglist[], int); + +int GRSThtcpNOPrequestMake(char **, int *, unsigned int); +int GRSThtcpNOPresponseMake(char **, int *, unsigned int); +int GRSThtcpTSTrequestMake(char **, int *, unsigned int, char *, char *, char *); +int GRSThtcpTSTresponseMake(char **, int *, unsigned int, char *, char *, char *); +int GRSThtcpMessageParse(GRSThtcpMessage *, char *, int); diff --git a/org.gridsite.core/project/version.properties b/org.gridsite.core/project/version.properties index 87511c8..6c6d643 100644 --- a/org.gridsite.core/project/version.properties +++ b/org.gridsite.core/project/version.properties @@ -1,2 +1,2 @@ -module.version=1.1.11 +module.version=1.1.12 module.age=1 diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index 381def9..5eeac2e 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -64,40 +64,44 @@ build: libgridsite_globus.so.$(VERSION) libgridsite_globus.a # First, normal versions using system OpenSSL rather than Globus OpenSSL -libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o +libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ - -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o + -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o -libgridsite.a: grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o - ar src libgridsite.a grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o +libgridsite.a: grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o + ar src libgridsite.a grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o grst_x509.o: grst_x509.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ + gcc -g $(MYCFLAGS) \ -I/usr/kerberos/include -c grst_x509.c grst_gacl.o: grst_gacl.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ + gcc -g $(MYCFLAGS) \ -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c grst_xacml.o: grst_xacml.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ + gcc -g $(MYCFLAGS) \ -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c grst_http.o: grst_http.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ + gcc -g $(MYCFLAGS) \ -I/usr/kerberos/include -c grst_http.c grst_asn1.o: grst_asn1.c ../interface/gridsite.h - gcc $(MYCFLAGS) \ + gcc -g $(MYCFLAGS) \ -I/usr/kerberos/include -c grst_asn1.c +grst_htcp.o: grst_htcp.c ../interface/gridsite.h + gcc -g $(MYCFLAGS) \ + -I/usr/kerberos/include -c grst_htcp.c + # Then build versions using Globus OpenSSL if configured ifdef OPENSSL_GLOBUS_LIBS libgridsite_globus.so.$(VERSION): \ grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o \ - grst_asn1_globus.o grst_xacml_globus.o + grst_asn1_globus.o grst_xacml_globus.o grst_htcp_globus.o gcc -shared -Wl,-soname,libgridsite_globus.so.$(MINOR_VERSION) \ -o libgridsite_globus.so.$(PATCH_VERSION) \ grst_x509_globus.o grst_gacl_globus.o grst_xacml_globus.o grst_http_globus.o grst_asn1_globus.o @@ -107,30 +111,35 @@ libgridsite_globus.a: grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o g grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o grst_x509_globus.o: grst_x509.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ -I/usr/kerberos/include -c grst_x509.c \ -o grst_x509_globus.o grst_gacl_globus.o: grst_gacl.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c \ -o grst_gacl_globus.o grst_xacml_globus.o: grst_xacml.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c \ -o grst_xacml_globus.o grst_http_globus.o: grst_http.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ -I/usr/kerberos/include -c grst_http.c \ -o grst_http_globus.o grst_asn1_globus.o: grst_asn1.c ../interface/gridsite.h - gcc $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ -I/usr/kerberos/include -c grst_asn1.c \ -o grst_asn1_globus.o +grst_htcp_globus.o: grst_htcp.c ../interface/gridsite.h + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + -I/usr/kerberos/include -c grst_htcp.c \ + -o grst_htcp_globus.o + else libgridsite_globus.so.$(VERSION): libgridsite.so.$(VERSION) @@ -142,21 +151,21 @@ libgridsite_globus.a: libgridsite.a endif gsexec: gsexec.c gsexec.h - gcc -DVERSION=\"$(PATCH_VERSION)\" -I/usr/include/httpd \ + gcc -g -DVERSION=\"$(PATCH_VERSION)\" -I/usr/include/httpd \ -I/usr/include/apr-0 \ -o gsexec gsexec.c urlencode: urlencode.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ + gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ -o urlencode urlencode.c -L. \ -I/usr/kerberos/include -lgridsite htcp: htcp.c - gcc -DVERSION=\"$(PATCH_VERSION)\" -I. -o htcp htcp.c \ + gcc -g -DVERSION=\"$(PATCH_VERSION)\" -I. -o htcp htcp.c \ `curl-config --cflags` `curl-config --libs` mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a - gcc $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ + gcc -g $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ -I/usr/kerberos/include \ -I/usr/include/libxml2 \ -DVERSION=\"$(VERSION)\" -o mod_gridsite.so \ @@ -164,7 +173,7 @@ mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a real-gridsite-admin.cgi: grst_admin_main.c grst_admin_gacl.c \ grst_admin_file.c grst_admin.h - gcc $(MYCFLAGS) $(MYLDFLAGS) -o real-gridsite-admin.cgi \ + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o real-gridsite-admin.cgi \ grst_admin_main.c \ grst_admin_gacl.c \ grst_admin_file.c \ @@ -172,13 +181,13 @@ real-gridsite-admin.cgi: grst_admin_main.c grst_admin_gacl.c \ -DVERSION=\"$(VERSION)\" -lgridsite -lssl -lcrypto -lxml2 -lz -lm findproxyfile: findproxyfile.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ + gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ -o findproxyfile findproxyfile.c -L. \ -I/usr/kerberos/include -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm showx509exts: showx509exts.c libgridsite.a - gcc -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ + gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) $(MYLDFLAGS) \ -o showx509exts showx509exts.c -L. \ -I/usr/kerberos/include \ -lgridsite \ @@ -188,12 +197,12 @@ apidoc: doxygen Doxyfile gaclexample: gaclexample.c libgridsite.a - gcc -o gaclexample gaclexample.c -I. -L. \ + gcc -g -o gaclexample gaclexample.c -I. -L. \ -I/usr/kerberos/include -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm xacmlexample: xacmlexample.c libgridsite.a - gcc -o xacmlexample xacmlexample.c -I. -L. \ + gcc -g -o xacmlexample xacmlexample.c -I. -L. \ -I/usr/kerberos/include -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm @@ -212,12 +221,12 @@ delegation.wsdl: delegation.h $(GSOAPDIR)/bin/soapcpp2 -c delegation.h libstdsoap2.a: $(GSOAPDIR)/stdsoap2.c - gcc -c -DWITH_OPENSSL $(GSOAPDIR)/stdsoap2.c + gcc -g -c -DWITH_OPENSSL $(GSOAPDIR)/stdsoap2.c ar src libstdsoap2.a stdsoap2.o gridsite-delegation.cgi: grst-delegation.c delegation.h delegation.wsdl \ soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-delegation.cgi \ grst-delegation.c \ -I/usr/kerberos/include -I$(GSOAPDIR)/include \ -DVERSION=\"$(VERSION)\" -L$(GSOAPDIR)/lib \ @@ -226,7 +235,7 @@ gridsite-delegation.cgi: grst-delegation.c delegation.h delegation.wsdl \ htproxyput: htproxyput.c delegation.h delegation.wsdl \ soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o htproxyput \ htproxyput.c \ -I/usr/kerberos/include \ -g -DVERSION=\"$(VERSION)\" \ @@ -236,7 +245,7 @@ htproxyput: htproxyput.c delegation.h delegation.wsdl \ proxyput-example: proxyput-example.c delegation.h delegation.wsdl \ soapC.c soapServer.c - gcc $(MYCFLAGS) $(MYLDFLAGS) -o proxyput-example \ + gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o proxyput-example \ proxyput-example.c \ -I/usr/kerberos/include \ -g -DVERSION=\"$(VERSION)\" \ diff --git a/org.gridsite.core/src/grst_htcp.c b/org.gridsite.core/src/grst_htcp.c new file mode 100644 index 0000000..55a32e6 --- /dev/null +++ b/org.gridsite.core/src/grst_htcp.c @@ -0,0 +1,307 @@ +/* + Copyright (c) 2002-5, 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 "x.x.x" +#endif + +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include + +#include "gridsite.h" + +int GRSThtcpNOPrequestMake(char **request, int *request_length, + unsigned int trans_id) +/* + Make a complete HTCP NOP request and return a pointer to malloc'd + memory pointing to it. +*/ +{ + *request_length = + asprintf(request,"%c%c" /* place holder for total length */ + "%c%c" /* HTCP version 0.0 */ + "%c%c" /* DATA length place holder */ + "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ + "%c%c%c%c" /* TRANS-ID placeholder */ + "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ + 0, 0, + 0, 0, + 0, 0, + GRSThtcpNOPop * 16, 2, + 0, 0, 0, 0, + 0, 2); + + if (*request_length < 0) return GRST_RET_FAILED; + + (*request)[0] = *request_length / 256; + (*request)[1] = *request_length % 256; + + (*request)[4] = (*request_length - 6) / 256; + (*request)[5] = (*request_length - 6) % 256; + + memcpy(&((*request)[8]), &trans_id, 4); + + return GRST_RET_OK; +} + +int GRSThtcpNOPresponseMake(char **message, int *message_length, + unsigned int trans_id) +/* + Make a complete HTCP NOP response for a found file and return a pointer + to malloc'd memory pointing to it. +*/ +{ + *message_length = + asprintf(message, + "%c%c" /* place holder for total length */ + "%c%c" /* HTCP version 0.0 */ + "%c%c" /* DATA length place holder */ + "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ + "%c%c%c%c" /* TRANS-ID place holder */ + "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ + 0, 0, + 0, 0, + 0, 0, + GRSThtcpNOPop * 16, 1, /* RR=1, MO=0, RESPONSE=0 (ie found) */ + 0, 0, 0, 0, + 0, 2); + + if (*message_length < 0) return GRST_RET_FAILED; + + (*message)[0] = *message_length / 256; + (*message)[1] = *message_length % 256; + + (*message)[4] = (*message_length - 6) / 256; + (*message)[5] = (*message_length - 6) % 256; + + memcpy(&((*message)[8]), &trans_id, 4); + + return GRST_RET_OK; +} + +int GRSThtcpTSTrequestMake(char **request, int *request_length, + unsigned int trans_id, + char *method, char *uri, char *req_hdrs) +/* + Make a complete HTCP TST request and return a pointer to malloc'd + memory pointing to it. +*/ +{ + if ((method == NULL) || (uri == NULL) || (req_hdrs == NULL)) + return GRST_RET_FAILED; + + *request_length = + asprintf(request,"%c%c" /* place holder for total length */ + "%c%c" /* HTCP version 0.0 */ + "%c%c" /* DATA length place holder */ + "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ + "%c%c%c%c" /* TRANS-ID placeholder */ + "%c%c%s" /* OP-DATA: METHOD */ + "%c%c%s" /* OP-DATA: URI */ + "%c%c%s" /* OP-DATA: VERSION */ + "%c%c%s" /* OP-DATA: REQ-HDRS */ + "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ + 0, 0, + 0, 0, + 0, 0, + GRSThtcpTSTop * 16, 2, + 0, 0, 0, 0, + strlen(method) / 256, strlen(method) % 256, method, + strlen(uri) / 256, strlen(uri) % 256, uri, + 0, 8, "HTTP/1.1", + strlen(req_hdrs)/256, strlen(req_hdrs) % 256, req_hdrs, + 0, 2); + + if (*request_length < 0) return GRST_RET_FAILED; + + (*request)[0] = *request_length / 256; + (*request)[1] = *request_length % 256; + + (*request)[4] = (*request_length - 6) / 256; + (*request)[5] = (*request_length - 6) % 256; + + memcpy(&((*request)[8]), &trans_id, 4); + + return GRST_RET_OK; +} + +int GRSThtcpTSTresponseMake(char **message, int *message_length, + unsigned int trans_id, + char *resp_hdrs, char *entity_hdrs, + char *cache_hdrs) +/* + Make a complete HTCP TST response for a found file and return a pointer + to malloc'd memory pointing to it. +*/ +{ + if ((resp_hdrs != NULL) && (entity_hdrs != NULL) && (cache_hdrs != NULL)) + /* found file response */ + *message_length = + asprintf(message, + "%c%c" /* place holder for total length */ + "%c%c" /* HTCP version 0.0 */ + "%c%c" /* DATA length place holder */ + "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ + "%c%c%c%c" /* TRANS-ID place holder */ + "%c%c%s" /* OP-DATA: RESP-HDRS */ + "%c%c%s" /* OP-DATA: ENTITY-HDRS */ + "%c%c%s" /* OP-DATA: CACHE-HDRS */ + "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ + 0, 0, + 0, 0, + 0, 0, + GRSThtcpTSTop * 16, 1, /* RR=1, MO=0, RESPONSE=0 (ie found) */ + 0, 0, 0, 0, + strlen(resp_hdrs) / 256, strlen(resp_hdrs) % 256, resp_hdrs, + strlen(entity_hdrs) / 256, strlen(entity_hdrs) % 256, entity_hdrs, + strlen(cache_hdrs) / 256, strlen(cache_hdrs) % 256, cache_hdrs, + 0, 2); + else if (cache_hdrs != NULL) + /* not found file response, just cache_hdrs given */ + *message_length = + asprintf(message, + "%c%c" /* place holder for total length */ + "%c%c" /* HTCP version 0.0 */ + "%c%c" /* DATA length place holder */ + "%c%c" /* OPCODE,RESPONSE,RESERVED,F1,RR */ + "%c%c%c%c" /* TRANS-ID */ + "%c%c%s" /* OP-DATA: CACHE-HDRS */ + "%c%c", /* AUTH (LENGTH=2 means no AUTH) */ + 0, 0, + 0, 0, + 0, 0, + GRSThtcpTSTop * 16 + 1, 1, /* RR=1, MO=0, RESPONSE=1 (missing) */ + 0, 0, 0, 0, + strlen(cache_hdrs) / 256, strlen(cache_hdrs) % 256, cache_hdrs, + 0, 2); + else return GRST_RET_FAILED; + + if (*message_length < 0) return GRST_RET_FAILED; + + (*message)[0] = *message_length / 256; + (*message)[1] = *message_length % 256; + + (*message)[4] = (*message_length - 6) / 256; + (*message)[5] = (*message_length - 6) % 256; + + memcpy(&((*message)[8]), &trans_id, 4); + + return GRST_RET_OK; +} + +int GRSThtcpMessageParse(GRSThtcpMessage *parsed, char *raw, int length) +{ + GRSThtcpCountstr *s; + + bzero(parsed, sizeof(GRSThtcpMessage)); + + if (length < (void *) &(parsed->method) + - (void *) &(parsed->total_length_msb) + 2) + return GRST_RET_FAILED; + + memcpy(parsed, raw, (void *) &(parsed->method) + - (void *) &(parsed->total_length_msb)); + + if (parsed->opcode == GRSThtcpNOPop) return GRST_RET_OK; + + if ((parsed->opcode == GRSThtcpTSTop) && (parsed->rr == 0)) + { + /* point to start of data/auth in raw */ + s = (GRSThtcpCountstr *) &(((GRSThtcpMessage *) raw)->method); + + /* METHOD string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->method = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + /* URI string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->uri = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + /* VERSION string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->version = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + /* REQ-HDRS string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->req_hdrs = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + return GRST_RET_OK; + } + + if ((parsed->opcode == GRSThtcpTSTop) && (parsed->rr == 1)) + { + /* point to start of data/auth in raw */ + s = (GRSThtcpCountstr *) &(((GRSThtcpMessage *) raw)->method); + + /* RESP-HDRS string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->resp_hdrs = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + /* ENTITY-HDRS string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->entity_hdrs = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + /* CACHE-HDRS string */ + + if ((void *) s + 2 + GRSThtcpCountstrLen(s) > (void *) raw + length) + return GRST_RET_FAILED; + parsed->cache_hdrs = s; + s = (GRSThtcpCountstr *) ((void *) s + 2 + GRSThtcpCountstrLen(s)); + + return GRST_RET_OK; + } + + return GRST_RET_FAILED; +} diff --git a/org.gridsite.core/src/htcp b/org.gridsite.core/src/htcp index a71a2c5a93ed74a4365b6bf644c566d53bfbb5fb..96935f758f70651237d962801326b8d0a62644f5 100644 GIT binary patch delta 8314 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 WNe1S_$9=Gcwq>E`zklHIhW`PCYGtqh delta 101 zcmeDG&Uk(s;{*laDV_{qV8Wolz|Nq-Aj2TJ(b&a-(QtExgDb~mvGnVcFS%)KF3C8+ zJlQ8#fOW421H<*ng*n2LOL7HxzxXmRY+z?#kOrEeGkIdJG}DsM&FgZnF>d~nKbso> DxrrZK diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index b81d7b2..a64d155 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -42,6 +42,7 @@ #endif #include +#include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +65,11 @@ #include #include +#include +#include +#include +#include + #include #include @@ -77,10 +84,24 @@ module AP_MODULE_DECLARE_DATA gridsite_module; -typedef struct -{ - char *onetimesdir; -} mod_gridsite_srv_cfg; /* per-server config choices */ +#define GRST_SITECAST_GROUPS 32 + +struct sitecast_group + { int socket; int quad1; int quad2; int quad3; int quad4; int port; }; + +#define GRST_SITECAST_ALIASES 32 + +struct sitecast_alias + { const char *sitecast_url; const char *local_path; server_rec *server; }; + +/* Globals, defined by main server directives in httpd.conf + These are assigned default values in create_gridsite_srv_config() */ + +int gridhttpport = 0; +char *onetimesdir = NULL; +char *sitecastdnlists = NULL; +struct sitecast_group sitecastgroups[GRST_SITECAST_GROUPS+1]; +struct sitecast_alias sitecastaliases[GRST_SITECAST_ALIASES]; typedef struct { @@ -890,9 +911,7 @@ int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf) filetemplate = apr_psprintf(r->pool, "%s/%016llxXXXXXX", ap_server_root_relative(r->pool, - ((mod_gridsite_srv_cfg *) - ap_get_module_config(r->server->module_config, - &gridsite_module))->onetimesdir), + onetimesdir), gridauthcookie); if (apr_file_mktemp(&fp, @@ -946,9 +965,13 @@ int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf) "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); + + if (gridhttpport != DEFAULT_HTTP_PORT) + httpurl = apr_psprintf(r->pool, "http://%s:%d%s", r->hostname, + gridhttpport, ap_escape_uri(r->pool, r->uri)); + else 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; @@ -1495,24 +1518,37 @@ static int mod_gridsite_dnlistsuri_handler(request_rec *r, static void *create_gridsite_srv_config(apr_pool_t *p, server_rec *s) { - mod_gridsite_srv_cfg *srv_conf = apr_palloc(p, sizeof(*srv_conf)); + int i; - srv_conf->onetimesdir = apr_pstrdup(p, "/var/www/onetimes"); - /* GridSiteOnetimesDir dir-path */ - return srv_conf; -} + if (!(s->is_virtual)) + { + gridhttpport = GRST_HTTP_PORT; + + onetimesdir = apr_pstrdup(p, "/var/www/onetimes"); + /* GridSiteOnetimesDir dir-path */ -static void *merge_gridsite_srv_config(apr_pool_t *p, void *srvroot, - void *vhost) -/* merge virtual host with server-wide configs */ -{ - mod_gridsite_srv_cfg *conf;; + sitecastdnlists = NULL; - conf = apr_palloc(p, sizeof(*conf)); + sitecastgroups[0].quad1 = 0; + sitecastgroups[0].quad2 = 0; + sitecastgroups[0].quad3 = 0; + sitecastgroups[0].quad4 = 0; + sitecastgroups[0].port = GRST_HTCP_PORT; + /* GridSiteCastUniPort udp-port */ - conf->onetimesdir = ((mod_gridsite_srv_cfg *) srvroot)->onetimesdir; - - return conf; + for (i=1; i <= GRST_SITECAST_GROUPS; ++i) + sitecastgroups[i].port = 0; + /* GridSiteCastGroup mcast-list */ + + for (i=1; i <= GRST_SITECAST_ALIASES; ++i) + { + sitecastaliases[i].sitecast_url = NULL; + sitecastaliases[i].local_path = NULL; + sitecastaliases[i].server = NULL; + } /* GridSiteCastAlias url path */ + } + + return NULL; } static void *create_gridsite_dir_config(apr_pool_t *p, char *path) @@ -1547,7 +1583,7 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path) conf->footfile = apr_pstrdup(p, GRST_FOOTFILE); /* GridSiteHeadFile and GridSiteFootFile file name */ - conf->gridhttp = 0; /* GridSiteGridHTTP on/off */ + conf->gridhttp = 0; /* GridSiteGridHTTP on/off */ conf->soap2cgi = 0; /* GridSiteSoap2cgi on/off */ conf->aclformat = apr_pstrdup(p, "GACL"); /* GridSiteACLFormat gacl/xacml */ @@ -1690,18 +1726,60 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, const char *parm) { - int n; + int n, i; char *p; - mod_gridsite_srv_cfg *srv_cfg = - (mod_gridsite_srv_cfg *) ap_get_module_config(a->server->module_config, - &gridsite_module); if (strcasecmp(a->cmd->name, "GridSiteOnetimesDir") == 0) { if (a->server->is_virtual) return "GridSiteOnetimesDir cannot be used inside a virtual server"; - srv_cfg->onetimesdir = apr_pstrdup(a->pool, parm); + onetimesdir = apr_pstrdup(a->pool, parm); + } + else if (strcasecmp(a->cmd->name, "GridSiteGridHTTPport") == 0) + { + gridhttpport = atoi(parm); + } + else if (strcasecmp(a->cmd->name, "GridSiteCastDNlists") == 0) + { + if (a->server->is_virtual) + return "GridSiteDNlists cannot be used inside a virtual server"; + + sitecastdnlists = apr_pstrdup(a->pool, parm); + } + else if (strcasecmp(a->cmd->name, "GridSiteCastUniPort") == 0) + { + if (a->server->is_virtual) + return "GridSiteCastUniPort cannot be used inside a virtual server"; + + if (sscanf(parm, "%d", &(sitecastgroups[0].port)) != 1) + return "Failed parsing GridSiteCastUniPort numeric value"; + } + else if (strcasecmp(a->cmd->name, "GridSiteCastGroup") == 0) + { + if (a->server->is_virtual) + return "GridSiteCastGroup cannot be used inside a virtual server"; + + for (i=1; i <= GRST_SITECAST_GROUPS; ++i) + { + if (sitecastgroups[i].port == 0) /* a free slot */ + { + sitecastgroups[i].port = GRST_HTCP_PORT; + + if (sscanf(parm, "%d.%d.%d.%d:%d", + &(sitecastgroups[i].quad1), + &(sitecastgroups[i].quad2), + &(sitecastgroups[i].quad3), + &(sitecastgroups[i].quad4), + &(sitecastgroups[i].port)) < 4) + return "Failed parsing GridSiteCastGroup nnn.nnn.nnn.nnn[:port]"; + + break; + } + } + + if (i > GRST_SITECAST_GROUPS) + return "Maximum GridSiteCastGroup groups reached"; } else if (strcasecmp(a->cmd->name, "GridSiteAdminFile") == 0) { @@ -1827,6 +1905,8 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg, const char *parm1, const char *parm2) { + int i; + if (strcasecmp(a->cmd->name, "GridSiteUserGroup") == 0) { if (!(unixd_config.suexec_enabled)) @@ -1859,6 +1939,27 @@ static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg, | ((APR_GREAD | APR_GWRITE) * (strcasecmp(parm1, "GroupWrite") == 0)) | ((APR_GREAD | APR_WREAD) * (strcasecmp(parm2, "WorldRead") == 0)); } + else if (strcasecmp(a->cmd->name, "GridSiteCastAlias") == 0) + { + for (i=0; i < GRST_SITECAST_ALIASES; ++i) /* look for free slot */ + { + if ( +// srv_cfg-> + sitecastaliases[i].sitecast_url == NULL) + { +/* + srv_cfg->sitecastaliases[i].sitecast_url = parm1; + srv_cfg->sitecastaliases[i].local_path = parm2; + srv_cfg->sitecastaliases[i].server = a->server; +*/ + sitecastaliases[i].sitecast_url = parm1; + sitecastaliases[i].local_path = parm2; + sitecastaliases[i].server = a->server; + + break; + } + } + } return NULL; } @@ -1945,9 +2046,20 @@ static const command_rec mod_gridsite_cmds[] = AP_INIT_FLAG("GridSiteGridHTTP", mod_gridsite_flag_cmds, NULL, OR_FILEINFO, "on or off"), + AP_INIT_TAKE1("GridSiteGridHTTPport", mod_gridsite_take1_cmds, + NULL, RSRC_CONF, "GridHTTP port"), AP_INIT_TAKE1("GridSiteOnetimesDir", mod_gridsite_take1_cmds, NULL, RSRC_CONF, "directory with GridHTTP onetime passcodes"), - + + AP_INIT_TAKE1("GridSiteCastDNlists", mod_gridsite_take1_cmds, + NULL, RSRC_CONF, "DN Lists directories search path for SiteCast"), + AP_INIT_TAKE1("GridSiteCastUniPort", mod_gridsite_take1_cmds, + NULL, RSRC_CONF, "UDP port for unicast/replies"), + AP_INIT_TAKE1("GridSiteCastGroup", mod_gridsite_take1_cmds, + NULL, RSRC_CONF, "multicast group[:port] to listen for HTCP on"), + AP_INIT_TAKE2("GridSiteCastAlias", mod_gridsite_take2_cmds, + NULL, RSRC_CONF, "URL and local path mapping"), + AP_INIT_FLAG("GridSiteSoap2cgi", mod_gridsite_flag_cmds, NULL, OR_FILEINFO, "on or off"), @@ -2196,9 +2308,7 @@ static int mod_gridsite_perm_handler(request_rec *r) { cookiefile = apr_psprintf(r->pool, "%s/%s", ap_server_root_relative(r->pool, - ((mod_gridsite_srv_cfg *) - ap_get_module_config(r->server->module_config, - &gridsite_module))->onetimesdir), + onetimesdir), &gridauthonetime[18]); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, @@ -2551,12 +2661,390 @@ int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) return returned_ok; } +void sitecast_handle_NOP_request(server_rec *main_server, + GRSThtcpMessage *htcp_mesg, int igroup, + struct sockaddr_in *client_addr_ptr) +{ + int outbuf_len; + char *outbuf; + + if (GRSThtcpNOPresponseMake(&outbuf, &outbuf_len, + htcp_mesg->trans_id) == GRST_RET_OK) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast sends NOP response from port %d to %s:%d", + sitecastgroups[0].port, inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + + sendto(sitecastgroups[0].socket, outbuf, outbuf_len, 0, + client_addr_ptr, sizeof(struct sockaddr_in)); + + free(outbuf); + } +} + +void sitecast_handle_TST_GET(server_rec *main_server, + GRSThtcpMessage *htcp_mesg, int igroup, + struct sockaddr_in *client_addr_ptr) +{ + int i, outbuf_len, ialias, port; + char *filename, *outbuf, *location, *local_uri = NULL; + struct stat statbuf; + SSLSrvConfigRec *ssl_srv; + + /* check sanity of requested uri */ + + if (strncmp(htcp_mesg->uri->text, "http://", 7) == 0) + { + for (i=7; i < GRSThtcpCountstrLen(htcp_mesg->uri); ++i) + if (htcp_mesg->uri->text[i] == '/') + { + local_uri = &(htcp_mesg->uri->text[i]); + break; + } + } + else if (strncmp(htcp_mesg->uri->text, "https://", 8) == 0) + { + for (i=8; i < GRSThtcpCountstrLen(htcp_mesg->uri); ++i) + if (htcp_mesg->uri->text[i] == '/') + { + local_uri = &(htcp_mesg->uri->text[i]); + break; + } + } + + if (local_uri == NULL) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast responder only handles http(s):// (%*s requested by %s:%d)", + GRSThtcpCountstrLen(htcp_mesg->uri), + htcp_mesg->uri->text, + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + return; + } + + /* find if any GridSiteCastAlias lines match */ + + for (ialias=0; ialias < GRST_SITECAST_ALIASES ; ++ialias) + { + if (sitecastaliases[ialias].sitecast_url == NULL) return; /* no match */ + + if ((strlen(sitecastaliases[ialias].sitecast_url) + <= GRSThtcpCountstrLen(htcp_mesg->uri)) && + (strncmp(sitecastaliases[ialias].sitecast_url, + htcp_mesg->uri->text, + strlen(sitecastaliases[ialias].sitecast_url))==0)) break; + } + + if (ialias == GRST_SITECAST_ALIASES) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast responder does not handle %*s requested by %s:%d", + GRSThtcpCountstrLen(htcp_mesg->uri), + htcp_mesg->uri->text, + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + + return; /* no match */ + } + + /* convert URL to filename, using alias mapping */ + + asprintf(&filename, "%s%*s", + sitecastaliases[ialias].local_path, + GRSThtcpCountstrLen(htcp_mesg->uri) + - strlen(sitecastaliases[ialias].sitecast_url), + &(htcp_mesg->uri->text[strlen(sitecastaliases[ialias].sitecast_url)]) ); + + if (stat(filename, &statbuf) == 0) /* found file */ + { + ssl_srv = (SSLSrvConfigRec *) + ap_get_module_config(sitecastaliases[ialias].server->module_config, + &ssl_module); + + port = sitecastaliases[ialias].server->addrs->host_port; + if (port == 0) port = ((ssl_srv != NULL) && (ssl_srv->enabled)) + ? GRST_HTTPS_PORT : GRST_HTTP_PORT; + + asprintf(&location, "Location: http%s://%s:%d%s\r\n", + ((ssl_srv != NULL) && (ssl_srv->enabled)) ? "s" : "", + sitecastaliases[ialias].server->server_hostname, port, + local_uri); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast finds %*s at %s, redirects with %s", + GRSThtcpCountstrLen(htcp_mesg->uri), + htcp_mesg->uri->text, filename, location); + + if (GRSThtcpTSTresponseMake(&outbuf, &outbuf_len, + htcp_mesg->trans_id, + location, "", "") == GRST_RET_OK) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast sends TST response from port %d to %s:%d", + sitecastgroups[0].port, inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + + sendto(sitecastgroups[0].socket, outbuf, outbuf_len, 0, + client_addr_ptr, sizeof(struct sockaddr_in)); + + free(outbuf); + } + + free(location); + } + + free(filename); +} + +void sitecast_handle_request(server_rec *main_server, + char *reqbuf, int reqbuf_len, int igroup, + struct sockaddr_in *client_addr_ptr) +{ + GRSThtcpMessage htcp_mesg; + + if (GRSThtcpMessageParse(&htcp_mesg,reqbuf,reqbuf_len) != GRST_RET_OK) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast responder rejects format of UDP message from %s:%d", + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + return; + } + + if (htcp_mesg.rr != 0) /* ignore HTCP responses: we just do requests */ + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast responder ignores HTCP response from %s:%d", + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + return; + } + + if (htcp_mesg.opcode == GRSThtcpNOPop) + { + sitecast_handle_NOP_request(main_server, &htcp_mesg, + igroup, client_addr_ptr); + return; + } + + if (htcp_mesg.opcode == GRSThtcpTSTop) + { + if (((GRSThtcpCountstrLen(htcp_mesg.method) == 3) && + (strncmp(htcp_mesg.method->text, "GET", 3) == 0)) || + ((GRSThtcpCountstrLen(htcp_mesg.method) == 4) && + (strncmp(htcp_mesg.method->text, "HEAD", 4) == 0))) + { + sitecast_handle_TST_GET(main_server, &htcp_mesg, + igroup, client_addr_ptr); + return; + } + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast responder rejects method %*s in TST message from %s:%d", + GRSThtcpCountstrLen(htcp_mesg.method), htcp_mesg.method->text, + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); + return; + } + + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast does not implement HTCP op-code %d in message from %s:%d", + htcp_mesg.opcode, + inet_ntoa(client_addr_ptr->sin_addr), + ntohs(client_addr_ptr->sin_port)); +} + +void sitecast_responder(server_rec *main_server) +{ +#define GRST_SITECAST_MAXBUF 8192 + char reqbuf[GRST_SITECAST_MAXBUF], *p; + int n, reqbuf_len, i, j, igroup, + quad1, quad2, quad3, quad4, port, retval, client_addr_len; + struct sockaddr_in srv, client_addr; + struct ip_mreq mreq; + fd_set readsckts; + struct hostent *server_hostent; + + strcpy((char *) main_server->process->argv[0], "GridSiteCast UDP responder"); + + /* initialise unicast/replies socket first */ + + bzero(&srv, sizeof(srv)); + srv.sin_family = AF_INET; + srv.sin_port = htons(sitecastgroups[0].port); + + if ((server_hostent = gethostbyname(main_server->server_hostname)) == NULL) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast UDP Responder fails to look up servername %s", + main_server->server_hostname); + return; + } + + srv.sin_addr.s_addr = (u_int32_t) (server_hostent->h_addr_list[0][0]); + + if (((sitecastgroups[0].socket + = socket(AF_INET, SOCK_DGRAM, 0)) < 0) || + (bind(sitecastgroups[0].socket, + (struct sockaddr *) &srv, sizeof(srv)) < 0)) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "mod_gridsite: sitecast responder fails on unicast bind (%s)", + strerror(errno)); + return; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast UDP unicast/replies on %d.%d.%d.%d:%d", + server_hostent->h_addr_list[0][0], + server_hostent->h_addr_list[0][1], + server_hostent->h_addr_list[0][2], + server_hostent->h_addr_list[0][3], + sitecastgroups[0].port); + + /* initialise multicast listener sockets next */ + + for (i=1; (i <= GRST_SITECAST_GROUPS) && + (sitecastgroups[i].port != 0); ++i) + { + bzero(&srv, sizeof(srv)); + srv.sin_family = AF_INET; + srv.sin_port = htons(sitecastgroups[i].port); + srv.sin_addr.s_addr = htonl(sitecastgroups[i].quad1*0x1000000 + + sitecastgroups[i].quad2*0x10000 + + sitecastgroups[i].quad3*0x100 + + sitecastgroups[i].quad4); + + if (((sitecastgroups[i].socket + = socket(AF_INET, SOCK_DGRAM, 0)) < 0) || + (bind(sitecastgroups[i].socket, + (struct sockaddr *) &srv, sizeof(srv)) < 0)) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast UDP Responder fails on multicast bind (%s)", + strerror(errno)); + return; + } + + bzero(&mreq, sizeof(mreq)); + mreq.imr_multiaddr.s_addr = srv.sin_addr.s_addr; + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if (setsockopt(sitecastgroups[i].socket, IPPROTO_IP, + IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_server, + "SiteCast UDP Responder fails on setting multicast"); + return; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast UDP Responder listening on %d.%d.%d.%d:%d", + sitecastgroups[i].quad1, sitecastgroups[i].quad2, + sitecastgroups[i].quad3, sitecastgroups[i].quad4, sitecastgroups[i].port); + } + + while (1) /* **** main listening loop **** */ + { + /* set up bitmasks for select */ + + FD_ZERO(&readsckts); + + n = 0; + for (i=0; (i <= GRST_SITECAST_GROUPS) && + (sitecastgroups[i].port != 0); ++i) /* reset bitmask */ + { + FD_SET(sitecastgroups[i].socket, &readsckts); + if (sitecastgroups[i].socket > n) n = sitecastgroups[i].socket; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast UDP Responder waiting for requests"); + + if ((retval = select(n + 1, &readsckts, NULL, NULL, NULL)) < 1) + continue; /* < 1 on timeout or error */ + + for (igroup=0; (igroup <= GRST_SITECAST_GROUPS) && + (sitecastgroups[igroup].port != 0); ++igroup) + { + if (FD_ISSET(sitecastgroups[igroup].socket, &readsckts)) + { + client_addr_len = sizeof(client_addr); + + if ((reqbuf_len = recvfrom(sitecastgroups[igroup].socket, + reqbuf, GRST_SITECAST_MAXBUF, 0, + (struct sockaddr *) &client_addr, &client_addr_len)) >= 0) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast receives UDP message from %s:%d " + "to %d.%d.%d.%d:%d", + inet_ntoa(client_addr.sin_addr), + ntohs(client_addr.sin_port), + sitecastgroups[igroup].quad1, + sitecastgroups[igroup].quad2, + sitecastgroups[igroup].quad3, + sitecastgroups[igroup].quad4, + sitecastgroups[igroup].port); + + sitecast_handle_request(main_server, reqbuf, + reqbuf_len, igroup, + &client_addr); + } + } + } + + } /* **** end of main listening loop **** */ +} + static int mod_gridsite_server_post_config(apr_pool_t *pPool, apr_pool_t *pLog, apr_pool_t *pTemp, server_rec *main_server) { SSL_CTX *ctx; SSLSrvConfigRec *sc; server_rec *this_server; + apr_proc_t *procnew = NULL; + apr_status_t status; + const char *userdata_key = "sitecast_init"; + + apr_pool_userdata_get((void **) &procnew, userdata_key, + main_server->process->pool); + + /* we only fork responder if one not already forked and we have at + least one GridSiteCastAlias defined. This means it is possible + to run a responder with no groups - listening on unicast only! */ + + if ((procnew == NULL) && + (sitecastaliases[0].sitecast_url != NULL)) + { + /* UDP multicast responder required but not yet started */ + + procnew = apr_pcalloc(main_server->process->pool, sizeof(*procnew)); + apr_pool_userdata_set((const void *) procnew, userdata_key, + apr_pool_cleanup_null, main_server->process->pool); + + status = apr_proc_fork(procnew, pPool); + + if (status < 0) + { + ap_log_error(APLOG_MARK, APLOG_CRIT, status, main_server, + "mod_gridsite: Failed to spawn SiteCast responder process"); + return HTTP_INTERNAL_SERVER_ERROR; + } + else if (status == APR_INCHILD) + { + ap_log_error(APLOG_MARK, APLOG_NOTICE, status, main_server, + "mod_gridsite: Spawning SiteCast responder process"); + sitecast_responder(main_server); + exit(-1); + } + + apr_pool_note_subprocess(main_server->process->pool, + procnew, APR_KILL_AFTER_TIMEOUT); + } + + /* continue with normal HTTP/HTTPS servers */ ap_add_version_component(pPool, apr_psprintf(pPool, "mod_gridsite/%s", VERSION)); @@ -2565,6 +3053,8 @@ static int mod_gridsite_server_post_config(apr_pool_t *pPool, this_server != NULL; this_server = this_server->next) { + /* we do some GridSite OpenSSL magic for HTTPS servers */ + sc = ap_get_module_config(this_server->module_config, &ssl_module); if ((sc != NULL) && @@ -2676,7 +3166,7 @@ module AP_MODULE_DECLARE_DATA gridsite_module = create_gridsite_dir_config, /* dir config creater */ merge_gridsite_dir_config, /* dir merger */ create_gridsite_srv_config, /* create server config */ - merge_gridsite_srv_config, /* merge server config */ + NULL, /* merge server config */ mod_gridsite_cmds, /* command apr_table_t */ register_hooks /* register hooks */ }; -- 1.8.2.3