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

#include "cryptenroll-wipe.h"
#include "cryptenroll.h"
#include "json.h"
#include "memory-util.h"
#include "parse-util.h"
#include "set.h"
#include "sort-util.h"

static int find_all_slots(struct crypt_device *cd, Set *wipe_slots, Set *keep_slots) {
        int slot_max;

        assert(cd);
        assert(wipe_slots);
        assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);

        /* Finds all currently assigned slots, and adds them to 'wipe_slots', except if listed already in 'keep_slots' */

        for (int slot = 0; slot < slot_max; slot++) {
                crypt_keyslot_info status;

                /* No need to check this slot if we already know we want to wipe it or definitely keep it. */
                if (set_contains(keep_slots, INT_TO_PTR(slot)) ||
                    set_contains(wipe_slots, INT_TO_PTR(slot)))
                        continue;

                status = crypt_keyslot_status(cd, slot);
                if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
                        continue;

                if (set_put(wipe_slots, INT_TO_PTR(slot)) < 0)
                        return log_oom();
        }

        return 0;
}

static int find_empty_passphrase_slots(struct crypt_device *cd, Set *wipe_slots, Set *keep_slots) {
        size_t vks;
        int r, slot_max;

        assert(cd);
        assert(wipe_slots);
        assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);

        /* Finds all slots with an empty passphrase assigned (i.e. "") and adds them to 'wipe_slots', except
         * if listed already in 'keep_slots' */

        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;

        for (int slot = 0; slot < slot_max; slot++) {
                _cleanup_(erase_and_freep) char *vk = NULL;
                crypt_keyslot_info status;

                /* No need to check this slot if we already know we want to wipe it or definitely keep it. */
                if (set_contains(keep_slots, INT_TO_PTR(slot)) ||
                    set_contains(wipe_slots, INT_TO_PTR(slot)))
                        continue;

                status = crypt_keyslot_status(cd, slot);
                if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
                        continue;

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

                r = crypt_volume_key_get(cd, slot, vk, &vks, "", 0);
                if (r < 0) {
                        log_debug_errno(r, "Failed to acquire volume key from slot %i with empty password, ignoring: %m", slot);
                        continue;
                }

                if (set_put(wipe_slots, INT_TO_PTR(r)) < 0)
                        return log_oom();
        }

        return 0;
}

static int find_slots_by_mask(
                struct crypt_device *cd,
                Set *wipe_slots,
                Set *keep_slots,
                unsigned by_mask) {

        _cleanup_(set_freep) Set *listed_slots = NULL;
        int r;

        assert(cd);
        assert(wipe_slots);

        if (by_mask == 0)
                return 0;

        /* Find all slots that are associated with a token of a type in the specified token type mask */

        for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
                _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
                JsonVariant *w, *z;
                EnrollType t;

                r = cryptsetup_get_token_as_json(cd, token, NULL, &v);
                if (IN_SET(r, -ENOENT, -EINVAL))
                        continue;
                if (r < 0) {
                        log_warning_errno(r, "Failed to read JSON token data off disk, ignoring: %m");
                        continue;
                }

                w = json_variant_by_key(v, "type");
                if (!w || !json_variant_is_string(w)) {
                        log_warning("Token JSON data lacks type field, ignoring.");
                        continue;
                }

                t = luks2_token_type_from_string(json_variant_string(w));

                w = json_variant_by_key(v, "keyslots");
                if (!w || !json_variant_is_array(w)) {
                        log_warning("Token JSON data lacks keyslots field, ignoring.");
                        continue;
                }

                JSON_VARIANT_ARRAY_FOREACH(z, w) {
                        int slot;

                        if (!json_variant_is_string(z)) {
                                log_warning("Token JSON data's keyslot field is not an array of strings, ignoring.");
                                continue;
                        }

                        r = safe_atoi(json_variant_string(z), &slot);
                        if (r < 0) {
                                log_warning_errno(r, "Token JSON data's keyslot filed is not an integer formatted as string, ignoring.");
                                continue;
                        }

                        if (t >= 0 && (by_mask & (1U << t)) != 0) {
                                /* Selected by token type */
                                if (set_put(wipe_slots, INT_TO_PTR(slot)) < 0)
                                        return log_oom();
                        } else if ((by_mask & (1U << ENROLL_PASSWORD)) != 0) {
                                /* If we shall remove all plain password slots, let's maintain a list of
                                 * slots that are listed in any tokens, since those are *NOT* plain
                                 * passwords */
                                if (set_ensure_allocated(&listed_slots, NULL) < 0)
                                        return log_oom();

                                if (set_put(listed_slots, INT_TO_PTR(slot)) < 0)
                                        return log_oom();
                        }
                }
        }

        /* "password" slots are those which have no token assigned. If we shall remove those, iterate through
         * all slots and mark those for wiping that weren't listed in any token */
        if ((by_mask & (1U << ENROLL_PASSWORD)) != 0) {
                int slot_max;

                assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);

                for (int slot = 0; slot < slot_max; slot++) {
                        crypt_keyslot_info status;

                        /* No need to check this slot if we already know we want to wipe it or definitely keep it. */
                        if (set_contains(keep_slots, INT_TO_PTR(slot)) ||
                            set_contains(wipe_slots, INT_TO_PTR(slot)))
                                continue;

                        if (set_contains(listed_slots, INT_TO_PTR(slot))) /* This has a token, hence is not a password. */
                                continue;

                        status = crypt_keyslot_status(cd, slot);
                        if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST)) /* Not actually assigned? */
                                continue;

                        /* Finally, we found a password, add it to the list of slots to wipe */
                        if (set_put(wipe_slots, INT_TO_PTR(slot)) < 0)
                                return log_oom();
                }
        }

        return 0;
}

static int find_slot_tokens(struct crypt_device *cd, Set *wipe_slots, Set *keep_slots, Set *wipe_tokens) {
        int r;

        assert(cd);
        assert(wipe_slots);
        assert(keep_slots);
        assert(wipe_tokens);

        /* Find all tokens matching the slots we want to wipe, so that we can wipe them too. Also, for update
         * the slots sets according to the token data: add any other slots listed in the tokens we act on. */

        for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
                _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
                bool shall_wipe = false;
                JsonVariant *w, *z;

                r = cryptsetup_get_token_as_json(cd, token, NULL, &v);
                if (IN_SET(r, -ENOENT, -EINVAL))
                        continue;
                if (r < 0) {
                        log_warning_errno(r, "Failed to read JSON token data off disk, ignoring: %m");
                        continue;
                }

                w = json_variant_by_key(v, "keyslots");
                if (!w || !json_variant_is_array(w)) {
                        log_warning("Token JSON data lacks keyslots field, ignoring.");
                        continue;
                }

                /* Go through the slots associated with this token: if we shall keep any slot of them, the token shall stay too. */
                JSON_VARIANT_ARRAY_FOREACH(z, w) {
                        int slot;

                        if (!json_variant_is_string(z)) {
                                log_warning("Token JSON data's keyslot field is not an array of strings, ignoring.");
                                continue;
                        }

                        r = safe_atoi(json_variant_string(z), &slot);
                        if (r < 0) {
                                log_warning_errno(r, "Token JSON data's keyslot filed is not an integer formatted as string, ignoring.");
                                continue;
                        }

                        if (set_contains(keep_slots, INT_TO_PTR(slot))) {
                                shall_wipe = false;
                                break; /* If we shall keep this slot, then this is definite: we will keep its token too */
                        }

                        /* If there's a slot associated with this token that we shall wipe, then remove the
                         * token too. But we are careful here: let's continue iterating, maybe there's a slot
                         * that we need to keep, in which case we can reverse the decision again. */
                        if (set_contains(wipe_slots, INT_TO_PTR(slot)))
                                shall_wipe = true;
                }

                /* Go through the slots again, and this time add them to the list of slots to keep/remove */
                JSON_VARIANT_ARRAY_FOREACH(z, w) {
                        int slot;

                        if (!json_variant_is_string(z))
                                continue;
                        if (safe_atoi(json_variant_string(z), &slot) < 0)
                                continue;

                        if (set_put(shall_wipe ? wipe_slots : keep_slots, INT_TO_PTR(slot)) < 0)
                                return log_oom();
                }

                /* And of course, also remember the tokens to remove. */
                if (shall_wipe)
                        if (set_put(wipe_tokens, INT_TO_PTR(token)) < 0)
                                return log_oom();
        }

        return 0;
}

static bool slots_remain(struct crypt_device *cd, Set *wipe_slots, Set *keep_slots) {
        int slot_max;

        assert(cd);
        assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);

        /* Checks if any slots remaining in the LUKS2 header if we remove all slots listed in 'wipe_slots'
         * (keeping those listed in 'keep_slots') */

        for (int slot = 0; slot < slot_max; slot++) {
                crypt_keyslot_info status;

                status = crypt_keyslot_status(cd, slot);
                if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
                        continue;

                /* The "keep" set wins if a slot is listed in both sets. This is important so that we can
                 * safely add a new slot and remove all others of the same type, which in a naive
                 * implementation might mean we remove what we just added — which we of course don't want. */
                if (set_contains(keep_slots, INT_TO_PTR(slot)) ||
                    !set_contains(wipe_slots, INT_TO_PTR(slot)))
                        return true;
        }

        return false;
}

int wipe_slots(struct crypt_device *cd,
               const int explicit_slots[],
               size_t n_explicit_slots,
               WipeScope by_scope,
               unsigned by_mask,
               int except_slot) {

        _cleanup_(set_freep) Set *wipe_slots = NULL, *wipe_tokens = NULL, *keep_slots = NULL;
        _cleanup_free_ int *ordered_slots = NULL, *ordered_tokens = NULL;
        size_t n_ordered_slots = 0, n_ordered_tokens = 0;
        int r, slot_max, ret;
        void *e;

        assert_se(cd);

        /* Shortcut if nothing to wipe. */
        if (n_explicit_slots == 0 && by_mask == 0 && by_scope == WIPE_EXPLICIT)
                return 0;

        /* So this is a bit more complicated than I'd wish, but we want support three different axis for wiping slots:
         *
         *    1. Wiping by slot indexes
         *    2. Wiping slots of specified token types
         *    3. Wiping "all" entries, or entries with an empty password (i.e. "")
         *
         * (or any combination of the above)
         *
         * Plus: We always want to remove tokens matching the slots.
         * Plus: We always want to exclude the slots/tokens we just added.
         */

        wipe_slots = set_new(NULL);
        keep_slots = set_new(NULL);
        wipe_tokens = set_new(NULL);
        if (!wipe_slots || !keep_slots || !wipe_tokens)
                return log_oom();

        /* Let's maintain one set of slots for the slots we definitely want to keep */
        if (except_slot >= 0)
                if (set_put(keep_slots, INT_TO_PTR(except_slot)) < 0)
                        return log_oom();

        assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);

        /* Maintain another set of the slots we intend to wipe */
        for (size_t i = 0; i < n_explicit_slots; i++) {
                if (explicit_slots[i] >= slot_max)
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Slot index %i out of range.", explicit_slots[i]);

                if (set_put(wipe_slots, INT_TO_PTR(explicit_slots[i])) < 0)
                        return log_oom();
        }

        /* Now, handle the "all" and "empty passphrase" cases. */
        switch (by_scope) {

        case WIPE_EXPLICIT:
                break; /* Nothing to do here */

        case WIPE_ALL:
                r = find_all_slots(cd, wipe_slots, keep_slots);
                if (r < 0)
                        return r;

                break;

        case WIPE_EMPTY_PASSPHRASE:
                r = find_empty_passphrase_slots(cd, wipe_slots, keep_slots);
                if (r < 0)
                        return r;

                break;
        default:
                assert_not_reached("Unexpected wipe scope");
        }

        /* Then add all slots that match a token type */
        r = find_slots_by_mask(cd, wipe_slots, keep_slots, by_mask);
        if (r < 0)
                return r;

        /* And determine tokens that we shall remove */
        r = find_slot_tokens(cd, wipe_slots, keep_slots, wipe_tokens);
        if (r < 0)
                return r;

        /* Safety check: let's make sure that after we are done there's at least one slot remaining */
        if (!slots_remain(cd, wipe_slots, keep_slots))
                return log_error_errno(SYNTHETIC_ERRNO(EPERM),
                                       "Wipe operation would leave no valid slots around, can't allow that, sorry.");

        /* Generated ordered lists of the slots and the tokens to remove */
        ordered_slots = new(int, set_size(wipe_slots));
        if (!ordered_slots)
                return log_oom();
        SET_FOREACH(e, wipe_slots) {
                int slot = PTR_TO_INT(e);

                if (set_contains(keep_slots, INT_TO_PTR(slot)))
                        continue;

                ordered_slots[n_ordered_slots++] = slot;
        }
        typesafe_qsort(ordered_slots, n_ordered_slots, cmp_int);

        ordered_tokens = new(int, set_size(wipe_tokens));
        if (!ordered_tokens)
                return log_oom();
        SET_FOREACH(e, wipe_tokens)
                ordered_tokens[n_ordered_tokens++] = PTR_TO_INT(e);
        typesafe_qsort(ordered_tokens, n_ordered_tokens, cmp_int);

        if (n_ordered_slots == 0 && n_ordered_tokens == 0) {
                log_full(except_slot < 0 ? LOG_NOTICE : LOG_DEBUG,
                         "No slots to remove selected.");
                return 0;
        }

        if (DEBUG_LOGGING) {
                for (size_t i = 0; i < n_ordered_slots; i++)
                        log_debug("Going to wipe slot %i.", ordered_slots[i]);
                for (size_t i = 0; i < n_ordered_tokens; i++)
                        log_debug("Going to wipe token %i.", ordered_tokens[i]);
        }

        /* Now, let's actually start wiping things. (We go from back to front, to make space at the end
         * first.) */
        ret = 0;
        for (size_t i = n_ordered_slots; i > 0; i--) {
                r = crypt_keyslot_destroy(cd, ordered_slots[i - 1]);
                if (r < 0) {
                        log_warning_errno(r, "Failed to wipe slot %i, continuing: %m", ordered_slots[i - 1]);
                        if (ret == 0)
                                ret = r;
                } else
                        log_info("Wiped slot %i.", ordered_slots[i - 1]);
        }

        for (size_t i = n_ordered_tokens; i > 0; i--) {
                r = crypt_token_json_set(cd, ordered_tokens[i - 1], NULL);
                if (r < 0) {
                        log_warning_errno(r, "Failed to wipe token %i, continuing: %m", ordered_tokens[i - 1]);
                        if (ret == 0)
                                ret = r;
                }
        }

        return ret;
}
