/* 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 "ap_config.h"
#include "ap_mmn.h"
#include "httpd.h"
#include "http_config.h"
#include "http_connection.h"
#include "http_protocol.h"
#include "http_log.h"
#include "apr_strings.h"
#include "apr_lib.h"
#define APR_WANT_BYTEFUNC
#include "apr_want.h"
#include "apr_network_io.h"

module AP_MODULE_DECLARE_DATA remoteip_module;

typedef struct {
    /** A proxy IP mask to match */
    apr_ipsubnet_t *ip;
    /** Flagged if internal, otherwise an external trusted proxy */
    void  *internal;
} remoteip_proxymatch_t;

typedef struct {
    /** The header to retrieve a proxy-via IP list */
    const char *header_name;
    /** A header to record the proxied IP's
     * (removed as the physical connection and
     * from the proxy-via IP header value list)
     */
    const char *proxies_header_name;
    /** A list of trusted proxies, ideally configured
     *  with the most commonly encountered listed first
     */
    apr_array_header_t *proxymatch_ip;
} remoteip_config_t;

typedef struct {
    apr_sockaddr_t *useragent_addr;
    char *useragent_ip;
    /** The list of proxy IP's ignored as remote IP's */
    const char *proxy_ips;
    /** The remaining list of untrusted proxied remote IP's */
    const char *proxied_remote;
} remoteip_req_t;

static void *create_remoteip_server_config(apr_pool_t *p, server_rec *s)
{
    remoteip_config_t *config = apr_pcalloc(p, sizeof *config);
    /* config->header_name = NULL;
     * config->proxies_header_name = NULL;
     */
    return config;
}

static void *merge_remoteip_server_config(apr_pool_t *p, void *globalv,
                                          void *serverv)
{
    remoteip_config_t *global = (remoteip_config_t *) globalv;
    remoteip_config_t *server = (remoteip_config_t *) serverv;
    remoteip_config_t *config;

    config = (remoteip_config_t *) apr_palloc(p, sizeof(*config));
    config->header_name = server->header_name
                        ? server->header_name
                        : global->header_name;
    config->proxies_header_name = server->proxies_header_name
                                ? server->proxies_header_name
                                : global->proxies_header_name;
    config->proxymatch_ip = server->proxymatch_ip
                          ? server->proxymatch_ip
                          : global->proxymatch_ip;
    return config;
}

static const char *header_name_set(cmd_parms *cmd, void *dummy,
                                   const char *arg)
{
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                     &remoteip_module);
    config->header_name = arg;
    return NULL;
}

static const char *proxies_header_name_set(cmd_parms *cmd, void *dummy,
                                           const char *arg)
{
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                     &remoteip_module);
    config->proxies_header_name = arg;
    return NULL;
}

/* Would be quite nice if APR exported this */
/* apr:network_io/unix/sockaddr.c */
static int looks_like_ip(const char *ipstr)
{
    if (ap_strchr_c(ipstr, ':')) {
        /* definitely not a hostname; assume it is intended to be an IPv6 address */
        return 1;
    }

    /* simple IPv4 address string check */
    while ((*ipstr == '.') || apr_isdigit(*ipstr))
        ipstr++;
    return (*ipstr == '\0');
}

static const char *proxies_set(cmd_parms *cmd, void *cfg,
                               const char *arg)
{
    remoteip_config_t *config = ap_get_module_config(cmd->server->module_config,
                                                     &remoteip_module);
    remoteip_proxymatch_t *match;
    apr_status_t rv;
    char *ip = apr_pstrdup(cmd->temp_pool, arg);
    char *s = ap_strchr(ip, '/');
    if (s) {
        *s++ = '\0';
    }

    if (!config->proxymatch_ip) {
        config->proxymatch_ip = apr_array_make(cmd->pool, 1, sizeof(*match));
    }
    match = (remoteip_proxymatch_t *) apr_array_push(config->proxymatch_ip);
    match->internal = cmd->info;

    if (looks_like_ip(ip)) {
        /* Note s may be null, that's fine (explicit host) */
        rv = apr_ipsubnet_create(&match->ip, ip, s, cmd->pool);
    }
    else
    {
        apr_sockaddr_t *temp_sa;

        if (s) {
            return apr_pstrcat(cmd->pool, "RemoteIP: Error parsing IP ", arg,
                               " the subnet /", s, " is invalid for ",
                               cmd->cmd->name, NULL);
        }

        rv = apr_sockaddr_info_get(&temp_sa,  ip, APR_UNSPEC, 0,
                                   APR_IPV4_ADDR_OK, cmd->temp_pool);
        while (rv == APR_SUCCESS)
        {
            apr_sockaddr_ip_get(&ip, temp_sa);
            rv = apr_ipsubnet_create(&match->ip, ip, NULL, cmd->pool);
            if (!(temp_sa = temp_sa->next)) {
                break;
            }
            match = (remoteip_proxymatch_t *)
                    apr_array_push(config->proxymatch_ip);
            match->internal = cmd->info;
        }
    }

    if (rv != APR_SUCCESS) {
        return apr_psprintf(cmd->pool,
                            "RemoteIP: Error parsing IP %s (%pm error) for %s",
                            arg, &rv, cmd->cmd->name);
    }

    return NULL;
}

static const char *proxylist_read(cmd_parms *cmd, void *cfg,
                                  const char *filename)
{
    char lbuf[MAX_STRING_LEN];
    char *arg;
    const char *args;
    const char *errmsg;
    ap_configfile_t *cfp;
    apr_status_t rv;

    filename = ap_server_root_relative(cmd->temp_pool, filename);
    rv = ap_pcfg_openfile(&cfp, 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(lbuf, MAX_STRING_LEN, cfp))) {
        args = lbuf;
        while (*(arg = ap_getword_conf(cmd->temp_pool, &args)) != '\0') {
            if (*arg == '#') {
                break;
            }
            errmsg = proxies_set(cmd, cfg, arg);
            if (errmsg) {
                ap_cfg_closefile(cfp);
                errmsg = apr_psprintf(cmd->pool, "%s at line %d of %s",
                                      errmsg, cfp->line_number, filename);
                return errmsg;
            }
        }
    }

    ap_cfg_closefile(cfp);
    return NULL;
}

static int remoteip_modify_request(request_rec *r)
{
    conn_rec *c = r->connection;
    remoteip_config_t *config = (remoteip_config_t *)
        ap_get_module_config(r->server->module_config, &remoteip_module);
    remoteip_req_t *req = NULL;

    apr_sockaddr_t *temp_sa;

    apr_status_t rv;
    char *remote;
    char *proxy_ips = NULL;
    char *parse_remote;
    char *eos;
    unsigned char *addrbyte;

    /* If no RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
       or RemoteIPTrustedProxyList directive is configured,
       all proxies will be considered as external trusted proxies.
     */
    void *internal = NULL;

    if (!config->header_name) {
        return DECLINED;
    }
 
    if (config->proxymatch_ip) {
        /* This indicates that a RemoteIPInternalProxy, RemoteIPInternalProxyList, RemoteIPTrustedProxy
           or RemoteIPTrustedProxyList directive is configured.
           In this case, default to internal proxy.
         */
        internal = (void *) 1;
    }

    remote = (char *) apr_table_get(r->headers_in, config->header_name);
    if (!remote) {
        return OK;
    }
    remote = apr_pstrdup(r->pool, remote);

    temp_sa = r->useragent_addr ? r->useragent_addr : c->client_addr;

    while (remote) {

        /* verify user agent IP against the trusted proxy list
         */
        if (config->proxymatch_ip) {
            int i;
            remoteip_proxymatch_t *match;
            match = (remoteip_proxymatch_t *)config->proxymatch_ip->elts;
            for (i = 0; i < config->proxymatch_ip->nelts; ++i) {
                if (apr_ipsubnet_test(match[i].ip, temp_sa)) {
                    if (internal) {
                        /* Allow an internal proxy to present an external proxy,
                           but do not allow an external proxy to present an internal proxy.
                           In this case, the presented internal proxy will be considered external.
                         */
                        internal = match[i].internal;
                    }
                    break;
                }
            }
            if (i && i >= config->proxymatch_ip->nelts) {
                break;
            }
        }

        if ((parse_remote = strrchr(remote, ',')) == NULL) {
            parse_remote = remote;
            remote = NULL;
        }
        else {
            *(parse_remote++) = '\0';
        }

        while (*parse_remote == ' ') {
            ++parse_remote;
        }

        eos = parse_remote + strlen(parse_remote) - 1;
        while (eos >= parse_remote && *eos == ' ') {
            *(eos--) = '\0';
        }

        if (eos < parse_remote) {
            if (remote) {
                *(remote + strlen(remote)) = ',';
            }
            else {
                remote = parse_remote;
            }
            break;
        }

        /* We map as IPv4 rather than IPv6 for equivalent host names
         * or IPV4OVERIPV6
         */
        rv = apr_sockaddr_info_get(&temp_sa,  parse_remote,
                                   APR_UNSPEC, temp_sa->port,
                                   APR_IPV4_ADDR_OK, r->pool);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r, APLOGNO(01568)
                          "RemoteIP: Header %s value of %s cannot be parsed "
                          "as a client IP",
                          config->header_name, parse_remote);

            if (remote) {
                *(remote + strlen(remote)) = ',';
            }
            else {
                remote = parse_remote;
            }
            break;
        }

        addrbyte = (unsigned char *) &temp_sa->sa.sin.sin_addr;

        /* For intranet (Internal proxies) ignore all restrictions below */
        if (!internal
              && ((temp_sa->family == APR_INET
                   /* For internet (non-Internal proxies) deny all
                    * RFC3330 designated local/private subnets:
                    * 10.0.0.0/8   169.254.0.0/16  192.168.0.0/16
                    * 127.0.0.0/8  172.16.0.0/12
                    */
                      && (addrbyte[0] == 10
                       || addrbyte[0] == 127
                       || (addrbyte[0] == 169 && addrbyte[1] == 254)
                       || (addrbyte[0] == 172 && (addrbyte[1] & 0xf0) == 16)
                       || (addrbyte[0] == 192 && addrbyte[1] == 168)))
#if APR_HAVE_IPV6
               || (temp_sa->family == APR_INET6
                   /* For internet (non-Internal proxies) we translated
                    * IPv4-over-IPv6-mapped addresses as IPv4, above.
                    * Accept only Global Unicast 2000::/3 defined by RFC4291
                    */
                      && ((temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xe0) != 0x20))
#endif
        )) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG,  rv, r, APLOGNO(01569)
                          "RemoteIP: Header %s value of %s appears to be "
                          "a private IP or nonsensical.  Ignored",
                          config->header_name, parse_remote);
            if (remote) {
                *(remote + strlen(remote)) = ',';
            }
            else {
                remote = parse_remote;
            }

            break;
        }

        /* save away our results */
        if (!req) {
            req = (remoteip_req_t *) apr_palloc(r->pool, sizeof(remoteip_req_t));
            req->useragent_ip = r->useragent_ip;
        }

        /* Set useragent_ip string */
        if (!internal) {
            if (proxy_ips) {
                proxy_ips = apr_pstrcat(r->pool, proxy_ips, ", ",
                                        req->useragent_ip, NULL);
            }
            else {
                proxy_ips = req->useragent_ip;
            }
        }

        req->useragent_addr = temp_sa;
        apr_sockaddr_ip_get(&req->useragent_ip, req->useragent_addr);
    }

    /* Nothing happened? */
    if (!req) {
        return OK;
    }

    req->proxied_remote = remote;
    req->proxy_ips = proxy_ips;

    if (req->proxied_remote) {
        apr_table_setn(r->headers_in, config->header_name,
                       req->proxied_remote);
    }
    else {
        apr_table_unset(r->headers_in, config->header_name);
    }
    if (req->proxy_ips) {
        apr_table_setn(r->notes, "remoteip-proxy-ip-list", req->proxy_ips);
        if (config->proxies_header_name) {
            apr_table_setn(r->headers_in, config->proxies_header_name,
                           req->proxy_ips);
        }
    }

    r->useragent_addr = req->useragent_addr;
    r->useragent_ip = req->useragent_ip;

    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                  req->proxy_ips
                      ? "Using %s as client's IP by proxies %s"
                      : "Using %s as client's IP by internal proxies%s",
                  req->useragent_ip,
                  (req->proxy_ips ? req->proxy_ips : ""));
    return OK;
}

static const command_rec remoteip_cmds[] =
{
    AP_INIT_TAKE1("RemoteIPHeader", header_name_set, NULL, RSRC_CONF,
                  "Specifies a request header to trust as the client IP, "
                  "e.g. X-Forwarded-For"),
    AP_INIT_TAKE1("RemoteIPProxiesHeader", proxies_header_name_set,
                  NULL, RSRC_CONF,
                  "Specifies a request header to record proxy IP's, "
                  "e.g. X-Forwarded-By; if not given then do not record"),
    AP_INIT_ITERATE("RemoteIPTrustedProxy", proxies_set, 0, RSRC_CONF,
                    "Specifies one or more proxies which are trusted "
                    "to present IP headers"),
    AP_INIT_ITERATE("RemoteIPInternalProxy", proxies_set, (void*)1, RSRC_CONF,
                    "Specifies one or more internal (transparent) proxies "
                    "which are trusted to present IP headers"),
    AP_INIT_TAKE1("RemoteIPTrustedProxyList", proxylist_read, 0,
                  RSRC_CONF | EXEC_ON_READ,
                  "The filename to read the list of trusted proxies, "
                  "see the RemoteIPTrustedProxy directive"),
    AP_INIT_TAKE1("RemoteIPInternalProxyList", proxylist_read, (void*)1,
                  RSRC_CONF | EXEC_ON_READ,
                  "The filename to read the list of internal proxies, "
                  "see the RemoteIPInternalProxy directive"),
    { NULL }
};

static void register_hooks(apr_pool_t *p)
{
    ap_hook_post_read_request(remoteip_modify_request, NULL, NULL, APR_HOOK_FIRST);
}

AP_DECLARE_MODULE(remoteip) = {
    STANDARD20_MODULE_STUFF,
    NULL,                          /* create per-directory config structure */
    NULL,                          /* merge per-directory config structures */
    create_remoteip_server_config, /* create per-server config structure */
    merge_remoteip_server_config,  /* merge per-server config structures */
    remoteip_cmds,                 /* command apr_table_t */
    register_hooks                 /* register hooks */
};
