RFC 7505 ("Null MX") handling
authorop <op@openbsd.org>
Wed, 8 Nov 2023 08:46:34 +0000 (08:46 +0000)
committerop <op@openbsd.org>
Wed, 8 Nov 2023 08:46:34 +0000 (08:46 +0000)
mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@

usr.sbin/smtpd/dns.c
usr.sbin/smtpd/mta.c
usr.sbin/smtpd/smtpd.h

index 4cf5d23..dc7987a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.90 2021/06/14 17:58:15 eric Exp $   */
+/*     $OpenBSD: dns.c,v 1.91 2023/11/08 08:46:34 op Exp $     */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -232,10 +232,10 @@ dns_dispatch_mx(struct asr_result *ar, void *arg)
        struct dns_rr            rr;
        char                     buf[512];
        size_t                   found;
+       int                      nullmx = 0;
 
        if (ar->ar_h_errno && ar->ar_h_errno != NO_DATA &&
            ar->ar_h_errno != NOTIMP) {
-
                m_create(s->p,  IMSG_MTA_DNS_HOST_END, 0, 0, -1);
                m_add_id(s->p, s->reqid);
                if (ar->ar_rcode == NXDOMAIN)
@@ -259,13 +259,29 @@ dns_dispatch_mx(struct asr_result *ar, void *arg)
                unpack_rr(&pack, &rr);
                if (rr.rr_type != T_MX)
                        continue;
+
                print_dname(rr.rr.mx.exchange, buf, sizeof(buf));
                buf[strlen(buf) - 1] = '\0';
+
+               if (rr.rr.mx.preference == 0 && !strcmp(buf, "")) {
+                       nullmx = 1;
+                       continue;
+               }
+
                dns_lookup_host(s, buf, rr.rr.mx.preference);
                found++;
        }
        free(ar->ar_data);
 
+       if (nullmx && found == 0) {
+               m_create(s->p, IMSG_MTA_DNS_HOST_END, 0, 0, -1);
+               m_add_id(s->p, s->reqid);
+               m_add_int(s->p, DNS_NULLMX);
+               m_close(s->p);
+               free(s);
+               return;
+       }
+
        /* fallback to host if no MX is found. */
        if (found == 0)
                dns_lookup_host(s, s->name, 0);
index c0d0fc0..f0bb42c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mta.c,v 1.245 2023/05/31 16:51:46 op Exp $    */
+/*     $OpenBSD: mta.c,v 1.246 2023/11/08 08:46:35 op Exp $    */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -1088,6 +1088,10 @@ mta_on_mx(void *tag, void *arg, void *data)
                else
                        relay->failstr = "No MX found for domain";
                break;
+       case DNS_NULLMX:
+               relay->fail = IMSG_MTA_DELIVERY_PERMFAIL;
+               relay->failstr = "Domain does not accept mail";
+               break;
        default:
                fatalx("bad DNS lookup error code");
                break;
index 6781286..25090c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: smtpd.h,v 1.678 2023/09/29 18:30:14 op Exp $  */
+/*     $OpenBSD: smtpd.h,v 1.679 2023/11/08 08:46:35 op Exp $  */
 
 /*
  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -1026,6 +1026,8 @@ enum dns_error {
        DNS_EINVAL,
        DNS_ENONAME,
        DNS_ENOTFOUND,
+       /* RFC 7505 */
+       DNS_NULLMX,
 };
 
 enum lka_resp_status {