mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-10-05 16:46:35 -05:00
Unix: process protection keyfiles before cached mounts
Apply protection keyfiles once in the application, including cached-password mounts. This keeps PC/SC out of the core service before FUSE forks. Preserve protection errors and cache retries, and ignore protection credentials when protection is disabled.
This commit is contained in:
1 file changed
+70
-49
@@ -91,65 +91,86 @@ namespace VeraCrypt
|
|||||||
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options)
|
virtual shared_ptr <VolumeInfo> MountVolume (MountOptions &options)
|
||||||
{
|
{
|
||||||
shared_ptr <VolumeInfo> mountedVolume;
|
shared_ptr <VolumeInfo> mountedVolume;
|
||||||
|
const bool useCachedPasswords = !VolumePasswordCache::IsEmpty()
|
||||||
if (!VolumePasswordCache::IsEmpty()
|
|
||||||
&& (!options.Password || options.Password->IsEmpty())
|
&& (!options.Password || options.Password->IsEmpty())
|
||||||
&& (!options.Keyfiles || options.Keyfiles->empty()))
|
&& (!options.Keyfiles || options.Keyfiles->empty());
|
||||||
{
|
MountOptions newOptions = options;
|
||||||
finally_do_arg (MountOptions*, &options, { if (finally_arg->Password) finally_arg->Password.reset(); });
|
|
||||||
|
|
||||||
PasswordIncorrect passwordException;
|
|
||||||
foreach (shared_ptr <VolumePassword> password, VolumePasswordCache::GetPasswords())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
options.Password = password;
|
|
||||||
mountedVolume = CoreService::RequestMountVolume (options);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (PasswordIncorrect &e)
|
|
||||||
{
|
|
||||||
passwordException = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mountedVolume)
|
|
||||||
passwordException.Throw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MountOptions newOptions = options;
|
|
||||||
|
|
||||||
|
// Resolve keyfiles in the application process, also when the outer password
|
||||||
|
// is cached. Token access must not initialize PC/SC in the core service
|
||||||
|
// before it forks FUSE.
|
||||||
|
if (!useCachedPasswords)
|
||||||
newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVSupportEnabled);
|
newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVSupportEnabled);
|
||||||
if (newOptions.Keyfiles)
|
if (newOptions.Keyfiles)
|
||||||
newOptions.Keyfiles->clear();
|
newOptions.Keyfiles->clear();
|
||||||
|
|
||||||
|
if (options.Protection == VolumeProtection::HiddenVolumeReadOnly)
|
||||||
newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword, options.EMVSupportEnabled);
|
newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword, options.EMVSupportEnabled);
|
||||||
if (newOptions.ProtectionKeyfiles)
|
else
|
||||||
newOptions.ProtectionKeyfiles->clear();
|
newOptions.ProtectionPassword.reset();
|
||||||
|
if (newOptions.ProtectionKeyfiles)
|
||||||
|
newOptions.ProtectionKeyfiles->clear();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (useCachedPasswords)
|
||||||
|
{
|
||||||
|
finally_do_arg (MountOptions*, &options, { if (finally_arg->Password) finally_arg->Password.reset(); });
|
||||||
|
|
||||||
|
PasswordIncorrect passwordException;
|
||||||
|
foreach (shared_ptr <VolumePassword> password, VolumePasswordCache::GetPasswords())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
newOptions.Password = password;
|
||||||
|
mountedVolume = CoreService::RequestMountVolume (newOptions);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (ProtectionPasswordIncorrect&)
|
||||||
|
{
|
||||||
|
// The outer password was accepted; another cached password cannot
|
||||||
|
// correct the hidden-volume protection credentials.
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (ProtectionPasswordKeyfilesIncorrect&)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (PasswordIncorrect &e)
|
||||||
|
{
|
||||||
|
passwordException = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mountedVolume)
|
||||||
|
passwordException.Throw();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mountedVolume = CoreService::RequestMountVolume (newOptions);
|
mountedVolume = CoreService::RequestMountVolume (newOptions);
|
||||||
}
|
}
|
||||||
catch (ProtectionPasswordIncorrect &e)
|
}
|
||||||
{
|
catch (ProtectionPasswordIncorrect &e)
|
||||||
if (options.ProtectionKeyfiles && !options.ProtectionKeyfiles->empty())
|
{
|
||||||
throw ProtectionPasswordKeyfilesIncorrect (e.what());
|
if (options.ProtectionKeyfiles && !options.ProtectionKeyfiles->empty())
|
||||||
throw;
|
throw ProtectionPasswordKeyfilesIncorrect (e.what());
|
||||||
}
|
throw;
|
||||||
catch (PasswordIncorrect &e)
|
}
|
||||||
{
|
catch (ProtectionPasswordKeyfilesIncorrect&)
|
||||||
if (options.Keyfiles && !options.Keyfiles->empty())
|
{
|
||||||
throw PasswordKeyfilesIncorrect (e.what());
|
throw;
|
||||||
throw;
|
}
|
||||||
}
|
catch (PasswordIncorrect &e)
|
||||||
|
{
|
||||||
|
if (options.Keyfiles && !options.Keyfiles->empty())
|
||||||
|
throw PasswordKeyfilesIncorrect (e.what());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.CachePassword
|
if (!useCachedPasswords && options.CachePassword
|
||||||
&& ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty())))
|
&& ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty())))
|
||||||
{
|
{
|
||||||
VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVSupportEnabled));
|
VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVSupportEnabled));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VolumeEventArgs eventArgs (mountedVolume);
|
VolumeEventArgs eventArgs (mountedVolume);
|
||||||
|
|||||||
Reference in new issue
Block a user