xref: /netbsd-src/external/ibm-public/postfix/dist/src/dns/dns_sec.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
1*67b9b338Schristos /*	$NetBSD: dns_sec.c,v 1.2 2022/10/08 16:12:45 christos Exp $	*/
24a672054Schristos 
34a672054Schristos /*++
44a672054Schristos /* NAME
54a672054Schristos /*	dns_sec 3
64a672054Schristos /* SUMMARY
74a672054Schristos /*	DNSSEC validation availability
84a672054Schristos /* SYNOPSIS
94a672054Schristos /*	#include <dns.h>
104a672054Schristos /*
114a672054Schristos /*	DNS_SEC_STATS_SET(
124a672054Schristos /*	int	flags)
134a672054Schristos /*
144a672054Schristos /*	DNS_SEC_STATS_TEST(
154a672054Schristos /*	int	flags)
164a672054Schristos /*
174a672054Schristos /*	void	dns_sec_probe(
184a672054Schristos /*	int	rflags)
194a672054Schristos /* DESCRIPTION
204a672054Schristos /*	This module maintains information about the availability of
214a672054Schristos /*	DNSSEC validation, in global flags that summarize
224a672054Schristos /*	process-lifetime history.
234a672054Schristos /* .IP DNS_SEC_FLAG_AVAILABLE
244a672054Schristos /*	The process has received at least one DNSSEC validated
254a672054Schristos /*	response to a query that requested DNSSEC validation.
264a672054Schristos /* .IP DNS_SEC_FLAG_DONT_PROBE
274a672054Schristos /*	The process has sent a DNSSEC probe (see below), or DNSSEC
284a672054Schristos /*	probing is disabled by configuration.
294a672054Schristos /* .PP
304a672054Schristos /*	DNS_SEC_STATS_SET() sets one or more DNS_SEC_FLAG_* flags,
314a672054Schristos /*	and DNS_SEC_STATS_TEST() returns non-zero if any of the
324a672054Schristos /*	specified flags is set.
334a672054Schristos /*
344a672054Schristos /*	dns_sec_probe() generates a query to the target specified
354a672054Schristos /*	with the \fBdnssec_probe\fR configuration parameter. It
364a672054Schristos /*	sets the DNS_SEC_FLAG_DONT_PROBE flag, and it calls
374a672054Schristos /*	dns_lookup() which sets DNS_SEC_FLAG_AVAILABLE if it receives
384a672054Schristos /*	a DNSSEC validated response. Preconditions:
394a672054Schristos /* .IP \(bu
404a672054Schristos /*	The rflags argument must request DNSSEC validation (in the
414a672054Schristos /*	same manner as dns_lookup() rflags argument).
424a672054Schristos /* .IP \(bu
434a672054Schristos /*	The DNS_SEC_FLAG_AVAILABLE and DNS_SEC_FLAG_DONT_PROBE
444a672054Schristos /*	flags must be false.
454a672054Schristos /* LICENSE
464a672054Schristos /* .ad
474a672054Schristos /* .fi
484a672054Schristos /*	The Secure Mailer license must be distributed with this software.
494a672054Schristos /* AUTHOR(S)
504a672054Schristos /*	Wietse Venema
514a672054Schristos /*	Google, Inc.
524a672054Schristos /*	111 8th Avenue
534a672054Schristos /*	New York, NY 10011, USA
544a672054Schristos /*--*/
554a672054Schristos 
564a672054Schristos #include <sys_defs.h>
574a672054Schristos 
584a672054Schristos  /*
594a672054Schristos   * Utility library.
604a672054Schristos   */
614a672054Schristos #include <msg.h>
624a672054Schristos #include <mymalloc.h>
634a672054Schristos #include <split_at.h>
644a672054Schristos #include <vstring.h>
654a672054Schristos 
664a672054Schristos  /*
674a672054Schristos   * Global library.
684a672054Schristos   */
694a672054Schristos #include <mail_params.h>
704a672054Schristos 
714a672054Schristos  /*
724a672054Schristos   * DNS library.
734a672054Schristos   */
744a672054Schristos #include <dns.h>
754a672054Schristos 
764a672054Schristos int     dns_sec_stats;
774a672054Schristos 
784a672054Schristos /* dns_sec_probe - send a probe to establish DNSSEC viability */
794a672054Schristos 
dns_sec_probe(int rflags)804a672054Schristos void    dns_sec_probe(int rflags)
814a672054Schristos {
824a672054Schristos     const char myname[] = "dns_sec_probe";
834a672054Schristos     char   *saved_dnssec_probe;
844a672054Schristos     char   *qname;
854a672054Schristos     int     qtype;
864a672054Schristos     DNS_RR *rrlist = 0;
874a672054Schristos     int     dns_status;
884a672054Schristos     VSTRING *why;
894a672054Schristos 
904a672054Schristos     /*
914a672054Schristos      * Sanity checks.
924a672054Schristos      */
934a672054Schristos     if (!DNS_WANT_DNSSEC_VALIDATION(rflags))
944a672054Schristos 	msg_panic("%s: DNSSEC is not requested", myname);
954a672054Schristos     if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_DONT_PROBE))
964a672054Schristos 	msg_panic("%s: DNSSEC probe was already sent, or probing is disabled",
974a672054Schristos 		  myname);
984a672054Schristos     if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
994a672054Schristos 	msg_panic("%s: already have validated DNS response", myname);
1004a672054Schristos 
1014a672054Schristos     /*
1024a672054Schristos      * Don't recurse.
1034a672054Schristos      */
1044a672054Schristos     DNS_SEC_STATS_SET(DNS_SEC_FLAG_DONT_PROBE);
1054a672054Schristos 
1064a672054Schristos     /*
1074a672054Schristos      * Don't probe.
1084a672054Schristos      */
1094a672054Schristos     if (*var_dnssec_probe == 0)
1104a672054Schristos 	return;
1114a672054Schristos 
1124a672054Schristos     /*
1134a672054Schristos      * Parse the probe spec. Format is type:resource.
1144a672054Schristos      */
1154a672054Schristos     saved_dnssec_probe = mystrdup(var_dnssec_probe);
1164a672054Schristos     if ((qname = split_at(saved_dnssec_probe, ':')) == 0 || *qname == 0
1174a672054Schristos 	|| (qtype = dns_type(saved_dnssec_probe)) == 0)
1184a672054Schristos 	msg_fatal("malformed %s value: %s format is qtype:qname",
1194a672054Schristos 		  VAR_DNSSEC_PROBE, var_dnssec_probe);
1204a672054Schristos 
1214a672054Schristos     why = vstring_alloc(100);
1224a672054Schristos     dns_status = dns_lookup(qname, qtype, rflags, &rrlist, (VSTRING *) 0, why);
1234a672054Schristos     if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
1244a672054Schristos 	msg_warn("DNSSEC validation may be unavailable");
1254a672054Schristos     else if (msg_verbose)
1264a672054Schristos 	msg_info(VAR_DNSSEC_PROBE
1274a672054Schristos 		 " '%s' received a response that is DNSSEC validated",
1284a672054Schristos 		 var_dnssec_probe);
1294a672054Schristos     switch (dns_status) {
1304a672054Schristos     default:
1314a672054Schristos 	if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE))
1324a672054Schristos 	    msg_warn("reason: " VAR_DNSSEC_PROBE
1334a672054Schristos 		     " '%s' received a response that is not DNSSEC validated",
1344a672054Schristos 		     var_dnssec_probe);
1354a672054Schristos 	if (rrlist)
1364a672054Schristos 	    dns_rr_free(rrlist);
1374a672054Schristos 	break;
1384a672054Schristos     case DNS_RETRY:
1394a672054Schristos     case DNS_FAIL:
1404a672054Schristos 	msg_warn("reason: " VAR_DNSSEC_PROBE " '%s' received no response: %s",
1414a672054Schristos 		 var_dnssec_probe, vstring_str(why));
1424a672054Schristos 	break;
1434a672054Schristos     }
1444a672054Schristos     myfree(saved_dnssec_probe);
1454a672054Schristos     vstring_free(why);
1464a672054Schristos }
147