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 | } | 
