/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <fcntl.h>

#include "config.h"
#include "gcmalloc.h"
#include "libpfkey.h"
#include "var.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "vmbuf.h"
#include "crypto_openssl.h"
#include "oakley.h"
#include "ipsec_doi.h"
#include "algorithm.h"
#include "vendorid.h"
#include "schedule.h"
#include "pfkey.h"
#include "nattraversal.h"
#include "proposal.h"
#include "sainfo.h"
#include "localconf.h"
#include "remoteconf.h"
#include "sockmisc.h"
#include "grabmyaddr.h"
#include "plog.h"
#include "admin.h"
#include "privsep.h"
#include "misc.h"

static struct localconf localconf;
static struct sainfo sainfo;
static char *pre_shared_key;

static char *interface;
static struct sockaddr *target;
static struct {
    struct sockaddr *addr;
    int fd;
} myaddrs[2];

struct localconf *lcconf = &localconf;
char *script_names[SCRIPT_MAX + 1];
int f_local = 0;

/*****************************************************************************/

static void add_sainfo_algorithm(int class, int algorithm, int length)
{
    struct sainfoalg *p = calloc(1, sizeof(struct sainfoalg));
    p->alg = algorithm;
    p->encklen = length;

    if (!sainfo.algs[class]) {
        sainfo.algs[class] = p;
    } else {
        struct sainfoalg *q = sainfo.algs[class];
        while (q->next) {
            q = q->next;
        }
        q->next = p;
    }
}

static void set_globals(char *interfaze, char *server)
{
    struct addrinfo hints = {
        .ai_flags = AI_NUMERICSERV,
#ifndef INET6
        .ai_family = AF_INET,
#else
        .ai_family = AF_UNSPEC,
#endif
        .ai_socktype = SOCK_DGRAM,
    };
    struct addrinfo *info;

    if (getaddrinfo(server, "80", &hints, &info) != 0) {
        do_plog(LLV_ERROR, "Cannot resolve address: %s\n", server);
        exit(1);
    }
    if (info->ai_next) {
        do_plog(LLV_WARNING, "Found multiple addresses. Use the first one.\n");
    }
    target = dupsaddr(info->ai_addr);
    freeaddrinfo(info);

    interface = interfaze;
    myaddrs[0].addr = getlocaladdr(target);
    if (!myaddrs[0].addr) {
        do_plog(LLV_ERROR, "Cannot get local address\n");
        exit(1);
    }
    set_port(target, 0);
    set_port(myaddrs[0].addr, 0);
    myaddrs[0].fd = -1;
    myaddrs[1].addr = dupsaddr(myaddrs[0].addr);
    myaddrs[1].fd = -1;

    localconf.port_isakmp = PORT_ISAKMP;
    localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
    localconf.default_af = AF_INET;
    localconf.pad_random = LC_DEFAULT_PAD_RANDOM;
    localconf.pad_randomlen = LC_DEFAULT_PAD_RANDOM;
    localconf.pad_strict = LC_DEFAULT_PAD_STRICT;
    localconf.pad_excltail = LC_DEFAULT_PAD_EXCLTAIL;
    localconf.retry_counter = 10;
    localconf.retry_interval = 3;
    localconf.count_persend = LC_DEFAULT_COUNT_PERSEND;
    localconf.secret_size = LC_DEFAULT_SECRETSIZE;
    localconf.retry_checkph1 = LC_DEFAULT_RETRY_CHECKPH1;
    localconf.wait_ph2complete = LC_DEFAULT_WAIT_PH2COMPLETE;
    localconf.natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;

    sainfo.lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
    sainfo.lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0);
    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
}

/*****************************************************************************/

static int policy_match(struct sadb_address *address)
{
    if (address) {
        return cmpsaddr(PFKEY_ADDR_SADDR(address), target) < CMPSADDR_MISMATCH;
    }
    return 0;
}

/* flush; spdflush; */
static void flush()
{
    struct sadb_msg *p;
    int replies = 0;
    int key = pfkey_open();

    if (pfkey_send_dump(key, SADB_SATYPE_UNSPEC) <= 0 ||
        pfkey_send_spddump(key) <= 0) {
        do_plog(LLV_ERROR, "Cannot dump SAD and SPD");
        exit(1);
    }

    for (p = NULL; replies < 2 && (p = pfkey_recv(key)) != NULL; free(p)) {
        caddr_t q[SADB_EXT_MAX + 1];

        if (p->sadb_msg_type != SADB_DUMP &&
            p->sadb_msg_type != SADB_X_SPDDUMP) {
            continue;
        }
        replies += !p->sadb_msg_seq;

        if (p->sadb_msg_errno || pfkey_align(p, q) || pfkey_check(q)) {
            continue;
        }
        if (policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_SRC]) ||
            policy_match((struct sadb_address *)q[SADB_EXT_ADDRESS_DST])) {
            p->sadb_msg_type = (p->sadb_msg_type == SADB_DUMP) ?
                               SADB_DELETE : SADB_X_SPDDELETE;
            p->sadb_msg_reserved = 0;
            p->sadb_msg_seq = 0;
            pfkey_send(key, p, PFKEY_UNUNIT64(p->sadb_msg_len));
        }
    }

    pfkey_close(key);
}

/* flush; spdflush;
 * spdadd src dst protocol -P out ipsec esp/transport//require; OR
 * spdadd src any protocol -P out ipsec esp/tunnel/local-remote/require; */
static void spdadd(struct sockaddr *src, struct sockaddr *dst,
        int protocol, struct sockaddr *local, struct sockaddr *remote)
{
    struct __attribute__((packed)) {
        struct sadb_x_policy p;
        struct sadb_x_ipsecrequest q;
        char addresses[sizeof(struct sockaddr_storage) * 2];
    } policy;

    struct sockaddr_storage any = {
#ifndef __linux__
        .ss_len = src->sa_len,
#endif
        .ss_family = src->sa_family,
    };

    int src_prefix = (src->sa_family == AF_INET) ? 32 : 128;
    int dst_prefix = src_prefix;
    int length = 0;
    int key;

    /* Fill default values. */
    memset(&policy, 0, sizeof(policy));
    policy.p.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
    policy.p.sadb_x_policy_type = IPSEC_POLICY_IPSEC;
    policy.p.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
#ifdef HAVE_PFKEY_POLICY_PRIORITY
    policy.p.sadb_x_policy_priority = PRIORITY_DEFAULT;
#endif
    policy.q.sadb_x_ipsecrequest_proto = IPPROTO_ESP;
    policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
    policy.q.sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;

    /* Deal with tunnel mode. */
    if (!dst) {
        policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
        dst = (struct sockaddr *)&any;
        dst_prefix = 0;

        length = sysdep_sa_len(local);
        memcpy(policy.addresses, local, length);
        memcpy(&policy.addresses[length], remote, length);
        length += length;

        /* Use the source address to flush policies. */
        racoon_free(target);
        target = dupsaddr(src);
    }

    /* Fix lengths. */
    length += sizeof(policy.q);
    policy.q.sadb_x_ipsecrequest_len = length;
    length += sizeof(policy.p);
    policy.p.sadb_x_policy_len = PFKEY_UNIT64(length);

    /* Always do a flush before adding the new policy. */
    flush();
    key = pfkey_open();
    if (pfkey_send_spdadd(key, src, src_prefix, dst, dst_prefix, protocol,
            (caddr_t)&policy, length, 0) <= 0) {
        do_plog(LLV_ERROR, "Cannot initialize SAD and SPD\n");
        exit(1);
    }
    pfkey_close(key);
    atexit(flush);
}

/*****************************************************************************/

static void add_proposal(struct remoteconf *remoteconf,
        int auth, int hash, int encryption, int length)
{
    struct isakmpsa *p = racoon_calloc(1, sizeof(struct isakmpsa));
    p->prop_no = 1;
    p->lifetime = OAKLEY_ATTR_SA_LD_SEC_DEFAULT;
    p->enctype = encryption;
    p->encklen = length;
    p->authmethod = auth;
    p->hashtype = hash;
    p->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
    p->vendorid = VENDORID_UNKNOWN;

    if (!remoteconf->proposal) {
      p->trns_no = 1;
      remoteconf->proposal = p;
    } else {
        struct isakmpsa *q = remoteconf->proposal;
        while (q->next) {
            q = q->next;
        }
        p->trns_no = q->trns_no + 1;
        q->next = p;
    }
}

void setup(int argc, char **argv)
{
    struct remoteconf *remoteconf;
    int auth;

    if (argc > 2) {
        set_globals(argv[1], argv[2]);

        /* Initialize everything else. */
        eay_init();
        initrmconf();
        oakley_dhinit();
        compute_vendorids();
        sched_init();
        if (pfkey_init() < 0 || isakmp_init() < 0) {
            exit(1);
        }
#ifdef ENABLE_NATT
        natt_keepalive_init();
#endif

        /* Create remote configuration. */
        remoteconf = newrmconf();
        remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes));
        remoteconf->etypes->type = ISAKMP_ETYPE_IDENT;
        remoteconf->ike_frag = TRUE;
        remoteconf->pcheck_level = PROP_CHECK_OBEY;
        remoteconf->gen_policy = TRUE;
        remoteconf->nat_traversal = TRUE;
        remoteconf->remote = dupsaddr(target);
        set_port(remoteconf->remote, localconf.port_isakmp);
    }

    /* Set authentication method and credentials. */
    if (argc == 6 && !strcmp(argv[3], "udppsk")) {
        set_port(target, atoi(argv[4]));
        spdadd(myaddrs[0].addr, target, IPPROTO_UDP, NULL, NULL);
        pre_shared_key = argv[5];
        remoteconf->idvtype = IDTYPE_ADDRESS;
        auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY;
    } else if (argc == 8 && !strcmp(argv[3], "udprsa")) {
        set_port(target, atoi(argv[4]));
        spdadd(myaddrs[0].addr, target, IPPROTO_UDP, NULL, NULL);
        remoteconf->myprivfile = argv[5];
        remoteconf->mycertfile = argv[6];
        remoteconf->cacertfile = argv[7];
        remoteconf->idvtype = IDTYPE_ASN1DN;
        auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;
    } else {
        printf("Usage: %s <interface> <server> [...],\n"
               "    where [...] can be:\n"
               "    udppsk <port> <pre-shared-key>\n"
               "    udprsa <port> <my-private-key> <my-cert> <ca-cert>\n",
               argv[0]);
        exit(0);
    }

    /* Add proposals. */
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_DES, 0);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_DES, 0);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 128);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 128);

    /* Install remote configuration. */
    insrmconf(remoteconf);

    /* Create ISAKMP sockets. */
    set_port(myaddrs[0].addr, localconf.port_isakmp);
    myaddrs[0].fd = isakmp_open(myaddrs[0].addr, FALSE);
    if (myaddrs[0].fd == -1) {
        do_plog(LLV_ERROR, "Cannot create ISAKMP socket");
        exit(1);
    }
#ifdef ENABLE_NATT
    set_port(myaddrs[1].addr, localconf.port_isakmp_natt);
    myaddrs[1].fd = isakmp_open(myaddrs[1].addr, TRUE);
    if (myaddrs[1].fd == -1) {
        do_plog(LLV_WARNING, "Cannot create ISAKMP socket for NAT-T");
    }
#endif
}

/*****************************************************************************/

/* localconf.h */

vchar_t *getpskbyaddr(struct sockaddr *addr)
{
    vchar_t *p = NULL;
    if (pre_shared_key && (p = vmalloc(strlen(pre_shared_key)))) {
        memcpy(p->v, pre_shared_key, p->l);
    }
    return p;
}

vchar_t *getpskbyname(vchar_t *name)
{
    return NULL;
}

void getpathname(char *path, int length, int type, const char *name)
{
    strncpy(path, name, length);
}

/* sainfo.h */

struct sainfo *getsainfo(const vchar_t *src, const vchar_t *dst,
        const vchar_t *peer, const vchar_t *client, uint32_t remoteid)
{
    return &sainfo;
}

const char *sainfo2str(const struct sainfo *si)
{
    return "*";
}

/* privsep.h */

int privsep_socket(int domain, int type, int protocol)
{
    int fd = socket(domain, type, protocol);
    if ((domain == AF_INET || domain == AF_INET6) && setsockopt(
            fd, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface))) {
        do_plog(LLV_WARNING, "Cannot bind socket to %s", interface);
    }
    return fd;
}

int privsep_bind(int fd, const struct sockaddr *addr, socklen_t addrlen)
{
    return bind(fd, addr, addrlen);
}

vchar_t *privsep_eay_get_pkcs1privkey(char *file)
{
    return eay_get_pkcs1privkey(file);
}

int privsep_script_exec(char *script, int name, char * const *environ)
{
    return 0;
}

/* grabmyaddr.h */

int myaddr_getsport(struct sockaddr *addr)
{
    return 0;
}

int myaddr_getfd(struct sockaddr *addr)
{
#ifdef ENABLE_NATT
    if (myaddrs[1].fd != -1 &&
            cmpsaddr(addr, myaddrs[1].addr) == CMPSADDR_MATCH) {
        return myaddrs[1].fd;
    }
#endif
    if (cmpsaddr(addr, myaddrs[0].addr) < CMPSADDR_MISMATCH) {
        return myaddrs[0].fd;
    }
    return -1;
}

/* misc.h */

int racoon_hexdump(void *data, size_t length)
{
    return 0;
}

void close_on_exec(int fd)
{
    fcntl(fd, F_SETFD, FD_CLOEXEC);
}
