/* 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.
 */

#include "mod_session.h"
#include "apu_version.h"
#include "apr_base64.h"                /* for apr_base64_decode et al */
#include "apr_lib.h"
#include "apr_md5.h"
#include "apr_strings.h"
#include "http_log.h"
#include "http_core.h"

#if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4

#error session_crypto_module requires APU v1.4.0 or later

#elif APU_HAVE_CRYPTO == 0

#error Crypto support must be enabled in APR

#else

#include "apr_crypto.h"                /* for apr_*_crypt et al */

#define CRYPTO_KEY "session_crypto_context"

module AP_MODULE_DECLARE_DATA session_crypto_module;

/**
 * Structure to carry the per-dir session config.
 */
typedef struct {
    apr_array_header_t *passphrases;
    int passphrases_set;
    const char *cipher;
    int cipher_set;
} session_crypto_dir_conf;

/**
 * Structure to carry the server wide session config.
 */
typedef struct {
    const char *library;
    const char *params;
    int library_set;
} session_crypto_conf;

/* Wrappers around apr_siphash24() and apr_crypto_equals(),
 * available in APU-1.6/APR-2.0 only.
 */
#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)

#include "apr_siphash.h"

#define AP_SIPHASH_DSIZE    APR_SIPHASH_DSIZE
#define AP_SIPHASH_KSIZE    APR_SIPHASH_KSIZE
#define ap_siphash24_auth   apr_siphash24_auth

#define ap_crypto_equals    apr_crypto_equals

#else

#define AP_SIPHASH_DSIZE    8
#define AP_SIPHASH_KSIZE    16

#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))

#define U8TO64_LE(p) \
    (((apr_uint64_t)((p)[0])      ) | \
     ((apr_uint64_t)((p)[1]) <<  8) | \
     ((apr_uint64_t)((p)[2]) << 16) | \
     ((apr_uint64_t)((p)[3]) << 24) | \
     ((apr_uint64_t)((p)[4]) << 32) | \
     ((apr_uint64_t)((p)[5]) << 40) | \
     ((apr_uint64_t)((p)[6]) << 48) | \
     ((apr_uint64_t)((p)[7]) << 56))

#define U64TO8_LE(p, v) \
do { \
    (p)[0] = (unsigned char)((v)      ); \
    (p)[1] = (unsigned char)((v) >>  8); \
    (p)[2] = (unsigned char)((v) >> 16); \
    (p)[3] = (unsigned char)((v) >> 24); \
    (p)[4] = (unsigned char)((v) >> 32); \
    (p)[5] = (unsigned char)((v) >> 40); \
    (p)[6] = (unsigned char)((v) >> 48); \
    (p)[7] = (unsigned char)((v) >> 56); \
} while (0)

#define SIPROUND() \
do { \
    v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
    v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
    v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
    v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
} while(0)

static apr_uint64_t ap_siphash24(const void *src, apr_size_t len,
                                 const unsigned char key[AP_SIPHASH_KSIZE])
{
    const unsigned char *ptr, *end;
    apr_uint64_t v0, v1, v2, v3, m;
    apr_uint64_t k0, k1;
    unsigned int rem;

    k0 = U8TO64_LE(key + 0);
    k1 = U8TO64_LE(key + 8);
    v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL;
    v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL;
    v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL;
    v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL;

    rem = (unsigned int)(len & 0x7);
    for (ptr = src, end = ptr + len - rem; ptr < end; ptr += 8) {
        m = U8TO64_LE(ptr);
        v3 ^= m;
        SIPROUND();
        SIPROUND();
        v0 ^= m;
    }
    m = (apr_uint64_t)(len & 0xff) << 56;
    switch (rem) {
        case 7: m |= (apr_uint64_t)ptr[6] << 48;
        case 6: m |= (apr_uint64_t)ptr[5] << 40;
        case 5: m |= (apr_uint64_t)ptr[4] << 32;
        case 4: m |= (apr_uint64_t)ptr[3] << 24;
        case 3: m |= (apr_uint64_t)ptr[2] << 16;
        case 2: m |= (apr_uint64_t)ptr[1] << 8;
        case 1: m |= (apr_uint64_t)ptr[0];
        case 0: break;
    }
    v3 ^= m;
    SIPROUND();
    SIPROUND();
    v0 ^= m;

    v2 ^= 0xff;
    SIPROUND();
    SIPROUND();
    SIPROUND();
    SIPROUND();

    return v0 ^ v1 ^ v2 ^ v3;
}

static void ap_siphash24_auth(unsigned char out[AP_SIPHASH_DSIZE],
                              const void *src, apr_size_t len,
                              const unsigned char key[AP_SIPHASH_KSIZE])
{
    apr_uint64_t h;
    h = ap_siphash24(src, len, key);
    U64TO8_LE(out, h);
}

static int ap_crypto_equals(const void *buf1, const void *buf2,
                            apr_size_t size)
{
    const unsigned char *p1 = buf1;
    const unsigned char *p2 = buf2;
    unsigned char diff = 0;
    apr_size_t i;

    for (i = 0; i < size; ++i) {
        diff |= p1[i] ^ p2[i];
    }

    return 1 & ((diff - 1) >> 8);
}

#endif

static void compute_auth(const void *src, apr_size_t len,
                         const char *passphrase, apr_size_t passlen,
                         unsigned char auth[AP_SIPHASH_DSIZE])
{
    unsigned char key[APR_MD5_DIGESTSIZE];

    /* XXX: if we had a way to get the raw bytes from an apr_crypto_key_t
     *      we could use them directly (not available in APR-1.5.x).
     * MD5 is 128bit too, so use it to get a suitable siphash key
     * from the passphrase.
     */
    apr_md5(key, passphrase, passlen);

    ap_siphash24_auth(auth, src, len, key);
}

/**
 * Initialise the encryption as per the current config.
 *
 * Returns APR_SUCCESS if successful.
 */
static apr_status_t crypt_init(request_rec *r,
        const apr_crypto_t *f, apr_crypto_block_key_type_e **cipher,
        session_crypto_dir_conf * dconf)
{
    apr_status_t res;
    apr_hash_t *ciphers;

    res = apr_crypto_get_block_key_types(&ciphers, f);
    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01823)
                "no ciphers returned by APR. "
                "session encryption not possible");
        return res;
    }

    *cipher = apr_hash_get(ciphers, dconf->cipher, APR_HASH_KEY_STRING);
    if (!(*cipher)) {
        apr_hash_index_t *hi;
        const void *key;
        apr_ssize_t klen;
        int sum = 0;
        int offset = 0;
        char *options = NULL;

        for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
            apr_hash_this(hi, NULL, &klen, NULL);
            sum += klen + 2;
        }
        for (hi = apr_hash_first(r->pool, ciphers); hi; hi = apr_hash_next(hi)) {
            apr_hash_this(hi, &key, &klen, NULL);
            if (!options) {
                options = apr_palloc(r->pool, sum + 1);
            }
            else {
                options[offset++] = ',';
                options[offset++] = ' ';
            }
            strncpy(options + offset, key, klen);
            offset += klen;
        }
        options[offset] = 0;

        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01824)
                "cipher '%s' not recognised by crypto driver. "
                "session encryption not possible, options: %s", dconf->cipher, options);

        return APR_EGENERAL;
    }

    return APR_SUCCESS;
}

/**
 * Encrypt the string given as per the current config.
 *
 * Returns APR_SUCCESS if successful.
 */
static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f,
        session_crypto_dir_conf *dconf, const char *in, char **out)
{
    apr_status_t res;
    apr_crypto_key_t *key = NULL;
    apr_size_t ivSize = 0;
    apr_crypto_block_t *block = NULL;
    unsigned char *encrypt = NULL;
    unsigned char *combined = NULL;
    apr_size_t encryptlen, tlen, combinedlen;
    char *base64;
    apr_size_t blockSize = 0;
    const unsigned char *iv = NULL;
    apr_uuid_t salt;
    apr_crypto_block_key_type_e *cipher;
    const char *passphrase;
    apr_size_t passlen;

    /* use a uuid as a salt value, and prepend it to our result */
    apr_uuid_get(&salt);
    res = crypt_init(r, f, &cipher, dconf);
    if (res != APR_SUCCESS) {
        return res;
    }

    /* encrypt using the first passphrase in the list */
    passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, const char *);
    passlen = strlen(passphrase);
    res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
            (unsigned char *) (&salt), sizeof(apr_uuid_t),
            *cipher, APR_MODE_CBC, 1, 4096, f, r->pool);
    if (APR_STATUS_IS_ENOKEY(res)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01825)
                "failure generating key from passphrase");
    }
    if (APR_STATUS_IS_EPADDING(res)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01826)
                "padding is not supported for cipher");
    }
    if (APR_STATUS_IS_EKEYTYPE(res)) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01827)
                "the key type is not known");
    }
    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01828)
                "encryption could not be configured.");
        return res;
    }

    res = apr_crypto_block_encrypt_init(&block, &iv, key, &blockSize, r->pool);
    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01829)
                "apr_crypto_block_encrypt_init failed");
        return res;
    }

    /* encrypt the given string */
    res = apr_crypto_block_encrypt(&encrypt, &encryptlen,
                                   (const unsigned char *)in, strlen(in),
                                   block);
    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01830)
                "apr_crypto_block_encrypt failed");
        return res;
    }
    res = apr_crypto_block_encrypt_finish(encrypt + encryptlen, &tlen, block);
    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01831)
                "apr_crypto_block_encrypt_finish failed");
        return res;
    }
    encryptlen += tlen;

    /* prepend the salt and the iv to the result (keep room for the MAC) */
    combinedlen = AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize + encryptlen;
    combined = apr_palloc(r->pool, combinedlen);
    memcpy(combined + AP_SIPHASH_DSIZE, &salt, sizeof(apr_uuid_t));
    memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t), iv, ivSize);
    memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize,
           encrypt, encryptlen);
    /* authenticate the whole salt+IV+ciphertext with a leading MAC */
    compute_auth(combined + AP_SIPHASH_DSIZE, combinedlen - AP_SIPHASH_DSIZE,
                 passphrase, passlen, combined);

    /* base64 encode the result (APR handles the trailing '\0') */
    base64 = apr_palloc(r->pool, apr_base64_encode_len(combinedlen));
    apr_base64_encode(base64, (const char *) combined, combinedlen);
    *out = base64;

    return res;

}

/**
 * Decrypt the string given as per the current config.
 *
 * Returns APR_SUCCESS if successful.
 */
static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f,
        session_crypto_dir_conf *dconf, const char *in, char **out)
{
    apr_status_t res;
    apr_crypto_key_t *key = NULL;
    apr_size_t ivSize = 0;
    apr_crypto_block_t *block = NULL;
    unsigned char *decrypted = NULL;
    apr_size_t decryptedlen, tlen;
    apr_size_t decodedlen;
    char *decoded;
    apr_size_t blockSize = 0;
    apr_crypto_block_key_type_e *cipher;
    unsigned char auth[AP_SIPHASH_DSIZE];
    int i = 0;

    /* strip base64 from the string */
    decoded = apr_palloc(r->pool, apr_base64_decode_len(in));
    decodedlen = apr_base64_decode(decoded, in);
    decoded[decodedlen] = '\0';

    /* sanity check - decoded too short? */
    if (decodedlen < (AP_SIPHASH_DSIZE + sizeof(apr_uuid_t))) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(10005)
                "too short to decrypt, aborting");
        return APR_ECRYPT;
    }

    res = crypt_init(r, f, &cipher, dconf);
    if (res != APR_SUCCESS) {
        return res;
    }

    res = APR_ECRYPT; /* in case we exhaust all passphrases */

    /* try each passphrase in turn */
    for (; i < dconf->passphrases->nelts; i++) {
        const char *passphrase = APR_ARRAY_IDX(dconf->passphrases, i, char *);
        apr_size_t passlen = strlen(passphrase);
        apr_size_t len = decodedlen - AP_SIPHASH_DSIZE;
        unsigned char *slider = (unsigned char *)decoded + AP_SIPHASH_DSIZE;

        /* Verify authentication of the whole salt+IV+ciphertext by computing
         * the MAC and comparing it (timing safe) with the one in the payload.
         */
        compute_auth(slider, len, passphrase, passlen, auth);
        if (!ap_crypto_equals(auth, decoded, AP_SIPHASH_DSIZE)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(10006)
                    "auth does not match, skipping");
            continue;
        }

        /* encrypt using the first passphrase in the list */
        res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen,
                                    slider, sizeof(apr_uuid_t),
                                    *cipher, APR_MODE_CBC, 1, 4096,
                                    f, r->pool);
        if (APR_STATUS_IS_ENOKEY(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01832)
                    "failure generating key from passphrase");
            continue;
        }
        else if (APR_STATUS_IS_EPADDING(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01833)
                    "padding is not supported for cipher");
            continue;
        }
        else if (APR_STATUS_IS_EKEYTYPE(res)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01834)
                    "the key type is not known");
            continue;
        }
        else if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01835)
                    "encryption could not be configured.");
            continue;
        }

        /* sanity check - decoded too short? */
        if (len < (sizeof(apr_uuid_t) + ivSize)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01836)
                    "too short to decrypt, skipping");
            res = APR_ECRYPT;
            continue;
        }

        /* bypass the salt at the start of the decoded block */
        slider += sizeof(apr_uuid_t);
        len -= sizeof(apr_uuid_t);

        res = apr_crypto_block_decrypt_init(&block, &blockSize, slider, key,
                                            r->pool);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01837)
                    "apr_crypto_block_decrypt_init failed");
            continue;
        }

        /* bypass the iv at the start of the decoded block */
        slider += ivSize;
        len -= ivSize;

        /* decrypt the given string */
        res = apr_crypto_block_decrypt(&decrypted, &decryptedlen,
                                       slider, len, block);
        if (res) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01838)
                    "apr_crypto_block_decrypt failed");
            continue;
        }
        *out = (char *) decrypted;

        res = apr_crypto_block_decrypt_finish(decrypted + decryptedlen, &tlen, block);
        if (APR_SUCCESS != res) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01839)
                    "apr_crypto_block_decrypt_finish failed");
            continue;
        }
        decryptedlen += tlen;
        decrypted[decryptedlen] = 0;

        break;
    }

    if (APR_SUCCESS != res) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, res, r, APLOGNO(01840)
                "decryption failed");
    }

    return res;

}

/**
 * Crypto encoding for the session.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_crypto_encode(request_rec * r, session_rec * z)
{

    char *encoded = NULL;
    apr_status_t res;
    const apr_crypto_t *f = NULL;
    session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
            &session_crypto_module);

    if (dconf->passphrases_set && z->encoded && *z->encoded) {
        apr_pool_userdata_get((void **)&f, CRYPTO_KEY, r->server->process->pconf);
        res = encrypt_string(r, f, dconf, z->encoded, &encoded);
        if (res != OK) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01841)
                    "encrypt session failed");
            return res;
        }
        z->encoded = encoded;
    }

    return OK;

}

/**
 * Crypto decoding for the session.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_crypto_decode(request_rec * r,
        session_rec * z)
{

    char *encoded = NULL;
    apr_status_t res;
    const apr_crypto_t *f = NULL;
    session_crypto_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
            &session_crypto_module);

    if ((dconf->passphrases_set) && z->encoded && *z->encoded) {
        apr_pool_userdata_get((void **)&f, CRYPTO_KEY,
                r->server->process->pconf);
        res = decrypt_string(r, f, dconf, z->encoded, &encoded);
        if (res != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01842)
                    "decrypt session failed, wrong passphrase?");
            return res;
        }
        z->encoded = encoded;
    }

    return OK;

}

/**
 * Initialise the SSL in the post_config hook.
 */
static int session_crypto_init(apr_pool_t *p, apr_pool_t *plog,
        apr_pool_t *ptemp, server_rec *s)
{
    const apr_crypto_driver_t *driver = NULL;
    apr_crypto_t *f = NULL;

    session_crypto_conf *conf = ap_get_module_config(s->module_config,
            &session_crypto_module);

    /* session_crypto_init() will be called twice. Don't bother
     * going through all of the initialization on the first call
     * because it will just be thrown away.*/
    if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
        return OK;
    }

    if (conf->library) {

        const apu_err_t *err = NULL;
        apr_status_t rv;

        rv = apr_crypto_init(p);
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01843)
                    "APR crypto could not be initialised");
            return rv;
        }

        rv = apr_crypto_get_driver(&driver, conf->library, conf->params, &err, p);
        if (APR_EREINIT == rv) {
            ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01844)
                    "warning: crypto for '%s' was already initialised, "
                    "using existing configuration", conf->library);
            rv = APR_SUCCESS;
        }
        if (APR_SUCCESS != rv && err) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01845)
                    "The crypto library '%s' could not be loaded: %s (%s: %d)", conf->library, err->msg, err->reason, err->rc);
            return rv;
        }
        if (APR_ENOTIMPL == rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01846)
                    "The crypto library '%s' could not be found",
                    conf->library);
            return rv;
        }
        if (APR_SUCCESS != rv || !driver) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01847)
                    "The crypto library '%s' could not be loaded",
                    conf->library);
            return rv;
        }

        rv = apr_crypto_make(&f, driver, conf->params, p);
        if (APR_SUCCESS != rv) {
            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01848)
                    "The crypto library '%s' could not be initialised",
                    conf->library);
            return rv;
        }

        ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(01849)
                "The crypto library '%s' was loaded successfully",
                conf->library);

        apr_pool_userdata_set((const void *)f, CRYPTO_KEY,
                apr_pool_cleanup_null, s->process->pconf);

    }

    return OK;
}

static void *create_session_crypto_config(apr_pool_t * p, server_rec *s)
{
    session_crypto_conf *new =
    (session_crypto_conf *) apr_pcalloc(p, sizeof(session_crypto_conf));

    /* if no library has been configured, set the recommended library
     * as a sensible default.
     */
#ifdef APU_CRYPTO_RECOMMENDED_DRIVER
    new->library = APU_CRYPTO_RECOMMENDED_DRIVER;
#endif

    return (void *) new;
}

static void *create_session_crypto_dir_config(apr_pool_t * p, char *dummy)
{
    session_crypto_dir_conf *new =
    (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));

    new->passphrases = apr_array_make(p, 10, sizeof(char *));

    /* default cipher AES256-SHA */
    new->cipher = "aes256";

    return (void *) new;
}

static void *merge_session_crypto_dir_config(apr_pool_t * p, void *basev, void *addv)
{
    session_crypto_dir_conf *new = (session_crypto_dir_conf *) apr_pcalloc(p, sizeof(session_crypto_dir_conf));
    session_crypto_dir_conf *add = (session_crypto_dir_conf *) addv;
    session_crypto_dir_conf *base = (session_crypto_dir_conf *) basev;

    new->passphrases = (add->passphrases_set == 0) ? base->passphrases : add->passphrases;
    new->passphrases_set = add->passphrases_set || base->passphrases_set;
    new->cipher = (add->cipher_set == 0) ? base->cipher : add->cipher;
    new->cipher_set = add->cipher_set || base->cipher_set;

    return new;
}

static const char *set_crypto_driver(cmd_parms * cmd, void *config, const char *arg)
{
    session_crypto_conf *conf =
    (session_crypto_conf *)ap_get_module_config(cmd->server->module_config,
            &session_crypto_module);

    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);

    if (err != NULL) {
        return err;
    }

    conf->library = ap_getword_conf(cmd->pool, &arg);
    conf->params = arg;
    conf->library_set = 1;

    return NULL;
}

static const char *set_crypto_passphrase(cmd_parms * cmd, void *config, const char *arg)
{
    int arglen = strlen(arg);
    char **argv;
    char *result;
    const char **passphrase;
    session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;

    passphrase = apr_array_push(dconf->passphrases);

    if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
        if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
            return apr_pstrcat(cmd->pool,
                               "Unable to parse exec arguments from ",
                               arg+5, NULL);
        }
        argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);

        if (!argv[0]) {
            return apr_pstrcat(cmd->pool,
                               "Invalid SessionCryptoPassphrase exec location:",
                               arg+5, NULL);
        }
        result = ap_get_exec_line(cmd->pool,
                                  (const char*)argv[0], (const char * const *)argv);

        if(!result) {
            return apr_pstrcat(cmd->pool,
                               "Unable to get bind password from exec of ",
                               arg+5, NULL);
        }
        *passphrase = result;
    }
    else {
        *passphrase = arg;
    }

    dconf->passphrases_set = 1;

    return NULL;
}

static const char *set_crypto_passphrase_file(cmd_parms *cmd, void *config,
                                  const char *filename)
{
    char buffer[MAX_STRING_LEN];
    char *arg;
    const char *args;
    ap_configfile_t *file;
    apr_status_t rv;

    filename = ap_server_root_relative(cmd->temp_pool, filename);
    rv = ap_pcfg_openfile(&file, cmd->temp_pool, filename);
    if (rv != APR_SUCCESS) {
        return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
                            cmd->cmd->name, filename, &rv);
    }

    while (!(ap_cfg_getline(buffer, sizeof(buffer), file))) {
        args = buffer;
        while (*(arg = ap_getword_conf(cmd->pool, &args)) != '\0') {
            if (*arg == '#') {
                break;
            }
            set_crypto_passphrase(cmd, config, arg);
        }
    }

    ap_cfg_closefile(file);

    return NULL;
}

static const char *set_crypto_cipher(cmd_parms * cmd, void *config, const char *cipher)
{
    session_crypto_dir_conf *dconf = (session_crypto_dir_conf *) config;

    dconf->cipher = cipher;
    dconf->cipher_set = 1;

    return NULL;
}

static const command_rec session_crypto_cmds[] =
{
    AP_INIT_ITERATE("SessionCryptoPassphrase", set_crypto_passphrase, NULL, RSRC_CONF|OR_AUTHCFG,
            "The passphrase(s) used to encrypt the session. First will be used for encryption, all phrases will be accepted for decryption"),
    AP_INIT_TAKE1("SessionCryptoPassphraseFile", set_crypto_passphrase_file, NULL, RSRC_CONF|ACCESS_CONF,
            "File containing passphrase(s) used to encrypt the session, one per line. First will be used for encryption, all phrases will be accepted for decryption"),
    AP_INIT_TAKE1("SessionCryptoCipher", set_crypto_cipher, NULL, RSRC_CONF|OR_AUTHCFG,
            "The underlying crypto cipher to use"),
    AP_INIT_RAW_ARGS("SessionCryptoDriver", set_crypto_driver, NULL, RSRC_CONF,
            "The underlying crypto library driver to use"),
    { NULL }
};

static void register_hooks(apr_pool_t * p)
{
    ap_hook_session_encode(session_crypto_encode, NULL, NULL, APR_HOOK_LAST);
    ap_hook_session_decode(session_crypto_decode, NULL, NULL, APR_HOOK_FIRST);
    ap_hook_post_config(session_crypto_init, NULL, NULL, APR_HOOK_LAST);
}

AP_DECLARE_MODULE(session_crypto) =
{
    STANDARD20_MODULE_STUFF,
    create_session_crypto_dir_config, /* dir config creater */
    merge_session_crypto_dir_config, /* dir merger --- default is to override */
    create_session_crypto_config, /* server config */
    NULL, /* merge server config */
    session_crypto_cmds, /* command apr_table_t */
    register_hooks /* register hooks */
};

#endif
