diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index 70a1405a..45ba6049 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -1508,6 +1508,38 @@ namespace VeraCrypt options.EMVSupportEnabled = true; + bool retryWithCachedPasswords = false; + bool autoBackupHeaderUsed = false; + + auto mountWithProtectionRecovery = [&] () -> shared_ptr + { + // The proxy clears options.Password after a cached attempt, so remember + // to reuse the cache while correcting hidden-volume credentials. + retryWithCachedPasswords = (!options.Password || options.Password->IsEmpty()) + && (!options.Keyfiles || options.Keyfiles->empty()) + && !Core->IsPasswordCacheEmpty(); + + try + { + return UserInterface::MountVolume (options); + } + catch (ProtectionPasswordIncorrect &e) + { + ShowInfo (e); + options.ProtectionPassword.reset(); + options.ProtectionPim = -1; + } + catch (ProtectionPasswordKeyfilesIncorrect &e) + { + ShowInfo (e); + options.ProtectionPassword.reset(); + options.ProtectionPim = -1; + options.ProtectionKeyfiles.reset(); + } + + return shared_ptr (); + }; + if (tryCachedPasswords && (!options.Password || options.Password->IsEmpty()) && (!options.Keyfiles || options.Keyfiles->empty()) @@ -1516,29 +1548,35 @@ namespace VeraCrypt // Cached password try { - volume = UserInterface::MountVolume (options); + volume = mountWithProtectionRecovery(); + } + catch (PasswordException&) + { + retryWithCachedPasswords = false; } - catch (PasswordException&) { } } int incorrectPasswordCount = 0; while (!volume) { - // Password - if (!options.Password) + if (!retryWithCachedPasswords) { - options.Password = AskPassword (StringFormatter (_("Enter password for {0}"), wstring (*options.Path))); - } + // Password + if (!options.Password) + { + options.Password = AskPassword (StringFormatter (_("Enter password for {0}"), wstring (*options.Path))); + } - if (options.Pim < 0) - { - options.Pim = AskPim (StringFormatter (_("Enter PIM for {0}"), wstring (*options.Path))); - } + if (options.Pim < 0) + { + options.Pim = AskPim (StringFormatter (_("Enter PIM for {0}"), wstring (*options.Path))); + } - // Keyfiles - if (!options.Keyfiles) - options.Keyfiles = AskKeyfiles(); + // Keyfiles + if (!options.Keyfiles) + options.Keyfiles = AskKeyfiles(); + } // Hidden volume protection if (options.Protection == VolumeProtection::None @@ -1558,35 +1596,25 @@ namespace VeraCrypt try { - volume = UserInterface::MountVolume (options); - } - catch (ProtectionPasswordIncorrect &e) - { - ShowInfo (e); - options.ProtectionPassword.reset(); - options.ProtectionPim = -1; - } - catch (ProtectionPasswordKeyfilesIncorrect &e) - { - ShowInfo (e); - options.ProtectionPassword.reset(); - options.ProtectionPim = -1; - options.ProtectionKeyfiles.reset(); + volume = mountWithProtectionRecovery(); } catch (PasswordIncorrect &e) { + retryWithCachedPasswords = false; if (++incorrectPasswordCount > 2 && !options.UseBackupHeaders) { // Try to mount the volume using the backup header options.UseBackupHeaders = true; + autoBackupHeaderUsed = true; try { - volume = UserInterface::MountVolume (options); - ShowWarning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK"); + volume = mountWithProtectionRecovery(); } catch (...) { + retryWithCachedPasswords = false; + autoBackupHeaderUsed = false; options.UseBackupHeaders = false; ShowInfo (e); options.Password.reset(); @@ -1604,11 +1632,15 @@ namespace VeraCrypt } catch (PasswordException &e) { + retryWithCachedPasswords = false; ShowInfo (e); options.Password.reset(); } } + if (autoBackupHeaderUsed) + ShowWarning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK"); + #ifdef TC_LINUX if (!Preferences.NonInteractive && !Preferences.DisableKernelEncryptionModeWarning && volume->EncryptionModeName != L"XTS")