]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
keyring-util: add new keyring-util.h helpers
authorLennart Poettering <lennart@poettering.net>
Tue, 2 Nov 2021 17:20:12 +0000 (18:20 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 12 Nov 2021 21:15:06 +0000 (22:15 +0100)
This adds to new helpers: keyring_read() for reading a key data from a
keyring entry, and TAKE_KEY_SERIAL which is what TAKE_FD is for fds, but
for key_serial_t.

The former is immediately used by ask-password-api.c

src/shared/ask-password-api.c
src/shared/keyring-util.c [new file with mode: 0644]
src/shared/keyring-util.h [new file with mode: 0644]
src/shared/meson.build

index a60ccee4d852a9cd09d42d29b14d79d75b5c0f5d..367c1df240f18ba91ef2e9e5aea43fb0c5624bf0 100644 (file)
@@ -28,6 +28,7 @@
 #include "fs-util.h"
 #include "glyph-util.h"
 #include "io-util.h"
+#include "keyring-util.h"
 #include "log.h"
 #include "macro.h"
 #include "memory-util.h"
@@ -62,35 +63,18 @@ static int lookup_key(const char *keyname, key_serial_t *ret) {
 }
 
 static int retrieve_key(key_serial_t serial, char ***ret) {
-        size_t nfinal, m = 100;
+        _cleanup_(erase_and_freep) void *p = NULL;
         char **l;
-        _cleanup_(erase_and_freep) char *pfinal = NULL;
+        size_t n;
+        int r;
 
         assert(ret);
 
-        for (;;) {
-                _cleanup_(erase_and_freep) char *p = NULL;
-                long n;
-
-                p = new(char, m);
-                if (!p)
-                        return -ENOMEM;
-
-                n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
-                if (n < 0)
-                        return -errno;
-                if ((size_t) n <= m) {
-                        nfinal = (size_t) n;
-                        pfinal = TAKE_PTR(p);
-                        break;
-                }
-
-                if (m > LONG_MAX / 2) /* overflow check */
-                        return -ENOMEM;
-                m *= 2;
-        }
+        r = keyring_read(serial, &p, &n);
+        if (r < 0)
+                return r;
 
-        l = strv_parse_nulstr(pfinal, nfinal);
+        l = strv_parse_nulstr(p, n);
         if (!l)
                 return -ENOMEM;
 
diff --git a/src/shared/keyring-util.c b/src/shared/keyring-util.c
new file mode 100644 (file)
index 0000000..655cf52
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "keyring-util.h"
+#include "memory-util.h"
+#include "missing_syscall.h"
+
+int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) {
+        size_t m = 100;
+
+        for (;;) {
+                _cleanup_(erase_and_freep) uint8_t *p = NULL;
+                long n;
+
+                p = new(uint8_t, m+1);
+                if (!p)
+                        return -ENOMEM;
+
+                n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
+                if (n < 0)
+                        return -errno;
+
+                if ((size_t) n <= m) {
+                        p[n] = 0; /* NUL terminate, just in case */
+
+                        if (ret)
+                                *ret = TAKE_PTR(p);
+                        if (ret_size)
+                                *ret_size = n;
+
+                        return 0;
+                }
+
+                if (m > (SIZE_MAX-1) / 2) /* overflow check */
+                        return -ENOMEM;
+
+                m *= 2;
+        }
+}
diff --git a/src/shared/keyring-util.h b/src/shared/keyring-util.h
new file mode 100644 (file)
index 0000000..838e990
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <sys/types.h>
+
+#include "missing_keyctl.h"
+
+/* TAKE_FD but for key_serial_t instead of fds */
+#define TAKE_KEY_SERIAL(key_serial)                             \
+        ({                                                      \
+                key_serial_t *_key_serialp_ = &(key_serial);    \
+                key_serial_t _key_serial_ = *_key_serialp_;     \
+                *_key_serialp_ = -1;                            \
+                _key_serial_;                                   \
+        })
+
+int keyring_read(key_serial_t serial, void **ret, size_t *ret_size);
index a23d43ce09aac2a5201f145d690f20dc3d9094df..229e58bebab7afe11aaa9d464dd6f6909994ef6a 100644 (file)
@@ -173,6 +173,8 @@ shared_sources = files('''
         json.h
         kbd-util.c
         kbd-util.h
+        keyring-util.h
+        keyring-util.c
         killall.c
         killall.h
         label.c