]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: moved nspawn-creds.[ch] to shared/machine-credential.[ch]
authorSam Leonard <sam.leonard@codethink.co.uk>
Thu, 12 Oct 2023 11:56:08 +0000 (12:56 +0100)
committerSam Leonard <sam.leonard@codethink.co.uk>
Thu, 2 Nov 2023 15:37:40 +0000 (15:37 +0000)
This was done in order to allow sharing of this code between
systemd-nspawn and systemd-vmspawn.

src/nspawn/meson.build
src/nspawn/nspawn-creds.c [deleted file]
src/nspawn/nspawn-creds.h [deleted file]
src/nspawn/nspawn.c
src/shared/machine-credential.c [new file with mode: 0644]
src/shared/machine-credential.h [new file with mode: 0644]
src/shared/meson.build

index e2605f895bbfd06689e04f03ef656656b7a5a11a..2a913b156df9b6228713f9b805269a0f3c17b7e9 100644 (file)
@@ -3,7 +3,6 @@
 libnspawn_core_sources = files(
         'nspawn-bind-user.c',
         'nspawn-cgroup.c',
-        'nspawn-creds.c',
         'nspawn-expose-ports.c',
         'nspawn-mount.c',
         'nspawn-network.c',
diff --git a/src/nspawn/nspawn-creds.c b/src/nspawn/nspawn-creds.c
deleted file mode 100644 (file)
index 0900d8c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "macro.h"
-#include "memory-util.h"
-#include "nspawn-creds.h"
-
-static void credential_free(Credential *cred) {
-        assert(cred);
-
-        cred->id = mfree(cred->id);
-        cred->data = erase_and_free(cred->data);
-        cred->size = 0;
-}
-
-void credential_free_all(Credential *creds, size_t n) {
-        size_t i;
-
-        assert(creds || n == 0);
-
-        for (i = 0; i < n; i++)
-                credential_free(creds + i);
-
-        free(creds);
-}
diff --git a/src/nspawn/nspawn-creds.h b/src/nspawn/nspawn-creds.h
deleted file mode 100644 (file)
index de0661b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <sys/types.h>
-
-typedef struct Credential {
-        char *id;
-        void *data;
-        size_t size;
-} Credential;
-
-void credential_free_all(Credential *creds, size_t n);
index ca9745328397698bbcd83b064bdb7fcb0e41def0..ed29d9bba932895dee5a2ed796215e4db5abe1b5 100644 (file)
@@ -60,6 +60,7 @@
 #include "log.h"
 #include "loop-util.h"
 #include "loopback-setup.h"
+#include "machine-credential.h"
 #include "macro.h"
 #include "main-func.h"
 #include "missing_sched.h"
@@ -70,7 +71,6 @@
 #include "netlink-util.h"
 #include "nspawn-bind-user.h"
 #include "nspawn-cgroup.h"
-#include "nspawn-creds.h"
 #include "nspawn-def.h"
 #include "nspawn-expose-ports.h"
 #include "nspawn-mount.h"
@@ -229,7 +229,7 @@ static DeviceNode* arg_extra_nodes = NULL;
 static size_t arg_n_extra_nodes = 0;
 static char **arg_sysctl = NULL;
 static ConsoleMode arg_console_mode = _CONSOLE_MODE_INVALID;
-static Credential *arg_credentials = NULL;
+static MachineCredential *arg_credentials = NULL;
 static size_t arg_n_credentials = 0;
 static char **arg_bind_user = NULL;
 static bool arg_suppress_sync = false;
@@ -1567,106 +1567,24 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_pager_flags |= PAGER_DISABLE;
                         break;
 
-                case ARG_SET_CREDENTIAL: {
-                        _cleanup_free_ char *word = NULL, *data = NULL;
-                        const char *p = optarg;
-                        Credential *a;
-                        ssize_t l;
-
-                        r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                case ARG_SET_CREDENTIAL:
+                        r = machine_credential_set(&arg_credentials, &arg_n_credentials, optarg);
                         if (r == -ENOMEM)
                                 return log_oom();
                         if (r < 0)
-                                return log_error_errno(r, "Failed to parse --set-credential= parameter: %m");
-                        if (r == 0 || !p)
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --set-credential=: %s", optarg);
-
-                        if (!credential_name_valid(word))
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", word);
-
-                        for (size_t i = 0; i < arg_n_credentials; i++)
-                                if (streq(arg_credentials[i].id, word))
-                                        return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
-
-                        l = cunescape(p, UNESCAPE_ACCEPT_NUL, &data);
-                        if (l < 0)
-                                return log_error_errno(l, "Failed to unescape credential data: %s", p);
-
-                        a = reallocarray(arg_credentials, arg_n_credentials + 1, sizeof(Credential));
-                        if (!a)
-                                return log_oom();
-
-                        a[arg_n_credentials++] = (Credential) {
-                                .id = TAKE_PTR(word),
-                                .data = TAKE_PTR(data),
-                                .size = l,
-                        };
-
-                        arg_credentials = a;
-
+                                return log_error_errno(r, "Failed to set credential from %s: %m", optarg);
                         arg_settings_mask |= SETTING_CREDENTIALS;
                         break;
-                }
 
-                case ARG_LOAD_CREDENTIAL: {
-                        ReadFullFileFlags flags = READ_FULL_FILE_SECURE;
-                        _cleanup_(erase_and_freep) char *data = NULL;
-                        _cleanup_free_ char *word = NULL, *j = NULL;
-                        const char *p = optarg;
-                        Credential *a;
-                        size_t size, i;
-
-                        r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                case ARG_LOAD_CREDENTIAL:
+                        r = machine_credential_load(&arg_credentials, &arg_n_credentials, optarg);
                         if (r == -ENOMEM)
                                 return log_oom();
                         if (r < 0)
-                                return log_error_errno(r, "Failed to parse --load-credential= parameter: %m");
-                        if (r == 0 || !p)
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --load-credential=: %s", optarg);
-
-                        if (!credential_name_valid(word))
-                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", word);
-
-                        for (i = 0; i < arg_n_credentials; i++)
-                                if (streq(arg_credentials[i].id, word))
-                                        return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
-
-                        if (path_is_absolute(p))
-                                flags |= READ_FULL_FILE_CONNECT_SOCKET;
-                        else {
-                                const char *e;
-
-                                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)
-                                        return log_oom();
-                        }
-
-                        r = read_full_file_full(AT_FDCWD, j ?: p, UINT64_MAX, SIZE_MAX,
-                                                flags,
-                                                NULL,
-                                                &data, &size);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to read credential '%s': %m", j ?: p);
-
-                        a = reallocarray(arg_credentials, arg_n_credentials + 1, sizeof(Credential));
-                        if (!a)
-                                return log_oom();
-
-                        a[arg_n_credentials++] = (Credential) {
-                                .id = TAKE_PTR(word),
-                                .data = TAKE_PTR(data),
-                                .size = size,
-                        };
-
-                        arg_credentials = a;
+                                return log_error_errno(r, "Failed to load credential from %s: %m", optarg);
 
                         arg_settings_mask |= SETTING_CREDENTIALS;
                         break;
-                }
 
                 case ARG_BIND_USER:
                         if (!valid_user_group_name(optarg, 0))
@@ -5929,7 +5847,7 @@ finish:
         expose_port_free_all(arg_expose_ports);
         rlimit_free_all(arg_rlimit);
         device_node_array_free(arg_extra_nodes, arg_n_extra_nodes);
-        credential_free_all(arg_credentials, arg_n_credentials);
+        machine_credential_free_all(arg_credentials, arg_n_credentials);
 
         if (r < 0)
                 return r;
diff --git a/src/shared/machine-credential.c b/src/shared/machine-credential.c
new file mode 100644 (file)
index 0000000..752bf0d
--- /dev/null
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "creds-util.h"
+#include "escape.h"
+#include "extract-word.h"
+#include "fileio.h"
+#include "macro.h"
+#include "memory-util.h"
+#include "machine-credential.h"
+#include "path-util.h"
+#include "string-util-fundamental.h"
+
+static void machine_credential_done(MachineCredential *cred) {
+        assert(cred);
+
+        cred->id = mfree(cred->id);
+        cred->data = erase_and_free(cred->data);
+        cred->size = 0;
+}
+
+void machine_credential_free_all(MachineCredential *creds, size_t n) {
+        assert(creds || n == 0);
+
+        FOREACH_ARRAY(cred, creds, n)
+                machine_credential_done(cred);
+
+        free(creds);
+}
+
+int machine_credential_set(MachineCredential **credentials, size_t *n_credentials, const char *cred_string) {
+        _cleanup_free_ char *word = NULL, *data = NULL;
+        MachineCredential *creds = *ASSERT_PTR(credentials);
+        ssize_t l;
+        size_t n_creds = *ASSERT_PTR(n_credentials);
+        int r;
+        const char *p = ASSERT_PTR(cred_string);
+
+        assert(creds || n_creds == 0);
+
+        r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+        if (r == -ENOMEM)
+                return r;
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse --set-credential= parameter: %m");
+        if (r == 0 || !p)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --set-credential=: %s", cred_string);
+
+        if (!credential_name_valid(word))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "MachineCredential name is not valid: %s", word);
+
+        FOREACH_ARRAY(cred, creds, n_creds)
+                if (streq(cred->id, word))
+                        return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
+
+        l = cunescape(p, UNESCAPE_ACCEPT_NUL, &data);
+        if (l < 0)
+                return log_error_errno(l, "Failed to unescape credential data: %s", p);
+
+        GREEDY_REALLOC(creds, n_creds + 1);
+        if (!creds)
+                return -ENOMEM;
+
+        creds[n_creds++] = (MachineCredential) {
+                .id = TAKE_PTR(word),
+                .data = TAKE_PTR(data),
+                .size = l,
+        };
+
+        *credentials = creds;
+        *n_credentials = n_creds;
+
+        return 0;
+}
+
+int machine_credential_load(MachineCredential **credentials, size_t *n_credentials, const char *cred_path) {
+        ReadFullFileFlags flags = READ_FULL_FILE_SECURE;
+        _cleanup_(erase_and_freep) char *data = NULL;
+        _cleanup_free_ char *word = NULL, *j = NULL;
+        MachineCredential *creds = *ASSERT_PTR(credentials);
+        size_t size, n_creds = *ASSERT_PTR(n_credentials);
+        int r;
+        const char *p = ASSERT_PTR(cred_path);
+
+        assert(creds || n_creds == 0);
+
+        r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+        if (r == -ENOMEM)
+                return -ENOMEM;
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse --load-credential= parameter: %m");
+        if (r == 0 || !p)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --load-credential=: %s", cred_path);
+
+        if (!credential_name_valid(word))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "MachineCredential name is not valid: %s", word);
+
+        FOREACH_ARRAY(cred, creds, n_creds)
+                if (streq(cred->id, word))
+                        return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
+
+        if (path_is_absolute(p))
+                flags |= READ_FULL_FILE_CONNECT_SOCKET;
+        else {
+                const char *e;
+
+                r = get_credentials_dir(&e);
+                if (r < 0)
+                        return log_error_errno(r, "MachineCredential not available (no credentials passed at all): %s", word);
+
+                j = path_join(e, p);
+                if (!j)
+                        return -ENOMEM;
+        }
+
+        r = read_full_file_full(AT_FDCWD, j ?: p, UINT64_MAX, SIZE_MAX,
+                                flags,
+                                NULL,
+                                &data, &size);
+        if (r < 0)
+                return log_error_errno(r, "Failed to read credential '%s': %m", j ?: p);
+
+        GREEDY_REALLOC(creds, n_creds + 1);
+        if (!creds)
+                return -ENOMEM;
+
+        creds[n_creds++] = (MachineCredential) {
+                .id = TAKE_PTR(word),
+                .data = TAKE_PTR(data),
+                .size = size,
+        };
+
+        *credentials = creds;
+        *n_credentials = n_creds;
+
+        return 0;
+}
diff --git a/src/shared/machine-credential.h b/src/shared/machine-credential.h
new file mode 100644 (file)
index 0000000..c9044a2
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <sys/types.h>
+
+typedef struct MachineCredential {
+        char *id;
+        void *data;
+        size_t size;
+} MachineCredential;
+
+void machine_credential_free_all(MachineCredential *creds, size_t n);
+int machine_credential_set(MachineCredential **credentials, size_t *n_credentials, const char *cred_string);
+int machine_credential_load(MachineCredential **credentials, size_t *n_credentials, const char *cred_path);
index 0ef34d4bc864c84095e401042bff25e135e56680..67bb0943b76a42b6ebf1ba5c1465431cd57422d6 100644 (file)
@@ -111,6 +111,7 @@ shared_sources = files(
         'loop-util.c',
         'loopback-setup.c',
         'lsm-util.c',
+        'machine-credential.c',
         'machine-id-setup.c',
         'machine-pool.c',
         'macvlan-util.c',