From: Lennart Poettering Date: Wed, 10 Mar 2021 22:03:40 +0000 (+0100) Subject: util: add creds-util.[ch] with helpers for dealing with credentials X-Git-Tag: v249-rc1~507^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=786d19fd1bb26e70d624cda2fa44d8e3680e0262;p=thirdparty%2Fsystemd.git util: add creds-util.[ch] with helpers for dealing with credentials --- diff --git a/src/basic/creds-util.c b/src/basic/creds-util.c new file mode 100644 index 00000000000..58076705e7d --- /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 00000000000..5e33ca37760 --- /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 60ef801a253..a7b8be26acc 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 50ba44492e5..f40f3f27e96 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 74ee6362eac..c0746f68d7a 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 4a1585f6633..eda21f4734e 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 c6fc4fe083f..95960b2608b 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 629966ea60e..57bb25ca254 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 a4ac8ed2bb7..106dac15567 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)