Add --force-offline-reencrypt option.

It can be used to enforce offline reencryption
in batch mode when data_device is regular file
and therefore cryptsetup cannot detect properly
active device dm name.

Also it may be useful when active device
auto-detection fails for some reason and user
has no other choice but inspect device holders
manually.
This commit is contained in:
Ondrej Kozina
2022-04-06 19:09:10 +02:00
parent 496a0e37c4
commit 31c4afbc17
7 changed files with 23 additions and 35 deletions

View File

@@ -1342,6 +1342,16 @@ with the \-\-header option. Use with care.
.B "\-\-header\-backup\-file <file>" .B "\-\-header\-backup\-file <file>"
Specify file with header backup for \fIluksHeaderBackup\fR or Specify file with header backup for \fIluksHeaderBackup\fR or
\fIluksHeaderRestore\fR actions. \fIluksHeaderRestore\fR actions.
.TP
.B "\-\-force\-offline\-reencrypt"
Bypass active device auto-detection and enforce offline LUKS2 reencryption.
This option is useful in case active device auto-detection on particular data
device does not work or report errors.
\fBWARNING:\fR Use with extreme caution! This may destroy data
if the device is activated and/or actively used.
.TP .TP
.B "\-\-force\-password" .B "\-\-force\-password"
Do not use password quality checking for new LUKS passwords. Do not use password quality checking for new LUKS passwords.

View File

@@ -2787,6 +2787,9 @@ static const char *verify_reencrypt(void)
if (isLUKS1(luksType(device_type)) && ARG_SET(OPT_ACTIVE_NAME_ID)) if (isLUKS1(luksType(device_type)) && ARG_SET(OPT_ACTIVE_NAME_ID))
return _("Option --active-name can be set only for LUKS2 device."); return _("Option --active-name can be set only for LUKS2 device.");
if (ARG_SET(OPT_ACTIVE_NAME_ID) && ARG_SET(OPT_FORCE_OFFLINE_REENCRYPT_ID))
return _("Options --active-name and --force-offline-reencrypt cannot be combined.");
return NULL; return NULL;
} }

View File

@@ -59,6 +59,8 @@ ARG(OPT_ENCRYPT, '\0', POPT_ARG_NONE, N_("Encrypt LUKS2 device (in-place encrypt
ARG(OPT_FORCE_PASSWORD, '\0', POPT_ARG_NONE, N_("Disable password quality check (if enabled)"), NULL, CRYPT_ARG_BOOL, {}, {}) ARG(OPT_FORCE_PASSWORD, '\0', POPT_ARG_NONE, N_("Disable password quality check (if enabled)"), NULL, CRYPT_ARG_BOOL, {}, {})
ARG(OPT_FORCE_OFFLINE_REENCRYPT, '\0', POPT_ARG_NONE, N_("Force offline LUKS2 reencryption and bypass active device detection."), NULL, CRYPT_ARG_BOOL, {}, OPT_FORCE_OFFLINE_REENCRYPT_ACTIONS)
ARG(OPT_HASH, 'h', POPT_ARG_STRING, N_("The hash used to create the encryption key from the passphrase"), NULL, CRYPT_ARG_STRING, {}, {}) ARG(OPT_HASH, 'h', POPT_ARG_STRING, N_("The hash used to create the encryption key from the passphrase"), NULL, CRYPT_ARG_STRING, {}, {})
ARG(OPT_HEADER, '\0', POPT_ARG_STRING, N_("Device or file with separated LUKS header"), NULL, CRYPT_ARG_STRING, {}, {}) ARG(OPT_HEADER, '\0', POPT_ARG_STRING, N_("Device or file with separated LUKS header"), NULL, CRYPT_ARG_STRING, {}, {})

View File

@@ -59,6 +59,7 @@
#define OPT_DEVICE_SIZE_ACTIONS { OPEN_ACTION, RESIZE_ACTION, REENCRYPT_ACTION } #define OPT_DEVICE_SIZE_ACTIONS { OPEN_ACTION, RESIZE_ACTION, REENCRYPT_ACTION }
#define OPT_DISABLE_VERACRYPT_ACTIONS { OPEN_ACTION, TCRYPTDUMP_ACTION } #define OPT_DISABLE_VERACRYPT_ACTIONS { OPEN_ACTION, TCRYPTDUMP_ACTION }
#define OPT_HOTZONE_SIZE_ACTIONS { REENCRYPT_ACTION } #define OPT_HOTZONE_SIZE_ACTIONS { REENCRYPT_ACTION }
#define OPT_FORCE_OFFLINE_REENCRYPT_ACTIONS { REENCRYPT_ACTION }
#define OPT_INTEGRITY_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION } #define OPT_INTEGRITY_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
#define OPT_INTEGRITY_NO_WIPE_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION } #define OPT_INTEGRITY_NO_WIPE_ACTIONS { FORMAT_ACTION, REENCRYPT_ACTION }
#define OPT_ITER_TIME_ACTIONS { BENCHMARK_ACTION, FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, REENCRYPT_ACTION } #define OPT_ITER_TIME_ACTIONS { BENCHMARK_ACTION, FORMAT_ACTION, ADDKEY_ACTION, CHANGEKEY_ACTION, CONVERTKEY_ACTION, REENCRYPT_ACTION }

View File

@@ -53,6 +53,7 @@
#define OPT_FEC_OFFSET "fec-offset" #define OPT_FEC_OFFSET "fec-offset"
#define OPT_FEC_ROOTS "fec-roots" #define OPT_FEC_ROOTS "fec-roots"
#define OPT_FORCE_PASSWORD "force-password" #define OPT_FORCE_PASSWORD "force-password"
#define OPT_FORCE_OFFLINE_REENCRYPT "force-offline-reencrypt"
#define OPT_FORMAT "format" #define OPT_FORMAT "format"
#define OPT_HASH "hash" #define OPT_HASH "hash"
#define OPT_HASH_BLOCK_SIZE "hash-block-size" #define OPT_HASH_BLOCK_SIZE "hash-block-size"

View File

@@ -126,7 +126,7 @@ static int reencrypt_get_active_name(struct crypt_device *cd, const char *data_d
assert(cd); assert(cd);
assert(r_active_name); assert(r_active_name);
if (ARG_SET(OPT_INIT_ONLY_ID)) { if (ARG_SET(OPT_INIT_ONLY_ID) || ARG_SET(OPT_FORCE_OFFLINE_REENCRYPT_ID)) {
*r_active_name = NULL; *r_active_name = NULL;
return 0; return 0;
} }
@@ -870,6 +870,9 @@ static int reencrypt_luks2_resume(struct crypt_device *cd)
.device = tools_get_device_name(crypt_get_device_name(cd), &backing_file) .device = tools_get_device_name(crypt_get_device_name(cd), &backing_file)
}; };
if (ARG_SET(OPT_FORCE_OFFLINE_REENCRYPT_ID) && !ARG_SET(OPT_BATCH_MODE_ID))
log_std(_("Resuming LUKS reencryption in forced offline mode.\n"));
set_int_handler(0); set_int_handler(0);
r = crypt_reencrypt_run(cd, tools_progress, &prog_parms); r = crypt_reencrypt_run(cd, tools_progress, &prog_parms);
free(backing_file); free(backing_file);

View File

@@ -155,37 +155,12 @@ function img_check_fail()
function img_run_reenc_ok() function img_run_reenc_ok()
{ {
local EXPECT_TIMEOUT=60 $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt --resilience none || fail
# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here.
expect_run - >/dev/null <<EOF
proc abort {} { send_error "Timeout. "; exit 2 }
set timeout $EXPECT_TIMEOUT
eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks --resilience none
expect timeout abort "Are you sure? (Type 'yes' in capital letters):"
send "YES\n"
expect timeout abort eof
exit
EOF
[ $? -eq 0 ] || fail "Expect script failed."
} }
function img_run_reenc_fail() function img_run_reenc_fail()
{ {
local EXPECT_TIMEOUT=60 $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --force-offline-reencrypt --disable-locks -q 2>/dev/null && fail "Reencryption passed (should have failed)."
# For now, we cannot run reencryption in batch mode for non-block device. Just fake the terminal here.
expect_run - >/dev/null <<EOF
proc abort {} { send_error "Timeout. "; exit 42 }
set timeout $EXPECT_TIMEOUT
eval spawn $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --disable-locks
expect timeout abort "Are you sure? (Type 'yes' in capital letters):"
send "YES\n"
expect timeout abort eof
catch wait result
exit [lindex \$result 3]
EOF
local ret=$?
[ $ret -eq 0 ] && fail "Reencryption passed (should have failed)."
[ $ret -eq 42 ] && fail "Expect script failed."
img_hash_unchanged img_hash_unchanged
} }
@@ -218,18 +193,11 @@ function valgrind_run()
INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@"
} }
function expect_run()
{
export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}"
expect "$@"
}
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
bin_check jq bin_check jq
bin_check sha256sum bin_check sha256sum
bin_check xxd bin_check xxd
bin_check expect
export LANG=C export LANG=C