|
Packit |
90a5c9 |
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
Packit |
90a5c9 |
* contributor license agreements. See the NOTICE file distributed with
|
|
Packit |
90a5c9 |
* this work for additional information regarding copyright ownership.
|
|
Packit |
90a5c9 |
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
Packit |
90a5c9 |
* (the "License"); you may not use this file except in compliance with
|
|
Packit |
90a5c9 |
* the License. You may obtain a copy of the License at
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
90a5c9 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
90a5c9 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
90a5c9 |
* See the License for the specific language governing permissions and
|
|
Packit |
90a5c9 |
* limitations under the License.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* _ _
|
|
Packit |
90a5c9 |
* _ __ ___ ___ __| | ___ ___| | mod_ssl
|
|
Packit |
90a5c9 |
* | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
|
|
Packit |
90a5c9 |
* | | | | | | (_) | (_| | \__ \__ \ |
|
|
Packit |
90a5c9 |
* |_| |_| |_|\___/ \__,_|___|___/___/_|
|
|
Packit |
90a5c9 |
* |_____|
|
|
Packit |
90a5c9 |
* ssl_util.c
|
|
Packit |
90a5c9 |
* Utility Functions
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
/* ``Every day of my life
|
|
Packit |
90a5c9 |
I am forced to add another
|
|
Packit |
90a5c9 |
name to the list of people
|
|
Packit |
90a5c9 |
who piss me off!''
|
|
Packit |
90a5c9 |
-- Calvin */
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#include "ssl_private.h"
|
|
Packit |
90a5c9 |
#include "ap_mpm.h"
|
|
Packit |
90a5c9 |
#include "apr_thread_mutex.h"
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* _________________________________________________________________
|
|
Packit |
90a5c9 |
**
|
|
Packit |
90a5c9 |
** Utility Functions
|
|
Packit |
90a5c9 |
** _________________________________________________________________
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
char *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
SSLSrvConfigRec *sc;
|
|
Packit |
90a5c9 |
apr_port_t port;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (s->port != 0)
|
|
Packit |
90a5c9 |
port = s->port;
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
sc = mySrvConfig(s);
|
|
Packit |
90a5c9 |
port = sc->enabled == TRUE ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return apr_psprintf(p, "%s:%lu", s->server_hostname, (unsigned long)port);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Return TRUE iff the given servername matches the server record when
|
|
Packit |
90a5c9 |
* selecting virtual hosts.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
BOOL ssl_util_vhost_matches(const char *servername, server_rec *s)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_array_header_t *names;
|
|
Packit |
90a5c9 |
int i;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* check ServerName */
|
|
Packit |
90a5c9 |
if (!strcasecmp(servername, s->server_hostname)) {
|
|
Packit |
90a5c9 |
return TRUE;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* if not matched yet, check ServerAlias entries
|
|
Packit |
90a5c9 |
* (adapted from vhost.c:matches_aliases())
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
names = s->names;
|
|
Packit |
90a5c9 |
if (names) {
|
|
Packit |
90a5c9 |
char **name = (char **)names->elts;
|
|
Packit |
90a5c9 |
for (i = 0; i < names->nelts; ++i) {
|
|
Packit |
90a5c9 |
if (!name[i])
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
if (!strcasecmp(servername, name[i])) {
|
|
Packit |
90a5c9 |
return TRUE;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* if still no match, check ServerAlias entries with wildcards */
|
|
Packit |
90a5c9 |
names = s->wild_names;
|
|
Packit |
90a5c9 |
if (names) {
|
|
Packit |
90a5c9 |
char **name = (char **)names->elts;
|
|
Packit |
90a5c9 |
for (i = 0; i < names->nelts; ++i) {
|
|
Packit |
90a5c9 |
if (!name[i])
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
if (!ap_strcasecmp_match(servername, name[i])) {
|
|
Packit |
90a5c9 |
return TRUE;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
|
|
Packit |
90a5c9 |
const char * const *argv)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_procattr_t *procattr;
|
|
Packit |
90a5c9 |
apr_proc_t *proc;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
|
|
Packit |
90a5c9 |
APR_FULL_BLOCK) != APR_SUCCESS)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
if (apr_procattr_dir_set(procattr,
|
|
Packit |
90a5c9 |
ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
proc = apr_pcalloc(p, sizeof(apr_proc_t));
|
|
Packit |
90a5c9 |
if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
return proc->out;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_file_close(fp);
|
|
Packit |
90a5c9 |
return;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Run a filter program and read the first line of its stdout output
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
|
|
Packit |
90a5c9 |
const char * const *argv)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
static char buf[MAX_STRING_LEN];
|
|
Packit |
90a5c9 |
apr_file_t *fp;
|
|
Packit |
90a5c9 |
apr_size_t nbytes = 1;
|
|
Packit |
90a5c9 |
char c;
|
|
Packit |
90a5c9 |
int k;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
/* XXX: we are reading 1 byte at a time here */
|
|
Packit |
90a5c9 |
for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
|
|
Packit |
90a5c9 |
&& nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) {
|
|
Packit |
90a5c9 |
if (c == '\n' || c == '\r')
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
buf[k++] = c;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
buf[k] = NUL;
|
|
Packit |
90a5c9 |
ssl_util_ppclose(s, p, fp);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return buf;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_finfo_t finfo;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (path == NULL)
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
|
|
Packit |
90a5c9 |
APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
|
|
Packit |
90a5c9 |
!(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
|
|
Packit |
90a5c9 |
if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
|
|
Packit |
90a5c9 |
return FALSE;
|
|
Packit |
90a5c9 |
return TRUE;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
70c855 |
/* Decrypted private keys are cached to survive restarts. The cached
|
|
Packit |
70c855 |
* data must have lifetime of the process (hence malloc/free rather
|
|
Packit |
70c855 |
* than pools), and uses raw DER since the EVP_PKEY structure
|
|
Packit |
70c855 |
* internals may not survive across a module reload. */
|
|
Packit |
70c855 |
ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
|
|
Packit |
70c855 |
EVP_PKEY *pkey)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_ssize_t klen = strlen(key);
|
|
Packit |
90a5c9 |
ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
|
|
Packit |
70c855 |
apr_size_t length = i2d_PrivateKey(pkey, NULL);
|
|
Packit |
70c855 |
unsigned char *p;
|
|
Packit |
90a5c9 |
|
|
Packit |
70c855 |
/* Re-use structure if cached previously. */
|
|
Packit |
90a5c9 |
if (asn1) {
|
|
Packit |
90a5c9 |
if (asn1->nData != length) {
|
|
Packit |
70c855 |
asn1->cpData = ap_realloc(asn1->cpData, length);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
asn1 = ap_malloc(sizeof(*asn1));
|
|
Packit |
90a5c9 |
asn1->source_mtime = 0; /* used as a note for encrypted private keys */
|
|
Packit |
90a5c9 |
asn1->cpData = ap_malloc(length);
|
|
Packit |
70c855 |
|
|
Packit |
70c855 |
apr_hash_set(table, key, klen, asn1);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
70c855 |
asn1->nData = length;
|
|
Packit |
70c855 |
p = asn1->cpData;
|
|
Packit |
70c855 |
i2d_PrivateKey(pkey, &p); /* increases p by length */
|
|
Packit |
90a5c9 |
|
|
Packit |
70c855 |
return asn1;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
|
|
Packit |
90a5c9 |
const char *key)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
void ssl_asn1_table_unset(apr_hash_t *table,
|
|
Packit |
90a5c9 |
const char *key)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_ssize_t klen = strlen(key);
|
|
Packit |
90a5c9 |
ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (!asn1) {
|
|
Packit |
90a5c9 |
return;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (asn1->cpData) {
|
|
Packit |
90a5c9 |
free(asn1->cpData);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
free(asn1);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
apr_hash_set(table, key, klen, NULL);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* To ensure thread-safetyness in OpenSSL - work in progress
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static apr_thread_mutex_t **lock_cs;
|
|
Packit |
90a5c9 |
static int lock_num_locks;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void ssl_util_thr_lock(int mode, int type,
|
|
Packit |
90a5c9 |
const char *file, int line)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
if (type < lock_num_locks) {
|
|
Packit |
90a5c9 |
if (mode & CRYPTO_LOCK) {
|
|
Packit |
90a5c9 |
apr_thread_mutex_lock(lock_cs[type]);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
apr_thread_mutex_unlock(lock_cs[type]);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Dynamic lock structure */
|
|
Packit |
90a5c9 |
struct CRYPTO_dynlock_value {
|
|
Packit |
90a5c9 |
apr_pool_t *pool;
|
|
Packit |
90a5c9 |
const char* file;
|
|
Packit |
90a5c9 |
int line;
|
|
Packit |
90a5c9 |
apr_thread_mutex_t *mutex;
|
|
Packit |
90a5c9 |
};
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Global reference to the pool passed into ssl_util_thread_setup() */
|
|
Packit |
90a5c9 |
apr_pool_t *dynlockpool = NULL;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Dynamic lock creation callback
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
|
|
Packit |
90a5c9 |
int line)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
struct CRYPTO_dynlock_value *value;
|
|
Packit |
90a5c9 |
apr_pool_t *p;
|
|
Packit |
90a5c9 |
apr_status_t rv;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* We need a pool to allocate our mutex. Since we can't clear
|
|
Packit |
90a5c9 |
* allocated memory from a pool, create a subpool that we can blow
|
|
Packit |
90a5c9 |
* away in the destruction callback.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
apr_pool_create(&p, dynlockpool);
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
|
|
Packit |
90a5c9 |
"Creating dynamic lock");
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
|
|
Packit |
90a5c9 |
value->pool = p;
|
|
Packit |
90a5c9 |
/* Keep our own copy of the place from which we were created,
|
|
Packit |
90a5c9 |
using our own pool. */
|
|
Packit |
90a5c9 |
value->file = apr_pstrdup(p, file);
|
|
Packit |
90a5c9 |
value->line = line;
|
|
Packit |
90a5c9 |
rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
|
|
Packit |
90a5c9 |
p);
|
|
Packit |
90a5c9 |
if (rv != APR_SUCCESS) {
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
|
|
Packit |
90a5c9 |
"Failed to create thread mutex for dynamic lock");
|
|
Packit |
90a5c9 |
apr_pool_destroy(p);
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
return value;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Dynamic locking and unlocking function
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
|
|
Packit |
90a5c9 |
const char *file, int line)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_status_t rv;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (mode & CRYPTO_LOCK) {
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
|
|
Packit |
90a5c9 |
"Acquiring mutex %s:%d", l->file, l->line);
|
|
Packit |
90a5c9 |
rv = apr_thread_mutex_lock(l->mutex);
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
|
|
Packit |
90a5c9 |
"Mutex %s:%d acquired!", l->file, l->line);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else {
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
|
|
Packit |
90a5c9 |
"Releasing mutex %s:%d", l->file, l->line);
|
|
Packit |
90a5c9 |
rv = apr_thread_mutex_unlock(l->mutex);
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
|
|
Packit |
90a5c9 |
"Mutex %s:%d released!", l->file, l->line);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Dynamic lock destruction callback
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
|
|
Packit |
90a5c9 |
const char *file, int line)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
apr_status_t rv;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
|
|
Packit |
90a5c9 |
"Destroying dynamic lock %s:%d", l->file, l->line);
|
|
Packit |
90a5c9 |
rv = apr_thread_mutex_destroy(l->mutex);
|
|
Packit |
90a5c9 |
if (rv != APR_SUCCESS) {
|
|
Packit |
90a5c9 |
ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
|
|
Packit |
90a5c9 |
APLOGNO(02192) "Failed to destroy mutex for dynamic "
|
|
Packit |
90a5c9 |
"lock %s:%d", l->file, l->line);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Trust that whomever owned the CRYPTO_dynlock_value we were
|
|
Packit |
90a5c9 |
* passed has no future use for it...
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
apr_pool_destroy(l->pool);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void ssl_util_thr_id(CRYPTO_THREADID *id)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
/* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
|
|
Packit |
90a5c9 |
* id is a structure twice that big. Use the TCB pointer instead as a
|
|
Packit |
90a5c9 |
* unique unsigned long.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
#ifdef __MVS__
|
|
Packit |
90a5c9 |
struct PSA {
|
|
Packit |
90a5c9 |
char unmapped[540]; /* PSATOLD is at offset 540 in the PSA */
|
|
Packit |
90a5c9 |
unsigned long PSATOLD;
|
|
Packit |
90a5c9 |
} *psaptr = 0; /* PSA is at address 0 */
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
CRYPTO_THREADID_set_numeric(id, psaptr->PSATOLD);
|
|
Packit |
90a5c9 |
#else
|
|
Packit |
90a5c9 |
CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
|
|
Packit |
90a5c9 |
#endif
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static apr_status_t ssl_util_thr_id_cleanup(void *old)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
CRYPTO_THREADID_set_callback(old);
|
|
Packit |
90a5c9 |
return APR_SUCCESS;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#else
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static unsigned long ssl_util_thr_id(void)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
/* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
|
|
Packit |
90a5c9 |
* id is a structure twice that big. Use the TCB pointer instead as a
|
|
Packit |
90a5c9 |
* unique unsigned long.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
#ifdef __MVS__
|
|
Packit |
90a5c9 |
struct PSA {
|
|
Packit |
90a5c9 |
char unmapped[540];
|
|
Packit |
90a5c9 |
unsigned long PSATOLD;
|
|
Packit |
90a5c9 |
} *psaptr = 0;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return psaptr->PSATOLD;
|
|
Packit |
90a5c9 |
#else
|
|
Packit |
90a5c9 |
return (unsigned long) apr_os_thread_current();
|
|
Packit |
90a5c9 |
#endif
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static apr_status_t ssl_util_thr_id_cleanup(void *old)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
CRYPTO_set_id_callback(old);
|
|
Packit |
90a5c9 |
return APR_SUCCESS;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#endif
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static apr_status_t ssl_util_thread_cleanup(void *data)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
CRYPTO_set_locking_callback(NULL);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_create_callback(NULL);
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_lock_callback(NULL);
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_destroy_callback(NULL);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
dynlockpool = NULL;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Let the registered mutex cleanups do their own thing
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
return APR_SUCCESS;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
void ssl_util_thread_setup(apr_pool_t *p)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
int i;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
lock_num_locks = CRYPTO_num_locks();
|
|
Packit |
90a5c9 |
lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
for (i = 0; i < lock_num_locks; i++) {
|
|
Packit |
90a5c9 |
apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
CRYPTO_set_locking_callback(ssl_util_thr_lock);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Set up dynamic locking scaffolding for OpenSSL to use at its
|
|
Packit |
90a5c9 |
* convenience.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
dynlockpool = p;
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
|
|
Packit |
90a5c9 |
CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
|
|
Packit |
90a5c9 |
apr_pool_cleanup_null);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
void ssl_util_thread_id_setup(apr_pool_t *p)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
|
Packit |
90a5c9 |
CRYPTO_THREADID_set_callback(ssl_util_thr_id);
|
|
Packit |
90a5c9 |
#else
|
|
Packit |
90a5c9 |
CRYPTO_set_id_callback(ssl_util_thr_id);
|
|
Packit |
90a5c9 |
#endif
|
|
Packit |
90a5c9 |
apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
|
|
Packit |
90a5c9 |
apr_pool_cleanup_null);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
|
|
Packit |
70c855 |
|
|
Packit |
70c855 |
int modssl_is_engine_id(const char *name)
|
|
Packit |
70c855 |
{
|
|
Packit |
70c855 |
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
|
|
Packit |
70c855 |
/* ### Can handle any other special ENGINE key names here? */
|
|
Packit |
70c855 |
return strncmp(name, "pkcs11:", 7) == 0;
|
|
Packit |
70c855 |
#else
|
|
Packit |
70c855 |
return 0;
|
|
Packit |
70c855 |
#endif
|
|
Packit |
70c855 |
}
|