diff options
Diffstat (limited to 'www/lynx/patches.v6/patch-ad')
-rw-r--r-- | www/lynx/patches.v6/patch-ad | 646 |
1 files changed, 646 insertions, 0 deletions
diff --git a/www/lynx/patches.v6/patch-ad b/www/lynx/patches.v6/patch-ad new file mode 100644 index 00000000000..418ecce598b --- /dev/null +++ b/www/lynx/patches.v6/patch-ad @@ -0,0 +1,646 @@ +$NetBSD: patch-ad,v 1.1 2000/01/15 17:44:21 hubertf Exp $ + +Place(s) where this was (most probably...) in before: + +diff -x *.orig -urN ./WWW/Library/Implementation/HTAAServ.c /usr/pkgsrc/www/lynx/work.unpatched/lynx2-8-2/WWW/Library/Implementation/HTAAServ.c +--- ./WWW/Library/Implementation/HTAAServ.c Thu Jan 1 01:00:00 1970 ++++ /usr/pkgsrc/www/lynx/work.unpatched/lynx2-8-2/WWW/Library/Implementation/HTAAServ.c Sat Jan 15 07:57:17 2000 +@@ -0,0 +1,638 @@ ++ ++/* MODULE HTAAServ.c ++** SERVER SIDE ACCESS AUTHORIZATION MODULE ++** ++** Contains the means for checking the user access ++** authorization for a file. ++** ++** IMPORTANT: ++** Routines in this module use dynamic allocation, but free ++** automatically all the memory reserved by them. ++** ++** Therefore the caller never has to (and never should) ++** free() any object returned by these functions. ++** ++** Therefore also all the strings returned by this package ++** are only valid until the next call to the same function ++** is made. This approach is selected, because of the nature ++** of access authorization: no string returned by the package ++** needs to be valid longer than until the next call. ++** ++** This also makes it easy to plug the AA package in: ++** you don't have to ponder whether to free() something ++** here or is it done somewhere else (because it is always ++** done somewhere else). ++** ++** The strings that the package needs to store are copied ++** so the original strings given as parameters to AA ++** functions may be freed or modified with no side effects. ++** ++** The AA package does not free() anything else than what ++** it has itself allocated. ++** ++** AUTHORS: ++** AL Ari Luotonen luotonen@dxcern.cern.ch ++** ++** HISTORY: ++** ++** ++** BUGS: ++** ++** ++*/ ++ ++#include <HTUtils.h> ++ ++#include <HTString.h> ++#include <HTAccess.h> /* HTSecure */ ++#include <HTFile.h> /* HTLocalName */ ++#include <HTRules.h> /* */ ++#include <HTParse.h> /* URL parsing function */ ++#include <HTList.h> /* HTList object */ ++ ++#include <HTAAUtil.h> /* AA common parts */ ++#include <HTAuth.h> /* Authentication */ ++#include <HTACL.h> /* Access Control List */ ++#include <HTGroup.h> /* Group handling */ ++#include <HTAAProt.h> /* Protection file parsing */ ++#include <HTAAServ.h> /* Implemented here */ ++ ++#include <LYLeaks.h> ++ ++/* ++** Global variables ++*/ ++PUBLIC time_t theTime; ++ ++ ++/* ++** Module-wide global variables ++*/ ++PRIVATE FILE * htaa_logfile = NULL; /* Log file */ ++PRIVATE HTAAUser *htaa_user = NULL; /* Authenticated user */ ++PRIVATE HTAAFailReasonType HTAAFailReason = HTAA_OK; /* AA fail reason */ ++ ++ ++/* SERVER PUBLIC HTAA_statusMessage() ++** RETURN A STRING EXPLAINING ACCESS ++** AUTHORIZATION FAILURE ++** (Can be used in server reply status line ++** with 401/403 replies.) ++** ON EXIT: ++** returns a string containing the error message ++** corresponding to internal HTAAFailReason. ++*/ ++PUBLIC char *HTAA_statusMessage NOARGS ++{ ++ switch (HTAAFailReason) { ++ ++ /* 401 cases */ ++ case HTAA_NO_AUTH: ++ return "Unauthorized -- authentication failed"; ++ case HTAA_NOT_MEMBER: ++ return "Unauthorized to access the document"; ++ ++ /* 403 cases */ ++ case HTAA_BY_RULE: ++ return "Forbidden -- by rule"; ++ case HTAA_IP_MASK: ++ return "Forbidden -- server refuses to serve to your IP address"; ++ case HTAA_NO_ACL: ++ case HTAA_NO_ENTRY: ++ return "Forbidden -- access to file is never allowed"; ++ case HTAA_SETUP_ERROR: ++ return "Forbidden -- server protection setup error"; ++ case HTAA_DOTDOT: ++ return "Forbidden -- URL containing /../ disallowed"; ++ case HTAA_HTBIN: ++ return "Forbidden -- /htbin feature not enabled on this server"; ++ ++ /* 404 cases */ ++ case HTAA_NOT_FOUND: ++ return "Not found -- file doesn't exist or is read protected"; ++ ++ /* Success */ ++ case HTAA_OK: ++ return "AA: Access should be ok but something went wrong"; ++ ++ case HTAA_OK_GATEWAY: ++ return "AA check bypassed (gatewaying) but something went wrong"; ++ ++ /* Others */ ++ default: ++ return "Access denied -- unable to specify reason (bug)"; ++ ++ } /* switch */ ++} ++ ++ ++PRIVATE char *status_name ARGS1(HTAAFailReasonType, reason) ++{ ++ switch (reason) { ++ ++ /* 401 cases */ ++ case HTAA_NO_AUTH: ++ return "NO-AUTHENTICATION"; ++ case HTAA_NOT_MEMBER: ++ return "NOT-AUTHORIZED"; ++ ++ /* 403 cases */ ++ case HTAA_BY_RULE: ++ return "FORB-RULE"; ++ case HTAA_IP_MASK: ++ return "FORB-IP"; ++ case HTAA_NO_ACL: ++ return "NO-ACL-FILE"; ++ case HTAA_NO_ENTRY: ++ return "NO-ACL-ENTRY"; ++ case HTAA_SETUP_ERROR: ++ return "SETUP-ERROR"; ++ case HTAA_DOTDOT: ++ return "SLASH-DOT-DOT"; ++ case HTAA_HTBIN: ++ return "HTBIN-OFF"; ++ ++ /* 404 cases */ ++ case HTAA_NOT_FOUND: ++ return "NOT-FOUND"; ++ ++ /* Success */ ++ case HTAA_OK: ++ return "OK"; ++ case HTAA_OK_GATEWAY: ++ return "OK-GATEWAY"; ++ ++ /* Others */ ++ default: ++ return "SERVER-BUG"; ++ } /* switch */ ++} ++ ++ ++/* PRIVATE check_uthorization() ++** CHECK IF USER IS AUTHORIZED TO ACCESS A FILE ++** ON ENTRY: ++** pathname is the physical file pathname ++** to access. ++** method method, e.g. METHOD_GET, METHOD_PUT, ... ++** scheme authentication scheme. ++** scheme_specifics authentication string (or other ++** scheme specific parameters, like ++** Kerberos-ticket). ++** ++** ON EXIT: ++** returns HTAA_OK on success. ++** Otherwise the reason for failing. ++** NOTE: ++** This function does not check whether the file ++** exists or not -- so the status 404 Not found ++** must be returned from somewhere else (this is ++** to avoid unnecessary overhead of opening the ++** file twice). ++*/ ++PRIVATE HTAAFailReasonType check_authorization ARGS4(CONST char *, pathname, ++ HTAAMethod, method, ++ HTAAScheme, scheme, ++ char *, scheme_specifics) ++{ ++ HTAAFailReasonType reason; ++ GroupDef *allowed_groups; ++ FILE *acl_file = NULL; ++ HTAAProt *prot = NULL; /* Protection mode */ ++ ++ htaa_user = NULL; ++ ++ if (!pathname) { ++ CTRACE(tfp, "HTAA_checkAuthorization: Forbidden by rule\n"); ++ return HTAA_BY_RULE; ++ } ++ CTRACE(tfp, "%s `%s' %s %s\n", ++ "HTAA_checkAuthorization: translated path:", ++ pathname, "method:", HTAAMethod_name(method)); ++ ++ /* ++ ** Get protection setting (set up by callbacks from rule system) ++ ** NULL, if not protected by a "protect" rule. ++ */ ++ prot = HTAA_getCurrentProtection(); ++ ++ /* ++ ** Check ACL existence ++ */ ++ if (!(acl_file = HTAA_openAcl(pathname))) { ++ if (prot) { /* protect rule, but no ACL */ ++ if (prot->mask_group) { ++ /* ++ ** Only mask enabled, check that ++ */ ++ GroupDefList *group_def_list = ++ HTAA_readGroupFile(HTAssocList_lookup(prot->values, ++ "group")); ++ /* ++ ** Authenticate if authentication info given ++ */ ++ if (scheme != HTAA_UNKNOWN && scheme != HTAA_NONE) { ++ htaa_user = HTAA_authenticate(scheme, ++ scheme_specifics, ++ prot); ++ CTRACE(tfp, "Authentication returned: %s\n", ++ (htaa_user ? htaa_user->username ++ : "NOT-AUTHENTICATED")); ++ } ++ HTAA_resolveGroupReferences(prot->mask_group, group_def_list); ++ reason = HTAA_userAndInetInGroup(prot->mask_group, ++ htaa_user ++ ? htaa_user->username : "", ++ HTClientHost, ++ NULL); ++ if (reason != HTAA_OK) { ++ CTRACE(tfp, "%s %s %s %s\n", ++ "HTAA_checkAuthorization: access denied", ++ "by mask (no ACL, only Protect rule)", ++ "host", HTClientHost); ++ } else { ++ CTRACE(tfp, "%s %s %s %s\n", ++ "HTAA_checkAuthorization: request from", ++ HTClientHost, ++ "accepted by only mask match (no ACL, only", ++ "Protect rule, and only mask enabled)"); ++ } ++ return reason; ++ } ++ else { /* 403 Forbidden */ ++ CTRACE(tfp, "%s %s\n", ++ "HTAA_checkAuthorization: Protected, but", ++ "no mask group nor ACL -- forbidden"); ++ return HTAA_NO_ACL; ++ } ++ } ++ else { /* No protect rule and no ACL => OK 200 */ ++ CTRACE(tfp, "HTAA_checkAuthorization: %s\n", ++ "no protect rule nor ACL -- ok\n"); ++ return HTAA_OK; ++ } ++ } ++ ++ /* ++ ** Now we know that ACL exists ++ */ ++ if (!prot) { /* Not protected by "protect" rule */ ++ CTRACE(tfp, "HTAA_checkAuthorization: default protection\n"); ++ prot = HTAA_getDefaultProtection(); /* Also sets current protection */ ++ ++ if (!prot) { /* @@ Default protection not set ?? */ ++ CTRACE(tfp, "%s %s\n", ++ "HTAA_checkAuthorization: default protection", ++ "not set (internal server error)!!"); ++ return HTAA_SETUP_ERROR; ++ } ++ } ++ ++ /* ++ ** Now we know that document is protected and ACL exists. ++ ** Check against ACL entry. ++ */ ++ { ++ GroupDefList *group_def_list = ++ HTAA_readGroupFile(HTAssocList_lookup(prot->values, "group")); ++ ++ /* ++ ** Authenticate now that we know protection mode ++ */ ++ if (scheme != HTAA_UNKNOWN && scheme != HTAA_NONE) { ++ htaa_user = HTAA_authenticate(scheme, ++ scheme_specifics, ++ prot); ++ CTRACE(tfp, "Authentication returned: %s\n", ++ (htaa_user ++ ? htaa_user->username : "NOT-AUTHENTICATED")); ++ } ++ /* ++ ** Check mask group ++ */ ++ if (prot->mask_group) { ++ HTAA_resolveGroupReferences(prot->mask_group, group_def_list); ++ reason=HTAA_userAndInetInGroup(prot->mask_group, ++ htaa_user ? htaa_user->username : "", ++ HTClientHost, ++ NULL); ++ if (reason != HTAA_OK) { ++ CTRACE(tfp, "%s %s %s\n", ++ "HTAA_checkAuthorization: access denied", ++ "by mask, host:", HTClientHost); ++ return reason; ++ } ++ else { ++ CTRACE(tfp, "%s %s %s %s %s\n", ++ "HTAA_checkAuthorization: request from", ++ HTClientHost, ++ "accepted by just mask group match", ++ "(no ACL, only Protect rule, and only", ++ "mask enabled)"); ++ /* And continue authorization checking */ ++ } ++ } ++ /* ++ ** Get ACL entries; get first one first, the loop others ++ ** Remember, allowed_groups is automatically freed by ++ ** HTAA_getAclEntry(). ++ */ ++ allowed_groups = HTAA_getAclEntry(acl_file, pathname, method); ++ if (!allowed_groups) { ++ CTRACE(tfp, "%s `%s' %s\n", ++ "No entry for file", pathname, "in ACL"); ++ HTAA_closeAcl(acl_file); ++ return HTAA_NO_ENTRY; /* Forbidden -- no entry in the ACL */ ++ } ++ else { ++ do { ++ HTAA_resolveGroupReferences(allowed_groups, group_def_list); ++ reason = HTAA_userAndInetInGroup(allowed_groups, ++ htaa_user ++ ? htaa_user->username : "", ++ HTClientHost, ++ NULL); ++ if (reason == HTAA_OK) { ++ HTAA_closeAcl(acl_file); ++ return HTAA_OK; /* OK */ ++ } ++ allowed_groups = HTAA_getAclEntry(acl_file, pathname, method); ++ } while (allowed_groups); ++ HTAA_closeAcl(acl_file); ++ return HTAA_NOT_MEMBER; /* Unauthorized */ ++ } ++ } ++} ++ ++ ++/* PUBLIC HTAA_checkAuthorization() ++** CHECK IF USER IS AUTHORIZED TO ACCESS A FILE ++** ON ENTRY: ++** url is the document to be accessed. ++** method_name name of the method, e.g. "GET" ++** scheme_name authentication scheme name. ++** scheme_specifics authentication string (or other ++** scheme specific parameters, like ++** Kerberos-ticket). ++** ++** ON EXIT: ++** returns status codes uniform with those of HTTP: ++** 200 OK if file access is ok. ++** 401 Unauthorized if user is not authorized to ++** access the file. ++** 403 Forbidden if there is no entry for the ++** requested file in the ACL. ++** ++** NOTE: ++** This function does not check whether the file ++** exists or not -- so the status 404 Not found ++** must be returned from somewhere else (this is ++** to avoid unnecessary overhead of opening the ++** file twice). ++** ++*/ ++PUBLIC int HTAA_checkAuthorization ARGS4(CONST char *, url, ++ CONST char *, method_name, ++ CONST char *, scheme_name, ++ char *, scheme_specifics) ++{ ++ static char *pathname = NULL; ++ char *local_copy = NULL; ++ HTAAMethod method = HTAAMethod_enum(method_name); ++ HTAAScheme scheme = HTAAScheme_enum(scheme_name); ++ ++ HTAAFailReason = HTAA_OK; ++ ++ /* ++ ** Translate into absolute pathname, and ++ ** check for "protect" and "defprot" rules. ++ */ ++ FREE(pathname); /* From previous call */ ++ StrAllocCopy(local_copy, url); ++ { ++ char *keywords = strchr(local_copy, '?'); ++ if (keywords) ++ *keywords = '\0'; /* Chop off keywords */ ++ } ++ HTSimplify(local_copy); /* Remove ".." etc. */ ++ ++ /* HTSimplify will leave in a "/../" at the top, which can ++ ** be a security hole. ++ */ ++ if (strstr(local_copy, "/../")) { ++ CTRACE(tfp, "HTAA_checkAuthorization: %s (`%s')\n", ++ "Illegal attempt to use /../", url); ++ HTAAFailReason = HTAA_DOTDOT; ++ } ++ else { ++ pathname = HTTranslate(local_copy); /* Translate rules even if */ ++ /* a /htbin call to set up */ ++ /* protections. */ ++ if (0 == strncmp(local_copy, "/htbin/", 7)) { ++ if (!HTBinDir) ++ HTAAFailReason = HTAA_HTBIN; ++ else { ++ char *end = strchr(local_copy+7, '/'); ++ if (end) ++ *end = '\0'; ++ FREE(pathname); ++ pathname=(char*)malloc(strlen(HTBinDir)+strlen(local_copy)+1); ++ strcpy(pathname, HTBinDir); ++ strcat(pathname, local_copy+6); ++ } ++ } ++ ++ if (!pathname) { /* Forbidden by rule */ ++ CTRACE(tfp, "HTAA_checkAuthorization: Forbidden by rule\n"); ++ HTAAFailReason = HTAA_BY_RULE; ++ } ++ else if (HTAAFailReason != HTAA_HTBIN) { ++ /* pathname != NULL */ ++ char *acc_method = HTParse(pathname, "", PARSE_ACCESS); ++ if (!*acc_method || 0 == strcmp(acc_method,"file")) { /*Local file, do AA*/ ++ if (!HTSecure && 0 != strncmp(local_copy, "/htbin/", 7)) { ++ char *localname = HTLocalName(pathname); ++ FREE(pathname); ++ pathname = localname; ++ } ++ HTAAFailReason = check_authorization(pathname, method, ++ scheme, scheme_specifics); ++ } ++ else { /* Not local access */ ++ HTAAFailReason = HTAA_OK_GATEWAY; ++ CTRACE(tfp, "HTAA_checkAuthorization: %s (%s access)\n", ++ "Gatewaying -- skipping authorization check", ++ acc_method); ++ } ++ } /* pathname */ ++ } ++ FREE(local_copy); ++ ++ if (htaa_logfile) { ++ time(&theTime); ++ fprintf(htaa_logfile, "%24.24s %s %s %s %s %s\n", ++ ctime(&theTime), ++ HTClientHost ? HTClientHost : "local", ++ method_name, ++ url, ++ status_name(HTAAFailReason), ++ htaa_user && htaa_user->username ++ ? htaa_user->username : ""); ++ fflush(htaa_logfile); /* Actually update it on disk */ ++ CTRACE(tfp, "Log: %24.24s %s %s %s %s %s\n", ++ ctime(&theTime), ++ HTClientHost ? HTClientHost : "local", ++ method_name, ++ url, ++ status_name(HTAAFailReason), ++ htaa_user && htaa_user->username ++ ? htaa_user->username : ""); ++ } ++ ++ switch (HTAAFailReason) { ++ ++ case HTAA_NO_AUTH: ++ case HTAA_NOT_MEMBER: ++ return 401; ++ ++ case HTAA_BY_RULE: ++ case HTAA_IP_MASK: ++ case HTAA_NO_ACL: ++ case HTAA_NO_ENTRY: ++ case HTAA_SETUP_ERROR: ++ case HTAA_DOTDOT: ++ case HTAA_HTBIN: ++ return 403; ++ ++ case HTAA_NOT_FOUND: ++ return 404; ++ ++ case HTAA_OK: ++ case HTAA_OK_GATEWAY: ++ return 200; ++ ++ default: ++ return 500; ++ } /* switch */ ++} ++ ++ ++/* PRIVATE compose_scheme_specifics() ++** COMPOSE SCHEME-SPECIFIC PARAMETERS ++** TO BE SENT ALONG WITH SERVER REPLY ++** IN THE WWW-Authenticate: FIELD. ++** ON ENTRY: ++** scheme is the authentication scheme for which ++** parameters are asked for. ++** prot protection setup structure. ++** ++** ON EXIT: ++** returns scheme specific parameters in an ++** auto-freed string. ++*/ ++PRIVATE char *compose_scheme_specifics ARGS2(HTAAScheme, scheme, ++ HTAAProt *, prot) ++{ ++ static char *result = NULL; ++ ++ FREE(result); /* From previous call */ ++ ++ switch (scheme) { ++ case HTAA_BASIC: ++ { ++ char *realm = HTAssocList_lookup(prot->values, "server"); ++ result = (char*)malloc(60); ++ sprintf(result, "realm=\"%s\"", ++ (realm ? realm : "UNKNOWN")); ++ return result; ++ } ++ ++ case HTAA_PUBKEY: ++ { ++ char *realm = HTAssocList_lookup(prot->values, "server"); ++ result = (char*)malloc(200); ++ sprintf(result, "realm=\"%s\", key=\"%s\"", ++ (realm ? realm : "UNKNOWN"), ++ "PUBKEY-NOT-IMPLEMENTED"); ++ return result; ++ } ++ default: ++ return NULL; ++ } ++} ++ ++ ++/* SERVER PUBLIC HTAA_composeAuthHeaders() ++** COMPOSE WWW-Authenticate: HEADER LINES ++** INDICATING VALID AUTHENTICATION SCHEMES ++** FOR THE REQUESTED DOCUMENT ++** ON ENTRY: ++** No parameters, but HTAA_checkAuthorization() must ++** just before have failed because a wrong (or none) ++** authentication scheme was used. ++** ++** ON EXIT: ++** returns a buffer containing all the WWW-Authenticate: ++** fields including CRLFs (this buffer is auto-freed). ++** NULL, if authentication won't help in accessing ++** the requested document. ++** ++*/ ++PUBLIC char *HTAA_composeAuthHeaders NOARGS ++{ ++ static char *result = NULL; ++ int n; ++ char *scheme_name; ++ char *scheme_params; ++ HTAAProt *prot = HTAA_getCurrentProtection(); ++ ++ if (!prot) { ++ CTRACE(tfp, "%s %s\n", ++ "HTAA_composeAuthHeaders: Document not protected", ++ "-- why was this function called??"); ++ return NULL; ++ } else { ++ CTRACE(tfp, "HTAA_composeAuthHeaders: for file `%s'\n", ++ prot->filename); ++ } ++ ++ FREE(result); /* From previous call */ ++ if (!(result = (char*)malloc(4096))) /* @@ */ ++ outofmem(__FILE__, "HTAA_composeAuthHeaders"); ++ *result = '\0'; ++ ++ for (n = 0; n < (int) HTAA_MAX_SCHEMES; n++) { ++ HTAAScheme scheme = (HTAAScheme) n; ++ if (-1 < HTList_indexOf(prot->valid_schemes, (void*)scheme)) { ++ if ((scheme_name = HTAAScheme_name(scheme))) { ++ scheme_params = compose_scheme_specifics(scheme,prot); ++ strcat(result, "WWW-Authenticate: "); ++ strcat(result, scheme_name); ++ if (scheme_params) { ++ strcat(result, " "); ++ strcat(result, scheme_params); ++ } ++ strcat(result, "\r\n"); ++ } /* scheme name found */ ++ else { ++ CTRACE(tfp, "HTAA_composeAuthHeaders: %s %d\n", ++ "No name found for scheme number", scheme); ++ } ++ } /* scheme valid for requested document */ ++ } /* for every scheme */ ++ ++ return result; ++} ++ ++ ++/* PUBLIC HTAA_startLogging() ++** START UP ACCESS AUTHORIZATION LOGGING ++** ON ENTRY: ++** fp is the open log file. ++** ++*/ ++PUBLIC void HTAA_startLogging ARGS1(FILE *, fp) ++{ ++ htaa_logfile = fp; ++} ++ |