/*
 * iperf, Copyright (c) 2014-2020, The Regents of the University of
 * California, through Lawrence Berkeley National Laboratory (subject
 * to receipt of any required approvals from the U.S. Dept. of
 * Energy).  All rights reserved.
 *
 * If you have questions about your rights to use or distribute this
 * software, please contact Berkeley Lab's Technology Transfer
 * Department at TTD@lbl.gov.
 *
 * NOTICE.  This software is owned by the U.S. Department of Energy.
 * As such, the U.S. Government has been granted for itself and others
 * acting on its behalf a paid-up, nonexclusive, irrevocable,
 * worldwide license in the Software to reproduce, prepare derivative
 * works, and perform publicly and display publicly.  Beginning five
 * (5) years after the date permission to assert copyright is obtained
 * from the U.S. Department of Energy, and subject to any subsequent
 * five (5) year renewals, the U.S. Government is granted for itself
 * and others acting on its behalf a paid-up, nonexclusive,
 * irrevocable, worldwide license in the Software to reproduce,
 * prepare derivative works, distribute copies to the public, perform
 * publicly and display publicly, and to permit others to do so.
 *
 * This code is distributed under a BSD style license, see the LICENSE file
 * for complete information.
 */

#include "iperf_config.h"

#include <string.h>
#include <assert.h>
#include <time.h>
#include <sys/types.h>
/* FreeBSD needs _WITH_GETLINE to enable the getline() declaration */
#define _WITH_GETLINE
#include <stdio.h>
#include <termios.h>

#if defined(HAVE_SSL)

#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/buffer.h>
#include <openssl/err.h>

const char *auth_text_format = "user: %s\npwd:  %s\nts:   %ld";

void sha256(const char *string, char outputBuffer[65])
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, string, strlen(string));
    SHA256_Final(hash, &sha256);
    int i = 0;
    for(i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
    }
    outputBuffer[64] = 0;
}

int check_authentication(const char *username, const char *password, const time_t ts, const char *filename){
    time_t t = time(NULL);
    time_t utc_seconds = mktime(localtime(&t));
    if ( (utc_seconds - ts) > 10 || (utc_seconds - ts) < -10 ) {
        return 1;
    }

    char passwordHash[65];
    char salted[strlen(username) + strlen(password) + 3];
    sprintf(salted, "{%s}%s", username, password);
    sha256(&salted[0], passwordHash);

    char *s_username, *s_password;
    int i;
    FILE *ptr_file;
    char buf[1024];

    ptr_file =fopen(filename,"r");
    if (!ptr_file)
        return 2;

    while (fgets(buf,1024, ptr_file)){
        //strip the \n or \r\n chars
        for (i = 0; buf[i] != '\0'; i++){
            if (buf[i] == '\n' || buf[i] == '\r'){
                buf[i] = '\0';
                break;
            }
        }
        //skip empty / not completed / comment lines
        if (strlen(buf) == 0 || strchr(buf, ',') == NULL || buf[0] == '#'){
            continue;
        }
        s_username = strtok(buf, ",");
        s_password = strtok(NULL, ",");
        if (strcmp( username, s_username ) == 0 && strcmp( passwordHash, s_password ) == 0){
            fclose(ptr_file);
            return 0;
        }
    }
    fclose(ptr_file);
    return 3;
}


int Base64Encode(const unsigned char* buffer, const size_t length, char** b64text) { //Encodes a binary safe base 64 string
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
    BIO_write(bio, buffer, length);
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    *b64text = strndup( (*bufferPtr).data, (*bufferPtr).length );
    BIO_free_all(bio);

    return (0); //success
}

size_t calcDecodeLength(const char* b64input) { //Calculates the length of a decoded string
    size_t len = strlen(b64input), padding = 0;
    if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are =
        padding = 2;
    else if (b64input[len-1] == '=') //last char is =
        padding = 1;

    return (len*3)/4 - padding;
}

int Base64Decode(const char* b64message, unsigned char** buffer, size_t* length) { //Decodes a base64 encoded string
    BIO *bio, *b64;

    int decodeLen = calcDecodeLength(b64message);
    *buffer = (unsigned char*)malloc(decodeLen + 1);
    (*buffer)[decodeLen] = '\0';

    bio = BIO_new_mem_buf(b64message, -1);
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_push(b64, bio);

    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
    *length = BIO_read(bio, *buffer, strlen(b64message));
    assert(*length == decodeLen); //length should equal decodeLen, else something went horribly wrong
    BIO_free_all(bio);

    return (0); //success
}

EVP_PKEY *load_pubkey_from_file(const char *file) {
    BIO *key = NULL;
    EVP_PKEY *pkey = NULL;

    if (file) {
      key = BIO_new_file(file, "r");
      pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
 
      BIO_free(key);
    }
    return (pkey);
}   

EVP_PKEY *load_pubkey_from_base64(const char *buffer) {
    unsigned char *key = NULL;
    size_t key_len;
    Base64Decode(buffer, &key, &key_len);

    BIO* bio = BIO_new(BIO_s_mem());
    BIO_write(bio, key, key_len);
    free(key);
    EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return (pkey);
}

EVP_PKEY *load_privkey_from_file(const char *file) {
    BIO *key = NULL;
    EVP_PKEY *pkey = NULL;

    if (file) {
      key = BIO_new_file(file, "r");
      pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);

      BIO_free(key);
    }
    return (pkey);
}

EVP_PKEY *load_privkey_from_base64(const char *buffer) {
    unsigned char *key = NULL;
    size_t key_len;
    Base64Decode(buffer, &key, &key_len);

    BIO* bio = BIO_new(BIO_s_mem());
    BIO_write(bio, key, key_len);
    free(key);
    EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return (pkey);
}

int test_load_pubkey_from_file(const char *file){
    EVP_PKEY *key = load_pubkey_from_file(file);
    if (key == NULL){
        return -1;
    }
    EVP_PKEY_free(key);
    return 0;
}

int test_load_private_key_from_file(const char *file){
    EVP_PKEY *key = load_privkey_from_file(file);
    if (key == NULL){
        return -1;
    }
    EVP_PKEY_free(key);
    return 0;
}

int encrypt_rsa_message(const char *plaintext, EVP_PKEY *public_key, unsigned char **encryptedtext) {
    RSA *rsa = NULL;
    unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
    int keysize, encryptedtext_len, rsa_buffer_len;

    rsa = EVP_PKEY_get1_RSA(public_key);
    keysize = RSA_size(rsa);

    rsa_buffer  = OPENSSL_malloc(keysize * 2);
    *encryptedtext = (unsigned char*)OPENSSL_malloc(keysize);

    BIO *bioBuff   = BIO_new_mem_buf((void*)plaintext, (int)strlen(plaintext));
    rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
    encryptedtext_len = RSA_public_encrypt(rsa_buffer_len, rsa_buffer, *encryptedtext, rsa, pad);

    RSA_free(rsa);
    OPENSSL_free(rsa_buffer);
    BIO_free(bioBuff);

    if (encryptedtext_len < 0) {
      /* We probably shoudln't be printing stuff like this */
      fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
    }

    return encryptedtext_len;  
}

int decrypt_rsa_message(const unsigned char *encryptedtext, const int encryptedtext_len, EVP_PKEY *private_key, unsigned char **plaintext) {
    RSA *rsa = NULL;
    unsigned char *rsa_buffer = NULL, pad = RSA_PKCS1_PADDING;
    int plaintext_len, rsa_buffer_len, keysize;
    
    rsa = EVP_PKEY_get1_RSA(private_key);

    keysize = RSA_size(rsa);
    rsa_buffer  = OPENSSL_malloc(keysize * 2);
    *plaintext = (unsigned char*)OPENSSL_malloc(keysize);

    BIO *bioBuff   = BIO_new_mem_buf((void*)encryptedtext, encryptedtext_len);
    rsa_buffer_len = BIO_read(bioBuff, rsa_buffer, keysize * 2);
    plaintext_len = RSA_private_decrypt(rsa_buffer_len, rsa_buffer, *plaintext, rsa, pad);

    RSA_free(rsa);
    OPENSSL_free(rsa_buffer);
    BIO_free(bioBuff);

    if (plaintext_len < 0) {
      /* We probably shoudln't be printing stuff like this */
      fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));
    }

    return plaintext_len;
}

int encode_auth_setting(const char *username, const char *password, EVP_PKEY *public_key, char **authtoken){
    time_t t = time(NULL);
    time_t utc_seconds = mktime(localtime(&t));

    /*
     * Compute a pessimistic/conservative estimate of storage required.
     * It's OK to allocate too much storage but too little is bad.
     */
    const int text_len = strlen(auth_text_format) + strlen(username) + strlen(password) + 32;
    char *text = (char *) calloc(text_len, sizeof(char));
    if (text == NULL) {
	return -1;
    }
    snprintf(text, text_len, auth_text_format, username, password, utc_seconds);

    unsigned char *encrypted = NULL;
    int encrypted_len;
    encrypted_len = encrypt_rsa_message(text, public_key, &encrypted);
    free(text);
    if (encrypted_len < 0) {
      return -1;
    }
    Base64Encode(encrypted, encrypted_len, authtoken);
    OPENSSL_free(encrypted);

    return (0); //success
}

int decode_auth_setting(int enable_debug, const char *authtoken, EVP_PKEY *private_key, char **username, char **password, time_t *ts){
    unsigned char *encrypted_b64 = NULL;
    size_t encrypted_len_b64;
    Base64Decode(authtoken, &encrypted_b64, &encrypted_len_b64);        

    unsigned char *plaintext = NULL;
    int plaintext_len;
    plaintext_len = decrypt_rsa_message(encrypted_b64, encrypted_len_b64, private_key, &plaintext);
    free(encrypted_b64);
    if (plaintext_len < 0) {
        return -1;
    }
    plaintext[plaintext_len] = '\0';

    char *s_username, *s_password;
    s_username = (char *) calloc(plaintext_len, sizeof(char));
    if (s_username == NULL) {
	return -1;
    }
    s_password = (char *) calloc(plaintext_len, sizeof(char));
    if (s_password == NULL) {
	free(s_username);
	return -1;
    }

    int rc = sscanf((char *) plaintext, auth_text_format, s_username, s_password, ts);
    if (rc != 3) {
	free(s_password);
	free(s_username);
	return -1;
    }

    if (enable_debug) {
        printf("Auth Token Content:\n%s\n", plaintext);
        printf("Auth Token Credentials:\n--> %s %s\n", s_username, s_password);
    }
    *username = s_username;
    *password = s_password;
    OPENSSL_free(plaintext);
    return (0);
}

#endif //HAVE_SSL

ssize_t iperf_getpass (char **lineptr, size_t *n, FILE *stream) {
    struct termios old, new;
    ssize_t nread;

    /* Turn echoing off and fail if we can't. */
    if (tcgetattr (fileno (stream), &old) != 0)
        return -1;
    new = old;
    new.c_lflag &= ~ECHO;
    if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
        return -1;

    /* Read the password. */
    printf("Password: ");
    nread = getline (lineptr, n, stream);

    /* Restore terminal. */
    (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);

    //strip the \n or \r\n chars
    char *buf = *lineptr;
    int i;
    for (i = 0; buf[i] != '\0'; i++){
        if (buf[i] == '\n' || buf[i] == '\r'){
            buf[i] = '\0';
            break;
        }
    }

    return nread;
}


