+
+
+/* postlicyd filter declaration */
+
+#include "filter.h"
+
+static greylist_config_t *greylist_config_new(void)
+{
+ const greylist_config_t g = GREYLIST_INIT;
+ greylist_config_t *config = p_new(greylist_config_t, 1);
+ *config = g;
+ return config;
+}
+
+static void greylist_config_delete(greylist_config_t **config)
+{
+ if (*config) {
+ greylist_shutdown(*config);
+ p_delete(config);
+ }
+}
+
+static bool greylist_filter_constructor(filter_t *filter)
+{
+ const char* path = NULL;
+ const char* prefix = NULL;
+ greylist_config_t *config = greylist_config_new();
+
+#define PARSE_CHECK(Expr, Str, ...) \
+ if (!(Expr)) { \
+ err(Str, ##__VA_ARGS__); \
+ greylist_config_delete(&config); \
+ return false; \
+ }
+
+ foreach (filter_param_t *param, filter->params) {
+ switch (param->type) {
+ FILTER_PARAM_PARSE_STRING(PATH, path);
+ FILTER_PARAM_PARSE_STRING(PREFIX, prefix);
+ FILTER_PARAM_PARSE_BOOLEAN(LOOKUP_BY_HOST, config->lookup_by_host);
+ FILTER_PARAM_PARSE_INT(RETRY_WINDOW, config->retry_window);
+ FILTER_PARAM_PARSE_INT(CLIENT_AWL, config->client_awl);
+ FILTER_PARAM_PARSE_INT(DELAY, config->delay);
+ FILTER_PARAM_PARSE_INT(MAX_AGE, config->max_age);
+
+ default: break;
+ }
+ }}
+
+ PARSE_CHECK(path, "path to greylist db not given");
+ PARSE_CHECK(greylist_initialize(config, path, prefix ? prefix : ""),
+ "can not load greylist database");
+
+ filter->data = config;
+ return true;
+}
+
+static void greylist_filter_destructor(filter_t *filter)
+{
+ greylist_config_t *data = filter->data;
+ greylist_config_delete(&data);
+ filter->data = data;
+}
+
+static filter_result_t greylist_filter(const filter_t *filter,
+ const query_t *query,
+ filter_context_t *context)
+{
+ const greylist_config_t *config = filter->data;
+ if (query->state != SMTP_RCPT) {
+ warn("greylisting only works as smtpd_recipient_restrictions");
+ return HTK_ABORT;
+ }
+
+ return try_greylist(config, query->sender, query->client_address,
+ query->client_name, query->recipient) ?
+ HTK_WHITELIST : HTK_GREYLIST;
+}
+
+static int greylist_init(void)
+{
+ filter_type_t type = filter_register("greylist", greylist_filter_constructor,
+ greylist_filter_destructor,
+ greylist_filter, NULL, NULL);
+ /* Hooks.
+ */
+ (void)filter_hook_register(type, "abort");
+ (void)filter_hook_register(type, "error");
+ (void)filter_hook_register(type, "greylist");
+ (void)filter_hook_register(type, "whitelist");
+
+ /* Parameters.
+ */
+ (void)filter_param_register(type, "lookup_by_host");
+ (void)filter_param_register(type, "delay");
+ (void)filter_param_register(type, "retry_window");
+ (void)filter_param_register(type, "client_awl");
+ (void)filter_param_register(type, "max_age");
+ (void)filter_param_register(type, "path");
+ (void)filter_param_register(type, "prefix");
+ return 0;
+}
+module_init(greylist_init)