note ACL

This patch investigates the new note ACL type, to match transaction annotation.
Syntax:
   acl aclname note name [value ...]

Without values, matches any annotation with a given name. With value(s), matches
any annotation with a given name that also has one of the given values.
Annotation sources include note and adaptation_meta directives as well as helper
and eCAP responses.

This is a Measurement Factory project

=== modified file 'src/AclRegs.cc'
--- src/AclRegs.cc	2013-01-27 17:35:07 +0000
+++ src/AclRegs.cc	2013-05-02 10:21:29 +0000
@@ -20,40 +20,42 @@
 #include "acl/DomainData.h"
 #if USE_AUTH
 #include "acl/ExtUser.h"
 #endif
 #include "acl/FilledChecklist.h"
 #include "acl/Gadgets.h"
 #include "acl/HierCodeData.h"
 #include "acl/HierCode.h"
 #include "acl/HttpHeaderData.h"
 #include "acl/HttpRepHeader.h"
 #include "acl/HttpReqHeader.h"
 #include "acl/HttpStatus.h"
 #include "acl/IntRange.h"
 #include "acl/Ip.h"
 #include "acl/LocalIp.h"
 #include "acl/LocalPort.h"
 #include "acl/MaxConnection.h"
 #include "acl/MethodData.h"
 #include "acl/Method.h"
 #include "acl/MyPortName.h"
+#include "acl/Note.h"
+#include "acl/NoteData.h"
 #include "acl/PeerName.h"
 #include "acl/ProtocolData.h"
 #include "acl/Protocol.h"
 #include "acl/Random.h"
 #include "acl/Referer.h"
 #include "acl/RegexData.h"
 #include "acl/ReplyHeaderStrategy.h"
 #include "acl/ReplyMimeType.h"
 #include "acl/RequestHeaderStrategy.h"
 #include "acl/RequestMimeType.h"
 #include "acl/SourceAsn.h"
 #include "acl/SourceDomain.h"
 #include "acl/SourceIp.h"
 #if USE_SSL
 #include "acl/SslErrorData.h"
 #include "acl/SslError.h"
 #include "acl/CertificateData.h"
 #include "acl/Certificate.h"
 #endif
 #include "acl/Strategised.h"
@@ -164,20 +166,23 @@
 
 #if USE_IDENT
 ACL::Prototype ACLIdent::UserRegistryProtoype(&ACLIdent::UserRegistryEntry_, "ident");
 ACLIdent ACLIdent::UserRegistryEntry_(new ACLUserData, "ident");
 ACL::Prototype ACLIdent::RegexRegistryProtoype(&ACLIdent::RegexRegistryEntry_, "ident_regex" );
 ACLIdent ACLIdent::RegexRegistryEntry_(new ACLRegexData, "ident_regex");
 #endif
 
 #if USE_AUTH
 ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth");
 ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData, "proxy_auth");
 ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex" );
 ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData, "proxy_auth_regex");
 
 ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip");
 ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip");
 #endif
 
 ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag");
 ACLStrategised<const char *> ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag");
+
+ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note");
+ACLStrategised<HttpRequest *> ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note");

=== modified file 'src/acl/Makefile.am'
--- src/acl/Makefile.am	2012-11-13 18:19:17 +0000
+++ src/acl/Makefile.am	2013-01-25 20:18:48 +0000
@@ -56,40 +56,44 @@
 	HttpRepHeader.cc \
 	HttpRepHeader.h \
 	HttpReqHeader.cc \
 	HttpReqHeader.h \
 	HttpStatus.cc \
 	HttpStatus.h \
 	Ip.cc \
 	Ip.h \
 	LocalIp.cc \
 	LocalIp.h \
 	LocalPort.cc \
 	LocalPort.h \
 	MaxConnection.cc \
 	MaxConnection.h \
 	Method.cc \
 	MethodData.cc \
 	MethodData.h \
 	Method.h \
 	MyPortName.cc \
 	MyPortName.h \
+	Note.h \
+	Note.cc \
+	NoteData.h \
+	NoteData.cc \
 	PeerName.cc \
 	PeerName.h \
 	Protocol.cc \
 	ProtocolData.cc \
 	ProtocolData.h \
 	Protocol.h \
 	Random.cc \
 	Random.h \
 	Referer.cc \
 	Referer.h \
 	ReplyHeaderStrategy.h \
 	ReplyMimeType.cc \
 	ReplyMimeType.h \
 	RequestHeaderStrategy.h \
 	RequestMimeType.cc \
 	RequestMimeType.h \
 	SourceAsn.h \
 	SourceDomain.cc \
 	SourceDomain.h \
 	SourceIp.cc \

=== added file 'src/acl/Note.cc'
--- src/acl/Note.cc	1970-01-01 00:00:00 +0000
+++ src/acl/Note.cc	2013-05-02 10:34:22 +0000
@@ -0,0 +1,55 @@
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "squid.h"
+#include "acl/Note.h"
+#include "acl/HttpHeaderData.h"
+#include "acl/Checklist.h"
+#include "HttpRequest.h"
+#include "Notes.h"
+
+int
+ACLNoteStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &)
+{
+    if (checklist->request != NULL)
+        return data->match(checklist->request);
+
+    return 0;
+}
+
+ACLNoteStrategy *
+ACLNoteStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLNoteStrategy ACLNoteStrategy::Instance_;
+

=== added file 'src/acl/Note.h'
--- src/acl/Note.h	1970-01-01 00:00:00 +0000
+++ src/acl/Note.h	2013-05-02 10:11:59 +0000
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef SQUID_ACLNOTE_H
+#define SQUID_ACLNOTE_H
+
+#include "acl/Strategy.h"
+#include "acl/Strategised.h"
+
+class HttpRequest;
+
+/// \ingroup ACLAPI
+class ACLNoteStrategy : public ACLStrategy<HttpRequest *>
+{
+
+public:
+    virtual int match (ACLData<MatchType> * &, ACLFilledChecklist *, ACLFlags &);
+    virtual bool requiresRequest() const { return true; }
+
+    static ACLNoteStrategy *Instance();
+    /* Not implemented to prevent copies of the instance. */
+    /* Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends */
+    ACLNoteStrategy(ACLNoteStrategy const &);
+
+private:
+    static ACLNoteStrategy Instance_;
+    ACLNoteStrategy() { }
+
+    ACLNoteStrategy& operator = (ACLNoteStrategy const &);
+};
+
+/// \ingroup ACLAPI
+class ACLNote
+{
+
+private:
+    static ACL::Prototype RegistryProtoype;
+    static ACLStrategised<HttpRequest *> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLNOTE_H */

=== added file 'src/acl/NoteData.cc'
--- src/acl/NoteData.cc	1970-01-01 00:00:00 +0000
+++ src/acl/NoteData.cc	2013-05-02 11:40:56 +0000
@@ -0,0 +1,120 @@
+/*
+ * DEBUG: section 28    Access Control
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "squid.h"
+#include "acl/Acl.h"
+#include "acl/Checklist.h"
+#include "acl/NoteData.h"
+#include "acl/StringData.h"
+#include "cache_cf.h"
+#include "ConfigParser.h"
+#include "Debug.h"
+#include "HttpRequest.h"
+#include "Notes.h"
+#include "wordlist.h"
+
+ACLNoteData::ACLNoteData() : values(new ACLStringData)
+{}
+
+ACLNoteData::~ACLNoteData()
+{
+    delete values;
+}
+
+bool
+ACLNoteData::matchNotes(NotePairs *note)
+{
+    if (note == NULL)
+        return false;
+
+    debugs(28, 3, "Checking " << name);
+
+    if (values->empty())
+        return (note->findFirst(name.termedBuf()) != NULL);
+
+    for (Vector<NotePairs::Entry *>::iterator i = note->entries.begin(); i!= note->entries.end(); ++i) {
+        if ((*i)->name.cmp(name.termedBuf()) == 0) {
+            if (values->match((*i)->value.termedBuf()))
+                return true;
+        }
+    }
+    return false;
+}
+
+bool
+ACLNoteData::match(HttpRequest *request)
+{
+    if (request->notes != NULL &&
+        matchNotes(request->notes.getRaw()))
+        return true;
+#if USE_ADAPTATION
+    const Adaptation::History::Pointer ah = request->adaptLogHistory();
+    if (ah != NULL && ah->metaHeaders != NULL && matchNotes(ah->metaHeaders.getRaw()))
+        return true;
+#endif
+    return false;
+}
+
+wordlist *
+ACLNoteData::dump()
+{
+    wordlist *W = NULL;
+    wordlistAdd(&W, name.termedBuf());
+    wordlist * dumpR = values->dump();
+    wordlistAddWl(&W, dumpR);
+    wordlistDestroy(&dumpR);
+    return W;
+}
+
+void
+ACLNoteData::parse()
+{
+    char* t = strtokFile();
+    assert (t != NULL);
+    name = t;
+    values->parse();
+}
+
+bool
+ACLNoteData::empty() const
+{
+    return name.undefined();
+}
+
+ACLData<HttpRequest *> *
+ACLNoteData::clone() const
+{
+    ACLNoteData * result = new ACLNoteData;
+    result->values = values->clone();
+    result->name = name;
+    return result;
+}

=== added file 'src/acl/NoteData.h'
--- src/acl/NoteData.h	1970-01-01 00:00:00 +0000
+++ src/acl/NoteData.h	2013-05-02 11:44:06 +0000
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+#ifndef SQUID_ACLNOTEDATA_H
+#define SQUID_ACLNOTEDATA_H
+
+/* becaue we inherit from it */
+#include "acl/Data.h"
+/* for String field */
+#include "SquidString.h"
+/* because we use its MEMPROXY_CLASS() macros */
+#include "MemPool.h"
+
+class HttpRequest;
+class NotePairs;
+
+/// \ingroup ACLAPI
+class ACLNoteData : public ACLData<HttpRequest *>
+{
+public:
+    MEMPROXY_CLASS(ACLNoteData);
+
+    ACLNoteData();
+    virtual ~ACLNoteData();
+    virtual bool match(HttpRequest* request);
+    virtual wordlist *dump();
+    virtual void parse();
+    virtual bool empty() const;
+    virtual ACLData<HttpRequest *> *clone() const;
+
+private:
+    bool matchNotes(NotePairs *note);
+    String name;                     /**< always set */
+    ACLData<char const *> *values; ///< if set, at least one value must match
+};
+
+MEMPROXY_CLASS_INLINE(ACLNoteData);
+
+#endif /* SQUID_ACLNOTEDATA_H */

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2013-04-23 14:22:51 +0000
+++ src/cf.data.pre	2013-05-02 09:57:12 +0000
@@ -1028,40 +1028,49 @@
 	acl aclname ca_cert attribute values...
 	  # match against attributes a users issuing CA SSL certificate
 	  # attribute is one of DN/C/O/CN/L/ST [fast]
 
 	acl aclname ext_user username ...
 	acl aclname ext_user_regex [-i] pattern ...
 	  # string match on username returned by external acl helper [slow]
 	  # use REQUIRED to accept any non-null user name.
 
 	acl aclname tag tagvalue ...
 	  # string match on tag returned by external acl helper [slow]
 
 	acl aclname hier_code codename ...
 	  # string match against squid hierarchy code(s); [fast]
 	  #  e.g., DIRECT, PARENT_HIT, NONE, etc.
 	  #
 	  # NOTE: This has no effect in http_access rules. It only has
 	  # effect in rules that affect the reply data stream such as
 	  # http_reply_access.
 
+	acl aclname note name [value ...]
+	  # match transaction annotation [fast]
+	  # Without values, matches any annotation with a given name.
+	  # With value(s), matches any annotation with a given name that
+	  # also has one of the given values.
+	  # Names and values are compared using a string equality test.
+	  # Annotation sources include note and adaptation_meta directives
+	  # as well as helper and eCAP responses.
+
 IF USE_SSL
 	acl aclname ssl_error errorname
 	  # match against SSL certificate validation error [fast]
 	  #
 	  # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt
 	  # template file.
 	  #
 	  # The following can be used as shortcuts for certificate properties:
 	  #  [ssl::]certHasExpired: the "not after" field is in the past
 	  #  [ssl::]certNotYetValid: the "not before" field is in the future
 	  #  [ssl::]certUntrusted: The certificate issuer is not to be trusted.
 	  #  [ssl::]certSelfSigned: The certificate is self signed.
 	  #  [ssl::]certDomainMismatch: The certificate CN domain does not
 	  #         match the name the name of the host we are connecting to.
 	  #
 	  # The ssl::certHasExpired, ssl::certNotYetValid, ssl::certDomainMismatch,
 	  # ssl::certUntrusted, and ssl::certSelfSigned can also be used as
 	  # predefined ACLs, just like the 'all' ACL.
 	  #
 	  # NOTE: The ssl_error ACL is only supported with sslproxy_cert_error,


