mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
Currently, if user doesn't specify a key file, /etc/cryptsetup-keys.d/ and /run/cryptsetup-keys.d/ will be searched for a key file with name matching the volume name. But current implementation has an important flaw. When the auto-discovered key is a socket file - it will read the key only once, while the socket might provide different keys for different types of tokens. The issue is fixed by trying to discover the key on each unlock attempt, this way we can populate the socket bind name with something the key provider might use to differentiate between different keys it has to provide.
56 lines
2.1 KiB
C
56 lines
2.1 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "cryptsetup-keyfile.h"
|
|
#include "fileio.h"
|
|
#include "path-util.h"
|
|
#include "strv.h"
|
|
|
|
int find_key_file(const char *key_file, char **search_path, const char *bindname, struct iovec *ret_key) {
|
|
|
|
int r;
|
|
|
|
assert(key_file);
|
|
assert(ret_key);
|
|
|
|
if (strv_isempty(search_path) || path_is_absolute(key_file)) {
|
|
|
|
r = read_full_file_full(
|
|
AT_FDCWD, key_file, UINT64_MAX, SIZE_MAX,
|
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
|
|
bindname,
|
|
(char**) &ret_key->iov_base, &ret_key->iov_len);
|
|
if (r == -E2BIG)
|
|
return log_error_errno(r, "Key file '%s' too large.", key_file);
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to load key file '%s': %m", key_file);
|
|
|
|
return 1;
|
|
}
|
|
|
|
STRV_FOREACH(i, search_path) {
|
|
_cleanup_free_ char *joined = NULL;
|
|
|
|
joined = path_join(*i, key_file);
|
|
if (!joined)
|
|
return log_oom();
|
|
|
|
r = read_full_file_full(
|
|
AT_FDCWD, joined, UINT64_MAX, SIZE_MAX,
|
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
|
|
bindname,
|
|
(char**) &ret_key->iov_base, &ret_key->iov_len);
|
|
if (r >= 0)
|
|
return 1;
|
|
if (r == -E2BIG) {
|
|
log_warning_errno(r, "Key file '%s' too large, ignoring.", key_file);
|
|
continue;
|
|
}
|
|
if (r != -ENOENT)
|
|
return log_error_errno(r, "Failed to load key file '%s': %m", key_file);
|
|
}
|
|
|
|
/* Search path supplied, but file not found, report by returning NULL, but not failing */
|
|
*ret_key = IOVEC_MAKE(NULL, 0);
|
|
return 0;
|
|
}
|