~ubuntu-branches/ubuntu/vivid/postfix/vivid-proposed

« back to all changes in this revision

Viewing changes to src/tls/tls_mgr.c

Tags: upstream-2.2.6
ImportĀ upstreamĀ versionĀ 2.2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_types)
 
14
/*      int     *cache_types;
 
15
/*
 
16
/*      int     tls_mgr_update(cache_type, cache_id,
 
17
/*                              openssl_version, flags, buf, len)
 
18
/*      int     cache_type;
 
19
/*      const char *cache_id;
 
20
/*      long    openssl_version;
 
21
/*      int     flags;
 
22
/*      const char *buf;
 
23
/*      int     len;
 
24
/*
 
25
/*      int     tls_mgr_lookup(cache_type, cache_id,
 
26
/*                              openssl_version, flags, buf)
 
27
/*      int     cache_type;
 
28
/*      const char *cache_id;
 
29
/*      long    openssl_version;
 
30
/*      int     flags;
 
31
/*      VSTRING *buf;
 
32
/*
 
33
/*      int     tls_mgr_delete(cache_type, cache_id)
 
34
/*      int     cache_type;
 
35
/*      const char *cache_id;
 
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
/*      Arguments
 
57
/* .IP cache_types
 
58
/*      The bit-wise OR of zero or more of the following:
 
59
/* .RS
 
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.
 
64
/* .RE
 
65
/* .IP cache_type
 
66
/*      One of TLS_MGR_SCACHE_CLIENT or TLS_MGR_SCACHE_SERVER (see above).
 
67
/* .IP cache_id
 
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.
 
72
/* .IP flags
 
73
/*      Flags that must be set in the retrieved cache entry; it not,
 
74
/*      the cache entry is deleted.
 
75
/* .IP buf
 
76
/*      The result or input buffer.
 
77
/* .IP len
 
78
/*      The length of the input buffer, or the amount of data requested.
 
79
/* DIAGNOSTICS
 
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).
 
92
/* SEE ALSO
 
93
/*      tlsmgr(8) TLS session and PRNG management
 
94
/* LICENSE
 
95
/* .ad
 
96
/* .fi
 
97
/*      The Secure Mailer license must be distributed with this software.
 
98
/* AUTHOR(S)
 
99
/*      Wietse Venema
 
100
/*      IBM T.J. Watson Research
 
101
/*      P.O. Box 704
 
102
/*      Yorktown Heights, NY 10598, USA
 
103
/*--*/
 
104
 
 
105
/* System library. */
 
106
 
 
107
#include <sys_defs.h>
 
108
 
 
109
#ifdef USE_TLS
 
110
 
 
111
/* Utility library. */
 
112
 
 
113
#include <msg.h>
 
114
#include <vstream.h>
 
115
#include <vstring.h>
 
116
#include <attr.h>
 
117
#include <attr_clnt.h>
 
118
 
 
119
/* Global library. */
 
120
 
 
121
#include <mail_params.h>
 
122
#include <mail_proto.h>
 
123
#include <tls_mgr.h>
 
124
 
 
125
/* Application-specific. */
 
126
 
 
127
static ATTR_CLNT *tls_mgr;
 
128
 
 
129
/* tls_mgr_open - create client handle */
 
130
 
 
131
static void tls_mgr_open(void)
 
132
{
 
133
 
 
134
    /*
 
135
     * Sanity check.
 
136
     */
 
137
    if (tls_mgr != 0)
 
138
        msg_panic("tls_mgr_open: multiple initialization");
 
139
 
 
140
    /*
 
141
     * Use whatever IPC is preferred for internal use: UNIX-domain sockets or
 
142
     * Solaris streams.
 
143
     */
 
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,
 
147
                               var_ipc_ttl_limit);
 
148
#else
 
149
    tls_mgr = attr_clnt_create(var_tlsmgr_service, var_ipc_timeout,
 
150
                               var_ipc_idle_limit, var_ipc_ttl_limit);
 
151
#endif
 
152
    attr_clnt_control(tls_mgr,
 
153
                      ATTR_CLNT_CTL_PROTO, attr_vprint, attr_vscan,
 
154
                      ATTR_CLNT_CTL_END);
 
155
}
 
156
 
 
157
/* tls_mgr_seed - request PRNG seed */
 
158
 
 
159
int     tls_mgr_seed(VSTRING *buf, int len)
 
160
{
 
161
    int     status;
 
162
 
 
163
    /*
 
164
     * Create the tlsmgr client handle.
 
165
     */
 
166
    if (tls_mgr == 0)
 
167
        tls_mgr_open();
 
168
 
 
169
    /*
 
170
     * Request seed.
 
171
     */
 
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,
 
176
                          ATTR_TYPE_END,
 
177
                          ATTR_FLAG_MISSING,    /* Reply attributes */
 
178
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
 
179
                          ATTR_TYPE_DATA, TLS_MGR_ATTR_SEED, buf,
 
180
                          ATTR_TYPE_END) != 2)
 
181
        status = TLS_MGR_STAT_FAIL;
 
182
    return (status);
 
183
}
 
184
 
 
185
/* tls_mgr_policy - request caching policy */
 
186
 
 
187
int     tls_mgr_policy(int *policy)
 
188
{
 
189
    int     status;
 
190
 
 
191
    /*
 
192
     * Create the tlsmgr client handle.
 
193
     */
 
194
    if (tls_mgr == 0)
 
195
        tls_mgr_open();
 
196
 
 
197
    /*
 
198
     * Request policy.
 
199
     */
 
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,
 
203
                          ATTR_TYPE_END,
 
204
                          ATTR_FLAG_MISSING,    /* Reply attributes */
 
205
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
 
206
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_POLICY, policy,
 
207
                          ATTR_TYPE_END) != 2)
 
208
        status = TLS_MGR_STAT_FAIL;
 
209
    return (status);
 
210
}
 
211
 
 
212
/* tls_mgr_lookup - request cached session */
 
213
 
 
214
int     tls_mgr_lookup(int cache_type, const char *cache_id,
 
215
                               long openssl_vsn, int flags, VSTRING *buf)
 
216
{
 
217
    int     status;
 
218
 
 
219
    /*
 
220
     * Create the tlsmgr client handle.
 
221
     */
 
222
    if (tls_mgr == 0)
 
223
        tls_mgr_open();
 
224
 
 
225
    /*
 
226
     * Send the request and receive the reply.
 
227
     */
 
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,
 
235
                          ATTR_TYPE_END,
 
236
                          ATTR_FLAG_MISSING,    /* Reply */
 
237
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
 
238
                          ATTR_TYPE_DATA, TLS_MGR_ATTR_SESSION, buf,
 
239
                          ATTR_TYPE_END) != 2)
 
240
        status = TLS_MGR_STAT_FAIL;
 
241
    return (status);
 
242
}
 
243
 
 
244
/* tls_mgr_update - save session to cache */
 
245
 
 
246
int     tls_mgr_update(int cache_type, const char *cache_id,
 
247
                               long openssl_vsn, int flags,
 
248
                               const char *buf, int len)
 
249
{
 
250
    int     status;
 
251
 
 
252
    /*
 
253
     * Create the tlsmgr client handle.
 
254
     */
 
255
    if (tls_mgr == 0)
 
256
        tls_mgr_open();
 
257
 
 
258
    /*
 
259
     * Send the request and receive the reply.
 
260
     */
 
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,
 
269
                          ATTR_TYPE_END,
 
270
                          ATTR_FLAG_MISSING,    /* Reply */
 
271
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
 
272
                          ATTR_TYPE_END) != 1)
 
273
        status = TLS_MGR_STAT_FAIL;
 
274
    return (status);
 
275
}
 
276
 
 
277
/* tls_mgr_delete - remove cached session */
 
278
 
 
279
int     tls_mgr_delete(int cache_type, const char *cache_id)
 
280
{
 
281
    int     status;
 
282
 
 
283
    /*
 
284
     * Create the tlsmgr client handle.
 
285
     */
 
286
    if (tls_mgr == 0)
 
287
        tls_mgr_open();
 
288
 
 
289
    /*
 
290
     * Send the request and receive the reply.
 
291
     */
 
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,
 
297
                          ATTR_TYPE_END,
 
298
                          ATTR_FLAG_MISSING,    /* Reply */
 
299
                          ATTR_TYPE_NUM, TLS_MGR_ATTR_STATUS, &status,
 
300
                          ATTR_TYPE_END) != 1)
 
301
        status = TLS_MGR_STAT_FAIL;
 
302
    return (status);
 
303
}
 
304
 
 
305
#ifdef TEST
 
306
 
 
307
/* System library. */
 
308
 
 
309
#include <stdlib.h>
 
310
 
 
311
/* Utility library. */
 
312
 
 
313
#include <argv.h>
 
314
#include <msg_vstream.h>
 
315
#include <vstring_vstream.h>
 
316
#include <hex_code.h>
 
317
 
 
318
/* Global library. */
 
319
 
 
320
#include <config.h>
 
321
 
 
322
/* Application-specific. */
 
323
 
 
324
#define STR(x) vstring_str(x)
 
325
#define LEN(x) VSTRING_LEN(x)
 
326
 
 
327
int     main(int unused_ac, char **av)
 
328
{
 
329
    VSTRING *inbuf = vstring_alloc(10);
 
330
    int     status;
 
331
    ARGV   *argv = 0;
 
332
 
 
333
    msg_vstream_init(av[0], VSTREAM_ERR);
 
334
 
 
335
    msg_verbose = 3;
 
336
 
 
337
    mail_conf_read();
 
338
    msg_info("using config files in %s", var_config_dir);
 
339
 
 
340
    if (chdir(var_queue_dir) < 0)
 
341
        msg_fatal("chdir %s: %m", var_queue_dir);
 
342
 
 
343
    while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
 
344
        argv = argv_split(STR(inbuf), " \t\r\n");
 
345
        if (argv->argc == 0)
 
346
            continue;
 
347
 
 
348
#define COMMAND(argv, str, len) \
 
349
    (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len)
 
350
 
 
351
        if (COMMAND(argv, "policy", 1)) {
 
352
            int     cache_types;
 
353
 
 
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]);
 
360
 
 
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));
 
364
            vstring_free(hex);
 
365
            vstring_free(buf);
 
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]);
 
371
 
 
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]);
 
380
 
 
381
            status = tls_mgr_update(cache_type, argv->argv[2],
 
382
                                    openssl_vsn, flags,
 
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]);
 
387
 
 
388
            status = tls_mgr_delete(cache_type, argv->argv[2]);
 
389
            vstream_printf("status=%d\n", status);
 
390
        } else {
 
391
            vstream_printf("usage:\n"
 
392
                           "seed byte_count\n"
 
393
                           "policy\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");
 
397
        }
 
398
        vstream_fflush(VSTREAM_OUT);
 
399
    }
 
400
    if (argv)
 
401
        argv_free(argv);
 
402
 
 
403
    vstring_free(inbuf);
 
404
}
 
405
 
 
406
#endif                                  /* TEST */
 
407
 
 
408
#endif                                  /* USE_TLS */