mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-13 11:50:10 +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;
|
json_object *jobj_keyslots, *jobj;
|
||||||
crypt_keyslot_priority slot_priority;
|
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_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
|
||||||
|
|
||||||
json_object_object_foreach(jobj_keyslots, slot, val) {
|
json_object_object_foreach(jobj_keyslots, slot, val) {
|
||||||
|
r_old = r;
|
||||||
|
|
||||||
if (!json_object_object_get_ex(val, "priority", &jobj))
|
if (!json_object_object_get_ex(val, "priority", &jobj))
|
||||||
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
||||||
else
|
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 */
|
former meaning password wrong, latter key slot unusable for segment */
|
||||||
if ((r != -EPERM) && (r != -ENOENT))
|
if ((r != -EPERM) && (r != -ENOENT))
|
||||||
break;
|
break;
|
||||||
|
/* If a previous keyslot failed with EPERM (bad password) prefer it */
|
||||||
|
if (r_old == -EPERM && r == -ENOENT)
|
||||||
|
r = -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@@ -453,11 +458,13 @@ static int LUKS2_keyslot_open_priority(struct crypt_device *cd,
|
|||||||
{
|
{
|
||||||
json_object *jobj_keyslots, *jobj;
|
json_object *jobj_keyslots, *jobj;
|
||||||
crypt_keyslot_priority slot_priority;
|
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_get_ex(hdr->jobj, "keyslots", &jobj_keyslots);
|
||||||
|
|
||||||
json_object_object_foreach(jobj_keyslots, slot, val) {
|
json_object_object_foreach(jobj_keyslots, slot, val) {
|
||||||
|
r_old = r;
|
||||||
|
|
||||||
if (!json_object_object_get_ex(val, "priority", &jobj))
|
if (!json_object_object_get_ex(val, "priority", &jobj))
|
||||||
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
slot_priority = CRYPT_SLOT_PRIORITY_NORMAL;
|
||||||
else
|
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 */
|
former meaning password wrong, latter key slot unusable for segment */
|
||||||
if ((r != -EPERM) && (r != -ENOENT))
|
if ((r != -EPERM) && (r != -ENOENT))
|
||||||
break;
|
break;
|
||||||
|
/* If a previous keyslot failed with EPERM (bad password) prefer it */
|
||||||
|
if (r_old == -EPERM && r == -ENOENT)
|
||||||
|
r = -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -501,6 +501,37 @@ EOF
|
|||||||
[ $? -eq 0 ] || return 1
|
[ $? -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
|
export LANG=C
|
||||||
|
|
||||||
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
|
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
|
||||||
@@ -1618,5 +1649,11 @@ if [ $? -eq 0 ] ; then
|
|||||||
$CRYPTSETUP close $DEV_NAME || fail
|
$CRYPTSETUP close $DEV_NAME || fail
|
||||||
fi
|
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
|
remove_mapping
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user