]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/sendmail/src/domain.c
Merge commit '850ef5ae11d69ea3381bd310f564f025fc8caea3'
[FreeBSD/FreeBSD.git] / contrib / sendmail / src / domain.c
1 /*
2  * Copyright (c) 1998-2004, 2006, 2010, 2020-2023 Proofpoint, Inc. and its suppliers.
3  *      All rights reserved.
4  * Copyright (c) 1986, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13
14 #include <sendmail.h>
15 #include "map.h"
16
17 #if NAMED_BIND
18 SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (with name server)")
19 #else
20 SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (without name server)")
21 #endif
22
23 #include <sm/sendmail.h>
24
25 #if NAMED_BIND
26 # include <arpa/inet.h>
27 # include "sm_resolve.h"
28 # if DANE
29 #  include <tls.h>
30 #  ifndef SM_NEG_TTL
31 #   define SM_NEG_TTL 60 /* "negative" TTL */
32 #  endif
33 # endif
34
35 #if USE_EAI
36 #include <unicode/uidna.h>
37 #endif
38
39
40 # ifndef MXHOSTBUFSIZE
41 #  define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
42 # endif
43
44 static char     MXHostBuf[MXHOSTBUFSIZE];
45 # if (MXHOSTBUFSIZE < 2) || (MXHOSTBUFSIZE >= INT_MAX/2)
46         ERROR: _MXHOSTBUFSIZE is out of range
47 # endif
48
49 # ifndef MAXDNSRCH
50 #  define MAXDNSRCH     6       /* number of possible domains to search */
51 # endif
52
53 # ifndef RES_DNSRCH_VARIABLE
54 #  define RES_DNSRCH_VARIABLE   _res.dnsrch
55 # endif
56
57 # ifndef HFIXEDSZ
58 #  define HFIXEDSZ      12      /* sizeof(HEADER) */
59 # endif
60
61 # define MAXCNAMEDEPTH  10      /* maximum depth of CNAME recursion */
62
63 # if defined(__RES) && (__RES >= 19940415)
64 #  define RES_UNC_T     char *
65 # else
66 #  define RES_UNC_T     unsigned char *
67 # endif
68
69 static int      mxrand __P((char *));
70 static int      fallbackmxrr __P((int, unsigned short *, char **));
71
72 # if DANE
73
74 static void tlsa_rr_print __P((const unsigned char *, unsigned int));
75
76 static void
77 tlsa_rr_print(rr, len)
78         const unsigned char *rr;
79         unsigned int len;
80 {
81         unsigned int i, l;
82
83         if (!tTd(8, 2))
84                 return;
85
86         sm_dprintf("len=%u, %02x-%02x-%02x",
87                 len, (int)rr[0], (int)rr[1], (int)rr[2]);
88         l = tTd(8, 8) ? len : 4;
89         for (i = 3; i < l; i++)
90                 sm_dprintf(":%02X", (int)rr[i]);
91         sm_dprintf("\n");
92 }
93
94 /*
95 **  TLSA_RR_CMP -- Compare two TLSA RRs
96 **
97 **      Parameters:
98 **              rr1 -- TLSA RR (entry to be added)
99 **              l1 -- length of rr1
100 **              rr2 -- TLSA RR
101 **              l2 -- length of rr2
102 **
103 **      Returns:
104 **               0: rr1 == rr2
105 **               1: rr1 is unsupported
106 */
107
108 static int tlsa_rr_cmp __P((unsigned char *, int, unsigned char *, int));
109
110 static int
111 tlsa_rr_cmp(rr1, l1, rr2, l2)
112         unsigned char *rr1;
113         int l1;
114         unsigned char *rr2;
115         int l2;
116 {
117 /* temporary #if while investigating the implications of the alternative */
118 #if FULL_COMPARE
119         unsigned char r1, r2;
120         int cmp;
121 #endif /* FULL_COMPARE */
122
123         SM_REQUIRE(NULL != rr1);
124         SM_REQUIRE(NULL != rr2);
125         SM_REQUIRE(l1 > 3);
126         SM_REQUIRE(l2 > 3);
127
128 #if FULL_COMPARE
129         /*
130         **  certificate usage
131         **  3: cert/fp must match
132         **  2: cert/fp must be trust anchor
133         */
134
135         /* preference[]: lower value: higher preference */
136         r1 = rr1[0];
137         r2 = rr2[0];
138         if (r1 != r2)
139         {
140                 int preference[] = { 3, 2, 1, 0 };
141
142                 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
143                 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
144                 return preference[r1] - preference[r2];
145         }
146
147         /*
148         **  selector:
149         **  0: full cert
150         **  1: fp
151         */
152
153         r1 = rr1[1];
154         r2 = rr2[1];
155         if (r1 != r2)
156         {
157                 int preference[] = { 1, 0 };
158
159                 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
160                 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
161                 return preference[r1] - preference[r2];
162         }
163
164         /*
165         **  matching type:
166         **  0 -- Exact match
167         **  1 -- SHA-256 hash
168         **  2 -- SHA-512 hash
169         */
170
171         r1 = rr1[2];
172         r2 = rr2[2];
173         if (r1 != r2)
174         {
175                 int preference[] = { 2, 0, 1 };
176
177                 SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
178                 SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
179                 return preference[r1] - preference[r2];
180         }
181
182         /* not the same length despite the same type? */
183         if (l1 != l2)
184                 return 1;
185         cmp = memcmp(rr1, rr2, l1);
186         if (0 == cmp)
187                 return 0;
188         return 1;
189 #else /* FULL_COMPARE */
190         /* identical? */
191         if (l1 == l2 && 0 == memcmp(rr1, rr2, l1))
192                 return 0;
193
194         /* new entry is unsupported? -> append */
195         if (TLSA_UNSUPP == dane_tlsa_chk(rr1, l1, "", false))
196                 return 1;
197         /* current entry is unsupported? -> insert new one */
198         if (TLSA_UNSUPP == dane_tlsa_chk(rr2, l2, "", false))
199                 return -1;
200
201         /* default: preserve order */
202         return 1;
203 #endif /* FULL_COMPARE */
204 }
205
206 /*
207 **  TLSAINSERT -- Insert a TLSA RR
208 **
209 **      Parameters:
210 **              dane_tlsa -- dane_tlsa entry
211 **              rr -- TLSA RR
212 **              pn -- (point to) number of entries
213 **
214 **      Returns:
215 **              SM_SUCCESS: rr inserted
216 **              SM_NOTDONE: rr not inserted: exists
217 **              SM_FULL: rr not inserted: no space left
218 */
219
220 static int tlsainsert __P((dane_tlsa_P, RESOURCE_RECORD_T *, int *));
221
222 static int
223 tlsainsert(dane_tlsa, rr, pn)
224         dane_tlsa_P dane_tlsa;
225         RESOURCE_RECORD_T *rr;
226         int *pn;
227 {
228         int i, l1, ret;
229         unsigned char *r1;
230
231         SM_ASSERT(pn != NULL);
232         SM_ASSERT(*pn <= MAX_TLSA_RR);
233         r1 = rr->rr_u.rr_data;
234         l1 = rr->rr_size;
235
236         ret = SM_SUCCESS;
237         for (i = 0; i < *pn; i++)
238         {
239                 int r, j;
240
241                 r = tlsa_rr_cmp(r1, l1, dane_tlsa->dane_tlsa_rr[i],
242                         dane_tlsa->dane_tlsa_len[i]);
243
244                 if (0 == r)
245                 {
246                         if (tTd(8, 80))
247                                 sm_dprintf("func=tlsainsert, i=%d, n=%d, status=exists\n", i, *pn);
248                         ret = SM_NOTDONE;
249                         goto done;
250                 }
251                 if (r > 0)
252                         continue;
253
254                 if (*pn + 1 >= MAX_TLSA_RR)
255                 {
256                         j = MAX_TLSA_RR - 1;
257                         SM_FREE(dane_tlsa->dane_tlsa_rr[j]);
258                         dane_tlsa->dane_tlsa_len[j] = 0;
259                 }
260                 else
261                         (*pn)++;
262
263                 for (j = MAX_TLSA_RR - 2; j >= i; j--)
264                 {
265                         dane_tlsa->dane_tlsa_rr[j + 1] = dane_tlsa->dane_tlsa_rr[j];
266                         dane_tlsa->dane_tlsa_len[j + 1] = dane_tlsa->dane_tlsa_len[j];
267                 }
268                 SM_ASSERT(i < MAX_TLSA_RR);
269                 dane_tlsa->dane_tlsa_rr[i] = r1;
270                 dane_tlsa->dane_tlsa_len[i] = l1;
271                 if (tTd(8, 80))
272                         sm_dprintf("func=tlsainsert, i=%d, n=%d, status=inserted\n", i, *pn);
273                 goto added;
274         }
275
276         if (*pn + 1 <= MAX_TLSA_RR)
277         {
278                 dane_tlsa->dane_tlsa_rr[*pn] = r1;
279                 dane_tlsa->dane_tlsa_len[*pn] = l1;
280                 (*pn)++;
281                 if (tTd(8, 80))
282                         sm_dprintf("func=tlsainsert, n=%d, status=appended\n", *pn);
283         }
284         else
285         {
286                 if (tTd(8, 80))
287                         sm_dprintf("func=tlsainsert, n=%d, status=full\n", *pn);
288                 return SM_FULL;
289         }
290
291   added:
292         /* hack: instead of copying the data, just "take it over" */
293         rr->rr_u.rr_data = NULL;
294   done:
295         return ret;
296 }
297
298 /*
299 **  TLSAADD -- add TLSA records to dane_tlsa entry
300 **
301 **      Parameters:
302 **              name -- key for stab entry (for debugging output)
303 **              dr -- DNS reply
304 **              dane_tlsa -- dane_tlsa entry
305 **              dnsrc -- DNS lookup return code (h_errno)
306 **              nr -- current number of TLSA records in dane_tlsa entry
307 **              pttl -- (pointer to) TTL (in/out)
308 **              level -- recursion level (CNAMEs)
309 **
310 **      Returns:
311 **              new number of TLSA records
312 **
313 **      NOTE: the array for TLSA RRs could be "full" which is not
314 **              handled well (yet).
315 */
316
317 static int tlsaadd __P((const char *, DNS_REPLY_T *, dane_tlsa_P, int, int,
318                         unsigned int *, int));
319
320 static int
321 tlsaadd(name, dr, dane_tlsa, dnsrc, nr, pttl, level)
322         const char *name;
323         DNS_REPLY_T *dr;
324         dane_tlsa_P dane_tlsa;
325         int dnsrc;
326         int nr;
327         unsigned int *pttl;
328         int level;
329 {
330         RESOURCE_RECORD_T *rr;
331         unsigned int ttl;
332         int nprev;
333
334         if (dnsrc != 0)
335         {
336                 if (tTd(8, 2))
337                         sm_dprintf("tlsaadd, name=%s, prev=%d, dnsrc=%d\n",
338                                 name, dane_tlsa->dane_tlsa_dnsrc, dnsrc);
339
340                 /* check previous error and keep the "most important" one? */
341                 dane_tlsa->dane_tlsa_dnsrc = dnsrc;
342 #  if DNSSEC_TEST
343                 if (tTd(8, 110))
344                         *pttl = tTdlevel(8)-110; /* how to make this an option? */
345                 else
346 #  endif
347                 /* "else" in #if code above */
348                         *pttl = SM_NEG_TTL;
349                 return nr;
350         }
351         if (dr == NULL)
352                 return nr;
353         if (dr->dns_r_h.ad != 1 && Dane == DANE_SECURE) /* not secure? */
354                 return nr;
355         ttl = *pttl;
356
357         /* first: try to find TLSA records */
358         nprev = nr;
359         for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
360         {
361                 int tlsa_chk, r;
362
363                 if (rr->rr_type != T_TLSA)
364                 {
365                         if (rr->rr_type != T_CNAME && tTd(8, 8))
366                                 sm_dprintf("tlsaadd: name=%s, type=%s\n", name,
367                                         dns_type_to_string(rr->rr_type));
368                         continue;
369                 }
370                 tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data, rr->rr_size, name,
371                                         true);
372                 if (TLSA_UNSUPP == tlsa_chk)
373                         TLSA_SET_FL(dane_tlsa, TLSAFLUNS);
374                 if (!TLSA_IS_VALID(tlsa_chk))
375                         continue;
376                 if (TLSA_IS_SUPPORTED(tlsa_chk))
377                         TLSA_SET_FL(dane_tlsa, TLSAFLSUP);
378
379                 /*
380                 **  Note: rr_u.rr_data might be NULL after tlsainsert()
381                 **  for nice debug output: print the data into a string
382                 **  and then use it after tlsainsert().
383                 */
384
385                 if (tTd(8, 2))
386                 {
387                         sm_dprintf("tlsaadd: name=%s, nr=%d, ", name, nr);
388                         tlsa_rr_print(rr->rr_u.rr_data, rr->rr_size);
389                 }
390                 r = tlsainsert(dane_tlsa, rr, &nr);
391                 if (SM_FULL == r)
392                         TLSA_SET_FL(dane_tlsa, TLSAFL2MANY);
393                 if (tTd(8, 2))
394                         sm_dprintf("tlsainsert=%d, nr=%d\n", r, nr);
395
396                 /* require some minimum TTL? */
397                 if (ttl > rr->rr_ttl && rr->rr_ttl > 0)
398                         ttl = rr->rr_ttl;
399         }
400
401         if (tTd(8, 2))
402         {
403                 unsigned int ui;
404
405                 SM_ASSERT(nr <= MAX_TLSA_RR);
406                 for (ui = 0; ui < (unsigned int)nr; ui++)
407                 {
408                         sm_dprintf("tlsaadd: name=%s, ui=%u, ", name, ui);
409                         tlsa_rr_print(dane_tlsa->dane_tlsa_rr[ui],
410                                 dane_tlsa->dane_tlsa_len[ui]);
411                 }
412         }
413
414         if (TLSA_IS_FL(dane_tlsa, TLSAFL2MANY))
415         {
416                 if (tTd(8, 20))
417                         sm_dprintf("tlsaadd: name=%s, rr=%p, nr=%d, toomany=%d\n", name, rr, nr, TLSA_IS_FL(dane_tlsa, TLSAFL2MANY));
418         }
419
420         /* second: check for CNAME records, but only if no TLSA RR was added */
421         for (rr = dr->dns_r_head; rr != NULL && nprev == nr; rr = rr->rr_next)
422         {
423                 DNS_REPLY_T *drc;
424                 int err, herr;
425
426                 if (rr->rr_type != T_CNAME)
427                         continue;
428                 if (level > 1)
429                 {
430                         if (tTd(8, 2))
431                                 sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d\n",
432                                         name, rr->rr_u.rr_txt, level);
433                         continue;
434                 }
435
436                 drc = dns_lookup_int(rr->rr_u.rr_txt, C_IN, T_TLSA, 0, 0,
437                         Dane == DANE_SECURE ? SM_RES_DNSSEC : 0,
438                         RR_RAW, &err, &herr);
439
440                 if (tTd(8, 2))
441                         sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d, dr=%p, ad=%d, err=%d, herr=%d\n",
442                                 name, rr->rr_u.rr_txt, level,
443                                 (void *)drc, drc != NULL ? drc->dns_r_h.ad : -1,
444                                 err, herr);
445                 nprev = nr = tlsaadd(name, drc, dane_tlsa, herr, nr, pttl,
446                                 level + 1);
447                 dns_free_data(drc);
448                 drc = NULL;
449         }
450
451         if (TLSA_IS_FL(dane_tlsa, TLSAFLUNS) &&
452             !TLSA_IS_FL(dane_tlsa, TLSAFLSUP) && LogLevel > 9)
453         {
454                 sm_syslog(LOG_NOTICE, NOQID,
455                           "TLSA=%s, records=%d%s",
456                           name, nr, ONLYUNSUPTLSARR);
457         }
458         *pttl = ttl;
459         return nr;
460 }
461
462 /*
463 **  GETTLSA -- get TLSA records for named host using DNS
464 **
465 **      Parameters:
466 **              host -- host
467 **              name -- name for stab entry key (if NULL: host)
468 **              pste -- (pointer to) stab entry (output)
469 **              flags -- TLSAFL*
470 **              mxttl -- TTL of MX (or host)
471 **              port -- port number used in TLSA queries (_PORT._tcp.)
472 **
473 **      Returns:
474 **              The number of TLSA records found.
475 **              <0 if there is an internal failure.
476 **
477 **      Side effects:
478 **              Enters TLSA RRs into stab().
479 **              If the DNS lookup fails temporarily, an "empty" entry is
480 **              created with that DNS error code.
481 */
482
483 int
484 gettlsa(host, name, pste, flags, mxttl, port)
485         char *host;
486         char *name;
487         STAB **pste;
488         unsigned long flags;
489         unsigned int mxttl;
490         unsigned int port;
491 {
492         DNS_REPLY_T *dr;
493         dane_tlsa_P dane_tlsa;
494         STAB *ste;
495         time_t now;
496         unsigned int ttl;
497         int n_rrs, len, err, herr;
498         bool isrname, expired;
499         char nbuf[MAXDNAME];
500         char key[MAXDNAME];
501
502         SM_REQUIRE(host != NULL);
503         if (pste != NULL)
504                 *pste = NULL;
505         if ('\0' == *host)
506                 return 0;
507
508         expired = false;
509         isrname = NULL == name;
510         if (isrname)
511                 name = host;
512
513         /*
514         **  If host->MX lookup was not secure then do not look up TLSA RRs.
515         **  Note: this is currently a hack: TLSAFLADMX is used as input flag,
516         **  it is (SHOULD!) NOT stored in dane_tlsa->dane_tlsa_flags
517         */
518
519         if (DANE_SECURE == Dane && 0 == (TLSAFLADMX & flags) &&
520             0 != (TLSAFLNEW & flags))
521         {
522                 if (tTd(8, 2))
523                         sm_dprintf("gettlsa: host=%s, flags=%#lx, no ad but Dane=Secure\n",
524                                 host, flags);
525                 return 0;
526         }
527
528         now = 0;
529         n_rrs = 0;
530         dr = NULL;
531         dane_tlsa = NULL;
532         len = strlen(name);
533         if (len > 1 && name[len - 1] == '.')
534         {
535                 len--;
536                 name[len] = '\0';
537         }
538         else
539                 len = -1;
540         if (0 == port || tTd(66, 101))
541                 port = 25;
542         (void) sm_snprintf(key, sizeof(key), "_%u.%s", port, name);
543         ste = stab(key, ST_TLSA_RR, ST_FIND);
544         if (tTd(8, 2))
545                 sm_dprintf("gettlsa: host=%s, %s, ste=%p, pste=%p, flags=%#lx, port=%d\n",
546                         host, isrname ? "" : name, (void *)ste, (void *)pste,
547                         flags, port);
548
549         if (ste != NULL)
550                 dane_tlsa = ste->s_tlsa;
551
552 #if 0
553 //      /* Do not reload TLSA RRs if the MX RRs were not securely retrieved. */
554 //      if (pste != NULL
555 //          && dane_tlsa != NULL && TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX)
556 //          && DANE_SECURE == Dane)
557 //              goto end;
558 #endif
559         if (ste != NULL)
560         {
561                 SM_ASSERT(dane_tlsa != NULL);
562                 now = curtime();
563                 if (tTd(8, 20))
564                         sm_dprintf("gettlsa: host=%s, found-ste=%p, ste_flags=%#lx, expired=%d\n", host, ste, ste->s_tlsa->dane_tlsa_flags, dane_tlsa->dane_tlsa_exp <= now);
565                 if (dane_tlsa->dane_tlsa_exp <= now
566                     && 0 == (TLSAFLNOEXP & flags))
567                 {
568                         dane_tlsa_clr(dane_tlsa);
569                         expired = true;
570                 }
571                 else
572                 {
573                         n_rrs = dane_tlsa->dane_tlsa_n;
574                         goto end;
575                 }
576         }
577
578         /* get entries if none exist yet? */
579         if ((0 == (TLSAFLNEW & flags)) && !expired)
580                 goto end;
581
582         if (dane_tlsa == NULL)
583         {
584                 dane_tlsa = (dane_tlsa_P) sm_malloc(sizeof(*dane_tlsa));
585                 if (dane_tlsa == NULL)
586                 {
587                         n_rrs = -ENOMEM;
588                         goto end;
589                 }
590                 memset(dane_tlsa, '\0', sizeof(*dane_tlsa));
591         }
592
593         /* There are flags to store -- just set those, do nothing else. */
594         if (TLSA_STORE_FL(flags))
595         {
596                 dane_tlsa->dane_tlsa_flags = flags;
597                 ttl = mxttl > 0 ? mxttl: SM_DEFAULT_TTL;
598                 goto done;
599         }
600
601         (void) sm_snprintf(nbuf, sizeof(nbuf), "_%u._tcp.%s", port, host);
602         dr = dns_lookup_int(nbuf, C_IN, T_TLSA, 0, 0,
603                 (TLSAFLADMX & flags) ? SM_RES_DNSSEC : 0,
604                 RR_RAW, &err, &herr);
605         if (tTd(8, 2))
606         {
607 #if 0
608 /* disabled -- what to do with these two counters? log them "somewhere"? */
609 //              if (NULL != dr && tTd(8, 12))
610 //              {
611 //                      RESOURCE_RECORD_T *rr;
612 //                      unsigned int ntlsarrs, usable;
613 //
614 //                      ntlsarrs = usable = 0;
615 //                      for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
616 //                      {
617 //                              int tlsa_chk;
618 //
619 //                              if (rr->rr_type != T_TLSA)
620 //                                      continue;
621 //                              ++ntlsarrs;
622 //                              tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data,
623 //                                              rr->rr_size, name, false);
624 //                              if (TLSA_IS_SUPPORTED(tlsa_chk))
625 //                                      ++usable;
626 //
627 //                      }
628 //                      sm_dprintf("gettlsa: host=%s, ntlsarrs=%u, usable\%u\n", host, ntlsarrs, usable);
629 //              }
630 #endif /* 0 */
631                 sm_dprintf("gettlsa: host=%s, dr=%p, ad=%d, err=%d, herr=%d\n",
632                         host, (void *)dr,
633                         dr != NULL ? dr->dns_r_h.ad : -1, err, herr);
634         }
635         ttl = UINT_MAX;
636         n_rrs = tlsaadd(key, dr, dane_tlsa, herr, n_rrs, &ttl, 0);
637
638         /* no valid entries found? */
639         if (n_rrs == 0 && !TLSA_RR_TEMPFAIL(dane_tlsa))
640         {
641                 if (tTd(8, 2))
642                         sm_dprintf("gettlsa: host=%s, n_rrs=%d, herr=%d, status=NOT_ADDED\n",
643                                 host, n_rrs, dane_tlsa->dane_tlsa_dnsrc);
644                 goto cleanup;
645         }
646
647   done:
648         dane_tlsa->dane_tlsa_n = n_rrs;
649         if (!isrname)
650         {
651                 SM_FREE(dane_tlsa->dane_tlsa_sni);
652                 dane_tlsa->dane_tlsa_sni = sm_strdup(host);
653         }
654         if (NULL == ste)
655         {
656                 ste = stab(key, ST_TLSA_RR, ST_ENTER);
657                 if (NULL == ste)
658                         goto error;
659         }
660         ste->s_tlsa = dane_tlsa;
661         if (now == 0)
662                 now = curtime();
663         dane_tlsa->dane_tlsa_exp = now + SM_MIN(ttl, SM_DEFAULT_TTL);
664         dns_free_data(dr);
665         dr = NULL;
666         goto end;
667
668   error:
669         if (tTd(8, 2))
670                 sm_dprintf("gettlsa: host=%s, key=%s, status=error\n", host, key);
671         n_rrs = -1;
672   cleanup:
673         if (NULL == ste)
674                 dane_tlsa_free(dane_tlsa);
675         dns_free_data(dr);
676         dr = NULL;
677
678   end:
679         if (pste != NULL && ste != NULL)
680                 *pste = ste;
681         if (len > 0)
682                 host[len] = '.';
683         return n_rrs;
684 }
685 # endif /* DANE */
686
687 /*
688 **  GETFALLBACKMXRR -- get MX resource records for fallback MX host.
689 **
690 **      We have to initialize this once before doing anything else.
691 **      Moreover, we have to repeat this from time to time to avoid
692 **      stale data, e.g., in persistent queue runners.
693 **      This should be done in a parent process so the child
694 **      processes have the right data.
695 **
696 **      Parameters:
697 **              host -- the name of the fallback MX host.
698 **
699 **      Returns:
700 **              number of MX records.
701 **
702 **      Side Effects:
703 **              Populates NumFallbackMXHosts and fbhosts.
704 **              Sets renewal time (based on TTL).
705 */
706
707 int NumFallbackMXHosts = 0;     /* Number of fallback MX hosts (after MX expansion) */
708 static char *fbhosts[MAXMXHOSTS + 1];
709
710 int
711 getfallbackmxrr(host)
712         char *host;
713 {
714         int i, rcode;
715         int ttl;
716         static time_t renew = 0;
717
718 # if 0
719         /* This is currently done before this function is called. */
720         if (SM_IS_EMPTY(host))
721                 return 0;
722 # endif /* 0 */
723         if (NumFallbackMXHosts > 0 && renew > curtime())
724                 return NumFallbackMXHosts;
725
726         /*
727         **  For DANE we need to invoke getmxrr() to get the TLSA RRs.
728         **  Hack: don't do that if its not a FQHN (e.g., [localhost])
729         **  This also triggers for IPv4 addresses, but not IPv6!
730         */
731
732         if (host[0] == '[' && (!Dane || strchr(host, '.') == NULL))
733         {
734                 fbhosts[0] = host;
735                 NumFallbackMXHosts = 1;
736         }
737         else
738         {
739                 /* free old data */
740                 for (i = 0; i < NumFallbackMXHosts; i++)
741                         sm_free(fbhosts[i]);
742
743                 /*
744                 **  Get new data.
745                 **  Note: passing 0 as port is not correct but we cannot
746                 **  determine the port number as there is no mailer.
747                 */
748
749                 NumFallbackMXHosts = getmxrr(host, fbhosts, NULL,
750 # if DANE
751                                         (DANE_SECURE == Dane) ? ISAD :
752 # endif
753                                         0, &rcode, &ttl, 0, NULL);
754                 renew = curtime() + ttl;
755                 for (i = 0; i < NumFallbackMXHosts; i++)
756                         fbhosts[i] = newstr(fbhosts[i]);
757         }
758         if (NumFallbackMXHosts == NULLMX)
759                 NumFallbackMXHosts = 0;
760         return NumFallbackMXHosts;
761 }
762
763 /*
764 **  FALLBACKMXRR -- add MX resource records for fallback MX host to list.
765 **
766 **      Parameters:
767 **              nmx -- current number of MX records.
768 **              prefs -- array of preferences.
769 **              mxhosts -- array of MX hosts (maximum size: MAXMXHOSTS)
770 **
771 **      Returns:
772 **              new number of MX records.
773 **
774 **      Side Effects:
775 **              If FallbackMX was set, it appends the MX records for
776 **              that host to mxhosts (and modifies prefs accordingly).
777 */
778
779 static int
780 fallbackmxrr(nmx, prefs, mxhosts)
781         int nmx;
782         unsigned short *prefs;
783         char **mxhosts;
784 {
785         int i;
786
787         for (i = 0; i < NumFallbackMXHosts && nmx < MAXMXHOSTS; i++)
788         {
789                 if (nmx > 0)
790                         prefs[nmx] = prefs[nmx - 1] + 1;
791                 else
792                         prefs[nmx] = 0;
793                 mxhosts[nmx++] = fbhosts[i];
794         }
795         return nmx;
796 }
797
798 # if USE_EAI
799
800 /*
801 **  HN2ALABEL -- convert hostname in U-label format to A-label format
802 **
803 **      Parameters:
804 **              hostname -- hostname in U-label format
805 **
806 **      Returns:
807 **              hostname in A-label format in a local static buffer.
808 **              It must be copied before the function is called again.
809 */
810
811 const char *
812 hn2alabel(hostname)
813         const char *hostname;
814 {
815         UErrorCode error = U_ZERO_ERROR;
816         UIDNAInfo info = UIDNA_INFO_INITIALIZER;
817         UIDNA *idna;
818         static char buf[MAXNAME_I];     /* XXX ??? */
819
820         if (str_is_print(hostname))
821                 return hostname;
822         idna = uidna_openUTS46(UIDNA_NONTRANSITIONAL_TO_ASCII, &error);
823         (void) uidna_nameToASCII_UTF8(idna, hostname, strlen(hostname),
824                                      buf, sizeof(buf) - 1,
825                                      &info, &error);
826         uidna_close(idna);
827         return buf;
828 }
829 # endif /* USE_EAI */
830
831 /*
832 **  GETMXRR -- get MX resource records for a domain
833 **
834 **      Parameters:
835 **              host -- the name of the host to MX [must be x]
836 **              mxhosts -- a pointer to a return buffer of MX records.
837 **              mxprefs -- a pointer to a return buffer of MX preferences.
838 **                      If NULL, don't try to populate.
839 **              flags -- flags:
840 **                      DROPLOCALHOST -- If true, all MX records less preferred
841 **                      than the local host (as determined by $=w) will
842 **                      be discarded.
843 **                      TRYFALLBACK -- add also fallback MX host?
844 **                      ISAD -- host lookup was secure?
845 **              rcode -- a pointer to an EX_ status code.
846 **              pttl -- pointer to return TTL (can be NULL).
847 **              port -- port number used in TLSA queries (_PORT._tcp.)
848 **              pad -- (output parameter, pointer to) AD flag (can be NULL)
849 **
850 **      Returns:
851 **              The number of MX records found.
852 **              -1 if there is an internal failure.
853 **              If no MX records are found, mxhosts[0] is set to host
854 **                      and 1 is returned.
855 **
856 **      Side Effects:
857 **              The entries made for mxhosts point to a static array
858 **              MXHostBuf[MXHOSTBUFSIZE], so the data needs to be copied,
859 **              if it must be preserved across calls to this function.
860 */
861
862 int
863 getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port, pad)
864         char *host;
865         char **mxhosts;
866         unsigned short *mxprefs;
867         unsigned int flags;
868         int *rcode;
869         int *pttl;
870         int port;
871         int *pad;
872 {
873         register unsigned char *eom, *cp;
874         register int i, j, n;
875         int nmx = 0;
876         register char *bp;
877         HEADER *hp;
878         querybuf answer;
879         int ancount, qdcount, buflen;
880         bool seenlocal = false;
881         unsigned short pref, type;
882         unsigned short localpref = 256;
883         char *fallbackMX = FallbackMX;
884         bool trycanon = false;
885         unsigned short *prefs;
886         int (*resfunc) __P((const char *, int, int, u_char *, int));
887         unsigned short prefer[MAXMXHOSTS];
888         int weight[MAXMXHOSTS];
889         int ttl = 0;
890         bool ad;
891         bool seennullmx = false;
892         extern int res_query __P((const char *, int, int, u_char *, int));
893         extern int res_search __P((const char *, int, int , u_char *, int));
894 # if DANE
895         bool cname2mx;
896         char qname[MAXNAME];    /* EAI: copy of host: ok? */
897         unsigned long old_options = 0;
898 # endif
899
900         if (tTd(8, 2))
901                 sm_dprintf("getmxrr(%s, droplocalhost=%d, flags=%X, port=%d)\n",
902                            host, (flags & DROPLOCALHOST) != 0, flags, port);
903         ad = (flags & ISAD) != 0;
904         *rcode = EX_OK;
905         if (pttl != NULL)
906                 *pttl = SM_DEFAULT_TTL;
907         if (*host == '\0')
908                 return 0;
909 # if DANE
910         cname2mx = false;
911         qname[0] = '\0';
912         old_options = _res.options;
913         if (ad)
914                 _res.options |= SM_RES_DNSSEC;
915 # endif
916
917         if ((fallbackMX != NULL && (flags & DROPLOCALHOST) != 0 &&
918              wordinclass(fallbackMX, 'w')) || (flags & TRYFALLBACK) == 0)
919         {
920                 /* don't use fallback for this pass */
921                 fallbackMX = NULL;
922         }
923
924         if (mxprefs != NULL)
925                 prefs = mxprefs;
926         else
927                 prefs = prefer;
928
929         /* efficiency hack -- numeric or non-MX lookups */
930         if (host[0] == '[')
931                 goto punt;
932
933 # if DANE
934         /*
935         **  NOTE: This only works if nocanonify is used,
936         **  otherwise the name is already rewritten.
937         */
938
939         /* always or only when "needed"? */
940         if (DANE_ALWAYS == Dane || (ad && DANE_SECURE == Dane))
941                 (void) sm_strlcpy(qname, host, sizeof(qname));
942 # endif /* DANE */
943
944 # if USE_EAI
945         if (!str_is_print(host))
946         {
947                 /* XXX memory leak? */
948                 host = sm_rpool_strdup_x(CurEnv->e_rpool, hn2alabel(host));
949         }
950 # endif /* USE_EAI */
951
952         /*
953         **  If we don't have MX records in our host switch, don't
954         **  try for MX records.  Note that this really isn't "right",
955         **  since we might be set up to try NIS first and then DNS;
956         **  if the host is found in NIS we really shouldn't be doing
957         **  MX lookups.  However, that should be a degenerate case.
958         */
959
960         if (!UseNameServer)
961                 goto punt;
962         if (HasWildcardMX && ConfigLevel >= 6)
963                 resfunc = res_query;
964         else
965                 resfunc = res_search;
966 # if DNSSEC_TEST
967         if (tTd(8, 110))
968                 resfunc = tstdns_search;
969 # endif
970
971         errno = 0;
972         hp = (HEADER *)&answer;
973         n = (*resfunc)(host, C_IN, T_MX, (unsigned char *) &answer,
974                        sizeof(answer));
975         if (n < 0)
976         {
977                 if (tTd(8, 1))
978 # if DNSSEC_TEST
979                         sm_dprintf("getmxrr: res_search(%s) failed (errno=%d (%s), h_errno=%d (%s))\n",
980                                 host, errno, strerror(errno),
981                                 h_errno, herrno2txt(h_errno));
982 # else
983                         sm_dprintf("getmxrr: res_search(%s) failed, h_errno=%d\n",
984                                 host, h_errno);
985 # endif
986                 switch (h_errno)
987                 {
988                   case NO_DATA:
989                         trycanon = true;
990                         /* FALLTHROUGH */
991
992                   case NO_RECOVERY:
993                         /* no MX data on this host */
994                         goto punt;
995
996                   case HOST_NOT_FOUND:
997 # if BROKEN_RES_SEARCH
998                   case 0: /* Ultrix resolver returns failure w/ h_errno=0 */
999 # endif
1000                         /* host doesn't exist in DNS; might be in /etc/hosts */
1001                         trycanon = true;
1002                         *rcode = EX_NOHOST;
1003                         goto punt;
1004
1005                   case TRY_AGAIN:
1006                   case -1:
1007                         /* couldn't connect to the name server */
1008                         if (fallbackMX != NULL)
1009                         {
1010                                 /* name server is hosed -- push to fallback */
1011                                 nmx = fallbackmxrr(nmx, prefs, mxhosts);
1012                                 goto done;
1013                         }
1014                         /* it might come up later; better queue it up */
1015                         *rcode = EX_TEMPFAIL;
1016                         break;
1017
1018                   default:
1019                         syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)",
1020                                 host, h_errno);
1021                         *rcode = EX_OSERR;
1022                         break;
1023                 }
1024
1025                 /* irreconcilable differences */
1026                 goto error;
1027         }
1028
1029         ad = ad && hp->ad;
1030         if (tTd(8, 2))
1031                 sm_dprintf("getmxrr(%s), hp=%p, ad=%d\n", host, (void*)hp, ad);
1032         if (pad != NULL)
1033                 *pad = ad;
1034
1035         /* avoid problems after truncation in tcp packets */
1036         if (n > sizeof(answer))
1037                 n = sizeof(answer);
1038
1039         /* find first satisfactory answer */
1040         cp = (unsigned char *)&answer + HFIXEDSZ;
1041         eom = (unsigned char *)&answer + n;
1042
1043         for (qdcount = ntohs((unsigned short) hp->qdcount);
1044              qdcount--;
1045              cp += n + QFIXEDSZ)
1046         {
1047                 if ((n = dn_skipname(cp, eom)) < 0)
1048                         goto punt;
1049         }
1050
1051         /* NOTE: see definition of MXHostBuf! */
1052         buflen = sizeof(MXHostBuf) - 1;
1053         SM_ASSERT(buflen > 0);
1054         bp = MXHostBuf;
1055         ancount = ntohs((unsigned short) hp->ancount);
1056
1057         /* See RFC 1035 for layout of RRs. */
1058         /* XXX leave room for FallbackMX ? */
1059         while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1)
1060         {
1061                 if ((n = dn_expand((unsigned char *)&answer, eom, cp,
1062                                    (RES_UNC_T) bp, buflen)) < 0)
1063                         break;
1064                 cp += n;
1065                 GETSHORT(type, cp);
1066                 cp += INT16SZ;          /* skip over class */
1067                 GETLONG(ttl, cp);
1068                 GETSHORT(n, cp);        /* rdlength */
1069 # if DANE
1070                 if (type == T_CNAME)
1071                         cname2mx = true;
1072 # endif
1073                 if (type != T_MX)
1074                 {
1075                         if ((tTd(8, 8) || _res.options & RES_DEBUG)
1076 # if DANE
1077                             && type != T_RRSIG
1078 # endif
1079                             )
1080                                 sm_dprintf("unexpected answer type %s, size %d\n",
1081                                         dns_type_to_string(type), n);
1082                         cp += n;
1083                         continue;
1084                 }
1085                 GETSHORT(pref, cp);
1086                 if ((n = dn_expand((unsigned char *)&answer, eom, cp,
1087                                    (RES_UNC_T) bp, buflen)) < 0)
1088                         break;
1089                 cp += n;
1090                 n = strlen(bp);
1091
1092                 /* Support for RFC7505 "MX 0 ." */
1093                 if (pref == 0 && *bp == '\0')
1094                         seennullmx = true;
1095
1096                 if (wordinclass(bp, 'w'))
1097                 {
1098                         if (tTd(8, 3))
1099                                 sm_dprintf("found localhost (%s) in MX list, pref=%d\n",
1100                                         bp, pref);
1101                         if ((flags & DROPLOCALHOST) != 0)
1102                         {
1103                                 if (!seenlocal || pref < localpref)
1104                                         localpref = pref;
1105                                 seenlocal = true;
1106                                 continue;
1107                         }
1108                         weight[nmx] = 0;
1109                 }
1110                 else
1111                         weight[nmx] = mxrand(bp);
1112                 prefs[nmx] = pref;
1113                 mxhosts[nmx++] = bp;
1114 # if DANE
1115                 if (CHK_DANE(Dane) && port >= 0)
1116                 {
1117                         int nrr;
1118                         unsigned long flags;
1119
1120                         flags = TLSAFLNEW;
1121                         if (pad != NULL && *pad)
1122                                 flags |= TLSAFLADMX;
1123                         if (tTd(8, 20))
1124                                 sm_dprintf("getmxrr: 1: host=%s, mx=%s, flags=%#lx\n", host, bp, flags);
1125                         nrr = gettlsa(bp, NULL, NULL, flags, ttl, port);
1126
1127                         /* Only check qname if no TLSA RRs were found */
1128                         if (0 == nrr && cname2mx && '\0' != qname[0] &&
1129                             strcmp(qname, bp))
1130                         {
1131                                 if (tTd(8, 20))
1132                                         sm_dprintf("getmxrr: 2: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
1133                                 gettlsa(qname, bp, NULL, flags, ttl, port);
1134                         /* XXX is this the right ad flag? */
1135                         }
1136                 }
1137 # endif
1138
1139                 /*
1140                 **  Note: n can be 0 for something like:
1141                 **  host MX 0 .
1142                 **  See RFC 7505
1143                 */
1144
1145                 bp += n;
1146                 if (0 == n || bp[-1] != '.')
1147                 {
1148                         *bp++ = '.';
1149                         n++;
1150                 }
1151                 *bp++ = '\0';
1152                 if (buflen < n + 1)
1153                 {
1154                         /* don't want to wrap buflen */
1155                         break;
1156                 }
1157                 buflen -= n + 1;
1158         }
1159
1160         /* Support for RFC7505 "MX 0 ." */
1161         if (seennullmx && nmx == 1)
1162         {
1163                 if (tTd(8, 4))
1164                         sm_dprintf("getmxrr: Null MX record found, domain doesn't accept mail (RFC7505)\n");
1165                 *rcode = EX_UNAVAILABLE;
1166                 return NULLMX;
1167         }
1168
1169         /* return only one TTL entry, that should be sufficient */
1170         if (ttl > 0 && pttl != NULL)
1171                 *pttl = ttl;
1172
1173         /* sort the records */
1174         for (i = 0; i < nmx; i++)
1175         {
1176                 for (j = i + 1; j < nmx; j++)
1177                 {
1178                         if (prefs[i] > prefs[j] ||
1179                             (prefs[i] == prefs[j] && weight[i] > weight[j]))
1180                         {
1181                                 register int temp;
1182                                 register char *temp1;
1183
1184                                 temp = prefs[i];
1185                                 prefs[i] = prefs[j];
1186                                 prefs[j] = temp;
1187                                 temp1 = mxhosts[i];
1188                                 mxhosts[i] = mxhosts[j];
1189                                 mxhosts[j] = temp1;
1190                                 temp = weight[i];
1191                                 weight[i] = weight[j];
1192                                 weight[j] = temp;
1193                         }
1194                 }
1195                 if (seenlocal && prefs[i] >= localpref)
1196                 {
1197                         /* truncate higher preference part of list */
1198                         nmx = i;
1199                 }
1200         }
1201
1202         /* delete duplicates from list (yes, some bozos have duplicates) */
1203         for (i = 0; i < nmx - 1; )
1204         {
1205                 if (!SM_STRCASEEQ(mxhosts[i], mxhosts[i + 1]))
1206                         i++;
1207                 else
1208                 {
1209                         /* compress out duplicate */
1210                         for (j = i + 1; j < nmx; j++)
1211                         {
1212                                 mxhosts[j] = mxhosts[j + 1];
1213                                 prefs[j] = prefs[j + 1];
1214                         }
1215                         nmx--;
1216                 }
1217         }
1218
1219         if (nmx == 0)
1220         {
1221 punt:
1222                 if (seenlocal)
1223                 {
1224                         struct hostent *h = NULL;
1225
1226                         /*
1227                         **  If we have deleted all MX entries, this is
1228                         **  an error -- we should NEVER send to a host that
1229                         **  has an MX, and this should have been caught
1230                         **  earlier in the config file.
1231                         **
1232                         **  Some sites prefer to go ahead and try the
1233                         **  A record anyway; that case is handled by
1234                         **  setting TryNullMXList.  I believe this is a
1235                         **  bad idea, but it's up to you....
1236                         */
1237
1238                         if (TryNullMXList)
1239                         {
1240                                 SM_SET_H_ERRNO(0);
1241                                 errno = 0;
1242                                 h = sm_gethostbyname(host, AF_INET);
1243                                 if (h == NULL)
1244                                 {
1245                                         if (errno == ETIMEDOUT ||
1246                                             h_errno == TRY_AGAIN ||
1247                                             (errno == ECONNREFUSED &&
1248                                              UseNameServer))
1249                                         {
1250                                                 *rcode = EX_TEMPFAIL;
1251                                                 goto error;
1252                                         }
1253 # if NETINET6
1254                                         SM_SET_H_ERRNO(0);
1255                                         errno = 0;
1256                                         h = sm_gethostbyname(host, AF_INET6);
1257                                         if (h == NULL &&
1258                                             (errno == ETIMEDOUT ||
1259                                              h_errno == TRY_AGAIN ||
1260                                              (errno == ECONNREFUSED &&
1261                                               UseNameServer)))
1262                                         {
1263                                                 *rcode = EX_TEMPFAIL;
1264                                                 goto error;
1265                                         }
1266 # endif /* NETINET6 */
1267                                 }
1268                         }
1269
1270                         if (h == NULL)
1271                         {
1272                                 *rcode = EX_CONFIG;
1273                                 syserr("MX list for %s points back to %s",
1274                                        host, MyHostName);
1275                                 goto error;
1276                         }
1277 # if NETINET6
1278                         freehostent(h);
1279                         h = NULL;
1280 # endif
1281                 }
1282                 if (strlen(host) >= sizeof(MXHostBuf))
1283                 {
1284                         *rcode = EX_CONFIG;
1285                         syserr("Host name %s too long",
1286                                shortenstring(host, MAXSHORTSTR));
1287                         goto error;
1288                 }
1289                 (void) sm_strlcpy(MXHostBuf, host, sizeof(MXHostBuf));
1290                 mxhosts[0] = MXHostBuf;
1291                 prefs[0] = 0;
1292                 if (host[0] == '[')
1293                 {
1294                         register char *p;
1295 # if NETINET6
1296                         struct sockaddr_in6 tmp6;
1297 # endif
1298
1299                         /* this may be an MX suppression-style address */
1300                         p = strchr(MXHostBuf, ']');
1301                         if (p != NULL)
1302                         {
1303                                 *p = '\0';
1304
1305                                 if (inet_addr(&MXHostBuf[1]) != INADDR_NONE)
1306                                 {
1307                                         nmx++;
1308                                         *p = ']';
1309                                 }
1310 # if NETINET6
1311                                 else if (anynet_pton(AF_INET6, &MXHostBuf[1],
1312                                                      &tmp6.sin6_addr) == 1)
1313                                 {
1314                                         nmx++;
1315                                         *p = ']';
1316                                 }
1317 # endif /* NETINET6 */
1318                                 else
1319                                 {
1320 # if USE_EAI
1321                                         char *hn;
1322
1323                                         hn = MXHostBuf + 1;
1324                                         if (!str_is_print(hn))
1325                                         {
1326                                                 const char *ahn;
1327
1328                                                 ahn = hn2alabel(hn);
1329                                                 if (strlen(ahn) >= sizeof(MXHostBuf) - 1)
1330                                                 {
1331                                                         *rcode = EX_CONFIG;
1332                                                         syserr("Encoded host name %s too long",
1333                                                                shortenstring(ahn, MAXSHORTSTR));
1334                                                         goto error;
1335                                                 }
1336                                                 (void) sm_strlcpy(hn, ahn, sizeof(MXHostBuf) - 1);
1337                                         }
1338 # endif /* USE_EAI */
1339                                         trycanon = true;
1340                                         mxhosts[0]++;
1341                                 }
1342                         }
1343                 }
1344                 if (trycanon &&
1345                     (n = getcanonname(mxhosts[0], sizeof(MXHostBuf) - 2, false,
1346                                 pttl)) != HOST_NOTFOUND)
1347                 {
1348                         /* XXX MXHostBuf == "" ?  is that possible? */
1349                         bp = &MXHostBuf[strlen(MXHostBuf)];
1350                         if (bp[-1] != '.')
1351                         {
1352                                 *bp++ = '.';
1353                                 *bp = '\0';
1354                         }
1355                         nmx = 1;
1356 # if DANE
1357                         if (tTd(8, 3))
1358                                 sm_dprintf("getmxrr=%s, getcanonname=%d\n",
1359                                         mxhosts[0], n);
1360                         if (CHK_DANE(Dane) && port >= 0)
1361                         {
1362                                 int nrr;
1363                                 unsigned long flags;
1364                                 unsigned int cttl;
1365
1366                                 if (pttl != NULL)
1367                                         cttl = *pttl;
1368                                 else if (ttl > 0)
1369                                         cttl = ttl;
1370                                 else
1371                                         cttl = SM_DEFAULT_TTL;
1372
1373                                 flags = TLSAFLNEW;
1374                                 if (ad && HOST_SECURE == n)
1375                                 {
1376                                         flags |= TLSAFLADMX;
1377                                         if (pad != NULL)
1378                                                 *pad = ad;
1379                                 }
1380                                 if (TTD(8, 20))
1381                                         sm_dprintf("getmxrr: 3: host=%s, mx=%s, flags=%#lx, ad=%d\n",
1382                                                 host, mxhosts[0], flags, ad);
1383                                 nrr = gettlsa(mxhosts[0], NULL, NULL, flags,
1384                                                 cttl, port);
1385
1386                                 /*
1387                                 **  Only check qname if no TLSA RRs were found
1388                                 **  XXX: what about (temp) DNS errors?
1389                                 */
1390
1391                                 if (0 == nrr && '\0' != qname[0] &&
1392                                     strcmp(qname, mxhosts[0]))
1393                                 {
1394                                         gettlsa(qname, mxhosts[0], NULL, flags,
1395                                                 cttl, port);
1396                                         if (tTd(8, 20))
1397                                                 sm_dprintf("getmxrr: 4: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
1398                                 /* XXX is this the right ad flag? */
1399                                 }
1400                         }
1401 # endif
1402                 }
1403         }
1404
1405         /* if we have a default lowest preference, include that */
1406         if (fallbackMX != NULL && !seenlocal)
1407         {
1408                 /* TODO: DNSSEC status of fallbacks */
1409                 nmx = fallbackmxrr(nmx, prefs, mxhosts);
1410         }
1411     done:
1412 # if DANE
1413         _res.options = old_options;
1414 # endif
1415         return nmx;
1416
1417    error:
1418 # if DANE
1419         _res.options = old_options;
1420 # endif
1421         return -1;
1422 }
1423
1424 /*
1425 **  MXRAND -- create a randomizer for equal MX preferences
1426 **
1427 **      If two MX hosts have equal preferences we want to randomize
1428 **      the selection.  But in order for signatures to be the same,
1429 **      we need to randomize the same way each time.  This function
1430 **      computes a pseudo-random hash function from the host name.
1431 **
1432 **      Parameters:
1433 **              host -- the name of the host.
1434 **
1435 **      Returns:
1436 **              A random but repeatable value based on the host name.
1437 */
1438
1439 static int
1440 mxrand(host)
1441         register char *host;
1442 {
1443         int hfunc;
1444         static unsigned int seed;
1445
1446         if (seed == 0)
1447         {
1448                 seed = (int) curtime() & 0xffff;
1449                 if (seed == 0)
1450                         seed++;
1451         }
1452
1453         if (tTd(17, 9))
1454                 sm_dprintf("mxrand(%s)", host);
1455
1456         hfunc = seed;
1457         while (*host != '\0')
1458         {
1459                 int c = *host++;
1460
1461                 if (isascii(c) && isupper(c))
1462                         c = tolower(c);
1463                 hfunc = ((hfunc << 1) ^ c) % 2003;
1464         }
1465
1466         hfunc &= 0xff;
1467         hfunc++;
1468
1469         if (tTd(17, 9))
1470                 sm_dprintf(" = %d\n", hfunc);
1471         return hfunc;
1472 }
1473 /*
1474 **  BESTMX -- find the best MX for a name
1475 **
1476 **      This is really a hack, but I don't see any obvious way
1477 **      to generalize it at the moment.
1478 */
1479
1480 /* ARGSUSED3 */
1481 char *
1482 bestmx_map_lookup(map, name, av, statp)
1483         MAP *map;
1484         char *name;
1485         char **av;
1486         int *statp;
1487 {
1488         int nmx;
1489         int saveopts = _res.options;
1490         int i;
1491         ssize_t len = 0;
1492         char *result;
1493         char *mxhosts[MAXMXHOSTS + 1];
1494 # if _FFR_BESTMX_BETTER_TRUNCATION
1495         char *buf;
1496 # else
1497         char *p;
1498         char buf[PSBUFSIZE / 2];
1499 # endif
1500
1501         _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
1502         nmx = getmxrr(name, mxhosts, NULL, 0, statp, NULL, -1, NULL);
1503         _res.options = saveopts;
1504         if (nmx <= 0)
1505                 return NULL;
1506         if (bitset(MF_MATCHONLY, map->map_mflags))
1507                 return map_rewrite(map, name, strlen(name), NULL);
1508         if ((map->map_coldelim == '\0') || (nmx == 1))
1509                 return map_rewrite(map, mxhosts[0], strlen(mxhosts[0]), av);
1510
1511         /*
1512         **  We were given a -z flag (return all MXs) and there are multiple
1513         **  ones.  We need to build them all into a list.
1514         */
1515
1516 # if _FFR_BESTMX_BETTER_TRUNCATION
1517         for (i = 0; i < nmx; i++)
1518         {
1519                 if (strchr(mxhosts[i], map->map_coldelim) != NULL)
1520                 {
1521                         syserr("bestmx_map_lookup: MX host %.64s includes map delimiter character 0x%02X",
1522                                mxhosts[i], map->map_coldelim);
1523                         return NULL;
1524                 }
1525                 len += strlen(mxhosts[i]) + 1;
1526                 if (len < 0)
1527                 {
1528                         len -= strlen(mxhosts[i]) + 1;
1529                         break;
1530                 }
1531         }
1532         buf = (char *) sm_malloc(len);
1533         if (buf == NULL)
1534         {
1535                 *statp = EX_UNAVAILABLE;
1536                 return NULL;
1537         }
1538         *buf = '\0';
1539         for (i = 0; i < nmx; i++)
1540         {
1541                 int end;
1542
1543                 end = sm_strlcat(buf, mxhosts[i], len);
1544                 if (i != nmx && end + 1 < len)
1545                 {
1546                         buf[end] = map->map_coldelim;
1547                         buf[end + 1] = '\0';
1548                 }
1549         }
1550
1551         /* Cleanly truncate for rulesets */
1552         truncate_at_delim(buf, PSBUFSIZE / 2, map->map_coldelim);
1553 # else /* _FFR_BESTMX_BETTER_TRUNCATION */
1554         p = buf;
1555         for (i = 0; i < nmx; i++)
1556         {
1557                 size_t slen;
1558
1559                 if (strchr(mxhosts[i], map->map_coldelim) != NULL)
1560                 {
1561                         syserr("bestmx_map_lookup: MX host %.64s includes map delimiter character 0x%02X",
1562                                mxhosts[i], map->map_coldelim);
1563                         return NULL;
1564                 }
1565                 slen = strlen(mxhosts[i]);
1566                 if (len + slen + 2 > sizeof(buf))
1567                         break;
1568                 if (i > 0)
1569                 {
1570                         *p++ = map->map_coldelim;
1571                         len++;
1572                 }
1573                 (void) sm_strlcpy(p, mxhosts[i], sizeof(buf) - len);
1574                 p += slen;
1575                 len += slen;
1576         }
1577 # endif /* _FFR_BESTMX_BETTER_TRUNCATION */
1578
1579         result = map_rewrite(map, buf, len, av);
1580 # if _FFR_BESTMX_BETTER_TRUNCATION
1581         sm_free(buf);
1582 # endif
1583         return result;
1584 }
1585 /*
1586 **  DNS_GETCANONNAME -- get the canonical name for named host using DNS
1587 **
1588 **      This algorithm tries to be smart about wildcard MX records.
1589 **      This is hard to do because DNS doesn't tell is if we matched
1590 **      against a wildcard or a specific MX.
1591 **
1592 **      We always prefer A & CNAME records, since these are presumed
1593 **      to be specific.
1594 **
1595 **      If we match an MX in one pass and lose it in the next, we use
1596 **      the old one.  For example, consider an MX matching *.FOO.BAR.COM.
1597 **      A hostname bletch.foo.bar.com will match against this MX, but
1598 **      will stop matching when we try bletch.bar.com -- so we know
1599 **      that bletch.foo.bar.com must have been right.  This fails if
1600 **      there was also an MX record matching *.BAR.COM, but there are
1601 **      some things that just can't be fixed.
1602 **
1603 **      Parameters:
1604 **              host -- a buffer containing the name of the host.
1605 **                      This is a value-result parameter.
1606 **              hbsize -- the size of the host buffer.
1607 **              trymx -- if set, try MX records as well as A and CNAME.
1608 **              statp -- pointer to place to store status.
1609 **              pttl -- pointer to return TTL (can be NULL).
1610 **
1611 **      Returns:
1612 **              >0 -- if the host was found.
1613 **              0 -- otherwise.
1614 */
1615
1616 int
1617 dns_getcanonname(host, hbsize, trymx, statp, pttl)
1618         char *host;
1619         int hbsize;
1620         bool trymx;
1621         int *statp;
1622         int *pttl;
1623 {
1624         register unsigned char *eom, *ap;
1625         register char *cp;
1626         register int n;
1627         HEADER *hp;
1628         querybuf answer;
1629         int ancount, qdcount, ret, type, qtype, initial, loopcnt, ttl, sli;
1630         char **domain;
1631         char *dp;
1632         char *mxmatch;
1633         bool amatch, gotmx, ad;
1634         char nbuf[SM_MAX(MAXPACKET, MAXDNAME*2+2)];
1635 # if DNSSEC_TEST
1636 #  define ADDSL 1 /* NameSearchList may add another entry to searchlist! */
1637 # else
1638 #  define ADDSL 0
1639 # endif
1640         char *searchlist[MAXDNSRCH + 2 + ADDSL];
1641 # define SLSIZE SM_ARRAY_SIZE(searchlist)
1642         int (*resqdomain) __P((const char *, const char *, int, int, unsigned char *, int));
1643 # if DANE
1644         unsigned long old_options = 0;
1645 # endif
1646
1647         ttl = 0;
1648         gotmx = false;
1649         ad = true;
1650         if (tTd(8, 2))
1651                 sm_dprintf("dns_getcanonname(%s, trymx=%d)\n", host, trymx);
1652
1653         if ((_res.options & RES_INIT) == 0 && res_init() == -1)
1654         {
1655                 *statp = EX_UNAVAILABLE;
1656                 return HOST_NOTFOUND;
1657         }
1658
1659 # if DANE
1660         old_options = _res.options;
1661         if (DANE_SECURE == Dane)
1662                 _res.options |= SM_RES_DNSSEC;
1663 # endif
1664
1665         *statp = EX_OK;
1666         resqdomain = res_querydomain;
1667 # if DNSSEC_TEST
1668         if (tTd(8, 110))
1669                 resqdomain = tstdns_querydomain;
1670 # endif
1671
1672         /*
1673         **  Initialize domain search list.  If there is at least one
1674         **  dot in the name, search the unmodified name first so we
1675         **  find "vse.CS" in Czechoslovakia instead of in the local
1676         **  domain (e.g., vse.CS.Berkeley.EDU).  Note that there is no
1677         **  longer a country named Czechoslovakia but this type of problem
1678         **  is still present.
1679         **
1680         **  Older versions of the resolver could create this
1681         **  list by tearing apart the host name.
1682         */
1683
1684         loopcnt = 0;
1685 cnameloop:
1686         /* Check for dots in the name */
1687         for (cp = host, n = 0; *cp != '\0'; cp++)
1688                 if (*cp == '.')
1689                         n++;
1690
1691         /*
1692         **  Build the search list.
1693         **      If there is at least one dot in name, start with a null
1694         **      domain to search the unmodified name first.
1695         **      If name does not end with a dot and search up local domain
1696         **      tree desired, append each local domain component to the
1697         **      search list; if name contains no dots and default domain
1698         **      name is desired, append default domain name to search list;
1699         **      else if name ends in a dot, remove that dot.
1700         */
1701
1702         sli = 0;
1703         if (n > 0)
1704                 searchlist[sli++] = "";
1705 # if DNSSEC_TEST
1706         if (NameSearchList != NULL)
1707         {
1708                 SM_ASSERT(sli < SLSIZE);
1709                 searchlist[sli++] = NameSearchList;
1710         }
1711 # endif
1712         if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options))
1713         {
1714                 /* make sure there are less than MAXDNSRCH domains */
1715                 for (domain = RES_DNSRCH_VARIABLE, ret = 0;
1716                      *domain != NULL && ret < MAXDNSRCH && sli < SLSIZE;
1717                      ret++)
1718                         searchlist[sli++] = *domain++;
1719         }
1720         else if (n == 0 && bitset(RES_DEFNAMES, _res.options))
1721         {
1722                 SM_ASSERT(sli < SLSIZE);
1723                 searchlist[sli++] = _res.defdname;
1724         }
1725         else if (*cp == '.')
1726         {
1727                 *cp = '\0';
1728         }
1729         SM_ASSERT(sli < SLSIZE);
1730         searchlist[sli] = NULL;
1731
1732         /*
1733         **  Now loop through the search list, appending each domain in turn
1734         **  name and searching for a match.
1735         */
1736
1737         mxmatch = NULL;
1738         initial = T_A;
1739 # if NETINET6
1740         if (InetMode == AF_INET6)
1741                 initial = T_AAAA;
1742 # endif
1743         qtype = initial;
1744
1745         for (sli = 0; sli < SLSIZE; )
1746         {
1747                 dp = searchlist[sli];
1748                 if (NULL == dp)
1749                         break;
1750                 if (qtype == initial)
1751                         gotmx = false;
1752                 if (tTd(8, 5))
1753                         sm_dprintf("dns_getcanonname: trying %s.%s (%s)\n",
1754                                 host, dp,
1755 # if NETINET6
1756                                 qtype == T_AAAA ? "AAAA" :
1757 # endif
1758                                 qtype == T_A ? "A" :
1759                                 qtype == T_MX ? "MX" :
1760                                 "???");
1761                 errno = 0;
1762                 hp = (HEADER *) &answer;
1763                 ret = (*resqdomain)(host, dp, C_IN, qtype,
1764                                       answer.qb2, sizeof(answer.qb2));
1765                 if (ret <= 0)
1766                 {
1767                         int save_errno = errno;
1768
1769                         if (tTd(8, 7))
1770                                 sm_dprintf("\tNO: errno=%d, h_errno=%d\n",
1771                                            save_errno, h_errno);
1772
1773                         if (save_errno == ECONNREFUSED || h_errno == TRY_AGAIN)
1774                         {
1775                                 /*
1776                                 **  the name server seems to be down or broken.
1777                                 */
1778
1779                                 SM_SET_H_ERRNO(TRY_AGAIN);
1780                                 if (*dp == '\0')
1781                                 {
1782                                         if (*statp == EX_OK)
1783                                                 *statp = EX_TEMPFAIL;
1784                                         goto nexttype;
1785                                 }
1786                                 *statp = EX_TEMPFAIL;
1787
1788                                 if (WorkAroundBrokenAAAA)
1789                                 {
1790                                         /*
1791                                         **  Only return if not TRY_AGAIN as an
1792                                         **  attempt with a different qtype may
1793                                         **  succeed (res_querydomain() calls
1794                                         **  res_query() calls res_send() which
1795                                         **  sets errno to ETIMEDOUT if the
1796                                         **  nameservers could be contacted but
1797                                         **  didn't give an answer).
1798                                         */
1799
1800                                         if (save_errno != ETIMEDOUT)
1801                                                 goto error;
1802                                 }
1803                                 else
1804                                         goto error;
1805                         }
1806
1807 nexttype:
1808                         if (h_errno != HOST_NOT_FOUND)
1809                         {
1810                                 /* might have another type of interest */
1811 # if NETINET6
1812                                 if (qtype == T_AAAA)
1813                                 {
1814                                         qtype = T_A;
1815                                         continue;
1816                                 }
1817                                 else
1818 # endif /* NETINET6 */
1819                                 if (qtype == T_A && !gotmx &&
1820                                     (trymx || *dp == '\0'))
1821                                 {
1822                                         qtype = T_MX;
1823                                         continue;
1824                                 }
1825                         }
1826
1827                         /* definite no -- try the next domain */
1828                         sli++;
1829                         qtype = initial;
1830                         continue;
1831                 }
1832                 else if (tTd(8, 7))
1833                         sm_dprintf("\tYES\n");
1834
1835                 /* avoid problems after truncation in tcp packets */
1836                 if (ret > sizeof(answer))
1837                         ret = sizeof(answer);
1838                 SM_ASSERT(ret >= 0);
1839
1840                 /*
1841                 **  Appear to have a match.  Confirm it by searching for A or
1842                 **  CNAME records.  If we don't have a local domain
1843                 **  wild card MX record, we will accept MX as well.
1844                 */
1845
1846                 ap = (unsigned char *) &answer + HFIXEDSZ;
1847                 eom = (unsigned char *) &answer + ret;
1848
1849                 if (0 == hp->ad)
1850                         ad = false;
1851
1852                 /* skip question part of response -- we know what we asked */
1853                 for (qdcount = ntohs((unsigned short) hp->qdcount);
1854                      qdcount--;
1855                      ap += ret + QFIXEDSZ)
1856                 {
1857                         if ((ret = dn_skipname(ap, eom)) < 0)
1858                         {
1859                                 if (tTd(8, 20))
1860                                         sm_dprintf("qdcount failure (%d)\n",
1861                                                 ntohs((unsigned short) hp->qdcount));
1862                                 *statp = EX_SOFTWARE;
1863                                 goto error;
1864                         }
1865                 }
1866
1867                 amatch = false;
1868                 for (ancount = ntohs((unsigned short) hp->ancount);
1869                      --ancount >= 0 && ap < eom;
1870                      ap += n)
1871                 {
1872                         n = dn_expand((unsigned char *) &answer, eom, ap,
1873                                       (RES_UNC_T) nbuf, sizeof(nbuf));
1874                         if (n < 0)
1875                                 break;
1876                         ap += n;
1877                         GETSHORT(type, ap);
1878                         ap += INT16SZ;          /* skip over class */
1879                         GETLONG(ttl, ap);
1880                         GETSHORT(n, ap);        /* rdlength */
1881                         switch (type)
1882                         {
1883                           case T_MX:
1884                                 gotmx = true;
1885                                 if (*dp != '\0' && HasWildcardMX)
1886                                 {
1887                                         /*
1888                                         **  If we are using MX matches and have
1889                                         **  not yet gotten one, save this one
1890                                         **  but keep searching for an A or
1891                                         **  CNAME match.
1892                                         */
1893
1894                                         if (trymx && mxmatch == NULL)
1895                                                 mxmatch = dp;
1896                                         continue;
1897                                 }
1898
1899                                 /*
1900                                 **  If we did not append a domain name, this
1901                                 **  must have been a canonical name to start
1902                                 **  with.  Even if we did append a domain name,
1903                                 **  in the absence of a wildcard MX this must
1904                                 **  still be a real MX match.
1905                                 **  Such MX matches are as good as an A match,
1906                                 **  fall through.
1907                                 */
1908                                 /* FALLTHROUGH */
1909
1910 # if NETINET6
1911                           case T_AAAA:
1912 # endif
1913                           case T_A:
1914                                 /* Flag that a good match was found */
1915                                 amatch = true;
1916
1917                                 /* continue in case a CNAME also exists */
1918                                 continue;
1919
1920                           case T_CNAME:
1921                                 if (DontExpandCnames)
1922                                 {
1923                                         /* got CNAME -- guaranteed canonical */
1924                                         amatch = true;
1925                                         break;
1926                                 }
1927
1928                                 if (loopcnt++ > MAXCNAMEDEPTH)
1929                                 {
1930                                         /*XXX should notify postmaster XXX*/
1931                                         message("DNS failure: CNAME loop for %s",
1932                                                 host);
1933                                         if (CurEnv->e_message == NULL)
1934                                         {
1935                                                 char ebuf[MAXLINE];
1936
1937                                                 (void) sm_snprintf(ebuf,
1938                                                         sizeof(ebuf),
1939                                                         "Deferred: DNS failure: CNAME loop for %.100s",
1940                                                         host);
1941                                                 CurEnv->e_message =
1942                                                     sm_rpool_strdup_x(
1943                                                         CurEnv->e_rpool, ebuf);
1944                                         }
1945                                         SM_SET_H_ERRNO(NO_RECOVERY);
1946                                         *statp = EX_CONFIG;
1947                                         goto error;
1948                                 }
1949
1950                                 /* value points at name */
1951                                 if ((ret = dn_expand((unsigned char *)&answer,
1952                                                      eom, ap, (RES_UNC_T) nbuf,
1953                                                      sizeof(nbuf))) < 0)
1954                                         break;
1955                                 (void) sm_strlcpy(host, nbuf, hbsize);
1956
1957                                 /*
1958                                 **  RFC 1034 section 3.6 specifies that CNAME
1959                                 **  should point at the canonical name -- but
1960                                 **  urges software to try again anyway.
1961                                 */
1962
1963                                 goto cnameloop;
1964
1965                           default:
1966                                 /* not a record of interest */
1967                                 continue;
1968                         }
1969                 }
1970
1971                 if (amatch)
1972                 {
1973                         /*
1974                         **  Got a good match -- either an A, CNAME, or an
1975                         **  exact MX record.  Save it and get out of here.
1976                         */
1977
1978                         mxmatch = dp;
1979                         break;
1980                 }
1981
1982                 /*
1983                 **  Nothing definitive yet.
1984                 **      If this was a T_A query and we haven't yet found a MX
1985                 **              match, try T_MX if allowed to do so.
1986                 **      Otherwise, try the next domain.
1987                 */
1988
1989 # if NETINET6
1990                 if (qtype == T_AAAA)
1991                         qtype = T_A;
1992                 else
1993 # endif
1994                 if (qtype == T_A && !gotmx && (trymx || *dp == '\0'))
1995                         qtype = T_MX;
1996                 else
1997                 {
1998                         qtype = initial;
1999                         sli++;
2000                 }
2001         }
2002
2003         /* if nothing was found, we are done */
2004         if (mxmatch == NULL)
2005         {
2006                 if (*statp == EX_OK)
2007                         *statp = EX_NOHOST;
2008                 goto error;
2009         }
2010
2011         /*
2012         **  Create canonical name and return.
2013         **  If saved domain name is null, name was already canonical.
2014         **  Otherwise append the saved domain name.
2015         */
2016
2017         (void) sm_snprintf(nbuf, sizeof(nbuf), "%.*s%s%.*s", MAXDNAME, host,
2018                            *mxmatch == '\0' ? "" : ".",
2019                            MAXDNAME, mxmatch);
2020         (void) sm_strlcpy(host, nbuf, hbsize);
2021         if (tTd(8, 5))
2022                 sm_dprintf("dns_getcanonname: %s\n", host);
2023         *statp = EX_OK;
2024
2025         /* return only one TTL entry, that should be sufficient */
2026         if (ttl > 0 && pttl != NULL)
2027                 *pttl = ttl;
2028 # if DANE
2029         _res.options = old_options;
2030 # endif
2031         return ad ? HOST_SECURE : HOST_OK;
2032
2033   error:
2034 # if DANE
2035         _res.options = old_options;
2036 # endif
2037         return HOST_NOTFOUND;
2038 }
2039
2040 #endif /* NAMED_BIND */