1 /* $NetBSD: dns_sec.c,v 1.2 2022/10/08 16:12:45 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* dns_sec 3 6 /* SUMMARY 7 /* DNSSEC validation availability 8 /* SYNOPSIS 9 /* #include <dns.h> 10 /* 11 /* DNS_SEC_STATS_SET( 12 /* int flags) 13 /* 14 /* DNS_SEC_STATS_TEST( 15 /* int flags) 16 /* 17 /* void dns_sec_probe( 18 /* int rflags) 19 /* DESCRIPTION 20 /* This module maintains information about the availability of 21 /* DNSSEC validation, in global flags that summarize 22 /* process-lifetime history. 23 /* .IP DNS_SEC_FLAG_AVAILABLE 24 /* The process has received at least one DNSSEC validated 25 /* response to a query that requested DNSSEC validation. 26 /* .IP DNS_SEC_FLAG_DONT_PROBE 27 /* The process has sent a DNSSEC probe (see below), or DNSSEC 28 /* probing is disabled by configuration. 29 /* .PP 30 /* DNS_SEC_STATS_SET() sets one or more DNS_SEC_FLAG_* flags, 31 /* and DNS_SEC_STATS_TEST() returns non-zero if any of the 32 /* specified flags is set. 33 /* 34 /* dns_sec_probe() generates a query to the target specified 35 /* with the \fBdnssec_probe\fR configuration parameter. It 36 /* sets the DNS_SEC_FLAG_DONT_PROBE flag, and it calls 37 /* dns_lookup() which sets DNS_SEC_FLAG_AVAILABLE if it receives 38 /* a DNSSEC validated response. Preconditions: 39 /* .IP \(bu 40 /* The rflags argument must request DNSSEC validation (in the 41 /* same manner as dns_lookup() rflags argument). 42 /* .IP \(bu 43 /* The DNS_SEC_FLAG_AVAILABLE and DNS_SEC_FLAG_DONT_PROBE 44 /* flags must be false. 45 /* LICENSE 46 /* .ad 47 /* .fi 48 /* The Secure Mailer license must be distributed with this software. 49 /* AUTHOR(S) 50 /* Wietse Venema 51 /* Google, Inc. 52 /* 111 8th Avenue 53 /* New York, NY 10011, USA 54 /*--*/ 55 56 #include <sys_defs.h> 57 58 /* 59 * Utility library. 60 */ 61 #include <msg.h> 62 #include <mymalloc.h> 63 #include <split_at.h> 64 #include <vstring.h> 65 66 /* 67 * Global library. 68 */ 69 #include <mail_params.h> 70 71 /* 72 * DNS library. 73 */ 74 #include <dns.h> 75 76 int dns_sec_stats; 77 78 /* dns_sec_probe - send a probe to establish DNSSEC viability */ 79 80 void dns_sec_probe(int rflags) 81 { 82 const char myname[] = "dns_sec_probe"; 83 char *saved_dnssec_probe; 84 char *qname; 85 int qtype; 86 DNS_RR *rrlist = 0; 87 int dns_status; 88 VSTRING *why; 89 90 /* 91 * Sanity checks. 92 */ 93 if (!DNS_WANT_DNSSEC_VALIDATION(rflags)) 94 msg_panic("%s: DNSSEC is not requested", myname); 95 if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_DONT_PROBE)) 96 msg_panic("%s: DNSSEC probe was already sent, or probing is disabled", 97 myname); 98 if (DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) 99 msg_panic("%s: already have validated DNS response", myname); 100 101 /* 102 * Don't recurse. 103 */ 104 DNS_SEC_STATS_SET(DNS_SEC_FLAG_DONT_PROBE); 105 106 /* 107 * Don't probe. 108 */ 109 if (*var_dnssec_probe == 0) 110 return; 111 112 /* 113 * Parse the probe spec. Format is type:resource. 114 */ 115 saved_dnssec_probe = mystrdup(var_dnssec_probe); 116 if ((qname = split_at(saved_dnssec_probe, ':')) == 0 || *qname == 0 117 || (qtype = dns_type(saved_dnssec_probe)) == 0) 118 msg_fatal("malformed %s value: %s format is qtype:qname", 119 VAR_DNSSEC_PROBE, var_dnssec_probe); 120 121 why = vstring_alloc(100); 122 dns_status = dns_lookup(qname, qtype, rflags, &rrlist, (VSTRING *) 0, why); 123 if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) 124 msg_warn("DNSSEC validation may be unavailable"); 125 else if (msg_verbose) 126 msg_info(VAR_DNSSEC_PROBE 127 " '%s' received a response that is DNSSEC validated", 128 var_dnssec_probe); 129 switch (dns_status) { 130 default: 131 if (!DNS_SEC_STATS_TEST(DNS_SEC_FLAG_AVAILABLE)) 132 msg_warn("reason: " VAR_DNSSEC_PROBE 133 " '%s' received a response that is not DNSSEC validated", 134 var_dnssec_probe); 135 if (rrlist) 136 dns_rr_free(rrlist); 137 break; 138 case DNS_RETRY: 139 case DNS_FAIL: 140 msg_warn("reason: " VAR_DNSSEC_PROBE " '%s' received no response: %s", 141 var_dnssec_probe, vstring_str(why)); 142 break; 143 } 144 myfree(saved_dnssec_probe); 145 vstring_free(why); 146 } 147