diff src/context.cpp @ 233:5c3e9bf45bb5 stable-6-0-23

Add whitelisting by regex expression filtering. Add queueid to whitelist extension log message.
author Carl Byington <carl@five-ten-sg.com>
date Mon, 25 May 2009 11:14:32 -0700
parents 82886d4dd71f
children ef97c7cd4a6e
line wrap: on
line diff
--- a/src/context.cpp	Fri May 08 15:21:40 2009 -0700
+++ b/src/context.cpp	Mon May 25 11:14:32 2009 -0700
@@ -62,6 +62,7 @@
 const char *token_uribl;
 const char *token_verify;
 const char *token_white;
+const char *token_white_regex;
 const char *token_yes;
 
 const char *token_myhostname;
@@ -692,6 +693,7 @@
     verifier            = NULL;
     generic_regx        = NULL;
     generic_message     = NULL;
+    white_regx          = NULL;
     autowhite_file      = NULL;
     whitelister         = NULL;
     env_from_default    = (parent) ? token_inherit : token_unknown;
@@ -720,6 +722,7 @@
         delete d;
     }
     if (generic_regx) regfree(&generic_pattern);
+    if (white_regx)   regfree(&white_pattern);
 }
 
 
@@ -738,6 +741,26 @@
 }
 
 
+bool CONTEXT::set_white(const char *regx)
+{
+    int rc = 0;
+    if (white_regx) regfree(&white_pattern);
+    white_regx = regx;
+    if (white_regx) {
+        rc = regcomp(&white_pattern, regx, REG_NOSUB | REG_ICASE | REG_EXTENDED);
+    }
+    return rc;  // true iff bad pattern
+}
+
+
+bool CONTEXT::white_match(const char *from)
+{
+    return (from       &&
+            white_regx &&
+            (0 == regexec(&white_pattern, from, 0, NULL, 0)));
+}
+
+
 bool CONTEXT::set_generic(const char *regx, const char *msg)
 {
     int rc = 0;
@@ -806,7 +829,7 @@
 }
 
 
-const char *CONTEXT::find_from(const char *from, bool update_white) {
+const char *CONTEXT::find_from(const char *from, bool update_white, const char *queueid) {
     WHITELISTERP w = whitelister;
     CONTEXTP     p = parent;
     while (!w && p) {
@@ -814,12 +837,12 @@
         p = p->parent;
     }
     if (w && w->is_white(from)) {
-        if (update_white) {
+        if (update_white && queueid) {
             // update senders timestamp to extend the whitelisting period
             if (debug_syslog > 1) {
                 char buf[maxlen];
                 char msg[maxlen];
-                snprintf(msg, sizeof(msg), "extend whitelist reply from <%s> in context %s", from, get_full_name(buf,maxlen));
+                snprintf(msg, sizeof(msg), "%s: extend whitelist reply from <%s> in context %s", queueid, from, get_full_name(buf,maxlen));
                 my_syslog(msg);
             }
             w->sent(strdup(from));
@@ -844,6 +867,10 @@
             }
         }
     }
+    if ((rc == token_inherit) || (rc == token_unknown)) {
+        bool ok = white_match(from);
+        if (ok) rc = token_white;
+    }
     if ((rc == token_inherit) && parent) return parent->find_from(from);
     return (rc == token_inherit) ? token_unknown : rc;
 }
@@ -1067,6 +1094,10 @@
         printf("%s             \"%s\"; \n", indent, generic_message);
     }
 
+    if (white_regx) {
+        printf("%s     white_regex \"%s\"; \n", indent, white_regx);
+    }
+
     if (autowhite_file && whitelister) {
         printf("%s     autowhite %d %s; \n", indent, whitelister->get_days(), autowhite_file);
     }
@@ -1465,6 +1496,20 @@
 
 ////////////////////////////////////////////////
 //
+bool parse_white(TOKEN &tok, CONFIG &dc, CONTEXT &me);
+bool parse_white(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
+    const char *regx = tok.next();
+    if (!tsa(tok, token_semi)) return false;
+    if (me.set_white(regx)) {
+        tok.token_error("invalid regular expression %s", regx, regx);
+        return false;
+    }
+    return true;
+}
+
+
+////////////////////////////////////////////////
+//
 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me);
 bool parse_autowhite(TOKEN &tok, CONFIG &dc, CONTEXT &me) {
     int days = tok.nextint();
@@ -1607,6 +1652,9 @@
         else if (have == token_generic) {
             if (!parse_generic(tok, dc, *con)) return false;
         }
+        else if (have == token_white_regex) {
+            if (!parse_white(tok, dc, *con)) return false;
+        }
         else if (have == token_autowhite) {
             if (!parse_autowhite(tok, dc, *con)) return false;
         }
@@ -1708,6 +1756,7 @@
     token_uribl         = register_string("uribl");
     token_verify        = register_string("verify");
     token_white         = register_string("white");
+    token_white_regex   = register_string("white_regex");
     token_yes           = register_string("yes");
 
     if (gethostname(myhostname, HOST_NAME_MAX+1) != 0) {