The function is quite general, and can be used at other places.
Let's move to our shared library.
#include <getopt.h>
#include "build.h"
-#include "copy.h"
#include "creds-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "network-generator.h"
#include "path-util.h"
#include "proc-cmdline.h"
-#include "recurse-dir.h"
#define NETWORK_UNIT_DIRECTORY "/run/systemd/network/"
return r;
}
-static int pick_up_credentials(void) {
- _cleanup_close_ int credential_dir_fd = -EBADF;
- int r, ret = 0;
-
- credential_dir_fd = open_credentials_dir();
- if (IN_SET(credential_dir_fd, -ENXIO, -ENOENT)) /* Credential env var not set, or dir doesn't exist. */
- return 0;
- if (credential_dir_fd < 0)
- return log_error_errno(credential_dir_fd, "Failed to open credentials directory: %m");
-
- _cleanup_free_ DirectoryEntries *des = NULL;
- r = readdir_all(credential_dir_fd, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE, &des);
- if (r < 0)
- return log_error_errno(r, "Failed to enumerate credentials: %m");
-
- FOREACH_ARRAY(i, des->entries, des->n_entries) {
- static const struct {
- const char *credential_prefix;
- const char *filename_suffix;
- } table[] = {
- { "network.link.", ".link" },
- { "network.netdev.", ".netdev" },
- { "network.network.", ".network" },
- };
-
- _cleanup_free_ char *fn = NULL;
- struct dirent *de = *i;
-
- if (de->d_type != DT_REG)
- continue;
-
- FOREACH_ARRAY(t, table, ELEMENTSOF(table)) {
- const char *e = startswith(de->d_name, t->credential_prefix);
-
- if (e) {
- fn = strjoin(e, t->filename_suffix);
- if (!fn)
- return log_oom();
-
- break;
- }
- }
-
- if (!fn)
- continue;
-
- if (!filename_is_valid(fn)) {
- log_warning("Passed credential '%s' would result in invalid filename '%s', ignoring.", de->d_name, fn);
- continue;
- }
-
- _cleanup_free_ char *output = path_join(NETWORK_UNIT_DIRECTORY, fn);
- if (!output)
- return log_oom();
-
- r = copy_file_at(
- credential_dir_fd, de->d_name,
- AT_FDCWD, output,
- /* open_flags= */ 0,
- 0644,
- /* flags= */ 0);
- if (r < 0)
- RET_GATHER(ret, log_warning_errno(r, "Failed to copy credential %s → file %s: %m", de->d_name, output));
- else
- log_info("Installed %s from credential.", output);
- }
-
- return ret;
-}
-
static int help(void) {
printf("%s [OPTIONS...] [-- KERNEL_CMDLINE]\n"
" -h --help Show this help\n"
return log_warning_errno(r, "Failed to merge multiple command line options: %m");
RET_GATHER(ret, context_save(&context));
- RET_GATHER(ret, pick_up_credentials());
+
+ static const PickUpCredential table[] = {
+ { "network.link.", NETWORK_UNIT_DIRECTORY, ".link" },
+ { "network.netdev.", NETWORK_UNIT_DIRECTORY, ".netdev" },
+ { "network.network.", NETWORK_UNIT_DIRECTORY, ".network" },
+ };
+ RET_GATHER(ret, pick_up_credentials(table, ELEMENTSOF(table)));
return ret;
}
#include "capability-util.h"
#include "chattr-util.h"
#include "constants.h"
+#include "copy.h"
#include "creds-util.h"
#include "efi-api.h"
#include "env-util.h"
#include "fs-util.h"
#include "io-util.h"
#include "memory-util.h"
-#include "mkdir.h"
+#include "mkdir-label.h"
#include "openssl-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "random-util.h"
+#include "recurse-dir.h"
#include "sparse-endian.h"
#include "stat-util.h"
#include "tmpfile-util.h"
return 0;
}
+
+static int pick_up_credential_one(
+ int credential_dir_fd,
+ const char *credential_name,
+ const PickUpCredential *table_entry) {
+
+ _cleanup_free_ char *fn = NULL, *target_path = NULL;
+ const char *e;
+ int r;
+
+ assert(credential_dir_fd >= 0);
+ assert(credential_name);
+ assert(table_entry);
+
+ e = startswith(credential_name, table_entry->credential_prefix);
+ if (!e)
+ return 0; /* unmatched */
+
+ fn = strjoin(e, table_entry->filename_suffix);
+ if (!fn)
+ return log_oom();
+
+ if (!filename_is_valid(fn))
+ return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Passed credential '%s' would result in invalid filename '%s'.",
+ credential_name, fn);
+
+ r = mkdir_p_label(table_entry->target_dir, 0755);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to create '%s': %m", table_entry->target_dir);
+
+ target_path = path_join(table_entry->target_dir, fn);
+ if (!target_path)
+ return log_oom();
+
+ r = copy_file_at(
+ credential_dir_fd, credential_name,
+ AT_FDCWD, target_path,
+ /* open_flags= */ 0,
+ 0644,
+ /* flags= */ 0);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to copy credential %s → file %s: %m",
+ credential_name, target_path);
+
+ log_info("Installed %s from credential.", target_path);
+ return 1; /* done */
+}
+
+int pick_up_credentials(const PickUpCredential *table, size_t n_table_entry) {
+ _cleanup_close_ int credential_dir_fd = -EBADF;
+ int r, ret = 0;
+
+ assert(table);
+ assert(n_table_entry > 0);
+
+ credential_dir_fd = open_credentials_dir();
+ if (IN_SET(credential_dir_fd, -ENXIO, -ENOENT)) {
+ /* Credential env var not set, or dir doesn't exist. */
+ log_debug("No credentials found.");
+ return 0;
+ }
+ if (credential_dir_fd < 0)
+ return log_error_errno(credential_dir_fd, "Failed to open credentials directory: %m");
+
+ _cleanup_free_ DirectoryEntries *des = NULL;
+ r = readdir_all(credential_dir_fd, RECURSE_DIR_SORT|RECURSE_DIR_IGNORE_DOT|RECURSE_DIR_ENSURE_TYPE, &des);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enumerate credentials: %m");
+
+ FOREACH_ARRAY(i, des->entries, des->n_entries) {
+ struct dirent *de = *i;
+
+ if (de->d_type != DT_REG)
+ continue;
+
+ FOREACH_ARRAY(t, table, n_table_entry) {
+ r = pick_up_credential_one(credential_dir_fd, de->d_name, t);
+ if (r != 0) {
+ RET_GATHER(ret, r);
+ break; /* Done, or failed. Let's move to the next credential. */
+ }
+ }
+ }
+
+ return ret;
+}
int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after, uid_t uid, const struct iovec *input, CredentialFlags flags, struct iovec *ret);
int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp, uid_t uid, const struct iovec *input, CredentialFlags flags, struct iovec *ret);
+
+typedef struct PickUpCredential {
+ const char *credential_prefix;
+ const char *target_dir;
+ const char *filename_suffix;
+} PickUpCredential;
+
+int pick_up_credentials(const PickUpCredential *table, size_t n_table_entry);