From: serassio <> Date: Thu, 15 Jun 2006 01:18:24 +0000 (+0000) Subject: Bug #961: Add support for arbitrary headers access controls X-Git-Tag: SQUID_3_0_PRE4~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00634927915f0a13deb39a1685259390f4df2fc5;p=thirdparty%2Fsquid.git Bug #961: Add support for arbitrary headers access controls Forward port of 2.5 patch by Gonzalo Arana. --- diff --git a/src/ACLHTTPHeaderData.cc b/src/ACLHTTPHeaderData.cc new file mode 100644 index 0000000000..0bbd2c45f4 --- /dev/null +++ b/src/ACLHTTPHeaderData.cc @@ -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 + */ + +#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(¤t->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 * +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 index 0000000000..141c8aa1af --- /dev/null +++ b/src/ACLHTTPHeaderData.h @@ -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 + */ + +#ifndef SQUID_ACLREGEXDATA_H +#define SQUID_ACLREGEXDATA_H +#include "ACLData.h" + +class ACLHTTPHeaderData : public ACLData +{ + +public: + MEMPROXY_CLASS(ACLHTTPHeaderData); + + virtual ~ACLHTTPHeaderData(); + virtual bool match(HttpHeader* hdr); + virtual wordlist *dump(); + virtual void parse(); + virtual bool empty() const; + virtual ACLData *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 index 0000000000..9935c40f59 --- /dev/null +++ b/src/ACLHTTPRepHeader.cc @@ -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 + */ + +#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 + +; + +ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header"); + +ACLStrategised ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header"); + +int +ACLHTTPRepHeaderStrategy::match (ACLData * &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 index 0000000000..1f25d0725f --- /dev/null +++ b/src/ACLHTTPRepHeader.h @@ -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 + */ + +#ifndef SQUID_ACLMETHOD_H +#define SQUID_ACLMETHOD_H +#include "ACLStrategy.h" +#include "ACLStrategised.h" +#include "HttpHeader.h" + +class ACLHTTPRepHeaderStrategy : public ACLStrategy +{ + +public: + virtual int match (ACLData * &, 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 RegistryEntry_; +}; + +#endif /* SQUID_ACLMETHOD_H */ diff --git a/src/ACLHTTPReqHeader.cc b/src/ACLHTTPReqHeader.cc new file mode 100644 index 0000000000..c71421a44b --- /dev/null +++ b/src/ACLHTTPReqHeader.cc @@ -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 + */ + +#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 + +; + +ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header"); + +ACLStrategised ACLHTTPReqHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPReqHeaderStrategy::Instance(), "req_header"); + +int +ACLHTTPReqHeaderStrategy::match (ACLData * &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 index 0000000000..abb25eccfa --- /dev/null +++ b/src/ACLHTTPReqHeader.h @@ -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 + */ + +#ifndef SQUID_ACLMETHOD_H +#define SQUID_ACLMETHOD_H +#include "ACLStrategy.h" +#include "ACLStrategised.h" +#include "HttpHeader.h" + +class ACLHTTPReqHeaderStrategy : public ACLStrategy +{ + +public: + virtual int match (ACLData * &, 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 RegistryEntry_; +}; + +#endif /* SQUID_ACLMETHOD_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 51ed1fd7ab..8e3bc9f2c3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/cf.data.pre b/src/cf.data.pre index 00b6890417..e875a40f42 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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.