⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_engine_scache.c

📁 apach加密模块
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                      _             _**  _ __ ___   ___   __| |    ___ ___| |  mod_ssl** | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL** | | | | | | (_) | (_| |   \__ \__ \ |  www.modssl.org** |_| |_| |_|\___/ \__,_|___|___/___/_|  ftp.modssl.org**                      |_____|**  ssl_engine_scache.c**  Session Cache*//* ==================================================================== * Copyright (c) 1998-2000 Ralf S. Engelschall. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following *    disclaimer in the documentation and/or other materials *    provided with the distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by *     Ralf S. Engelschall <rse@engelschall.com> for use in the *     mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote *    products derived from this software without prior written *    permission. For written permission, please contact *    rse@engelschall.com. * * 5. Products derived from this software may not be called "mod_ssl" *    nor may "mod_ssl" appear in their names without prior *    written permission of Ralf S. Engelschall. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by *     Ralf S. Engelschall <rse@engelschall.com> for use in the *     mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``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. * ==================================================================== */                             /* ``Open-Source Software: generous                                  programmers from around the world all                                  join forces to help you shoot                                  yourself in the foot for free.''                                                 -- Unknown         */#include "mod_ssl.h"/*  _________________________________________________________________****  Session Cache Support (Common)**  _________________________________________________________________*//* *  FIXME: There is no define in OpenSSL, but OpenSSL uses 1024*10, *  so 1024*20 should be ok. */#define MAX_SESSION_DER 1024*20void ssl_scache_init(server_rec *s, pool *p){    SSLModConfigRec *mc = myModConfig();    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_init(s, p);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_init(s, p);    ssl_scache_expire(s, time(NULL));#ifdef SSL_VENDOR    ap_hook_use("ap::mod_ssl::vendor::scache_init",                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, p);#endif    return;}void ssl_scache_kill(server_rec *s){    SSLModConfigRec *mc = myModConfig();    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_kill(s);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_kill(s);#ifdef SSL_VENDOR    ap_hook_use("ap::mod_ssl::vendor::scache_kill",                AP_HOOK_SIG1(void), AP_HOOK_ALL);#endif    return;}BOOL ssl_scache_store(server_rec *s, SSL_SESSION *pSession, int timeout){    SSLModConfigRec *mc = myModConfig();    ssl_scinfo_t SCI;    UCHAR buf[MAX_SESSION_DER];    UCHAR *b;    BOOL rc = FALSE;    /* add the key */    SCI.ucaKey = pSession->session_id;    SCI.nKey   = pSession->session_id_length;    /* transform the session into a data stream */    SCI.ucaData    = b = buf;    SCI.nData      = i2d_SSL_SESSION(pSession, &b);    SCI.tExpiresAt = timeout;    /* and store it... */    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        rc = ssl_scache_dbm_store(s, &SCI);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        rc = ssl_scache_shm_store(s, &SCI);#ifdef SSL_VENDOR    ap_hook_use("ap::mod_ssl::vendor::scache_store",                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI);#endif        /* allow the regular expiring to occur */    ssl_scache_expire(s, time(NULL));    return rc;}SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen){    SSLModConfigRec *mc = myModConfig();    SSL_SESSION *pSession = NULL;    ssl_scinfo_t SCI;    time_t tNow;    /* determine current time */    tNow = time(NULL);    /* allow the regular expiring to occur */    ssl_scache_expire(s, tNow);    /* create cache query */    SCI.ucaKey     = id;    SCI.nKey       = idlen;    SCI.ucaData    = NULL;    SCI.nData      = 0;    SCI.tExpiresAt = 0;    /* perform cache query */    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_retrieve(s, &SCI);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_retrieve(s, &SCI);#ifdef SSL_VENDOR    ap_hook_use("ap::mod_ssl::vendor::scache_retrieve",                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI);#endif    /* return immediately if not found */    if (SCI.ucaData == NULL)        return NULL;    /* check for expire time */    if (SCI.tExpiresAt <= tNow) {        if (mc->nSessionCacheMode == SSL_SCMODE_DBM)            ssl_scache_dbm_remove(s, &SCI);        else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)            ssl_scache_shm_remove(s, &SCI);#ifdef SSL_VENDOR        ap_hook_use("ap::mod_ssl::vendor::scache_remove",                    AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI);#endif        return NULL;    }    /* extract result and return it */    pSession = d2i_SSL_SESSION(NULL, &SCI.ucaData, SCI.nData);    return pSession;}void ssl_scache_remove(server_rec *s, SSL_SESSION *pSession){    SSLModConfigRec *mc = myModConfig();    ssl_scinfo_t SCI;    /* create cache query */    SCI.ucaKey     = pSession->session_id;    SCI.nKey       = pSession->session_id_length;    SCI.ucaData    = NULL;    SCI.nData      = 0;    SCI.tExpiresAt = 0;    /* perform remove */    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_remove(s, &SCI);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_remove(s, &SCI);#ifdef SSL_VENDOR    ap_hook_use("ap::mod_ssl::vendor::scache_remove",                AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI);#endif    return;}void ssl_scache_expire(server_rec *s, time_t now){    SSLModConfigRec *mc = myModConfig();    SSLSrvConfigRec *sc = mySrvConfig(s);    static time_t last = 0;    /*     * make sure the expiration for still not-accessed session     * cache entries is done only from time to time     */    if (now < last+sc->nSessionCacheTimeout)        return;    last = now;    /*     * Now perform the expiration      */    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_expire(s, now);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_expire(s, now);    return;}void ssl_scache_status(server_rec *s, pool *p, void (*func)(char *, void *), void *arg){    SSLModConfigRec *mc = myModConfig();    /* allow the regular expiring to occur */    ssl_scache_expire(s, time(NULL));    if (mc->nSessionCacheMode == SSL_SCMODE_DBM)        ssl_scache_dbm_status(s, p, func, arg);    else if (mc->nSessionCacheMode == SSL_SCMODE_SHM)        ssl_scache_shm_status(s, p, func, arg);    else        func("N.A.", arg);    return;}char *ssl_scache_id2sz(UCHAR *id, int idlen){    static char str[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2];    char *cp;    int n;    cp = str;    for (n = 0; n < idlen && n < SSL_MAX_SSL_SESSION_ID_LENGTH; n++) {        ap_snprintf(cp, sizeof(str)-(cp-str), "%02X", id[n]);        cp += 2;    }    *cp = NUL;    return str;}/*  _________________________________________________________________****  Session Cache Support (DBM)**  _________________________________________________________________*/void ssl_scache_dbm_init(server_rec *s, pool *p){    SSLModConfigRec *mc = myModConfig();    DBM *dbm;    /*     * for the DBM we need the data file     */    if (mc->szSessionCacheDataFile == NULL) {        ssl_log(s, SSL_LOG_ERROR, "SSLSessionCache required");        ssl_die();    }    /*     * Open it once to create it and to make sure it     * _can_ be created.     */    ssl_mutex_on(s);    if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,                            O_RDWR|O_CREAT, SSL_DBM_FILE_MODE)) == NULL) {        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,                "Cannot create SSLSessionCache DBM file `%s'",                mc->szSessionCacheDataFile);        ssl_mutex_off(s);        return;    }    ssl_dbm_close(dbm);#if !defined(OS2) && !defined(WIN32)    /*     * We have to make sure the Apache child processes     * have access to the DBM file. But because there     * are brain-dead platforms where we cannot exactly     * determine the suffixes we try all possibilities.     */    if (geteuid() == 0 /* is superuser */) {        chown(mc->szSessionCacheDataFile, ap_user_id, -1 /* no gid change */);        if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL),                  ap_user_id, -1) == -1) {            if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL),                      ap_user_id, -1) == -1)                chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL),                      ap_user_id, -1);        }        if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL),                  ap_user_id, -1) == -1) {            if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL),                      ap_user_id, -1) == -1)                chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL),                      ap_user_id, -1);        }    }#endif    ssl_mutex_off(s);    return;}void ssl_scache_dbm_kill(server_rec *s){    SSLModConfigRec *mc = myModConfig();    pool *p;    if ((p = ap_make_sub_pool(NULL)) != NULL) {        /* the correct way */        unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL));        unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL));        /* the additional ways to be sure */        unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL));        unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL));        unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL));        unlink(mc->szSessionCacheDataFile);        ap_destroy_pool(p);    }    return;}BOOL ssl_scache_dbm_store(server_rec *s, ssl_scinfo_t *SCI){    SSLModConfigRec *mc = myModConfig();    DBM *dbm;    datum dbmkey;    datum dbmval;    /* be careful: do not try to store too much bytes in a DBM file! */#ifdef SSL_USE_SDBM    if ((SCI->nKey + SCI->nData) >= PAIRMAX)        return FALSE;#else    if ((SCI->nKey + SCI->nData) >= 950 /* at least less than approx. 1KB */)        return FALSE;#endif    /* create DBM key */    dbmkey.dptr  = (char *)(SCI->ucaKey);    dbmkey.dsize = SCI->nKey;    /* create DBM value */    dbmval.dsize = sizeof(time_t) + SCI->nData;    dbmval.dptr  = (char *)malloc(dbmval.dsize);    if (dbmval.dptr == NULL)        return FALSE;    memcpy((char *)dbmval.dptr, &SCI->tExpiresAt, sizeof(time_t));    memcpy((char *)dbmval.dptr+sizeof(time_t), SCI->ucaData, SCI->nData);    /* and store it to the DBM file */    ssl_mutex_on(s);    if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,                            O_RDWR, SSL_DBM_FILE_MODE)) == NULL) {        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,                "Cannot open SSLSessionCache DBM file `%s' for writing (store)",                mc->szSessionCacheDataFile);        ssl_mutex_off(s);        free(dbmval.dptr);        return FALSE;    }    if (ssl_dbm_store(dbm, dbmkey, dbmval, DBM_INSERT) < 0) {        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,                "Cannot store SSL session to DBM file `%s'",                mc->szSessionCacheDataFile);        ssl_dbm_close(dbm);        ssl_mutex_off(s);        free(dbmval.dptr);        return FALSE;    }    ssl_dbm_close(dbm);    ssl_mutex_off(s);    /* free temporary buffers */    free(dbmval.dptr);    return TRUE;}void ssl_scache_dbm_retrieve(server_rec *s, ssl_scinfo_t *SCI){    SSLModConfigRec *mc = myModConfig();    DBM *dbm;    datum dbmkey;    datum dbmval;    /* initialize result */    SCI->ucaData    = NULL;    SCI->nData      = 0;    SCI->tExpiresAt = 0;    /* create DBM key and values */    dbmkey.dptr  = (char *)(SCI->ucaKey);    dbmkey.dsize = SCI->nKey;    /* and fetch it from the DBM file */    ssl_mutex_on(s);    if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile,                            O_RDONLY, SSL_DBM_FILE_MODE)) == NULL) {        ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO,                "Cannot open SSLSessionCache DBM file `%s' for reading (fetch)",                mc->szSessionCacheDataFile);        ssl_mutex_off(s);        return;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -