Add support for rbl by dns resolution.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sat, 4 Oct 2008 14:14:13 +0000 (16:14 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sat, 4 Oct 2008 14:14:13 +0000 (16:14 +0200)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
common/Makefile
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 94% similarity]
postlicyd/iplist.h [moved from postlicyd/rbl.h with 98% similarity]
postlicyd/tst-rbl.c

index 3720069..be9d473 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
 
 include ../mk/common.mk
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 ac0e95a..84dec14 100644 (file)
@@ -38,7 +38,7 @@ GENERATED = policy_tokens.h policy_tokens.c \
                                                param_tokens.h param_tokens.c
 TESTS     = test-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)
similarity index 94%
rename from postlicyd/rbl.c
rename to postlicyd/iplist.c
index a84f73e..256c360 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)
@@ -385,6 +386,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",
@@ -400,6 +402,30 @@ static filter_result_t rbl_filter(const filter_t *filter, const query_t *query)
                 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;
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 3087560..057018f 100644 (file)
@@ -38,7 +38,7 @@
             __FILE__, __LINE__, __func__, ##__VA_ARGS__)
 
 #include "common.h"
-#include "rbl.c"
+#include "iplist.c"
 
 int main(int argc, char *argv[])
 {