/*
 * Copyright (C) 2011 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/param.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 "isakmp_xauth.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 "throttle.h"
#include "misc.h"
#include "handler.h"

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

static struct sockaddr *targets[2];
static struct sockaddr *source;
static struct myaddrs myaddrs[2];

struct localconf *lcconf = &localconf;
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 add_sainfo() {
    if (pk_checkalg(algclass_ipsec_auth, algtype_hmac_sha2_512, 0) == 0) {
        add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_512, 0);
    } else {
        do_plog(LLV_WARNING, "Kernel does not support SHA512, not enabling\n");
    }
    if (pk_checkalg(algclass_ipsec_auth, algtype_hmac_sha2_384, 0) == 0) {
        add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_384, 0);
    } else {
        do_plog(LLV_WARNING, "Kernel does not support SHA384, not enabling\n");
    }
    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0);
    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, 0);
    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
}

static void set_globals(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, "500", &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");
    }
    targets[0] = dupsaddr(info->ai_addr);
    freeaddrinfo(info);

    source = getlocaladdr(targets[0]);
    if (!source) {
        do_plog(LLV_ERROR, "Cannot get local address\n");
        exit(1);
    }
    set_port(targets[0], 0);
    set_port(source, 0);

    myaddrs[0].addr = dupsaddr(source);
    set_port(myaddrs[0].addr, PORT_ISAKMP);
    myaddrs[0].sock = -1;
#ifdef ENABLE_NATT
    myaddrs[0].next = &myaddrs[1];
    myaddrs[1].addr = dupsaddr(myaddrs[0].addr);
    set_port(myaddrs[1].addr, PORT_ISAKMP_NATT);
    myaddrs[1].sock = -1;
    myaddrs[1].udp_encap = 1;
#endif

    localconf.myaddrs = &myaddrs[0];
    localconf.port_isakmp = PORT_ISAKMP;
    localconf.port_isakmp_natt = PORT_ISAKMP_NATT;
    localconf.default_af = AF_INET;
    localconf.pathinfo[LC_PATHTYPE_CERT] = "./";
    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;

    memset(script_names, 0, sizeof(script_names));
}

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

static int policy_match(struct sadb_address *address)
{
    if (address) {
        struct sockaddr *addr = PFKEY_ADDR_SADDR(address);
        return !cmpsaddrwop(addr, targets[0]) || !cmpsaddrwop(addr, targets[1]);
    }
    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\n");
        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);
}

/* spdadd src dst protocol -P out ipsec esp/transport//require;
 * spdadd dst src protocol -P in  ipsec esp/transport//require;
 * or
 * spdadd src any protocol -P out ipsec esp/tunnel/local-remote/require;
 * spdadd any src protocol -P in  ipsec esp/tunnel/remote-local/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 values for outbound policy. */
    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) {
        int size = sysdep_sa_len(local);
        memcpy(policy.addresses, local, size);
        memcpy(&policy.addresses[size], remote, size);
        length += size + size;

        policy.q.sadb_x_ipsecrequest_mode = IPSEC_MODE_TUNNEL;
        dst = (struct sockaddr *)&any;
        dst_prefix = 0;

        /* Also use the source address to filter policies. */
        targets[1] = 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 new policies. */
    flush();

    /* Set outbound policy. */
    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 set outbound policy\n");
        exit(1);
    }

    /* Flip values for inbound policy. */
    policy.p.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
    if (!dst_prefix) {
        int size = sysdep_sa_len(local);
        memcpy(policy.addresses, remote, size);
        memcpy(&policy.addresses[size], local, size);
    }

    /* Set inbound policy. */
    if (pfkey_send_spdadd(key, dst, dst_prefix, src, src_prefix, protocol,
            (caddr_t)&policy, length, 0) <= 0) {
        do_plog(LLV_ERROR, "Cannot set inbound policy\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;
    p->rmconf = remoteconf;

    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;
    }
}

static vchar_t *strtovchar(char *string)
{
    vchar_t *vchar = string ? vmalloc(strlen(string) + 1) : NULL;
    if (vchar) {
        memcpy(vchar->v, string, vchar->l);
        vchar->l -= 1;
    }
    return vchar;
}

static void set_pre_shared_key(struct remoteconf *remoteconf,
        char *identifier, char *key)
{
    pre_shared_key = key;
    if (identifier[0]) {
        remoteconf->idv = strtovchar(identifier);
        remoteconf->etypes->type = ISAKMP_ETYPE_AGG;

        remoteconf->idvtype = IDTYPE_KEYID;
        if (strchr(identifier, '.')) {
            remoteconf->idvtype = IDTYPE_FQDN;
            if (strchr(identifier, '@')) {
                remoteconf->idvtype = IDTYPE_USERFQDN;
            }
        }
    }
}

static void set_certificates(struct remoteconf *remoteconf,
        char *user_private_key, char *user_certificate,
        char *ca_certificate, char *server_certificate)
{
    remoteconf->myprivfile = user_private_key;
    remoteconf->mycertfile = user_certificate;
    if (user_certificate) {
        remoteconf->idvtype = IDTYPE_ASN1DN;
    }
    if (!ca_certificate[0]) {
        remoteconf->verify_cert = FALSE;
    } else {
        remoteconf->cacertfile = ca_certificate;
    }
    if (server_certificate[0]) {
        remoteconf->peerscertfile = server_certificate;
        remoteconf->getcert_method = ISAKMP_GETCERT_LOCALFILE;
    }
}

#ifdef ENABLE_HYBRID

static void set_xauth_and_more(struct remoteconf *remoteconf,
        char *username, char *password, char *phase1_up, char *script_arg)
{
    struct xauth_rmconf *xauth = racoon_calloc(1, sizeof(struct xauth_rmconf));
    xauth->login = strtovchar(username);
    xauth->login->l += 1;
    xauth->pass = strtovchar(password);
    // Unlike the code that reads login, the code that reads pass does not
    // strip trailing nulls, so don't add one here.
    remoteconf->xauth = xauth;
    remoteconf->mode_cfg = TRUE;
    remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar(phase1_up);
    script_names[SCRIPT_PHASE1_UP] = script_arg;
}

#endif

extern void monitor_fd(int fd, void (*callback)(int));

void add_isakmp_handler(int fd, const char *interface)
{
    if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
            interface, strlen(interface))) {
        do_plog(LLV_WARNING, "Cannot bind socket to %s\n", interface);
    }
    monitor_fd(fd, (void *)isakmp_handler);
}

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

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

        /* Initialize everything else. */
        eay_init();
        initrmconf();
        oakley_dhinit();
        compute_vendorids();
        sched_init();
        if (pfkey_init() < 0 || isakmp_init() < 0) {
            exit(1);
        }
        add_sainfo();
        monitor_fd(localconf.sock_pfkey, (void *)pfkey_handler);
        add_isakmp_handler(myaddrs[0].sock, argv[1]);

#ifdef ENABLE_NATT
        add_isakmp_handler(myaddrs[1].sock, argv[1]);
        natt_keepalive_init();
#endif

        /* Create remote configuration. */
        remoteconf = newrmconf();
        remoteconf->etypes = racoon_calloc(1, sizeof(struct etypes));
        remoteconf->etypes->type = ISAKMP_ETYPE_IDENT;
        remoteconf->idvtype = IDTYPE_ADDRESS;
        remoteconf->ike_frag = TRUE;
        remoteconf->pcheck_level = PROP_CHECK_CLAIM;
        remoteconf->certtype = ISAKMP_CERT_X509SIGN;
        remoteconf->gen_policy = TRUE;
        remoteconf->nat_traversal = TRUE;
        remoteconf->dh_group = OAKLEY_ATTR_GRP_DESC_MODP1024;
        remoteconf->script[SCRIPT_PHASE1_UP] = strtovchar("");
        remoteconf->script[SCRIPT_PHASE1_DOWN] = strtovchar("");
        oakley_setdhgroup(remoteconf->dh_group, &remoteconf->dhgrp);
        remoteconf->remote = dupsaddr(targets[0]);
    }

    /* Set authentication method and credentials. */
    if (argc == 7 && !strcmp(argv[3], "udppsk")) {
        set_pre_shared_key(remoteconf, argv[4], argv[5]);
        auth = OAKLEY_ATTR_AUTH_METHOD_PSKEY;

        set_port(targets[0], atoi(argv[6]));
        spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
    } else if (argc == 9 && !strcmp(argv[3], "udprsa")) {
        set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
        auth = OAKLEY_ATTR_AUTH_METHOD_RSASIG;

        set_port(targets[0], atoi(argv[8]));
        spdadd(source, targets[0], IPPROTO_UDP, NULL, NULL);
#ifdef ENABLE_HYBRID
    } else if (argc == 10 && !strcmp(argv[3], "xauthpsk")) {
        set_pre_shared_key(remoteconf, argv[4], argv[5]);
        set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]);
        auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I;
    } else if (argc == 12 && !strcmp(argv[3], "xauthrsa")) {
        set_certificates(remoteconf, argv[4], argv[5], argv[6], argv[7]);
        set_xauth_and_more(remoteconf, argv[8], argv[9], argv[10], argv[11]);
        auth = OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I;
    } else if (argc == 10 && !strcmp(argv[3], "hybridrsa")) {
        set_certificates(remoteconf, NULL, NULL, argv[4], argv[5]);
        set_xauth_and_more(remoteconf, argv[6], argv[7], argv[8], argv[9]);
        auth = OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I;
#endif
    } else {
        printf("Usage: %s <interface> <server> [...], where [...] can be:\n"
                " udppsk    <identifier> <pre-shared-key> <port>; \n"
                " udprsa    <user-private-key> <user-certificate> \\\n"
                "           <ca-certificate> <server-certificate> <port>;\n"
#ifdef ENABLE_HYBRID
                " xauthpsk  <identifier> <pre-shared-key> \\\n"
                "           <username> <password> <phase1-up> <script-arg>;\n"
                " xauthrsa  <user-private-key> <user-certificate> \\\n"
                "           <ca-certificate> <server-certificate> \\\n"
                "           <username> <password> <phase1-up> <script-arg>;\n"
                " hybridrsa <ca-certificate> <server-certificate> \\\n"
                "           <username> <password> <phase1-up> <script-arg>;\n"
#endif
                "", argv[0]);
        exit(0);
    }

    /* Add proposals. */
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_384, OAKLEY_ATTR_ENC_ALG_AES, 256);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 256);
    // VPNs to openswan breaks when SHA2_512 is used as the first proposal.
    // openswan supports SHA2_256 or lower hash alg. With this add_proposal
    // order, openswan picks SHA2_256 and others pick SHA2_384
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_512, OAKLEY_ATTR_ENC_ALG_AES, 256);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 256);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 256);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_512, OAKLEY_ATTR_ENC_ALG_AES, 128);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_384, OAKLEY_ATTR_ENC_ALG_AES, 128);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 128);
    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);
    add_proposal(remoteconf, auth,
            OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_3DES, 0);
    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_SHA2_256, OAKLEY_ATTR_ENC_ALG_DES, 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);

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

    /* Start phase 1 negotiation for xauth. */
    if (remoteconf->xauth) {
        isakmp_ph1begin_i(remoteconf, remoteconf->remote, source);
    }
}

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

/* localconf.h */

vchar_t *getpskbyaddr(struct sockaddr *addr)
{
    return strtovchar(pre_shared_key);
}

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

void getpathname(char *path, int length, int type, const char *name)
{
    if (pname) {
        snprintf(path, length, pname, name);
    } else {
        strncpy(path, name, length);
    }
    path[length - 1] = '\0';
}

/* grabmyaddr.h */

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

int getsockmyaddr(struct sockaddr *addr)
{
#ifdef ENABLE_NATT
    if (!cmpsaddrstrict(addr, myaddrs[1].addr)) {
        return myaddrs[1].sock;
    }
#endif
    if (!cmpsaddrwop(addr, myaddrs[0].addr)) {
        return myaddrs[0].sock;
    }
    return -1;
}

/* privsep.h */

int privsep_pfkey_open()
{
    return pfkey_open();
}

void privsep_pfkey_close(int key)
{
    pfkey_close(key);
}

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

static char *get_env(char * const *envp, char *key)
{
    int length = strlen(key);
    while (*envp && (strncmp(*envp, key, length) || (*envp)[length] != '=')) {
        ++envp;
    }
    return *envp ? &(*envp)[length + 1] : "";
}

static int skip_script = 0;
extern const char *android_hook(char **envp);

int privsep_script_exec(char *script, int name, char * const *envp)
{
    if (skip_script) {
        return 0;
    }
    skip_script = 1;

    if (name == SCRIPT_PHASE1_DOWN) {
        exit(1);
    }
    if (script_names[SCRIPT_PHASE1_UP]) {
        /* Racoon ignores INTERNAL_IP6_ADDRESS, so we only do IPv4. */
        struct sockaddr *addr4 = str2saddr(get_env(envp, "INTERNAL_ADDR4"),
                NULL);
        struct sockaddr *local = str2saddr(get_env(envp, "LOCAL_ADDR"),
                get_env(envp, "LOCAL_PORT"));
        struct sockaddr *remote = str2saddr(get_env(envp, "REMOTE_ADDR"),
                get_env(envp, "REMOTE_PORT"));

        if (addr4 && local && remote) {
#ifdef ANDROID_CHANGES
            if (pname) {
                script = (char *)android_hook((char **)envp);
            }
#endif
            spdadd(addr4, NULL, IPPROTO_IP, local, remote);
        } else {
            do_plog(LLV_ERROR, "Cannot get parameters for SPD policy.\n");
            exit(1);
        }

        racoon_free(addr4);
        racoon_free(local);
        racoon_free(remote);
        return script_exec(script, name, envp);
    }
    return 0;
}

int privsep_accounting_system(int port, struct sockaddr *addr,
        char *user, int status)
{
    return 0;
}

int privsep_xauth_login_system(char *user, char *password)
{
    return -1;
}

/* misc.h */

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

/* sainfo.h */

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

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

/* throttle.h */

int throttle_host(struct sockaddr *addr, int fail)
{
    return 0;
}

void shutdown_session()
{
    flushph2();
    flushph1();
    isakmp_close();
    pfkey_close(localconf.sock_pfkey);
}
