diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index db12d7c0..b7dd4f49 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -286,8 +286,9 @@ inaccessible. .PP \fIluksKillSlot\fR .IP -Wipe the key-slot number from the LUKS device. A remaining -passphrase must be supplied, either interactively or via \-\-key-file. +Wipe the key-slot number from the LUKS device. Except running +in batch-mode (\-q) a remaining passphrase must be supplied, +either interactively or via \-\-key-file. This command can remove the last remaining key-slot, but requires an interactive confirmation when doing so. Removing the last passphrase makes a LUKS container permanently inaccessible. @@ -297,11 +298,16 @@ passphrase makes a LUKS container permanently inaccessible. \fBWARNING:\fR If you read the passphrase from stdin (without further argument or with '-' as argument -to \-\-key-file), batch-mode (\-q) will be implicitely +to \-\-key-file), batch-mode (\-q) will be implicitly switched on and no warning will be given when you remove the last remaining passphrase from a LUKS container. Removing the last passphrase makes the LUKS container permanently inaccessible. + +\fBNOTE:\fR If there is no passphrase provided (on stdin or through +\-\-key-file argument) and batch-mode (\-q) is active, the +key-slot is removed without any other warning. + .PP \fIerase\fR .br diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 76763ff1..15587bfe 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -824,7 +824,8 @@ static int verify_keyslot(struct crypt_device *cd, int key_slot, int i, r; ki = crypt_keyslot_status(cd, key_slot); - if (ki == CRYPT_SLOT_ACTIVE_LAST && msg_last && !yesDialog(msg_last, NULL)) + if (ki == CRYPT_SLOT_ACTIVE_LAST && !opt_batch_mode && !key_file && + msg_last && !yesDialog(msg_last, NULL)) return -EPERM; r = tools_get_key(msg_pass, &password, &passwordLen, @@ -851,6 +852,10 @@ static int verify_keyslot(struct crypt_device *cd, int key_slot, } } + /* Handle inactive keyslots the same as bad password here */ + if (r == -ENOENT) + r = -EPERM; + if (r == -EPERM) log_err(_("No key available with this passphrase.\n")); out: @@ -883,7 +888,7 @@ static int action_luksKillSlot(void) goto out; } - if (!opt_batch_mode) { + if (!opt_batch_mode || opt_key_file || !isatty(STDIN_FILENO)) { r = verify_keyslot(cd, opt_key_slot, _("This is the last keyslot. Device will become unusable after purging this key."), _("Enter any remaining passphrase: "), diff --git a/tests/compat-test b/tests/compat-test index 10c2fbf3..4d51142b 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -355,6 +355,12 @@ $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY1 2>/dev/null && fail $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY2 --keyfile-size 1 2>/dev/null && fail $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY2 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 4: DISABLED" || fail +# if password or keyfile is provided, batch mode must not suppress it +echo "badpw" | $CRYPTSETUP luksKillSlot $LOOPDEV 2 2>/dev/null && fail +echo "badpw" | $CRYPTSETUP luksKillSlot $LOOPDEV 2 -q 2>/dev/null && fail +echo "badpw" | $CRYPTSETUP luksKillSlot $LOOPDEV 2 --key-file=- 2>/dev/null && fail +echo "badpw" | $CRYPTSETUP luksKillSlot $LOOPDEV 2 --key-file=- -q 2>/dev/null && fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 2: ENABLED" || fail # kill slot using passphrase from 1 echo $PWD2 | $CRYPTSETUP luksKillSlot $LOOPDEV 2 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 2: DISABLED" || fail