CLI: preserve protection recovery across cached and backup mounts

Reuse hidden-credential recovery for cached and backup-header attempts.
Keep the outer credential source and backup selection during correction.
Warn about automatic backup-header use only after mounting succeeds.
This commit is contained in:
Mounir IDRASSI
2026-09-25 13:37:41 +02:00
parent 035b116d53
commit d7fa847de0
+61 -29
View File
@@ -1508,6 +1508,38 @@ namespace VeraCrypt
options.EMVSupportEnabled = true;
bool retryWithCachedPasswords = false;
bool autoBackupHeaderUsed = false;
auto mountWithProtectionRecovery = [&] () -> shared_ptr <VolumeInfo>
{
// 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 <VolumeInfo>();
};
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")