Hiya, I'd like to integrate distcache support into mod_ssl on HEAD: are the copyright holders willing to contribute copyright ownership to the ASF for ssl_scache_dc.c and the other changes?
I've rediffed the published patch for 2.0.48 against HEAD, attached for review. Changes relative to the original patch are: - don't add #if 0 around #if APR_HAVE_UNISTD_H - style fixes in ssl_scache_dc.c: if( -> if (, untabify - don't cast the void * to DC_CTX * in ssl_scache_dc.c - rediff ssl_scache.c against HEAD - adjust ssl_scache_dc.c for new status API in HEAD - move distcache checks into modules/ssl/config.m4 Regards, joe
Index: config.m4 =================================================================== RCS file: /home/cvs/httpd-2.0/modules/ssl/config.m4,v retrieving revision 1.18 diff -u -r1.18 config.m4 --- config.m4 25 Nov 2003 15:46:36 -0000 1.18 +++ config.m4 26 Nov 2003 11:50:57 -0000 @@ -46,6 +46,76 @@ dnl ## SUCH DAMAGE. dnl ## ==================================================================== +AC_DEFUN([CHECK_DISTCACHE], [ + AC_MSG_CHECKING(whether Distcache is required) + ap_ssltk_dc="no" + tmp_nomessage="" + tmp_forced="no" + AC_ARG_ENABLE(distcache, + APACHE_HELP_STRING(--enable-distcache=yes/no,Select distcache support), + ap_ssltk_dc="$enableval" + tmp_nomessage="" + tmp_forced="yes" + if test "x$ap_ssltk_dc" = "x"; then + ap_ssltk_dc="yes" + dnl our "error"s become "tests revealed that..." + tmp_forced="no" + fi + if test "$ap_ssltk_dc" != "yes" -a "$ap_ssltk_dc" != "no"; then + tmp_nomessage="--enable-distcache had illegal syntax - disabling" + ap_ssltk_dc="no" + fi) + if test "$tmp_forced" = "no"; then + AC_MSG_RESULT($ap_ssltk_dc (default)) + else + AC_MSG_RESULT($ap_ssltk_dc (specified)) + fi + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno" -a "x$tmp_nomessage" != "x"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_CHECK_HEADER( + [distcache/dc_client.h], + [], + [tmp_nomessage="can't include distcache headers" + ap_ssltk_dc="no"]) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_MSG_CHECKING(for Distcache version) + AC_TRY_COMPILE( +[#include <distcache/dc_client.h>], +[#if DISTCACHE_CLIENT_API != 0x0001 +#error "distcache API version is unrecognised" +#endif], +[], +[tmp_nomessage="distcache has an unsupported API version" +ap_ssltk_dc="no"]) + AC_MSG_RESULT($ap_ssltk_dc) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + fi + if test "$ap_ssltk_dc" = "yes"; then + AC_MSG_CHECKING(for Distcache libraries) + save_libs=$LIBS + LIBS="$LIBS -ldistcache -lnal" + AC_TRY_LINK( + [#include <distcache/dc_client.h>], + [DC_CTX *foo = DC_CTX_new((const char *)0,0);], + [], + [tmp_no_message="failed to link with distcache libraries" + ap_ssltk_dc="no"]) + LIBS=$save_libs + AC_MSG_RESULT($ap_ssltk_dc) + if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then + AC_MSG_ERROR(distcache support failed: $tmp_nomessage) + fi + fi +]) + dnl # start of module specific part APACHE_MODPATH_INIT(ssl) @@ -69,12 +139,14 @@ ssl_scache.lo dnl ssl_scache_dbm.lo dnl ssl_scache_shmcb.lo dnl +ssl_scache_dc.lo dnl ssl_util.lo dnl ssl_util_ssl.lo dnl " dnl # hook module into the Autoconf mechanism (--enable-ssl option) APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , no, [ APACHE_CHECK_SSL_TOOLKIT + CHECK_DISTCACHE ]) dnl # end of module specific part Index: mod_ssl.dsp =================================================================== RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.dsp,v retrieving revision 1.25 diff -u -r1.25 mod_ssl.dsp --- mod_ssl.dsp 25 Nov 2003 15:46:36 -0000 1.25 +++ mod_ssl.dsp 26 Nov 2003 11:50:57 -0000 @@ -164,6 +164,10 @@ # End Source File # Begin Source File +SOURCE=.\ssl_scache_dc.c +# End Source File +# Begin Source File + SOURCE=.\ssl_util.c # End Source File # Begin Source File Index: mod_ssl.h =================================================================== RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.h,v retrieving revision 1.142 diff -u -r1.142 mod_ssl.h --- mod_ssl.h 26 Nov 2003 09:34:15 -0000 1.142 +++ mod_ssl.h 26 Nov 2003 11:50:57 -0000 @@ -602,7 +602,15 @@ void ssl_scache_shmcb_expire(server_rec *); void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *pool); -/* Pass Phrase Support */ +void ssl_scache_dc_init(server_rec *, apr_pool_t *); +void ssl_scache_dc_kill(server_rec *); +BOOL ssl_scache_dc_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *); +SSL_SESSION *ssl_scache_dc_retrieve(server_rec *, UCHAR *, int); +void ssl_scache_dc_remove(server_rec *, UCHAR *, int); +void ssl_scache_dc_expire(server_rec *); +void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool); + +/* PASS Phrase Support */ void ssl_pphrase_Handle(server_rec *, apr_pool_t *); /* Diffie-Hellman Parameter Support */ Index: ssl_scache.c =================================================================== RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_scache.c,v retrieving revision 1.17 diff -u -r1.17 ssl_scache.c --- ssl_scache.c 25 Nov 2003 16:59:10 -0000 1.17 +++ ssl_scache.c 26 Nov 2003 11:50:57 -0000 @@ -88,6 +88,10 @@ if (mc->nSessionCacheMode == SSL_SCMODE_DBM) ssl_scache_dbm_init(s, p); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_init(s, p); +#endif else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) { void *data; const char *userdata_key = "ssl_scache_init"; @@ -110,6 +114,10 @@ ssl_scache_dbm_kill(s); else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) ssl_scache_shmcb_kill(s); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_kill(s); +#endif return; } @@ -122,6 +130,10 @@ rv = ssl_scache_dbm_store(s, id, idlen, expiry, sess); else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) rv = ssl_scache_shmcb_store(s, id, idlen, expiry, sess); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + rv = ssl_scache_dc_store(s, id, idlen, expiry, sess); +#endif return rv; } @@ -134,6 +146,10 @@ sess = ssl_scache_dbm_retrieve(s, id, idlen); else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) sess = ssl_scache_shmcb_retrieve(s, id, idlen); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + sess = ssl_scache_dc_retrieve(s, id, idlen); +#endif return sess; } @@ -145,6 +161,10 @@ ssl_scache_dbm_remove(s, id, idlen); else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) ssl_scache_shmcb_remove(s, id, idlen); +#ifdef HAVE_DISTCACHE + else if (mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_remove(s, id, idlen); +#endif return; } @@ -182,6 +202,10 @@ ssl_scache_dbm_status(r, flags, r->pool); else if (sc->mc->nSessionCacheMode == SSL_SCMODE_SHMCB) ssl_scache_shmcb_status(r, flags, r->pool); +#ifdef HAVE_DISTCACHE + else if (sc->mc->nSessionCacheMode == SSL_SCMODE_DC) + ssl_scache_dc_status(r, flags, r->pool); +#endif ap_rputs("</td></tr>\n", r); ap_rputs("</table>\n", r); Index: ssl_scache_dc.c =================================================================== RCS file: ssl_scache_dc.c diff -N ssl_scache_dc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ssl_scache_dc.c 26 Nov 2003 11:50:57 -0000 @@ -0,0 +1,183 @@ +/* _ _ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org +** |_____| +** ssl_scache_dc.c +** Distributed Session Cache (client support) +*/ + +/* ==================================================================== + * THIS SOFTWARE IS PROVIDED BY GEOFF THORPE ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR + * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "mod_ssl.h" + +/* Only build this code if it's enabled at configure-time. */ +#ifdef HAVE_DISTCACHE + +#include "distcache/dc_client.h" + +#if !defined(DISTCACHE_CLIENT_API) || (DISTCACHE_CLIENT_API < 0x0001) +#error "You must compile with a more recent version of the distcache-base package" +#endif + +/* + * This cache implementation allows modssl to access 'distcache' servers (or + * proxies) to facilitate distributed session caching. It is based on code + * released as open source by Cryptographic Appliances Inc, and was developed by + * Geoff Thorpe, Steve Robb, and Chris Zimmerman. + */ + +/* +** +** High-Level "handlers" as per ssl_scache.c +** +*/ + +void ssl_scache_dc_init(server_rec *s, apr_pool_t *p) +{ + DC_CTX *ctx; + SSLModConfigRec *mc = myModConfig(s); + /* + * Create a session context + */ + if (mc->szSessionCacheDataFile == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); + ssl_die(); + } +#if 0 + /* If a "persistent connection" mode of operation is preferred, you *must* + * also use the PIDCHECK flag to ensure fork()'d processes don't interlace + * comms on the same connection as each other. */ +#define SESSION_CTX_FLAGS SESSION_CTX_FLAG_PERSISTENT | \ + SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \ + SESSION_CTX_FLAG_PERSISTENT_RETRY | \ + SESSION_CTX_FLAG_PERSISTENT_LATE +#else + /* This mode of operation will open a temporary connection to the 'target' + * for each cache operation - this makes it safe against fork() + * automatically. This mode is preferred when running a local proxy (over + * unix domain sockets) because overhead is negligable and it reduces the + * performance/stability danger of file-descriptor bloatage. */ +#define SESSION_CTX_FLAGS 0 +#endif + ctx = DC_CTX_new(mc->szSessionCacheDataFile, SESSION_CTX_FLAGS); + if (!ctx) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache failed to obtain context"); + ssl_die(); + } + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "distributed scache context initialised"); + /* + * Success ... + */ + mc->tSessionCacheDataTable = ctx; + return; +} + +void ssl_scache_dc_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(s); + + if (mc->tSessionCacheDataTable) + DC_CTX_free(mc->tSessionCacheDataTable); + mc->tSessionCacheDataTable = NULL; +} + +BOOL ssl_scache_dc_store(server_rec *s, UCHAR *id, int idlen, + time_t timeout, SSL_SESSION * pSession) +{ + unsigned char der[SSL_SESSION_MAX_DER]; + int der_len; + unsigned char *pder = der; + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Serialise the SSL_SESSION object */ + if ((der_len = i2d_SSL_SESSION(pSession, NULL)) > SSL_SESSION_MAX_DER) + return FALSE; + i2d_SSL_SESSION(pSession, &pder); + /* [EMAIL PROTECTED] - why do we deal with *absolute* time anyway??? */ + timeout -= time(NULL); + /* Send the serialised session to the distributed cache context */ + if (!DC_CTX_add_session(ctx, id, idlen, der, der_len, + (unsigned long)timeout * 1000)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed"); + return FALSE; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'add_session' successful"); + return TRUE; +} + +SSL_SESSION *ssl_scache_dc_retrieve(server_rec *s, UCHAR *id, int idlen) +{ + unsigned char der[SSL_SESSION_MAX_DER]; + unsigned int der_len; + SSL_SESSION *pSession; + unsigned char *pder = der; + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Retrieve any corresponding session from the distributed cache context */ + if (!DC_CTX_get_session(ctx, id, idlen, der, SSL_SESSION_MAX_DER, + &der_len)) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS"); + return NULL; + } + if (der_len > SSL_SESSION_MAX_DER) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW"); + return NULL; + } + pSession = d2i_SSL_SESSION(NULL, &pder, der_len); + if (!pSession) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' CORRUPT"); + return NULL; + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT"); + return pSession; +} + +void ssl_scache_dc_remove(server_rec *s, UCHAR *id, int idlen) +{ + SSLModConfigRec *mc = myModConfig(s); + DC_CTX *ctx = mc->tSessionCacheDataTable; + + /* Remove any corresponding session from the distributed cache context */ + if (!DC_CTX_remove_session(ctx, id, idlen)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' MISS"); + } else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' HIT"); + } +} + +void ssl_scache_dc_expire(server_rec *s) +{ + /* NOP */ + return; +} + +void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool) +{ + SSLModConfigRec *mc = myModConfig(r->server); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "distributed scache 'ssl_scache_dc_status'"); + ap_rprintf(r, "cache type: <b>DC (Distributed Cache)</b>, " + " target: <b>%s</b><br>", mc->szSessionCacheDataFile); +} + +#endif +