From: Lennart Poettering Date: Thu, 18 Sep 2025 07:20:00 +0000 (+0200) Subject: machine-credential: add low-level machine_credential_add() as common back-end for... X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F38982%2Fhead;p=thirdparty%2Fsystemd.git machine-credential: add low-level machine_credential_add() as common back-end for machine_credential_set() + machine_credential_load() --- diff --git a/src/shared/machine-credential.c b/src/shared/machine-credential.c index 407bd18bff2..ace10b43dba 100644 --- a/src/shared/machine-credential.c +++ b/src/shared/machine-credential.c @@ -5,6 +5,7 @@ #include "escape.h" #include "extract-word.h" #include "fileio.h" +#include "iovec-util.h" #include "log.h" #include "machine-credential.h" #include "memory-util.h" @@ -39,63 +40,107 @@ MachineCredential* machine_credential_find(MachineCredentialContext *ctx, const return NULL; } -int machine_credential_set(MachineCredentialContext *ctx, const char *cred_str) { +int machine_credential_add( + MachineCredentialContext *ctx, + const char *id, + const char *value, + size_t size) { + + assert(ctx); + assert(id); + assert(value || size == 0); + + if (!credential_name_valid(id)) + return -EINVAL; + + if (machine_credential_find(ctx, id)) + return -EEXIST; + + if (size == SIZE_MAX) + size = strlen_ptr(value); + _cleanup_(machine_credential_done) MachineCredential cred = {}; - ssize_t l; + cred.id = strdup(id); + if (!cred.id) + return -ENOMEM; + + cred.data = memdup(value, size); + if (!cred.data) + return -ENOMEM; + + cred.size = size; + + if (!GREEDY_REALLOC(ctx->credentials, ctx->n_credentials + 1)) + return -ENOMEM; + + ctx->credentials[ctx->n_credentials++] = TAKE_STRUCT(cred); + return 0; +} + +static int machine_credential_add_and_log( + MachineCredentialContext *ctx, + const char *id, + const char *value, + size_t size) { + int r; assert(ctx); + assert(id); + assert(value || size == 0); + + r = machine_credential_add(ctx, id, value, size); + if (r == -EEXIST) + return log_error_errno(r, "Duplicated credential '%s', refusing.", id); + if (r == -EINVAL) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", id); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Failed to add credential '%s': %m", id); - const char *p = ASSERT_PTR(cred_str); + return 0; +} - r = extract_first_word(&p, &cred.id, ":", EXTRACT_DONT_COALESCE_SEPARATORS); + +int machine_credential_set(MachineCredentialContext *ctx, const char *cred_str) { + int r; + + assert(ctx); + + const char *p = ASSERT_PTR(cred_str); + _cleanup_free_ char *id = NULL; + r = extract_first_word(&p, &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_credential_find(ctx, cred.id)) - return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", cred.id); - - l = cunescape(p, UNESCAPE_ACCEPT_NUL, &cred.data); + _cleanup_free_ char *data = NULL; + ssize_t l; + l = cunescape(p, UNESCAPE_ACCEPT_NUL, &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; + return machine_credential_add_and_log(ctx, id, data, l); } 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); + _cleanup_free_ char *id = NULL; + r = extract_first_word(&p, &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_credential_find(ctx, cred.id)) - return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", cred.id); - + ReadFullFileFlags flags = READ_FULL_FILE_SECURE; + _cleanup_free_ char *path_alloc = NULL; if (is_path(p) && path_is_valid(p)) flags |= READ_FULL_FILE_CONNECT_SOCKET; else if (credential_name_valid(p)) { @@ -103,8 +148,7 @@ int machine_credential_load(MachineCredentialContext *ctx, const char *cred_path r = get_credentials_dir(&e); if (r < 0) - return log_error_errno(r, - "Credential not available (no credentials passed at all): %s", cred.id); + return log_error_errno(r, "Credential not available (no credentials passed at all): %s", p); path_alloc = path_join(e, p); if (!path_alloc) @@ -115,17 +159,16 @@ int machine_credential_load(MachineCredentialContext *ctx, const char *cred_path 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); + _cleanup_(iovec_done_erase) struct iovec iov = {}; + r = read_full_file_full( + AT_FDCWD, p, + /* offset= */ UINT64_MAX, + /* size= */ SIZE_MAX, + flags, + /* bind_name= */ NULL, + (char**) &iov.iov_base, &iov.iov_len); 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; + return machine_credential_add_and_log(ctx, id, iov.iov_base, iov.iov_len); } diff --git a/src/shared/machine-credential.h b/src/shared/machine-credential.h index 1b5f4fa1121..244ebd6192a 100644 --- a/src/shared/machine-credential.h +++ b/src/shared/machine-credential.h @@ -18,5 +18,6 @@ void machine_credential_context_done(MachineCredentialContext *ctx); MachineCredential* machine_credential_find(MachineCredentialContext *ctx, const char *id); +int machine_credential_add(MachineCredentialContext *ctx, const char *id, const char *value, size_t size); int machine_credential_set(MachineCredentialContext *ctx, const char *cred_str); int machine_credential_load(MachineCredentialContext *ctx, const char *cred_path);