No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / tls / tls_mgr.c
blob526fe988562a1bfa3be4dc1baeda76d717973869
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* tls_mgr 3
6 /* SUMMARY
7 /* tlsmgr client interface
8 /* SYNOPSIS
9 /* #include <tls_mgr.h>
11 /* int tls_mgr_seed(buf, len)
12 /* VSTRING *buf;
13 /* int len;
15 /* int tls_mgr_policy(cache_type, cachable)
16 /* const char *cache_type;
17 /* int *cachable;
19 /* int tls_mgr_update(cache_type, cache_id, buf, len)
20 /* const char *cache_type;
21 /* const char *cache_id;
22 /* const char *buf;
23 /* ssize_t len;
25 /* int tls_mgr_lookup(cache_type, cache_id, buf)
26 /* const char *cache_type;
27 /* const char *cache_id;
28 /* VSTRING *buf;
30 /* int tls_mgr_delete(cache_type, cache_id)
31 /* const char *cache_type;
32 /* const char *cache_id;
33 /* DESCRIPTION
34 /* These routines communicate with the tlsmgr(8) server for
35 /* entropy and session cache management. Since these are
36 /* non-critical services, requests are allowed to fail without
37 /* disrupting Postfix.
39 /* tls_mgr_seed() requests entropy from the tlsmgr(8)
40 /* Pseudo Random Number Generator (PRNG) pool.
42 /* tls_mgr_policy() requests the session caching policy.
44 /* tls_mgr_lookup() loads the specified session from
45 /* the specified session cache.
47 /* tls_mgr_update() saves the specified session to
48 /* the specified session cache.
50 /* tls_mgr_delete() removes specified session from
51 /* the specified session cache.
53 /* Arguments
54 /* .IP cache_type
55 /* One of TLS_MGR_SCACHE_SMTPD, TLS_MGR_SCACHE_SMTP or
56 /* TLS_MGR_SCACHE_LMTP.
57 /* .IP cachable
58 /* Pointer to int, set non-zero if the requested cache_type
59 /* is enabled.
60 /* .IP cache_id
61 /* The session cache lookup key.
62 /* .IP buf
63 /* The result or input buffer.
64 /* .IP len
65 /* The length of the input buffer, or the amount of data requested.
66 /* DIAGNOSTICS
67 /* All client functions return one of the following status codes:
68 /* .IP TLS_MGR_STAT_OK
69 /* The request completed, and the requested operation was
70 /* successful (for example, the requested session was found,
71 /* or the specified session was saved or removed).
72 /* .IP TLS_MGR_STAT_ERR
73 /* The request completed, but the requested operation failed
74 /* (for example, the requested object was not found or the
75 /* specified session was not saved or removed).
76 /* .IP TLS_MGR_STAT_FAIL
77 /* The request could not complete (the client could not
78 /* communicate with the tlsmgr(8) server).
79 /* SEE ALSO
80 /* tlsmgr(8) TLS session and PRNG management
81 /* LICENSE
82 /* .ad
83 /* .fi
84 /* The Secure Mailer license must be distributed with this software.
85 /* AUTHOR(S)
86 /* Wietse Venema
87 /* IBM T.J. Watson Research
88 /* P.O. Box 704
89 /* Yorktown Heights, NY 10598, USA
90 /*--*/
92 /* System library. */
94 #include <sys_defs.h>
96 #ifdef USE_TLS
98 #ifdef STRCASECMP_IN_STRINGS_H
99 #include <strings.h>
100 #endif
102 /* Utility library. */
104 #include <msg.h>
105 #include <vstream.h>
106 #include <vstring.h>
107 #include <attr.h>
108 #include <attr_clnt.h>
110 /* Global library. */
112 #include <mail_params.h>
113 #include <mail_proto.h>
114 #include <tls_mgr.h>
116 /* Application-specific. */
118 static ATTR_CLNT *tls_mgr;
120 /* tls_mgr_open - create client handle */
122 static void tls_mgr_open(void)
126 * Sanity check.
128 if (tls_mgr != 0)
129 msg_panic("tls_mgr_open: multiple initialization");
132 * Use whatever IPC is preferred for internal use: UNIX-domain sockets or
133 * Solaris streams.
135 #ifndef VAR_TLS_MGR_SERVICE
136 tls_mgr = attr_clnt_create("local:" TLS_MGR_CLASS "/" TLS_MGR_SERVICE,
137 var_ipc_timeout, var_ipc_idle_limit,
138 var_ipc_ttl_limit);
139 #else
140 tls_mgr = attr_clnt_create(var_tlsmgr_service, var_ipc_timeout,
141 var_ipc_idle_limit, var_ipc_ttl_limit);
142 #endif
143 attr_clnt_control(tls_mgr,
144 ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
145 ATTR_CLNT_CTL_END);
148 /* tls_mgr_seed - request PRNG seed */
150 int tls_mgr_seed(VSTRING *buf, int len)
152 int status;
155 * Create the tlsmgr client handle.
157 if (tls_mgr == 0)
158 tls_mgr_open();
161 * Request seed.
163 if (attr_clnt_request(tls_mgr,
164 ATTR_FLAG_NONE, /* Request attributes */
165 ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_SEED,
166 ATTR_TYPE_INT, TLS_MGR_ATTR_SIZE, len,
167 ATTR_TYPE_END,
168 ATTR_FLAG_MISSING, /* Reply attributes */
169 ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
170 ATTR_TYPE_DATA, TLS_MGR_ATTR_SEED, buf,
171 ATTR_TYPE_END) != 2)
172 status = TLS_MGR_STAT_FAIL;
173 return (status);
176 /* tls_mgr_policy - request caching policy */
178 int tls_mgr_policy(const char *cache_type, int *cachable)
180 int status;
183 * Create the tlsmgr client handle.
185 if (tls_mgr == 0)
186 tls_mgr_open();
189 * Request policy.
191 if (attr_clnt_request(tls_mgr,
192 ATTR_FLAG_NONE, /* Request attributes */
193 ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_POLICY,
194 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
195 ATTR_TYPE_END,
196 ATTR_FLAG_MISSING, /* Reply attributes */
197 ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
198 ATTR_TYPE_INT, TLS_MGR_ATTR_CACHABLE, cachable,
199 ATTR_TYPE_END) != 2)
200 status = TLS_MGR_STAT_FAIL;
201 return (status);
204 /* tls_mgr_lookup - request cached session */
206 int tls_mgr_lookup(const char *cache_type, const char *cache_id,
207 VSTRING *buf)
209 int status;
212 * Create the tlsmgr client handle.
214 if (tls_mgr == 0)
215 tls_mgr_open();
218 * Send the request and receive the reply.
220 if (attr_clnt_request(tls_mgr,
221 ATTR_FLAG_NONE, /* Request */
222 ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_LOOKUP,
223 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
224 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
225 ATTR_TYPE_END,
226 ATTR_FLAG_MISSING, /* Reply */
227 ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
228 ATTR_TYPE_DATA, TLS_MGR_ATTR_SESSION, buf,
229 ATTR_TYPE_END) != 2)
230 status = TLS_MGR_STAT_FAIL;
231 return (status);
234 /* tls_mgr_update - save session to cache */
236 int tls_mgr_update(const char *cache_type, const char *cache_id,
237 const char *buf, ssize_t len)
239 int status;
242 * Create the tlsmgr client handle.
244 if (tls_mgr == 0)
245 tls_mgr_open();
248 * Send the request and receive the reply.
250 if (attr_clnt_request(tls_mgr,
251 ATTR_FLAG_NONE, /* Request */
252 ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_UPDATE,
253 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
254 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
255 ATTR_TYPE_DATA, TLS_MGR_ATTR_SESSION, len, buf,
256 ATTR_TYPE_END,
257 ATTR_FLAG_MISSING, /* Reply */
258 ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
259 ATTR_TYPE_END) != 1)
260 status = TLS_MGR_STAT_FAIL;
261 return (status);
264 /* tls_mgr_delete - remove cached session */
266 int tls_mgr_delete(const char *cache_type, const char *cache_id)
268 int status;
271 * Create the tlsmgr client handle.
273 if (tls_mgr == 0)
274 tls_mgr_open();
277 * Send the request and receive the reply.
279 if (attr_clnt_request(tls_mgr,
280 ATTR_FLAG_NONE, /* Request */
281 ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_DELETE,
282 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
283 ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
284 ATTR_TYPE_END,
285 ATTR_FLAG_MISSING, /* Reply */
286 ATTR_TYPE_INT, TLS_MGR_ATTR_STATUS, &status,
287 ATTR_TYPE_END) != 1)
288 status = TLS_MGR_STAT_FAIL;
289 return (status);
292 #ifdef TEST
294 /* System library. */
296 #include <stdlib.h>
298 /* Utility library. */
300 #include <argv.h>
301 #include <msg_vstream.h>
302 #include <vstring_vstream.h>
303 #include <hex_code.h>
305 /* Global library. */
307 #include <config.h>
309 /* Application-specific. */
311 #define STR(x) vstring_str(x)
312 #define LEN(x) VSTRING_LEN(x)
314 int main(int unused_ac, char **av)
316 VSTRING *inbuf = vstring_alloc(10);
317 int status;
318 ARGV *argv = 0;
320 msg_vstream_init(av[0], VSTREAM_ERR);
322 msg_verbose = 3;
324 mail_conf_read();
325 msg_info("using config files in %s", var_config_dir);
327 if (chdir(var_queue_dir) < 0)
328 msg_fatal("chdir %s: %m", var_queue_dir);
330 while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
331 argv = argv_split(STR(inbuf), " \t\r\n");
332 if (argv->argc == 0) {
333 argv_free(argv);
334 continue;
337 #define COMMAND(argv, str, len) \
338 (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len)
340 if (COMMAND(argv, "policy", 2)) {
341 int cachable;
343 status = tls_mgr_policy(argv->argv[1], &cachable);
344 vstream_printf("status=%d cachable=%d\n", status, cachable);
345 } else if (COMMAND(argv, "seed", 2)) {
346 VSTRING *buf = vstring_alloc(10);
347 VSTRING *hex = vstring_alloc(10);
348 int len = atoi(argv->argv[1]);
350 status = tls_mgr_seed(buf, len);
351 hex_encode(hex, STR(buf), LEN(buf));
352 vstream_printf("status=%d seed=%s\n", status, STR(hex));
353 vstring_free(hex);
354 vstring_free(buf);
355 } else if (COMMAND(argv, "lookup", 3)) {
356 VSTRING *buf = vstring_alloc(10);
358 status = tls_mgr_lookup(argv->argv[1], argv->argv[2], buf);
359 vstream_printf("status=%d session=%.*s\n",
360 status, LEN(buf), STR(buf));
361 vstring_free(buf);
362 } else if (COMMAND(argv, "update", 4)) {
363 status = tls_mgr_update(argv->argv[1], argv->argv[2],
364 argv->argv[3], strlen(argv->argv[3]));
365 vstream_printf("status=%d\n", status);
366 } else if (COMMAND(argv, "delete", 3)) {
367 status = tls_mgr_delete(argv->argv[1], argv->argv[2]);
368 vstream_printf("status=%d\n", status);
369 } else {
370 vstream_printf("usage:\n"
371 "seed byte_count\n"
372 "policy smtpd|smtp|lmtp\n"
373 "lookup smtpd|smtp|lmtp cache_id\n"
374 "update smtpd|smtp|lmtp cache_id session\n"
375 "delete smtpd|smtp|lmtp cache_id\n");
377 vstream_fflush(VSTREAM_OUT);
378 argv_free(argv);
381 vstring_free(inbuf);
382 return (0);
385 #endif /* TEST */
387 #endif /* USE_TLS */