Postfix3.3.1
tls_mgr.c
[詳解]
1 /*++
2 /* NAME
3 /* tls_mgr 3
4 /* SUMMARY
5 /* tlsmgr client interface
6 /* SYNOPSIS
7 /* #include <tls_mgr.h>
8 /*
9 /* int tls_mgr_seed(buf, len)
10 /* VSTRING *buf;
11 /* int len;
12 /*
13 /* int tls_mgr_policy(cache_type, cachable, timeout)
14 /* const char *cache_type;
15 /* int *cachable;
16 /* int *timeout;
17 /*
18 /* int tls_mgr_update(cache_type, cache_id, buf, len)
19 /* const char *cache_type;
20 /* const char *cache_id;
21 /* const char *buf;
22 /* ssize_t len;
23 /*
24 /* int tls_mgr_lookup(cache_type, cache_id, buf)
25 /* const char *cache_type;
26 /* const char *cache_id;
27 /* VSTRING *buf;
28 /*
29 /* int tls_mgr_delete(cache_type, cache_id)
30 /* const char *cache_type;
31 /* const char *cache_id;
32 /*
33 /* TLS_TICKET_KEY *tls_mgr_key(keyname, timeout)
34 /* unsigned char *keyname;
35 /* int timeout;
36 /* DESCRIPTION
37 /* These routines communicate with the tlsmgr(8) server for
38 /* entropy and session cache management. Since these are
39 /* non-critical services, requests are allowed to fail without
40 /* disrupting Postfix.
41 /*
42 /* tls_mgr_seed() requests entropy from the tlsmgr(8)
43 /* Pseudo Random Number Generator (PRNG) pool.
44 /*
45 /* tls_mgr_policy() requests the session caching policy.
46 /*
47 /* tls_mgr_lookup() loads the specified session from
48 /* the specified session cache.
49 /*
50 /* tls_mgr_update() saves the specified session to
51 /* the specified session cache.
52 /*
53 /* tls_mgr_delete() removes specified session from
54 /* the specified session cache.
55 /*
56 /* tls_mgr_key() is used to retrieve the current TLS session ticket
57 /* encryption or decryption keys.
58 /*
59 /* Arguments:
60 /* .IP cache_type
61 /* One of TLS_MGR_SCACHE_SMTPD, TLS_MGR_SCACHE_SMTP or
62 /* TLS_MGR_SCACHE_LMTP.
63 /* .IP cachable
64 /* Pointer to int, set non-zero if the requested cache_type
65 /* is enabled.
66 /* .IP timeout
67 /* Pointer to int, returns the cache entry timeout.
68 /* .IP cache_id
69 /* The session cache lookup key.
70 /* .IP buf
71 /* The result or input buffer.
72 /* .IP len
73 /* The length of the input buffer, or the amount of data requested.
74 /* .IP keyname
75 /* Is null when requesting the current encryption keys. Otherwise,
76 /* keyname is a pointer to an array of TLS_TICKET_NAMELEN unsigned
77 /* chars (not NUL terminated) that is an identifier for a key
78 /* previously used to encrypt a session ticket. When encrypting
79 /* a null result indicates that session tickets are not supported, when
80 /* decrypting it indicates that no matching keys were found.
81 /* .IP timeout
82 /* The encryption key timeout. Once a key has been active for this many
83 /* seconds it is retired and used only for decrypting previously issued
84 /* session tickets for another timeout seconds, and is then destroyed.
85 /* The timeout must not be longer than half the SSL session lifetime.
86 /* DIAGNOSTICS
87 /* All client functions return one of the following status codes:
88 /* .IP TLS_MGR_STAT_OK
89 /* The request completed, and the requested operation was
90 /* successful (for example, the requested session was found,
91 /* or the specified session was saved or removed).
92 /* .IP TLS_MGR_STAT_ERR
93 /* The request completed, but the requested operation failed
94 /* (for example, the requested object was not found or the
95 /* specified session was not saved or removed).
96 /* .IP TLS_MGR_STAT_FAIL
97 /* The request could not complete (the client could not
98 /* communicate with the tlsmgr(8) server).
99 /* SEE ALSO
100 /* tlsmgr(8) TLS session and PRNG management
101 /* LICENSE
102 /* .ad
103 /* .fi
104 /* The Secure Mailer license must be distributed with this software.
105 /* AUTHOR(S)
106 /* Wietse Venema
107 /* IBM T.J. Watson Research
108 /* P.O. Box 704
109 /* Yorktown Heights, NY 10598, USA
110 /*--*/
111 
112 /* System library. */
113 
114 #include <sys_defs.h>
115 
116 #ifdef USE_TLS
117 
118 #ifdef STRCASECMP_IN_STRINGS_H
119 #include <strings.h>
120 #endif
121 
122 /* Utility library. */
123 
124 #include <msg.h>
125 #include <vstream.h>
126 #include <vstring.h>
127 #include <attr.h>
128 #include <attr_clnt.h>
129 #include <mymalloc.h>
130 #include <stringops.h>
131 
132 /* Global library. */
133 
134 #include <mail_params.h>
135 #include <mail_proto.h>
136 
137 /* TLS library. */
138 #include <tls_mgr.h>
139 
140 /* Application-specific. */
141 
142 #define STR(x) vstring_str(x)
143 #define LEN(x) VSTRING_LEN(x)
144 
145 static ATTR_CLNT *tls_mgr;
146 
147 /* tls_mgr_open - create client handle */
148 
149 static void tls_mgr_open(void)
150 {
151  char *service;
152 
153  /*
154  * Sanity check.
155  */
156  if (tls_mgr != 0)
157  msg_panic("tls_mgr_open: multiple initialization");
158 
159  /*
160  * Use whatever IPC is preferred for internal use: UNIX-domain sockets or
161  * Solaris streams.
162  */
163  service = concatenate("local:" TLS_MGR_CLASS "/", var_tls_mgr_service,
164  (char *) 0);
165  tls_mgr = attr_clnt_create(service, var_ipc_timeout,
167  myfree(service);
168 
169  attr_clnt_control(tls_mgr,
172 }
173 
174 /* tls_mgr_seed - request PRNG seed */
175 
176 int tls_mgr_seed(VSTRING *buf, int len)
177 {
178  int status;
179 
180  /*
181  * Create the tlsmgr client handle.
182  */
183  if (tls_mgr == 0)
184  tls_mgr_open();
185 
186  /*
187  * Request seed.
188  */
189  if (attr_clnt_request(tls_mgr,
190  ATTR_FLAG_NONE, /* Request attributes */
194  ATTR_FLAG_MISSING, /* Reply attributes */
197  ATTR_TYPE_END) != 2)
198  status = TLS_MGR_STAT_FAIL;
199  return (status);
200 }
201 
202 /* tls_mgr_policy - request caching policy */
203 
204 int tls_mgr_policy(const char *cache_type, int *cachable, int *timeout)
205 {
206  int status;
207 
208  /*
209  * Create the tlsmgr client handle.
210  */
211  if (tls_mgr == 0)
212  tls_mgr_open();
213 
214  /*
215  * Request policy.
216  */
217  if (attr_clnt_request(tls_mgr,
218  ATTR_FLAG_NONE, /* Request attributes */
222  ATTR_FLAG_MISSING, /* Reply attributes */
226  ATTR_TYPE_END) != 3)
227  status = TLS_MGR_STAT_FAIL;
228  return (status);
229 }
230 
231 /* tls_mgr_lookup - request cached session */
232 
233 int tls_mgr_lookup(const char *cache_type, const char *cache_id,
234  VSTRING *buf)
235 {
236  int status;
237 
238  /*
239  * Create the tlsmgr client handle.
240  */
241  if (tls_mgr == 0)
242  tls_mgr_open();
243 
244  /*
245  * Send the request and receive the reply.
246  */
247  if (attr_clnt_request(tls_mgr,
248  ATTR_FLAG_NONE, /* Request */
253  ATTR_FLAG_MISSING, /* Reply */
256  ATTR_TYPE_END) != 2)
257  status = TLS_MGR_STAT_FAIL;
258  return (status);
259 }
260 
261 /* tls_mgr_update - save session to cache */
262 
263 int tls_mgr_update(const char *cache_type, const char *cache_id,
264  const char *buf, ssize_t len)
265 {
266  int status;
267 
268  /*
269  * Create the tlsmgr client handle.
270  */
271  if (tls_mgr == 0)
272  tls_mgr_open();
273 
274  /*
275  * Send the request and receive the reply.
276  */
277  if (attr_clnt_request(tls_mgr,
278  ATTR_FLAG_NONE, /* Request */
284  ATTR_FLAG_MISSING, /* Reply */
286  ATTR_TYPE_END) != 1)
287  status = TLS_MGR_STAT_FAIL;
288  return (status);
289 }
290 
291 /* tls_mgr_delete - remove cached session */
292 
293 int tls_mgr_delete(const char *cache_type, const char *cache_id)
294 {
295  int status;
296 
297  /*
298  * Create the tlsmgr client handle.
299  */
300  if (tls_mgr == 0)
301  tls_mgr_open();
302 
303  /*
304  * Send the request and receive the reply.
305  */
306  if (attr_clnt_request(tls_mgr,
307  ATTR_FLAG_NONE, /* Request */
312  ATTR_FLAG_MISSING, /* Reply */
314  ATTR_TYPE_END) != 1)
315  status = TLS_MGR_STAT_FAIL;
316  return (status);
317 }
318 
319 /* request_scache_key - ask tlsmgr(8) for matching key */
320 
321 static TLS_TICKET_KEY *request_scache_key(unsigned char *keyname)
322 {
323  TLS_TICKET_KEY tmp;
324  static VSTRING *keybuf;
325  char *name;
326  size_t len;
327  int status;
328 
329  /*
330  * Create the tlsmgr client handle.
331  */
332  if (tls_mgr == 0)
333  tls_mgr_open();
334 
335  if (keybuf == 0)
336  keybuf = vstring_alloc(sizeof(tmp));
337 
338  /* In tlsmgr requests we encode null key names as empty strings. */
339  name = keyname ? (char *) keyname : "";
340  len = keyname ? TLS_TICKET_NAMELEN : 0;
341 
342  /*
343  * Send the request and receive the reply.
344  */
345  if (attr_clnt_request(tls_mgr,
346  ATTR_FLAG_NONE, /* Request */
350  ATTR_FLAG_MISSING, /* Reply */
353  ATTR_TYPE_END) != 2
354  || status != TLS_MGR_STAT_OK
355  || LEN(keybuf) != sizeof(tmp))
356  return (0);
357 
358  memcpy((void *) &tmp, STR(keybuf), sizeof(tmp));
359  return (tls_scache_key_rotate(&tmp));
360 }
361 
362 /* tls_mgr_key - session ticket key lookup, local cache, then tlsmgr(8) */
363 
364 TLS_TICKET_KEY *tls_mgr_key(unsigned char *keyname, int timeout)
365 {
366  TLS_TICKET_KEY *key = 0;
367  time_t now = time((time_t *) 0);
368 
369  /* A zero timeout disables session tickets. */
370  if (timeout <= 0)
371  return (0);
372 
373  if ((key = tls_scache_key(keyname, now, timeout)) == 0)
374  key = request_scache_key(keyname);
375  return (key);
376 }
377 
378 #ifdef TEST
379 
380 /* System library. */
381 
382 #include <stdlib.h>
383 
384 /* Utility library. */
385 
386 #include <argv.h>
387 #include <msg_vstream.h>
388 #include <vstring_vstream.h>
389 #include <hex_code.h>
390 
391 /* Global library. */
392 
393 #include <config.h>
394 
395 /* Application-specific. */
396 
397 int main(int unused_ac, char **av)
398 {
399  VSTRING *inbuf = vstring_alloc(10);
400  int status;
401  ARGV *argv = 0;
402 
404 
405  msg_verbose = 3;
406 
407  mail_conf_read();
408  msg_info("using config files in %s", var_config_dir);
409 
410  if (chdir(var_queue_dir) < 0)
411  msg_fatal("chdir %s: %m", var_queue_dir);
412 
413  while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
414  argv = argv_split(STR(inbuf), CHARS_SPACE);
415  if (argv->argc == 0) {
416  argv_free(argv);
417  continue;
418  }
419 #define COMMAND(argv, str, len) \
420  (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len)
421 
422  if (COMMAND(argv, "policy", 2)) {
423  int cachable;
424  int timeout;
425 
426  status = tls_mgr_policy(argv->argv[1], &cachable, &timeout);
427  vstream_printf("status=%d cachable=%d timeout=%d\n",
428  status, cachable, timeout);
429  } else if (COMMAND(argv, "seed", 2)) {
430  VSTRING *buf = vstring_alloc(10);
431  VSTRING *hex = vstring_alloc(10);
432  int len = atoi(argv->argv[1]);
433 
434  status = tls_mgr_seed(buf, len);
435  hex_encode(hex, STR(buf), LEN(buf));
436  vstream_printf("status=%d seed=%s\n", status, STR(hex));
437  vstring_free(hex);
438  vstring_free(buf);
439  } else if (COMMAND(argv, "lookup", 3)) {
440  VSTRING *buf = vstring_alloc(10);
441 
442  status = tls_mgr_lookup(argv->argv[1], argv->argv[2], buf);
443  vstream_printf("status=%d session=%.*s\n",
444  status, LEN(buf), STR(buf));
445  vstring_free(buf);
446  } else if (COMMAND(argv, "update", 4)) {
447  status = tls_mgr_update(argv->argv[1], argv->argv[2],
448  argv->argv[3], strlen(argv->argv[3]));
449  vstream_printf("status=%d\n", status);
450  } else if (COMMAND(argv, "delete", 3)) {
451  status = tls_mgr_delete(argv->argv[1], argv->argv[2]);
452  vstream_printf("status=%d\n", status);
453  } else {
454  vstream_printf("usage:\n"
455  "seed byte_count\n"
456  "policy smtpd|smtp|lmtp\n"
457  "lookup smtpd|smtp|lmtp cache_id\n"
458  "update smtpd|smtp|lmtp cache_id session\n"
459  "delete smtpd|smtp|lmtp cache_id\n");
460  }
462  argv_free(argv);
463  }
464 
465  vstring_free(inbuf);
466  return (0);
467 }
468 
469 #endif /* TEST */
470 
471 #endif /* USE_TLS */
int msg_verbose
Definition: msg.c:177
#define vstring_fgets_nonl(s, p)
int var_ipc_timeout
Definition: mail_params.c:255
#define ATTR_FLAG_NONE
Definition: attr.h:98
#define ATTR_CLNT_CTL_PROTO
Definition: attr_clnt.h:37
void myfree(void *ptr)
Definition: mymalloc.c:207
#define TLS_MGR_ATTR_SIZE
Definition: tls_mgr.h:37
ARGV * argv_free(ARGV *argvp)
Definition: argv.c:136
#define TLS_TICKET_NAMELEN
Definition: tls_scache.h:32
int var_ipc_idle_limit
Definition: mail_params.c:268
Definition: argv.h:17
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define VSTREAM_OUT
Definition: vstream.h:67
#define TLS_MGR_STAT_OK
Definition: tls_mgr.h:46
#define ATTR_FLAG_MISSING
Definition: attr.h:99
#define ATTR_CLNT_CTL_END
Definition: attr_clnt.h:36
int main(int argc, char **argv)
Definition: anvil.c:1010
#define TLS_MGR_REQ_TKTKEY
Definition: tls_mgr.h:31
#define TLS_MGR_CLASS
Definition: tls_mgr.h:23
char ** argv
Definition: argv.h:20
int tls_mgr_lookup(const char *, const char *, VSTRING *)
TLS_TICKET_KEY * tls_scache_key_rotate(TLS_TICKET_KEY *)
#define RECV_ATTR_INT(name, val)
Definition: attr.h:71
#define ATTR_TYPE_END
Definition: attr.h:39
char * var_config_dir
Definition: mail_params.c:241
#define LEN
Definition: cleanup_addr.c:106
#define VSTREAM_IN
Definition: vstream.h:66
int tls_mgr_update(const char *, const char *, const char *, ssize_t)
int tls_mgr_seed(VSTRING *, int)
ATTR_CLNT * attr_clnt_create(const char *service, int timeout, int max_idle, int max_ttl)
Definition: attr_clnt.c:130
void mail_conf_read(void)
Definition: mail_conf.c:178
#define TLS_MGR_ATTR_SESSION
Definition: tls_mgr.h:36
#define TLS_MGR_ATTR_SESSTOUT
Definition: tls_mgr.h:41
char * var_tls_mgr_service
#define TLS_MGR_ATTR_SEED
Definition: tls_mgr.h:34
#define TLS_MGR_ATTR_KEYBUF
Definition: tls_mgr.h:40
void attr_clnt_control(ATTR_CLNT *client, int name,...)
Definition: attr_clnt.c:246
#define TLS_MGR_REQ_DELETE
Definition: tls_mgr.h:30
VSTRING * hex_encode(VSTRING *result, const char *in, ssize_t len)
Definition: hex_code.c:62
TLS_TICKET_KEY * tls_scache_key(unsigned char *, time_t, int)
#define TLS_MGR_ATTR_KEYNAME
Definition: tls_mgr.h:39
int var_ipc_ttl_limit
Definition: mail_params.c:269
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
#define STR(x)
Definition: anvil.c:518
#define RECV_ATTR_DATA(name, val)
Definition: attr.h:76
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define CHARS_SPACE
Definition: sys_defs.h:1762
#define TLS_MGR_STAT_FAIL
Definition: tls_mgr.h:48
#define TLS_MGR_REQ_LOOKUP
Definition: tls_mgr.h:28
#define SEND_ATTR_INT(name, val)
Definition: attr.h:63
int tls_mgr_delete(const char *, const char *)
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
TLS_TICKET_KEY * tls_mgr_key(unsigned char *, int)
int tls_mgr_policy(const char *, int *, int *)
#define TLS_MGR_REQ_UPDATE
Definition: tls_mgr.h:29
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
#define attr_vprint
Definition: attr.h:110
char * concatenate(const char *arg0,...)
Definition: concatenate.c:42
ARGV * argv_split(const char *, const char *)
Definition: argv_split.c:63
int attr_clnt_request(ATTR_CLNT *client, int send_flags,...)
Definition: attr_clnt.c:148
#define TLS_MGR_ATTR_STATUS
Definition: tls_mgr.h:38
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define TLS_MGR_ATTR_REQ
Definition: tls_mgr.h:25
#define TLS_MGR_ATTR_CACHE_TYPE
Definition: tls_mgr.h:33
char * var_queue_dir
Definition: mail_params.c:246
void msg_vstream_init(const char *name, VSTREAM *vp)
Definition: msg_vstream.c:77
#define TLS_MGR_ATTR_CACHE_ID
Definition: tls_mgr.h:35
ssize_t argc
Definition: argv.h:19
#define TLS_MGR_ATTR_CACHABLE
Definition: tls_mgr.h:32
#define TLS_MGR_REQ_SEED
Definition: tls_mgr.h:26
#define attr_vscan
Definition: attr.h:112
#define SEND_ATTR_STR(name, val)
Definition: attr.h:64
#define SEND_ATTR_DATA(name, len, val)
Definition: attr.h:68
#define TLS_MGR_REQ_POLICY
Definition: tls_mgr.h:27
#define VSTREAM_ERR
Definition: vstream.h:68
void msg_info(const char *fmt,...)
Definition: msg.c:199