1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "creds-util.h"
6 #include "extract-word.h"
9 #include "memory-util.h"
10 #include "machine-credential.h"
11 #include "path-util.h"
12 #include "string-util-fundamental.h"
14 static void machine_credential_done(MachineCredential
*cred
) {
17 cred
->id
= mfree(cred
->id
);
18 cred
->data
= erase_and_free(cred
->data
);
22 void machine_credential_free_all(MachineCredential
*creds
, size_t n
) {
23 assert(creds
|| n
== 0);
25 FOREACH_ARRAY(cred
, creds
, n
)
26 machine_credential_done(cred
);
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
);
35 size_t n_creds
= *ASSERT_PTR(n_credentials
);
37 const char *p
= ASSERT_PTR(cred_string
);
39 assert(creds
|| n_creds
== 0);
41 r
= extract_first_word(&p
, &word
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
43 return log_error_errno(r
, "Failed to parse --set-credential= parameter: %m");
45 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Missing value for --set-credential=: %s", cred_string
);
47 if (!credential_name_valid(word
))
48 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "MachineCredential name is not valid: %s", word
);
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
);
54 l
= cunescape(p
, UNESCAPE_ACCEPT_NUL
, &data
);
56 return log_error_errno(l
, "Failed to unescape credential data: %s", p
);
58 GREEDY_REALLOC(creds
, n_creds
+ 1);
62 creds
[n_creds
++] = (MachineCredential
) {
64 .data
= TAKE_PTR(data
),
69 *n_credentials
= n_creds
;
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
);
81 const char *p
= ASSERT_PTR(cred_path
);
83 assert(creds
|| n_creds
== 0);
85 r
= extract_first_word(&p
, &word
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
87 return log_error_errno(r
, "Failed to parse --load-credential= parameter: %m");
89 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Missing value for --load-credential=: %s", cred_path
);
91 if (!credential_name_valid(word
))
92 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "MachineCredential name is not valid: %s", word
);
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
);
98 if (path_is_absolute(p
))
99 flags
|= READ_FULL_FILE_CONNECT_SOCKET
;
103 r
= get_credentials_dir(&e
);
105 return log_error_errno(r
, "MachineCredential not available (no credentials passed at all): %s", word
);
112 r
= read_full_file_full(AT_FDCWD
, j
?: p
, UINT64_MAX
, SIZE_MAX
,
117 return log_error_errno(r
, "Failed to read credential '%s': %m", j
?: p
);
119 GREEDY_REALLOC(creds
, n_creds
+ 1);
123 creds
[n_creds
++] = (MachineCredential
) {
124 .id
= TAKE_PTR(word
),
125 .data
= TAKE_PTR(data
),
129 *credentials
= creds
;
130 *n_credentials
= n_creds
;