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 
tlsmgr_prng_exch_event(int unused_event,void * dummy)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 
tlsmgr_reseed_event(int unused_event,void * dummy)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 
tlsmgr_cache_run_event(int unused_event,void * ctx)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 
tlsmgr_key(VSTRING * buffer,int timeout)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 
tlsmgr_loop(char * unused_name,char ** unused_argv)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 
tlsmgr_request_receive(VSTREAM * client_stream,VSTRING * request)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 
tlsmgr_service(VSTREAM * client_stream,char * unused_service,char ** argv)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 
tlsmgr_pre_init(char * unused_name,char ** unused_argv)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 
tlsmgr_post_init(char * unused_name,char ** unused_argv)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 
tlsmgr_post_accept(VSTREAM * stream,char * unused_name,char ** unused_argv,HTABLE * unused_table)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 
tlsmgr_before_exit(char * unused_service_name,char ** unused_argv)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 
main(int argc,char ** argv)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 
tlsmgr_service(VSTREAM * unused_stream,char * unused_service,char ** unused_argv)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 
main(int argc,char ** argv)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