]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Added deny_info support from maex@space.net. Redirect denied accesses to
authorwessels <>
Thu, 12 Sep 1996 04:31:04 +0000 (04:31 +0000)
committerwessels <>
Thu, 12 Sep 1996 04:31:04 +0000 (04:31 +0000)
a specific URL.

src/acl.cc
src/client_side.cc
src/errorpage.cc

index 643103f40fbf95ed303b6e467268f131c1b1da6e..c6b38b348921c10fb91c4d5978b2a6bc8eb22737 100644 (file)
@@ -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
 
 #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);
+    }
+}
index 638d2dbf3c76b3e4eebe8341644268fffac82090..c7db4a759b47260a89787642e8a651295e165e9e 100644 (file)
@@ -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;
index c5405430cb65d38d1e450f48a40e3dd969edeb56..b813fc36982e3bdd91015c081a45b98710673990 100644 (file)
@@ -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\
+<HTML><HEAD><TITLE>Cache Access Denied</TITLE></HEAD>\n\
+<BODY><H1>Error</H1>\n\
+<H2>Access Denied</H2>\n\
+<P>\n\
+Sorry, you are not currently allowed to request\n\
+<PRE>    %s</PRE>\n\
+from this cache.\n\
+<P>\n\
+You may take a look at\n\
+<PRE> <A HREF=\"%s\">%s</A></PRE>\n\
+or check with the cache administrator if you\n\
+believe this is incorrect.\n\
+<P>\n\
+%s\n\
+<HR>\n\
+<ADDRESS>\n\
+Generated by %s/%s@%s\n\
+</ADDRESS></BODY></HTML>\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;