summaryrefslogtreecommitdiffstats
path: root/src/home/homework-password-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/home/homework-password-cache.c')
-rw-r--r--src/home/homework-password-cache.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/home/homework-password-cache.c b/src/home/homework-password-cache.c
new file mode 100644
index 0000000..00a0f69
--- /dev/null
+++ b/src/home/homework-password-cache.c
@@ -0,0 +1,57 @@
+/* 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.");
+}