1
0
mirror of https://github.com/systemd/systemd synced 2026-03-30 03:34:49 +02:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Yu Watanabe
b00756030b
Merge pull request #20969 from poettering/cryptenroll-no-homed
cryptenroll: politely refuse enrolling keys into homed volumes
2021-10-10 16:00:07 +09:00
Lennart Poettering
de4a575e41 update TODO 2021-10-08 23:50:04 +02:00
Lennart Poettering
e0142d4ff8 cryptenroll: politely refuse enrolling keys into homed volumes
People should use homectl to enroll tokens into home directories, hence
point them there. Otherwise the auth data for the account and for the
LUKS volume will end up being different.
2021-10-08 23:50:04 +02:00
Lennart Poettering
d71059072a homed: don't forget to look at all enrolled tokens
We accidentally increased the token index twice whenever we found our
token. Fix that.
2021-10-08 23:50:04 +02:00
Lennart Poettering
e7e30330ff homed: use crypt_token_max() where appropriate
Let's use the new crypt_token_max() API in systemd-homework too, to cut
iteration of tokens short.

We already use it in cryptenroll/cryptsetup, so let's use it here too.
2021-10-08 23:50:04 +02:00
Lennart Poettering
4a09a67755 cryptsetup: also define crypt_token_max() as fallback locally, not just sym_crypt_token_max()
Our code that links directly against libcryptsetup, and doesn't use
dlopen() might want to use this fallback glue function too.
2021-10-08 23:50:04 +02:00
4 changed files with 31 additions and 8 deletions

3
TODO
View File

@ -226,9 +226,6 @@ Features:
* introduce a new group to own TPM devices
* cryptenroll: politely refuse enrolling new keys to homed volumes, since we
we cannot update identity info
* cryptsetup: if only recovery keys are registered and no regular passphrases,
ask user for "recovery key", not "passphrase"

View File

@ -381,6 +381,28 @@ static int parse_argv(int argc, char *argv[]) {
return 1;
}
static int check_for_homed(struct crypt_device *cd) {
int r;
assert_se(cd);
/* Politely refuse operating on homed volumes. The enrolled tokens for the user record and the LUKS2
* volume should not get out of sync. */
for (int token = 0; token < crypt_token_max(CRYPT_LUKS2); token ++) {
r = cryptsetup_get_token_as_json(cd, token, "systemd-homed", NULL);
if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE))
continue;
if (r < 0)
return log_error_errno(r, "Failed to read JSON token data off disk: %m");
return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN),
"LUKS2 volume is managed by systemd-homed, please use homectl to enroll tokens.");
}
return 0;
}
static int prepare_luks(
struct crypt_device **ret_cd,
void **ret_volume_key,
@ -405,6 +427,10 @@ static int prepare_luks(
if (r < 0)
return log_error_errno(r, "Failed to load LUKS2 superblock: %m");
r = check_for_homed(cd);
if (r < 0)
return r;
if (!ret_volume_key) {
*ret_cd = TAKE_PTR(cd);
return 0;

View File

@ -698,7 +698,7 @@ static int luks_validate_home_record(
assert(cd);
assert(h);
for (int token = 0;; token++) {
for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *rr = NULL;
_cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *context = NULL;
_cleanup_(user_record_unrefp) UserRecord *lhr = NULL;
@ -894,7 +894,7 @@ int home_store_header_identity_luks(
_cleanup_(user_record_unrefp) UserRecord *header_home = NULL;
_cleanup_free_ char *text = NULL;
int token = 0, r;
int r;
assert(h);
@ -924,7 +924,7 @@ int home_store_header_identity_luks(
if (r < 0)
return r;
for (;; token++) {
for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
crypt_token_info state;
const char *type;
@ -946,7 +946,6 @@ int home_store_header_identity_luks(
/* Now, let's free the text so that for all further matching tokens we all crypt_json_token_set()
* with a NULL text in order to invalidate the tokens. */
text = mfree(text);
token++;
}
if (text)

View File

@ -54,11 +54,12 @@ extern int (*sym_crypt_token_json_set)(struct crypt_device *cd, int token, const
extern int (*sym_crypt_token_max)(const char *type);
#else
/* As a fallback, use the same hard-coded value libcryptsetup uses internally. */
static inline int sym_crypt_token_max(_unused_ const char *type) {
static inline int crypt_token_max(_unused_ const char *type) {
assert(streq(type, CRYPT_LUKS2));
return 32;
}
#define sym_crypt_token_max(type) crypt_token_max(type)
#endif
extern crypt_token_info (*sym_crypt_token_status)(struct crypt_device *cd, int token, const char **type);
extern int (*sym_crypt_volume_key_get)(struct crypt_device *cd, int keyslot, char *volume_key, size_t *volume_key_size, const char *passphrase, size_t passphrase_size);