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