]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/machine-credential.c
machine-credential: fix error logging
[thirdparty/systemd.git] / src / shared / machine-credential.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "creds-util.h"
5 #include "escape.h"
6 #include "extract-word.h"
7 #include "fileio.h"
8 #include "macro.h"
9 #include "memory-util.h"
10 #include "machine-credential.h"
11 #include "path-util.h"
12 #include "string-util-fundamental.h"
13
14 static void machine_credential_done(MachineCredential *cred) {
15 assert(cred);
16
17 cred->id = mfree(cred->id);
18 cred->data = erase_and_free(cred->data);
19 cred->size = 0;
20 }
21
22 void machine_credential_free_all(MachineCredential *creds, size_t n) {
23 assert(creds || n == 0);
24
25 FOREACH_ARRAY(cred, creds, n)
26 machine_credential_done(cred);
27
28 free(creds);
29 }
30
31 int machine_credential_set(MachineCredential **credentials, size_t *n_credentials, const char *cred_string) {
32 _cleanup_free_ char *word = NULL, *data = NULL;
33 MachineCredential *creds = *ASSERT_PTR(credentials);
34 ssize_t l;
35 size_t n_creds = *ASSERT_PTR(n_credentials);
36 int r;
37 const char *p = ASSERT_PTR(cred_string);
38
39 assert(creds || n_creds == 0);
40
41 r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
42 if (r < 0)
43 return log_error_errno(r, "Failed to parse --set-credential= parameter: %m");
44 if (r == 0 || !p)
45 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --set-credential=: %s", cred_string);
46
47 if (!credential_name_valid(word))
48 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "MachineCredential name is not valid: %s", word);
49
50 FOREACH_ARRAY(cred, creds, n_creds)
51 if (streq(cred->id, word))
52 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
53
54 l = cunescape(p, UNESCAPE_ACCEPT_NUL, &data);
55 if (l < 0)
56 return log_error_errno(l, "Failed to unescape credential data: %s", p);
57
58 GREEDY_REALLOC(creds, n_creds + 1);
59 if (!creds)
60 return log_oom();
61
62 creds[n_creds++] = (MachineCredential) {
63 .id = TAKE_PTR(word),
64 .data = TAKE_PTR(data),
65 .size = l,
66 };
67
68 *credentials = creds;
69 *n_credentials = n_creds;
70
71 return 0;
72 }
73
74 int machine_credential_load(MachineCredential **credentials, size_t *n_credentials, const char *cred_path) {
75 ReadFullFileFlags flags = READ_FULL_FILE_SECURE;
76 _cleanup_(erase_and_freep) char *data = NULL;
77 _cleanup_free_ char *word = NULL, *j = NULL;
78 MachineCredential *creds = *ASSERT_PTR(credentials);
79 size_t size, n_creds = *ASSERT_PTR(n_credentials);
80 int r;
81 const char *p = ASSERT_PTR(cred_path);
82
83 assert(creds || n_creds == 0);
84
85 r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
86 if (r < 0)
87 return log_error_errno(r, "Failed to parse --load-credential= parameter: %m");
88 if (r == 0 || !p)
89 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Missing value for --load-credential=: %s", cred_path);
90
91 if (!credential_name_valid(word))
92 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "MachineCredential name is not valid: %s", word);
93
94 FOREACH_ARRAY(cred, creds, n_creds)
95 if (streq(cred->id, word))
96 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
97
98 if (path_is_absolute(p))
99 flags |= READ_FULL_FILE_CONNECT_SOCKET;
100 else {
101 const char *e;
102
103 r = get_credentials_dir(&e);
104 if (r < 0)
105 return log_error_errno(r, "MachineCredential not available (no credentials passed at all): %s", word);
106
107 j = path_join(e, p);
108 if (!j)
109 return log_oom();
110 }
111
112 r = read_full_file_full(AT_FDCWD, j ?: p, UINT64_MAX, SIZE_MAX,
113 flags,
114 NULL,
115 &data, &size);
116 if (r < 0)
117 return log_error_errno(r, "Failed to read credential '%s': %m", j ?: p);
118
119 GREEDY_REALLOC(creds, n_creds + 1);
120 if (!creds)
121 return log_oom();
122
123 creds[n_creds++] = (MachineCredential) {
124 .id = TAKE_PTR(word),
125 .data = TAKE_PTR(data),
126 .size = size,
127 };
128
129 *credentials = creds;
130 *n_credentials = n_creds;
131
132 return 0;
133 }