Postfix3.3.1
smtp_tls_policy.c
[詳解]
1 /*++
2 /* NAME
3 /* smtp_tls_policy 3
4 /* SUMMARY
5 /* SMTP_TLS_POLICY structure management
6 /* SYNOPSIS
7 /* #include "smtp.h"
8 /*
9 /* void smtp_tls_list_init()
10 /*
11 /* int smtp_tls_policy_cache_query(why, tls, iter)
12 /* DSN_BUF *why;
13 /* SMTP_TLS_POLICY *tls;
14 /* SMTP_ITERATOR *iter;
15 /*
16 /* void smtp_tls_policy_dummy(tls)
17 /* SMTP_TLS_POLICY *tls;
18 /*
19 /* void smtp_tls_policy_cache_flush()
20 /* DESCRIPTION
21 /* smtp_tls_list_init() initializes lookup tables used by the TLS
22 /* policy engine.
23 /*
24 /* smtp_tls_policy_cache_query() returns a shallow copy of the
25 /* cached SMTP_TLS_POLICY structure for the iterator's
26 /* destination, host, port and DNSSEC validation status.
27 /* This copy is guaranteed to be valid until the next
28 /* smtp_tls_policy_cache_query() or smtp_tls_policy_cache_flush()
29 /* call. The caller can override the TLS security level without
30 /* corrupting the policy cache.
31 /* When any required table or DNS lookups fail, the TLS level
32 /* is set to TLS_LEV_INVALID, the "why" argument is updated
33 /* with the error reason and the result value is zero (false).
34 /*
35 /* smtp_tls_policy_dummy() initializes a trivial, non-cached,
36 /* policy with TLS disabled.
37 /*
38 /* smtp_tls_policy_cache_flush() destroys the TLS policy cache
39 /* and contents.
40 /*
41 /* Arguments:
42 /* .IP why
43 /* A pointer to a DSN_BUF which holds error status information when
44 /* the TLS policy lookup fails.
45 /* .IP tls
46 /* Pointer to TLS policy storage.
47 /* .IP iter
48 /* The literal next-hop or fall-back destination including
49 /* the optional [] and including the :port or :service;
50 /* the name of the remote host after MX and CNAME expansions
51 /* (see smtp_cname_overrides_servername for the handling
52 /* of hostnames that resolve to a CNAME record);
53 /* the printable address of the remote host;
54 /* the remote port in network byte order;
55 /* the DNSSEC validation status of the host name lookup after
56 /* MX and CNAME expansions.
57 /* LICENSE
58 /* .ad
59 /* .fi
60 /* This software is free. You can do with it whatever you want.
61 /* The original author kindly requests that you acknowledge
62 /* the use of his software.
63 /* AUTHOR(S)
64 /* TLS support originally by:
65 /* Lutz Jaenicke
66 /* BTU Cottbus
67 /* Allgemeine Elektrotechnik
68 /* Universitaetsplatz 3-4
69 /* D-03044 Cottbus, Germany
70 /*
71 /* Updated by:
72 /* Wietse Venema
73 /* IBM T.J. Watson Research
74 /* P.O. Box 704
75 /* Yorktown Heights, NY 10598, USA
76 /*
77 /* Viktor Dukhovni
78 /*--*/
79 
80 /* System library. */
81 
82 #include <sys_defs.h>
83 
84 #ifdef USE_TLS
85 
86 #include <netinet/in.h> /* ntohs() for Solaris or BSD */
87 #include <arpa/inet.h> /* ntohs() for Linux or BSD */
88 #include <stdlib.h>
89 #include <string.h>
90 
91 #ifdef STRCASECMP_IN_STRINGS_H
92 #include <strings.h>
93 #endif
94 
95 /* Utility library. */
96 
97 #include <msg.h>
98 #include <mymalloc.h>
99 #include <vstring.h>
100 #include <stringops.h>
101 #include <valid_utf8_hostname.h>
102 #include <ctable.h>
103 
104 /* Global library. */
105 
106 #include <mail_params.h>
107 #include <maps.h>
108 #include <dsn_buf.h>
109 
110 /* DNS library. */
111 
112 #include <dns.h>
113 
114 /* Application-specific. */
115 
116 #include "smtp.h"
117 
118 /* XXX Cache size should scale with [sl]mtp_mx_address_limit. */
119 #define CACHE_SIZE 20
120 static CTABLE *policy_cache;
121 
122 static int global_tls_level(void);
123 static void dane_init(SMTP_TLS_POLICY *, SMTP_ITERATOR *);
124 
125 static MAPS *tls_policy; /* lookup table(s) */
126 static MAPS *tls_per_site; /* lookup table(s) */
127 
128 /* smtp_tls_list_init - initialize per-site policy lists */
129 
130 void smtp_tls_list_init(void)
131 {
132  if (*var_smtp_tls_policy) {
133  tls_policy = maps_create(VAR_LMTP_SMTP(TLS_POLICY),
138  msg_warn("%s ignored when %s is not empty.",
139  VAR_LMTP_SMTP(TLS_PER_SITE), VAR_LMTP_SMTP(TLS_POLICY));
140  return;
141  }
142  if (*var_smtp_tls_per_site) {
143  tls_per_site = maps_create(VAR_LMTP_SMTP(TLS_PER_SITE),
147  }
148 }
149 
150 /* policy_name - printable tls policy level */
151 
152 static const char *policy_name(int tls_level)
153 {
154  const char *name = str_tls_level(tls_level);
155 
156  if (name == 0)
157  name = "unknown";
158  return name;
159 }
160 
161 #define MARK_INVALID(why, levelp) do { \
162  dsb_simple((why), "4.7.5", "client TLS configuration problem"); \
163  *(levelp) = TLS_LEV_INVALID; } while (0)
164 
165 /* tls_site_lookup - look up per-site TLS security level */
166 
167 static void tls_site_lookup(SMTP_TLS_POLICY *tls, int *site_level,
168  const char *site_name, const char *site_class)
169 {
170  const char *lookup;
171 
172  /*
173  * Look up a non-default policy. In case of multiple lookup results, the
174  * precedence order is a permutation of the TLS enforcement level order:
175  * VERIFY, ENCRYPT, NONE, MAY, NOTFOUND. I.e. we override MAY with a more
176  * specific policy including NONE, otherwise we choose the stronger
177  * enforcement level.
178  */
179  if ((lookup = maps_find(tls_per_site, site_name, 0)) != 0) {
180  if (!strcasecmp(lookup, "NONE")) {
181  /* NONE overrides MAY or NOTFOUND. */
182  if (*site_level <= TLS_LEV_MAY)
183  *site_level = TLS_LEV_NONE;
184  } else if (!strcasecmp(lookup, "MAY")) {
185  /* MAY overrides NOTFOUND but not NONE. */
186  if (*site_level < TLS_LEV_NONE)
187  *site_level = TLS_LEV_MAY;
188  } else if (!strcasecmp(lookup, "MUST_NOPEERMATCH")) {
189  if (*site_level < TLS_LEV_ENCRYPT)
190  *site_level = TLS_LEV_ENCRYPT;
191  } else if (!strcasecmp(lookup, "MUST")) {
192  if (*site_level < TLS_LEV_VERIFY)
193  *site_level = TLS_LEV_VERIFY;
194  } else {
195  msg_warn("%s: unknown TLS policy '%s' for %s %s",
196  tls_per_site->title, lookup, site_class, site_name);
197  MARK_INVALID(tls->why, site_level);
198  return;
199  }
200  } else if (tls_per_site->error) {
201  msg_warn("%s: %s \"%s\": per-site table lookup error",
202  tls_per_site->title, site_class, site_name);
203  dsb_simple(tls->why, "4.3.0", "Temporary lookup error");
204  *site_level = TLS_LEV_INVALID;
205  return;
206  }
207  return;
208 }
209 
210 /* tls_policy_lookup_one - look up destination TLS policy */
211 
212 static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
213  const char *site_name,
214  const char *site_class)
215 {
216  const char *lookup;
217  char *policy;
218  char *saved_policy;
219  char *tok;
220  const char *err;
221  char *name;
222  char *val;
223  static VSTRING *cbuf;
224 
225 #undef FREE_RETURN
226 #define FREE_RETURN do { myfree(saved_policy); return; } while (0)
227 
228 #define INVALID_RETURN(why, levelp) do { \
229  MARK_INVALID((why), (levelp)); FREE_RETURN; } while (0)
230 
231 #define WHERE \
232  STR(vstring_sprintf(cbuf, "%s, %s \"%s\"", \
233  tls_policy->title, site_class, site_name))
234 
235  if (cbuf == 0)
236  cbuf = vstring_alloc(10);
237 
238  if ((lookup = maps_find(tls_policy, site_name, 0)) == 0) {
239  if (tls_policy->error) {
240  msg_warn("%s: policy table lookup error", WHERE);
241  MARK_INVALID(tls->why, site_level);
242  }
243  return;
244  }
245  saved_policy = policy = mystrdup(lookup);
246 
247  if ((tok = mystrtok(&policy, CHARS_COMMA_SP)) == 0) {
248  msg_warn("%s: invalid empty policy", WHERE);
249  INVALID_RETURN(tls->why, site_level);
250  }
251  *site_level = tls_level_lookup(tok);
252  if (*site_level == TLS_LEV_INVALID) {
253  /* tls_level_lookup() logs no warning. */
254  msg_warn("%s: invalid security level \"%s\"", WHERE, tok);
255  INVALID_RETURN(tls->why, site_level);
256  }
257 
258  /*
259  * Warn about ignored attributes when TLS is disabled.
260  */
261  if (*site_level < TLS_LEV_MAY) {
262  while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0)
263  msg_warn("%s: ignoring attribute \"%s\" with TLS disabled",
264  WHERE, tok);
265  FREE_RETURN;
266  }
267 
268  /*
269  * Errors in attributes may have security consequences, don't ignore
270  * errors that can degrade security.
271  */
272  while ((tok = mystrtok(&policy, CHARS_COMMA_SP)) != 0) {
273  if ((err = split_nameval(tok, &name, &val)) != 0) {
274  msg_warn("%s: malformed attribute/value pair \"%s\": %s",
275  WHERE, tok, err);
276  INVALID_RETURN(tls->why, site_level);
277  }
278  /* Only one instance per policy. */
279  if (!strcasecmp(name, "ciphers")) {
280  if (*val == 0) {
281  msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
282  INVALID_RETURN(tls->why, site_level);
283  }
284  if (tls->grade) {
285  msg_warn("%s: attribute \"%s\" is specified multiple times",
286  WHERE, name);
287  INVALID_RETURN(tls->why, site_level);
288  }
289  tls->grade = mystrdup(val);
290  continue;
291  }
292  /* Only one instance per policy. */
293  if (!strcasecmp(name, "protocols")) {
294  if (tls->protocols) {
295  msg_warn("%s: attribute \"%s\" is specified multiple times",
296  WHERE, name);
297  INVALID_RETURN(tls->why, site_level);
298  }
299  tls->protocols = mystrdup(val);
300  continue;
301  }
302  /* Multiple instances per policy. */
303  if (!strcasecmp(name, "match")) {
304  if (*val == 0) {
305  msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
306  INVALID_RETURN(tls->why, site_level);
307  }
308  switch (*site_level) {
309  default:
310  msg_warn("%s: attribute \"%s\" invalid at security level "
311  "\"%s\"", WHERE, name, policy_name(*site_level));
312  INVALID_RETURN(tls->why, site_level);
313  break;
314  case TLS_LEV_FPRINT:
315  if (!tls->dane)
316  tls->dane = tls_dane_alloc();
317  tls_dane_add_ee_digests(tls->dane,
318  var_smtp_tls_fpt_dgst, val, "|");
319  break;
320  case TLS_LEV_VERIFY:
321  case TLS_LEV_SECURE:
322  if (tls->matchargv == 0)
323  tls->matchargv = argv_split(val, ":");
324  else
325  argv_split_append(tls->matchargv, val, ":");
326  break;
327  }
328  continue;
329  }
330  /* Only one instance per policy. */
331  if (!strcasecmp(name, "exclude")) {
332  if (tls->exclusions) {
333  msg_warn("%s: attribute \"%s\" is specified multiple times",
334  WHERE, name);
335  INVALID_RETURN(tls->why, site_level);
336  }
337  tls->exclusions = vstring_strcpy(vstring_alloc(10), val);
338  continue;
339  }
340  /* Multiple instances per policy. */
341  if (!strcasecmp(name, "tafile")) {
342  /* Only makes sense if we're using CA-based trust */
343  if (!TLS_MUST_PKIX(*site_level)) {
344  msg_warn("%s: attribute \"%s\" invalid at security level"
345  " \"%s\"", WHERE, name, policy_name(*site_level));
346  INVALID_RETURN(tls->why, site_level);
347  }
348  if (*val == 0) {
349  msg_warn("%s: attribute \"%s\" has empty value", WHERE, name);
350  INVALID_RETURN(tls->why, site_level);
351  }
352  if (!tls->dane)
353  tls->dane = tls_dane_alloc();
354  if (!tls_dane_load_trustfile(tls->dane, val)) {
355  INVALID_RETURN(tls->why, site_level);
356  }
357  continue;
358  }
359  msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
360  INVALID_RETURN(tls->why, site_level);
361  }
362 
363  FREE_RETURN;
364 }
365 
366 /* tls_policy_lookup - look up destination TLS policy */
367 
368 static void tls_policy_lookup(SMTP_TLS_POLICY *tls, int *site_level,
369  const char *site_name,
370  const char *site_class)
371 {
372 
373  /*
374  * Only one lookup with [nexthop]:port, [nexthop] or nexthop:port These
375  * are never the domain part of localpart@domain, rather they are
376  * explicit nexthops from transport:nexthop, and match only the
377  * corresponding policy. Parent domain matching (below) applies only to
378  * sub-domains of the recipient domain.
379  *
380  * XXX UNIX-domain connections query with the pathname as destination.
381  */
383  tls_policy_lookup_one(tls, site_level, site_name, site_class);
384  return;
385  }
386  do {
387  tls_policy_lookup_one(tls, site_level, site_name, site_class);
388  } while (*site_level == TLS_LEV_NOTFOUND
389  && (site_name = strchr(site_name + 1, '.')) != 0);
390 }
391 
392 /* load_tas - load one or more ta files */
393 
394 static int load_tas(TLS_DANE *dane, const char *files)
395 {
396  int ret = 0;
397  char *save = mystrdup(files);
398  char *buf = save;
399  char *file;
400 
401  do {
402  if ((file = mystrtok(&buf, CHARS_COMMA_SP)) != 0)
403  ret = tls_dane_load_trustfile(dane, file);
404  } while (file && ret);
405 
406  myfree(save);
407  return (ret);
408 }
409 
410 /* set_cipher_grade - Set cipher grade and exclusions */
411 
412 static void set_cipher_grade(SMTP_TLS_POLICY *tls)
413 {
414  const char *mand_exclude = "";
415  const char *also_exclude = "";
416 
417  /*
418  * Use main.cf cipher level if no per-destination value specified. With
419  * mandatory encryption at least encrypt, and with mandatory verification
420  * at least authenticate!
421  */
422  switch (tls->level) {
423  case TLS_LEV_INVALID:
424  case TLS_LEV_NONE:
425  return;
426 
427  case TLS_LEV_MAY:
428  if (tls->grade == 0)
429  tls->grade = mystrdup(var_smtp_tls_ciph);
430  break;
431 
432  case TLS_LEV_ENCRYPT:
433  if (tls->grade == 0)
434  tls->grade = mystrdup(var_smtp_tls_mand_ciph);
435  mand_exclude = var_smtp_tls_mand_excl;
436  also_exclude = "eNULL";
437  break;
438 
439  case TLS_LEV_HALF_DANE:
440  case TLS_LEV_DANE:
441  case TLS_LEV_DANE_ONLY:
442  case TLS_LEV_FPRINT:
443  case TLS_LEV_VERIFY:
444  case TLS_LEV_SECURE:
445  if (tls->grade == 0)
446  tls->grade = mystrdup(var_smtp_tls_mand_ciph);
447  mand_exclude = var_smtp_tls_mand_excl;
448  also_exclude = "aNULL";
449  break;
450  }
451 
452 #define ADD_EXCLUDE(vstr, str) \
453  do { \
454  if (*(str)) \
455  vstring_sprintf_append((vstr), "%s%s", \
456  VSTRING_LEN(vstr) ? " " : "", (str)); \
457  } while (0)
458 
459  /*
460  * The "exclude" policy table attribute overrides main.cf exclusion
461  * lists.
462  */
463  if (tls->exclusions == 0) {
464  tls->exclusions = vstring_alloc(10);
465  ADD_EXCLUDE(tls->exclusions, var_smtp_tls_excl_ciph);
466  ADD_EXCLUDE(tls->exclusions, mand_exclude);
467  }
468  ADD_EXCLUDE(tls->exclusions, also_exclude);
469 }
470 
471 /* policy_create - create SMTP TLS policy cache object (ctable call-back) */
472 
473 static void *policy_create(const char *unused_key, void *context)
474 {
475  SMTP_ITERATOR *iter = (SMTP_ITERATOR *) context;
476  int site_level;
477  const char *dest = STR(iter->dest);
478  const char *host = STR(iter->host);
479 
480  /*
481  * Prepare a pristine policy object.
482  */
483  SMTP_TLS_POLICY *tls = (SMTP_TLS_POLICY *) mymalloc(sizeof(*tls));
484 
485  smtp_tls_policy_init(tls, dsb_create());
486 
487  /*
488  * Compute the per-site TLS enforcement level. For compatibility with the
489  * original TLS patch, this algorithm is gives equal precedence to host
490  * and next-hop policies.
491  */
492  tls->level = global_tls_level();
493  site_level = TLS_LEV_NOTFOUND;
494 
495  if (tls_policy) {
496  tls_policy_lookup(tls, &site_level, dest, "next-hop destination");
497  } else if (tls_per_site) {
498  tls_site_lookup(tls, &site_level, dest, "next-hop destination");
499  if (site_level != TLS_LEV_INVALID
500  && strcasecmp_utf8(dest, host) != 0)
501  tls_site_lookup(tls, &site_level, host, "server hostname");
502 
503  /*
504  * Override a wild-card per-site policy with a more specific global
505  * policy.
506  *
507  * With the original TLS patch, 1) a per-site ENCRYPT could not override
508  * a global VERIFY, and 2) a combined per-site (NONE+MAY) policy
509  * produced inconsistent results: it changed a global VERIFY into
510  * NONE, while producing MAY with all weaker global policy settings.
511  *
512  * With the current implementation, a combined per-site (NONE+MAY)
513  * consistently overrides global policy with NONE, and global policy
514  * can override only a per-site MAY wildcard. That is, specific
515  * policies consistently override wildcard policies, and
516  * (non-wildcard) per-site policies consistently override global
517  * policies.
518  */
519  if (site_level == TLS_LEV_MAY && tls->level > TLS_LEV_MAY)
520  site_level = tls->level;
521  }
522  switch (site_level) {
523  default:
524  tls->level = site_level;
525  /* FALLTHROUGH */
526  case TLS_LEV_NOTFOUND:
527  break;
528  case TLS_LEV_INVALID:
529  tls->level = site_level;
530  return ((void *) tls);
531  }
532 
533  /*
534  * DANE initialization may change the security level to something else,
535  * so do this early, so that we use the right level below. Note that
536  * "dane-only" changes to "dane" once we obtain the requisite TLSA
537  * records.
538  */
539  if (TLS_DANE_BASED(tls->level))
540  dane_init(tls, iter);
541  if (tls->level == TLS_LEV_INVALID)
542  return ((void *) tls);
543 
544  /*
545  * Use main.cf protocols setting if not set in per-destination table.
546  */
547  if (tls->level > TLS_LEV_NONE && tls->protocols == 0)
548  tls->protocols =
549  mystrdup((tls->level == TLS_LEV_MAY) ?
551 
552  /*
553  * Compute cipher grade (if set in per-destination table, else
554  * set_cipher() uses main.cf settings) and security level dependent
555  * cipher exclusion list.
556  */
557  set_cipher_grade(tls);
558 
559  /*
560  * Use main.cf cert_match setting if not set in per-destination table.
561  */
562  switch (tls->level) {
563  case TLS_LEV_INVALID:
564  case TLS_LEV_NONE:
565  case TLS_LEV_MAY:
566  case TLS_LEV_ENCRYPT:
567  case TLS_LEV_HALF_DANE:
568  case TLS_LEV_DANE:
569  case TLS_LEV_DANE_ONLY:
570  break;
571  case TLS_LEV_FPRINT:
572  if (tls->dane == 0)
573  tls->dane = tls_dane_alloc();
574  if (!TLS_DANE_HASEE(tls->dane)) {
575  tls_dane_add_ee_digests(tls->dane, var_smtp_tls_fpt_dgst,
577  if (!TLS_DANE_HASEE(tls->dane)) {
578  msg_warn("nexthop domain %s: configured at fingerprint "
579  "security level, but with no fingerprints to match.",
580  dest);
581  MARK_INVALID(tls->why, &tls->level);
582  return ((void *) tls);
583  }
584  }
585  break;
586  case TLS_LEV_VERIFY:
587  case TLS_LEV_SECURE:
588  if (tls->matchargv == 0)
589  tls->matchargv =
590  argv_split(tls->level == TLS_LEV_VERIFY ?
592  CHARS_COMMA_SP ":");
593  if (*var_smtp_tls_tafile) {
594  if (tls->dane == 0)
595  tls->dane = tls_dane_alloc();
596  if (!TLS_DANE_HASTA(tls->dane)
597  && !load_tas(tls->dane, var_smtp_tls_tafile)) {
598  MARK_INVALID(tls->why, &tls->level);
599  return ((void *) tls);
600  }
601  }
602  break;
603  default:
604  msg_panic("unexpected TLS security level: %d", tls->level);
605  }
606 
607  if (msg_verbose && tls->level != global_tls_level())
608  msg_info("%s TLS level: %s", "effective", policy_name(tls->level));
609 
610  return ((void *) tls);
611 }
612 
613 /* policy_delete - free no longer cached policy (ctable call-back) */
614 
615 static void policy_delete(void *item, void *unused_context)
616 {
617  SMTP_TLS_POLICY *tls = (SMTP_TLS_POLICY *) item;
618 
619  if (tls->protocols)
620  myfree(tls->protocols);
621  if (tls->grade)
622  myfree(tls->grade);
623  if (tls->exclusions)
624  vstring_free(tls->exclusions);
625  if (tls->matchargv)
626  argv_free(tls->matchargv);
627  if (tls->dane)
628  tls_dane_free(tls->dane);
629  dsb_free(tls->why);
630 
631  myfree((void *) tls);
632 }
633 
634 /* smtp_tls_policy_cache_query - cached lookup of TLS policy */
635 
636 int smtp_tls_policy_cache_query(DSN_BUF *why, SMTP_TLS_POLICY *tls,
637  SMTP_ITERATOR *iter)
638 {
639  VSTRING *key;
640 
641  /*
642  * Create an empty TLS Policy cache on the fly.
643  */
644  if (policy_cache == 0)
645  policy_cache =
646  ctable_create(CACHE_SIZE, policy_create, policy_delete, (void *) 0);
647 
648  /*
649  * Query the TLS Policy cache, with a search key that reflects our shared
650  * values that also appear in other cache and table search keys.
651  */
652  key = vstring_alloc(100);
653  smtp_key_prefix(key, ":", iter, SMTP_KEY_FLAG_NEXTHOP
656  ctable_newcontext(policy_cache, (void *) iter);
657  *tls = *(SMTP_TLS_POLICY *) ctable_locate(policy_cache, STR(key));
658  vstring_free(key);
659 
660  /*
661  * Report errors. Both error and non-error results are cached. We must
662  * therefore copy the cached DSN buffer content to the caller's buffer.
663  */
664  if (tls->level == TLS_LEV_INVALID) {
665  /* XXX Simplify this by implementing a "copy" primitive. */
666  dsb_update(why,
667  STR(tls->why->status), STR(tls->why->action),
668  STR(tls->why->mtype), STR(tls->why->mname),
669  STR(tls->why->dtype), STR(tls->why->dtext),
670  "%s", STR(tls->why->reason));
671  return (0);
672  } else {
673  return (1);
674  }
675 }
676 
677 /* smtp_tls_policy_cache_flush - flush TLS policy cache */
678 
679 void smtp_tls_policy_cache_flush(void)
680 {
681  if (policy_cache != 0) {
682  ctable_free(policy_cache);
683  policy_cache = 0;
684  }
685 }
686 
687 /* global_tls_level - parse and cache var_smtp_tls_level */
688 
689 static int global_tls_level(void)
690 {
691  static int l = TLS_LEV_NOTFOUND;
692 
693  if (l != TLS_LEV_NOTFOUND)
694  return l;
695 
696  /*
697  * Compute the global TLS policy. This is the default policy level when
698  * no per-site policy exists. It also is used to override a wild-card
699  * per-site policy.
700  *
701  * We require that the global level is valid on startup.
702  */
703  if (*var_smtp_tls_level) {
705  msg_fatal("invalid tls security level: \"%s\"", var_smtp_tls_level);
706  } else if (var_smtp_enforce_tls)
708  else
710 
711  if (msg_verbose)
712  msg_info("%s TLS level: %s", "global", policy_name(l));
713 
714  return l;
715 }
716 
717 #define NONDANE_CONFIG 0 /* Administrator's fault */
718 #define NONDANE_DEST 1 /* Remote server's fault */
719 #define DANE_CANTAUTH 2 /* Remote server's fault */
720 
721 static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
722  SMTP_ITERATOR *iter,
723  int errtype,
724  const char *fmt,...)
725 {
726  va_list ap;
727 
728  va_start(ap, fmt);
729  if (tls->level == TLS_LEV_DANE) {
730  tls->level = (errtype == DANE_CANTAUTH) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
731  if (errtype == NONDANE_CONFIG)
732  vmsg_warn(fmt, ap);
733  else if (msg_verbose)
734  vmsg_info(fmt, ap);
735  } else { /* dane-only */
736  if (errtype == NONDANE_CONFIG) {
737  vmsg_warn(fmt, ap);
738  MARK_INVALID(tls->why, &tls->level);
739  } else {
740  tls->level = TLS_LEV_INVALID;
741  vdsb_simple(tls->why, "4.7.5", fmt, ap);
742  }
743  }
744  va_end(ap);
745 }
746 
747 /* dane_init - special initialization for "dane" security level */
748 
749 static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
750 {
751  TLS_DANE *dane;
752 
753  if (!iter->port) {
754  msg_warn("%s: the \"dane\" security level is invalid for delivery via"
755  " unix-domain sockets", STR(iter->dest));
756  MARK_INVALID(tls->why, &tls->level);
757  return;
758  }
759  if (!tls_dane_avail()) {
760  dane_incompat(tls, iter, NONDANE_CONFIG,
761  "%s: %s configured, but no requisite library support",
762  STR(iter->dest), policy_name(tls->level));
763  return;
764  }
767  dane_incompat(tls, iter, NONDANE_CONFIG,
768  "%s: %s configured with dnssec lookups disabled",
769  STR(iter->dest), policy_name(tls->level));
770  return;
771  }
772 
773  /*
774  * If we ignore MX lookup errors, we also ignore DNSSEC security problems
775  * and thus avoid any reasonable expectation that we get the right DANE
776  * key material.
777  */
779  dane_incompat(tls, iter, NONDANE_CONFIG,
780  "%s: %s configured with MX lookup errors ignored",
781  STR(iter->dest), policy_name(tls->level));
782  return;
783  }
784 
785  /*
786  * This is not optional, code in tls_dane.c assumes that the nexthop
787  * qname is already an fqdn. If we're using these flags to go from qname
788  * to rname, the assumption is invalid. Likewise we cannot add the qname
789  * to certificate name checks, ...
790  */
791  if (smtp_dns_res_opt & (RES_DEFNAMES | RES_DNSRCH)) {
792  dane_incompat(tls, iter, NONDANE_CONFIG,
793  "%s: dns resolver options incompatible with %s TLS",
794  STR(iter->dest), policy_name(tls->level));
795  return;
796  }
797 
798  /*
799  * When the MX name is present and insecure, DANE may not apply, we then
800  * either fail if DANE is mandatory or use regular opportunistic TLS if
801  * the insecure MX level is "may".
802  */
803  if (iter->mx && !iter->mx->dnssec_valid
804  && (tls->level == TLS_LEV_DANE_ONLY ||
805  smtp_tls_insecure_mx_policy <= TLS_LEV_MAY)) {
806  dane_incompat(tls, iter, NONDANE_DEST, "non DNSSEC destination");
807  return;
808  }
809  /* When TLSA lookups fail, we defer the message */
810  if ((dane = tls_dane_resolve(iter->port, "tcp", iter->rr,
811  var_smtp_tls_force_tlsa)) == 0) {
812  tls->level = TLS_LEV_INVALID;
813  dsb_simple(tls->why, "4.7.5", "TLSA lookup error for %s:%u",
814  STR(iter->host), ntohs(iter->port));
815  return;
816  }
817  if (tls_dane_notfound(dane)) {
818  dane_incompat(tls, iter, NONDANE_DEST, "no TLSA records found");
819  tls_dane_free(dane);
820  return;
821  }
822 
823  /*
824  * Some TLSA records found, but none usable, per
825  *
826  * https://tools.ietf.org/html/draft-ietf-dane-srv-02#section-4
827  *
828  * we MUST use TLS, and SHALL use full PKIX certificate checks. The latter
829  * would be unwise for SMTP: no human present to "click ok" and risk of
830  * non-delivery in most cases exceeds risk of interception.
831  *
832  * We also have a form of Goedel's incompleteness theorem in play: any list
833  * of public root CA certs is either incomplete or inconsistent (for any
834  * given verifier some of the CAs are surely not trustworthy).
835  */
836  if (tls_dane_unusable(dane)) {
837  dane_incompat(tls, iter, DANE_CANTAUTH, "TLSA records unusable");
838  tls_dane_free(dane);
839  return;
840  }
841 
842  /*
843  * Perhaps downgrade to "encrypt" if MX is insecure.
844  */
845  if (iter->mx && !iter->mx->dnssec_valid) {
846  if (smtp_tls_insecure_mx_policy == TLS_LEV_ENCRYPT) {
847  dane_incompat(tls, iter, DANE_CANTAUTH,
848  "Verification not possible, MX RRset is insecure");
849  tls_dane_free(dane);
850  return;
851  }
852  if (tls->level != TLS_LEV_DANE
853  || smtp_tls_insecure_mx_policy != TLS_LEV_DANE)
854  msg_panic("wrong state for insecure MX host DANE policy");
855 
856  /* For correct logging in tls_client_start() */
857  tls->level = TLS_LEV_HALF_DANE;
858  }
859 
860  /*
861  * With DANE trust anchors, peername matching is not configurable.
862  */
863  if (TLS_DANE_HASTA(dane)) {
864  tls->matchargv = argv_alloc(2);
865  argv_add(tls->matchargv, dane->base_domain, ARGV_END);
866  if (iter->mx) {
867  if (strcmp(iter->mx->qname, iter->mx->rname) == 0)
868  argv_add(tls->matchargv, iter->mx->qname, ARGV_END);
869  else
870  argv_add(tls->matchargv, iter->mx->rname,
871  iter->mx->qname, ARGV_END);
872  }
873  } else if (!TLS_DANE_HASEE(dane))
874  msg_panic("empty DANE match list");
875  tls->dane = dane;
876  return;
877 }
878 
879 #endif
#define SMTP_KEY_FLAG_HOSTNAME
Definition: smtp.h:614
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
#define CTABLE
Definition: ctable.h:19
#define TLS_LEV_DANE_ONLY
Definition: tls.h:49
#define ARGV_END
Definition: argv.h:52
DSN_BUF * dsb_create(void)
Definition: dsn_buf.c:169
unsigned port
Definition: smtp.h:56
char * mystrdup(const char *str)
Definition: mymalloc.c:225
bool var_smtp_use_tls
Definition: smtp.c:893
#define TLS_LEV_HALF_DANE
Definition: tls.h:47
char * qname
Definition: dns.h:140
char * var_smtp_tls_per_site
Definition: smtp.c:895
ARGV * argv_free(ARGV *argvp)
Definition: argv.c:136
const char * str_tls_level(int)
Definition: tls_level.c:92
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
DSN_BUF * dsb_update(DSN_BUF *dsb, const char *status, const char *action, const char *mtype, const char *mname, const char *dtype, const char *dtext, const char *format,...)
Definition: dsn_buf.c:239
int smtp_mode
Definition: smtp.c:963
char * var_smtp_tls_mand_excl
bool var_ign_mx_lookup_err
Definition: smtp.c:853
struct DNS_RR * rr
Definition: smtp.h:57
#define TLS_DANE_BASED(l)
Definition: tls.h:58
char * var_smtp_tls_level
Definition: smtp.c:892
const void * ctable_locate(CTABLE *cache, const char *key)
Definition: ctable.c:140
Definition: maps.h:22
void dsb_free(DSN_BUF *dsb)
Definition: dsn_buf.c:190
DSN_BUF * vdsb_simple(DSN_BUF *dsb, const char *status, const char *format, va_list ap)
Definition: dsn_buf.c:259
#define TLS_LEV_VERIFY
Definition: tls.h:50
void argv_add(ARGV *argvp,...)
Definition: argv.c:197
int smtp_host_lookup_mask
Definition: smtp.c:964
char * var_smtp_tls_policy
Definition: smtp.c:896
#define TLS_LEV_NONE
Definition: tls.h:43
#define DICT_FLAG_UTF8_REQUEST
Definition: dict.h:130
int var_smtputf8_enable
Definition: mail_params.c:343
#define strcasecmp_utf8(s1, s2)
Definition: stringops.h:75
char * mystrtok(char **src, const char *sep)
Definition: mystrtok.c:54
ARGV * argv_alloc(ssize_t len)
Definition: argv.c:149
const char * split_nameval(char *buf, char **name, char **value)
Definition: split_nameval.c:61
#define DICT_FLAG_FOLD_FIX
Definition: dict.h:124
char * var_smtp_tls_vfy_cmatch
#define TLS_LEV_DANE
Definition: tls.h:48
VSTRING * dest
Definition: smtp.h:53
#define SMTP_HOST_FLAG_DNS
Definition: smtp.h:269
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
int const char * fmt
#define TLS_LEV_SECURE
Definition: tls.h:51
int smtp_dns_support
Definition: smtp.c:965
void ctable_newcontext(CTABLE *cache, void *context)
Definition: ctable.c:207
int valid_utf8_hostname(int enable_utf8, const char *name, int gripe)
char * var_smtp_tls_proto
struct DNS_RR * mx
Definition: smtp.h:58
bool var_smtp_tls_force_tlsa
MAPS * maps_create(const char *title, const char *map_names, int dict_flags)
Definition: maps.c:112
VSTRING * host
Definition: smtp.h:54
#define SMTP_KEY_FLAG_PORT
Definition: smtp.h:616
char * var_smtp_tls_tafile
char * title
Definition: maps.h:23
#define DICT_FLAG_LOCK
Definition: dict.h:116
#define STR(x)
Definition: anvil.c:518
void msg_warn(const char *fmt,...)
Definition: msg.c:215
CTABLE * ctable_create(ssize_t limit, CTABLE_CREATE_FN create, CTABLE_DELETE_FN delete, void *context)
Definition: ctable.c:119
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define VAR_LMTP_SMTP(x)
Definition: smtp.h:671
#define TLS_LEV_ENCRYPT
Definition: tls.h:45
char * var_smtp_tls_ciph
unsigned smtp_dns_res_opt
Definition: smtp.c:971
DSN_BUF * dsb_simple(DSN_BUF *dsb, const char *status, const char *format,...)
Definition: dsn_buf.c:275
char * var_smtp_tls_excl_ciph
void vmsg_warn(const char *fmt, va_list ap)
Definition: msg.c:224
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
bool var_smtp_tls_enforce_peername
#define TLS_LEV_FPRINT
Definition: tls.h:46
#define CHARS_COMMA_SP
Definition: sys_defs.h:1761
int error
Definition: maps.h:25
int tls_level_lookup(const char *)
Definition: tls_level.c:85
#define TLS_MUST_PKIX(l)
Definition: tls.h:56
ARGV * argv_split(const char *, const char *)
Definition: argv_split.c:63
char * var_smtp_tls_fpt_cmatch
int strcasecmp(const char *s1, const char *s2)
Definition: strcasecmp.c:41
#define SMTP_KEY_FLAG_NEXTHOP
Definition: smtp.h:613
void vmsg_info(const char *fmt, va_list ap)
Definition: msg.c:208
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
char * var_smtp_tls_fpt_dgst
char * rname
Definition: dns.h:141
unsigned int dnssec_valid
Definition: dns.h:145
ARGV * argv_split_append(ARGV *, const char *, const char *)
Definition: argv_split.c:101
bool var_smtp_enforce_tls
Definition: smtp.c:894
#define SMTP_DNS_DNSSEC
Definition: smtp.h:277
#define TLS_LEV_NOTFOUND
Definition: tls.h:42
#define TLS_LEV_MAY
Definition: tls.h:44
char * var_smtp_tls_mand_proto
#define PRINTFLIKE(x, y)
Definition: sys_defs.h:1600
#define TLS_LEV_INVALID
Definition: tls.h:41
char * var_smtp_tls_sec_cmatch
void ctable_free(CTABLE *cache)
Definition: ctable.c:226
const char * maps_find(MAPS *maps, const char *name, int flags)
Definition: maps.c:162
char * smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int)
Definition: smtp_key.c:146
char * var_smtp_tls_mand_ciph
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
#define DONT_GRIPE
Definition: haproxy_srvr.h:31
void msg_info(const char *fmt,...)
Definition: msg.c:199