/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *  Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
 *  Copyright (C) 2016-2018 David Sommerseth <davids@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#include "buffer.h"
#include "misc.h"
#include "base64.h"
#include "tun.h"
#include "error.h"
#include "otime.h"
#include "plugin.h"
#include "options.h"
#include "manage.h"
#include "crypto.h"
#include "route.h"
#include "console.h"
#include "win32.h"

#include "memdbg.h"

#ifdef ENABLE_IPROUTE
const char *iproute_path = IPROUTE_PATH; /* GLOBAL */
#endif

/*
 * Set standard file descriptors to /dev/null
 */
void
set_std_files_to_null(bool stdin_only)
{
#if defined(HAVE_DUP) && defined(HAVE_DUP2)
    int fd;
    if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
    {
        dup2(fd, 0);
        if (!stdin_only)
        {
            dup2(fd, 1);
            dup2(fd, 2);
        }
        if (fd > 2)
        {
            close(fd);
        }
    }
#endif
}

/*
 *  dup inetd/xinetd socket descriptor and save
 */

int inetd_socket_descriptor = SOCKET_UNDEFINED; /* GLOBAL */

void
save_inetd_socket_descriptor(void)
{
    inetd_socket_descriptor = INETD_SOCKET_DESCRIPTOR;
#if defined(HAVE_DUP) && defined(HAVE_DUP2)
    /* use handle passed by inetd/xinetd */
    if ((inetd_socket_descriptor = dup(INETD_SOCKET_DESCRIPTOR)) < 0)
    {
        msg(M_ERR, "INETD_SOCKET_DESCRIPTOR dup(%d) failed", INETD_SOCKET_DESCRIPTOR);
    }
    set_std_files_to_null(true);
#endif
}

/*
 * Prepend a random string to hostname to prevent DNS caching.
 * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
 * Of course, this requires explicit support in the DNS server (wildcard).
 */
const char *
hostname_randomize(const char *hostname, struct gc_arena *gc)
{
#define n_rnd_bytes 6

    uint8_t rnd_bytes[n_rnd_bytes];
    const char *rnd_str;
    struct buffer hname = alloc_buf_gc(strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);

    prng_bytes(rnd_bytes, sizeof(rnd_bytes));
    rnd_str = format_hex_ex(rnd_bytes, sizeof(rnd_bytes), 40, 0, NULL, gc);
    buf_printf(&hname, "%s.%s", rnd_str, hostname);
    return BSTR(&hname);
#undef n_rnd_bytes
}

#ifdef ENABLE_MANAGEMENT
/* Get username/password from the management interface */
static bool
auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags,
                    const char *auth_challenge)
{
    const char *sc = NULL;

    if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
    {
        management_auth_failure(management, prefix, "previous auth credentials failed");
    }

    if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
    {
        sc = auth_challenge;
    }
    if (!management_query_user_pass(management, up, prefix, flags, sc))
    {
        if ((flags & GET_USER_PASS_NOFATAL) != 0)
        {
            return false;
        }
        else
        {
            msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
        }
    }
    return true;
}
#endif /* ifdef ENABLE_MANAGEMENT */

/*
 * Get and store a username/password
 */

bool
get_user_pass_cr(struct user_pass *up,
                 const char *auth_file,
                 const char *prefix,
                 const unsigned int flags,
                 const char *auth_challenge)
{
    struct gc_arena gc = gc_new();

    if (!up->defined)
    {
        bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
        bool username_from_stdin = false;
        bool password_from_stdin = false;
        bool response_from_stdin = true;

        if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
        {
            msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
        }

#ifdef ENABLE_MANAGEMENT
        /*
         * Get username/password from management interface?
         */
        if (management
            && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
            && management_query_user_pass_enabled(management))
        {
            response_from_stdin = false;
            if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
            {
                return false;
            }
        }
        else
#endif /* ifdef ENABLE_MANAGEMENT */
        /*
         * Get NEED_OK confirmation from the console
         */
        if (flags & GET_USER_PASS_NEED_OK)
        {
            struct buffer user_prompt = alloc_buf_gc(128, &gc);

            buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
            if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
                                   up->password, USER_PASS_LEN, false))
            {
                msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
            }

            if (!strlen(up->password))
            {
                strcpy(up->password, "ok");
            }
        }
        else if (flags & GET_USER_PASS_INLINE_CREDS)
        {
            struct buffer buf;
            buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
            if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
            {
                buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
            }
            buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
        }
        /*
         * Read from auth file unless this is a dynamic challenge request.
         */
        else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
        {
            /*
             * Try to get username/password from a file.
             */
            FILE *fp;
            char password_buf[USER_PASS_LEN] = { '\0' };

            fp = platform_fopen(auth_file, "r");
            if (!fp)
            {
                msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
            }

            if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
            {
                /* Read username first */
                if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
                {
                    msg(M_FATAL, "Error reading username from %s authfile: %s",
                        prefix,
                        auth_file);
                }
            }
            chomp(up->username);

            if (fgets(password_buf, USER_PASS_LEN, fp) != NULL)
            {
                chomp(password_buf);
            }

            if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
            {
                msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
            }

            if (password_buf[0])
            {
                strncpy(up->password, password_buf, USER_PASS_LEN);
            }
            /* The auth-file does not have the password: get both username
             * and password from the management interface if possible.
             * Otherwise set to read password from console.
             */
#if defined(ENABLE_MANAGEMENT)
            else if (management
                     && (flags & GET_USER_PASS_MANAGEMENT)
                     && management_query_user_pass_enabled(management))
            {
                msg(D_LOW, "No password found in %s authfile '%s'. Querying the management interface", prefix, auth_file);
                if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
                {
                    return false;
                }
            }
#endif
            else
            {
                password_from_stdin = 1;
            }

            fclose(fp);

            if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
            {
                msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
            }
        }
        else
        {
            username_from_stdin = true;
            password_from_stdin = true;
        }

        /*
         * Get username/password from standard input?
         */
        if (username_from_stdin || password_from_stdin || response_from_stdin)
        {
#ifdef ENABLE_MANAGEMENT
            if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin)
            {
                struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc);
                if (ac)
                {
                    char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
                    struct buffer packed_resp, challenge;

                    challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc);
                    buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
                    buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);

                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
                                           response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
                    {
                        msg(M_FATAL, "ERROR: could not read challenge response from stdin");
                    }
                    strncpynt(up->username, ac->user, USER_PASS_LEN);
                    buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
                }
                else
                {
                    msg(M_FATAL, "ERROR: received malformed challenge request from server");
                }
            }
            else
#endif /* ifdef ENABLE_MANAGEMENT */
            {
                struct buffer user_prompt = alloc_buf_gc(128, &gc);
                struct buffer pass_prompt = alloc_buf_gc(128, &gc);

                query_user_clear();
                buf_printf(&user_prompt, "Enter %s Username:", prefix);
                buf_printf(&pass_prompt, "Enter %s Password:", prefix);

                if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
                {
                    query_user_add(BSTR(&user_prompt), BLEN(&user_prompt),
                                   up->username, USER_PASS_LEN, true);
                }

                if (password_from_stdin)
                {
                    query_user_add(BSTR(&pass_prompt), BLEN(&pass_prompt),
                                   up->password, USER_PASS_LEN, false);
                }

                if (!query_user_exec() )
                {
                    msg(M_FATAL, "ERROR: Failed retrieving username or password");
                }

                if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
                {
                    if (strlen(up->username) == 0)
                    {
                        msg(M_FATAL, "ERROR: %s username is empty", prefix);
                    }
                }

#ifdef ENABLE_MANAGEMENT
                if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin)
                {
                    char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
                    struct buffer packed_resp, challenge;
                    char *pw64 = NULL, *resp64 = NULL;

                    challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
                    buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);

                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
                                           response, USER_PASS_LEN,
                                           BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
                    {
                        msg(M_FATAL, "ERROR: could not retrieve static challenge response");
                    }
                    if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
                        || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
                    {
                        msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
                    }
                    buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
                    buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
                    string_clear(pw64);
                    free(pw64);
                    string_clear(resp64);
                    free(resp64);
                }
#endif /* ifdef ENABLE_MANAGEMENT */
            }
        }

        string_mod(up->username, CC_PRINT, CC_CRLF, 0);
        string_mod(up->password, CC_PRINT, CC_CRLF, 0);

        up->defined = true;
    }

#if 0
    msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
#endif

    gc_free(&gc);

    return true;
}

#ifdef ENABLE_MANAGEMENT

/*
 * See management/management-notes.txt for more info on the
 * the dynamic challenge/response protocol implemented here.
 */
struct auth_challenge_info *
get_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
{
    if (auth_challenge)
    {
        struct auth_challenge_info *ac;
        const int len = strlen(auth_challenge);
        char *work = (char *) gc_malloc(len+1, false, gc);
        char *cp;

        struct buffer b;
        buf_set_read(&b, (const uint8_t *)auth_challenge, len);

        ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);

        /* parse prefix */
        if (!buf_parse(&b, ':', work, len))
        {
            return NULL;
        }
        if (strcmp(work, "CRV1"))
        {
            return NULL;
        }

        /* parse flags */
        if (!buf_parse(&b, ':', work, len))
        {
            return NULL;
        }
        for (cp = work; *cp != '\0'; ++cp)
        {
            const char c = *cp;
            if (c == 'E')
            {
                ac->flags |= CR_ECHO;
            }
            else if (c == 'R')
            {
                ac->flags |= CR_RESPONSE;
            }
        }

        /* parse state ID */
        if (!buf_parse(&b, ':', work, len))
        {
            return NULL;
        }
        ac->state_id = string_alloc(work, gc);

        /* parse user name */
        if (!buf_parse(&b, ':', work, len))
        {
            return NULL;
        }
        ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
        openvpn_base64_decode(work, (void *)ac->user, -1);

        /* parse challenge text */
        ac->challenge_text = string_alloc(BSTR(&b), gc);

        return ac;
    }
    else
    {
        return NULL;
    }
}

#endif /* ifdef ENABLE_MANAGEMENT */

void
purge_user_pass(struct user_pass *up, const bool force)
{
    const bool nocache = up->nocache;
    static bool warn_shown = false;
    if (nocache || force)
    {
        secure_memzero(up, sizeof(*up));
        up->nocache = nocache;
    }
    /*
     * don't show warning if the pass has been replaced by a token: this is an
     * artificial "auth-nocache"
     */
    else if (!warn_shown)
    {
        msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
        warn_shown = true;
    }
}

void
set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token)
{

    if (strlen(token) && (up->defined || tk->defined))
    {
        /* auth-token has no password, so it needs the username
         * either already set or copied from up */
        strncpynt(tk->password, token, USER_PASS_LEN);
        if (up->defined)
        {
            strncpynt(tk->username, up->username, USER_PASS_LEN);
        }
        tk->defined = true;
    }

    /* Cleans user/pass for nocache */
    purge_user_pass(up, false);
}

/*
 * Process string received by untrusted peer before
 * printing to console or log file.
 *
 * Assumes that string has been null terminated.
 */
const char *
safe_print(const char *str, struct gc_arena *gc)
{
    return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
}

const char **
make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
{
    char **ret = NULL;
    int base = 0;
    const int max_parms = MAX_PARMS + 2;
    int n = 0;

    /* alloc return array */
    ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);

    /* process first parameter, if provided */
    if (first)
    {
        ret[base++] = string_alloc(first, gc);
    }

    if (parms)
    {
        n = parse_line(parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
        ASSERT(n >= 0 && n + base + 1 <= max_parms);
    }
    ret[base + n] = NULL;

    return (const char **)ret;
}

static const char **
make_inline_array(const char *str, struct gc_arena *gc)
{
    char line[OPTION_LINE_SIZE];
    struct buffer buf;
    int len = 0;
    char **ret = NULL;
    int i = 0;

    buf_set_read(&buf, (const uint8_t *) str, strlen(str));
    while (buf_parse(&buf, '\n', line, sizeof(line)))
    {
        ++len;
    }

    /* alloc return array */
    ALLOC_ARRAY_CLEAR_GC(ret, char *, len + 1, gc);

    buf_set_read(&buf, (const uint8_t *) str, strlen(str));
    while (buf_parse(&buf, '\n', line, sizeof(line)))
    {
        chomp(line);
        ASSERT(i < len);
        ret[i] = string_alloc(skip_leading_whitespace(line), gc);
        ++i;
    }
    ASSERT(i <= len);
    ret[i] = NULL;
    return (const char **)ret;
}

static const char **
make_arg_copy(char **p, struct gc_arena *gc)
{
    char **ret = NULL;
    const int len = string_array_len((const char **)p);
    const int max_parms = len + 1;
    int i;

    /* alloc return array */
    ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);

    for (i = 0; i < len; ++i)
    {
        ret[i] = p[i];
    }

    return (const char **)ret;
}

const char **
make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
{
    const int argc = string_array_len((const char **)p);
    if (is_inline)
    {
        return make_inline_array(p[0], gc);
    }
    else if (argc == 0)
    {
        return make_arg_array(NULL, NULL, gc);
    }
    else if (argc == 1)
    {
        return make_arg_array(p[0], NULL, gc);
    }
    else if (argc == 2)
    {
        return make_arg_array(p[0], p[1], gc);
    }
    else
    {
        return make_arg_copy(p, gc);
    }
}

/*
 * Remove security-sensitive strings from control message
 * so that they will not be output to log file.
 */
const char *
sanitize_control_message(const char *src, struct gc_arena *gc)
{
    char *ret = gc_malloc(strlen(src)+1, false, gc);
    char *dest = ret;
    bool redact = false;
    int skip = 0;

    for (;; )
    {
        const char c = *src;
        if (c == '\0')
        {
            break;
        }
        if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
        {
            skip = 7;
            redact = true;
        }
        else if (c == 'e' && !strncmp(src, "echo ", 5))
        {
            skip = 4;
            redact = true;
        }
        else if (!check_debug_level(D_SHOW_KEYS)
                 && (c == 'a' && !strncmp(src, "auth-token ", 11)))
        {
            /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
             * the auth-token value coming in the src string
             */
            skip = 10;
            redact = true;
        }

        if (c == ',') /* end of redacted item? */
        {
            skip = 0;
            redact = false;
        }

        if (redact)
        {
            if (skip > 0)
            {
                --skip;
                *dest++ = c;
            }
        }
        else
        {
            *dest++ = c;
        }

        ++src;
    }
    *dest = '\0';
    return ret;
}

/* helper to parse peer_info received from multi client, validate
 * (this is untrusted data) and put into environment
 */
bool
validate_peer_info_line(char *line)
{
    uint8_t c;
    int state = 0;
    while (*line)
    {
        c = *line;
        switch (state)
        {
            case 0:
            case 1:
                if (c == '=' && state == 1)
                {
                    state = 2;
                }
                else if (isalnum(c) || c == '_')
                {
                    state = 1;
                }
                else
                {
                    return false;
                }

            case 2:
                /* after the '=', replace non-printable or shell meta with '_' */
                if (!isprint(c) || isspace(c)
                    || c == '$' || c == '(' || c == '`')
                {
                    *line = '_';
                }
        }
        line++;
    }
    return (state == 2);
}

void
output_peer_info_env(struct env_set *es, const char *peer_info)
{
    char line[256];
    struct buffer buf;
    buf_set_read(&buf, (const uint8_t *) peer_info, strlen(peer_info));
    while (buf_parse(&buf, '\n', line, sizeof(line)))
    {
        chomp(line);
        if (validate_peer_info_line(line)
            && (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0) )
        {
            msg(M_INFO, "peer info: %s", line);
            env_set_add(es, line);
        }
        else
        {
            msg(M_WARN, "validation failed on peer_info line received from client");
        }
    }
}

int
get_num_elements(const char *string, char delimiter)
{
    int string_len = strlen(string);

    ASSERT(0 != string_len);

    int element_count = 1;
    /* Get number of ciphers */
    for (int i = 0; i < string_len; i++)
    {
        if (string[i] == delimiter)
        {
            element_count++;
        }
    }

    return element_count;
}

struct buffer
prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
{
    size_t len = strlen(dir) + strlen(PATH_SEPARATOR_STR) + strlen(path) + 1;
    struct buffer combined_path = alloc_buf_gc(len, gc);
    buf_printf(&combined_path, "%s%s%s", dir, PATH_SEPARATOR_STR, path);
    ASSERT(combined_path.len > 0);

    return combined_path;
}
