diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:18 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:35:18 +0000 |
commit | b750101eb236130cf056c675997decbac904cc49 (patch) | |
tree | a5df1a06754bdd014cb975c051c83b01c9a97532 /src/cryptenroll/cryptenroll-list.c | |
parent | Initial commit. (diff) | |
download | systemd-upstream.tar.xz systemd-upstream.zip |
Adding upstream version 252.22.upstream/252.22upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/cryptenroll/cryptenroll-list.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/cryptenroll/cryptenroll-list.c b/src/cryptenroll/cryptenroll-list.c new file mode 100644 index 0000000..d21df71 --- /dev/null +++ b/src/cryptenroll/cryptenroll-list.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "cryptenroll-list.h" +#include "cryptenroll.h" +#include "format-table.h" +#include "parse-util.h" + +struct keyslot_metadata { + int slot; + const char *type; +}; + +int list_enrolled(struct crypt_device *cd) { + _cleanup_free_ struct keyslot_metadata *keyslot_metadata = NULL; + _cleanup_(table_unrefp) Table *t = NULL; + size_t n_keyslot_metadata = 0; + int slot_max, r; + TableCell *cell; + + assert(cd); + + /* First step, find out all currently used slots */ + assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0); + 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; + + if (!GREEDY_REALLOC(keyslot_metadata, n_keyslot_metadata+1)) + return log_oom(); + + keyslot_metadata[n_keyslot_metadata++] = (struct keyslot_metadata) { + .slot = slot, + }; + } + + /* Second step, enumerate through all tokens, and update the slot table, indicating what kind of + * token they are assigned to */ + for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) { + _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + const char *type; + JsonVariant *w, *z; + EnrollType et; + + 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; + } + + et = luks2_token_type_from_string(json_variant_string(w)); + if (et < 0) + type = "other"; + else + type = enroll_type_to_string(et); + + 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) { + unsigned u; + + if (!json_variant_is_string(z)) { + log_warning("Token JSON data's keyslot field is not an array of strings, ignoring."); + continue; + } + + r = safe_atou(json_variant_string(z), &u); + if (r < 0) { + log_warning_errno(r, "Token JSON data's keyslot field is not an integer formatted as string, ignoring."); + continue; + } + + for (size_t i = 0; i < n_keyslot_metadata; i++) { + if ((unsigned) keyslot_metadata[i].slot != u) + continue; + + if (keyslot_metadata[i].type) /* Slot claimed multiple times? */ + keyslot_metadata[i].type = POINTER_MAX; + else + keyslot_metadata[i].type = type; + } + } + } + + /* Finally, create a table out of it all */ + t = table_new("slot", "type"); + if (!t) + return log_oom(); + + assert_se(cell = table_get_cell(t, 0, 0)); + (void) table_set_align_percent(t, cell, 100); + + for (size_t i = 0; i < n_keyslot_metadata; i++) { + r = table_add_many( + t, + TABLE_INT, keyslot_metadata[i].slot, + TABLE_STRING, keyslot_metadata[i].type == POINTER_MAX ? "conflict" : + keyslot_metadata[i].type ?: "password"); + if (r < 0) + return table_log_add_error(r); + } + + if (table_get_rows(t) <= 1) { + log_info("No slots found."); + return 0; + } + + r = table_print(t, stdout); + if (r < 0) + return log_error_errno(r, "Failed to show slot table: %m"); + + return 0; +} |