summaryrefslogtreecommitdiffstatsabout
path: root/src/gnutls_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnutls_cache.c')
-rw-r--r--src/gnutls_cache.c153
1 files changed, 118 insertions, 35 deletions
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c
index 868568b..91e6ec9 100644
--- a/src/gnutls_cache.c
+++ b/src/gnutls_cache.c
@@ -32,15 +32,14 @@
32#include "unixd.h" 32#include "unixd.h"
33#endif 33#endif
34 34
35#define GNUTLS_SESSION_ID_STRING_LEN \ 35
36 ((GNUTLS_MAX_SESSION_ID + 1) * 2)
37#define MC_TAG "mod_gnutls:" 36#define MC_TAG "mod_gnutls:"
38#define MC_TAG_LEN \ 37#define MC_TAG_LEN \
39 (sizeof(MC_TAG)) 38 (sizeof(MC_TAG))
40#define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN) 39#define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN)
41 40
42static char *gnutls_session_id2sz(unsigned char *id, int idlen, 41static char *gnutls_session_id2sz(unsigned char *id, int idlen,
43 char *str, int strsize) 42 char *str, int strsize)
44{ 43{
45 char *cp; 44 char *cp;
46 int n; 45 int n;
@@ -54,6 +53,21 @@ static char *gnutls_session_id2sz(unsigned char *id, int idlen,
54 return str; 53 return str;
55} 54}
56 55
56char *mod_gnutls_session_id2sz(unsigned char *id, int idlen,
57 char *str, int strsize)
58{
59 char *cp;
60 int n;
61
62 cp = str;
63 for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
64 apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]);
65 cp += 2;
66 }
67 *cp = '\0';
68 return str;
69}
70
57 71
58#if HAVE_APR_MEMCACHE 72#if HAVE_APR_MEMCACHE
59 73
@@ -103,13 +117,13 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s,
103 apr_port_t port; 117 apr_port_t port;
104 118
105 rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p); 119 rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
106 if(rv != APR_SUCCESS) { 120 if (rv != APR_SUCCESS) {
107 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 121 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
108 "[gnutls_cache] Failed to Parse Server: '%s'", split); 122 "[gnutls_cache] Failed to Parse Server: '%s'", split);
109 return rv; 123 return rv;
110 } 124 }
111 125
112 if(host_str == NULL) { 126 if (host_str == NULL) {
113 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 127 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
114 "[gnutls_cache] Failed to Parse Server, " 128 "[gnutls_cache] Failed to Parse Server, "
115 "no hostname specified: '%s'", split); 129 "no hostname specified: '%s'", split);
@@ -128,7 +142,7 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s,
128 thread_limit, 142 thread_limit,
129 600, 143 600,
130 &st); 144 &st);
131 if(rv != APR_SUCCESS) { 145 if (rv != APR_SUCCESS) {
132 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 146 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
133 "[gnutls_cache] Failed to Create Server: %s:%d", 147 "[gnutls_cache] Failed to Create Server: %s:%d",
134 host_str, port); 148 host_str, port);
@@ -136,7 +150,7 @@ int mc_cache_child_init(apr_pool_t *p, server_rec *s,
136 } 150 }
137 151
138 rv = apr_memcache_add_server(mc, st); 152 rv = apr_memcache_add_server(mc, st);
139 if(rv != APR_SUCCESS) { 153 if (rv != APR_SUCCESS) {
140 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 154 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
141 "[gnutls_cache] Failed to Add Server: %s:%d", 155 "[gnutls_cache] Failed to Add Server: %s:%d",
142 host_str, port); 156 host_str, port);
@@ -161,11 +175,11 @@ static int mc_cache_store(void* baton, gnutls_datum_t key,
161 if(!strkey) 175 if(!strkey)
162 return -1; 176 return -1;
163 177
164 timeout = ctxt->sc->cache_timeout; 178 timeout = apr_time_sec(ctxt->sc->cache_timeout);
165 179
166 rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); 180 rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0);
167 181
168 if(rv != APR_SUCCESS) { 182 if (rv != APR_SUCCESS) {
169 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, 183 ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
170 ctxt->c->base_server, 184 ctxt->c->base_server,
171 "[gnutls_cache] error setting key '%s' " 185 "[gnutls_cache] error setting key '%s' "
@@ -187,14 +201,14 @@ static gnutls_datum_t mc_cache_fetch(void* baton, gnutls_datum_t key)
187 gnutls_datum_t data = { NULL, 0 }; 201 gnutls_datum_t data = { NULL, 0 };
188 202
189 strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf)); 203 strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf));
190 if(!strkey) { 204 if (!strkey) {
191 return data; 205 return data;
192 } 206 }
193 207
194 rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, 208 rv = apr_memcache_getp(mc, ctxt->c->pool, strkey,
195 &value, &value_len, NULL); 209 &value, &value_len, NULL);
196 210
197 if(rv != APR_SUCCESS) { 211 if (rv != APR_SUCCESS) {
198 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, 212 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
199 ctxt->c->base_server, 213 ctxt->c->base_server,
200 "[gnutls_cache] error fetching key '%s' ", 214 "[gnutls_cache] error fetching key '%s' ",
@@ -229,7 +243,7 @@ static int mc_cache_delete(void* baton, gnutls_datum_t key)
229 243
230 rv = apr_memcache_delete(mc, strkey, 0); 244 rv = apr_memcache_delete(mc, strkey, 0);
231 245
232 if(rv != APR_SUCCESS) { 246 if (rv != APR_SUCCESS) {
233 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, 247 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
234 ctxt->c->base_server, 248 ctxt->c->base_server,
235 "[gnutls_cache] error deleting key '%s' ", 249 "[gnutls_cache] error deleting key '%s' ",
@@ -248,18 +262,80 @@ static int dbm_cache_expire(mod_gnutls_handle_t *ctxt)
248{ 262{
249 apr_status_t rv; 263 apr_status_t rv;
250 apr_dbm_t *dbm; 264 apr_dbm_t *dbm;
251 265 apr_datum_t *keylist;
252 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 266 apr_datum_t dbmkey;
253 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 267 apr_datum_t dbmval;
268 apr_time_t ex;
269 apr_time_t dtime;
270 apr_pool_t* spool;
271 int i = 0;
272 int keyidx = 0;
273 int should_delete = 0;
274
275 apr_pool_create(&spool, ctxt->c->pool);
276 ex = apr_time_now();
277
278 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, APR_DBM_READONLY,
279 SSL_DBM_FILE_MODE, spool);
254 if (rv != APR_SUCCESS) { 280 if (rv != APR_SUCCESS) {
255 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 281 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
256 ctxt->c->base_server, 282 ctxt->c->base_server,
257 "[gnutls_cache] error opening cache '%s'", 283 "[gnutls_cache] error opening cache searcher '%s'",
258 ctxt->sc->cache_config); 284 ctxt->sc->cache_config);
259 return -1; 285 return -1;
260 } 286 }
287
288#define KEYMAX 128
289
290 keylist = apr_palloc(spool, sizeof(dbmkey)*KEYMAX);
291
292 apr_dbm_firstkey(dbm, &dbmkey);
293 while (dbmkey.dptr != NULL) {
294 apr_dbm_fetch(dbm, dbmkey, &dbmval);
295 if (dbmval.dptr != NULL) {
296 if (dbmval.dsize >= sizeof(apr_time_t)) {
297 memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t));
298 if (dtime < ex) {
299 should_delete = 1;
300 }
301 }
302 else {
303 should_delete = 1;
304 }
305
306 if (should_delete == 1) {
307 should_delete = 0;
308 keylist[keyidx].dptr = apr_palloc(spool, dbmkey.dsize) ;
309 memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize);
310 keylist[keyidx].dsize = dbmkey.dsize;
311 keyidx++;
312 if (keyidx == KEYMAX) {
313 break;
314 }
315 }
316
317 }
318 apr_dbm_nextkey(dbm, &dbmkey);
319 }
261 apr_dbm_close(dbm); 320 apr_dbm_close(dbm);
262 321
322 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
323 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, spool);
324 if (rv != APR_SUCCESS) {
325 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
326 ctxt->c->base_server,
327 "[gnutls_cache] error opening cache writer '%s'",
328 ctxt->sc->cache_config);
329 return -1;
330 }
331
332 for (i = 0; i < keyidx; i++) {
333 apr_dbm_delete(dbm, keylist[i]);
334 }
335
336 apr_dbm_close(dbm);
337 apr_pool_destroy(spool);
338
263 return 0; 339 return 0;
264} 340}
265 341
@@ -275,6 +351,8 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key)
275 dbmkey.dptr = key.data; 351 dbmkey.dptr = key.data;
276 dbmkey.dsize = key.size; 352 dbmkey.dsize = key.size;
277 353
354 dbm_cache_expire(ctxt);
355
278 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 356 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
279 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 357 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
280 if (rv != APR_SUCCESS) { 358 if (rv != APR_SUCCESS) {
@@ -286,7 +364,7 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key)
286 } 364 }
287 365
288 rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); 366 rv = apr_dbm_fetch(dbm, dbmkey, &dbmval);
289 367
290 if (rv != APR_SUCCESS) { 368 if (rv != APR_SUCCESS) {
291 apr_dbm_close(dbm); 369 apr_dbm_close(dbm);
292 return data; 370 return data;
@@ -296,15 +374,17 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key)
296 apr_dbm_close(dbm); 374 apr_dbm_close(dbm);
297 return data; 375 return data;
298 } 376 }
299 377 apr_dbm_close(dbm);
300 data.data = gnutls_malloc(dbmval.dsize - sizeof(apr_time_t));
301 if (data.data == NULL)
302 return data;
303 378
304 data.size = dbmval.dsize - sizeof(apr_time_t); 379 data.size = dbmval.dsize - sizeof(apr_time_t);
380
381 data.data = gnutls_malloc(data.size);
382 if (data.data == NULL) {
383 return data;
384 }
385
305 memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); 386 memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size);
306 387
307 apr_dbm_close(dbm);
308 return data; 388 return data;
309} 389}
310 390
@@ -316,18 +396,23 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key,
316 apr_datum_t dbmval; 396 apr_datum_t dbmval;
317 mod_gnutls_handle_t *ctxt = baton; 397 mod_gnutls_handle_t *ctxt = baton;
318 apr_status_t rv; 398 apr_status_t rv;
319 apr_time_t timeout; 399 apr_time_t expiry;
320 400
321 dbmkey.dptr = (char *)key.data; 401 dbmkey.dptr = (char *)key.data;
322 dbmkey.dsize = key.size; 402 dbmkey.dsize = key.size;
323 403
324 /* create DBM value */ 404 /* create DBM value */
325 dbmval.dsize = data.size; 405 dbmval.dsize = data.size + sizeof(apr_time_t);
326 dbmval.dptr = (char *)malloc(dbmval.dsize+sizeof(apr_time_t)); 406 dbmval.dptr = (char *)malloc(dbmval.dsize);
407
408 expiry = apr_time_now() + ctxt->sc->cache_timeout;
327 409
410 memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t));
328 memcpy((char *)dbmval.dptr+sizeof(apr_time_t), 411 memcpy((char *)dbmval.dptr+sizeof(apr_time_t),
329 data.data, data.size); 412 data.data, data.size);
330 413
414 dbm_cache_expire(ctxt);
415
331 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 416 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
332 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 417 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
333 if (rv != APR_SUCCESS) { 418 if (rv != APR_SUCCESS) {
@@ -340,7 +425,7 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key,
340 } 425 }
341 426
342 rv = apr_dbm_store(dbm, dbmkey, dbmval); 427 rv = apr_dbm_store(dbm, dbmkey, dbmval);
343 428
344 if (rv != APR_SUCCESS) { 429 if (rv != APR_SUCCESS) {
345 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 430 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
346 ctxt->c->base_server, 431 ctxt->c->base_server,
@@ -368,6 +453,8 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key)
368 dbmkey.dptr = (char *)key.data; 453 dbmkey.dptr = (char *)key.data;
369 dbmkey.dsize = key.size; 454 dbmkey.dsize = key.size;
370 455
456 dbm_cache_expire(ctxt);
457
371 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 458 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
372 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 459 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
373 if (rv != APR_SUCCESS) { 460 if (rv != APR_SUCCESS) {
@@ -383,7 +470,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key)
383 if (rv != APR_SUCCESS) { 470 if (rv != APR_SUCCESS) {
384 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 471 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
385 ctxt->c->base_server, 472 ctxt->c->base_server,
386 "[gnutls_cache] error storing in cache '%s'", 473 "[gnutls_cache] error deleting from cache '%s'",
387 ctxt->sc->cache_config); 474 ctxt->sc->cache_config);
388 apr_dbm_close(dbm); 475 apr_dbm_close(dbm);
389 return -1; 476 return -1;
@@ -394,7 +481,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key)
394 return 0; 481 return 0;
395} 482}
396 483
397static int dbm_cache_child_init(apr_pool_t *p, server_rec *s, 484static int dbm_cache_post_config(apr_pool_t *p, server_rec *s,
398 mod_gnutls_srvconf_rec *sc) 485 mod_gnutls_srvconf_rec *sc)
399{ 486{
400 apr_status_t rv; 487 apr_status_t rv;
@@ -434,7 +521,7 @@ int mod_gnutls_cache_post_config(apr_pool_t *p, server_rec *s,
434 mod_gnutls_srvconf_rec *sc) 521 mod_gnutls_srvconf_rec *sc)
435{ 522{
436 if (sc->cache_type == mod_gnutls_cache_dbm) { 523 if (sc->cache_type == mod_gnutls_cache_dbm) {
437 return dbm_cache_child_init(p, s, sc); 524 return dbm_cache_post_config(p, s, sc);
438 } 525 }
439 return 0; 526 return 0;
440} 527}
@@ -457,7 +544,6 @@ int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s,
457 544
458int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) 545int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt)
459{ 546{
460 printf("Type: %d Params: %s\n",ctxt->sc->cache_type, ctxt->sc->cache_config);
461 if (ctxt->sc->cache_type == mod_gnutls_cache_dbm) { 547 if (ctxt->sc->cache_type == mod_gnutls_cache_dbm) {
462 gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); 548 gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch);
463 gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); 549 gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete);
@@ -472,9 +558,6 @@ int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt)
472 gnutls_db_set_ptr(ctxt->session, ctxt); 558 gnutls_db_set_ptr(ctxt->session, ctxt);
473 } 559 }
474#endif 560#endif
475 else { 561
476 assert(1);
477 /* No Session Cache is Available. Opps. */
478 }
479 return 0; 562 return 0;
480} 563}