842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * http://www.apache.org/licenses/LICENSE-2.0
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd */
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd/* _ _
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * _ __ ___ ___ __| | ___ ___| | mod_ssl
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * | | | | | | (_) | (_| | \__ \__ \ |
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * |_| |_| |_|\___/ \__,_|___|___/___/_|
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * |_____|
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * ssl_util.c
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Utility Functions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse */
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* ``Every day of my life
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse I am forced to add another
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse name to the list of people
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse who piss me off!''
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse -- Calvin */
e18e68b42830409bf48de0df9eed3fe363664aa7aaron
70535d6421eb979ac79d8f49d31cd94d75dd8b2fjorton#include "ssl_private.h"
8464a9c46b967001e38fe3c8afff51a649e9de51dougm#include "ap_mpm.h"
579fd9e90990eee18b5e504eb4c0d2ce18f76208aaron#include "apr_thread_mutex.h"
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/* _________________________________________________________________
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse**
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse** Utility Functions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse** _________________________________________________________________
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse*/
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rsechar *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse{
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse char *id;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse SSLSrvConfigRec *sc;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse char *host;
05413593151a238718198cc04ca849b2426be106rse apr_port_t port;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse host = s->server_hostname;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (s->port != 0)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse port = s->port;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse else {
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse sc = mySrvConfig(s);
434ad3e8e769a6a7a78c15f3ae2f7ae3adbfbb49wrowe if (sc->enabled == TRUE)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse port = DEFAULT_HTTPS_PORT;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse else
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse port = DEFAULT_HTTP_PORT;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse }
05413593151a238718198cc04ca849b2426be106rse id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return id;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse}
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
87a1c79b7b37702a254920ca5214fb282a4fb085dougmapr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
87a1c79b7b37702a254920ca5214fb282a4fb085dougm const char * const *argv)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse{
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse apr_procattr_t *procattr;
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse apr_proc_t *proc;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
e8f95a682820a599fe41b22977010636be5c2717jim if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return NULL;
e8f95a682820a599fe41b22977010636be5c2717jim if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse APR_FULL_BLOCK) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse return NULL;
e8f95a682820a599fe41b22977010636be5c2717jim if (apr_procattr_dir_set(procattr,
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse return NULL;
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse return NULL;
b03fb85d1fa331f36bdf6c8982be62129913d755sf proc = apr_pcalloc(p, sizeof(apr_proc_t));
87a1c79b7b37702a254920ca5214fb282a4fb085dougm if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse return NULL;
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse return proc->out;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse}
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rsevoid ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse{
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse apr_file_close(fp);
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse}
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/*
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Run a filter program and read the first line of its stdout output
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse */
87a1c79b7b37702a254920ca5214fb282a4fb085dougmchar *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
87a1c79b7b37702a254920ca5214fb282a4fb085dougm const char * const *argv)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse{
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse static char buf[MAX_STRING_LEN];
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse apr_file_t *fp;
87a1c79b7b37702a254920ca5214fb282a4fb085dougm apr_size_t nbytes = 1;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse char c;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse int k;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
87a1c79b7b37702a254920ca5214fb282a4fb085dougm if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return NULL;
87a1c79b7b37702a254920ca5214fb282a4fb085dougm /* XXX: we are reading 1 byte at a time here */
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) {
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (c == '\n' || c == '\r')
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse break;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse buf[k++] = c;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse }
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse buf[k] = NUL;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse ssl_util_ppclose(s, p, fp);
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return buf;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse}
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
03181bdde77be8e10ed297a02db5d8f98ecb703ewroweBOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse{
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse apr_finfo_t finfo;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (path == NULL)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return FALSE;
e8f95a682820a599fe41b22977010636be5c2717jim if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return FALSE;
ff763af21e893972ed8c0235cd28589811c9d2b2sf AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
ff763af21e893972ed8c0235cd28589811c9d2b2sf !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return FALSE;
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return FALSE;
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return FALSE;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse return TRUE;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse}
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse
a0e0d20b666cfc453ac76506079eb50e03997eefdougm/*
60998c490ad3334eb07ae63b23b479ac564dec94kbrand * certain key data needs to survive restarts,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * which are stored in the user data table of s->process->pool.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * to prevent "leaking" of this data, we use malloc/free
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * rather than apr_palloc and these wrappers to help make sure
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * we do not leak the malloc-ed data.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm */
a0e0d20b666cfc453ac76506079eb50e03997eefdougmunsigned char *ssl_asn1_table_set(apr_hash_t *table,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm long int length)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm{
a0e0d20b666cfc453ac76506079eb50e03997eefdougm apr_ssize_t klen = strlen(key);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm /*
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * if a value for this key already exists,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * reuse as much of the already malloc-ed data
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * as possible.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm if (asn1) {
a0e0d20b666cfc453ac76506079eb50e03997eefdougm if (asn1->nData != length) {
a0e0d20b666cfc453ac76506079eb50e03997eefdougm free(asn1->cpData); /* XXX: realloc? */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm asn1->cpData = NULL;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm else {
3a59bb90be3bc6246632384c3d885b875ae507d5sf asn1 = ap_malloc(sizeof(*asn1));
a0e0d20b666cfc453ac76506079eb50e03997eefdougm asn1->source_mtime = 0; /* used as a note for encrypted private keys */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm asn1->cpData = NULL;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm asn1->nData = length;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm if (!asn1->cpData) {
3a59bb90be3bc6246632384c3d885b875ae507d5sf asn1->cpData = ap_malloc(length);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm apr_hash_set(table, key, klen, asn1);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return asn1->cpData; /* caller will assign a value to this */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm}
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougmssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm{
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm}
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougmvoid ssl_asn1_table_unset(apr_hash_t *table,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm{
a0e0d20b666cfc453ac76506079eb50e03997eefdougm apr_ssize_t klen = strlen(key);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm if (!asn1) {
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return;
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm if (asn1->cpData) {
a0e0d20b666cfc453ac76506079eb50e03997eefdougm free(asn1->cpData);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm }
a0e0d20b666cfc453ac76506079eb50e03997eefdougm free(asn1);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
a0e0d20b666cfc453ac76506079eb50e03997eefdougm apr_hash_set(table, key, klen, NULL);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm}
a0e0d20b666cfc453ac76506079eb50e03997eefdougm
6a26d195dfba3a91f8352cabd4547afa77675bb1aaron#if APR_HAS_THREADS
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm/*
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm * To ensure thread-safetyness in OpenSSL - work in progress
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm */
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm
e18e68b42830409bf48de0df9eed3fe363664aa7aaronstatic apr_thread_mutex_t **lock_cs;
3c65aa88903de7330a07e133dfda779842fadad4wrowestatic int lock_num_locks;
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm
d54a31567fc49f1841d27a14796ae726016c54aadougmstatic void ssl_util_thr_lock(int mode, int type,
3c65aa88903de7330a07e133dfda779842fadad4wrowe const char *file, int line)
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm{
3c65aa88903de7330a07e133dfda779842fadad4wrowe if (type < lock_num_locks) {
3c65aa88903de7330a07e133dfda779842fadad4wrowe if (mode & CRYPTO_LOCK) {
3c65aa88903de7330a07e133dfda779842fadad4wrowe apr_thread_mutex_lock(lock_cs[type]);
3c65aa88903de7330a07e133dfda779842fadad4wrowe }
3c65aa88903de7330a07e133dfda779842fadad4wrowe else {
3c65aa88903de7330a07e133dfda779842fadad4wrowe apr_thread_mutex_unlock(lock_cs[type]);
3c65aa88903de7330a07e133dfda779842fadad4wrowe }
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm }
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm}
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme/* Dynamic lock structure */
8e09f1830f114c016598a3b76fd6d31e1589c012sctemmestruct CRYPTO_dynlock_value {
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme apr_pool_t *pool;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim const char* file;
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme int line;
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme apr_thread_mutex_t *mutex;
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme};
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme/* Global reference to the pool passed into ssl_util_thread_setup() */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemmeapr_pool_t *dynlockpool = NULL;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme/*
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic lock creation callback
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jimstatic struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme int line)
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme{
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme struct CRYPTO_dynlock_value *value;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_pool_t *p;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_status_t rv;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim /*
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * We need a pool to allocate our mutex. Since we can't clear
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * allocated memory from a pool, create a subpool that we can blow
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * away in the destruction callback.
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
b03fb85d1fa331f36bdf6c8982be62129913d755sf apr_pool_create(&p, dynlockpool);
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Creating dynamic lock");
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
b03fb85d1fa331f36bdf6c8982be62129913d755sf value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme value->pool = p;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Keep our own copy of the place from which we were created,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme using our own pool. */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme value->file = apr_pstrdup(p, file);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme value->line = line;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme p);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme if (rv != APR_SUCCESS) {
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Failed to create thread mutex for dynamic lock");
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_pool_destroy(p);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme return NULL;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme }
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme return value;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme}
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme/*
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic locking and unlocking function
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemmestatic void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme const char *file, int line)
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme{
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_status_t rv;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme if (mode & CRYPTO_LOCK) {
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Acquiring mutex %s:%d", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme rv = apr_thread_mutex_lock(l->mutex);
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Mutex %s:%d acquired!", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme }
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme else {
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Releasing mutex %s:%d", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme rv = apr_thread_mutex_unlock(l->mutex);
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Mutex %s:%d released!", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme }
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme}
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme/*
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic lock destruction callback
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jimstatic void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme const char *file, int line)
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme{
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_status_t rv;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
59bdac473e4f8e7b7aa2548947722c278289ed26sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Destroying dynamic lock %s:%d", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme rv = apr_thread_mutex_destroy(l->mutex);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme if (rv != APR_SUCCESS) {
9f2628baf370d9cf6197b7ca9358b0fb18bd1ce3sf ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
59bdac473e4f8e7b7aa2548947722c278289ed26sf APLOGNO(02192) "Failed to destroy mutex for dynamic "
59bdac473e4f8e7b7aa2548947722c278289ed26sf "lock %s:%d", l->file, l->line);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme }
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Trust that whomever owned the CRYPTO_dynlock_value we were
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * passed has no future use for it...
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme apr_pool_destroy(l->pool);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme}
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#if OPENSSL_VERSION_NUMBER >= 0x10000000L
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrhstatic void ssl_util_thr_id(CRYPTO_THREADID *id)
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh{
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh * id is a structure twice that big. Use the TCB pointer instead as a
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh * unique unsigned long.
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh */
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#ifdef __MVS__
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh struct PSA {
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh char unmapped[540];
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh unsigned long PSATOLD;
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh } *psaptr = 0;
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#else
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#endif
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh}
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#else
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh
dd9940ba9b4d9c09f034b910d1569db4a5111c75dougmstatic unsigned long ssl_util_thr_id(void)
e62985c7a1b46a5036a247f35bddac1308985758dougm{
e8f95a682820a599fe41b22977010636be5c2717jim /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
e8f95a682820a599fe41b22977010636be5c2717jim * id is a structure twice that big. Use the TCB pointer instead as a
98f81eac9530d487f05013cda9df99755bb59689trawick * unique unsigned long.
98f81eac9530d487f05013cda9df99755bb59689trawick */
98f81eac9530d487f05013cda9df99755bb59689trawick#ifdef __MVS__
98f81eac9530d487f05013cda9df99755bb59689trawick struct PSA {
98f81eac9530d487f05013cda9df99755bb59689trawick char unmapped[540];
98f81eac9530d487f05013cda9df99755bb59689trawick unsigned long PSATOLD;
98f81eac9530d487f05013cda9df99755bb59689trawick } *psaptr = 0;
98f81eac9530d487f05013cda9df99755bb59689trawick
98f81eac9530d487f05013cda9df99755bb59689trawick return psaptr->PSATOLD;
98f81eac9530d487f05013cda9df99755bb59689trawick#else
e62985c7a1b46a5036a247f35bddac1308985758dougm return (unsigned long) apr_os_thread_current();
98f81eac9530d487f05013cda9df99755bb59689trawick#endif
e62985c7a1b46a5036a247f35bddac1308985758dougm}
e62985c7a1b46a5036a247f35bddac1308985758dougm
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#endif
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh
8464a9c46b967001e38fe3c8afff51a649e9de51dougmstatic apr_status_t ssl_util_thread_cleanup(void *data)
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm{
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm CRYPTO_set_locking_callback(NULL);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#if OPENSSL_VERSION_NUMBER >= 0x10000000L
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh CRYPTO_THREADID_set_callback(NULL);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#else
462f3213ebe7eb2a3527530497d0428e2298a034jorton CRYPTO_set_id_callback(NULL);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#endif
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_create_callback(NULL);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_lock_callback(NULL);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_destroy_callback(NULL);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme dynlockpool = NULL;
8464a9c46b967001e38fe3c8afff51a649e9de51dougm
e8f95a682820a599fe41b22977010636be5c2717jim /* Let the registered mutex cleanups do their own thing
3c65aa88903de7330a07e133dfda779842fadad4wrowe */
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm return APR_SUCCESS;
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm}
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm
3c65aa88903de7330a07e133dfda779842fadad4wrowevoid ssl_util_thread_setup(apr_pool_t *p)
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm{
3c65aa88903de7330a07e133dfda779842fadad4wrowe int i;
8464a9c46b967001e38fe3c8afff51a649e9de51dougm
3c65aa88903de7330a07e133dfda779842fadad4wrowe lock_num_locks = CRYPTO_num_locks();
3c65aa88903de7330a07e133dfda779842fadad4wrowe lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));
8464a9c46b967001e38fe3c8afff51a649e9de51dougm
3c65aa88903de7330a07e133dfda779842fadad4wrowe for (i = 0; i < lock_num_locks; i++) {
e18e68b42830409bf48de0df9eed3fe363664aa7aaron apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm }
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#if OPENSSL_VERSION_NUMBER >= 0x10000000L
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh CRYPTO_THREADID_set_callback(ssl_util_thr_id);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#else
e62985c7a1b46a5036a247f35bddac1308985758dougm CRYPTO_set_id_callback(ssl_util_thr_id);
aafba4d7e3ecc7fcaa87efa8d7fae3e700d2428bdrh#endif
9e530d1e49062250c345bfd45810e145b4f435eddougm
e62985c7a1b46a5036a247f35bddac1308985758dougm CRYPTO_set_locking_callback(ssl_util_thr_lock);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Set up dynamic locking scaffolding for OpenSSL to use at its
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * convenience.
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme dynlockpool = p;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
8464a9c46b967001e38fe3c8afff51a649e9de51dougm
3c65aa88903de7330a07e133dfda779842fadad4wrowe apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
3c65aa88903de7330a07e133dfda779842fadad4wrowe apr_pool_cleanup_null);
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm}
6a26d195dfba3a91f8352cabd4547afa77675bb1aaron#endif