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