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