/* 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_util.c
 *  Utility Functions
 */
                             /* ``Every day of my life
                                  I am forced to add another
                                  name to the list of people
                                  who piss me off!''
                                            -- Calvin          */

#include "ssl_private.h"
#include "ap_mpm.h"
#include "apr_thread_mutex.h"

/*  _________________________________________________________________
**
**  Utility Functions
**  _________________________________________________________________
*/

char *ssl_util_vhostid(apr_pool_t *p, server_rec *s)
{
    SSLSrvConfigRec *sc;
    apr_port_t port;

    if (s->port != 0)
        port = s->port;
    else {
        sc = mySrvConfig(s);
        port = sc->enabled == TRUE ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
    }

    return apr_psprintf(p, "%s:%lu", s->server_hostname, (unsigned long)port);
}

/*
 * Return TRUE iff the given servername matches the server record when
 * selecting virtual hosts.
 */
BOOL ssl_util_vhost_matches(const char *servername, server_rec *s)
{
    apr_array_header_t *names;
    int i;
    
    /* check ServerName */
    if (!strcasecmp(servername, s->server_hostname)) {
        return TRUE;
    }
    
    /*
     * if not matched yet, check ServerAlias entries
     * (adapted from vhost.c:matches_aliases())
     */
    names = s->names;
    if (names) {
        char **name = (char **)names->elts;
        for (i = 0; i < names->nelts; ++i) {
            if (!name[i])
                continue;
            if (!strcasecmp(servername, name[i])) {
                return TRUE;
            }
        }
    }
    
    /* if still no match, check ServerAlias entries with wildcards */
    names = s->wild_names;
    if (names) {
        char **name = (char **)names->elts;
        for (i = 0; i < names->nelts; ++i) {
            if (!name[i])
                continue;
            if (!ap_strcasecmp_match(servername, name[i])) {
                return TRUE;
            }
        }
    }
    
    return FALSE;
}

int modssl_request_is_tls(const request_rec *r, SSLConnRec **scout)
{
    SSLConnRec *sslconn = myConnConfig(r->connection);
    SSLSrvConfigRec *sc = mySrvConfig(r->server);

    if (!(sslconn && sslconn->ssl) && r->connection->master) {
        sslconn = myConnConfig(r->connection->master);
    }

    if (sc->enabled == SSL_ENABLED_FALSE || !sslconn || !sslconn->ssl)
        return 0;
    
    if (scout) *scout = sslconn;

    return 1;
}

apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
                            const char * const *argv)
{
    apr_procattr_t *procattr;
    apr_proc_t *proc;

    if (apr_procattr_create(&procattr, p) != APR_SUCCESS)
        return NULL;
    if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
                            APR_FULL_BLOCK) != APR_SUCCESS)
        return NULL;
    if (apr_procattr_dir_set(procattr,
                             ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS)
        return NULL;
    if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
        return NULL;
    proc = apr_pcalloc(p, sizeof(apr_proc_t));
    if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
        return NULL;
    return proc->out;
}

void ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
{
    apr_file_close(fp);
    return;
}

/*
 * Run a filter program and read the first line of its stdout output
 */
char *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
                          const char * const *argv)
{
    static char buf[MAX_STRING_LEN];
    apr_file_t *fp;
    apr_size_t nbytes = 1;
    char c;
    int k;

    if ((fp = ssl_util_ppopen(s, p, cmd, argv)) == NULL)
        return NULL;
    /* XXX: we are reading 1 byte at a time here */
    for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
                && nbytes == 1 && (k < MAX_STRING_LEN-1)     ; ) {
        if (c == '\n' || c == '\r')
            break;
        buf[k++] = c;
    }
    buf[k] = NUL;
    ssl_util_ppclose(s, p, fp);

    return buf;
}

BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
{
    apr_finfo_t finfo;

    if (path == NULL)
        return FALSE;
    if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
                                APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
        return FALSE;
    AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
                    !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
    if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
        return FALSE;
    if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
        return FALSE;
    if (pcm & SSL_PCM_ISNONZERO && finfo.size <= 0)
        return FALSE;
    return TRUE;
}

/* Decrypted private keys are cached to survive restarts.  The cached
 * data must have lifetime of the process (hence malloc/free rather
 * than pools), and uses raw DER since the EVP_PKEY structure
 * internals may not survive across a module reload. */
ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
                               EVP_PKEY *pkey)
{
    apr_ssize_t klen = strlen(key);
    ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
    apr_size_t length = i2d_PrivateKey(pkey, NULL);
    unsigned char *p;

    /* Re-use structure if cached previously. */
    if (asn1) {
        if (asn1->nData != length) {
            asn1->cpData = ap_realloc(asn1->cpData, length);
        }
    }
    else {
        asn1 = ap_malloc(sizeof(*asn1));
        asn1->source_mtime = 0; /* used as a note for encrypted private keys */
        asn1->cpData = ap_malloc(length);

        apr_hash_set(table, key, klen, asn1);
    }

    asn1->nData = length;
    p = asn1->cpData;
    i2d_PrivateKey(pkey, &p); /* increases p by length */

    return asn1;
}

ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
                               const char *key)
{
    return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
}

#if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API

/*
 * To ensure thread-safetyness in OpenSSL - work in progress
 */

#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && \
        (_WIN32 || __BEOS__ || AP_OPENSSL_USE_ERRNO_THREADID)
/* Windows and BeOS can use the default THREADID callback shipped with OpenSSL
 * 1.0.x, as can any platform with a thread-safe errno. */
# define DEFAULT_THREADID_IS_SAFE 1
#endif

static apr_thread_mutex_t **lock_cs;
static int                  lock_num_locks;

static void ssl_util_thr_lock(int mode, int type,
                              const char *file, int line)
{
    if (type < lock_num_locks) {
        if (mode & CRYPTO_LOCK) {
            apr_thread_mutex_lock(lock_cs[type]);
        }
        else {
            apr_thread_mutex_unlock(lock_cs[type]);
        }
    }
}

/* Dynamic lock structure */
struct CRYPTO_dynlock_value {
    apr_pool_t *pool;
    const char* file;
    int line;
    apr_thread_mutex_t *mutex;
};

/* Global reference to the pool passed into ssl_util_thread_setup() */
apr_pool_t *dynlockpool = NULL;

/*
 * Dynamic lock creation callback
 */
static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
                                                     int line)
{
    struct CRYPTO_dynlock_value *value;
    apr_pool_t *p;
    apr_status_t rv;

    /*
     * We need a pool to allocate our mutex.  Since we can't clear
     * allocated memory from a pool, create a subpool that we can blow
     * away in the destruction callback.
     */
    apr_pool_create(&p, dynlockpool);
    apr_pool_tag(p, "modssl_dynlock_value");
    ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
                  "Creating dynamic lock");

    value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value));
    value->pool = p;
    /* Keep our own copy of the place from which we were created,
       using our own pool. */
    value->file = apr_pstrdup(p, file);
    value->line = line;
    rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
                                p);
    if (rv != APR_SUCCESS) {
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
                      "Failed to create thread mutex for dynamic lock");
        apr_pool_destroy(p);
        return NULL;
    }
    return value;
}

/*
 * Dynamic locking and unlocking function
 */

static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
                           const char *file, int line)
{
    apr_status_t rv;

    if (mode & CRYPTO_LOCK) {
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
                      "Acquiring mutex %s:%d", l->file, l->line);
        rv = apr_thread_mutex_lock(l->mutex);
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
                      "Mutex %s:%d acquired!", l->file, l->line);
    }
    else {
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
                      "Releasing mutex %s:%d", l->file, l->line);
        rv = apr_thread_mutex_unlock(l->mutex);
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
                      "Mutex %s:%d released!", l->file, l->line);
    }
}

/*
 * Dynamic lock destruction callback
 */
static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
                          const char *file, int line)
{
    apr_status_t rv;

    ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
                  "Destroying dynamic lock %s:%d", l->file, l->line);
    rv = apr_thread_mutex_destroy(l->mutex);
    if (rv != APR_SUCCESS) {
        ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
                      APLOGNO(02192) "Failed to destroy mutex for dynamic "
                      "lock %s:%d", l->file, l->line);
    }

    /* Trust that whomever owned the CRYPTO_dynlock_value we were
     * passed has no future use for it...
     */
    apr_pool_destroy(l->pool);
}

#if DEFAULT_THREADID_IS_SAFE

/* We don't need to set up a threadid callback on this platform. */
void ssl_util_thread_id_setup(apr_pool_t *p)
{
    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10027)
                  "using builtin threadid callback for OpenSSL");
}

#else

/**
 * Used by both versions of ssl_util_thr_id(). Returns an unsigned long that
 * should be unique to the currently executing thread.
 */
static unsigned long ssl_util_thr_id_internal(void)
{
    /* OpenSSL needs this to return an unsigned long.  On OS/390, the pthread
     * id is a structure twice that big.  Use the TCB pointer instead as a
     * unique unsigned long.
     */
#ifdef __MVS__
    struct PSA {
        char unmapped[540]; /* PSATOLD is at offset 540 in the PSA */
        unsigned long PSATOLD;
    } *psaptr = 0; /* PSA is at address 0 */

    return psaptr->PSATOLD;
#else
    return (unsigned long) apr_os_thread_current();
#endif
}

#if HAVE_CRYPTO_SET_ID_CALLBACK

static unsigned long ssl_util_thr_id(void)
{
    return ssl_util_thr_id_internal();
}

#else

static void ssl_util_thr_id(CRYPTO_THREADID *id)
{
    /* XXX Ideally we would be using the _set_pointer() callback on platforms
     * that have a pointer-based thread "identity". But this entire API is
     * fraught with problems (see PR60947) and has been removed completely in
     * OpenSSL 1.1.0, so I'm not too invested in fixing it right now. */
    CRYPTO_THREADID_set_numeric(id, ssl_util_thr_id_internal());
}

#endif /* HAVE_CRYPTO_SET_ID_CALLBACK */

static apr_status_t ssl_util_thr_id_cleanup(void *old)
{
#if HAVE_CRYPTO_SET_ID_CALLBACK
    CRYPTO_set_id_callback(old);
#else
    /* XXX This does nothing. The new-style THREADID callback is write-once. */
    CRYPTO_THREADID_set_callback(old);
#endif

    return APR_SUCCESS;
}

void ssl_util_thread_id_setup(apr_pool_t *p)
{
#if HAVE_CRYPTO_SET_ID_CALLBACK
    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10028)
                  "using deprecated CRYPTO_set_id_callback for OpenSSL");

    /* This API is deprecated, but we prefer it to its replacement since it
     * allows us to unset the callback when this module is being unloaded. */
    CRYPTO_set_id_callback(ssl_util_thr_id);
#else
    ap_log_perror(APLOG_MARK, APLOG_NOTICE, 0, p, APLOGNO(10029)
                  "using dangerous CRYPTO_THREADID_set_callback for OpenSSL");

    /* This is a last resort. We can only set this once, which means that we'd
     * better not get loaded into a different address during a restart. See
     * PR60947. */
    CRYPTO_THREADID_set_callback(ssl_util_thr_id);

    if (CRYPTO_THREADID_get_callback() != ssl_util_thr_id) {
        /* XXX Unfortunately this doesn't seem to get logged unless you're
         * running in one-process mode, due to PR60999. */
        ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, p, APLOGNO(10030)
            "OpenSSL's THREADID callback was already set to another address, "
            "and the server is probably going to crash. See bug #60947 for "
            "more details. You may need to recompile or upgrade either OpenSSL "
            "or httpd.");
    }
#endif

    apr_pool_cleanup_register(p, NULL, ssl_util_thr_id_cleanup,
                                       apr_pool_cleanup_null);
}

#endif /* DEFAULT_THREADID_IS_SAFE */

static apr_status_t ssl_util_thread_cleanup(void *data)
{
    CRYPTO_set_locking_callback(NULL);

    CRYPTO_set_dynlock_create_callback(NULL);
    CRYPTO_set_dynlock_lock_callback(NULL);
    CRYPTO_set_dynlock_destroy_callback(NULL);

    dynlockpool = NULL;

    /* Let the registered mutex cleanups do their own thing
     */
    return APR_SUCCESS;
}

void ssl_util_thread_setup(apr_pool_t *p)
{
    int i;

    lock_num_locks = CRYPTO_num_locks();
    lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));

    for (i = 0; i < lock_num_locks; i++) {
        apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
    }

    CRYPTO_set_locking_callback(ssl_util_thr_lock);

    /* Set up dynamic locking scaffolding for OpenSSL to use at its
     * convenience.
     */
    dynlockpool = p;
    CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
    CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
    CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);

    apr_pool_cleanup_register(p, NULL, ssl_util_thread_cleanup,
                                       apr_pool_cleanup_null);
}

#endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */

int modssl_is_engine_id(const char *name)
{
#if MODSSL_HAVE_ENGINE_API || MODSSL_HAVE_OPENSSL_STORE
    /* ### Can handle any other special ENGINE key names here? */
    return strncmp(name, "pkcs11:", 7) == 0;
#else
    return 0;
#endif
}
