On 22.09.24 18:46, Philipp wrote:
> [2024-09-22 16:04] Christian Schulte <c...@schulte.it>
>> On 22.09.24 15:35, Christian Schulte wrote:
>>> On 22.09.24 12:16, Philipp wrote:
>>>> [2024-09-22 09:39] Christian Schulte <c...@schulte.it>
>>>>>
>>>>> [snip]
>>>>>
>>>>
>>>> There are several problems:
>>>>
>>>> First of all it's not that simple to know for wich domains your server
>>>> is reponsible for. Yes you could check MX recourds and lookup the A
>>>> and AAAA records. But a negativ match isn't true, because you might
>>>> be a MX later in the chain or run behind some NAT.
>>>>
>>>> Next when you have a server for outgoing mails and one for incomming
>>>> mails the mails within the domain might just be relayed like any other
>>>> mail. This way the mails for the "own" domain also flowin like other
>>>> mails from extern. There are other setups where your check wouldn't
>>>> work.
>>
>> If a SMTP daemon does not know about which domains it is responsible
>> for, I would rate such a setup as broken by design. That would mean
>> someone has given up lots of control about the setup. Doing all kinds of
>> routing solely based on network addresses and such giving up on SMTP
>> semantics, I do not understand why that may make sense.
> 
> You miss the point.

Seems I missed a lot of points by just reading the man page. Would this be ok
to add? Adds a new domain-from keyword to the grammar, though.


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      22 Sep 2024 17:22:41 -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    22 Sep 2024 17:22:41 -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 22 Sep 2024 17:22:41 -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      22 Sep 2024 17:22:41 -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 22 Sep 2024 17:22:41 -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);

Reply via email to