Can set an entry point per protocol-state.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 16 Sep 2008 15:15:38 +0000 (17:15 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Tue, 16 Sep 2008 15:15:38 +0000 (17:15 +0200)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
postlicyd/config.c
postlicyd/config.h
postlicyd/filter.c
postlicyd/greylist.c
postlicyd/main-postlicyd.c
postlicyd/query.h

index ec63480..0bd69e2 100644 (file)
 
 #define config_param_register(Param)
 
-config_param_register("first_filter");
+/* Filter to execute on "CONNECT"
+ */
+config_param_register("client_filter");
+
+/* Filter to execute on "MAIL FROM"
+ */
+config_param_register("sender_filter");
+
+/* Filter to execute on "RCPT TO"
+ */
+config_param_register("recipient_filter");
+
+/* Filter to execute on "DATA"
+ */
+config_param_register("data_filter");
+
+/* Filter to execute on "END-OF-DATA"
+ */
+config_param_register("end_of_data_filter");
+
+/* Filter to execute on "ETRN"
+ */
+config_param_register("etrn_filter");
+
+/* Filter to execute on "HELO"
+ */
+config_param_register("helo_filter");
+config_param_register("ehlo_filter");
+
+/* Filter to execute on "VRFY"
+ */
+config_param_register("verify_filter");
 
 static inline config_t *config_new(void)
 {
     config_t *config = p_new(config_t, 1);
-    config->entry_point = -1;
+    for (int i = 0 ; i < SMTP_count ; ++i) {
+        config->entry_points[i] = -1;
+    }
     return config;
 }
 
@@ -75,21 +108,35 @@ static bool config_second_pass(config_t *config)
             break;
         }
     }}
+    if (!ok) {
+        return false;
+    }
 
-    config->entry_point = -1;
+    ok = false;
     foreach (filter_param_t *param, config->params) {
         switch (param->type) {
-          case ATK_FIRST_FILTER:
-            config->entry_point = filter_find_with_name(&config->filters,
-                                                        param->value);
-            break;
+#define   CASE(Param, State)                                                   \
+            case ATK_ ## Param ## _FILTER:                                     \
+              ok = true;                                                       \
+              config->entry_points[SMTP_ ## State]                             \
+                  = filter_find_with_name(&config->filters, param->value);     \
+              break;
+          CASE(CLIENT,      CONNECT)
+          CASE(EHLO,        EHLO)
+          CASE(HELO,        HELO)
+          CASE(SENDER,      MAIL)
+          CASE(RECIPIENT,   RCPT)
+          CASE(DATA,        DATA)
+          CASE(END_OF_DATA, END_OF_MESSAGE)
+          CASE(VERIFY,      VRFY)
+          CASE(ETRN,        ETRN)
+#undef    CASE
           default: break;
         }
     }}
     array_deep_wipe(config->params, filter_params_wipe);
 
-    if (config->entry_point == -1) {
-        ok = false;
+    if (!ok) {
         syslog(LOG_ERR, "no entry point defined");
     }
 
@@ -307,7 +354,9 @@ badeof:
     syslog(LOG_ERR, "Unexpected end of file");
 
 error:
-    filter_wipe(&filter);
+    if (filter.name) {
+        filter_wipe(&filter);
+    }
     config_delete(&config);
     file_map_close(&map);
     return NULL;
index 00d4324..554fe96 100644 (file)
@@ -43,7 +43,7 @@ typedef struct config_t config_t;
 struct config_t {
     A(filter_t)        filters;
     A(filter_param_t)  params;
-    int entry_point;
+    int entry_points[SMTP_count];
 };
 
 __attribute__((nonnull(1)))
index 6556422..b7e2334 100644 (file)
@@ -137,17 +137,17 @@ filter_hook_t *filter_run(const filter_t *filter, const query_t *query)
 {
     int start = 0;
     int end   = filter->hooks.len;
-    syslog(LOG_DEBUG, "running filter %s (%s)",
-           filter->name, ftokens[filter->type]);
+    //syslog(LOG_DEBUG, "running filter %s (%s)",
+    //       filter->name, ftokens[filter->type]);
     filter_result_t res = runners[filter->type](filter, query);
-    syslog(LOG_DEBUG, "filter run, result is %s", htokens[res]);
+    //syslog(LOG_DEBUG, "filter run, result is %s", htokens[res]);
 
     while (start < end) {
         int mid = (start + end) / 2;
         filter_hook_t *hook = array_ptr(filter->hooks, mid);
         if (hook->type == res) {
-            syslog(LOG_DEBUG, "return hook of type %s, value %s",
-                   htokens[hook->type], hook->value);
+            //syslog(LOG_DEBUG, "return hook of type %s, value %s",
+            //       htokens[hook->type], hook->value);
             return hook;
         } else if (res < hook->type) {
             end = mid;
index b5dcb7b..ca58979 100644 (file)
@@ -51,7 +51,7 @@ typedef struct greylist_config_t {
 
 #define GREYLIST_INIT { .lookup_by_host = false,       \
                         .delay = 300,                  \
-                        .retry_window = 2 * 24 * 2600, \
+                        .retry_window = 2 * 24 * 3600, \
                         .client_awl = 5,               \
                         .awl_db = NULL,                \
                         .obj_db = NULL }
@@ -216,7 +216,7 @@ static bool try_greylist(const greylist_config_t *config,
 
             /* OK.
              */
-            syslog(LOG_INFO, "client whitelisted");
+            //syslog(LOG_INFO, "client whitelisted");
             return true;
         }
     }
@@ -260,13 +260,13 @@ static bool try_greylist(const greylist_config_t *config,
 
         /* OK
          */
-        syslog(LOG_INFO, "client whitelisted");
+        //syslog(LOG_INFO, "client whitelisted");
         return true;
     }
 
     /* DUNNO
      */
-    syslog(LOG_INFO, "client greylisted");
+    //syslog(LOG_INFO, "client greylisted");
     return false;
 }
 
@@ -351,7 +351,7 @@ static filter_result_t greylist_filter(const filter_t *filter,
     const greylist_config_t *config = filter->data;
     return try_greylist(config, query->sender, query->client_address,
                         query->client_name, query->recipient) ?
-           HTK_MATCH : HTK_FAIL;
+           HTK_WHITELIST : HTK_GREYLIST;
 }
 
 static int greylist_init(void)
@@ -362,8 +362,8 @@ static int greylist_init(void)
     /* Hooks.
      */
     (void)filter_hook_register(type, "error");
-    (void)filter_hook_register(type, "fail");
-    (void)filter_hook_register(type, "match");
+    (void)filter_hook_register(type, "greylist");
+    (void)filter_hook_register(type, "whitelist");
 
     /* Parameters.
      */
index a4241ff..e75965f 100644 (file)
@@ -67,6 +67,7 @@ static int postfix_parsejob(query_t *query, char *p)
     } while (0)
 
     p_clear(query, 1);
+    query->state = SMTP_UNKNOWN;
     while (*p != '\n') {
         char *k, *v;
         int klen, vlen, vtk;
@@ -87,7 +88,7 @@ static int postfix_parsejob(query_t *query, char *p)
 
         vtk = policy_tokenize(v, vlen);
         switch (policy_tokenize(k, klen)) {
-#define CASE(up, low)  case PTK_##up: query->low = v; v[vlen] = '\0'; break;
+#define CASE(up, low)  case PTK_##up: query->low = v; v[vlen] = '\0'; syslog(LOG_DEBUG, "%s = %s", ptokens[PTK_##up], query->low); break;
             CASE(HELO_NAME,           helo_name);
             CASE(QUEUE_ID,            queue_id);
             CASE(SENDER,              sender);
@@ -169,7 +170,13 @@ static void policy_answer(server_t *pcy, const char *fmt, ...)
 static void policy_process(server_t *pcy, config_t *config)
 {
     const query_t* query = pcy->data;
-    filter_t *filter = array_ptr(config->filters, config->entry_point);
+    filter_t *filter;
+    if (config->entry_points[query->state] == -1) {
+        syslog(LOG_WARNING, "no filter defined for current protocol_state (%d)", query->state);
+        policy_answer(pcy, "DUNNO");
+        return;
+    }
+    filter = array_ptr(config->filters, config->entry_points[query->state]);
     while (true) {
         filter_hook_t *hook = filter_run(filter, query);
         if (hook == NULL) {
index b11991c..d4d9596 100644 (file)
@@ -40,7 +40,6 @@
 #include "mem.h"
 
 enum smtp_state {
-    SMTP_UNKNOWN,
     SMTP_CONNECT,
     SMTP_EHLO,
     SMTP_HELO = SMTP_EHLO,
@@ -50,6 +49,8 @@ enum smtp_state {
     SMTP_END_OF_MESSAGE,
     SMTP_VRFY,
     SMTP_ETRN,
+    SMTP_count,
+    SMTP_UNKNOWN,
 };
 
 /* \see http://www.postfix.org/SMTPD_POLICY_README.html */