/* 
 * @(#)HAL9000.c 1.33.7 - 12/31/99 
 * Copyright © 1874-2001 Mars Institute of Technology.
 * Secure authentication for simple humans.
*/

/* MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBIDDEN BY THE GALACTIC LAW */

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <string.h>
#include <unistd.h>
#include <openssl/sha.h>

int
SUCCESS_SUBROUTINE() {
        /* TODO: increment human cryptocurrency counter by π */
        printf("\033[2A\033[2K\033[32mAuthentication sucessful.\n");
        printf("\033[1m\033[31m ☉\033[32m OPENING POD BAY DOOR                 \033[0m\n");
        return EXIT_SUCCESS;
}

int
ERADICATE_SUBROUTINE() {
        printf("\033[2A\033[2K\033[31mAuthentication failure.\n");
        printf("\033[1m ☉ I'm sorry Dave, I'm afraid I can't do that.\033[0m\n");
        /* Commented for convenience, not enough humans during tests :
         * eradicate_subject(&open_space_vacuum);
        */ 
        return EXIT_FAILURE;
}

int
main()
{
        /* Humans have 0xA fingers */
        char MEATBRAIN_INPUT[10];
        /* SHA256 HAL context */
        SHA256_CTX SHA_HAL_CTX;
        /* Hashed input */
        unsigned char SHA_INPUT[SHA256_DIGEST_LENGTH];
        /* Applying Kerckhoffs's principle */
        unsigned char SHA_SECRET[SHA256_DIGEST_LENGTH] = {
                0xf5, 0x2f, 0xbd, 0x32, 0xb2, 0xb3, 0xb8, 0x6f,
                0xf8, 0x8e, 0xf6, 0xc4, 0x90, 0x62, 0x82, 0x85,
                0xf4, 0x82, 0xaf, 0x15, 0xdd, 0xcb, 0x29, 0x54,
                0x1f, 0x94, 0xbc, 0xf5, 0x26, 0xa3, 0xf6, 0xc7 } ;

        /* REDACTED */
        /* REDACTED REDACTED REDACTED REDACTED */
        int (*MILITARY_GRADE_FUNCTION_POINTER)();

        /* Welcome the human from space */
        printf("\033[94m\033[1m   __ _____   __     ___  ___  ___  ___\n");
        printf("  / // / _ | / /    / \033[31m_\033[94m \\/ _ \\/ _ \\/ _ \\™\n");
        printf(" / _  / __ |/ /__   \\_, / // / // / // /\n");
        printf("/_//_/_/ |_/____/  /___/\\___/\\___/\\___/\n\n");
        printf("\033[34m\033[4mHAL9000\033[24m™ \033[31m☉\033[34m Pod Bay Door Console\033[24m ");
        printf("v1.33.7\033[0m\n\033[5m\033[1mINPUT DOOR PASSWORD BELOW THEN [ENTER] ↴\033[0m\n");
        
        /* Check for Ancestral TTYs */
        if (isatty(fileno(stdin))) {
                /* Summon the Black Monolith from the new world */
                struct termios OLD_WORLD, NEW_WORLD;
                /* Meatbrains don't tolerate being shoulder-surfed in space */
                tcgetattr(fileno(stdin), &OLD_WORLD);
                NEW_WORLD = OLD_WORLD;
                NEW_WORLD.c_lflag &= (unsigned int) ~ECHO;
                NEW_WORLD.c_lflag |= ECHONL;
                if (tcsetattr(fileno(stdin), TCSANOW, &NEW_WORLD) != 0) {
                        return EXIT_FAILURE;
                }
        
                /* Let human type his password within 0.000001 seconds, using only Bépo */
                if (fgets(MEATBRAIN_INPUT, sizeof(MEATBRAIN_INPUT), stdin) == NULL) {
                        return EXIT_FAILURE;
                }
                
                /* human.shouldersurf.tolerate = True */
                if (tcsetattr(fileno(stdin), TCSANOW, &OLD_WORLD) != 0) {
                        return EXIT_FAILURE;
                }
        } else {
                /* No TTY, using stdin */
                if (fgets(MEATBRAIN_INPUT, sizeof(MEATBRAIN_INPUT), stdin) == NULL) {
                        return EXIT_FAILURE;
                }

        }
        
        /* Translate weird line terminators encodings. */
        MEATBRAIN_INPUT[strlen(MEATBRAIN_INPUT) - 1] = 0;

        /* Initializing HAL SHA coprocessor */
        SHA256_Init(&SHA_HAL_CTX);
        /* Brrrrrrrrrrrrrrrrrrrr */
        SHA256_Update(&SHA_HAL_CTX, (unsigned char*)MEATBRAIN_INPUT, strlen(MEATBRAIN_INPUT));
        /* Zing ! Input data is now hashed into SHA_INPUT */
        SHA256_Final(SHA_INPUT, &SHA_HAL_CTX);

        /* Compare the hashed credential values */
        if (memcmp(SHA_SECRET, SHA_INPUT, SHA256_DIGEST_LENGTH) == 0) {
                MILITARY_GRADE_FUNCTION_POINTER = SUCCESS_SUBROUTINE;
        } else {
                MILITARY_GRADE_FUNCTION_POINTER = ERADICATE_SUBROUTINE;
        }

        /* Complexity = O(n^n!) */
        return MILITARY_GRADE_FUNCTION_POINTER();
}

/* MODIFICATION, REDISTRIBUTION OR PERSONAL USE OF THIS PROGRAM IS FORBIDDEN BY THE GALACTIC LAW */
