From 786d19fd1bb26e70d624cda2fa44d8e3680e0262 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Mar 2021 23:03:40 +0100 Subject: [PATCH] util: add creds-util.[ch] with helpers for dealing with credentials --- src/basic/creds-util.c | 54 ++++++++++++++++++++++++++++++++++++++++ src/basic/creds-util.h | 12 +++++++++ src/basic/meson.build | 2 ++ src/basic/path-util.c | 6 ----- src/basic/path-util.h | 2 -- src/core/dbus-execute.c | 1 + src/core/load-fragment.c | 3 ++- src/core/manager.c | 7 +++--- src/nspawn/nspawn.c | 7 +++--- 9 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 src/basic/creds-util.c create mode 100644 src/basic/creds-util.h diff --git a/src/basic/creds-util.c b/src/basic/creds-util.c new file mode 100644 index 0000000000..58076705e7 --- /dev/null +++ b/src/basic/creds-util.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "creds-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "path-util.h" + +bool credential_name_valid(const char *s) { + /* We want that credential names are both valid in filenames (since that's our primary way to pass + * them around) and as fdnames (which is how we might want to pass them around eventually) */ + return filename_is_valid(s) && fdname_is_valid(s); +} + +int get_credentials_dir(const char **ret) { + const char *e; + + assert(ret); + + e = secure_getenv("CREDENTIALS_DIRECTORY"); + if (!e) + return -ENXIO; + + if (!path_is_absolute(e) || !path_is_normalized(e)) + return -EINVAL; + + *ret = e; + return 0; +} + +int read_credential(const char *name, void **ret, size_t *ret_size) { + _cleanup_free_ char *fn = NULL; + const char *d; + int r; + + assert(ret); + + if (!credential_name_valid(name)) + return -EINVAL; + + r = get_credentials_dir(&d); + if (r < 0) + return r; + + fn = path_join(d, name); + if (!fn) + return -ENOMEM; + + return read_full_file_full( + AT_FDCWD, fn, + UINT64_MAX, SIZE_MAX, + READ_FULL_FILE_SECURE, + NULL, + (char**) ret, ret_size); +} diff --git a/src/basic/creds-util.h b/src/basic/creds-util.h new file mode 100644 index 0000000000..5e33ca3776 --- /dev/null +++ b/src/basic/creds-util.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include +#include + +bool credential_name_valid(const char *s); + +int get_credentials_dir(const char **ret); + +int read_credential(const char *name, void **ret, size_t *ret_size); diff --git a/src/basic/meson.build b/src/basic/meson.build index 60ef801a25..a7b8be26ac 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -35,6 +35,8 @@ basic_sources = files(''' conf-files.h copy.c copy.h + creds-util.c + creds-util.h def.h device-nodes.c device-nodes.h diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 50ba44492e..f40f3f27e9 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -1190,9 +1190,3 @@ bool prefixed_path_strv_contains(char **l, const char *path) { return false; } - -bool credential_name_valid(const char *s) { - /* We want that credential names are both valid in filenames (since that's our primary way to pass - * them around) and as fdnames (which is how we might want to pass them around eventually) */ - return filename_is_valid(s) && fdname_is_valid(s); -} diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 74ee6362ea..c0746f68d7 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -183,5 +183,3 @@ static inline const char *empty_to_root(const char *path) { bool path_strv_contains(char **l, const char *path); bool prefixed_path_strv_contains(char **l, const char *path); - -bool credential_name_valid(const char *s); diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 4a1585f663..eda21f4734 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -13,6 +13,7 @@ #include "cap-list.h" #include "capability-util.h" #include "cpu-set-util.h" +#include "creds-util.h" #include "dbus-execute.h" #include "dbus-util.h" #include "env-util.h" diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index c6fc4fe083..95960b2608 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -16,8 +16,8 @@ #include "sd-messages.h" #include "af-list.h" -#include "alloc-util.h" #include "all-units.h" +#include "alloc-util.h" #include "bpf-firewall.h" #include "bus-error.h" #include "bus-internal.h" @@ -28,6 +28,7 @@ #include "conf-parser.h" #include "core-varlink.h" #include "cpu-set-util.h" +#include "creds-util.h" #include "env-util.h" #include "errno-list.h" #include "escape.h" diff --git a/src/core/manager.c b/src/core/manager.c index 629966ea60..57bb25ca25 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -30,6 +30,7 @@ #include "clean-ipc.h" #include "clock-util.h" #include "core-varlink.h" +#include "creds-util.h" #include "dbus-job.h" #include "dbus-manager.h" #include "dbus-unit.h" @@ -49,8 +50,8 @@ #include "install.h" #include "io-util.h" #include "label.h" -#include "locale-setup.h" #include "load-fragment.h" +#include "locale-setup.h" #include "log.h" #include "macro.h" #include "manager.h" @@ -852,8 +853,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager if (r < 0) return r; - e = secure_getenv("CREDENTIALS_DIRECTORY"); - if (e) { + r = get_credentials_dir(&e); + if (r >= 0) { m->received_credentials = strdup(e); if (!m->received_credentials) return -ENOMEM; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index a4ac8ed2bb..106dac1556 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -35,6 +35,7 @@ #include "cgroup-util.h" #include "copy.h" #include "cpu-set-util.h" +#include "creds-util.h" #include "dev-setup.h" #include "discover-image.h" #include "dissect-image.h" @@ -1592,9 +1593,9 @@ static int parse_argv(int argc, char *argv[]) { else { const char *e; - e = getenv("CREDENTIALS_DIRECTORY"); - if (!e) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential not available (no credentials passed at all): %s", word); + r = get_credentials_dir(&e); + if (r < 0) + return log_error_errno(r, "Credential not available (no credentials passed at all): %s", word); j = path_join(e, p); if (!j)