source: mod_gnutls/src/gnutls_config.c @ c39ae1a

debian/masterdebian/stretch-backportsupstream
Last change on this file since c39ae1a was c39ae1a, checked in by Thomas Klute <thomas2.klute@…>, 3 years ago

Initialize OCSP timeouts with an "unset" value

The configuration merge function used the default timeout to check if
an OCSP related timeout has been set in a virtual host
configuration. This would work most of the time, but break in the
corner case of the global configuration setting a non-default timeout
and a virtual host configuration restoring the default. In this
situation the merge would handle the value from the virtual host
configuration as unset and copy the global timeout.

The problem is solved by initializing the timeouts using the new macro
MGS_TIMEOUT_UNSET. Timeouts as used in the mod_gnutls configuration
cannot be negative, so there is ample room for explicitly unset
values. MGS_TIMEOUT_UNSET is also used for the session cache timeout
instead of hard coded -1.

  • Property mode set to 100644
File size: 40.8 KB
Line 
1/**
2 *  Copyright 2004-2005 Paul Querna
3 *  Copyright 2008, 2014 Nikos Mavrogiannopoulos
4 *  Copyright 2011 Dash Shendy
5 *  Copyright 2015-2016 Thomas Klute
6 *
7 *  Licensed under the Apache License, Version 2.0 (the "License");
8 *  you may not use this file except in compliance with the License.
9 *  You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 *  Unless required by applicable law or agreed to in writing, software
14 *  distributed under the License is distributed on an "AS IS" BASIS,
15 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 *  See the License for the specific language governing permissions and
17 *  limitations under the License.
18 *
19 */
20
21#include "gnutls_config.h"
22#include "mod_gnutls.h"
23#include "gnutls_ocsp.h"
24#include "apr_lib.h"
25#include <gnutls/abstract.h>
26
27#define INIT_CA_SIZE 128
28
29#ifdef APLOG_USE_MODULE
30APLOG_USE_MODULE(gnutls);
31#endif
32
33static int pin_callback(void *user, int attempt __attribute__((unused)),
34                        const char *token_url __attribute__((unused)),
35                        const char *token_label, unsigned int flags,
36                        char *pin, size_t pin_max)
37{
38    mgs_srvconf_rec *sc = user;
39
40    if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY ||
41        flags & GNUTLS_PIN_WRONG) {
42        return -1;
43    }
44
45    if (token_label && strcmp(token_label, "SRK") == 0) {
46         snprintf(pin, pin_max, "%s", sc->srk_pin);
47    } else {
48         snprintf(pin, pin_max, "%s", sc->pin);
49    }
50    return 0;
51}
52
53static int load_datum_from_file(apr_pool_t * pool,
54                                const char *file, gnutls_datum_t * data)
55{
56    apr_file_t *fp;
57    apr_finfo_t finfo;
58    apr_status_t rv;
59    apr_size_t br = 0;
60
61    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
62                       APR_OS_DEFAULT, pool);
63    if (rv != APR_SUCCESS) {
64        return rv;
65    }
66
67    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
68
69    if (rv != APR_SUCCESS) {
70        return rv;
71    }
72
73    data->data = apr_palloc(pool, finfo.size + 1);
74    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
75
76    if (rv != APR_SUCCESS) {
77        return rv;
78    }
79    apr_file_close(fp);
80
81    data->data[br] = '\0';
82    data->size = br;
83
84    return 0;
85}
86
87/* 2048-bit group parameters from SRP specification */
88const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
89        "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
90        "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
91        "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
92        "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
93        "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
94        "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
95        "-----END DH PARAMETERS-----\n";
96
97/*
98 * Clean up the various GnuTLS data structures allocated from
99 * mgs_load_files()
100 */
101static apr_status_t mgs_pool_free_credentials(void *arg)
102{
103    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) arg;
104
105    if (sc->certs)
106    {
107        gnutls_certificate_free_credentials(sc->certs);
108        sc->certs = NULL;
109    }
110
111    if (sc->anon_creds)
112    {
113        gnutls_anon_free_server_credentials(sc->anon_creds);
114        sc->anon_creds = NULL;
115    }
116
117#ifdef ENABLE_SRP
118    if (sc->srp_creds)
119    {
120        gnutls_srp_free_server_credentials(sc->srp_creds);
121        sc->srp_creds = NULL;
122    }
123#endif
124
125    if (sc->dh_params)
126    {
127        gnutls_dh_params_deinit(sc->dh_params);
128        sc->dh_params = NULL;
129    }
130
131    for (unsigned int i = 0; i < sc->certs_x509_chain_num; i++)
132    {
133        gnutls_pcert_deinit(&sc->certs_x509_chain[i]);
134        gnutls_x509_crt_deinit(sc->certs_x509_crt_chain[i]);
135    }
136
137    if (sc->privkey_x509)
138    {
139        gnutls_privkey_deinit(sc->privkey_x509);
140        sc->privkey_x509 = NULL;
141    }
142
143    if (sc->ca_list)
144    {
145        for (unsigned int i = 0; i < sc->ca_list_size; i++)
146        {
147            gnutls_x509_crt_deinit(sc->ca_list[i]);
148        }
149        gnutls_free(sc->ca_list);
150        sc->ca_list = NULL;
151    }
152
153    if (sc->cert_pgp)
154    {
155        gnutls_pcert_deinit(&sc->cert_pgp[0]);
156        sc->cert_pgp = NULL;
157        gnutls_openpgp_crt_deinit(sc->cert_crt_pgp[0]);
158        sc->cert_crt_pgp = NULL;
159    }
160
161    if (sc->privkey_pgp)
162    {
163        gnutls_privkey_deinit(sc->privkey_pgp);
164        sc->privkey_pgp = NULL;
165#if GNUTLS_VERSION_NUMBER < 0x030312
166        gnutls_openpgp_privkey_deinit(sc->privkey_pgp_internal);
167        sc->privkey_pgp_internal = NULL;
168#endif
169    }
170
171    if (sc->pgp_list)
172    {
173        gnutls_openpgp_keyring_deinit(sc->pgp_list);
174        sc->pgp_list = NULL;
175    }
176
177    if (sc->priorities)
178    {
179        gnutls_priority_deinit(sc->priorities);
180        sc->priorities = NULL;
181    }
182
183    return APR_SUCCESS;
184}
185
186int mgs_load_files(apr_pool_t *pconf, apr_pool_t *ptemp, server_rec *s)
187{
188    apr_pool_t *spool;
189    const char *file;
190    gnutls_datum_t data;
191    int ret;
192    mgs_srvconf_rec *sc =
193        (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
194                                                 &gnutls_module);
195
196    apr_pool_create(&spool, ptemp);
197
198    /* Cleanup function for the GnuTLS structures allocated below */
199    apr_pool_cleanup_register(pconf, sc, mgs_pool_free_credentials,
200                              apr_pool_cleanup_null);
201
202    if (sc->certs == NULL)
203    {
204        ret = gnutls_certificate_allocate_credentials(&sc->certs);
205        if (ret < 0) {
206            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
207                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
208                         gnutls_strerror(ret));
209            ret = -1;
210            goto cleanup;
211        }
212    }
213
214    if (sc->anon_creds == NULL)
215    {
216        ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
217        if (ret < 0) {
218            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
219                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
220                         gnutls_strerror(ret));
221            ret = -1;
222            goto cleanup;
223        }
224    }
225
226    /* Load SRP parameters */
227#ifdef ENABLE_SRP
228    if (sc->srp_creds == NULL)
229    {
230        ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
231        if (ret < 0) {
232            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
233                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
234                         gnutls_strerror(ret));
235            ret = -1;
236            goto cleanup;
237        }
238    }
239
240    if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL)
241    {
242        ret = gnutls_srp_set_server_credentials_file
243            (sc->srp_creds, sc->srp_tpasswd_file,
244             sc->srp_tpasswd_conf_file);
245
246        if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
247            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
248                         "GnuTLS: Host '%s:%d' is missing a "
249                         "SRP password or conf File!",
250                         s->server_hostname, s->port);
251            ret = -1;
252            goto cleanup;
253        }
254    }
255#endif
256
257    if (sc->dh_params == NULL)
258    {
259        ret = gnutls_dh_params_init(&sc->dh_params);
260        if (ret < 0) {
261            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
262                         "GnuTLS: Failed to initialize"
263                         ": (%d) %s", ret, gnutls_strerror(ret));
264            ret = -1;
265            goto cleanup;
266        }
267
268        /* Load DH parameters */
269        if (sc->dh_file)
270        {
271            if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
272                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
273                             "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
274                ret = -1;
275                goto cleanup;
276            }
277
278            ret =
279                gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
280                                              GNUTLS_X509_FMT_PEM);
281            if (ret < 0) {
282                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
283                             "GnuTLS: Failed to Import "
284                             "DH params '%s': (%d) %s", sc->dh_file, ret,
285                             gnutls_strerror(ret));
286                ret = -1;
287                goto cleanup;
288            }
289        } else {
290            gnutls_datum_t pdata = {
291                (void *) static_dh_params,
292                sizeof(static_dh_params)
293            };
294
295            ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
296            if (ret < 0) {
297                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
298                             "GnuTLS: Unable to generate or load DH Params: (%d) %s",
299                             ret, gnutls_strerror(ret));
300                ret = -1;
301                goto cleanup;
302            }
303        }
304    }
305
306    if (sc->x509_cert_file != NULL && sc->certs_x509_crt_chain == NULL)
307    {
308        sc->certs_x509_chain =
309            apr_pcalloc(pconf,
310                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
311        sc->certs_x509_crt_chain =
312            apr_pcalloc(pconf,
313                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
314        unsigned int chain_num = MAX_CHAIN_SIZE;
315        unsigned format = GNUTLS_X509_FMT_PEM;
316
317        /* Load X.509 certificate */
318        if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
319            gnutls_pkcs11_obj_t obj;
320
321            file = sc->x509_cert_file;
322
323            ret = gnutls_pkcs11_obj_init(&obj);
324            if (ret < 0) {
325                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
326                             "GnuTLS: Error Initializing PKCS #11 object");
327                ret = -1;
328                goto cleanup;
329            }
330
331            gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
332
333            ret = gnutls_pkcs11_obj_import_url(obj, file,
334                                               GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
335            if (ret < 0) {
336                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
337                             "GnuTLS: Error Importing PKCS #11 object: "
338                             "'%s': %s",
339                             file, gnutls_strerror(ret));
340                ret = -1;
341                goto cleanup;
342            }
343
344            format = GNUTLS_X509_FMT_DER;
345            ret = gnutls_pkcs11_obj_export2(obj, &data);
346            if (ret < 0) {
347                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
348                             "GnuTLS: Error Exporting a PKCS #11 object: "
349                             "'%s': %s",
350                             file, gnutls_strerror(ret));
351                ret = -1;
352                goto cleanup;
353            }
354
355            gnutls_pkcs11_obj_deinit(obj);
356        } else {
357            file = ap_server_root_relative(spool, sc->x509_cert_file);
358
359            ret = gnutls_load_file(file, &data);
360            if (ret < 0) {
361                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
362                             "GnuTLS: Error Reading Certificate '%s': %s",
363                             file, gnutls_strerror(ret));
364                ret = -1;
365                goto cleanup;
366            }
367        }
368
369        ret = gnutls_x509_crt_list_import(sc->certs_x509_crt_chain,
370                                          &chain_num, &data, format,
371                                          GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
372        gnutls_free(data.data);
373        sc->certs_x509_chain_num = chain_num;
374
375        if (ret < 0) {
376            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
377                         "GnuTLS: Failed to Import Certificate Chain "
378                         "'%s': (%d) %s",
379                         file, ret, gnutls_strerror(ret));
380            ret = -1;
381            goto cleanup;
382        }
383
384        for (unsigned int i = 0; i < chain_num; i++)
385        {
386            ret =
387                gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
388                                         sc->certs_x509_crt_chain[i], 0);
389            if (ret < 0) {
390                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
391                             "GnuTLS: Failed to Import pCertificate "
392                             "'%s': (%d) %s",
393                             file, ret, gnutls_strerror(ret));
394                ret = -1;
395                goto cleanup;
396            }
397        }
398        sc->certs_x509_chain_num = chain_num;
399    }
400
401    if (sc->x509_key_file && sc->privkey_x509 == NULL)
402    {
403        ret = gnutls_privkey_init(&sc->privkey_x509);
404        if (ret < 0) {
405            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
406                         "GnuTLS: Failed to initialize: (%d) %s", ret,
407                         gnutls_strerror(ret));
408            ret = -1;
409            goto cleanup;
410        }
411
412        if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
413            file = sc->x509_key_file;
414
415            gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
416                                            sc);
417
418            ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
419
420            if (ret < 0) {
421                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
422                             "GnuTLS: Failed to Import Private Key URL "
423                             "'%s': (%d) %s",
424                             file, ret, gnutls_strerror(ret));
425                ret = -1;
426                goto cleanup;
427            }
428        } else {
429            file = ap_server_root_relative(spool, sc->x509_key_file);
430
431            if (load_datum_from_file(spool, file, &data) != 0) {
432                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
433                             "GnuTLS: Error Reading Private Key '%s'",
434                             file);
435                ret = -1;
436                goto cleanup;
437            }
438
439            ret =
440                gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
441                                               GNUTLS_X509_FMT_PEM, sc->pin,
442                                               0);
443
444            if (ret < 0) {
445                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
446                             "GnuTLS: Failed to Import Private Key "
447                             "'%s': (%d) %s",
448                             file, ret, gnutls_strerror(ret));
449                ret = -1;
450                goto cleanup;
451            }
452        }
453    }
454
455    /* Load the X.509 CA file */
456    if (sc->x509_ca_file)
457    {
458        if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
459            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
460                         "GnuTLS: Error Reading " "Client CA File '%s'",
461                         sc->x509_ca_file);
462            ret = -1;
463            goto cleanup;
464        }
465
466        ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
467                                           &data, GNUTLS_X509_FMT_PEM, 0);
468        if (ret < 0) {
469            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
470                         "GnuTLS: Failed to load "
471                         "Client CA File '%s': (%d) %s", sc->x509_ca_file,
472                         ret, gnutls_strerror(ret));
473            ret = -1;
474            goto cleanup;
475        }
476    }
477
478    if (sc->pgp_cert_file && sc->cert_pgp == NULL)
479    {
480        sc->cert_pgp = apr_pcalloc(pconf, sizeof(sc->cert_pgp[0]));
481        sc->cert_crt_pgp = apr_pcalloc(pconf, sizeof(sc->cert_crt_pgp[0]));
482
483        if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
484            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
485                         "GnuTLS: Error Reading " "Certificate '%s'",
486                         sc->pgp_cert_file);
487            ret = -1;
488            goto cleanup;
489        }
490
491        ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
492        if (ret < 0) {
493            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
494                         "GnuTLS: Failed to Init "
495                         "PGP Certificate: (%d) %s", ret,
496                         gnutls_strerror(ret));
497            ret = -1;
498            goto cleanup;
499        }
500
501        ret = gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
502                                        GNUTLS_OPENPGP_FMT_BASE64);
503        if (ret < 0) {
504            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
505                         "GnuTLS: Failed to Import "
506                         "PGP Certificate: (%d) %s", ret,
507                         gnutls_strerror(ret));
508            ret = -1;
509            goto cleanup;
510        }
511
512        ret = gnutls_pcert_import_openpgp(sc->cert_pgp,
513                                          sc->cert_crt_pgp[0], 0);
514        if (ret < 0) {
515            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
516                         "GnuTLS: Failed to Import "
517                         "PGP pCertificate: (%d) %s", ret,
518                         gnutls_strerror(ret));
519            ret = -1;
520            goto cleanup;
521        }
522    }
523
524    /* Load the PGP key file */
525    if (sc->pgp_key_file && sc->privkey_pgp == NULL)
526    {
527        if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
528            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
529                         "GnuTLS: Error Reading " "Private Key '%s'",
530                         sc->pgp_key_file);
531            ret = -1;
532            goto cleanup;
533        }
534
535        ret = gnutls_privkey_init(&sc->privkey_pgp);
536        if (ret < 0) {
537            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
538                         "GnuTLS: Failed to initialize"
539                         ": (%d) %s", ret, gnutls_strerror(ret));
540            ret = -1;
541            goto cleanup;
542        }
543
544#if GNUTLS_VERSION_NUMBER < 0x030312
545        /* GnuTLS versions before 3.3.12 contain a bug in
546         * gnutls_privkey_import_openpgp_raw which frees data that is
547         * accessed when the key is used, leading to segfault. Loading
548         * the key into a gnutls_openpgp_privkey_t and then assigning
549         * it to the gnutls_privkey_t works around the bug, hence this
550         * chain of gnutls_openpgp_privkey_init,
551         * gnutls_openpgp_privkey_import and
552         * gnutls_privkey_import_openpgp. */
553        ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal);
554        if (ret != 0) {
555            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
556                         "GnuTLS: Failed to initialize "
557                         "PGP Private Key '%s': (%d) %s",
558                         sc->pgp_key_file, ret, gnutls_strerror(ret));
559            ret = -1;
560            goto cleanup;
561        }
562
563        ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data,
564                                            GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
565        if (ret != 0) {
566            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
567                         "GnuTLS: Failed to Import "
568                         "PGP Private Key '%s': (%d) %s",
569                         sc->pgp_key_file, ret, gnutls_strerror(ret));
570            ret = -1;
571            goto cleanup;
572        }
573
574        ret = gnutls_privkey_import_openpgp(sc->privkey_pgp,
575                                            sc->privkey_pgp_internal, 0);
576        if (ret != 0)
577        {
578            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
579                         "GnuTLS: Failed to assign PGP Private Key '%s' "
580                         "to gnutls_privkey_t structure: (%d) %s",
581                         sc->pgp_key_file, ret, gnutls_strerror(ret));
582            ret = -1;
583            goto cleanup;
584        }
585#else
586        ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
587                                                GNUTLS_OPENPGP_FMT_BASE64,
588                                                NULL, NULL);
589        if (ret != 0)
590        {
591            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
592                         "GnuTLS: Failed to Import "
593                         "PGP Private Key '%s': (%d) %s",
594                         sc->pgp_key_file, ret, gnutls_strerror(ret));
595            ret = -1;
596            goto cleanup;
597        }
598#endif
599    }
600
601    /* Load the keyring file */
602    if (sc->pgp_ring_file && sc->pgp_list == NULL)
603    {
604        if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
605            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
606                         "GnuTLS: Error Reading " "Keyring File '%s'",
607                         sc->pgp_ring_file);
608            ret = -1;
609            goto cleanup;
610        }
611
612        ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
613        if (ret < 0) {
614            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
615                         "GnuTLS: Failed to initialize"
616                         "keyring: (%d) %s", ret, gnutls_strerror(ret));
617            ret = -1;
618            goto cleanup;
619        }
620
621        ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
622                                            GNUTLS_OPENPGP_FMT_BASE64);
623        if (ret < 0) {
624            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
625                         "GnuTLS: Failed to load "
626                         "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
627                         ret, gnutls_strerror(ret));
628            ret = -1;
629            goto cleanup;
630        }
631    }
632
633    if (sc->priorities_str && sc->priorities == NULL)
634    {
635        const char *err;
636        ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err);
637
638        if (ret < 0) {
639            if (ret == GNUTLS_E_INVALID_REQUEST) {
640                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
641                             "GnuTLS: Syntax error parsing priorities string at: %s",
642                             err);
643            } else {
644                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
645                             "GnuTLS: error parsing priorities string");
646
647            }
648            ret = -1;
649            goto cleanup;
650        }
651    }
652
653    ret = 0;
654 cleanup:
655    apr_pool_destroy(spool);
656
657    return ret;
658}
659
660int mgs_pkcs11_reinit(server_rec * base_server)
661{
662    int ret;
663    server_rec *s;
664    mgs_srvconf_rec *sc;
665
666    gnutls_pkcs11_reinit();
667
668    for (s = base_server; s; s = s->next) {
669        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
670
671            /* gnutls caches the session in a private key, so we need to open
672             * a new one */
673            if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) {
674                gnutls_privkey_deinit(sc->privkey_x509);
675
676                ret = gnutls_privkey_init(&sc->privkey_x509);
677                if (ret < 0) {
678                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
679                                 "GnuTLS: Failed to initialize: (%d) %s", ret,
680                                 gnutls_strerror(ret));
681                    goto fail;
682                }
683
684                gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc);
685
686                ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0);
687                if (ret < 0) {
688                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
689                             "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s",
690                             sc->x509_key_file, ret, gnutls_strerror(ret));
691                    goto fail;
692                }
693            }
694    }
695
696    return 0;
697
698 fail:
699    gnutls_privkey_deinit(sc->privkey_x509);
700    return -1;
701}
702
703const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)),
704        const char *arg) {
705    mgs_srvconf_rec *sc =
706        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
707                                                 module_config,
708                                                 &gnutls_module);
709
710    sc->dh_file = ap_server_root_relative(parms->pool, arg);
711
712    return NULL;
713}
714
715const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
716
717    mgs_srvconf_rec *sc =
718        (mgs_srvconf_rec *) ap_get_module_config(parms->
719                                                 server->module_config,
720                                                 &gnutls_module);
721
722    sc->x509_cert_file = apr_pstrdup(parms->pool, arg);
723
724    return NULL;
725
726}
727
728const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
729
730    mgs_srvconf_rec *sc =
731        (mgs_srvconf_rec *) ap_get_module_config(parms->
732                                                 server->module_config,
733                                                 &gnutls_module);
734
735    sc->x509_key_file = apr_pstrdup(parms->pool, arg);
736
737    return NULL;
738}
739
740const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)),
741        const char *arg)
742{
743    mgs_srvconf_rec *sc =
744        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
745                                                 module_config,
746                                                 &gnutls_module);
747
748    sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg);
749
750    return NULL;
751}
752
753const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)),
754        const char *arg) {
755    mgs_srvconf_rec *sc =
756        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
757                                                 module_config,
758                                                 &gnutls_module);
759
760    sc->pgp_key_file = ap_server_root_relative(parms->pool, arg);
761
762    return NULL;
763}
764
765const char *mgs_set_tickets(cmd_parms *parms,
766                            void *dummy __attribute__((unused)),
767                            const int arg)
768{
769    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
770        ap_get_module_config(parms->server->module_config, &gnutls_module);
771
772    if (arg)
773        sc->tickets = GNUTLS_ENABLED_TRUE;
774    else
775        sc->tickets = GNUTLS_ENABLED_FALSE;
776
777    return NULL;
778}
779
780
781#ifdef ENABLE_SRP
782
783const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy __attribute__((unused)),
784        const char *arg) {
785    mgs_srvconf_rec *sc =
786        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
787                                                 module_config,
788                                                 &gnutls_module);
789
790    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
791
792    return NULL;
793}
794
795const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy __attribute__((unused)),
796        const char *arg) {
797    mgs_srvconf_rec *sc =
798        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
799                                                 module_config,
800                                                 &gnutls_module);
801
802    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
803
804    return NULL;
805}
806
807#endif
808
809const char *mgs_set_cache(cmd_parms * parms, void *dummy __attribute__((unused)),
810        const char *type, const char *arg) {
811    const char *err;
812    mgs_srvconf_rec *sc =
813        ap_get_module_config(parms->server->module_config,
814                             &gnutls_module);
815    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
816        return err;
817    }
818
819    if (strcasecmp("none", type) == 0) {
820        sc->cache_type = mgs_cache_none;
821        sc->cache_config = NULL;
822        return NULL;
823    } else if (strcasecmp("dbm", type) == 0) {
824        sc->cache_type = mgs_cache_dbm;
825    } else if (strcasecmp("gdbm", type) == 0) {
826        sc->cache_type = mgs_cache_gdbm;
827    }
828#if HAVE_APR_MEMCACHE
829    else if (strcasecmp("memcache", type) == 0) {
830        sc->cache_type = mgs_cache_memcache;
831    }
832#endif
833    else {
834        return "Invalid Type for GnuTLSCache!";
835    }
836
837    if (arg == NULL)
838        return "Invalid argument 2 for GnuTLSCache!";
839
840    if (sc->cache_type == mgs_cache_dbm
841        || sc->cache_type == mgs_cache_gdbm) {
842        sc->cache_config = ap_server_root_relative(parms->pool, arg);
843    } else {
844        sc->cache_config = apr_pstrdup(parms->pool, arg);
845    }
846
847    return NULL;
848}
849
850const char *mgs_set_timeout(cmd_parms * parms,
851                            void *dummy __attribute__((unused)),
852                            const char *arg)
853{
854    apr_int64_t argint = apr_atoi64(arg);
855    /* timeouts cannot be negative */
856    if (argint < 0)
857        return apr_psprintf(parms->pool, "%s: Invalid argument",
858                            parms->directive->directive);
859
860    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
861        ap_get_module_config(parms->server->module_config, &gnutls_module);
862
863    if (!apr_strnatcasecmp(parms->directive->directive, "GnuTLSCacheTimeout"))
864    {
865        const char *err;
866        if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY)))
867            return err;
868        sc->cache_timeout = apr_time_from_sec(argint);
869    }
870    else if (!apr_strnatcasecmp(parms->directive->directive,
871                                "GnuTLSOCSPGraceTime"))
872        sc->ocsp_grace_time = apr_time_from_sec(argint);
873    else if (!apr_strnatcasecmp(parms->directive->directive,
874                                "GnuTLSOCSPFailureTimeout"))
875        sc->ocsp_failure_timeout = apr_time_from_sec(argint);
876    else if (!apr_strnatcasecmp(parms->directive->directive,
877                                "GnuTLSOCSPSocketTimeout"))
878        sc->ocsp_socket_timeout = apr_time_from_sec(argint);
879    else
880        /* Can't happen unless there's a serious bug in mod_gnutls or Apache */
881        return apr_psprintf(parms->pool,
882                            "mod_gnutls: %s called for invalid option '%s'",
883                            __func__, parms->directive->directive);
884
885    return NULL;
886}
887
888const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy __attribute__((unused)),
889        const char *arg) {
890    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)ap_get_module_config(parms->server->module_config, &gnutls_module);
891
892    if (strcasecmp("cartel", arg) == 0) {
893        sc->client_verify_method = mgs_cvm_cartel;
894    } else if (strcasecmp("msva", arg) == 0) {
895#ifdef ENABLE_MSVA
896        sc->client_verify_method = mgs_cvm_msva;
897#else
898        return "GnuTLSClientVerifyMethod: msva is not supported";
899#endif
900    } else {
901        return "GnuTLSClientVerifyMethod: Invalid argument";
902    }
903
904    return NULL;
905}
906
907const char *mgs_set_client_verify(cmd_parms * parms,
908                                  void *dirconf,
909                                  const char *arg) {
910    int mode;
911
912    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
913        mode = GNUTLS_CERT_IGNORE;
914    } else if (strcasecmp("optional", arg) == 0
915               || strcasecmp("request", arg) == 0) {
916        mode = GNUTLS_CERT_REQUEST;
917    } else if (strcasecmp("require", arg) == 0) {
918        mode = GNUTLS_CERT_REQUIRE;
919    } else {
920        return "GnuTLSClientVerify: Invalid argument";
921    }
922
923    /* This was set from a directory context */
924    if (parms->path) {
925        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dirconf;
926        dc->client_verify_mode = mode;
927    } else {
928        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
929            ap_get_module_config(parms->server->module_config,
930                                 &gnutls_module);
931        sc->client_verify_mode = mode;
932    }
933
934    return NULL;
935}
936
937const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy __attribute__((unused)),
938        const char *arg) {
939    mgs_srvconf_rec *sc =
940        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
941                                                 module_config,
942                                                 &gnutls_module);
943
944    sc->x509_ca_file = ap_server_root_relative(parms->pool, arg);
945
946    return NULL;
947}
948
949const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy __attribute__((unused)),
950        const char *arg) {
951    mgs_srvconf_rec *sc =
952        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
953                                                 module_config,
954                                                 &gnutls_module);
955
956    sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg);
957
958    return NULL;
959}
960
961/*
962 * Enable TLS proxy operation if arg is true, disable it otherwise.
963 */
964const char *mgs_set_proxy_engine(cmd_parms *parms,
965                                 void *dummy __attribute__((unused)),
966                                 const int arg)
967{
968    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
969        ap_get_module_config(parms->server->module_config, &gnutls_module);
970
971    if (arg)
972        sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
973    else
974        sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
975
976    return NULL;
977}
978
979/*
980 * Enable TLS for the server/vhost if arg is true, disable it
981 * otherwise.
982 */
983const char *mgs_set_enabled(cmd_parms *parms,
984                            void *dummy __attribute__((unused)),
985                            const int arg)
986{
987    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
988        ap_get_module_config(parms->server->module_config, &gnutls_module);
989
990    if (arg)
991        sc->enabled = GNUTLS_ENABLED_TRUE;
992    else
993        sc->enabled = GNUTLS_ENABLED_FALSE;
994
995    return NULL;
996}
997
998const char *mgs_set_export_certificates_size(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
999    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
1000    if (!strcasecmp(arg, "On")) {
1001        sc->export_certificates_size = 16 * 1024;
1002    } else if (!strcasecmp(arg, "Off")) {
1003        sc->export_certificates_size = 0;
1004    } else {
1005        char *endptr;
1006        sc->export_certificates_size = strtol(arg, &endptr, 10);
1007        while (apr_isspace(*endptr))
1008            endptr++;
1009        if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
1010            ;
1011        } else if (*endptr == 'k' || *endptr == 'K') {
1012            sc->export_certificates_size *= 1024;
1013        } else {
1014            return
1015                "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
1016        }
1017    }
1018
1019    return NULL;
1020}
1021
1022
1023
1024/*
1025 * Store GnuTLS priority strings. Used for GnuTLSPriorities and
1026 * GnuTLSProxyPriorities.
1027 */
1028const char *mgs_set_priorities(cmd_parms * parms,
1029                               void *dummy __attribute__((unused)),
1030                               const char *arg)
1031{
1032    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1033        ap_get_module_config(parms->server->module_config, &gnutls_module);
1034
1035    if (!strcasecmp(parms->directive->directive, "GnuTLSPriorities"))
1036        sc->priorities_str = apr_pstrdup(parms->pool, arg);
1037    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyPriorities"))
1038        sc->proxy_priorities_str = apr_pstrdup(parms->pool, arg);
1039    else
1040        /* Can't happen unless there's a serious bug in mod_gnutls or Apache */
1041        return apr_psprintf(parms->pool,
1042                            "mod_gnutls: %s called for invalid option '%s'",
1043                            __func__, parms->directive->directive);
1044
1045    return NULL;
1046}
1047
1048
1049
1050const char *mgs_set_pin(cmd_parms * parms, void *dummy __attribute__((unused)),
1051                        const char *arg)
1052{
1053
1054    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1055        ap_get_module_config(parms->server->module_config, &gnutls_module);
1056
1057    sc->pin = apr_pstrdup(parms->pool, arg);
1058
1059    return NULL;
1060}
1061
1062const char *mgs_set_srk_pin(cmd_parms * parms,
1063                            void *dummy __attribute__((unused)),
1064                            const char *arg)
1065{
1066
1067    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1068        ap_get_module_config(parms->server->module_config, &gnutls_module);
1069
1070    sc->srk_pin = apr_pstrdup(parms->pool, arg);
1071
1072    return NULL;
1073}
1074
1075
1076
1077static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p,
1078                                                  char **err __attribute__((unused)))
1079{
1080    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
1081
1082    sc->enabled = GNUTLS_ENABLED_UNSET;
1083
1084    sc->privkey_x509 = NULL;
1085    sc->anon_creds = NULL;
1086#ifdef ENABLE_SRP
1087    sc->srp_creds = NULL;
1088#endif
1089    sc->certs = NULL;
1090    sc->certs_x509_chain = NULL;
1091    sc->certs_x509_crt_chain = NULL;
1092    sc->certs_x509_chain_num = 0;
1093    sc->p11_modules = NULL;
1094    sc->pin = NULL;
1095
1096    sc->cert_pgp = NULL;
1097    sc->cert_crt_pgp = NULL;
1098    sc->privkey_pgp = NULL;
1099#if GNUTLS_VERSION_NUMBER < 0x030312
1100    sc->privkey_pgp_internal = NULL;
1101#endif
1102    sc->pgp_list = NULL;
1103
1104    sc->priorities_str = NULL;
1105    sc->cache_timeout = MGS_TIMEOUT_UNSET;
1106    sc->cache_type = mgs_cache_unset;
1107    sc->cache_config = NULL;
1108    sc->cache = NULL;
1109    sc->tickets = GNUTLS_ENABLED_UNSET;
1110    sc->priorities = NULL;
1111    sc->dh_params = NULL;
1112    sc->ca_list = NULL;
1113    sc->ca_list_size = 0;
1114    sc->proxy_enabled = GNUTLS_ENABLED_UNSET;
1115    sc->export_certificates_size = -1;
1116    sc->client_verify_method = mgs_cvm_unset;
1117
1118    sc->proxy_x509_key_file = NULL;
1119    sc->proxy_x509_cert_file = NULL;
1120    sc->proxy_x509_ca_file = NULL;
1121    sc->proxy_x509_crl_file = NULL;
1122    sc->proxy_priorities_str = NULL;
1123    sc->proxy_x509_creds = NULL;
1124    sc->anon_client_creds = NULL;
1125    sc->proxy_priorities = NULL;
1126    sc->proxy_x509_tl = NULL;
1127
1128    sc->ocsp_staple = GNUTLS_ENABLED_UNSET;
1129    sc->ocsp_response_file = NULL;
1130    sc->ocsp_mutex = NULL;
1131    sc->ocsp_grace_time = MGS_TIMEOUT_UNSET;
1132    sc->ocsp_failure_timeout = MGS_TIMEOUT_UNSET;
1133    sc->ocsp_socket_timeout = MGS_TIMEOUT_UNSET;
1134
1135/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
1136    sc->client_verify_mode = -1;
1137
1138    return sc;
1139}
1140
1141void *mgs_config_server_create(apr_pool_t * p,
1142                               server_rec * s __attribute__((unused))) {
1143    char *err = NULL;
1144    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
1145    if (sc)
1146        return sc;
1147    else
1148        return err;
1149}
1150
1151#define gnutls_srvconf_merge(t, unset) sc->t = (add->t == unset) ? base->t : add->t
1152#define gnutls_srvconf_assign(t) sc->t = add->t
1153
1154void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD)
1155{
1156    int i;
1157    char *err = NULL;
1158    mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;
1159    mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;
1160    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
1161    if (NULL == sc)
1162        return err;
1163
1164    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
1165    gnutls_srvconf_merge(tickets, GNUTLS_ENABLED_UNSET);
1166    gnutls_srvconf_merge(proxy_enabled, GNUTLS_ENABLED_UNSET);
1167    gnutls_srvconf_merge(export_certificates_size, -1);
1168    gnutls_srvconf_merge(client_verify_method, mgs_cvm_unset);
1169    gnutls_srvconf_merge(client_verify_mode, -1);
1170    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
1171    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
1172    gnutls_srvconf_merge(x509_cert_file, NULL);
1173
1174    gnutls_srvconf_merge(x509_key_file, NULL);
1175    gnutls_srvconf_merge(x509_ca_file, NULL);
1176    gnutls_srvconf_merge(p11_modules, NULL);
1177    gnutls_srvconf_merge(pin, NULL);
1178    gnutls_srvconf_merge(pgp_cert_file, NULL);
1179    gnutls_srvconf_merge(pgp_key_file, NULL);
1180    gnutls_srvconf_merge(pgp_ring_file, NULL);
1181    gnutls_srvconf_merge(dh_file, NULL);
1182    gnutls_srvconf_merge(priorities_str, NULL);
1183
1184    gnutls_srvconf_merge(proxy_x509_key_file, NULL);
1185    gnutls_srvconf_merge(proxy_x509_cert_file, NULL);
1186    gnutls_srvconf_merge(proxy_x509_ca_file, NULL);
1187    gnutls_srvconf_merge(proxy_x509_crl_file, NULL);
1188    gnutls_srvconf_merge(proxy_priorities_str, NULL);
1189    gnutls_srvconf_merge(proxy_priorities, NULL);
1190
1191    gnutls_srvconf_merge(ocsp_staple, GNUTLS_ENABLED_UNSET);
1192    gnutls_srvconf_assign(ocsp_response_file);
1193    gnutls_srvconf_merge(ocsp_grace_time, MGS_TIMEOUT_UNSET);
1194    gnutls_srvconf_merge(ocsp_failure_timeout, MGS_TIMEOUT_UNSET);
1195    gnutls_srvconf_merge(ocsp_socket_timeout, MGS_TIMEOUT_UNSET);
1196
1197    gnutls_srvconf_assign(ca_list);
1198    gnutls_srvconf_assign(ca_list_size);
1199    gnutls_srvconf_assign(cert_pgp);
1200    gnutls_srvconf_assign(cert_crt_pgp);
1201    gnutls_srvconf_assign(pgp_list);
1202    gnutls_srvconf_assign(certs);
1203    gnutls_srvconf_assign(anon_creds);
1204    gnutls_srvconf_assign(srp_creds);
1205    gnutls_srvconf_assign(certs_x509_chain);
1206    gnutls_srvconf_assign(certs_x509_crt_chain);
1207    gnutls_srvconf_assign(certs_x509_chain_num);
1208
1209    /* how do these get transferred cleanly before the data from ADD
1210     * goes away? */
1211    gnutls_srvconf_assign(cert_cn);
1212    for (i = 0; i < MAX_CERT_SAN; i++)
1213        gnutls_srvconf_assign(cert_san[i]);
1214
1215    return sc;
1216}
1217
1218#undef gnutls_srvconf_merge
1219#undef gnutls_srvconf_assign
1220
1221void *mgs_config_dir_merge(apr_pool_t * p,
1222                           void *basev __attribute__((unused)),
1223                           void *addv __attribute__((unused))) {
1224    mgs_dirconf_rec *new;
1225    /*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
1226    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
1227
1228    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
1229    new->client_verify_mode = add->client_verify_mode;
1230    return new;
1231}
1232
1233void *mgs_config_dir_create(apr_pool_t * p,
1234                            char *dir __attribute__((unused))) {
1235    mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc));
1236    dc->client_verify_mode = -1;
1237    return dc;
1238}
1239
1240
1241
1242/*
1243 * Store paths to proxy credentials
1244 *
1245 * This function copies the paths provided in the configuration file
1246 * into the server configuration. The post configuration hook takes
1247 * care of actually loading the credentials, which means than invalid
1248 * paths or the like will be detected there.
1249 */
1250const char *mgs_store_cred_path(cmd_parms * parms,
1251                                void *dummy __attribute__((unused)),
1252                                const char *arg)
1253{
1254    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1255        ap_get_module_config(parms->server->module_config, &gnutls_module);
1256
1257    /* parms->directive->directive contains the directive string */
1258    if (!strcasecmp(parms->directive->directive, "GnuTLSProxyKeyFile"))
1259        sc->proxy_x509_key_file = apr_pstrdup(parms->pool, arg);
1260    else if (!strcasecmp(parms->directive->directive,
1261                         "GnuTLSProxyCertificateFile"))
1262        sc->proxy_x509_cert_file = apr_pstrdup(parms->pool, arg);
1263    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCAFile"))
1264        sc->proxy_x509_ca_file = apr_pstrdup(parms->pool, arg);
1265    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCRLFile"))
1266        sc->proxy_x509_crl_file = apr_pstrdup(parms->pool, arg);
1267    return NULL;
1268}
1269
1270
1271
1272/*
1273 * Record PKCS #11 module to load. Note that the value is only used in
1274 * the base config, settings in virtual hosts are ignored.
1275 */
1276const char *mgs_set_p11_module(cmd_parms * parms,
1277                               void *dummy __attribute__((unused)),
1278                               const char *arg)
1279{
1280    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1281        ap_get_module_config(parms->server->module_config, &gnutls_module);
1282    /* initialize PKCS #11 module list if necessary */
1283    if (sc->p11_modules == NULL)
1284        sc->p11_modules = apr_array_make(parms->pool, 2, sizeof(char*));
1285
1286    *(char **) apr_array_push(sc->p11_modules) = apr_pstrdup(parms->pool, arg);
1287
1288    return NULL;
1289}
Note: See TracBrowser for help on using the repository browser.