Changeset a66e147 in mod_gnutls


Ignore:
Timestamp:
Dec 10, 2004, 1:08:52 AM (15 years ago)
Author:
Paul Querna <chip@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, upstream
Children:
95ca7c0
Parents:
76bd3bf
Message:

working support for a ssl session cache via memcached.

Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • configure.ac

    r76bd3bf ra66e147  
    2525CHECK_APR_MEMCACHE()
    2626
    27 MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES}"
    28 MODULE_LIBS="${LIBGNUTLS_LIBS} ${APR_MEMCACHE_LIBS}"
     27MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES}"
     28MODULE_LIBS="${APR_MEMCACHE_LIBS} ${LIBGNUTLS_LIBS}"
    2929
    3030AC_SUBST(MODULE_CFLAGS)
  • include/mod_gnutls.h

    r76bd3bf ra66e147  
    2929#include "apr_strings.h"
    3030#include "apr_tables.h"
     31
     32#include "apr_memcache.h"
    3133
    3234#include <gcrypt.h>
     
    6971    int protocol[16];
    7072    int compression[16];
     73    const char* cache_config;
    7174} mod_gnutls_srvconf_rec;
    7275
     
    156159
    157160
     161/**
     162 * Init the Cache inside each Process
     163 */
     164int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s,
     165                                mod_gnutls_srvconf_rec *sc);
     166/**
     167 * Setup the Session Caching
     168 */
     169int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt);
    158170#endif /*  __mod_gnutls_h_inc */
  • src/Makefile.am

    r76bd3bf ra66e147  
    33libmod_gnutls_la_SOURCES = mod_gnutls.c gnutls_io.c gnutls_cache.c
    44libmod_gnutls_la_CFLAGS = -Wall ${MODULE_CFLAGS}
    5 libmod_gnutls_la_LDFLAGS = ${MODULE_LIBS}
     5libmod_gnutls_la_LDFLAGS = -rpath ${AP_LIBEXECDIR} -module -avoid-version ${MODULE_LIBS}
    66
    77lib_LTLIBRARIES = libmod_gnutls.la
  • src/gnutls_cache.c

    r76bd3bf ra66e147  
    1717
    1818#include "mod_gnutls.h"
     19#include "ap_mpm.h"
    1920
    2021/**
     
    2223 *
    2324 */
    24 /*
    25 #include "memcache.h"
    26 
    27 int mod_gnutls_cache_init()
    28 {
    29   return 0;
    30 }
    31 static int cache_store((void* baton, gnutls_datum_t key, gnutls_datum_t data)
    32 {
    33     mc_set(struct memcache *mc,
    34            key->data, key->size,
    35            data->data, data->size,
    36            3600, 0);
    37   return 0;
    38 }
    39 
    40 static int cache_fetch(void* baton, gnutls_datum_t key)
    41 {
     25
     26/* The underlying apr_memcache system is thread safe... woohoo */
     27static apr_memcache_t* mc;
     28
     29int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s,
     30                                mod_gnutls_srvconf_rec *sc)
     31{
     32    apr_status_t rv = APR_SUCCESS;
     33    int thread_limit = 0;
     34    int nservers = 0;
     35    char* cache_config;
     36    char* split;
     37    char* tok;
     38
     39    ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
     40
     41    /* Find all the servers in the first run to get a total count */
     42    cache_config = apr_pstrdup(p, sc->cache_config);
     43    split = apr_strtok(cache_config, " ", &tok);
     44    while (split) {
     45        nservers++;
     46        split = apr_strtok(NULL," ", &tok);
     47    }
     48
     49    rv = apr_memcache_create(p, nservers, 0, &mc);
     50    if (rv != APR_SUCCESS) {
     51        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
     52                        "[gnutls_cache] Failed to create Memcache Object of '%d' size.",
     53                         nservers);
     54        return rv;
     55    }
     56
     57    /* Now add each server to the memcache */
     58    cache_config = apr_pstrdup(p, sc->cache_config);
     59    split = apr_strtok(cache_config, " ", &tok);
     60    while (split) {
     61        apr_memcache_server_t* st;
     62        char* split2;
     63        char* host_str;
     64        char* port_str;
     65        int port;
     66
     67        host_str = apr_strtok(split,":", &split2);
     68        port_str = apr_strtok(NULL,":", &split2);
     69        if (!port_str) {
     70            port = 11211; /* default port */
     71        }
     72        else {
     73            port = atoi(port_str);
     74        }
     75
     76        /* Should Max Conns be (thread_limit / nservers) ? */
     77        rv = apr_memcache_server_create(p,
     78                                        host_str, port,
     79                                        0,
     80                                        1,
     81                                        thread_limit,
     82                                        600,
     83                                        &st);
     84        if(rv != APR_SUCCESS) {
     85            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
     86                         "[gnutls_cache] Failed to Create Server: %s:%d",
     87                         host_str, port);
     88            return rv;
     89        }
     90
     91        rv = apr_memcache_add_server(mc, st);
     92        if(rv != APR_SUCCESS) {
     93            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
     94                         "[gnutls_cache] Failed to Add Server: %s:%d",
     95                         host_str, port);
     96            return rv;
     97        }
     98
     99        split = apr_strtok(NULL," ", &tok);
     100    }
     101    return rv;
     102}
     103
     104/* thanks mod_ssl */
     105#define GNUTLS_SESSION_ID_STRING_LEN \
     106    ((GNUTLS_MAX_SESSION_ID + 1) * 2)
     107#define MC_TAG "mod_gnutls:"
     108#define MC_TAG_LEN \
     109    (sizeof(MC_TAG))
     110#define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN)
     111
     112
     113static char *gnutls_session_id2sz(unsigned char *id, int idlen,
     114                        char *str, int strsize)
     115{
     116    char *cp;
     117    int n;
     118 
     119    cp = apr_cpystrn(str, MC_TAG, MC_TAG_LEN);
     120    for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
     121        apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]);
     122        cp += 2;
     123    }
     124    *cp = '\0';
     125    return str;
     126}
     127
     128
     129static int cache_store(void* baton, gnutls_datum_t key, gnutls_datum_t data)
     130{
     131    apr_status_t rv = APR_SUCCESS;
    42132    mod_gnutls_handle_t *ctxt = baton;
    43   return 0;
     133    char buf[STR_SESSION_LEN];
     134    char* strkey = NULL;
     135    apr_uint32_t timeout;
     136
     137    strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf));
     138    if(!strkey)
     139        return -1;
     140
     141    timeout = 3600;
     142
     143    rv = apr_memcache_set(mc,  strkey, data.data, data.size, timeout, 0);
     144
     145    if(rv != APR_SUCCESS) {
     146        ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
     147                     ctxt->c->base_server,
     148                     "[gnutls_cache] error setting key '%s' "
     149                     "with %d bytes of data", strkey, data.size);
     150        return -1;
     151    }
     152
     153    return 0;
     154}
     155
     156static gnutls_datum_t cache_fetch(void* baton, gnutls_datum_t key)
     157{
     158    apr_status_t rv = APR_SUCCESS;
     159    mod_gnutls_handle_t *ctxt = baton;
     160    char buf[STR_SESSION_LEN];
     161    char* strkey = NULL;
     162    char* value;
     163    apr_size_t value_len;
     164    gnutls_datum_t data = { NULL, 0 };
     165
     166    strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf));
     167    if(!strkey) {
     168        return data;
     169    }
     170
     171    rv = apr_memcache_getp(mc, ctxt->c->pool, strkey,
     172                           &value, &value_len, NULL);
     173
     174    if(rv != APR_SUCCESS) {
     175        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
     176                     ctxt->c->base_server,
     177                     "[gnutls_cache] error fetching key '%s' ",
     178                     strkey);
     179
     180        data.size = 0;
     181        data.data = NULL;
     182        return data;
     183    }
     184
     185    /* TODO: Eliminate this memcpy. ffs. gnutls-- */
     186    data.data = gnutls_malloc(value_len);
     187    if (data.data == NULL)
     188        return data;
     189
     190    data.size = value_len;
     191    memcpy(data.data, value, value_len);
     192
     193    return data;
    44194}
    45195
    46196static int cache_delete(void* baton, gnutls_datum_t key)
    47197{
     198    apr_status_t rv = APR_SUCCESS;
    48199    mod_gnutls_handle_t *ctxt = baton;
    49   return 0;
     200    char buf[STR_SESSION_LEN];
     201    char* strkey = NULL;
     202
     203    strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf));
     204    if(!strkey)
     205        return -1;
     206
     207    rv = apr_memcache_delete(mc, strkey, 0);
     208
     209    if(rv != APR_SUCCESS) {
     210        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
     211                     ctxt->c->base_server,
     212                     "[gnutls_cache] error deleting key '%s' ",
     213                      strkey);
     214        return -1;
     215    }
     216
     217    return 0;
    50218}
    51219
    52220int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt)
    53221{
    54     gnutls_db_set_cache_expiration
    55     gnutls_db_set_retrieve_function(session, cache_fetch);
    56     gnutls_db_set_remove_function(session, cache_delete);
    57     gnutls_db_set_store_function(session, cache_store);
    58     gnutls_db_set_ptr(session, NULL);
    59   return 0;
    60 }
    61 */
     222    gnutls_db_set_retrieve_function(ctxt->session, cache_fetch);
     223    gnutls_db_set_remove_function(ctxt->session, cache_delete);
     224    gnutls_db_set_store_function(ctxt->session, cache_store);
     225    gnutls_db_set_ptr(ctxt->session, ctxt);
     226    return 0;
     227}
  • src/gnutls_io.c

    r76bd3bf ra66e147  
    274274            else {
    275275                /* Some Other Error. Report it. Die. */
    276                 ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc,
    277                              ctxt->c->base_server,
    278                              "GnuTLS: Error reading data. (%d) '%s'", rc,
    279                              gnutls_strerror(rc));
     276                if(gnutls_error_is_fatal(rc)) {
     277                    ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc,
     278                                 ctxt->c->base_server,
     279                                 "GnuTLS: Error reading data. (%d) '%s'", rc,
     280                                 gnutls_strerror(rc));
     281                }
     282                else if(*len > 0) {
     283                    ctxt->input_rc = APR_SUCCESS;
     284                    break;
     285                }
    280286            }
    281287
     
    450456    while (!APR_BRIGADE_EMPTY(bb)) {
    451457        apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
    452         if (APR_BUCKET_IS_EOS(bucket)) {
    453 
    454             /* gnutls_bye(ctxt->session, GNUTLS_SHUT_RDWR); */
     458        if (APR_BUCKET_IS_EOS(bucket) || AP_BUCKET_IS_EOC(bucket)) {
     459
     460            gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
     461            gnutls_deinit(ctxt->session);
    455462
    456463            if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
     
    465472            }
    466473            break;
    467 
    468         }
    469         else if (AP_BUCKET_IS_EOC(bucket)) {
    470 
    471             gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    472             gnutls_deinit(ctxt->session);
    473             if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
    474                 return status;
    475             }
    476             break;
    477 
    478474        }
    479475        else {
  • src/mod_gnutls.c

    r76bd3bf ra66e147  
    7171
    7272
    73     if(first_run) {
     73//    if(first_run) {
    7474        /* TODO: Should we regenerate these after X requests / X time ? */
    7575        gnutls_dh_params_init(&dh_params);
     
    7979        gnutls_rsa_params_generate2(rsa_params, RSA_BITS);
    8080#endif
    81     }
     81//    }
    8282
    8383    for (s = base_server; s; s = s->next) {
     
    106106}
    107107
     108static void mod_gnutls_hook_child_init(apr_pool_t *p, server_rec *s)
     109{
     110    apr_status_t rv = APR_SUCCESS;
     111    mod_gnutls_srvconf_rec *sc = ap_get_module_config(s->module_config,
     112                                                      &gnutls_module);
     113
     114    if(sc->cache_config != NULL) {
     115        rv = mod_gnutls_cache_child_init(p, s, sc);
     116        if(rv != APR_SUCCESS) {
     117            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
     118                             "[GnuTLS] - Failed to run Cache Init");
     119        }
     120    }
     121    else {
     122            ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
     123                             "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache");
     124    }
     125}
     126
    108127static const char *mod_gnutls_hook_http_method(const request_rec * r)
    109128{
     
    173192    gnutls_dh_set_prime_bits(ctxt->session, DH_BITS);
    174193
     194    mod_gnutls_cache_session_init(ctxt);
    175195    return ctxt;
    176196}
     
    248268                                                        &gnutls_module);
    249269    sc->key_file = ap_server_root_relative(parms->pool, arg);
     270    return NULL;
     271}
     272
     273static const char *gnutls_set_cache(cmd_parms * parms, void *dummy,
     274                                       const char *arg)
     275{
     276    const char* err;
     277    mod_gnutls_srvconf_rec *sc = ap_get_module_config(parms->server->
     278                                                        module_config,
     279                                                        &gnutls_module);
     280    if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) {
     281        return err;
     282    }
     283
     284    sc->cache_config = apr_pstrdup(parms->pool, arg);
    250285    return NULL;
    251286}
     
    280315                  RSRC_CONF,
    281316                  "SSL Server Certificate file"),
     317    AP_INIT_TAKE1("GnuTLSCache", gnutls_set_cache,
     318                  NULL,
     319                  RSRC_CONF,
     320                  "SSL Server Certificate file"),
    282321    AP_INIT_TAKE1("GnuTLSEnable", gnutls_set_enabled,
    283322                  NULL, RSRC_CONF,
     
    299338                           APR_HOOK_MIDDLE);
    300339    ap_hook_post_config(mod_gnutls_hook_post_config, NULL, NULL,
     340                        APR_HOOK_MIDDLE);
     341    ap_hook_child_init(mod_gnutls_hook_child_init, NULL, NULL,
    301342                        APR_HOOK_MIDDLE);
    302343    ap_hook_http_method(mod_gnutls_hook_http_method, NULL, NULL,
     
    332373    sc->key_file = NULL;
    333374    sc->cert_file = NULL;
     375    sc->cache_config = NULL;
    334376
    335377    i = 0;
Note: See TracChangeset for help on using the changeset viewer.