diff options
Diffstat (limited to 'src/gnutls_cache.c')
-rw-r--r-- | src/gnutls_cache.c | 247 |
1 files changed, 235 insertions, 12 deletions
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c index c1a6f37..868568b 100644 --- a/src/gnutls_cache.c +++ b/src/gnutls_cache.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* ==================================================================== | 1 | /** |
2 | * Copyright 2004 Paul Querna | 2 | * Copyright 2004-2005 Paul Querna |
3 | * | 3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
@@ -21,8 +21,17 @@ | |||
21 | #include "apr_memcache.h" | 21 | #include "apr_memcache.h" |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #include "apr_dbm.h" | ||
25 | |||
24 | #include "ap_mpm.h" | 26 | #include "ap_mpm.h" |
25 | 27 | ||
28 | #include <unistd.h> | ||
29 | #include <sys/types.h> | ||
30 | |||
31 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) | ||
32 | #include "unixd.h" | ||
33 | #endif | ||
34 | |||
26 | #define GNUTLS_SESSION_ID_STRING_LEN \ | 35 | #define GNUTLS_SESSION_ID_STRING_LEN \ |
27 | ((GNUTLS_MAX_SESSION_ID + 1) * 2) | 36 | ((GNUTLS_MAX_SESSION_ID + 1) * 2) |
28 | #define MC_TAG "mod_gnutls:" | 37 | #define MC_TAG "mod_gnutls:" |
@@ -152,7 +161,7 @@ static int mc_cache_store(void* baton, gnutls_datum_t key, | |||
152 | if(!strkey) | 161 | if(!strkey) |
153 | return -1; | 162 | return -1; |
154 | 163 | ||
155 | timeout = 3600; | 164 | timeout = ctxt->sc->cache_timeout; |
156 | 165 | ||
157 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); | 166 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); |
158 | 167 | ||
@@ -233,25 +242,239 @@ static int mc_cache_delete(void* baton, gnutls_datum_t key) | |||
233 | 242 | ||
234 | #endif /* have_apr_memcache */ | 243 | #endif /* have_apr_memcache */ |
235 | 244 | ||
245 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) | ||
246 | |||
247 | static int dbm_cache_expire(mod_gnutls_handle_t *ctxt) | ||
248 | { | ||
249 | apr_status_t rv; | ||
250 | apr_dbm_t *dbm; | ||
251 | |||
252 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
253 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | ||
254 | if (rv != APR_SUCCESS) { | ||
255 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
256 | ctxt->c->base_server, | ||
257 | "[gnutls_cache] error opening cache '%s'", | ||
258 | ctxt->sc->cache_config); | ||
259 | return -1; | ||
260 | } | ||
261 | apr_dbm_close(dbm); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | ||
267 | { | ||
268 | gnutls_datum_t data = { NULL, 0 }; | ||
269 | apr_dbm_t *dbm; | ||
270 | apr_datum_t dbmkey; | ||
271 | apr_datum_t dbmval; | ||
272 | mod_gnutls_handle_t *ctxt = baton; | ||
273 | apr_status_t rv; | ||
274 | |||
275 | dbmkey.dptr = key.data; | ||
276 | dbmkey.dsize = key.size; | ||
277 | |||
278 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
279 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | ||
280 | if (rv != APR_SUCCESS) { | ||
281 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
282 | ctxt->c->base_server, | ||
283 | "[gnutls_cache] error opening cache '%s'", | ||
284 | ctxt->sc->cache_config); | ||
285 | return data; | ||
286 | } | ||
287 | |||
288 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | ||
289 | |||
290 | if (rv != APR_SUCCESS) { | ||
291 | apr_dbm_close(dbm); | ||
292 | return data; | ||
293 | } | ||
294 | |||
295 | if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) { | ||
296 | apr_dbm_close(dbm); | ||
297 | return data; | ||
298 | } | ||
299 | |||
300 | data.data = gnutls_malloc(dbmval.dsize - sizeof(apr_time_t)); | ||
301 | if (data.data == NULL) | ||
302 | return data; | ||
303 | |||
304 | data.size = dbmval.dsize - sizeof(apr_time_t); | ||
305 | memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); | ||
306 | |||
307 | apr_dbm_close(dbm); | ||
308 | return data; | ||
309 | } | ||
310 | |||
311 | static int dbm_cache_store(void* baton, gnutls_datum_t key, | ||
312 | gnutls_datum_t data) | ||
313 | { | ||
314 | apr_dbm_t *dbm; | ||
315 | apr_datum_t dbmkey; | ||
316 | apr_datum_t dbmval; | ||
317 | mod_gnutls_handle_t *ctxt = baton; | ||
318 | apr_status_t rv; | ||
319 | apr_time_t timeout; | ||
320 | |||
321 | dbmkey.dptr = (char *)key.data; | ||
322 | dbmkey.dsize = key.size; | ||
323 | |||
324 | /* create DBM value */ | ||
325 | dbmval.dsize = data.size; | ||
326 | dbmval.dptr = (char *)malloc(dbmval.dsize+sizeof(apr_time_t)); | ||
327 | |||
328 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), | ||
329 | data.data, data.size); | ||
330 | |||
331 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
332 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | ||
333 | if (rv != APR_SUCCESS) { | ||
334 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
335 | ctxt->c->base_server, | ||
336 | "[gnutls_cache] error opening cache '%s'", | ||
337 | ctxt->sc->cache_config); | ||
338 | free(dbmval.dptr); | ||
339 | return -1; | ||
340 | } | ||
341 | |||
342 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | ||
343 | |||
344 | if (rv != APR_SUCCESS) { | ||
345 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
346 | ctxt->c->base_server, | ||
347 | "[gnutls_cache] error storing in cache '%s'", | ||
348 | ctxt->sc->cache_config); | ||
349 | apr_dbm_close(dbm); | ||
350 | free(dbmval.dptr); | ||
351 | return -1; | ||
352 | } | ||
353 | |||
354 | apr_dbm_close(dbm); | ||
355 | |||
356 | free(dbmval.dptr); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int dbm_cache_delete(void* baton, gnutls_datum_t key) | ||
362 | { | ||
363 | apr_dbm_t *dbm; | ||
364 | apr_datum_t dbmkey; | ||
365 | mod_gnutls_handle_t *ctxt = baton; | ||
366 | apr_status_t rv; | ||
367 | |||
368 | dbmkey.dptr = (char *)key.data; | ||
369 | dbmkey.dsize = key.size; | ||
370 | |||
371 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
372 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | ||
373 | if (rv != APR_SUCCESS) { | ||
374 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
375 | ctxt->c->base_server, | ||
376 | "[gnutls_cache] error opening cache '%s'", | ||
377 | ctxt->sc->cache_config); | ||
378 | return -1; | ||
379 | } | ||
380 | |||
381 | rv = apr_dbm_delete(dbm, dbmkey); | ||
382 | |||
383 | if (rv != APR_SUCCESS) { | ||
384 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | ||
385 | ctxt->c->base_server, | ||
386 | "[gnutls_cache] error storing in cache '%s'", | ||
387 | ctxt->sc->cache_config); | ||
388 | apr_dbm_close(dbm); | ||
389 | return -1; | ||
390 | } | ||
391 | |||
392 | apr_dbm_close(dbm); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static int dbm_cache_child_init(apr_pool_t *p, server_rec *s, | ||
398 | mod_gnutls_srvconf_rec *sc) | ||
399 | { | ||
400 | apr_status_t rv; | ||
401 | apr_dbm_t *dbm; | ||
402 | const char* path1; | ||
403 | const char* path2; | ||
404 | |||
405 | rv = apr_dbm_open(&dbm, sc->cache_config, APR_DBM_RWCREATE, | ||
406 | SSL_DBM_FILE_MODE, p); | ||
407 | |||
408 | if (rv != APR_SUCCESS) { | ||
409 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, | ||
410 | "GnuTLS: Cannot create DBM Cache at `%s'", | ||
411 | sc->cache_config); | ||
412 | return rv; | ||
413 | } | ||
414 | |||
415 | apr_dbm_close(dbm); | ||
416 | |||
417 | apr_dbm_get_usednames(p, sc->cache_config, &path1, &path2); | ||
418 | |||
419 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ | ||
420 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) | ||
421 | /* Running as Root */ | ||
422 | if (geteuid() == 0) { | ||
423 | chown(path1, unixd_config.user_id, -1); | ||
424 | if (path2 != NULL) { | ||
425 | chown(path2, unixd_config.user_id, -1); | ||
426 | } | ||
427 | } | ||
428 | #endif | ||
429 | |||
430 | return rv; | ||
431 | } | ||
432 | |||
433 | int mod_gnutls_cache_post_config(apr_pool_t *p, server_rec *s, | ||
434 | mod_gnutls_srvconf_rec *sc) | ||
435 | { | ||
436 | if (sc->cache_type == mod_gnutls_cache_dbm) { | ||
437 | return dbm_cache_child_init(p, s, sc); | ||
438 | } | ||
439 | return 0; | ||
440 | } | ||
441 | |||
236 | int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s, | 442 | int mod_gnutls_cache_child_init(apr_pool_t *p, server_rec *s, |
237 | mod_gnutls_srvconf_rec *sc) | 443 | mod_gnutls_srvconf_rec *sc) |
238 | { | 444 | { |
445 | if (sc->cache_type == mod_gnutls_cache_dbm) { | ||
446 | return 0; | ||
447 | } | ||
239 | #if HAVE_APR_MEMCACHE | 448 | #if HAVE_APR_MEMCACHE |
240 | return mc_cache_child_init(p, s, sc); | 449 | else if (sc->cache_type == mod_gnutls_cache_memcache) { |
241 | #else | 450 | return mc_cache_child_init(p, s, sc); |
242 | return 0; | 451 | } |
243 | #endif | 452 | #endif |
453 | return 0; | ||
244 | } | 454 | } |
245 | 455 | ||
456 | #include <assert.h> | ||
457 | |||
246 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) | 458 | int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt) |
247 | { | 459 | { |
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) { | ||
462 | gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); | ||
463 | gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); | ||
464 | gnutls_db_set_store_function(ctxt->session, dbm_cache_store); | ||
465 | gnutls_db_set_ptr(ctxt->session, ctxt); | ||
466 | } | ||
248 | #if HAVE_APR_MEMCACHE | 467 | #if HAVE_APR_MEMCACHE |
249 | gnutls_db_set_retrieve_function(ctxt->session, mc_cache_fetch); | 468 | else if (ctxt->sc->cache_type == mod_gnutls_cache_memcache) { |
250 | gnutls_db_set_remove_function(ctxt->session, mc_cache_delete); | 469 | gnutls_db_set_retrieve_function(ctxt->session, mc_cache_fetch); |
251 | gnutls_db_set_store_function(ctxt->session, mc_cache_store); | 470 | gnutls_db_set_remove_function(ctxt->session, mc_cache_delete); |
252 | gnutls_db_set_ptr(ctxt->session, ctxt); | 471 | gnutls_db_set_store_function(ctxt->session, mc_cache_store); |
253 | #else | 472 | gnutls_db_set_ptr(ctxt->session, ctxt); |
254 | /* TODO: Alternative Cache Backends */ | 473 | } |
255 | #endif | 474 | #endif |
475 | else { | ||
476 | assert(1); | ||
477 | /* No Session Cache is Available. Opps. */ | ||
478 | } | ||
256 | return 0; | 479 | return 0; |
257 | } | 480 | } |