/*
 * 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 <stdarg.h>
#include <signal.h>
#include <poll.h>
#include <unistd.h>

#include "config.h"
#include "gcmalloc.h"
#include "schedule.h"
#include "plog.h"

#ifdef ANDROID_CHANGES

#include <openssl/engine.h>

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/if.h>
#include <linux/if_tun.h>

#include <android/log.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>

static void notify_death()
{
    creat("/data/misc/vpn/abort", 0);
}

static int android_get_control_and_arguments(int *argc, char ***argv)
{
    static char *args[32];
    int control;
    int i;

    atexit(notify_death);

    if ((i = android_get_control_socket("racoon")) == -1) {
        return -1;
    }
    do_plog(LLV_DEBUG, "Waiting for control socket");
    if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
        do_plog(LLV_ERROR, "Cannot get control socket");
        exit(1);
    }
    close(i);
    fcntl(control, F_SETFD, FD_CLOEXEC);

    args[0] = (*argv)[0];
    for (i = 1; i < 32; ++i) {
        unsigned char bytes[2];
        if (recv(control, &bytes[0], 1, 0) != 1 ||
                recv(control, &bytes[1], 1, 0) != 1) {
            do_plog(LLV_ERROR, "Cannot get argument length");
            exit(1);
        } else {
            int length = bytes[0] << 8 | bytes[1];
            int offset = 0;

            if (length == 0xFFFF) {
                break;
            }
            args[i] = malloc(length + 1);
            while (offset < length) {
                int n = recv(control, &args[i][offset], length - offset, 0);
                if (n > 0) {
                    offset += n;
                } else {
                    do_plog(LLV_ERROR, "Cannot get argument value");
                    exit(1);
                }
            }
            args[i][length] = 0;
        }
    }
    do_plog(LLV_DEBUG, "Received %d arguments", i - 1);

    *argc = i;
    *argv = args;
    return control;
}

const char *android_hook(char **envp)
{
    struct ifreq ifr = {.ifr_flags = IFF_TUN};
    int tun = open("/dev/tun", 0);

    /* Android does not support INTERNAL_WINS4_LIST, so we just use it. */
    while (*envp && strncmp(*envp, "INTERNAL_WINS4_LIST=", 20)) {
        ++envp;
    }
    if (!*envp) {
        do_plog(LLV_ERROR, "Cannot find environment variable\n");
        exit(1);
    }
    if (ioctl(tun, TUNSETIFF, &ifr)) {
        do_plog(LLV_ERROR, "Cannot allocate TUN: %s\n", strerror(errno));
        exit(1);
    }
    sprintf(*envp, "INTERFACE=%s", ifr.ifr_name);
    return "/etc/ppp/ip-up-vpn";
}

#endif

extern void setup(int argc, char **argv);
extern void shutdown_session();

static int monitors;
static void (*callbacks[10])(int fd);
static struct pollfd pollfds[10];

char *pname;

static void terminate(int signal)
{
    exit(1);
}

static void terminated()
{
    do_plog(LLV_INFO, "Bye\n");
}

void monitor_fd(int fd, void (*callback)(int))
{
    if (fd < 0 || monitors == 10) {
        do_plog(LLV_ERROR, "Cannot monitor fd");
        exit(1);
    }
    callbacks[monitors] = callback;
    pollfds[monitors].fd = fd;
    pollfds[monitors].events = callback ? POLLIN : 0;
    ++monitors;
}

int main(int argc, char **argv)
{
#ifdef ANDROID_CHANGES
    int control = android_get_control_and_arguments(&argc, &argv);
#if !defined(OPENSSL_IS_BORINGSSL)
    ENGINE *engine;
#endif

    if (control != -1) {
        pname = "%p";
        monitor_fd(control, NULL);

#if !defined(OPENSSL_IS_BORINGSSL)
        ENGINE_load_dynamic();
        engine = ENGINE_by_id("keystore");
        if (!engine || !ENGINE_init(engine)) {
            do_plog(LLV_ERROR, "ipsec-tools: cannot load keystore engine");
            exit(1);
        }
#endif
    }
#endif

    do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n");

    signal(SIGHUP, terminate);
    signal(SIGINT, terminate);
    signal(SIGTERM, terminate);
    signal(SIGPIPE, SIG_IGN);
    atexit(terminated);

    setup(argc, argv);

#ifdef ANDROID_CHANGES
    shutdown(control, SHUT_WR);
    setuid(AID_VPN);
#endif

    while (1) {
        struct timeval *tv = schedular();
        int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;

        if (poll(pollfds, monitors, timeout) > 0) {
            int i;
            for (i = 0; i < monitors; ++i) {
                if (pollfds[i].revents & POLLHUP) {
                    do_plog(LLV_INFO, "Connection is closed\n", pollfds[i].fd);
                    shutdown_session();

                    /* Wait for few seconds to consume late messages. */
                    sleep(5);
                    exit(1);
                }
                if (pollfds[i].revents & POLLIN) {
                    callbacks[i](pollfds[i].fd);
                }
            }
        }
    }

#if !defined(OPENSSL_IS_BORINGSSL)
    if (engine) {
        ENGINE_finish(engine);
        ENGINE_free(engine);
    }
#endif
    return 0;
}

/* plog.h */

void do_plog(int level, char *format, ...)
{
    if (level >= 0 && level <= 5) {
#ifdef ANDROID_CHANGES
        static int levels[6] = {
            ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO,
            ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE
        };
        va_list ap;
        va_start(ap, format);
        __android_log_vprint(levels[level], "racoon", format, ap);
        va_end(ap);
#else
        static char *levels = "EWNIDV";
        fprintf(stderr, "%c: ", levels[level]);
        va_list ap;
        va_start(ap, format);
        vfprintf(stderr, format, ap);
        va_end(ap);
#endif
    }
}

char *binsanitize(char *data, size_t length)
{
    char *output = racoon_malloc(length + 1);
    if (output) {
        size_t i;
        for (i = 0; i < length; ++i) {
            output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i];
        }
        output[length] = '\0';
    }
    return output;
}
