diff --git a/.travis-functions.sh b/.travis-functions.sh index d825c6ab..5e88a709 100644 --- a/.travis-functions.sh +++ b/.travis-functions.sh @@ -75,6 +75,7 @@ function travis_install_script pkg-config \ autopoint \ gettext \ + expect || return } diff --git a/src/cryptsetup.c b/src/cryptsetup.c index b5b529fe..d08d0e25 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -813,7 +813,7 @@ static int action_open_luks(void) const char *data_device, *header_device, *activated_name; char *key = NULL; uint32_t activate_flags = 0; - int r, keysize; + int r, keysize, tries; char *password = NULL; size_t passwordLen; @@ -850,14 +850,17 @@ static int action_open_luks(void) r = crypt_activate_by_volume_key(cd, activated_name, key, keysize, activate_flags); } else { - r = tools_get_key(NULL, &password, &passwordLen, - opt_keyfile_offset, opt_keyfile_size, opt_key_file, - opt_timeout, _verify_passphrase(0), 0, cd); - if (r < 0) - goto out; + tries = (opt_key_file && !tools_is_stdin(opt_key_file)) ? 1 : opt_tries; + do { + r = tools_get_key(NULL, &password, &passwordLen, + opt_keyfile_offset, opt_keyfile_size, opt_key_file, + opt_timeout, _verify_passphrase(0), 0, cd); + if (r < 0) + goto out; - r = crypt_activate_by_passphrase(cd, activated_name, - opt_key_slot, password, passwordLen, activate_flags); + r = crypt_activate_by_passphrase(cd, activated_name, + opt_key_slot, password, passwordLen, activate_flags); + } while ((r == -EPERM || r == -EINVAL || r == -ERANGE) && (--tries > 0)); } out: crypt_safe_free(key); @@ -1286,7 +1289,7 @@ static int action_luksResume(void) struct crypt_device *cd = NULL; char *password = NULL; size_t passwordLen; - int r; + int r, tries; if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(opt_header_device)))) goto out; @@ -1294,13 +1297,17 @@ static int action_luksResume(void) if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) goto out; - r = tools_get_key(NULL, &password, &passwordLen, - opt_keyfile_offset, opt_keyfile_size, opt_key_file, - opt_timeout, _verify_passphrase(0), 0, cd); - if (r) - goto out; + tries = (opt_key_file && !tools_is_stdin(opt_key_file)) ? 1 : opt_tries; + do { + r = tools_get_key(NULL, &password, &passwordLen, + opt_keyfile_offset, opt_keyfile_size, opt_key_file, + opt_timeout, _verify_passphrase(0), 0, cd); + if (r) + goto out; - r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT, password, passwordLen); + r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT, + password, passwordLen); + } while ((r == -EPERM || r == -EINVAL || r == -ERANGE) && (--tries > 0)); out: crypt_safe_free(password); crypt_free(cd); diff --git a/tests/compat-test b/tests/compat-test index 7f7681cf..56c6264b 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -43,9 +43,9 @@ LOOPDEV=$(losetup -f 2>/dev/null) function remove_mapping() { - [ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove $DEV_NAME3 - [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 - [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME + [ -b /dev/mapper/$DEV_NAME3 ] && dmsetup remove $DEV_NAME3 >/dev/null 2>&1 + [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 >/dev/null 2>&1 + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1 losetup -d $LOOPDEV >/dev/null 2>&1 rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG >/dev/null 2>&1 } @@ -79,7 +79,7 @@ function skip() function prepare() { - [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1 case "$2" in wipe) @@ -611,5 +611,22 @@ else $CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 fi +prepare "[32] Interactive password retry from terminal." new +which expect >/dev/null 2>&1 || skip "WARNING: expect tool missing, interactive test will be skipped." +expect - >/dev/null 2>&1 <