diff options
Diffstat (limited to 'src/gnutls_cache.c')
-rw-r--r-- | src/gnutls_cache.c | 118 |
1 files changed, 50 insertions, 68 deletions
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c index 4d0a733..3ca8cb5 100644 --- a/src/gnutls_cache.c +++ b/src/gnutls_cache.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #include "unixd.h" | 33 | #include "unixd.h" |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* it seems the default has some strange errors. Use SDBM | ||
37 | */ | ||
38 | #define ODB "SDBM" | ||
36 | 39 | ||
37 | #define MC_TAG "mod_gnutls:" | 40 | #define MC_TAG "mod_gnutls:" |
38 | #define MC_TAG_LEN sizeof(MC_TAG) | 41 | #define MC_TAG_LEN sizeof(MC_TAG) |
@@ -295,92 +298,68 @@ static int mc_cache_delete(void* baton, gnutls_datum_t key) | |||
295 | 298 | ||
296 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) | 299 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) |
297 | 300 | ||
298 | static int dbm_cache_expire(mgs_handle_t *ctxt) | 301 | static void dbm_cache_expire(mgs_handle_t *ctxt) |
299 | { | 302 | { |
300 | apr_status_t rv; | 303 | apr_status_t rv; |
301 | apr_dbm_t *dbm; | 304 | apr_dbm_t *dbm; |
302 | apr_datum_t *keylist; | ||
303 | apr_datum_t dbmkey; | 305 | apr_datum_t dbmkey; |
304 | apr_datum_t dbmval; | 306 | apr_datum_t dbmval; |
305 | apr_time_t ex; | 307 | apr_time_t now; |
306 | apr_time_t dtime; | 308 | apr_time_t dtime; |
307 | apr_pool_t* spool; | 309 | apr_pool_t* spool; |
308 | int i = 0; | 310 | int total, deleted; |
309 | int keyidx = 0; | ||
310 | int should_delete = 0; | ||
311 | |||
312 | ex = apr_time_now(); | ||
313 | 311 | ||
314 | if (ex - ctxt->sc->last_cache_check < 900) | 312 | now = apr_time_now(); |
315 | return 0; | 313 | |
314 | if (now - ctxt->sc->last_cache_check < (ctxt->sc->cache_timeout)/2) | ||
315 | return; | ||
316 | 316 | ||
317 | ctxt->sc->last_cache_check = ex; | 317 | ctxt->sc->last_cache_check = now; |
318 | 318 | ||
319 | apr_pool_create(&spool, ctxt->c->pool); | 319 | apr_pool_create(&spool, ctxt->c->pool); |
320 | 320 | ||
321 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, APR_DBM_READONLY, | 321 | total = 0; |
322 | deleted = 0; | ||
323 | |||
324 | rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config, APR_DBM_RWCREATE, | ||
322 | SSL_DBM_FILE_MODE, spool); | 325 | SSL_DBM_FILE_MODE, spool); |
323 | if (rv != APR_SUCCESS) { | 326 | if (rv != APR_SUCCESS) { |
324 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 327 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
325 | ctxt->c->base_server, | 328 | ctxt->c->base_server, |
326 | "[gnutls_cache] error opening cache searcher '%s'", | 329 | "[gnutls_cache] error opening cache searcher '%s'", |
327 | ctxt->sc->cache_config); | 330 | ctxt->sc->cache_config); |
328 | return -1; | 331 | apr_pool_destroy(spool); |
332 | return; | ||
329 | } | 333 | } |
330 | 334 | ||
331 | #define KEYMAX 128 | ||
332 | |||
333 | keylist = apr_palloc(spool, sizeof(dbmkey)*KEYMAX); | ||
334 | |||
335 | apr_dbm_firstkey(dbm, &dbmkey); | 335 | apr_dbm_firstkey(dbm, &dbmkey); |
336 | while (dbmkey.dptr != NULL) { | 336 | while (dbmkey.dptr != NULL) { |
337 | apr_dbm_fetch(dbm, dbmkey, &dbmval); | 337 | apr_dbm_fetch(dbm, dbmkey, &dbmval); |
338 | if (dbmval.dptr != NULL) { | 338 | if (dbmval.dptr != NULL && dbmval.dsize >= sizeof(apr_time_t)) { |
339 | if (dbmval.dsize >= sizeof(apr_time_t)) { | ||
340 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); | 339 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); |
341 | if (dtime < ex) { | 340 | |
342 | should_delete = 1; | 341 | if (now >= dtime) { |
343 | } | 342 | apr_dbm_delete(dbm, dbmkey); |
344 | } | 343 | deleted++; |
345 | else { | ||
346 | should_delete = 1; | ||
347 | } | ||
348 | |||
349 | if (should_delete == 1) { | ||
350 | should_delete = 0; | ||
351 | keylist[keyidx].dptr = apr_palloc(spool, dbmkey.dsize) ; | ||
352 | memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize); | ||
353 | keylist[keyidx].dsize = dbmkey.dsize; | ||
354 | keyidx++; | ||
355 | if (keyidx == KEYMAX) { | ||
356 | break; | ||
357 | } | 344 | } |
358 | } | 345 | apr_dbm_freedatum( dbm, dbmval); |
359 | apr_dbm_freedatum( dbm, dbmval); | 346 | } else { |
360 | 347 | apr_dbm_delete(dbm, dbmkey); | |
348 | deleted++; | ||
361 | } | 349 | } |
350 | total++; | ||
362 | apr_dbm_nextkey(dbm, &dbmkey); | 351 | apr_dbm_nextkey(dbm, &dbmkey); |
363 | } | 352 | } |
364 | apr_dbm_close(dbm); | 353 | apr_dbm_close(dbm); |
365 | 354 | ||
366 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 355 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
367 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, spool); | 356 | ctxt->c->base_server, |
368 | if (rv != APR_SUCCESS) { | 357 | "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d", |
369 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 358 | ctxt->sc->cache_config, deleted, total-deleted); |
370 | ctxt->c->base_server, | ||
371 | "[gnutls_cache] error opening cache writer '%s'", | ||
372 | ctxt->sc->cache_config); | ||
373 | return -1; | ||
374 | } | ||
375 | |||
376 | for (i = 0; i < keyidx; i++) { | ||
377 | apr_dbm_delete(dbm, keylist[i]); | ||
378 | } | ||
379 | 359 | ||
380 | apr_dbm_close(dbm); | ||
381 | apr_pool_destroy(spool); | 360 | apr_pool_destroy(spool); |
382 | 361 | ||
383 | return 0; | 362 | return; |
384 | } | 363 | } |
385 | 364 | ||
386 | static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | 365 | static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) |
@@ -395,7 +374,7 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | |||
395 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 374 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
396 | return data; | 375 | return data; |
397 | 376 | ||
398 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 377 | rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config, |
399 | APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool); | 378 | APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool); |
400 | if (rv != APR_SUCCESS) { | 379 | if (rv != APR_SUCCESS) { |
401 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 380 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
@@ -444,13 +423,20 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key, | |||
444 | mgs_handle_t *ctxt = baton; | 423 | mgs_handle_t *ctxt = baton; |
445 | apr_status_t rv; | 424 | apr_status_t rv; |
446 | apr_time_t expiry; | 425 | apr_time_t expiry; |
426 | apr_pool_t* spool; | ||
447 | 427 | ||
448 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 428 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
449 | return -1; | 429 | return -1; |
450 | 430 | ||
431 | /* we expire dbm only on every store | ||
432 | */ | ||
433 | dbm_cache_expire(ctxt); | ||
434 | |||
435 | apr_pool_create(&spool, ctxt->c->pool); | ||
436 | |||
451 | /* create DBM value */ | 437 | /* create DBM value */ |
452 | dbmval.dsize = data.size + sizeof(apr_time_t); | 438 | dbmval.dsize = data.size + sizeof(apr_time_t); |
453 | dbmval.dptr = (char *)malloc(dbmval.dsize); | 439 | dbmval.dptr = (char *)apr_palloc(spool, dbmval.dsize); |
454 | 440 | ||
455 | expiry = apr_time_now() + ctxt->sc->cache_timeout; | 441 | expiry = apr_time_now() + ctxt->sc->cache_timeout; |
456 | 442 | ||
@@ -458,18 +444,14 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key, | |||
458 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), | 444 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), |
459 | data.data, data.size); | 445 | data.data, data.size); |
460 | 446 | ||
461 | /* we expire dbm only on every store | 447 | rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config, |
462 | */ | ||
463 | dbm_cache_expire(ctxt); | ||
464 | |||
465 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | ||
466 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 448 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); |
467 | if (rv != APR_SUCCESS) { | 449 | if (rv != APR_SUCCESS) { |
468 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 450 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
469 | ctxt->c->base_server, | 451 | ctxt->c->base_server, |
470 | "[gnutls_cache] error opening cache '%s'", | 452 | "[gnutls_cache] error opening cache '%s'", |
471 | ctxt->sc->cache_config); | 453 | ctxt->sc->cache_config); |
472 | free(dbmval.dptr); | 454 | apr_pool_destroy(spool); |
473 | return -1; | 455 | return -1; |
474 | } | 456 | } |
475 | 457 | ||
@@ -481,13 +463,13 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key, | |||
481 | "[gnutls_cache] error storing in cache '%s'", | 463 | "[gnutls_cache] error storing in cache '%s'", |
482 | ctxt->sc->cache_config); | 464 | ctxt->sc->cache_config); |
483 | apr_dbm_close(dbm); | 465 | apr_dbm_close(dbm); |
484 | free(dbmval.dptr); | 466 | apr_pool_destroy(spool); |
485 | return -1; | 467 | return -1; |
486 | } | 468 | } |
487 | 469 | ||
488 | apr_dbm_close(dbm); | 470 | apr_dbm_close(dbm); |
489 | 471 | ||
490 | free(dbmval.dptr); | 472 | apr_pool_destroy(spool); |
491 | 473 | ||
492 | return 0; | 474 | return 0; |
493 | } | 475 | } |
@@ -502,7 +484,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key) | |||
502 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 484 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
503 | return -1; | 485 | return -1; |
504 | 486 | ||
505 | rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, | 487 | rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config, |
506 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 488 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); |
507 | if (rv != APR_SUCCESS) { | 489 | if (rv != APR_SUCCESS) { |
508 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 490 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
@@ -536,7 +518,7 @@ static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, | |||
536 | const char* path1; | 518 | const char* path1; |
537 | const char* path2; | 519 | const char* path2; |
538 | 520 | ||
539 | rv = apr_dbm_open(&dbm, sc->cache_config, APR_DBM_RWCREATE, | 521 | rv = apr_dbm_open_ex(&dbm, ODB, sc->cache_config, APR_DBM_RWCREATE, |
540 | SSL_DBM_FILE_MODE, p); | 522 | SSL_DBM_FILE_MODE, p); |
541 | 523 | ||
542 | if (rv != APR_SUCCESS) { | 524 | if (rv != APR_SUCCESS) { |
@@ -548,12 +530,12 @@ static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, | |||
548 | 530 | ||
549 | apr_dbm_close(dbm); | 531 | apr_dbm_close(dbm); |
550 | 532 | ||
551 | apr_dbm_get_usednames(p, sc->cache_config, &path1, &path2); | 533 | apr_dbm_get_usednames_ex(p, ODB, sc->cache_config, &path1, &path2); |
552 | 534 | ||
553 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ | 535 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ |
554 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) | 536 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) |
555 | /* Running as Root */ | 537 | /* Running as Root */ |
556 | if (geteuid() == 0) { | 538 | if (path1 && geteuid() == 0) { |
557 | chown(path1, ap_unixd_config.user_id, -1); | 539 | chown(path1, ap_unixd_config.user_id, -1); |
558 | if (path2 != NULL) { | 540 | if (path2 != NULL) { |
559 | chown(path2, ap_unixd_config.user_id, -1); | 541 | chown(path2, ap_unixd_config.user_id, -1); |