summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2018-12-22 13:09:06 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2018-12-22 13:09:06 +0000
commite1d86d0d2b376fc4eca78c2e0688b8e32d83025e (patch)
tree02432ca7b1a1275bd97a00a155326b0e31c8f4a7 /usr.sbin
parentf3ea28ffaf36d59fc4519f0ae771b282702925a7 (diff)
introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/lka_filter.c42
-rw-r--r--usr.sbin/smtpd/parse.y17
-rw-r--r--usr.sbin/smtpd/smtpd.h8
3 files changed, 63 insertions, 4 deletions
diff --git a/usr.sbin/smtpd/lka_filter.c b/usr.sbin/smtpd/lka_filter.c
index 3daa57a390b..ea3074c5bfb 100644
--- a/usr.sbin/smtpd/lka_filter.c
+++ b/usr.sbin/smtpd/lka_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka_filter.c,v 1.27 2018/12/22 12:31:40 gilles Exp $ */
+/* $OpenBSD: lka_filter.c,v 1.28 2018/12/22 13:09:05 gilles Exp $ */
/*
* Copyright (c) 2018 Gilles Chehade <gilles@poolp.org>
@@ -841,6 +841,32 @@ filter_check_mail_from_regex(struct filter *filter, const char *key)
}
static int
+filter_check_rcpt_to_table(struct filter *filter, enum table_service kind, const char *key)
+{
+ int ret = 0;
+
+ if (filter->config->rcpt_to_table) {
+ if (table_lookup(filter->config->rcpt_to_table, NULL, key, kind, NULL) > 0)
+ ret = 1;
+ ret = filter->config->not_rcpt_to_table < 0 ? !ret : ret;
+ }
+ return ret;
+}
+
+static int
+filter_check_rcpt_to_regex(struct filter *filter, const char *key)
+{
+ int ret = 0;
+
+ if (filter->config->rcpt_to_regex) {
+ if (table_lookup(filter->config->rcpt_to_regex, NULL, key, K_REGEX, NULL) > 0)
+ ret = 1;
+ ret = filter->config->not_rcpt_to_regex < 0 ? !ret : ret;
+ }
+ return ret;
+}
+
+static int
filter_check_fcrdns(struct filter *filter, int fcrdns)
{
int ret = 0;
@@ -912,5 +938,17 @@ filter_builtins_mail_from(struct filter_session *fs, struct filter *filter, uint
static int
filter_builtins_rcpt_to(struct filter_session *fs, struct filter *filter, uint64_t reqid, const char *param)
{
- return filter_builtins_global(fs, filter, reqid, param);
+ int ret = 0;
+ char *rcpt_to;
+
+ rcpt_to = xstrdup(param + 1);
+ *strchr(rcpt_to, '>') = '\0';
+
+ if (filter_builtins_global(fs, filter, reqid, param) ||
+ filter_check_rcpt_to_table(filter, K_MAILADDR, rcpt_to) ||
+ filter_check_rcpt_to_regex(filter, rcpt_to))
+ ret = 1;
+
+ free(rcpt_to);
+ return ret;
}
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index f68ebe8eb6b..06d72d0fcd4 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.245 2018/12/22 12:31:40 gilles Exp $ */
+/* $OpenBSD: parse.y,v 1.246 2018/12/22 13:09:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1356,6 +1356,19 @@ negation MAIL_FROM REGEX tables {
}
;
+filter_phase_check_rcpt_to_table:
+negation RCPT_TO tables {
+ filter_config->not_rcpt_to_table = $1 ? -1 : 1;
+ filter_config->rcpt_to_table = $3;
+}
+;
+filter_phase_check_rcpt_to_regex:
+negation RCPT_TO REGEX tables {
+ filter_config->not_rcpt_to_regex = $1 ? -1 : 1;
+ filter_config->rcpt_to_regex = $4;
+}
+;
+
filter_phase_global_options:
filter_phase_check_fcrdns |
filter_phase_check_rdns |
@@ -1384,6 +1397,8 @@ filter_phase_check_helo_table |
filter_phase_check_helo_regex |
filter_phase_check_mail_from_table |
filter_phase_check_mail_from_regex |
+filter_phase_check_rcpt_to_table |
+filter_phase_check_rcpt_to_regex |
filter_phase_global_options;
filter_phase_data_options:
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index bcafee6085a..1e844880381 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.600 2018/12/22 12:31:40 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.601 2018/12/22 13:09:05 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1088,6 +1088,12 @@ struct filter_config {
int8_t not_mail_from_regex;
struct table *mail_from_regex;
+ int8_t not_rcpt_to_table;
+ struct table *rcpt_to_table;
+
+ int8_t not_rcpt_to_regex;
+ struct table *rcpt_to_regex;
+
};
enum filter_status {