]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.6-20200930
authorWietse Venema <wietse@porcupine.org>
Wed, 30 Sep 2020 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 12 Oct 2020 01:32:45 +0000 (23:32 -0200)
19 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/mantools/postlink
postfix/proto/postconf.proto
postfix/src/dns/Makefile.in
postfix/src/dns/dns.h
postfix/src/dns/dns_lookup.c
postfix/src/dns/dns_sec.c [new file with mode: 0644]
postfix/src/dns/test_dns_lookup.c
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/smtp/smtp.c

index 5b9f68cb6868e4703b3135a33233585b8f44d29f..cc017256298377e75bfde055bce6ee6da69c41ca 100644 (file)
@@ -25171,3 +25171,15 @@ Apologies for any names omitted.
        looks for Delivered-To: headers ignored headers longer than
        $line_length_limit. Also added unit tests. File:
        global/delivered_hdr.c.
+
+20200930
+
+       Feature: when a Postfix program makes a DNS query that
+       requests DNSSEC validation (usually for Postfix DANE support)
+       but the DNS response is not DNSSEC validated, Postfix will
+       send a DNS query configured with the "dnssec_probe" parameter
+       to determine if DNSSEC support is available, and logs a
+       warning if it is not. By default, the probe has type "ns"
+       and domain name ".". The probe is sent once per process
+       lifetime. Files: dns/dns.h, dns/dns_lookup.c, dns/dns_sec.c,
+       test_dns_lookup.c.
index f9ce0ef5ca2ad73c6737e202c56c7ceec2e7f3f0..1f44e1593c33c57046ae1952fe2d0a9d112b5d46 100644 (file)
@@ -25,6 +25,31 @@ more recent Eclipse Public License 2.0. Recipients can choose to take
 the software under the license of their choice. Those who are more
 comfortable with the IPL can continue with that license.
 
+Major changes with snapshot 20200930
+====================================
+
+The dnssec_probe parameter specifies the DNS query type (default:
+"ns") and DNS query name (default: ".") that Postfix may use to
+determine whether DNSSEC validation is available. Specify an empty
+value to disable this feature.
+
+Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using opportunistic DANE will not be protected by
+server certificate info in TLSA records, and mail deliveries using
+mandatory DANE will not be made at all.
+
+By default, a Postfix process will send a DNSSEC probe after 1) the
+process made a DNS query that requested DNSSEC validation, 2) the
+process did not receive a DNSSEC validated response to this query
+or to an earlier query, and 3) the process did not already send a
+DNSSEC probe.
+
+When the DNSSEC probe has no response, or when the response is not
+DNSSEC validated, Postfix logs a warning that DNSSEC validation may
+be unavailable.
+
 Incompatible change with snapshot 20200920
 ==========================================
 
index 6ff3680d16d0e8472a3ff007c8b22292b387f7c2..b6c7990546af29ab4d6dbaa293ff639d9a7c7aee 100644 (file)
@@ -2,19 +2,32 @@ Wish list:
 
        Does tlsproxy terminate to soon after 'postfix reload'?
 
+       touch all files that contain Binfo_log_address_format
+       then re-generate manpages.
+
        The documented order of relay/recipient restrictions differs
        from the implementation. This may need a new compatibility
        parameter. For example:
        http://postfix.1071664.n5.nabble.com/Relay-attempt-questions-td103646.html
 
+       check_mumble_mx_access also generates synthetic MX records
+       i.e. A/AAAA where no MX exists.
+
+       Someone suggested adding References: and In-Reply-To: headers
+       in bounce messages. Downside: that will make it harder to
+       delete a bounce without deleting other mail. Therefore do
+       not enable by defalut.
+
        Hardening the half-dane behavior: some sites may rely on
        current behavior which allows original MX domain name for
        certificate matches. Requires a new (compatibility) parameter
        setting?
 
-       multi_server applications could be migrated to event_server;
-       after accept(), they would have to set up their own read
-       event callback for handling requests.
+       Code deduplication: migrate multi_server applications to
+       event_server. In addition to the default event_server
+       accept() handler, also register a read event callback for
+       handling post_accept events. But the currrent multi_server
+       API foits typical usage better.
 
        Maybe expand %m to "application error" when errno == 0.
 
index ec2370e96fcf28d5d2c7a53abb3c40b5c31a4b1e..f35557304d0a82b5b761a3b2afb6acbdb78df3a0 100644 (file)
@@ -361,10 +361,17 @@ SMTP(8)                                                                SMTP(8)
 
        Available in Postfix 3.5 and later:
 
-       <b>info_log_address_format (external)</b>
+       <b><a href="postconf.5.html#info_log_address_format">info_log_address_format</a> (external)</b>
               The  email  address  form that will be used in non-debug logging
               (info, warning, etc.).
 
+       Available in Postfix 3.6 and later:
+
+       <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b>
+              The DNS query type (default: "ns") and DNS query name  (default:
+              ".")  that Postfix may use to determine whether DNSSEC is avail-
+              able.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
index da454c37f1fbda6d7cf6a502df1d1dd8a118cc47..7efb19f79545aef36a028eb360baafe5dc4ef2a5 100644 (file)
@@ -3035,6 +3035,57 @@ service performs DNS white/blacklist lookups. </p>
 <p> This feature is available in Postfix 2.8 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="dnssec_probe">dnssec_probe</a>
+(default: ns:.)</b></DT><DD>
+
+<p> The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+</p>
+
+<p> Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using <i>opportunistic</i> DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using <i>mandatory</i> DANE will not be made at all. </p>
+
+<p> By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe. <p>
+
+<p> When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable. </p>
+
+<p> Possible reasons why DNSSEC validation may be unavailable: </p>
+
+<ul>
+
+<li> The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$<a href="postconf.5.html#queue_directory">queue_directory</a>/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+
+<li> The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+
+</ul>
+
+<p> By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty <a href="postconf.5.html#dnssec_probe">dnssec_probe</a>
+value to disable the feature. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="dont_remove">dont_remove</a>
@@ -4082,7 +4133,7 @@ characters in the localpart. </p>
 form that Postfix 3.2 and later prefer for most table lookups. This
 is therefore the more useful form for non-debug logging. </p>
 
-<p> Specify "<b>info_log_address_format = internal</b>" for backwards
+<p> Specify "<b><a href="postconf.5.html#info_log_address_format">info_log_address_format</a> = internal</b>" for backwards
 compatibility. </p>
 
 <p> Postfix uses the unquoted form internally, because an attacker
index ec2370e96fcf28d5d2c7a53abb3c40b5c31a4b1e..f35557304d0a82b5b761a3b2afb6acbdb78df3a0 100644 (file)
@@ -361,10 +361,17 @@ SMTP(8)                                                                SMTP(8)
 
        Available in Postfix 3.5 and later:
 
-       <b>info_log_address_format (external)</b>
+       <b><a href="postconf.5.html#info_log_address_format">info_log_address_format</a> (external)</b>
               The  email  address  form that will be used in non-debug logging
               (info, warning, etc.).
 
+       Available in Postfix 3.6 and later:
+
+       <b><a href="postconf.5.html#dnssec_probe">dnssec_probe</a> (ns:.)</b>
+              The DNS query type (default: "ns") and DNS query name  (default:
+              ".")  that Postfix may use to determine whether DNSSEC is avail-
+              able.
+
 <b>MIME PROCESSING CONTROLS</b>
        Available in Postfix version 2.0 and later:
 
index 95ea214830ef850c32eaf74900e4900664440a9f..bc7c54edf09d70e50ef292fce726c244b5c82b76 100644 (file)
@@ -1902,6 +1902,47 @@ The name of the \fBdnsblog\fR(8) service entry in master.cf. This
 service performs DNS white/blacklist lookups.
 .PP
 This feature is available in Postfix 2.8 and later.
+.SH dnssec_probe (default: ns:.)
+The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+.PP
+Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using \fIopportunistic\fR DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using \fImandatory\fR DANE will not be made at all.
+.PP
+By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe.
+.PP
+When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable.
+.PP
+Possible reasons why DNSSEC validation may be unavailable:
+.IP \(bu
+The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$queue_directory/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+.IP \(bu
+The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+.br
+.PP
+By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty dnssec_probe
+value to disable the feature.
+.PP
+This feature is available in Postfix 3.6 and later.
 .SH dont_remove (default: 0)
 Don't remove queue files and save them to the "saved" mail queue.
 This is a debugging aid.  To inspect the envelope information and
index 6f72db307126523484a3aabd62c251f3e52b1200..ad111897afa1b3d044b64d4d36df79a767b2f67a 100644 (file)
@@ -356,6 +356,11 @@ Available in Postfix 3.5 and later:
 .IP "\fBinfo_log_address_format (external)\fR"
 The email address form that will be used in non\-debug logging
 (info, warning, etc.).
+.PP
+Available in Postfix 3.6 and later:
+.IP "\fBdnssec_probe (ns:.)\fR"
+The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC is available.
 .SH "MIME PROCESSING CONTROLS"
 .na
 .nf
index b87e1eb801c32b8fe143e6bb1ff92733fa11dca2..556b4cde7461d339943d28c1510e8cdc23106093 100755 (executable)
@@ -695,6 +695,8 @@ while (<>) {
     s;\bsmtp_per_record_deadline\b;<a href="postconf.5.html#smtp_per_record_deadline">$&</a>;g;
     s;\bsmtp_send_dummy_mail_auth\b;<a href="postconf.5.html#smtp_send_dummy_mail_auth">$&</a>;g;
     s;\bsmtp_balance_inet_protocols\b;<a href="postconf.5.html#smtp_balance_inet_protocols">$&</a>;g;
+    s;\binfo_log_address_format\b;<a href="postconf.5.html#info_log_address_format">$&</a>;g;
+    s;\bdnssec_probe\b;<a href="postconf.5.html#dnssec_probe">$&</a>;g;
     s;\bsmtp_tls_connection_reuse\b;<a href="postconf.5.html#smtp_tls_connection_reuse">$&</a>;g;
     s;\blmtp_tls_connection_reuse\b;<a href="postconf.5.html#lmtp_tls_connection_reuse">$&</a>;g;
     s;\bsmtpd_enforce_tls\b;<a href="postconf.5.html#smtpd_enforce_tls">$&</a>;g;
index d317f43de9abc8ac56df465ba35ed7c511d5bdd1..768250b85dc2ae2a9fcd68df6dee5acd4cc24c9d 100644 (file)
@@ -17842,3 +17842,50 @@ smtpd_sasl_mechanism_filter = /etc/postfix/smtpd_mechs
 </pre>
 
 <p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM dnssec_probe ns:.
+
+<p> The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+</p>
+
+<p> Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using <i>opportunistic</i> DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using <i>mandatory</i> DANE will not be made at all. </p>
+
+<p> By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe. <p>
+
+<p> When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable. </p>
+
+<p> Possible reasons why DNSSEC validation may be unavailable: </p>
+
+<ul>
+
+<li> The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$queue_directory/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+
+<li> The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+
+</ul>
+
+<p> By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty dnssec_probe
+value to disable the feature. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
index aec91e0b5e2b656c4e7d42d5ddc94fcc6dd91dc9..795f9ba2a807de4203e94f0866f172f16b2e9243 100644 (file)
@@ -1,10 +1,10 @@
 SHELL  = /bin/sh
 SRCS   = dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c dns_rr_to_pa.c \
        dns_sa_to_rr.c dns_rr_eq_sa.c dns_rr_to_sa.c dns_strrecord.c \
-       dns_rr_filter.c dns_str_resflags.c
+       dns_rr_filter.c dns_str_resflags.c dns_sec.c
 OBJS   = dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o dns_rr_to_pa.o \
        dns_sa_to_rr.o dns_rr_eq_sa.o dns_rr_to_sa.o dns_strrecord.o \
-       dns_rr_filter.o dns_str_resflags.o
+       dns_rr_filter.o dns_str_resflags.o dns_sec.o
 HDRS   = dns.h
 TESTSRC        = test_dns_lookup.c test_alias_token.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
@@ -76,7 +76,7 @@ update: $(LIB_DIR)/$(LIB) $(HDRS)
        done
        cd $(INC_DIR); chmod 644 $(HDRS)
 
-test_dns_lookup: test_dns_lookup.c $(LIB) $(LIBS)
+test_dns_lookup: test_dns_lookup.c all $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
 dns_rr_to_pa: $(LIB) $(LIBS)
@@ -346,6 +346,18 @@ dns_sa_to_rr.o: ../../include/vbuf.h
 dns_sa_to_rr.o: ../../include/vstring.h
 dns_sa_to_rr.o: dns.h
 dns_sa_to_rr.o: dns_sa_to_rr.c
+dns_sec.o: ../../include/check_arg.h
+dns_sec.o: ../../include/mail_params.h
+dns_sec.o: ../../include/msg.h
+dns_sec.o: ../../include/myaddrinfo.h
+dns_sec.o: ../../include/mymalloc.h
+dns_sec.o: ../../include/sock_addr.h
+dns_sec.o: ../../include/split_at.h
+dns_sec.o: ../../include/sys_defs.h
+dns_sec.o: ../../include/vbuf.h
+dns_sec.o: ../../include/vstring.h
+dns_sec.o: dns.h
+dns_sec.o: dns_sec.c
 dns_str_resflags.o: ../../include/check_arg.h
 dns_str_resflags.o: ../../include/myaddrinfo.h
 dns_str_resflags.o: ../../include/name_mask.h
index 4182aceba4063452b61f78bfc5fb9d9902d3660f..26a346279af0ef10c1fb54ef811cfc4b557b61cf 100644 (file)
@@ -256,7 +256,12 @@ extern int dns_get_h_errno(void);
        (lflags), (ltype))
 
  /*
-  * Request flags.
+  * The dns_lookup() rflag that requests DNSSEC validation.
+  */
+#define DNS_WANT_DNSSEC_VALIDATION(rflags)      ((rflags) & RES_USE_DNSSEC)
+
+ /*
+  * lflags.
   */
 #define DNS_REQ_FLAG_STOP_OK   (1<<0)
 #define DNS_REQ_FLAG_STOP_INVAL        (1<<1)
@@ -321,6 +326,18 @@ extern int dns_rr_filter_execute(DNS_RR **);
   */
 const char *dns_str_resflags(unsigned long);
 
+ /*
+  * dns_sec.c.
+  */
+#define DNS_SEC_FLAG_AVAILABLE (1<<0)  /* got some DNSSEC validated reply */
+#define DNS_SEC_FLAG_DONT_PROBE        (1<<1)  /* probe already sent, or disabled */
+
+#define DNS_SEC_STATS_SET(flags) (dns_sec_stats |= (flags))
+#define DNS_SEC_STATS_TEST(flags) (dns_sec_stats & (flags))
+
+extern int dns_sec_stats;              /* See flags below */
+extern void dns_sec_probe(int);
+
 /* LICENSE
 /* .ad
 /* .fi
index 185f6baf6f3eec2501dbbcf341594fac6263b6ed..61375e23c9d0fafffe8304bb143a59f17464d996 100644 (file)
 /*     Pointer to storage for the reply RCODE value. This gives
 /*     more detailed information than DNS_FAIL, DNS_RETRY, etc.
 /* DIAGNOSTICS
+/*     If DNSSEC validation is requested but the response is not
+/*     DNSSEC validated, dns_lookup() will send a one-time probe
+/*     query as configured with the \fBdnssec_probe\fR configuration
+/*     parameter, and will log a warning when the probe response
+/*     was not DNSSEC validated.
+/* .PP
 /*     dns_lookup() returns one of the following codes and sets the
 /*     \fIwhy\fR argument accordingly:
 /* .IP DNS_OK
@@ -510,7 +516,7 @@ static int dns_query(const char *name, int type, unsigned flags,
      */
 #define XTRA_FLAGS (RES_USE_EDNS0 | RES_TRUSTAD)
 
-    if (flags & RES_USE_DNSSEC)
+    if (DNS_WANT_DNSSEC_VALIDATION(flags))
        flags |= (RES_USE_EDNS0 | RES_TRUSTAD);
 
     /*
@@ -557,6 +563,8 @@ static int dns_query(const char *name, int type, unsigned flags,
        dns_res_state.options |= saved_options;
        reply_header = (HEADER *) reply->buf;
        reply->rcode = reply_header->rcode;
+       if ((reply->dnssec_ad = !!reply_header->ad) != 0)
+           DNS_SEC_STATS_SET(DNS_SEC_FLAG_AVAILABLE);
        if (DNS_GET_H_ERRNO(&dns_res_state) != 0) {
            if (why)
                vstring_sprintf(why, "Host or domain name not found. "
@@ -610,13 +618,8 @@ static int dns_query(const char *name, int type, unsigned flags,
 
     /*
      * Initialize the reply structure. Some structure members are filled on
-     * the fly while the reply is being parsed.  Coerce AD bit to boolean.
+     * the fly while the reply is being parsed.
      */
-#if RES_USE_DNSSEC != 0
-    reply->dnssec_ad = (flags & RES_USE_DNSSEC) ? !!reply_header->ad : 0;
-#else
-    reply->dnssec_ad = 0;
-#endif
     SET_HAVE_DNS_REPLY_PACKET(reply, len);
     reply->query_start = reply->buf + sizeof(HEADER);
     reply->answer_start = 0;
@@ -934,7 +937,9 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
            CORRUPT(DNS_RETRY);
        if ((status = dns_get_fixed(pos, &fixed)) != DNS_OK)
            CORRUPT(status);
-       if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
+       if (strcmp(orig_name, ".") == 0 && *rr_name == 0)
+            /* Allow empty response name for root queries. */ ;
+       else if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
            CORRUPT(DNS_INVAL);
        if (fqdn)
            vstring_strcpy(fqdn, rr_name);
@@ -1022,7 +1027,7 @@ int     dns_lookup_x(const char *name, unsigned type, unsigned flags,
     /*
      * The Linux resolver misbehaves when given an invalid domain name.
      */
-    if (!valid_hostname(name, DONT_GRIPE)) {
+    if (strcmp(name, ".") && !valid_hostname(name, DONT_GRIPE)) {
        if (why)
            vstring_sprintf(why,
                   "Name service error for %s: invalid host or domain name",
@@ -1059,6 +1064,10 @@ int     dns_lookup_x(const char *name, unsigned type, unsigned flags,
                (void) dns_get_answer(orig_name, &reply, T_SOA, rrlist, fqdn,
                                      cname, c_len, &maybe_secure);
            }
+           if (DNS_WANT_DNSSEC_VALIDATION(flags)
+               && !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \
+                                      DNS_SEC_FLAG_DONT_PROBE))
+               dns_sec_probe(flags);           /* XXX Clobbers 'reply' */
            return (status);
        }
 
@@ -1068,6 +1077,10 @@ int     dns_lookup_x(const char *name, unsigned type, unsigned flags,
         */
        status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
                                cname, c_len, &maybe_secure);
+       if (DNS_WANT_DNSSEC_VALIDATION(flags)
+           && !DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE | \
+                                  DNS_SEC_FLAG_DONT_PROBE))
+           dns_sec_probe(flags);               /* XXX Clobbers 'reply' */
        switch (status) {
        default:
            if (why)
diff --git a/postfix/src/dns/dns_sec.c b/postfix/src/dns/dns_sec.c
new file mode 100644 (file)
index 0000000..cc1d5bc
--- /dev/null
@@ -0,0 +1,149 @@
+/*++
+/* NAME
+/*     dns_sec 3
+/* SUMMARY
+/*     DNSSEC validation availability
+/* SYNOPSIS
+/*     #include <dns.h>
+/*
+/*     DNS_SEC_STATS_SET(
+/*     int     flags)
+/*
+/*     DNS_SEC_STATS_TEST(
+/*     int     flags)
+/*
+/*     void    dns_sec_probe(
+/*     int     rflags)
+/* DESCRIPTION
+/*     This module maintains information about the availability of
+/*     DNSSEC validation, in global flags that summarize
+/*     process-lifetime history.
+/* .IP DNS_SEC_FLAG_AVAILABLE
+/*     The process has received at least one DNSSEC validated
+/*     response to a query that requested DNSSEC validation.
+/* .IP DNS_SEC_FLAG_DONT_PROBE
+/*     The process has sent a DNSSEC probe (see below), or DNSSEC
+/*     probing is disabled by configuration.
+/* .PP
+/*     DNS_SEC_STATS_SET() sets one or more DNS_SEC_FLAG_* flags,
+/*     and DNS_SEC_STATS_TEST() returns non-zero if any of the
+/*     specified flags is set.
+/*
+/*     dns_sec_probe() generates a query to the target specified
+/*     with the \fBdnssec_probe\fR configuration parameter. It
+/*     sets the DNS_SEC_FLAG_DONT_PROBE flag, and it calls
+/*     dns_lookup() which sets DNS_SEC_FLAG_AVAILABLE if it receives
+/*     a DNSSEC validated response. Preconditions:
+/* .IP \(bu
+/*     The rflags argument must request DNSSEC validation (in the
+/*     same manner as dns_lookup() rflags argument).
+/* .IP \(bu
+/*     The DNS_SEC_FLAG_AVAILABLE and DNS_SEC_FLAG_DONT_PROBE
+/*     flags must be false.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     Google, Inc.
+/*     111 8th Avenue
+/*     New York, NY 10011, USA
+/*--*/
+
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <mymalloc.h>
+#include <split_at.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * DNS library.
+  */
+#include <dns.h>
+
+int     dns_sec_stats;
+
+/* dns_sec_probe - send a probe to establish DNSSEC viability */
+
+void    dns_sec_probe(int rflags)
+{
+    const char myname[] = "dns_sec_probe";
+    char   *saved_dnssec_probe;
+    char   *qname;
+    int     qtype;
+    DNS_RR *rrlist = 0;
+    int     dns_status;
+    VSTRING *why;
+
+    /*
+     * Sanity checks.
+     */
+    if (!DNS_WANT_DNSSEC_VALIDATION(rflags))
+       msg_panic("%s: DNSSEC is not requested", myname);
+    if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_DONT_PROBE))
+       msg_panic("%s: DNSSEC probe was already sent, or probing is disabled",
+                 myname);
+    if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+       msg_panic("%s: already have validated DNS response", myname);
+
+    /*
+     * Don't recurse.
+     */
+    DNS_SEC_STATS_SET(DNS_SEC_FLAG_DONT_PROBE);
+
+    /*
+     * Don't probe.
+     */
+    if (*var_dnssec_probe == 0)
+       return;
+
+    /*
+     * Parse the probe spec. Format is type:resource.
+     */
+    saved_dnssec_probe = mystrdup(var_dnssec_probe);
+    if ((qname = split_at(saved_dnssec_probe, ':')) == 0 || *qname == 0
+       || (qtype = dns_type(saved_dnssec_probe)) == 0)
+       msg_fatal("malformed %s value: %s format is qtype:qname",
+                 VAR_DNSSEC_PROBE, var_dnssec_probe);
+
+    why = vstring_alloc(100);
+    dns_status = dns_lookup(qname, qtype, rflags, &rrlist, (char) 0, why);
+    switch (dns_status) {
+    default:
+       if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+           msg_warn(VAR_DNSSEC_PROBE
+                    " '%s' got a response that is not DNSSEC validated",
+                    var_dnssec_probe);
+       if (rrlist)
+           dns_rr_free(rrlist);
+       break;
+    case DNS_POLICY:
+       msg_warn(VAR_DNSSEC_PROBE
+                " '%s' response was deleted by DNS reply filter",
+                var_dnssec_probe);
+       break;
+    case DNS_RETRY:
+    case DNS_FAIL:
+       msg_warn(VAR_DNSSEC_PROBE " '%s' got no response: %s",
+                var_dnssec_probe, vstring_str(why));
+       break;
+    }
+    if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
+       msg_warn("DNSSEC support may be unavailable");
+    else if (msg_verbose)
+       msg_info(VAR_DNSSEC_PROBE
+                " '%s' got a response that is DNSSEC validated",
+                var_dnssec_probe);
+    myfree(saved_dnssec_probe);
+    vstring_free(why);
+}
index 003fc39928b38498b62d17c1296ed4f458e336b6..8366cf7c048f8c1faad592cf3f32cab04f7cb9d8 100644 (file)
@@ -77,6 +77,9 @@ int     main(int argc, char **argv)
     int     ch;
     int     lflags = DNS_REQ_FLAG_NONE;
 
+    if (var_dnssec_probe == 0)
+       var_dnssec_probe = mystrdup(DEF_DNSSEC_PROBE);
+
     msg_vstream_init(argv[0], VSTREAM_ERR);
     while ((ch = GETOPT(argc, argv, "f:npv")) > 0) {
        switch (ch) {
index 0efd00eda7d470d6bfd5c2ceee313c5eaf3b1084..b609c38a447aef1bfd4c7bddab36850a03b680af 100644 (file)
 /*     char    *var_maillog_file_comp;
 /*     char    *var_maillog_file_stamp;
 /*     char    *var_postlog_service;
+/*
+/*     char    *var_dnssec_probe;
 /* DESCRIPTION
 /*     This module (actually the associated include file) defines
 /*     the names and defaults of all mail configuration parameters.
@@ -366,6 +368,8 @@ char   *var_maillog_file_comp;
 char   *var_maillog_file_stamp;
 char   *var_postlog_service;
 
+char   *var_dnssec_probe;
+
 const char null_format_string[1] = "";
 
  /*
@@ -717,6 +721,7 @@ void    mail_params_init()
        VAR_MAILLOG_FILE_COMP, DEF_MAILLOG_FILE_COMP, &var_maillog_file_comp, 1, 0,
        VAR_MAILLOG_FILE_STAMP, DEF_MAILLOG_FILE_STAMP, &var_maillog_file_stamp, 1, 0,
        VAR_POSTLOG_SERVICE, DEF_POSTLOG_SERVICE, &var_postlog_service, 1, 0,
+       VAR_DNSSEC_PROBE, DEF_DNSSEC_PROBE, &var_dnssec_probe, 0, 0,
        0,
     };
     static const CONFIG_BOOL_TABLE first_bool_defaults[] = {
index 2578c7af1ad1032ded00ab124472490f0fd1c866..e41bffab4c86e2fc4062381ec4184e3ac528b59c 100644 (file)
@@ -4218,6 +4218,13 @@ extern int var_postlogd_watchdog;
 #define DEF_INFO_LOG_ADDR_FORM INFO_LOG_ADDR_FORM_NAME_EXTERNAL
 extern char *var_info_log_addr_form;
 
+ /*
+  * DNSSEC probing, to find out if DNSSEC validation is available.
+  */
+#define VAR_DNSSEC_PROBE       "dnssec_probe"
+#define DEF_DNSSEC_PROBE       "ns:."
+extern char *var_dnssec_probe;
+
 /* LICENSE
 /* .ad
 /* .fi
index 129950725efb410b0050db70b05ffc4bda5534ee..8c387cd1e85e04622525bf80f9fd2e1d08ee0f04 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20200925"
+#define MAIL_RELEASE_DATE      "20200930"
 #define MAIL_VERSION_NUMBER    "3.6"
 
 #ifdef SNAPSHOT
index ecab89f8d8a58f2c9bac73dd056dbbc8ae6ada99..a89dcdb03941d5256d49411c6cd264935cae8a77 100644 (file)
 /* .IP "\fBinfo_log_address_format (external)\fR"
 /*     The email address form that will be used in non-debug logging
 /*     (info, warning, etc.).
+/* .PP
+/*     Available in Postfix 3.6 and later:
+/* .IP "\fBdnssec_probe (ns:.)\fR"
+/*     The DNS query type (default: "ns") and DNS query name (default:
+/*     ".") that Postfix may use to determine whether DNSSEC is available.
 /* MIME PROCESSING CONTROLS
 /* .ad
 /* .fi