From 1b1dd23d801dd48f4c8ae47aeb7acb58e5046017 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Wed, 15 Apr 2009 13:24:17 +0000 Subject: [PATCH] Major merging of public/private divergences --- org.gridsite.core/CHANGES | 3 + org.gridsite.core/interface/gridsite.h | 6 + org.gridsite.core/src/grst_admin.h | 5 + org.gridsite.core/src/grst_admin_file.c | 214 ++++++++++++++++++------- org.gridsite.core/src/grst_admin_gacl.c | 32 +++- org.gridsite.core/src/mod_gridsite.c | 269 +++++++++++++++++++++++++++++--- org.gridsite.core/src/mod_ssl-private.h | 64 ++++++++ 7 files changed, 510 insertions(+), 83 deletions(-) diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES index 29e76d1..b0a6de9 100644 --- a/org.gridsite.core/CHANGES +++ b/org.gridsite.core/CHANGES @@ -1,3 +1,6 @@ +* Thu Jan 29 2009 Andrew McNab +- Merge in private version changes from Yibiao Li. +- Merge in major 1.7.x vs 1.5.x divergences. * Fri Feb 8 2008 Andrew McNab - ==== GridSite version 1.7.0 ==== * Thu Nov 15 2007 Andrew McNab diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h index cf5a056..10da0a7 100644 --- a/org.gridsite.core/interface/gridsite.h +++ b/org.gridsite.core/interface/gridsite.h @@ -437,3 +437,9 @@ 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); + +#ifndef GRST_PASSCODE_JS +//#define __GRST_PASSCODE_JS__ +#define GRST_PASSCODE_JS "" +#endif + diff --git a/org.gridsite.core/src/grst_admin.h b/org.gridsite.core/src/grst_admin.h index cddc415..5b5a0a1 100644 --- a/org.gridsite.core/src/grst_admin.h +++ b/org.gridsite.core/src/grst_admin.h @@ -55,3 +55,8 @@ void del_cred_sure(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_u //void error(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file, GRSThttpBody *bp); +//functions for cgi program +int verifypasscode(); +void outputformactionerror(char *dn, GRSTgaclPerm perm, char *help_uri, + char *dir_path, char *dir_uri, char *admin_file); + diff --git a/org.gridsite.core/src/grst_admin_file.c b/org.gridsite.core/src/grst_admin_file.c index a9071c2..66fd13b 100644 --- a/org.gridsite.core/src/grst_admin_file.c +++ b/org.gridsite.core/src/grst_admin_file.c @@ -16,22 +16,22 @@ 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. +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.gridsite.org/ * - *------------------------------------------------------------------*/ +* This program is part of GridSite: http://www.gridsite.org/ * +*------------------------------------------------------------------*/ #ifndef VERSION #define VERSION "x.x.x" @@ -57,6 +57,46 @@ #include "grst_admin.h" +//char *GRST_PASSCODE_JS = ""; + + +int verifypasscode() +{ + char *issuedpc=NULL, *returnedpc=NULL; + issuedpc = getenv("GRST_PASSCODE_COOKIE"); + returnedpc = GRSThttpGetCGI("passcode"); +// GRSThttpError(issuedpc); + if( issuedpc==NULL )return 0; + if( returnedpc==NULL )return 0; + if( strcmp( issuedpc, returnedpc )==0 )return 1; + else return 0; +} + +void outputformactionerror(char *dn, GRSTgaclPerm perm, char *help_uri, + char *dir_path, char *dir_uri, char *admin_file) +{ + GRSThttpBody bp; + puts("Status: 500 Failed trying to upload\nContent-Type: text/html"); + GRSThttpBodyInit(&bp); + + GRSThttpPrintf(&bp,"Forbidden operation\n"); + GRSThttpPrintHeader(&bp, dir_path); + + GRSThttpPrintf(&bp, "

Forbidden operation

\n"); + + GRSThttpPrintf(&bp,"

" + "Return to " + "directory listing\n", dir_uri, admin_file); + + if (GRSTgaclPermHasList(perm)) + adminfooter(&bp, dn, help_uri, dir_uri, admin_file); + else adminfooter(&bp, dn, help_uri, dir_uri, NULL); + GRSThttpPrintFooter(&bp, dir_path); + + GRSThttpWriteOut(&bp); + return; +} + char *storeuploadfile(char *boundary, int *bufferused) { // rewrite this to copy whole POSTed stdin HTTP body to disk then @@ -112,6 +152,10 @@ void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, #define MIMESTUPLOAD 2 #define MIMESTFILENM 3 + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); p = getenv("CONTENT_TYPE"); @@ -264,6 +308,12 @@ void deletefileaction(char *dn, GRSTgaclPerm perm, char *help_uri, struct dirent *subdirfile_ent; DIR *subDIR; + + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } + if ((file[0] == '\0') || ((strcmp(file, GRST_ACL_FILE) != 0) && !GRSTgaclPermHasWrite(perm)) || ((strcmp(file, GRST_ACL_FILE) == 0) && !GRSTgaclPermHasAdmin(perm))) @@ -378,46 +428,50 @@ void deletefileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintHeader(&bp, dir_path); GRSThttpPrintf(&bp, "

Delete %s

\n", file); + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); + GRSThttpPrintf(&bp,"\n",dir_uri,admin_file); GRSThttpPrintf(&bp,"

Do you really want to delete %s?", file); - GRSThttpPrintf(&bp,"

\n", file); - GRSThttpPrintf(&bp,"\n", file); - GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"
\n"); +GRSThttpPrintf(&bp,"

\n", file); +GRSThttpPrintf(&bp,"\n", file); +GRSThttpPrintf(&bp,"\n"); +GRSThttpPrintf(&bp,"\n"); +GRSThttpPrintf(&bp,"\n"); - GRSThttpPrintf(&bp,"

Or " - "return to " - "directory listing\n", dir_uri, admin_file); - - adminfooter(&bp, dn, help_uri, dir_uri, admin_file); - GRSThttpPrintFooter(&bp, dir_path); +GRSThttpPrintf(&bp,"

Or " + "return to " + "directory listing\n", dir_uri, admin_file); - GRSThttpWriteOut(&bp); +adminfooter(&bp, dn, help_uri, dir_uri, admin_file); +GRSThttpPrintFooter(&bp, dir_path); + +GRSThttpWriteOut(&bp); } void renameform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, - char *file, char *dir_uri, char *admin_file) + char *file, char *dir_uri, char *admin_file) { - GRSThttpBody bp; +GRSThttpBody bp; - if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); +if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); - puts("Status: 200 OK\nContent-Type: text/html"); - - GRSThttpBodyInit(&bp); +puts("Status: 200 OK\nContent-Type: text/html"); - GRSThttpPrintf(&bp, "Rename %s\n", file); +GRSThttpBodyInit(&bp); - GRSThttpPrintHeader(&bp, dir_path); +GRSThttpPrintf(&bp, "Rename %s\n", file); - GRSThttpPrintf(&bp, "

Rename %s%s

\n", dir_uri, file); - - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); +GRSThttpPrintHeader(&bp, dir_path); + +GRSThttpPrintf(&bp, "

Rename %s%s

\n", dir_uri, file); +GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); + +GRSThttpPrintf(&bp,"\n",dir_uri,admin_file); GRSThttpPrintf(&bp,"

What do you want to rename %s to?

", file); GRSThttpPrintf(&bp,"\n", file); + GRSThttpPrintf(&bp,"\n"); GRSThttpPrintf(&bp,"

New name: \n", file); - GRSThttpPrintf(&bp,"\n"); + GRSThttpPrintf(&bp,"\n"); GRSThttpPrintf(&bp,"

\n"); @@ -439,6 +493,11 @@ void editfileaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, FILE *fp; GRSThttpBody bp; + + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if ((file[0] == '\0') || !GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) GRSThttpError("403 Forbidden"); @@ -516,6 +575,10 @@ void create_acl(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, FILE *fp; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError("403 Forbidden"); asprintf(&tmpgacl, "%s/.tmp.XXXXXX", dir_path); @@ -575,6 +638,10 @@ void renameaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, FILE *fp; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) GRSThttpError("403 Forbidden"); @@ -653,6 +720,10 @@ void newdirectory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, FILE *fp; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if ((file[0] == '\0') || !GRSTgaclPermHasWrite(perm) || (strcmp(file, GRST_ACL_FILE) == 0)) GRSThttpError("403 Forbidden"); @@ -710,6 +781,10 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat struct stat statbuf; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasWrite(perm)) GRSThttpError("403 Forbidden"); dnlistsuri = getenv("GRST_DN_LISTS_URI"); @@ -1022,15 +1097,18 @@ void ziplist(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, pclose(fp); GRSThttpPrintf(&bp, "\n"); - if (GRSTgaclPermHasWrite(perm)) + if (GRSTgaclPermHasWrite(perm)){ + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); GRSThttpPrintf(&bp, - "

" - " in %s" + "

" + " in %s" "" + "" "" "

(All files are placed in the same directory and files " "beginning with "." are ignored.)

\n", dir_uri, admin_file, dir_uri, file); + } } else GRSThttpPrintf(&bp, "

unzip path not defined!\n"); @@ -1129,10 +1207,12 @@ void editfileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintHeader(&bp, dir_path); GRSThttpPrintf(&bp, "

Edit file %s

\n", file); + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); + GRSThttpPrintf(&bp,"\n",dir_uri,admin_file); + GRSThttpPrintf(&bp,"

\n"); GRSThttpPrintf(&bp,"

File name: \n", file); + GRSThttpPrintf(&bp,"\n"); GRSThttpPrintf(&bp,"\n"); GRSThttpPrintf(&bp,"

\n"); - GRSThttpPrintf(&bp, "

\n"); + GRSThttpPrintf(&bp, "

\n"); + GRSThttpPrintf(&bp, "

\n"); if (fp != NULL) fclose(fp); @@ -1226,11 +1307,13 @@ void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintHeader(&bp, dir_path); GRSThttpPrintf(&bp, "

Edit DN List

\n"); + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); - GRSThttpPrintf(&bp,"
\n",dir_uri,admin_file); - GRSThttpPrintf(&bp,"

\n"); + GRSThttpPrintf(&bp,"\n",dir_uri,admin_file); + GRSThttpPrintf(&bp,"

\n"); GRSThttpPrintf(&bp,"

List URL: \n", file, strlen(file)); + GRSThttpPrintf(&bp,"\n"); GRSThttpPrintf(&bp,"\n"); if (fp != NULL) @@ -1258,7 +1341,7 @@ void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintf(&bp, "

Add new DN: \n"); - GRSThttpPrintf(&bp,"

\n"); + GRSThttpPrintf(&bp,"

\n"); GRSThttpPrintf(&bp, "

\n"); if (fp != NULL) fclose(fp); @@ -1347,11 +1430,14 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, GRSThttpPrintf(&bp, " \n"); } - else if (GRSTgaclPermHasAdmin(perm)) - GRSThttpPrintf(&bp, "
\n" - "\n" + else if (GRSTgaclPermHasAdmin(perm)){ + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); + GRSThttpPrintf(&bp, "\n" + "\n" + "" "
\n", dir_uri, admin_file); + } } if (GRSTgaclPermHasList(perm)) @@ -1471,22 +1557,25 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, if (GRSTgaclPermHasWrite(perm)) { - GRSThttpPrintf(&bp, "
\n" + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); + GRSThttpPrintf(&bp, "\n" "
\n" "New name:" "\n" - "\n" - "\n" + "\n" + "\n" + "" "
\n", dir_uri, admin_file); GRSThttpPrintf(&bp, - "
\n" + "\n" "
\n" "Upload file:" "New name:" " " - "\n" + "" + "\n" "Local name:" "\n" "
\n", dir_uri, admin_file); @@ -1608,18 +1697,21 @@ void managednlists(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, unencuri, unencuri, statbuf.st_size, modified); + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); GRSThttpPrintf(&bp, - "
" - "" + "" + "" "" + "" "" "
\n", admin_file, unencuri); GRSThttpPrintf(&bp, - "
" - "" + "" + "" "" + "" "" "
\n", admin_file, unencuri); @@ -1635,11 +1727,13 @@ void managednlists(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, if (has_any_admin) { - GRSThttpPrintf(&bp, "
\n" + GRSThttpPrintf(&bp, "\n%s\n", GRST_PASSCODE_JS); + GRSThttpPrintf(&bp, "\n" "New DN list name: " "\n" + "" "" - "\n" + "\n" "
\n", admin_file, dnlistsprefix, strlen(dnlistsprefix)+8); } diff --git a/org.gridsite.core/src/grst_admin_gacl.c b/org.gridsite.core/src/grst_admin_gacl.c index 37aabc2..249b94e 100644 --- a/org.gridsite.core/src/grst_admin_gacl.c +++ b/org.gridsite.core/src/grst_admin_gacl.c @@ -47,6 +47,10 @@ extern int grst_perm_vals[]; #include "grst_admin.h" +//char *GRST_PASSCODE_JS1 = ""; + + + // CGI GACL Editor interface functions 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); void new_entry_form(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, char *file, char *dir_uri, char *admin_file); @@ -210,6 +214,12 @@ void new_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, GRSTgaclCred *cred; char *cred_auri_1, *p; GRSThttpBody bp; + + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } + if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); // Get new credential info and perform checks @@ -251,6 +261,10 @@ void del_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, GRSTgaclEntry *previous, *entry; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); // Load the ACL @@ -343,6 +357,10 @@ void edit_entry(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, char variable[30], *cred_auri_i, *p; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); // Load the ACL @@ -470,6 +488,10 @@ void add_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, c GRSThttpBody bp; char *cred_auri_1, *p; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path));// Load the ACL @@ -515,6 +537,10 @@ void del_cred(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *help_uri, c GRSTgaclCred *previous, *cred; GRSThttpBody bp; + if( verifypasscode()==0 ){ + outputformactionerror(dn, perm, help_uri, dir_path, dir_uri, admin_file); + return; + } if (!GRSTgaclPermHasAdmin(perm)) GRSThttpError ("403 Forbidden"); acl = GRSTgaclAclLoadFile(GRSTgaclFileFindAclname(dir_path)); @@ -773,9 +799,13 @@ void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path){ void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function){ // Starts an HTML form with gridsite admin as the target and target_function as the value of cmd. // Also inputs the dir_uri and the timestamp - GRSThttpPrintf (bp, "
\n", dir_uri, admin_file, dir_uri); + GRSThttpPrintf (bp, "\n%s\n", GRST_PASSCODE_JS); +// GRSThttpPrintf (bp, "\n%s\n", GRST_PASSCODE_JS1); +// GRSThttpPrintf (bp, "\n", target_function, dir_uri, admin_file, dir_uri); //please note that we use targetfunction here to dentify the forms + GRSThttpPrintf (bp, "\n", target_function, dir_uri, admin_file, dir_uri, target_function); //please note that we use targetfunction here to dentify the forms GRSThttpPrintf (bp, " \n", target_function); GRSThttpPrintf (bp, " \n", timestamp); + GRSThttpPrintf (bp, " \n"); return; } diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index 6988b2c..6379bb9 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2003-8, Andrew McNab, Shiv Kaushal, Joseph Dada, + Copyright (c) 2003-9, Andrew McNab, Shiv Kaushal, Joseph Dada, and Yibiao Li, University of Manchester. All rights reserved. Redistribution and use in source and binary forms, with or @@ -71,6 +71,13 @@ #include #include #include + +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#endif + #include #include @@ -126,11 +133,17 @@ char *ocspmodes = NULL; struct sitecast_group sitecastgroups[GRST_SITECAST_GROUPS+1]; struct sitecast_alias sitecastaliases[GRST_SITECAST_ALIASES]; +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +/* SSL_app_data2_idx is private in Apache 2.2 mod_ssl but can be + determined at init time, and then recorded here */ +int GRST_SSL_app_data2_idx = -1; +#endif + typedef struct { int auth; int autopasscode; - int requirepasscode; + int requirepasscode; int zoneslashes; int envs; int format; @@ -149,7 +162,7 @@ typedef struct char *methods; char *editable; char *headfile; - char *footfile; + char *footfile; int gridhttp; char *aclformat; char *aclpath; @@ -312,9 +325,9 @@ char *make_admin_footer(request_rec *r, mod_gridsite_dir_cfg *conf, out = apr_pstrcat(r->pool, out, "
", NULL); - if (r->notes != NULL) + if (r->connection->notes != NULL) { - grst_cred_auri_0 = (char *) + grst_cred_auri_0 = (char *) apr_table_get(r->notes, "GRST_CRED_AURI_0"); } @@ -1765,7 +1778,7 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver, if (direct->loginuri != NULL) conf->loginuri = direct->loginuri; else conf->loginuri = server->loginuri; - + if (direct->dnlists != NULL) conf->dnlists = direct->dnlists; else conf->dnlists = server->dnlists; @@ -1919,11 +1932,6 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, ((mod_gridsite_dir_cfg *) cfg)->helpuri = apr_pstrdup(a->pool, parm); } - else if (strcasecmp(a->cmd->name, "GridSiteLoginURI") == 0) - { - ((mod_gridsite_dir_cfg *) cfg)->loginuri = - apr_pstrdup(a->pool, parm); - } else if (strcasecmp(a->cmd->name, "GridSiteDNlists") == 0) { ((mod_gridsite_dir_cfg *) cfg)->dnlists = @@ -2880,7 +2888,6 @@ static int mod_gridsite_perm_handler(request_rec *r) /* if not succeeded from passcode file, try from connection notes if a GSI Proxy or have GridSiteAutoPasscode on (the default) - or have GridSiteRequirePasscode off (the default). If GridSiteAutoPasscode off and GridSiteRequirePasscode on then interactive websites must use a login script to make passcode and file instead. @@ -3214,7 +3221,7 @@ static int mod_gridsite_perm_handler(request_rec *r) cred = user->firstcred; if ((cred != NULL) && (strncmp(cred->auri, "dn:", 3) == 0)) { - apr_table_setn(r->notes, "GRST_CRED_AURI_0", + apr_table_setn(r->notes, "GRST_CRED_AURI_0", apr_psprintf(r->pool, "%s", cred->auri)); } @@ -3246,6 +3253,10 @@ static int mod_gridsite_perm_handler(request_rec *r) apr_table_setn(env, "GRST_PERM", apr_psprintf(r->pool, "%d", perm)); + if (((mod_gridsite_dir_cfg *) cfg)->requirepasscode == 0) + apr_table_set(env, "GRST_REQUIRE_PASSCODE", "off"); + else apr_table_set(env, "GRST_REQUIRE_PASSCODE", "on"); + if (((dir_path = apr_pstrdup(r->pool, r->filename)) != NULL) && ((p = rindex(dir_path, '/')) != NULL)) { @@ -3462,23 +3473,227 @@ int GRST_verify_cert_wrapper(X509_STORE_CTX *ctx, void *p) return X509_verify_cert(ctx); } +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +/* + Include this here until libgridsite functions can be used +*/ +int GRST_ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) +{ + server_rec *s = c->base_server; + SSLSrvConfigRec *sc = (SSLSrvConfigRec *) ap_get_module_config(s->module_config, &ssl_module); + SSLConnRec *sslconn = (SSLConnRec *) ap_get_module_config(c->conn_config, &ssl_module); + modssl_ctx_t *mctx = sslconn->is_proxy ? sc->proxy : sc->server; + X509_OBJECT obj; + X509_NAME *subject, *issuer; + X509 *cert; + X509_CRL *crl; + EVP_PKEY *pubkey; + int i, n, rc; + + /* + * Unless a revocation store for CRLs was created we + * cannot do any CRL-based verification, of course. + */ + if (!mctx->crl) { + return ok; + } + + /* + * Determine certificate ingredients in advance + */ + cert = X509_STORE_CTX_get_current_cert(ctx); + subject = X509_get_subject_name(cert); + issuer = X509_get_issuer_name(cert); + + /* + * OpenSSL provides the general mechanism to deal with CRLs but does not + * use them automatically when verifying certificates, so we do it + * explicitly here. We will check the CRL for the currently checked + * certificate, if there is such a CRL in the store. + * + * We come through this procedure for each certificate in the certificate + * chain, starting with the root-CA's certificate. At each step we've to + * both verify the signature on the CRL (to make sure it's a valid CRL) + * and it's revocation list (to make sure the current certificate isn't + * revoked). But because to check the signature on the CRL we need the + * public key of the issuing CA certificate (which was already processed + * one round before), we've a little problem. But we can both solve it and + * at the same time optimize the processing by using the following + * verification scheme (idea and code snippets borrowed from the GLOBUS + * project): + * + * 1. We'll check the signature of a CRL in each step when we find a CRL + * through the _subject_ name of the current certificate. This CRL + * itself will be needed the first time in the next round, of course. + * But we do the signature processing one round before this where the + * public key of the CA is available. + * + * 2. We'll check the revocation list of a CRL in each step when + * we find a CRL through the _issuer_ name of the current certificate. + * This CRLs signature was then already verified one round before. + * + * This verification scheme allows a CA to revoke its own certificate as + * well, of course. + */ + + /* + * Try to retrieve a CRL corresponding to the _subject_ of + * the current certificate in order to verify it's integrity. + */ + memset((char *)&obj, 0, sizeof(obj)); + { + X509_STORE_CTX pStoreCtx; + X509_STORE_CTX_init(&pStoreCtx, mctx->crl, NULL, NULL); + rc = X509_STORE_get_by_subject(&pStoreCtx, X509_LU_CRL, subject, &obj); + X509_STORE_CTX_cleanup(&pStoreCtx); + } + + crl = obj.data.crl; + + if ((rc > 0) && crl) { + /* + * Log information about CRL + * (A little bit complicated because of ASN.1 and BIOs...) + */ + if (s->loglevel >= APLOG_DEBUG) { + char buff[512]; /* should be plenty */ + BIO *bio = BIO_new(BIO_s_mem()); + + BIO_printf(bio, "CA CRL: Issuer: "); + X509_NAME_print(bio, issuer, 0); + + BIO_printf(bio, ", lastUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); + + BIO_printf(bio, ", nextUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); + + n = BIO_read(bio, buff, sizeof(buff) - 1); + buff[n] = '\0'; + + BIO_free(bio); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", buff); + } + + /* + * Verify the signature on this CRL + */ + pubkey = X509_get_pubkey(cert); + rc = X509_CRL_verify(crl, pubkey); +#ifdef OPENSSL_VERSION_NUMBER + /* Only refcounted in OpenSSL */ + if (pubkey) + EVP_PKEY_free(pubkey); +#endif + if (rc <= 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Invalid signature on CRL"); + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + + /* + * Check date of CRL to make sure it's not expired + */ + i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); + + if (i == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Found CRL has invalid nextUpdate field"); + + X509_STORE_CTX_set_error(ctx, + X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + + if (i < 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "Found CRL is expired - " + "revoking all certificates until you get updated CRL"); + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + + X509_OBJECT_free_contents(&obj); + } + + /* + * Try to retrieve a CRL corresponding to the _issuer_ of + * the current certificate in order to check for revocation. + */ + memset((char *)&obj, 0, sizeof(obj)); + { + X509_STORE_CTX pStoreCtx; + X509_STORE_CTX_init(&pStoreCtx, mctx->crl, NULL, NULL); + rc = X509_STORE_get_by_subject(&pStoreCtx, X509_LU_CRL, issuer, &obj); + X509_STORE_CTX_cleanup(&pStoreCtx); + } + + crl = obj.data.crl; + if ((rc > 0) && crl) { + /* + * Check if the current certificate is revoked by this CRL + */ + n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); + + for (i = 0; i < n; i++) { + X509_REVOKED *revoked = + sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); + +// ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked); + ASN1_INTEGER *sn = revoked->serialNumber; + + if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { + if (s->loglevel >= APLOG_DEBUG) { + char *cp = X509_NAME_oneline(issuer, NULL, 0); + long serial = ASN1_INTEGER_get(sn); + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, + "Certificate with serial %ld (0x%lX) " + "revoked per CRL from issuer %s", + serial, serial, cp); + OPENSSL_free(cp); + } + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); + X509_OBJECT_free_contents(&obj); + + return FALSE; + } + } + + X509_OBJECT_free_contents(&obj); + } + + return ok; +} +#endif + int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) { SSL *ssl = (SSL *) X509_STORE_CTX_get_app_data(ctx); conn_rec *conn = (conn_rec *) SSL_get_app_data(ssl); server_rec *s = conn->base_server; SSLConnRec *sslconn = - (SSLConnRec *) ap_get_module_config(conn->conn_config, &ssl_module); + (SSLConnRec *) ap_get_module_config(conn->conn_config, &ssl_module); int errnum = X509_STORE_CTX_get_error(ctx); int errdepth = X509_STORE_CTX_get_error_depth(ctx); int returned_ok; int first_non_ca; #if AP_MODULE_MAGIC_AT_LEAST(20051115,0) - request_rec *r = (request_rec *)SSL_get_app_data2(ssl); - SSLSrvConfigRec *sc = mySrvConfig(s); - SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; - modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); - int verify; + request_rec *r = (request_rec *) SSL_get_ex_data(ssl, GRST_SSL_app_data2_idx); + SSLSrvConfigRec *sc = (SSLSrvConfigRec *) ap_get_module_config(s->module_config, &ssl_module); + SSLDirConfigRec *dc = r ? (SSLDirConfigRec *) ap_get_module_config(r->per_dir_config, &ssl_module) : NULL; + modssl_ctx_t *mctx = sslconn->is_proxy ? sc->proxy : sc->server; + int verify, depth; #endif STACK_OF(X509) *certstack; GRSTx509Chain *grst_chain; @@ -3500,9 +3715,9 @@ int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) sname ? sname : "-unknown-", iname ? iname : "-unknown-"); - if (sname) modssl_free(sname); + if (sname) OPENSSL_free(sname); - if (iname) modssl_free(iname); + if (iname) OPENSSL_free(iname); } /* @@ -3544,7 +3759,7 @@ int GRST_callback_SSLVerify_wrapper(int ok, X509_STORE_CTX *ctx) */ if (ok) { - if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) + if (!(ok = GRST_ssl_callback_SSLVerify_CRL(ok, ctx, conn))) { errnum = X509_STORE_CTX_get_error(ctx); } @@ -4061,6 +4276,16 @@ static int mod_gridsite_server_post_config(apr_pool_t *pPool, ap_add_version_component(pPool, apr_psprintf(pPool, "mod_gridsite/%s", VERSION)); +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) + /* establish value of SSL_app_data2_idx and record it */ + GRST_SSL_app_data2_idx = SSL_get_ex_new_index(0, + "Dummy Application Data for mod_gridsite", + NULL, NULL, NULL) - 1; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "mod_gridsite: GRST_SSL_app_data2_idx=%d", + GRST_SSL_app_data2_idx); +#endif + for (this_server = main_server; this_server != NULL; this_server = this_server->next) diff --git a/org.gridsite.core/src/mod_ssl-private.h b/org.gridsite.core/src/mod_ssl-private.h index f8d3647..f4d3582 100644 --- a/org.gridsite.core/src/mod_ssl-private.h +++ b/org.gridsite.core/src/mod_ssl-private.h @@ -85,6 +85,24 @@ typedef enum { SSL_ENABLED_OPTIONAL = 3 } ssl_enabled_t; +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +typedef enum { + SSL_CVERIFY_UNSET = -1, + SSL_CVERIFY_NONE = 0, + SSL_CVERIFY_OPTIONAL = 1, + SSL_CVERIFY_REQUIRE = 2, + SSL_CVERIFY_OPTIONAL_NO_CA = 3 +} ssl_verify_t; + +#define ssl_verify_error_is_optional(errnum) \ + ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) \ + || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) \ + || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) \ + || (errnum == X509_V_ERR_CERT_UNTRUSTED) \ + || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) + +#endif + typedef struct { SSL *ssl; const char *client_dn; @@ -98,9 +116,38 @@ typedef struct { int non_ssl_request; } SSLConnRec; +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +typedef struct { + const char *ca_cert_path; + const char *ca_cert_file; + + const char *cipher_suite; + + int verify_depth; + ssl_verify_t verify_mode; +} modssl_auth_ctx_t; +#endif + typedef struct { void *sc; /* pointer back to server config */ SSL_CTX *ssl_ctx; +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) + void *pks; + void *pkp; + + int protocol; + + int pphrase_dialog_type; + const char *pphrase_dialog_path; + + const char *cert_chain; + + const char *crl_path; + const char *crl_file; + X509_STORE *crl; + + modssl_auth_ctx_t auth; +#endif } modssl_ctx_t; typedef struct { @@ -117,4 +164,21 @@ typedef struct { modssl_ctx_t *proxy; } SSLSrvConfigRec; +#if AP_MODULE_MAGIC_AT_LEAST(20051115,0) +typedef struct { + BOOL bSSLRequired; + apr_array_header_t *aRequirement; + int nOptions; + int nOptionsAdd; + int nOptionsDel; + const char *szCipherSuite; + ssl_verify_t nVerifyClient; + int nVerifyDepth; + const char *szCACertificatePath; + const char *szCACertificateFile; + const char *szUserName; +} SSLDirConfigRec; +#endif + + extern module AP_MODULE_DECLARE_DATA ssl_module; -- 1.8.2.3