ssl_scache_dc.c revision cf9ada3713548ca11de76ff801839b79c879d380
842ae4bd224140319ae7feec1872b93dfd491143fielding/* Copyright 2004-2005 The Apache Software Foundation or its licensors, as
842ae4bd224140319ae7feec1872b93dfd491143fielding * applicable.
842ae4bd224140319ae7feec1872b93dfd491143fielding *
842ae4bd224140319ae7feec1872b93dfd491143fielding * Licensed under the Apache License, Version 2.0 (the "License");
842ae4bd224140319ae7feec1872b93dfd491143fielding * you may not use this file except in compliance with the License.
842ae4bd224140319ae7feec1872b93dfd491143fielding * You may obtain a copy of the License at
2d2eda71267231c2526be701fe655db125852c1ffielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * http://www.apache.org/licenses/LICENSE-2.0
2d2eda71267231c2526be701fe655db125852c1ffielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
2d2eda71267231c2526be701fe655db125852c1ffielding */
2d2eda71267231c2526be701fe655db125852c1ffielding
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh/* _ _
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * _ __ ___ ___ __| | ___ ___| | mod_ssl
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * | | | | | | (_) | (_| | \__ \__ \ |
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * |_| |_| |_|\___/ \__,_|___|___/___/_|
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * |_____|
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * ssl_scache_dc.c
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh * Distributed Session Cache (client support)
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh */
2d2eda71267231c2526be701fe655db125852c1ffielding
2d2eda71267231c2526be701fe655db125852c1ffielding#include "ssl_private.h"
2d2eda71267231c2526be701fe655db125852c1ffielding
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb/* Only build this code if it's enabled at configure-time. */
ab5581cc78e9d865b0a6ab1404c53347b3276968rbb#ifdef HAVE_DISTCACHE
92f3af936ce61f25358a3ee4f28df2f6d62040dfdreid
fcc25eda7b150e226d3c1cdaea66a943d3fdee4erbb#include "distcache/dc_client.h"
c9a95767fbf0f5fb0976a06b97a256033925e433rbb
fd0edaa8e3d4dd67d0604ccef2e96b071db96643fielding#if !defined(DISTCACHE_CLIENT_API) || (DISTCACHE_CLIENT_API < 0x0001)
2d2eda71267231c2526be701fe655db125852c1ffielding#error "You must compile with a more recent version of the distcache-base package"
2d2eda71267231c2526be701fe655db125852c1ffielding#endif
2d2eda71267231c2526be701fe655db125852c1ffielding
2d2eda71267231c2526be701fe655db125852c1ffielding/*
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj * This cache implementation allows modssl to access 'distcache' servers (or
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj * proxies) to facilitate distributed session caching. It is based on code
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj * released as open source by Cryptographic Appliances Inc, and was developed by
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj * Geoff Thorpe, Steve Robb, and Chris Zimmerman.
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj */
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj
52de7a47876ce1748910cf3a0ee97f78842fab54rederpj/*
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh**
fd492f9543f14fb5bae78e04b135c3448eb9cc56rbb** High-Level "handlers" as per ssl_scache.c
fd492f9543f14fb5bae78e04b135c3448eb9cc56rbb**
fd492f9543f14fb5bae78e04b135c3448eb9cc56rbb*/
fd492f9543f14fb5bae78e04b135c3448eb9cc56rbb
2d2eda71267231c2526be701fe655db125852c1ffieldingvoid ssl_scache_dc_init(server_rec *s, apr_pool_t *p)
2d2eda71267231c2526be701fe655db125852c1ffielding{
2d2eda71267231c2526be701fe655db125852c1ffielding DC_CTX *ctx;
2d2eda71267231c2526be701fe655db125852c1ffielding SSLModConfigRec *mc = myModConfig(s);
2d2eda71267231c2526be701fe655db125852c1ffielding /*
61fd0cab072a05b855cbef9c585702401ac5ae29rbb * Create a session context
61fd0cab072a05b855cbef9c585702401ac5ae29rbb */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if (mc->szSessionCacheDataFile == NULL) {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required");
742318b93e89c311f66b55f426c4d9cf2c14628bjim ssl_die();
2d2eda71267231c2526be701fe655db125852c1ffielding }
2d2eda71267231c2526be701fe655db125852c1ffielding#if 0
8af88bd6958b80c224e964892b8237720b13ab1ajerenkrantz /* If a "persistent connection" mode of operation is preferred, you *must*
8af88bd6958b80c224e964892b8237720b13ab1ajerenkrantz * also use the PIDCHECK flag to ensure fork()'d processes don't interlace
8af88bd6958b80c224e964892b8237720b13ab1ajerenkrantz * comms on the same connection as each other. */
8af88bd6958b80c224e964892b8237720b13ab1ajerenkrantz#define SESSION_CTX_FLAGS SESSION_CTX_FLAG_PERSISTENT | \
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp SESSION_CTX_FLAG_PERSISTENT_RETRY | \
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp SESSION_CTX_FLAG_PERSISTENT_LATE
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp#else
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp /* This mode of operation will open a temporary connection to the 'target'
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp * for each cache operation - this makes it safe against fork()
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp * automatically. This mode is preferred when running a local proxy (over
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp * unix domain sockets) because overhead is negligable and it reduces the
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp * performance/stability danger of file-descriptor bloatage. */
50e60f30bdc074fbc887f0b98f4d570457ac97c9brianp#define SESSION_CTX_FLAGS 0
8af88bd6958b80c224e964892b8237720b13ab1ajerenkrantz#endif
bfb62a96023822c56c9120e4ee627d4091cc59c2rbb ctx = DC_CTX_new(mc->szSessionCacheDataFile, SESSION_CTX_FLAGS);
bfb62a96023822c56c9120e4ee627d4091cc59c2rbb if (!ctx) {
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache failed to obtain context");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ssl_die();
61fd0cab072a05b855cbef9c585702401ac5ae29rbb }
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "distributed scache context initialised");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb /*
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * Success ...
2d2eda71267231c2526be701fe655db125852c1ffielding */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb mc->tSessionCacheDataTable = ctx;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb return;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb}
742318b93e89c311f66b55f426c4d9cf2c14628bjim
742318b93e89c311f66b55f426c4d9cf2c14628bjimvoid ssl_scache_dc_kill(server_rec *s)
742318b93e89c311f66b55f426c4d9cf2c14628bjim{
742318b93e89c311f66b55f426c4d9cf2c14628bjim SSLModConfigRec *mc = myModConfig(s);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
2d2eda71267231c2526be701fe655db125852c1ffielding if (mc->tSessionCacheDataTable)
3d96ee83babeec32482c9082c9426340cee8c44dwrowe DC_CTX_free(mc->tSessionCacheDataTable);
2d2eda71267231c2526be701fe655db125852c1ffielding mc->tSessionCacheDataTable = NULL;
2d2eda71267231c2526be701fe655db125852c1ffielding}
2d2eda71267231c2526be701fe655db125852c1ffielding
2d2eda71267231c2526be701fe655db125852c1ffieldingBOOL ssl_scache_dc_store(server_rec *s, UCHAR *id, int idlen,
000b67449410515eac43e76ef6667915bfd4d2abgstein time_t timeout, SSL_SESSION * pSession)
2d2eda71267231c2526be701fe655db125852c1ffielding{
2d2eda71267231c2526be701fe655db125852c1ffielding unsigned char der[SSL_SESSION_MAX_DER];
2d2eda71267231c2526be701fe655db125852c1ffielding int der_len;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb unsigned char *pder = der;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb SSLModConfigRec *mc = myModConfig(s);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb DC_CTX *ctx = mc->tSessionCacheDataTable;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
61fd0cab072a05b855cbef9c585702401ac5ae29rbb /* Serialise the SSL_SESSION object */
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein if ((der_len = i2d_SSL_SESSION(pSession, NULL)) > SSL_SESSION_MAX_DER)
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein return FALSE;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb i2d_SSL_SESSION(pSession, &pder);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb /* !@#$%^ - why do we deal with *absolute* time anyway??? */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb timeout -= time(NULL);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb /* Send the serialised session to the distributed cache context */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if (!DC_CTX_add_session(ctx, id, idlen, der, der_len,
3d96ee83babeec32482c9082c9426340cee8c44dwrowe (unsigned long)timeout * 1000)) {
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb return FALSE;
742318b93e89c311f66b55f426c4d9cf2c14628bjim }
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'add_session' successful");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb return TRUE;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb}
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
61fd0cab072a05b855cbef9c585702401ac5ae29rbbSSL_SESSION *ssl_scache_dc_retrieve(server_rec *s, UCHAR *id, int idlen)
3d96ee83babeec32482c9082c9426340cee8c44dwrowe{
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein unsigned char der[SSL_SESSION_MAX_DER];
c9a95767fbf0f5fb0976a06b97a256033925e433rbb unsigned int der_len;
c9a95767fbf0f5fb0976a06b97a256033925e433rbb SSL_SESSION *pSession;
c9a95767fbf0f5fb0976a06b97a256033925e433rbb MODSSL_D2I_SSL_SESSION_CONST unsigned char *pder = der;
cf8d02ea0c91653917b044529f3133c5a1bb9200fielding SSLModConfigRec *mc = myModConfig(s);
c9a95767fbf0f5fb0976a06b97a256033925e433rbb DC_CTX *ctx = mc->tSessionCacheDataTable;
c9a95767fbf0f5fb0976a06b97a256033925e433rbb
c9a95767fbf0f5fb0976a06b97a256033925e433rbb /* Retrieve any corresponding session from the distributed cache context */
c9a95767fbf0f5fb0976a06b97a256033925e433rbb if (!DC_CTX_get_session(ctx, id, idlen, der, SSL_SESSION_MAX_DER,
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh &der_len)) {
c9a95767fbf0f5fb0976a06b97a256033925e433rbb ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS");
742318b93e89c311f66b55f426c4d9cf2c14628bjim return NULL;
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp }
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp if (der_len > SSL_SESSION_MAX_DER) {
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW");
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp return NULL;
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp }
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh pSession = d2i_SSL_SESSION(NULL, &pder, der_len);
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp if (!pSession) {
d82d78a97558238d16c52ec5278fe921bb7d7ec3brianp ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' CORRUPT");
c9a95767fbf0f5fb0976a06b97a256033925e433rbb return NULL;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb }
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb return pSession;
61fd0cab072a05b855cbef9c585702401ac5ae29rbb}
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
61fd0cab072a05b855cbef9c585702401ac5ae29rbbvoid ssl_scache_dc_remove(server_rec *s, UCHAR *id, int idlen)
61fd0cab072a05b855cbef9c585702401ac5ae29rbb{
742318b93e89c311f66b55f426c4d9cf2c14628bjim SSLModConfigRec *mc = myModConfig(s);
3d96ee83babeec32482c9082c9426340cee8c44dwrowe DC_CTX *ctx = mc->tSessionCacheDataTable;
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein
61fd0cab072a05b855cbef9c585702401ac5ae29rbb /* Remove any corresponding session from the distributed cache context */
61fd0cab072a05b855cbef9c585702401ac5ae29rbb if (!DC_CTX_remove_session(ctx, id, idlen)) {
9d129b55f5a43abf43865c6b0eb6dd19bc22aba8ianh ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' MISS");
61fd0cab072a05b855cbef9c585702401ac5ae29rbb } else {
3d96ee83babeec32482c9082c9426340cee8c44dwrowe ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' HIT");
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein }
61fd0cab072a05b855cbef9c585702401ac5ae29rbb}
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
61fd0cab072a05b855cbef9c585702401ac5ae29rbbvoid ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool)
61fd0cab072a05b855cbef9c585702401ac5ae29rbb{
3d96ee83babeec32482c9082c9426340cee8c44dwrowe SSLModConfigRec *mc = myModConfig(r->server);
7bdef86e15d47d16dcbe7a5611683191774bd5fbgstein
61fd0cab072a05b855cbef9c585702401ac5ae29rbb ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
61fd0cab072a05b855cbef9c585702401ac5ae29rbb "distributed scache 'ssl_scache_dc_status'");
742318b93e89c311f66b55f426c4d9cf2c14628bjim ap_rprintf(r, "cache type: <b>DC (Distributed Cache)</b>, "
61fd0cab072a05b855cbef9c585702401ac5ae29rbb " target: <b>%s</b><br>", mc->szSessionCacheDataFile);
61fd0cab072a05b855cbef9c585702401ac5ae29rbb}
78ae1cbba5a848a24ca551629bbf0a90d2b931f0stas
78ae1cbba5a848a24ca551629bbf0a90d2b931f0stas#endif
61fd0cab072a05b855cbef9c585702401ac5ae29rbb
3d96ee83babeec32482c9082c9426340cee8c44dwrowe