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