// Copyright (C) 2016 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program 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.

#include "android/base/files/PathUtils.h"
#include "android/base/files/ScopedFd.h"
#include "android/base/misc/FileUtils.h"
#include "android/base/misc/StringUtils.h"
#include "android/base/system/System.h"
#include "android/console_auth.h"
#include "android/console_auth_internal.h"
#include "android/misc/Random.h"
extern "C" {
#include "android/proxy/proxy_int.h"
}
#include "android/utils/debug.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/string.h"

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#ifndef _WIN32
#define O_BINARY 0
#endif

#define E(...) derror(__VA_ARGS__)

using android::base::System;
using android::base::ScopedFd;

namespace android {
namespace console_auth {

// creates a string suitable for use as an authentication token
// (text that is hard to guess)
bool tokenGenerate(std::string* auth_token) {
    char buf[12];  // 96 bit
    if (!android::generateRandomBytes(buf, sizeof(buf))) {
        return false;
    }

    const size_t kBase64Len = 4 * ((sizeof(buf) + 2) / 3);
    char base64[kBase64Len];
    int err = proxy_base64_encode(buf, sizeof(buf), base64, kBase64Len);
    if (err < 0) {
        E("proxy_base64_encode failed.  (What?)");
        return false;
    }

    auth_token->assign(base64, kBase64Len);
    return true;
}

// reads auth token from the specified path
// if the file does not exist, creates a file at the specified path
// and writes an auth token to it
//
// |path| is a separate parameter to make it unit testable
bool tokenLoadOrCreate(const std::string& path, std::string* auth_token) {
    // it is critical that this file only be readable by the current user
    // to prevent other users on the system from reading it and gaining access
    // to the emulator console
    const mode_t user_read_only = 0600;

    // this open will fail if the file already exists
    ScopedFd fd(HANDLE_EINTR(
            open(path.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_TRUNC | O_BINARY,
                 user_read_only)));
    if (fd.get() < 0) {
        // file already exists, read it
        ScopedFd read(HANDLE_EINTR(open(path.c_str(), O_RDONLY | O_BINARY)));
        if (read.get() < 0) {
            return false;
        }

        std::string file_contents;
        if (!android::readFileIntoString(read.get(), &file_contents)) {
            return false;
        }
        *auth_token = android::base::trim(file_contents);
    } else {
        if (!tokenGenerate(auth_token)) {
            fd.close();
            unlink(path.c_str());
            return false;
        }
        if (!android::writeStringToFile(fd.get(), *auth_token)) {
            E("Oh snap!  couldn't write ~/.emulator_console_auth_token");
            return false;
        }
    }
    return true;
}

// Returns a path to the console auth token file on the current system
std::string tokenGetPathDefault() {
    System* sys = System::get();
    return android::base::PathUtils::join(
            sys->getHomeDirectory(), ".emulator_console_auth_token");
}

fn_get_auth_token_path g_get_auth_token_path = tokenGetPathDefault;

// Gets/creates an auth token in the default path
bool tokenGet(std::string* auth_token) {
    return tokenLoadOrCreate(g_get_auth_token_path(), auth_token);
}

}  // namespace console_auth

}  // namespace android

char* android_console_auth_get_token_dup() {
    std::string auth_token;
    if (!android::console_auth::tokenGet(&auth_token)) {
        // couldn't get auth token, disable the console
        return nullptr;
    }

    return strdup(auth_token.c_str());
}

int android_console_auth_get_status() {
    std::string auth_token;
    if (!android::console_auth::tokenGet(&auth_token)) {
        // couldn't get auth token, disable the console
        return CONSOLE_AUTH_STATUS_ERROR;
    }

    if (auth_token.size() == 0) {
        // an empty auth token string means that auth isn't required
        return CONSOLE_AUTH_STATUS_DISABLED;
    }
    return CONSOLE_AUTH_STATUS_REQUIRED;
}

char* android_console_auth_token_path_dup() {
    std::string auth_token = android::console_auth::g_get_auth_token_path();
    return strdup(auth_token.c_str());
}
