mirror of
https://github.com/systemd/systemd.git
synced 2025-01-26 14:04:03 +03:00
nspawn: moved nspawn-creds.[ch] to shared/machine-credential.[ch]
This was done in order to allow sharing of this code between systemd-nspawn and systemd-vmspawn.
This commit is contained in:
parent
6d5202ccaa
commit
e8ac916ec3
@ -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',
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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;
|
||||
|
137
src/shared/machine-credential.c
Normal file
137
src/shared/machine-credential.c
Normal file
@ -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;
|
||||
}
|
14
src/shared/machine-credential.h
Normal file
14
src/shared/machine-credential.h
Normal file
@ -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);
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user