source: mod_gnutls/src/gnutls_config.c @ c6dda6d

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

Rate limit OCSP requests

Retries after failed OCSP requests must be rate limited. If the
responder is overloaded or buggy we don't want to add too much more
load, and if a MITM is messing with requests a repetition loop might
end up being a self-inflicted denial of service.

The minimum time to wait between retries can be configured using the
GnuTLSOCSPFailureTimeout directive.

  • Property mode set to 100644
File size: 40.6 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 "apr_lib.h"
23#include <gnutls/abstract.h>
24
25#define INIT_CA_SIZE 128
26/* Default OCSP response grace time in seconds */
27#define MGS_GRACE_TIME 60
28/* Default OCSP failure timeout in seconds */
29#define MGS_FAILURE_TIMEOUT 300
30
31#ifdef APLOG_USE_MODULE
32APLOG_USE_MODULE(gnutls);
33#endif
34
35static int pin_callback(void *user, int attempt __attribute__((unused)),
36                        const char *token_url __attribute__((unused)),
37                        const char *token_label, unsigned int flags,
38                        char *pin, size_t pin_max)
39{
40    mgs_srvconf_rec *sc = user;
41
42    if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY ||
43        flags & GNUTLS_PIN_WRONG) {
44        return -1;
45    }
46
47    if (token_label && strcmp(token_label, "SRK") == 0) {
48         snprintf(pin, pin_max, "%s", sc->srk_pin);
49    } else {
50         snprintf(pin, pin_max, "%s", sc->pin);
51    }
52    return 0;
53}
54
55static int load_datum_from_file(apr_pool_t * pool,
56                                const char *file, gnutls_datum_t * data)
57{
58    apr_file_t *fp;
59    apr_finfo_t finfo;
60    apr_status_t rv;
61    apr_size_t br = 0;
62
63    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
64                       APR_OS_DEFAULT, pool);
65    if (rv != APR_SUCCESS) {
66        return rv;
67    }
68
69    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
70
71    if (rv != APR_SUCCESS) {
72        return rv;
73    }
74
75    data->data = apr_palloc(pool, finfo.size + 1);
76    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
77
78    if (rv != APR_SUCCESS) {
79        return rv;
80    }
81    apr_file_close(fp);
82
83    data->data[br] = '\0';
84    data->size = br;
85
86    return 0;
87}
88
89/* 2048-bit group parameters from SRP specification */
90const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
91        "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
92        "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
93        "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
94        "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
95        "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
96        "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
97        "-----END DH PARAMETERS-----\n";
98
99/*
100 * Clean up the various GnuTLS data structures allocated from
101 * mgs_load_files()
102 */
103static apr_status_t mgs_pool_free_credentials(void *arg)
104{
105    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) arg;
106
107    if (sc->certs)
108    {
109        gnutls_certificate_free_credentials(sc->certs);
110        sc->certs = NULL;
111    }
112
113    if (sc->anon_creds)
114    {
115        gnutls_anon_free_server_credentials(sc->anon_creds);
116        sc->anon_creds = NULL;
117    }
118
119#ifdef ENABLE_SRP
120    if (sc->srp_creds)
121    {
122        gnutls_srp_free_server_credentials(sc->srp_creds);
123        sc->srp_creds = NULL;
124    }
125#endif
126
127    if (sc->dh_params)
128    {
129        gnutls_dh_params_deinit(sc->dh_params);
130        sc->dh_params = NULL;
131    }
132
133    for (unsigned int i = 0; i < sc->certs_x509_chain_num; i++)
134    {
135        gnutls_pcert_deinit(&sc->certs_x509_chain[i]);
136        gnutls_x509_crt_deinit(sc->certs_x509_crt_chain[i]);
137    }
138
139    if (sc->privkey_x509)
140    {
141        gnutls_privkey_deinit(sc->privkey_x509);
142        sc->privkey_x509 = NULL;
143    }
144
145    if (sc->ca_list)
146    {
147        for (unsigned int i = 0; i < sc->ca_list_size; i++)
148        {
149            gnutls_x509_crt_deinit(sc->ca_list[i]);
150        }
151        gnutls_free(sc->ca_list);
152        sc->ca_list = NULL;
153    }
154
155    if (sc->cert_pgp)
156    {
157        gnutls_pcert_deinit(&sc->cert_pgp[0]);
158        sc->cert_pgp = NULL;
159        gnutls_openpgp_crt_deinit(sc->cert_crt_pgp[0]);
160        sc->cert_crt_pgp = NULL;
161    }
162
163    if (sc->privkey_pgp)
164    {
165        gnutls_privkey_deinit(sc->privkey_pgp);
166        sc->privkey_pgp = NULL;
167#if GNUTLS_VERSION_NUMBER < 0x030312
168        gnutls_openpgp_privkey_deinit(sc->privkey_pgp_internal);
169        sc->privkey_pgp_internal = NULL;
170#endif
171    }
172
173    if (sc->pgp_list)
174    {
175        gnutls_openpgp_keyring_deinit(sc->pgp_list);
176        sc->pgp_list = NULL;
177    }
178
179    if (sc->priorities)
180    {
181        gnutls_priority_deinit(sc->priorities);
182        sc->priorities = NULL;
183    }
184
185    return APR_SUCCESS;
186}
187
188int mgs_load_files(apr_pool_t *pconf, apr_pool_t *ptemp, server_rec *s)
189{
190    apr_pool_t *spool;
191    const char *file;
192    gnutls_datum_t data;
193    int ret;
194    mgs_srvconf_rec *sc =
195        (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
196                                                 &gnutls_module);
197
198    apr_pool_create(&spool, ptemp);
199
200    /* Cleanup function for the GnuTLS structures allocated below */
201    apr_pool_cleanup_register(pconf, sc, mgs_pool_free_credentials,
202                              apr_pool_cleanup_null);
203
204    if (sc->certs == NULL)
205    {
206        ret = gnutls_certificate_allocate_credentials(&sc->certs);
207        if (ret < 0) {
208            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
209                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
210                         gnutls_strerror(ret));
211            ret = -1;
212            goto cleanup;
213        }
214    }
215
216    if (sc->anon_creds == NULL)
217    {
218        ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
219        if (ret < 0) {
220            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
221                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
222                         gnutls_strerror(ret));
223            ret = -1;
224            goto cleanup;
225        }
226    }
227
228    /* Load SRP parameters */
229#ifdef ENABLE_SRP
230    if (sc->srp_creds == NULL)
231    {
232        ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
233        if (ret < 0) {
234            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
235                         "GnuTLS: Failed to initialize" ": (%d) %s", ret,
236                         gnutls_strerror(ret));
237            ret = -1;
238            goto cleanup;
239        }
240    }
241
242    if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL)
243    {
244        ret = gnutls_srp_set_server_credentials_file
245            (sc->srp_creds, sc->srp_tpasswd_file,
246             sc->srp_tpasswd_conf_file);
247
248        if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
249            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
250                         "GnuTLS: Host '%s:%d' is missing a "
251                         "SRP password or conf File!",
252                         s->server_hostname, s->port);
253            ret = -1;
254            goto cleanup;
255        }
256    }
257#endif
258
259    if (sc->dh_params == NULL)
260    {
261        ret = gnutls_dh_params_init(&sc->dh_params);
262        if (ret < 0) {
263            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
264                         "GnuTLS: Failed to initialize"
265                         ": (%d) %s", ret, gnutls_strerror(ret));
266            ret = -1;
267            goto cleanup;
268        }
269
270        /* Load DH parameters */
271        if (sc->dh_file)
272        {
273            if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
274                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
275                             "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
276                ret = -1;
277                goto cleanup;
278            }
279
280            ret =
281                gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
282                                              GNUTLS_X509_FMT_PEM);
283            if (ret < 0) {
284                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
285                             "GnuTLS: Failed to Import "
286                             "DH params '%s': (%d) %s", sc->dh_file, ret,
287                             gnutls_strerror(ret));
288                ret = -1;
289                goto cleanup;
290            }
291        } else {
292            gnutls_datum_t pdata = {
293                (void *) static_dh_params,
294                sizeof(static_dh_params)
295            };
296
297            ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
298            if (ret < 0) {
299                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
300                             "GnuTLS: Unable to generate or load DH Params: (%d) %s",
301                             ret, gnutls_strerror(ret));
302                ret = -1;
303                goto cleanup;
304            }
305        }
306    }
307
308    if (sc->x509_cert_file != NULL && sc->certs_x509_crt_chain == NULL)
309    {
310        sc->certs_x509_chain =
311            apr_pcalloc(pconf,
312                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
313        sc->certs_x509_crt_chain =
314            apr_pcalloc(pconf,
315                        MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
316        unsigned int chain_num = MAX_CHAIN_SIZE;
317        unsigned format = GNUTLS_X509_FMT_PEM;
318
319        /* Load X.509 certificate */
320        if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
321            gnutls_pkcs11_obj_t obj;
322
323            file = sc->x509_cert_file;
324
325            ret = gnutls_pkcs11_obj_init(&obj);
326            if (ret < 0) {
327                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
328                             "GnuTLS: Error Initializing PKCS #11 object");
329                ret = -1;
330                goto cleanup;
331            }
332
333            gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
334
335            ret = gnutls_pkcs11_obj_import_url(obj, file,
336                                               GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
337            if (ret < 0) {
338                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
339                             "GnuTLS: Error Importing PKCS #11 object: "
340                             "'%s': %s",
341                             file, gnutls_strerror(ret));
342                ret = -1;
343                goto cleanup;
344            }
345
346            format = GNUTLS_X509_FMT_DER;
347            ret = gnutls_pkcs11_obj_export2(obj, &data);
348            if (ret < 0) {
349                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
350                             "GnuTLS: Error Exporting a PKCS #11 object: "
351                             "'%s': %s",
352                             file, gnutls_strerror(ret));
353                ret = -1;
354                goto cleanup;
355            }
356
357            gnutls_pkcs11_obj_deinit(obj);
358        } else {
359            file = ap_server_root_relative(spool, sc->x509_cert_file);
360
361            ret = gnutls_load_file(file, &data);
362            if (ret < 0) {
363                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
364                             "GnuTLS: Error Reading Certificate '%s': %s",
365                             file, gnutls_strerror(ret));
366                ret = -1;
367                goto cleanup;
368            }
369        }
370
371        ret = gnutls_x509_crt_list_import(sc->certs_x509_crt_chain,
372                                          &chain_num, &data, format,
373                                          GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
374        gnutls_free(data.data);
375        sc->certs_x509_chain_num = chain_num;
376
377        if (ret < 0) {
378            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
379                         "GnuTLS: Failed to Import Certificate Chain "
380                         "'%s': (%d) %s",
381                         file, ret, gnutls_strerror(ret));
382            ret = -1;
383            goto cleanup;
384        }
385
386        for (unsigned int i = 0; i < chain_num; i++)
387        {
388            ret =
389                gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
390                                         sc->certs_x509_crt_chain[i], 0);
391            if (ret < 0) {
392                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
393                             "GnuTLS: Failed to Import pCertificate "
394                             "'%s': (%d) %s",
395                             file, ret, gnutls_strerror(ret));
396                ret = -1;
397                goto cleanup;
398            }
399        }
400        sc->certs_x509_chain_num = chain_num;
401    }
402
403    if (sc->x509_key_file && sc->privkey_x509 == NULL)
404    {
405        ret = gnutls_privkey_init(&sc->privkey_x509);
406        if (ret < 0) {
407            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
408                         "GnuTLS: Failed to initialize: (%d) %s", ret,
409                         gnutls_strerror(ret));
410            ret = -1;
411            goto cleanup;
412        }
413
414        if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
415            file = sc->x509_key_file;
416
417            gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
418                                            sc);
419
420            ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
421
422            if (ret < 0) {
423                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
424                             "GnuTLS: Failed to Import Private Key URL "
425                             "'%s': (%d) %s",
426                             file, ret, gnutls_strerror(ret));
427                ret = -1;
428                goto cleanup;
429            }
430        } else {
431            file = ap_server_root_relative(spool, sc->x509_key_file);
432
433            if (load_datum_from_file(spool, file, &data) != 0) {
434                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
435                             "GnuTLS: Error Reading Private Key '%s'",
436                             file);
437                ret = -1;
438                goto cleanup;
439            }
440
441            ret =
442                gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
443                                               GNUTLS_X509_FMT_PEM, sc->pin,
444                                               0);
445
446            if (ret < 0) {
447                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
448                             "GnuTLS: Failed to Import Private Key "
449                             "'%s': (%d) %s",
450                             file, ret, gnutls_strerror(ret));
451                ret = -1;
452                goto cleanup;
453            }
454        }
455    }
456
457    /* Load the X.509 CA file */
458    if (sc->x509_ca_file)
459    {
460        if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
461            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
462                         "GnuTLS: Error Reading " "Client CA File '%s'",
463                         sc->x509_ca_file);
464            ret = -1;
465            goto cleanup;
466        }
467
468        ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
469                                           &data, GNUTLS_X509_FMT_PEM, 0);
470        if (ret < 0) {
471            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
472                         "GnuTLS: Failed to load "
473                         "Client CA File '%s': (%d) %s", sc->x509_ca_file,
474                         ret, gnutls_strerror(ret));
475            ret = -1;
476            goto cleanup;
477        }
478    }
479
480    if (sc->pgp_cert_file && sc->cert_pgp == NULL)
481    {
482        sc->cert_pgp = apr_pcalloc(pconf, sizeof(sc->cert_pgp[0]));
483        sc->cert_crt_pgp = apr_pcalloc(pconf, sizeof(sc->cert_crt_pgp[0]));
484
485        if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
486            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
487                         "GnuTLS: Error Reading " "Certificate '%s'",
488                         sc->pgp_cert_file);
489            ret = -1;
490            goto cleanup;
491        }
492
493        ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
494        if (ret < 0) {
495            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
496                         "GnuTLS: Failed to Init "
497                         "PGP Certificate: (%d) %s", ret,
498                         gnutls_strerror(ret));
499            ret = -1;
500            goto cleanup;
501        }
502
503        ret = gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
504                                        GNUTLS_OPENPGP_FMT_BASE64);
505        if (ret < 0) {
506            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
507                         "GnuTLS: Failed to Import "
508                         "PGP Certificate: (%d) %s", ret,
509                         gnutls_strerror(ret));
510            ret = -1;
511            goto cleanup;
512        }
513
514        ret = gnutls_pcert_import_openpgp(sc->cert_pgp,
515                                          sc->cert_crt_pgp[0], 0);
516        if (ret < 0) {
517            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
518                         "GnuTLS: Failed to Import "
519                         "PGP pCertificate: (%d) %s", ret,
520                         gnutls_strerror(ret));
521            ret = -1;
522            goto cleanup;
523        }
524    }
525
526    /* Load the PGP key file */
527    if (sc->pgp_key_file && sc->privkey_pgp == NULL)
528    {
529        if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
530            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
531                         "GnuTLS: Error Reading " "Private Key '%s'",
532                         sc->pgp_key_file);
533            ret = -1;
534            goto cleanup;
535        }
536
537        ret = gnutls_privkey_init(&sc->privkey_pgp);
538        if (ret < 0) {
539            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
540                         "GnuTLS: Failed to initialize"
541                         ": (%d) %s", ret, gnutls_strerror(ret));
542            ret = -1;
543            goto cleanup;
544        }
545
546#if GNUTLS_VERSION_NUMBER < 0x030312
547        /* GnuTLS versions before 3.3.12 contain a bug in
548         * gnutls_privkey_import_openpgp_raw which frees data that is
549         * accessed when the key is used, leading to segfault. Loading
550         * the key into a gnutls_openpgp_privkey_t and then assigning
551         * it to the gnutls_privkey_t works around the bug, hence this
552         * chain of gnutls_openpgp_privkey_init,
553         * gnutls_openpgp_privkey_import and
554         * gnutls_privkey_import_openpgp. */
555        ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal);
556        if (ret != 0) {
557            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
558                         "GnuTLS: Failed to initialize "
559                         "PGP Private Key '%s': (%d) %s",
560                         sc->pgp_key_file, ret, gnutls_strerror(ret));
561            ret = -1;
562            goto cleanup;
563        }
564
565        ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data,
566                                            GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
567        if (ret != 0) {
568            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
569                         "GnuTLS: Failed to Import "
570                         "PGP Private Key '%s': (%d) %s",
571                         sc->pgp_key_file, ret, gnutls_strerror(ret));
572            ret = -1;
573            goto cleanup;
574        }
575
576        ret = gnutls_privkey_import_openpgp(sc->privkey_pgp,
577                                            sc->privkey_pgp_internal, 0);
578        if (ret != 0)
579        {
580            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
581                         "GnuTLS: Failed to assign PGP Private Key '%s' "
582                         "to gnutls_privkey_t structure: (%d) %s",
583                         sc->pgp_key_file, ret, gnutls_strerror(ret));
584            ret = -1;
585            goto cleanup;
586        }
587#else
588        ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
589                                                GNUTLS_OPENPGP_FMT_BASE64,
590                                                NULL, NULL);
591        if (ret != 0)
592        {
593            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
594                         "GnuTLS: Failed to Import "
595                         "PGP Private Key '%s': (%d) %s",
596                         sc->pgp_key_file, ret, gnutls_strerror(ret));
597            ret = -1;
598            goto cleanup;
599        }
600#endif
601    }
602
603    /* Load the keyring file */
604    if (sc->pgp_ring_file && sc->pgp_list == NULL)
605    {
606        if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
607            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
608                         "GnuTLS: Error Reading " "Keyring File '%s'",
609                         sc->pgp_ring_file);
610            ret = -1;
611            goto cleanup;
612        }
613
614        ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
615        if (ret < 0) {
616            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
617                         "GnuTLS: Failed to initialize"
618                         "keyring: (%d) %s", ret, gnutls_strerror(ret));
619            ret = -1;
620            goto cleanup;
621        }
622
623        ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
624                                            GNUTLS_OPENPGP_FMT_BASE64);
625        if (ret < 0) {
626            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
627                         "GnuTLS: Failed to load "
628                         "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
629                         ret, gnutls_strerror(ret));
630            ret = -1;
631            goto cleanup;
632        }
633    }
634
635    if (sc->priorities_str && sc->priorities == NULL)
636    {
637        const char *err;
638        ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err);
639
640        if (ret < 0) {
641            if (ret == GNUTLS_E_INVALID_REQUEST) {
642                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
643                             "GnuTLS: Syntax error parsing priorities string at: %s",
644                             err);
645            } else {
646                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
647                             "GnuTLS: error parsing priorities string");
648
649            }
650            ret = -1;
651            goto cleanup;
652        }
653    }
654
655    ret = 0;
656 cleanup:
657    apr_pool_destroy(spool);
658
659    return ret;
660}
661
662int mgs_pkcs11_reinit(server_rec * base_server)
663{
664    int ret;
665    server_rec *s;
666    mgs_srvconf_rec *sc;
667
668    gnutls_pkcs11_reinit();
669
670    for (s = base_server; s; s = s->next) {
671        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
672
673            /* gnutls caches the session in a private key, so we need to open
674             * a new one */
675            if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) {
676                gnutls_privkey_deinit(sc->privkey_x509);
677
678                ret = gnutls_privkey_init(&sc->privkey_x509);
679                if (ret < 0) {
680                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
681                                 "GnuTLS: Failed to initialize: (%d) %s", ret,
682                                 gnutls_strerror(ret));
683                    goto fail;
684                }
685
686                gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc);
687
688                ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0);
689                if (ret < 0) {
690                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
691                             "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s",
692                             sc->x509_key_file, ret, gnutls_strerror(ret));
693                    goto fail;
694                }
695            }
696    }
697
698    return 0;
699
700 fail:
701    gnutls_privkey_deinit(sc->privkey_x509);
702    return -1;
703}
704
705const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)),
706        const char *arg) {
707    mgs_srvconf_rec *sc =
708        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
709                                                 module_config,
710                                                 &gnutls_module);
711
712    sc->dh_file = ap_server_root_relative(parms->pool, arg);
713
714    return NULL;
715}
716
717const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
718
719    mgs_srvconf_rec *sc =
720        (mgs_srvconf_rec *) ap_get_module_config(parms->
721                                                 server->module_config,
722                                                 &gnutls_module);
723
724    sc->x509_cert_file = apr_pstrdup(parms->pool, arg);
725
726    return NULL;
727
728}
729
730const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
731
732    mgs_srvconf_rec *sc =
733        (mgs_srvconf_rec *) ap_get_module_config(parms->
734                                                 server->module_config,
735                                                 &gnutls_module);
736
737    sc->x509_key_file = apr_pstrdup(parms->pool, arg);
738
739    return NULL;
740}
741
742const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)),
743        const char *arg)
744{
745    mgs_srvconf_rec *sc =
746        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
747                                                 module_config,
748                                                 &gnutls_module);
749
750    sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg);
751
752    return NULL;
753}
754
755const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)),
756        const char *arg) {
757    mgs_srvconf_rec *sc =
758        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
759                                                 module_config,
760                                                 &gnutls_module);
761
762    sc->pgp_key_file = ap_server_root_relative(parms->pool, arg);
763
764    return NULL;
765}
766
767const char *mgs_set_tickets(cmd_parms *parms,
768                            void *dummy __attribute__((unused)),
769                            const int arg)
770{
771    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
772        ap_get_module_config(parms->server->module_config, &gnutls_module);
773
774    if (arg)
775        sc->tickets = GNUTLS_ENABLED_TRUE;
776    else
777        sc->tickets = GNUTLS_ENABLED_FALSE;
778
779    return NULL;
780}
781
782
783#ifdef ENABLE_SRP
784
785const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy __attribute__((unused)),
786        const char *arg) {
787    mgs_srvconf_rec *sc =
788        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
789                                                 module_config,
790                                                 &gnutls_module);
791
792    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
793
794    return NULL;
795}
796
797const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy __attribute__((unused)),
798        const char *arg) {
799    mgs_srvconf_rec *sc =
800        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
801                                                 module_config,
802                                                 &gnutls_module);
803
804    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
805
806    return NULL;
807}
808
809#endif
810
811const char *mgs_set_cache(cmd_parms * parms, void *dummy __attribute__((unused)),
812        const char *type, const char *arg) {
813    const char *err;
814    mgs_srvconf_rec *sc =
815        ap_get_module_config(parms->server->module_config,
816                             &gnutls_module);
817    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
818        return err;
819    }
820
821    if (strcasecmp("none", type) == 0) {
822        sc->cache_type = mgs_cache_none;
823        sc->cache_config = NULL;
824        return NULL;
825    } else if (strcasecmp("dbm", type) == 0) {
826        sc->cache_type = mgs_cache_dbm;
827    } else if (strcasecmp("gdbm", type) == 0) {
828        sc->cache_type = mgs_cache_gdbm;
829    }
830#if HAVE_APR_MEMCACHE
831    else if (strcasecmp("memcache", type) == 0) {
832        sc->cache_type = mgs_cache_memcache;
833    }
834#endif
835    else {
836        return "Invalid Type for GnuTLSCache!";
837    }
838
839    if (arg == NULL)
840        return "Invalid argument 2 for GnuTLSCache!";
841
842    if (sc->cache_type == mgs_cache_dbm
843        || sc->cache_type == mgs_cache_gdbm) {
844        sc->cache_config = ap_server_root_relative(parms->pool, arg);
845    } else {
846        sc->cache_config = apr_pstrdup(parms->pool, arg);
847    }
848
849    return NULL;
850}
851
852const char *mgs_set_timeout(cmd_parms * parms,
853                            void *dummy __attribute__((unused)),
854                            const char *arg)
855{
856    apr_int64_t argint = apr_atoi64(arg);
857    if (argint < 0)
858        return apr_psprintf(parms->pool, "%s: Invalid argument",
859                            parms->directive->directive);
860
861    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
862        ap_get_module_config(parms->server->module_config, &gnutls_module);
863
864    if (!apr_strnatcasecmp(parms->directive->directive, "GnuTLSCacheTimeout"))
865    {
866        const char *err;
867        if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY)))
868            return err;
869        sc->cache_timeout = apr_time_from_sec(argint);
870    }
871    else if (!apr_strnatcasecmp(parms->directive->directive,
872                                "GnuTLSOCSPGraceTime"))
873        sc->ocsp_grace_time = apr_time_from_sec(argint);
874    else if (!apr_strnatcasecmp(parms->directive->directive,
875                                "GnuTLSOCSPFailureTimeout"))
876        sc->ocsp_failure_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_FAILURE_TIMEOUT);
1131
1132/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
1133    sc->client_verify_mode = -1;
1134
1135    return sc;
1136}
1137
1138void *mgs_config_server_create(apr_pool_t * p,
1139                               server_rec * s __attribute__((unused))) {
1140    char *err = NULL;
1141    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
1142    if (sc)
1143        return sc;
1144    else
1145        return err;
1146}
1147
1148#define gnutls_srvconf_merge(t, unset) sc->t = (add->t == unset) ? base->t : add->t
1149#define gnutls_srvconf_assign(t) sc->t = add->t
1150
1151void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD)
1152{
1153    int i;
1154    char *err = NULL;
1155    mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;
1156    mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;
1157    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
1158    if (NULL == sc)
1159        return err;
1160
1161    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
1162    gnutls_srvconf_merge(tickets, GNUTLS_ENABLED_UNSET);
1163    gnutls_srvconf_merge(proxy_enabled, GNUTLS_ENABLED_UNSET);
1164    gnutls_srvconf_merge(export_certificates_size, -1);
1165    gnutls_srvconf_merge(client_verify_method, mgs_cvm_unset);
1166    gnutls_srvconf_merge(client_verify_mode, -1);
1167    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
1168    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
1169    gnutls_srvconf_merge(x509_cert_file, NULL);
1170
1171    gnutls_srvconf_merge(x509_key_file, NULL);
1172    gnutls_srvconf_merge(x509_ca_file, NULL);
1173    gnutls_srvconf_merge(p11_modules, NULL);
1174    gnutls_srvconf_merge(pin, NULL);
1175    gnutls_srvconf_merge(pgp_cert_file, NULL);
1176    gnutls_srvconf_merge(pgp_key_file, NULL);
1177    gnutls_srvconf_merge(pgp_ring_file, NULL);
1178    gnutls_srvconf_merge(dh_file, NULL);
1179    gnutls_srvconf_merge(priorities_str, NULL);
1180
1181    gnutls_srvconf_merge(proxy_x509_key_file, NULL);
1182    gnutls_srvconf_merge(proxy_x509_cert_file, NULL);
1183    gnutls_srvconf_merge(proxy_x509_ca_file, NULL);
1184    gnutls_srvconf_merge(proxy_x509_crl_file, NULL);
1185    gnutls_srvconf_merge(proxy_priorities_str, NULL);
1186    gnutls_srvconf_merge(proxy_priorities, NULL);
1187
1188    gnutls_srvconf_merge(ocsp_staple, GNUTLS_ENABLED_UNSET);
1189    gnutls_srvconf_assign(ocsp_response_file);
1190    gnutls_srvconf_merge(ocsp_grace_time, apr_time_from_sec(MGS_GRACE_TIME));
1191    gnutls_srvconf_merge(ocsp_failure_timeout,
1192                         apr_time_from_sec(MGS_FAILURE_TIMEOUT));
1193
1194    gnutls_srvconf_assign(ca_list);
1195    gnutls_srvconf_assign(ca_list_size);
1196    gnutls_srvconf_assign(cert_pgp);
1197    gnutls_srvconf_assign(cert_crt_pgp);
1198    gnutls_srvconf_assign(pgp_list);
1199    gnutls_srvconf_assign(certs);
1200    gnutls_srvconf_assign(anon_creds);
1201    gnutls_srvconf_assign(srp_creds);
1202    gnutls_srvconf_assign(certs_x509_chain);
1203    gnutls_srvconf_assign(certs_x509_crt_chain);
1204    gnutls_srvconf_assign(certs_x509_chain_num);
1205
1206    /* how do these get transferred cleanly before the data from ADD
1207     * goes away? */
1208    gnutls_srvconf_assign(cert_cn);
1209    for (i = 0; i < MAX_CERT_SAN; i++)
1210        gnutls_srvconf_assign(cert_san[i]);
1211
1212    return sc;
1213}
1214
1215#undef gnutls_srvconf_merge
1216#undef gnutls_srvconf_assign
1217
1218void *mgs_config_dir_merge(apr_pool_t * p,
1219                           void *basev __attribute__((unused)),
1220                           void *addv __attribute__((unused))) {
1221    mgs_dirconf_rec *new;
1222    /*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
1223    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
1224
1225    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
1226    new->client_verify_mode = add->client_verify_mode;
1227    return new;
1228}
1229
1230void *mgs_config_dir_create(apr_pool_t * p,
1231                            char *dir __attribute__((unused))) {
1232    mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc));
1233    dc->client_verify_mode = -1;
1234    return dc;
1235}
1236
1237
1238
1239/*
1240 * Store paths to proxy credentials
1241 *
1242 * This function copies the paths provided in the configuration file
1243 * into the server configuration. The post configuration hook takes
1244 * care of actually loading the credentials, which means than invalid
1245 * paths or the like will be detected there.
1246 */
1247const char *mgs_store_cred_path(cmd_parms * parms,
1248                                void *dummy __attribute__((unused)),
1249                                const char *arg)
1250{
1251    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1252        ap_get_module_config(parms->server->module_config, &gnutls_module);
1253
1254    /* parms->directive->directive contains the directive string */
1255    if (!strcasecmp(parms->directive->directive, "GnuTLSProxyKeyFile"))
1256        sc->proxy_x509_key_file = apr_pstrdup(parms->pool, arg);
1257    else if (!strcasecmp(parms->directive->directive,
1258                         "GnuTLSProxyCertificateFile"))
1259        sc->proxy_x509_cert_file = apr_pstrdup(parms->pool, arg);
1260    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCAFile"))
1261        sc->proxy_x509_ca_file = apr_pstrdup(parms->pool, arg);
1262    else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCRLFile"))
1263        sc->proxy_x509_crl_file = apr_pstrdup(parms->pool, arg);
1264    return NULL;
1265}
1266
1267
1268
1269/*
1270 * Record PKCS #11 module to load. Note that the value is only used in
1271 * the base config, settings in virtual hosts are ignored.
1272 */
1273const char *mgs_set_p11_module(cmd_parms * parms,
1274                               void *dummy __attribute__((unused)),
1275                               const char *arg)
1276{
1277    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
1278        ap_get_module_config(parms->server->module_config, &gnutls_module);
1279    /* initialize PKCS #11 module list if necessary */
1280    if (sc->p11_modules == NULL)
1281        sc->p11_modules = apr_array_make(parms->pool, 2, sizeof(char*));
1282
1283    *(char **) apr_array_push(sc->p11_modules) = apr_pstrdup(parms->pool, arg);
1284
1285    return NULL;
1286}
Note: See TracBrowser for help on using the repository browser.