summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-11-02 18:20:12 +0100
committerLennart Poettering <lennart@poettering.net>2021-11-12 22:15:06 +0100
commitcbae575e0f63b47ed3809ce6c68d385a66a4ca5e (patch)
tree3b7c170a9ce230944d3caa965ed8ff7efa9135bf
parent7b9eaec069b61b852adeb8df5b9a8b910251a426 (diff)
downloadsystemd-cbae575e0f63b47ed3809ce6c68d385a66a4ca5e.tar.gz
keyring-util: add new keyring-util.h helpers
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
-rw-r--r--src/shared/ask-password-api.c32
-rw-r--r--src/shared/keyring-util.c38
-rw-r--r--src/shared/keyring-util.h17
-rw-r--r--src/shared/meson.build2
4 files changed, 65 insertions, 24 deletions
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index a60ccee4d8..367c1df240 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -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
index 0000000000..655cf5241d
--- /dev/null
+++ b/src/shared/keyring-util.c
@@ -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
index 0000000000..838e990b80
--- /dev/null
+++ b/src/shared/keyring-util.h
@@ -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);
diff --git a/src/shared/meson.build b/src/shared/meson.build
index a23d43ce09..229e58beba 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -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