diff options
Diffstat (limited to 'WWW/Library/Implementation/HTAAServ.c')
-rw-r--r-- | WWW/Library/Implementation/HTAAServ.c | 646 |
1 files changed, 0 insertions, 646 deletions
diff --git a/WWW/Library/Implementation/HTAAServ.c b/WWW/Library/Implementation/HTAAServ.c deleted file mode 100644 index c8c26300..00000000 --- a/WWW/Library/Implementation/HTAAServ.c +++ /dev/null @@ -1,646 +0,0 @@ - -/* 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_authorization() -** 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 { - -#ifndef NO_RULES - 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); - if (pathname == NULL) - outofmem(__FILE__, "HTAA_checkAuthorization"); - 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) { -#endif /* NO_RULES */ - - /* 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); - } - -#ifndef NO_RULES - } /* pathname */ -#endif /* NO_RULES */ - - } - 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"); - HTSprintf0(&result, "realm=\"%s\"", - (realm ? realm : "UNKNOWN")); - return result; - } - - case HTAA_PUBKEY: - { - char *realm = HTAssocList_lookup(prot->values, "server"); - HTSprintf0(&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; -} - |