| /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| |
| #include "homework-password-cache.h" |
| #include "keyring-util.h" |
| #include "missing_syscall.h" |
| #include "user-record.h" |
| |
| void password_cache_free(PasswordCache *cache) { |
| if (!cache) |
| return; |
| |
| cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords); |
| cache->fido2_passwords = strv_free_erase(cache->fido2_passwords); |
| cache->keyring_passswords = strv_free_erase(cache->keyring_passswords); |
| } |
| |
| void password_cache_load_keyring(UserRecord *h, PasswordCache *cache) { |
| _cleanup_(erase_and_freep) void *p = NULL; |
| _cleanup_free_ char *name = NULL; |
| char **strv; |
| key_serial_t serial; |
| size_t sz; |
| int r; |
| |
| assert(h); |
| assert(cache); |
| |
| /* Loads the password we need to for automatic resizing from the kernel keyring */ |
| |
| name = strjoin("homework-user-", h->user_name); |
| if (!name) |
| return (void) log_oom(); |
| |
| serial = request_key("user", name, NULL, 0); |
| if (serial == -1) |
| return (void) log_debug_errno(errno, "Failed to request key '%s', ignoring: %m", name); |
| |
| r = keyring_read(serial, &p, &sz); |
| if (r < 0) |
| return (void) log_debug_errno(r, "Failed to read keyring key '%s', ignoring: %m", name); |
| |
| if (memchr(p, 0, sz)) |
| return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Cached password contains embedded NUL byte, ignoring."); |
| |
| strv = new(char*, 2); |
| if (!strv) |
| return (void) log_oom(); |
| |
| strv[0] = TAKE_PTR(p); /* Note that keyring_read() will NUL terminate implicitly, hence we don't have |
| * to NUL terminate manually here: it's a valid string. */ |
| strv[1] = NULL; |
| |
| strv_free_erase(cache->keyring_passswords); |
| cache->keyring_passswords = strv; |
| |
| log_debug("Successfully acquired home key from kernel keyring."); |
| } |