📄 ssl_scache_dbm.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* _ _ * _ __ ___ ___ __| | ___ ___| | mod_ssl * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL * | | | | | | (_) | (_| | \__ \__ \ | * |_| |_| |_|\___/ \__,_|___|___/___/_| * |_____| * ssl_scache_dbm.c * Session Cache via DBM */#include "ssl_private.h"static void ssl_scache_dbm_expire(server_rec *s);void ssl_scache_dbm_init(server_rec *s, apr_pool_t *p){ SSLModConfigRec *mc = myModConfig(s); apr_dbm_t *dbm; apr_status_t rv; /* for the DBM we need the data file */ if (mc->szSessionCacheDataFile == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required"); ssl_die(); } /* open it once to create it and to make sure it _can_ be created */ ssl_mutex_on(s); if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot create SSLSessionCache DBM file `%s'", mc->szSessionCacheDataFile); ssl_mutex_off(s); return; } apr_dbm_close(dbm);#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) /* * 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, unixd_config.user_id, -1 /* no gid change */); if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL), unixd_config.user_id, -1) == -1) { if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), unixd_config.user_id, -1) == -1) chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL), unixd_config.user_id, -1); } if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL), unixd_config.user_id, -1) == -1) { if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), unixd_config.user_id, -1) == -1) chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL), unixd_config.user_id, -1); } }#endif ssl_mutex_off(s); ssl_scache_dbm_expire(s); return;}void ssl_scache_dbm_kill(server_rec *s){ SSLModConfigRec *mc = myModConfig(s); apr_pool_t *p; apr_pool_create_ex(&p, mc->pPool, NULL, NULL); if (p != NULL) { /* the correct way */ unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL)); unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL)); /* the additional ways to be sure */ unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL)); unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL)); unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL)); unlink(mc->szSessionCacheDataFile); apr_pool_destroy(p); } return;}BOOL ssl_scache_dbm_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess){ SSLModConfigRec *mc = myModConfig(s); apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; UCHAR ucaData[SSL_SESSION_MAX_DER]; int nData; UCHAR *ucp; apr_status_t rv; /* streamline session data */ if ((nData = i2d_SSL_SESSION(sess, NULL)) > sizeof(ucaData)) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "streamline session data size too large: %d > " "%" APR_SIZE_T_FMT, nData, sizeof(ucaData)); return FALSE; } ucp = ucaData; i2d_SSL_SESSION(sess, &ucp); /* be careful: do not try to store too much bytes in a DBM file! */#ifdef PAIRMAX if ((idlen + nData) >= PAIRMAX) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "data size too large for DBM session cache: %d >= %d", (idlen + nData), PAIRMAX); return FALSE; }#else if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "data size too large for DBM session cache: %d >= %d", (idlen + nData), 950); return FALSE; }#endif /* create DBM key */ dbmkey.dptr = (char *)id; dbmkey.dsize = idlen; /* create DBM value */ dbmval.dsize = sizeof(time_t) + nData; dbmval.dptr = (char *)malloc(dbmval.dsize); if (dbmval.dptr == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "malloc error creating DBM value"); return FALSE; } memcpy((char *)dbmval.dptr, &expiry, sizeof(time_t)); memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData); /* and store it to the DBM file */ ssl_mutex_on(s); if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot open SSLSessionCache DBM file `%s' for writing " "(store)", mc->szSessionCacheDataFile); ssl_mutex_off(s); free(dbmval.dptr); return FALSE; } if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, "Cannot store SSL session to DBM file `%s'", mc->szSessionCacheDataFile); apr_dbm_close(dbm); ssl_mutex_off(s); free(dbmval.dptr); return FALSE; } apr_dbm_close(dbm); ssl_mutex_off(s); /* free temporary buffers */ free(dbmval.dptr); /* allow the regular expiring to occur */ ssl_scache_dbm_expire(s); return TRUE;}SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *s, UCHAR *id, int idlen){ SSLModConfigRec *mc = myModConfig(s); apr_dbm_t *dbm; apr_datum_t dbmkey; apr_datum_t dbmval; SSL_SESSION *sess = NULL; MODSSL_D2I_SSL_SESSION_CONST unsigned char *ucpData; int nData; time_t expiry; time_t now; apr_status_t rc; /* allow the regular expiring to occur */ ssl_scache_dbm_expire(s); /* create DBM key and values */ dbmkey.dptr = (char *)id; dbmkey.dsize = idlen; /* and fetch it from the DBM file * XXX: Should we open the dbm against r->pool so the cleanup will * do the apr_dbm_close? This would make the code a bit cleaner. */ ssl_mutex_on(s); if ((rc = apr_dbm_open(&dbm, mc->szSessionCacheDataFile, APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "Cannot open SSLSessionCache DBM file `%s' for reading " "(fetch)", mc->szSessionCacheDataFile); ssl_mutex_off(s); return NULL; } rc = apr_dbm_fetch(dbm, dbmkey, &dbmval); if (rc != APR_SUCCESS) { apr_dbm_close(dbm); ssl_mutex_off(s); return NULL; } if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) { apr_dbm_close(dbm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -