/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed 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.
 */

#include <assert.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fs_mgr.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>

#include <algorithm>
#include <thread>

#define LOG_TAG "VoldCryptCmdListener"

#include <android-base/logging.h>
#include <android-base/stringprintf.h>

#include <cutils/fs.h>
#include <cutils/log.h>
#include <cutils/sockets.h>

#include <sysutils/SocketClient.h>
#include <private/android_filesystem_config.h>

#include "CryptCommandListener.h"
#include "Process.h"
#include "ResponseCode.h"
#include "cryptfs.h"
#include "Ext4Crypt.h"
#include "MetadataCrypt.h"
#include "Utils.h"

#define DUMP_ARGS 0

CryptCommandListener::CryptCommandListener() :
FrameworkListener("cryptd", true) {
    registerCmd(new CryptfsCmd());
}

#if DUMP_ARGS
void CryptCommandListener::dumpArgs(int argc, char **argv, int argObscure) {
    char buffer[4096];
    char *p = buffer;

    memset(buffer, 0, sizeof(buffer));
    int i;
    for (i = 0; i < argc; i++) {
        unsigned int len = strlen(argv[i]) + 1; // Account for space
        if (i == argObscure) {
            len += 2; // Account for {}
        }
        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
            if (i == argObscure) {
                *p++ = '{';
                *p++ = '}';
                *p++ = ' ';
                continue;
            }
            strcpy(p, argv[i]);
            p+= strlen(argv[i]);
            if (i != (argc -1)) {
                *p++ = ' ';
            }
        }
    }
    SLOGD("%s", buffer);
}
#else
void CryptCommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
#endif

int CryptCommandListener::sendGenericOkFailOnBool(SocketClient *cli, bool success) {
    if (success) {
        return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
    } else {
        return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
    }
}

CryptCommandListener::CryptfsCmd::CryptfsCmd() :
                 VoldCommand("cryptfs") {
}

static int getType(const char* type)
{
    if (!strcmp(type, "default")) {
        return CRYPT_TYPE_DEFAULT;
    } else if (!strcmp(type, "password")) {
        return CRYPT_TYPE_PASSWORD;
    } else if (!strcmp(type, "pin")) {
        return CRYPT_TYPE_PIN;
    } else if (!strcmp(type, "pattern")) {
        return CRYPT_TYPE_PATTERN;
    } else {
        return -1;
    }
}

static char* parseNull(char* arg) {
    if (strcmp(arg, "!") == 0) {
        return nullptr;
    } else {
        return arg;
    }
}

static bool check_argc(SocketClient *cli, const std::string &subcommand, int argc,
        int expected, std::string usage) {
    assert(expected >= 2);
    if (expected == 2) {
        assert(usage.empty());
    } else {
        assert(!usage.empty());
        assert(std::count(usage.begin(), usage.end(), ' ') + 3 == expected);
    }
    if (argc == expected) {
        return true;
    }
    auto message = std::string() + "Usage: cryptfs " + subcommand;
    if (!usage.empty()) {
        message += " " + usage;
    }
    cli->sendMsg(ResponseCode::CommandSyntaxError, message.c_str(), false);
    return false;
}

static int do_enablecrypto(char* arg2, char* arg4, int type, bool no_ui) {
    int rc;
    int tries;
    for (tries = 0; tries < 2; ++tries) {
        if (type == CRYPT_TYPE_DEFAULT) {
            rc = cryptfs_enable_default(arg2, no_ui);
        } else {
            rc = cryptfs_enable(arg2, type, arg4, no_ui);
        }

        if (rc == 0) {
            free(arg2);
            free(arg4);
            return 0;
        } else if (tries == 0) {
            Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
        }
    }

    free(arg2);
    free(arg4);
    return -1;
}

int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
                                                 int argc, char **argv) {
    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run cryptfs commands", false);
        return 0;
    }

    if (argc < 2) {
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing subcommand", false);
        return 0;
    }

    int rc = 0;

    std::string subcommand(argv[1]);
    if (subcommand == "checkpw") {
        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
        dumpArgs(argc, argv, 2);
        rc = cryptfs_check_passwd(argv[2]);
    } else if (subcommand == "restart") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        dumpArgs(argc, argv, -1);

        // Spawn as thread so init can issue commands back to vold without
        // causing deadlock, usually as a result of prep_data_fs.
        std::thread(&cryptfs_restart).detach();
    } else if (subcommand == "cryptocomplete") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        dumpArgs(argc, argv, -1);
        rc = cryptfs_crypto_complete();
    } else if (subcommand == "enablecrypto") {
        if (e4crypt_is_native()) {
            if (argc != 5 || strcmp(argv[2], "inplace") || strcmp(argv[3], "default")
                    || strcmp(argv[4], "noui")) {
                cli->sendMsg(ResponseCode::CommandSyntaxError,
                        "Usage with ext4crypt: cryptfs enablecrypto inplace default noui", false);
                return 0;
            }
            return sendGenericOkFailOnBool(cli, e4crypt_enable_crypto());
        }
        const char* syntax = "Usage: cryptfs enablecrypto <wipe|inplace> "
                             "default|password|pin|pattern [passwd] [noui]";

        // This should be replaced with a command line parser if more options
        // are added
        bool valid = true;
        bool no_ui = false;
        int type = CRYPT_TYPE_DEFAULT;
        int options = 4; // Optional parameters are at this offset
        if (argc < 4) {
            // Minimum 4 parameters
            valid = false;
        } else if (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace") ) {
            // Second parameter must be wipe or inplace
            valid = false;
        } else {
            // Third parameter must be valid type
            type = getType(argv[3]);
            if (type == -1) {
                valid = false;
            } else if (type != CRYPT_TYPE_DEFAULT) {
                options++;
            }
        }

        if (valid) {
            if(argc < options) {
                // Too few parameters
                valid = false;
            } else if (argc == options) {
                // No more, done
            } else if (argc == options + 1) {
                // One option, must be noui
                if (!strcmp(argv[options], "noui")) {
                    no_ui = true;
                } else {
                    valid = false;
                }
            } else {
                // Too many options
                valid = false;
            }
        }

        if (!valid) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
            return 0;
        }

        dumpArgs(argc, argv, 4);

        // Spawn as thread so init can issue commands back to vold without
        // causing deadlock, usually as a result of prep_data_fs.
        char* arg2 = argc > 2 ? strdup(argv[2]) : NULL;
        char* arg4 = argc > 4 ? strdup(argv[4]) : NULL;
        std::thread(&do_enablecrypto, arg2, arg4, type, no_ui).detach();
    } else if (subcommand == "enablefilecrypto") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        dumpArgs(argc, argv, -1);
        rc = e4crypt_initialize_global_de();
    } else if (subcommand == "changepw") {
        const char* syntax = "Usage: cryptfs changepw "
                             "default|password|pin|pattern [newpasswd]";
        const char* password;
        if (argc == 3) {
            password = "";
        } else if (argc == 4) {
            password = argv[3];
        } else {
            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
            return 0;
        }
        int type = getType(argv[2]);
        if (type == -1) {
            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
            return 0;
        }
        SLOGD("cryptfs changepw %s {}", argv[2]);
        rc = cryptfs_changepw(type, password);
    } else if (subcommand == "verifypw") {
        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
        SLOGD("cryptfs verifypw {}");
        rc = cryptfs_verify_passwd(argv[2]);
    } else if (subcommand == "getfield") {
        if (!check_argc(cli, subcommand, argc, 3, "<fieldname>")) return 0;
        char *valbuf;
        int valbuf_len = PROPERTY_VALUE_MAX;

        dumpArgs(argc, argv, -1);

        // Increase the buffer size until it is big enough for the field value stored.
        while (1) {
            valbuf = (char*)malloc(valbuf_len);
            if (valbuf == NULL) {
                cli->sendMsg(ResponseCode::OperationFailed, "Failed to allocate memory", false);
                return 0;
            }
            rc = cryptfs_getfield(argv[2], valbuf, valbuf_len);
            if (rc != CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL) {
                break;
            }
            free(valbuf);
            valbuf_len *= 2;
        }
        if (rc == CRYPTO_GETFIELD_OK) {
            cli->sendMsg(ResponseCode::CryptfsGetfieldResult, valbuf, false);
        }
        free(valbuf);
    } else if (subcommand == "setfield") {
        if (!check_argc(cli, subcommand, argc, 4, "<fieldname> <value>")) return 0;
        dumpArgs(argc, argv, -1);
        rc = cryptfs_setfield(argv[2], argv[3]);
    } else if (subcommand == "mountdefaultencrypted") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        SLOGD("cryptfs mountdefaultencrypted");
        dumpArgs(argc, argv, -1);

        if (e4crypt_is_native()) {
            return sendGenericOkFailOnBool(cli, e4crypt_mount_metadata_encrypted());
        }
        // Spawn as thread so init can issue commands back to vold without
        // causing deadlock, usually as a result of prep_data_fs.
        std::thread(&cryptfs_mount_default_encrypted).detach();
    } else if (subcommand == "getpwtype") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        SLOGD("cryptfs getpwtype");
        dumpArgs(argc, argv, -1);
        switch(cryptfs_get_password_type()) {
        case CRYPT_TYPE_PASSWORD:
            cli->sendMsg(ResponseCode::PasswordTypeResult, "password", false);
            return 0;
        case CRYPT_TYPE_PATTERN:
            cli->sendMsg(ResponseCode::PasswordTypeResult, "pattern", false);
            return 0;
        case CRYPT_TYPE_PIN:
            cli->sendMsg(ResponseCode::PasswordTypeResult, "pin", false);
            return 0;
        case CRYPT_TYPE_DEFAULT:
            cli->sendMsg(ResponseCode::PasswordTypeResult, "default", false);
            return 0;
        default:
          /** @TODO better error and make sure handled by callers */
            cli->sendMsg(ResponseCode::OpFailedStorageNotFound, "Error", false);
            return 0;
        }
    } else if (subcommand == "getpw") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        SLOGD("cryptfs getpw");
        dumpArgs(argc, argv, -1);
        const char* password = cryptfs_get_password();
        if (password) {
            char* message = 0;
            int size = asprintf(&message, "{{sensitive}} %s", password);
            if (size != -1) {
                cli->sendMsg(ResponseCode::CommandOkay, message, false);
                memset(message, 0, size);
                free (message);
                return 0;
            }
        }
        rc = -1;
    } else if (subcommand == "clearpw") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        SLOGD("cryptfs clearpw");
        dumpArgs(argc, argv, -1);
        cryptfs_clear_password();
        rc = 0;

    } else if (subcommand == "isConvertibleToFBE") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        // ext4enc:TODO: send a CommandSyntaxError if argv[2] not an integer
        SLOGD("cryptfs isConvertibleToFBE");
        dumpArgs(argc, argv, -1);
        rc = cryptfs_isConvertibleToFBE();

    } else if (subcommand == "init_user0") {
        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_init_user0());

    } else if (subcommand == "create_user_key") {
        if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <ephemeral>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_vold_create_user_key(
            atoi(argv[2]), atoi(argv[3]), atoi(argv[4]) != 0));

    } else if (subcommand == "destroy_user_key") {
        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_destroy_user_key(atoi(argv[2])));

    } else if (subcommand == "add_user_key_auth") {
        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_add_user_key_auth(
            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));

    } else if (subcommand == "fixate_newest_user_key_auth") {
        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_fixate_newest_user_key_auth(atoi(argv[2])));

    } else if (subcommand == "unlock_user_key") {
        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_unlock_user_key(
            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));

    } else if (subcommand == "lock_user_key") {
        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_lock_user_key(atoi(argv[2])));

    } else if (subcommand == "prepare_user_storage") {
        if (!check_argc(cli, subcommand, argc, 6, "<uuid> <user> <serial> <flags>")) return 0;
        return sendGenericOkFailOnBool(cli, e4crypt_prepare_user_storage(
            parseNull(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])));

    } else if (subcommand == "destroy_user_storage") {
        if (!check_argc(cli, subcommand, argc, 5, "<uuid> <user> <flags>")) return 0;
        return sendGenericOkFailOnBool(cli,
                e4crypt_destroy_user_storage(parseNull(argv[2]), atoi(argv[3]), atoi(argv[4])));

    } else if (subcommand == "secdiscard") {
        if (!check_argc(cli, subcommand, argc, 3, "<path>")) return 0;
        return sendGenericOkFailOnBool(cli,
                e4crypt_secdiscard(parseNull(argv[2])));

    } else {
        dumpArgs(argc, argv, -1);
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs subcommand", false);
        return 0;
    }

    // Always report that the command succeeded and return the error code.
    // The caller will check the return value to see what the error was.
    char msg[255];
    snprintf(msg, sizeof(msg), "%d", rc);
    cli->sendMsg(ResponseCode::CommandOkay, msg, false);

    return 0;
}
