1 /* $NetBSD: tlsmgr.c,v 1.4 2022/10/08 16:12:50 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* tlsmgr 8 6 /* SUMMARY 7 /* Postfix TLS session cache and PRNG manager 8 /* SYNOPSIS 9 /* \fBtlsmgr\fR [generic Postfix daemon options] 10 /* DESCRIPTION 11 /* The \fBtlsmgr\fR(8) manages the Postfix TLS session caches. 12 /* It stores and retrieves cache entries on request by 13 /* \fBsmtpd\fR(8) and \fBsmtp\fR(8) processes, and periodically 14 /* removes entries that have expired. 15 /* 16 /* The \fBtlsmgr\fR(8) also manages the PRNG (pseudo random number 17 /* generator) pool. It answers queries by the \fBsmtpd\fR(8) 18 /* and \fBsmtp\fR(8) 19 /* processes to seed their internal PRNG pools. 20 /* 21 /* The \fBtlsmgr\fR(8)'s PRNG pool is initially seeded from 22 /* an external source (EGD, /dev/urandom, or regular file). 23 /* It is updated at configurable pseudo-random intervals with 24 /* data from the external source. It is updated periodically 25 /* with data from TLS session cache entries and with the time 26 /* of day, and is updated with the time of day whenever a 27 /* process requests \fBtlsmgr\fR(8) service. 28 /* 29 /* The \fBtlsmgr\fR(8) saves the PRNG state to an exchange file 30 /* periodically and when the process terminates, and reads 31 /* the exchange file when initializing its PRNG. 32 /* SECURITY 33 /* .ad 34 /* .fi 35 /* The \fBtlsmgr\fR(8) is not security-sensitive. The code that maintains 36 /* the external and internal PRNG pools does not "trust" the 37 /* data that it manipulates, and the code that maintains the 38 /* TLS session cache does not touch the contents of the cached 39 /* entries, except for seeding its internal PRNG pool. 40 /* 41 /* The \fBtlsmgr\fR(8) can be run chrooted and with reduced privileges. 42 /* At process startup it connects to the entropy source and 43 /* exchange file, and creates or truncates the optional TLS 44 /* session cache files. 45 /* 46 /* With Postfix version 2.5 and later, the \fBtlsmgr\fR(8) no 47 /* longer uses root privileges when opening cache files. These 48 /* files should now be stored under the Postfix-owned 49 /* \fBdata_directory\fR. As a migration aid, an attempt to 50 /* open a cache file under a non-Postfix directory is redirected 51 /* to the Postfix-owned \fBdata_directory\fR, and a warning 52 /* is logged. 53 /* DIAGNOSTICS 54 /* Problems and transactions are logged to \fBsyslogd\fR(8) 55 /* or \fBpostlogd\fR(8). 56 /* BUGS 57 /* There is no automatic means to limit the number of entries in the 58 /* TLS session caches and/or the size of the TLS cache files. 59 /* CONFIGURATION PARAMETERS 60 /* .ad 61 /* .fi 62 /* Changes to \fBmain.cf\fR are not picked up automatically, 63 /* because \fBtlsmgr\fR(8) is a persistent processes. Use the 64 /* command "\fBpostfix reload\fR" after a configuration change. 65 /* 66 /* The text below provides only a parameter summary. See 67 /* \fBpostconf\fR(5) for more details including examples. 68 /* TLS SESSION CACHE 69 /* .ad 70 /* .fi 71 /* .IP "\fBlmtp_tls_loglevel (0)\fR" 72 /* The LMTP-specific version of the smtp_tls_loglevel 73 /* configuration parameter. 74 /* .IP "\fBlmtp_tls_session_cache_database (empty)\fR" 75 /* The LMTP-specific version of the smtp_tls_session_cache_database 76 /* configuration parameter. 77 /* .IP "\fBlmtp_tls_session_cache_timeout (3600s)\fR" 78 /* The LMTP-specific version of the smtp_tls_session_cache_timeout 79 /* configuration parameter. 80 /* .IP "\fBsmtp_tls_loglevel (0)\fR" 81 /* Enable additional Postfix SMTP client logging of TLS activity. 82 /* .IP "\fBsmtp_tls_session_cache_database (empty)\fR" 83 /* Name of the file containing the optional Postfix SMTP client 84 /* TLS session cache. 85 /* .IP "\fBsmtp_tls_session_cache_timeout (3600s)\fR" 86 /* The expiration time of Postfix SMTP client TLS session cache 87 /* information. 88 /* .IP "\fBsmtpd_tls_loglevel (0)\fR" 89 /* Enable additional Postfix SMTP server logging of TLS activity. 90 /* .IP "\fBsmtpd_tls_session_cache_database (empty)\fR" 91 /* Name of the file containing the optional Postfix SMTP server 92 /* TLS session cache. 93 /* .IP "\fBsmtpd_tls_session_cache_timeout (3600s)\fR" 94 /* The expiration time of Postfix SMTP server TLS session cache 95 /* information. 96 /* PSEUDO RANDOM NUMBER GENERATOR 97 /* .ad 98 /* .fi 99 /* .IP "\fBtls_random_source (see 'postconf -d' output)\fR" 100 /* The external entropy source for the in-memory \fBtlsmgr\fR(8) pseudo 101 /* random number generator (PRNG) pool. 102 /* .IP "\fBtls_random_bytes (32)\fR" 103 /* The number of bytes that \fBtlsmgr\fR(8) reads from $tls_random_source 104 /* when (re)seeding the in-memory pseudo random number generator (PRNG) 105 /* pool. 106 /* .IP "\fBtls_random_exchange_name (see 'postconf -d' output)\fR" 107 /* Name of the pseudo random number generator (PRNG) state file 108 /* that is maintained by \fBtlsmgr\fR(8). 109 /* .IP "\fBtls_random_prng_update_period (3600s)\fR" 110 /* The time between attempts by \fBtlsmgr\fR(8) to save the state of 111 /* the pseudo random number generator (PRNG) to the file specified 112 /* with $tls_random_exchange_name. 113 /* .IP "\fBtls_random_reseed_period (3600s)\fR" 114 /* The maximal time between attempts by \fBtlsmgr\fR(8) to re-seed the 115 /* in-memory pseudo random number generator (PRNG) pool from external 116 /* sources. 117 /* MISCELLANEOUS CONTROLS 118 /* .ad 119 /* .fi 120 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR" 121 /* The default location of the Postfix main.cf and master.cf 122 /* configuration files. 123 /* .IP "\fBdata_directory (see 'postconf -d' output)\fR" 124 /* The directory with Postfix-writable data files (for example: 125 /* caches, pseudo-random numbers). 126 /* .IP "\fBdaemon_timeout (18000s)\fR" 127 /* How much time a Postfix daemon process may take to handle a 128 /* request before it is terminated by a built-in watchdog timer. 129 /* .IP "\fBprocess_id (read-only)\fR" 130 /* The process ID of a Postfix command or daemon process. 131 /* .IP "\fBprocess_name (read-only)\fR" 132 /* The process name of a Postfix command or daemon process. 133 /* .IP "\fBsyslog_facility (mail)\fR" 134 /* The syslog facility of Postfix logging. 135 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR" 136 /* A prefix that is prepended to the process name in syslog 137 /* records, so that, for example, "smtpd" becomes "prefix/smtpd". 138 /* .PP 139 /* Available in Postfix 3.3 and later: 140 /* .IP "\fBservice_name (read-only)\fR" 141 /* The master.cf service name of a Postfix daemon process. 142 /* SEE ALSO 143 /* smtp(8), Postfix SMTP client 144 /* smtpd(8), Postfix SMTP server 145 /* postconf(5), configuration parameters 146 /* master(5), generic daemon options 147 /* master(8), process manager 148 /* postlogd(8), Postfix logging 149 /* syslogd(8), system logging 150 /* README FILES 151 /* .ad 152 /* .fi 153 /* Use "\fBpostconf readme_directory\fR" or 154 /* "\fBpostconf html_directory\fR" to locate this information. 155 /* .na 156 /* .nf 157 /* TLS_README, Postfix TLS configuration and operation 158 /* LICENSE 159 /* .ad 160 /* .fi 161 /* The Secure Mailer license must be distributed with this software. 162 /* HISTORY 163 /* This service was introduced with Postfix version 2.2. 164 /* AUTHOR(S) 165 /* Lutz Jaenicke 166 /* BTU Cottbus 167 /* Allgemeine Elektrotechnik 168 /* Universitaetsplatz 3-4 169 /* D-03044 Cottbus, Germany 170 /* 171 /* Adapted by: 172 /* Wietse Venema 173 /* IBM T.J. Watson Research 174 /* P.O. Box 704 175 /* Yorktown Heights, NY 10598, USA 176 /* 177 /* Wietse Venema 178 /* Google, Inc. 179 /* 111 8th Avenue 180 /* New York, NY 10011, USA 181 /*--*/ 182 183 /* System library. */ 184 185 #include <sys_defs.h> 186 #include <sys/stat.h> 187 #include <stdlib.h> 188 #include <unistd.h> 189 #include <ctype.h> 190 #include <errno.h> 191 #include <string.h> 192 #include <sys/time.h> /* gettimeofday, not POSIX */ 193 #include <limits.h> 194 195 #ifndef UCHAR_MAX 196 #define UCHAR_MAX 0xff 197 #endif 198 199 /* OpenSSL library. */ 200 201 #ifdef USE_TLS 202 #include <openssl/rand.h> /* For the PRNG */ 203 #endif 204 205 /* Utility library. */ 206 207 #include <msg.h> 208 #include <events.h> 209 #include <stringops.h> 210 #include <mymalloc.h> 211 #include <iostuff.h> 212 #include <vstream.h> 213 #include <vstring.h> 214 #include <vstring_vstream.h> 215 #include <attr.h> 216 #include <set_eugid.h> 217 #include <htable.h> 218 #include <warn_stat.h> 219 220 /* Global library. */ 221 222 #include <mail_conf.h> 223 #include <mail_params.h> 224 #include <mail_version.h> 225 #include <mail_proto.h> 226 #include <data_redirect.h> 227 228 /* Master process interface. */ 229 230 #include <master_proto.h> 231 #include <mail_server.h> 232 233 /* TLS library. */ 234 235 #ifdef USE_TLS 236 #include <tls_mgr.h> 237 #define TLS_INTERNAL 238 #include <tls.h> /* TLS_MGR_SCACHE_<type> */ 239 #include <tls_prng.h> 240 #include <tls_scache.h> 241 242 /* Application-specific. */ 243 244 /* 245 * Tunables. 246 */ 247 char *var_tls_rand_source; 248 int var_tls_rand_bytes; 249 int var_tls_reseed_period; 250 int var_tls_prng_exch_period; 251 char *var_smtpd_tls_loglevel; 252 char *var_smtpd_tls_scache_db; 253 int var_smtpd_tls_scache_timeout; 254 char *var_smtp_tls_loglevel; 255 char *var_smtp_tls_scache_db; 256 int var_smtp_tls_scache_timeout; 257 char *var_lmtp_tls_loglevel; 258 char *var_lmtp_tls_scache_db; 259 int var_lmtp_tls_scache_timeout; 260 char *var_tls_rand_exch_name; 261 262 /* 263 * Bound the time that we are willing to wait for an I/O operation. This 264 * produces better error messages than waiting until the watchdog timer 265 * kills the process. 266 */ 267 #define TLS_MGR_TIMEOUT 10 268 269 /* 270 * State for updating the PRNG exchange file. 271 */ 272 static TLS_PRNG_SRC *rand_exch; 273 274 /* 275 * State for seeding the internal PRNG from external source. 276 */ 277 static TLS_PRNG_SRC *rand_source_dev; 278 static TLS_PRNG_SRC *rand_source_egd; 279 static TLS_PRNG_SRC *rand_source_file; 280 281 /* 282 * The external entropy source type is encoded in the source name. The 283 * obvious alternative is to have separate configuration parameters per 284 * source type, so that one process can query multiple external sources. 285 */ 286 #define DEV_PREF "dev:" 287 #define DEV_PREF_LEN (sizeof((DEV_PREF)) - 1) 288 #define DEV_PATH(dev) ((dev) + EGD_PREF_LEN) 289 290 #define EGD_PREF "egd:" 291 #define EGD_PREF_LEN (sizeof((EGD_PREF)) - 1) 292 #define EGD_PATH(egd) ((egd) + EGD_PREF_LEN) 293 294 /* 295 * State for TLS session caches. 296 */ 297 typedef struct { 298 char *cache_label; /* cache short-hand name */ 299 TLS_SCACHE *cache_info; /* cache handle */ 300 int cache_active; /* cache status */ 301 char **cache_db; /* main.cf parameter value */ 302 const char *log_param; /* main.cf parameter name */ 303 char **log_level; /* main.cf parameter value */ 304 int *cache_timeout; /* main.cf parameter value */ 305 } TLSMGR_SCACHE; 306 307 static TLSMGR_SCACHE cache_table[] = { 308 TLS_MGR_SCACHE_SMTPD, 0, 0, &var_smtpd_tls_scache_db, 309 VAR_SMTPD_TLS_LOGLEVEL, 310 &var_smtpd_tls_loglevel, &var_smtpd_tls_scache_timeout, 311 TLS_MGR_SCACHE_SMTP, 0, 0, &var_smtp_tls_scache_db, 312 VAR_SMTP_TLS_LOGLEVEL, 313 &var_smtp_tls_loglevel, &var_smtp_tls_scache_timeout, 314 TLS_MGR_SCACHE_LMTP, 0, 0, &var_lmtp_tls_scache_db, 315 VAR_LMTP_TLS_LOGLEVEL, 316 &var_lmtp_tls_loglevel, &var_lmtp_tls_scache_timeout, 317 0, 318 }; 319 320 #define smtpd_cache (cache_table[0]) 321 322 /* 323 * SLMs. 324 */ 325 #define STR(x) vstring_str(x) 326 #define LEN(x) VSTRING_LEN(x) 327 #define STREQ(x, y) (strcmp((x), (y)) == 0) 328 329 /* tlsmgr_prng_exch_event - update PRNG exchange file */ 330 331 static void tlsmgr_prng_exch_event(int unused_event, void *dummy) 332 { 333 const char *myname = "tlsmgr_prng_exch_event"; 334 unsigned char randbyte; 335 int next_period; 336 struct stat st; 337 338 if (msg_verbose) 339 msg_info("%s: update PRNG exchange file", myname); 340 341 /* 342 * Sanity check. If the PRNG exchange file was removed, there is no point 343 * updating it further. Restart the process and update the new file. 344 */ 345 if (fstat(rand_exch->fd, &st) < 0) 346 msg_fatal("cannot fstat() the PRNG exchange file: %m"); 347 if (st.st_nlink == 0) { 348 msg_warn("PRNG exchange file was removed -- exiting to reopen"); 349 sleep(1); 350 exit(0); 351 } 352 tls_prng_exch_update(rand_exch); 353 354 /* 355 * Make prediction difficult for outsiders and calculate the time for the 356 * next execution randomly. 357 */ 358 RAND_bytes(&randbyte, 1); 359 next_period = (var_tls_prng_exch_period * randbyte) / UCHAR_MAX; 360 event_request_timer(tlsmgr_prng_exch_event, dummy, next_period); 361 } 362 363 /* tlsmgr_reseed_event - re-seed the internal PRNG pool */ 364 365 static void tlsmgr_reseed_event(int unused_event, void *dummy) 366 { 367 int next_period; 368 unsigned char randbyte; 369 int must_exit = 0; 370 371 /* 372 * Reseed the internal PRNG from external source. Errors are recoverable. 373 * We simply restart and reconnect without making a fuss. This is OK 374 * because we do require that exchange file updates succeed. The exchange 375 * file is the only entropy source that really matters in the long term. 376 * 377 * If the administrator specifies an external randomness source that we 378 * could not open upon start-up, restart to see if we can open it now 379 * (and log a nagging warning if we can't). 380 */ 381 if (*var_tls_rand_source) { 382 383 /* 384 * Source is a random device. 385 */ 386 if (rand_source_dev) { 387 if (tls_prng_dev_read(rand_source_dev, var_tls_rand_bytes) <= 0) { 388 msg_info("cannot read from entropy device %s: %m -- " 389 "exiting to reopen", DEV_PATH(var_tls_rand_source)); 390 must_exit = 1; 391 } 392 } 393 394 /* 395 * Source is an EGD compatible socket. 396 */ 397 else if (rand_source_egd) { 398 if (tls_prng_egd_read(rand_source_egd, var_tls_rand_bytes) <= 0) { 399 msg_info("lost connection to EGD server %s -- " 400 "exiting to reconnect", EGD_PATH(var_tls_rand_source)); 401 must_exit = 1; 402 } 403 } 404 405 /* 406 * Source is a regular file. Read the content once and close the 407 * file. 408 */ 409 else if (rand_source_file) { 410 if (tls_prng_file_read(rand_source_file, var_tls_rand_bytes) <= 0) 411 msg_warn("cannot read from entropy file %s: %m", 412 var_tls_rand_source); 413 tls_prng_file_close(rand_source_file); 414 rand_source_file = 0; 415 var_tls_rand_source[0] = 0; 416 } 417 418 /* 419 * Could not open the external source upon start-up. See if we can 420 * open it this time. Save PRNG state before we exit. 421 */ 422 else { 423 msg_info("exiting to reopen external entropy source %s", 424 var_tls_rand_source); 425 must_exit = 1; 426 } 427 } 428 429 /* 430 * Save PRNG state in case we must exit. 431 */ 432 if (must_exit) { 433 if (rand_exch) 434 tls_prng_exch_update(rand_exch); 435 sleep(1); 436 exit(0); 437 } 438 439 /* 440 * Make prediction difficult for outsiders and calculate the time for the 441 * next execution randomly. 442 */ 443 RAND_bytes(&randbyte, 1); 444 next_period = (var_tls_reseed_period * randbyte) / UCHAR_MAX; 445 event_request_timer(tlsmgr_reseed_event, dummy, next_period); 446 } 447 448 /* tlsmgr_cache_run_event - start TLS session cache scan */ 449 450 static void tlsmgr_cache_run_event(int unused_event, void *ctx) 451 { 452 const char *myname = "tlsmgr_cache_run_event"; 453 TLSMGR_SCACHE *cache = (TLSMGR_SCACHE *) ctx; 454 455 /* 456 * This routine runs when it is time for another TLS session cache scan. 457 * Make sure this routine gets called again in the future. 458 * 459 * Don't start a new scan when the timer goes off while cache cleanup is 460 * still in progress. 461 */ 462 if (cache->cache_info->verbose) 463 msg_info("%s: start TLS %s session cache cleanup", 464 myname, cache->cache_label); 465 466 if (cache->cache_active == 0) 467 cache->cache_active = 468 tls_scache_sequence(cache->cache_info, DICT_SEQ_FUN_FIRST, 469 TLS_SCACHE_SEQUENCE_NOTHING); 470 471 event_request_timer(tlsmgr_cache_run_event, (void *) cache, 472 cache->cache_info->timeout); 473 } 474 475 /* tlsmgr_key - return matching or current RFC 5077 session ticket keys */ 476 477 static int tlsmgr_key(VSTRING *buffer, int timeout) 478 { 479 TLS_TICKET_KEY *key; 480 TLS_TICKET_KEY tmp; 481 unsigned char *name; 482 time_t now = time((time_t *) 0); 483 484 /* In tlsmgr requests we encode null key names as empty strings. */ 485 name = LEN(buffer) ? (unsigned char *) STR(buffer) : 0; 486 487 /* 488 * Each key's encrypt and subsequent decrypt-only timeout is half of the 489 * total session timeout. 490 */ 491 timeout /= 2; 492 493 /* Attempt to locate existing key */ 494 if ((key = tls_scache_key(name, now, timeout)) == 0) { 495 if (name == 0) { 496 /* Create new encryption key */ 497 if (RAND_bytes(tmp.name, TLS_TICKET_NAMELEN) <= 0 498 || RAND_bytes(tmp.bits, TLS_TICKET_KEYLEN) <= 0 499 || RAND_bytes(tmp.hmac, TLS_TICKET_MACLEN) <= 0) 500 return (TLS_MGR_STAT_ERR); 501 tmp.tout = now + timeout - 1; 502 key = tls_scache_key_rotate(&tmp); 503 } else { 504 /* No matching decryption key found */ 505 return (TLS_MGR_STAT_ERR); 506 } 507 } 508 /* Return value overwrites name buffer */ 509 vstring_memcpy(buffer, (char *) key, sizeof(*key)); 510 return (TLS_MGR_STAT_OK); 511 } 512 513 /* tlsmgr_loop - TLS manager main loop */ 514 515 static int tlsmgr_loop(char *unused_name, char **unused_argv) 516 { 517 struct timeval tv; 518 int active = 0; 519 TLSMGR_SCACHE *ent; 520 521 /* 522 * Update the PRNG pool with the time of day. We do it here after every 523 * event (including internal timer events and external client request 524 * events), instead of doing it in individual event call-back routines. 525 */ 526 GETTIMEOFDAY(&tv); 527 RAND_seed(&tv, sizeof(struct timeval)); 528 529 /* 530 * This routine runs as part of the event handling loop, after the event 531 * manager has delivered a timer or I/O event, or after it has waited for 532 * a specified amount of time. The result value of tlsmgr_loop() 533 * specifies how long the event manager should wait for the next event. 534 * 535 * We use this loop to interleave TLS session cache cleanup with other 536 * activity. Interleaved processing is needed when we use a client-server 537 * protocol for entropy and session state exchange with smtp(8) and 538 * smtpd(8) processes. 539 */ 540 #define DONT_WAIT 0 541 #define WAIT_FOR_EVENT (-1) 542 543 for (ent = cache_table; ent->cache_label; ++ent) { 544 if (ent->cache_info && ent->cache_active) 545 active |= ent->cache_active = 546 tls_scache_sequence(ent->cache_info, DICT_SEQ_FUN_NEXT, 547 TLS_SCACHE_SEQUENCE_NOTHING); 548 } 549 550 return (active ? DONT_WAIT : WAIT_FOR_EVENT); 551 } 552 553 /* tlsmgr_request_receive - receive request */ 554 555 static int tlsmgr_request_receive(VSTREAM *client_stream, VSTRING *request) 556 { 557 int count; 558 559 /* 560 * Kluge: choose the protocol depending on the request size. 561 */ 562 if (read_wait(vstream_fileno(client_stream), var_ipc_timeout) < 0) { 563 msg_warn("timeout while waiting for data from %s", 564 VSTREAM_PATH(client_stream)); 565 return (-1); 566 } 567 if ((count = peekfd(vstream_fileno(client_stream))) < 0) { 568 msg_warn("cannot examine read buffer of %s: %m", 569 VSTREAM_PATH(client_stream)); 570 return (-1); 571 } 572 573 /* 574 * Short request: master trigger. Use the string+null protocol. 575 */ 576 if (count <= 2) { 577 if (vstring_get_null(request, client_stream) == VSTREAM_EOF) { 578 msg_warn("end-of-input while reading request from %s: %m", 579 VSTREAM_PATH(client_stream)); 580 return (-1); 581 } 582 } 583 584 /* 585 * Long request: real tlsmgr client. Use the attribute list protocol. 586 */ 587 else { 588 if (attr_scan(client_stream, 589 ATTR_FLAG_MORE | ATTR_FLAG_STRICT, 590 RECV_ATTR_STR(TLS_MGR_ATTR_REQ, request), 591 ATTR_TYPE_END) != 1) { 592 return (-1); 593 } 594 } 595 return (0); 596 } 597 598 /* tlsmgr_service - respond to external request */ 599 600 static void tlsmgr_service(VSTREAM *client_stream, char *unused_service, 601 char **argv) 602 { 603 static VSTRING *request = 0; 604 static VSTRING *cache_type = 0; 605 static VSTRING *cache_id = 0; 606 static VSTRING *buffer = 0; 607 int len; 608 static char wakeup[] = { /* master wakeup request */ 609 TRIGGER_REQ_WAKEUP, 610 0, 611 }; 612 TLSMGR_SCACHE *ent; 613 int status = TLS_MGR_STAT_FAIL; 614 615 /* 616 * Sanity check. This service takes no command-line arguments. 617 */ 618 if (argv[0]) 619 msg_fatal("unexpected command-line argument: %s", argv[0]); 620 621 /* 622 * Initialize. We're select threaded, so we can use static buffers. 623 */ 624 if (request == 0) { 625 request = vstring_alloc(10); 626 cache_type = vstring_alloc(10); 627 cache_id = vstring_alloc(10); 628 buffer = vstring_alloc(10); 629 } 630 631 /* 632 * This routine runs whenever a client connects to the socket dedicated 633 * to the tlsmgr service (including wake up events sent by the master). 634 * All connection-management stuff is handled by the common code in 635 * multi_server.c. 636 */ 637 if (tlsmgr_request_receive(client_stream, request) == 0) { 638 639 /* 640 * Load session from cache. 641 */ 642 if (STREQ(STR(request), TLS_MGR_REQ_LOOKUP)) { 643 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 644 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type), 645 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id), 646 ATTR_TYPE_END) == 2) { 647 for (ent = cache_table; ent->cache_label; ++ent) 648 if (strcmp(ent->cache_label, STR(cache_type)) == 0) 649 break; 650 if (ent->cache_label == 0) { 651 msg_warn("bogus cache type \"%s\" in \"%s\" request", 652 STR(cache_type), TLS_MGR_REQ_LOOKUP); 653 VSTRING_RESET(buffer); 654 } else if (ent->cache_info == 0) { 655 656 /* 657 * Cache type valid, but not enabled 658 */ 659 VSTRING_RESET(buffer); 660 } else { 661 status = tls_scache_lookup(ent->cache_info, 662 STR(cache_id), buffer) ? 663 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR; 664 } 665 } 666 attr_print(client_stream, ATTR_FLAG_NONE, 667 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 668 SEND_ATTR_DATA(TLS_MGR_ATTR_SESSION, 669 LEN(buffer), STR(buffer)), 670 ATTR_TYPE_END); 671 } 672 673 /* 674 * Save session to cache. 675 */ 676 else if (STREQ(STR(request), TLS_MGR_REQ_UPDATE)) { 677 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 678 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type), 679 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id), 680 RECV_ATTR_DATA(TLS_MGR_ATTR_SESSION, buffer), 681 ATTR_TYPE_END) == 3) { 682 for (ent = cache_table; ent->cache_label; ++ent) 683 if (strcmp(ent->cache_label, STR(cache_type)) == 0) 684 break; 685 if (ent->cache_label == 0) { 686 msg_warn("bogus cache type \"%s\" in \"%s\" request", 687 STR(cache_type), TLS_MGR_REQ_UPDATE); 688 } else if (ent->cache_info != 0) { 689 status = 690 tls_scache_update(ent->cache_info, STR(cache_id), 691 STR(buffer), LEN(buffer)) ? 692 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR; 693 } 694 } 695 attr_print(client_stream, ATTR_FLAG_NONE, 696 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 697 ATTR_TYPE_END); 698 } 699 700 /* 701 * Delete session from cache. 702 */ 703 else if (STREQ(STR(request), TLS_MGR_REQ_DELETE)) { 704 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 705 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type), 706 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_ID, cache_id), 707 ATTR_TYPE_END) == 2) { 708 for (ent = cache_table; ent->cache_label; ++ent) 709 if (strcmp(ent->cache_label, STR(cache_type)) == 0) 710 break; 711 if (ent->cache_label == 0) { 712 msg_warn("bogus cache type \"%s\" in \"%s\" request", 713 STR(cache_type), TLS_MGR_REQ_DELETE); 714 } else if (ent->cache_info != 0) { 715 status = tls_scache_delete(ent->cache_info, 716 STR(cache_id)) ? 717 TLS_MGR_STAT_OK : TLS_MGR_STAT_ERR; 718 } 719 } 720 attr_print(client_stream, ATTR_FLAG_NONE, 721 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 722 ATTR_TYPE_END); 723 } 724 725 /* 726 * RFC 5077 TLS session ticket keys 727 */ 728 else if (STREQ(STR(request), TLS_MGR_REQ_TKTKEY)) { 729 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 730 RECV_ATTR_DATA(TLS_MGR_ATTR_KEYNAME, buffer), 731 ATTR_TYPE_END) == 1) { 732 if (LEN(buffer) != 0 && LEN(buffer) != TLS_TICKET_NAMELEN) { 733 msg_warn("invalid session ticket key name length: %ld", 734 (long) LEN(buffer)); 735 VSTRING_RESET(buffer); 736 } else if (*smtpd_cache.cache_timeout <= 0) { 737 status = TLS_MGR_STAT_ERR; 738 VSTRING_RESET(buffer); 739 } else { 740 status = tlsmgr_key(buffer, *smtpd_cache.cache_timeout); 741 } 742 } 743 attr_print(client_stream, ATTR_FLAG_NONE, 744 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 745 SEND_ATTR_DATA(TLS_MGR_ATTR_KEYBUF, 746 LEN(buffer), STR(buffer)), 747 ATTR_TYPE_END); 748 } 749 750 /* 751 * Entropy request. 752 */ 753 else if (STREQ(STR(request), TLS_MGR_REQ_SEED)) { 754 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 755 RECV_ATTR_INT(TLS_MGR_ATTR_SIZE, &len), 756 ATTR_TYPE_END) == 1) { 757 VSTRING_RESET(buffer); 758 if (len <= 0 || len > 255) { 759 msg_warn("bogus seed length \"%d\" in \"%s\" request", 760 len, TLS_MGR_REQ_SEED); 761 } else { 762 VSTRING_SPACE(buffer, len); 763 RAND_bytes((unsigned char *) STR(buffer), len); 764 vstring_set_payload_size(buffer, len); 765 status = TLS_MGR_STAT_OK; 766 } 767 } 768 attr_print(client_stream, ATTR_FLAG_NONE, 769 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 770 SEND_ATTR_DATA(TLS_MGR_ATTR_SEED, 771 LEN(buffer), STR(buffer)), 772 ATTR_TYPE_END); 773 } 774 775 /* 776 * Caching policy request. 777 */ 778 else if (STREQ(STR(request), TLS_MGR_REQ_POLICY)) { 779 int cachable = 0; 780 int timeout = 0; 781 782 if (attr_scan(client_stream, ATTR_FLAG_STRICT, 783 RECV_ATTR_STR(TLS_MGR_ATTR_CACHE_TYPE, cache_type), 784 ATTR_TYPE_END) == 1) { 785 for (ent = cache_table; ent->cache_label; ++ent) 786 if (strcmp(ent->cache_label, STR(cache_type)) == 0) 787 break; 788 if (ent->cache_label == 0) { 789 msg_warn("bogus cache type \"%s\" in \"%s\" request", 790 STR(cache_type), TLS_MGR_REQ_POLICY); 791 } else { 792 cachable = (ent->cache_info != 0) ? 1 : 0; 793 timeout = *ent->cache_timeout; 794 status = TLS_MGR_STAT_OK; 795 } 796 } 797 attr_print(client_stream, ATTR_FLAG_NONE, 798 SEND_ATTR_INT(MAIL_ATTR_STATUS, status), 799 SEND_ATTR_INT(TLS_MGR_ATTR_CACHABLE, cachable), 800 SEND_ATTR_INT(TLS_MGR_ATTR_SESSTOUT, timeout), 801 ATTR_TYPE_END); 802 } 803 804 /* 805 * Master trigger. Normally, these triggers arrive only after some 806 * other process requested the tlsmgr's service. The purpose is to 807 * restart the tlsmgr after it aborted due to a fatal run-time error, 808 * so that it can continue its housekeeping even while nothing is 809 * using TLS. 810 * 811 * XXX Which begs the question, if TLS isn't used often, do we need a 812 * tlsmgr background process? It could terminate when the session 813 * caches are empty. 814 */ 815 else if (STREQ(STR(request), wakeup)) { 816 if (msg_verbose) 817 msg_info("received master trigger"); 818 multi_server_disconnect(client_stream); 819 return; /* NOT: vstream_fflush */ 820 } 821 } 822 823 /* 824 * Protocol error. 825 */ 826 else { 827 attr_print(client_stream, ATTR_FLAG_NONE, 828 SEND_ATTR_INT(MAIL_ATTR_STATUS, TLS_MGR_STAT_FAIL), 829 ATTR_TYPE_END); 830 } 831 vstream_fflush(client_stream); 832 } 833 834 /* tlsmgr_pre_init - pre-jail initialization */ 835 836 static void tlsmgr_pre_init(char *unused_name, char **unused_argv) 837 { 838 char *path; 839 struct timeval tv; 840 TLSMGR_SCACHE *ent; 841 VSTRING *redirect; 842 HTABLE *dup_filter; 843 const char *dup_label; 844 845 /* 846 * If nothing else works then at least this will get us a few bits of 847 * entropy. 848 * 849 * XXX This is our first call into the OpenSSL library. We should find out 850 * if this can be moved to the post-jail initialization phase, without 851 * breaking compatibility with existing installations. 852 */ 853 GETTIMEOFDAY(&tv); 854 tv.tv_sec ^= getpid(); 855 RAND_seed(&tv, sizeof(struct timeval)); 856 857 /* 858 * Open the external entropy source. We will not be able to open it again 859 * after we are sent to chroot jail, so we keep it open. Errors are not 860 * fatal. The exchange file (see below) is the only entropy source that 861 * really matters in the long run. 862 * 863 * Security note: we open the entropy source while privileged, but we don't 864 * access the source until after we release privileges. This way, none of 865 * the OpenSSL code gets to execute while we are privileged. 866 */ 867 if (*var_tls_rand_source) { 868 869 /* 870 * Source is a random device. 871 */ 872 if (!strncmp(var_tls_rand_source, DEV_PREF, DEV_PREF_LEN)) { 873 path = DEV_PATH(var_tls_rand_source); 874 rand_source_dev = tls_prng_dev_open(path, TLS_MGR_TIMEOUT); 875 if (rand_source_dev == 0) 876 msg_warn("cannot open entropy device %s: %m", path); 877 } 878 879 /* 880 * Source is an EGD compatible socket. 881 */ 882 else if (!strncmp(var_tls_rand_source, EGD_PREF, EGD_PREF_LEN)) { 883 path = EGD_PATH(var_tls_rand_source); 884 rand_source_egd = tls_prng_egd_open(path, TLS_MGR_TIMEOUT); 885 if (rand_source_egd == 0) 886 msg_warn("cannot connect to EGD server %s: %m", path); 887 } 888 889 /* 890 * Source is regular file. We read this only once. 891 */ 892 else { 893 rand_source_file = 894 tls_prng_file_open(var_tls_rand_source, TLS_MGR_TIMEOUT); 895 } 896 } else { 897 msg_warn("no entropy source specified with parameter %s", 898 VAR_TLS_RAND_SOURCE); 899 msg_warn("encryption keys etc. may be predictable"); 900 } 901 902 /* 903 * Security: don't create root-owned files that contain untrusted data. 904 * And don't create Postfix-owned files in root-owned directories, 905 * either. We want a correct relationship between (file/directory) 906 * ownership and (file/directory) content. 907 */ 908 SAVE_AND_SET_EUGID(var_owner_uid, var_owner_gid); 909 redirect = vstring_alloc(100); 910 911 /* 912 * Open the PRNG exchange file before going to jail, but don't use root 913 * privileges. Start the exchange file read/update pseudo thread after 914 * dropping privileges. 915 */ 916 if (*var_tls_rand_exch_name) { 917 rand_exch = 918 tls_prng_exch_open(data_redirect_file(redirect, 919 var_tls_rand_exch_name)); 920 if (rand_exch == 0) 921 msg_fatal("cannot open PRNG exchange file %s: %m", 922 var_tls_rand_exch_name); 923 } 924 925 /* 926 * Open the session cache files and discard old information before going 927 * to jail, but don't use root privilege. Start the cache maintenance 928 * pseudo threads after dropping privileges. 929 */ 930 dup_filter = htable_create(sizeof(cache_table) / sizeof(cache_table[0])); 931 for (ent = cache_table; ent->cache_label; ++ent) { 932 /* Sanitize session timeout */ 933 if (*ent->cache_timeout > 0) { 934 if (*ent->cache_timeout < TLS_SESSION_LIFEMIN) 935 *ent->cache_timeout = TLS_SESSION_LIFEMIN; 936 } else { 937 *ent->cache_timeout = 0; 938 } 939 /* External cache database disabled if timeout is non-positive */ 940 if (*ent->cache_timeout > 0 && **ent->cache_db) { 941 if ((dup_label = htable_find(dup_filter, *ent->cache_db)) != 0) 942 msg_fatal("do not use the same TLS cache file %s for %s and %s", 943 *ent->cache_db, dup_label, ent->cache_label); 944 htable_enter(dup_filter, *ent->cache_db, ent->cache_label); 945 ent->cache_info = 946 tls_scache_open(data_redirect_map(redirect, *ent->cache_db), 947 ent->cache_label, 948 tls_log_mask(ent->log_param, 949 *ent->log_level) & TLS_LOG_CACHE, 950 *ent->cache_timeout); 951 } 952 } 953 htable_free(dup_filter, (void (*) (void *)) 0); 954 955 /* 956 * Clean up and restore privilege. 957 */ 958 vstring_free(redirect); 959 RESTORE_SAVED_EUGID(); 960 } 961 962 /* tlsmgr_post_init - post-jail initialization */ 963 964 static void tlsmgr_post_init(char *unused_name, char **unused_argv) 965 { 966 TLSMGR_SCACHE *ent; 967 968 #define NULL_EVENT (0) 969 #define NULL_CONTEXT ((char *) 0) 970 971 /* 972 * This routine runs after the skeleton code has entered the chroot jail, 973 * but before any client requests are serviced. Prevent automatic process 974 * suicide after a limited number of client requests or after a limited 975 * amount of idle time. 976 */ 977 var_use_limit = 0; 978 var_idle_limit = 0; 979 980 /* 981 * Start the internal PRNG re-seeding pseudo thread first. 982 */ 983 if (*var_tls_rand_source) { 984 if (var_tls_reseed_period > INT_MAX / UCHAR_MAX) 985 var_tls_reseed_period = INT_MAX / UCHAR_MAX; 986 tlsmgr_reseed_event(NULL_EVENT, NULL_CONTEXT); 987 } 988 989 /* 990 * Start the exchange file read/update pseudo thread. 991 */ 992 if (*var_tls_rand_exch_name) { 993 if (var_tls_prng_exch_period > INT_MAX / UCHAR_MAX) 994 var_tls_prng_exch_period = INT_MAX / UCHAR_MAX; 995 tlsmgr_prng_exch_event(NULL_EVENT, NULL_CONTEXT); 996 } 997 998 /* 999 * Start the cache maintenance pseudo threads last. Strictly speaking 1000 * there is nothing to clean up after we truncate the database to zero 1001 * length, but early cleanup makes verbose logging more informative (we 1002 * get positive confirmation that the cleanup threads are running). 1003 */ 1004 for (ent = cache_table; ent->cache_label; ++ent) 1005 if (ent->cache_info) 1006 tlsmgr_cache_run_event(NULL_EVENT, (void *) ent); 1007 } 1008 1009 /* tlsmgr_post_accept - announce our protocol */ 1010 1011 static void tlsmgr_post_accept(VSTREAM *stream, char *unused_name, 1012 char **unused_argv, HTABLE *unused_table) 1013 { 1014 1015 /* 1016 * Announce the protocol. 1017 */ 1018 attr_print(stream, ATTR_FLAG_NONE, 1019 SEND_ATTR_STR(MAIL_ATTR_PROTO, MAIL_ATTR_PROTO_TLSMGR), 1020 ATTR_TYPE_END); 1021 (void) vstream_fflush(stream); 1022 } 1023 1024 1025 /* tlsmgr_before_exit - save PRNG state before exit */ 1026 1027 static void tlsmgr_before_exit(char *unused_service_name, char **unused_argv) 1028 { 1029 1030 /* 1031 * Save state before we exit after "postfix reload". 1032 */ 1033 if (rand_exch) 1034 tls_prng_exch_update(rand_exch); 1035 } 1036 1037 MAIL_VERSION_STAMP_DECLARE; 1038 1039 /* main - the main program */ 1040 1041 int main(int argc, char **argv) 1042 { 1043 static const CONFIG_STR_TABLE str_table[] = { 1044 VAR_TLS_RAND_SOURCE, DEF_TLS_RAND_SOURCE, &var_tls_rand_source, 0, 0, 1045 VAR_TLS_RAND_EXCH_NAME, DEF_TLS_RAND_EXCH_NAME, &var_tls_rand_exch_name, 0, 0, 1046 VAR_SMTPD_TLS_SCACHE_DB, DEF_SMTPD_TLS_SCACHE_DB, &var_smtpd_tls_scache_db, 0, 0, 1047 VAR_SMTP_TLS_SCACHE_DB, DEF_SMTP_TLS_SCACHE_DB, &var_smtp_tls_scache_db, 0, 0, 1048 VAR_LMTP_TLS_SCACHE_DB, DEF_LMTP_TLS_SCACHE_DB, &var_lmtp_tls_scache_db, 0, 0, 1049 VAR_SMTPD_TLS_LOGLEVEL, DEF_SMTPD_TLS_LOGLEVEL, &var_smtpd_tls_loglevel, 0, 0, 1050 VAR_SMTP_TLS_LOGLEVEL, DEF_SMTP_TLS_LOGLEVEL, &var_smtp_tls_loglevel, 0, 0, 1051 VAR_LMTP_TLS_LOGLEVEL, DEF_LMTP_TLS_LOGLEVEL, &var_lmtp_tls_loglevel, 0, 0, 1052 0, 1053 }; 1054 static const CONFIG_TIME_TABLE time_table[] = { 1055 VAR_TLS_RESEED_PERIOD, DEF_TLS_RESEED_PERIOD, &var_tls_reseed_period, 1, 0, 1056 VAR_TLS_PRNG_UPD_PERIOD, DEF_TLS_PRNG_UPD_PERIOD, &var_tls_prng_exch_period, 1, 0, 1057 VAR_SMTPD_TLS_SCACHTIME, DEF_SMTPD_TLS_SCACHTIME, &var_smtpd_tls_scache_timeout, 0, MAX_SMTPD_TLS_SCACHETIME, 1058 VAR_SMTP_TLS_SCACHTIME, DEF_SMTP_TLS_SCACHTIME, &var_smtp_tls_scache_timeout, 0, MAX_SMTP_TLS_SCACHETIME, 1059 VAR_LMTP_TLS_SCACHTIME, DEF_LMTP_TLS_SCACHTIME, &var_lmtp_tls_scache_timeout, 0, MAX_LMTP_TLS_SCACHETIME, 1060 0, 1061 }; 1062 static const CONFIG_INT_TABLE int_table[] = { 1063 VAR_TLS_RAND_BYTES, DEF_TLS_RAND_BYTES, &var_tls_rand_bytes, 1, 0, 1064 0, 1065 }; 1066 1067 /* 1068 * Fingerprint executables and core dumps. 1069 */ 1070 MAIL_VERSION_STAMP_ALLOCATE; 1071 1072 /* 1073 * Use the multi service skeleton, and require that no-one else is 1074 * monitoring our service port while this process runs. 1075 */ 1076 multi_server_main(argc, argv, tlsmgr_service, 1077 CA_MAIL_SERVER_TIME_TABLE(time_table), 1078 CA_MAIL_SERVER_INT_TABLE(int_table), 1079 CA_MAIL_SERVER_STR_TABLE(str_table), 1080 CA_MAIL_SERVER_PRE_INIT(tlsmgr_pre_init), 1081 CA_MAIL_SERVER_POST_INIT(tlsmgr_post_init), 1082 CA_MAIL_SERVER_POST_ACCEPT(tlsmgr_post_accept), 1083 CA_MAIL_SERVER_EXIT(tlsmgr_before_exit), 1084 CA_MAIL_SERVER_LOOP(tlsmgr_loop), 1085 CA_MAIL_SERVER_SOLITARY, 1086 0); 1087 } 1088 1089 #else 1090 1091 /* tlsmgr_service - respond to external trigger(s), non-TLS version */ 1092 1093 static void tlsmgr_service(VSTREAM *unused_stream, char *unused_service, 1094 char **unused_argv) 1095 { 1096 msg_info("TLS support is not compiled in -- exiting"); 1097 } 1098 1099 /* main - the main program, non-TLS version */ 1100 1101 int main(int argc, char **argv) 1102 { 1103 1104 /* 1105 * 200411 We can't simply use msg_fatal() here, because the logging 1106 * hasn't been initialized. The text would disappear because stderr is 1107 * redirected to /dev/null. 1108 * 1109 * We invoke multi_server_main() to complete program initialization 1110 * (including logging) and then invoke the tlsmgr_service() routine to 1111 * log the message that says why this program will not run. 1112 */ 1113 multi_server_main(argc, argv, tlsmgr_service, 1114 0); 1115 } 1116 1117 #endif 1118