source: mod_gnutls/src/gnutls_config.c @ 040387c

debian/masterdebian/stretch-backportsjessie-backportsmsvaupstream
Last change on this file since 040387c was 040387c, checked in by Daniel Kahn Gillmor <dkg@…>, 7 years ago

server-wide settings should be defaults unless overridden in a vhost

Previously, there was no merging possible; so if any directives were
set in a vhost, all other directives set from the server config would
be thrown away.

  • Property mode set to 100644
File size: 19.7 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
22static int load_datum_from_file(apr_pool_t * pool,
23        const char *file, gnutls_datum_t * data) {
24    apr_file_t *fp;
25    apr_finfo_t finfo;
26    apr_status_t rv;
27    apr_size_t br = 0;
28
29    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
30            APR_OS_DEFAULT, pool);
31    if (rv != APR_SUCCESS) {
32        return rv;
33    }
34
35    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
36
37    if (rv != APR_SUCCESS) {
38        return rv;
39    }
40
41    data->data = apr_palloc(pool, finfo.size + 1);
42    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
43
44    if (rv != APR_SUCCESS) {
45        return rv;
46    }
47    apr_file_close(fp);
48
49    data->data[br] = '\0';
50    data->size = br;
51
52    return 0;
53}
54
55const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
56        const char *arg) {
57    int ret;
58    gnutls_datum_t data;
59    const char *file;
60    apr_pool_t *spool;
61    mgs_srvconf_rec *sc =
62            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
63            module_config,
64            &gnutls_module);
65
66    apr_pool_create(&spool, parms->pool);
67
68    file = ap_server_root_relative(spool, arg);
69
70    if (load_datum_from_file(spool, file, &data) != 0) {
71        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
72                "DH params '%s'", file);
73    }
74
75    ret = gnutls_dh_params_init(&sc->dh_params);
76    if (ret < 0) {
77        return apr_psprintf(parms->pool,
78                "GnuTLS: Failed to initialize"
79                ": (%d) %s", ret,
80                gnutls_strerror(ret));
81    }
82
83    ret =
84            gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
85            GNUTLS_X509_FMT_PEM);
86    if (ret < 0) {
87        return apr_psprintf(parms->pool,
88                "GnuTLS: Failed to Import "
89                "DH params '%s': (%d) %s", file, ret,
90                gnutls_strerror(ret));
91    }
92
93    apr_pool_destroy(spool);
94
95    return NULL;
96}
97
98const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, const char *arg) {
99
100    int ret;
101    gnutls_datum_t data;
102    const char *file;
103    apr_pool_t *spool;
104
105    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
106    apr_pool_create(&spool, parms->pool);
107
108    file = ap_server_root_relative(spool, arg);
109
110    if (load_datum_from_file(spool, file, &data) != 0) {
111                apr_pool_destroy(spool);
112        return apr_psprintf(parms->pool, "GnuTLS: Error Reading Certificate '%s'", file);
113    }
114
115    sc->certs_x509_chain_num = MAX_CHAIN_SIZE;
116    ret = gnutls_x509_crt_list_import(sc->certs_x509_chain, &sc->certs_x509_chain_num, &data, GNUTLS_X509_FMT_PEM, 0);
117    if (ret < 0) {
118                apr_pool_destroy(spool);
119        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret));
120    }
121   
122        apr_pool_destroy(spool);
123    return NULL;
124
125}
126
127const char *mgs_set_key_file(cmd_parms * parms, void *dummy, const char *arg) {
128
129    int ret;
130    gnutls_datum_t data;
131    const char *file;
132    apr_pool_t *spool;
133
134        mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
135   
136        apr_pool_create(&spool, parms->pool);
137
138    file = ap_server_root_relative(spool, arg);
139
140    if (load_datum_from_file(spool, file, &data) != 0) {
141                apr_pool_destroy(spool);
142        return apr_psprintf(parms->pool, "GnuTLS: Error Reading Private Key '%s'", file);
143    }
144
145    ret = gnutls_x509_privkey_init(&sc->privkey_x509);
146
147    if (ret < 0) {
148                apr_pool_destroy(spool);
149        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize: (%d) %s", ret, gnutls_strerror(ret));
150    }
151
152    ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
153
154    if (ret < 0) {
155        ret = gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN);
156        }
157
158    if (ret < 0) {
159                apr_pool_destroy(spool);
160        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Private Key '%s': (%d) %s", file, ret, gnutls_strerror(ret));
161    }
162
163    apr_pool_destroy(spool);
164
165    return NULL;
166}
167
168const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
169        const char *arg) {
170    int ret;
171    gnutls_datum_t data;
172    const char *file;
173    apr_pool_t *spool;
174    mgs_srvconf_rec *sc =
175            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
176            module_config,
177            &gnutls_module);
178    apr_pool_create(&spool, parms->pool);
179
180    file = ap_server_root_relative(spool, arg);
181
182    if (load_datum_from_file(spool, file, &data) != 0) {
183        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
184                "Certificate '%s'", file);
185    }
186
187    ret = gnutls_openpgp_crt_init(&sc->cert_pgp);
188    if (ret < 0) {
189        return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
190                "PGP Certificate: (%d) %s", ret,
191                gnutls_strerror(ret));
192    }
193
194    ret =
195            gnutls_openpgp_crt_import(sc->cert_pgp, &data,
196            GNUTLS_OPENPGP_FMT_BASE64);
197    if (ret < 0) {
198        return apr_psprintf(parms->pool,
199                "GnuTLS: Failed to Import "
200                "PGP Certificate '%s': (%d) %s", file,
201                ret, gnutls_strerror(ret));
202    }
203
204    apr_pool_destroy(spool);
205    return NULL;
206}
207
208const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
209        const char *arg) {
210    int ret;
211    gnutls_datum_t data;
212    const char *file;
213    apr_pool_t *spool;
214    mgs_srvconf_rec *sc =
215            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
216            module_config,
217            &gnutls_module);
218    apr_pool_create(&spool, parms->pool);
219
220    file = ap_server_root_relative(spool, arg);
221
222    if (load_datum_from_file(spool, file, &data) != 0) {
223        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
224                "Private Key '%s'", file);
225    }
226
227    ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
228    if (ret < 0) {
229        return apr_psprintf(parms->pool,
230                "GnuTLS: Failed to initialize"
231                ": (%d) %s", ret,
232                gnutls_strerror(ret));
233    }
234
235    ret =
236            gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
237            GNUTLS_OPENPGP_FMT_BASE64, NULL,
238            0);
239    if (ret != 0) {
240        return apr_psprintf(parms->pool,
241                "GnuTLS: Failed to Import "
242                "PGP Private Key '%s': (%d) %s", file,
243                ret, gnutls_strerror(ret));
244    }
245    apr_pool_destroy(spool);
246    return NULL;
247}
248
249const char *mgs_set_tickets(cmd_parms * parms, void *dummy,
250        const char *arg) {
251    mgs_srvconf_rec *sc =
252            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
253            module_config,
254            &gnutls_module);
255
256    sc->tickets = 0;
257    if (strcasecmp("on", arg) == 0) {
258        sc->tickets = 1;
259    }
260
261    return NULL;
262}
263
264
265#ifdef ENABLE_SRP
266
267const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
268        const char *arg) {
269    mgs_srvconf_rec *sc =
270            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
271            module_config,
272            &gnutls_module);
273
274    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
275
276    return NULL;
277}
278
279const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
280        const char *arg) {
281    mgs_srvconf_rec *sc =
282            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
283            module_config,
284            &gnutls_module);
285
286    sc->srp_tpasswd_conf_file =
287            ap_server_root_relative(parms->pool, arg);
288
289    return NULL;
290}
291
292#endif
293
294const char *mgs_set_cache(cmd_parms * parms, void *dummy,
295        const char *type, const char *arg) {
296    const char *err;
297    mgs_srvconf_rec *sc =
298            ap_get_module_config(parms->server->module_config,
299            &gnutls_module);
300    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
301        return err;
302    }
303
304    if (strcasecmp("none", type) == 0) {
305        sc->cache_type = mgs_cache_none;
306        sc->cache_config = NULL;
307        return NULL;
308    } else if (strcasecmp("dbm", type) == 0) {
309        sc->cache_type = mgs_cache_dbm;
310    } else if (strcasecmp("gdbm", type) == 0) {
311        sc->cache_type = mgs_cache_gdbm;
312    }
313#if HAVE_APR_MEMCACHE
314    else if (strcasecmp("memcache", type) == 0) {
315        sc->cache_type = mgs_cache_memcache;
316    }
317#endif
318    else {
319        return "Invalid Type for GnuTLSCache!";
320    }
321
322    if (arg == NULL)
323        return "Invalid argument 2 for GnuTLSCache!";
324
325    if (sc->cache_type == mgs_cache_dbm
326            || sc->cache_type == mgs_cache_gdbm) {
327        sc->cache_config =
328                ap_server_root_relative(parms->pool, arg);
329    } else {
330        sc->cache_config = apr_pstrdup(parms->pool, arg);
331    }
332
333    return NULL;
334}
335
336const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
337        const char *arg) {
338    int argint;
339    mgs_srvconf_rec *sc =
340            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
341            module_config,
342            &gnutls_module);
343
344    argint = atoi(arg);
345
346    if (argint < 0) {
347        return "GnuTLSCacheTimeout: Invalid argument";
348    } else if (argint == 0) {
349        sc->cache_timeout = 0;
350    } else {
351        sc->cache_timeout = apr_time_from_sec(argint);
352    }
353
354    return NULL;
355}
356
357const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
358        const char *arg) {
359    int mode;
360
361    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
362        mode = GNUTLS_CERT_IGNORE;
363    } else if (strcasecmp("optional", arg) == 0
364            || strcasecmp("request", arg) == 0) {
365        mode = GNUTLS_CERT_REQUEST;
366    } else if (strcasecmp("require", arg) == 0) {
367        mode = GNUTLS_CERT_REQUIRE;
368    } else {
369        return "GnuTLSClientVerify: Invalid argument";
370    }
371
372    /* This was set from a directory context */
373    if (parms->path) {
374        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
375        dc->client_verify_mode = mode;
376    } else {
377        mgs_srvconf_rec *sc =
378                (mgs_srvconf_rec *)
379                ap_get_module_config(parms->server->module_config,
380                &gnutls_module);
381        sc->client_verify_mode = mode;
382    }
383
384    return NULL;
385}
386
387#define INIT_CA_SIZE 128
388
389const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
390        const char *arg) {
391    int rv;
392    const char *file;
393    apr_pool_t *spool;
394    gnutls_datum_t data;
395
396    mgs_srvconf_rec *sc =
397            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
398            module_config,
399            &gnutls_module);
400    apr_pool_create(&spool, parms->pool);
401
402    file = ap_server_root_relative(spool, arg);
403
404    if (load_datum_from_file(spool, file, &data) != 0) {
405        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
406                "Client CA File '%s'", file);
407    }
408
409    sc->ca_list_size = INIT_CA_SIZE;
410    sc->ca_list = malloc(sc->ca_list_size * sizeof (*sc->ca_list));
411    if (sc->ca_list == NULL) {
412        return apr_psprintf(parms->pool,
413                "mod_gnutls: Memory allocation error");
414    }
415
416    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
417            &data, GNUTLS_X509_FMT_PEM,
418            GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
419    if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) {
420        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
421                "Client CA File '%s': (%d) %s", file,
422                rv, gnutls_strerror(rv));
423    }
424
425    if (INIT_CA_SIZE < sc->ca_list_size) {
426        sc->ca_list =
427                realloc(sc->ca_list,
428                sc->ca_list_size * sizeof (*sc->ca_list));
429        if (sc->ca_list == NULL) {
430            return apr_psprintf(parms->pool,
431                    "mod_gnutls: Memory allocation error");
432        }
433
434        /* re-read */
435        rv = gnutls_x509_crt_list_import(sc->ca_list,
436                &sc->ca_list_size, &data,
437                GNUTLS_X509_FMT_PEM, 0);
438
439        if (rv < 0) {
440            return apr_psprintf(parms->pool,
441                    "GnuTLS: Failed to load "
442                    "Client CA File '%s': (%d) %s",
443                    file, rv, gnutls_strerror(rv));
444        }
445    }
446
447    apr_pool_destroy(spool);
448    return NULL;
449}
450
451const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
452        const char *arg) {
453    int rv;
454    const char *file;
455    apr_pool_t *spool;
456    gnutls_datum_t data;
457
458    mgs_srvconf_rec *sc =
459            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
460            module_config,
461            &gnutls_module);
462    apr_pool_create(&spool, parms->pool);
463
464    file = ap_server_root_relative(spool, arg);
465
466    if (load_datum_from_file(spool, file, &data) != 0) {
467        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
468                "Keyring File '%s'", file);
469    }
470
471    rv = gnutls_openpgp_keyring_init(&sc->pgp_list);
472    if (rv < 0) {
473        return apr_psprintf(parms->pool,
474                "GnuTLS: Failed to initialize"
475                "keyring: (%d) %s", rv,
476                gnutls_strerror(rv));
477    }
478
479    rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
480            GNUTLS_OPENPGP_FMT_BASE64);
481    if (rv < 0) {
482        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
483                "Keyring File '%s': (%d) %s", file, rv,
484                gnutls_strerror(rv));
485    }
486
487    apr_pool_destroy(spool);
488    return NULL;
489}
490
491const char *mgs_set_proxy_engine(cmd_parms * parms, void *dummy,
492        const char *arg) {
493   
494    mgs_srvconf_rec *sc =(mgs_srvconf_rec *) 
495            ap_get_module_config(parms->server->module_config, &gnutls_module);
496   
497    if (!strcasecmp(arg, "On")) {
498        sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
499    } else if (!strcasecmp(arg, "Off")) {
500        sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
501    } else {
502        return "SSLProxyEngine must be set to 'On' or 'Off'";
503    }
504
505    return NULL;
506}
507
508const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
509        const char *arg) {
510    mgs_srvconf_rec *sc =
511            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
512            module_config,
513            &gnutls_module);
514    if (!strcasecmp(arg, "On")) {
515        sc->enabled = GNUTLS_ENABLED_TRUE;
516    } else if (!strcasecmp(arg, "Off")) {
517        sc->enabled = GNUTLS_ENABLED_FALSE;
518    } else {
519        return "GnuTLSEnable must be set to 'On' or 'Off'";
520    }
521
522    return NULL;
523}
524
525const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg) {
526
527        int ret;
528    const char *err;
529
530    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 
531                                                  ap_get_module_config(parms->server->module_config, &gnutls_module);
532
533    ret = gnutls_priority_init(&sc->priorities, arg, &err);
534
535    if (ret < 0) {
536        if (ret == GNUTLS_E_INVALID_REQUEST) {
537            return apr_psprintf(parms->pool, 
538                                                                "GnuTLS: Syntax error parsing priorities string at: %s", err);
539                }
540        return "Error setting priorities";
541    }
542
543    return NULL;
544}
545
546static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, char** err) {
547    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof (*sc));
548    int ret;
549
550    sc->enabled = GNUTLS_ENABLED_UNSET;
551
552    ret = gnutls_certificate_allocate_credentials(&sc->certs);
553    if (ret < 0) {
554        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
555                            ": (%d) %s", ret,
556                            gnutls_strerror(ret));
557        return NULL;
558    }
559
560    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
561    if (ret < 0) {
562        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
563                            ": (%d) %s", ret,
564                            gnutls_strerror(ret));
565        return NULL;
566    }
567#ifdef ENABLE_SRP
568    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
569    if (ret < 0) {
570        *err =  apr_psprintf(p, "GnuTLS: Failed to initialize"
571                             ": (%d) %s", ret,
572                             gnutls_strerror(ret));
573        return NULL;
574    }
575
576    sc->srp_tpasswd_conf_file = NULL;
577    sc->srp_tpasswd_file = NULL;
578#endif
579
580    sc->privkey_x509 = NULL;
581        /* Initialize all Certificate Chains */
582    /* FIXME: how do we indicate that this is unset for a merge? (that
583     * is, how can a subordinate server override the chain by setting
584     * an empty one?  what would that even look like in the
585     * configuration?) */
586        sc->certs_x509_chain = malloc(MAX_CHAIN_SIZE * sizeof (*sc->certs_x509_chain));
587    sc->certs_x509_chain_num = 0;
588    sc->cache_timeout = -1; /* -1 means "unset" */
589    sc->cache_type = mgs_cache_unset;
590    sc->cache_config = NULL;
591    sc->tickets = GNUTLS_ENABLED_UNSET;
592    sc->priorities = NULL;
593    sc->dh_params = NULL;
594    sc->proxy_enabled = GNUTLS_ENABLED_UNSET;
595   
596/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
597    sc->client_verify_mode = -1; 
598
599    return sc;
600}
601
602void *mgs_config_server_create(apr_pool_t * p, server_rec * s) {
603    char *err = NULL;
604    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
605    if (sc) return sc; else return err;
606}
607
608#define gnutls_srvconf_merge(t, unset) sc->t = (add->t == unset) ? base->t : add->t
609#define gnutls_srvconf_assign(t) sc->t = add->t
610
611void *mgs_config_server_merge(apr_pool_t *p, void *BASE, void *ADD) {
612    int i;
613    char *err = NULL;
614    mgs_srvconf_rec *base = (mgs_srvconf_rec *)BASE;
615    mgs_srvconf_rec *add = (mgs_srvconf_rec *)ADD;
616    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
617    if (NULL == sc) return err;
618
619    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
620    gnutls_srvconf_merge(tickets, GNUTLS_ENABLED_UNSET);
621    gnutls_srvconf_merge(proxy_enabled, GNUTLS_ENABLED_UNSET);
622    gnutls_srvconf_merge(client_verify_mode, -1);
623    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
624    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
625    gnutls_srvconf_merge(privkey_x509, NULL);
626    gnutls_srvconf_merge(priorities, NULL);
627    gnutls_srvconf_merge(dh_params, NULL);
628
629    /* FIXME: the following items are pre-allocated, and should be
630     * properly disposed of before assigning in order to avoid leaks;
631     * so at the moment, we can't actually have them in the config.
632     * what happens during de-allocation?
633
634     * This is probably leaky.
635     */
636    gnutls_srvconf_assign(certs);
637    gnutls_srvconf_assign(anon_creds);
638    gnutls_srvconf_assign(srp_creds);
639    gnutls_srvconf_assign(certs_x509_chain);
640    gnutls_srvconf_assign(certs_x509_chain_num);
641
642    /* how do these get transferred cleanly before the data from ADD
643     * goes away? */
644    gnutls_srvconf_assign(cert_cn);
645    for (i = 0; i < MAX_CERT_SAN; i++)
646        gnutls_srvconf_assign(cert_san[i]);
647    gnutls_srvconf_assign(ca_list);
648    gnutls_srvconf_assign(ca_list_size);
649    gnutls_srvconf_assign(cert_pgp);
650    gnutls_srvconf_assign(pgp_list);
651    gnutls_srvconf_assign(privkey_pgp);
652
653    return sc;
654}
655
656#undef gnutls_srvconf_merge
657#undef gnutls_srvconf_assign
658
659void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) {
660    mgs_dirconf_rec *new;
661    /*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
662    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
663
664    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof (mgs_dirconf_rec));
665    new->client_verify_mode = add->client_verify_mode;
666    return new;
667}
668
669void *mgs_config_dir_create(apr_pool_t * p, char *dir) {
670    mgs_dirconf_rec *dc = apr_palloc(p, sizeof (*dc));
671    dc->client_verify_mode = -1;
672    return dc;
673}
674
Note: See TracBrowser for help on using the repository browser.