From: wessels <> Date: Thu, 12 Sep 1996 04:31:04 +0000 (+0000) Subject: Added deny_info support from maex@space.net. Redirect denied accesses to X-Git-Tag: SQUID_3_0_PRE1~5841 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e92d33a5d07ee80dc1a73e7354e1ae215afc0876;p=thirdparty%2Fsquid.git Added deny_info support from maex@space.net. Redirect denied accesses to a specific URL. --- diff --git a/src/acl.cc b/src/acl.cc index 643103f40f..c6b38b3489 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,5 +1,5 @@ /* - * $Id: acl.cc,v 1.29 1996/09/04 22:03:18 wessels Exp $ + * $Id: acl.cc,v 1.30 1996/09/11 22:31:04 wessels Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -30,7 +30,11 @@ #include "squid.h" -/* These two should never be referenced directly in this file! */ +/* Global */ +char *AclMatchedName = NULL; + +/* These three should never be referenced directly in this file! */ +struct _acl_deny_info_list *DenyInfoList = NULL; struct _acl_access *HTTPAccessList = NULL; struct _acl_access *ICPAccessList = NULL; @@ -472,6 +476,81 @@ void aclParseAclLine() AclListTail = &A->next; } +/* maex@space.net (06.09.96) + * get (if any) the URL from deny_info for a certain acl + */ +char *aclGetDenyInfoUrl(head, name) + struct _acl_deny_info_list **head; + char *name; +{ + struct _acl_deny_info_list *A = NULL; + struct _acl_name_list *L = NULL; + + A = *head; + if (NULL == *head) /* empty list */ + return (NULL); + while (A) { + L = A->acl_list; + if (NULL == L) /* empty list should never happen, but in case */ + continue; + while (L) { + if (!strcmp(name, L->name)) + return (A->url); + L = L->next; + } + A = A->next; + } + return (NULL); +} +/* maex@space.net (05.09.96) + * get the info for redirecting "access denied" to info pages + * TODO (probably ;-) + * currently there is no optimization for + * - more than one deny_info line with the same url + * - a check, whether the given acl really is defined + * - a check, whether an acl is added more than once for the same url + */ +void aclParseDenyInfoLine(head) + struct _acl_deny_info_list **head; +{ + char *t = NULL; + struct _acl_deny_info_list *A = NULL; + struct _acl_deny_info_list *B = NULL; + struct _acl_deny_info_list **T = NULL; + struct _acl_name_list *L = NULL; + struct _acl_name_list **Tail = NULL; + + /* first expect an url */ + if ((t = strtok(NULL, w_space)) == NULL) { + debug(28, 0, "%s line %d: %s\n", + cfg_filename, config_lineno, config_input_line); + debug(28, 0, "aclParseDenyInfoLine: missing 'url' parameter.\n"); + return; + } + A = xcalloc(1, sizeof(struct _acl_deny_info_list)); + strncpy(A->url, t, MAX_URL); + A->url[MAX_URL] = '\0'; /* just in case strlen(t) >= MAX_URL */ + A->next = (struct _acl_deny_info_list *) NULL; + /* next expect a list of ACL names */ + Tail = &A->acl_list; + while ((t = strtok(NULL, w_space))) { + L = xcalloc(1, sizeof(struct _acl_name_list)); + strncpy(L->name, t, ACL_NAME_SZ); + L->name[ACL_NAME_SZ] = '\0'; /* just in case strlen(t) >= ACL_NAME_SZ */ + *Tail = L; + Tail = &L->next; + } + if (A->acl_list == NULL) { + debug(28, 0, "%s line %d: %s\n", + cfg_filename, config_lineno, config_input_line); + debug(28, 0, "aclParseDenyInfoLine: deny_info line contains no ACL's, skipping\n"); + xfree(A); + return; + } + for (B = *head, T = head; B; T = &B->next, B = B->next); /* find the tail */ + *T = A; +} + void aclParseAccessLine(head) struct _acl_access **head; { @@ -759,6 +838,7 @@ static int aclMatchAclList(list, checklist) aclCheck_t *checklist; { while (list) { + AclMatchedName = list->acl->name; debug(28, 3, "aclMatchAclList: checking %s%s\n", list->op ? "" : "!", list->acl->name); if (aclMatchAcl(list->acl, checklist) != list->op) { @@ -887,3 +967,24 @@ void aclDestroyAccessList(list) } *list = NULL; } + +/* maex@space.net (06.09.1996) + * destroy an _acl_deny_info_list + */ +void aclDestroyDenyInfoList(list) + struct _acl_deny_info_list **list; +{ + struct _acl_deny_info_list *a = NULL; + struct _acl_deny_info_list *a_next = NULL; + struct _acl_name_list *l = NULL; + struct _acl_name_list *l_next = NULL; + + for (a = *list; a; a = a_next) { + for (l = a->acl_list; l; l = l_next) { + l_next = l->next; + safe_free(l); + } + a_next = a->next; + safe_free(a); + } +} diff --git a/src/client_side.cc b/src/client_side.cc index 638d2dbf3c..c7db4a759b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.16 1996/09/05 16:59:49 wessels Exp $ + * $Id: client_side.cc,v 1.17 1996/09/11 22:31:07 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -169,17 +169,29 @@ void clientAccessCheckDone(icpState, answer) { int fd = icpState->fd; char *buf = NULL; + char *redirectUrl = NULL; debug(33, 5, "clientAccessCheckDone: '%s' answer=%d\n", icpState->url, answer); if (answer) { urlCanonical(icpState->request, icpState->url); redirectStart(fd, icpState, clientRedirectDone, icpState); } else { debug(33, 5, "Access Denied: %s\n", icpState->url); - buf = access_denied_msg(icpState->http_code = 400, - icpState->method, - icpState->url, - fd_table[fd].ipaddr); - icpSendERROR(fd, LOG_TCP_DENIED, buf, icpState, 403); + redirectUrl = aclGetDenyInfoUrl(&DenyInfoList, AclMatchedName); + if (redirectUrl) { + icpState->http_code = 302, + buf = access_denied_redirect(icpState->http_code, + icpState->method, + icpState->url, + fd_table[fd].ipaddr, + redirectUrl); + } else { + icpState->http_code = 400; + buf = access_denied_msg(icpState->http_code, + icpState->method, + icpState->url, + fd_table[fd].ipaddr); + } + icpSendERROR(fd, LOG_TCP_DENIED, buf, icpState, icpState->http_code); } } @@ -388,6 +400,7 @@ int icpHandleIMSReply(fd, entry, data) MemObject *mem = entry->mem_obj; LOCAL_ARRAY(char, hbuf, 8192); int len; + int unlink_request = 0; debug(33, 0, "icpHandleIMSReply: FD %d '%s'\n", fd, entry->url); /* unregister this handler */ storeUnregister(entry, fd); @@ -405,8 +418,10 @@ int icpHandleIMSReply(fd, entry, data) icpState->log_type = LOG_TCP_EXPIRED_HIT; /* We initiated the IMS request, the client is not expecting * 304, so put the good one back */ - if (icpState->old_entry->mem_obj->request == NULL) + if (icpState->old_entry->mem_obj->request == NULL) { icpState->old_entry->mem_obj->request = requestLink(mem->request); + unlink_request = 1; + } storeUnlockObject(entry); entry = icpState->entry = icpState->old_entry; /* Extend the TTL @@ -417,7 +432,8 @@ int icpHandleIMSReply(fd, entry, data) fatal_dump("icpHandleIMSReply: failed to load headers, lost race"); httpParseHeaders(hbuf, entry->mem_obj->reply); ttlSet(entry); - requestUnlink(entry->mem_obj->request); + if (unlink_request) + requestUnlink(entry->mem_obj->request); } else { /* the client can handle this reply, whatever it is */ icpState->log_type = LOG_TCP_EXPIRED_MISS; diff --git a/src/errorpage.cc b/src/errorpage.cc index c5405430cb..b813fc3698 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -1,6 +1,6 @@ /* - * $Id: errorpage.cc,v 1.36 1996/09/04 22:03:22 wessels Exp $ + * $Id: errorpage.cc,v 1.37 1996/09/11 22:31:06 wessels Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -154,6 +154,7 @@ void squid_error_entry(entry, type, msg) char *msg; { int index; + if (type < ERR_MIN || type > ERR_MAX) fatal_dump("squid_error_entry: type out of range."); index = (int) (type - ERR_MIN); @@ -192,6 +193,7 @@ char *squid_error_url(url, method, type, address, code, msg) char *msg; { int index; + *tmp_error_buf = '\0'; if (type < ERR_MIN || type > ERR_MAX) fatal_dump("squid_error_url: type out of range."); @@ -241,6 +243,7 @@ char *squid_error_request(request, type, address, code) int code; { int index; + *tmp_error_buf = '\0'; if (type < ERR_MIN || type > ERR_MAX) fatal_dump("squid_error_request: type out of range."); @@ -293,6 +296,53 @@ Generated by %s/%s@%s\n\ return tmp_error_buf; } +/* maex@space.net (06.09.1996) + * the message that is sent on deny_info + * add a Location: and for old browsers a HREF to the info page + */ +char *access_denied_redirect(code, method, url, client, redirect) + int code; + int method; + char *url; + char *client; + char *redirect; +{ + sprintf(tmp_error_buf, "\ +HTTP/1.0 %d Cache Access Deny Redirect\r\n\ +Location: %s\r\n\ +Content-type: text/html\r\n\ +\r\n\ +Cache Access Denied\n\ +

Error

\n\ +

Access Denied

\n\ +

\n\ +Sorry, you are not currently allowed to request\n\ +

    %s
\n\ +from this cache.\n\ +

\n\ +You may take a look at\n\ +

 %s
\n\ +or check with the cache administrator if you\n\ +believe this is incorrect.\n\ +

\n\ +%s\n\ +


\n\ +
\n\ +Generated by %s/%s@%s\n\ +
\n\ +\n", + code, + redirect, + url, + redirect, + redirect, + Config.errHtmlText, + appname, + version_string, + getMyHostname()); + return tmp_error_buf; +} + char *authorization_needed_msg(request, realm) request_t *request; char *realm;