/*************************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
//
// @@@ END COPYRIGHT @@@
 **************************************************************************/
//
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "security.h"
#include "secpwd.h"
#include "utils.h"
#include "drvrglobal.h"


#ifdef _WINDOWS
#define SEPARATOR "\\"
#else
#define SEPARATOR "/"
#endif

const int BUFSIZE = 1024;
    static void copyFile(char* source, char* target)
throw (SecurityException)
{
    FILE *in = fopen(source, "r");
    if ( in == NULL )
        throw SecurityException(ERR_READ_CERT_FILE, source);

    FILE *out = fopen(target, "w");
    if ( out == NULL )
        throw SecurityException(ERR_WRITE_CERT_FILE, target);

    char buf[BUFSIZE];
    while ( !feof(in) )
    {
        int bread = fread(buf, 1, BUFSIZE, in);
        if (bread == 0) break;
        int bwrite = fwrite(buf, 1, bread, out);
        if ( bread != bwrite )
        {
            fclose(in);
            fclose(out);
            throw SecurityException(ERR_WRITE_CERT_FILE, target);
        }
    }
    fclose(in);
    fclose(out);
}

static int compareFile(char* source, char* target)
{
    FILE *in = fopen(source, "r");
    FILE *out = fopen(target, "r");

    if ( in == NULL || out == NULL ) return 1;

    int retVal = 0;
    char inContent[BUFSIZE], outContent[BUFSIZE];
    while ( !feof(in) )
    {
        int bread_in = fread(inContent, 1, BUFSIZE, in);
        int bread_out = fread(outContent, 1, BUFSIZE, out);

        if ( bread_in != bread_out ||
                memcmp(inContent, outContent, bread_in) )
        {
            retVal = 1;
            break;
        }
    }
    fclose(in);
    fclose(out);
    return retVal;
}

static void TrimRight(char* str)
{
    // this function trims any unwanted spaces at the end of a string.

    char *buffer = str;

    int len = (int)strlen(buffer);
    int index = 0;

    for (index = len - 1; index >= 0; index--) {
        if ((index == 0) && (buffer[index] == ' ')) {
            buffer[index] = '\0';
            break;
        }
        if (buffer[index] != ' ') {
            buffer[index+1] = '\0';
            break;
        }
    }
}

static void TrimLeft(char *str)
{

    // this function trims any unwanted spaces at the beginning of a string.
    int len = strlen(str);
    char *buffer = new char[len + 1];
    strcpy(buffer, str);

    int index = 0;

    for (index = 0; index < len; index++) {
        if ((index == len - 1) && (buffer[index] == ' ')) {
            buffer[0] = '\0';
            strcpy(str ,buffer);
            break;
        }
        if (buffer[index]!= ' ') {
            strcpy(str,buffer+index);
            break;
        }
    }

    delete buffer;
}

#define CER ".cer"
#define ACTIVE_CER ".cer"

static char* buildName(const char* dir, const char* fileName, const char* serverName, const char* suffix)
{
    char *fname = NULL;
    int srvrNmLen = strlen(serverName);
    int sfxLen = strlen(suffix);
    int dirLen = strlen(dir);

    int len = dirLen + strlen(SEPARATOR);
    int fNmLen = srvrNmLen + sfxLen + 1;

    fname = new char[fNmLen];   // Runtime determine the buffer length of the cert file name

    if ( fileName == NULL )
    {
        strcpy_s(fname, fNmLen, serverName);
        strcat_s(fname, fNmLen, suffix);
        fileName = fname;
        len += strlen(fname) + 1;
    }
    else len += strlen(fileName) + 1;

    char* path = new char[len];
    sprintf(path, "%s%s%s\0", dir, SEPARATOR, fileName);
    delete[] fname;

    return path;
}

SecPwd::SecPwd(const char *dir, const char* fileName,
        const char* activeFileName,
        const char* serverName) throw (SecurityException)
: m_sec(NULL), certFile(NULL), activeCertFile(NULL)
{
    char* dir_from_env = NULL;
    char  certDir[MAX_SQL_IDENTIFIER_LEN + 1];

    if (serverName == NULL)
        throw SecurityException (INPUT_PARAMETER_IS_NULL, " - serverName.");

    dir = (dir != NULL) ? dir : getenv("HOME");

    if (dir == NULL)
    {
        //Check HOMEDRIVE (or HOMEDRIVE + HOMEPATH ) for interix
        char *hmdrive=getenv("HOMEDRIVE");
        char *hmpath=getenv("HOMEPATH");
        if (hmdrive != NULL && hmpath != NULL)
        {
            // Fix solution #10-090803-8661
            TrimLeft(hmdrive);
            TrimRight(hmdrive);
            TrimLeft(hmpath);
            TrimRight(hmpath);
            dir_from_env = new char[strlen(hmdrive) + strlen(hmpath) + 1];
            sprintf((char *)dir_from_env, "%s%s\0", hmdrive, hmpath);
        }
        else
            throw SecurityException (HOME_ENVIRONMENT_VAR_IS_NULL, NULL);
    }
    else
    {
        TrimLeft((char *)dir);
        TrimRight((char *)dir);
    }
    if(dir != NULL)
        strncpy(certDir, dir, sizeof(certDir));
    else
    {
        strncpy(certDir, dir_from_env, sizeof(certDir));
        certDir[sizeof(certDir) -1] = '\0';
        delete[] dir_from_env;
    }

    struct stat st;
    if(stat(certDir,&st) != 0)
        throw SecurityException(DIR_NOTFOUND, (char *)certDir);

    certFile = buildName(certDir, fileName, serverName, CER);
    activeCertFile = buildName(certDir, activeFileName, serverName, ACTIVE_CER);

    // If activeCertFile does not exist and certFile exist, create activeCertFile
    // by from copying certFile to activeCertFile
    struct stat certStats;
    struct stat aCertStats;

    if ( (stat(certFile, &certStats) == 0 ) &&
            (stat(activeCertFile, &aCertStats) != 0 ))
        copyFile(certFile, activeCertFile);
}

void SecPwd::openCertificate() throw (SecurityException)
{
    if(m_sec != NULL)
    {
        delete m_sec;
        m_sec = NULL;
    }
    m_sec = new Security(activeCertFile);
}

SecPwd::~SecPwd()
{
    delete certFile;
    delete activeCertFile;
    if(m_sec != NULL)
    {
        delete m_sec;
        m_sec = NULL;
    }
}
void SecPwd::encryptPwd(const char *pwd, const int pwdLen,
        const char *rolename, const int rolenameLen,
        const char *procInfo, const int procInfoLen,
        char *pwdkey, int *pwdkeyLen)
throw (SecurityException)
{
    // rolename is optional so can be NULL
    if (!pwd)
        throw SecurityException(INPUT_PARAMETER_IS_NULL, " - pwd.");
    if (!pwdkey)
        throw SecurityException(INPUT_PARAMETER_IS_NULL, " - pwdkey.");
    if (!procInfo)
        throw SecurityException(INPUT_PARAMETER_IS_NULL, " - procInfo.");
    if (*pwdkeyLen != m_sec->getPwdEBufferLen())
        throw SecurityException(BAD_PWDKEY_LENGTH, NULL);

    // If Little Endian, swap the 2 cpu bytes and the 2 pin bytes of the PprocInfo
    if (!m_sec->getLittleEndian())
    {
        ProcInfo *pI = (ProcInfo *) procInfo;
        ProcInfo *pInfo = new ProcInfo;

        pInfo->cpu = swapByteOrderOfS((unsigned int)pI->cpu);
        pInfo->pin = swapByteOrderOfS((unsigned int)pI->pin);
        //	  memcpy((char*)pInfo->seg_name, (char *)pI->seg_name, sizeof(pInfo->seg_name));
        pInfo->timestamp = (long long)swapByteOrderOfLL((unsigned long long)pI->timestamp);
        m_sec->encryptPwd(pwd, pwdLen, rolename, rolenameLen,
                (char *)pInfo, procInfoLen, pwdkey, pwdkeyLen);
        delete pInfo;
    }
    else
        m_sec->encryptPwd(pwd, pwdLen, rolename, rolenameLen,
                procInfo, procInfoLen, pwdkey, pwdkeyLen);
}


int SecPwd::getPwdEBufferLen() throw (SecurityException)
{
    return (m_sec->getPwdEBufferLen());
}

unsigned char* SecPwd::getCertExpDate()
{
    return m_sec->getCertExpDate();
}


    void SecPwd::switchCertificate(char* content, int len)
throw (SecurityException)
{
    FILE *out = fopen(activeCertFile, "w");
    if ( out == NULL )
        throw SecurityException(ERR_WRITE_CERT_FILE, activeCertFile);

    int bwrite = fwrite(content, 1, len, out);

    fclose(out);
    if ( bwrite != len )
        throw SecurityException(ERR_WRITE_CERT_FILE, activeCertFile);

    if(m_sec != NULL)
    {
        delete m_sec;
        m_sec = NULL;
    }
    m_sec = new Security(activeCertFile);
}

int SecPwd::switchCertificate() throw (SecurityException)
{
    // If same name, then no point trying to switch.
    if (strcmp(certFile, activeCertFile) == 0) return 1;

    struct stat inFileStats;
    struct stat outFileStats;
    int retVal = 0;

    if ( stat(certFile, &inFileStats) == 0 )
    {
        if ( stat(activeCertFile, &outFileStats) == 0 )
        {
            // if both files exist and they differ, then copy
            if ( inFileStats.st_size != outFileStats.st_size ||
                    compareFile(activeCertFile, certFile)   )
            {
                copyFile(certFile, activeCertFile);
            }
            else
            {
                // file with same content, don't switch.
                retVal = 1;
            }
        }
        else
        {
            // activeCertFile doesn't exist, copy from certFile
            copyFile(certFile, activeCertFile);
        }
    }
    else retVal = 1;

    if ( retVal == 0 )
    {
        delete m_sec;
        m_sec = new Security(activeCertFile);
    }
    return retVal;
}

char* SecPwd::getCertFile()
{
    return certFile;
}

char* SecPwd::getActiveCertFile()
{
    return activeCertFile;
}

