/*
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <string.h>
#include <openssl/err.h>
#include <openssl/ui.h>
#include "apps_ui.h"

static UI_METHOD *ui_method = NULL;
static const UI_METHOD *ui_fallback_method = NULL;


static int ui_open(UI *ui)
{
    int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method);

    if (opener)
        return opener(ui);
    return 1;
}

static int ui_read(UI *ui, UI_STRING *uis)
{
    int (*reader)(UI *ui, UI_STRING *uis) = NULL;

    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
        && UI_get0_user_data(ui)) {
        switch (UI_get_string_type(uis)) {
        case UIT_PROMPT:
        case UIT_VERIFY:
            {
                const char *password =
                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
                if (password && password[0] != '\0') {
                    UI_set_result(ui, uis, password);
                    return 1;
                }
            }
            break;
        case UIT_NONE:
        case UIT_BOOLEAN:
        case UIT_INFO:
        case UIT_ERROR:
            break;
        }
    }

    reader = UI_method_get_reader(ui_fallback_method);
    if (reader)
        return reader(ui, uis);
    return 1;
}

static int ui_write(UI *ui, UI_STRING *uis)
{
    int (*writer)(UI *ui, UI_STRING *uis) = NULL;

    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
        && UI_get0_user_data(ui)) {
        switch (UI_get_string_type(uis)) {
        case UIT_PROMPT:
        case UIT_VERIFY:
            {
                const char *password =
                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
                if (password && password[0] != '\0')
                    return 1;
            }
            break;
        case UIT_NONE:
        case UIT_BOOLEAN:
        case UIT_INFO:
        case UIT_ERROR:
            break;
        }
    }

    writer = UI_method_get_writer(ui_fallback_method);
    if (writer)
        return writer(ui, uis);
    return 1;
}

static int ui_close(UI *ui)
{
    int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method);

    if (closer)
        return closer(ui);
    return 1;
}

int setup_ui_method(void)
{
    ui_fallback_method = UI_null();
#ifndef OPENSSL_NO_UI_CONSOLE
    ui_fallback_method = UI_OpenSSL();
#endif
    ui_method = UI_create_method("OpenSSL application user interface");
    UI_method_set_opener(ui_method, ui_open);
    UI_method_set_reader(ui_method, ui_read);
    UI_method_set_writer(ui_method, ui_write);
    UI_method_set_closer(ui_method, ui_close);
    return 0;
}

void destroy_ui_method(void)
{
    if (ui_method) {
        UI_destroy_method(ui_method);
        ui_method = NULL;
    }
}

const UI_METHOD *get_ui_method(void)
{
    return ui_method;
}

static void *ui_malloc(int sz, const char *what)
{
    void *vp = OPENSSL_malloc(sz);

    if (vp == NULL) {
        BIO_printf(bio_err, "Could not allocate %d bytes for %s\n", sz, what);
        ERR_print_errors(bio_err);
        exit(1);
    }
    return vp;
}

int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data)
{
    int res = 0;
    UI *ui;
    int ok = 0;
    char *buff = NULL;
    int ui_flags = 0;
    const char *prompt_info = NULL;
    char *prompt;

    if ((ui = UI_new_method(ui_method)) == NULL)
        return 0;

    if (cb_data != NULL && cb_data->prompt_info != NULL)
        prompt_info = cb_data->prompt_info;
    prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
    if (prompt == NULL) {
        BIO_printf(bio_err, "Out of memory\n");
        UI_free(ui);
        return 0;
    }

    ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
    UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);

    /* We know that there is no previous user data to return to us */
    (void)UI_add_user_data(ui, cb_data);

    ok = UI_add_input_string(ui, prompt, ui_flags, buf,
                             PW_MIN_LENGTH, bufsiz - 1);

    if (ok >= 0 && verify) {
        buff = ui_malloc(bufsiz, "password buffer");
        ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
                                  PW_MIN_LENGTH, bufsiz - 1, buf);
    }
    if (ok >= 0)
        do {
            ok = UI_process(ui);
        } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));

    OPENSSL_clear_free(buff, (unsigned int)bufsiz);

    if (ok >= 0)
        res = strlen(buf);
    if (ok == -1) {
        BIO_printf(bio_err, "User interface error\n");
        ERR_print_errors(bio_err);
        OPENSSL_cleanse(buf, (unsigned int)bufsiz);
        res = 0;
    }
    if (ok == -2) {
        BIO_printf(bio_err, "aborted!\n");
        OPENSSL_cleanse(buf, (unsigned int)bufsiz);
        res = 0;
    }
    UI_free(ui);
    OPENSSL_free(prompt);
    return res;
}
