5
/* tlsmgr client interface
7
/* #include <tls_mgr.h>
9
/* int tls_mgr_seed(buf, len)
13
/* int tls_mgr_policy(cache_types)
16
/* int tls_mgr_update(cache_type, cache_id,
17
/* openssl_version, flags, buf, len)
19
/* const char *cache_id;
20
/* long openssl_version;
25
/* int tls_mgr_lookup(cache_type, cache_id,
26
/* openssl_version, flags, buf)
28
/* const char *cache_id;
29
/* long openssl_version;
33
/* int tls_mgr_delete(cache_type, cache_id)
35
/* const char *cache_id;
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.
42
/* tls_mgr_seed() requests entropy from the tlsmgr(8)
43
/* Pseudo Random Number Generator (PRNG) pool.
45
/* tls_mgr_policy() requests the session caching policy.
47
/* tls_mgr_lookup() loads the specified session from
48
/* the specified session cache.
50
/* tls_mgr_update() saves the specified session to
51
/* the specified session cache.
53
/* tls_mgr_delete() removes specified session from
54
/* the specified session cache.
58
/* The bit-wise OR of zero or more of the following:
60
/* .IP TLS_MGR_SCACHE_CLIENT
61
/* Session caching is enabled for SMTP client sessions.
62
/* .IP TLS_MGR_SCACHE_SERVER
63
/* Session caching is enabled for SMTP server sessions.
66
/* One of TLS_MGR_SCACHE_CLIENT or TLS_MGR_SCACHE_SERVER (see above).
68
/* The session cache lookup key.
69
/* .IP openssl_version
70
/* The OpenSSL version. Sessions saved by the wrong OpenSSL version are
71
/* deleted, to avoid compatibility problems.
73
/* Flags that must be set in the retrieved cache entry; it not,
74
/* the cache entry is deleted.
76
/* The result or input buffer.
78
/* The length of the input buffer, or the amount of data requested.
80
/* All client functions return one of the following status codes:
81
/* .IP TLS_MGR_STAT_OK
82
/* The request completed, and the requested operation was
83
/* successful (for example, the requested session was found,
84
/* or the specified session was saved or removed).
85
/* .IP TLS_MGR_STAT_ERR
86
/* The request completed, but the requested operation failed
87
/* (for example, the requested object was not found or the
88
/* specified session was not saved or removed).
89
/* .IP TLS_MGR_STAT_FAIL
90
/* The request could not complete (the client could not
91
/* communicate with the tlsmgr(8) server).
93
/* tlsmgr(8) TLS session and PRNG management
97
/* The Secure Mailer license must be distributed with this software.
100
/* IBM T.J. Watson Research
102
/* Yorktown Heights, NY 10598, USA
105
/* System library. */
107
#include <sys_defs.h>
111
/* Utility library. */
117
#include <attr_clnt.h>
119
/* Global library. */
121
#include <mail_params.h>
122
#include <mail_proto.h>
125
/* Application-specific. */
127
static ATTR_CLNT *tls_mgr;
129
/* tls_mgr_open - create client handle */
131
static void tls_mgr_open(void)
138
msg_panic("tls_mgr_open: multiple initialization");
141
* Use whatever IPC is preferred for internal use: UNIX-domain sockets or
144
#ifndef VAR_TLS_MGR_SERVICE
145
tls_mgr = attr_clnt_create("local:" TLS_MGR_CLASS "/" TLS_MGR_SERVICE,
146
var_ipc_timeout, var_ipc_idle_limit,
149
tls_mgr = attr_clnt_create(var_tlsmgr_service, var_ipc_timeout,
150
var_ipc_idle_limit, var_ipc_ttl_limit);
152
attr_clnt_control(tls_mgr,
153
ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
157
/* tls_mgr_seed - request PRNG seed */
159
int tls_mgr_seed(VSTRING *buf, int len)
164
* Create the tlsmgr client handle.
172
if (attr_clnt_request(tls_mgr,
173
ATTR_FLAG_NONE, /* Request attributes */
174
ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_SEED,
175
ATTR_TYPE_NUM, TLS_MGR_ATTR_SIZE, len,
177
ATTR_FLAG_MISSING, /* Reply attributes */
178
ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
179
ATTR_TYPE_DATA, TLS_MGR_ATTR_SEED, buf,
181
status = TLS_MGR_STAT_FAIL;
185
/* tls_mgr_policy - request caching policy */
187
int tls_mgr_policy(int *policy)
192
* Create the tlsmgr client handle.
200
if (attr_clnt_request(tls_mgr,
201
ATTR_FLAG_NONE, /* Request attributes */
202
ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_POLICY,
204
ATTR_FLAG_MISSING, /* Reply attributes */
205
ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
206
ATTR_TYPE_NUM, TLS_MGR_ATTR_POLICY, policy,
208
status = TLS_MGR_STAT_FAIL;
212
/* tls_mgr_lookup - request cached session */
214
int tls_mgr_lookup(int cache_type, const char *cache_id,
215
long openssl_vsn, int flags, VSTRING *buf)
220
* Create the tlsmgr client handle.
226
* Send the request and receive the reply.
228
if (attr_clnt_request(tls_mgr,
229
ATTR_FLAG_NONE, /* Request */
230
ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_LOOKUP,
231
ATTR_TYPE_NUM, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
232
ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
233
ATTR_TYPE_LONG, TLS_MGR_ATTR_VERSION, openssl_vsn,
234
ATTR_TYPE_NUM, TLS_MGR_ATTR_FLAGS, flags,
236
ATTR_FLAG_MISSING, /* Reply */
237
ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
238
ATTR_TYPE_DATA, TLS_MGR_ATTR_SESSION, buf,
240
status = TLS_MGR_STAT_FAIL;
244
/* tls_mgr_update - save session to cache */
246
int tls_mgr_update(int cache_type, const char *cache_id,
247
long openssl_vsn, int flags,
248
const char *buf, int len)
253
* Create the tlsmgr client handle.
259
* Send the request and receive the reply.
261
if (attr_clnt_request(tls_mgr,
262
ATTR_FLAG_NONE, /* Request */
263
ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_UPDATE,
264
ATTR_TYPE_NUM, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
265
ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
266
ATTR_TYPE_LONG, TLS_MGR_ATTR_VERSION, openssl_vsn,
267
ATTR_TYPE_NUM, TLS_MGR_ATTR_FLAGS, flags,
268
ATTR_TYPE_DATA, TLS_MGR_ATTR_SESSION, len, buf,
270
ATTR_FLAG_MISSING, /* Reply */
271
ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
273
status = TLS_MGR_STAT_FAIL;
277
/* tls_mgr_delete - remove cached session */
279
int tls_mgr_delete(int cache_type, const char *cache_id)
284
* Create the tlsmgr client handle.
290
* Send the request and receive the reply.
292
if (attr_clnt_request(tls_mgr,
293
ATTR_FLAG_NONE, /* Request */
294
ATTR_TYPE_STR, TLS_MGR_ATTR_REQ, TLS_MGR_REQ_DELETE,
295
ATTR_TYPE_NUM, TLS_MGR_ATTR_CACHE_TYPE, cache_type,
296
ATTR_TYPE_STR, TLS_MGR_ATTR_CACHE_ID, cache_id,
298
ATTR_FLAG_MISSING, /* Reply */
299
ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
301
status = TLS_MGR_STAT_FAIL;
307
/* System library. */
311
/* Utility library. */
314
#include <msg_vstream.h>
315
#include <vstring_vstream.h>
316
#include <hex_code.h>
318
/* Global library. */
322
/* Application-specific. */
324
#define STR(x) vstring_str(x)
325
#define LEN(x) VSTRING_LEN(x)
327
int main(int unused_ac, char **av)
329
VSTRING *inbuf = vstring_alloc(10);
333
msg_vstream_init(av[0], VSTREAM_ERR);
338
msg_info("using config files in %s", var_config_dir);
340
if (chdir(var_queue_dir) < 0)
341
msg_fatal("chdir %s: %m", var_queue_dir);
343
while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
344
argv = argv_split(STR(inbuf), " \t\r\n");
348
#define COMMAND(argv, str, len) \
349
(strcasecmp(argv->argv[0], str) == 0 && argv->argc == len)
351
if (COMMAND(argv, "policy", 1)) {
354
status = tls_mgr_policy(&cache_types);
355
vstream_printf("status=%d policy=0x%x\n", status, cache_types);
356
} else if (COMMAND(argv, "seed", 2)) {
357
VSTRING *buf = vstring_alloc(10);
358
VSTRING *hex = vstring_alloc(10);
359
int len = atoi(argv->argv[1]);
361
status = tls_mgr_seed(buf, len);
362
hex_encode(hex, STR(buf), LEN(buf));
363
vstream_printf("status=%d seed=%s\n", status, STR(hex));
366
} else if (COMMAND(argv, "lookup", 5)) {
367
VSTRING *buf = vstring_alloc(10);
368
int cache_type = atoi(argv->argv[1]);
369
long openssl_vsn = atol(argv->argv[3]);
370
int flags = atoi(argv->argv[4]);
372
status = tls_mgr_lookup(cache_type, argv->argv[2],
373
openssl_vsn, flags, buf);
374
vstream_printf("status=%d session=%.*s\n",
375
status, LEN(buf), STR(buf));
376
} else if (COMMAND(argv, "update", 6)) {
377
int cache_type = atoi(argv->argv[1]);
378
long openssl_vsn = atol(argv->argv[3]);
379
int flags = atoi(argv->argv[4]);
381
status = tls_mgr_update(cache_type, argv->argv[2],
383
argv->argv[5], strlen(argv->argv[5]));
384
vstream_printf("status=%d\n", status);
385
} else if (COMMAND(argv, "delete", 3)) {
386
int cache_type = atoi(argv->argv[1]);
388
status = tls_mgr_delete(cache_type, argv->argv[2]);
389
vstream_printf("status=%d\n", status);
391
vstream_printf("usage:\n"
394
"lookup cache_type cache_id openssl_version flags\n"
395
"update cache_type cache_id openssl_version flags session\n"
396
"delete cache_type cache_id\n");
398
vstream_fflush(VSTREAM_OUT);