Changeset de1ceab in mod_gnutls
- Timestamp:
- Apr 23, 2018, 4:39:28 PM (3 years ago)
- Branches:
- asyncio, debian/master, master, proxy-ticket
- Children:
- 14a6f41
- Parents:
- 0470e44
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
include/mod_gnutls.h.in
r0470e44 rde1ceab 71 71 mgs_cache_memcache, 72 72 #endif 73 mgs_cache_shmcb, 73 74 mgs_cache_unset 74 75 } mgs_cache_e; -
src/gnutls_cache.c
r0470e44 rde1ceab 47 47 #include "mod_gnutls.h" 48 48 #include "gnutls_config.h" 49 50 #include <ap_socache.h> 49 51 50 52 #if HAVE_APR_MEMCACHE … … 129 131 } 130 132 131 #if HAVE_APR_MEMCACHE 132 133 /** 134 * Turn a GnuTLS session ID into the key format we use with memcached 135 * caches. Name the Session ID as `server:port.SessionID` to disallow 136 * resuming sessions on different servers. 137 * 138 * @return `0` on success, `-1` on failure 139 */ 140 static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen) 141 { 142 char sz[GNUTLS_SESSION_ID_STRING_LEN]; 143 apr_status_t rv = apr_escape_hex(sz, id, idlen, 0, NULL); 133 134 135 static int socache_store(server_rec *server, gnutls_datum_t key, 136 gnutls_datum_t data, apr_time_t expiry) 137 { 138 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 139 ap_get_module_config(server->module_config, &gnutls_module); 140 141 apr_pool_t *spool; 142 apr_pool_create(&spool, NULL); 143 144 apr_global_mutex_lock(sc->cache->mutex); 145 apr_status_t rv = sc->cache->prov->store(sc->cache->socache, server, 146 key.data, key.size, 147 expiry, 148 data.data, data.size, 149 spool); 150 apr_global_mutex_unlock(sc->cache->mutex); 151 144 152 if (rv != APR_SUCCESS) 145 return NULL; 146 147 return apr_psprintf(c->pool, MC_TAG "%s:%d.%s", 148 c->base_server->server_hostname, 149 c->base_server->port, sz); 150 } 151 152 /** 153 * GnuTLS Session Cache using libmemcached 154 * 155 */ 156 157 /* The underlying apr_memcache system is thread safe... woohoo */ 158 static apr_memcache_t *mc; 159 160 static int mc_cache_child_init(apr_pool_t * p, server_rec * s, 161 mgs_srvconf_rec * sc) { 162 apr_status_t rv = APR_SUCCESS; 163 int thread_limit = 0; 164 int nservers = 0; 165 char *cache_config; 166 char *split; 167 char *tok; 168 169 ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); 170 171 /* Find all the servers in the first run to get a total count */ 172 cache_config = apr_pstrdup(p, sc->cache_config); 173 split = apr_strtok(cache_config, " ", &tok); 174 while (split) { 175 nservers++; 176 split = apr_strtok(NULL, " ", &tok); 177 } 178 179 rv = apr_memcache_create(p, nservers, 0, &mc); 180 if (rv != APR_SUCCESS) { 181 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 182 "Failed to create Memcache object of size '%d'.", 183 nservers); 184 return rv; 185 } 186 187 /* Now add each server to the memcache */ 188 cache_config = apr_pstrdup(p, sc->cache_config); 189 split = apr_strtok(cache_config, " ", &tok); 190 while (split) { 191 apr_memcache_server_t *st; 192 char *host_str; 193 char *scope_id; 194 apr_port_t port; 195 196 rv = apr_parse_addr_port(&host_str, &scope_id, &port, 197 split, p); 198 if (rv != APR_SUCCESS) { 199 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 200 "Failed to parse server: '%s'", split); 201 return rv; 202 } 203 204 if (host_str == NULL) { 205 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 206 "Failed to parse server, " 207 "no hostname specified: '%s'", split); 208 return rv; 209 } 210 211 if (port == 0) { 212 port = 11211; /* default port */ 213 } 214 215 /* Should Max Conns be (thread_limit / nservers) ? */ 216 rv = apr_memcache_server_create(p, 217 host_str, port, 218 0, 219 1, thread_limit, 600, &st); 220 if (rv != APR_SUCCESS) { 221 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 222 "Failed to create server: %s:%d", 223 host_str, port); 224 return rv; 225 } 226 227 rv = apr_memcache_add_server(mc, st); 228 if (rv != APR_SUCCESS) { 229 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 230 "Failed to add server: %s:%d", 231 host_str, port); 232 return rv; 233 } 234 235 split = apr_strtok(NULL, " ", &tok); 236 } 237 return rv; 238 } 239 240 static int mc_cache_store(server_rec *s, const char *key, 241 gnutls_datum_t data, apr_uint32_t timeout) 242 { 243 apr_status_t rv = apr_memcache_set(mc, key, (char *) data.data, 244 data.size, timeout, 0); 245 246 if (rv != APR_SUCCESS) 247 { 248 ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, 249 "error storing key '%s' with %d bytes of data", 250 key, data.size); 153 { 154 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, server, 155 "error storing in cache '%s:%s'", 156 sc->cache->prov->name, sc->cache_config); 157 apr_pool_destroy(spool); 251 158 return -1; 252 159 } 253 160 161 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server, 162 "stored %u bytes of data (%u byte key) in cache '%s:%s'", 163 data.size, key.size, 164 sc->cache->prov->name, sc->cache_config); 165 apr_pool_destroy(spool); 254 166 return 0; 255 167 } 256 168 257 static int mc_cache_store_generic(server_rec *s, gnutls_datum_t key, 258 gnutls_datum_t data, apr_time_t expiry) 259 { 260 apr_uint32_t timeout = apr_time_sec(expiry - apr_time_now()); 261 262 apr_pool_t *p; 263 apr_pool_create(&p, NULL); 264 265 const char *hex = apr_pescape_hex(p, key.data, key.size, 1); 266 if (hex == NULL) 267 { 268 apr_pool_destroy(p); 169 170 171 static int socache_store_session(void *baton, gnutls_datum_t key, 172 gnutls_datum_t data) 173 { 174 mgs_handle_t *ctxt = baton; 175 gnutls_datum_t dbmkey; 176 177 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 269 178 return -1; 270 } 271 272 const char *strkey = apr_psprintf(p, MC_TAG "%s", hex); 273 274 int ret = mc_cache_store(s, strkey, data, timeout); 275 276 apr_pool_destroy(p); 277 return ret; 278 } 279 280 static int mc_cache_store_session(void *baton, gnutls_datum_t key, 281 gnutls_datum_t data) 282 { 283 mgs_handle_t *ctxt = baton; 284 285 const char *strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); 286 if (!strkey) 287 return -1; 288 289 apr_uint32_t timeout = apr_time_sec(ctxt->sc->cache_timeout); 290 291 return mc_cache_store(ctxt->c->base_server, strkey, data, timeout); 292 } 293 294 /** 295 * @param s server reference for logging 296 * @param key the key to fetch 297 * @param pool pool from which to allocate memory for the result 298 */ 299 static gnutls_datum_t mc_cache_fetch(server_rec *s, const char *key, 300 apr_pool_t *pool) 301 { 302 apr_status_t rv = APR_SUCCESS; 303 char *value; 304 apr_size_t value_len; 179 180 apr_time_t expiry = apr_time_now() + ctxt->sc->cache_timeout; 181 182 return socache_store(ctxt->c->base_server, dbmkey, data, expiry); 183 } 184 185 186 187 // 4K should be enough for OCSP responses and sessions alike 188 #define SOCACHE_FETCH_BUF_SIZE 4096 189 static gnutls_datum_t socache_fetch(server_rec *server, gnutls_datum_t key, 190 apr_pool_t *pool) 191 { 192 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 193 ap_get_module_config(server->module_config, &gnutls_module); 194 305 195 gnutls_datum_t data = {NULL, 0}; 306 307 rv = apr_memcache_getp(mc, pool, key, &value, &value_len, NULL); 308 309 if (rv != APR_SUCCESS) 310 { 311 ap_log_error(APLOG_MARK, APLOG_TRACE2, rv, s, 312 "error fetching key '%s'", 313 key); 314 return data; 315 } 316 317 /* TODO: Eliminate this memcpy. gnutls-- */ 318 data.data = gnutls_malloc(value_len); 196 data.data = gnutls_malloc(SOCACHE_FETCH_BUF_SIZE); 319 197 if (data.data == NULL) 320 198 return data; 321 322 data.size = value_len; 323 memcpy(data.data, value, value_len); 324 325 return data; 326 } 327 328 static gnutls_datum_t mc_cache_fetch_generic(server_rec *server, 329 gnutls_datum_t key, 330 apr_pool_t *pool) 331 { 332 gnutls_datum_t data = {NULL, 0}; 333 const char *hex = apr_pescape_hex(pool, key.data, key.size, 1); 334 if (hex == NULL) 335 return data; 336 337 const char *strkey = apr_psprintf(pool, MC_TAG "%s", hex); 338 return mc_cache_fetch(server, strkey, pool); 339 } 340 341 static gnutls_datum_t mc_cache_fetch_session(void *baton, gnutls_datum_t key) 342 { 343 mgs_handle_t *ctxt = baton; 344 gnutls_datum_t data = {NULL, 0}; 345 346 const char *strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); 347 if (!strkey) 348 return data; 349 350 return mc_cache_fetch(ctxt->c->base_server, strkey, ctxt->c->pool); 351 } 352 353 static int mc_cache_delete(void *baton, gnutls_datum_t key) { 354 apr_status_t rv = APR_SUCCESS; 355 mgs_handle_t *ctxt = baton; 356 char *strkey = NULL; 357 358 strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); 359 if (!strkey) 360 return -1; 361 362 rv = apr_memcache_delete(mc, strkey, 0); 363 364 if (rv != APR_SUCCESS) { 365 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, 366 ctxt->c->base_server, 367 "error deleting key '%s'", 368 strkey); 369 return -1; 370 } 371 372 return 0; 373 } 374 375 #endif /* have_apr_memcache */ 376 377 static const char *db_type(mgs_srvconf_rec * sc) { 378 if (sc->cache_type == mgs_cache_gdbm) 379 return "gdbm"; 380 else 381 return "db"; 382 } 383 384 #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) 385 386 static void dbm_cache_expire(server_rec *s) 387 { 388 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 389 ap_get_module_config(s->module_config, &gnutls_module); 390 391 apr_status_t rv; 392 apr_dbm_t *dbm; 393 apr_datum_t dbmkey; 394 apr_datum_t dbmval; 395 apr_time_t dtime; 199 data.size = SOCACHE_FETCH_BUF_SIZE; 200 396 201 apr_pool_t *spool; 397 int total, deleted; 398 399 apr_time_t now = apr_time_now(); 400 401 if (now - sc->last_cache_check < (sc->cache_timeout) / 2) 402 return; 403 404 sc->last_cache_check = now; 405 406 apr_pool_create(&spool, NULL); 407 408 total = 0; 409 deleted = 0; 202 apr_pool_create(&spool, pool); 410 203 411 204 apr_global_mutex_lock(sc->cache->mutex); 412 413 rv = apr_dbm_open_ex(&dbm, db_type(sc), 414 sc->cache_config, APR_DBM_RWCREATE, 415 SSL_DBM_FILE_MODE, spool); 416 if (rv != APR_SUCCESS) { 417 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s, 418 "error opening cache '%s'", 419 sc->cache_config); 420 apr_global_mutex_unlock(sc->cache->mutex); 421 apr_pool_destroy(spool); 422 return; 423 } 424 425 apr_dbm_firstkey(dbm, &dbmkey); 426 while (dbmkey.dptr != NULL) { 427 apr_dbm_fetch(dbm, dbmkey, &dbmval); 428 if (dbmval.dptr != NULL 429 && dbmval.dsize >= sizeof (apr_time_t)) { 430 memcpy(&dtime, dbmval.dptr, sizeof (apr_time_t)); 431 432 if (now >= dtime) { 433 apr_dbm_delete(dbm, dbmkey); 434 deleted++; 435 } 436 apr_dbm_freedatum(dbm, dbmval); 437 } else { 438 apr_dbm_delete(dbm, dbmkey); 439 deleted++; 440 } 441 total++; 442 apr_dbm_nextkey(dbm, &dbmkey); 443 } 444 apr_dbm_close(dbm); 445 446 rv = apr_global_mutex_unlock(sc->cache->mutex); 447 448 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, 449 "Cleaned up cache '%s'. Deleted %d and left %d", 450 sc->cache_config, deleted, total - deleted); 451 452 apr_pool_destroy(spool); 453 454 return; 455 } 456 457 458 459 static gnutls_datum_t dbm_cache_fetch(server_rec *server, gnutls_datum_t key, 460 apr_pool_t *pool) 461 { 462 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 463 ap_get_module_config(server->module_config, &gnutls_module); 464 465 gnutls_datum_t data = {NULL, 0}; 466 apr_dbm_t *dbm; 467 apr_datum_t dbmkey = {(char*) key.data, key.size}; 468 apr_datum_t dbmval; 469 apr_time_t expiry = 0; 470 apr_status_t rv; 471 472 /* check if it is time for cache expiration */ 473 dbm_cache_expire(server); 474 475 apr_global_mutex_lock(sc->cache->mutex); 476 477 rv = apr_dbm_open_ex(&dbm, db_type(sc), 478 sc->cache_config, APR_DBM_READONLY, 479 SSL_DBM_FILE_MODE, pool); 480 if (rv != APR_SUCCESS) { 481 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, server, 482 "error opening cache '%s'", 483 sc->cache_config); 484 apr_global_mutex_unlock(sc->cache->mutex); 485 return data; 486 } 487 488 rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); 205 apr_status_t rv = sc->cache->prov->retrieve(sc->cache->socache, server, 206 key.data, key.size, 207 data.data, &data.size, 208 spool); 209 apr_global_mutex_unlock(sc->cache->mutex); 489 210 490 211 if (rv != APR_SUCCESS) 491 goto close_db; 492 493 if (dbmval.dptr == NULL || dbmval.dsize <= sizeof (apr_time_t)) 494 goto cleanup; 495 496 data.size = dbmval.dsize - sizeof (apr_time_t); 497 /* get data expiration tag */ 498 expiry = *((apr_time_t *) dbmval.dptr); 499 500 data.data = gnutls_malloc(data.size); 501 if (data.data == NULL) 502 { 503 data.size = 0; 504 goto cleanup; 505 } 506 507 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server, 508 "fetched %" APR_SIZE_T_FMT " bytes from cache", 509 dbmval.dsize); 510 511 memcpy(data.data, dbmval.dptr + sizeof (apr_time_t), data.size); 512 513 cleanup: 514 apr_dbm_freedatum(dbm, dbmval); 515 close_db: 516 apr_dbm_close(dbm); 517 apr_global_mutex_unlock(sc->cache->mutex); 518 519 /* cache entry might have expired since last cache cleanup */ 520 if (expiry != 0 && expiry < apr_time_now()) 521 { 212 { 213 /* APR_NOTFOUND means there's no such object. */ 214 if (rv == APR_NOTFOUND) 215 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server, 216 "requested entry not found in cache '%s:%s'.", 217 sc->cache->prov->name, sc->cache_config); 218 else 219 ap_log_error(APLOG_MARK, APLOG_WARNING, rv, server, 220 "error fetching from cache '%s:%s'", 221 sc->cache->prov->name, sc->cache_config); 222 /* free unused buffer */ 522 223 gnutls_free(data.data); 523 224 data.data = NULL; 524 225 data.size = 0; 525 ap_log_error(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, server, 526 "dropped expired cache data"); 527 } 226 } 227 else 228 { 229 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, server, 230 "fetched %u bytes from cache '%s:%s'", 231 data.size, sc->cache->prov->name, sc->cache_config); 232 } 233 apr_pool_destroy(spool); 528 234 529 235 return data; 530 236 } 531 237 532 static gnutls_datum_t dbm_cache_fetch_session(void *baton, gnutls_datum_t key)238 static gnutls_datum_t socache_fetch_session(void *baton, gnutls_datum_t key) 533 239 { 534 240 gnutls_datum_t data = {NULL, 0}; … … 539 245 return data; 540 246 541 return dbm_cache_fetch(ctxt->c->base_server, dbmkey, ctxt->c->pool); 542 } 543 544 static int dbm_cache_store(server_rec *s, gnutls_datum_t key, 545 gnutls_datum_t data, apr_time_t expiry) 546 { 547 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 548 ap_get_module_config(s->module_config, &gnutls_module); 549 550 apr_dbm_t *dbm; 551 apr_datum_t dbmkey = {(char*) key.data, key.size}; 552 apr_datum_t dbmval; 553 apr_status_t rv; 554 apr_pool_t *spool; 555 556 /* check if it is time for cache expiration */ 557 dbm_cache_expire(s); 558 559 apr_pool_create(&spool, NULL); 560 561 /* create DBM value */ 562 dbmval.dsize = data.size + sizeof (apr_time_t); 563 dbmval.dptr = (char *) apr_palloc(spool, dbmval.dsize); 564 565 /* prepend expiration time */ 566 memcpy((char *) dbmval.dptr, &expiry, sizeof (apr_time_t)); 567 memcpy((char *) dbmval.dptr + sizeof (apr_time_t), 568 data.data, data.size); 569 570 apr_global_mutex_lock(sc->cache->mutex); 571 572 rv = apr_dbm_open_ex(&dbm, db_type(sc), 573 sc->cache_config, APR_DBM_RWCREATE, 574 SSL_DBM_FILE_MODE, spool); 575 if (rv != APR_SUCCESS) 576 { 577 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s, 578 "error opening cache '%s'", 579 sc->cache_config); 580 apr_global_mutex_unlock(sc->cache->mutex); 581 apr_pool_destroy(spool); 582 return -1; 583 } 584 585 rv = apr_dbm_store(dbm, dbmkey, dbmval); 586 if (rv != APR_SUCCESS) 587 { 588 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, 589 "error storing in cache '%s'", 590 sc->cache_config); 591 apr_dbm_close(dbm); 592 apr_global_mutex_unlock(sc->cache->mutex); 593 apr_pool_destroy(spool); 594 return -1; 595 } 596 597 apr_dbm_close(dbm); 598 apr_global_mutex_unlock(sc->cache->mutex); 599 600 ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, s, 601 "stored %" APR_SIZE_T_FMT " bytes of data (%" 602 APR_SIZE_T_FMT " byte key) in cache '%s'", 603 dbmval.dsize, dbmkey.dsize, sc->cache_config); 604 605 apr_pool_destroy(spool); 606 607 return 0; 608 } 609 610 static int dbm_cache_store_session(void *baton, gnutls_datum_t key, 611 gnutls_datum_t data) 612 { 613 mgs_handle_t *ctxt = baton; 614 gnutls_datum_t dbmkey; 615 616 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 617 return -1; 618 619 apr_time_t expiry = apr_time_now() + ctxt->sc->cache_timeout; 620 621 return dbm_cache_store(ctxt->c->base_server, dbmkey, data, expiry); 622 } 623 624 static int dbm_cache_delete(void *baton, gnutls_datum_t key) 625 { 626 apr_dbm_t *dbm; 247 return socache_fetch(ctxt->c->base_server, dbmkey, ctxt->c->pool); 248 } 249 250 251 252 static int socache_delete(void *baton, gnutls_datum_t key) 253 { 627 254 gnutls_datum_t tmpkey; 628 255 mgs_handle_t *ctxt = baton; 629 apr_status_t rv;630 256 631 257 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &tmpkey) < 0) 632 258 return -1; 633 apr_datum_t dbmkey = {(char*) tmpkey.data, tmpkey.size};634 259 635 260 apr_global_mutex_lock(ctxt->sc->cache->mutex); 636 637 rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), 638 ctxt->sc->cache_config, APR_DBM_RWCREATE, 639 SSL_DBM_FILE_MODE, ctxt->c->pool); 261 apr_status_t rv = ctxt->sc->cache->prov->remove(ctxt->sc->cache->socache, 262 ctxt->c->base_server, 263 key.data, key.size, 264 ctxt->c->pool); 265 apr_global_mutex_unlock(ctxt->sc->cache->mutex); 266 640 267 if (rv != APR_SUCCESS) { 641 268 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 642 269 ctxt->c->base_server, 643 "error opening cache '%s'", 644 ctxt->sc->cache_config); 645 apr_global_mutex_unlock(ctxt->sc->cache->mutex); 270 "error deleting from cache '%s:%s'", 271 ctxt->sc->cache->prov->name, ctxt->sc->cache_config); 646 272 return -1; 647 273 } 648 649 rv = apr_dbm_delete(dbm, dbmkey);650 651 if (rv != APR_SUCCESS) {652 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,653 ctxt->c->base_server,654 "error deleting from cache '%s'",655 ctxt->sc->cache_config);656 apr_dbm_close(dbm);657 apr_global_mutex_unlock(ctxt->sc->cache->mutex);658 return -1;659 }660 661 apr_dbm_close(dbm);662 apr_global_mutex_unlock(ctxt->sc->cache->mutex);663 664 274 return 0; 665 275 } 666 276 667 static int dbm_cache_post_config(apr_pool_t * p, server_rec * s, 668 mgs_srvconf_rec * sc) { 669 apr_status_t rv; 670 apr_dbm_t *dbm; 671 const char *path1; 672 const char *path2; 673 674 rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config, 675 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p); 676 677 if (rv != APR_SUCCESS) { 678 ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, 679 "GnuTLS: Cannot create DBM Cache at `%s'", 680 sc->cache_config); 681 return rv; 682 } 683 684 apr_dbm_close(dbm); 685 686 apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1, 687 &path2); 688 689 /* The Following Code takes logic directly from mod_ssl's DBM Cache */ 690 #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) 691 /* Running as Root */ 692 if (path1 && geteuid() == 0) { 693 if (0 != chown(path1, ap_unixd_config.user_id, -1)) 694 ap_log_error(APLOG_MARK, APLOG_NOTICE, -1, s, 695 "GnuTLS: could not chown cache path1 `%s' to uid %d (errno: %d)", 696 path1, ap_unixd_config.user_id, errno); 697 if (path2 != NULL) { 698 if (0 != chown(path2, ap_unixd_config.user_id, -1)) 699 ap_log_error(APLOG_MARK, APLOG_NOTICE, -1, s, 700 "GnuTLS: could not chown cache path2 `%s' to uid %d (errno: %d)", 701 path2, ap_unixd_config.user_id, errno); 702 } 703 } 704 #endif 705 706 return rv; 707 } 708 709 int mgs_cache_post_config(apr_pool_t * p, server_rec * s, 710 mgs_srvconf_rec * sc) { 711 277 278 279 static apr_status_t cleanup_socache(void *data) 280 { 281 server_rec *s = data; 282 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 283 ap_get_module_config(s->module_config, &gnutls_module); 284 ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s, 285 "Cleaning up socache '%s:%s'", 286 sc->cache->prov->name, sc->cache_config); 287 sc->cache->prov->destroy(sc->cache->socache, s); 288 return APR_SUCCESS; 289 } 290 291 292 293 int mgs_cache_post_config(apr_pool_t *pconf, apr_pool_t *ptemp, 294 server_rec *s, mgs_srvconf_rec *sc) 295 { 296 apr_status_t rv = APR_SUCCESS; 712 297 /* if GnuTLSCache was never explicitly set: */ 713 if (sc->cache_type == mgs_cache_unset) 298 if (sc->cache_type == mgs_cache_unset || sc->cache_type == mgs_cache_none) 299 { 714 300 sc->cache_type = mgs_cache_none; 301 /* Cache disabled, done. */ 302 return APR_SUCCESS; 303 } 715 304 /* if GnuTLSCacheTimeout was never explicitly set: */ 716 305 if (sc->cache_timeout == MGS_TIMEOUT_UNSET) … … 720 309 if (sc->cache == NULL) 721 310 { 722 sc->cache = apr_palloc(p , sizeof(struct mgs_cache));723 apr_status_trv = ap_global_mutex_create(&sc->cache->mutex, NULL,724 725 NULL, s, p, 0);311 sc->cache = apr_palloc(pconf, sizeof(struct mgs_cache)); 312 rv = ap_global_mutex_create(&sc->cache->mutex, NULL, 313 MGS_CACHE_MUTEX_NAME, 314 NULL, s, pconf, 0); 726 315 if (rv != APR_SUCCESS) 727 316 return rv; 728 317 } 729 318 319 char *pname = NULL; 320 730 321 if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) 731 322 { 732 sc->cache->store = dbm_cache_store; 733 sc->cache->fetch = dbm_cache_fetch; 734 return dbm_cache_post_config(p, s, sc); 323 pname = "dbm"; 324 sc->cache->store = socache_store; 325 sc->cache->fetch = socache_fetch; 326 //return dbm_cache_post_config(pconf, s, sc); 735 327 } 736 328 #if HAVE_APR_MEMCACHE 737 329 else if (sc->cache_type == mgs_cache_memcache) 738 330 { 739 sc->cache->store = mc_cache_store_generic; 740 sc->cache->fetch = mc_cache_fetch_generic; 741 } 742 #endif 331 pname = "memcache"; 332 sc->cache->store = socache_store; 333 sc->cache->fetch = socache_fetch; 334 } 335 #endif 336 else if (sc->cache_type == mgs_cache_shmcb) 337 { 338 pname = "shmcb"; 339 sc->cache->store = socache_store; 340 sc->cache->fetch = socache_fetch; 341 } 342 343 /* Find the right socache provider */ 344 sc->cache->prov = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP, 345 pname, 346 AP_SOCACHE_PROVIDER_VERSION); 347 if (sc->cache->prov) 348 { 349 /* Cache found; create it, passing anything beyond the colon. */ 350 const char *err = sc->cache->prov->create(&sc->cache->socache, 351 sc->cache_config, 352 ptemp, pconf); 353 if (err != NULL) 354 { 355 ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, s, 356 "Creating cache '%s:%s' failed: %s", 357 pname, sc->cache_config, err); 358 return HTTP_INSUFFICIENT_STORAGE; 359 } 360 ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s, 361 "%s: Socache '%s' created.", __func__, pname); 362 363 // TODO: provide hints 364 rv = sc->cache->prov->init(sc->cache->socache, 365 "mod_gnutls-session", NULL, s, pconf); 366 if (rv != APR_SUCCESS) 367 { 368 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, 369 "Initializing cache '%s:%s' failed!", 370 pname, sc->cache_config); 371 return HTTP_INSUFFICIENT_STORAGE; 372 } 373 ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, s, 374 "%s: socache '%s:%s' created.", __func__, 375 pname, sc->cache_config); 376 } 377 else 378 { 379 ap_log_error(APLOG_MARK, APLOG_EMERG, APR_EGENERAL, s, 380 "Could not find socache provider '%s', please make sure " 381 "that the provider name is valid and the " 382 "appropriate mod_socache submodule is loaded.", pname); 383 return HTTP_NOT_FOUND; 384 } 385 386 apr_pool_pre_cleanup_register(pconf, s, cleanup_socache); 743 387 744 388 return APR_SUCCESS; … … 757 401 "Failed to reinit mutex '%s'", MGS_CACHE_MUTEX_NAME); 758 402 759 if (sc->cache_type == mgs_cache_dbm760 || sc->cache_type == mgs_cache_gdbm) {761 return 0;762 }763 #if HAVE_APR_MEMCACHE764 else if (sc->cache_type == mgs_cache_memcache) {765 return mc_cache_child_init(p, s, sc);766 }767 #endif768 403 return 0; 769 404 } … … 771 406 #include <assert.h> 772 407 773 int mgs_cache_session_init(mgs_handle_t * ctxt) { 774 if (ctxt->sc->cache_type == mgs_cache_dbm 775 || ctxt->sc->cache_type == mgs_cache_gdbm) { 408 int mgs_cache_session_init(mgs_handle_t * ctxt) 409 { 410 if (ctxt->sc->cache_type != mgs_cache_none) 411 { 776 412 gnutls_db_set_retrieve_function(ctxt->session, 777 dbm_cache_fetch_session);413 socache_fetch_session); 778 414 gnutls_db_set_remove_function(ctxt->session, 779 dbm_cache_delete);415 socache_delete); 780 416 gnutls_db_set_store_function(ctxt->session, 781 dbm_cache_store_session);417 socache_store_session); 782 418 gnutls_db_set_ptr(ctxt->session, ctxt); 783 419 } 784 #if HAVE_APR_MEMCACHE785 else if (ctxt->sc->cache_type == mgs_cache_memcache) {786 gnutls_db_set_retrieve_function(ctxt->session,787 mc_cache_fetch_session);788 gnutls_db_set_remove_function(ctxt->session,789 mc_cache_delete);790 gnutls_db_set_store_function(ctxt->session,791 mc_cache_store_session);792 gnutls_db_set_ptr(ctxt->session, ctxt);793 }794 #endif795 796 420 return 0; 797 421 } -
src/gnutls_cache.h
r0470e44 rde1ceab 28 28 #include "mod_gnutls.h" 29 29 #include <httpd.h> 30 #include <ap_socache.h> 30 31 31 32 /** Name of the mod_gnutls cache access mutex, for use with Apache's … … 38 39 * parsed. 39 40 * 40 * @param p configuration memory pool 41 * @param pconf configuration memory pool 42 * @param ptemp temporary memory pool 41 43 * @param s default server of the Apache configuration, head of the 42 44 * server list 43 45 * @param sc mod_gnutls data associated with `s` 44 46 */ 45 int mgs_cache_post_config(apr_pool_t *p, server_rec *s, mgs_srvconf_rec *sc); 47 int mgs_cache_post_config(apr_pool_t *pconf, apr_pool_t *ptemp, 48 server_rec *s, mgs_srvconf_rec *sc); 46 49 47 50 /** … … 113 116 */ 114 117 struct mgs_cache { 118 /** Socache provider to use for this cache */ 119 const ap_socache_provider_t *prov; 120 /** The actual socache instance */ 121 ap_socache_instance_t *socache; 115 122 /** Store function for this cache */ 116 123 cache_store_func store; -
src/gnutls_config.c
r0470e44 rde1ceab 623 623 } 624 624 #endif 625 else if (strcasecmp("shmcb", type) == 0) { 626 sc->cache_type = mgs_cache_shmcb; 627 } 625 628 else { 626 629 return "Invalid Type for GnuTLSCache!"; -
src/gnutls_hooks.c
r0470e44 rde1ceab 577 577 578 578 579 rv = mgs_cache_post_config(pconf, s, sc_base);579 rv = mgs_cache_post_config(pconf, ptemp, s, sc_base); 580 580 if (rv != APR_SUCCESS) 581 581 { -
src/gnutls_ocsp.c
r0470e44 rde1ceab 1092 1092 mgs_srvconf_rec *sc = (mgs_srvconf_rec *) 1093 1093 ap_get_module_config(server->module_config, &gnutls_module); 1094 // TODO: check for cache! 1094 1095 1095 1096 if (sc->certs_x509_chain_num < 2) -
test/base_apache.conf
r0470e44 rde1ceab 12 12 LoadModule authz_core_module ${AP_LIBEXECDIR}/mod_authz_core.so 13 13 LoadModule mime_module ${AP_LIBEXECDIR}/mod_mime.so 14 15 LoadModule socache_dbm_module ${AP_LIBEXECDIR}/mod_socache_dbm.so 16 LoadModule socache_shmcb_module ${AP_LIBEXECDIR}/mod_socache_shmcb.so 17 14 18 TypesConfig ${srcdir}/mime.types 15 19 -
test/tests/00_basic/apache.conf
r0470e44 rde1ceab 1 1 Include ${srcdir}/base_apache.conf 2 2 3 GnuTLSCache dbm cache/gnutls_cache3 GnuTLSCache dbm:cache/gnutls_cache_${TEST_NAME} 4 4 5 5 <VirtualHost _default_:${TEST_PORT}> -
test/tests/27_OCSP_server/apache.conf
r0470e44 rde1ceab 1 1 Include ${srcdir}/base_apache.conf 2 GnuTLSCache dbm:cache/gnutls_cache_${TEST_NAME}2 GnuTLSCache shmcb:cache/gnutls_cache_${TEST_NAME} 3 3 4 4 <VirtualHost _default_:${TEST_PORT}>
Note: See TracChangeset
for help on using the changeset viewer.