Changeset 7bebb42 in mod_gnutls for src


Ignore:
Timestamp:
Nov 28, 2007, 1:29:21 PM (12 years ago)
Author:
Nokis Mavrogiannopoulos <nmav@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, upstream
Children:
3e6bc31
Parents:
8e33f2d
git-author:
Nikos Mavrogiannopoulos <nmav@…> (11/28/07 13:29:21)
git-committer:
Nokis Mavrogiannopoulos <nmav@…> (11/28/07 13:29:21)
Message:

upgraded to 0.4.0

Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/Makefile.am

    r8e33f2d r7bebb42  
    11CLEANFILES = .libs/libmod_gnutls *~
    22
    3 libmod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c gnutls_config.c gnutls_hooks.c gnutls_lua.c
     3libmod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c gnutls_config.c gnutls_hooks.c
     4#gnutls_lua.c
    45libmod_gnutls_la_CFLAGS = -Wall ${MODULE_CFLAGS} ${LUA_CFLAGS}
    56libmod_gnutls_la_LDFLAGS = -rpath ${AP_LIBEXECDIR} -module -avoid-version ${MODULE_LIBS} ${LUA_LIBS}
  • src/gnutls_cache.c

    r8e33f2d r7bebb42  
    3939#define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN)
    4040
     41#if 0
    4142static char *gnutls_session_id2sz(unsigned char *id, int idlen,
    4243                               char *str, int strsize)
     
    5152    }
    5253    *cp = '\0';
     54    return str;
     55}
     56#endif
     57
     58#define CTIME "%b %d %k:%M:%S %Y %Z"
     59char *mgs_time2sz(time_t in_time, char *str, int strsize)
     60{
     61    apr_time_exp_t vtm;
     62    apr_size_t ret_size;
     63    apr_time_t t;
     64   
     65 
     66    apr_time_ansi_put (&t, in_time);
     67    apr_time_exp_gmt (&vtm, t);
     68    apr_strftime(str, &ret_size, strsize-1, CTIME, &vtm);
     69
    5370    return str;
    5471}
     
    350367    apr_status_t rv;
    351368
    352     dbmkey.dptr  = key.data;
     369    dbmkey.dptr  = (void*)key.data;
    353370    dbmkey.dsize = key.size;
    354 
    355     dbm_cache_expire(ctxt);
    356371
    357372    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
     
    413428           data.data, data.size);
    414429
     430    /* we expire dbm only on every store
     431     */
    415432    dbm_cache_expire(ctxt);
    416433
     
    455472    dbmkey.dsize = key.size;
    456473
    457     dbm_cache_expire(ctxt);
    458    
    459474    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
    460475                      APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
  • src/gnutls_config.c

    r8e33f2d r7bebb42  
    1818#include "mod_gnutls.h"
    1919
    20 static int load_datum_from_file(apr_pool_t* pool,
    21                                 const char* file,
    22                                 gnutls_datum_t* data)
    23 {
    24     apr_file_t* fp;
     20static int load_datum_from_file(apr_pool_t * pool,
     21                                const char *file, gnutls_datum_t * data)
     22{
     23    apr_file_t *fp;
    2524    apr_finfo_t finfo;
    2625    apr_status_t rv;
    2726    apr_size_t br = 0;
    28    
    29     rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT,
    30                        pool);
     27
     28    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,
     29                       pool);
    3130    if (rv != APR_SUCCESS) {
    32         return rv;
    33     }
    34    
     31        return rv;
     32    }
     33
    3534    rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
    36    
     35
    3736    if (rv != APR_SUCCESS) {
    38         return rv;
    39     }
    40    
    41     data->data = apr_palloc(pool, finfo.size+1);
     37        return rv;
     38    }
     39
     40    data->data = apr_palloc(pool, finfo.size + 1);
    4241    rv = apr_file_read_full(fp, data->data, finfo.size, &br);
    43    
     42
    4443    if (rv != APR_SUCCESS) {
    45         return rv;
     44        return rv;
    4645    }
    4746    apr_file_close(fp);
    48    
     47
    4948    data->data[br] = '\0';
    5049    data->size = br;
    51    
     50
    5251    return 0;
    5352}
    5453
     54const char *mgs_set_dh_file(cmd_parms * parms, void *dummy,
     55                            const char *arg)
     56{
     57    mgs_srvconf_rec *sc =
     58        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     59                                                 module_config,
     60                                                 &gnutls_module);
     61
     62    sc->dh_params_file = ap_server_root_relative(parms->pool, arg);
     63
     64    return NULL;
     65}
     66
     67const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy,
     68                                    const char *arg)
     69{
     70    mgs_srvconf_rec *sc =
     71        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     72                                                 module_config,
     73                                                 &gnutls_module);
     74
     75    sc->rsa_params_file = ap_server_root_relative(parms->pool, arg);
     76
     77    return NULL;
     78}
     79
     80
    5581const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
    56                                         const char *arg)
     82                              const char *arg)
    5783{
    5884    int ret;
    5985    gnutls_datum_t data;
    60     const char* file;
    61     apr_pool_t* spool;
    62     mgs_srvconf_rec *sc =
    63         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    64                                                         module_config,
    65                                                         &gnutls_module);
     86    const char *file;
     87    apr_pool_t *spool;
     88    mgs_srvconf_rec *sc =
     89        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     90                                                module_config,
     91                                                &gnutls_module);
    6692    apr_pool_create(&spool, parms->pool);
    67    
     93
    6894    file = ap_server_root_relative(spool, arg);
    6995
    7096    if (load_datum_from_file(spool, file, &data) != 0) {
    71         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    72                             "Certificate '%s'", file);
    73     }
    74    
     97        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     98                            "Certificate '%s'", file);
     99    }
     100
    75101    gnutls_x509_crt_init(&sc->cert_x509);
    76     ret = gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
     102    ret =
     103        gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM);
    77104    if (ret != 0) {
    78         return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
    79                             "Certificate'%s': (%d) %s", file, ret,
    80                             gnutls_strerror(ret));
    81     }
    82    
     105        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
     106                            "Certificate'%s': (%d) %s", file, ret,
     107                            gnutls_strerror(ret));
     108    }
     109
    83110    apr_pool_destroy(spool);
    84111    return NULL;
     
    86113
    87114const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
    88                                        const char *arg)
     115                             const char *arg)
    89116{
    90117    int ret;
    91118    gnutls_datum_t data;
    92     const char* file;
    93     apr_pool_t* spool;
    94     mgs_srvconf_rec *sc =
    95         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    96                                                         module_config,
    97                                                         &gnutls_module);
     119    const char *file;
     120    apr_pool_t *spool;
     121    mgs_srvconf_rec *sc =
     122        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     123                                                module_config,
     124                                                &gnutls_module);
    98125    apr_pool_create(&spool, parms->pool);
    99    
     126
    100127    file = ap_server_root_relative(spool, arg);
    101    
     128
    102129    if (load_datum_from_file(spool, file, &data) != 0) {
    103         return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
    104                             "Private Key '%s'", file);
    105     }
    106    
     130        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     131                            "Private Key '%s'", file);
     132    }
     133
    107134    gnutls_x509_privkey_init(&sc->privkey_x509);
    108     ret = gnutls_x509_privkey_import(sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM);
     135    ret =
     136        gnutls_x509_privkey_import(sc->privkey_x509, &data,
     137                                   GNUTLS_X509_FMT_PEM);
    109138    if (ret != 0) {
    110         return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
    111                             "Private Key '%s': (%d) %s", file, ret,
    112                             gnutls_strerror(ret));
     139        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
     140                            "Private Key '%s': (%d) %s", file, ret,
     141                            gnutls_strerror(ret));
    113142    }
    114143    apr_pool_destroy(spool);
     
    116145}
    117146
     147const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
     148                                     const char *arg)
     149{
     150    mgs_srvconf_rec *sc =
     151        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     152                                                 module_config,
     153                                                 &gnutls_module);
     154
     155    sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg);
     156
     157    return NULL;
     158}
     159
     160const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy,
     161                                          const char *arg)
     162{
     163    mgs_srvconf_rec *sc =
     164        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     165                                                 module_config,
     166                                                 &gnutls_module);
     167
     168    sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg);
     169
     170    return NULL;
     171}
     172
    118173const char *mgs_set_cache(cmd_parms * parms, void *dummy,
    119                                        const char *type, const char* arg)
    120 {
    121     const char* err;
     174                          const char *type, const char *arg)
     175{
     176    const char *err;
    122177    mgs_srvconf_rec *sc = ap_get_module_config(parms->server->
    123                                                         module_config,
    124                                                         &gnutls_module);
     178                                               module_config,
     179                                               &gnutls_module);
    125180    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
    126         return err;
     181        return err;
    127182    }
    128183
    129184    if (strcasecmp("none", type) == 0) {
    130         sc->cache_type = mgs_cache_none;
    131     }
    132     else if (strcasecmp("dbm", type) == 0) {
    133         sc->cache_type = mgs_cache_dbm;
     185        sc->cache_type = mgs_cache_none;
     186    } else if (strcasecmp("dbm", type) == 0) {
     187        sc->cache_type = mgs_cache_dbm;
    134188    }
    135189#if HAVE_APR_MEMCACHE
    136190    else if (strcasecmp("memcache", type) == 0) {
    137         sc->cache_type = mgs_cache_memcache;
     191        sc->cache_type = mgs_cache_memcache;
    138192    }
    139193#endif
    140194    else {
    141         return "Invalid Type for GnuTLSCache!";
     195        return "Invalid Type for GnuTLSCache!";
    142196    }
    143197
    144198    if (sc->cache_type == mgs_cache_dbm) {
    145         sc->cache_config = ap_server_root_relative(parms->pool, arg);
    146     }
    147     else {
    148         sc->cache_config = apr_pstrdup(parms->pool, arg);
     199        sc->cache_config = ap_server_root_relative(parms->pool, arg);
     200    } else {
     201        sc->cache_config = apr_pstrdup(parms->pool, arg);
    149202    }
    150203
     
    153206
    154207const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy,
    155                                             const char *arg)
     208                                  const char *arg)
    156209{
    157210    int argint;
    158211    mgs_srvconf_rec *sc =
    159     (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    160                                                     module_config,
    161                                                     &gnutls_module);
    162    
     212        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     213                                                module_config,
     214                                                &gnutls_module);
     215
    163216    argint = atoi(arg);
    164    
     217
    165218    if (argint < 0) {
    166         return "GnuTLSCacheTimeout: Invalid argument";
    167     }
    168     else if (argint == 0) {
    169         sc->cache_timeout = 0;
    170     }
    171     else {
    172         sc->cache_timeout = apr_time_from_sec(argint);
    173     }
    174    
     219        return "GnuTLSCacheTimeout: Invalid argument";
     220    } else if (argint == 0) {
     221        sc->cache_timeout = 0;
     222    } else {
     223        sc->cache_timeout = apr_time_from_sec(argint);
     224    }
     225
    175226    return NULL;
    176227}
    177228
    178229const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
    179                                             const char *arg)
     230                                  const char *arg)
    180231{
    181232    int mode;
    182233
    183234    if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) {
    184         mode = GNUTLS_CERT_IGNORE;
    185     }
    186     else if (strcasecmp("optional", arg) == 0 || strcasecmp("request", arg) == 0) {
    187         mode = GNUTLS_CERT_REQUEST;
    188     }
    189     else if (strcasecmp("require", arg) == 0) {
    190         mode = GNUTLS_CERT_REQUIRE;
    191     }
    192     else {
    193         return "GnuTLSClientVerify: Invalid argument";
    194     }
    195    
     235        mode = GNUTLS_CERT_IGNORE;
     236    } else if (strcasecmp("optional", arg) == 0
     237               || strcasecmp("request", arg) == 0) {
     238        mode = GNUTLS_CERT_REQUEST;
     239    } else if (strcasecmp("require", arg) == 0) {
     240        mode = GNUTLS_CERT_REQUIRE;
     241    } else {
     242        return "GnuTLSClientVerify: Invalid argument";
     243    }
     244
    196245    /* This was set from a directory context */
    197246    if (parms->path) {
    198         mgs_dirconf_rec *dc = (mgs_dirconf_rec *)dummy;
    199         dc->client_verify_mode = mode;
    200     }
    201     else {
    202         mgs_srvconf_rec *sc =
    203         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    204                                                         module_config,
    205                                                         &gnutls_module);       
    206         sc->client_verify_mode = mode;
     247        mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy;
     248        dc->client_verify_mode = mode;
     249    } else {
     250        mgs_srvconf_rec *sc =
     251            (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     252                                                     module_config,
     253                                                     &gnutls_module);
     254        sc->client_verify_mode = mode;
    207255    }
    208256
     
    211259
    212260const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
    213                                             const char *arg)
     261                                   const char *arg)
    214262{
    215263    int rv;
    216     const char* file;
    217     apr_pool_t* spool;
     264    const char *file;
     265    apr_pool_t *spool;
    218266    gnutls_datum_t data;
    219267
    220     mgs_srvconf_rec *sc = 
    221         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    222                                                         module_config,
    223                                                         &gnutls_module);       
     268    mgs_srvconf_rec *sc =
     269        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     270                                                module_config,
     271                                                 &gnutls_module);
    224272    apr_pool_create(&spool, parms->pool);
    225273
    226274    file = ap_server_root_relative(spool, arg);
    227275
    228     sc->ca_list_size = 16;
    229 
    230     load_datum_from_file(spool, file, &data);
    231 
    232     rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
    233                                      &data, GNUTLS_X509_FMT_PEM,
    234                                      GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
     276    if (load_datum_from_file(spool, file, &data) != 0) {
     277        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     278                            "Client CA File '%s'", file);
     279    }
     280
     281    sc->ca_list_size = MAX_CA_CRTS;
     282    rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size,
     283                                     &data, GNUTLS_X509_FMT_PEM,
     284                                     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
    235285    if (rv < 0) {
    236         return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
    237                             "Client CA File '%s': (%d) %s", file, rv,
    238                             gnutls_strerror(rv));   
     286        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
     287                            "Client CA File '%s': (%d) %s", file, rv,
     288                            gnutls_strerror(rv));
    239289    }
    240290
     
    244294
    245295const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
    246                                       const char *arg)
    247 {
    248     mgs_srvconf_rec *sc =
    249         (mgs_srvconf_rec *) ap_get_module_config(parms->server->
    250                                                         module_config,
    251                                                         &gnutls_module);
     296                            const char *arg)
     297{
     298    mgs_srvconf_rec *sc =
     299        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     300                                                module_config,
     301                                                &gnutls_module);
    252302    if (!strcasecmp(arg, "On")) {
    253         sc->enabled = GNUTLS_ENABLED_TRUE;
    254     }
    255     else if (!strcasecmp(arg, "Off")) {
    256         sc->enabled = GNUTLS_ENABLED_FALSE;
    257     }
    258     else {
    259         return "GnuTLSEnable must be set to 'On' or 'Off'";
     303        sc->enabled = GNUTLS_ENABLED_TRUE;
     304    } else if (!strcasecmp(arg, "Off")) {
     305        sc->enabled = GNUTLS_ENABLED_FALSE;
     306    } else {
     307        return "GnuTLSEnable must be set to 'On' or 'Off'";
     308    }
     309
     310    return NULL;
     311}
     312
     313const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
     314                            const char *arg)
     315{
     316    mgs_srvconf_rec *sc =
     317        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     318                                                 module_config,
     319                                                 &gnutls_module);
     320    if (!strcasecmp(arg, "On")) {
     321        sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE;
     322    } else if (!strcasecmp(arg, "Off")) {
     323        sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE;
     324    } else {
     325        return "GnuTLSExportCertificates must be set to 'On' or 'Off'";
     326    }
     327
     328    return NULL;
     329}
     330
     331
     332const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg)
     333{
     334    int ret;
     335    char *err;
     336    mgs_srvconf_rec *sc =
     337        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     338                                                 module_config,
     339                                                 &gnutls_module);
     340
     341
     342    ret = gnutls_priority_init( &sc->priorities, arg, &err);
     343    if (ret < 0) {
     344      if (ret == GNUTLS_E_INVALID_REQUEST)
     345        return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err);
     346      return "Error setting priorities";
    260347    }
    261348
     
    265352void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
    266353{
    267     int i;
    268354    mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc));
    269    
     355
    270356    sc->enabled = GNUTLS_ENABLED_FALSE;
    271    
     357
    272358    gnutls_certificate_allocate_credentials(&sc->certs);
     359    gnutls_anon_allocate_server_credentials(&sc->anon_creds);
     360    gnutls_srp_allocate_server_credentials(&sc->srp_creds);
     361
     362    sc->srp_tpasswd_conf_file = NULL;
     363    sc->srp_tpasswd_file = NULL;
    273364    sc->privkey_x509 = NULL;
    274365    sc->cert_x509 = NULL;
     
    276367    sc->cache_type = mgs_cache_dbm;
    277368    sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
    278    
    279     /* TODO: Make this Configurable. But it isn't configurable in mod_ssl? */
     369
    280370    sc->dh_params_file = ap_server_root_relative(p, "conf/dhfile");
    281371    sc->rsa_params_file = ap_server_root_relative(p, "conf/rsafile");
    282    
    283     /* Finish SSL Client Certificate Support */
     372
    284373    sc->client_verify_mode = GNUTLS_CERT_IGNORE;
    285    
    286     /* TODO: Make this Configurable ! */
    287     /* mod_ssl uses a flex based parser for this part.. sigh */
    288     i = 0;
    289     sc->ciphers[i++] = GNUTLS_CIPHER_AES_256_CBC;
    290     sc->ciphers[i++] = GNUTLS_CIPHER_AES_128_CBC;
    291     sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_128;
    292     sc->ciphers[i++] = GNUTLS_CIPHER_3DES_CBC;
    293     sc->ciphers[i++] = GNUTLS_CIPHER_ARCFOUR_40;
    294     sc->ciphers[i] = 0;
    295    
    296     i = 0;
    297     sc->key_exchange[i++] = GNUTLS_KX_RSA;
    298     sc->key_exchange[i++] = GNUTLS_KX_RSA_EXPORT;
    299     sc->key_exchange[i++] = GNUTLS_KX_DHE_DSS;
    300     sc->key_exchange[i++] = GNUTLS_KX_DHE_RSA;
    301     sc->key_exchange[i++] = GNUTLS_KX_ANON_DH;
    302     sc->key_exchange[i++] = GNUTLS_KX_SRP;
    303     sc->key_exchange[i++] = GNUTLS_KX_SRP_RSA;
    304     sc->key_exchange[i++] = GNUTLS_KX_SRP_DSS;
    305     sc->key_exchange[i] = 0;
    306    
    307     i = 0;
    308     sc->macs[i++] = GNUTLS_MAC_SHA;
    309     sc->macs[i++] = GNUTLS_MAC_MD5;
    310     sc->macs[i++] = GNUTLS_MAC_RMD160;
    311     sc->macs[i] = 0;
    312    
    313     i = 0;
    314     sc->protocol[i++] = GNUTLS_TLS1_1;
    315     sc->protocol[i++] = GNUTLS_TLS1;
    316     sc->protocol[i++] = GNUTLS_SSL3;
    317     sc->protocol[i] = 0;
    318    
    319     i = 0;
    320     sc->compression[i++] = GNUTLS_COMP_NULL;
    321     sc->compression[i++] = GNUTLS_COMP_ZLIB;
    322     sc->compression[i++] = GNUTLS_COMP_LZO;
    323     sc->compression[i] = 0;
    324    
    325     i = 0;
    326     sc->cert_types[i++] = GNUTLS_CRT_X509;
    327     sc->cert_types[i] = 0;
    328    
     374
    329375    return sc;
    330376}
    331377
    332 void *mgs_config_dir_merge(apr_pool_t *p, void *basev, void *addv)
     378void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv)
    333379{
    334380    mgs_dirconf_rec *new;
    335     mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev;
     381/*    mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */
    336382    mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv;
    337    
     383
    338384    new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec));
    339385    new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode,
    340                                        add->lua_bytecode_len);
     386                                       add->lua_bytecode_len);
    341387    new->lua_bytecode_len = add->lua_bytecode_len;
    342388    new->client_verify_mode = add->client_verify_mode;
     
    344390}
    345391
    346 void *mgs_config_dir_create(apr_pool_t *p, char *dir)
     392void *mgs_config_dir_create(apr_pool_t * p, char *dir)
    347393{
    348394    mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc));
    349    
     395
    350396    dc->client_verify_mode = -1;
    351397    dc->lua_bytecode = NULL;
     
    353399    return dc;
    354400}
    355 
  • src/gnutls_hooks.c

    r8e33f2d r7bebb42  
    11/**
    22 *  Copyright 2004-2005 Paul Querna
     3 *  Copyright 2007 Nikos Mavrogiannopoulos
    34 *
    45 *  Licensed under the Apache License, Version 2.0 (the "License");
     
    2930
    3031#if MOD_GNUTLS_DEBUG
    31 static apr_file_t* debug_log_fp;
     32static apr_file_t *debug_log_fp;
    3233#endif
    3334
    3435static int mpm_is_threaded;
     36
     37static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
     38/* use side==0 for server and side==1 for client */
     39static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert,
     40                                     int side, int export_certificates_enabled);
    3541
    3642static apr_status_t mgs_cleanup_pre_config(void *data)
     
    4147
    4248#if MOD_GNUTLS_DEBUG
    43 static void gnutls_debug_log_all( int level, const char* str)
     49static void gnutls_debug_log_all(int level, const char *str)
    4450{
    4551    apr_file_printf(debug_log_fp, "<%d> %s\n", level, str);
     
    4753#endif
    4854
    49 int mgs_hook_pre_config(apr_pool_t * pconf,
    50                         apr_pool_t * plog, apr_pool_t * ptemp)
     55int
     56mgs_hook_pre_config(apr_pool_t * pconf,
     57                    apr_pool_t * plog, apr_pool_t * ptemp)
    5158{
    5259
     
    5461    ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded);
    5562    if (mpm_is_threaded) {
    56         gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
     63        gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
    5764    }
    5865#else
     
    6370
    6471    apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
    65                               apr_pool_cleanup_null);
     72                              apr_pool_cleanup_null);
    6673
    6774#if MOD_GNUTLS_DEBUG
    6875    apr_file_open(&debug_log_fp, "/tmp/gnutls_debug",
    69                   APR_APPEND|APR_WRITE|APR_CREATE, APR_OS_DEFAULT, pconf);
     76                  APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
     77                  pconf);
    7078
    7179    gnutls_global_set_log_level(9);
     
    7785
    7886
    79 static gnutls_datum load_params(const char* file, server_rec* s,
    80                                 apr_pool_t* pool)
     87static gnutls_datum
     88load_params(const char *file, server_rec * s, apr_pool_t * pool)
    8189{
    8290    gnutls_datum ret = { NULL, 0 };
    83     apr_file_t* fp;
     91    apr_file_t *fp;
    8492    apr_finfo_t finfo;
    8593    apr_status_t rv;
    8694    apr_size_t br = 0;
    8795
    88     rv = apr_file_open(&fp, file, APR_READ|APR_BINARY, APR_OS_DEFAULT,
    89                        pool);
     96    rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,
     97                       pool);
    9098    if (rv != APR_SUCCESS) {
    91         ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    92                      "GnuTLS failed to load params file at: %s", file);
    93         return ret;
     99        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
     100                     "GnuTLS failed to load params file at: %s. Will use internal params.", file);
     101        return ret;
    94102    }
    95103
     
    97105
    98106    if (rv != APR_SUCCESS) {
    99         ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    100                      "GnuTLS failed to stat params file at: %s", file);
    101         return ret;
    102     }
    103 
    104     ret.data = apr_palloc(pool, finfo.size+1);
     107        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
     108                     "GnuTLS failed to stat params file at: %s", file);
     109        return ret;
     110    }
     111
     112    ret.data = apr_palloc(pool, finfo.size + 1);
    105113    rv = apr_file_read_full(fp, ret.data, finfo.size, &br);
    106114
    107115    if (rv != APR_SUCCESS) {
    108         ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    109                      "GnuTLS failed to read params file at: %s", file);
    110         return ret;
     116        ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
     117                     "GnuTLS failed to read params file at: %s", file);
     118        return ret;
    111119    }
    112120    apr_file_close(fp);
     
    117125}
    118126
    119 int mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
    120                                        apr_pool_t * ptemp,
    121                                        server_rec * base_server)
     127/* We don't support openpgp certificates, yet */
     128const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 };
     129
     130static int mgs_select_virtual_server_cb( gnutls_session_t session)
     131{
     132    mgs_handle_t *ctxt;
     133    mgs_srvconf_rec *tsc;
     134    int ret;
     135
     136    ctxt = gnutls_transport_get_ptr(session);
     137
     138    /* find the virtual server */
     139    tsc = mgs_find_sni_server(session);
     140
     141    if (tsc != NULL)
     142        ctxt->sc = tsc;
     143
     144    gnutls_certificate_server_set_request(session,
     145       ctxt->sc->client_verify_mode);
     146
     147    /* set the new server credentials
     148     */
     149
     150    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
     151      ctxt->sc->certs);
     152
     153    gnutls_credentials_set(session, GNUTLS_CRD_ANON,
     154      ctxt->sc->anon_creds);
     155
     156    if ( ctxt->sc->srp_tpasswd_conf_file != NULL && ctxt->sc->srp_tpasswd_file != NULL) {
     157       gnutls_credentials_set(session, GNUTLS_CRD_SRP,
     158         ctxt->sc->srp_creds);
     159    }
     160
     161    /* update the priorities - to avoid negotiating a ciphersuite that is not
     162     * enabled on this virtual server. Note that here we ignore the version
     163     * negotiation.
     164     */
     165    ret = gnutls_priority_set( session, ctxt->sc->priorities);
     166    gnutls_certificate_type_set_priority( session, cert_type_prio);
     167   
     168   
     169    /* actually it shouldn't fail since we have checked at startup */
     170    if (ret < 0) return ret;
     171
     172    /* allow separate caches per virtual host. Actually allowing the same is not
     173     * a good idea, especially if they have different security requirements.
     174     */
     175    mgs_cache_session_init(ctxt);
     176
     177    return 0;
     178}
     179
     180static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret)
     181{
     182    mgs_handle_t *ctxt;
     183
     184    ctxt = gnutls_transport_get_ptr(session);
     185
     186    ret->type = GNUTLS_CRT_X509;
     187    ret->ncerts = 1;
     188    ret->deinit_all = 0;
     189
     190    ret->cert.x509 = &ctxt->sc->cert_x509;
     191    ret->key.x509 = ctxt->sc->privkey_x509;
     192    return 0;
     193}
     194
     195const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
     196"MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
     197"gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
     198"KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n"
     199"dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n"
     200"YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n"
     201"Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n"
     202"-----END DH PARAMETERS-----\n";
     203
     204int
     205mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
     206                     apr_pool_t * ptemp, server_rec * base_server)
    122207{
    123208    int rv;
    124     int data_len;
     209    size_t data_len;
    125210    server_rec *s;
    126211    gnutls_dh_params_t dh_params;
     
    131216    int first_run = 0;
    132217    const char *userdata_key = "mgs_init";
    133          
     218
    134219    apr_pool_userdata_get(&data, userdata_key, base_server->process->pool);
    135220    if (data == NULL) {
    136         first_run = 1;
    137         apr_pool_userdata_set((const void *)1, userdata_key,
    138                               apr_pool_cleanup_null,
    139                               base_server->process->pool);
     221        first_run = 1;
     222        apr_pool_userdata_set((const void *) 1, userdata_key,
     223                              apr_pool_cleanup_null,
     224                              base_server->process->pool);
    140225    }
    141226
    142227
    143228    {
    144         gnutls_datum pdata;
    145         apr_pool_t* tpool;
    146         s = base_server;
    147         sc_base = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    148                                                              &gnutls_module);
    149 
    150         apr_pool_create(&tpool, p);
    151 
    152         gnutls_dh_params_init(&dh_params);
    153 
    154         pdata = load_params(sc_base->dh_params_file, s, tpool);
    155 
    156         if (pdata.size != 0) {
    157             rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
    158                                                GNUTLS_X509_FMT_PEM);
    159             if (rv != 0) {
    160                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    161                              "GnuTLS: Unable to load DH Params: (%d) %s",
    162                              rv, gnutls_strerror(rv));
    163                 exit(rv);
     229        gnutls_datum pdata;
     230        apr_pool_t *tpool;
     231        s = base_server;
     232        sc_base =
     233            (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     234                                                     &gnutls_module);
     235
     236        apr_pool_create(&tpool, p);
     237
     238        gnutls_dh_params_init(&dh_params);
     239
     240        pdata = load_params(sc_base->dh_params_file, s, tpool);
     241
     242        if (pdata.size != 0) {
     243            rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
     244                                               GNUTLS_X509_FMT_PEM);
     245            if (rv != 0) {
     246                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     247                             "GnuTLS: Unable to load DH Params: (%d) %s",
     248                             rv, gnutls_strerror(rv));
     249                exit(rv);
     250            }
     251        } else {
     252            /* If the file does not exist use internal parameters
     253             */
     254            pdata.data = (void*)static_dh_params;
     255            pdata.size = sizeof( static_dh_params);
     256            rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,
     257                                               GNUTLS_X509_FMT_PEM);
     258
     259            if (rv < 0) {
     260              ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     261                         "GnuTLS: Unable to load internal DH Params."
     262                         " Shutting down.");
     263              exit(-1);
    164264            }
    165         }
    166         else {
    167             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    168                          "GnuTLS: Unable to load DH Params."
    169                          " Shutting Down.");
    170             exit(-1);
    171         }
    172         apr_pool_clear(tpool);
    173 
    174         gnutls_rsa_params_init(&rsa_params);
    175 
    176         pdata = load_params(sc_base->rsa_params_file, s, tpool);
    177 
    178         if (pdata.size != 0) {
    179             rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata,
    180                                                 GNUTLS_X509_FMT_PEM);
    181             if (rv != 0) {
    182                 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    183                              "GnuTLS: Unable to load RSA Params: (%d) %s",
    184                              rv, gnutls_strerror(rv));
    185                 exit(rv);
    186             }
    187         }
    188         else {
    189             ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
    190                          "GnuTLS: Unable to load RSA Params."
    191                          " Shutting Down.");
    192             exit(-1);
    193         }
    194 
    195         apr_pool_destroy(tpool);
    196         rv = mgs_cache_post_config(p, s, sc_base);
    197         if (rv != 0) {
    198             ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
    199                          "GnuTLS: Post Config for GnuTLSCache Failed."
    200                          " Shutting Down.");
    201             exit(-1);
    202         }
    203          
    204         for (s = base_server; s; s = s->next) {
    205             sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    206                                                                  &gnutls_module);
    207             sc->cache_type = sc_base->cache_type;
    208             sc->cache_config = sc_base->cache_config;
    209 
    210             gnutls_certificate_set_rsa_export_params(sc->certs,
    211                                                      rsa_params);
    212             gnutls_certificate_set_dh_params(sc->certs, dh_params);
    213 
    214             if (sc->cert_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
    215                 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
    216                              "[GnuTLS] - Host '%s:%d' is missing a "
    217                              "Certificate File!",
    218                          s->server_hostname, s->port);
    219                 exit(-1);
     265        }
     266        apr_pool_clear(tpool);
     267
     268        rsa_params = NULL;
     269       
     270        pdata = load_params(sc_base->rsa_params_file, s, tpool);
     271
     272        if (pdata.size != 0) {
     273            gnutls_rsa_params_init(&rsa_params);
     274            rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata,
     275                                                GNUTLS_X509_FMT_PEM);
     276            if (rv != 0) {
     277                ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     278                             "GnuTLS: Unable to load RSA Params: (%d) %s",
     279                             rv, gnutls_strerror(rv));
     280                exit(rv);
     281            }
     282        }
     283        /* not an error but RSA-EXPORT ciphersuites are not available
     284         */
     285
     286        apr_pool_destroy(tpool);
     287        rv = mgs_cache_post_config(p, s, sc_base);
     288        if (rv != 0) {
     289            ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,
     290                         "GnuTLS: Post Config for GnuTLSCache Failed."
     291                         " Shutting Down.");
     292            exit(-1);
     293        }
     294
     295        for (s = base_server; s; s = s->next) {
     296            sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     297                                                          &gnutls_module);
     298            sc->cache_type = sc_base->cache_type;
     299            sc->cache_config = sc_base->cache_config;
     300
     301            if (rsa_params != NULL)
     302              gnutls_certificate_set_rsa_export_params(sc->certs,
     303                                                     rsa_params);
     304            gnutls_certificate_set_dh_params(sc->certs, dh_params);
     305
     306            gnutls_anon_set_server_dh_params( sc->anon_creds, dh_params);
     307           
     308            gnutls_certificate_server_set_retrieve_function(sc->certs,
     309                                                    cert_retrieve_fn);
     310
     311            if ( sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) {
     312                gnutls_srp_set_server_credentials_file( sc->srp_creds,
     313                    sc->srp_tpasswd_file, sc->srp_tpasswd_conf_file);
    220314            }
    221315           
    222             if (sc->privkey_x509 == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) {
    223                 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
    224                              "[GnuTLS] - Host '%s:%d' is missing a "
    225                              "Private Key File!",
    226                              s->server_hostname, s->port);
    227                 exit(-1);
     316            if (sc->cert_x509 == NULL
     317                && sc->enabled == GNUTLS_ENABLED_TRUE) {
     318                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     319                             "[GnuTLS] - Host '%s:%d' is missing a "
     320                             "Certificate File!", s->server_hostname,
     321                             s->port);
     322                exit(-1);
     323            }
     324
     325            if (sc->privkey_x509 == NULL
     326                && sc->enabled == GNUTLS_ENABLED_TRUE) {
     327                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     328                             "[GnuTLS] - Host '%s:%d' is missing a "
     329                             "Private Key File!",
     330                             s->server_hostname, s->port);
     331                exit(-1);
     332            }
     333
     334            if (sc->enabled == GNUTLS_ENABLED_TRUE) {
     335            rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
     336                                               GNUTLS_OID_X520_COMMON_NAME,
     337                                               0, 0, NULL, &data_len);
     338
     339            if (data_len < 1) {
     340                sc->enabled = GNUTLS_ENABLED_FALSE;
     341                sc->cert_cn = NULL;
     342                continue;
     343            }
     344
     345            sc->cert_cn = apr_palloc(p, data_len);
     346            rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
     347                                               GNUTLS_OID_X520_COMMON_NAME,
     348                                               0, 0, sc->cert_cn,
     349                                               &data_len);
    228350            }
    229            
    230             rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
    231                                                GNUTLS_OID_X520_COMMON_NAME, 0, 0,
    232                                                NULL, &data_len);
    233            
    234             if (data_len < 1) {
    235                 sc->enabled = GNUTLS_ENABLED_FALSE;
    236                 sc->cert_cn = NULL;
    237                 continue;
    238             }
    239            
    240             sc->cert_cn = apr_palloc(p, data_len);
    241             rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,
    242                                                GNUTLS_OID_X520_COMMON_NAME, 0, 0,
    243                                                sc->cert_cn, &data_len);
    244         }
     351        }
    245352    }
    246353
     
    250357}
    251358
    252 void mgs_hook_child_init(apr_pool_t *p, server_rec *s)
     359void mgs_hook_child_init(apr_pool_t * p, server_rec * s)
    253360{
    254361    apr_status_t rv = APR_SUCCESS;
    255362    mgs_srvconf_rec *sc = ap_get_module_config(s->module_config,
    256                                                       &gnutls_module);
     363                                               &gnutls_module);
    257364
    258365    if (sc->cache_type != mgs_cache_none) {
    259         rv = mgs_cache_child_init(p, s, sc);
    260         if(rv != APR_SUCCESS) {
    261             ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
    262                              "[GnuTLS] - Failed to run Cache Init");
    263         }
    264     }
    265     else {
    266         ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
    267                      "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
     366        rv = mgs_cache_child_init(p, s, sc);
     367        if (rv != APR_SUCCESS) {
     368            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
     369                         "[GnuTLS] - Failed to run Cache Init");
     370        }
     371    } else {
     372        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
     373                     "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
    268374    }
    269375}
     
    272378{
    273379    mgs_srvconf_rec *sc =
    274         (mgs_srvconf_rec *) ap_get_module_config(r->server->
    275                                                         module_config,
    276                                                         &gnutls_module);
     380        (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
     381                                                 &gnutls_module);
    277382
    278383    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
    279         return NULL;
     384        return NULL;
    280385    }
    281386
     
    286391{
    287392    mgs_srvconf_rec *sc =
    288         (mgs_srvconf_rec *) ap_get_module_config(r->server->
    289                                                         module_config,
    290                                                         &gnutls_module);
     393        (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
     394                                                 &gnutls_module);
    291395
    292396    if (sc->enabled == GNUTLS_ENABLED_FALSE) {
    293         return 0;
     397        return 0;
    294398    }
    295399
     
    300404
    301405#if USING_2_1_RECENT
    302 typedef struct
    303 {
     406typedef struct {
    304407    mgs_handle_t *ctxt;
    305408    mgs_srvconf_rec *sc;
    306     const char* sni_name;
     409    const char *sni_name;
    307410} vhost_cb_rec;
    308411
    309 static int vhost_cb (void* baton, conn_rec* conn, server_rec* s)
     412static int vhost_cb(void *baton, conn_rec * conn, server_rec * s)
    310413{
    311414    mgs_srvconf_rec *tsc;
    312     vhost_cb_rec* x = baton;
     415    vhost_cb_rec *x = baton;
    313416
    314417    tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    315                                                           &gnutls_module);
    316    
     418                                                   &gnutls_module);
     419
    317420    if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) {
    318         return 0;
    319     }
    320    
     421        return 0;
     422    }
     423
    321424    /* The CN can contain a * -- this will match those too. */
    322425    if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) {
    323         /* found a match */
     426        /* found a match */
    324427#if MOD_GNUTLS_DEBUG
    325         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    326                      x->ctxt->c->base_server,
    327                      "GnuTLS: Virtual Host CB: "
    328                      "'%s' == '%s'", tsc->cert_cn, x->sni_name);
    329 #endif
    330         /* Because we actually change the server used here, we need to reset
    331         * things like ClientVerify.
    332         */
    333         x->sc = tsc;
    334         /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
    335         * certificate structure *should* change when the server changes.
    336         * acccckkkkkk.
    337         */
    338         return 1;
     428        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     429                     x->ctxt->c->base_server,
     430                     "GnuTLS: Virtual Host CB: "
     431                     "'%s' == '%s'", tsc->cert_cn, x->sni_name);
     432#endif
     433        /* Because we actually change the server used here, we need to reset
     434        * things like ClientVerify.
     435        */
     436        x->sc = tsc;
     437        /* Shit. Crap. Dammit. We *really* should rehandshake here, as our
     438        * certificate structure *should* change when the server changes.
     439        * acccckkkkkk.
     440        */
     441        return 1;
    339442    }
    340443    return 0;
     
    342445#endif
    343446
    344 mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session)
     447mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
    345448{
    346449    int rv;
    347     int sni_type;
    348     int data_len = MAX_HOST_LEN;
     450    unsigned int sni_type;
     451    size_t data_len = MAX_HOST_LEN;
    349452    char sni_name[MAX_HOST_LEN];
    350453    mgs_handle_t *ctxt;
     
    352455    vhost_cb_rec cbx;
    353456#else
    354     server_rec* s;
    355     mgs_srvconf_rec *tsc;   
    356 #endif
    357    
     457    server_rec *s;
     458    mgs_srvconf_rec *tsc;
     459#endif
     460
    358461    ctxt = gnutls_transport_get_ptr(session);
    359    
     462
    360463    sni_type = gnutls_certificate_type_get(session);
    361464    if (sni_type != GNUTLS_CRT_X509) {
    362         /* In theory, we could support OpenPGP Certificates. Theory != code. */
    363         ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
    364                      ctxt->c->base_server,
    365                      "GnuTLS: Only x509 Certificates are currently supported.");
    366         return NULL;
    367     }
    368    
    369     rv = gnutls_server_name_get(ctxt->session, sni_name, 
    370                                 &data_len, &sni_type, 0);
    371    
     465        /* In theory, we could support OpenPGP Certificates. Theory != code. */
     466        ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
     467                     ctxt->c->base_server,
     468                     "GnuTLS: Only x509 Certificates are currently supported.");
     469        return NULL;
     470    }
     471
     472    rv = gnutls_server_name_get(ctxt->session, sni_name,
     473                                &data_len, &sni_type, 0);
     474
    372475    if (rv != 0) {
    373         return NULL;
    374     }
    375    
     476        return NULL;
     477    }
     478
    376479    if (sni_type != GNUTLS_NAME_DNS) {
    377         ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
    378                      ctxt->c->base_server,
    379                      "GnuTLS: Unknown type '%d' for SNI: "
    380                      "'%s'", sni_type, sni_name);
    381         return NULL;
    382     }
    383    
     480        ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
     481                     ctxt->c->base_server,
     482                     "GnuTLS: Unknown type '%d' for SNI: "
     483                     "'%s'", sni_type, sni_name);
     484        return NULL;
     485    }
     486
    384487    /**
    385488     * Code in the Core already sets up the c->base_server as the base
     
    390493    cbx.sc = NULL;
    391494    cbx.sni_name = sni_name;
    392    
     495
    393496    rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);
    394497    if (rv == 1) {
    395         return cbx.sc;
     498        return cbx.sc;
    396499    }
    397500#else
    398501    for (s = ap_server_conf; s; s = s->next) {
    399        
    400         tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
    401                                                        &gnutls_module);
    402         if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
    403             continue;
    404         }
     502
     503        tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config,
     504                                                       &gnutls_module);
     505        if (tsc->enabled != GNUTLS_ENABLED_TRUE) {
     506            continue;
     507        }
    405508#if MOD_GNUTLS_DEBUG
    406         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    407                      ctxt->c->base_server,
    408                      "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X  sc: 0x%08X", tsc->cert_cn, rv,
    409                      gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)),
    410                      (unsigned int)s, (unsigned int)s->next, (unsigned int)tsc);
    411 #endif           
    412         /* The CN can contain a * -- this will match those too. */
    413         if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
     509        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     510                     ctxt->c->base_server,
     511                     "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X  sc: 0x%08X",
     512                     tsc->cert_cn, rv,
     513                     gnutls_pk_algorithm_get_name
     514                     (gnutls_x509_privkey_get_pk_algorithm
     515                      (ctxt->sc->privkey_x509)), (unsigned int) s,
     516                     (unsigned int) s->next, (unsigned int) tsc);
     517#endif
     518        /* The CN can contain a * -- this will match those too. */
     519        if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) {
    414520#if MOD_GNUTLS_DEBUG
    415             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
    416                         ctxt->c->base_server,
    417                         "GnuTLS: Virtual Host: "
    418                         "'%s' == '%s'", tsc->cert_cn, sni_name);
    419 #endif
    420             return tsc;
    421         }
     521            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     522                        ctxt->c->base_server,
     523                        "GnuTLS: Virtual Host: "
     524                        "'%s' == '%s'", tsc->cert_cn, sni_name);
     525#endif
     526            return tsc;
     527        }
    422528    }
    423529#endif
     
    426532
    427533
    428 static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret)
    429 {
    430     mgs_handle_t *ctxt;
    431     mgs_srvconf_rec *tsc;
    432    
    433     ctxt = gnutls_transport_get_ptr(session);
    434 
    435     ret->type = GNUTLS_CRT_X509;
    436     ret->ncerts = 1;
    437     ret->deinit_all = 0;
    438 
    439     tsc = mgs_find_sni_server(session);
    440    
    441     if (tsc != NULL) {
    442         ctxt->sc = tsc;
    443         gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
    444     }
    445    
    446     ret->cert.x509 = &ctxt->sc->cert_x509;
    447     ret->key.x509 = ctxt->sc->privkey_x509;
    448     return 0;
    449 }
    450 
    451 static mgs_handle_t* create_gnutls_handle(apr_pool_t* pool, conn_rec * c)
     534static const int protocol_priority[] = {
     535  GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
     536         
     537
     538static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c)
    452539{
    453540    mgs_handle_t *ctxt;
    454541    mgs_srvconf_rec *sc =
    455         (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
    456                                                         module_config,
    457                                                         &gnutls_module);
     542        (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
     543                                                module_config,
     544                                                &gnutls_module);
    458545
    459546    ctxt = apr_pcalloc(pool, sizeof(*ctxt));
     
    472559
    473560    gnutls_init(&ctxt->session, GNUTLS_SERVER);
    474 
    475     gnutls_protocol_set_priority(ctxt->session, sc->protocol);
    476     gnutls_cipher_set_priority(ctxt->session, sc->ciphers);
    477     gnutls_compression_set_priority(ctxt->session, sc->compression);
    478     gnutls_kx_set_priority(ctxt->session, sc->key_exchange);
    479     gnutls_mac_set_priority(ctxt->session, sc->macs);
    480     gnutls_certificate_type_set_priority(ctxt->session, sc->cert_types);
    481 
    482     mgs_cache_session_init(ctxt);
    483561   
    484     gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs);
    485 
    486     gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn);
    487     gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode);
     562    /* This is not very good as it trades security for compatibility,
     563     * but it is the only way to be ultra-portable.
     564     */
     565    gnutls_session_enable_compatibility_mode( ctxt->session);
     566   
     567    /* because we don't set any default priorities here (we set later at
     568     * the user hello callback) we need to at least set this in order for
     569     * gnutls to be able to read packets.
     570     */
     571    gnutls_protocol_set_priority( ctxt->session, protocol_priority);
     572
     573    gnutls_handshake_set_post_client_hello_function( ctxt->session, mgs_select_virtual_server_cb);
     574
    488575    return ctxt;
    489576}
     
    493580    mgs_handle_t *ctxt;
    494581    mgs_srvconf_rec *sc =
    495         (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
    496                                                         module_config,
    497                                                         &gnutls_module);
     582        (mgs_srvconf_rec *) ap_get_module_config(c->base_server->
     583                                                module_config,
     584                                                &gnutls_module);
    498585
    499586    if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
    500         return DECLINED;
     587        return DECLINED;
    501588    }
    502589
     
    505592    ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    506593
    507     gnutls_transport_set_pull_function(ctxt->session,
    508                                        mgs_transport_read);
    509     gnutls_transport_set_push_function(ctxt->session,
    510                                        mgs_transport_write);
     594    gnutls_transport_set_pull_function(ctxt->session, mgs_transport_read);
     595    gnutls_transport_set_push_function(ctxt->session, mgs_transport_write);
    511596    gnutls_transport_set_ptr(ctxt->session, ctxt);
    512    
    513     ctxt->input_filter = ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt,
    514                                             NULL, c);
    515     ctxt->output_filter = ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt,
    516                                               NULL, c);
     597
     598    ctxt->input_filter =
     599        ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
     600    ctxt->output_filter =
     601        ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
    517602
    518603    return OK;
    519604}
    520605
    521 int mgs_hook_fixups(request_rec *r)
     606int mgs_hook_fixups(request_rec * r)
    522607{
    523608    unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
    524609    char buf[AP_IOBUFSIZE];
    525     const char* tmp;
    526     int len;
     610    const char *tmp;
     611    size_t len;
    527612    mgs_handle_t *ctxt;
    528613    int rv = OK;
    529    
     614
    530615    apr_table_t *env = r->subprocess_env;
    531616
    532     ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
    533 
    534     if(!ctxt) {
    535         return DECLINED;
     617    ctxt =
     618        ap_get_module_config(r->connection->conn_config, &gnutls_module);
     619
     620    if (!ctxt) {
     621        return DECLINED;
    536622    }
    537623
    538624    apr_table_setn(env, "HTTPS", "on");
    539625
    540     apr_table_setn(env, "GNUTLS_VERSION_INTERFACE", MOD_GNUTLS_VERSION);
    541     apr_table_setn(env, "GNUTLS_VERSION_LIBRARY", LIBGNUTLS_VERSION);
     626    apr_table_setn(env, "SSL_VERSION_LIBRARY", "GnuTLS/"LIBGNUTLS_VERSION);
     627    apr_table_setn(env, "SSL_VERSION_INTERFACE", "mod_gnutls/"MOD_GNUTLS_VERSION);
    542628
    543629    apr_table_setn(env, "SSL_PROTOCOL",
    544                    gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session)));
    545 
     630                   gnutls_protocol_get_name(gnutls_protocol_get_version
     631                                            (ctxt->session)));
     632
     633    /* should have been called SSL_CIPHERSUITE instead */                                         
    546634    apr_table_setn(env, "SSL_CIPHER",
    547                    gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session)));
    548 
    549     apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
    550 
    551     tmp = apr_psprintf(r->pool, "%d",
    552               8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)));
     635          gnutls_cipher_suite_get_name(
     636            gnutls_kx_get(ctxt->session), gnutls_cipher_get(ctxt->session),
     637                    gnutls_mac_get(ctxt->session)));
     638
     639    apr_table_setn(env, "SSL_COMPRESS_METHOD",
     640                   gnutls_compression_get_name(gnutls_compression_get
     641                                          (ctxt->session)));
     642
     643    apr_table_setn(env, "SSL_SRP_USER",
     644                   gnutls_srp_server_get_username( ctxt->session));
     645
     646    if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL)
     647        apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
     648
     649    unsigned int key_size =
     650        8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session));
     651    tmp = apr_psprintf(r->pool, "%u", key_size);
    553652
    554653    apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
    555654
    556655    apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
     656
     657    apr_table_setn(env, "SSL_CIPHER_EXPORT",
     658                   (key_size <= 40) ? "true" : "false");
    557659
    558660    len = sizeof(sbuf);
     
    561663    apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
    562664
    563     /* TODO: There are many other env vars that we need to add */
    564     {
    565         len = sizeof(buf);
    566         gnutls_x509_crt_get_dn(ctxt->sc->cert_x509, buf, &len);
    567         apr_table_setn(env, "SSL_SERVER_S_DN", apr_pstrmemdup(r->pool, buf, len));
    568            
    569         len = sizeof(buf);
    570         gnutls_x509_crt_get_issuer_dn(ctxt->sc->cert_x509, buf, &len);
    571         apr_table_setn(env, "SSL_SERVER_I_DN", apr_pstrmemdup(r->pool, buf, len));
    572     }
     665    mgs_add_common_cert_vars(r, ctxt->sc->cert_x509, 0, ctxt->sc->export_certificates_enabled);
     666
    573667    return rv;
    574668}
    575669
    576 int mgs_hook_authz(request_rec *r)
     670int mgs_hook_authz(request_rec * r)
    577671{
    578672    int rv;
    579     int status;
    580673    mgs_handle_t *ctxt;
    581674    mgs_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
    582                                                       &gnutls_module);
    583    
    584     ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module);
    585    
     675                                               &gnutls_module);
     676
     677    ctxt =
     678        ap_get_module_config(r->connection->conn_config, &gnutls_module);
     679
    586680    if (!ctxt) {
    587         return DECLINED;
     681        return DECLINED;
    588682    }
    589683
    590684    if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) {
    591         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    592                       "GnuTLS: Directory set to Ignore Client Certificate!");
    593     }
    594     else {
    595         if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
    596             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    597                           "GnuTLS: Attempting to rehandshake with peer. %d %d",
    598                           ctxt->sc->client_verify_mode, dc->client_verify_mode);
    599        
    600             gnutls_certificate_server_set_request(ctxt->session,
    601                                               dc->client_verify_mode);
    602    
    603             if (mgs_rehandshake(ctxt) != 0) {
    604                 return HTTP_FORBIDDEN;
    605             }
    606         }
    607         else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) {
     685        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     686                      "GnuTLS: Directory set to Ignore Client Certificate!");
     687    } else {
     688        if (ctxt->sc->client_verify_mode < dc->client_verify_mode) {
     689            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     690                          "GnuTLS: Attempting to rehandshake with peer. %d %d",
     691                          ctxt->sc->client_verify_mode,
     692                          dc->client_verify_mode);
     693
     694            gnutls_certificate_server_set_request(ctxt->session,
     695                                                  dc->client_verify_mode);
     696
     697            if (mgs_rehandshake(ctxt) != 0) {
     698                return HTTP_FORBIDDEN;
     699            }
     700        } else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) {
    608701#if MOD_GNUTLS_DEBUG
    609         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    610                       "GnuTLS: Peer is set to IGNORE");
    611 #endif
    612         }
    613         else {
    614             rv = mgs_cert_verify(r, ctxt);
    615             if (rv != DECLINED) {
    616                 return rv;
    617             }
    618         }
    619 
    620 
    621 static int mgs_cert_verify(request_rec *r, mgs_handle_t *ctxt)
    622 {
    623     const gnutls_datum_t* cert_list;
    624     int cert_list_size;
     702            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     703                          "GnuTLS: Peer is set to IGNORE");
     704#endif
     705        } else {
     706            rv = mgs_cert_verify(r, ctxt);
     707            if (rv != DECLINED) {
     708                return rv;
     709            }
     710        }
     711    }
     712
     713    return DECLINED;
     714}
     715
     716/* variables that are not sent by default:
     717 *
     718 * SSL_CLIENT_CERT      string  PEM-encoded client certificate
     719 * SSL_SERVER_CERT      string  PEM-encoded client certificate
     720 */
     721
     722/* side is either 0 for SERVER or 1 for CLIENT
     723 */
     724#define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT")
     725static void
     726mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, int export_certificates_enabled)
     727{
     728    unsigned char sbuf[64];     /* buffer to hold serials */
     729    char buf[AP_IOBUFSIZE];
     730    const char *tmp;
     731    size_t len;
     732    int alg;
     733
     734    apr_table_t *env = r->subprocess_env;
     735
     736    if (export_certificates_enabled != 0) {
     737      char cert_buf[10*1024];
     738      len = sizeof(cert_buf);
     739
     740      if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0)
     741        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL),
     742                   apr_pstrmemdup(r->pool, cert_buf, len));
     743     
     744    }
     745
     746    len = sizeof(buf);
     747    gnutls_x509_crt_get_dn(cert, buf, &len);
     748    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL),
     749                   apr_pstrmemdup(r->pool, buf, len));
     750
     751    len = sizeof(buf);
     752    gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
     753    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL),
     754                   apr_pstrmemdup(r->pool, buf, len));
     755
     756    len = sizeof(sbuf);
     757    gnutls_x509_crt_get_serial(cert, sbuf, &len);
     758    tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
     759    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL),
     760                   apr_pstrdup(r->pool, tmp));
     761
     762    tmp =
     763        mgs_time2sz(gnutls_x509_crt_get_expiration_time
     764                    (cert), buf, sizeof(buf));
     765    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
     766                   apr_pstrdup(r->pool, tmp));
     767
     768    tmp =
     769        mgs_time2sz(gnutls_x509_crt_get_activation_time
     770                    (cert), buf, sizeof(buf));
     771    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
     772                   apr_pstrdup(r->pool, tmp));
     773
     774    alg = gnutls_x509_crt_get_signature_algorithm( cert);
     775    if (alg >= 0) {
     776      apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL),
     777          gnutls_sign_algorithm_get_name( alg));
     778    }
     779
     780    alg = gnutls_x509_crt_get_pk_algorithm( cert, NULL);
     781    if (alg >= 0) {
     782      apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
     783          gnutls_pk_algorithm_get_name( alg));
     784    }
     785
     786
     787}
     788
     789
     790static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
     791{
     792    const gnutls_datum_t *cert_list;
     793    unsigned int cert_list_size, status, expired;
     794    int rv, ret;
    625795    gnutls_x509_crt_t cert;
    626 
    627 
    628     cert_list = gnutls_certificate_get_peers(ctxt->session, &cert_list_size);
     796    apr_time_t activation_time, expiration_time, cur_time;
     797
     798    cert_list =
     799        gnutls_certificate_get_peers(ctxt->session, &cert_list_size);
    629800
    630801    if (cert_list == NULL || cert_list_size == 0) {
    631         /* no certificate provided by the client, but one was required. */
    632         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    633                          "GnuTLS: Failed to Verify Peer: "
    634                          "Client did not submit a certificate");
    635         return HTTP_FORBIDDEN;
     802        /* It is perfectly OK for a client not to send a certificate if on REQUEST mode
     803         */
     804        if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
     805            return OK;
     806
     807        /* no certificate provided by the client, but one was required. */
     808        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     809                      "GnuTLS: Failed to Verify Peer: "
     810                      "Client did not submit a certificate");
     811        return HTTP_FORBIDDEN;
    636812    }
    637813
    638814    if (cert_list_size > 1) {
    639         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    640                          "GnuTLS: Failed to Verify Peer: "
    641                          "Chained Client Certificates are not supported.");
    642         return HTTP_FORBIDDEN;
     815        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     816                      "GnuTLS: Failed to Verify Peer: "
     817                      "Chained Client Certificates are not supported.");
     818        return HTTP_FORBIDDEN;
    643819    }
    644820
    645821    gnutls_x509_crt_init(&cert);
    646     gnutls_x509_crt_import(cert, &cert_chain[0], GNUTLS_X509_FMT_DER);
    647 
    648     rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list, ctxt->sc->ca_list_size, 0, &status);
    649 
     822    rv = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
    650823    if (rv < 0) {
    651         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    652                      "GnuTLS: Failed to Verify Peer: (%d) %s",
    653                      rv, gnutls_strerror(rv));
    654         return HTTP_FORBIDDEN;
    655     }
    656    
    657         if (status < 0) {
    658             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    659                          "GnuTLS: Peer Status is invalid.");
    660             return HTTP_FORBIDDEN;
    661         }
    662    
    663         if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
    664             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    665                          "GnuTLS: Could not find Signer for Peer Certificate");
    666         }
    667    
    668         if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
    669             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    670                          "GnuTLS: Could not find CA for Peer Certificate");
    671         }
    672    
    673         if (status & GNUTLS_CERT_INVALID) {
    674             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    675                          "GnuTLS: Peer Certificate is invalid.");
    676             return HTTP_FORBIDDEN;
    677         }
    678         else if (status & GNUTLS_CERT_REVOKED) {
    679             ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    680                          "GnuTLS: Peer Certificate is revoked.");
    681             return HTTP_FORBIDDEN;
    682         }
    683    
    684         /* TODO: OpenPGP Certificates */
    685         if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) {
    686             ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
    687                          "GnuTLS: Only x509 is supported for client certificates");         
    688             return HTTP_FORBIDDEN;
    689         }
    690         /* TODO: Further Verification. */
    691 //        gnutls_x509_crt_get_expiration_time() < time
    692 //        gnutls_x509_crt_get_activation_time() > time
     824        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     825                      "GnuTLS: Failed to Verify Peer: "
     826                      "Failed to import peer certificates.");
     827        ret = HTTP_FORBIDDEN;
     828        goto exit;
     829    }
     830
     831    apr_time_ansi_put(&expiration_time,
     832                      gnutls_x509_crt_get_expiration_time(cert));
     833    apr_time_ansi_put(&activation_time,
     834                      gnutls_x509_crt_get_activation_time(cert));
     835
     836    rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list,
     837                                ctxt->sc->ca_list_size, 0, &status);
     838
     839    if (rv < 0) {
     840        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     841                      "GnuTLS: Failed to Verify Peer certificate: (%d) %s",
     842                      rv, gnutls_strerror(rv));
     843        ret = HTTP_FORBIDDEN;
     844        goto exit;
     845    }
     846
     847    expired = 0;
     848    cur_time = apr_time_now();
     849    if (activation_time > cur_time) {
     850        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     851                      "GnuTLS: Failed to Verify Peer: "
     852                      "Peer Certificate is not yet activated.");
     853        expired = 1;
     854    }
     855
     856    if (expiration_time < cur_time) {
     857        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     858                      "GnuTLS: Failed to Verify Peer: "
     859                      "Peer Certificate is expired.");
     860        expired = 1;
     861    }
     862
     863    if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
     864        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     865                      "GnuTLS: Could not find Signer for Peer Certificate");
     866    }
     867
     868    if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
     869        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     870                      "GnuTLS: Peer's Certificate signer is not a CA");
     871    }
     872
     873    if (status & GNUTLS_CERT_INVALID) {
     874        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     875                      "GnuTLS: Peer Certificate is invalid.");
     876    } else if (status & GNUTLS_CERT_REVOKED) {
     877        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     878                      "GnuTLS: Peer Certificate is revoked.");
     879    }
     880
     881    /* TODO: Further Verification. */
     882    /* Revocation is X.509 non workable paradigm, I really doubt implementation
     883     * is worth doing --nmav
     884     */
    693885/// ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size);
    694         ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
    695                  "GnuTLS: Verified Peer.");     
    696     }
    697 
    698     ap_add_common_vars(r);
    699     mgs_hook_fixups(r);
    700     status = mgs_authz_lua(r);
    701 
    702     if (status != 0) {
    703         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    704                       "GnuTLS: FAILED Authorization Test");
    705         return HTTP_FORBIDDEN;
    706     }
    707 
    708 }
    709 
     886
     887//    mgs_hook_fixups(r);
     888//    rv = mgs_authz_lua(r);
     889
     890    mgs_add_common_cert_vars(r, cert, 1, ctxt->sc->export_certificates_enabled);
     891
     892    {
     893      /* days remaining */
     894      unsigned long remain = (apr_time_sec(expiration_time) - apr_time_sec(cur_time))/86400;
     895      apr_table_setn(r->subprocess_env, "SSL_CLIENT_V_REMAIN",
     896          apr_psprintf(r->pool, "%lu", remain));
     897    }
     898
     899    if (status == 0 && expired == 0) {
     900        apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY", "SUCCESS");
     901        ret = OK;
     902    } else {
     903        apr_table_setn(r->subprocess_env, "SSL_CLIENT_VERIFY", "FAILED");
     904        if (ctxt->sc->client_verify_mode == GNUTLS_CERT_REQUEST)
     905            ret = OK;
     906        else
     907            ret = HTTP_FORBIDDEN;
     908    }
     909
     910  exit:
     911    gnutls_x509_crt_deinit(cert);
     912    return ret;
     913
     914
     915}
  • src/gnutls_io.c

    r8e33f2d r7bebb42  
    544544        if (AP_BUCKET_IS_EOC(bucket)) {
    545545            do {
    546                 ret = gnutls_alert_send(ctxt->session, GNUTLS_AL_FATAL,
    547                                         GNUTLS_A_CLOSE_NOTIFY);
     546                ret = gnutls_bye( ctxt->session, GNUTLS_SHUT_WR);
    548547            } while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
    549548
     
    557556
    558557            apr_brigade_cleanup(ctxt->output_bb);
    559             gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    560558            gnutls_deinit(ctxt->session);
    561559            continue;
     
    569567                return status;
    570568            }
     569
    571570            apr_brigade_cleanup(ctxt->output_bb);
    572571            continue;
     
    600599                             ctxt->c->base_server,
    601600                             "GnuTLS: Error writing data."
    602                              " (%d) '%s'", ret, gnutls_strerror(ret));
     601                             " (%d) '%s'", (int)ret, gnutls_strerror(ret));
    603602                if (ctxt->output_rc == APR_SUCCESS) {
    604603                    ctxt->output_rc = APR_EGENERAL;
  • src/mod_gnutls.c

    r8e33f2d r7bebb42  
    6464                  NULL,
    6565                  RSRC_CONF,
    66                   "Set the CA File for Client Certificates"),
     66                  "Set the CA File to verify Client Certificates"),
     67    AP_INIT_TAKE1("GnuTLSDHFile", mgs_set_dh_file,
     68                  NULL,
     69                  RSRC_CONF,
     70                  "Set the file to read Diffie Hellman parameters from"),
     71    AP_INIT_TAKE1("GnuTLSRSAFile", mgs_set_rsa_export_file,
     72                  NULL,
     73                  RSRC_CONF,
     74                  "Set the file to read RSA-EXPORT parameters from"),
    6775    AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file,
    6876                  NULL,
     
    7280                  NULL,
    7381                  RSRC_CONF,
    74                   "SSL Server Certificate file"),
     82                  "SSL Server SRP Password file"),
     83    AP_INIT_TAKE1("GnuTLSSRPPasswdFile", mgs_set_srp_tpasswd_file,
     84                  NULL,
     85                  RSRC_CONF,
     86                  "SSL Server SRP Password Conf file"),
     87    AP_INIT_TAKE1("GnuTLSSRPPasswdConfFile", mgs_set_srp_tpasswd_conf_file,
     88                  NULL,
     89                  RSRC_CONF,
     90                  "SSL Server SRP Parameters file"),
    7591    AP_INIT_TAKE1("GnuTLSCacheTimeout", mgs_set_cache_timeout,
    7692                  NULL,
     
    8197                  RSRC_CONF,
    8298                  "Cache Configuration"),
     99    AP_INIT_RAW_ARGS("GnuTLSPriorities", mgs_set_priorities,
     100                  NULL,
     101                  RSRC_CONF,
     102                  "The priorities to enable (ciphers, Key exchange, macs, compression)"),
    83103    AP_INIT_TAKE1("GnuTLSEnable", mgs_set_enabled,
    84104                  NULL,
    85105                  RSRC_CONF,
    86106                  "Whether this server has GnuTLS Enabled. Default: Off"),
     107    AP_INIT_TAKE1("GnuTLSExportCertificates", mgs_set_export_certificates_enabled,
     108                  NULL,
     109                  RSRC_CONF,
     110                  "Whether to export PEM encoded certificates to CGIs. Default: Off"),
     111#if 0
    87112    AP_INIT_RAW_ARGS("<GnuTLSRequire", mgs_set_require_section,
    88113                  NULL,
     
    93118                     OR_ALL,
    94119                     "Internal Command for reading Lua Bytecode."),
     120#endif
    95121    {NULL}
    96122};
Note: See TracChangeset for help on using the changeset viewer.