Merge branch 'master' into with-dns-bl
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 5 Oct 2008 13:22:54 +0000 (15:22 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 5 Oct 2008 13:22:54 +0000 (15:22 +0200)
Conflicts:

postlicyd/iplist.c
postlicyd/tst-rbl.c

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
common/Makefile
common/array.h
common/rbl.c [new file with mode: 0644]
common/rbl.h [new file with mode: 0644]
postlicyd/Makefile
postlicyd/iplist.c [moved from postlicyd/rbl.c with 83% similarity]
postlicyd/iplist.h [moved from postlicyd/rbl.h with 98% similarity]
postlicyd/tst-rbl.c

index 541d5ac..3f30e73 100644 (file)
@@ -32,7 +32,7 @@
 LIBS  = lib
 TESTS = tst-trie
 
-lib_SOURCES = str.c buffer.c common.c epoll.c server.c trie.c file.c
+lib_SOURCES = str.c buffer.c common.c epoll.c server.c trie.c file.c rbl.c
 tst-trie_SOURCES = tst-trie.c lib.a
 
 all:
index 3a8fda5..6f5217d 100644 (file)
         array_ensure_capacity_delta(array, 1);                                 \
         (array).data[(array).len++] = (obj);                                   \
     } while (0)
-#define array_append(array, objs, len)                                         \
+#define array_append(array, objs, Len)                                         \
     do {                                                                       \
-        const typeof((array).len) __len = (len);                               \
+        const typeof((array).len) __len = (Len);                               \
         array_ensure_capacity_delta(array, __len);                             \
         memcpy((array).data + (array).len, objs,                               \
                __len * sizeof(*(array).data));                                 \
         array_ensure_can_edit(array);                                          \
         p_shrink(&(array).data, (array).len, &(array).size);                   \
     } while (0)
-#define array_elt(array, n) (array).data[(n)]
-#define array_ptr(array, n) (array).data + (n)
+#define array_elt(array, n) ((array).data[(n)])
+#define array_ptr(array, n) ((array).data + (n))
 
 #define foreach(var, array)                                                    \
     for (uint32_t __Ai = 0 ; __Ai < (array).len ; ++__Ai) {                    \
diff --git a/common/rbl.c b/common/rbl.c
new file mode 100644 (file)
index 0000000..11ed464
--- /dev/null
@@ -0,0 +1,66 @@
+/******************************************************************************/
+/*          pfixtools: a collection of postfix related tools                  */
+/*          ~~~~~~~~~                                                         */
+/*  ________________________________________________________________________  */
+/*                                                                            */
+/*  Redistribution and use in source and binary forms, with or without        */
+/*  modification, are permitted provided that the following conditions        */
+/*  are met:                                                                  */
+/*                                                                            */
+/*  1. Redistributions of source code must retain the above copyright         */
+/*     notice, this list of conditions and the following disclaimer.          */
+/*  2. Redistributions in binary form must reproduce the above copyright      */
+/*     notice, this list of conditions and the following disclaimer in the    */
+/*     documentation and/or other materials provided with the distribution.   */
+/*  3. The names of its contributors may not be used to endorse or promote    */
+/*     products derived from this software without specific prior written     */
+/*     permission.                                                            */
+/*                                                                            */
+/*  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   */
+/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     */
+/*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        */
+/*  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS    */
+/*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR    */
+/*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF      */
+/*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  */
+/*  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   */
+/*  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)   */
+/*  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF    */
+/*  THE POSSIBILITY OF SUCH DAMAGE.                                           */
+/******************************************************************************/
+
+/*
+ * Copyright © 2008 Florent Bruneau
+ */
+
+#include <netdb.h>
+#include "rbl.h"
+
+static inline rbl_result_t rbl_dns_check(const char *hostname)
+{
+    struct hostent *host = gethostbyname(hostname);
+    if (host != NULL) {
+        return RBL_FOUND;
+    } else {
+        if (h_errno == HOST_NOT_FOUND) {
+            return RBL_NOTFOUND;
+        }
+        return RBL_ERROR;
+    }
+}
+
+rbl_result_t rbl_check(const char *rbl, uint32_t ip)
+{
+    char host[257];
+    snprintf(host, 257, "%d.%d.%d.%d.%s",
+             ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff,
+             rbl);
+    return rbl_dns_check(host);
+}
+
+rbl_result_t rhbl_check(const char *rhbl, const char *hostname)
+{
+    char host[257];
+    snprintf(host, 257, "%s.%s", hostname, rhbl);
+    return rbl_dns_check(host);
+}
diff --git a/common/rbl.h b/common/rbl.h
new file mode 100644 (file)
index 0000000..4a1e763
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************************/
+/*          pfixtools: a collection of postfix related tools                  */
+/*          ~~~~~~~~~                                                         */
+/*  ________________________________________________________________________  */
+/*                                                                            */
+/*  Redistribution and use in source and binary forms, with or without        */
+/*  modification, are permitted provided that the following conditions        */
+/*  are met:                                                                  */
+/*                                                                            */
+/*  1. Redistributions of source code must retain the above copyright         */
+/*     notice, this list of conditions and the following disclaimer.          */
+/*  2. Redistributions in binary form must reproduce the above copyright      */
+/*     notice, this list of conditions and the following disclaimer in the    */
+/*     documentation and/or other materials provided with the distribution.   */
+/*  3. The names of its contributors may not be used to endorse or promote    */
+/*     products derived from this software without specific prior written     */
+/*     permission.                                                            */
+/*                                                                            */
+/*  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   */
+/*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE     */
+/*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        */
+/*  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS    */
+/*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR    */
+/*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF      */
+/*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  */
+/*  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN   */
+/*  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)   */
+/*  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF    */
+/*  THE POSSIBILITY OF SUCH DAMAGE.                                           */
+/******************************************************************************/
+
+/*
+ * Copyright © 2008 Florent Bruneau
+ */
+
+#ifndef PFIXTOOLS_RBL_H
+#define PFIXTOOLS_RBL_H
+
+#include "common.h"
+
+typedef enum {
+  RBL_ERROR,
+  RBL_FOUND,
+  RBL_NOTFOUND,
+} rbl_result_t;
+
+/** Check the presence of the given IP in the given rbl.
+ */
+__attribute__((nonnull(1)))
+rbl_result_t rbl_check(const char *rbl, uint32_t ip);
+
+/** Check the presence of the given hostname in the given rhbl.
+ */
+__attribute__((nonnull(1,2)))
+rbl_result_t rhbl_check(const char *rhbl, const char *hostname);
+
+#endif
index 363a9a0..0983841 100644 (file)
@@ -38,12 +38,12 @@ GENERATED = policy_tokens.h policy_tokens.c \
                                                param_tokens.h param_tokens.c
 TESTS     = tst-rbl tst-filters
 
-FILTERS                = rbl.c greylist.c strlist.c match.c
+FILTERS                = iplist.c greylist.c strlist.c match.c
 
 postlicyd_SOURCES = main-postlicyd.c ../common/lib.a filter.c config.c query.c $(FILTERS) $(GENERATED)
 postlicyd_LIBADD  = $(TC_LIBS)
 
-tst-rbl_SOURCES   = tst-rbl.c ../common/lib.a filter.c config.c query.c rbl.c $(GENERATED)
+tst-rbl_SOURCES   = tst-rbl.c ../common/lib.a filter.c config.c query.c iplist.c $(GENERATED)
 tst-filters_SOURCES = tst-filters.c ../common/lib.a config.c filter.c query.c $(FILTERS) $(GENERATED)
 tst-filters_LIBADD  = $(TC_LIBS)
 
similarity index 83%
rename from postlicyd/rbl.c
rename to postlicyd/iplist.c
index 4e1ac27..3c14fda 100644 (file)
 #include <sys/mman.h>
 
 #include "common.h"
-#include "rbl.h"
+#include "iplist.h"
 #include "str.h"
 #include "file.h"
 #include "array.h"
+#include "rbl.h"
 
 #define IPv4_BITS        5
 #define IPv4_PREFIX(ip)  ((uint32_t)(ip) >> IPv4_BITS)
@@ -227,6 +228,9 @@ bool rbldb_ipv4_lookup(const rbldb_t *db, uint32_t ip)
 typedef struct rbl_filter_t {
     PA(rbldb_t) rbls;
     A(int)      weights;
+    A(char)     hosts;
+    A(int)      host_offsets;
+    A(int)      host_weights;
 
     int32_t     hard_threshold;
     int32_t     soft_threshold;
@@ -242,6 +246,9 @@ static void rbl_filter_delete(rbl_filter_t **rbl)
     if (*rbl) {
         array_deep_wipe((*rbl)->rbls, rbldb_delete);
         array_wipe((*rbl)->weights);
+        array_wipe((*rbl)->hosts);
+        array_wipe((*rbl)->host_offsets);
+        array_wipe((*rbl)->host_weights);
         p_delete(rbl);
     }
 }
@@ -318,6 +325,39 @@ static bool rbl_filter_constructor(filter_t *filter)
             }
           } break;
 
+          /* dns parameter.
+           *  weight:hostname.
+           * define a RBL to use through DNS resolution.
+           */
+          case ATK_DNS: {
+            int  weight = 0;
+            const char *current = param->value;
+            const char *p = m_strchrnul(param->value, ':');
+            char *next = NULL;
+            for (int i = 0 ; i < 2 ; ++i) {
+                PARSE_CHECK(i == 1 || *p,
+                            "host parameter must contains a weight option");
+                switch (i) {
+                  case 0:
+                    weight = strtol(current, &next, 10);
+                    PARSE_CHECK(next == p && weight >= 0 && weight <= 1024,
+                                "illegal weight value %.*s",
+                                (p - current), current);
+                    break;
+
+                  case 1:
+                    array_add(data->host_offsets, array_len(data->hosts));
+                    array_append(data->hosts, current, strlen(current) + 1);
+                    array_add(data->host_weights, weight);
+                    break;
+                }
+                if (i != 1) {
+                    current = p + 1;
+                    p = m_strchrnul(current, ':');
+                }
+            }
+          } break;
+
           /* hard_threshold parameter is an integer.
            *  If the matching score is greater or equal than this threshold,
            *  the hook "hard_match" is called.
@@ -357,6 +397,7 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query)
     int32_t sum = 0;
     const char *end = NULL;
     const rbl_filter_t *data = filter->data;
+    bool  error = true;
 
     if (parse_ipv4(query->client_address, &end, &ip) != 0) {
         warn("invalid client address: %s, expected ipv4",
@@ -368,7 +409,34 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query)
         int weight   = array_elt(data->weights, i);
         if (rbldb_ipv4_lookup(rbl, ip)) {
             sum += weight;
+            if (sum >= data->hard_threshold) {
+                return HTK_HARD_MATCH;
+            }
         }
+        error = false;
+    }
+    for (uint32_t i = 0 ; i < data->host_offsets.len ; ++i) {
+        const char *rbl = array_ptr(data->hosts, array_elt(data->host_offsets, i));
+        int weight      = array_elt(data->host_weights, i);
+        switch (rbl_check(rbl, ip)) {
+          case RBL_FOUND:
+            error = false;
+            sum += weight;
+            if (sum >= data->hard_threshold) {
+                return HTK_HARD_MATCH;
+            }
+            break;
+          case RBL_NOTFOUND:
+            error = false;
+            break;
+          case RBL_ERROR:
+            warn("rbl %s unavailable", rbl);
+            break;
+        }
+    }
+    if (error) {
+        err("filter %s: all the rbl returned an error", filter->name);
+        return HTK_ERROR;
     }
     if (sum >= data->hard_threshold) {
         return HTK_HARD_MATCH;
@@ -395,6 +463,7 @@ static int rbl_init(void)
      */
     (void)filter_param_register(type, "file");
     (void)filter_param_register(type, "rbldns");
+    (void)filter_param_register(type, "dns");
     (void)filter_param_register(type, "hard_threshold");
     (void)filter_param_register(type, "soft_threshold");
     return 0;
similarity index 98%
rename from postlicyd/rbl.h
rename to postlicyd/iplist.h
index dc9a03d..45a0088 100644 (file)
@@ -34,8 +34,8 @@
  * Copyright © 2008 Florent Bruneau
  */
 
-#ifndef PFIXTOOLS_RBL_H
-#define PFIXTOOLS_RBL_H
+#ifndef PFIXTOOLS_IPLIST_H
+#define PFIXTOOLS_IPLIST_H
 
 typedef struct rbldb_t rbldb_t;
 
index 7e567b1..9cafae1 100644 (file)
@@ -38,7 +38,7 @@
             __FILE__, __LINE__, __func__, ##__VA_ARGS__)
 
 #include "common.h"
-#include "rbl.h"
+#include "iplist.h"
 #include "array.h"
 
 int main(int argc, char *argv[])