Download raw body.
smtpd.conf(5): Add domain-from match option in addition to mail-from
Sorry for disturbing you again. This has been discussed on the OpenSMTPD
mailing list, where I got pointed to the "correct" direction.
<https://www.mail-archive.com/misc@opensmtpd.org/msg06370.html>
Since I sent a patch to @tech, I somehow feel I should at least send the
corrected version here as well. My bad. I should not have sent anything like
this here in the first place.
All the diff adds is a domain-from match option modeled after the mail-from
match option with the only difference, that the domain-from match option will
be backed by a table of service K_DOMAIN instead of K_MAILADDR.
The discussion on the misc@opensmtpd.org mailing list ended with
Hi
Can you stop spamming me.
That's the last response I got after having used telnet on port 25 to
demonstrate that it's exactly about this kind of spamming I woud like to
get rid of. I take that response as a proof of concept. It should not have been
possible to send those mails without beeing authenticated in the first place.
So. Here's the final diff I will be running locally although I hate running
something great with patches. I got pointed to various options including
writing a table backend myself and got told that this would be flexibility.
No. I am not going to write a whole new table backend, when I just can run
OpenSMTPD with the following diff applied.
Sorry for stealing your time. You have better things to do, of course.
I can live with running OpenSMTPD with patches, although I really hate doing
that.
Index: usr.sbin/smtpd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v
retrieving revision 1.299
diff -u -p -u -r1.299 parse.y
--- usr.sbin/smtpd/parse.y 19 Feb 2024 21:00:19 -0000 1.299
+++ usr.sbin/smtpd/parse.y 24 Sep 2024 03:13:33 -0000
@@ -167,7 +167,7 @@ typedef struct {
%token ACTION ADMD ALIAS ANY ARROW AUTH AUTH_OPTIONAL
%token BACKUP BOUNCE BYPASS
%token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT
-%token DATA DATA_LINE DHE DISCONNECT DOMAIN
+%token DATA DATA_LINE DHE DISCONNECT DOMAIN DOMAIN_FROM
%token EHLO ENABLE ENCRYPTION ERROR EXPAND_ONLY
%token FCRDNS FILTER FOR FORWARD_ONLY FROM
%token GROUP
@@ -1129,6 +1129,41 @@ negation TAG REGEX tables {
rule->flag_smtp_auth_regex = 1;
rule->table_smtp_auth = strdup(t->t_name);
}
+| negation DOMAIN_FROM tables {
+ struct table *t = $3;
+
+ if (rule->flag_smtp_domain_from) {
+ yyerror("domain-from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST|T_HASH, K_DOMAIN)) {
+ yyerror("table \"%s\" may not be used for domain-from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_smtp_domain_from = $1 ? -1 : 1;
+ rule->table_smtp_domain_from = strdup(t->t_name);
+}
+| negation DOMAIN_FROM REGEX tables {
+ struct table *t = $4;
+
+ if (rule->flag_smtp_domain_from) {
+ yyerror("domain-from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_REGEX)) {
+ yyerror("table \"%s\" may not be used for domain-from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_smtp_domain_from = $1 ? -1 : 1;
+ rule->flag_smtp_domain_from_regex = 1;
+ rule->table_smtp_domain_from = strdup(t->t_name);
+}
| negation MAIL_FROM tables {
struct table *t = $3;
@@ -1363,6 +1398,48 @@ negation TAG REGEX tables {
rule->table_smtp_auth = strdup(t->t_name);
}
+| negation FROM DOMAIN_FROM tables {
+ struct table *anyhost = table_find(conf, "<anyhost>");
+ struct table *t = $4;
+
+ if (rule->flag_from) {
+ yyerror("from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST|T_HASH, K_DOMAIN)) {
+ yyerror("table \"%s\" may not be used for from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_from = 1;
+ rule->table_from = strdup(anyhost->t_name);
+ rule->flag_smtp_domain_from = $1 ? -1 : 1;
+ rule->table_smtp_domain_from = strdup(t->t_name);
+}
+| negation FROM DOMAIN_FROM REGEX tables {
+ struct table *anyhost = table_find(conf, "<anyhost>");
+ struct table *t = $5;
+
+ if (rule->flag_from) {
+ yyerror("from already specified for this rule");
+ YYERROR;
+ }
+
+ if (!table_check_use(t, T_DYNAMIC|T_LIST, K_REGEX)) {
+ yyerror("table \"%s\" may not be used for from lookups",
+ t->t_name);
+ YYERROR;
+ }
+
+ rule->flag_from = 1;
+ rule->table_from = strdup(anyhost->t_name);
+ rule->flag_smtp_domain_from = $1 ? -1 : 1;
+ rule->flag_smtp_domain_from_regex = 1;
+ rule->table_smtp_domain_from = strdup(t->t_name);
+}
+
| negation FROM MAIL_FROM tables {
struct table *anyhost = table_find(conf, "<anyhost>");
struct table *t = $4;
@@ -2667,6 +2744,7 @@ lookup(char *s)
{ "dhe", DHE },
{ "disconnect", DISCONNECT },
{ "domain", DOMAIN },
+ { "domain-from", DOMAIN_FROM },
{ "ehlo", EHLO },
{ "encryption", ENCRYPTION },
{ "expand-only", EXPAND_ONLY },
Index: usr.sbin/smtpd/ruleset.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/ruleset.c,v
retrieving revision 1.48
diff -u -p -u -r1.48 ruleset.c
--- usr.sbin/smtpd/ruleset.c 14 Jun 2021 17:58:16 -0000 1.48
+++ usr.sbin/smtpd/ruleset.c 24 Sep 2024 03:13:33 -0000
@@ -165,6 +165,27 @@ ruleset_match_smtp_auth(struct rule *r,
}
static int
+ruleset_match_smtp_domain_from(struct rule *r, const struct envelope *evp)
+{
+ int ret;
+ const char *key;
+ struct table *table;
+ enum table_service service = K_DOMAIN;
+
+ if (!r->flag_smtp_domain_from)
+ return 1;
+
+ if (r->flag_smtp_domain_from_regex)
+ service = K_REGEX;
+
+ key = evp->sender.domain;
+ table = table_find(env, r->table_smtp_domain_from);
+ ret = table_match(table, service, key);
+
+ return MATCH_RESULT(ret, r->flag_smtp_domain_from);
+}
+
+static int
ruleset_match_smtp_mail_from(struct rule *r, const struct envelope *evp)
{
int ret;
@@ -230,6 +251,7 @@ ruleset_match(const struct envelope *evp
MATCH_EVAL(ruleset_match_smtp_helo(r, evp));
MATCH_EVAL(ruleset_match_smtp_auth(r, evp));
MATCH_EVAL(ruleset_match_smtp_starttls(r, evp));
+ MATCH_EVAL(ruleset_match_smtp_domain_from(r, evp));
MATCH_EVAL(ruleset_match_smtp_mail_from(r, evp));
MATCH_EVAL(ruleset_match_smtp_rcpt_to(r, evp));
goto matched;
Index: usr.sbin/smtpd/smtpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v
retrieving revision 1.272
diff -u -p -u -r1.272 smtpd.conf.5
--- usr.sbin/smtpd/smtpd.conf.5 26 Jul 2024 06:24:52 -0000 1.272
+++ usr.sbin/smtpd/smtpd.conf.5 24 Sep 2024 03:13:33 -0000
@@ -675,6 +675,22 @@ or from the local enqueuer.
This is the default, and may be omitted.
.It Xo
.Op Ic \&!
+.Cm from domain-from
+.Ar domain | Pf < Ar domain Ns >
+.Xc
+Specify that session may originate from sender domain or sender domain list
+.Ar domain ,
+no matter the source IP address.
+.It Xo
+.Op Ic \&!
+.Cm from domain-from regex
+.Ar domain | Pf < Ar domain Ns >
+.Xc
+Specify that session may originate from regex or regex list
+.Ar domain ,
+no matter the source IP address.
+.It Xo
+.Op Ic \&!
.Cm from mail-from
.Ar sender | Pf < Ar sender Ns >
.Xc
Index: usr.sbin/smtpd/smtpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v
retrieving revision 1.688
diff -u -p -u -r1.688 smtpd.h
--- usr.sbin/smtpd/smtpd.h 3 Sep 2024 12:07:40 -0000 1.688
+++ usr.sbin/smtpd/smtpd.h 24 Sep 2024 03:13:33 -0000
@@ -1236,12 +1236,14 @@ struct rule {
int8_t flag_smtp_helo;
int8_t flag_smtp_starttls;
int8_t flag_smtp_auth;
+ int8_t flag_smtp_domain_from;
int8_t flag_smtp_mail_from;
int8_t flag_smtp_rcpt_to;
int8_t flag_smtp_helo_regex;
int8_t flag_smtp_starttls_regex;
int8_t flag_smtp_auth_regex;
+ int8_t flag_smtp_domain_from_regex;
int8_t flag_smtp_mail_from_regex;
int8_t flag_smtp_rcpt_to_regex;
@@ -1252,6 +1254,7 @@ struct rule {
char *table_smtp_helo;
char *table_smtp_auth;
+ char *table_smtp_domain_from;
char *table_smtp_mail_from;
char *table_smtp_rcpt_to;
Index: usr.sbin/smtpd/to.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/to.c,v
retrieving revision 1.50
diff -u -p -u -r1.50 to.c
--- usr.sbin/smtpd/to.c 31 May 2023 16:51:46 -0000 1.50
+++ usr.sbin/smtpd/to.c 24 Sep 2024 03:13:33 -0000
@@ -480,6 +480,13 @@ rule_to_text(struct rule *r)
(void)strlcat(buf, " tls", sizeof buf);
}
+ if (r->flag_smtp_domain_from) {
+ if (r->flag_smtp_domain_from < 0)
+ (void)strlcat(buf, " !", sizeof buf);
+ (void)strlcat(buf, " domain-from ", sizeof buf);
+ (void)strlcat(buf, r->table_smtp_domain_from, sizeof buf);
+ }
+
if (r->flag_smtp_mail_from) {
if (r->flag_smtp_mail_from < 0)
(void)strlcat(buf, " !", sizeof buf);
smtpd.conf(5): Add domain-from match option in addition to mail-from