]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/external_acl.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / external_acl.cc
index e5f466edf23f8f3e58ebe254007a5e1bb1c0a3af..d7b01e597a6518afc6dddc6211e686282e876494 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -22,6 +22,7 @@
 #include "format/Token.h"
 #include "helper.h"
 #include "helper/Reply.h"
+#include "http/Stream.h"
 #include "HttpHeaderTools.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
@@ -120,10 +121,7 @@ public:
     bool require_auth;
 #endif
 
-    enum {
-        QUOTE_METHOD_SHELL = 1,
-        QUOTE_METHOD_URL
-    } quote;
+    Format::Quoting quote; // default quoting to use, set by protocol= parameter
 
     Ip::Address local_addr;
 };
@@ -146,7 +144,7 @@ external_acl::external_acl() :
 #if USE_AUTH
     require_auth(0),
 #endif
-    quote(external_acl::QUOTE_METHOD_URL)
+    quote(Format::LOG_QUOTE_URL)
 {
     local_addr.setLocalhost();
 }
@@ -180,12 +178,14 @@ external_acl::~external_acl()
 void
 parse_externalAclHelper(external_acl ** list)
 {
-    external_acl *a = new external_acl;
     char *token = ConfigParser::NextToken();
 
-    if (!token)
+    if (!token) {
         self_destruct();
+        return;
+    }
 
+    external_acl *a = new external_acl;
     a->name = xstrdup(token);
 
     // Allow supported %macros inside quoted tokens
@@ -217,16 +217,16 @@ parse_externalAclHelper(external_acl ** list)
         } else if (strncmp(token, "grace=", 6) == 0) {
             a->grace = atoi(token + 6);
         } else if (strcmp(token, "protocol=2.5") == 0) {
-            a->quote = external_acl::QUOTE_METHOD_SHELL;
+            a->quote = Format::LOG_QUOTE_SHELL;
         } else if (strcmp(token, "protocol=3.0") == 0) {
             debugs(3, DBG_PARSE_NOTE(2), "WARNING: external_acl_type option protocol=3.0 is deprecated. Remove this from your config.");
-            a->quote = external_acl::QUOTE_METHOD_URL;
+            a->quote = Format::LOG_QUOTE_URL;
         } else if (strcmp(token, "quote=url") == 0) {
             debugs(3, DBG_PARSE_NOTE(2), "WARNING: external_acl_type option quote=url is deprecated. Remove this from your config.");
-            a->quote = external_acl::QUOTE_METHOD_URL;
+            a->quote = Format::LOG_QUOTE_URL;
         } else if (strcmp(token, "quote=shell") == 0) {
             debugs(3, DBG_PARSE_NOTE(2), "WARNING: external_acl_type option quote=shell is deprecated. Use protocol=2.5 if still needed.");
-            a->quote = external_acl::QUOTE_METHOD_SHELL;
+            a->quote = Format::LOG_QUOTE_SHELL;
 
             /* INET6: allow admin to configure some helpers explicitly to
                       bind to IPv4/v6 localhost port. */
@@ -278,6 +278,10 @@ parse_externalAclHelper(external_acl ** list)
         // these tokens are whitespace delimited
         (*fmt)->space = true;
 
+        // set the default encoding to match the protocol= config
+        // this will be overridden by explicit %macro attributes
+        (*fmt)->quote = a->quote;
+
         // compatibility for old tokens incompatible with Format::Token syntax
 #if USE_OPENSSL // dont bother if we dont have to.
         if (strncmp(token, "%USER_CERT_", 11) == 0) {
@@ -309,26 +313,33 @@ parse_externalAclHelper(external_acl ** list)
             a->require_auth = true;
 #endif
 
-       if ((*fmt)->type == Format::LFT_EXT_ACL_DATA)
-           data_used = true;
+        if ((*fmt)->type == Format::LFT_EXT_ACL_DATA)
+            data_used = true;
 
         fmt = &((*fmt)->next);
         token = ConfigParser::NextToken();
     }
 
     /* There must be at least one format token */
-    if (!a->format.format)
+    if (!a->format.format) {
+        delete a;
         self_destruct();
+        return;
+    }
 
     // format has implicit %DATA on the end if not used explicitly
     if (!data_used) {
         *fmt = new Format::Token;
         (*fmt)->type = Format::LFT_EXT_ACL_DATA;
+        (*fmt)->quote = Format::LOG_QUOTE_NONE;
     }
 
     /* helper */
-    if (!token)
+    if (!token) {
+        delete a;
         self_destruct();
+        return;
+    }
 
     wordlistAdd(&a->cmdline, token);
 
@@ -367,19 +378,19 @@ dump_externalAclHelper(StoreEntry * sentry, const char *name, const external_acl
         if (node->children.n_max != DEFAULT_EXTERNAL_ACL_CHILDREN)
             storeAppendPrintf(sentry, " children-max=%d", node->children.n_max);
 
-        if (node->children.n_startup != 1)
+        if (node->children.n_startup != 0) // sync with helper/ChildConfig.cc default
             storeAppendPrintf(sentry, " children-startup=%d", node->children.n_startup);
 
-        if (node->children.n_idle != (node->children.n_max + node->children.n_startup) )
+        if (node->children.n_idle != 1) // sync with helper/ChildConfig.cc default
             storeAppendPrintf(sentry, " children-idle=%d", node->children.n_idle);
 
-        if (node->children.concurrency)
+        if (node->children.concurrency != 0)
             storeAppendPrintf(sentry, " concurrency=%d", node->children.concurrency);
 
         if (node->cache)
             storeAppendPrintf(sentry, " cache=%d", node->cache_size);
 
-        if (node->quote == external_acl::QUOTE_METHOD_SHELL)
+        if (node->quote == Format::LOG_QUOTE_SHELL)
             storeAppendPrintf(sentry, " protocol=2.5");
 
         node->format.dump(sentry, NULL, false);
@@ -463,18 +474,25 @@ external_acl_data::~external_acl_data()
 void
 ACLExternal::parse()
 {
-    if (data)
+    if (data) {
         self_destruct();
+        return;
+    }
 
     char *token = ConfigParser::strtokFile();
 
-    if (!token)
+    if (!token) {
         self_destruct();
+        return;
+    }
 
     data = new external_acl_data(find_externalAclHelper(token));
 
-    if (!data->def)
+    if (!data->def) {
+        delete data;
         self_destruct();
+        return;
+    }
 
     // def->name is the name of the external_acl_type.
     // this is the name of the 'acl' directive being tested
@@ -610,7 +628,8 @@ aclMatchExternal(external_acl_data *acl, ACLFilledChecklist *ch)
         if (!entry) {
             debugs(82, 2, HERE << acl->def->name << "(\"" << key << "\") = lookup needed");
 
-            if (!acl->def->theHelper->queueFull()) {
+            // TODO: All other helpers allow temporary overload. Should not we?
+            if (!acl->def->theHelper->willOverload()) {
                 debugs(82, 2, HERE << "\"" << key << "\": queueing a call.");
                 if (!ch->goAsync(ExternalACLLookup::Instance()))
                     debugs(82, 2, "\"" << key << "\": no async support!");
@@ -619,12 +638,12 @@ aclMatchExternal(external_acl_data *acl, ACLFilledChecklist *ch)
             } else {
                 if (!staleEntry) {
                     debugs(82, DBG_IMPORTANT, "WARNING: external ACL '" << acl->def->name <<
-                           "' queue overload. Request rejected '" << key << "'.");
+                           "' queue full. Request rejected '" << key << "'.");
                     external_acl_message = "SYSTEM TOO BUSY, TRY AGAIN LATER";
                     return ACCESS_DUNNO;
                 } else {
                     debugs(82, DBG_IMPORTANT, "WARNING: external ACL '" << acl->def->name <<
-                           "' queue overload. Using stale result. '" << key << "'.");
+                           "' queue full. Using stale result. '" << key << "'.");
                     entry = staleEntry;
                     /* Fall thru to processing below */
                 }
@@ -716,8 +735,8 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
 
         if (t->type == Format::LFT_EXT_ACL_NAME) {
             // setup for %ACL
-            safe_free(ch->al->_private.lastAclName);
-            ch->al->_private.lastAclName = xstrdup(acl_data->name);
+            safe_free(ch->al->lastAclName);
+            ch->al->lastAclName = xstrdup(acl_data->name);
         }
 
         if (t->type == Format::LFT_EXT_ACL_DATA) {
@@ -727,7 +746,7 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
                 if (sb.length())
                     sb.append(" ", 1);
 
-                if (acl_data->def->quote == external_acl::QUOTE_METHOD_URL) {
+                if (acl_data->def->quote == Format::LOG_QUOTE_URL) {
                     const char *quoted = rfc1738_escape(arg->key);
                     sb.append(quoted, strlen(quoted));
                 } else {
@@ -739,9 +758,10 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
                 }
             }
 
-            ch->al->_private.lastAclData = sb.c_str();
+            ch->al->lastAclData = sb;
         }
 
+#if USE_IDENT
         if (t->type == Format::LFT_USER_IDENT) {
             if (!*ch->rfc931) {
                 // if we fail to go async, we still return NULL and the caller
@@ -750,6 +770,7 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
                 return NULL;
             }
         }
+#endif
     }
 
     // assemble the full helper lookup string