mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-11 19:00:02 +01:00
Fix interactive query retry if LUKS2 unbound keyslot is present
If an unbound keyslot is present (e.g.. slot 0 usual slot, slot 1 unbound), the query loop could return ENOENT (keyslot not valid for segment) and this will stop epxected retry for slot quewry (--tries option). If any previous slot rerutned EPERM (no valid passphrase), prefer this return code.
This commit is contained in:
@@ -415,11 +415,13 @@ static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
{
|
||||
json_object *jobj_keyslots, *jobj;
|
||||
crypt_keyslot_priority slot_priority;
|
||||
int keyslot, r = -ENOENT;
|
||||
int keyslot, r = -ENOENT, r_old;
|
||||
|
||||
json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
|
||||
|
||||
json_object_object_foreach(jobj_keyslots, slot, val) {
|
||||
r_old = r;
|
||||
|
||||
if (!json_object_object_get_ex(val, "priority", &jobj))
|
||||
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
||||
else
|
||||
@@ -438,6 +440,9 @@ static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
former meaning password wrong, latter key slot unusable for segment */
|
||||
if ((r != -EPERM) && (r != -ENOENT))
|
||||
break;
|
||||
/* If a previous keyslot failed with EPERM (bad password) prefer it */
|
||||
if (r_old == -EPERM && r == -ENOENT)
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -453,11 +458,13 @@ static int LUKS2_keyslot_open_priority(struct crypt_device *cd,
|
||||
{
|
||||
json_object *jobj_keyslots, *jobj;
|
||||
crypt_keyslot_priority slot_priority;
|
||||
int keyslot, r = -ENOENT;
|
||||
int keyslot, r = -ENOENT, r_old;
|
||||
|
||||
json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
|
||||
|
||||
json_object_object_foreach(jobj_keyslots, slot, val) {
|
||||
r_old = r;
|
||||
|
||||
if (!json_object_object_get_ex(val, "priority", &jobj))
|
||||
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
||||
else
|
||||
@@ -476,6 +483,9 @@ static int LUKS2_keyslot_open_priority(struct crypt_device *cd,
|
||||
former meaning password wrong, latter key slot unusable for segment */
|
||||
if ((r != -EPERM) && (r != -ENOENT))
|
||||
break;
|
||||
/* If a previous keyslot failed with EPERM (bad password) prefer it */
|
||||
if (r_old == -EPERM && r == -ENOENT)
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
@@ -501,6 +501,37 @@ EOF
|
||||
[ $? -eq 0 ] || return 1
|
||||
}
|
||||
|
||||
# expected unlocked keyslot id
|
||||
# password
|
||||
# command arguments
|
||||
function expect_retried_unlocked_keyslot()
|
||||
{
|
||||
command -v expect >/dev/null || {
|
||||
echo "WARNING: expect tool missing, interactive test will be skipped."
|
||||
return 0
|
||||
}
|
||||
|
||||
EXPECT_TIMEOUT=60
|
||||
|
||||
expect_run - >/dev/null <<EOF
|
||||
proc abort {} { send_error "Timeout. "; exit 2 }
|
||||
set timeout $EXPECT_TIMEOUT
|
||||
eval spawn $CRYPTSETUP_RAW $3
|
||||
expect timeout abort "Enter passphrase for*:"
|
||||
sleep 0.1
|
||||
send "$2 x\n"
|
||||
expect timeout abort "No key available with this passphrase."
|
||||
expect timeout abort "Enter passphrase for*:"
|
||||
sleep 0.1
|
||||
send "$2\n"
|
||||
expect timeout abort "Key slot $1 unlocked."
|
||||
expect timeout abort "Command successful."
|
||||
expect timeout abort eof
|
||||
exit
|
||||
EOF
|
||||
[ $? -eq 0 ] || return 1
|
||||
}
|
||||
|
||||
export LANG=C
|
||||
|
||||
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
|
||||
@@ -1618,5 +1649,11 @@ if [ $? -eq 0 ] ; then
|
||||
$CRYPTSETUP close $DEV_NAME || fail
|
||||
fi
|
||||
|
||||
prepare "[48] Interactive retry keyslot test" wipe
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
|
||||
echo $PWD2 | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_OPT --unbound --key-size 256 $LOOPDEV || fail
|
||||
expect_retried_unlocked_keyslot 0 $PWD1 "open -v --test-passphrase --tries 2 $LOOPDEV" || fail
|
||||
expect_retried_unlocked_keyslot 1 $PWD2 "open -v --test-passphrase --tries 2 -S1 $LOOPDEV" || fail
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user