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