/* suites.c
 *
 * Copyright (C) 2006-2014 wolfSSL Inc.
 *
 * This file is part of CyaSSL.
 *
 * CyaSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * CyaSSL 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>
#endif

#include <cyassl/ctaocrypt/settings.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cyassl/ssl.h>
#include <tests/unit.h>


#define MAX_ARGS 40
#define MAX_COMMAND_SZ 240
#define MAX_SUITE_SZ 80 
#define NOT_BUILT_IN -123
#ifdef NO_OLD_TLS
    #define VERSION_TOO_OLD -124
#endif

#include "examples/client/client.h"
#include "examples/server/server.h"


static CYASSL_CTX* cipherSuiteCtx = NULL;
static char nonblockFlag[] = "-N";
static char noVerifyFlag[] = "-d";
static char portFlag[] = "-p";
static char flagSep[] = " ";
static char svrPort[] = "0";


#ifdef NO_OLD_TLS
/* if the protocol version is less than tls 1.2 return 1, else 0 */
static int IsOldTlsVersion(const char* line)
{
    const char* find = "-v ";
    char* begin = strstr(line, find);

    if (begin) {
        int version = -1;

        begin += 3;

        version = atoi(begin);

        if (version < 3)
            return 1;
    }

    return 0;
} 
#endif /* NO_OLD_TLS */


/* if the cipher suite on line is valid store in suite and return 1, else 0 */
static int IsValidCipherSuite(const char* line, char* suite)
{
    int  found = 0;
    int  valid = 0;

    const char* find = "-l ";
    const char* begin = strstr(line, find);
    const char* end;

    suite[0] = '\0';

    if (begin) {
        begin += 3;

        end = strstr(begin, " ");

        if (end) {
            long len = end - begin;
            if (len > MAX_SUITE_SZ) {
                printf("suite too long!\n");
                return 0;
            }
            memcpy(suite, begin, len);
            suite[len] = '\0';
        }
        else
            strncpy(suite, begin, MAX_SUITE_SZ);

        suite[MAX_SUITE_SZ] = '\0';
        found = 1;
    }

    if (found) {
        if (CyaSSL_CTX_set_cipher_list(cipherSuiteCtx, suite) == SSL_SUCCESS)
            valid = 1;
    }

    return valid;
}


static int execute_test_case(int svr_argc, char** svr_argv,
                              int cli_argc, char** cli_argv,
                              int addNoVerify, int addNonBlocking)
{
    func_args cliArgs = {cli_argc, cli_argv, 0, NULL, NULL};
    func_args svrArgs = {svr_argc, svr_argv, 0, NULL, NULL};

    tcp_ready   ready;
    THREAD_TYPE serverThread;
    char        commandLine[MAX_COMMAND_SZ];
    char        cipherSuite[MAX_SUITE_SZ+1];
    int         i;
    size_t      added = 0;
    static      int tests = 1;

    commandLine[0] = '\0';
    for (i = 0; i < svr_argc; i++) {
        added += strlen(svr_argv[i]) + 2;
        if (added >= MAX_COMMAND_SZ) {
            printf("server command line too long\n"); 
            break;
        }
        strcat(commandLine, svr_argv[i]);
        strcat(commandLine, flagSep);
    }

    if (IsValidCipherSuite(commandLine, cipherSuite) == 0) {
        #ifdef DEBUG_SUITE_TESTS
            printf("cipher suite %s not supported in build\n", cipherSuite);
        #endif
        return NOT_BUILT_IN;
    }

#ifdef NO_OLD_TLS
    if (IsOldTlsVersion(commandLine) == 1) {
        #ifdef DEBUG_SUITE_TESTS
            printf("protocol version on line %s is too old\n", commandLine);
        #endif
        return VERSION_TOO_OLD;
    }
#endif

    if (addNoVerify) {
        printf("repeating test with client cert request off\n"); 
        added += 4;   /* -d plus space plus terminator */
        if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
            printf("server command line too long\n");
        else {
            svr_argv[svr_argc++] = noVerifyFlag;
            svrArgs.argc = svr_argc;
            strcat(commandLine, noVerifyFlag);
            strcat(commandLine, flagSep);
        }
    }
    if (addNonBlocking) {
        printf("repeating test with non blocking on\n"); 
        added += 4;   /* -N plus terminator */
        if (added >= MAX_COMMAND_SZ || svr_argc >= MAX_ARGS)
            printf("server command line too long\n");
        else {
            svr_argv[svr_argc++] = nonblockFlag;
            svrArgs.argc = svr_argc;
            strcat(commandLine, nonblockFlag);
            strcat(commandLine, flagSep);
        }
    }
    #ifndef USE_WINDOWS_API
        /* add port 0 */
        if (svr_argc + 2 > MAX_ARGS)
            printf("cannot add the magic port number flag to server\n");
        else
        {
            svr_argv[svr_argc++] = portFlag;
            svr_argv[svr_argc++] = svrPort;
            svrArgs.argc = svr_argc;
        }
    #endif
    printf("trying server command line[%d]: %s\n", tests, commandLine);

    commandLine[0] = '\0';
    added = 0;
    for (i = 0; i < cli_argc; i++) {
        added += strlen(cli_argv[i]) + 2;
        if (added >= MAX_COMMAND_SZ) {
            printf("client command line too long\n"); 
            break;
        }
        strcat(commandLine, cli_argv[i]);
        strcat(commandLine, flagSep);
    }
    if (addNonBlocking) {
        added += 4;   /* -N plus space plus terminator  */
        if (added >= MAX_COMMAND_SZ)
            printf("client command line too long\n");
        else  {
            cli_argv[cli_argc++] = nonblockFlag;
            strcat(commandLine, nonblockFlag);
            strcat(commandLine, flagSep);
            cliArgs.argc = cli_argc;
        }
    }
    printf("trying client command line[%d]: %s\n", tests++, commandLine);

    InitTcpReady(&ready);

    /* start server */
    svrArgs.signal = &ready;
    start_thread(server_test, &svrArgs, &serverThread);
    wait_tcp_ready(&svrArgs);
    #ifndef USE_WINDOWS_API
        if (ready.port != 0)
        {
            if (cli_argc + 2 > MAX_ARGS)
                printf("cannot add the magic port number flag to client\n");
            else {
                char portNumber[8];
                snprintf(portNumber, sizeof(portNumber), "%d", ready.port);
                cli_argv[cli_argc++] = portFlag;
                cli_argv[cli_argc++] = portNumber;
                cliArgs.argc = cli_argc;
            }
        }
    #endif
    /* start client */
    client_test(&cliArgs);

    /* verify results */ 
    if (cliArgs.return_code != 0) {
        printf("client_test failed\n");
        exit(EXIT_FAILURE);
    }

    join_thread(serverThread);
    if (svrArgs.return_code != 0) { 
        printf("server_test failed\n");
        exit(EXIT_FAILURE);
    }

    FreeTcpReady(&ready);
    
    return 0;
}

static void test_harness(void* vargs)
{
    func_args* args = (func_args*)vargs;
    char* script;
    long  sz, len;
    int   cliMode = 0;   /* server or client command flag, server first */
    int   ret;
    FILE* file;
    char* svrArgs[MAX_ARGS];
    int   svrArgsSz;
    char* cliArgs[MAX_ARGS];
    int   cliArgsSz;
    char* cursor;
    char* comment;
    const char* fname = "tests/test.conf";

    if (args->argc == 1) {
        printf("notice: using default file %s\n", fname);
    }
    else if(args->argc != 2) {
        printf("usage: harness [FILE]\n");
        args->return_code = 1;
        return;
    }
    else {
        fname = args->argv[1];
    }

    file = fopen(fname, "r");
    if (file == NULL) {
        fprintf(stderr, "unable to open %s\n", fname);
        args->return_code = 1;
        return;
    }
    fseek(file, 0, SEEK_END);
    sz = ftell(file);
    rewind(file);
    if (sz <= 0) {
        fprintf(stderr, "%s is empty\n", fname);
        fclose(file);
        args->return_code = 1;
        return;
    }

    script = (char*)malloc(sz+1);
    if (script == 0) {
        fprintf(stderr, "unable to allocte script buffer\n");
        fclose(file);
        args->return_code = 1;
        return;
    }

    len = fread(script, 1, sz, file);
    if (len != sz) {
        fprintf(stderr, "read error\n");
        fclose(file);
        free(script);
        args->return_code = 1;
        return;
    }
    
    fclose(file);
    script[sz] = 0;

    cursor = script;
    svrArgsSz = 1;
    svrArgs[0] = args->argv[0];
    cliArgsSz = 1;
    cliArgs[0] = args->argv[0];

    while (*cursor != 0) {
        int do_it = 0;

        switch (*cursor) {
            case '\n':
                /* A blank line triggers test case execution or switches
                   to client mode if we don't have the client command yet */
                if (cliMode == 0)
                    cliMode = 1;  /* switch to client mode processing */
                else
                    do_it = 1;    /* Do It, we have server and client */
                cursor++;
                break;
            case '#':
                /* Ignore lines that start with a #. */
                comment = strsep(&cursor, "\n");
#ifdef DEBUG_SUITE_TESTS
                printf("%s\n", comment);
#else
                (void)comment;
#endif
                break;
            case '-':
                /* Parameters start with a -. They end in either a newline
                 * or a space. Capture until either, save in Args list. */
                if (cliMode)
                    cliArgs[cliArgsSz++] = strsep(&cursor, " \n");
                else
                    svrArgs[svrArgsSz++] = strsep(&cursor, " \n");
                break;
            default:
                /* Anything from cursor until end of line that isn't the above
                 * is data for a paramter. Just up until the next newline in
                 * the Args list. */
                if (cliMode)
                    cliArgs[cliArgsSz++] = strsep(&cursor, "\n");
                else
                    svrArgs[svrArgsSz++] = strsep(&cursor, "\n");
                if (*cursor == 0)  /* eof */
                    do_it = 1; 
        }

        if (svrArgsSz == MAX_ARGS || cliArgsSz == MAX_ARGS) {
            fprintf(stderr, "too many arguments, forcing test run\n");
            do_it = 1;
        }

        if (do_it) {
            ret = execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs,0,0);
            /* don't repeat if not supported in build */
            if (ret == 0) {
                execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 0, 1);
                execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 0);
                execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 1);
            }
            svrArgsSz = 1;
            cliArgsSz = 1;
            cliMode   = 0;
        }
    }

    free(script);
    args->return_code = 0;
}


int SuiteTest(void)
{
    func_args args;
    char argv0[2][80];
    char* myArgv[2];

    printf(" Begin Cipher Suite Tests\n");

    /* setup */
    myArgv[0] = argv0[0];
    myArgv[1] = argv0[1];
    args.argv = myArgv;
    strcpy(argv0[0], "SuiteTest");

    (void)test_harness;

    cipherSuiteCtx = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
    if (cipherSuiteCtx == NULL) {
        printf("can't get cipher suite ctx\n");
        exit(EXIT_FAILURE);  
    }

    /* default case */
    args.argc = 1;
    printf("starting default cipher suite tests\n");
    test_harness(&args);
    if (args.return_code != 0) {
        printf("error from script %d\n", args.return_code);
        exit(EXIT_FAILURE);  
    }

    /* any extra cases will need another argument */
    args.argc = 2;

#ifdef CYASSL_DTLS 
    /* add dtls extra suites */
    strcpy(argv0[1], "tests/test-dtls.conf");
    printf("starting dtls extra cipher suite tests\n");
    test_harness(&args);
    if (args.return_code != 0) {
        printf("error from script %d\n", args.return_code);
        exit(EXIT_FAILURE);  
    }
#endif

    printf(" End Cipher Suite Tests\n");

    CyaSSL_CTX_free(cipherSuiteCtx);

    return args.return_code;
}


