/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <getopt.h>

#include "ask-password-api.h"
#include "cryptenroll-fido2.h"
#include "cryptenroll-list.h"
#include "cryptenroll-password.h"
#include "cryptenroll-pkcs11.h"
#include "cryptenroll-recovery.h"
#include "cryptenroll-tpm2.h"
#include "cryptenroll-wipe.h"
#include "cryptenroll.h"
#include "cryptsetup-util.h"
#include "escape.h"
#include "libfido2-util.h"
#include "main-func.h"
#include "memory-util.h"
#include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h"
#include "pkcs11-util.h"
#include "pretty-print.h"
#include "string-table.h"
#include "strv.h"
#include "terminal-util.h"
#include "tpm2-util.h"

static EnrollType arg_enroll_type = _ENROLL_TYPE_INVALID;
static char *arg_pkcs11_token_uri = NULL;
static char *arg_fido2_device = NULL;
static char *arg_tpm2_device = NULL;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static char *arg_node = NULL;
static int *arg_wipe_slots = NULL;
static size_t arg_n_wipe_slots = 0;
static WipeScope arg_wipe_slots_scope = WIPE_EXPLICIT;
static unsigned arg_wipe_slots_mask = 0; /* Bitmask of (1U << EnrollType), for wiping all slots of specific types */
static Fido2EnrollFlags arg_fido2_lock_with = FIDO2ENROLL_PIN | FIDO2ENROLL_UP;

assert_cc(sizeof(arg_wipe_slots_mask) * 8 >= _ENROLL_TYPE_MAX);

STATIC_DESTRUCTOR_REGISTER(arg_pkcs11_token_uri, freep);
STATIC_DESTRUCTOR_REGISTER(arg_fido2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
STATIC_DESTRUCTOR_REGISTER(arg_node, freep);

static bool wipe_requested(void) {
        return arg_n_wipe_slots > 0 ||
                arg_wipe_slots_scope != WIPE_EXPLICIT ||
                arg_wipe_slots_mask != 0;
}

static const char* const enroll_type_table[_ENROLL_TYPE_MAX] = {
        [ENROLL_PASSWORD] = "password",
        [ENROLL_RECOVERY] = "recovery",
        [ENROLL_PKCS11] = "pkcs11",
        [ENROLL_FIDO2] = "fido2",
        [ENROLL_TPM2] = "tpm2",
};

DEFINE_STRING_TABLE_LOOKUP(enroll_type, EnrollType);

static const char *const luks2_token_type_table[_ENROLL_TYPE_MAX] = {
        /* ENROLL_PASSWORD has no entry here, as slots of this type do not have a token in the LUKS2 header */
        [ENROLL_RECOVERY] = "systemd-recovery",
        [ENROLL_PKCS11] = "systemd-pkcs11",
        [ENROLL_FIDO2] = "systemd-fido2",
        [ENROLL_TPM2] = "systemd-tpm2",
};

DEFINE_STRING_TABLE_LOOKUP(luks2_token_type, EnrollType);

static int help(void) {
        _cleanup_free_ char *link = NULL;
        int r;

        r = terminal_urlify_man("systemd-cryptenroll", "1", &link);
        if (r < 0)
                return log_oom();

        printf("%s [OPTIONS...] BLOCK-DEVICE\n"
               "\n%sEnroll a security token or authentication credential to a LUKS volume.%s\n\n"
               "  -h --help            Show this help\n"
               "     --version         Show package version\n"
               "     --password        Enroll a user-supplied password\n"
               "     --recovery-key    Enroll a recovery key\n"
               "     --pkcs11-token-uri=URI\n"
               "                       Specify PKCS#11 security token URI\n"
               "     --fido2-device=PATH\n"
               "                       Enroll a FIDO2-HMAC security token\n"
               "     --fido2-with-client-pin=BOOL\n"
               "                       Whether to require entering a PIN to unlock the volume\n"
               "     --fido2-with-user-presence=BOOL\n"
               "                       Whether to require user presence to unlock the volume\n"
               "     --fido2-with-user-verification=BOOL\n"
               "                       Whether to require user verification to unlock the volume\n"
               "     --tpm2-device=PATH\n"
               "                       Enroll a TPM2 device\n"
               "     --tpm2-pcrs=PCR1+PCR2+PCR3+…\n"
               "                       Specify TPM2 PCRs to seal against\n"
               "     --wipe-slot=SLOT1,SLOT2,…\n"
               "                       Wipe specified slots\n"
               "\nSee the %s for details.\n",
               program_invocation_short_name,
               ansi_highlight(),
               ansi_normal(),
               link);

        return 0;
}

static int parse_argv(int argc, char *argv[]) {

        enum {
                ARG_VERSION = 0x100,
                ARG_PASSWORD,
                ARG_RECOVERY_KEY,
                ARG_PKCS11_TOKEN_URI,
                ARG_FIDO2_DEVICE,
                ARG_TPM2_DEVICE,
                ARG_TPM2_PCRS,
                ARG_WIPE_SLOT,
                ARG_FIDO2_WITH_PIN,
                ARG_FIDO2_WITH_UP,
                ARG_FIDO2_WITH_UV,
        };

        static const struct option options[] = {
                { "help",                         no_argument,       NULL, 'h'                  },
                { "version",                      no_argument,       NULL, ARG_VERSION          },
                { "password",                     no_argument,       NULL, ARG_PASSWORD         },
                { "recovery-key",                 no_argument,       NULL, ARG_RECOVERY_KEY     },
                { "pkcs11-token-uri",             required_argument, NULL, ARG_PKCS11_TOKEN_URI },
                { "fido2-device",                 required_argument, NULL, ARG_FIDO2_DEVICE     },
                { "fido2-with-client-pin",        required_argument, NULL, ARG_FIDO2_WITH_PIN   },
                { "fido2-with-user-presence",     required_argument, NULL, ARG_FIDO2_WITH_UP    },
                { "fido2-with-user-verification", required_argument, NULL, ARG_FIDO2_WITH_UV    },
                { "tpm2-device",                  required_argument, NULL, ARG_TPM2_DEVICE      },
                { "tpm2-pcrs",                    required_argument, NULL, ARG_TPM2_PCRS        },
                { "wipe-slot",                    required_argument, NULL, ARG_WIPE_SLOT        },
                {}
        };

        int c, r;

        assert(argc >= 0);
        assert(argv);

        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {

                switch (c) {

                case 'h':
                        return help();

                case ARG_VERSION:
                        return version();

                case ARG_FIDO2_WITH_PIN: {
                        bool lock_with_pin;

                        r = parse_boolean_argument("--fido2-with-client-pin=", optarg, &lock_with_pin);
                        if (r < 0)
                                return r;

                        SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_PIN, lock_with_pin);
                        break;
                }

                case ARG_FIDO2_WITH_UP: {
                        bool lock_with_up;

                        r = parse_boolean_argument("--fido2-with-user-presence=", optarg, &lock_with_up);
                        if (r < 0)
                                return r;

                        SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_UP, lock_with_up);
                        break;
                }

                case ARG_FIDO2_WITH_UV: {
                        bool lock_with_uv;

                        r = parse_boolean_argument("--fido2-with-user-verification=", optarg, &lock_with_uv);
                        if (r < 0)
                                return r;

                        SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_UV, lock_with_uv);
                        break;
                }

                case ARG_PASSWORD:
                        if (arg_enroll_type >= 0)
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                       "Multiple operations specified at once, refusing.");

                        arg_enroll_type = ENROLL_PASSWORD;
                        break;

                case ARG_RECOVERY_KEY:
                        if (arg_enroll_type >= 0)
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                       "Multiple operations specified at once, refusing.");

                        arg_enroll_type = ENROLL_RECOVERY;
                        break;

                case ARG_PKCS11_TOKEN_URI: {
                        _cleanup_free_ char *uri = NULL;

                        if (streq(optarg, "list"))
                                return pkcs11_list_tokens();

                        if (arg_enroll_type >= 0 || arg_pkcs11_token_uri)
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                       "Multiple operations specified at once, refusing.");

                        if (streq(optarg, "auto")) {
                                r = pkcs11_find_token_auto(&uri);
                                if (r < 0)
                                        return r;
                        } else {
                                if (!pkcs11_uri_valid(optarg))
                                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid PKCS#11 URI: %s", optarg);

                                uri = strdup(optarg);
                                if (!uri)
                                        return log_oom();
                        }

                        arg_enroll_type = ENROLL_PKCS11;
                        arg_pkcs11_token_uri = TAKE_PTR(uri);
                        break;
                }

                case ARG_FIDO2_DEVICE: {
                        _cleanup_free_ char *device = NULL;

                        if (streq(optarg, "list"))
                                return fido2_list_devices();

                        if (arg_enroll_type >= 0 || arg_fido2_device)
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                       "Multiple operations specified at once, refusing.");

                        if (streq(optarg, "auto")) {
                                r = fido2_find_device_auto(&device);
                                if (r < 0)
                                        return r;
                        } else {
                                device = strdup(optarg);
                                if (!device)
                                        return log_oom();
                        }

                        arg_enroll_type = ENROLL_FIDO2;
                        arg_fido2_device = TAKE_PTR(device);
                        break;
                }

                case ARG_TPM2_DEVICE: {
                        _cleanup_free_ char *device = NULL;

                        if (streq(optarg, "list"))
                                return tpm2_list_devices();

                        if (arg_enroll_type >= 0 || arg_tpm2_device)
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                       "Multiple operations specified at once, refusing.");

                        if (!streq(optarg, "auto")) {
                                device = strdup(optarg);
                                if (!device)
                                        return log_oom();
                        }

                        arg_enroll_type = ENROLL_TPM2;
                        arg_tpm2_device = TAKE_PTR(device);
                        break;
                }

                case ARG_TPM2_PCRS: {
                        uint32_t mask;

                        if (isempty(optarg)) {
                                arg_tpm2_pcr_mask = 0;
                                break;
                        }

                        r = tpm2_parse_pcrs(optarg, &mask);
                        if (r < 0)
                                return r;

                        if (arg_tpm2_pcr_mask == UINT32_MAX)
                                arg_tpm2_pcr_mask = mask;
                        else
                                arg_tpm2_pcr_mask |= mask;

                        break;
                }

                case ARG_WIPE_SLOT: {
                        const char *p = optarg;

                        if (isempty(optarg)) {
                                arg_wipe_slots_mask = 0;
                                arg_wipe_slots_scope = WIPE_EXPLICIT;
                                break;
                        }

                        for (;;) {
                                _cleanup_free_ char *slot = NULL;
                                unsigned n;

                                r = extract_first_word(&p, &slot, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
                                if (r == 0)
                                        break;
                                if (r < 0)
                                        return log_error_errno(r, "Failed to parse slot list: %s", optarg);

                                if (streq(slot, "all"))
                                        arg_wipe_slots_scope = WIPE_ALL;
                                else if (streq(slot, "empty")) {
                                        if (arg_wipe_slots_scope != WIPE_ALL) /* if "all" was specified before, that wins */
                                                arg_wipe_slots_scope = WIPE_EMPTY_PASSPHRASE;
                                } else if (streq(slot, "password"))
                                        arg_wipe_slots_mask = 1U << ENROLL_PASSWORD;
                                else if (streq(slot, "recovery"))
                                        arg_wipe_slots_mask = 1U << ENROLL_RECOVERY;
                                else if (streq(slot, "pkcs11"))
                                        arg_wipe_slots_mask = 1U << ENROLL_PKCS11;
                                else if (streq(slot, "fido2"))
                                        arg_wipe_slots_mask = 1U << ENROLL_FIDO2;
                                else if (streq(slot, "tpm2"))
                                        arg_wipe_slots_mask = 1U << ENROLL_TPM2;
                                else {
                                        int *a;

                                        r = safe_atou(slot, &n);
                                        if (r < 0)
                                                return log_error_errno(r, "Failed to parse slot index: %s", slot);
                                        if (n > INT_MAX)
                                                return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Slot index out of range: %u", n);

                                        a = reallocarray(arg_wipe_slots, sizeof(int), arg_n_wipe_slots + 1);
                                        if (!a)
                                                return log_oom();

                                        arg_wipe_slots = a;
                                        arg_wipe_slots[arg_n_wipe_slots++] = (int) n;
                                }
                        }
                        break;
                }

                case '?':
                        return -EINVAL;

                default:
                        assert_not_reached("Unhandled option");
                }
        }

        if (optind >= argc)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                       "No block device node specified, refusing.");

        if (argc > optind+1)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                       "Too many arguments, refusing.");

        r = parse_path_argument(argv[optind], false, &arg_node);
        if (r < 0)
                return r;

        if (arg_tpm2_pcr_mask == UINT32_MAX)
                arg_tpm2_pcr_mask = TPM2_PCR_MASK_DEFAULT;

        return 1;
}

static int prepare_luks(
                struct crypt_device **ret_cd,
                void **ret_volume_key,
                size_t *ret_volume_key_size) {

        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
        _cleanup_(erase_and_freep) void *vk = NULL;
        char *e = NULL;
        size_t vks;
        int r;

        assert(ret_cd);
        assert(!ret_volume_key == !ret_volume_key_size);

        r = crypt_init(&cd, arg_node);
        if (r < 0)
                return log_error_errno(r, "Failed to allocate libcryptsetup context: %m");

        cryptsetup_enable_logging(cd);

        r = crypt_load(cd, CRYPT_LUKS2, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to load LUKS2 superblock: %m");

        if (!ret_volume_key) {
                *ret_cd = TAKE_PTR(cd);
                return 0;
        }

        r = crypt_get_volume_key_size(cd);
        if (r <= 0)
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
        vks = (size_t) r;

        vk = malloc(vks);
        if (!vk)
                return log_oom();

        e = getenv("PASSWORD");
        if (e) {
                _cleanup_(erase_and_freep) char *password = NULL;

                password = strdup(e);
                if (!password)
                        return log_oom();

                string_erase(e);
                assert_se(unsetenv("PASSWORD") >= 0);

                r = crypt_volume_key_get(
                                cd,
                                CRYPT_ANY_SLOT,
                                vk,
                                &vks,
                                password,
                                strlen(password));
                if (r < 0)
                        return log_error_errno(r, "Password from environment variable $PASSWORD did not work.");
        } else {
                AskPasswordFlags ask_password_flags = ASK_PASSWORD_PUSH_CACHE|ASK_PASSWORD_ACCEPT_CACHED;
                _cleanup_free_ char *question = NULL, *disk_path = NULL;
                unsigned i = 5;
                const char *id;

                question = strjoin("Please enter current passphrase for disk ", arg_node, ":");
                if (!question)
                        return log_oom();

                disk_path = cescape(arg_node);
                if (!disk_path)
                        return log_oom();

                id = strjoina("cryptsetup:", disk_path);

                for (;;) {
                        _cleanup_strv_free_erase_ char **passwords = NULL;
                        char **p;

                        if (--i == 0)
                                return log_error_errno(SYNTHETIC_ERRNO(ENOKEY),
                                                       "Too many attempts, giving up:");

                        r = ask_password_auto(
                                        question, "drive-harddisk", id, "cryptenroll", "cryptenroll.passphrase", USEC_INFINITY,
                                        ask_password_flags,
                                        &passwords);
                        if (r < 0)
                                return log_error_errno(r, "Failed to query password: %m");

                        r = -EPERM;
                        STRV_FOREACH(p, passwords) {
                                r = crypt_volume_key_get(
                                                cd,
                                                CRYPT_ANY_SLOT,
                                                vk,
                                                &vks,
                                                *p,
                                                strlen(*p));
                                if (r >= 0)
                                        break;
                        }
                        if (r >= 0)
                                break;

                        log_error_errno(r, "Password not correct, please try again.");
                        ask_password_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
                }
        }

        *ret_cd = TAKE_PTR(cd);
        *ret_volume_key = TAKE_PTR(vk);
        *ret_volume_key_size = vks;

        return 0;
}

static int run(int argc, char *argv[]) {
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
        _cleanup_(erase_and_freep) void *vk = NULL;
        size_t vks;
        int slot, r;

        log_show_color(true);
        log_parse_environment();
        log_open();

        r = parse_argv(argc, argv);
        if (r <= 0)
                return r;

        cryptsetup_enable_logging(NULL);

        if (arg_enroll_type < 0)
                r = prepare_luks(&cd, NULL, NULL); /* No need to unlock device if we don't need the volume key because we don't need to enroll anything */
        else
                r = prepare_luks(&cd, &vk, &vks);
        if (r < 0)
                return r;

        switch (arg_enroll_type) {

        case ENROLL_PASSWORD:
                slot = enroll_password(cd, vk, vks);
                break;

        case ENROLL_RECOVERY:
                slot = enroll_recovery(cd, vk, vks);
                break;

        case ENROLL_PKCS11:
                slot = enroll_pkcs11(cd, vk, vks, arg_pkcs11_token_uri);
                break;

        case ENROLL_FIDO2:
                slot = enroll_fido2(cd, vk, vks, arg_fido2_device, arg_fido2_lock_with);
                break;

        case ENROLL_TPM2:
                slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_pcr_mask);
                break;

        case _ENROLL_TYPE_INVALID:
                /* List enrolled slots if we are called without anything to enroll or wipe */
                if (!wipe_requested())
                        return list_enrolled(cd);

                /* Only slot wiping selected */
                return wipe_slots(cd, arg_wipe_slots, arg_n_wipe_slots, arg_wipe_slots_scope, arg_wipe_slots_mask, -1);

        default:
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Operation not implemented yet.");
        }
        if (slot < 0)
                return slot;

        /* After we completed enrolling, remove user selected slots */
        r = wipe_slots(cd, arg_wipe_slots, arg_n_wipe_slots, arg_wipe_slots_scope, arg_wipe_slots_mask, slot);
        if (r < 0)
                return r;

        return 0;
}

DEFINE_MAIN_FUNCTION(run);
