Changeset ae29683 in mod_gnutls for src/gnutls_config.c


Ignore:
Timestamp:
Feb 21, 2014, 12:15:56 AM (6 years ago)
Author:
Daniel Kahn Gillmor <dkg@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, upstream
Children:
4addf74, 62f781c
Parents:
180e49f (diff), 1a99240 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Imported Upstream version 0.6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_config.c

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