summaryrefslogtreecommitdiff
path: root/www/lynx/patches.v6/patch-ad
diff options
context:
space:
mode:
Diffstat (limited to 'www/lynx/patches.v6/patch-ad')
-rw-r--r--www/lynx/patches.v6/patch-ad646
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;
++}
++