/* 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 "apr_lib.h"
#include "apr_strings.h"
#include "http_log.h"
#include "util_cookies.h"

#define MOD_SESSION_COOKIE "mod_session_cookie"

module AP_MODULE_DECLARE_DATA session_cookie_module;

/**
 * Structure to carry the per-dir session config.
 */
typedef struct {
    const char *name;
    int name_set;
    const char *name_attrs;
    const char *name2;
    int name2_set;
    const char *name2_attrs;
    int remove;
    int remove_set;
    int maxage;
    int maxage_set;
} session_cookie_dir_conf;

/**
 * Set the cookie and embed the session within it.
 *
 * This function adds an RFC2109 compliant Set-Cookie header for
 * the cookie specified in SessionCookieName, and an RFC2965 compliant
 * Set-Cookie2 header for the cookie specified in SessionCookieName2.
 *
 * If specified, the optional cookie attributes will be added to
 * each cookie. If defaults are not specified, DEFAULT_ATTRS
 * will be used.
 *
 * On success, this method will return APR_SUCCESS.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_cookie_save(request_rec * r, session_rec * z)
{

    session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                    &session_cookie_module);
    int maxage = conf->maxage ? z->maxage : 0;

    /* create RFC2109 compliant cookie */
    if (conf->name_set) {
        if (z->encoded && z->encoded[0]) {
            ap_cookie_write(r, conf->name, z->encoded, conf->name_attrs,
                            maxage, r->err_headers_out,
                            NULL);
        }
        else {
            ap_cookie_remove(r, conf->name, conf->name_attrs,
                             r->err_headers_out, NULL);
        }
    }

    /* create RFC2965 compliant cookie */
    if (conf->name2_set) {
        if (z->encoded && z->encoded[0]) {
            ap_cookie_write2(r, conf->name2, z->encoded, conf->name2_attrs,
                             maxage, r->err_headers_out,
                             NULL);
        }
        else {
            ap_cookie_remove2(r, conf->name2, conf->name2_attrs,
                              r->err_headers_out, NULL);
        }
    }

    if (conf->name_set || conf->name2_set) {
        return OK;
    }
    return DECLINED;

}

/**
 * Isolate the cookie with the name "name", and if present, extract
 * the payload from the cookie.
 *
 * If the cookie is found, the cookie and any other cookies with the
 * same name are removed from the cookies passed in the request, so
 * that credentials are not leaked to a backend server or process.
 *
 * A missing or malformed cookie will cause this function to return
 * APR_EGENERAL.
 *
 * On success, this returns APR_SUCCESS.
 */
static apr_status_t session_cookie_load(request_rec * r, session_rec ** z)
{

    session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                    &session_cookie_module);

    session_rec *zz = NULL;
    const char *val = NULL;
    const char *note = NULL;
    const char *name = NULL;
    request_rec *m = r;

    /* find the first redirect */
    while (m->prev) {
        m = m->prev;
    }
    /* find the main request */
    while (m->main) {
        m = m->main;
    }

    /* is our session in a cookie? */
    if (conf->name2_set) {
        name = conf->name2;
    }
    else if (conf->name_set) {
        name = conf->name;
    }
    else {
        return DECLINED;
    }

    /* first look in the notes */
    note = apr_pstrcat(m->pool, MOD_SESSION_COOKIE, name, NULL);
    zz = (session_rec *)apr_table_get(m->notes, note);
    if (zz) {
        *z = zz;
        return OK;
    }

    /* otherwise, try parse the cookie */
    ap_cookie_read(r, name, &val, conf->remove);

    /* create a new session and return it */
    zz = (session_rec *) apr_pcalloc(m->pool, sizeof(session_rec));
    zz->pool = m->pool;
    zz->entries = apr_table_make(m->pool, 10);
    zz->encoded = val;
    *z = zz;

    /* put the session in the notes so we don't have to parse it again */
    apr_table_setn(m->notes, note, (char *)zz);

    /* don't cache auth protected pages */
    apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");

    return OK;

}



static void *create_session_cookie_dir_config(apr_pool_t * p, char *dummy)
{
    session_cookie_dir_conf *new =
    (session_cookie_dir_conf *) apr_pcalloc(p, sizeof(session_cookie_dir_conf));
    new->maxage = 1;

    return (void *) new;
}

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

    new->name = (add->name_set == 0) ? base->name : add->name;
    new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
    new->name_set = add->name_set || base->name_set;
    new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
    new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
    new->name2_set = add->name2_set || base->name2_set;
    new->remove = (add->remove_set == 0) ? base->remove : add->remove;
    new->remove_set = add->remove_set || base->remove_set;
    new->maxage = (add->maxage_set == 0) ? base->maxage : add->maxage;
    new->maxage_set = add->maxage_set || base->maxage_set;

    return new;
}

/**
 * Sanity check a given string that it exists, is not empty,
 * and does not contain special characters.
 */
static const char *check_string(cmd_parms * cmd, const char *string)
{
    if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
        return apr_pstrcat(cmd->pool, cmd->directive->directive,
                           " cannot be empty, or contain '=' or '&'.",
                           NULL);
    }
    return NULL;
}

static const char *set_cookie_name(cmd_parms * cmd, void *config,
                                   const char *args)
{
    char *last;
    char *line = apr_pstrdup(cmd->pool, args);
    session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
    char *cookie = apr_strtok(line, " \t", &last);
    conf->name = cookie;
    conf->name_set = 1;
    while (apr_isspace(*last)) {
        last++;
    }
    conf->name_attrs = last;
    return check_string(cmd, cookie);
}

static const char *set_cookie_name2(cmd_parms * cmd, void *config,
                                    const char *args)
{
    char *last;
    char *line = apr_pstrdup(cmd->pool, args);
    session_cookie_dir_conf *conf = (session_cookie_dir_conf *) config;
    char *cookie = apr_strtok(line, " \t", &last);
    conf->name2 = cookie;
    conf->name2_set = 1;
    while (apr_isspace(*last)) {
        last++;
    }
    conf->name2_attrs = last;
    return check_string(cmd, cookie);
}

static const char *
     set_remove(cmd_parms * parms, void *dconf, int flag)
{
    session_cookie_dir_conf *conf = dconf;

    conf->remove = flag;
    conf->remove_set = 1;

    return NULL;
}

static const char *
     set_maxage(cmd_parms * parms, void *dconf, int flag)
{
    session_cookie_dir_conf *conf = dconf;

    conf->maxage = flag;
    conf->maxage_set = 1;

    return NULL;
}
static const command_rec session_cookie_cmds[] =
{
    AP_INIT_RAW_ARGS("SessionCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
                     "The name of the RFC2109 cookie carrying the session"),
    AP_INIT_RAW_ARGS("SessionCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
                     "The name of the RFC2965 cookie carrying the session"),
    AP_INIT_FLAG("SessionCookieRemove", set_remove, NULL, RSRC_CONF|OR_AUTHCFG,
                 "Set to 'On' to remove the session cookie from the headers "
                 "and hide the cookie from a backend server or process"),
    AP_INIT_FLAG("SessionCookieMaxAge", set_maxage, NULL, RSRC_CONF|OR_AUTHCFG,
                 "Set to 'Off' to disable propogating SessionMaxAge to the client"),

    {NULL}
};

static void register_hooks(apr_pool_t * p)
{
    ap_hook_session_load(session_cookie_load, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_session_save(session_cookie_save, NULL, NULL, APR_HOOK_MIDDLE);
}

AP_DECLARE_MODULE(session_cookie) =
{
    STANDARD20_MODULE_STUFF,
    create_session_cookie_dir_config, /* dir config creater */
    merge_session_cookie_dir_config,  /* dir merger --- default is to
                                       * override */
    NULL,                             /* server config */
    NULL,                             /* merge server config */
    session_cookie_cmds,              /* command apr_table_t */
    register_hooks                    /* register hooks */
};
