diff -urN stunnel-4.04/configure.ac stunnel-4.04-patched/configure.ac --- stunnel-4.04/configure.ac 2003-01-01 07:32:03.000000000 -0500 +++ stunnel-4.04-patched/configure.ac 2003-03-01 17:04:32.000000000 -0500 @@ -15,6 +15,7 @@ AC_DISABLE_STATIC AC_PROG_LIBTOOL +dnl FIXME: convert the given directory to an absolute path checkssldir() { : if test -f "$1/include/openssl/ssl.h"; then AC_DEFINE(HAVE_OPENSSL) @@ -105,6 +106,8 @@ AC_DEFINE_UNQUOTED(HOST, "$host") dnl Checks for standard libraries. +AC_CHECK_LIB(dl, dlopen) +AC_CHECK_LIB(dld, shl_load) AC_CHECK_LIB(nsl, gethostbyname) AC_CHECK_LIB(socket, socket) @@ -178,6 +181,48 @@ AC_CHECK_FILE("/dev/ptmx", AC_DEFINE(HAVE_DEV_PTMX)) AC_CHECK_FILE("/dev/ptc", AC_DEFINE(HAVE_DEV_PTS_AND_PTC)) +dnl Use Distcache? +AC_MSG_CHECKING([whether to disable Distcache]) +test_distcache="yes" +AC_ARG_ENABLE(distcache, +[ --disable-distcache Disable Distcache support], + [ AC_MSG_RESULT([yes]) + AC_DEFINE(NO_DISTCACHE) + test_distcache="no" ], + [ AC_MSG_RESULT([no]) ] +) +if test "$test_distcache" = "yes"; then + dc_fail="" + AC_CHECK_HEADERS(distcache/dc_client.h, [], + [dc_fail="distcache headers missing or unusable"]) + dnl continue if headers were found + if test "x$dc_fail" = "x"; then + saved_LIBS="$LIBS" + LIBS="$saved_LIBS -ldistcache -lnal" + AC_MSG_CHECKING([for distcache libraries]) + AC_TRY_LINK([#include ], + [DC_CTX *foo = DC_CTX_new((const char *)0,0);], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + dc_fail="distcache libraries missing or unusable" + LIBS="$saved_LIBS"]) + fi + dnl continue if linking worked + if test "x$dc_fail" = "x"; then + AC_TRY_COMPILE([#include ], +[#if DISTCACHE_CLIENT_API != 0x0001 +#error "invalid DISTCACHE_CLIENT_API" +#endif], [], + [dc_fail="unknown distcache API version"]) + fi + if test "x$dc_fail" = "x"; then + echo "enabling distcache support" + else + AC_DEFINE(NO_DISTCACHE) + echo "disabling distcache support: $dc_fail" + fi +fi + dnl Checks for header files. # AC_HEADER_DIRENT # AC_HEADER_STDC @@ -207,4 +252,4 @@ AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile tools/Makefile tools/stunnel.conf-sample tools/stunnel.init]) AC_OUTPUT -# End of configure.in +# End of configure.ac diff -urN stunnel-4.04/src/common.h stunnel-4.04-patched/src/common.h --- stunnel-4.04/src/common.h 2003-01-01 09:45:57.000000000 -0500 +++ stunnel-4.04-patched/src/common.h 2003-03-01 17:04:50.000000000 -0500 @@ -232,6 +232,15 @@ #include /* for CRYPTO_* and SSLeay_version */ #endif +/* Distcache headers */ +#ifndef NO_DISTCACHE + +#ifdef HAVE_DISTCACHE_DC_CLIENT_H +#include +#endif + +#endif + /* I/O buffer size */ #define BUFFSIZE 16384 diff -urN stunnel-4.04/src/options.c stunnel-4.04-patched/src/options.c --- stunnel-4.04/src/options.c 2003-01-01 09:21:58.000000000 -0500 +++ stunnel-4.04-patched/src/options.c 2003-03-01 17:04:59.000000000 -0500 @@ -307,6 +307,32 @@ break; } + /* distcache_target */ + switch(cmd) { + case CMD_INIT: +#ifndef NO_DISTCACHE + options.distcache_target=NULL; +#endif + break; + case CMD_EXEC: + if(strcasecmp(opt, "dc_target")) + break; +#ifdef NO_DISTCACHE + return "distcache support is missing from this version"; + default: + break; +#else + options.distcache_target=stralloc(arg); + return NULL; /* OK */ + case CMD_DEFAULT: + log_raw("%-15s = %s", "dc_target", options.distcache_target); + break; + case CMD_HELP: + log_raw("%-15s = distcache target address", "dc_target"); + break; +#endif + } + /* output */ switch(cmd) { case CMD_INIT: diff -urN stunnel-4.04/src/prototypes.h stunnel-4.04-patched/src/prototypes.h --- stunnel-4.04/src/prototypes.h 2003-01-01 09:33:54.000000000 -0500 +++ stunnel-4.04-patched/src/prototypes.h 2003-03-01 17:05:07.000000000 -0500 @@ -105,6 +105,11 @@ int verify_use_only_my; long ssl_options; + /* If distcache support is built in */ +#ifndef NO_DISTCACHE + char *distcache_target; /* eg. "UNIX:/tmp/scache", "IP:foo:9001" */ +#endif + /* some global data for stunnel.c */ #ifndef USE_WIN32 #ifdef HAVE_CHROOT diff -urN stunnel-4.04/src/ssl.c stunnel-4.04-patched/src/ssl.c --- stunnel-4.04/src/ssl.c 2003-01-01 09:07:08.000000000 -0500 +++ stunnel-4.04-patched/src/ssl.c 2003-03-01 17:05:12.000000000 -0500 @@ -41,6 +41,12 @@ #endif /* NO_RSA */ +#ifndef NO_DISTCACHE +/* Distcache support needs a limit on the size of serialised session data it + * will try to cache. */ +#define DC_MAX_SESSION_LEN 2048 +#endif + #include "common.h" #include "prototypes.h" @@ -62,8 +68,18 @@ #endif static void print_stats(void); static void sslerror_stack(void); +#ifndef NO_DISTCACHE + /* Distcache support */ +static int dc_init(const char *); +static int dc_new_callback(SSL *, SSL_SESSION *); +static SSL_SESSION *dc_get_callback(SSL *, unsigned char *, int, int *); +static void dc_remove_callback(SSL_CTX *, SSL_SESSION *); +#endif SSL_CTX *ctx; /* global SSL context */ +#ifndef NO_DISTCACHE +DC_CTX *dc_ctx; /* global distcache context */ +#endif void context_init(void) { /* init SSL */ int i; @@ -95,6 +111,25 @@ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_timeout(ctx, options.session_timeout); +#ifndef NO_DISTCACHE + if(options.distcache_target) { + if(options.option.client) + log(LOG_WARNING, "Distcache support is ignored for client SSL/TLS"); + else if(!dc_init(options.distcache_target)) + log(LOG_ERR, "Distcache support failed for target: %s", + options.distcache_target); + else { + /* Rewire caching to use distcache */ + log(LOG_INFO, "Distcache support set to target: %s", + options.distcache_target); + SSL_CTX_set_session_cache_mode(ctx, + SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL_LOOKUP); + SSL_CTX_sess_set_new_cb(ctx, dc_new_callback); + SSL_CTX_sess_set_get_cb(ctx, dc_get_callback); + SSL_CTX_sess_set_remove_cb(ctx, dc_remove_callback); + } + } +#endif if(options.option.cert) { if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) { log(LOG_ERR, "Error reading certificate file: %s", options.cert); @@ -513,4 +548,61 @@ log(LOG_ERR, "error stack: %lX : %s", err, string); } +#ifndef NO_DISTCACHE + /* Distcache support */ +#if 0 + /* If a "persistent connection" mode of operations is preferred, you *must* + * also use the PIDCHECK flag to ensure fork()'d processes don't interlace. */ +#define DC_CTX_OUR_FLAGS SESSION_CTX_FLAG_PERSISTENT | \ + SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \ + SESSION_CTX_FLAG_PERSISTENT_RETRY | \ + SESSION_CTX_FLAG_PERSISTENT_LATE +#else + /* Use a temporary connection for each cache operation */ +#define DC_CTX_OUR_FLAGS 0 +#endif +static int dc_init(const char *addr) +{ + dc_ctx = DC_CTX_new(addr, DC_CTX_OUR_FLAGS); + return (dc_ctx ? 1 : 0); +} + +static int dc_new_callback(SSL *ssl, SSL_SESSION *sess) +{ + unsigned char der[DC_MAX_SESSION_LEN]; + int der_len; + unsigned char *pder = der; + if((der_len = i2d_SSL_SESSION(sess, NULL)) > DC_MAX_SESSION_LEN) + return 0; + i2d_SSL_SESSION(sess, &pder); + log(LOG_INFO, "Distcache new: timeout=%lu", SSL_SESSION_get_timeout(sess)); + if(!DC_CTX_add_session(dc_ctx, sess->session_id, sess->session_id_length, + der, der_len, (unsigned long)SSL_SESSION_get_timeout(sess) * 1000)) + return 0; + return 1; +} + +static SSL_SESSION *dc_get_callback(SSL *ssl, unsigned char *id, int idlen, int *do_copy) +{ + unsigned char der[DC_MAX_SESSION_LEN]; + unsigned int der_len; + unsigned char *pder = der; + /* We won't hold a reference to any return value */ + *do_copy = 0; + log(LOG_INFO, "Distcache get"); + if(!DC_CTX_get_session(dc_ctx, id, idlen, der, DC_MAX_SESSION_LEN, &der_len)) + return NULL; + if(der_len > DC_MAX_SESSION_LEN) + return NULL; + return d2i_SSL_SESSION(NULL, &pder, der_len); +} + +static void dc_remove_callback(SSL_CTX *ssl_ctx, SSL_SESSION *sess) +{ + log(LOG_INFO, "Distcache remove"); + DC_CTX_remove_session(dc_ctx, sess->session_id, sess->session_id_length); +} + +#endif + /* End of ssl.c */