You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2004/01/08 17:26:53 UTC

cvs commit: httpd-2.0/modules/ssl ssl_scache_dc.c config.m4 mod_ssl.dsp mod_ssl.h ssl_engine_config.c ssl_scache.c

jorton      2004/01/08 08:26:53

  Modified:    .        CHANGES LAYOUT
               modules/ssl config.m4 mod_ssl.dsp mod_ssl.h
                        ssl_engine_config.c ssl_scache.c
  Added:       modules/ssl ssl_scache_dc.c
  Log:
  Add support to mod_ssl for a distributed session cache using
  distcache.
  
  * LAYOUT: Update for removal of scache_shmht and addition of scache_dc.
  
  * modules/ssl/config.m4: Check for libdistcache; build ssl_scache_dc.lo.
  
  * modules/ssl/mod_ssl.dsp: Build ssl_scache_dc (with luck).
  
  * modules/ssl/mod_ssl.h: Add SSL_SCMODE_DC and scache_dc_* prototypes.
  
  * modules/ssl/ssl_engine_config.c (ssl_cmd_SSLSessionCache): Allow
  use of dc: argument.
  
  * modules/ssl/ssl_scache_dc.c: New file.
  
  * modules/ssl/ssl_scache.c (ssl_scache_init, ssl_scache_kill,
  ssl_scache_store, ssl_scache_retrieve, ssl_scache_remove,
  ssl_ext_status_hook): Hook into scache_dc.
  
  Submitted by: Geoff Thorpe <ge...@geoffthorpe.net>
  
  Revision  Changes    Path
  1.1355    +3 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.1354
  retrieving revision 1.1355
  diff -b -d -u -r1.1354 -r1.1355
  --- CHANGES	8 Jan 2004 13:11:37 -0000	1.1354
  +++ CHANGES	8 Jan 2004 16:26:52 -0000	1.1355
  @@ -2,6 +2,9 @@
   
     [Remove entries to the current 2.0 section below, when backported]
   
  +  *) mod_ssl: Add support for distributed session cache using 'distcache'.
  +     [Geoff Thorpe <geoff geoffthorpe.net>]
  +
     *) mod_dav: Disallow requests with an unescaped hash character in
        the Request-URI.  PR 21779.  [Amit Athavale <amit_athavale lycos.com>]
   
  
  
  
  1.3       +1 -1      httpd-2.0/LAYOUT
  
  Index: LAYOUT
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/LAYOUT,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -b -d -u -r1.2 -r1.3
  --- LAYOUT	8 Dec 2002 21:05:55 -0000	1.2
  +++ LAYOUT	8 Jan 2004 16:26:53 -0000	1.3
  @@ -128,7 +128,7 @@
       ssl_scache.c ............ session cache abstraction layer
       ssl_scache_dbm.c ........ session cache via DBM file
       ssl_scache_shmcb.c ...... session cache via shared memory cyclic buffer
  -    ssl_scache_shmht.c ...... session cache via shared memory hash table
  +    ssl_scache_dc.c ......... session cache offloading via 'distcache'
       ssl_util.c .............. utility functions
       ssl_util_ssl.c .......... the OpenSSL companion source
       ssl_util_ssl.h .......... the OpenSSL companion header
  
  
  
  1.19      +75 -0     httpd-2.0/modules/ssl/config.m4
  
  Index: config.m4
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/config.m4,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -b -d -u -r1.18 -r1.19
  --- config.m4	25 Nov 2003 15:46:36 -0000	1.18
  +++ config.m4	8 Jan 2004 16:26:53 -0000	1.19
  @@ -46,6 +46,79 @@
   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,Select distcache support in mod_ssl),
  +    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)
  +    else
  +      APR_ADDTO(LIBS,[-ldistcache -lnal])
  +      AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled])
  +    fi
  +  fi
  +])
  +
   dnl #  start of module specific part
   APACHE_MODPATH_INIT(ssl)
   
  @@ -69,12 +142,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
  
  
  
  1.27      +4 -0      httpd-2.0/modules/ssl/mod_ssl.dsp
  
  Index: mod_ssl.dsp
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.dsp,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -b -d -u -r1.26 -r1.27
  --- mod_ssl.dsp	15 Dec 2003 11:35:34 -0000	1.26
  +++ mod_ssl.dsp	8 Jan 2004 16:26:53 -0000	1.27
  @@ -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
  
  
  
  1.144     +11 -2     httpd-2.0/modules/ssl/mod_ssl.h
  
  Index: mod_ssl.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/mod_ssl.h,v
  retrieving revision 1.143
  retrieving revision 1.144
  diff -b -d -u -r1.143 -r1.144
  --- mod_ssl.h	1 Jan 2004 13:26:21 -0000	1.143
  +++ mod_ssl.h	8 Jan 2004 16:26:53 -0000	1.144
  @@ -306,7 +306,8 @@
       SSL_SCMODE_UNSET = UNSET,
       SSL_SCMODE_NONE  = 0,
       SSL_SCMODE_DBM   = 1,
  -    SSL_SCMODE_SHMCB = 3
  +    SSL_SCMODE_SHMCB = 3,
  +    SSL_SCMODE_DC    = 4
   } ssl_scmode_t;
   
   /*
  @@ -602,7 +603,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  */
  
  
  
  1.85      +13 -0     httpd-2.0/modules/ssl/ssl_engine_config.c
  
  Index: ssl_engine_config.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_engine_config.c,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -b -d -u -r1.84 -r1.85
  --- ssl_engine_config.c	1 Jan 2004 13:26:21 -0000	1.84
  +++ ssl_engine_config.c	8 Jan 2004 16:26:53 -0000	1.85
  @@ -1051,6 +1051,19 @@
               }
           }
       }
  +    else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) {
  +#ifdef HAVE_DISTCACHE
  +        mc->nSessionCacheMode      = SSL_SCMODE_DC;
  +        mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3);
  +        if (!mc->szSessionCacheDataFile) {
  +            return apr_pstrcat(cmd->pool, 
  +                               "SSLSessionCache: Invalid cache file path: ",
  +                               arg+3, NULL);
  +        }
  +#else
  +        return "SSLSessionCache: distcache support disabled";
  +#endif
  +    }
       else {
           return "SSLSessionCache: Invalid argument";
       }
  
  
  
  1.19      +24 -0     httpd-2.0/modules/ssl/ssl_scache.c
  
  Index: ssl_scache.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/ssl/ssl_scache.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -b -d -u -r1.18 -r1.19
  --- ssl_scache.c	1 Jan 2004 13:26:21 -0000	1.18
  +++ ssl_scache.c	8 Jan 2004 16:26:53 -0000	1.19
  @@ -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);
  
  
  
  1.1                  httpd-2.0/modules/ssl/ssl_scache_dc.c
  
  Index: ssl_scache_dc.c
  ===================================================================
  /*                      _             _
  **  _ __ ___   ___   __| |    ___ ___| |  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);
      /* !@#$%^ - 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