cryptsetup: make key discovery more robust

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.
This commit is contained in:
Kamil Szczęk
2024-06-27 12:58:45 +02:00
committed by Luca Boccassi
parent db2b897a86
commit 53b6c99018
4 changed files with 136 additions and 94 deletions
+4 -11
View File
@@ -5,18 +5,12 @@
#include "path-util.h"
#include "strv.h"
int find_key_file(
const char *key_file,
char **search_path,
const char *bindname,
void **ret_key,
size_t *ret_key_size) {
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);
assert(ret_key_size);
if (strv_isempty(search_path) || path_is_absolute(key_file)) {
@@ -24,7 +18,7 @@ int find_key_file(
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, ret_key_size);
(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)
@@ -44,7 +38,7 @@ int find_key_file(
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, ret_key_size);
(char**) &ret_key->iov_base, &ret_key->iov_len);
if (r >= 0)
return 1;
if (r == -E2BIG) {
@@ -56,7 +50,6 @@ int find_key_file(
}
/* Search path supplied, but file not found, report by returning NULL, but not failing */
*ret_key = NULL;
*ret_key_size = 0;
*ret_key = IOVEC_MAKE(NULL, 0);
return 0;
}