source: mod_gnutls/src/gnutls_config.c @ 1d9cfaf

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

gnutls_config.c: Backport function signature changes from master

Commit fd82e591c4be610b1c6f3a6fd861c4199aaa6066 on master changed
various function signatures to explicitly mark unused parameters.
Backport this and one parameter rename to avoid merge conflicts.

Note that this does not avoid all merge conflicts, it merely helps
focusing on the functional ones. At the time of this commit, master was
at commit c32240fe453de3ce9c48887f2ecd649a5555340f.

  • Property mode set to 100644
File size: 27.1 KB
Line 
1/**
2 *  Copyright 2004-2005 Paul Querna
3 *  Copyright 2008 Nikos Mavrogiannopoulos
4 *  Copyright 2011 Dash Shendy
5 *
6 *  Licensed under the Apache License, Version 2.0 (the "License");
7 *  you may not use this file except in compliance with the License.
8 *  You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *  Unless required by applicable law or agreed to in writing, software
13 *  distributed under the License is distributed on an "AS IS" BASIS,
14 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 *  See the License for the specific language governing permissions and
16 *  limitations under the License.
17 *
18 */
19
20#include "mod_gnutls.h"
21#include "apr_lib.h"
22#include <gnutls/abstract.h>
23
24#define INIT_CA_SIZE 128
25
26#ifdef APLOG_USE_MODULE
27APLOG_USE_MODULE(gnutls);
28#endif
29
30static int pin_callback(void *user, int attempt, const char *token_url,
31                        const char *token_label, unsigned int flags,
32                        char *pin, size_t pin_max)
33{
34    mgs_srvconf_rec *sc = user;
35
36    if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY ||
37        flags & GNUTLS_PIN_WRONG) {
38        return -1;
39    }
40
41    if (token_label && strcmp(token_label, "SRK") == 0) {
42         snprintf(pin, pin_max, "%s", sc->srk_pin);
43    } else {
44         snprintf(pin, pin_max, "%s", sc->pin);
45    }
46    return 0;
47}
48
49static int load_datum_from_file(apr_pool_t * pool,
50                                const char *file, gnutls_datum_t * data)
51{
52    apr_file_t *fp;
53    apr_finfo_t finfo;
54    apr_status_t rv;
55    apr_size_t br = 0;
56
57    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
58                       APR_OS_DEFAULT, pool);
59    if (rv != APR_SUCCESS) {
60        return rv;
61    }
62
63    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
64
65    if (rv != APR_SUCCESS) {
66        return rv;
67    }
68
69    data->data = apr_palloc(pool, finfo.size + 1);
70    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
71
72    if (rv != APR_SUCCESS) {
73        return rv;
74    }
75    apr_file_close(fp);
76
77    data->data[br] = '\0';
78    data->size = br;
79
80    return 0;
81}
82
83/* 2048-bit group parameters from SRP specification */
84const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
85        "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
86        "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
87        "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
88        "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
89        "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
90        "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
91        "-----END DH PARAMETERS-----\n";
92
93int mgs_load_files(apr_pool_t * p, server_rec * s)
94{
95    apr_pool_t *spool;
96    const char *file;
97    gnutls_datum_t data;
98    int ret;
99    mgs_srvconf_rec *sc =
100        (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
101                                                 &gnutls_module);
102
103    apr_pool_create(&spool, p);
104
105    sc->cert_pgp = apr_pcalloc(p, sizeof(sc->cert_pgp[0]));
106    sc->cert_crt_pgp = apr_pcalloc(p, sizeof(sc->cert_crt_pgp[0]));
107    sc->certs_x509_chain =
108        apr_pcalloc(p, MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
109    sc->certs_x509_crt_chain =
110        apr_pcalloc(p,
111                    MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
112
113    ret = gnutls_certificate_allocate_credentials(&sc->certs);
114    if (ret < 0) {
115        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
116                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
117                     gnutls_strerror(ret));
118        ret = -1;
119        goto cleanup;
120    }
121
122    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
123    if (ret < 0) {
124        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
125                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
126                     gnutls_strerror(ret));
127        ret = -1;
128        goto cleanup;
129    }
130
131    /* Load SRP parameters */
132#ifdef ENABLE_SRP
133    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
134    if (ret < 0) {
135        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
136                     "GnuTLS: Failed to initialize" ": (%d) %s", ret,
137                     gnutls_strerror(ret));
138        ret = -1;
139        goto cleanup;
140    }
141
142    if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) {
143        ret = gnutls_srp_set_server_credentials_file
144            (sc->srp_creds, sc->srp_tpasswd_file,
145             sc->srp_tpasswd_conf_file);
146
147        if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
148            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
149                         s,
150                         "GnuTLS: Host '%s:%d' is missing a "
151                         "SRP password or conf File!",
152                         s->server_hostname, s->port);
153            ret = -1;
154            goto cleanup;
155        }
156    }
157#endif
158
159    ret = gnutls_dh_params_init(&sc->dh_params);
160    if (ret < 0) {
161            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
162                         "GnuTLS: Failed to initialize"
163                         ": (%d) %s", ret, gnutls_strerror(ret));
164            ret = -1;
165            goto cleanup;
166    }
167
168    /* Load DH parameters */
169    if (sc->dh_file) {
170        if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
171            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
172                         "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
173            ret = -1;
174            goto cleanup;
175        }
176
177
178        ret =
179            gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
180                                          GNUTLS_X509_FMT_PEM);
181        if (ret < 0) {
182            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
183                         "GnuTLS: Failed to Import "
184                         "DH params '%s': (%d) %s", sc->dh_file, ret,
185                         gnutls_strerror(ret));
186            ret = -1;
187            goto cleanup;
188        }
189    } else {
190        gnutls_datum_t pdata = {
191            (void *) static_dh_params,
192            sizeof(static_dh_params)
193        };
194
195        ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
196        if (ret < 0) {
197            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
198                    "GnuTLS: Unable to generate or load DH Params: (%d) %s",
199                    ret, gnutls_strerror(ret));
200            ret = -1;
201            goto cleanup;
202        }
203    }
204
205    if (sc->x509_cert_file != NULL) {
206        unsigned int chain_num, i;
207        unsigned format = GNUTLS_X509_FMT_PEM;
208
209        /* Load X.509 certificate */
210        if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
211            gnutls_pkcs11_obj_t obj;
212
213            file = sc->x509_cert_file;
214
215            ret = gnutls_pkcs11_obj_init(&obj);
216            if (ret < 0) {
217                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
218                             "GnuTLS: Error Initializing PKCS #11 object");
219                ret = -1;
220                goto cleanup;
221            }
222
223            gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
224
225            ret = gnutls_pkcs11_obj_import_url(obj, file, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
226            if (ret < 0) {
227                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
228                             "GnuTLS: Error Importing PKCS #11 object: '%s': %s",
229                             file, gnutls_strerror(ret));
230                ret = -1;
231                goto cleanup;
232            }
233
234            format = GNUTLS_X509_FMT_DER;
235            ret = gnutls_pkcs11_obj_export2(obj, &data);
236            if (ret < 0) {
237                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
238                             "GnuTLS: Error Exporting a PKCS #11 object: '%s': %s",
239                             file, gnutls_strerror(ret));
240                ret = -1;
241                goto cleanup;
242            }
243
244            gnutls_pkcs11_obj_deinit(obj);
245        } else {
246            file = ap_server_root_relative(spool, sc->x509_cert_file);
247
248            ret = gnutls_load_file(file, &data);
249            if (ret < 0) {
250                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
251                             "GnuTLS: Error Reading Certificate '%s': %s",
252                             file, gnutls_strerror(ret));
253                ret = -1;
254                goto cleanup;
255            }
256        }
257
258        ret =
259            gnutls_x509_crt_list_import2(&sc->certs_x509_crt_chain,
260                                        &chain_num, &data, format,
261                                        GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
262        gnutls_free(data.data);
263        sc->certs_x509_chain_num = chain_num;
264
265        if (ret < 0) {
266            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
267                         "GnuTLS: Failed to Import Certificate Chain '%s': (%d) %s",
268                         file, ret, gnutls_strerror(ret));
269            ret = -1;
270            goto cleanup;
271        }
272
273        for (i = 0; i < chain_num; i++) {
274            ret =
275                gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
276                                         sc->certs_x509_crt_chain[i], 0);
277            if (ret < 0) {
278                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
279                             "GnuTLS: Failed to Import pCertificate '%s': (%d) %s",
280                             file, ret, gnutls_strerror(ret));
281                ret = -1;
282                goto cleanup;
283            }
284        }
285        sc->certs_x509_chain_num = chain_num;
286    }
287
288    if (sc->x509_key_file) {
289        ret = gnutls_privkey_init(&sc->privkey_x509);
290        if (ret < 0) {
291            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
292                         "GnuTLS: Failed to initialize: (%d) %s", ret,
293                         gnutls_strerror(ret));
294            ret = -1;
295            goto cleanup;
296        }
297
298        if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
299            file = sc->x509_key_file;
300
301            gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
302                                            sc);
303
304            ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
305
306            if (ret < 0) {
307                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
308                             "GnuTLS: Failed to Import Private Key URL '%s': (%d) %s",
309                             file, ret, gnutls_strerror(ret));
310                ret = -1;
311                goto cleanup;
312            }
313        } else {
314            file = ap_server_root_relative(spool, sc->x509_key_file);
315
316            if (load_datum_from_file(spool, file, &data) != 0) {
317                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
318                             "GnuTLS: Error Reading Private Key '%s'",
319                             file);
320                ret = -1;
321                goto cleanup;
322            }
323
324            ret =
325                gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
326                                               GNUTLS_X509_FMT_PEM, sc->pin,
327                                               0);
328
329            if (ret < 0) {
330                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
331                             "GnuTLS: Failed to Import Private Key '%s': (%d) %s",
332                             file, ret, gnutls_strerror(ret));
333                ret = -1;
334                goto cleanup;
335            }
336        }
337    }
338
339    /* Load the X.509 CA file */
340    if (sc->x509_ca_file) {
341        if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
342            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
343                         "GnuTLS: Error Reading " "Client CA File '%s'",
344                         sc->x509_ca_file);
345            ret = -1;
346            goto cleanup;
347        }
348
349        ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
350                                         &data, GNUTLS_X509_FMT_PEM, 0);
351        if (ret < 0) {
352            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
353                         "GnuTLS: Failed to load "
354                         "Client CA File '%s': (%d) %s", sc->x509_ca_file,
355                         ret, gnutls_strerror(ret));
356            ret = -1;
357            goto cleanup;
358        }
359    }
360
361    if (sc->pgp_cert_file) {
362        if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
363            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
364                         "GnuTLS: Error Reading " "Certificate '%s'",
365                         sc->pgp_cert_file);
366            ret = -1;
367            goto cleanup;
368        }
369
370        ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
371        if (ret < 0) {
372            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
373                         "GnuTLS: Failed to Init "
374                         "PGP Certificate: (%d) %s", ret,
375                         gnutls_strerror(ret));
376            ret = -1;
377            goto cleanup;
378        }
379
380        ret =
381            gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
382                                      GNUTLS_OPENPGP_FMT_BASE64);
383        if (ret < 0) {
384            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
385                         "GnuTLS: Failed to Import "
386                         "PGP Certificate: (%d) %s", ret,
387                         gnutls_strerror(ret));
388            ret = -1;
389            goto cleanup;
390        }
391
392        ret =
393            gnutls_pcert_import_openpgp(sc->cert_pgp, sc->cert_crt_pgp[0],
394                                        0);
395        if (ret < 0) {
396            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
397                         "GnuTLS: Failed to Import "
398                         "PGP pCertificate: (%d) %s", ret,
399                         gnutls_strerror(ret));
400            ret = -1;
401            goto cleanup;
402        }
403    }
404
405    /* Load the PGP key file */
406    if (sc->pgp_key_file) {
407        if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
408            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
409                         "GnuTLS: Error Reading " "Private Key '%s'",
410                         sc->pgp_key_file);
411            ret = -1;
412            goto cleanup;
413        }
414
415        ret = gnutls_privkey_init(&sc->privkey_pgp);
416        if (ret < 0) {
417            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
418                         "GnuTLS: Failed to initialize"
419                         ": (%d) %s", ret, gnutls_strerror(ret));
420            ret = -1;
421            goto cleanup;
422        }
423
424        ret =
425            gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
426                                              GNUTLS_OPENPGP_FMT_BASE64,
427                                              NULL, NULL);
428        if (ret != 0) {
429            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
430                         "GnuTLS: Failed to Import "
431                         "PGP Private Key '%s': (%d) %s",
432                         sc->pgp_key_file, ret, gnutls_strerror(ret));
433            ret = -1;
434            goto cleanup;
435        }
436    }
437
438    /* Load the keyring file */
439    if (sc->pgp_ring_file) {
440        if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
441            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
442                         "GnuTLS: Error Reading " "Keyring File '%s'",
443                         sc->pgp_ring_file);
444            ret = -1;
445            goto cleanup;
446        }
447
448        ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
449        if (ret < 0) {
450            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
451                         "GnuTLS: Failed to initialize"
452                         "keyring: (%d) %s", ret, gnutls_strerror(ret));
453            ret = -1;
454            goto cleanup;
455        }
456
457        ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
458                                           GNUTLS_OPENPGP_FMT_BASE64);
459        if (ret < 0) {
460            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
461                         "GnuTLS: Failed to load "
462                         "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
463                         ret, gnutls_strerror(ret));
464            ret = -1;
465            goto cleanup;
466        }
467    }
468
469    if (sc->priorities_str) {
470        const char *err;
471        ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err);
472
473        if (ret < 0) {
474            if (ret == GNUTLS_E_INVALID_REQUEST) {
475                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
476                             "GnuTLS: Syntax error parsing priorities string at: %s",
477                             err);
478            } else {
479                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
480                             "GnuTLS: error parsing priorities string");
481
482            }
483            ret = -1;
484            goto cleanup;
485        }
486    }
487
488    ret = 0;
489  cleanup:
490    apr_pool_destroy(spool);
491
492    return ret;
493}
494
495int mgs_pkcs11_reinit(server_rec * base_server)
496{
497    int ret;
498    server_rec *s;
499    mgs_srvconf_rec *sc;
500
501    gnutls_pkcs11_reinit();
502
503    for (s = base_server; s; s = s->next) {
504        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
505
506            /* gnutls caches the session in a private key, so we need to open
507             * a new one */
508            if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) {
509                gnutls_privkey_deinit(sc->privkey_x509);
510
511                ret = gnutls_privkey_init(&sc->privkey_x509);
512                if (ret < 0) {
513                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
514                                 "GnuTLS: Failed to initialize: (%d) %s", ret,
515                                 gnutls_strerror(ret));
516                    goto fail;
517                }
518
519                gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc);
520
521                ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0);
522                if (ret < 0) {
523                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
524                             "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s",
525                             sc->x509_key_file, ret, gnutls_strerror(ret));
526                    goto fail;
527                }
528            }
529    }
530
531    return 0;
532
533 fail:
534    gnutls_privkey_deinit(sc->privkey_x509);
535    return -1;
536}
537
538const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)),
539        const char *arg) {
540    mgs_srvconf_rec *sc =
541        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
542                                                 module_config,
543                                                 &gnutls_module);
544
545    sc->dh_file = ap_server_root_relative(parms->pool, arg);
546
547    return NULL;
548}
549
550const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
551
552    mgs_srvconf_rec *sc =
553        (mgs_srvconf_rec *) ap_get_module_config(parms->
554                                                 server->module_config,
555                                                 &gnutls_module);
556
557    sc->x509_cert_file = apr_pstrdup(parms->pool, arg);
558
559    return NULL;
560
561}
562
563const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
564
565    mgs_srvconf_rec *sc =
566        (mgs_srvconf_rec *) ap_get_module_config(parms->
567                                                 server->module_config,
568                                                 &gnutls_module);
569
570    sc->x509_key_file = apr_pstrdup(parms->pool, arg);
571
572    return NULL;
573}
574
575const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)),
576        const char *arg) {
577    mgs_srvconf_rec *sc =
578        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
579                                                 module_config,
580                                                 &gnutls_module);
581
582    sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg);
583
584    return NULL;
585}
586
587const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)),
588        const char *arg) {
589    mgs_srvconf_rec *sc =
590        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
591                                                 module_config,
592                                                 &gnutls_module);
593
594    sc->pgp_key_file = ap_server_root_relative(parms->pool, arg);
595
596    return NULL;
597}
598
599const char *mgs_set_tickets(cmd_parms * parms, void *dummy __attribute__((unused)),
600        const char *arg) {
601    mgs_srvconf_rec *sc =
602        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
603                                                 module_config,
604                                                 &gnutls_module);
605
606    sc->tickets = 0;
607    if (strcasecmp("on", arg) == 0) {
608        sc->tickets = 1;
609    }
610
611    return NULL;
612}
613
614
615#ifdef ENABLE_SRP
616
617const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy __attribute__((unused)),
618        const char *arg) {
619    mgs_srvconf_rec *sc =
620        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
621                                                 module_config,
622                                                 &gnutls_module);
623
624    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
625
626    return NULL;
627}
628
629const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy __attribute__((unused)),
630        const char *arg) {
631    mgs_srvconf_rec *sc =
632        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
633                                                 module_config,
634                                                 &gnutls_module);
635
636    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
637
638    return NULL;
639}
640
641#endif
642
643const char *mgs_set_cache(cmd_parms * parms, void *dummy __attribute__((unused)),
644        const char *type, const char *arg) {
645    const char *err;
646    mgs_srvconf_rec *sc =
647        ap_get_module_config(parms->server->module_config,
648                             &gnutls_module);
649    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
650        return err;
651    }
652
653    if (strcasecmp("none", type) == 0) {
654        sc->cache_type = mgs_cache_none;
655        sc->cache_config = NULL;
656        return NULL;
657    } else if (strcasecmp("dbm", type) == 0) {
658        sc->cache_type = mgs_cache_dbm;
659    } else if (strcasecmp("gdbm", type) == 0) {
660        sc->cache_type = mgs_cache_gdbm;
661    }
662#if HAVE_APR_MEMCACHE
663    else if (strcasecmp("memcache", type) == 0) {
664        sc->cache_type = mgs_cache_memcache;
665    }
666#endif
667    else {
668        return "Invalid Type for GnuTLSCache!";
669    }
670
671    if (arg == NULL)
672        return "Invalid argument 2 for GnuTLSCache!";
673
674    if (sc->cache_type == mgs_cache_dbm
675        || sc->cache_type == mgs_cache_gdbm) {
676        sc->cache_config = ap_server_root_relative(parms->pool, arg);
677    } else {
678        sc->cache_config = apr_pstrdup(parms->pool, arg);
679    }
680
681    return NULL;
682}
683
684const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy __attribute__((unused)),
685        const char *arg) {
686    int argint;
687    const char *err;
688    mgs_srvconf_rec *sc =
689        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
690                                                 module_config,
691                                                 &gnutls_module);
692
693    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
694        return err;
695    }
696
697    argint = atoi(arg);
698
699    if (argint < 0) {
700        return "GnuTLSCacheTimeout: Invalid argument";
701    } else if (argint == 0) {
702        sc->cache_timeout = 0;
703    } else {
704        sc->cache_timeout = apr_time_from_sec(argint);
705    }
706
707    return NULL;
708}
709
710const char *mgs_set_client_verify_method(cmd_parms * parms, void *dummy __attribute__((unused)),
711        const char *arg) {
712    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)ap_get_module_config(parms->server->module_config, &gnutls_module);
713
714    if (strcasecmp("cartel", arg) == 0) {
715        sc->client_verify_method = mgs_cvm_cartel;
716    } else if (strcasecmp("msva", arg) == 0) {
717#ifdef ENABLE_MSVA
718        sc->client_verify_method = mgs_cvm_msva;
719#else
720        return "GnuTLSClientVerifyMethod: msva is not supported";
721#endif
722    } else {
723        return "GnuTLSClientVerifyMethod: Invalid argument";
724    }
725
726    return NULL;
727}
728
729const char *mgs_set_client_verify(cmd_parms * parms,
730                                  void *dirconf,
731                                  const char *arg) {
732    int mode;
733
734    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
735        mode = GNUTLS_CERT_IGNORE;
736    } else if (strcasecmp("optional", arg) == 0
737               || strcasecmp("request", arg) == 0) {
738        mode = GNUTLS_CERT_REQUEST;
739    } else if (strcasecmp("require", arg) == 0) {
740        mode = GNUTLS_CERT_REQUIRE;
741    } else {
742        return "GnuTLSClientVerify: Invalid argument";
743    }
744
745    /* This was set from a directory context */
746    if (parms->path) {
747        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dirconf;
748        dc->client_verify_mode = mode;
749    } else {
750        mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
751            ap_get_module_config(parms->server->module_config,
752                                 &gnutls_module);
753        sc->client_verify_mode = mode;
754    }
755
756    return NULL;
757}
758
759const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy __attribute__((unused)),
760        const char *arg) {
761    mgs_srvconf_rec *sc =
762        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
763                                                 module_config,
764                                                 &gnutls_module);
765
766    sc->x509_ca_file = ap_server_root_relative(parms->pool, arg);
767
768    return NULL;
769}
770
771const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy __attribute__((unused)),
772        const char *arg) {
773    mgs_srvconf_rec *sc =
774        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
775                                                 module_config,
776                                                 &gnutls_module);
777
778    sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg);
779
780    return NULL;
781}
782
783const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy __attribute__((unused)),
784        const char *arg) {
785
786    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
787        ap_get_module_config(parms->server->module_config, &gnutls_module);
788
789    if (!strcasecmp(arg, "On")) {
790        sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
791    } else if (!strcasecmp(arg, "Off")) {
792        sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
793    } else {
794        return "SSLProxyEngine must be set to 'On' or 'Off'";
795    }
796
797    return NULL;
798}
799
800const char *mgs_set_enabled(cmd_parms * parms, void *dummy __attribute__((unused)),
801        const char *arg) {
802    mgs_srvconf_rec *sc =
803        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
804                                                 module_config,
805                                                 &gnutls_module);
806    if (!strcasecmp(arg, "On")) {
807        sc->enabled = GNUTLS_ENABLED_TRUE;
808    } else if (!strcasecmp(arg, "Off")) {
809        sc->enabled = GNUTLS_ENABLED_FALSE;
810    } else {
811        return "GnuTLSEnable must be set to 'On' or 'Off'";
812    }
813
814    return NULL;
815}
816
817const char *mgs_set_export_certificates_size(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
818    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
819    if (!strcasecmp(arg, "On")) {
820        sc->export_certificates_size = 16 * 1024;
821    } else if (!strcasecmp(arg, "Off")) {
822        sc->export_certificates_size = 0;
823    } else {
824        char *endptr;
825        sc->export_certificates_size = strtol(arg, &endptr, 10);
826        while (apr_isspace(*endptr))
827            endptr++;
828        if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
829            ;
830        } else if (*endptr == 'k' || *endptr == 'K') {
831            sc->export_certificates_size *= 1024;
832        } else {
833            return
834                "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
835        }
836    }
837
838    return NULL;
839}
840
841const char *mgs_set_priorities(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
842
843    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
844        ap_get_module_config(parms->server->module_config, &gnutls_module);
845
846    sc->priorities_str = apr_pstrdup(parms->pool, arg);
847
848    return NULL;
849}
850
851const char *mgs_set_pin(cmd_parms * parms, void *dummy, const char *arg)
852{
853
854    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
855        ap_get_module_config(parms->server->module_config, &gnutls_module);
856
857    sc->pin = apr_pstrdup(parms->pool, arg);
858
859    return NULL;
860}
861
862const char *mgs_set_srk_pin(cmd_parms * parms, void *dummy, const char *arg)
863{
864
865    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
866        ap_get_module_config(parms->server->module_config, &gnutls_module);
867
868    sc->srk_pin = apr_pstrdup(parms->pool, arg);
869
870    return NULL;
871}
872
873static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p,
874                                                  char **err)
875{
876    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
877
878    sc->enabled = GNUTLS_ENABLED_UNSET;
879
880
881    sc->privkey_x509 = NULL;
882    sc->privkey_pgp = NULL;
883    sc->certs_x509_chain_num = 0;
884    sc->cache_timeout = -1;     /* -1 means "unset" */
885    sc->cache_type = mgs_cache_unset;
886    sc->cache_config = NULL;
887    sc->tickets = GNUTLS_ENABLED_UNSET;
888    sc->priorities = NULL;
889    sc->dh_params = NULL;
890    sc->proxy_enabled = GNUTLS_ENABLED_UNSET;
891    sc->export_certificates_size = -1;
892    sc->client_verify_method = mgs_cvm_unset;
893
894/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
895    sc->client_verify_mode = -1;
896
897    return sc;
898}
899
900void *mgs_config_server_create(apr_pool_t * p,
901                               server_rec * s __attribute__((unused))) {
902    char *err = NULL;
903    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
904    if (sc)
905        return sc;
906    else
907        return err;
908}
909
910#define gnutls_srvconf_merge(t, unset) sc->t = (add->t == unset) ? base->t : add->t
911#define gnutls_srvconf_assign(t) sc->t = add->t
912
913void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD)
914{
915    int i;
916    char *err = NULL;
917    mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;
918    mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;
919    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
920    if (NULL == sc)
921        return err;
922
923    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
924    gnutls_srvconf_merge(tickets, GNUTLS_ENABLED_UNSET);
925    gnutls_srvconf_merge(proxy_enabled, GNUTLS_ENABLED_UNSET);
926    gnutls_srvconf_merge(export_certificates_size, -1);
927    gnutls_srvconf_merge(client_verify_method, mgs_cvm_unset);
928    gnutls_srvconf_merge(client_verify_mode, -1);
929    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
930    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
931    gnutls_srvconf_merge(x509_cert_file, NULL);
932
933    gnutls_srvconf_merge(x509_key_file, NULL);
934    gnutls_srvconf_merge(x509_ca_file, NULL);
935    gnutls_srvconf_merge(pin, NULL);
936    gnutls_srvconf_merge(pgp_cert_file, NULL);
937    gnutls_srvconf_merge(pgp_key_file, NULL);
938    gnutls_srvconf_merge(pgp_ring_file, NULL);
939    gnutls_srvconf_merge(dh_file, NULL);
940    gnutls_srvconf_merge(priorities_str, NULL);
941
942    /* FIXME: the following items are pre-allocated, and should be
943     * properly disposed of before assigning in order to avoid leaks;
944     * so at the moment, we can't actually have them in the config.
945     * what happens during de-allocation? */
946    gnutls_srvconf_assign(ca_list);
947    gnutls_srvconf_assign(ca_list_size);
948    gnutls_srvconf_assign(cert_pgp);
949    gnutls_srvconf_assign(cert_crt_pgp);
950    gnutls_srvconf_assign(pgp_list);
951    gnutls_srvconf_assign(certs);
952    gnutls_srvconf_assign(anon_creds);
953    gnutls_srvconf_assign(srp_creds);
954    gnutls_srvconf_assign(certs_x509_chain);
955    gnutls_srvconf_assign(certs_x509_crt_chain);
956    gnutls_srvconf_assign(certs_x509_chain_num);
957
958    /* how do these get transferred cleanly before the data from ADD
959     * goes away? */
960    gnutls_srvconf_assign(cert_cn);
961    for (i = 0; i < MAX_CERT_SAN; i++)
962        gnutls_srvconf_assign(cert_san[i]);
963
964    return sc;
965}
966
967#undef gnutls_srvconf_merge
968#undef gnutls_srvconf_assign
969
970void *mgs_config_dir_merge(apr_pool_t * p,
971                           void *basev __attribute__((unused)),
972                           void *addv __attribute__((unused))) {
973    mgs_dirconf_rec *new;
974    /*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
975    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
976
977    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
978    new->client_verify_mode = add->client_verify_mode;
979    return new;
980}
981
982void *mgs_config_dir_create(apr_pool_t * p,
983                            char *dir __attribute__((unused))) {
984    mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc));
985    dc->client_verify_mode = -1;
986    return dc;
987}
Note: See TracBrowser for help on using the repository browser.