diff src/dnsbl.cpp @ 75:1142e46be550

start coding on new config syntax
author carl
date Wed, 13 Jul 2005 23:04:14 -0700
parents b7449114ebb0
children 81f1e400e8ab
line wrap: on
line diff
--- a/src/dnsbl.cpp	Sun Jul 10 14:19:00 2005 -0700
+++ b/src/dnsbl.cpp	Wed Jul 13 23:04:14 2005 -0700
@@ -91,6 +91,7 @@
 
 bool debug_syslog  = false;
 bool syslog_opened = false;
+bool use_syslog    = true;  // false to printf
 bool loader_run    = true;   // used to stop the config loader thread
 CONFIG * config = NULL;      // protected by the config_mutex
 int  generation = 0;         // protected by the config_mutex
@@ -382,6 +383,7 @@
         snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text);
         text = buf;
     }
+    if (use_syslog) {
     pthread_mutex_lock(&syslog_mutex);
         if (!syslog_opened) {
             openlog("dnsbl", LOG_PID, LOG_MAIL);
@@ -390,6 +392,10 @@
         syslog(LOG_NOTICE, "%s", text);
     pthread_mutex_unlock(&syslog_mutex);
 }
+    else {
+        printf("%s \n", text);
+    }
+}
 
 void my_syslog(char *text) {
     my_syslog(NULL, text);
@@ -584,7 +590,7 @@
 bool check_single(mlfiPriv &priv, int ip, char *suffix) {
     // make a dns question
     const u_char *src = (const u_char *)&ip;
-    if (src[0] == 127) return oksofar;  // don't do dns lookups on localhost
+    if (src[0] == 127) return false;    // don't do dns lookups on localhost
 #ifdef NS_MAXDNAME
     char question[NS_MAXDNAME];
 #else
@@ -610,7 +616,7 @@
 //
 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist);
 bool check_dnsbl(mlfiPriv &priv, dnsblp_list &dnsbll, DNSBLP &rejectlist) {
-    if (priv.authenticated) return oksofar;
+    if (priv.authenticated) return false;
     for (dnsblp_list::iterator i=dnsbll.begin(); i!=dnsbll.end(); i++) {
         DNSBLP dp = *i;     // non null by construction
         bool st;
@@ -639,6 +645,7 @@
     CONFIG &dc = *priv.pc;
     string_set &hosts  = priv.memory->get_hosts();
     string_set &ignore = dc.get_content_host_ignore();
+    char       *suffix = dc.get_content_suffix();
 
     int count = 0;
     int   cnt = hosts.size();   // number of hosts we could look at
@@ -680,7 +687,7 @@
             int_set::iterator i = ips.find(ip);
             if (i == ips.end()) {
                 ips.insert(ip);
-                if (check_single(priv, ip, dc.get_content_suffix())) {
+                if (check_single(priv, ip, suffix)) {
                     return true;
                 }
             }
@@ -713,7 +720,7 @@
             int_set::iterator i = ips.find(ip);
             if (i == ips.end()) {
                 ips.insert(ip);
-                if (check_single(priv, ip, dc.get_content_suffix())) {
+                if (check_single(priv, ip, suffix)) {
                     string_map::iterator j = nameservers.ns_host.find(host);
                     if (j != nameservers.ns_host.end()) {
                         char *refer = (*j).second;
@@ -734,6 +741,23 @@
 
 
 ////////////////////////////////////////////////
+// this email address is passed in from sendmail, and will
+// always be enclosed in <>. It may have mixed case, just
+// as the mail client sent it. We dup the string and convert
+// the duplicate to lower case.
+//
+char *to_lower_string(char *email);
+char *to_lower_string(char *email) {
+    int n = strlen(email)-2;
+    if (n < 1) return strdup(email);
+    char *key = strdup(email+1);
+    key[n] = '\0';
+    for (int i=0; i<n; i++) key[i] = tolower(key[i]);
+    return key;
+}
+
+
+////////////////////////////////////////////////
 // start of sendmail milter interfaces
 //
 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
@@ -754,7 +778,7 @@
 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from)
 {
     mlfiPriv &priv = *MLFIPRIV;
-    priv.mailaddr      = strdup(from[0]);
+    priv.mailaddr      = to_lower_string(from[0]);
     priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL);
     return SMFIS_CONTINUE;
 }
@@ -766,8 +790,10 @@
     CONFIG &dc = *priv.pc;
     if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i"));
     char *rcptaddr = rcpt[0];
-    CONTEXT &con = *(dc.find_context(rcptaddr, priv.mailaddr));
+    char *loto      = to_lower_string(rcptaddr);
+    CONTEXT     con = *(dc.find_context(loto)->find_context(priv.mailaddr));
     char *fromvalue = con.find_from(priv.mailaddr);
+    free(loto);
     status st;
     if (fromvalue == token_black) {
         st = black;
@@ -986,7 +1012,7 @@
 void usage(char *prog);
 void usage(char *prog)
 {
-    fprintf(stderr, "Usage: %s  [-d] [-c] -r port -p sm-sock-addr [-t timeout]\n", prog);
+    fprintf(stderr, "Usage: %s  [-d] [-c] [-s] [-e from|to] -r port -p sm-sock-addr [-t timeout]\n", prog);
     fprintf(stderr, "where port is for the connection to our own dns resolver processes\n");
     fprintf(stderr, "    and should be local-domain-socket-file-name\n");
     fprintf(stderr, "where sm-sock-addr is for the connection to sendmail\n");
@@ -994,7 +1020,12 @@
     fprintf(stderr, "        inet:port@ip-address\n");
     fprintf(stderr, "        local:local-domain-socket-file-name\n");
     fprintf(stderr, "-c will load and dump the config to stdout\n");
+    fprintf(stderr, "-s will stress test the config loading code by repeating the load/free cycle\n");
+    fprintf(stderr, "        in an infinte loop.\n");
     fprintf(stderr, "-d will add some syslog debug messages\n");
+    fprintf(stderr, "-e will print the results of looking up the from and to addresses in the\n");
+    fprintf(stderr, "        current config. The | character is used to separate the from and to\n");
+    fprintf(stderr, "        addresses in the argument to the -e switch\n");
 }
 
 
@@ -1030,10 +1061,12 @@
 {
     token_init();
     bool check   = false;
+    bool stress  = false;
     bool setconn = false;
     bool setreso = false;
+    char *email = NULL;
     int c;
-    const char *args = "r:p:t:hcd";
+    const char *args = "r:p:t:e:cdhs";
     extern char *optarg;
 
     // Process command line options
@@ -1074,10 +1107,19 @@
                 }
                 break;
 
+            case 'e':
+                if (email) free(email);
+                email = strdup(optarg);
+                break;
+
             case 'c':
                 check = true;
                 break;
 
+            case 's':
+                stress = true;
+                break;
+
             case 'd':
                 debug_syslog = true;
                 break;
@@ -1090,6 +1132,7 @@
     }
 
     if (check) {
+        use_syslog = false;
         CONFIG *conf = new_conf();
         if (conf) {
             conf->dump();
@@ -1101,6 +1144,42 @@
         }
     }
 
+    if (stress) {
+        fprintf(stdout, "stress testing\n");
+        while (1) {
+            for (int i=0; i<10; i++) {
+                CONFIG *conf = new_conf();
+                if (conf) delete conf;
+            }
+            fprintf(stdout, ".");
+            fflush(stdout);
+            sleep(1);
+        }
+    }
+
+    if (email) {
+        char *x = strchr(email, '|');
+        if (x) {
+            *x = '\0';
+            char *from = strdup(email);
+            char *to   = strdup(x+1);
+            use_syslog = false;
+            CONFIG *conf = new_conf();
+            if (conf) {
+                CONTEXTP con = conf->find_context(to);
+                const int maxlen = 1000;
+                char buf[maxlen];
+                fprintf(stdout, "envelope to   <%s> finds context %s\n", to, con->get_full_name(buf,maxlen));
+                CONTEXTP fc = con->find_context(from);
+                fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen));
+                char *st = fc->find_from(from);
+                fprintf(stdout, "envelope from <%s> finds status %s\n", from, st);
+                delete conf;
+            }
+        }
+        return 0;
+    }
+
     if (!setconn) {
         fprintf(stderr, "%s: Missing required -p argument\n", argv[0]);
         usage(argv[0]);