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