Files
systemd/src/shared/machine-credential.c
Daan De Meyer 69a283c5f2 shared: Clean up includes
Split out of #37344.
2025-05-24 14:00:44 +02:00

132 lines
4.6 KiB
C

/* 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 "log.h"
#include "machine-credential.h"
#include "memory-util.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_context_done(MachineCredentialContext *ctx) {
assert(ctx);
FOREACH_ARRAY(cred, ctx->credentials, ctx->n_credentials)
machine_credential_done(cred);
free(ctx->credentials);
}
bool machine_credentials_contains(const MachineCredentialContext *ctx, const char *id) {
assert(ctx);
assert(id);
FOREACH_ARRAY(cred, ctx->credentials, ctx->n_credentials)
if (streq(cred->id, id))
return true;
return false;
}
int machine_credential_set(MachineCredentialContext *ctx, const char *cred_str) {
_cleanup_(machine_credential_done) MachineCredential cred = {};
ssize_t l;
int r;
assert(ctx);
const char *p = ASSERT_PTR(cred_str);
r = extract_first_word(&p, &cred.id, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
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_str);
if (!credential_name_valid(cred.id))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", cred.id);
if (machine_credentials_contains(ctx, cred.id))
return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", cred.id);
l = cunescape(p, UNESCAPE_ACCEPT_NUL, &cred.data);
if (l < 0)
return log_error_errno(l, "Failed to unescape credential data: %s", p);
cred.size = l;
if (!GREEDY_REALLOC(ctx->credentials, ctx->n_credentials + 1))
return log_oom();
ctx->credentials[ctx->n_credentials++] = TAKE_STRUCT(cred);
return 0;
}
int machine_credential_load(MachineCredentialContext *ctx, const char *cred_path) {
_cleanup_(machine_credential_done) MachineCredential cred = {};
_cleanup_free_ char *path_alloc = NULL;
ReadFullFileFlags flags = READ_FULL_FILE_SECURE;
int r;
assert(ctx);
const char *p = ASSERT_PTR(cred_path);
r = extract_first_word(&p, &cred.id, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
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(cred.id))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", cred.id);
if (machine_credentials_contains(ctx, cred.id))
return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", cred.id);
if (is_path(p) && path_is_valid(p))
flags |= READ_FULL_FILE_CONNECT_SOCKET;
else if (credential_name_valid(p)) {
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", cred.id);
path_alloc = path_join(e, p);
if (!path_alloc)
return log_oom();
p = path_alloc;
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Credential source appears to be neither a valid path nor a credential name: %s", p);
r = read_full_file_full(AT_FDCWD, p, UINT64_MAX, SIZE_MAX,
flags,
NULL,
&cred.data, &cred.size);
if (r < 0)
return log_error_errno(r, "Failed to read credential '%s': %m", p);
if (!GREEDY_REALLOC(ctx->credentials, ctx->n_credentials + 1))
return log_oom();
ctx->credentials[ctx->n_credentials++] = TAKE_STRUCT(cred);
return 0;
}