]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #961: Add support for arbitrary headers access controls
authorserassio <>
Thu, 15 Jun 2006 01:18:24 +0000 (01:18 +0000)
committerserassio <>
Thu, 15 Jun 2006 01:18:24 +0000 (01:18 +0000)
Forward port of 2.5 patch by Gonzalo Arana.

src/ACLHTTPHeaderData.cc [new file with mode: 0644]
src/ACLHTTPHeaderData.h [new file with mode: 0644]
src/ACLHTTPRepHeader.cc [new file with mode: 0644]
src/ACLHTTPRepHeader.h [new file with mode: 0644]
src/ACLHTTPReqHeader.cc [new file with mode: 0644]
src/ACLHTTPReqHeader.h [new file with mode: 0644]
src/Makefile.am
src/cf.data.pre

diff --git a/src/ACLHTTPHeaderData.cc b/src/ACLHTTPHeaderData.cc
new file mode 100644 (file)
index 0000000..0bbd2c4
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * $Id: ACLHTTPHeaderData.cc,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ * DEBUG: section 28    Access Control
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "ACLHTTPHeaderData.h"
+#include "authenticate.h"
+#include "ACLChecklist.h"
+#include "ACL.h"
+#include "wordlist.h"
+#include "ConfigParser.h"
+
+//TODO: These should be unified
+static void aclDestroyRegexList(relist * data);
+void
+aclDestroyRegexList(relist * data)
+{
+    relist *next = NULL;
+
+    for (; data; data = next) {
+        next = data->next;
+        regfree(&data->regex);
+        safe_free(data->pattern);
+        memFree(data, MEM_RELIST);
+    }
+}
+
+ACLHTTPHeaderData::~ACLHTTPHeaderData()
+{
+    aclDestroyRegexList(data);
+}
+
+bool
+ACLHTTPHeaderData::match(HttpHeader* hdr)
+{
+    if (hdr == NULL)
+        return false;
+
+    debug(28, 3) ("aclHeaderData::match: checking '%s'\n", hdrName.buf());
+
+    relist *first, *prev;
+
+    first = data;
+
+    prev = NULL;
+
+    relist *current = first;
+
+    String value = hdrId != HDR_BAD_HDR ? hdr->getStrOrList(hdrId) : hdr->getByName(hdrName.buf());
+
+    // A header value will not be modified, but may not be present
+    while (value.buf() && current) {
+        debug(28, 3) ("aclHeaderData::match: looking for '%s'\n", current->pattern);
+
+        if (regexec(&current->regex, value.buf(), 0, 0, 0) == 0) {
+            if (prev != NULL) {
+                /* shift the element just found to the second position
+                 * in the list */
+                prev->next = current->next;
+                current->next = first->next;
+                first->next = current;
+            }
+
+            debug(28, 2) ("aclHeaderData::match: match '%s' found in '%s'\n",
+                          current->pattern, value.buf());
+            return 1;
+        }
+
+        prev = current;
+        current = current->next;
+    }
+
+    return 0;
+}
+
+wordlist *
+ACLHTTPHeaderData::dump()
+{
+    wordlist *W = NULL;
+    relist *temp = data;
+
+    while (temp != NULL) {
+        wordlistAdd(&W, temp->pattern);
+        temp = temp->next;
+    }
+
+    return W;
+}
+
+static void aclParseHeaderList(relist **curlist);
+//TODO: These should be merged...
+void
+aclParseHeaderList(relist **curlist)
+{
+    relist **Tail;
+    relist *q = NULL;
+    char *t = NULL;
+    regex_t comp;
+    int errcode;
+    int flags = REG_EXTENDED | REG_NOSUB;
+
+    for (Tail = (relist **)curlist; *Tail; Tail = &((*Tail)->next))
+
+        ;
+
+    while ((t = ConfigParser::strtokFile())) {
+        if (strcmp(t, "-i") == 0) {
+            flags |= REG_ICASE;
+            continue;
+        }
+
+        if (strcmp(t, "+i") == 0) {
+            flags &= ~REG_ICASE;
+            continue;
+        }
+
+        if ((errcode = regcomp(&comp, t, flags)) != 0) {
+            char errbuf[256];
+            regerror(errcode, &comp, errbuf, sizeof errbuf);
+            debug(28, 0) ("%s line %d: %s\n",
+                          cfg_filename, config_lineno, config_input_line);
+            debug(28, 0) ("aclParseHeaderList: Invalid regular expression '%s': %s\n",
+                          t, errbuf);
+            continue;
+        }
+
+        q = (relist *)memAllocate(MEM_RELIST);
+        q->pattern = xstrdup(t);
+        q->regex = comp;
+        *(Tail) = q;
+        Tail = &q->next;
+    }
+}
+
+void
+ACLHTTPHeaderData::parse()
+{
+    char* t = strtokFile();
+    assert (t != NULL);
+    hdrName = t;
+    hdrId = httpHeaderIdByNameDef(hdrName.buf(), strlen(hdrName.buf()));
+    aclParseHeaderList(&data);
+}
+
+bool
+ACLHTTPHeaderData::empty() const
+{
+    return data == NULL;
+}
+
+ACLData<HttpHeader*> *
+ACLHTTPHeaderData::clone() const
+{
+    /* Header's don't clone yet. */
+    assert (!data);
+    return new ACLHTTPHeaderData;
+}
+
diff --git a/src/ACLHTTPHeaderData.h b/src/ACLHTTPHeaderData.h
new file mode 100644 (file)
index 0000000..141c8aa
--- /dev/null
@@ -0,0 +1,61 @@
+
+/*
+ * $Id: ACLHTTPHeaderData.h,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLREGEXDATA_H
+#define SQUID_ACLREGEXDATA_H
+#include "ACLData.h"
+
+class ACLHTTPHeaderData : public ACLData<HttpHeader*>
+{
+
+public:
+    MEMPROXY_CLASS(ACLHTTPHeaderData);
+
+    virtual ~ACLHTTPHeaderData();
+    virtual bool match(HttpHeader* hdr);
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual bool empty() const;
+    virtual ACLData<HttpHeader*> *clone() const;
+
+private:
+    http_hdr_type hdrId; // set if header is known
+    String hdrName; // always set
+    relist *data;
+};
+
+MEMPROXY_CLASS_INLINE(ACLHTTPHeaderData)
+
+#endif /* SQUID_ACLREGEXDATA_H */
diff --git a/src/ACLHTTPRepHeader.cc b/src/ACLHTTPRepHeader.cc
new file mode 100644 (file)
index 0000000..9935c40
--- /dev/null
@@ -0,0 +1,65 @@
+
+/*
+ * $Id: ACLHTTPRepHeader.cc,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "ACLHTTPRepHeader.h"
+#include "ACLHTTPHeaderData.h"
+#include "ACLChecklist.h"
+#include "HttpReply.h"
+
+/* explicit template instantiation required for some systems */
+
+template class ACLStrategised<HttpHeader*>
+
+;
+
+ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header");
+
+ACLStrategised<HttpHeader*> ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header");
+
+int
+ACLHTTPRepHeaderStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
+{
+    return data->match (&checklist->reply->header);
+}
+
+ACLHTTPRepHeaderStrategy *
+ACLHTTPRepHeaderStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLHTTPRepHeaderStrategy ACLHTTPRepHeaderStrategy::Instance_;
+
diff --git a/src/ACLHTTPRepHeader.h b/src/ACLHTTPRepHeader.h
new file mode 100644 (file)
index 0000000..1f25d07
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * $Id: ACLHTTPRepHeader.h,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLMETHOD_H
+#define SQUID_ACLMETHOD_H
+#include "ACLStrategy.h"
+#include "ACLStrategised.h"
+#include "HttpHeader.h"
+
+class ACLHTTPRepHeaderStrategy : public ACLStrategy<HttpHeader*>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, ACLChecklist *);
+    virtual bool requiresReply() const { return true; }
+
+    static ACLHTTPRepHeaderStrategy *Instance();
+    /* Not implemented to prevent copies of the instance. */
+    /* Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends */
+    ACLHTTPRepHeaderStrategy(ACLHTTPRepHeaderStrategy const &);
+
+private:
+    static ACLHTTPRepHeaderStrategy Instance_;
+    ACLHTTPRepHeaderStrategy() { }
+
+    ACLHTTPRepHeaderStrategy&operator = (ACLHTTPRepHeaderStrategy const &);
+};
+
+class ACLHTTPRepHeader
+{
+
+private:
+    static ACL::Prototype RegistryProtoype;
+    static ACLStrategised<HttpHeader*> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLMETHOD_H */
diff --git a/src/ACLHTTPReqHeader.cc b/src/ACLHTTPReqHeader.cc
new file mode 100644 (file)
index 0000000..c71421a
--- /dev/null
@@ -0,0 +1,65 @@
+
+/*
+ * $Id: ACLHTTPReqHeader.cc,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "squid.h"
+#include "ACLHTTPReqHeader.h"
+#include "ACLHTTPHeaderData.h"
+#include "ACLChecklist.h"
+#include "HttpRequest.h"
+
+/* explicit template instantiation required for some systems */
+
+template class ACLStrategised<HttpHeader*>
+
+;
+
+ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header");
+
+ACLStrategised<HttpHeader*> ACLHTTPReqHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPReqHeaderStrategy::Instance(), "req_header");
+
+int
+ACLHTTPReqHeaderStrategy::match (ACLData<MatchType> * &data, ACLChecklist *checklist)
+{
+    return data->match (&checklist->request->header);
+}
+
+ACLHTTPReqHeaderStrategy *
+ACLHTTPReqHeaderStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLHTTPReqHeaderStrategy ACLHTTPReqHeaderStrategy::Instance_;
+
diff --git a/src/ACLHTTPReqHeader.h b/src/ACLHTTPReqHeader.h
new file mode 100644 (file)
index 0000000..abb25ec
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*
+ * $Id: ACLHTTPReqHeader.h,v 1.1 2006/06/14 19:18:24 serassio Exp $
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLMETHOD_H
+#define SQUID_ACLMETHOD_H
+#include "ACLStrategy.h"
+#include "ACLStrategised.h"
+#include "HttpHeader.h"
+
+class ACLHTTPReqHeaderStrategy : public ACLStrategy<HttpHeader*>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, ACLChecklist *);
+    virtual bool requiresRequest() const { return true; }
+
+    static ACLHTTPReqHeaderStrategy *Instance();
+    /* Not implemented to prevent copies of the instance. */
+    /* Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends */
+    ACLHTTPReqHeaderStrategy(ACLHTTPReqHeaderStrategy const &);
+
+private:
+    static ACLHTTPReqHeaderStrategy Instance_;
+    ACLHTTPReqHeaderStrategy() { }
+
+    ACLHTTPReqHeaderStrategy&operator = (ACLHTTPReqHeaderStrategy const &);
+};
+
+class ACLHTTPReqHeader
+{
+
+private:
+    static ACL::Prototype RegistryProtoype;
+    static ACLStrategised<HttpHeader*> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLMETHOD_H */
index 51ed1fd7ab23a347403a861fb415a24d2516527a..8e3bc9f2c3d5466791584173d8c0b3f71f61e6cb 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.155 2006/06/13 20:52:05 serassio Exp $
+#  $Id: Makefile.am,v 1.156 2006/06/14 19:18:24 serassio Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -279,6 +279,8 @@ squid_ACLSOURCES = \
        ACLDomainData.cc \
        ACLExtUser.h \
        ACLExtUser.cc \
+       ACLHTTPHeaderData.h \
+       ACLHTTPHeaderData.cc \
        ACLHTTPStatus.h \
        ACLHTTPStatus.cc \
        ACLIntRange.cc \
@@ -310,6 +312,10 @@ squid_ACLSOURCES = \
        ACLReplyHeaderStrategy.h \
        ACLReplyMIMEType.cc \
        ACLReplyMIMEType.h \
+       ACLHTTPRepHeader.cc \
+       ACLHTTPRepHeader.h \
+       ACLHTTPReqHeader.cc \
+       ACLHTTPReqHeader.h \
        ACLRequestHeaderStrategy.h \
        ACLRequestMIMEType.cc \
        ACLRequestMIMEType.h \
index 00b68904174665f3b530620c4df959233edeb99a..e875a40f42fb8ee5923c05f06d142b6e6ef65ec8 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.417 2006/06/11 20:48:45 robertc Exp $
+# $Id: cf.data.pre,v 1.418 2006/06/14 19:18:24 serassio Exp $
 #
 #
 # SQUID Web Proxy Cache                http://www.squid-cache.org/
@@ -2557,7 +2557,7 @@ DOC_START
        acl aclname proto    HTTP FTP ...
        acl aclname method   GET POST ...
        acl aclname browser  [-i] regexp ...
-         # pattern match on User-Agent header
+         # pattern match on User-Agent header (see also req_header below)
        acl aclname referer_regex  [-i] regexp ...
          # pattern match on Referer header
          # Referer is highly unreliable, so use with care
@@ -2622,6 +2622,11 @@ DOC_START
          # NOTE: This does NOT match the reply. You cannot use this
          # to match the returned file type.
 
+       acl aclname req_header header-name [-i] any\.regex\.here
+         # regex match against any of the known request headers.  May be
+         # thought of as a superset of "browser", "referer" and "mime-type"
+         # ACLs.
+
        acl aclname rep_mime_type mime-type1 ...
          # regex match against the mime type of the reply received by
          # squid. Can be used to detect file download or some
@@ -2630,6 +2635,11 @@ DOC_START
          # effect in rules that affect the reply data stream such as
          # http_reply_access.
 
+       acl aclname req_header header-name [-i] any\.regex\.here
+         # regex match against any of the known request headers.  May be
+         # thought of as a superset of "browser", "referer" and "mime-type"
+         # ACLs.
+
        acl acl_name external class_name [arguments...]
          # external ACL lookup via a helper class defined by the
          # external_acl_type directive.