From 9fc48ba2176a71585c13cd346968bdba499e80de Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Tue, 16 Sep 2008 17:15:38 +0200 Subject: [PATCH] Can set an entry point per protocol-state. Signed-off-by: Florent Bruneau --- postlicyd/config.c | 69 ++++++++++++++++++++++++++++++++------ postlicyd/config.h | 2 +- postlicyd/filter.c | 10 +++--- postlicyd/greylist.c | 14 ++++---- postlicyd/main-postlicyd.c | 11 ++++-- postlicyd/query.h | 3 +- 6 files changed, 83 insertions(+), 26 deletions(-) diff --git a/postlicyd/config.c b/postlicyd/config.c index ec63480..0bd69e2 100644 --- a/postlicyd/config.c +++ b/postlicyd/config.c @@ -39,12 +39,45 @@ #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; diff --git a/postlicyd/config.h b/postlicyd/config.h index 00d4324..554fe96 100644 --- a/postlicyd/config.h +++ b/postlicyd/config.h @@ -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))) diff --git a/postlicyd/filter.c b/postlicyd/filter.c index 6556422..b7e2334 100644 --- a/postlicyd/filter.c +++ b/postlicyd/filter.c @@ -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; diff --git a/postlicyd/greylist.c b/postlicyd/greylist.c index b5dcb7b..ca58979 100644 --- a/postlicyd/greylist.c +++ b/postlicyd/greylist.c @@ -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. */ diff --git a/postlicyd/main-postlicyd.c b/postlicyd/main-postlicyd.c index a4241ff..e75965f 100644 --- a/postlicyd/main-postlicyd.c +++ b/postlicyd/main-postlicyd.c @@ -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) { diff --git a/postlicyd/query.h b/postlicyd/query.h index b11991c..d4d9596 100644 --- a/postlicyd/query.h +++ b/postlicyd/query.h @@ -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 */ -- 2.20.1