source: mod_gnutls/src/gnutls_config.c @ 333bbc7

asynciodebian/masterdebian/stretch-backportsproxy-ticketupstream
Last change on this file since 333bbc7 was 333bbc7, checked in by Thomas Klute <thomas2.klute@…>, 4 years ago

Configurable OCSP socket timeout

Stalled OCSP requests must time out after a while to prevent stalling
the server too much. However, if the timeout is too short requests may
fail with a slow OCSP responder or high latency network
connection. Using the new GnuTLSOCSPFailureTimeout parameter users can
adjust the timeout if necessary.

All macros defining default values for OCSP related times are now
collected in gnutls_ocsp.h.

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