From 9cabe0dc4ee4c45fafe4a5b822a11048ee1abf13 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 8 Jul 2026 13:03:45 +0900 Subject: [PATCH] Unix: isolate auto-mount options and EMV settings Clone command-line auto-mount options before device and favorite batches, and clone the batch options again for each favorite before applying favorite-specific fields. This prevents interactive credentials, PIM, KDF choices, and per-favorite filesystem settings from carrying over to later favorites. Propagate EMVSupportEnabled through MountOptions serialization and mount setup so elevated core service requests use the same EMV setting as the caller. --- src/Core/MountOptions.cpp | 3 ++ src/Core/MountOptions.h | 3 +- src/Main/Forms/VolumeCreationWizard.cpp | 1 + src/Main/GraphicUserInterface.cpp | 5 +- src/Main/GraphicUserInterface.h | 2 +- src/Main/TextUserInterface.cpp | 5 +- src/Main/TextUserInterface.h | 2 +- src/Main/UserInterface.cpp | 70 ++++++++++++++++++++----- src/Main/UserInterface.h | 2 +- 9 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/Core/MountOptions.cpp b/src/Core/MountOptions.cpp index 30d8d60f..3b776520 100644 --- a/src/Core/MountOptions.cpp +++ b/src/Core/MountOptions.cpp @@ -55,6 +55,7 @@ namespace VeraCrypt TC_CLONE (SharedAccessAllowed); TC_CLONE (SlotNumber); TC_CLONE (UseBackupHeaders); + TC_CLONE (EMVSupportEnabled); } void MountOptions::Deserialize (shared_ptr stream) @@ -105,6 +106,7 @@ namespace VeraCrypt sr.Deserialize ("SharedAccessAllowed", SharedAccessAllowed); sr.Deserialize ("SlotNumber", SlotNumber); sr.Deserialize ("UseBackupHeaders", UseBackupHeaders); + sr.Deserialize ("EMVSupportEnabled", EMVSupportEnabled); try { @@ -172,6 +174,7 @@ namespace VeraCrypt sr.Serialize ("SharedAccessAllowed", SharedAccessAllowed); sr.Serialize ("SlotNumber", SlotNumber); sr.Serialize ("UseBackupHeaders", UseBackupHeaders); + sr.Serialize ("EMVSupportEnabled", EMVSupportEnabled); sr.Serialize ("KdfNull", Kdf == nullptr); if (Kdf) diff --git a/src/Core/MountOptions.h b/src/Core/MountOptions.h index 2ea5e305..f70cd22e 100644 --- a/src/Core/MountOptions.h +++ b/src/Core/MountOptions.h @@ -40,7 +40,8 @@ namespace VeraCrypt Removable (false), SharedAccessAllowed (false), SlotNumber (0), - UseBackupHeaders (false) + UseBackupHeaders (false), + EMVSupportEnabled (false) { } diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 6fdbf418..0250445c 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -848,6 +848,7 @@ namespace VeraCrypt mountOptions.Pim = Pim; mountOptions.Keyfiles = Keyfiles; mountOptions.Kdf = Kdf; + mountOptions.EMVSupportEnabled = Gui->GetPreferences().EMVSupportEnabled; shared_ptr volume = Core->MountVolume (mountOptions); finally_do_arg (shared_ptr , volume, { Core->DismountVolume (finally_arg, true); }); diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp index d58fd97e..321a9396 100644 --- a/src/Main/GraphicUserInterface.cpp +++ b/src/Main/GraphicUserInterface.cpp @@ -904,7 +904,7 @@ namespace VeraCrypt } } - shared_ptr GraphicUserInterface::MountVolume (MountOptions &options) const + shared_ptr GraphicUserInterface::MountVolume (MountOptions &options, bool tryCachedPasswords) const { CheckRequirementsForMountingVolume(); @@ -937,7 +937,8 @@ namespace VeraCrypt try { - if ((!options.Password || options.Password->IsEmpty()) + if (tryCachedPasswords + && (!options.Password || options.Password->IsEmpty()) && (!options.Keyfiles || options.Keyfiles->empty()) && !Core->IsPasswordCacheEmpty()) { diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h index be05f934..fba52b19 100644 --- a/src/Main/GraphicUserInterface.h +++ b/src/Main/GraphicUserInterface.h @@ -67,7 +67,7 @@ namespace VeraCrypt virtual void ListSecurityTokenKeyfiles () const; virtual void ListEMVTokenKeyfiles () const; virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; - virtual shared_ptr MountVolume (MountOptions &options) const; + virtual shared_ptr MountVolume (MountOptions &options, bool tryCachedPasswords = true) const; virtual void MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const; virtual void OnAutoDismountAllEvent (); virtual bool OnInit (); diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index aba0aa15..cd46b112 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -1466,7 +1466,7 @@ namespace VeraCrypt } } - shared_ptr TextUserInterface::MountVolume (MountOptions &options) const + shared_ptr TextUserInterface::MountVolume (MountOptions &options, bool tryCachedPasswords) const { shared_ptr volume; @@ -1508,7 +1508,8 @@ namespace VeraCrypt options.EMVSupportEnabled = true; - if ((!options.Password || options.Password->IsEmpty()) + if (tryCachedPasswords + && (!options.Password || options.Password->IsEmpty()) && (!options.Keyfiles || options.Keyfiles->empty()) && !Core->IsPasswordCacheEmpty()) { diff --git a/src/Main/TextUserInterface.h b/src/Main/TextUserInterface.h index 21248f11..0552ad18 100644 --- a/src/Main/TextUserInterface.h +++ b/src/Main/TextUserInterface.h @@ -62,7 +62,7 @@ namespace VeraCrypt virtual void ListSecurityTokenKeyfiles () const; virtual void ListEMVTokenKeyfiles () const; virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; - virtual shared_ptr MountVolume (MountOptions &options) const; + virtual shared_ptr MountVolume (MountOptions &options, bool tryCachedPasswords = true) const; virtual bool OnInit (); #ifndef TC_NO_GUI virtual bool OnInitGui () { return true; } diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 57ec848f..8ea98fb6 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -44,6 +44,30 @@ namespace VeraCrypt } }; + class CloseSecurityTokenSessionsAfterMountScope + { + public: + CloseSecurityTokenSessionsAfterMountScope (bool &preference) + : Preference (preference), RestoreValue (preference) + { + if (RestoreValue) + Preference = false; + } + + ~CloseSecurityTokenSessionsAfterMountScope () + { + if (RestoreValue) + Preference = true; + } + + private: + bool &Preference; + bool RestoreValue; + + CloseSecurityTokenSessionsAfterMountScope (const CloseSecurityTokenSessionsAfterMountScope &); + CloseSecurityTokenSessionsAfterMountScope &operator= (const CloseSecurityTokenSessionsAfterMountScope &); + }; + UserInterface::UserInterface () { } @@ -792,6 +816,7 @@ namespace VeraCrypt { BusyScope busy (this); + MountOptions batchOptions (options); VolumeInfoList newMountedVolumes; foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList()) { @@ -803,13 +828,15 @@ namespace VeraCrypt continue; } - favorite.ToMountOptions (options); + // Keep credentials and KDF/PIM selected for one favorite from leaking into the next one. + MountOptions favoriteOptions (batchOptions); + favorite.ToMountOptions (favoriteOptions); bool mountPerformed = false; if (Preferences.NonInteractive) { BusyScope busy (this); - newMountedVolumes.push_back (Core->MountVolume (options)); + newMountedVolumes.push_back (Core->MountVolume (favoriteOptions)); mountPerformed = true; } else @@ -817,19 +844,26 @@ namespace VeraCrypt try { BusyScope busy (this); - newMountedVolumes.push_back (Core->MountVolume (options)); + newMountedVolumes.push_back (Core->MountVolume (favoriteOptions)); mountPerformed = true; } + catch (PasswordException&) + { + CloseSecurityTokenSessionsAfterMountScope closeTokenSessionsScope (Preferences.CloseSecurityTokenSessionsAfterMount); + + // The initial silent mount attempt has already consulted cached passwords. + // Avoid repeating the same failed cache sweep before prompting the user. + shared_ptr volume = MountVolume (favoriteOptions, false); + + if (!volume) + break; + newMountedVolumes.push_back (volume); + } catch (...) { - UserPreferences prefs = GetPreferences(); - if (prefs.CloseSecurityTokenSessionsAfterMount) - Preferences.CloseSecurityTokenSessionsAfterMount = false; + CloseSecurityTokenSessionsAfterMountScope closeTokenSessionsScope (Preferences.CloseSecurityTokenSessionsAfterMount); - shared_ptr volume = MountVolume (options); - - if (prefs.CloseSecurityTokenSessionsAfterMount) - Preferences.CloseSecurityTokenSessionsAfterMount = true; + shared_ptr volume = MountVolume (favoriteOptions); if (!volume) break; @@ -847,8 +881,9 @@ namespace VeraCrypt return newMountedVolumes; } - shared_ptr UserInterface::MountVolume (MountOptions &options) const + shared_ptr UserInterface::MountVolume (MountOptions &options, bool tryCachedPasswords) const { + (void) tryCachedPasswords; shared_ptr volume; try @@ -1118,6 +1153,9 @@ const FileManager fileManagers[] = { cmdLine.ArgMountOptions.Pim = cmdLine.ArgPim; cmdLine.ArgMountOptions.Keyfiles = cmdLine.ArgKeyfiles; cmdLine.ArgMountOptions.SharedAccessAllowed = cmdLine.ArgForce; + cmdLine.ArgMountOptions.EMVSupportEnabled = + Application::GetUserInterfaceType() == UserInterfaceType::Text + || GetPreferences().EMVSupportEnabled; if (cmdLine.ArgHash) { cmdLine.ArgMountOptions.Kdf = cmdLine.ArgHash; @@ -1131,17 +1169,21 @@ const FileManager fileManagers[] = { case CommandId::AutoMountFavorites: case CommandId::AutoMountDevicesFavorites: { + MountOptions autoMountOptions (cmdLine.ArgMountOptions); + if (cmdLine.ArgCommand == CommandId::AutoMountDevices || cmdLine.ArgCommand == CommandId::AutoMountDevicesFavorites) { + MountOptions deviceMountOptions (autoMountOptions); if (Preferences.NonInteractive) - mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (cmdLine.ArgMountOptions); + mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (deviceMountOptions); else - mountedVolumes = MountAllDeviceHostedVolumes (cmdLine.ArgMountOptions); + mountedVolumes = MountAllDeviceHostedVolumes (deviceMountOptions); } if (cmdLine.ArgCommand == CommandId::AutoMountFavorites || cmdLine.ArgCommand == CommandId::AutoMountDevicesFavorites) { - foreach (shared_ptr v, MountAllFavoriteVolumes(cmdLine.ArgMountOptions)) + MountOptions favoriteMountOptions (autoMountOptions); + foreach (shared_ptr v, MountAllFavoriteVolumes(favoriteMountOptions)) mountedVolumes.push_back (v); } } diff --git a/src/Main/UserInterface.h b/src/Main/UserInterface.h index 02803417..6f6792bb 100644 --- a/src/Main/UserInterface.h +++ b/src/Main/UserInterface.h @@ -59,7 +59,7 @@ namespace VeraCrypt virtual void ListTokenKeyfiles () const = 0; virtual void ListSecurityTokenKeyfiles () const = 0; virtual void ListEMVTokenKeyfiles () const = 0; - virtual shared_ptr MountVolume (MountOptions &options) const; + virtual shared_ptr MountVolume (MountOptions &options, bool tryCachedPasswords = true) const; virtual shared_ptr MountVolumeThread (MountOptions &options) const { return Core->MountVolume (options);} virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; virtual VolumeInfoList MountAllFavoriteVolumes (MountOptions &options);