Merge pull request #19768 from poettering/homectl-fido2-lock-with

homed: catch up with FIDO2 features in cryptsetup + other fixes
This commit is contained in:
Lennart Poettering
2021-06-01 15:53:36 +02:00
committed by GitHub
37 changed files with 479 additions and 161 deletions
+2
View File
@@ -510,6 +510,8 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
cryptsetup_enable_logging(NULL);
if (arg_enroll_type < 0)
r = prepare_luks(&cd, NULL, NULL); /* No need to unlock device if we don't need the volume key because we don't need to enroll anything */
else
+1 -1
View File
@@ -1449,7 +1449,7 @@ static int run(int argc, char *argv[]) {
log_setup();
cryptsetup_enable_logging(cd);
cryptsetup_enable_logging(NULL);
umask(0022);
+13 -6
View File
@@ -68,7 +68,8 @@ static int add_fido2_salt(
const void *fido2_salt,
size_t fido2_salt_size,
const void *secret,
size_t secret_size) {
size_t secret_size,
Fido2EnrollFlags lock_with) {
_cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
_cleanup_(erase_and_freep) char *base64_encoded = NULL, *hashed = NULL;
@@ -87,7 +88,11 @@ static int add_fido2_salt(
r = json_build(&e, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("credential", JSON_BUILD_BASE64(cid, cid_size)),
JSON_BUILD_PAIR("salt", JSON_BUILD_BASE64(fido2_salt, fido2_salt_size)),
JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed))));
JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed)),
JSON_BUILD_PAIR("up", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UP))),
JSON_BUILD_PAIR("uv", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UV))),
JSON_BUILD_PAIR("clientPin", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_PIN)))));
if (r < 0)
return log_error_errno(r, "Failed to build FIDO2 salt JSON key object: %m");
@@ -112,7 +117,8 @@ static int add_fido2_salt(
int identity_add_fido2_parameters(
JsonVariant **v,
const char *device) {
const char *device,
Fido2EnrollFlags lock_with) {
#if HAVE_LIBFIDO2
JsonVariant *un, *realm, *rn;
@@ -158,12 +164,12 @@ int identity_add_fido2_parameters(
/* user_display_name= */ rn ? json_variant_string(rn) : NULL,
/* user_icon_name= */ NULL,
/* askpw_icon_name= */ "user-home",
FIDO2ENROLL_PIN | FIDO2ENROLL_UP, // FIXME: add a --lock-with-pin/up parameter like cryptenroll
lock_with,
&cid, &cid_size,
&salt, &salt_size,
&secret, &secret_size,
&used_pin,
NULL);
&lock_with);
if (r < 0)
return r;
@@ -181,7 +187,8 @@ int identity_add_fido2_parameters(
salt,
salt_size,
secret,
secret_size);
secret_size,
lock_with);
if (r < 0)
return r;
+2 -1
View File
@@ -2,5 +2,6 @@
#pragma once
#include "json.h"
#include "libfido2-util.h"
int identity_add_fido2_parameters(JsonVariant **v, const char *device);
int identity_add_fido2_parameters(JsonVariant **v, const char *device, Fido2EnrollFlags lock_with);
+71 -9
View File
@@ -57,6 +57,7 @@ static uint64_t arg_disk_size = UINT64_MAX;
static uint64_t arg_disk_size_relative = UINT64_MAX;
static char **arg_pkcs11_token_uri = NULL;
static char **arg_fido2_device = NULL;
static Fido2EnrollFlags arg_fido2_lock_with = FIDO2ENROLL_PIN | FIDO2ENROLL_UP;
static bool arg_recovery_key = false;
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
static bool arg_and_resize = false;
@@ -380,7 +381,7 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
log_notice("%s%sAuthentication requires presence verification on security token.",
log_notice("%s%sPlease confirm presence on security token.",
emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
@@ -388,6 +389,16 @@ static int handle_generic_user_record_error(
if (r < 0)
return log_error_errno(r, "Failed to set FIDO2 user presence permitted flag: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED)) {
log_notice("%s%sPlease verify user on security token.",
emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
emoji_enabled() ? " " : "");
r = user_record_set_fido2_user_verification_permitted(hr, true);
if (r < 0)
return log_error_errno(r, "Failed to set FIDO2 user verification permitted flag: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_LOCKED))
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)");
@@ -560,9 +571,9 @@ static void dump_home_record(UserRecord *hr) {
_cleanup_(user_record_unrefp) UserRecord *stripped = NULL;
if (arg_export_format == EXPORT_FORMAT_STRIPPED)
r = user_record_clone(hr, USER_RECORD_EXTRACT_EMBEDDED, &stripped);
r = user_record_clone(hr, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &stripped);
else if (arg_export_format == EXPORT_FORMAT_MINIMAL)
r = user_record_clone(hr, USER_RECORD_EXTRACT_SIGNABLE, &stripped);
r = user_record_clone(hr, USER_RECORD_EXTRACT_SIGNABLE|USER_RECORD_PERMISSIVE, &stripped);
else
r = 0;
if (r < 0)
@@ -667,7 +678,7 @@ static int inspect_home(int argc, char *argv[], void *userdata) {
if (!hr)
return log_oom();
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG);
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0) {
if (ret == 0)
ret = r;
@@ -1027,7 +1038,7 @@ static int acquire_new_home_record(UserRecord **ret) {
}
STRV_FOREACH(i, arg_fido2_device) {
r = identity_add_fido2_parameters(&v, *i);
r = identity_add_fido2_parameters(&v, *i, arg_fido2_lock_with);
if (r < 0)
return r;
}
@@ -1049,7 +1060,7 @@ static int acquire_new_home_record(UserRecord **ret) {
if (!hr)
return log_oom();
r = user_record_load(hr, v, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_LOG);
r = user_record_load(hr, v, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -1397,7 +1408,7 @@ static int acquire_updated_home_record(
}
STRV_FOREACH(i, arg_fido2_device) {
r = identity_add_fido2_parameters(&json, *i);
r = identity_add_fido2_parameters(&json, *i, arg_fido2_lock_with);
if (r < 0)
return r;
}
@@ -1415,7 +1426,7 @@ static int acquire_updated_home_record(
if (!hr)
return log_oom();
r = user_record_load(hr, json, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_LOG);
r = user_record_load(hr, json, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -1440,6 +1451,10 @@ static int home_record_reset_human_interaction_permission(UserRecord *hr) {
if (r < 0)
return log_error_errno(r, "Failed to reset FIDO2 user presence permission flag: %m");
r = user_record_set_fido2_user_verification_permitted(hr, -1);
if (r < 0)
return log_error_errno(r, "Failed to reset FIDO2 user verification permission flag: %m");
return 0;
}
@@ -2071,6 +2086,15 @@ static int help(int argc, char *argv[], void *userdata) {
" private key and matching X.509 certificate\n"
" --fido2-device=PATH Path to FIDO2 hidraw device with hmac-secret\n"
" extension\n"
" --fido2-with-client-pin=BOOL\n"
" Whether to require entering a PIN to unlock the\n"
" account\n"
" --fido2-with-user-presence=BOOL\n"
" Whether to require user presence to unlock the\n"
" account\n"
" --fido2-with-user-verification=BOOL\n"
" Whether to require user verification to unlock the\n"
" account\n"
" --recovery-key=BOOL Add a recovery key\n"
"\n%4$sAccount Management User Record Properties:%5$s\n"
" --locked=BOOL Set locked account state\n"
@@ -2220,6 +2244,9 @@ static int parse_argv(int argc, char *argv[]) {
ARG_AUTO_LOGIN,
ARG_PKCS11_TOKEN_URI,
ARG_FIDO2_DEVICE,
ARG_FIDO2_WITH_PIN,
ARG_FIDO2_WITH_UP,
ARG_FIDO2_WITH_UV,
ARG_RECOVERY_KEY,
ARG_AND_RESIZE,
ARG_AND_CHANGE_PASSWORD,
@@ -2299,6 +2326,9 @@ static int parse_argv(int argc, char *argv[]) {
{ "export-format", required_argument, NULL, ARG_EXPORT_FORMAT },
{ "pkcs11-token-uri", required_argument, NULL, ARG_PKCS11_TOKEN_URI },
{ "fido2-device", required_argument, NULL, ARG_FIDO2_DEVICE },
{ "fido2-with-client-pin", required_argument, NULL, ARG_FIDO2_WITH_PIN },
{ "fido2-with-user-presence", required_argument, NULL, ARG_FIDO2_WITH_UP },
{ "fido2-with-user-verification",required_argument, NULL, ARG_FIDO2_WITH_UV },
{ "recovery-key", required_argument, NULL, ARG_RECOVERY_KEY },
{ "and-resize", required_argument, NULL, ARG_AND_RESIZE },
{ "and-change-password", required_argument, NULL, ARG_AND_CHANGE_PASSWORD },
@@ -3323,7 +3353,6 @@ static int parse_argv(int argc, char *argv[]) {
r = strv_consume(&arg_fido2_device, TAKE_PTR(found));
} else
r = strv_extend(&arg_fido2_device, optarg);
if (r < 0)
return r;
@@ -3331,6 +3360,39 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
case ARG_FIDO2_WITH_PIN: {
bool lock_with_pin;
r = parse_boolean_argument("--fido2-with-client-pin=", optarg, &lock_with_pin);
if (r < 0)
return r;
SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_PIN, lock_with_pin);
break;
}
case ARG_FIDO2_WITH_UP: {
bool lock_with_up;
r = parse_boolean_argument("--fido2-with-user-presence=", optarg, &lock_with_up);
if (r < 0)
return r;
SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_UP, lock_with_up);
break;
}
case ARG_FIDO2_WITH_UV: {
bool lock_with_uv;
r = parse_boolean_argument("--fido2-with-user-verification=", optarg, &lock_with_uv);
if (r < 0)
return r;
SET_FLAG(arg_fido2_lock_with, FIDO2ENROLL_UV, lock_with_uv);
break;
}
case ARG_RECOVERY_KEY: {
const char *p;
+1 -1
View File
@@ -28,7 +28,7 @@ int bus_message_read_secret(sd_bus_message *m, UserRecord **ret, sd_bus_error *e
if (!hr)
return -ENOMEM;
r = user_record_load(hr, full, USER_RECORD_REQUIRE_SECRET);
r = user_record_load(hr, full, USER_RECORD_REQUIRE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
+2 -2
View File
@@ -95,7 +95,7 @@ int bus_home_get_record_json(
trusted = false;
}
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE;
if (trusted)
flags |= USER_RECORD_ALLOW_PRIVILEGED;
else
@@ -443,7 +443,7 @@ int bus_home_method_update(
assert(message);
assert(h);
r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_REQUIRE_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE, &hr, error);
r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_REQUIRE_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE, &hr, error);
if (r < 0)
return r;
+10 -8
View File
@@ -145,7 +145,7 @@ int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret) {
return r;
}
r = user_record_clone(hr, USER_RECORD_LOAD_MASK_SECRET, &home->record);
r = user_record_clone(hr, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &home->record);
if (r < 0)
return r;
@@ -243,7 +243,7 @@ int home_set_record(Home *h, UserRecord *hr) {
if (!new_hr)
return -ENOMEM;
r = user_record_load(new_hr, v, USER_RECORD_LOAD_REFUSE_SECRET);
r = user_record_load(new_hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -384,7 +384,7 @@ static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
if (!hr)
return log_oom();
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET);
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
return log_error_errno(r, "Failed to load home record identity: %m");
@@ -461,7 +461,9 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
case -ERFKILL:
return sd_bus_error_set(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, "Security token requires protected authentication path.");
case -EMEDIUMTYPE:
return sd_bus_error_set(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, "Security token requires user presence.");
return sd_bus_error_set(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, "Security token requires presence confirmation.");
case -ENOCSI:
return sd_bus_error_set(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED, "Security token requires user verification.");
case -ENOSTR:
return sd_bus_error_set(error, BUS_ERROR_TOKEN_ACTION_TIMEOUT, "Token action timeout. (User was supposed to verify presence or similar, by interacting with the token, and didn't do that in time.)");
case -EOWNERDEAD:
@@ -1408,7 +1410,7 @@ static int home_update_internal(
return sd_bus_error_set(error, BUS_ERROR_HOME_RECORD_DOWNGRADE, "Refusing to update to older home record.");
if (!secret && FLAGS_SET(hr->mask, USER_RECORD_SECRET)) {
r = user_record_clone(hr, USER_RECORD_EXTRACT_SECRET, &saved_secret);
r = user_record_clone(hr, USER_RECORD_EXTRACT_SECRET|USER_RECORD_PERMISSIVE, &saved_secret);
if (r < 0)
return r;
@@ -1443,7 +1445,7 @@ static int home_update_internal(
return r;
}
r = user_record_extend_with_binding(hr, h->record, USER_RECORD_LOAD_MASK_SECRET, &new_hr);
r = user_record_extend_with_binding(hr, h->record, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_hr);
if (r < 0)
return r;
@@ -1537,7 +1539,7 @@ int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *e
if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE, &c);
if (r < 0)
return r;
@@ -1626,7 +1628,7 @@ int home_passwd(Home *h,
if (r < 0)
return r;
r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE, &c);
if (r < 0)
return r;
+2 -2
View File
@@ -398,7 +398,7 @@ static int method_register_home(
assert(message);
assert(m);
r = bus_message_read_home_record(message, USER_RECORD_LOAD_EMBEDDED, &hr, error);
r = bus_message_read_home_record(message, USER_RECORD_LOAD_EMBEDDED|USER_RECORD_PERMISSIVE, &hr, error);
if (r < 0)
return r;
@@ -513,7 +513,7 @@ static int method_update_home(sd_bus_message *message, void *userdata, sd_bus_er
assert(message);
assert(m);
r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE, &hr, error);
r = bus_message_read_home_record(message, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_SECRET|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE, &hr, error);
if (r < 0)
return r;
+1 -1
View File
@@ -364,7 +364,7 @@ static int manager_add_home_by_record(
if (!hr)
return log_oom();
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG);
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
+1 -1
View File
@@ -42,7 +42,7 @@ static int build_user_json(Home *h, bool trusted, JsonVariant **ret) {
assert(h);
assert(ret);
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE;
if (trusted)
flags |= USER_RECORD_ALLOW_PRIVILEGED;
else
+1 -1
View File
@@ -185,7 +185,7 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
if (r < 0)
return r;
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET, &new_home);
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_home);
if (r < 0)
return log_error_errno(r, "Failed to clone record: %m");
+1 -1
View File
@@ -158,7 +158,7 @@ int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home) {
if (r < 0)
return r;
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET, &new_home);
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_home);
if (r < 0)
return log_error_errno(r, "Failed to clone record: %m");
+32 -1
View File
@@ -6,6 +6,7 @@
#include "homework-fido2.h"
#include "libfido2-util.h"
#include "memory-util.h"
#include "strv.h"
int fido2_use_token(
UserRecord *h,
@@ -15,6 +16,7 @@ int fido2_use_token(
_cleanup_(erase_and_freep) void *hmac = NULL;
size_t hmac_size;
Fido2EnrollFlags flags = 0;
int r;
assert(h);
@@ -22,13 +24,42 @@ int fido2_use_token(
assert(salt);
assert(ret);
/* If we know the up/uv/clientPin settings used during enrollment, let's pass this on for
* authentication, or generate errors immediately if interactivity of the specified kind is not
* allowed. */
if (salt->up > 0) {
if (h->fido2_user_presence_permitted <= 0)
return -EMEDIUMTYPE;
flags |= FIDO2ENROLL_UP;
} else if (salt->up < 0) /* unset? */
flags |= FIDO2ENROLL_UP_IF_NEEDED; /* compat with pre-248 */
if (salt->uv > 0) {
if (h->fido2_user_verification_permitted <= 0)
return -ENOCSI;
flags |= FIDO2ENROLL_UV;
} else if (salt->uv < 0)
flags |= FIDO2ENROLL_UV_OMIT; /* compat with pre-248 */
if (salt->client_pin > 0) {
if (strv_isempty(secret->token_pin))
return -ENOANO;
flags |= FIDO2ENROLL_PIN;
} else if (salt->client_pin < 0)
flags |= FIDO2ENROLL_PIN_IF_NEEDED; /* compat with pre-248 */
r = fido2_use_hmac_hash(
NULL,
"io.systemd.home",
salt->salt, salt->salt_size,
salt->credential.id, salt->credential.size,
secret->token_pin,
FIDO2ENROLL_PIN | (h->fido2_user_presence_permitted > 0 ? FIDO2ENROLL_UP : 0), // FIXME: add a --lock-with-pin parameter like cryptenroll
flags,
&hmac,
&hmac_size);
if (r < 0)
+1 -1
View File
@@ -550,7 +550,7 @@ int home_create_fscrypt(
if (r < 0)
return r;
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET, &new_home);
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, &new_home);
if (r < 0)
return log_error_errno(r, "Failed to clone record: %m");
+96 -64
View File
@@ -243,7 +243,7 @@ static int luks_try_passwords(
STRV_FOREACH(pp, passwords) {
size_t vks = *volume_key_size;
r = crypt_volume_key_get(
r = sym_crypt_volume_key_get(
cd,
CRYPT_ANY_SLOT,
volume_key,
@@ -276,7 +276,7 @@ static int luks_setup(
void **ret_volume_key,
size_t *ret_volume_key_size) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *vk = NULL;
sd_id128_t p;
size_t vks;
@@ -287,17 +287,17 @@ static int luks_setup(
assert(dm_name);
assert(ret);
r = crypt_init(&cd, node);
r = sym_crypt_init(&cd, node);
if (r < 0)
return log_error_errno(r, "Failed to allocate libcryptsetup context: %m");
cryptsetup_enable_logging(cd);
r = crypt_load(cd, CRYPT_LUKS2, NULL);
r = sym_crypt_load(cd, CRYPT_LUKS2, NULL);
if (r < 0)
return log_error_errno(r, "Failed to load LUKS superblock: %m");
r = crypt_get_volume_key_size(cd);
r = sym_crypt_get_volume_key_size(cd);
if (r <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
vks = (size_t) r;
@@ -305,7 +305,7 @@ static int luks_setup(
if (!sd_id128_is_null(uuid) || ret_found_uuid) {
const char *s;
s = crypt_get_uuid(cd);
s = sym_crypt_get_uuid(cd);
if (!s)
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "LUKS superblock has no UUID.");
@@ -319,10 +319,10 @@ static int luks_setup(
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "LUKS superblock has wrong UUID.");
}
if (cipher && !streq_ptr(cipher, crypt_get_cipher(cd)))
if (cipher && !streq_ptr(cipher, sym_crypt_get_cipher(cd)))
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "LUKS superblock declares wrong cipher.");
if (cipher_mode && !streq_ptr(cipher_mode, crypt_get_cipher_mode(cd)))
if (cipher_mode && !streq_ptr(cipher_mode, sym_crypt_get_cipher_mode(cd)))
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "LUKS superblock declares wrong cipher mode.");
if (volume_key_size != UINT64_MAX && vks != volume_key_size)
@@ -343,7 +343,7 @@ static int luks_setup(
if (r < 0)
return log_error_errno(r, "Failed to unlocks LUKS superblock: %m");
r = crypt_activate_by_volume_key(
r = sym_crypt_activate_by_volume_key(
cd,
dm_name,
vk, vks,
@@ -374,7 +374,7 @@ static int luks_open(
void **ret_volume_key,
size_t *ret_volume_key_size) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *vk = NULL;
sd_id128_t p;
char **list;
@@ -387,17 +387,17 @@ static int luks_open(
/* Opens a LUKS device that is already set up. Re-validates the password while doing so (which also
* provides us with the volume key, which we want). */
r = crypt_init_by_name(&cd, dm_name);
r = sym_crypt_init_by_name(&cd, dm_name);
if (r < 0)
return log_error_errno(r, "Failed to initialize cryptsetup context for %s: %m", dm_name);
cryptsetup_enable_logging(cd);
r = crypt_load(cd, CRYPT_LUKS2, NULL);
r = sym_crypt_load(cd, CRYPT_LUKS2, NULL);
if (r < 0)
return log_error_errno(r, "Failed to load LUKS superblock: %m");
r = crypt_get_volume_key_size(cd);
r = sym_crypt_get_volume_key_size(cd);
if (r <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
vks = (size_t) r;
@@ -405,7 +405,7 @@ static int luks_open(
if (ret_found_uuid) {
const char *s;
s = crypt_get_uuid(cd);
s = sym_crypt_get_uuid(cd);
if (!s)
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "LUKS superblock has no UUID.");
@@ -433,7 +433,7 @@ static int luks_open(
/* This is needed so that crypt_resize() can operate correctly for pre-existing LUKS devices. We need
* to tell libcryptsetup the volume key explicitly, so that it is in the kernel keyring. */
r = crypt_activate_by_volume_key(cd, NULL, vk, vks, CRYPT_ACTIVATE_KEYRING_KEY);
r = sym_crypt_activate_by_volume_key(cd, NULL, vk, vks, CRYPT_ACTIVATE_KEYRING_KEY);
if (r < 0)
return log_error_errno(r, "Failed to upload volume key again: %m");
@@ -640,11 +640,11 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
/* Let's find the right OpenSSL EVP_CIPHER object that matches the encryption settings of the LUKS
* device */
cipher = crypt_get_cipher(cd);
cipher = sym_crypt_get_cipher(cd);
if (!cipher)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot get cipher from LUKS device.");
cipher_mode = crypt_get_cipher_mode(cd);
cipher_mode = sym_crypt_get_cipher_mode(cd);
if (!cipher_mode)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot get cipher mode from LUKS device.");
@@ -652,7 +652,7 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
if (e)
cipher_mode = strndupa(cipher_mode, e - cipher_mode);
r = crypt_get_volume_key_size(cd);
r = sym_crypt_get_volume_key_size(cd);
if (r <= 0)
return log_error_errno(r < 0 ? r : SYNTHETIC_ERRNO(EINVAL), "Cannot get volume key size from LUKS device.");
@@ -703,7 +703,7 @@ static int luks_validate_home_record(
unsigned line, column;
const EVP_CIPHER *cc;
state = crypt_token_status(cd, token, &type);
state = sym_crypt_token_status(cd, token, &type);
if (state == CRYPT_TOKEN_INACTIVE) /* First unconfigured token, give up */
break;
if (IN_SET(state, CRYPT_TOKEN_INTERNAL, CRYPT_TOKEN_INTERNAL_UNKNOWN, CRYPT_TOKEN_EXTERNAL))
@@ -714,7 +714,7 @@ static int luks_validate_home_record(
if (!streq(type, "systemd-homed"))
continue;
r = crypt_token_json_get(cd, token, &text);
r = sym_crypt_token_json_get(cd, token, &text);
if (r < 0)
return log_error_errno(r, "Failed to read LUKS token %i: %m", token);
@@ -779,7 +779,7 @@ static int luks_validate_home_record(
if (!lhr)
return log_oom();
r = user_record_load(lhr, rr, USER_RECORD_LOAD_EMBEDDED);
r = user_record_load(lhr, rr, USER_RECORD_LOAD_EMBEDDED|USER_RECORD_PERMISSIVE);
if (r < 0)
return log_error_errno(r, "Failed to parse user record: %m");
@@ -902,7 +902,7 @@ int home_store_header_identity_luks(
* the file system, so that we can validate it first, and only then mount the file system. To keep
* things simple we use the same encryption settings for this record as for the file system itself. */
r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED, &header_home);
r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &header_home);
if (r < 0)
return log_error_errno(r, "Failed to determine new header record: %m");
@@ -919,7 +919,7 @@ int home_store_header_identity_luks(
crypt_token_info state;
const char *type;
state = crypt_token_status(setup->crypt_device, token, &type);
state = sym_crypt_token_status(setup->crypt_device, token, &type);
if (state == CRYPT_TOKEN_INACTIVE) /* First unconfigured token, we are done */
break;
if (IN_SET(state, CRYPT_TOKEN_INTERNAL, CRYPT_TOKEN_INTERNAL_UNKNOWN, CRYPT_TOKEN_EXTERNAL))
@@ -930,7 +930,7 @@ int home_store_header_identity_luks(
if (!streq(type, "systemd-homed"))
continue;
r = crypt_token_json_set(setup->crypt_device, token, text);
r = sym_crypt_token_json_set(setup->crypt_device, token, text);
if (r < 0)
return log_error_errno(r, "Failed to set JSON token for slot %i: %m", token);
@@ -1048,7 +1048,7 @@ int home_prepare_luks(
sd_id128_t found_partition_uuid, found_luks_uuid, found_fs_uuid;
_cleanup_(user_record_unrefp) UserRecord *luks_home = NULL;
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *volume_key = NULL;
_cleanup_close_ int root_fd = -1, image_fd = -1;
bool dm_activated = false, mounted = false;
@@ -1064,6 +1064,10 @@ int home_prepare_luks(
assert(user_record_storage(h) == USER_LUKS);
r = dlopen_cryptsetup();
if (r < 0)
return r;
if (already_activated) {
struct loop_info64 info;
const char *n;
@@ -1082,7 +1086,7 @@ int home_prepare_luks(
if (r < 0)
return r;
n = crypt_get_device_name(cd);
n = sym_crypt_get_device_name(cd);
if (!n)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine backing device for DM %s.", setup->dm_name);
@@ -1265,7 +1269,7 @@ fail:
(void) umount_verbose(LOG_ERR, "/run/systemd/user-home-mount", UMOUNT_NOFOLLOW);
if (dm_activated)
(void) crypt_deactivate(cd, setup->dm_name);
(void) sym_crypt_deactivate_by_name(cd, setup->dm_name, 0);
if (image_fd >= 0 && marked_dirty)
(void) run_mark_dirty(image_fd, false);
@@ -1301,6 +1305,10 @@ int home_activate_luks(
assert(user_record_storage(h) == USER_LUKS);
assert(ret_home);
r = dlopen_cryptsetup();
if (r < 0)
return r;
assert_se(hdo = user_record_home_directory(h));
hd = strdupa(hdo); /* copy the string out, since it might change later in the home record object */
@@ -1358,7 +1366,7 @@ int home_activate_luks(
loop_device_relinquish(setup.loop);
r = crypt_deactivate_by_name(NULL, setup.dm_name, CRYPT_DEACTIVATE_DEFERRED);
r = sym_crypt_deactivate_by_name(NULL, setup.dm_name, CRYPT_DEACTIVATE_DEFERRED);
if (r < 0)
log_warning_errno(r, "Failed to relinquish DM device, ignoring: %m");
@@ -1375,7 +1383,7 @@ int home_activate_luks(
}
int home_deactivate_luks(UserRecord *h) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
bool we_detached;
int r;
@@ -1386,11 +1394,15 @@ int home_deactivate_luks(UserRecord *h) {
* don't bother about the loopback device because unlike the DM device it doesn't have a fixed
* name. */
r = dlopen_cryptsetup();
if (r < 0)
return r;
r = make_dm_names(h->user_name, &dm_name, &dm_node);
if (r < 0)
return r;
r = crypt_init_by_name(&cd, dm_name);
r = sym_crypt_init_by_name(&cd, dm_name);
if (IN_SET(r, -ENODEV, -EINVAL, -ENOENT)) {
log_debug_errno(r, "LUKS device %s has already been detached.", dm_name);
we_detached = false;
@@ -1401,7 +1413,7 @@ int home_deactivate_luks(UserRecord *h) {
cryptsetup_enable_logging(cd);
r = crypt_deactivate(cd, dm_name);
r = sym_crypt_deactivate_by_name(cd, dm_name, 0);
if (IN_SET(r, -ENODEV, -EINVAL, -ENOENT)) {
log_debug_errno(r, "LUKS device %s is already detached.", dm_node);
we_detached = false;
@@ -1477,7 +1489,7 @@ static int luks_format(
struct crypt_device **ret) {
_cleanup_(user_record_unrefp) UserRecord *reduced = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *volume_key = NULL;
struct crypt_pbkdf_type good_pbkdf, minimal_pbkdf;
char suuid[ID128_UUID_STRING_MAX], **pp;
@@ -1490,7 +1502,7 @@ static int luks_format(
assert(hr);
assert(ret);
r = crypt_init(&cd, node);
r = sym_crypt_init(&cd, node);
if (r < 0)
return log_error_errno(r, "Failed to allocate libcryptsetup context: %m");
@@ -1511,7 +1523,7 @@ static int luks_format(
#if HAVE_CRYPT_SET_METADATA_SIZE
/* Increase the metadata space to 4M, the largest LUKS2 supports */
r = crypt_set_metadata_size(cd, 4096U*1024U, 0);
r = sym_crypt_set_metadata_size(cd, 4096U*1024U, 0);
if (r < 0)
return log_error_errno(r, "Failed to change LUKS2 metadata size: %m");
#endif
@@ -1519,7 +1531,7 @@ static int luks_format(
build_good_pbkdf(&good_pbkdf, hr);
build_minimal_pbkdf(&minimal_pbkdf, hr);
r = crypt_format(cd,
r = sym_crypt_format(cd,
CRYPT_LUKS2,
user_record_luks_cipher(hr),
user_record_luks_cipher_mode(hr),
@@ -1542,15 +1554,15 @@ static int luks_format(
if (strv_contains(cache->pkcs11_passwords, *pp) ||
strv_contains(cache->fido2_passwords, *pp)) {
log_debug("Using minimal PBKDF for slot %i", slot);
r = crypt_set_pbkdf_type(cd, &minimal_pbkdf);
r = sym_crypt_set_pbkdf_type(cd, &minimal_pbkdf);
} else {
log_debug("Using good PBKDF for slot %i", slot);
r = crypt_set_pbkdf_type(cd, &good_pbkdf);
r = sym_crypt_set_pbkdf_type(cd, &good_pbkdf);
}
if (r < 0)
return log_error_errno(r, "Failed to tweak PBKDF for slot %i: %m", slot);
r = crypt_keyslot_add_by_volume_key(
r = sym_crypt_keyslot_add_by_volume_key(
cd,
slot,
volume_key,
@@ -1564,7 +1576,7 @@ static int luks_format(
slot++;
}
r = crypt_activate_by_volume_key(
r = sym_crypt_activate_by_volume_key(
cd,
dm_name,
volume_key,
@@ -1575,7 +1587,7 @@ static int luks_format(
log_info("LUKS activation by volume key succeeded.");
r = user_record_clone(hr, USER_RECORD_EXTRACT_EMBEDDED, &reduced);
r = user_record_clone(hr, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &reduced);
if (r < 0)
return log_error_errno(r, "Failed to prepare home record for LUKS: %m");
@@ -1583,7 +1595,7 @@ static int luks_format(
if (r < 0)
return r;
r = crypt_token_json_set(cd, CRYPT_ANY_TOKEN, text);
r = sym_crypt_token_json_set(cd, CRYPT_ANY_TOKEN, text);
if (r < 0)
return log_error_errno(r, "Failed to set LUKS JSON token: %m");
@@ -1876,7 +1888,7 @@ int home_create_luks(
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
sd_id128_t partition_uuid, fs_uuid, luks_uuid, disk_uuid;
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_close_ int image_fd = -1, root_fd = -1;
const char *fstype, *ip;
struct statfs sfs;
@@ -1886,6 +1898,10 @@ int home_create_luks(
assert(h->storage < 0 || h->storage == USER_LUKS);
assert(ret_home);
r = dlopen_cryptsetup();
if (r < 0)
return r;
assert_se(ip = user_record_image_path(h));
fstype = user_record_file_system_type(h);
@@ -2139,7 +2155,7 @@ int home_create_luks(
if (r < 0)
goto fail;
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_LOG, &new_home);
r = user_record_clone(h, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE, &new_home);
if (r < 0) {
log_error_errno(r, "Failed to clone record: %m");
goto fail;
@@ -2152,8 +2168,8 @@ int home_create_luks(
partition_uuid,
luks_uuid,
fs_uuid,
crypt_get_cipher(cd),
crypt_get_cipher_mode(cd),
sym_crypt_get_cipher(cd),
sym_crypt_get_cipher_mode(cd),
luks_volume_key_size_convert(cd),
fstype,
NULL,
@@ -2178,13 +2194,13 @@ int home_create_luks(
mounted = false;
r = crypt_deactivate(cd, dm_name);
r = sym_crypt_deactivate_by_name(cd, dm_name, 0);
if (r < 0) {
log_error_errno(r, "Failed to deactivate LUKS device: %m");
goto fail;
}
crypt_free(cd);
sym_crypt_free(cd);
cd = NULL;
dm_activated = false;
@@ -2245,7 +2261,7 @@ fail:
(void) umount_verbose(LOG_WARNING, "/run/systemd/user-home-mount", UMOUNT_NOFOLLOW);
if (dm_activated)
(void) crypt_deactivate(cd, dm_name);
(void) sym_crypt_deactivate_by_name(cd, dm_name, 0);
loop = loop_device_unref(loop);
@@ -2633,6 +2649,10 @@ int home_resize_luks(
assert(setup);
assert(ret_home);
r = dlopen_cryptsetup();
if (r < 0)
return r;
assert_se(ipo = user_record_image_path(h));
ip = strdupa(ipo); /* copy out since original might change later in home record object */
@@ -2733,7 +2753,7 @@ int home_resize_luks(
setup->partition_offset + new_partition_size > new_image_size)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "New partition doesn't fit into backing storage, refusing.");
crypto_offset = crypt_get_data_offset(setup->crypt_device);
crypto_offset = sym_crypt_get_data_offset(setup->crypt_device);
if (setup->partition_size / 512U <= crypto_offset)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Weird, old crypto payload offset doesn't actually fit in partition size?");
if (new_partition_size / 512U <= crypto_offset)
@@ -2797,7 +2817,7 @@ int home_resize_luks(
log_debug_errno(errno, "BLKRRPART failed on block device, ignoring: %m");
/* Tell LUKS about the new bigger size too */
r = crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512U);
r = sym_crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512U);
if (r < 0)
return log_error_errno(r, "Failed to grow LUKS device: %m");
@@ -2838,7 +2858,7 @@ int home_resize_luks(
if (new_fs_size < old_fs_size) {
/* Shrink the LUKS device now, matching the new file system size */
r = crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512);
r = sym_crypt_resize(setup->crypt_device, setup->dm_name, new_fs_size / 512);
if (r < 0)
return log_error_errno(r, "Failed to shrink LUKS device: %m");
@@ -2919,16 +2939,20 @@ int home_passwd_luks(
assert(user_record_storage(h) == USER_LUKS);
assert(setup);
type = crypt_get_type(setup->crypt_device);
r = dlopen_cryptsetup();
if (r < 0)
return r;
type = sym_crypt_get_type(setup->crypt_device);
if (!type)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine crypto device type.");
r = crypt_keyslot_max(type);
r = sym_crypt_keyslot_max(type);
if (r <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine number of key slots.");
max_key_slots = r;
r = crypt_get_volume_key_size(setup->crypt_device);
r = sym_crypt_get_volume_key_size(setup->crypt_device);
if (r <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine volume key size.");
volume_key_size = (size_t) r;
@@ -2954,7 +2978,7 @@ int home_passwd_luks(
build_minimal_pbkdf(&minimal_pbkdf, h);
for (size_t i = 0; i < max_key_slots; i++) {
r = crypt_keyslot_destroy(setup->crypt_device, i);
r = sym_crypt_keyslot_destroy(setup->crypt_device, i);
if (r < 0 && !IN_SET(r, -ENOENT, -EINVAL)) /* Returns EINVAL or ENOENT if there's no key in this slot already */
return log_error_errno(r, "Failed to destroy LUKS password: %m");
@@ -2967,15 +2991,15 @@ int home_passwd_luks(
if (strv_contains(cache->pkcs11_passwords, effective_passwords[i]) ||
strv_contains(cache->fido2_passwords, effective_passwords[i])) {
log_debug("Using minimal PBKDF for slot %zu", i);
r = crypt_set_pbkdf_type(setup->crypt_device, &minimal_pbkdf);
r = sym_crypt_set_pbkdf_type(setup->crypt_device, &minimal_pbkdf);
} else {
log_debug("Using good PBKDF for slot %zu", i);
r = crypt_set_pbkdf_type(setup->crypt_device, &good_pbkdf);
r = sym_crypt_set_pbkdf_type(setup->crypt_device, &good_pbkdf);
}
if (r < 0)
return log_error_errno(r, "Failed to tweak PBKDF for slot %zu: %m", i);
r = crypt_keyslot_add_by_volume_key(
r = sym_crypt_keyslot_add_by_volume_key(
setup->crypt_device,
i,
volume_key,
@@ -2992,7 +3016,7 @@ int home_passwd_luks(
}
int home_lock_luks(UserRecord *h) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
_cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
_cleanup_close_ int root_fd = -1;
const char *p;
@@ -3009,7 +3033,11 @@ int home_lock_luks(UserRecord *h) {
if (r < 0)
return r;
r = crypt_init_by_name(&cd, dm_name);
r = dlopen_cryptsetup();
if (r < 0)
return r;
r = sym_crypt_init_by_name(&cd, dm_name);
if (r < 0)
return log_error_errno(r, "Failed to initialize cryptsetup context for %s: %m", dm_name);
@@ -3025,7 +3053,7 @@ int home_lock_luks(UserRecord *h) {
/* Note that we don't invoke FIFREEZE here, it appears libcryptsetup/device-mapper already does that on its own for us */
r = crypt_suspend(cd, dm_name);
r = sym_crypt_suspend(cd, dm_name);
if (r < 0)
return log_error_errno(r, "Failed to suspend cryptsetup device: %s: %m", dm_node);
@@ -3045,7 +3073,7 @@ static int luks_try_resume(
assert(dm_name);
STRV_FOREACH(pp, password) {
r = crypt_resume_by_passphrase(
r = sym_crypt_resume_by_passphrase(
cd,
dm_name,
CRYPT_ANY_SLOT,
@@ -3064,7 +3092,7 @@ static int luks_try_resume(
int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
_cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
char **list;
int r;
@@ -3074,7 +3102,11 @@ int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
if (r < 0)
return r;
r = crypt_init_by_name(&cd, dm_name);
r = dlopen_cryptsetup();
if (r < 0)
return r;
r = sym_crypt_init_by_name(&cd, dm_name);
if (r < 0)
return log_error_errno(r, "Failed to initialize cryptsetup context for %s: %m", dm_name);
+1 -1
View File
@@ -31,7 +31,7 @@ static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
/* Convert the "int" to uint64_t, which we usually use for byte sizes stored on disk. */
k = crypt_get_volume_key_size(cd);
k = sym_crypt_get_volume_key_size(cd);
if (k <= 0)
return UINT64_MAX;
+36 -20
View File
@@ -48,8 +48,10 @@ int user_record_authenticate(
PasswordCache *cache,
bool strict_verify) {
bool need_password = false, need_recovery_key = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false, need_user_presence_permitted = false,
pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false, token_action_timeout = false;
bool need_password = false, need_recovery_key = false, need_token = false, need_pin = false,
need_protected_authentication_path_permitted = false, need_user_presence_permitted = false,
need_user_verification_permitted = false, pin_locked = false, pin_incorrect = false,
pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false, token_action_timeout = false;
int r;
assert(h);
@@ -125,7 +127,7 @@ int user_record_authenticate(
return log_error_errno(r, "Failed to check supplied FIDO2 password: %m");
if (r > 0) {
log_info("Previously acquired FIDO2 password unlocks user record.");
return 0;
return 1;
}
}
}
@@ -178,7 +180,7 @@ int user_record_authenticate(
if (r < 0)
return log_oom();
return 0;
return 1;
}
#else
need_token = true;
@@ -208,6 +210,9 @@ int user_record_authenticate(
case -EMEDIUMTYPE:
need_user_presence_permitted = true;
break;
case -ENOCSI:
need_user_verification_permitted = true;
break;
case -ENOSTR:
token_action_timeout = true;
break;
@@ -250,6 +255,8 @@ int user_record_authenticate(
return -ERFKILL;
if (need_user_presence_permitted)
return -EMEDIUMTYPE;
if (need_user_verification_permitted)
return -ENOCSI;
if (need_pin)
return -ENOANO;
if (need_token)
@@ -297,7 +304,7 @@ int home_setup_undo(HomeSetup *setup) {
}
if (setup->undo_dm && setup->crypt_device && setup->dm_name) {
q = crypt_deactivate(setup->crypt_device, setup->dm_name);
q = sym_crypt_deactivate_by_name(setup->crypt_device, setup->dm_name, 0);
if (q < 0)
r = q;
}
@@ -328,8 +335,10 @@ int home_setup_undo(HomeSetup *setup) {
setup->dm_node = mfree(setup->dm_node);
setup->loop = loop_device_unref(setup->loop);
crypt_free(setup->crypt_device);
setup->crypt_device = NULL;
if (setup->crypt_device) {
sym_crypt_free(setup->crypt_device);
setup->crypt_device = NULL;
}
explicit_bzero_safe(setup->volume_key, setup->volume_key_size);
setup->volume_key = mfree(setup->volume_key);
@@ -517,7 +526,7 @@ int home_load_embedded_identity(
if (!embedded_home)
return log_oom();
r = user_record_load(embedded_home, v, USER_RECORD_LOAD_EMBEDDED);
r = user_record_load(embedded_home, v, USER_RECORD_LOAD_EMBEDDED|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -602,7 +611,7 @@ int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserReco
assert(root_fd >= 0);
assert(uid_is_valid(uid));
r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED, &embedded);
r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &embedded);
if (r < 0)
return log_error_errno(r, "Failed to determine new embedded record: %m");
@@ -653,8 +662,8 @@ int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *se
setup->found_partition_uuid,
setup->found_luks_uuid,
setup->found_fs_uuid,
setup->crypt_device ? crypt_get_cipher(setup->crypt_device) : NULL,
setup->crypt_device ? crypt_get_cipher_mode(setup->crypt_device) : NULL,
setup->crypt_device ? sym_crypt_get_cipher(setup->crypt_device) : NULL,
setup->crypt_device ? sym_crypt_get_cipher_mode(setup->crypt_device) : NULL,
setup->crypt_device ? luks_volume_key_size_convert(setup->crypt_device) : UINT64_MAX,
file_system_type_fd(setup->root_fd),
user_record_home_directory(used),
@@ -1086,15 +1095,21 @@ static int determine_default_storage(UserStorage *ret) {
return log_error_errno(r, "Failed to determine whether we are in a container: %m");
if (r == 0) {
r = path_is_encrypted("/home");
if (r < 0)
log_warning_errno(r, "Failed to determine if /home is encrypted, ignoring: %m");
if (r <= 0) {
log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
*ret = USER_LUKS;
return 0;
}
if (r > 0)
log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS));
else {
if (r < 0)
log_warning_errno(r, "Failed to determine if /home is encrypted, ignoring: %m");
log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS));
r = dlopen_cryptsetup();
if (r < 0)
log_info("Not using '%s' storage, since libcryptsetup could not be loaded.", user_storage_to_string(USER_LUKS));
else {
log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
*ret = USER_LUKS;
return 0;
}
}
} else
log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));
@@ -1661,7 +1676,7 @@ static int run(int argc, char *argv[]) {
if (!home)
return log_oom();
r = user_record_load(home, v, USER_RECORD_LOAD_FULL|USER_RECORD_LOG);
r = user_record_load(home, v, USER_RECORD_LOAD_FULL|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -1680,6 +1695,7 @@ static int run(int argc, char *argv[]) {
* ENOANO → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
* ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
* EMEDIUMTYPE → suitable FIDO2 device found, but OK to ask for user presence not given
* ENOCSI → suitable FIDO2 device found, but OK to ask for user verification not given
* ENOSTR → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
* EOWNERDEAD → suitable PKCS#11/FIDO2 device found, but its PIN is locked
* ENOLCK → suitable PKCS#11/FIDO2 device found, but PIN incorrect
+12 -2
View File
@@ -216,7 +216,7 @@ static int acquire_user_record(
if (!ur)
return pam_log_oom(handle);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to load user record: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
@@ -377,7 +377,7 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please verify presence on security token of user %s.", user_name);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please confirm presence on security token of user %s.", user_name);
r = user_record_set_fido2_user_presence_permitted(secret, true);
if (r < 0) {
@@ -385,6 +385,16 @@ static int handle_generic_user_record_error(
return PAM_SERVICE_ERR;
}
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED)) {
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please verify user on security token of user %s.", user_name);
r = user_record_set_fido2_user_verification_permitted(secret, true);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to set FIDO2 user verification permitted flag: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
}
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_LOCKED)) {
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)");
+2 -2
View File
@@ -14,7 +14,7 @@ static int user_record_signable_json(UserRecord *ur, char **ret) {
assert(ur);
assert(ret);
r = user_record_clone(ur, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_STRIP_SECRET|USER_RECORD_STRIP_BINDING|USER_RECORD_STRIP_STATUS|USER_RECORD_STRIP_SIGNATURE, &reduced);
r = user_record_clone(ur, USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PRIVILEGED|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_STRIP_SECRET|USER_RECORD_STRIP_BINDING|USER_RECORD_STRIP_STATUS|USER_RECORD_STRIP_SIGNATURE|USER_RECORD_PERMISSIVE, &reduced);
if (r < 0)
return r;
@@ -95,7 +95,7 @@ int user_record_sign(UserRecord *ur, EVP_PKEY *private_key, UserRecord **ret) {
if (!signed_ur)
return log_oom();
r = user_record_load(signed_ur, v, USER_RECORD_LOAD_FULL);
r = user_record_load(signed_ur, v, USER_RECORD_LOAD_FULL|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
+38 -2
View File
@@ -252,7 +252,7 @@ int user_record_reconcile(
if (!merged)
return -ENOMEM;
r = user_record_load(merged, extended, USER_RECORD_LOAD_MASK_SECRET);
r = user_record_load(merged, extended, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -261,7 +261,7 @@ int user_record_reconcile(
}
/* Strip out secrets */
r = user_record_clone(host, USER_RECORD_LOAD_MASK_SECRET, ret);
r = user_record_clone(host, USER_RECORD_LOAD_MASK_SECRET|USER_RECORD_PERMISSIVE, ret);
if (r < 0)
return r;
@@ -1065,6 +1065,34 @@ int user_record_set_fido2_user_presence_permitted(UserRecord *h, int b) {
return 0;
}
int user_record_set_fido2_user_verification_permitted(UserRecord *h, int b) {
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
int r;
assert(h);
w = json_variant_ref(json_variant_by_key(h->json, "secret"));
if (b < 0)
r = json_variant_filter(&w, STRV_MAKE("fido2UserVerificationPermitted"));
else
r = json_variant_set_field_boolean(&w, "fido2UserVerificationPermitted", b);
if (r < 0)
return r;
if (json_variant_is_blank_object(w))
r = json_variant_filter(&h->json, STRV_MAKE("secret"));
else
r = json_variant_set_field(&h->json, "secret", w);
if (r < 0)
return r;
h->fido2_user_verification_permitted = b;
SET_FLAG(h->mask, USER_RECORD_SECRET, !json_variant_is_blank_object(w));
return 0;
}
static bool per_machine_entry_empty(JsonVariant *v) {
const char *k;
_unused_ JsonVariant *e;
@@ -1167,6 +1195,14 @@ int user_record_merge_secret(UserRecord *h, UserRecord *secret) {
return r;
}
if (secret->fido2_user_verification_permitted >= 0) {
r = user_record_set_fido2_user_verification_permitted(
h,
secret->fido2_user_verification_permitted);
if (r < 0)
return r;
}
return 0;
}
+1
View File
@@ -52,6 +52,7 @@ int user_record_set_hashed_password(UserRecord *h, char **hashed_password);
int user_record_set_token_pin(UserRecord *h, char **pin, bool prepend);
int user_record_set_pkcs11_protected_authentication_path_permitted(UserRecord *h, int b);
int user_record_set_fido2_user_presence_permitted(UserRecord *h, int b);
int user_record_set_fido2_user_verification_permitted(UserRecord *h, int b);
int user_record_set_password_change_now(UserRecord *h, int b);
int user_record_merge_secret(UserRecord *h, UserRecord *secret);
int user_record_good_authentication(UserRecord *h);
@@ -125,6 +125,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PIN_NEEDED, ENOANO),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, ERFKILL),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, EMEDIUMTYPE),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED, ENOCSI),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_ACTION_TIMEOUT, ENOSTR),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PIN_LOCKED, EOWNERDEAD),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_BAD_PIN, ENOLCK),
@@ -107,6 +107,8 @@
#define BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED \
"org.freedesktop.home1.TokenProtectedAuthenticationPathNeeded"
#define BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED "org.freedesktop.home1.TokenUserPresenceNeeded"
#define BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED \
"org.freedesktop.home1.TokenUserVerificationNeeded"
#define BUS_ERROR_TOKEN_ACTION_TIMEOUT "org.freedesktop.home1.TokenActionTimeout"
#define BUS_ERROR_TOKEN_PIN_LOCKED "org.freedesktop.home1.TokenPinLocked"
#define BUS_ERROR_TOKEN_BAD_PIN "org.freedesktop.home1.BadPin"
+1 -1
View File
@@ -141,7 +141,7 @@ static int acquire_user_record(
if (!ur)
return pam_log_oom(handle);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to load user record: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
+4 -2
View File
@@ -377,14 +377,16 @@ int bind_user_setup(
USER_RECORD_STRIP_PRIVILEGED|
USER_RECORD_ALLOW_PER_MACHINE|
USER_RECORD_ALLOW_BINDING|
USER_RECORD_ALLOW_SIGNATURE;
USER_RECORD_ALLOW_SIGNATURE|
USER_RECORD_PERMISSIVE;
static const UserRecordLoadFlags shadow_flags = /* Extracts privileged info */
USER_RECORD_STRIP_REGULAR|
USER_RECORD_ALLOW_PRIVILEGED|
USER_RECORD_STRIP_PER_MACHINE|
USER_RECORD_STRIP_BINDING|
USER_RECORD_STRIP_SIGNATURE|
USER_RECORD_EMPTY_OK;
USER_RECORD_EMPTY_OK|
USER_RECORD_PERMISSIVE;
int r;
assert(root);
+52 -11
View File
@@ -17,23 +17,38 @@ int (*sym_crypt_activate_by_volume_key)(struct crypt_device *cd, const char *nam
int (*sym_crypt_deactivate_by_name)(struct crypt_device *cd, const char *name, uint32_t flags);
int (*sym_crypt_format)(struct crypt_device *cd, const char *type, const char *cipher, const char *cipher_mode, const char *uuid, const char *volume_key, size_t volume_key_size, void *params);
void (*sym_crypt_free)(struct crypt_device *cd);
const char *(*sym_crypt_get_cipher)(struct crypt_device *cd);
const char *(*sym_crypt_get_cipher_mode)(struct crypt_device *cd);
uint64_t (*sym_crypt_get_data_offset)(struct crypt_device *cd);
const char *(*sym_crypt_get_device_name)(struct crypt_device *cd);
const char *(*sym_crypt_get_dir)(void);
const char *(*sym_crypt_get_type)(struct crypt_device *cd);
const char *(*sym_crypt_get_uuid)(struct crypt_device *cd);
int (*sym_crypt_get_verity_info)(struct crypt_device *cd, struct crypt_params_verity *vp);
int (*sym_crypt_get_volume_key_size)(struct crypt_device *cd);
int (*sym_crypt_init)(struct crypt_device **cd, const char *device);
int (*sym_crypt_init_by_name)(struct crypt_device **cd, const char *name);
int (*sym_crypt_keyslot_add_by_volume_key)(struct crypt_device *cd, int keyslot, const char *volume_key, size_t volume_key_size, const char *passphrase, size_t passphrase_size);
int (*sym_crypt_keyslot_destroy)(struct crypt_device *cd, int keyslot);
int (*sym_crypt_keyslot_max)(const char *type);
int (*sym_crypt_load)(struct crypt_device *cd, const char *requested_type, void *params);
int (*sym_crypt_resize)(struct crypt_device *cd, const char *name, uint64_t new_size);
int (*sym_crypt_resume_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size);
int (*sym_crypt_set_data_device)(struct crypt_device *cd, const char *device);
void (*sym_crypt_set_debug_level)(int level);
void (*sym_crypt_set_log_callback)(struct crypt_device *cd, void (*log)(int level, const char *msg, void *usrptr), void *usrptr);
int (*sym_crypt_set_pbkdf_type)(struct crypt_device *cd, const struct crypt_pbkdf_type *pbkdf) = NULL;
int (*sym_crypt_token_json_get)(struct crypt_device *cd, int token, const char **json) = NULL;
int (*sym_crypt_token_json_set)(struct crypt_device *cd, int token, const char *json) = NULL;
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);
#if HAVE_CRYPT_SET_METADATA_SIZE
int (*sym_crypt_set_metadata_size)(struct crypt_device *cd, uint64_t metadata_size, uint64_t keyslots_size);
#endif
int (*sym_crypt_set_pbkdf_type)(struct crypt_device *cd, const struct crypt_pbkdf_type *pbkdf);
int (*sym_crypt_suspend)(struct crypt_device *cd, const char *name);
int (*sym_crypt_token_json_get)(struct crypt_device *cd, int token, const char **json);
int (*sym_crypt_token_json_set)(struct crypt_device *cd, int token, const char *json);
#if HAVE_CRYPT_TOKEN_MAX
int (*sym_crypt_token_max)(const char *type);
#endif
crypt_token_info (*sym_crypt_token_status)(struct crypt_device *cd, int token, const char **type);
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);
int dlopen_cryptsetup(void) {
_cleanup_(dlclosep) void *dl = NULL;
@@ -58,23 +73,38 @@ int dlopen_cryptsetup(void) {
DLSYM_ARG(crypt_deactivate_by_name),
DLSYM_ARG(crypt_format),
DLSYM_ARG(crypt_free),
DLSYM_ARG(crypt_get_cipher),
DLSYM_ARG(crypt_get_cipher_mode),
DLSYM_ARG(crypt_get_data_offset),
DLSYM_ARG(crypt_get_device_name),
DLSYM_ARG(crypt_get_dir),
DLSYM_ARG(crypt_get_type),
DLSYM_ARG(crypt_get_uuid),
DLSYM_ARG(crypt_get_verity_info),
DLSYM_ARG(crypt_get_volume_key_size),
DLSYM_ARG(crypt_init),
DLSYM_ARG(crypt_init_by_name),
DLSYM_ARG(crypt_keyslot_add_by_volume_key),
DLSYM_ARG(crypt_keyslot_destroy),
DLSYM_ARG(crypt_keyslot_max),
DLSYM_ARG(crypt_load),
DLSYM_ARG(crypt_resize),
DLSYM_ARG(crypt_resume_by_passphrase),
DLSYM_ARG(crypt_set_data_device),
DLSYM_ARG(crypt_set_debug_level),
DLSYM_ARG(crypt_set_log_callback),
#if HAVE_CRYPT_SET_METADATA_SIZE
DLSYM_ARG(crypt_set_metadata_size),
#endif
DLSYM_ARG(crypt_set_pbkdf_type),
DLSYM_ARG(crypt_suspend),
DLSYM_ARG(crypt_token_json_get),
DLSYM_ARG(crypt_token_json_set),
DLSYM_ARG(crypt_volume_key_get),
#if HAVE_CRYPT_TOKEN_MAX
DLSYM_ARG(crypt_token_max),
#endif
DLSYM_ARG(crypt_token_status),
DLSYM_ARG(crypt_volume_key_get),
NULL);
if (r < 0)
return r;
@@ -82,6 +112,13 @@ int dlopen_cryptsetup(void) {
/* Note that we never release the reference here, because there's no real reason to, after all this
* was traditionally a regular shared library dependency which lives forever too. */
cryptsetup_dl = TAKE_PTR(dl);
/* Redirect the default logging calls of libcryptsetup to our own logging infra. (Note that
* libcryptsetup also maintains per-"struct crypt_device" log functions, which we'll also set
* whenever allocating a "struct crypt_device" context. Why set both? To be defensive: maybe some
* other code loaded into this process also changes the global log functions of libcryptsetup, who
* knows? And if so, we still want our own objects to log via our own infra, at the very least.) */
cryptsetup_enable_logging(NULL);
return 1;
}
@@ -109,13 +146,17 @@ static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
}
void cryptsetup_enable_logging(struct crypt_device *cd) {
if (!cd)
return;
/* It's OK to call this with a NULL parameter, in which case libcryptsetup will set the defaut log
* function.
*
* Note that this is also called from dlopen_cryptsetup(), which we call here too. Sounds like an
* endless loop, but isn't because we break it via the check for 'cryptsetup_dl' early in
* dlopen_cryptsetup(). */
if (dlopen_cryptsetup() < 0) /* If this fails, let's gracefully ignore the issue, this is just debug
* logging after all, and if this failed we already generated a debug
* log message that should help to track things down. */
return;
if (dlopen_cryptsetup() < 0)
return; /* If this fails, let's gracefully ignore the issue, this is just debug logging after
* all, and if this failed we already generated a debug log message that should help
* to track things down. */
sym_crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
sym_crypt_set_debug_level(DEBUG_LOGGING ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
+16 -1
View File
@@ -23,20 +23,33 @@ extern int (*sym_crypt_activate_by_volume_key)(struct crypt_device *cd, const ch
extern int (*sym_crypt_deactivate_by_name)(struct crypt_device *cd, const char *name, uint32_t flags);
extern int (*sym_crypt_format)(struct crypt_device *cd, const char *type, const char *cipher, const char *cipher_mode, const char *uuid, const char *volume_key, size_t volume_key_size, void *params);
extern void (*sym_crypt_free)(struct crypt_device *cd);
extern const char *(*sym_crypt_get_cipher)(struct crypt_device *cd);
extern const char *(*sym_crypt_get_cipher_mode)(struct crypt_device *cd);
extern uint64_t (*sym_crypt_get_data_offset)(struct crypt_device *cd);
extern const char *(*sym_crypt_get_device_name)(struct crypt_device *cd);
extern const char *(*sym_crypt_get_dir)(void);
extern const char *(*sym_crypt_get_type)(struct crypt_device *cd);
extern const char *(*sym_crypt_get_uuid)(struct crypt_device *cd);
extern int (*sym_crypt_get_verity_info)(struct crypt_device *cd, struct crypt_params_verity *vp);
extern int (*sym_crypt_get_volume_key_size)(struct crypt_device *cd);
extern int (*sym_crypt_init)(struct crypt_device **cd, const char *device);
extern int (*sym_crypt_init_by_name)(struct crypt_device **cd, const char *name);
extern int (*sym_crypt_keyslot_add_by_volume_key)(struct crypt_device *cd, int keyslot, const char *volume_key, size_t volume_key_size, const char *passphrase, size_t passphrase_size);
extern int (*sym_crypt_keyslot_destroy)(struct crypt_device *cd, int keyslot);
extern int (*sym_crypt_keyslot_max)(const char *type);
extern int (*sym_crypt_load)(struct crypt_device *cd, const char *requested_type, void *params);
extern int (*sym_crypt_resize)(struct crypt_device *cd, const char *name, uint64_t new_size);
extern int (*sym_crypt_resume_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size);
extern int (*sym_crypt_set_data_device)(struct crypt_device *cd, const char *device);
extern void (*sym_crypt_set_debug_level)(int level);
extern void (*sym_crypt_set_log_callback)(struct crypt_device *cd, void (*log)(int level, const char *msg, void *usrptr), void *usrptr);
#if HAVE_CRYPT_SET_METADATA_SIZE
extern int (*sym_crypt_set_metadata_size)(struct crypt_device *cd, uint64_t metadata_size, uint64_t keyslots_size);
#endif
extern int (*sym_crypt_set_pbkdf_type)(struct crypt_device *cd, const struct crypt_pbkdf_type *pbkdf);
extern int (*sym_crypt_suspend)(struct crypt_device *cd, const char *name);
extern int (*sym_crypt_token_json_get)(struct crypt_device *cd, int token, const char **json);
extern int (*sym_crypt_token_json_set)(struct crypt_device *cd, int token, const char *json);
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);
#if HAVE_CRYPT_TOKEN_MAX
extern int (*sym_crypt_token_max)(const char *type);
#else
@@ -47,6 +60,8 @@ static inline int sym_crypt_token_max(_unused_ const char *type) {
return 32;
}
#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);
int dlopen_cryptsetup(void);
+2
View File
@@ -1926,6 +1926,8 @@ static int verity_can_reuse(
if (r < 0)
return log_debug_errno(r, "Error opening verity device, crypt_init_by_name failed: %m");
cryptsetup_enable_logging(cd);
r = sym_crypt_get_verity_info(cd, &crypt_params);
if (r < 0)
return log_debug_errno(r, "Error opening verity device, crypt_get_verity_info failed: %m");
+15 -6
View File
@@ -200,6 +200,7 @@ UserRecord* user_record_new(void) {
.password_change_now = -1,
.pkcs11_protected_authentication_path_permitted = -1,
.fido2_user_presence_permitted = -1,
.fido2_user_verification_permitted = -1,
};
return h;
@@ -774,6 +775,7 @@ static int dispatch_secret(const char *name, JsonVariant *variant, JsonDispatchF
{ "pkcs11Pin", /* legacy alias */ _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, token_pin), 0 },
{ "pkcs11ProtectedAuthenticationPathPermitted", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, pkcs11_protected_authentication_path_permitted), 0 },
{ "fido2UserPresencePermitted", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, fido2_user_presence_permitted), 0 },
{ "fido2UserVerificationPermitted", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, fido2_user_verification_permitted), 0 },
{},
};
@@ -1016,9 +1018,12 @@ static int dispatch_fido2_hmac_salt(const char *name, JsonVariant *variant, Json
Fido2HmacSalt *array, *k;
static const JsonDispatch fido2_hmac_salt_dispatch_table[] = {
{ "credential", JSON_VARIANT_STRING, dispatch_fido2_hmac_credential, offsetof(Fido2HmacSalt, credential), JSON_MANDATORY },
{ "salt", JSON_VARIANT_STRING, dispatch_fido2_hmac_salt_value, 0, JSON_MANDATORY },
{ "hashedPassword", JSON_VARIANT_STRING, json_dispatch_string, offsetof(Fido2HmacSalt, hashed_password), JSON_MANDATORY },
{ "credential", JSON_VARIANT_STRING, dispatch_fido2_hmac_credential, offsetof(Fido2HmacSalt, credential), JSON_MANDATORY },
{ "salt", JSON_VARIANT_STRING, dispatch_fido2_hmac_salt_value, 0, JSON_MANDATORY },
{ "hashedPassword", JSON_VARIANT_STRING, json_dispatch_string, offsetof(Fido2HmacSalt, hashed_password), JSON_MANDATORY },
{ "up", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(Fido2HmacSalt, up), 0 },
{ "uv", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(Fido2HmacSalt, uv), 0 },
{ "clientPin", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(Fido2HmacSalt, client_pin), 0 },
{},
};
@@ -1031,7 +1036,11 @@ static int dispatch_fido2_hmac_salt(const char *name, JsonVariant *variant, Json
h->fido2_hmac_salt = array;
k = h->fido2_hmac_salt + h->n_fido2_hmac_salt;
*k = (Fido2HmacSalt) {};
*k = (Fido2HmacSalt) {
.uv = -1,
.up = -1,
.client_pin = -1,
};
r = json_dispatch(e, fido2_hmac_salt_dispatch_table, NULL, flags, k);
if (r < 0) {
@@ -2105,7 +2114,7 @@ int user_record_masked_equal(UserRecord *a, UserRecord *b, UserRecordMask mask)
/* Compares the two records, but ignores anything not listed in the specified mask */
if ((a->mask & ~mask) != 0) {
r = user_record_clone(a, USER_RECORD_ALLOW(mask) | USER_RECORD_STRIP(~mask & _USER_RECORD_MASK_MAX), &x);
r = user_record_clone(a, USER_RECORD_ALLOW(mask) | USER_RECORD_STRIP(~mask & _USER_RECORD_MASK_MAX) | USER_RECORD_PERMISSIVE, &x);
if (r < 0)
return r;
@@ -2113,7 +2122,7 @@ int user_record_masked_equal(UserRecord *a, UserRecord *b, UserRecordMask mask)
}
if ((b->mask & ~mask) != 0) {
r = user_record_clone(b, USER_RECORD_ALLOW(mask) | USER_RECORD_STRIP(~mask & _USER_RECORD_MASK_MAX), &y);
r = user_record_clone(b, USER_RECORD_ALLOW(mask) | USER_RECORD_STRIP(~mask & _USER_RECORD_MASK_MAX) | USER_RECORD_PERMISSIVE, &y);
if (r < 0)
return r;
+4
View File
@@ -236,6 +236,9 @@ typedef struct Fido2HmacSalt {
/* What to test the hashed salt value against, usually UNIX password hash here. */
char *hashed_password;
/* Whether the 'up', 'uv', 'clientPin' features are enabled. */
int uv, up, client_pin;
} Fido2HmacSalt;
typedef struct RecoveryKey {
@@ -371,6 +374,7 @@ typedef struct UserRecord {
Fido2HmacSalt *fido2_hmac_salt;
size_t n_fido2_hmac_salt;
int fido2_user_presence_permitted;
int fido2_user_verification_permitted;
char **recovery_key_type;
RecoveryKey *recovery_key;
+4 -2
View File
@@ -82,7 +82,8 @@ static int load_user(
USER_RECORD_ALLOW_PER_MACHINE|
USER_RECORD_ALLOW_BINDING|
USER_RECORD_ALLOW_SIGNATURE|
(have_privileged ? USER_RECORD_ALLOW_PRIVILEGED : 0));
(have_privileged ? USER_RECORD_ALLOW_PRIVILEGED : 0)|
USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
@@ -225,7 +226,8 @@ static int load_group(
USER_RECORD_ALLOW_PER_MACHINE|
USER_RECORD_ALLOW_BINDING|
USER_RECORD_ALLOW_SIGNATURE|
(have_privileged ? USER_RECORD_ALLOW_PRIVILEGED : 0));
(have_privileged ? USER_RECORD_ALLOW_PRIVILEGED : 0)|
USER_RECORD_PERMISSIVE);
if (r < 0)
return r;
+2 -2
View File
@@ -88,7 +88,7 @@ static int build_user_json(Varlink *link, UserRecord *ur, JsonVariant **ret) {
} else
trusted = peer_uid == 0 || peer_uid == ur->uid;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE;
if (trusted)
flags |= USER_RECORD_ALLOW_PRIVILEGED;
else
@@ -232,7 +232,7 @@ static int build_group_json(Varlink *link, GroupRecord *gr, JsonVariant **ret) {
} else
trusted = peer_uid == 0;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE;
flags = USER_RECORD_REQUIRE_REGULAR|USER_RECORD_ALLOW_PER_MACHINE|USER_RECORD_ALLOW_BINDING|USER_RECORD_STRIP_SECRET|USER_RECORD_ALLOW_STATUS|USER_RECORD_ALLOW_SIGNATURE|USER_RECORD_PERMISSIVE;
if (trusted)
flags |= USER_RECORD_ALLOW_PRIVILEGED;
else
+2
View File
@@ -138,6 +138,8 @@ static int run(int argc, char *argv[]) {
log_setup();
cryptsetup_enable_logging(NULL);
umask(0022);
if (streq(argv[1], "attach")) {