1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "homework-password-cache.h"
4 #include "keyring-util.h"
5 #include "missing_syscall.h"
6 #include "user-record.h"
7 
password_cache_free(PasswordCache * cache)8 void password_cache_free(PasswordCache *cache) {
9         if (!cache)
10                 return;
11 
12         cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords);
13         cache->fido2_passwords = strv_free_erase(cache->fido2_passwords);
14         cache->keyring_passswords = strv_free_erase(cache->keyring_passswords);
15 }
16 
password_cache_load_keyring(UserRecord * h,PasswordCache * cache)17 void password_cache_load_keyring(UserRecord *h, PasswordCache *cache) {
18         _cleanup_(erase_and_freep) void *p = NULL;
19         _cleanup_free_ char *name = NULL;
20         char **strv;
21         key_serial_t serial;
22         size_t sz;
23         int r;
24 
25         assert(h);
26         assert(cache);
27 
28         /* Loads the password we need to for automatic resizing from the kernel keyring */
29 
30         name = strjoin("homework-user-", h->user_name);
31         if (!name)
32                 return (void) log_oom();
33 
34         serial = request_key("user", name, NULL, 0);
35         if (serial == -1)
36                 return (void) log_debug_errno(errno, "Failed to request key '%s', ignoring: %m", name);
37 
38         r = keyring_read(serial, &p, &sz);
39         if (r < 0)
40                 return (void) log_debug_errno(r, "Failed to read keyring key '%s', ignoring: %m", name);
41 
42         if (memchr(p, 0, sz))
43                 return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Cached password contains embedded NUL byte, ignoring.");
44 
45         strv = new(char*, 2);
46         if (!strv)
47                 return (void) log_oom();
48 
49         strv[0] = TAKE_PTR(p); /* Note that keyring_read() will NUL terminate implicitly, hence we don't have
50                                 * to NUL terminate manually here: it's a valid string. */
51         strv[1] = NULL;
52 
53         strv_free_erase(cache->keyring_passswords);
54         cache->keyring_passswords = strv;
55 
56         log_debug("Successfully acquired home key from kernel keyring.");
57 }
58