Changes in / [9b20a1e:2afbe2e] in mod_gnutls


Ignore:
Files:
96 added
163 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r9b20a1e r2afbe2e  
    11**TODO:
     2- Fix support for proxy termination
    23- Handle Unclean Shutdowns
    34- make session cache use generic apache caches
    4 
    5 ** Version 0.7 beta (2015-06-27)
    6 - Security fix for TLS client authentication (CVE-2015-2091)
    7 - Bug fixes that enable support for reverse proxy operation
    8 - Various test suite improvements. Tests are configured through autoconf,
    9   so the test suite now works for builds without Monkeysphere support.
    10 - Add support for TLS connections to back end servers when operating as a
    11   reverse proxy (X.509 authentication only at the moment).
    12 - PKCS #11 support for server keys and certificates
    13 - Use strict compiler arguments by default (-Wall -Werror -Wextra)
    14 - Allow limiting the size of certificates exported as SSL_SERVER_CERT
    15   and SSL_CLIENT_CERT through the GnuTLSExportCertificates directive
    165
    176** Version 0.6 (2014-02-17)
     
    9988- Added support for subject alternative names in certificates.
    10089Only one per certificate is supported.
    101 - New enviroment variables: SSL_CLIENT_M_VERSION, SSL_CLIENT_S_SAN%,
     90- New enviroment variables: SSL_CLIENT_M_VERSION, SSL_CLIENT_S_SAN%, 
    10291SSL_CLIENT_S_TYPE, SSL_SERVER_M_VERSION, SSL_SERVER_S_SAN%, SSL_SERVER_S_TYPE
    10392- The compatibility mode can now be enabled explicitely with the
  • Makefile.am

    r9b20a1e r2afbe2e  
    22
    33EXTRA_DIST = m4/outoforder.m4 m4/apache.m4 \
    4                 m4/apr_memcache.m4 \
     4                m4/libgnutls.m4 m4/apr_memcache.m4 \
    55                m4/apache_test.m4  \
    66                include/mod_gnutls.h.in \
    7                 README CHANGELOG \
    8                 NOTICE LICENSE
     7                README README.ENV NEWS \
     8                NOTICE LICENSE autogen.sh
    99
    10 SUBDIRS = src test doc
     10SUBDIRS = src
    1111ACLOCAL_AMFLAGS = -I m4
     12TESTS = run_tests.sh
  • README

    r9b20a1e r2afbe2e  
    1818  Nikos Mavrogiannopoulos <nmav at gnutls.org>
    1919  Dash Shendy <neuromancer at dash.za.net>
    20   Thomas Klute <thomas2.klute@uni-dortmund.de>
    2120
    2221Prerequisites
    2322-------------
    2423
    25  * GnuTLS          >= 3.1.4 <http://www.gnutls.org/> (3.2.* or newer preferred)
     24 * GnuTLS          >= 2.12.6 <http://www.gnutls.org/> (3.* preferred)
    2625 * Apache HTTPD    >= 2.2 <http://httpd.apache.org/> (2.4.* preferred)
    2726 * autotools & gcc
    2827 * APR Memcache    >= 0.7.0 (Optional)
    29  * libmsv          >= 0.1 (Optional, enable with ./configure --enable-msva)
    30  * pandoc (for documentation, optional)
     28 * libmsv          >= 0.1 (Optional)
    3129
    3230Installation
     
    3634 cd mod_gnutls-version/
    3735 autoreconf -fiv
    38  ./configure
     36 ./configure --with-apxs=PATH --enable-msva
    3937 make
    4038 make install
  • configure.ac

    r9b20a1e r2afbe2e  
    11dnl
    2 AC_INIT(mod_gnutls, 0.7-beta)
     2AC_INIT(mod_gnutls, 0.6)
    33OOO_CONFIG_NICE(config.nice)
    44MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION
     
    2828)
    2929
    30 PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.1.4])
     30PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.12.6])
    3131
    3232LIBGNUTLS_VERSION=`pkg-config --modversion gnutls`
     
    3737       use_srp=$enableval, use_srp=yes)
    3838
    39 # check if the available GnuTLS library supports SRP
    40 AC_SEARCH_LIBS([gnutls_srp_server_get_username], [gnutls], [], [use_srp="no"])
    41 
    4239SRP_CFLAGS=""
    4340if test "$use_srp" != "no"; then
    44         SRP_CFLAGS="-DENABLE_SRP=1"
     41        SRP_CFLAGS="-DENABLE_SRP=1"
    4542fi
    4643
     
    6259               [enable Monkeysphere client certificate verification]),
    6360       use_msva=$enableval, use_msva=no)
    64 AM_CONDITIONAL([USE_MSVA], [test "$use_msva" != "no"])
    6561
    6662MSVA_CFLAGS=""
    6763if test "$use_msva" != "no"; then
    68         AC_CHECK_HEADERS([msv/msv.h], [],
     64        AC_CHECK_HEADERS([msv/msv.h], [],
    6965                         [AC_MSG_ERROR([*** No libmsv headers found!])])
    7066        AC_SEARCH_LIBS([msv_query_agent], [msv], [],
    7167                         [AC_MSG_ERROR([*** No libmsv found with msv_query_agent!])])
    72         MSVA_CFLAGS="-DENABLE_MSVA=1"
     68        MSVA_CFLAGS="-DENABLE_MSVA=1"
    7369fi
    7470
     
    8076AC_SUBST(have_apr_memcache)
    8177
    82 # Building documentation requires pandoc, which in turn needs pdflatex
    83 # to build PDF output.
    84 build_doc=no
    85 AC_PATH_PROG([PANDOC], [pandoc], [no])
    86 if test "$PANDOC" != "no"; then
    87         AC_PATH_PROG([PDFLATEX], [pdflatex], [no])
    88         if test "$PDFLATEX" != "no"; then
    89                 build_doc=yes
    90         else
    91                 build_doc="html only"
    92         fi
    93 fi
    94 AM_CONDITIONAL([USE_PANDOC], [test "$PANDOC" != "no"])
    95 AM_CONDITIONAL([USE_PDFLATEX], [test "$PANDOC" != "no" && \
    96                                test "$PDFLATEX" != "no"])
    97 
    98 # Check for Apache binary
    99 AC_PATH_PROGS([APACHE2], [apache2 httpd], [no])
    100 if test "${APACHE2}" = "no"; then
    101         AC_MSG_WARN([Neither apache2 nor httpd found in \
    102                      PATH. Test suite will fail.])
    103 fi
    104 
    10578MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${SRP_CFLAGS} ${MSVA_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES} ${STRICT_CFLAGS}"
    10679MODULE_LIBS="${APR_MEMCACHE_LIBS} ${LIBGNUTLS_LIBS}"
     
    10982AC_SUBST(MODULE_LIBS)
    11083
    111 AC_CONFIG_FILES([Makefile src/Makefile test/Makefile test/tests/Makefile \
    112                           doc/Makefile include/mod_gnutls.h])
     84AC_CONFIG_FILES([Makefile src/Makefile include/mod_gnutls.h])
    11385AC_OUTPUT
    11486
     
    11991echo "   * Apache Modules directory:    ${AP_LIBEXECDIR}"
    12092echo "   * GnuTLS Library version:      ${LIBGNUTLS_VERSION}"
    121 echo "   * SRP Authentication:  ${use_srp}"
    122 echo "   * MSVA Client Verification:    ${use_msva}"
    123 echo "   * Build documentation: ${build_doc}"
     93echo "   * SRP Authentication:          ${use_srp}"
     94echo "   * MSVA Client Verification:    ${use_msva}"
    12495echo ""
    12596echo "---"
  • include/mod_gnutls.h.in

    r9b20a1e r2afbe2e  
    11/**
    22 *  Copyright 2004-2005 Paul Querna
    3  *  Copyright 2015 Thomas Klute
    43 *
    54 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    3534#include <gnutls/extra.h>
    3635#endif
    37 #include <gnutls/abstract.h>
    3836#include <gnutls/openpgp.h>
    3937#include <gnutls/x509.h>
     
    106104/* Server Configuration Record */
    107105typedef struct {
    108     /* --- Configuration values --- */
    109         /* Is the module enabled? */
    110     int enabled;
    111         /* Is mod_proxy enabled? */
    112     int proxy_enabled;
    113         /* A Plain HTTP request */
    114     int non_ssl_request;
    115 
    116     /* Additional PKCS #11 provider module to load, only valid in the
    117      * base config, ignored in virtual hosts */
    118     char *p11_module;
    119 
    120     /* PIN used for PKCS #11 operations */
    121     char *pin;
    122 
    123     /* the SRK PIN used in TPM operations */
    124     char *srk_pin;
    125 
    126     char *x509_cert_file;
    127     char *x509_key_file;
    128     char *x509_ca_file;
    129 
    130     char *pgp_cert_file;
    131     char *pgp_key_file;
    132     char *pgp_ring_file;
    133 
    134     char *dh_file;
    135 
    136     char *priorities_str;
    137     char *proxy_priorities_str;
    138 
    139     const char* srp_tpasswd_file;
    140     const char* srp_tpasswd_conf_file;
    141 
    142         /* Cache timeout value */
    143     int cache_timeout;
    144         /* Chose Cache Type */
    145     mgs_cache_e cache_type;
    146     const char* cache_config;
    147 
    148         /* GnuTLS uses Session Tickets */
    149     int tickets;
    150 
    151     /* --- Things initialized at _child_init --- */
    152 
    153     /* x509 Certificate Structure */
     106        /* x509 Certificate Structure */
    154107    gnutls_certificate_credentials_t certs;
    155     /* x509 credentials for proxy connections */
    156     gnutls_certificate_credentials_t proxy_x509_creds;
    157     /* trust list for proxy_x509_creds */
    158     gnutls_x509_trust_list_t proxy_x509_tl;
    159     const char* proxy_x509_key_file;
    160     const char* proxy_x509_cert_file;
    161     const char* proxy_x509_ca_file;
    162     const char* proxy_x509_crl_file;
    163     /* GnuTLS priorities for proxy connections */
    164     gnutls_priority_t proxy_priorities;
    165     /* SRP Certificate Structure*/
     108        /* SRP Certificate Structure*/
    166109    gnutls_srp_server_credentials_t srp_creds;
    167     /* Anonymous Certificate Structure */
     110        /* Annonymous Certificate Structure */
    168111    gnutls_anon_server_credentials_t anon_creds;
    169     /* Anonymous Client Certificate Structure, used for proxy
    170      * connections */
    171     gnutls_anon_client_credentials_t anon_client_creds;
    172112        /* Current x509 Certificate CN [Common Name] */
    173113    char* cert_cn;
    174114        /* Current x509 Certificate SAN [Subject Alternate Name]s*/
    175     char* cert_san[MAX_CERT_SAN];
    176         /* An x509 Certificate Chain */
    177     gnutls_pcert_st *certs_x509_chain;
    178     gnutls_x509_crt_t *certs_x509_crt_chain;
     115        char* cert_san[MAX_CERT_SAN];
     116        /* A x509 Certificate Chain */
     117    gnutls_x509_crt_t *certs_x509_chain;
     118        /* Current x509 Certificate Private Key */
     119    gnutls_x509_privkey_t privkey_x509;
     120        /* OpenPGP Certificate */
     121    gnutls_openpgp_crt_t cert_pgp;
     122        /* OpenPGP Certificate Private Key */
     123    gnutls_openpgp_privkey_t privkey_pgp;
    179124        /* Number of Certificates in Chain */
    180125    unsigned int certs_x509_chain_num;
    181 
    182         /* Current x509 Certificate Private Key */
    183     gnutls_privkey_t privkey_x509;
    184 
    185         /* OpenPGP Certificate */
    186     gnutls_pcert_st *cert_pgp;
    187     gnutls_openpgp_crt_t *cert_crt_pgp;
    188 
    189         /* OpenPGP Certificate Private Key */
    190     gnutls_privkey_t privkey_pgp;
    191 #if GNUTLS_VERSION_NUMBER < 0x030312
    192     /* Internal structure for the OpenPGP private key, used in the
    193      * workaround for a bug in gnutls_privkey_import_openpgp_raw that
    194      * frees memory that is still needed. DO NOT USE for any other
    195      * purpose. */
    196     gnutls_openpgp_privkey_t privkey_pgp_internal;
    197 #endif
    198 
     126        /* Is the module enabled? */
     127    int enabled;
    199128    /* Export full certificates to CGI environment: */
    200129    int export_certificates_size;
     
    203132        /* GnuTLS DH Parameters */
    204133    gnutls_dh_params_t dh_params;
     134        /* Cache timeout value */
     135    int cache_timeout;
     136        /* Chose Cache Type */
     137    mgs_cache_e cache_type;
     138    const char* cache_config;
     139    const char* srp_tpasswd_file;
     140    const char* srp_tpasswd_conf_file;
    205141        /* A list of CA Certificates */
    206142    gnutls_x509_crt_t *ca_list;
     
    215151        /* Last Cache timestamp */
    216152    apr_time_t last_cache_check;
     153        /* GnuTLS uses Session Tickets */
     154    int tickets;
     155        /* Is mod_proxy enabled? */
     156    int proxy_enabled;
     157        /* A Plain HTTP request */
     158    int non_ssl_request;
    217159} mgs_srvconf_rec;
    218160
     
    229171        /* Connection record */
    230172    conn_rec* c;
    231         /* Is TLS enabled for this connection? */
    232     int enabled;
    233     /* Is this a proxy connection? */
    234     int is_proxy;
    235173        /* GnuTLS Session handle */
    236174    gnutls_session_t session;
     
    364302
    365303/**
    366  * Perform any reinitialization required in PKCS #11
    367  */
    368 int mgs_pkcs11_reinit(server_rec * s);
    369 
    370 /**
    371304 * Convert a SSL Session ID into a Null Terminated Hex Encoded String
    372305 * @param id raw SSL Session ID
     
    388321
    389322/* Configuration Functions */
    390 
    391 /* Loads all files set in the configuration */
    392 int mgs_load_files(apr_pool_t * p, server_rec * s);
    393323
    394324const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
     
    425355                                   const char *arg);
    426356
    427 const char *mgs_set_p11_module(cmd_parms * parms, void *dummy,
    428                                const char *arg);
    429 
    430 const char *mgs_set_pin(cmd_parms * parms, void *dummy,
    431                                    const char *arg);
    432 
    433 const char *mgs_set_srk_pin(cmd_parms * parms, void *dummy,
    434                                    const char *arg);
    435 
    436357const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
    437358                                   const char *arg);
     
    460381mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session);
    461382
    462 const char *mgs_store_cred_path(cmd_parms * parms,
    463                                 void *dummy __attribute__((unused)),
    464                                 const char *arg);
    465 
    466383/* mod_gnutls Hooks. */
    467384
  • m4/apr_memcache.m4

    r9b20a1e r2afbe2e  
    4545    apr_memcache_includedir=$includedir/apr_memcache-0
    4646fi
    47 
    4847CFLAGS="-I$apr_memcache_includedir $CFLAGS"
    49 
    5048
    5149AC_CHECK_LIB(
     
    6058    ]
    6159)
    62 
    63 
    64 dnl # if the apr_memcache was not found, try apr-util
    65 if test -z "${APR_MEMCACHE_LIBS}"; then
    66     if test -n "$apr_memcache_includes"; then
    67         apr_memcache_includedir=$apr_memcache_includes
    68     elif test -n "$apr_memcache_prefix"; then
    69         apr_memcache_includedir=$apr_memcache_prefix/include/aprutil-1
    70     else
    71         apr_memcache_includedir=$includedir/aprutil-1
    72     fi
    73     AC_CHECK_LIB(
    74         aprutil-1,
    75         apr_memcache_create,
    76         [
    77             APR_MEMCACHE_LIBS="`apu-1-config --link-ld`"
    78             APR_MEMCACHE_CFLAGS="`apu-1-config --includes`"
    79         ]
    80     )
    81 fi
    82 
    83 
    8460CFLAGS=$save_CFLAGS
    8561LDFLAGS=$save_LDFLAGS
  • src/gnutls_cache.c

    r9b20a1e r2afbe2e  
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
    65 *
    76 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    581580}
    582581
    583 #if HAVE_APR_MEMCACHE
    584 int mgs_cache_child_init(apr_pool_t * p,
    585                          server_rec * s,
    586                          mgs_srvconf_rec * sc)
    587 #else
    588 int mgs_cache_child_init(apr_pool_t * p __attribute__((unused)),
    589                          server_rec * s __attribute__((unused)),
    590                          mgs_srvconf_rec * sc)
    591 #endif
    592 {
     582int mgs_cache_child_init(apr_pool_t * p, server_rec * s,
     583        mgs_srvconf_rec * sc) {
    593584    if (sc->cache_type == mgs_cache_dbm
    594585            || sc->cache_type == mgs_cache_gdbm) {
  • src/gnutls_config.c

    r9b20a1e r2afbe2e  
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
    65 *
    76 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    2120#include "mod_gnutls.h"
    2221#include "apr_lib.h"
    23 #include <gnutls/abstract.h>
    24 
    25 #define INIT_CA_SIZE 128
    2622
    2723#ifdef APLOG_USE_MODULE
     
    2925#endif
    3026
    31 static int pin_callback(void *user, int attempt __attribute__((unused)),
    32                         const char *token_url __attribute__((unused)),
    33                         const char *token_label, unsigned int flags,
    34                         char *pin, size_t pin_max)
    35 {
    36     mgs_srvconf_rec *sc = user;
    37 
    38     if (sc->pin == NULL || flags & GNUTLS_PIN_FINAL_TRY ||
    39         flags & GNUTLS_PIN_WRONG) {
    40         return -1;
    41     }
    42 
    43     if (token_label && strcmp(token_label, "SRK") == 0) {
    44          snprintf(pin, pin_max, "%s", sc->srk_pin);
    45     } else {
    46          snprintf(pin, pin_max, "%s", sc->pin);
    47     }
    48     return 0;
    49 }
    50 
    5127static int load_datum_from_file(apr_pool_t * pool,
    52                                 const char *file, gnutls_datum_t * data)
    53 {
     28        const char *file, gnutls_datum_t * data) {
    5429    apr_file_t *fp;
    5530    apr_finfo_t finfo;
     
    5833
    5934    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY,
    60                        APR_OS_DEFAULT, pool);
     35            APR_OS_DEFAULT, pool);
    6136    if (rv != APR_SUCCESS) {
    62         return rv;
     37        return rv;
    6338    }
    6439
     
    6641
    6742    if (rv != APR_SUCCESS) {
    68         return rv;
     43        return rv;
    6944    }
    7045
     
    7348
    7449    if (rv != APR_SUCCESS) {
    75         return rv;
     50        return rv;
    7651    }
    7752    apr_file_close(fp);
     
    8358}
    8459
    85 /* 2048-bit group parameters from SRP specification */
    86 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
    87         "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
    88         "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
    89         "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
    90         "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
    91         "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
    92         "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
    93         "-----END DH PARAMETERS-----\n";
    94 
    95 int mgs_load_files(apr_pool_t * p, server_rec * s)
    96 {
     60const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)),
     61        const char *arg) {
     62    int ret;
     63    gnutls_datum_t data;
     64    const char *file;
    9765    apr_pool_t *spool;
     66    mgs_srvconf_rec *sc =
     67            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     68            module_config,
     69            &gnutls_module);
     70
     71    apr_pool_create(&spool, parms->pool);
     72
     73    file = ap_server_root_relative(spool, arg);
     74
     75    if (load_datum_from_file(spool, file, &data) != 0) {
     76        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     77                "DH params '%s'", file);
     78    }
     79
     80    ret = gnutls_dh_params_init(&sc->dh_params);
     81    if (ret < 0) {
     82        return apr_psprintf(parms->pool,
     83                "GnuTLS: Failed to initialize"
     84                ": (%d) %s", ret,
     85                gnutls_strerror(ret));
     86    }
     87
     88    ret =
     89            gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
     90            GNUTLS_X509_FMT_PEM);
     91    if (ret < 0) {
     92        return apr_psprintf(parms->pool,
     93                "GnuTLS: Failed to Import "
     94                "DH params '%s': (%d) %s", file, ret,
     95                gnutls_strerror(ret));
     96    }
     97
     98    apr_pool_destroy(spool);
     99
     100    return NULL;
     101}
     102
     103const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
     104
     105    int ret;
     106    gnutls_datum_t data;
    98107    const char *file;
     108    apr_pool_t *spool;
     109
     110    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
     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                apr_pool_destroy(spool);
     117        return apr_psprintf(parms->pool, "GnuTLS: Error Reading Certificate '%s'", file);
     118    }
     119
     120    sc->certs_x509_chain_num = MAX_CHAIN_SIZE;
     121    ret = gnutls_x509_crt_list_import(sc->certs_x509_chain, &sc->certs_x509_chain_num, &data, GNUTLS_X509_FMT_PEM, 0);
     122    if (ret < 0) {
     123                apr_pool_destroy(spool);
     124        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret));
     125    }
     126
     127        apr_pool_destroy(spool);
     128    return NULL;
     129
     130}
     131
     132const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
     133
     134    int ret;
    99135    gnutls_datum_t data;
     136    const char *file;
     137    apr_pool_t *spool;
     138    const char *out;
     139
     140        mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
     141
     142        apr_pool_create(&spool, parms->pool);
     143
     144    file = ap_server_root_relative(spool, arg);
     145
     146    if (load_datum_from_file(spool, file, &data) != 0) {
     147        out = apr_psprintf(parms->pool, "GnuTLS: Error Reading Private Key '%s'", file);
     148                apr_pool_destroy(spool);
     149        return out;
     150    }
     151
     152    ret = gnutls_x509_privkey_init(&sc->privkey_x509);
     153
     154    if (ret < 0) {
     155                apr_pool_destroy(spool);
     156        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize: (%d) %s", ret, gnutls_strerror(ret));
     157    }
     158
     159    ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
     160
     161    if (ret < 0) {
     162        ret = gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, NULL, GNUTLS_PKCS_PLAIN);
     163        }
     164
     165    if (ret < 0) {
     166        out = apr_psprintf(parms->pool, "GnuTLS: Failed to Import Private Key '%s': (%d) %s", file, ret, gnutls_strerror(ret));
     167                apr_pool_destroy(spool);
     168        return out;
     169    }
     170
     171    apr_pool_destroy(spool);
     172
     173    return NULL;
     174}
     175
     176const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)),
     177        const char *arg) {
    100178    int ret;
    101     mgs_srvconf_rec *sc =
    102         (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    103                                                  &gnutls_module);
    104 
    105     apr_pool_create(&spool, p);
    106 
    107     sc->cert_pgp = apr_pcalloc(p, sizeof(sc->cert_pgp[0]));
    108     sc->cert_crt_pgp = apr_pcalloc(p, sizeof(sc->cert_crt_pgp[0]));
    109     sc->certs_x509_chain =
    110         apr_pcalloc(p, MAX_CHAIN_SIZE * sizeof(sc->certs_x509_chain[0]));
    111     sc->certs_x509_crt_chain =
    112         apr_pcalloc(p,
    113                     MAX_CHAIN_SIZE * sizeof(sc->certs_x509_crt_chain[0]));
    114 
    115     ret = gnutls_certificate_allocate_credentials(&sc->certs);
    116     if (ret < 0) {
    117         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    118                      "GnuTLS: Failed to initialize" ": (%d) %s", ret,
    119                      gnutls_strerror(ret));
    120         ret = -1;
    121         goto cleanup;
    122     }
    123 
    124     ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
    125     if (ret < 0) {
    126         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    127                      "GnuTLS: Failed to initialize" ": (%d) %s", ret,
    128                      gnutls_strerror(ret));
    129         ret = -1;
    130         goto cleanup;
    131     }
    132 
    133     /* Load SRP parameters */
    134 #ifdef ENABLE_SRP
    135     ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
    136     if (ret < 0) {
    137         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    138                      "GnuTLS: Failed to initialize" ": (%d) %s", ret,
    139                      gnutls_strerror(ret));
    140         ret = -1;
    141         goto cleanup;
    142     }
    143 
    144     if (sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) {
    145         ret = gnutls_srp_set_server_credentials_file
    146             (sc->srp_creds, sc->srp_tpasswd_file,
    147              sc->srp_tpasswd_conf_file);
    148 
    149         if (ret < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
    150             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
    151                          s,
    152                          "GnuTLS: Host '%s:%d' is missing a "
    153                          "SRP password or conf File!",
    154                          s->server_hostname, s->port);
    155             ret = -1;
    156             goto cleanup;
    157         }
    158     }
    159 #endif
    160 
    161     ret = gnutls_dh_params_init(&sc->dh_params);
    162     if (ret < 0) {
    163             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    164                          "GnuTLS: Failed to initialize"
    165                          ": (%d) %s", ret, gnutls_strerror(ret));
    166             ret = -1;
    167             goto cleanup;
    168     }
    169 
    170     /* Load DH parameters */
    171     if (sc->dh_file) {
    172         if (load_datum_from_file(spool, sc->dh_file, &data) != 0) {
    173             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    174                          "GnuTLS: Error Reading " "DH params '%s'", sc->dh_file);
    175             ret = -1;
    176             goto cleanup;
    177         }
    178 
    179         ret =
    180             gnutls_dh_params_import_pkcs3(sc->dh_params, &data,
    181                                           GNUTLS_X509_FMT_PEM);
    182         if (ret < 0) {
    183             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    184                          "GnuTLS: Failed to Import "
    185                          "DH params '%s': (%d) %s", sc->dh_file, ret,
    186                          gnutls_strerror(ret));
    187             ret = -1;
    188             goto cleanup;
    189         }
    190     } else {
    191         gnutls_datum_t pdata = {
    192             (void *) static_dh_params,
    193             sizeof(static_dh_params)
    194         };
    195 
    196         ret = gnutls_dh_params_import_pkcs3(sc->dh_params, &pdata, GNUTLS_X509_FMT_PEM);
    197         if (ret < 0) {
    198             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    199                     "GnuTLS: Unable to generate or load DH Params: (%d) %s",
    200                     ret, gnutls_strerror(ret));
    201             ret = -1;
    202             goto cleanup;
    203         }
    204     }
    205 
    206     if (sc->x509_cert_file != NULL) {
    207         unsigned int chain_num, i;
    208         unsigned format = GNUTLS_X509_FMT_PEM;
    209 
    210         /* Load X.509 certificate */
    211         if (strncmp(sc->x509_cert_file, "pkcs11:", 7) == 0) {
    212             gnutls_pkcs11_obj_t obj;
    213 
    214             file = sc->x509_cert_file;
    215 
    216             ret = gnutls_pkcs11_obj_init(&obj);
    217             if (ret < 0) {
    218                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    219                              "GnuTLS: Error Initializing PKCS #11 object");
    220                 ret = -1;
    221                 goto cleanup;
    222             }
    223 
    224             gnutls_pkcs11_obj_set_pin_function(obj, pin_callback, sc);
    225 
    226             ret = gnutls_pkcs11_obj_import_url(obj, file, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
    227             if (ret < 0) {
    228                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    229                              "GnuTLS: Error Importing PKCS #11 object: '%s': %s",
    230                              file, gnutls_strerror(ret));
    231                 ret = -1;
    232                 goto cleanup;
    233             }
    234 
    235             format = GNUTLS_X509_FMT_DER;
    236             ret = gnutls_pkcs11_obj_export2(obj, &data);
    237             if (ret < 0) {
    238                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    239                              "GnuTLS: Error Exporting a PKCS #11 object: '%s': %s",
    240                              file, gnutls_strerror(ret));
    241                 ret = -1;
    242                 goto cleanup;
    243             }
    244 
    245             gnutls_pkcs11_obj_deinit(obj);
    246         } else {
    247             file = ap_server_root_relative(spool, sc->x509_cert_file);
    248 
    249             ret = gnutls_load_file(file, &data);
    250             if (ret < 0) {
    251                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    252                              "GnuTLS: Error Reading Certificate '%s': %s",
    253                              file, gnutls_strerror(ret));
    254                 ret = -1;
    255                 goto cleanup;
    256             }
    257         }
    258 
    259         ret =
    260             gnutls_x509_crt_list_import2(&sc->certs_x509_crt_chain,
    261                                         &chain_num, &data, format,
    262                                         GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
    263         gnutls_free(data.data);
    264         sc->certs_x509_chain_num = chain_num;
    265 
    266         if (ret < 0) {
    267             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    268                          "GnuTLS: Failed to Import Certificate Chain '%s': (%d) %s",
    269                          file, ret, gnutls_strerror(ret));
    270             ret = -1;
    271             goto cleanup;
    272         }
    273 
    274         for (i = 0; i < chain_num; i++) {
    275             ret =
    276                 gnutls_pcert_import_x509(&sc->certs_x509_chain[i],
    277                                          sc->certs_x509_crt_chain[i], 0);
    278             if (ret < 0) {
    279                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    280                              "GnuTLS: Failed to Import pCertificate '%s': (%d) %s",
    281                              file, ret, gnutls_strerror(ret));
    282                 ret = -1;
    283                 goto cleanup;
    284             }
    285         }
    286         sc->certs_x509_chain_num = chain_num;
    287     }
    288 
    289     if (sc->x509_key_file) {
    290         ret = gnutls_privkey_init(&sc->privkey_x509);
    291         if (ret < 0) {
    292             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    293                          "GnuTLS: Failed to initialize: (%d) %s", ret,
    294                          gnutls_strerror(ret));
    295             ret = -1;
    296             goto cleanup;
    297         }
    298 
    299         if (gnutls_url_is_supported(sc->x509_key_file) != 0) {
    300             file = sc->x509_key_file;
    301 
    302             gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback,
    303                                             sc);
    304 
    305             ret = gnutls_privkey_import_url(sc->privkey_x509, file, 0);
    306 
    307             if (ret < 0) {
    308                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    309                              "GnuTLS: Failed to Import Private Key URL '%s': (%d) %s",
    310                              file, ret, gnutls_strerror(ret));
    311                 ret = -1;
    312                 goto cleanup;
    313             }
    314         } else {
    315             file = ap_server_root_relative(spool, sc->x509_key_file);
    316 
    317             if (load_datum_from_file(spool, file, &data) != 0) {
    318                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    319                              "GnuTLS: Error Reading Private Key '%s'",
    320                              file);
    321                 ret = -1;
    322                 goto cleanup;
    323             }
    324 
    325             ret =
    326                 gnutls_privkey_import_x509_raw(sc->privkey_x509, &data,
    327                                                GNUTLS_X509_FMT_PEM, sc->pin,
    328                                                0);
    329 
    330             if (ret < 0) {
    331                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    332                              "GnuTLS: Failed to Import Private Key '%s': (%d) %s",
    333                              file, ret, gnutls_strerror(ret));
    334                 ret = -1;
    335                 goto cleanup;
    336             }
    337         }
    338     }
    339 
    340     /* Load the X.509 CA file */
    341     if (sc->x509_ca_file) {
    342         if (load_datum_from_file(spool, sc->x509_ca_file, &data) != 0) {
    343             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    344                          "GnuTLS: Error Reading " "Client CA File '%s'",
    345                          sc->x509_ca_file);
    346             ret = -1;
    347             goto cleanup;
    348         }
    349 
    350         ret = gnutls_x509_crt_list_import2(&sc->ca_list, &sc->ca_list_size,
    351                                          &data, GNUTLS_X509_FMT_PEM, 0);
    352         if (ret < 0) {
    353             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    354                          "GnuTLS: Failed to load "
    355                          "Client CA File '%s': (%d) %s", sc->x509_ca_file,
    356                          ret, gnutls_strerror(ret));
    357             ret = -1;
    358             goto cleanup;
    359         }
    360     }
    361 
    362     if (sc->pgp_cert_file) {
    363         if (load_datum_from_file(spool, sc->pgp_cert_file, &data) != 0) {
    364             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    365                          "GnuTLS: Error Reading " "Certificate '%s'",
    366                          sc->pgp_cert_file);
    367             ret = -1;
    368             goto cleanup;
    369         }
    370 
    371         ret = gnutls_openpgp_crt_init(&sc->cert_crt_pgp[0]);
    372         if (ret < 0) {
    373             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    374                          "GnuTLS: Failed to Init "
    375                          "PGP Certificate: (%d) %s", ret,
    376                          gnutls_strerror(ret));
    377             ret = -1;
    378             goto cleanup;
    379         }
    380 
    381         ret =
    382             gnutls_openpgp_crt_import(sc->cert_crt_pgp[0], &data,
    383                                       GNUTLS_OPENPGP_FMT_BASE64);
    384         if (ret < 0) {
    385             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    386                          "GnuTLS: Failed to Import "
    387                          "PGP Certificate: (%d) %s", ret,
    388                          gnutls_strerror(ret));
    389             ret = -1;
    390             goto cleanup;
    391         }
    392 
    393         ret =
    394             gnutls_pcert_import_openpgp(sc->cert_pgp, sc->cert_crt_pgp[0],
    395                                         0);
    396         if (ret < 0) {
    397             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    398                          "GnuTLS: Failed to Import "
    399                          "PGP pCertificate: (%d) %s", ret,
    400                          gnutls_strerror(ret));
    401             ret = -1;
    402             goto cleanup;
    403         }
    404     }
    405 
    406     /* Load the PGP key file */
    407     if (sc->pgp_key_file) {
    408         if (load_datum_from_file(spool, sc->pgp_key_file, &data) != 0) {
    409             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    410                          "GnuTLS: Error Reading " "Private Key '%s'",
    411                          sc->pgp_key_file);
    412             ret = -1;
    413             goto cleanup;
    414         }
    415 
    416         ret = gnutls_privkey_init(&sc->privkey_pgp);
    417         if (ret < 0) {
    418             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    419                          "GnuTLS: Failed to initialize"
    420                          ": (%d) %s", ret, gnutls_strerror(ret));
    421             ret = -1;
    422             goto cleanup;
    423         }
    424 
    425 #if GNUTLS_VERSION_NUMBER < 0x030312
    426         /* GnuTLS versions before 3.3.12 contain a bug in
    427          * gnutls_privkey_import_openpgp_raw which frees data that is
    428          * accessed when the key is used, leading to segfault. Loading
    429          * the key into a gnutls_openpgp_privkey_t and then assigning
    430          * it to the gnutls_privkey_t works around the bug, hence this
    431          * chain of gnutls_openpgp_privkey_init,
    432          * gnutls_openpgp_privkey_import and
    433          * gnutls_privkey_import_openpgp. */
    434         ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal);
    435         if (ret != 0) {
    436             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    437                          "GnuTLS: Failed to initialize "
    438                          "PGP Private Key '%s': (%d) %s",
    439                          sc->pgp_key_file, ret, gnutls_strerror(ret));
    440             ret = -1;
    441             goto cleanup;
    442         }
    443 
    444         ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data,
    445                                             GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
    446         if (ret != 0) {
    447             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    448                          "GnuTLS: Failed to Import "
    449                          "PGP Private Key '%s': (%d) %s",
    450                          sc->pgp_key_file, ret, gnutls_strerror(ret));
    451             ret = -1;
    452             goto cleanup;
    453         }
    454 
    455         ret = gnutls_privkey_import_openpgp(sc->privkey_pgp,
    456                                             sc->privkey_pgp_internal, 0);
    457         if (ret != 0)
    458         {
    459             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    460                          "GnuTLS: Failed to assign PGP Private Key '%s' "
    461                          "to gnutls_privkey_t structure: (%d) %s",
    462                          sc->pgp_key_file, ret, gnutls_strerror(ret));
    463             ret = -1;
    464             goto cleanup;
    465         }
    466 #else
    467         ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
    468                                                 GNUTLS_OPENPGP_FMT_BASE64,
    469                                                 NULL, NULL);
    470         if (ret != 0)
    471         {
    472             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    473                          "GnuTLS: Failed to Import "
    474                          "PGP Private Key '%s': (%d) %s",
    475                          sc->pgp_key_file, ret, gnutls_strerror(ret));
    476             ret = -1;
    477             goto cleanup;
    478         }
    479 #endif
    480     }
    481 
    482     /* Load the keyring file */
    483     if (sc->pgp_ring_file) {
    484         if (load_datum_from_file(spool, sc->pgp_ring_file, &data) != 0) {
    485             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    486                          "GnuTLS: Error Reading " "Keyring File '%s'",
    487                          sc->pgp_ring_file);
    488             ret = -1;
    489             goto cleanup;
    490         }
    491 
    492         ret = gnutls_openpgp_keyring_init(&sc->pgp_list);
    493         if (ret < 0) {
    494             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    495                          "GnuTLS: Failed to initialize"
    496                          "keyring: (%d) %s", ret, gnutls_strerror(ret));
    497             ret = -1;
    498             goto cleanup;
    499         }
    500 
    501         ret = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
    502                                            GNUTLS_OPENPGP_FMT_BASE64);
    503         if (ret < 0) {
    504             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    505                          "GnuTLS: Failed to load "
    506                          "Keyring File '%s': (%d) %s", sc->pgp_ring_file,
    507                          ret, gnutls_strerror(ret));
    508             ret = -1;
    509             goto cleanup;
    510         }
    511     }
    512 
    513     if (sc->priorities_str) {
    514         const char *err;
    515         ret = gnutls_priority_init(&sc->priorities, sc->priorities_str, &err);
    516 
    517         if (ret < 0) {
    518             if (ret == GNUTLS_E_INVALID_REQUEST) {
    519                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    520                              "GnuTLS: Syntax error parsing priorities string at: %s",
    521                              err);
    522             } else {
    523                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    524                              "GnuTLS: error parsing priorities string");
    525 
    526             }
    527             ret = -1;
    528             goto cleanup;
    529         }
    530     }
    531 
    532     ret = 0;
    533   cleanup:
     179    gnutls_datum_t data;
     180    const char *file;
     181    apr_pool_t *spool;
     182    mgs_srvconf_rec *sc =
     183            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     184            module_config,
     185            &gnutls_module);
     186    apr_pool_create(&spool, parms->pool);
     187
     188    file = ap_server_root_relative(spool, arg);
     189
     190    if (load_datum_from_file(spool, file, &data) != 0) {
     191        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     192                "Certificate '%s'", file);
     193    }
     194
     195    ret = gnutls_openpgp_crt_init(&sc->cert_pgp);
     196    if (ret < 0) {
     197        return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
     198                "PGP Certificate: (%d) %s", ret,
     199                gnutls_strerror(ret));
     200    }
     201
     202    ret =
     203            gnutls_openpgp_crt_import(sc->cert_pgp, &data,
     204            GNUTLS_OPENPGP_FMT_BASE64);
     205    if (ret < 0) {
     206        return apr_psprintf(parms->pool,
     207                "GnuTLS: Failed to Import "
     208                "PGP Certificate '%s': (%d) %s", file,
     209                ret, gnutls_strerror(ret));
     210    }
     211
    534212    apr_pool_destroy(spool);
    535 
    536     return ret;
    537 }
    538 
    539 int mgs_pkcs11_reinit(server_rec * base_server)
    540 {
     213    return NULL;
     214}
     215
     216const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)),
     217        const char *arg) {
    541218    int ret;
    542     server_rec *s;
    543     mgs_srvconf_rec *sc;
    544 
    545     gnutls_pkcs11_reinit();
    546 
    547     for (s = base_server; s; s = s->next) {
    548         sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    549 
    550             /* gnutls caches the session in a private key, so we need to open
    551              * a new one */
    552             if (sc->x509_key_file && gnutls_url_is_supported(sc->x509_key_file) != 0) {
    553                 gnutls_privkey_deinit(sc->privkey_x509);
    554 
    555                 ret = gnutls_privkey_init(&sc->privkey_x509);
    556                 if (ret < 0) {
    557                     ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
    558                                  "GnuTLS: Failed to initialize: (%d) %s", ret,
    559                                  gnutls_strerror(ret));
    560                     goto fail;
    561                 }
    562 
    563                 gnutls_privkey_set_pin_function(sc->privkey_x509, pin_callback, sc);
    564 
    565                 ret = gnutls_privkey_import_url(sc->privkey_x509, sc->x509_key_file, 0);
    566                 if (ret < 0) {
    567                     ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
    568                              "GnuTLS: Failed to Re-Import Private Key URL '%s': (%d) %s",
    569                              sc->x509_key_file, ret, gnutls_strerror(ret));
    570                     goto fail;
    571                 }
    572             }
    573     }
    574 
    575     return 0;
    576 
    577  fail:
    578     gnutls_privkey_deinit(sc->privkey_x509);
    579     return -1;
    580 }
    581 
    582 const char *mgs_set_dh_file(cmd_parms * parms, void *dummy __attribute__((unused)),
    583         const char *arg) {
    584     mgs_srvconf_rec *sc =
    585         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    586                                                  module_config,
    587                                                  &gnutls_module);
    588 
    589     sc->dh_file = ap_server_root_relative(parms->pool, arg);
    590 
    591     return NULL;
    592 }
    593 
    594 const char *mgs_set_cert_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
    595 
    596     mgs_srvconf_rec *sc =
    597         (mgs_srvconf_rec *) ap_get_module_config(parms->
    598                                                  server->module_config,
    599                                                  &gnutls_module);
    600 
    601     sc->x509_cert_file = apr_pstrdup(parms->pool, arg);
    602 
    603     return NULL;
    604 
    605 }
    606 
    607 const char *mgs_set_key_file(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
    608 
    609     mgs_srvconf_rec *sc =
    610         (mgs_srvconf_rec *) ap_get_module_config(parms->
    611                                                  server->module_config,
    612                                                  &gnutls_module);
    613 
    614     sc->x509_key_file = apr_pstrdup(parms->pool, arg);
    615 
    616     return NULL;
    617 }
    618 
    619 const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy __attribute__((unused)),
    620         const char *arg)
    621 {
    622     mgs_srvconf_rec *sc =
    623         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    624                                                  module_config,
    625                                                  &gnutls_module);
    626 
    627     sc->pgp_cert_file = ap_server_root_relative(parms->pool, arg);
    628 
    629     return NULL;
    630 }
    631 
    632 const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy __attribute__((unused)),
    633         const char *arg) {
    634     mgs_srvconf_rec *sc =
    635         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    636                                                  module_config,
    637                                                  &gnutls_module);
    638 
    639     sc->pgp_key_file = ap_server_root_relative(parms->pool, arg);
    640 
     219    gnutls_datum_t data;
     220    const char *file;
     221    apr_pool_t *spool;
     222    mgs_srvconf_rec *sc =
     223            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     224            module_config,
     225            &gnutls_module);
     226    apr_pool_create(&spool, parms->pool);
     227
     228    file = ap_server_root_relative(spool, arg);
     229
     230    if (load_datum_from_file(spool, file, &data) != 0) {
     231        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     232                "Private Key '%s'", file);
     233    }
     234
     235    ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
     236    if (ret < 0) {
     237        return apr_psprintf(parms->pool,
     238                "GnuTLS: Failed to initialize"
     239                ": (%d) %s", ret,
     240                gnutls_strerror(ret));
     241    }
     242
     243    ret =
     244            gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
     245            GNUTLS_OPENPGP_FMT_BASE64, NULL,
     246            0);
     247    if (ret != 0) {
     248        return apr_psprintf(parms->pool,
     249                "GnuTLS: Failed to Import "
     250                "PGP Private Key '%s': (%d) %s", file,
     251                ret, gnutls_strerror(ret));
     252    }
     253    apr_pool_destroy(spool);
    641254    return NULL;
    642255}
     
    645258        const char *arg) {
    646259    mgs_srvconf_rec *sc =
    647         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    648                                                 module_config,
    649                                                 &gnutls_module);
     260            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     261            module_config,
     262            &gnutls_module);
    650263
    651264    sc->tickets = 0;
    652265    if (strcasecmp("on", arg) == 0) {
    653         sc->tickets = 1;
     266        sc->tickets = 1;
    654267    }
    655268
     
    663276        const char *arg) {
    664277    mgs_srvconf_rec *sc =
    665         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    666                                                 module_config,
    667                                                 &gnutls_module);
     278            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     279            module_config,
     280            &gnutls_module);
    668281
    669282    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
     
    675288        const char *arg) {
    676289    mgs_srvconf_rec *sc =
    677         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    678                                                  module_config,
    679                                                  &gnutls_module);
    680 
    681     sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
     290            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     291            module_config,
     292            &gnutls_module);
     293
     294    sc->srp_tpasswd_conf_file =
     295            ap_server_root_relative(parms->pool, arg);
    682296
    683297    return NULL;
     
    690304    const char *err;
    691305    mgs_srvconf_rec *sc =
    692         ap_get_module_config(parms->server->module_config,
    693                              &gnutls_module);
     306            ap_get_module_config(parms->server->module_config,
     307            &gnutls_module);
    694308    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    695         return err;
     309        return err;
    696310    }
    697311
    698312    if (strcasecmp("none", type) == 0) {
    699         sc->cache_type = mgs_cache_none;
    700         sc->cache_config = NULL;
    701         return NULL;
     313        sc->cache_type = mgs_cache_none;
     314        sc->cache_config = NULL;
     315        return NULL;
    702316    } else if (strcasecmp("dbm", type) == 0) {
    703         sc->cache_type = mgs_cache_dbm;
     317        sc->cache_type = mgs_cache_dbm;
    704318    } else if (strcasecmp("gdbm", type) == 0) {
    705         sc->cache_type = mgs_cache_gdbm;
     319        sc->cache_type = mgs_cache_gdbm;
    706320    }
    707321#if HAVE_APR_MEMCACHE
    708322    else if (strcasecmp("memcache", type) == 0) {
    709         sc->cache_type = mgs_cache_memcache;
     323        sc->cache_type = mgs_cache_memcache;
    710324    }
    711325#endif
    712326    else {
    713         return "Invalid Type for GnuTLSCache!";
     327        return "Invalid Type for GnuTLSCache!";
    714328    }
    715329
    716330    if (arg == NULL)
    717         return "Invalid argument 2 for GnuTLSCache!";
     331        return "Invalid argument 2 for GnuTLSCache!";
    718332
    719333    if (sc->cache_type == mgs_cache_dbm
    720         || sc->cache_type == mgs_cache_gdbm) {
    721         sc->cache_config = ap_server_root_relative(parms->pool, arg);
     334            || sc->cache_type == mgs_cache_gdbm) {
     335        sc->cache_config =
     336                ap_server_root_relative(parms->pool, arg);
    722337    } else {
    723         sc->cache_config = apr_pstrdup(parms->pool, arg);
     338        sc->cache_config = apr_pstrdup(parms->pool, arg);
    724339    }
    725340
     
    732347    const char *err;
    733348    mgs_srvconf_rec *sc =
    734         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    735                                                 module_config,
    736                                                 &gnutls_module);
     349            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     350            module_config,
     351            &gnutls_module);
    737352
    738353    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    739         return err;
     354        return err;
    740355    }
    741356
     
    743358
    744359    if (argint < 0) {
    745         return "GnuTLSCacheTimeout: Invalid argument";
     360        return "GnuTLSCacheTimeout: Invalid argument";
    746361    } else if (argint == 0) {
    747         sc->cache_timeout = 0;
     362        sc->cache_timeout = 0;
    748363    } else {
    749         sc->cache_timeout = apr_time_from_sec(argint);
     364        sc->cache_timeout = apr_time_from_sec(argint);
    750365    }
    751366
     
    758373
    759374    if (strcasecmp("cartel", arg) == 0) {
    760         sc->client_verify_method = mgs_cvm_cartel;
     375        sc->client_verify_method = mgs_cvm_cartel;
    761376    } else if (strcasecmp("msva", arg) == 0) {
    762377#ifdef ENABLE_MSVA
    763         sc->client_verify_method = mgs_cvm_msva;
     378        sc->client_verify_method = mgs_cvm_msva;
    764379#else
    765         return "GnuTLSClientVerifyMethod: msva is not supported";
     380        return "GnuTLSClientVerifyMethod: msva is not supported";
    766381#endif
    767382    } else {
    768         return "GnuTLSClientVerifyMethod: Invalid argument";
     383        return "GnuTLSClientVerifyMethod: Invalid argument";
    769384    }
    770385
     
    778393
    779394    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
    780         mode = GNUTLS_CERT_IGNORE;
     395        mode = GNUTLS_CERT_IGNORE;
    781396    } else if (strcasecmp("optional", arg) == 0
    782                || strcasecmp("request", arg) == 0) {
    783         mode = GNUTLS_CERT_REQUEST;
     397            || strcasecmp("request", arg) == 0) {
     398        mode = GNUTLS_CERT_REQUEST;
    784399    } else if (strcasecmp("require", arg) == 0) {
    785         mode = GNUTLS_CERT_REQUIRE;
     400        mode = GNUTLS_CERT_REQUIRE;
    786401    } else {
    787         return "GnuTLSClientVerify: Invalid argument";
     402        return "GnuTLSClientVerify: Invalid argument";
    788403    }
    789404
     
    793408        dc->client_verify_mode = mode;
    794409    } else {
    795         mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    796             ap_get_module_config(parms->server->module_config,
    797                                  &gnutls_module);
    798         sc->client_verify_mode = mode;
    799     }
    800 
    801     return NULL;
    802 }
     410        mgs_srvconf_rec *sc =
     411                (mgs_srvconf_rec *)
     412                ap_get_module_config(parms->server->module_config,
     413                &gnutls_module);
     414        sc->client_verify_mode = mode;
     415    }
     416
     417    return NULL;
     418}
     419
     420#define INIT_CA_SIZE 128
    803421
    804422const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy __attribute__((unused)),
    805423        const char *arg) {
    806     mgs_srvconf_rec *sc =
    807         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    808                                                  module_config,
    809                                                  &gnutls_module);
    810 
    811     sc->x509_ca_file = ap_server_root_relative(parms->pool, arg);
    812 
     424    int rv;
     425    const char *file;
     426    apr_pool_t *spool;
     427    gnutls_datum_t data;
     428
     429    mgs_srvconf_rec *sc =
     430            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     431            module_config,
     432            &gnutls_module);
     433    apr_pool_create(&spool, parms->pool);
     434
     435    file = ap_server_root_relative(spool, arg);
     436
     437    if (load_datum_from_file(spool, file, &data) != 0) {
     438        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     439                "Client CA File '%s'", file);
     440    }
     441
     442    sc->ca_list_size = INIT_CA_SIZE;
     443    sc->ca_list = malloc(sc->ca_list_size * sizeof (*sc->ca_list));
     444    if (sc->ca_list == NULL) {
     445        return apr_psprintf(parms->pool,
     446                "mod_gnutls: Memory allocation error");
     447    }
     448
     449    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
     450            &data, GNUTLS_X509_FMT_PEM,
     451            GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
     452    if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) {
     453        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
     454                "Client CA File '%s': (%d) %s", file,
     455                rv, gnutls_strerror(rv));
     456    }
     457
     458    if (INIT_CA_SIZE < sc->ca_list_size) {
     459        sc->ca_list =
     460                realloc(sc->ca_list,
     461                sc->ca_list_size * sizeof (*sc->ca_list));
     462        if (sc->ca_list == NULL) {
     463            return apr_psprintf(parms->pool,
     464                    "mod_gnutls: Memory allocation error");
     465        }
     466
     467        /* re-read */
     468        rv = gnutls_x509_crt_list_import(sc->ca_list,
     469                &sc->ca_list_size, &data,
     470                GNUTLS_X509_FMT_PEM, 0);
     471
     472        if (rv < 0) {
     473            return apr_psprintf(parms->pool,
     474                    "GnuTLS: Failed to load "
     475                    "Client CA File '%s': (%d) %s",
     476                    file, rv, gnutls_strerror(rv));
     477        }
     478    }
     479
     480    apr_pool_destroy(spool);
    813481    return NULL;
    814482}
     
    816484const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy __attribute__((unused)),
    817485        const char *arg) {
    818     mgs_srvconf_rec *sc =
    819         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    820                                                  module_config,
    821                                                  &gnutls_module);
    822 
    823     sc->pgp_ring_file = ap_server_root_relative(parms->pool, arg);
    824 
     486    int rv;
     487    const char *file;
     488    apr_pool_t *spool;
     489    gnutls_datum_t data;
     490
     491    mgs_srvconf_rec *sc =
     492            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     493            module_config,
     494            &gnutls_module);
     495    apr_pool_create(&spool, parms->pool);
     496
     497    file = ap_server_root_relative(spool, arg);
     498
     499    if (load_datum_from_file(spool, file, &data) != 0) {
     500        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     501                "Keyring File '%s'", file);
     502    }
     503
     504    rv = gnutls_openpgp_keyring_init(&sc->pgp_list);
     505    if (rv < 0) {
     506        return apr_psprintf(parms->pool,
     507                "GnuTLS: Failed to initialize"
     508                "keyring: (%d) %s", rv,
     509                gnutls_strerror(rv));
     510    }
     511
     512    rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data,
     513            GNUTLS_OPENPGP_FMT_BASE64);
     514    if (rv < 0) {
     515        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
     516                "Keyring File '%s': (%d) %s", file, rv,
     517                gnutls_strerror(rv));
     518    }
     519
     520    apr_pool_destroy(spool);
    825521    return NULL;
    826522}
     
    829525        const char *arg) {
    830526
    831     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    832         ap_get_module_config(parms->server->module_config, &gnutls_module);
     527    mgs_srvconf_rec *sc =(mgs_srvconf_rec *)
     528            ap_get_module_config(parms->server->module_config, &gnutls_module);
    833529
    834530    if (!strcasecmp(arg, "On")) {
    835         sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
     531        sc->proxy_enabled = GNUTLS_ENABLED_TRUE;
    836532    } else if (!strcasecmp(arg, "Off")) {
    837         sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
     533        sc->proxy_enabled = GNUTLS_ENABLED_FALSE;
    838534    } else {
    839         return "GnuTLSProxyEngine must be set to 'On' or 'Off'";
     535        return "SSLProxyEngine must be set to 'On' or 'Off'";
    840536    }
    841537
     
    846542        const char *arg) {
    847543    mgs_srvconf_rec *sc =
    848         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    849                                                 module_config,
    850                                                 &gnutls_module);
     544            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     545            module_config,
     546            &gnutls_module);
    851547    if (!strcasecmp(arg, "On")) {
    852         sc->enabled = GNUTLS_ENABLED_TRUE;
     548        sc->enabled = GNUTLS_ENABLED_TRUE;
    853549    } else if (!strcasecmp(arg, "Off")) {
    854         sc->enabled = GNUTLS_ENABLED_FALSE;
     550        sc->enabled = GNUTLS_ENABLED_FALSE;
    855551    } else {
    856         return "GnuTLSEnable must be set to 'On' or 'Off'";
     552        return "GnuTLSEnable must be set to 'On' or 'Off'";
    857553    }
    858554
     
    863559    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(parms->server->module_config, &gnutls_module);
    864560    if (!strcasecmp(arg, "On")) {
    865         sc->export_certificates_size = 16 * 1024;
     561        sc->export_certificates_size = 16 * 1024;
    866562    } else if (!strcasecmp(arg, "Off")) {
    867         sc->export_certificates_size = 0;
     563        sc->export_certificates_size = 0;
    868564    } else {
    869         char *endptr;
    870         sc->export_certificates_size = strtol(arg, &endptr, 10);
    871         while (apr_isspace(*endptr))
    872             endptr++;
    873         if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
    874             ;
    875         } else if (*endptr == 'k' || *endptr == 'K') {
    876             sc->export_certificates_size *= 1024;
    877         } else {
    878             return
    879                 "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
    880         }
    881     }
    882 
    883     return NULL;
    884 }
    885 
    886 
    887 
    888 /*
    889  * Store GnuTLS priority strings. Used for GnuTLSPriorities and
    890  * GnuTLSProxyPriorities.
    891  */
    892 const char *mgs_set_priorities(cmd_parms * parms,
    893                                void *dummy __attribute__((unused)),
    894                                const char *arg)
    895 {
     565        char* endptr;
     566        sc->export_certificates_size = strtol(arg, &endptr, 10);
     567        while (apr_isspace(*endptr)) endptr++;
     568        if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
     569            ;
     570        } else if (*endptr == 'k' || *endptr == 'K') {
     571            sc->export_certificates_size *= 1024;
     572        } else {
     573            return "GnuTLSExportCertificates must be set to a size (in bytes) or 'On' or 'Off'";
     574        }
     575    }
     576
     577    return NULL;
     578}
     579
     580const char *mgs_set_priorities(cmd_parms * parms, void *dummy __attribute__((unused)), const char *arg) {
     581
     582        int ret;
     583    const char *err;
     584
    896585    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    897         ap_get_module_config(parms->server->module_config, &gnutls_module);
    898 
    899     if (!strcasecmp(parms->directive->directive, "GnuTLSPriorities"))
    900         sc->priorities_str = apr_pstrdup(parms->pool, arg);
    901     else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyPriorities"))
    902         sc->proxy_priorities_str = apr_pstrdup(parms->pool, arg);
    903     else
    904         /* Can't happen unless there's a serious bug in mod_gnutls or Apache */
    905         return apr_psprintf(parms->pool,
    906                             "mod_gnutls: %s called for invalid option '%s'",
    907                             __func__, parms->directive->directive);
    908 
    909     return NULL;
    910 }
    911 
    912 
    913 
    914 const char *mgs_set_pin(cmd_parms * parms, void *dummy __attribute__((unused)),
    915                         const char *arg)
    916 {
    917 
    918     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    919         ap_get_module_config(parms->server->module_config, &gnutls_module);
    920 
    921     sc->pin = apr_pstrdup(parms->pool, arg);
    922 
    923     return NULL;
    924 }
    925 
    926 const char *mgs_set_srk_pin(cmd_parms * parms,
    927                             void *dummy __attribute__((unused)),
    928                             const char *arg)
    929 {
    930 
    931     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    932         ap_get_module_config(parms->server->module_config, &gnutls_module);
    933 
    934     sc->srk_pin = apr_pstrdup(parms->pool, arg);
    935 
    936     return NULL;
    937 }
    938 
    939 
    940 
    941 static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p,
    942                                                   char **err __attribute__((unused)))
    943 {
    944     mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
     586                                                  ap_get_module_config(parms->server->module_config, &gnutls_module);
     587
     588    ret = gnutls_priority_init(&sc->priorities, arg, &err);
     589
     590    if (ret < 0) {
     591        if (ret == GNUTLS_E_INVALID_REQUEST) {
     592            return apr_psprintf(parms->pool,
     593                                                                "GnuTLS: Syntax error parsing priorities string at: %s", err);
     594                }
     595        return "Error setting priorities";
     596    }
     597
     598    return NULL;
     599}
     600
     601static mgs_srvconf_rec *_mgs_config_server_create(apr_pool_t * p, char** err) {
     602    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof (*sc));
     603    int ret;
    945604
    946605    sc->enabled = GNUTLS_ENABLED_UNSET;
    947606
     607    ret = gnutls_certificate_allocate_credentials(&sc->certs);
     608    if (ret < 0) {
     609        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
     610                            ": (%d) %s", ret,
     611                            gnutls_strerror(ret));
     612        return NULL;
     613    }
     614
     615    ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds);
     616    if (ret < 0) {
     617        *err = apr_psprintf(p, "GnuTLS: Failed to initialize"
     618                            ": (%d) %s", ret,
     619                            gnutls_strerror(ret));
     620        return NULL;
     621    }
     622#ifdef ENABLE_SRP
     623    ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds);
     624    if (ret < 0) {
     625        *err =  apr_psprintf(p, "GnuTLS: Failed to initialize"
     626                             ": (%d) %s", ret,
     627                             gnutls_strerror(ret));
     628        return NULL;
     629    }
     630
     631    sc->srp_tpasswd_conf_file = NULL;
     632    sc->srp_tpasswd_file = NULL;
     633#endif
     634
    948635    sc->privkey_x509 = NULL;
    949     sc->privkey_pgp = NULL;
     636        /* Initialize all Certificate Chains */
     637    /* FIXME: how do we indicate that this is unset for a merge? (that
     638     * is, how can a subordinate server override the chain by setting
     639     * an empty one?  what would that even look like in the
     640     * configuration?) */
     641        sc->certs_x509_chain = malloc(MAX_CHAIN_SIZE * sizeof (*sc->certs_x509_chain));
    950642    sc->certs_x509_chain_num = 0;
    951     sc->p11_module = NULL;
    952     sc->pin = NULL;
    953     sc->priorities_str = NULL;
    954     sc->cache_timeout = -1;     /* -1 means "unset" */
     643    sc->cache_timeout = -1; /* -1 means "unset" */
    955644    sc->cache_type = mgs_cache_unset;
    956645    sc->cache_config = NULL;
     
    962651    sc->client_verify_method = mgs_cvm_unset;
    963652
    964     sc->proxy_x509_key_file = NULL;
    965     sc->proxy_x509_cert_file = NULL;
    966     sc->proxy_x509_ca_file = NULL;
    967     sc->proxy_x509_crl_file = NULL;
    968     sc->proxy_priorities_str = NULL;
    969     sc->proxy_priorities = NULL;
    970 
    971653/* this relies on GnuTLS never changing the gnutls_certificate_request_t enum to define -1 */
    972654    sc->client_verify_mode = -1;
     
    979661    char *err = NULL;
    980662    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
    981     if (sc)
    982         return sc;
    983     else
    984         return err;
     663    if (sc) return sc; else return err;
    985664}
    986665
     
    988667#define gnutls_srvconf_assign(t) sc->t = add->t
    989668
    990 void *mgs_config_server_merge(apr_pool_t * p, void *BASE, void *ADD)
    991 {
     669void *mgs_config_server_merge(apr_pool_t *p, void *BASE, void *ADD) {
    992670    int i;
    993671    char *err = NULL;
    994     mgs_srvconf_rec *base = (mgs_srvconf_rec *) BASE;
    995     mgs_srvconf_rec *add = (mgs_srvconf_rec *) ADD;
     672    mgs_srvconf_rec *base = (mgs_srvconf_rec *)BASE;
     673    mgs_srvconf_rec *add = (mgs_srvconf_rec *)ADD;
    996674    mgs_srvconf_rec *sc = _mgs_config_server_create(p, &err);
    997     if (NULL == sc)
    998         return err;
     675    if (NULL == sc) return err;
    999676
    1000677    gnutls_srvconf_merge(enabled, GNUTLS_ENABLED_UNSET);
     
    1006683    gnutls_srvconf_merge(srp_tpasswd_file, NULL);
    1007684    gnutls_srvconf_merge(srp_tpasswd_conf_file, NULL);
    1008     gnutls_srvconf_merge(x509_cert_file, NULL);
    1009 
    1010     gnutls_srvconf_merge(x509_key_file, NULL);
    1011     gnutls_srvconf_merge(x509_ca_file, NULL);
    1012     gnutls_srvconf_merge(p11_module, NULL);
    1013     gnutls_srvconf_merge(pin, NULL);
    1014     gnutls_srvconf_merge(pgp_cert_file, NULL);
    1015     gnutls_srvconf_merge(pgp_key_file, NULL);
    1016     gnutls_srvconf_merge(pgp_ring_file, NULL);
    1017     gnutls_srvconf_merge(dh_file, NULL);
    1018     gnutls_srvconf_merge(priorities_str, NULL);
    1019 
    1020     gnutls_srvconf_merge(proxy_x509_key_file, NULL);
    1021     gnutls_srvconf_merge(proxy_x509_cert_file, NULL);
    1022     gnutls_srvconf_merge(proxy_x509_ca_file, NULL);
    1023     gnutls_srvconf_merge(proxy_x509_crl_file, NULL);
    1024     gnutls_srvconf_merge(proxy_priorities_str, NULL);
    1025     gnutls_srvconf_merge(proxy_priorities, NULL);
     685    gnutls_srvconf_merge(privkey_x509, NULL);
     686    gnutls_srvconf_merge(priorities, NULL);
     687    gnutls_srvconf_merge(dh_params, NULL);
    1026688
    1027689    /* FIXME: the following items are pre-allocated, and should be
    1028690     * properly disposed of before assigning in order to avoid leaks;
    1029691     * so at the moment, we can't actually have them in the config.
    1030      * what happens during de-allocation? */
    1031     /* TODO: mgs_load_files takes care of most of these now, verify
    1032      * and clean up the following lines */
    1033     gnutls_srvconf_assign(ca_list);
    1034     gnutls_srvconf_assign(ca_list_size);
    1035     gnutls_srvconf_assign(cert_pgp);
    1036     gnutls_srvconf_assign(cert_crt_pgp);
    1037     gnutls_srvconf_assign(pgp_list);
     692     * what happens during de-allocation?
     693
     694     * This is probably leaky.
     695     */
    1038696    gnutls_srvconf_assign(certs);
    1039697    gnutls_srvconf_assign(anon_creds);
    1040698    gnutls_srvconf_assign(srp_creds);
    1041699    gnutls_srvconf_assign(certs_x509_chain);
    1042     gnutls_srvconf_assign(certs_x509_crt_chain);
    1043700    gnutls_srvconf_assign(certs_x509_chain_num);
    1044701
     
    1047704    gnutls_srvconf_assign(cert_cn);
    1048705    for (i = 0; i < MAX_CERT_SAN; i++)
    1049         gnutls_srvconf_assign(cert_san[i]);
     706        gnutls_srvconf_assign(cert_san[i]);
     707    gnutls_srvconf_assign(ca_list);
     708    gnutls_srvconf_assign(ca_list_size);
     709    gnutls_srvconf_assign(cert_pgp);
     710    gnutls_srvconf_assign(pgp_list);
     711    gnutls_srvconf_assign(privkey_pgp);
    1050712
    1051713    return sc;
     
    1062724    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
    1063725
    1064     new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
     726    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof (mgs_dirconf_rec));
    1065727    new->client_verify_mode = add->client_verify_mode;
    1066728    return new;
     
    1074736}
    1075737
    1076 
    1077 
    1078 /*
    1079  * Store paths to proxy credentials
    1080  *
    1081  * This function copies the paths provided in the configuration file
    1082  * into the server configuration. The post configuration hook takes
    1083  * care of actually loading the credentials, which means than invalid
    1084  * paths or the like will be detected there.
    1085  */
    1086 const char *mgs_store_cred_path(cmd_parms * parms,
    1087                                 void *dummy __attribute__((unused)),
    1088                                 const char *arg)
    1089 {
    1090     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    1091         ap_get_module_config(parms->server->module_config, &gnutls_module);
    1092 
    1093     /* parms->directive->directive contains the directive string */
    1094     if (!strcasecmp(parms->directive->directive, "GnuTLSProxyKeyFile"))
    1095         sc->proxy_x509_key_file = apr_pstrdup(parms->pool, arg);
    1096     else if (!strcasecmp(parms->directive->directive,
    1097                          "GnuTLSProxyCertificateFile"))
    1098         sc->proxy_x509_cert_file = apr_pstrdup(parms->pool, arg);
    1099     else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCAFile"))
    1100         sc->proxy_x509_ca_file = apr_pstrdup(parms->pool, arg);
    1101     else if (!strcasecmp(parms->directive->directive, "GnuTLSProxyCRLFile"))
    1102         sc->proxy_x509_crl_file = apr_pstrdup(parms->pool, arg);
    1103     return NULL;
    1104 }
    1105 
    1106 
    1107 
    1108 /*
    1109  * Record additional PKCS #11 module to load. Note that the value is
    1110  * only used in the base config, settings in virtual hosts are
    1111  * ignored.
    1112  */
    1113 const char *mgs_set_p11_module(cmd_parms * parms,
    1114                                void *dummy __attribute__((unused)),
    1115                                const char *arg)
    1116 {
    1117     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    1118         ap_get_module_config(parms->server->module_config, &gnutls_module);
    1119     sc->p11_module = apr_pstrdup(parms->pool, arg);
    1120     return NULL;
    1121 }
  • src/gnutls_hooks.c

    r9b20a1e r2afbe2e  
    44 *  Copyright 2011 Dash Shendy
    55 *  Copyright 2013-2014 Daniel Kahn Gillmor
    6  *  Copyright 2015 Thomas Klute
    76 *
    87 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    4140#endif
    4241
    43 #define IS_PROXY_STR(c) \
    44     ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "")
    45 
    4642static gnutls_datum_t session_ticket_key = {NULL, 0};
    4743
     
    5450static const char* mgs_x509_construct_uid(request_rec * pool, gnutls_x509_crt_t cert);
    5551#endif
    56 static int load_proxy_x509_credentials(server_rec *s);
    5752
    5853/* Pool Cleanup Function */
     
    152147    gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode);
    153148
    154     /* Set x509 credentials */
     149    /* Set Anon credentials */
    155150    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    156     /* Set Anon credentials */
     151        /* Set x509 credentials */
    157152    gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds);
    158153
     
    176171
    177172static int cert_retrieve_fn(gnutls_session_t session,
    178                             const gnutls_datum_t * req_ca_rdn __attribute__((unused)),
    179                             int nreqs __attribute__((unused)),
    180                             const gnutls_pk_algorithm_t * pk_algos __attribute__((unused)),
    181                             int pk_algos_length __attribute__((unused)),
    182                             gnutls_pcert_st **pcerts,
    183                             unsigned int *pcert_length,
    184                             gnutls_privkey_t *privkey)
    185 {
    186     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    187 
    188     mgs_handle_t *ctxt;
     173                                                        const gnutls_datum_t * req_ca_rdn __attribute__((unused)), int nreqs __attribute__((unused)),
     174                                                        const gnutls_pk_algorithm_t * pk_algos __attribute__((unused)), int pk_algos_length __attribute__((unused)),
     175                                                        gnutls_retr2_st *ret) {
     176
     177
     178        _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     179
     180        mgs_handle_t *ctxt;
    189181
    190182    if (session == NULL) {
    191183                // ERROR INVALID SESSION
     184                ret->ncerts = 0;
     185                ret->deinit_all = 1;
    192186        return -1;
    193     }
    194 
     187        }
    195188    ctxt = gnutls_transport_get_ptr(session);
    196189
    197190    if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    198191                // X509 CERTIFICATE
    199         *pcerts = ctxt->sc->certs_x509_chain;
    200         *pcert_length = ctxt->sc->certs_x509_chain_num;
    201         *privkey = ctxt->sc->privkey_x509;
     192                ret->cert_type = GNUTLS_CRT_X509;
     193                ret->key_type = GNUTLS_PRIVKEY_X509;
     194        ret->ncerts = ctxt->sc->certs_x509_chain_num;
     195        ret->deinit_all = 0;
     196        ret->cert.x509 = ctxt->sc->certs_x509_chain;
     197        ret->key.x509 = ctxt->sc->privkey_x509;
    202198        return 0;
    203199    } else if (gnutls_certificate_type_get(session) == GNUTLS_CRT_OPENPGP) {
    204200                // OPENPGP CERTIFICATE
    205         *pcerts = ctxt->sc->cert_pgp;
    206         *pcert_length = 1;
    207         *privkey = ctxt->sc->privkey_pgp;
     201                ret->cert_type = GNUTLS_CRT_OPENPGP;
     202                ret->key_type = GNUTLS_PRIVKEY_OPENPGP;
     203        ret->ncerts = 1;
     204        ret->deinit_all = 0;
     205        ret->cert.pgp = ctxt->sc->cert_pgp;
     206        ret->key.pgp = ctxt->sc->privkey_pgp;
    208207        return 0;
    209208    } else {
    210209                // UNKNOWN CERTIFICATE
     210                ret->ncerts = 0;
     211                ret->deinit_all = 1;
    211212            return -1;
    212213        }
    213214}
     215
     216/* 2048-bit group parameters from SRP specification */
     217const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
     218        "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
     219        "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
     220        "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
     221        "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
     222        "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
     223        "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
     224        "-----END DH PARAMETERS-----\n";
    214225
    215226/* Read the common name or the alternative name of the certificate.
     
    311322    }
    312323
     324
    313325    s = base_server;
    314326    sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    315327
     328    gnutls_dh_params_init(&dh_params);
     329
     330    if (sc_base->dh_params == NULL) {
     331        gnutls_datum_t pdata = {
     332            (void *) static_dh_params,
     333            sizeof(static_dh_params)
     334        };
     335        rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, GNUTLS_X509_FMT_PEM);
     336        /* Generate DH Params
     337        int dh_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH,
     338                GNUTLS_SEC_PARAM_NORMAL);
     339        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     340            "GnuTLS: Generating DH Params of %i bits.  "
     341            "To avoid this use GnuTLSDHFile to specify DH Params for this host",
     342            dh_bits);
     343#if MOD_GNUTLS_DEBUG
     344            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
     345                    "GnuTLS: Generated DH Params of %i bits",dh_bits);
     346#endif
     347        rv = gnutls_dh_params_generate2 (dh_params,dh_bits);
     348        */
     349        if (rv < 0) {
     350            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     351                    "GnuTLS: Unable to generate or load DH Params: (%d) %s",
     352                    rv, gnutls_strerror(rv));
     353            exit(rv);
     354        }
     355    } else {
     356        dh_params = sc_base->dh_params;
     357    }
    316358
    317359    rv = mgs_cache_post_config(p, s, sc_base);
     
    323365    }
    324366
    325     /* Load additional PKCS #11 module, if requested */
    326     if (sc_base->p11_module != NULL)
    327     {
    328         rv = gnutls_pkcs11_add_provider(sc_base->p11_module, NULL);
    329         if (rv != GNUTLS_E_SUCCESS)
    330             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    331                          "GnuTLS: Loading PKCS #11 provider module %s "
    332                          "failed: %s (%d).",
    333                          sc_base->p11_module, gnutls_strerror(rv), rv);
    334     }
    335 
    336367    for (s = base_server; s; s = s->next) {
    337368        sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
     
    339370        sc->cache_config = sc_base->cache_config;
    340371        sc->cache_timeout = sc_base->cache_timeout;
    341 
    342         rv = mgs_load_files(p, s);
    343         if (rv != 0) {
    344             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    345                 "GnuTLS: Loading required files failed."
    346                 " Shutting Down.");
    347             exit(-1);
    348         }
    349372
    350373        /* defaults for unset values: */
     
    360383            sc->client_verify_method = mgs_cvm_cartel;
    361384
     385
    362386        /* Check if the priorities have been set */
    363387        if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
     
    377401        }
    378402
    379         /* The call after this comment is a workaround for bug in
    380          * gnutls_certificate_set_retrieve_function2 that ignores
    381          * supported certificate types. Should be fixed in GnuTLS
    382          * 3.3.12.
    383          *
    384          * Details:
    385          * https://lists.gnupg.org/pipermail/gnutls-devel/2015-January/007377.html
    386          * Workaround from:
    387          * https://github.com/vanrein/tlspool/commit/4938102d3d1b086491d147e6c8e4e2a02825fc12 */
    388 #if GNUTLS_VERSION_NUMBER < 0x030312
    389         gnutls_certificate_set_retrieve_function(sc->certs, (void *) exit);
    390 #endif
    391 
    392         gnutls_certificate_set_retrieve_function2(sc->certs, cert_retrieve_fn);
     403        gnutls_certificate_set_retrieve_function(sc->certs, cert_retrieve_fn);
     404
     405#ifdef ENABLE_SRP
     406        if (sc->srp_tpasswd_conf_file != NULL
     407                && sc->srp_tpasswd_file != NULL) {
     408            rv = gnutls_srp_set_server_credentials_file
     409                    (sc->srp_creds, sc->srp_tpasswd_file,
     410                    sc->srp_tpasswd_conf_file);
     411
     412            if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) {
     413                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0,
     414                        s,
     415                        "[GnuTLS] - Host '%s:%d' is missing a "
     416                        "SRP password or conf File!",
     417                        s->server_hostname, s->port);
     418                exit(-1);
     419            }
     420        }
     421#endif
    393422
    394423        if ((sc->certs_x509_chain == NULL || sc->certs_x509_chain_num < 1) &&
    395424            sc->cert_pgp == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
    396425                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    397                                                 "GnuTLS: Host '%s:%d' is missing a Certificate File!",
     426                                                "[GnuTLS] - Host '%s:%d' is missing a Certificate File!",
    398427                                                s->server_hostname, s->port);
    399428            exit(-1);
    400429        }
     430
    401431        if (sc->enabled == GNUTLS_ENABLED_TRUE &&
    402             ((sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||
    403              (sc->cert_crt_pgp[0] != NULL && sc->privkey_pgp == NULL))) {
     432            ((sc->certs_x509_chain != NULL && sc->certs_x509_chain_num > 0 && sc->privkey_x509 == NULL) ||
     433             (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) {
    404434                        ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    405                                                 "GnuTLS: Host '%s:%d' is missing a Private Key File!",
     435                                                "[GnuTLS] - Host '%s:%d' is missing a Private Key File!",
    406436                                                s->server_hostname, s->port);
    407437            exit(-1);
     
    411441            rv = -1;
    412442            if (sc->certs_x509_chain_num > 0) {
    413                 rv = read_crt_cn(s, p, sc->certs_x509_crt_chain[0], &sc->cert_cn);
     443                rv = read_crt_cn(s, p, sc->certs_x509_chain[0], &sc->cert_cn);
    414444            }
    415445            if (rv < 0 && sc->cert_pgp != NULL) {
    416                 rv = read_pgpcrt_cn(s, p, sc->cert_crt_pgp[0], &sc->cert_cn);
     446                rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
    417447                        }
    418448
    419449            if (rv < 0) {
    420450                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    421                                                         "GnuTLS: Cannot find a certificate for host '%s:%d'!",
     451                                                        "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
    422452                                                        s->server_hostname, s->port);
    423453                sc->cert_cn = NULL;
    424454                continue;
    425455            }
    426         }
    427 
    428         if (sc->enabled == GNUTLS_ENABLED_TRUE
    429             && sc->proxy_enabled == GNUTLS_ENABLED_TRUE
    430             && load_proxy_x509_credentials(s) != APR_SUCCESS)
    431         {
    432             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    433                          "%s: loading proxy credentials for host "
    434                          "'%s:%d' failed, exiting!",
    435                          __func__, s->server_hostname, s->port);
    436             exit(-1);
    437456        }
    438457    }
     
    455474}
    456475
    457 void mgs_hook_child_init(apr_pool_t * p, server_rec *s) {
     476void mgs_hook_child_init(apr_pool_t * p, server_rec * s) {
    458477    apr_status_t rv = APR_SUCCESS;
    459     mgs_srvconf_rec *sc =
    460         (mgs_srvconf_rec *) ap_get_module_config(s->module_config, &gnutls_module);
    461 
    462     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    463     /* if we use PKCS #11 reinitialize it */
    464 
    465     if (mgs_pkcs11_reinit(s) < 0) {
    466             ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
    467                     "GnuTLS: Failed to reinitialize PKCS #11");
    468             exit(-1);
    469     }
    470 
     478    mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
     479            &gnutls_module);
     480
     481    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    471482    if (sc->cache_type != mgs_cache_none) {
    472483        rv = mgs_cache_child_init(p, s, sc);
    473484        if (rv != APR_SUCCESS) {
    474485            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
    475                     "GnuTLS: Failed to run Cache Init");
     486                    "[GnuTLS] - Failed to run Cache Init");
    476487        }
    477488    }
     
    594605
    595606    if (tsc->certs_x509_chain_num > 0) {
    596         /* this check is there to warn administrator of any missing hostname
    597          * in the certificate. */
    598         ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_crt_chain[0], s->server_hostname);
     607        /* why are we doing this check? */
     608        ret = gnutls_x509_crt_check_hostname(tsc->certs_x509_chain[0], s->server_hostname);
    599609        if (0 == ret)
    600             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
    601                          "GnuTLS: the certificate doesn't match requested hostname "
     610            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
     611                         "GnuTLS: Error checking certificate for hostname "
    602612                         "'%s'", s->server_hostname);
    603613    } else {
     
    610620#endif
    611621
    612 mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
    613 {
     622mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) {
    614623    int rv;
    615624    unsigned int sni_type;
     
    662671
    663672        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    664                                                        &gnutls_module);
     673                &gnutls_module);
    665674
    666675        if (tsc->enabled != GNUTLS_ENABLED_TRUE) { continue; }
    667676
    668         if(check_server_aliases(x, s, tsc)) {
    669             return tsc;
    670         }
    671     }
     677                                if(check_server_aliases(x, s, tsc)) {
     678                                        return tsc;
     679                                }
    672680#endif
    673681    return NULL;
    674682}
    675683
    676 /*
    677  * This function is intended as a cleanup handler for connections
    678  * using GnuTLS.
    679  *
    680  * @param data must point to the mgs_handle_t associated with the
    681  * connection
    682  */
    683 static apr_status_t cleanup_gnutls_session(void *data)
    684 {
    685     /* nothing to do */
    686     if (data == NULL)
    687         return APR_SUCCESS;
    688 
    689     /* check if session needs closing */
    690     mgs_handle_t *ctxt = (mgs_handle_t *) data;
    691     if (ctxt->session != NULL)
    692     {
    693         int ret;
    694         /* Try A Clean Shutdown */
    695         do
    696             ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    697         while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
    698         if (ret != GNUTLS_E_SUCCESS)
    699             ap_log_cerror(APLOG_MARK, APLOG_INFO, ret, ctxt->c,
    700                           "%s: error while closing TLS %sconnection: %s (%d)",
    701                           __func__, IS_PROXY_STR(ctxt),
    702                           gnutls_strerror(ret), ret);
    703         else
    704             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c,
    705                           "%s: TLS %sconnection closed.",
    706                           __func__, IS_PROXY_STR(ctxt));
    707         /* De-Initialize Session */
    708         gnutls_deinit(ctxt->session);
    709         ctxt->session = NULL;
    710     }
    711     return APR_SUCCESS;
    712 }
    713 
    714 static void create_gnutls_handle(conn_rec * c)
    715 {
    716     /* Get mod_gnutls server configuration */
    717     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    718             ap_get_module_config(c->base_server->module_config, &gnutls_module);
    719 
    720     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    721 
    722     /* Get connection specific configuration */
    723     mgs_handle_t *ctxt = (mgs_handle_t *) ap_get_module_config(c->conn_config, &gnutls_module);
    724     if (ctxt == NULL)
    725     {
    726         ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    727         ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    728         ctxt->is_proxy = GNUTLS_ENABLED_FALSE;
    729     }
    730     ctxt->enabled = GNUTLS_ENABLED_TRUE;
     684static void create_gnutls_handle(conn_rec * c) {
     685    mgs_handle_t *ctxt;
     686    /* Get mod_gnutls Configuration Record */
     687    mgs_srvconf_rec *sc =(mgs_srvconf_rec *)
     688            ap_get_module_config(c->base_server->module_config,&gnutls_module);
     689
     690    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     691    ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    731692    ctxt->c = c;
    732693    ctxt->sc = sc;
     
    739700    ctxt->output_blen = 0;
    740701    ctxt->output_length = 0;
    741 
    742702    /* Initialize GnuTLS Library */
    743     int err = 0;
    744     if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
    745     {
    746         /* this is an outgoing proxy connection, client mode */
    747         err = gnutls_init(&ctxt->session, GNUTLS_CLIENT);
    748         if (err != GNUTLS_E_SUCCESS)
    749             ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
    750                           "gnutls_init for proxy connection failed: %s (%d)",
    751                           gnutls_strerror(err), err);
    752         err = gnutls_session_ticket_enable_client(ctxt->session);
    753         if (err != GNUTLS_E_SUCCESS)
    754             ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
    755                           "gnutls_session_ticket_enable_client failed: %s (%d)",
    756                           gnutls_strerror(err), err);
    757         /* Try to close and deinit the session when the connection
    758          * pool is cleared. Note that mod_proxy might not close
    759          * connections immediately, if you need that, look at the
    760          * "proxy-nokeepalive" environment variable for
    761          * mod_proxy_http. */
    762         apr_pool_pre_cleanup_register(c->pool, ctxt, cleanup_gnutls_session);
    763     }
    764     else
    765     {
    766         /* incoming connection, server mode */
    767         err = gnutls_init(&ctxt->session, GNUTLS_SERVER);
    768         if (err != GNUTLS_E_SUCCESS)
    769             ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
    770                           "gnutls_init for server side failed: %s (%d)",
    771                           gnutls_strerror(err), err);
    772         /* Initialize Session Tickets */
    773         if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0)
    774         {
    775             err = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key);
    776             if (err != GNUTLS_E_SUCCESS)
    777                 ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
    778                               "gnutls_session_ticket_enable_server failed: %s (%d)",
    779                               gnutls_strerror(err), err);
    780         }
     703    gnutls_init(&ctxt->session, GNUTLS_SERVER);
     704    /* Initialize Session Tickets */
     705    if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) {
     706        gnutls_session_ticket_enable_server(ctxt->session,&session_ticket_key);
    781707    }
    782708
    783709    /* Set Default Priority */
    784         err = gnutls_priority_set_direct(ctxt->session, "NORMAL", NULL);
    785     if (err != GNUTLS_E_SUCCESS)
    786         ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c, "gnutls_priority_set_direct failed!");
     710        gnutls_priority_set_direct (ctxt->session, "NORMAL", NULL);
    787711    /* Set Handshake function */
    788712    gnutls_handshake_set_post_client_hello_function(ctxt->session,
    789713            mgs_select_virtual_server_cb);
    790 
    791     /* Set GnuTLS user pointer, so we can access the module session
    792      * context in GnuTLS callbacks */
    793     gnutls_session_set_ptr(ctxt->session, ctxt);
    794 
    795     /* If mod_gnutls is the TLS server, mgs_select_virtual_server_cb
    796      * will load appropriate credentials during handshake. However,
    797      * when handling a proxy backend connection, mod_gnutls acts as
    798      * TLS client and credentials must be loaded here. */
    799     if (ctxt->is_proxy == GNUTLS_ENABLED_TRUE)
    800     {
    801         /* Set anonymous client credentials for proxy connections */
    802         gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON,
    803                                ctxt->sc->anon_client_creds);
    804         /* Set x509 credentials */
    805         gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE,
    806                                ctxt->sc->proxy_x509_creds);
    807         /* Load priorities from the server configuration */
    808         err = gnutls_priority_set(ctxt->session, ctxt->sc->proxy_priorities);
    809         if (err != GNUTLS_E_SUCCESS)
    810             ap_log_cerror(APLOG_MARK, APLOG_ERR, err, c,
    811                           "%s: setting priorities for proxy connection "
    812                           "failed: %s (%d)",
    813                           __func__, gnutls_strerror(err), err);
    814     }
    815 
    816714    /* Initialize Session Cache */
    817715    mgs_cache_session_init(ctxt);
    818716
     717    /* Set this config for this connection */
     718    ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    819719    /* Set pull, push & ptr functions */
    820720    gnutls_transport_set_pull_function(ctxt->session,
     
    830730}
    831731
    832 int mgs_hook_pre_connection(conn_rec * c, void *csd __attribute__((unused)))
    833 {
    834     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
    835 
    836     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    837         ap_get_module_config(c->base_server->module_config, &gnutls_module);
    838     mgs_handle_t *ctxt = (mgs_handle_t *)
    839         ap_get_module_config(c->conn_config, &gnutls_module);
    840 
    841     if ((sc && (!sc->enabled)) || (ctxt && ctxt->enabled == GNUTLS_ENABLED_FALSE))
    842     {
    843         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "%s declined connection",
    844                       __func__);
     732int mgs_hook_pre_connection(conn_rec * c, void *csd __attribute__((unused))) {
     733    mgs_srvconf_rec *sc;
     734
     735    _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     736
     737    sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server->module_config,
     738            &gnutls_module);
     739
     740    if (sc && (!sc->enabled || sc->proxy_enabled == GNUTLS_ENABLED_TRUE)) {
    845741        return DECLINED;
    846742    }
     
    864760    apr_table_t *env = r->subprocess_env;
    865761
    866     ctxt = ap_get_module_config(r->connection->conn_config,
    867                                 &gnutls_module);
    868 
    869     if (!ctxt || ctxt->enabled != GNUTLS_ENABLED_TRUE || ctxt->session == NULL)
    870     {
    871         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "request declined in %s", __func__);
     762    ctxt =
     763            ap_get_module_config(r->connection->conn_config,
     764            &gnutls_module);
     765
     766    if (!ctxt || ctxt->session == NULL) {
    872767        return DECLINED;
    873768    }
     
    926821
    927822    if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) {
    928         mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_crt_chain[0], 0, ctxt->sc->export_certificates_size);
    929     } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {
    930         mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_crt_pgp[0], 0, ctxt->sc->export_certificates_size);
    931     }
     823                mgs_add_common_cert_vars(r, ctxt->sc->certs_x509_chain[0], 0, ctxt->sc->export_certificates_size);
     824        } else if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_OPENPGP) {
     825        mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, ctxt->sc->export_certificates_size);
     826        }
    932827
    933828    return rv;
     
    984879        }
    985880        rv = mgs_cert_verify(r, ctxt);
    986         if (rv != DECLINED
    987             && (rv != HTTP_FORBIDDEN
    988                 || dc->client_verify_mode == GNUTLS_CERT_REQUIRE
    989                 || (dc->client_verify_mode == -1
    990                     && ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUIRE)))
    991         {
     881        if (rv != DECLINED &&
     882                (rv != HTTP_FORBIDDEN ||
     883                dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) {
    992884            return rv;
    993885        }
     
    16611553}
    16621554
    1663 
    1664 
    1665 /*
    1666  * Callback to check the server certificate for proxy HTTPS
    1667  * connections, to be used with
    1668  * gnutls_certificate_set_verify_function.
    1669 
    1670  * Returns: 0 if certificate check was successful (certificate
    1671  * trusted), non-zero otherwise (error during check or untrusted
    1672  * certificate).
    1673  */
    1674 static int gtls_check_server_cert(gnutls_session_t session)
    1675 {
    1676     mgs_handle_t *ctxt = (mgs_handle_t *) gnutls_session_get_ptr(session);
    1677     unsigned int status;
    1678 
    1679     /* Get peer hostname from a note left by mod_proxy */
    1680     const char *peer_hostname =
    1681         apr_table_get(ctxt->c->notes, "proxy-request-hostname");
    1682     if (peer_hostname == NULL)
    1683         ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, ctxt->c,
    1684                       "%s: proxy-request-hostname is NULL, cannot check "
    1685                       "peer's hostname", __func__);
    1686 
    1687     /* Verify certificate, including hostname match. Should
    1688      * peer_hostname be NULL for some reason, the name is not
    1689      * checked. */
    1690     int err = gnutls_certificate_verify_peers3(session, peer_hostname,
    1691                                                &status);
    1692     if (err != GNUTLS_E_SUCCESS)
    1693     {
    1694         ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
    1695                       "%s: server certificate check failed: %s (%d)",
    1696                       __func__, gnutls_strerror(err), err);
    1697         return err;
    1698     }
    1699 
    1700     gnutls_datum_t * out = gnutls_malloc(sizeof(gnutls_datum_t));
    1701     /* GNUTLS_CRT_X509: ATM, only X509 is supported for proxy certs
    1702      * 0: according to function API, the last argument should be 0 */
    1703     err = gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509,
    1704                                                        out, 0);
    1705     if (err != GNUTLS_E_SUCCESS)
    1706         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    1707                       "%s: server verify print failed: %s (%d)",
    1708                       __func__, gnutls_strerror(err), err);
    1709     else
    1710     {
    1711         /* If the certificate is trusted, logging the result is just
    1712          * nice for debugging. But if the back end server provided an
    1713          * untrusted certificate, warn! */
    1714         int level = (status == 0 ? APLOG_DEBUG : APLOG_WARNING);
    1715         ap_log_cerror(APLOG_MARK, level, 0, ctxt->c,
    1716                       "%s: server certificate verify result: %s",
    1717                       __func__, out->data);
    1718     }
    1719 
    1720     gnutls_free(out);
    1721     return status;
    1722 }
    1723 
    1724 
    1725 
    1726 static apr_status_t load_proxy_x509_credentials(server_rec *s)
    1727 {
    1728     mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    1729         ap_get_module_config(s->module_config, &gnutls_module);
    1730 
    1731     if (sc == NULL)
    1732         return APR_EGENERAL;
    1733 
    1734     apr_status_t ret = APR_SUCCESS;
    1735     int err = GNUTLS_E_SUCCESS;
    1736 
    1737     /* Function pool, gets destroyed before exit. */
    1738     apr_pool_t *pool;
    1739     ret = apr_pool_create(&pool, s->process->pool);
    1740     if (ret != APR_SUCCESS)
    1741     {
    1742         ap_log_error(APLOG_MARK, APLOG_ERR, ret, s,
    1743                      "%s: failed to allocate function memory pool.", __func__);
    1744         return ret;
    1745     }
    1746 
    1747     /* allocate credentials structures */
    1748     err = gnutls_certificate_allocate_credentials(&sc->proxy_x509_creds);
    1749     if (err != GNUTLS_E_SUCCESS)
    1750     {
    1751         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1752                      "%s: Failed to initialize proxy credentials: (%d) %s",
    1753                      __func__, err, gnutls_strerror(err));
    1754         return APR_EGENERAL;
    1755     }
    1756     err = gnutls_anon_allocate_client_credentials(&sc->anon_client_creds);
    1757     if (err != GNUTLS_E_SUCCESS)
    1758     {
    1759         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1760                      "%s: Failed to initialize anon credentials for proxy: "
    1761                      "(%d) %s", __func__, err, gnutls_strerror(err));
    1762         return APR_EGENERAL;
    1763     }
    1764 
    1765     /* Check if the proxy priorities have been set, fail immediately
    1766      * if not */
    1767     if (sc->proxy_priorities_str == NULL)
    1768     {
    1769         ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    1770                      "Host '%s:%d' is missing the GnuTLSProxyPriorities "
    1771                      "directive!",
    1772                      s->server_hostname, s->port);
    1773         return APR_EGENERAL;
    1774     }
    1775     /* parse proxy priorities */
    1776     const char *err_pos = NULL;
    1777     err = gnutls_priority_init(&sc->proxy_priorities,
    1778                                sc->proxy_priorities_str, &err_pos);
    1779     if (err != GNUTLS_E_SUCCESS)
    1780     {
    1781         if (ret == GNUTLS_E_INVALID_REQUEST)
    1782             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1783                          "%s: Syntax error parsing proxy priorities "
    1784                          "string at: %s",
    1785                          __func__, err_pos);
    1786         else
    1787             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1788                          "Error setting proxy priorities: %s (%d)",
    1789                          gnutls_strerror(err), err);
    1790         ret = APR_EGENERAL;
    1791     }
    1792 
    1793     /* load certificate and key for client auth, if configured */
    1794     if (sc->proxy_x509_key_file && sc->proxy_x509_cert_file)
    1795     {
    1796         char* cert_file = ap_server_root_relative(pool,
    1797                                                   sc->proxy_x509_cert_file);
    1798         char* key_file = ap_server_root_relative(pool,
    1799                                                  sc->proxy_x509_key_file);
    1800         err = gnutls_certificate_set_x509_key_file(sc->proxy_x509_creds,
    1801                                                    cert_file,
    1802                                                    key_file,
    1803                                                    GNUTLS_X509_FMT_PEM);
    1804         if (err != GNUTLS_E_SUCCESS)
    1805         {
    1806             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1807                          "%s: loading proxy client credentials failed: %s (%d)",
    1808                          __func__, gnutls_strerror(err), err);
    1809             ret = APR_EGENERAL;
    1810         }
    1811     }
    1812     else if (!sc->proxy_x509_key_file && sc->proxy_x509_cert_file)
    1813     {
    1814         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
    1815                      "%s: proxy key file not set!", __func__);
    1816         ret = APR_EGENERAL;
    1817     }
    1818     else if (!sc->proxy_x509_cert_file && sc->proxy_x509_key_file)
    1819     {
    1820         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
    1821                      "%s: proxy certificate file not set!", __func__);
    1822         ret = APR_EGENERAL;
    1823     }
    1824     else
    1825         /* if both key and cert are NULL, client auth is not used */
    1826         ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    1827                      "%s: no client credentials for proxy", __func__);
    1828 
    1829     /* must be set if the server certificate is to be checked */
    1830     if (sc->proxy_x509_ca_file)
    1831     {
    1832         /* initialize the trust list */
    1833         err = gnutls_x509_trust_list_init(&sc->proxy_x509_tl, 0);
    1834         if (err != GNUTLS_E_SUCCESS)
    1835         {
    1836             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1837                          "%s: gnutls_x509_trust_list_init failed: %s (%d)",
    1838                          __func__, gnutls_strerror(err), err);
    1839             ret = APR_EGENERAL;
    1840         }
    1841 
    1842         char* ca_file = ap_server_root_relative(pool,
    1843                                                 sc->proxy_x509_ca_file);
    1844         /* if no CRL is used, sc->proxy_x509_crl_file is NULL */
    1845         char* crl_file = NULL;
    1846         if (sc->proxy_x509_crl_file)
    1847             crl_file = ap_server_root_relative(pool,
    1848                                                sc->proxy_x509_crl_file);
    1849 
    1850         /* returns number of loaded elements */
    1851         err = gnutls_x509_trust_list_add_trust_file(sc->proxy_x509_tl,
    1852                                                     ca_file,
    1853                                                     crl_file,
    1854                                                     GNUTLS_X509_FMT_PEM,
    1855                                                     0 /* tl_flags */,
    1856                                                     0 /* tl_vflags */);
    1857         if (err > 0)
    1858             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
    1859                          "%s: proxy CA trust list: %d structures loaded",
    1860                          __func__, err);
    1861         else if (err == 0)
    1862             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
    1863                          "%s: proxy CA trust list is empty (%d)",
    1864                          __func__, err);
    1865         else /* err < 0 */
    1866         {
    1867             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
    1868                          "%s: error loading proxy CA trust list: %s (%d)",
    1869                          __func__, gnutls_strerror(err), err);
    1870             ret = APR_EGENERAL;
    1871         }
    1872 
    1873         /* attach trust list to credentials */
    1874         gnutls_certificate_set_trust_list(sc->proxy_x509_creds,
    1875                                           sc->proxy_x509_tl, 0);
    1876     }
    1877     else
    1878         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
    1879                      "%s: no CA trust list for proxy connections, "
    1880                      "TLS connections will fail!", __func__);
    1881 
    1882     gnutls_certificate_set_verify_function(sc->proxy_x509_creds,
    1883                                            gtls_check_server_cert);
    1884     apr_pool_destroy(pool);
    1885     return ret;
    1886 }
  • src/gnutls_io.c

    r9b20a1e r2afbe2e  
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
    65 *
    76 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    3938                               alloc)
    4039
    41 #define IS_PROXY_STR(c) \
    42     ((c->is_proxy == GNUTLS_ENABLED_TRUE) ? "proxy " : "")
    43 
    4440static apr_status_t gnutls_io_filter_error(ap_filter_t * f,
    4541        apr_bucket_brigade * bb,
     
    4945
    5046    switch (status) {
    51     case HTTP_BAD_REQUEST:
    52         /* log the situation */
    53         ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    54                      f->c->base_server,
    55                      "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
    56                      "trying to send HTML error page");
    57         mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    58             ap_get_module_config(f->c->base_server->module_config,
    59                                  &gnutls_module);
    60         ctxt->status = -1;
    61         sc->non_ssl_request = 1;
    62 
    63         /* fake the request line */
    64         bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
    65         break;
    66 
    67     default:
    68         return status;
     47        case HTTP_BAD_REQUEST:
     48            /* log the situation */
     49            ap_log_error(APLOG_MARK, APLOG_INFO, 0,
     50                    f->c->base_server,
     51                    "GnuTLS handshake failed: HTTP spoken on HTTPS port; "
     52                    "trying to send HTML error page");
     53
     54                                    mgs_srvconf_rec *sc = (mgs_srvconf_rec *) ap_get_module_config(
     55                                                                                                                                                                                                                                f->c->base_server->module_config,
     56                                                                                                                                                                                                                                &gnutls_module
     57                                                                                                                                                                                                                        );
     58            ctxt->status = -1;
     59            sc->non_ssl_request = 1;
     60
     61            /* fake the request line */
     62            bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
     63            break;
     64
     65        default:
     66            return status;
    6967    }
    7068
     
    188186
    189187static apr_status_t gnutls_io_input_read(mgs_handle_t * ctxt,
    190         char *buf, apr_size_t * len)
    191 {
     188        char *buf, apr_size_t * len) {
    192189    apr_size_t wanted = *len;
    193190    apr_size_t bytes = 0;
     
    228225
    229226    if (ctxt->session == NULL) {
    230         ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, ctxt->c,
    231                       "%s: GnuTLS session is NULL!", __func__);
    232227        return APR_EGENERAL;
    233228    }
     
    235230    while (1) {
    236231
    237         do
    238             rc = gnutls_record_recv(ctxt->session, buf + bytes,
    239                                     wanted - bytes);
    240         while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
     232        rc = gnutls_record_recv(ctxt->session, buf + bytes,
     233                wanted - bytes);
    241234
    242235        if (rc > 0) {
     
    277270            if (rc == GNUTLS_E_REHANDSHAKE) {
    278271                /* A client has asked for a new Hankshake. Currently, we don't do it */
    279                 ap_log_cerror(APLOG_MARK, APLOG_INFO,
     272                ap_log_error(APLOG_MARK, APLOG_INFO,
    280273                        ctxt->input_rc,
    281                         ctxt->c,
     274                        ctxt->c->base_server,
    282275                        "GnuTLS: Error reading data. Client Requested a New Handshake."
    283276                        " (%d) '%s'", rc,
     
    285278            } else if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
    286279                rc = gnutls_alert_get(ctxt->session);
    287                 ap_log_cerror(APLOG_MARK, APLOG_INFO,
     280                ap_log_error(APLOG_MARK, APLOG_INFO,
    288281                        ctxt->input_rc,
    289                         ctxt->c,
     282                        ctxt->c->base_server,
    290283                        "GnuTLS: Warning Alert From Client: "
    291284                        " (%d) '%s'", rc,
     
    293286            } else if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
    294287                rc = gnutls_alert_get(ctxt->session);
    295                 ap_log_cerror(APLOG_MARK, APLOG_INFO,
     288                ap_log_error(APLOG_MARK, APLOG_INFO,
    296289                        ctxt->input_rc,
    297                         ctxt->c,
     290                        ctxt->c->base_server,
    298291                        "GnuTLS: Fatal Alert From Client: "
    299292                        "(%d) '%s'", rc,
     
    304297                /* Some Other Error. Report it. Die. */
    305298                if (gnutls_error_is_fatal(rc)) {
    306                     ap_log_cerror(APLOG_MARK,
     299                    ap_log_error(APLOG_MARK,
    307300                            APLOG_INFO,
    308301                            ctxt->input_rc,
    309                             ctxt->c,
     302                            ctxt->c->base_server,
    310303                            "GnuTLS: Error reading data. (%d) '%s'",
    311304                            rc,
     
    318311
    319312            if (ctxt->input_rc == APR_SUCCESS) {
    320                 ap_log_cerror(APLOG_MARK, APLOG_INFO, ctxt->input_rc, ctxt->c,
    321                               "%s: GnuTLS error: %s (%d)",
    322                               __func__, gnutls_strerror(rc), rc);
    323313                ctxt->input_rc = APR_EGENERAL;
    324314            }
     
    415405            ap_log_error(APLOG_MARK, APLOG_INFO, 0,
    416406                    ctxt->c->base_server,
    417                     "GnuTLS: Handshake Alert (%d) '%s'.",
     407                    "GnuTLS: Hanshake Alert (%d) '%s'.",
    418408                    errcode,
    419409                    gnutls_alert_get_name(errcode));
     
    459449            }
    460450        }
    461         return GNUTLS_E_SUCCESS;
     451        return 0;
    462452    }
    463453}
     
    489479        apr_bucket_brigade * bb,
    490480        ap_input_mode_t mode,
    491         apr_read_type_e block, apr_off_t readbytes)
    492 {
     481        apr_read_type_e block, apr_off_t readbytes) {
    493482    apr_status_t status = APR_SUCCESS;
    494483    mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx;
     
    499488                apr_bucket_eos_create(f->c->bucket_alloc);
    500489        APR_BRIGADE_INSERT_TAIL(bb, bucket);
    501         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    502                       "%s: %sconnection aborted",
    503                       __func__, IS_PROXY_STR(ctxt));
    504490        return APR_ECONNABORTED;
    505491    }
    506492
    507493    if (ctxt->status == 0) {
    508         int ret = gnutls_do_handshake(ctxt);
    509         if (ret == GNUTLS_E_SUCCESS)
    510             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    511                           "%s: TLS %sconnection opened.",
    512                           __func__, IS_PROXY_STR(ctxt));
     494        gnutls_do_handshake(ctxt);
    513495    }
    514496
    515497    if (ctxt->status < 0) {
    516         ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    517                       "%s %s: ap_get_brigade", __func__, IS_PROXY_STR(ctxt));
    518498        return ap_get_brigade(f->next, bb, mode, block, readbytes);
    519499    }
     
    608588
    609589    if (ctxt->status == 0) {
    610         ret = gnutls_do_handshake(ctxt);
    611         if (ret == GNUTLS_E_SUCCESS)
    612             ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, ctxt->c,
    613                           "%s: TLS %sconnection opened.",
    614                           __func__, IS_PROXY_STR(ctxt));
     590        gnutls_do_handshake(ctxt);
    615591    }
    616592
     
    639615                    ret = gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    640616                } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
    641                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, ret, ctxt->c,
    642                               "%s: TLS %sconnection closed.",
    643                               __func__, IS_PROXY_STR(ctxt));
    644617                /* De-Initialize Session */
    645618                gnutls_deinit(ctxt->session);
  • src/mod_gnutls.c

    r9b20a1e r2afbe2e  
    33 *  Copyright 2008 Nikos Mavrogiannopoulos
    44 *  Copyright 2011 Dash Shendy
    5  *  Copyright 2015 Thomas Klute
    65 *
    76 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    2120#include "mod_gnutls.h"
    2221
    23 #ifdef APLOG_USE_MODULE
    24 APLOG_USE_MODULE(gnutls);
    25 #endif
     22static void gnutls_hooks(apr_pool_t * p __attribute__((unused))) {
    2623
    27 static void gnutls_hooks(apr_pool_t * p __attribute__((unused)))
    28 {
    2924    /* Try Run Post-Config Hook After mod_proxy */
    3025    static const char * const aszPre[] = { "mod_proxy.c", NULL };
    31     ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,
    32                         APR_HOOK_REALLY_LAST);
     26    ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,APR_HOOK_REALLY_LAST);
    3327    /* HTTP Scheme Hook */
    3428#if USING_2_1_RECENT
     
    3832#endif
    3933    /* Default Port Hook */
    40     ap_hook_default_port(mgs_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE);
     34    ap_hook_default_port(mgs_hook_default_port,  NULL,NULL, APR_HOOK_MIDDLE);
    4135    /* Pre-Connect Hook */
    42     ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL,
    43                            APR_HOOK_MIDDLE);
     36    ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL, APR_HOOK_MIDDLE);
    4437    /* Pre-Config Hook */
    4538    ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL,
    46                        APR_HOOK_MIDDLE);
     39            APR_HOOK_MIDDLE);
    4740    /* Child-Init Hook */
    4841    ap_hook_child_init(mgs_hook_child_init, NULL, NULL,
    49                        APR_HOOK_MIDDLE);
     42            APR_HOOK_MIDDLE);
    5043    /* Authentication Hook */
    5144    ap_hook_access_checker(mgs_hook_authz, NULL, NULL,
    52                            APR_HOOK_REALLY_FIRST);
     45            APR_HOOK_REALLY_FIRST);
    5346    /* Fixups Hook */
    5447    ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST);
     
    6053
    6154    /* Input Filter */
    62     ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, mgs_filter_input,
    63                              NULL, AP_FTYPE_CONNECTION + 5);
     55    ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME,
     56            mgs_filter_input, NULL,AP_FTYPE_CONNECTION + 5);
    6457    /* Output Filter */
    65     ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, mgs_filter_output,
    66                               NULL, AP_FTYPE_CONNECTION + 5);
     58    ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME,
     59            mgs_filter_output, NULL,AP_FTYPE_CONNECTION + 5);
    6760
    6861    /* mod_proxy calls these functions */
     
    7164}
    7265
    73 int ssl_is_https(conn_rec *c)
    74 {
     66int ssl_is_https(conn_rec *c) {
    7567    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    76         ap_get_module_config(c->base_server->module_config, &gnutls_module);
     68            ap_get_module_config(c->base_server->module_config, &gnutls_module);
    7769    if(sc->enabled == 0 || sc->non_ssl_request == 1) {
    7870        /* SSL/TLS Disabled or Plain HTTP Connection Detected */
     
    8375}
    8476
    85 int ssl_engine_disable(conn_rec *c)
    86 {
     77int ssl_engine_disable(conn_rec *c) {
    8778    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    88         ap_get_module_config(c->base_server->module_config, &gnutls_module);
     79            ap_get_module_config(c->base_server->module_config, &gnutls_module);
    8980    if(sc->enabled == GNUTLS_ENABLED_FALSE) {
    9081        return 1;
    9182    }
    92 
    93     /* disable TLS for this connection */
    94     mgs_handle_t *ctxt = (mgs_handle_t *)
    95         ap_get_module_config(c->conn_config, &gnutls_module);
    96     if (ctxt == NULL)
    97     {
    98         ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    99         ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    100     }
    101     ctxt->enabled = GNUTLS_ENABLED_FALSE;
    102     ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
    103 
    104     if (c->input_filters)
    105         ap_remove_input_filter(c->input_filters);
    106     if (c->output_filters)
    107         ap_remove_output_filter(c->output_filters);
    108 
     83    ap_remove_input_filter(c->input_filters);
     84    ap_remove_input_filter(c->output_filters);
     85    mgs_cleanup_pre_config(c->pool);
     86    sc->enabled = 0;
    10987    return 1;
    11088}
    11189
    112 int ssl_proxy_enable(conn_rec *c)
    113 {
    114     /* check if TLS proxy support is enabled */
     90int ssl_proxy_enable(conn_rec *c) {
    11591    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
    116         ap_get_module_config(c->base_server->module_config, &gnutls_module);
    117     if (sc->proxy_enabled != GNUTLS_ENABLED_TRUE)
    118     {
    119         ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
    120                       "%s: mod_proxy requested TLS proxy, but not enabled "
    121                       "for %s", __func__, sc->cert_cn);
    122         return 0;
    123     }
    124 
    125     /* enable TLS for this connection */
    126     mgs_handle_t *ctxt = (mgs_handle_t *)
    127         ap_get_module_config(c->conn_config, &gnutls_module);
    128     if (ctxt == NULL)
    129     {
    130         ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
    131         ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    132     }
    133     ctxt->enabled = GNUTLS_ENABLED_TRUE;
    134     ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
     92            ap_get_module_config(c->base_server->module_config, &gnutls_module);
     93    sc->proxy_enabled = 1;
     94    sc->enabled = 0;
    13595    return 1;
    13696}
    13797
    13898static const command_rec mgs_config_cmds[] = {
    139     AP_INIT_TAKE1("GnuTLSProxyEngine", mgs_set_proxy_engine,
     99    AP_INIT_TAKE1("SSLProxyEngine", mgs_set_proxy_engine,
    140100    NULL,
    141101    RSRC_CONF | OR_AUTHCFG,
    142102    "Enable SSL Proxy Engine"),
    143     AP_INIT_TAKE1("GnuTLSP11Module", mgs_set_p11_module,
    144     NULL,
    145     RSRC_CONF,
    146     "Load this additional PKCS #11 provider library"),
    147     AP_INIT_RAW_ARGS("GnuTLSPIN", mgs_set_pin,
    148     NULL,
    149     RSRC_CONF,
    150     "The PIN to use in case of encrypted keys or PKCS #11 tokens."),
    151     AP_INIT_RAW_ARGS("GnuTLSSRKPIN", mgs_set_srk_pin,
    152     NULL,
    153     RSRC_CONF,
    154     "The SRK PIN to use in case of TPM keys."),
    155103    AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify,
    156104    NULL,
     
    237185    RSRC_CONF,
    238186    "Max size to export PEM encoded certificates to CGIs (or off to disable). Default: off"),
    239     AP_INIT_TAKE1("GnuTLSProxyKeyFile", mgs_store_cred_path,
    240     NULL,
    241     RSRC_CONF,
    242     "X509 client private file for proxy connections"),
    243     AP_INIT_TAKE1("GnuTLSProxyCertificateFile", mgs_store_cred_path,
    244     NULL,
    245     RSRC_CONF,
    246     "X509 client certificate file for proxy connections"),
    247     AP_INIT_TAKE1("GnuTLSProxyCAFile", mgs_store_cred_path,
    248     NULL,
    249     RSRC_CONF,
    250     "X509 trusted CA file for proxy connections"),
    251     AP_INIT_TAKE1("GnuTLSProxyCRLFile", mgs_store_cred_path,
    252     NULL,
    253     RSRC_CONF,
    254     "X509 CRL file for proxy connections"),
    255     AP_INIT_RAW_ARGS("GnuTLSProxyPriorities", mgs_set_priorities,
    256     NULL,
    257     RSRC_CONF,
    258     "The priorities to enable for proxy connections (ciphers, key exchange, "
    259     "MACs, compression)."),
    260187    { NULL },
    261188};
Note: See TracChangeset for help on using the changeset viewer.