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