From 7ffce028d04a6b13ef762e2b89c34b688e8ca59d Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 31 May 2014 18:44:53 +0200 Subject: [PATCH] Add TrueCrypt 7.1a MacOSX/Linux specific source files. --- src/Build/Include/Makefile.inc | 58 + src/Build/Resources/MacOSX/Info.plist.xml | 44 + src/Core/Core.h | 20 + src/Core/Core.make | 27 + src/Core/CoreBase.cpp | 279 + src/Core/CoreBase.h | 99 + src/Core/CoreException.cpp | 29 + src/Core/CoreException.h | 52 + src/Core/FatFormatter.cpp | 384 + src/Core/FatFormatter.h | 29 + src/Core/HostDevice.cpp | 47 + src/Core/HostDevice.h | 45 + src/Core/MountOptions.cpp | 129 + src/Core/MountOptions.h | 70 + src/Core/RandomNumberGenerator.cpp | 213 + src/Core/RandomNumberGenerator.h | 55 + src/Core/Unix/CoreService.cpp | 544 + src/Core/Unix/CoreService.h | 63 + src/Core/Unix/CoreServiceProxy.h | 152 + src/Core/Unix/CoreServiceRequest.cpp | 269 + src/Core/Unix/CoreServiceRequest.h | 136 + src/Core/Unix/CoreServiceResponse.cpp | 119 + src/Core/Unix/CoreServiceResponse.h | 84 + src/Core/Unix/CoreUnix.cpp | 618 + src/Core/Unix/CoreUnix.h | 69 + src/Core/Unix/FreeBSD/CoreFreeBSD.cpp | 202 + src/Core/Unix/FreeBSD/CoreFreeBSD.h | 37 + src/Core/Unix/FreeBSD/System.h | 12 + src/Core/Unix/Linux/CoreLinux.cpp | 477 + src/Core/Unix/Linux/CoreLinux.h | 39 + src/Core/Unix/Linux/System.h | 12 + src/Core/Unix/MacOSX/CoreMacOSX.cpp | 215 + src/Core/Unix/MacOSX/CoreMacOSX.h | 36 + src/Core/Unix/MacOSX/System.h | 12 + src/Core/Unix/MountedFilesystem.h | 27 + src/Core/Unix/Solaris/CoreSolaris.cpp | 174 + src/Core/Unix/Solaris/CoreSolaris.h | 37 + src/Core/Unix/Solaris/System.h | 12 + src/Core/Unix/System.h | 12 + src/Core/VolumeCreator.cpp | 345 + src/Core/VolumeCreator.h | 119 + src/Driver/Fuse/Driver.make | 16 + src/Driver/Fuse/FuseService.cpp | 592 + src/Driver/Fuse/FuseService.h | 73 + src/Main/Application.cpp | 98 + src/Main/Application.h | 40 + src/Main/CommandLineInterface.cpp | 583 + src/Main/CommandLineInterface.h | 94 + src/Main/FatalErrorHandler.cpp | 274 + src/Main/FatalErrorHandler.h | 33 + src/Main/FavoriteVolume.cpp | 94 + src/Main/FavoriteVolume.h | 53 + src/Main/Forms/AboutDialog.cpp | 66 + src/Main/Forms/AboutDialog.h | 25 + src/Main/Forms/BenchmarkDialog.cpp | 157 + src/Main/Forms/BenchmarkDialog.h | 43 + src/Main/Forms/ChangePasswordDialog.cpp | 195 + src/Main/Forms/ChangePasswordDialog.h | 48 + src/Main/Forms/DeviceSelectionDialog.cpp | 120 + src/Main/Forms/DeviceSelectionDialog.h | 46 + .../Forms/EncryptionOptionsWizardPage.cpp | 137 + src/Main/Forms/EncryptionOptionsWizardPage.h | 41 + src/Main/Forms/EncryptionTestDialog.cpp | 227 + src/Main/Forms/EncryptionTestDialog.h | 40 + src/Main/Forms/FavoriteVolumesDialog.cpp | 118 + src/Main/Forms/FavoriteVolumesDialog.h | 45 + src/Main/Forms/Forms.cpp | 3062 +++ src/Main/Forms/Forms.h | 1023 + src/Main/Forms/InfoWizardPage.cpp | 33 + src/Main/Forms/InfoWizardPage.h | 32 + src/Main/Forms/KeyfileGeneratorDialog.cpp | 118 + src/Main/Forms/KeyfileGeneratorDialog.h | 34 + src/Main/Forms/KeyfilesDialog.cpp | 44 + src/Main/Forms/KeyfilesDialog.h | 33 + src/Main/Forms/KeyfilesPanel.cpp | 160 + src/Main/Forms/KeyfilesPanel.h | 37 + src/Main/Forms/LegalNoticesDialog.cpp | 28 + src/Main/Forms/LegalNoticesDialog.h | 23 + src/Main/Forms/MainFrame.cpp | 1585 ++ src/Main/Forms/MainFrame.h | 173 + src/Main/Forms/MountOptionsDialog.cpp | 174 + src/Main/Forms/MountOptionsDialog.h | 42 + .../Forms/NewSecurityTokenKeyfileDialog.cpp | 45 + .../Forms/NewSecurityTokenKeyfileDialog.h | 30 + src/Main/Forms/PreferencesDialog.cpp | 488 + src/Main/Forms/PreferencesDialog.h | 60 + src/Main/Forms/ProgressWizardPage.cpp | 80 + src/Main/Forms/ProgressWizardPage.h | 42 + src/Main/Forms/RandomPoolEnrichmentDialog.cpp | 93 + src/Main/Forms/RandomPoolEnrichmentDialog.h | 33 + .../Forms/SecurityTokenKeyfilesDialog.cpp | 197 + src/Main/Forms/SecurityTokenKeyfilesDialog.h | 47 + src/Main/Forms/SelectDirectoryWizardPage.cpp | 32 + src/Main/Forms/SelectDirectoryWizardPage.h | 33 + src/Main/Forms/SingleChoiceWizardPage.h | 116 + src/Main/Forms/TrueCrypt.fbp | 17436 ++++++++++++++++ .../VolumeCreationProgressWizardPage.cpp | 183 + .../Forms/VolumeCreationProgressWizardPage.h | 53 + src/Main/Forms/VolumeCreationWizard.cpp | 984 + src/Main/Forms/VolumeCreationWizard.h | 85 + .../Forms/VolumeFormatOptionsWizardPage.cpp | 81 + .../Forms/VolumeFormatOptionsWizardPage.h | 36 + src/Main/Forms/VolumeLocationWizardPage.cpp | 98 + src/Main/Forms/VolumeLocationWizardPage.h | 40 + src/Main/Forms/VolumePasswordPanel.cpp | 310 + src/Main/Forms/VolumePasswordPanel.h | 54 + src/Main/Forms/VolumePasswordWizardPage.cpp | 39 + src/Main/Forms/VolumePasswordWizardPage.h | 37 + src/Main/Forms/VolumePropertiesDialog.cpp | 97 + src/Main/Forms/VolumePropertiesDialog.h | 26 + src/Main/Forms/VolumeSizeWizardPage.cpp | 137 + src/Main/Forms/VolumeSizeWizardPage.h | 51 + src/Main/Forms/WizardFrame.cpp | 189 + src/Main/Forms/WizardFrame.h | 58 + src/Main/Forms/WizardPage.h | 41 + src/Main/GraphicUserInterface.cpp | 1690 ++ src/Main/GraphicUserInterface.h | 160 + src/Main/Hotkey.cpp | 241 + src/Main/Hotkey.h | 63 + src/Main/LanguageStrings.cpp | 86 + src/Main/LanguageStrings.h | 40 + src/Main/Main.h | 17 + src/Main/Main.make | 145 + src/Main/Resources.cpp | 184 + src/Main/Resources.h | 33 + src/Main/StringFormatter.cpp | 88 + src/Main/StringFormatter.h | 64 + src/Main/System.cpp | 10 + src/Main/System.h | 69 + src/Main/SystemPrecompiled.h | 29 + src/Main/TextUserInterface.cpp | 1552 ++ src/Main/TextUserInterface.h | 78 + src/Main/Unix/Main.cpp | 127 + src/Main/UserInterface.cpp | 1494 ++ src/Main/UserInterface.h | 111 + src/Main/UserInterfaceException.h | 36 + src/Main/UserInterfaceType.h | 25 + src/Main/UserPreferences.cpp | 235 + src/Main/UserPreferences.h | 107 + src/Main/VolumeHistory.cpp | 152 + src/Main/VolumeHistory.h | 46 + src/Main/Xml.cpp | 178 + src/Main/Xml.h | 75 + src/Makefile | 298 + src/Platform/Unix/Directory.cpp | 62 + src/Platform/Unix/File.cpp | 348 + src/Platform/Unix/FilesystemPath.cpp | 96 + src/Platform/Unix/Mutex.cpp | 62 + src/Platform/Unix/Pipe.cpp | 65 + src/Platform/Unix/Pipe.h | 38 + src/Platform/Unix/Poller.cpp | 57 + src/Platform/Unix/Poller.h | 33 + src/Platform/Unix/Process.cpp | 202 + src/Platform/Unix/Process.h | 40 + src/Platform/Unix/SyncEvent.cpp | 68 + src/Platform/Unix/System.h | 12 + src/Platform/Unix/SystemException.cpp | 66 + src/Platform/Unix/SystemInfo.cpp | 69 + src/Platform/Unix/SystemLog.cpp | 27 + src/Platform/Unix/Thread.cpp | 54 + src/Platform/Unix/Time.cpp | 23 + src/Resources/Icons/TrueCrypt-16x16.xpm | Bin 0 -> 4396 bytes src/Resources/Icons/TrueCrypt-48x48.xpm | Bin 0 -> 8073 bytes src/Volume/Cipher.cpp | 314 + src/Volume/Cipher.h | 129 + src/Volume/Crc32.h | 44 + src/Volume/EncryptionAlgorithm.cpp | 345 + src/Volume/EncryptionAlgorithm.h | 93 + src/Volume/EncryptionMode.cpp | 63 + src/Volume/EncryptionMode.h | 62 + src/Volume/EncryptionModeCBC.cpp | 335 + src/Volume/EncryptionModeCBC.h | 47 + src/Volume/EncryptionModeLRW.cpp | 195 + src/Volume/EncryptionModeLRW.h | 50 + src/Volume/EncryptionModeXTS.cpp | 374 + src/Volume/EncryptionModeXTS.h | 50 + src/Volume/EncryptionTest.cpp | 890 + src/Volume/EncryptionTest.h | 50 + src/Volume/EncryptionThreadPool.cpp | 325 + src/Volume/EncryptionThreadPool.h | 87 + src/Volume/Hash.cpp | 138 + src/Volume/Hash.h | 135 + src/Volume/Keyfile.cpp | 181 + src/Volume/Keyfile.h | 49 + src/Volume/Pkcs5Kdf.cpp | 96 + src/Volume/Pkcs5Kdf.h | 127 + src/Volume/Version.h | 25 + src/Volume/Volume.cpp | 388 + src/Volume/Volume.h | 126 + src/Volume/Volume.make | 62 + src/Volume/VolumeException.cpp | 32 + src/Volume/VolumeException.h | 43 + src/Volume/VolumeHeader.cpp | 340 + src/Volume/VolumeHeader.h | 126 + src/Volume/VolumeInfo.cpp | 118 + src/Volume/VolumeInfo.h | 66 + src/Volume/VolumeLayout.cpp | 254 + src/Volume/VolumeLayout.h | 153 + src/Volume/VolumePassword.cpp | 167 + src/Volume/VolumePassword.h | 92 + src/Volume/VolumePasswordCache.cpp | 43 + src/Volume/VolumePasswordCache.h | 36 + src/Volume/VolumeSlot.h | 19 + 203 files changed, 51616 insertions(+) create mode 100644 src/Build/Include/Makefile.inc create mode 100644 src/Build/Resources/MacOSX/Info.plist.xml create mode 100644 src/Core/Core.h create mode 100644 src/Core/Core.make create mode 100644 src/Core/CoreBase.cpp create mode 100644 src/Core/CoreBase.h create mode 100644 src/Core/CoreException.cpp create mode 100644 src/Core/CoreException.h create mode 100644 src/Core/FatFormatter.cpp create mode 100644 src/Core/FatFormatter.h create mode 100644 src/Core/HostDevice.cpp create mode 100644 src/Core/HostDevice.h create mode 100644 src/Core/MountOptions.cpp create mode 100644 src/Core/MountOptions.h create mode 100644 src/Core/RandomNumberGenerator.cpp create mode 100644 src/Core/RandomNumberGenerator.h create mode 100644 src/Core/Unix/CoreService.cpp create mode 100644 src/Core/Unix/CoreService.h create mode 100644 src/Core/Unix/CoreServiceProxy.h create mode 100644 src/Core/Unix/CoreServiceRequest.cpp create mode 100644 src/Core/Unix/CoreServiceRequest.h create mode 100644 src/Core/Unix/CoreServiceResponse.cpp create mode 100644 src/Core/Unix/CoreServiceResponse.h create mode 100644 src/Core/Unix/CoreUnix.cpp create mode 100644 src/Core/Unix/CoreUnix.h create mode 100644 src/Core/Unix/FreeBSD/CoreFreeBSD.cpp create mode 100644 src/Core/Unix/FreeBSD/CoreFreeBSD.h create mode 100644 src/Core/Unix/FreeBSD/System.h create mode 100644 src/Core/Unix/Linux/CoreLinux.cpp create mode 100644 src/Core/Unix/Linux/CoreLinux.h create mode 100644 src/Core/Unix/Linux/System.h create mode 100644 src/Core/Unix/MacOSX/CoreMacOSX.cpp create mode 100644 src/Core/Unix/MacOSX/CoreMacOSX.h create mode 100644 src/Core/Unix/MacOSX/System.h create mode 100644 src/Core/Unix/MountedFilesystem.h create mode 100644 src/Core/Unix/Solaris/CoreSolaris.cpp create mode 100644 src/Core/Unix/Solaris/CoreSolaris.h create mode 100644 src/Core/Unix/Solaris/System.h create mode 100644 src/Core/Unix/System.h create mode 100644 src/Core/VolumeCreator.cpp create mode 100644 src/Core/VolumeCreator.h create mode 100644 src/Driver/Fuse/Driver.make create mode 100644 src/Driver/Fuse/FuseService.cpp create mode 100644 src/Driver/Fuse/FuseService.h create mode 100644 src/Main/Application.cpp create mode 100644 src/Main/Application.h create mode 100644 src/Main/CommandLineInterface.cpp create mode 100644 src/Main/CommandLineInterface.h create mode 100644 src/Main/FatalErrorHandler.cpp create mode 100644 src/Main/FatalErrorHandler.h create mode 100644 src/Main/FavoriteVolume.cpp create mode 100644 src/Main/FavoriteVolume.h create mode 100644 src/Main/Forms/AboutDialog.cpp create mode 100644 src/Main/Forms/AboutDialog.h create mode 100644 src/Main/Forms/BenchmarkDialog.cpp create mode 100644 src/Main/Forms/BenchmarkDialog.h create mode 100644 src/Main/Forms/ChangePasswordDialog.cpp create mode 100644 src/Main/Forms/ChangePasswordDialog.h create mode 100644 src/Main/Forms/DeviceSelectionDialog.cpp create mode 100644 src/Main/Forms/DeviceSelectionDialog.h create mode 100644 src/Main/Forms/EncryptionOptionsWizardPage.cpp create mode 100644 src/Main/Forms/EncryptionOptionsWizardPage.h create mode 100644 src/Main/Forms/EncryptionTestDialog.cpp create mode 100644 src/Main/Forms/EncryptionTestDialog.h create mode 100644 src/Main/Forms/FavoriteVolumesDialog.cpp create mode 100644 src/Main/Forms/FavoriteVolumesDialog.h create mode 100644 src/Main/Forms/Forms.cpp create mode 100644 src/Main/Forms/Forms.h create mode 100644 src/Main/Forms/InfoWizardPage.cpp create mode 100644 src/Main/Forms/InfoWizardPage.h create mode 100644 src/Main/Forms/KeyfileGeneratorDialog.cpp create mode 100644 src/Main/Forms/KeyfileGeneratorDialog.h create mode 100644 src/Main/Forms/KeyfilesDialog.cpp create mode 100644 src/Main/Forms/KeyfilesDialog.h create mode 100644 src/Main/Forms/KeyfilesPanel.cpp create mode 100644 src/Main/Forms/KeyfilesPanel.h create mode 100644 src/Main/Forms/LegalNoticesDialog.cpp create mode 100644 src/Main/Forms/LegalNoticesDialog.h create mode 100644 src/Main/Forms/MainFrame.cpp create mode 100644 src/Main/Forms/MainFrame.h create mode 100644 src/Main/Forms/MountOptionsDialog.cpp create mode 100644 src/Main/Forms/MountOptionsDialog.h create mode 100644 src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp create mode 100644 src/Main/Forms/NewSecurityTokenKeyfileDialog.h create mode 100644 src/Main/Forms/PreferencesDialog.cpp create mode 100644 src/Main/Forms/PreferencesDialog.h create mode 100644 src/Main/Forms/ProgressWizardPage.cpp create mode 100644 src/Main/Forms/ProgressWizardPage.h create mode 100644 src/Main/Forms/RandomPoolEnrichmentDialog.cpp create mode 100644 src/Main/Forms/RandomPoolEnrichmentDialog.h create mode 100644 src/Main/Forms/SecurityTokenKeyfilesDialog.cpp create mode 100644 src/Main/Forms/SecurityTokenKeyfilesDialog.h create mode 100644 src/Main/Forms/SelectDirectoryWizardPage.cpp create mode 100644 src/Main/Forms/SelectDirectoryWizardPage.h create mode 100644 src/Main/Forms/SingleChoiceWizardPage.h create mode 100644 src/Main/Forms/TrueCrypt.fbp create mode 100644 src/Main/Forms/VolumeCreationProgressWizardPage.cpp create mode 100644 src/Main/Forms/VolumeCreationProgressWizardPage.h create mode 100644 src/Main/Forms/VolumeCreationWizard.cpp create mode 100644 src/Main/Forms/VolumeCreationWizard.h create mode 100644 src/Main/Forms/VolumeFormatOptionsWizardPage.cpp create mode 100644 src/Main/Forms/VolumeFormatOptionsWizardPage.h create mode 100644 src/Main/Forms/VolumeLocationWizardPage.cpp create mode 100644 src/Main/Forms/VolumeLocationWizardPage.h create mode 100644 src/Main/Forms/VolumePasswordPanel.cpp create mode 100644 src/Main/Forms/VolumePasswordPanel.h create mode 100644 src/Main/Forms/VolumePasswordWizardPage.cpp create mode 100644 src/Main/Forms/VolumePasswordWizardPage.h create mode 100644 src/Main/Forms/VolumePropertiesDialog.cpp create mode 100644 src/Main/Forms/VolumePropertiesDialog.h create mode 100644 src/Main/Forms/VolumeSizeWizardPage.cpp create mode 100644 src/Main/Forms/VolumeSizeWizardPage.h create mode 100644 src/Main/Forms/WizardFrame.cpp create mode 100644 src/Main/Forms/WizardFrame.h create mode 100644 src/Main/Forms/WizardPage.h create mode 100644 src/Main/GraphicUserInterface.cpp create mode 100644 src/Main/GraphicUserInterface.h create mode 100644 src/Main/Hotkey.cpp create mode 100644 src/Main/Hotkey.h create mode 100644 src/Main/LanguageStrings.cpp create mode 100644 src/Main/LanguageStrings.h create mode 100644 src/Main/Main.h create mode 100644 src/Main/Main.make create mode 100644 src/Main/Resources.cpp create mode 100644 src/Main/Resources.h create mode 100644 src/Main/StringFormatter.cpp create mode 100644 src/Main/StringFormatter.h create mode 100644 src/Main/System.cpp create mode 100644 src/Main/System.h create mode 100644 src/Main/SystemPrecompiled.h create mode 100644 src/Main/TextUserInterface.cpp create mode 100644 src/Main/TextUserInterface.h create mode 100644 src/Main/Unix/Main.cpp create mode 100644 src/Main/UserInterface.cpp create mode 100644 src/Main/UserInterface.h create mode 100644 src/Main/UserInterfaceException.h create mode 100644 src/Main/UserInterfaceType.h create mode 100644 src/Main/UserPreferences.cpp create mode 100644 src/Main/UserPreferences.h create mode 100644 src/Main/VolumeHistory.cpp create mode 100644 src/Main/VolumeHistory.h create mode 100644 src/Main/Xml.cpp create mode 100644 src/Main/Xml.h create mode 100644 src/Makefile create mode 100644 src/Platform/Unix/Directory.cpp create mode 100644 src/Platform/Unix/File.cpp create mode 100644 src/Platform/Unix/FilesystemPath.cpp create mode 100644 src/Platform/Unix/Mutex.cpp create mode 100644 src/Platform/Unix/Pipe.cpp create mode 100644 src/Platform/Unix/Pipe.h create mode 100644 src/Platform/Unix/Poller.cpp create mode 100644 src/Platform/Unix/Poller.h create mode 100644 src/Platform/Unix/Process.cpp create mode 100644 src/Platform/Unix/Process.h create mode 100644 src/Platform/Unix/SyncEvent.cpp create mode 100644 src/Platform/Unix/System.h create mode 100644 src/Platform/Unix/SystemException.cpp create mode 100644 src/Platform/Unix/SystemInfo.cpp create mode 100644 src/Platform/Unix/SystemLog.cpp create mode 100644 src/Platform/Unix/Thread.cpp create mode 100644 src/Platform/Unix/Time.cpp create mode 100644 src/Resources/Icons/TrueCrypt-16x16.xpm create mode 100644 src/Resources/Icons/TrueCrypt-48x48.xpm create mode 100644 src/Volume/Cipher.cpp create mode 100644 src/Volume/Cipher.h create mode 100644 src/Volume/Crc32.h create mode 100644 src/Volume/EncryptionAlgorithm.cpp create mode 100644 src/Volume/EncryptionAlgorithm.h create mode 100644 src/Volume/EncryptionMode.cpp create mode 100644 src/Volume/EncryptionMode.h create mode 100644 src/Volume/EncryptionModeCBC.cpp create mode 100644 src/Volume/EncryptionModeCBC.h create mode 100644 src/Volume/EncryptionModeLRW.cpp create mode 100644 src/Volume/EncryptionModeLRW.h create mode 100644 src/Volume/EncryptionModeXTS.cpp create mode 100644 src/Volume/EncryptionModeXTS.h create mode 100644 src/Volume/EncryptionTest.cpp create mode 100644 src/Volume/EncryptionTest.h create mode 100644 src/Volume/EncryptionThreadPool.cpp create mode 100644 src/Volume/EncryptionThreadPool.h create mode 100644 src/Volume/Hash.cpp create mode 100644 src/Volume/Hash.h create mode 100644 src/Volume/Keyfile.cpp create mode 100644 src/Volume/Keyfile.h create mode 100644 src/Volume/Pkcs5Kdf.cpp create mode 100644 src/Volume/Pkcs5Kdf.h create mode 100644 src/Volume/Version.h create mode 100644 src/Volume/Volume.cpp create mode 100644 src/Volume/Volume.h create mode 100644 src/Volume/Volume.make create mode 100644 src/Volume/VolumeException.cpp create mode 100644 src/Volume/VolumeException.h create mode 100644 src/Volume/VolumeHeader.cpp create mode 100644 src/Volume/VolumeHeader.h create mode 100644 src/Volume/VolumeInfo.cpp create mode 100644 src/Volume/VolumeInfo.h create mode 100644 src/Volume/VolumeLayout.cpp create mode 100644 src/Volume/VolumeLayout.h create mode 100644 src/Volume/VolumePassword.cpp create mode 100644 src/Volume/VolumePassword.h create mode 100644 src/Volume/VolumePasswordCache.cpp create mode 100644 src/Volume/VolumePasswordCache.h create mode 100644 src/Volume/VolumeSlot.h diff --git a/src/Build/Include/Makefile.inc b/src/Build/Include/Makefile.inc new file mode 100644 index 00000000..39395e95 --- /dev/null +++ b/src/Build/Include/Makefile.inc @@ -0,0 +1,58 @@ +# +# Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +$(NAME): $(NAME).a + +clean: + @echo Cleaning $(NAME) + rm -f $(APPNAME) $(NAME).a $(OBJS) $(OBJS:.o=.d) *.gch + +%.o: %.c + @echo Compiling $($@ + +%.txt.h: %.txt + @echo Converting $($@ + +%.bmp.h: %.bmp + @echo Converting $($@ + + +# Dependencies +-include $(OBJS:.o=.d) + + +$(NAME).a: $(OBJS) + @echo Updating library $@ + $(AR) $(AFLAGS) -rcu $@ $(OBJS) + $(RANLIB) $@ diff --git a/src/Build/Resources/MacOSX/Info.plist.xml b/src/Build/Resources/MacOSX/Info.plist.xml new file mode 100644 index 00000000..29e114fa --- /dev/null +++ b/src/Build/Resources/MacOSX/Info.plist.xml @@ -0,0 +1,44 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + + CFBundleIdentifier + org.TrueCryptFoundation.TrueCrypt + + CFBundleDevelopmentRegion + English + + CFBundleExecutable + TrueCrypt + + CFBundleIconFile + TrueCrypt.icns + + CFBundleName + TrueCrypt + + CFBundlePackageType + APPL + + CFBundleSignature + TRUE + + CFBundleVersion + 0 + + CFBundleShortVersionString + _VERSION_ + + CFBundleLongVersionString + TrueCrypt _VERSION_ + + LSRequiresCarbon + + + CSResourcesFileMapped + + + diff --git a/src/Core/Core.h b/src/Core/Core.h new file mode 100644 index 00000000..37bbb986 --- /dev/null +++ b/src/Core/Core.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Core +#define TC_HEADER_Core_Core + +#include "CoreBase.h" + +namespace TrueCrypt +{ + extern auto_ptr Core; + extern auto_ptr CoreDirect; +} + +#endif // TC_HEADER_Core_Core diff --git a/src/Core/Core.make b/src/Core/Core.make new file mode 100644 index 00000000..c4a5ccf2 --- /dev/null +++ b/src/Core/Core.make @@ -0,0 +1,27 @@ +# +# Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +OBJS := +OBJS += CoreBase.o +OBJS += CoreException.o +OBJS += FatFormatter.o +OBJS += HostDevice.o +OBJS += MountOptions.o +OBJS += RandomNumberGenerator.o +OBJS += VolumeCreator.o +OBJS += Unix/CoreService.o +OBJS += Unix/CoreServiceRequest.o +OBJS += Unix/CoreServiceResponse.o +OBJS += Unix/CoreUnix.o +OBJS += Unix/$(PLATFORM)/Core$(PLATFORM).o +OBJS += Unix/$(PLATFORM)/Core$(PLATFORM).o +ifeq "$(PLATFORM)" "MacOSX" +OBJS += Unix/FreeBSD/CoreFreeBSD.o +endif + +include $(BUILD_INC)/Makefile.inc diff --git a/src/Core/CoreBase.cpp b/src/Core/CoreBase.cpp new file mode 100644 index 00000000..b615b7ff --- /dev/null +++ b/src/Core/CoreBase.cpp @@ -0,0 +1,279 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include + +#include "CoreBase.h" +#include "RandomNumberGenerator.h" +#include "Volume/Volume.h" + +namespace TrueCrypt +{ + CoreBase::CoreBase () + : DeviceChangeInProgress (false) + { + } + + CoreBase::~CoreBase () + { + } + + void CoreBase::ChangePassword (shared_ptr openVolume, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf) const + { + if ((!newPassword || newPassword->Size() < 1) && (!newKeyfiles || newKeyfiles->empty())) + throw PasswordEmpty (SRC_POS); + + if (!newPkcs5Kdf) + newPkcs5Kdf = openVolume->GetPkcs5Kdf(); + + if ((openVolume->GetHeader()->GetFlags() & TC_HEADER_FLAG_ENCRYPTED_SYSTEM) != 0 + && openVolume->GetType() == VolumeType::Hidden + && openVolume->GetPath().IsDevice()) + { + throw EncryptedSystemRequired (SRC_POS); + } + + RandomNumberGenerator::SetHash (newPkcs5Kdf->GetHash()); + + SecureBuffer newSalt (openVolume->GetSaltSize()); + SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize()); + + shared_ptr password (Keyfile::ApplyListToPassword (newKeyfiles, newPassword)); + + bool backupHeader = false; + while (true) + { + for (int i = 1; i <= SecureWipePassCount; i++) + { + if (i == SecureWipePassCount) + RandomNumberGenerator::GetData (newSalt); + else + RandomNumberGenerator::GetDataFast (newSalt); + + newPkcs5Kdf->DeriveKey (newHeaderKey, *password, newSalt); + + openVolume->ReEncryptHeader (backupHeader, newSalt, newHeaderKey, newPkcs5Kdf); + openVolume->GetFile()->Flush(); + } + + if (!openVolume->GetLayout()->HasBackupHeader() || backupHeader) + break; + + backupHeader = true; + } + } + + void CoreBase::ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf) const + { + shared_ptr volume = OpenVolume (volumePath, preserveTimestamps, password, keyfiles); + ChangePassword (volume, newPassword, newKeyfiles, newPkcs5Kdf); + } + + void CoreBase::CoalesceSlotNumberAndMountPoint (MountOptions &options) const + { + if (options.SlotNumber < GetFirstSlotNumber()) + { + if (options.MountPoint && !options.MountPoint->IsEmpty()) + options.SlotNumber = MountPointToSlotNumber (*options.MountPoint); + else + options.SlotNumber = GetFirstFreeSlotNumber(); + } + + if (!IsSlotNumberAvailable (options.SlotNumber)) +#ifdef TC_WINDOWS + throw DriveLetterUnavailable (SRC_POS); +#else + throw VolumeSlotUnavailable (SRC_POS); +#endif + if (!options.NoFilesystem && (!options.MountPoint || options.MountPoint->IsEmpty())) + options.MountPoint.reset (new DirectoryPath (SlotNumberToMountPoint (options.SlotNumber))); + } + + void CoreBase::CreateKeyfile (const FilePath &keyfilePath) const + { + SecureBuffer keyfileBuffer (VolumePassword::MaxSize); + RandomNumberGenerator::GetData (keyfileBuffer); + + File keyfile; + keyfile.Open (keyfilePath, File::CreateWrite); + keyfile.Write (keyfileBuffer); + } + + VolumeSlotNumber CoreBase::GetFirstFreeSlotNumber (VolumeSlotNumber startFrom) const + { + if (startFrom < GetFirstSlotNumber()) + startFrom = GetFirstSlotNumber(); + + set usedSlotNumbers; + + foreach_ref (const VolumeInfo &volume, GetMountedVolumes()) + usedSlotNumbers.insert (volume.SlotNumber); + + for (VolumeSlotNumber slotNumber = startFrom; slotNumber <= GetLastSlotNumber(); ++slotNumber) + { + if (usedSlotNumbers.find (slotNumber) == usedSlotNumbers.end() + && IsMountPointAvailable (SlotNumberToMountPoint (slotNumber))) + return slotNumber; + } +#ifdef TC_WINDOWS + throw DriveLetterUnavailable (SRC_POS); +#else + throw VolumeSlotUnavailable (SRC_POS); +#endif + } + + uint64 CoreBase::GetMaxHiddenVolumeSize (shared_ptr outerVolume) const + { + uint32 sectorSize = outerVolume->GetSectorSize(); + + SecureBuffer bootSectorBuffer (sectorSize); + outerVolume->ReadSectors (bootSectorBuffer, 0); + + int fatType; + byte *bootSector = bootSectorBuffer.Ptr(); + + if (memcmp (bootSector + 54, "FAT12", 5) == 0) + fatType = 12; + else if (memcmp (bootSector + 54, "FAT16", 5) == 0) + fatType = 16; + else if (memcmp (bootSector + 82, "FAT32", 5) == 0) + fatType = 32; + else + throw ParameterIncorrect (SRC_POS); + + uint32 clusterSize = bootSector[13] * sectorSize; + uint32 reservedSectorCount = Endian::Little (*(uint16 *) (bootSector + 14)); + uint32 fatCount = bootSector[16]; + + uint64 fatSectorCount; + if (fatType == 32) + fatSectorCount = Endian::Little (*(uint32 *) (bootSector + 36)); + else + fatSectorCount = Endian::Little (*(uint16 *) (bootSector + 22)); + uint64 fatSize = fatSectorCount * sectorSize; + + uint64 fatStartOffset = reservedSectorCount * sectorSize; + uint64 dataAreaOffset = reservedSectorCount * sectorSize + fatSize * fatCount; + + if (fatType < 32) + dataAreaOffset += Endian::Little (*(uint16 *) (bootSector + 17)) * 32; + + SecureBuffer sector (sectorSize); + + // Find last used cluster + for (uint64 readOffset = fatStartOffset + fatSize - sectorSize; + readOffset >= fatStartOffset; + readOffset -= sectorSize) + { + outerVolume->ReadSectors (sector, readOffset); + + for (int offset = sectorSize - 4; offset >= 0; offset -= 4) + { + if (*(uint32 *) (sector.Ptr() + offset)) + { + uint64 clusterNumber = readOffset - fatStartOffset + offset; + + if (fatType == 12) + clusterNumber = (clusterNumber * 8) / 12; + else if (fatType == 16) + clusterNumber /= 2; + else if (fatType == 32) + clusterNumber /= 4; + + uint64 maxSize = outerVolume->GetSize() - dataAreaOffset; + + // Some FAT entries may span over sector boundaries + if (maxSize >= clusterSize) + maxSize -= clusterSize; + + uint64 clusterOffset = clusterNumber * clusterSize; + if (maxSize < clusterOffset) + return 0; + + return maxSize - clusterOffset; + } + } + } + + return 0; + } + + shared_ptr CoreBase::GetMountedVolume (const VolumePath &volumePath) const + { + VolumeInfoList volumes = GetMountedVolumes (volumePath); + if (volumes.empty()) + return shared_ptr (); + else + return volumes.front(); + } + + shared_ptr CoreBase::GetMountedVolume (VolumeSlotNumber slot) const + { + foreach (shared_ptr volume, GetMountedVolumes()) + { + if (volume->SlotNumber == slot) + return volume; + } + + return shared_ptr (); + } + + bool CoreBase::IsSlotNumberAvailable (VolumeSlotNumber slotNumber) const + { + if (!IsMountPointAvailable (SlotNumberToMountPoint (slotNumber))) + return false; + + foreach_ref (const VolumeInfo &volume, GetMountedVolumes()) + { + if (volume.SlotNumber == slotNumber) + return false; + } + + return true; + } + + bool CoreBase::IsVolumeMounted (const VolumePath &volumePath) const + { + return GetMountedVolume (volumePath); + } + + shared_ptr CoreBase::OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const + { + make_shared_auto (Volume, volume); + volume->Open (*volumePath, preserveTimestamps, password, keyfiles, protection, protectionPassword, protectionKeyfiles, sharedAccessAllowed, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); + return volume; + } + + void CoreBase::RandomizeEncryptionAlgorithmKey (shared_ptr encryptionAlgorithm) const + { + SecureBuffer eaKey (encryptionAlgorithm->GetKeySize()); + RandomNumberGenerator::GetData (eaKey); + encryptionAlgorithm->SetKey (eaKey); + + SecureBuffer modeKey (encryptionAlgorithm->GetMode()->GetKeySize()); + RandomNumberGenerator::GetData (modeKey); + encryptionAlgorithm->GetMode()->SetKey (modeKey); + } + + void CoreBase::ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, shared_ptr keyfiles) const + { + shared_ptr pkcs5Kdf = header->GetPkcs5Kdf(); + + RandomNumberGenerator::SetHash (pkcs5Kdf->GetHash()); + + SecureBuffer newSalt (header->GetSaltSize()); + SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize()); + + shared_ptr passwordKey (Keyfile::ApplyListToPassword (keyfiles, password)); + + RandomNumberGenerator::GetData (newSalt); + pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, newSalt); + + header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, pkcs5Kdf); + } +} diff --git a/src/Core/CoreBase.h b/src/Core/CoreBase.h new file mode 100644 index 00000000..d99420ab --- /dev/null +++ b/src/Core/CoreBase.h @@ -0,0 +1,99 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreBase +#define TC_HEADER_Core_CoreBase + +#include "Platform/Platform.h" +#include "Platform/Functor.h" +#include "Platform/User.h" +#include "Common/Crypto.h" +#include "Volume/Keyfile.h" +#include "Volume/VolumeInfo.h" +#include "Volume/Volume.h" +#include "Volume/VolumePassword.h" +#include "CoreException.h" +#include "HostDevice.h" +#include "MountOptions.h" + +namespace TrueCrypt +{ + class CoreBase + { + public: + virtual ~CoreBase (); + + virtual void ChangePassword (shared_ptr openVolume, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf = shared_ptr ()) const; + virtual void ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf = shared_ptr ()) const; + virtual void CheckFilesystem (shared_ptr mountedVolume, bool repair = false) const = 0; + virtual void CoalesceSlotNumberAndMountPoint (MountOptions &options) const; + virtual void CreateKeyfile (const FilePath &keyfilePath) const; + virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const = 0; + virtual shared_ptr DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false) = 0; + virtual bool FilesystemSupportsLargeFiles (const FilePath &filePath) const = 0; + virtual DirectoryPath GetDeviceMountPoint (const DevicePath &devicePath) const = 0; + virtual uint32 GetDeviceSectorSize (const DevicePath &devicePath) const = 0; + virtual uint64 GetDeviceSize (const DevicePath &devicePath) const = 0; + virtual VolumeSlotNumber GetFirstFreeSlotNumber (VolumeSlotNumber startFrom = 0) const; + virtual VolumeSlotNumber GetFirstSlotNumber () const { return 1; } + virtual VolumeSlotNumber GetLastSlotNumber () const { return 64; } + virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const = 0; + virtual FilePath GetApplicationExecutablePath () const { return ApplicationExecutablePath; } + virtual uint64 GetMaxHiddenVolumeSize (shared_ptr outerVolume) const; + virtual int GetOSMajorVersion () const = 0; + virtual int GetOSMinorVersion () const = 0; + virtual shared_ptr GetMountedVolume (const VolumePath &volumePath) const; + virtual shared_ptr GetMountedVolume (VolumeSlotNumber slot) const; + virtual VolumeInfoList GetMountedVolumes (const VolumePath &volumePath = VolumePath()) const = 0; + virtual bool HasAdminPrivileges () const = 0; + virtual void Init () { } + virtual bool IsDeviceChangeInProgress () const { return DeviceChangeInProgress; } + virtual bool IsDevicePresent (const DevicePath &device) const = 0; + virtual bool IsInPortableMode () const = 0; + virtual bool IsMountPointAvailable (const DirectoryPath &mountPoint) const = 0; + virtual bool IsOSVersion (int major, int minor) const = 0; + virtual bool IsOSVersionLower (int major, int minor) const = 0; + virtual bool IsPasswordCacheEmpty () const = 0; + virtual bool IsSlotNumberAvailable (VolumeSlotNumber slotNumber) const; + virtual bool IsSlotNumberValid (VolumeSlotNumber slotNumber) const { return slotNumber >= GetFirstSlotNumber() && slotNumber <= GetLastSlotNumber(); } + virtual bool IsVolumeMounted (const VolumePath &volumePath) const; + virtual VolumeSlotNumber MountPointToSlotNumber (const DirectoryPath &mountPoint) const = 0; + virtual shared_ptr MountVolume (MountOptions &options) = 0; + virtual shared_ptr OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const; + virtual void RandomizeEncryptionAlgorithmKey (shared_ptr encryptionAlgorithm) const; + virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, shared_ptr keyfiles) const; + virtual void SetAdminPasswordCallback (shared_ptr functor) { } + virtual void SetApplicationExecutablePath (const FilePath &path) { ApplicationExecutablePath = path; } + virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0; + virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const = 0; + virtual void WipePasswordCache () const = 0; + + Event VolumeDismountedEvent; + Event VolumeMountedEvent; + Event WarningEvent; + + protected: + CoreBase (); + + static const int SecureWipePassCount = PRAND_DISK_WIPE_PASSES; + bool DeviceChangeInProgress; + FilePath ApplicationExecutablePath; + + private: + CoreBase (const CoreBase &); + CoreBase &operator= (const CoreBase &); + }; + + struct VolumeEventArgs : EventArgs + { + VolumeEventArgs (shared_ptr volume) : mVolume (volume) { } + shared_ptr mVolume; + }; +} + +#endif // TC_HEADER_Core_CoreBase diff --git a/src/Core/CoreException.cpp b/src/Core/CoreException.cpp new file mode 100644 index 00000000..da939a8d --- /dev/null +++ b/src/Core/CoreException.cpp @@ -0,0 +1,29 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "CoreException.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + void ElevationFailed::Deserialize (shared_ptr stream) + { + ExecutedProcessFailed::Deserialize (stream); + } + + void ElevationFailed::Serialize (shared_ptr stream) const + { + ExecutedProcessFailed::Serialize (stream); + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (CoreException); +} diff --git a/src/Core/CoreException.h b/src/Core/CoreException.h new file mode 100644 index 00000000..40ffbcea --- /dev/null +++ b/src/Core/CoreException.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreException +#define TC_HEADER_Core_CoreException + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + struct ElevationFailed : public ExecutedProcessFailed + { + ElevationFailed () { } + ElevationFailed (const string &message, const string &command, int exitCode, const string &errorOutput) + : ExecutedProcessFailed (message, command, exitCode, errorOutput) { } + TC_SERIALIZABLE_EXCEPTION (ElevationFailed); + }; + + TC_EXCEPTION_DECL (RootDeviceUnavailable, SystemException); + +#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception) + +#undef TC_EXCEPTION_SET +#define TC_EXCEPTION_SET \ + TC_EXCEPTION_NODECL (ElevationFailed); \ + TC_EXCEPTION_NODECL (RootDeviceUnavailable); \ + TC_EXCEPTION (DriveLetterUnavailable); \ + TC_EXCEPTION (DriverError); \ + TC_EXCEPTION (EncryptedSystemRequired); \ + TC_EXCEPTION (HigherFuseVersionRequired); \ + TC_EXCEPTION (KernelCryptoServiceTestFailed); \ + TC_EXCEPTION (LoopDeviceSetupFailed); \ + TC_EXCEPTION (MountPointRequired); \ + TC_EXCEPTION (MountPointUnavailable); \ + TC_EXCEPTION (NoDriveLetterAvailable); \ + TC_EXCEPTION (TemporaryDirectoryFailure); \ + TC_EXCEPTION (UnsupportedSectorSizeHiddenVolumeProtection); \ + TC_EXCEPTION (UnsupportedSectorSizeNoKernelCrypto); \ + TC_EXCEPTION (VolumeAlreadyMounted); \ + TC_EXCEPTION (VolumeSlotUnavailable); + + TC_EXCEPTION_SET; + +#undef TC_EXCEPTION +} + +#endif // TC_HEADER_Core_CoreException diff --git a/src/Core/FatFormatter.cpp b/src/Core/FatFormatter.cpp new file mode 100644 index 00000000..ba69df61 --- /dev/null +++ b/src/Core/FatFormatter.cpp @@ -0,0 +1,384 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of Encryption for the Masses 2.02a, which is + Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License + Agreement for Encryption for the Masses'. Modifications and additions to + the original source code (contained in this file) and all other portions + of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association + and are governed by the TrueCrypt License 3.0 the full text of which is + contained in the file License.txt included in TrueCrypt binary and source + code distribution packages. */ + +#include "Common/Tcdefs.h" +#include "Platform/Platform.h" +#include "Volume/VolumeHeader.h" +#include "FatFormatter.h" +#include "RandomNumberGenerator.h" + +namespace TrueCrypt +{ + struct fatparams + { + char volume_name[11]; + uint32 num_sectors; /* total number of sectors */ + uint32 cluster_count; /* number of clusters */ + uint32 size_root_dir; /* size of the root directory in bytes */ + uint32 size_fat; /* size of FAT */ + uint32 fats; + uint32 media; + uint32 cluster_size; + uint32 fat_length; + uint16 dir_entries; + uint16 sector_size; + uint32 hidden; + uint16 reserved; + uint16 sectors; + uint32 total_sect; + + uint16 heads; + uint16 secs_track; + + }; + + static void GetFatParams (fatparams * ft) + { + uint64 volumeSize = (uint64) ft->num_sectors * ft->sector_size; + unsigned int fatsecs; + + if(ft->cluster_size == 0) // 'Default' cluster size + { + uint32 clusterSize; + + // Determine optimal cluster size to minimize FAT size (mounting delay), maximize number of files, keep 4 KB alignment, etc. + if (volumeSize >= 2 * BYTES_PER_TB) + clusterSize = 256 * BYTES_PER_KB; + else if (volumeSize >= 512 * BYTES_PER_GB) + clusterSize = 128 * BYTES_PER_KB; + else if (volumeSize >= 128 * BYTES_PER_GB) + clusterSize = 64 * BYTES_PER_KB; + else if (volumeSize >= 64 * BYTES_PER_GB) + clusterSize = 32 * BYTES_PER_KB; + else if (volumeSize >= 32 * BYTES_PER_GB) + clusterSize = 16 * BYTES_PER_KB; + else if (volumeSize >= 16 * BYTES_PER_GB) + clusterSize = 8 * BYTES_PER_KB; + else if (volumeSize >= 512 * BYTES_PER_MB) + clusterSize = 4 * BYTES_PER_KB; + else if (volumeSize >= 256 * BYTES_PER_MB) + clusterSize = 2 * BYTES_PER_KB; + else if (volumeSize >= 1 * BYTES_PER_MB) + clusterSize = 1 * BYTES_PER_KB; + else + clusterSize = 512; + + ft->cluster_size = clusterSize / ft->sector_size; + + if (ft->cluster_size == 0) + ft->cluster_size = 1; + + if (ft->cluster_size * ft->sector_size > TC_MAX_FAT_CLUSTER_SIZE) + ft->cluster_size = TC_MAX_FAT_CLUSTER_SIZE / ft->sector_size; + + if (ft->cluster_size > 128) + ft->cluster_size = 128; + } + + if (volumeSize <= TC_MAX_FAT_CLUSTER_SIZE * 4) + ft->cluster_size = 1; + + // Geometry always set to SECTORS/1/1 + ft->secs_track = 1; + ft->heads = 1; + + ft->dir_entries = 512; + ft->fats = 2; + ft->media = 0xf8; + ft->hidden = 0; + + ft->size_root_dir = ft->dir_entries * 32; + + // FAT12 + ft->size_fat = 12; + ft->reserved = 2; + fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved; + ft->cluster_count = (int) (((int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size)); + ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + ft->sector_size - 1) / ft->sector_size; + + if (ft->cluster_count >= 4085) // FAT16 + { + ft->size_fat = 16; + ft->reserved = 2; + fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved; + ft->cluster_count = (int) (((int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size)); + ft->fat_length = (ft->cluster_count * 2 + ft->sector_size - 1) / ft->sector_size; + } + + if(ft->cluster_count >= 65525) // FAT32 + { + ft->size_fat = 32; + ft->reserved = 32 - 1; + + do + { + ft->reserved++; + + fatsecs = ft->num_sectors - ft->reserved; + ft->size_root_dir = ft->cluster_size * ft->sector_size; + ft->cluster_count = (int) (((int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size)); + ft->fat_length = (ft->cluster_count * 4 + ft->sector_size - 1) / ft->sector_size; + + // Align data area on TC_MAX_VOLUME_SECTOR_SIZE + + } while (ft->sector_size == TC_SECTOR_SIZE_LEGACY + && (ft->reserved * ft->sector_size + ft->fat_length * ft->fats * ft->sector_size) % TC_MAX_VOLUME_SECTOR_SIZE != 0); + } + + ft->cluster_count -= ft->fat_length * ft->fats / ft->cluster_size; + + if (ft->num_sectors >= 65536 || ft->size_fat == 32) + { + ft->sectors = 0; + ft->total_sect = ft->num_sectors; + } + else + { + ft->sectors = (uint16) ft->num_sectors; + ft->total_sect = 0; + } + } + + static void PutBoot (fatparams * ft, byte *boot, uint32 volumeId) + { + int cnt = 0; + + boot[cnt++] = 0xeb; /* boot jump */ + boot[cnt++] = 0x3c; + boot[cnt++] = 0x90; + memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */ + cnt += 8; + *(int16 *)(boot + cnt) = Endian::Little (ft->sector_size); /* bytes per sector */ + cnt += 2; + boot[cnt++] = (int8) ft->cluster_size; /* sectors per cluster */ + *(int16 *)(boot + cnt) = Endian::Little (ft->reserved); /* reserved sectors */ + cnt += 2; + boot[cnt++] = (int8) ft->fats; /* 2 fats */ + + if(ft->size_fat == 32) + { + boot[cnt++] = 0x00; + boot[cnt++] = 0x00; + } + else + { + *(int16 *)(boot + cnt) = Endian::Little (ft->dir_entries); /* 512 root entries */ + cnt += 2; + } + + *(int16 *)(boot + cnt) = Endian::Little (ft->sectors); /* # sectors */ + cnt += 2; + boot[cnt++] = (int8) ft->media; /* media byte */ + + if(ft->size_fat == 32) + { + boot[cnt++] = 0x00; + boot[cnt++] = 0x00; + } + else + { + *(uint16 *)(boot + cnt) = Endian::Little ((uint16) ft->fat_length); /* fat size */ + cnt += 2; + } + + *(int16 *)(boot + cnt) = Endian::Little (ft->secs_track); /* # sectors per track */ + cnt += 2; + *(int16 *)(boot + cnt) = Endian::Little (ft->heads); /* # heads */ + cnt += 2; + *(int32 *)(boot + cnt) = Endian::Little (ft->hidden); /* # hidden sectors */ + cnt += 4; + *(int32 *)(boot + cnt) = Endian::Little (ft->total_sect); /* # huge sectors */ + cnt += 4; + + if(ft->size_fat == 32) + { + *(int32 *)(boot + cnt) = Endian::Little (ft->fat_length); cnt += 4; /* fat size 32 */ + boot[cnt++] = 0x00; /* ExtFlags */ + boot[cnt++] = 0x00; + boot[cnt++] = 0x00; /* FSVer */ + boot[cnt++] = 0x00; + boot[cnt++] = 0x02; /* RootClus */ + boot[cnt++] = 0x00; + boot[cnt++] = 0x00; + boot[cnt++] = 0x00; + boot[cnt++] = 0x01; /* FSInfo */ + boot[cnt++] = 0x00; + boot[cnt++] = 0x06; /* BkBootSec */ + boot[cnt++] = 0x00; + memset(boot+cnt, 0, 12); cnt+=12; /* Reserved */ + } + + boot[cnt++] = 0x00; /* drive number */ // FIXED 80 > 00 + boot[cnt++] = 0x00; /* reserved */ + boot[cnt++] = 0x29; /* boot sig */ + + *(int32 *)(boot + cnt) = volumeId; + cnt += 4; + + memcpy (boot + cnt, ft->volume_name, 11); /* vol title */ + cnt += 11; + + switch(ft->size_fat) /* filesystem type */ + { + case 12: memcpy (boot + cnt, "FAT12 ", 8); break; + case 16: memcpy (boot + cnt, "FAT16 ", 8); break; + case 32: memcpy (boot + cnt, "FAT32 ", 8); break; + } + cnt += 8; + + memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */ + cnt += ft->size_fat==32 ? 420:448; + boot[cnt++] = 0x55; + boot[cnt++] = 0xaa; /* boot sig */ + } + + + /* FAT32 FSInfo */ + static void PutFSInfo (byte *sector, fatparams *ft) + { + memset (sector, 0, ft->sector_size); + sector[3] = 0x41; /* LeadSig */ + sector[2] = 0x61; + sector[1] = 0x52; + sector[0] = 0x52; + sector[484+3] = 0x61; /* StrucSig */ + sector[484+2] = 0x41; + sector[484+1] = 0x72; + sector[484+0] = 0x72; + + // Free cluster count + *(uint32 *)(sector + 488) = Endian::Little (ft->cluster_count - ft->size_root_dir / ft->sector_size / ft->cluster_size); + + // Next free cluster + *(uint32 *)(sector + 492) = Endian::Little ((uint32) 2); + + sector[508+3] = 0xaa; /* TrailSig */ + sector[508+2] = 0x55; + sector[508+1] = 0x00; + sector[508+0] = 0x00; + } + + void FatFormatter::Format (WriteSectorCallback &writeSector, uint64 deviceSize, uint32 clusterSize, uint32 sectorSize) + { + fatparams fatParams; + +#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF +#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF +#endif + fatParams.sector_size = (uint16) sectorSize; + + if (deviceSize / fatParams.sector_size > 0xffffFFFF) + throw ParameterIncorrect (SRC_POS); + + fatParams.num_sectors = (uint32) (deviceSize / fatParams.sector_size); + fatParams.cluster_size = clusterSize / fatParams.sector_size; + memcpy (fatParams.volume_name, "NO NAME ", 11); + GetFatParams (&fatParams); + fatparams *ft = &fatParams; + + SecureBuffer sector (ft->sector_size); + uint32 sectorNumber = 0; + + /* Write the data area */ + + sector.Zero(); + + uint32 volumeId; + RandomNumberGenerator::GetDataFast (BufferPtr ((byte *) &volumeId, sizeof (volumeId))); + + PutBoot (ft, (byte *) sector, volumeId); + writeSector (sector); ++sectorNumber; + + /* fat32 boot area */ + if (ft->size_fat == 32) + { + /* fsinfo */ + PutFSInfo((byte *) sector, ft); + writeSector (sector); ++sectorNumber; + + /* reserved */ + while (sectorNumber < 6) + { + sector.Zero(); + sector[508+3] = 0xaa; /* TrailSig */ + sector[508+2] = 0x55; + writeSector (sector); ++sectorNumber; + } + + /* bootsector backup */ + sector.Zero(); + PutBoot (ft, (byte *) sector, volumeId); + writeSector (sector); ++sectorNumber; + + PutFSInfo((byte *) sector, ft); + writeSector (sector); ++sectorNumber; + } + + /* reserved */ + while (sectorNumber < (uint32)ft->reserved) + { + sector.Zero(); + writeSector (sector); ++sectorNumber; + } + + /* write fat */ + for (uint32 x = 1; x <= ft->fats; x++) + { + for (uint32 n = 0; n < ft->fat_length; n++) + { + sector.Zero(); + + if (n == 0) + { + byte fat_sig[12]; + if (ft->size_fat == 32) + { + fat_sig[0] = (byte) ft->media; + fat_sig[1] = fat_sig[2] = 0xff; + fat_sig[3] = 0x0f; + fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff; + fat_sig[7] = 0x0f; + fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff; + fat_sig[11] = 0x0f; + memcpy (sector, fat_sig, 12); + } + else if (ft->size_fat == 16) + { + fat_sig[0] = (byte) ft->media; + fat_sig[1] = 0xff; + fat_sig[2] = 0xff; + fat_sig[3] = 0xff; + memcpy (sector, fat_sig, 4); + } + else if (ft->size_fat == 12) + { + fat_sig[0] = (byte) ft->media; + fat_sig[1] = 0xff; + fat_sig[2] = 0xff; + fat_sig[3] = 0x00; + memcpy (sector, fat_sig, 4); + } + } + + if (!writeSector (sector)) + return; + } + } + + /* write rootdir */ + for (uint32 x = 0; x < ft->size_root_dir / ft->sector_size; x++) + { + sector.Zero(); + if (!writeSector (sector)) + return; + } + } +} diff --git a/src/Core/FatFormatter.h b/src/Core/FatFormatter.h new file mode 100644 index 00000000..47702190 --- /dev/null +++ b/src/Core/FatFormatter.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_FatFormatter +#define TC_HEADER_Core_FatFormatter + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + class FatFormatter + { + public: + struct WriteSectorCallback + { + virtual ~WriteSectorCallback () { } + virtual bool operator() (const BufferPtr §or) = 0; + }; + + static void Format (WriteSectorCallback &writeSector, uint64 deviceSize, uint32 clusterSize, uint32 sectorSize); + }; +} + +#endif // TC_HEADER_Core_FatFormatter diff --git a/src/Core/HostDevice.cpp b/src/Core/HostDevice.cpp new file mode 100644 index 00000000..0147d568 --- /dev/null +++ b/src/Core/HostDevice.cpp @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "HostDevice.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + void HostDevice::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + MountPoint = sr.DeserializeWString ("MountPoint"); + sr.Deserialize ("Name", Name); + Path = sr.DeserializeWString ("Path"); + sr.Deserialize ("Removable", Removable); + sr.Deserialize ("Size", Size); + sr.Deserialize ("SystemNumber", SystemNumber); + + uint32 partitionCount; + sr.Deserialize ("Partitions", partitionCount); + for (uint32 i = 0; i < partitionCount; i++) + Partitions.push_back (Serializable::DeserializeNew (stream)); + } + + void HostDevice::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("MountPoint", wstring (MountPoint)); + sr.Serialize ("Name", Name); + sr.Serialize ("Path", wstring (Path)); + sr.Serialize ("Removable", Removable); + sr.Serialize ("Size", Size); + sr.Serialize ("SystemNumber", SystemNumber); + + sr.Serialize ("Partitions", (uint32) Partitions.size()); + foreach_ref (const HostDevice &partition, Partitions) + partition.Serialize (stream); + } + + TC_SERIALIZER_FACTORY_ADD_CLASS (HostDevice); +} diff --git a/src/Core/HostDevice.h b/src/Core/HostDevice.h new file mode 100644 index 00000000..227dc241 --- /dev/null +++ b/src/Core/HostDevice.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_HostDevice +#define TC_HEADER_Core_HostDevice + +#include "Platform/Platform.h" +#include "Platform/Serializable.h" + +namespace TrueCrypt +{ + struct HostDevice; + typedef list < shared_ptr > HostDeviceList; + + struct HostDevice : public Serializable + { + HostDevice () + : Removable (false), + Size (0) + { + } + + virtual ~HostDevice () + { + } + + TC_SERIALIZABLE (HostDevice); + + DirectoryPath MountPoint; + wstring Name; + DevicePath Path; + bool Removable; + uint64 Size; + uint32 SystemNumber; + + HostDeviceList Partitions; + }; +} + +#endif // TC_HEADER_Core_HostDevice diff --git a/src/Core/MountOptions.cpp b/src/Core/MountOptions.cpp new file mode 100644 index 00000000..04187311 --- /dev/null +++ b/src/Core/MountOptions.cpp @@ -0,0 +1,129 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "MountOptions.h" +#include "Platform/MemoryStream.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + void MountOptions::CopyFrom (const MountOptions &other) + { +#define TC_CLONE(NAME) NAME = other.NAME +#define TC_CLONE_SHARED(TYPE,NAME) NAME = other.NAME ? make_shared (*other.NAME) : shared_ptr () + + TC_CLONE (CachePassword); + TC_CLONE (FilesystemOptions); + TC_CLONE (FilesystemType); + TC_CLONE_SHARED (KeyfileList, Keyfiles); + TC_CLONE_SHARED (DirectoryPath, MountPoint); + TC_CLONE (NoFilesystem); + TC_CLONE (NoHardwareCrypto); + TC_CLONE (NoKernelCrypto); + TC_CLONE_SHARED (VolumePassword, Password); + TC_CLONE_SHARED (VolumePath, Path); + TC_CLONE (PartitionInSystemEncryptionScope); + TC_CLONE (PreserveTimestamps); + TC_CLONE (Protection); + TC_CLONE_SHARED (VolumePassword, ProtectionPassword); + TC_CLONE_SHARED (KeyfileList, ProtectionKeyfiles); + TC_CLONE (Removable); + TC_CLONE (SharedAccessAllowed); + TC_CLONE (SlotNumber); + TC_CLONE (UseBackupHeaders); + } + + void MountOptions::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + + sr.Deserialize ("CachePassword", CachePassword); + sr.Deserialize ("FilesystemOptions", FilesystemOptions); + sr.Deserialize ("FilesystemType", FilesystemType); + + Keyfiles = Keyfile::DeserializeList (stream, "Keyfiles"); + + if (!sr.DeserializeBool ("MountPointNull")) + MountPoint.reset (new DirectoryPath (sr.DeserializeWString ("MountPoint"))); + else + MountPoint.reset(); + + sr.Deserialize ("NoFilesystem", NoFilesystem); + sr.Deserialize ("NoHardwareCrypto", NoHardwareCrypto); + sr.Deserialize ("NoKernelCrypto", NoKernelCrypto); + + if (!sr.DeserializeBool ("PasswordNull")) + Password = Serializable::DeserializeNew (stream); + else + Password.reset(); + + if (!sr.DeserializeBool ("PathNull")) + Path.reset (new VolumePath (sr.DeserializeWString ("Path"))); + else + Path.reset(); + + sr.Deserialize ("PartitionInSystemEncryptionScope", PartitionInSystemEncryptionScope); + sr.Deserialize ("PreserveTimestamps", PreserveTimestamps); + + Protection = static_cast (sr.DeserializeInt32 ("Protection")); + + if (!sr.DeserializeBool ("ProtectionPasswordNull")) + ProtectionPassword = Serializable::DeserializeNew (stream); + else + ProtectionPassword.reset(); + + ProtectionKeyfiles = Keyfile::DeserializeList (stream, "ProtectionKeyfiles"); + sr.Deserialize ("Removable", Removable); + sr.Deserialize ("SharedAccessAllowed", SharedAccessAllowed); + sr.Deserialize ("SlotNumber", SlotNumber); + sr.Deserialize ("UseBackupHeaders", UseBackupHeaders); + } + + void MountOptions::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + + sr.Serialize ("CachePassword", CachePassword); + sr.Serialize ("FilesystemOptions", FilesystemOptions); + sr.Serialize ("FilesystemType", FilesystemType); + Keyfile::SerializeList (stream, "Keyfiles", Keyfiles); + + sr.Serialize ("MountPointNull", MountPoint == nullptr); + if (MountPoint) + sr.Serialize ("MountPoint", wstring (*MountPoint)); + + sr.Serialize ("NoFilesystem", NoFilesystem); + sr.Serialize ("NoHardwareCrypto", NoHardwareCrypto); + sr.Serialize ("NoKernelCrypto", NoKernelCrypto); + + sr.Serialize ("PasswordNull", Password == nullptr); + if (Password) + Password->Serialize (stream); + + sr.Serialize ("PathNull", Path == nullptr); + if (Path) + sr.Serialize ("Path", wstring (*Path)); + + sr.Serialize ("PartitionInSystemEncryptionScope", PartitionInSystemEncryptionScope); + sr.Serialize ("PreserveTimestamps", PreserveTimestamps); + sr.Serialize ("Protection", static_cast (Protection)); + + sr.Serialize ("ProtectionPasswordNull", ProtectionPassword == nullptr); + if (ProtectionPassword) + ProtectionPassword->Serialize (stream); + + Keyfile::SerializeList (stream, "ProtectionKeyfiles", ProtectionKeyfiles); + sr.Serialize ("Removable", Removable); + sr.Serialize ("SharedAccessAllowed", SharedAccessAllowed); + sr.Serialize ("SlotNumber", SlotNumber); + sr.Serialize ("UseBackupHeaders", UseBackupHeaders); + } + + TC_SERIALIZER_FACTORY_ADD_CLASS (MountOptions); +} diff --git a/src/Core/MountOptions.h b/src/Core/MountOptions.h new file mode 100644 index 00000000..23fc7ca2 --- /dev/null +++ b/src/Core/MountOptions.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_MountOptions +#define TC_HEADER_Core_MountOptions + +#include "Platform/Serializable.h" +#include "Volume/Keyfile.h" +#include "Volume/Volume.h" +#include "Volume/VolumeSlot.h" +#include "Volume/VolumePassword.h" + +namespace TrueCrypt +{ + struct MountOptions : public Serializable + { + MountOptions () + : + CachePassword (false), + NoFilesystem (false), + NoHardwareCrypto (false), + NoKernelCrypto (false), + PartitionInSystemEncryptionScope (false), + PreserveTimestamps (true), + Protection (VolumeProtection::None), + Removable (false), + SharedAccessAllowed (false), + SlotNumber (0), + UseBackupHeaders (false) + { + } + + MountOptions (const MountOptions &other) { CopyFrom (other); } + virtual ~MountOptions () { } + + MountOptions &operator= (const MountOptions &other) { CopyFrom (other); return *this; } + + TC_SERIALIZABLE (MountOptions); + + bool CachePassword; + wstring FilesystemOptions; + wstring FilesystemType; + shared_ptr Keyfiles; + shared_ptr MountPoint; + bool NoFilesystem; + bool NoHardwareCrypto; + bool NoKernelCrypto; + shared_ptr Password; + bool PartitionInSystemEncryptionScope; + shared_ptr Path; + bool PreserveTimestamps; + VolumeProtection::Enum Protection; + shared_ptr ProtectionPassword; + shared_ptr ProtectionKeyfiles; + bool Removable; + bool SharedAccessAllowed; + VolumeSlotNumber SlotNumber; + bool UseBackupHeaders; + + protected: + void CopyFrom (const MountOptions &other); + }; +} + +#endif // TC_HEADER_Core_MountOptions diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp new file mode 100644 index 00000000..a010e7c6 --- /dev/null +++ b/src/Core/RandomNumberGenerator.cpp @@ -0,0 +1,213 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_WINDOWS +#include +#include +#include +#endif + +#include "RandomNumberGenerator.h" +#include "Volume/Crc32.h" + +namespace TrueCrypt +{ + void RandomNumberGenerator::AddSystemDataToPool (bool fast) + { + SecureBuffer buffer (PoolSize); + +#ifdef TC_WINDOWS +#ifndef DEBUG + throw NotImplemented (SRC_POS); +#endif +#else + int urandom = open ("/dev/urandom", O_RDONLY); + throw_sys_sub_if (urandom == -1, L"/dev/urandom"); + finally_do_arg (int, urandom, { close (finally_arg); }); + + throw_sys_sub_if (read (urandom, buffer, buffer.Size()) == -1, L"/dev/urandom"); + AddToPool (buffer); + + if (!fast) + { + // Read all bytes available in /dev/random up to buffer size + int random = open ("/dev/random", O_RDONLY | O_NONBLOCK); + throw_sys_sub_if (random == -1, L"/dev/random"); + finally_do_arg (int, random, { close (finally_arg); }); + + throw_sys_sub_if (read (random, buffer, buffer.Size()) == -1 && errno != EAGAIN, L"/dev/random"); + AddToPool (buffer); + } +#endif + } + + void RandomNumberGenerator::AddToPool (const ConstBufferPtr &data) + { + if (!Running) + throw NotInitialized (SRC_POS); + + ScopeLock lock (AccessMutex); + + for (size_t i = 0; i < data.Size(); ++i) + { + Pool[WriteOffset++] += data[i]; + + if (WriteOffset >= PoolSize) + WriteOffset = 0; + + if (++BytesAddedSincePoolHashMix >= MaxBytesAddedBeforePoolHashMix) + HashMixPool(); + } + } + + void RandomNumberGenerator::GetData (const BufferPtr &buffer, bool fast) + { + if (!Running) + throw NotInitialized (SRC_POS); + + if (buffer.Size() > PoolSize) + throw ParameterIncorrect (SRC_POS); + + ScopeLock lock (AccessMutex); + + // Poll system for data + AddSystemDataToPool (fast); + HashMixPool(); + + // Transfer bytes from pool to output buffer + for (size_t i = 0; i < buffer.Size(); ++i) + { + buffer[i] += Pool[ReadOffset++]; + + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } + + // Invert and mix the pool + for (size_t i = 0; i < Pool.Size(); ++i) + { + Pool[i] = ~Pool[i]; + } + + AddSystemDataToPool (true); + HashMixPool(); + + // XOR the current pool content into the output buffer to prevent pool state leaks + for (size_t i = 0; i < buffer.Size(); ++i) + { + buffer[i] ^= Pool[ReadOffset++]; + + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } + } + + shared_ptr RandomNumberGenerator::GetHash () + { + ScopeLock lock (AccessMutex); + return PoolHash; + } + + void RandomNumberGenerator::HashMixPool () + { + BytesAddedSincePoolHashMix = 0; + + for (size_t poolPos = 0; poolPos < Pool.Size(); ) + { + // Compute the message digest of the entire pool using the selected hash function + SecureBuffer digest (PoolHash->GetDigestSize()); + PoolHash->ProcessData (Pool); + PoolHash->GetDigest (digest); + + // Add the message digest to the pool + for (size_t digestPos = 0; digestPos < digest.Size() && poolPos < Pool.Size(); ++digestPos) + { + Pool[poolPos++] += digest[digestPos]; + } + } + } + + void RandomNumberGenerator::SetHash (shared_ptr hash) + { + ScopeLock lock (AccessMutex); + PoolHash = hash; + } + + void RandomNumberGenerator::Start () + { + ScopeLock lock (AccessMutex); + + if (IsRunning()) + return; + + BytesAddedSincePoolHashMix = 0; + ReadOffset = 0; + WriteOffset = 0; + Running = true; + EnrichedByUser = false; + + Pool.Allocate (PoolSize); + Test(); + + if (!PoolHash) + { + // First hash algorithm is the default one + PoolHash = Hash::GetAvailableAlgorithms().front(); + } + + AddSystemDataToPool (true); + } + + void RandomNumberGenerator::Stop () + { + ScopeLock lock (AccessMutex); + + if (Pool.IsAllocated()) + Pool.Free (); + + PoolHash.reset(); + + EnrichedByUser = false; + Running = false; + } + + void RandomNumberGenerator::Test () + { + shared_ptr origPoolHash = PoolHash; + PoolHash.reset (new Ripemd160()); + + Pool.Zero(); + Buffer buffer (1); + for (size_t i = 0; i < PoolSize * 10; ++i) + { + buffer[0] = (byte) i; + AddToPool (buffer); + } + + if (Crc32::ProcessBuffer (Pool) != 0x2de46d17) + throw TestFailed (SRC_POS); + + buffer.Allocate (PoolSize); + buffer.CopyFrom (PeekPool()); + AddToPool (buffer); + + if (Crc32::ProcessBuffer (Pool) != 0xcb88e019) + throw TestFailed (SRC_POS); + + PoolHash = origPoolHash; + } + + Mutex RandomNumberGenerator::AccessMutex; + size_t RandomNumberGenerator::BytesAddedSincePoolHashMix; + bool RandomNumberGenerator::EnrichedByUser; + SecureBuffer RandomNumberGenerator::Pool; + shared_ptr RandomNumberGenerator::PoolHash; + size_t RandomNumberGenerator::ReadOffset; + bool RandomNumberGenerator::Running = false; + size_t RandomNumberGenerator::WriteOffset; +} diff --git a/src/Core/RandomNumberGenerator.h b/src/Core/RandomNumberGenerator.h new file mode 100644 index 00000000..fb3a6917 --- /dev/null +++ b/src/Core/RandomNumberGenerator.h @@ -0,0 +1,55 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_RandomNumberGenerator +#define TC_HEADER_Core_RandomNumberGenerator + +#include "Platform/Platform.h" +#include "Volume/Hash.h" +#include "Common/Random.h" + +namespace TrueCrypt +{ + class RandomNumberGenerator + { + public: + static void AddToPool (const ConstBufferPtr &buffer); + static void GetData (const BufferPtr &buffer) { GetData (buffer, false); } + static void GetDataFast (const BufferPtr &buffer) { GetData (buffer, true); } + static shared_ptr GetHash (); + static bool IsEnrichedByUser () { return EnrichedByUser; } + static bool IsRunning () { return Running; } + static ConstBufferPtr PeekPool () { return Pool; } + static void SetEnrichedByUserStatus (bool enriched) { EnrichedByUser = enriched; } + static void SetHash (shared_ptr hash); + static void Start (); + static void Stop (); + + static const size_t PoolSize = RNG_POOL_SIZE; + + protected: + static void AddSystemDataToPool (bool fast); + static void GetData (const BufferPtr &buffer, bool fast); + static void HashMixPool (); + static void Test (); + RandomNumberGenerator (); + + static const size_t MaxBytesAddedBeforePoolHashMix = RANDMIX_BYTE_INTERVAL; + + static Mutex AccessMutex; + static size_t BytesAddedSincePoolHashMix; + static bool EnrichedByUser; + static SecureBuffer Pool; + static shared_ptr PoolHash; + static size_t ReadOffset; + static bool Running; + static size_t WriteOffset; + }; +} + +#endif // TC_HEADER_Core_RandomNumberGenerator diff --git a/src/Core/Unix/CoreService.cpp b/src/Core/Unix/CoreService.cpp new file mode 100644 index 00000000..0ec636c7 --- /dev/null +++ b/src/Core/Unix/CoreService.cpp @@ -0,0 +1,544 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "CoreService.h" +#include +#include +#include "Platform/FileStream.h" +#include "Platform/MemoryStream.h" +#include "Platform/Serializable.h" +#include "Platform/SystemLog.h" +#include "Platform/Thread.h" +#include "Platform/Unix/Poller.h" +#include "Core/Core.h" +#include "CoreUnix.h" +#include "CoreServiceRequest.h" +#include "CoreServiceResponse.h" + +namespace TrueCrypt +{ + template + auto_ptr CoreService::GetResponse () + { + auto_ptr deserializedObject (Serializable::DeserializeNew (ServiceOutputStream)); + + Exception *deserializedException = dynamic_cast (deserializedObject.get()); + if (deserializedException) + deserializedException->Throw(); + + if (dynamic_cast (deserializedObject.get()) == nullptr) + throw ParameterIncorrect (SRC_POS); + + return auto_ptr (dynamic_cast (deserializedObject.release())); + } + + void CoreService::ProcessElevatedRequests () + { + int pid = fork(); + throw_sys_if (pid == -1); + if (pid == 0) + { + try + { + int f = open ("/dev/null", 0); + throw_sys_sub_if (f == -1, "/dev/null"); + throw_sys_if (dup2 (f, STDERR_FILENO) == -1); + + // Wait for sync code + while (true) + { + byte b; + throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); + if (b != 0x00) + continue; + + throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); + if (b != 0x11) + continue; + + throw_sys_if (read (STDIN_FILENO, &b, 1) != 1); + if (b == 0x22) + break; + } + + ElevatedPrivileges = true; + ProcessRequests (STDIN_FILENO, STDOUT_FILENO); + _exit (0); + } + catch (exception &e) + { +#ifdef DEBUG + SystemLog::WriteException (e); +#endif + } + catch (...) { } + _exit (1); + } + } + + void CoreService::ProcessRequests (int inputFD, int outputFD) + { + try + { + Core = CoreDirect; + + shared_ptr inputStream (new FileStream (inputFD != -1 ? inputFD : InputPipe->GetReadFD())); + shared_ptr outputStream (new FileStream (outputFD != -1 ? outputFD : OutputPipe->GetWriteFD())); + + while (true) + { + shared_ptr request = Serializable::DeserializeNew (inputStream); + + try + { + // ExitRequest + if (dynamic_cast (request.get()) != nullptr) + { + if (ElevatedServiceAvailable) + request->Serialize (ServiceInputStream); + return; + } + + if (!ElevatedPrivileges && request->ElevateUserPrivileges) + { + if (!ElevatedServiceAvailable) + { + finally_do_arg (string *, &request->AdminPassword, { StringConverter::Erase (*finally_arg); }); + + CoreService::StartElevated (*request); + ElevatedServiceAvailable = true; + } + + request->Serialize (ServiceInputStream); + GetResponse ()->Serialize (outputStream); + continue; + } + + // CheckFilesystemRequest + CheckFilesystemRequest *checkRequest = dynamic_cast (request.get()); + if (checkRequest) + { + Core->CheckFilesystem (checkRequest->MountedVolumeInfo, checkRequest->Repair); + + CheckFilesystemResponse().Serialize (outputStream); + continue; + } + + // DismountFilesystemRequest + DismountFilesystemRequest *dismountFsRequest = dynamic_cast (request.get()); + if (dismountFsRequest) + { + Core->DismountFilesystem (dismountFsRequest->MountPoint, dismountFsRequest->Force); + + DismountFilesystemResponse().Serialize (outputStream); + continue; + } + + // DismountVolumeRequest + DismountVolumeRequest *dismountRequest = dynamic_cast (request.get()); + if (dismountRequest) + { + DismountVolumeResponse response; + response.DismountedVolumeInfo = Core->DismountVolume (dismountRequest->MountedVolumeInfo, dismountRequest->IgnoreOpenFiles, dismountRequest->SyncVolumeInfo); + response.Serialize (outputStream); + continue; + } + + // GetDeviceSectorSizeRequest + GetDeviceSectorSizeRequest *getDeviceSectorSizeRequest = dynamic_cast (request.get()); + if (getDeviceSectorSizeRequest) + { + GetDeviceSectorSizeResponse response; + response.Size = Core->GetDeviceSectorSize (getDeviceSectorSizeRequest->Path); + response.Serialize (outputStream); + continue; + } + + // GetDeviceSizeRequest + GetDeviceSizeRequest *getDeviceSizeRequest = dynamic_cast (request.get()); + if (getDeviceSizeRequest) + { + GetDeviceSizeResponse response; + response.Size = Core->GetDeviceSize (getDeviceSizeRequest->Path); + response.Serialize (outputStream); + continue; + } + + // GetHostDevicesRequest + GetHostDevicesRequest *getHostDevicesRequest = dynamic_cast (request.get()); + if (getHostDevicesRequest) + { + GetHostDevicesResponse response; + response.HostDevices = Core->GetHostDevices (getHostDevicesRequest->PathListOnly); + response.Serialize (outputStream); + continue; + } + + // MountVolumeRequest + MountVolumeRequest *mountRequest = dynamic_cast (request.get()); + if (mountRequest) + { + MountVolumeResponse ( + Core->MountVolume (*mountRequest->Options) + ).Serialize (outputStream); + + continue; + } + + // SetFileOwnerRequest + SetFileOwnerRequest *setFileOwnerRequest = dynamic_cast (request.get()); + if (setFileOwnerRequest) + { + CoreUnix *coreUnix = dynamic_cast (Core.get()); + if (!coreUnix) + throw ParameterIncorrect (SRC_POS); + + coreUnix->SetFileOwner (setFileOwnerRequest->Path, setFileOwnerRequest->Owner); + SetFileOwnerResponse().Serialize (outputStream); + continue; + } + + throw ParameterIncorrect (SRC_POS); + } + catch (Exception &e) + { + e.Serialize (outputStream); + } + catch (exception &e) + { + ExternalException (SRC_POS, StringConverter::ToExceptionString (e)).Serialize (outputStream); + } + } + } + catch (exception &e) + { +#ifdef DEBUG + SystemLog::WriteException (e); +#endif + throw; + } + } + + void CoreService::RequestCheckFilesystem (shared_ptr mountedVolume, bool repair) + { + CheckFilesystemRequest request (mountedVolume, repair); + SendRequest (request); + } + + void CoreService::RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force) + { + DismountFilesystemRequest request (mountPoint, force); + SendRequest (request); + } + + shared_ptr CoreService::RequestDismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo) + { + DismountVolumeRequest request (mountedVolume, ignoreOpenFiles, syncVolumeInfo); + return SendRequest (request)->DismountedVolumeInfo; + } + + uint32 CoreService::RequestGetDeviceSectorSize (const DevicePath &devicePath) + { + GetDeviceSectorSizeRequest request (devicePath); + return SendRequest (request)->Size; + } + + uint64 CoreService::RequestGetDeviceSize (const DevicePath &devicePath) + { + GetDeviceSizeRequest request (devicePath); + return SendRequest (request)->Size; + } + + HostDeviceList CoreService::RequestGetHostDevices (bool pathListOnly) + { + GetHostDevicesRequest request (pathListOnly); + return SendRequest (request)->HostDevices; + } + + shared_ptr CoreService::RequestMountVolume (MountOptions &options) + { + MountVolumeRequest request (&options); + return SendRequest (request)->MountedVolumeInfo; + } + + void CoreService::RequestSetFileOwner (const FilesystemPath &path, const UserId &owner) + { + SetFileOwnerRequest request (path, owner); + SendRequest (request); + } + + template + auto_ptr CoreService::SendRequest (CoreServiceRequest &request) + { + static Mutex mutex; + ScopeLock lock (mutex); + + if (request.RequiresElevation()) + { + request.ElevateUserPrivileges = true; + request.FastElevation = !ElevatedServiceAvailable; + request.ApplicationExecutablePath = Core->GetApplicationExecutablePath(); + + while (!ElevatedServiceAvailable) + { + try + { + request.Serialize (ServiceInputStream); + auto_ptr response (GetResponse ()); + ElevatedServiceAvailable = true; + return response; + } + catch (ElevationFailed &e) + { + if (!request.FastElevation) + { + ExceptionEventArgs args (e); + Core->WarningEvent.Raise (args); + } + + request.FastElevation = false; + (*AdminPasswordCallback) (request.AdminPassword); + } + } + } + + finally_do_arg (string *, &request.AdminPassword, { StringConverter::Erase (*finally_arg); }); + + request.Serialize (ServiceInputStream); + return GetResponse (); + } + + void CoreService::Start () + { + InputPipe.reset (new Pipe()); + OutputPipe.reset (new Pipe()); + + int pid = fork(); + throw_sys_if (pid == -1); + + if (pid == 0) + { + try + { + ProcessRequests(); + _exit (0); + } + catch (...) { } + _exit (1); + } + + ServiceInputStream = shared_ptr (new FileStream (InputPipe->GetWriteFD())); + ServiceOutputStream = shared_ptr (new FileStream (OutputPipe->GetReadFD())); + } + + void CoreService::StartElevated (const CoreServiceRequest &request) + { + auto_ptr inPipe (new Pipe()); + auto_ptr outPipe (new Pipe()); + Pipe errPipe; + + int forkedPid = fork(); + throw_sys_if (forkedPid == -1); + + if (forkedPid == 0) + { + try + { + try + { + throw_sys_if (dup2 (inPipe->GetReadFD(), STDIN_FILENO) == -1); + throw_sys_if (dup2 (outPipe->GetWriteFD(), STDOUT_FILENO) == -1); + throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1); + + string appPath = request.ApplicationExecutablePath; + if (appPath.empty()) + appPath = "truecrypt"; + + const char *args[] = { "sudo", "-S", "-p", "", appPath.c_str(), TC_CORE_SERVICE_CMDLINE_OPTION, nullptr }; + execvp (args[0], ((char* const*) args)); + throw SystemException (SRC_POS, args[0]); + } + catch (Exception &) + { + throw; + } + catch (exception &e) + { + throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e)); + } + catch (...) + { + throw UnknownException (SRC_POS); + } + } + catch (Exception &e) + { + try + { + shared_ptr outputStream (new FileStream (errPipe.GetWriteFD())); + e.Serialize (outputStream); + } + catch (...) { } + } + + _exit (1); + } + + vector adminPassword (request.AdminPassword.size() + 1); + int timeout = 6000; + + if (request.FastElevation) + { + string dummyPassword = "dummy\n"; + adminPassword = vector (dummyPassword.size()); + Memory::Copy (&adminPassword.front(), dummyPassword.c_str(), dummyPassword.size()); + timeout = 1000; + } + else + { + Memory::Copy (&adminPassword.front(), request.AdminPassword.c_str(), request.AdminPassword.size()); + adminPassword[request.AdminPassword.size()] = '\n'; + } + + if (write (inPipe->GetWriteFD(), &adminPassword.front(), adminPassword.size())) { } // Errors ignored + + Memory::Erase (&adminPassword.front(), adminPassword.size()); + + throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + + vector buffer (4096), errOutput (4096); + buffer.clear (); + errOutput.clear (); + + Poller poller (outPipe->GetReadFD(), errPipe.GetReadFD()); + int status, waitRes; + int exitCode = 1; + + try + { + do + { + ssize_t bytesRead = 0; + foreach (int fd, poller.WaitForData (timeout)) + { + bytesRead = read (fd, &buffer[0], buffer.capacity()); + if (bytesRead > 0 && fd == errPipe.GetReadFD()) + { + errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + + if (bytesRead > 5 && bytesRead < 80) // Short message captured + timeout = 200; + } + } + + if (bytesRead == 0) + { + waitRes = waitpid (forkedPid, &status, 0); + break; + } + + } while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0); + } + catch (TimeOut&) + { + if ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0) + { + inPipe->Close(); + outPipe->Close(); + errPipe.Close(); + + if (request.FastElevation) + { + // Prevent defunct process + struct WaitFunctor : public Functor + { + WaitFunctor (int pid) : Pid (pid) { } + virtual void operator() () + { + int status; + for (int t = 0; t < 10 && waitpid (Pid, &status, WNOHANG) == 0; t++) + Thread::Sleep (1000); + } + int Pid; + }; + Thread thread; + thread.Start (new WaitFunctor (forkedPid)); + + throw ElevationFailed (SRC_POS, "sudo", 1, ""); + } + + waitRes = waitpid (forkedPid, &status, 0); + } + } + + if (!errOutput.empty()) + { + auto_ptr deserializedObject; + Exception *deserializedException = nullptr; + + try + { + shared_ptr stream (new MemoryStream (ConstBufferPtr ((byte *) &errOutput[0], errOutput.size()))); + deserializedObject.reset (Serializable::DeserializeNew (stream)); + deserializedException = dynamic_cast (deserializedObject.get()); + } + catch (...) { } + + if (deserializedException) + deserializedException->Throw(); + } + + throw_sys_if (waitRes == -1); + exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1); + if (exitCode != 0) + { + string strErrOutput; + + if (!errOutput.empty()) + strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end()); + + // sudo may require a tty even if -S is used + if (strErrOutput.find (" tty") != string::npos) + strErrOutput += "\nTo enable use of 'sudo' by applications without a terminal window, please disable 'requiretty' option in '/etc/sudoers'. Newer versions of sudo automatically determine whether a terminal is required ('requiretty' option is obsolete)."; + + throw ElevationFailed (SRC_POS, "sudo", exitCode, strErrOutput); + } + + throw_sys_if (fcntl (outPipe->GetReadFD(), F_SETFL, 0) == -1); + + ServiceInputStream = shared_ptr (new FileStream (inPipe->GetWriteFD())); + ServiceOutputStream = shared_ptr (new FileStream (outPipe->GetReadFD())); + + // Send sync code + byte sync[] = { 0, 0x11, 0x22 }; + ServiceInputStream->Write (ConstBufferPtr (sync, array_capacity (sync))); + + AdminInputPipe = inPipe; + AdminOutputPipe = outPipe; + } + + void CoreService::Stop () + { + ExitRequest exitRequest; + exitRequest.Serialize (ServiceInputStream); + } + + shared_ptr CoreService::AdminPasswordCallback; + + auto_ptr CoreService::AdminInputPipe; + auto_ptr CoreService::AdminOutputPipe; + + auto_ptr CoreService::InputPipe; + auto_ptr CoreService::OutputPipe; + shared_ptr CoreService::ServiceInputStream; + shared_ptr CoreService::ServiceOutputStream; + + bool CoreService::ElevatedPrivileges = false; + bool CoreService::ElevatedServiceAvailable = false; +} diff --git a/src/Core/Unix/CoreService.h b/src/Core/Unix/CoreService.h new file mode 100644 index 00000000..9702dc7e --- /dev/null +++ b/src/Core/Unix/CoreService.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Unix_CoreService +#define TC_HEADER_Core_Unix_CoreService + +#include "CoreServiceRequest.h" +#include "Platform/Stream.h" +#include "Platform/Unix/Pipe.h" +#include "Core/Core.h" + +namespace TrueCrypt +{ + // This service facilitates process forking and elevation of user privileges + class CoreService + { + public: + static void ProcessElevatedRequests (); + static void ProcessRequests (int inputFD = -1, int outputFD = -1); + static void RequestCheckFilesystem (shared_ptr mountedVolume, bool repair); + static void RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force); + static shared_ptr RequestDismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false); + static uint32 RequestGetDeviceSectorSize (const DevicePath &devicePath); + static uint64 RequestGetDeviceSize (const DevicePath &devicePath); + static HostDeviceList RequestGetHostDevices (bool pathListOnly); + static shared_ptr RequestMountVolume (MountOptions &options); + static void RequestSetFileOwner (const FilesystemPath &path, const UserId &owner); + static void SetAdminPasswordCallback (shared_ptr functor) { AdminPasswordCallback = functor; } + static void Start (); + static void Stop (); + + protected: + template static auto_ptr GetResponse (); + template static auto_ptr SendRequest (CoreServiceRequest &request); + static void StartElevated (const CoreServiceRequest &request); + + static shared_ptr AdminPasswordCallback; + + static auto_ptr AdminInputPipe; + static auto_ptr AdminOutputPipe; + + static auto_ptr InputPipe; + static auto_ptr OutputPipe; + static shared_ptr ServiceInputStream; + static shared_ptr ServiceOutputStream; + + static bool ElevatedPrivileges; + static bool ElevatedServiceAvailable; + static bool Running; + + private: + CoreService (); + }; + +#define TC_CORE_SERVICE_CMDLINE_OPTION "--core-service" +} + +#endif // TC_HEADER_Core_Unix_CoreService diff --git a/src/Core/Unix/CoreServiceProxy.h b/src/Core/Unix/CoreServiceProxy.h new file mode 100644 index 00000000..2a264617 --- /dev/null +++ b/src/Core/Unix/CoreServiceProxy.h @@ -0,0 +1,152 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Windows_CoreServiceProxy +#define TC_HEADER_Core_Windows_CoreServiceProxy + +#include "CoreService.h" +#include "Volume/VolumePasswordCache.h" + +namespace TrueCrypt +{ + template + class CoreServiceProxy : public T + { + public: + CoreServiceProxy () { } + virtual ~CoreServiceProxy () { } + + virtual void CheckFilesystem (shared_ptr mountedVolume, bool repair) const + { + CoreService::RequestCheckFilesystem (mountedVolume, repair); + } + + virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const + { + CoreService::RequestDismountFilesystem (mountPoint, force); + } + + virtual shared_ptr DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false) + { + shared_ptr dismountedVolumeInfo = CoreService::RequestDismountVolume (mountedVolume, ignoreOpenFiles, syncVolumeInfo); + + VolumeEventArgs eventArgs (dismountedVolumeInfo); + T::VolumeDismountedEvent.Raise (eventArgs); + + return dismountedVolumeInfo; + } + + virtual uint32 GetDeviceSectorSize (const DevicePath &devicePath) const + { + return CoreService::RequestGetDeviceSectorSize (devicePath); + } + + virtual uint64 GetDeviceSize (const DevicePath &devicePath) const + { + return CoreService::RequestGetDeviceSize (devicePath); + } + +#ifndef TC_LINUX + virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const + { + if (pathListOnly) + return T::GetHostDevices (pathListOnly); + else + return CoreService::RequestGetHostDevices (pathListOnly); + } +#endif + virtual bool IsPasswordCacheEmpty () const { return VolumePasswordCache::IsEmpty(); } + + virtual shared_ptr MountVolume (MountOptions &options) + { + shared_ptr mountedVolume; + + if (!VolumePasswordCache::IsEmpty() + && (!options.Password || options.Password->IsEmpty()) + && (!options.Keyfiles || options.Keyfiles->empty())) + { + finally_do_arg (MountOptions*, &options, { if (finally_arg->Password) finally_arg->Password.reset(); }); + + PasswordIncorrect passwordException; + foreach (shared_ptr 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; + + newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + if (newOptions.Keyfiles) + newOptions.Keyfiles->clear(); + + newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword); + if (newOptions.ProtectionKeyfiles) + newOptions.ProtectionKeyfiles->clear(); + + try + { + mountedVolume = CoreService::RequestMountVolume (newOptions); + } + catch (ProtectionPasswordIncorrect &e) + { + if (options.ProtectionKeyfiles && !options.ProtectionKeyfiles->empty()) + throw ProtectionPasswordKeyfilesIncorrect (e.what()); + throw; + } + catch (PasswordIncorrect &e) + { + if (options.Keyfiles && !options.Keyfiles->empty()) + throw PasswordKeyfilesIncorrect (e.what()); + throw; + } + + if (options.CachePassword + && ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty()))) + { + VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password)); + } + } + + VolumeEventArgs eventArgs (mountedVolume); + T::VolumeMountedEvent.Raise (eventArgs); + + return mountedVolume; + } + + virtual void SetAdminPasswordCallback (shared_ptr functor) + { + CoreService::SetAdminPasswordCallback (functor); + } + + virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const + { + CoreService::RequestSetFileOwner (path, owner); + } + + virtual void WipePasswordCache () const + { + VolumePasswordCache::Clear(); + } + }; +} + +#endif // TC_HEADER_Core_Windows_CoreServiceProxy diff --git a/src/Core/Unix/CoreServiceRequest.cpp b/src/Core/Unix/CoreServiceRequest.cpp new file mode 100644 index 00000000..49ee8418 --- /dev/null +++ b/src/Core/Unix/CoreServiceRequest.cpp @@ -0,0 +1,269 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "CoreServiceRequest.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + void CoreServiceRequest::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + sr.Deserialize ("AdminPassword", AdminPassword); + ApplicationExecutablePath = sr.DeserializeWString ("ApplicationExecutablePath"); + sr.Deserialize ("ElevateUserPrivileges", ElevateUserPrivileges); + sr.Deserialize ("FastElevation", FastElevation); + } + + void CoreServiceRequest::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("AdminPassword", AdminPassword); + sr.Serialize ("ApplicationExecutablePath", wstring (ApplicationExecutablePath)); + sr.Serialize ("ElevateUserPrivileges", ElevateUserPrivileges); + sr.Serialize ("FastElevation", FastElevation); + } + + // CheckFilesystemRequest + void CheckFilesystemRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + MountedVolumeInfo = Serializable::DeserializeNew (stream); + sr.Deserialize ("Repair", Repair); + } + + bool CheckFilesystemRequest::RequiresElevation () const + { +#ifdef TC_MACOSX + return false; +#endif + return !Core->HasAdminPrivileges(); + } + + void CheckFilesystemRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + MountedVolumeInfo->Serialize (stream); + sr.Serialize ("Repair", Repair); + } + + // DismountFilesystemRequest + void DismountFilesystemRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("Force", Force); + MountPoint = sr.DeserializeWString ("MountPoint"); + } + + bool DismountFilesystemRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void DismountFilesystemRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Force", Force); + sr.Serialize ("MountPoint", wstring (MountPoint)); + } + + // DismountVolumeRequest + void DismountVolumeRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("IgnoreOpenFiles", IgnoreOpenFiles); + sr.Deserialize ("SyncVolumeInfo", SyncVolumeInfo); + MountedVolumeInfo = Serializable::DeserializeNew (stream); + } + + bool DismountVolumeRequest::RequiresElevation () const + { +#ifdef TC_MACOSX + if (MountedVolumeInfo->Path.IsDevice()) + { + try + { + File file; + file.Open (MountedVolumeInfo->Path, File::OpenReadWrite); + } + catch (...) + { + return true; + } + } + + return false; +#endif + return !Core->HasAdminPrivileges(); + } + + void DismountVolumeRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("IgnoreOpenFiles", IgnoreOpenFiles); + sr.Serialize ("SyncVolumeInfo", SyncVolumeInfo); + MountedVolumeInfo->Serialize (stream); + } + + // GetDeviceSectorSizeRequest + void GetDeviceSectorSizeRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + Path = sr.DeserializeWString ("Path"); + } + + bool GetDeviceSectorSizeRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void GetDeviceSectorSizeRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Path", wstring (Path)); + } + + // GetDeviceSizeRequest + void GetDeviceSizeRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + Path = sr.DeserializeWString ("Path"); + } + + bool GetDeviceSizeRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void GetDeviceSizeRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Path", wstring (Path)); + } + + // GetHostDevicesRequest + void GetHostDevicesRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("PathListOnly", PathListOnly); + } + + bool GetHostDevicesRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void GetHostDevicesRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("PathListOnly", PathListOnly); + } + + // ExitRequest + void ExitRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + } + + void ExitRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + } + + // MountVolumeRequest + void MountVolumeRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + DeserializedOptions = Serializable::DeserializeNew (stream); + Options = DeserializedOptions.get(); + } + + bool MountVolumeRequest::RequiresElevation () const + { +#ifdef TC_MACOSX + if (Options->Path->IsDevice()) + { + try + { + File file; + file.Open (*Options->Path, File::OpenReadWrite); + } + catch (...) + { + return true; + } + } + + return false; +#endif + return !Core->HasAdminPrivileges(); + } + + void MountVolumeRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + Options->Serialize (stream); + } + + // SetFileOwnerRequest + void SetFileOwnerRequest::Deserialize (shared_ptr stream) + { + CoreServiceRequest::Deserialize (stream); + Serializer sr (stream); + + uint64 owner; + sr.Deserialize ("Owner", owner); + Owner.SystemId = static_cast (owner); + + Path = sr.DeserializeWString ("Path"); + } + + bool SetFileOwnerRequest::RequiresElevation () const + { + return !Core->HasAdminPrivileges(); + } + + void SetFileOwnerRequest::Serialize (shared_ptr stream) const + { + CoreServiceRequest::Serialize (stream); + Serializer sr (stream); + + uint64 owner = Owner.SystemId; + sr.Serialize ("Owner", owner); + + sr.Serialize ("Path", wstring (Path)); + } + + + TC_SERIALIZER_FACTORY_ADD_CLASS (CoreServiceRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (CheckFilesystemRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (DismountFilesystemRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (DismountVolumeRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (ExitRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeRequest); + TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerRequest); +} diff --git a/src/Core/Unix/CoreServiceRequest.h b/src/Core/Unix/CoreServiceRequest.h new file mode 100644 index 00000000..030ac81b --- /dev/null +++ b/src/Core/Unix/CoreServiceRequest.h @@ -0,0 +1,136 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Unix_CoreServiceRequest +#define TC_HEADER_Core_Unix_CoreServiceRequest + +#include "Platform/Serializable.h" +#include "Core/Core.h" + +namespace TrueCrypt +{ + struct CoreServiceRequest : public Serializable + { + CoreServiceRequest () : ElevateUserPrivileges (false), FastElevation (false) { } + TC_SERIALIZABLE (CoreServiceRequest); + + virtual bool RequiresElevation () const { return false; } + + string AdminPassword; + FilePath ApplicationExecutablePath; + bool ElevateUserPrivileges; + bool FastElevation; + }; + + struct CheckFilesystemRequest : CoreServiceRequest + { + CheckFilesystemRequest () { } + CheckFilesystemRequest (shared_ptr volumeInfo, bool repair) + : MountedVolumeInfo (volumeInfo), Repair (repair) { } + TC_SERIALIZABLE (CheckFilesystemRequest); + + virtual bool RequiresElevation () const; + + shared_ptr MountedVolumeInfo; + bool Repair; + }; + + struct DismountFilesystemRequest : CoreServiceRequest + { + DismountFilesystemRequest () { } + DismountFilesystemRequest (const DirectoryPath &mountPoint, bool force) + : Force (force), MountPoint (mountPoint) { } + TC_SERIALIZABLE (DismountFilesystemRequest); + + virtual bool RequiresElevation () const; + + bool Force; + DirectoryPath MountPoint; + }; + + struct DismountVolumeRequest : CoreServiceRequest + { + DismountVolumeRequest () { } + DismountVolumeRequest (shared_ptr volumeInfo, bool ignoreOpenFiles, bool syncVolumeInfo) + : IgnoreOpenFiles (ignoreOpenFiles), MountedVolumeInfo (volumeInfo), SyncVolumeInfo (syncVolumeInfo) { } + TC_SERIALIZABLE (DismountVolumeRequest); + + virtual bool RequiresElevation () const; + + bool IgnoreOpenFiles; + shared_ptr MountedVolumeInfo; + bool SyncVolumeInfo; + }; + + struct GetDeviceSectorSizeRequest : CoreServiceRequest + { + GetDeviceSectorSizeRequest () { } + GetDeviceSectorSizeRequest (const DevicePath &path) : Path (path) { } + TC_SERIALIZABLE (GetDeviceSectorSizeRequest); + + virtual bool RequiresElevation () const; + + DevicePath Path; + }; + + struct GetDeviceSizeRequest : CoreServiceRequest + { + GetDeviceSizeRequest () { } + GetDeviceSizeRequest (const DevicePath &path) : Path (path) { } + TC_SERIALIZABLE (GetDeviceSizeRequest); + + virtual bool RequiresElevation () const; + + DevicePath Path; + }; + + struct GetHostDevicesRequest : CoreServiceRequest + { + GetHostDevicesRequest () { } + GetHostDevicesRequest (bool pathListOnly) : PathListOnly (pathListOnly) { } + TC_SERIALIZABLE (GetHostDevicesRequest); + + virtual bool RequiresElevation () const; + + bool PathListOnly; + }; + + struct ExitRequest : CoreServiceRequest + { + TC_SERIALIZABLE (ExitRequest); + }; + + struct MountVolumeRequest : CoreServiceRequest + { + MountVolumeRequest () { } + MountVolumeRequest (MountOptions *options) : Options (options) { } + TC_SERIALIZABLE (MountVolumeRequest); + + virtual bool RequiresElevation () const; + + MountOptions *Options; + + protected: + shared_ptr DeserializedOptions; + }; + + + struct SetFileOwnerRequest : CoreServiceRequest + { + SetFileOwnerRequest () { } + SetFileOwnerRequest (const FilesystemPath &path, const UserId &owner) : Owner (owner), Path (path) { } + TC_SERIALIZABLE (SetFileOwnerRequest); + + virtual bool RequiresElevation () const; + + UserId Owner; + FilesystemPath Path; + }; +} + +#endif // TC_HEADER_Core_Unix_CoreServiceRequest diff --git a/src/Core/Unix/CoreServiceResponse.cpp b/src/Core/Unix/CoreServiceResponse.cpp new file mode 100644 index 00000000..7809b448 --- /dev/null +++ b/src/Core/Unix/CoreServiceResponse.cpp @@ -0,0 +1,119 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "CoreServiceResponse.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + // CheckFilesystemResponse + void CheckFilesystemResponse::Deserialize (shared_ptr stream) + { + } + + void CheckFilesystemResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + } + + // DismountFilesystemResponse + void DismountFilesystemResponse::Deserialize (shared_ptr stream) + { + } + + void DismountFilesystemResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + } + + // DismountVolumeResponse + void DismountVolumeResponse::Deserialize (shared_ptr stream) + { + DismountedVolumeInfo = Serializable::DeserializeNew (stream); + } + + void DismountVolumeResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + DismountedVolumeInfo->Serialize (stream); + } + + // GetDeviceSectorSizeResponse + void GetDeviceSectorSizeResponse::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + sr.Deserialize ("Size", Size); + } + + void GetDeviceSectorSizeResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Size", Size); + } + + // GetDeviceSizeResponse + void GetDeviceSizeResponse::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + sr.Deserialize ("Size", Size); + } + + void GetDeviceSizeResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("Size", Size); + } + + // GetHostDevicesResponse + void GetHostDevicesResponse::Deserialize (shared_ptr stream) + { + Serializable::DeserializeList (stream, HostDevices); + } + + void GetHostDevicesResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializable::SerializeList (stream, HostDevices); + } + + // MountVolumeResponse + void MountVolumeResponse::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + MountedVolumeInfo = Serializable::DeserializeNew (stream); + } + + void MountVolumeResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + MountedVolumeInfo->Serialize (stream); + } + + // SetFileOwnerResponse + void SetFileOwnerResponse::Deserialize (shared_ptr stream) + { + } + + void SetFileOwnerResponse::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + } + + TC_SERIALIZER_FACTORY_ADD_CLASS (CheckFilesystemResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (DismountFilesystemResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (DismountVolumeResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSectorSizeResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetDeviceSizeResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (GetHostDevicesResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (MountVolumeResponse); + TC_SERIALIZER_FACTORY_ADD_CLASS (SetFileOwnerResponse); +} diff --git a/src/Core/Unix/CoreServiceResponse.h b/src/Core/Unix/CoreServiceResponse.h new file mode 100644 index 00000000..24c09b35 --- /dev/null +++ b/src/Core/Unix/CoreServiceResponse.h @@ -0,0 +1,84 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Unix_CoreServiceResponse +#define TC_HEADER_Core_Unix_CoreServiceResponse + +#include "Platform/Serializable.h" +#include "Core/Core.h" + +namespace TrueCrypt +{ + struct CoreServiceResponse : public Serializable + { + }; + + struct CheckFilesystemResponse : CoreServiceResponse + { + CheckFilesystemResponse () { } + TC_SERIALIZABLE (CheckFilesystemResponse); + }; + + struct DismountFilesystemResponse : CoreServiceResponse + { + DismountFilesystemResponse () { } + TC_SERIALIZABLE (DismountFilesystemResponse); + }; + + struct DismountVolumeResponse : CoreServiceResponse + { + DismountVolumeResponse () { } + TC_SERIALIZABLE (DismountVolumeResponse); + + shared_ptr DismountedVolumeInfo; + }; + + struct GetDeviceSectorSizeResponse : CoreServiceResponse + { + GetDeviceSectorSizeResponse () { } + GetDeviceSectorSizeResponse (uint32 size) : Size (size) { } + TC_SERIALIZABLE (GetDeviceSectorSizeResponse); + + uint32 Size; + }; + + struct GetDeviceSizeResponse : CoreServiceResponse + { + GetDeviceSizeResponse () { } + GetDeviceSizeResponse (uint64 size) : Size (size) { } + TC_SERIALIZABLE (GetDeviceSizeResponse); + + uint64 Size; + }; + + struct GetHostDevicesResponse : CoreServiceResponse + { + GetHostDevicesResponse () { } + GetHostDevicesResponse (const HostDeviceList &hostDevices) : HostDevices (hostDevices) { } + TC_SERIALIZABLE (GetHostDevicesResponse); + + HostDeviceList HostDevices; + }; + + struct MountVolumeResponse : CoreServiceResponse + { + MountVolumeResponse () { } + MountVolumeResponse (shared_ptr volumeInfo) : MountedVolumeInfo (volumeInfo) { } + TC_SERIALIZABLE (MountVolumeResponse); + + shared_ptr MountedVolumeInfo; + }; + + struct SetFileOwnerResponse : CoreServiceResponse + { + SetFileOwnerResponse () { } + TC_SERIALIZABLE (SetFileOwnerResponse); + }; +} + +#endif // TC_HEADER_Core_Unix_CoreServiceResponse diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp new file mode 100644 index 00000000..89f34e20 --- /dev/null +++ b/src/Core/Unix/CoreUnix.cpp @@ -0,0 +1,618 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "CoreUnix.h" +#include +#include +#include +#include +#include +#include +#include +#include "Platform/FileStream.h" +#include "Driver/Fuse/FuseService.h" +#include "Volume/VolumePasswordCache.h" + +namespace TrueCrypt +{ + CoreUnix::CoreUnix () + { + signal (SIGPIPE, SIG_IGN); + + char *loc = setlocale (LC_ALL, ""); + if (!loc || string (loc) == "C") + setlocale (LC_ALL, "en_US.UTF-8"); + } + + CoreUnix::~CoreUnix () + { + } + + void CoreUnix::CheckFilesystem (shared_ptr mountedVolume, bool repair) const + { + if (!mountedVolume->MountPoint.IsEmpty()) + DismountFilesystem (mountedVolume->MountPoint, false); + + list args; + + args.push_back ("-T"); + args.push_back ("fsck"); + + args.push_back ("-e"); + + string xargs = "fsck "; + +#ifdef TC_LINUX + if (!repair) + xargs += "-n "; + else + xargs += "-r "; +#endif + + xargs += string (mountedVolume->VirtualDevice) + "; echo '[Done]'; read W"; + args.push_back (xargs); + + try + { + Process::Execute ("xterm", args, 1000); + } catch (TimeOut&) { } + } + + void CoreUnix::DismountFilesystem (const DirectoryPath &mountPoint, bool force) const + { + list args; + +#ifdef TC_MACOSX + if (force) + args.push_back ("-f"); +#endif + args.push_back ("--"); + args.push_back (mountPoint); + + Process::Execute ("umount", args); + } + + shared_ptr CoreUnix::DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo) + { + if (!mountedVolume->MountPoint.IsEmpty()) + { + DismountFilesystem (mountedVolume->MountPoint, ignoreOpenFiles); + + // Delete mount directory if a default path has been used + if (string (mountedVolume->MountPoint).find (GetDefaultMountPointPrefix()) == 0) + mountedVolume->MountPoint.Delete(); + } + + try + { + DismountNativeVolume (mountedVolume); + } + catch (NotApplicable &) { } + + if (!mountedVolume->LoopDevice.IsEmpty()) + { + try + { + DetachLoopDevice (mountedVolume->LoopDevice); + } + catch (ExecutedProcessFailed&) { } + } + + if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly) + { + sync(); + VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path); + + if (ml.size() > 0) + mountedVolume = ml.front(); + } + + list args; + args.push_back ("--"); + args.push_back (mountedVolume->AuxMountPoint); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("umount", args); + break; + } + catch (ExecutedProcessFailed&) + { + if (t > 10) + throw; + Thread::Sleep (200); + } + } + + try + { + mountedVolume->AuxMountPoint.Delete(); + } + catch (...) { } + + VolumeEventArgs eventArgs (mountedVolume); + VolumeDismountedEvent.Raise (eventArgs); + + return mountedVolume; + } + + bool CoreUnix::FilesystemSupportsLargeFiles (const FilePath &filePath) const + { + string path = filePath; + size_t pos; + + while ((pos = path.find_last_of ('/')) != string::npos) + { + path = path.substr (0, pos); + + if (path.empty()) + break; + + try + { + MountedFilesystemList filesystems = GetMountedFilesystems (DevicePath(), path); + if (!filesystems.empty()) + { + const MountedFilesystem &fs = *filesystems.front(); + + if (fs.Type == "fat" + || fs.Type == "fat32" + || fs.Type == "vfat" + || fs.Type == "fatfs" + || fs.Type == "msdos" + || fs.Type == "msdosfs" + || fs.Type == "umsdos" + || fs.Type == "dos" + || fs.Type == "dosfs" + || fs.Type == "pcfs" + ) + { + return false; + } + + return true; + } + } + catch (...) { } + } + + return true; // Prevent errors if the filesystem cannot be identified + } + + bool CoreUnix::FilesystemSupportsUnixPermissions (const DevicePath &devicePath) const + { + File device; + device.Open (devicePath); + + Buffer bootSector (device.GetDeviceSectorSize()); + device.SeekAt (0); + device.ReadCompleteBuffer (bootSector); + + byte *b = bootSector.Ptr(); + + return memcmp (b + 3, "NTFS", 4) != 0 + && memcmp (b + 54, "FAT", 3) != 0 + && memcmp (b + 82, "FAT32", 5) != 0 + && memcmp (b + 3, "EXFAT", 5) != 0; + } + + string CoreUnix::GetDefaultMountPointPrefix () const + { + const char *envPrefix = getenv ("TRUECRYPT_MOUNT_PREFIX"); + if (envPrefix && !string (envPrefix).empty()) + return envPrefix; + + if (FilesystemPath ("/media").IsDirectory()) + return "/media/truecrypt"; + + if (FilesystemPath ("/mnt").IsDirectory()) + return "/mnt/truecrypt"; + + return GetTempDirectory() + "/truecrypt_mnt"; + } + + uint32 CoreUnix::GetDeviceSectorSize (const DevicePath &devicePath) const + { + File dev; + dev.Open (devicePath); + return dev.GetDeviceSectorSize(); + } + + uint64 CoreUnix::GetDeviceSize (const DevicePath &devicePath) const + { + File dev; + dev.Open (devicePath); + return dev.Length(); + } + + DirectoryPath CoreUnix::GetDeviceMountPoint (const DevicePath &devicePath) const + { + DevicePath devPath = devicePath; +#ifdef TC_MACOSX + if (string (devPath).find ("/dev/rdisk") != string::npos) + devPath = string ("/dev/") + string (devicePath).substr (6); +#endif + MountedFilesystemList mountedFilesystems = GetMountedFilesystems (devPath); + + if (mountedFilesystems.size() < 1) + return DirectoryPath(); + + return mountedFilesystems.front()->MountPoint; + } + + VolumeInfoList CoreUnix::GetMountedVolumes (const VolumePath &volumePath) const + { + VolumeInfoList volumes; + + foreach_ref (const MountedFilesystem &mf, GetMountedFilesystems ()) + { + if (string (mf.MountPoint).find (GetFuseMountDirPrefix()) == string::npos) + continue; + + shared_ptr mountedVol; + try + { + shared_ptr controlFile (new File); + controlFile->Open (string (mf.MountPoint) + FuseService::GetControlPath()); + + shared_ptr controlFileStream (new FileStream (controlFile)); + mountedVol = Serializable::DeserializeNew (controlFileStream); + } + catch (...) + { + continue; + } + + if (!volumePath.IsEmpty() && wstring (mountedVol->Path).compare (volumePath) != 0) + continue; + + mountedVol->AuxMountPoint = mf.MountPoint; + + if (!mountedVol->VirtualDevice.IsEmpty()) + { + MountedFilesystemList mpl = GetMountedFilesystems (mountedVol->VirtualDevice); + + if (mpl.size() > 0) + mountedVol->MountPoint = mpl.front()->MountPoint; + } + + volumes.push_back (mountedVol); + + if (!volumePath.IsEmpty()) + break; + } + + return volumes; + } + + gid_t CoreUnix::GetRealGroupId () const + { + const char *env = getenv ("SUDO_GID"); + if (env) + { + try + { + string s (env); + return static_cast (StringConverter::ToUInt64 (s)); + } + catch (...) { } + } + + return getgid(); + } + + uid_t CoreUnix::GetRealUserId () const + { + const char *env = getenv ("SUDO_UID"); + if (env) + { + try + { + string s (env); + return static_cast (StringConverter::ToUInt64 (s)); + } + catch (...) { } + } + + return getuid(); + } + + string CoreUnix::GetTempDirectory () const + { + char *envDir = getenv ("TMPDIR"); + return envDir ? envDir : "/tmp"; + } + + bool CoreUnix::IsMountPointAvailable (const DirectoryPath &mountPoint) const + { + return GetMountedFilesystems (DevicePath(), mountPoint).size() == 0; + } + + void CoreUnix::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const + { + if (GetMountedFilesystems (DevicePath(), mountPoint).size() > 0) + throw MountPointUnavailable (SRC_POS); + + list args; + string options; + + if (!filesystemType.empty()) + { +#ifdef TC_SOLARIS + args.push_back ("-F"); +#else + args.push_back ("-t"); +#endif + args.push_back (filesystemType); + } + + if (readOnly) + options = "-oro"; + + if (!systemMountOptions.empty()) + { + if (options.empty()) + options = "-o"; + else + options += ","; + + options += systemMountOptions; + } + + if (!options.empty()) + args.push_back (options); + + args.push_back ("--"); + args.push_back (devicePath); + args.push_back (mountPoint); + + Process::Execute ("mount", args); + } + + VolumeSlotNumber CoreUnix::MountPointToSlotNumber (const DirectoryPath &mountPoint) const + { + string mountPointStr (mountPoint); + if (mountPointStr.find (GetDefaultMountPointPrefix()) == 0) + { + try + { + return StringConverter::ToUInt32 (StringConverter::GetTrailingNumber (mountPointStr)); + } + catch (...) { } + } + return GetFirstFreeSlotNumber(); + } + + shared_ptr CoreUnix::MountVolume (MountOptions &options) + { + CoalesceSlotNumberAndMountPoint (options); + + if (IsVolumeMounted (*options.Path)) + throw VolumeAlreadyMounted (SRC_POS); + + Cipher::EnableHwSupport (!options.NoHardwareCrypto); + + shared_ptr volume; + + while (true) + { + try + { + volume = OpenVolume ( + options.Path, + options.PreserveTimestamps, + options.Password, + options.Keyfiles, + options.Protection, + options.ProtectionPassword, + options.ProtectionKeyfiles, + options.SharedAccessAllowed, + VolumeType::Unknown, + options.UseBackupHeaders, + options.PartitionInSystemEncryptionScope + ); + + options.Password.reset(); + } + catch (SystemException &e) + { + if (options.Protection != VolumeProtection::ReadOnly + && (e.GetErrorCode() == EROFS || e.GetErrorCode() == EACCES || e.GetErrorCode() == EPERM)) + { + // Read-only filesystem + options.Protection = VolumeProtection::ReadOnly; + continue; + } + + throw; + } + + break; + } + + if (options.Path->IsDevice()) + { + if (volume->GetFile()->GetDeviceSectorSize() != volume->GetSectorSize()) + throw ParameterIncorrect (SRC_POS); + +#if defined (TC_LINUX) + if (volume->GetSectorSize() != TC_SECTOR_SIZE_LEGACY) + { + if (options.Protection == VolumeProtection::HiddenVolumeReadOnly) + throw UnsupportedSectorSizeHiddenVolumeProtection(); + + if (options.NoKernelCrypto) + throw UnsupportedSectorSizeNoKernelCrypto(); + } +#endif + } + + // Find a free mount point for FUSE service + MountedFilesystemList mountedFilesystems = GetMountedFilesystems (); + string fuseMountPoint; + for (int i = 1; true; i++) + { + stringstream path; + path << GetTempDirectory() << "/" << GetFuseMountDirPrefix() << i; + FilesystemPath fsPath (path.str()); + + bool inUse = false; + + foreach_ref (const MountedFilesystem &mf, mountedFilesystems) + { + if (mf.MountPoint == path.str()) + { + inUse = true; + break; + } + } + + if (!inUse) + { + try + { + if (fsPath.IsDirectory()) + fsPath.Delete(); + + throw_sys_sub_if (mkdir (path.str().c_str(), S_IRUSR | S_IXUSR) == -1, path.str()); + + fuseMountPoint = fsPath; + break; + } + catch (...) + { + if (i > 255) + throw TemporaryDirectoryFailure (SRC_POS, StringConverter::ToWide (path.str())); + } + } + } + + try + { + FuseService::Mount (volume, options.SlotNumber, fuseMountPoint); + } + catch (...) + { + try + { + DirectoryPath (fuseMountPoint).Delete(); + } + catch (...) { } + throw; + } + + try + { + // Create a mount directory if a default path has been specified + bool mountDirCreated = false; + string mountPoint; + if (!options.NoFilesystem && options.MountPoint) + { + mountPoint = *options.MountPoint; + +#ifndef TC_MACOSX + if (mountPoint.find (GetDefaultMountPointPrefix()) == 0 && !options.MountPoint->IsDirectory()) + { + Directory::Create (*options.MountPoint); + try + { + throw_sys_sub_if (chown (mountPoint.c_str(), GetRealUserId(), GetRealGroupId()) == -1, mountPoint); + } catch (ParameterIncorrect&) { } + + mountDirCreated = true; + } +#endif + } + + try + { + try + { + MountVolumeNative (volume, options, fuseMountPoint); + } + catch (NotApplicable&) + { + MountAuxVolumeImage (fuseMountPoint, options); + } + } + catch (...) + { + if (mountDirCreated) + remove (mountPoint.c_str()); + throw; + } + } + catch (...) + { + try + { + VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); + if (mountedVolumes.size() > 0) + { + shared_ptr mountedVolume (mountedVolumes.front()); + DismountVolume (mountedVolume); + } + } + catch (...) { } + throw; + } + + VolumeInfoList mountedVolumes = GetMountedVolumes (*options.Path); + if (mountedVolumes.size() != 1) + throw ParameterIncorrect (SRC_POS); + + VolumeEventArgs eventArgs (mountedVolumes.front()); + VolumeMountedEvent.Raise (eventArgs); + + return mountedVolumes.front(); + } + + void CoreUnix::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const + { + DevicePath loopDev = AttachFileToLoopDevice (string (auxMountPoint) + FuseService::GetVolumeImagePath(), options.Protection == VolumeProtection::ReadOnly); + + try + { + FuseService::SendAuxDeviceInfo (auxMountPoint, loopDev, loopDev); + } + catch (...) + { + try + { + DetachLoopDevice (loopDev); + } + catch (...) { } + throw; + } + + if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty()) + { + MountFilesystem (loopDev, *options.MountPoint, + StringConverter::ToSingle (options.FilesystemType), + options.Protection == VolumeProtection::ReadOnly, + StringConverter::ToSingle (options.FilesystemOptions)); + } + } + + void CoreUnix::SetFileOwner (const FilesystemPath &path, const UserId &owner) const + { + throw_sys_if (chown (string (path).c_str(), owner.SystemId, (gid_t) -1) == -1); + } + + DirectoryPath CoreUnix::SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const + { + if (slotNumber < GetFirstSlotNumber() || slotNumber > GetLastSlotNumber()) + throw ParameterIncorrect (SRC_POS); + + stringstream s; + s << GetDefaultMountPointPrefix() << slotNumber; + return s.str(); + } +} diff --git a/src/Core/Unix/CoreUnix.h b/src/Core/Unix/CoreUnix.h new file mode 100644 index 00000000..1d7152fb --- /dev/null +++ b/src/Core/Unix/CoreUnix.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreUnix +#define TC_HEADER_Core_CoreUnix + +#include "System.h" +#include "Platform/Unix/Process.h" +#include "Core/CoreBase.h" +#include "Core/Unix/MountedFilesystem.h" + +namespace TrueCrypt +{ + class CoreUnix : public CoreBase + { + public: + CoreUnix (); + virtual ~CoreUnix (); + + virtual void CheckFilesystem (shared_ptr mountedVolume, bool repair = false) const; + virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const; + virtual shared_ptr DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false); + virtual bool FilesystemSupportsLargeFiles (const FilePath &filePath) const; + virtual DirectoryPath GetDeviceMountPoint (const DevicePath &devicePath) const; + virtual uint32 GetDeviceSectorSize (const DevicePath &devicePath) const; + virtual uint64 GetDeviceSize (const DevicePath &devicePath) const; + virtual int GetOSMajorVersion () const { throw NotApplicable (SRC_POS); } + virtual int GetOSMinorVersion () const { throw NotApplicable (SRC_POS); } + virtual VolumeInfoList GetMountedVolumes (const VolumePath &volumePath = VolumePath()) const; + virtual bool IsDevicePresent (const DevicePath &device) const { throw NotApplicable (SRC_POS); } + virtual bool IsInPortableMode () const { return false; } + virtual bool IsMountPointAvailable (const DirectoryPath &mountPoint) const; + virtual bool IsOSVersion (int major, int minor) const { throw NotApplicable (SRC_POS); } + virtual bool IsOSVersionLower (int major, int minor) const { throw NotApplicable (SRC_POS); } + virtual bool IsPasswordCacheEmpty () const { throw NotApplicable (SRC_POS); } + virtual bool HasAdminPrivileges () const { return getuid() == 0 || geteuid() == 0; } + virtual VolumeSlotNumber MountPointToSlotNumber (const DirectoryPath &mountPoint) const; + virtual shared_ptr MountVolume (MountOptions &options); + virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const; + virtual DirectoryPath SlotNumberToMountPoint (VolumeSlotNumber slotNumber) const; + virtual void WipePasswordCache () const { throw NotApplicable (SRC_POS); } + + protected: + virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const { throw NotApplicable (SRC_POS); } + virtual void DetachLoopDevice (const DevicePath &devicePath) const { throw NotApplicable (SRC_POS); } + virtual void DismountNativeVolume (shared_ptr mountedVolume) const { throw NotApplicable (SRC_POS); } + virtual bool FilesystemSupportsUnixPermissions (const DevicePath &devicePath) const; + virtual string GetDefaultMountPointPrefix () const; + virtual string GetFuseMountDirPrefix () const { return ".truecrypt_aux_mnt"; } + virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const = 0; + virtual uid_t GetRealUserId () const; + virtual gid_t GetRealGroupId () const; + virtual string GetTempDirectory () const; + virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const; + virtual void MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const; + virtual void MountVolumeNative (shared_ptr volume, MountOptions &options, const DirectoryPath &auxMountPoint) const { throw NotApplicable (SRC_POS); } + + private: + CoreUnix (const CoreUnix &); + CoreUnix &operator= (const CoreUnix &); + }; +} + +#endif // TC_HEADER_Core_CoreUnix diff --git a/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp new file mode 100644 index 00000000..e0a4dd5f --- /dev/null +++ b/src/Core/Unix/FreeBSD/CoreFreeBSD.cpp @@ -0,0 +1,202 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "CoreFreeBSD.h" +#include "Core/Unix/CoreServiceProxy.h" + +namespace TrueCrypt +{ + CoreFreeBSD::CoreFreeBSD () + { + } + + CoreFreeBSD::~CoreFreeBSD () + { + } + + DevicePath CoreFreeBSD::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const + { + list args; + args.push_back ("-a"); + args.push_back ("-t"); + args.push_back ("vnode"); + + if (readOnly) + { + args.push_back ("-o"); + args.push_back ("readonly"); + } + + args.push_back ("-f"); + args.push_back (filePath); + + string dev = StringConverter::Trim (Process::Execute ("mdconfig", args)); + + if (dev.find ("/") == string::npos) + dev = string ("/dev/") + dev; + + return dev; + } + + void CoreFreeBSD::DetachLoopDevice (const DevicePath &devicePath) const + { + list args; + args.push_back ("-d"); + args.push_back ("-u"); + args.push_back (StringConverter::GetTrailingNumber (devicePath)); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("mdconfig", args); + break; + } + catch (ExecutedProcessFailed&) + { + if (t > 5) + throw; + Thread::Sleep (200); + } + } + } + + HostDeviceList CoreFreeBSD::GetHostDevices (bool pathListOnly) const + { + HostDeviceList devices; +#ifdef TC_MACOSX + const string busType = "rdisk"; +#else + foreach (const string &busType, StringConverter::Split ("ad da")) +#endif + { + for (int devNumber = 0; devNumber < 64; devNumber++) + { + stringstream devPath; + devPath << "/dev/" << busType << devNumber; + + if (FilesystemPath (devPath.str()).IsBlockDevice() || FilesystemPath (devPath.str()).IsCharacterDevice()) + { + make_shared_auto (HostDevice, device); + device->Path = devPath.str(); + if (!pathListOnly) + { + try + { + device->Size = GetDeviceSize (device->Path); + } + catch (...) + { + device->Size = 0; + } + device->MountPoint = GetDeviceMountPoint (device->Path); + device->SystemNumber = 0; + } + devices.push_back (device); + + for (int partNumber = 1; partNumber < 32; partNumber++) + { +#ifdef TC_MACOSX + const string partLetter = ""; +#else + foreach (const string &partLetter, StringConverter::Split (",a,b,c,d,e,f,g,h", ",", true)) +#endif + { + stringstream partPath; + partPath << devPath.str() << "s" << partNumber << partLetter; + + if (FilesystemPath (partPath.str()).IsBlockDevice() || FilesystemPath (partPath.str()).IsCharacterDevice()) + { + make_shared_auto (HostDevice, partition); + partition->Path = partPath.str(); + if (!pathListOnly) + { + try + { + partition->Size = GetDeviceSize (partition->Path); + } + catch (...) + { + partition->Size = 0; + } + partition->MountPoint = GetDeviceMountPoint (partition->Path); + partition->SystemNumber = 0; + } + + device->Partitions.push_back (partition); + } + } + } + } + } + } + + return devices; + } + + MountedFilesystemList CoreFreeBSD::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const + { + + static Mutex mutex; + ScopeLock sl (mutex); + + struct statfs *sysMountList; + int count = getmntinfo (&sysMountList, MNT_NOWAIT); + throw_sys_if (count == 0); + + MountedFilesystemList mountedFilesystems; + + for (int i = 0; i < count; i++) + { + make_shared_auto (MountedFilesystem, mf); + + if (sysMountList[i].f_mntfromname[0]) + mf->Device = DevicePath (sysMountList[i].f_mntfromname); + else + continue; + + if (sysMountList[i].f_mntonname[0]) + mf->MountPoint = DirectoryPath (sysMountList[i].f_mntonname); + + mf->Type = sysMountList[i].f_fstypename; + + if ((devicePath.IsEmpty() || devicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint)) + mountedFilesystems.push_back (mf); + } + + return mountedFilesystems; + } + + void CoreFreeBSD::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const + { + try + { + // Try to mount FAT by default as mount is unable to probe filesystem type on BSD + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType.empty() ? "msdos" : filesystemType, readOnly, systemMountOptions); + } + catch (ExecutedProcessFailed&) + { + if (!filesystemType.empty()) + throw; + + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions); + } + } + +#ifdef TC_FREEBSD + auto_ptr Core (new CoreServiceProxy ); + auto_ptr CoreDirect (new CoreFreeBSD); +#endif +} diff --git a/src/Core/Unix/FreeBSD/CoreFreeBSD.h b/src/Core/Unix/FreeBSD/CoreFreeBSD.h new file mode 100644 index 00000000..a8230334 --- /dev/null +++ b/src/Core/Unix/FreeBSD/CoreFreeBSD.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreFreeBSD +#define TC_HEADER_Core_CoreFreeBSD + +#include "System.h" +#include "Core/Unix/CoreUnix.h" + +namespace TrueCrypt +{ + class CoreFreeBSD : public CoreUnix + { + public: + CoreFreeBSD (); + virtual ~CoreFreeBSD (); + + virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const; + + protected: + virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const; + virtual void DetachLoopDevice (const DevicePath &devicePath) const; + virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const; + virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const; + + private: + CoreFreeBSD (const CoreFreeBSD &); + CoreFreeBSD &operator= (const CoreFreeBSD &); + }; +} + +#endif // TC_HEADER_Core_CoreFreeBSD diff --git a/src/Core/Unix/FreeBSD/System.h b/src/Core/Unix/FreeBSD/System.h new file mode 100644 index 00000000..e0cac0ba --- /dev/null +++ b/src/Core/Unix/FreeBSD/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_FreeBSD_System +#define TC_HEADER_Platform_FreeBSD_System + +#endif // TC_HEADER_Platform_FreeBSD_System diff --git a/src/Core/Unix/Linux/CoreLinux.cpp b/src/Core/Unix/Linux/CoreLinux.cpp new file mode 100644 index 00000000..634a3a23 --- /dev/null +++ b/src/Core/Unix/Linux/CoreLinux.cpp @@ -0,0 +1,477 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CoreLinux.h" +#include "Platform/SystemInfo.h" +#include "Platform/TextReader.h" +#include "Volume/EncryptionModeLRW.h" +#include "Volume/EncryptionModeXTS.h" +#include "Driver/Fuse/FuseService.h" +#include "Core/Unix/CoreServiceProxy.h" + +namespace TrueCrypt +{ + CoreLinux::CoreLinux () + { + } + + CoreLinux::~CoreLinux () + { + } + + DevicePath CoreLinux::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const + { + list loopPaths; + loopPaths.push_back ("/dev/loop"); + loopPaths.push_back ("/dev/loop/"); + loopPaths.push_back ("/dev/.static/dev/loop"); + + for (int devIndex = 0; devIndex < 256; devIndex++) + { + string loopDev; + foreach (const string &loopPath, loopPaths) + { + loopDev = loopPath + StringConverter::ToSingle (devIndex); + if (FilesystemPath (loopDev).IsBlockDevice()) + break; + } + + if (loopDev.empty()) + continue; + + list args; + + list ::iterator readOnlyArg; + if (readOnly) + { + args.push_back ("-r"); + readOnlyArg = --args.end(); + } + + args.push_back ("--"); + args.push_back (loopDev); + args.push_back (filePath); + + try + { + Process::Execute ("losetup", args); + return loopDev; + } + catch (ExecutedProcessFailed&) + { + if (readOnly) + { + try + { + args.erase (readOnlyArg); + Process::Execute ("losetup", args); + return loopDev; + } + catch (ExecutedProcessFailed&) { } + } + } + } + + throw LoopDeviceSetupFailed (SRC_POS, wstring (filePath)); + } + + void CoreLinux::DetachLoopDevice (const DevicePath &devicePath) const + { + list args; + args.push_back ("-d"); + args.push_back (devicePath); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("losetup", args); + break; + } + catch (ExecutedProcessFailed&) + { + if (t > 5) + throw; + Thread::Sleep (200); + } + } + } + + void CoreLinux::DismountNativeVolume (shared_ptr mountedVolume) const + { + string devPath = mountedVolume->VirtualDevice; + + if (devPath.find ("/dev/mapper/truecrypt") != 0) + throw NotApplicable (SRC_POS); + + size_t devCount = 0; + while (FilesystemPath (devPath).IsBlockDevice()) + { + list dmsetupArgs; + dmsetupArgs.push_back ("remove"); + dmsetupArgs.push_back (StringConverter::Split (devPath, "/").back()); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("dmsetup", dmsetupArgs); + break; + } + catch (...) + { + if (t > 20) + throw; + + Thread::Sleep (100); + } + } + + for (int t = 0; FilesystemPath (devPath).IsBlockDevice() && t < 20; t++) + { + Thread::Sleep (100); + } + + devPath = string (mountedVolume->VirtualDevice) + "_" + StringConverter::ToSingle (devCount++); + } + } + + HostDeviceList CoreLinux::GetHostDevices (bool pathListOnly) const + { + HostDeviceList devices; + TextReader tr ("/proc/partitions"); + + string line; + while (tr.ReadLine (line)) + { + vector fields = StringConverter::Split (line); + + if (fields.size() != 4 + || fields[3].find ("loop") == 0 // skip loop devices + || fields[3].find ("cloop") == 0 + || fields[3].find ("ram") == 0 // skip RAM devices + || fields[3].find ("dm-") == 0 // skip device mapper devices + || fields[2] == "1" // skip extended partitions + ) + continue; + + try + { + StringConverter::ToUInt32 (fields[0]); + } + catch (...) + { + continue; + } + + try + { + make_shared_auto (HostDevice, hostDevice); + + hostDevice->Path = string (fields[3].find ("/dev/") == string::npos ? "/dev/" : "") + fields[3]; + + if (!pathListOnly) + { + hostDevice->Size = StringConverter::ToUInt64 (fields[2]) * 1024; + hostDevice->MountPoint = GetDeviceMountPoint (hostDevice->Path); + hostDevice->SystemNumber = 0; + } + + try + { + StringConverter::GetTrailingNumber (fields[3]); + if (devices.size() > 0) + { + HostDevice &prevDev = **--devices.end(); + if (string (hostDevice->Path).find (prevDev.Path) == 0) + { + prevDev.Partitions.push_back (hostDevice); + continue; + } + } + } + catch (...) { } + + devices.push_back (hostDevice); + continue; + } + catch (...) + { + continue; + } + } + + return devices; + } + + MountedFilesystemList CoreLinux::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const + { + MountedFilesystemList mountedFilesystems; + DevicePath realDevicePath = devicePath; + + if (!devicePath.IsEmpty()) + { + char *resolvedPath = realpath (string (devicePath).c_str(), NULL); + if (resolvedPath) + { + realDevicePath = resolvedPath; + free (resolvedPath); + } + } + + FILE *mtab = fopen ("/etc/mtab", "r"); + + if (!mtab) + mtab = fopen ("/proc/mounts", "r"); + + throw_sys_sub_if (!mtab, "/proc/mounts"); + finally_do_arg (FILE *, mtab, { fclose (finally_arg); }); + + static Mutex mutex; + ScopeLock sl (mutex); + + struct mntent *entry; + while ((entry = getmntent (mtab)) != nullptr) + { + make_shared_auto (MountedFilesystem, mf); + + if (entry->mnt_fsname) + mf->Device = DevicePath (entry->mnt_fsname); + else + continue; + + if (entry->mnt_dir) + mf->MountPoint = DirectoryPath (entry->mnt_dir); + + if (entry->mnt_type) + mf->Type = entry->mnt_type; + + if ((devicePath.IsEmpty() || devicePath == mf->Device || realDevicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint)) + mountedFilesystems.push_back (mf); + } + + return mountedFilesystems; + } + + void CoreLinux::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const + { + bool fsMounted = false; + + try + { + if (!FilesystemSupportsUnixPermissions (devicePath)) + { + stringstream userMountOptions; + userMountOptions << "uid=" << GetRealUserId() << ",gid=" << GetRealGroupId() << ",umask=077" << (!systemMountOptions.empty() ? "," : ""); + + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, userMountOptions.str() + systemMountOptions); + fsMounted = true; + } + } + catch (...) { } + + if (!fsMounted) + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions); + } + + void CoreLinux::MountVolumeNative (shared_ptr volume, MountOptions &options, const DirectoryPath &auxMountPoint) const + { + bool xts = (typeid (*volume->GetEncryptionMode()) == typeid (EncryptionModeXTS)); + bool lrw = (typeid (*volume->GetEncryptionMode()) == typeid (EncryptionModeLRW)); + + if (options.NoKernelCrypto + || (!xts && (!lrw || volume->GetEncryptionAlgorithm()->GetCiphers().size() > 1 || volume->GetEncryptionAlgorithm()->GetMinBlockSize() != 16)) + || volume->GetProtectionType() == VolumeProtection::HiddenVolumeReadOnly) + { + throw NotApplicable (SRC_POS); + } + + if (!SystemInfo::IsVersionAtLeast (2, 6, xts ? 24 : 20)) + throw NotApplicable (SRC_POS); + + // Load device mapper kernel module + list execArgs; + foreach (const string &dmModule, StringConverter::Split ("dm_mod dm-mod dm")) + { + execArgs.clear(); + execArgs.push_back (dmModule); + + try + { + Process::Execute ("modprobe", execArgs); + break; + } + catch (...) { } + } + + bool loopDevAttached = false; + bool nativeDevCreated = false; + bool filesystemMounted = false; + + // Attach volume to loopback device if required + VolumePath volumePath = volume->GetPath(); + if (!volumePath.IsDevice()) + { + volumePath = AttachFileToLoopDevice (volumePath, options.Protection == VolumeProtection::ReadOnly); + loopDevAttached = true; + } + + string nativeDevPath; + + try + { + // Create virtual device using device mapper + size_t nativeDevCount = 0; + size_t secondaryKeyOffset = volume->GetEncryptionMode()->GetKey().Size(); + size_t cipherCount = volume->GetEncryptionAlgorithm()->GetCiphers().size(); + + foreach_reverse_ref (const Cipher &cipher, volume->GetEncryptionAlgorithm()->GetCiphers()) + { + stringstream dmCreateArgs; + dmCreateArgs << "0 " << volume->GetSize() / ENCRYPTION_DATA_UNIT_SIZE << " crypt "; + + // Mode + dmCreateArgs << StringConverter::ToLower (StringConverter::ToSingle (cipher.GetName())) << (xts ? (SystemInfo::IsVersionAtLeast (2, 6, 33) ? "-xts-plain64 " : "-xts-plain ") : "-lrw-benbi "); + + size_t keyArgOffset = dmCreateArgs.str().size(); + dmCreateArgs << setw (cipher.GetKeySize() * (xts ? 4 : 2) + (xts ? 0 : 16 * 2)) << 0 << setw (0); + + // Sector and data unit offset + uint64 startSector = volume->GetLayout()->GetDataOffset (volume->GetHostSize()) / ENCRYPTION_DATA_UNIT_SIZE; + + dmCreateArgs << ' ' << (xts ? startSector + volume->GetEncryptionMode()->GetSectorOffset() : 0) << ' '; + if (nativeDevCount == 0) + dmCreateArgs << string (volumePath) << ' ' << startSector; + else + dmCreateArgs << nativeDevPath << " 0"; + + SecureBuffer dmCreateArgsBuf (dmCreateArgs.str().size()); + dmCreateArgsBuf.CopyFrom (ConstBufferPtr ((byte *) dmCreateArgs.str().c_str(), dmCreateArgs.str().size())); + + // Keys + const SecureBuffer &cipherKey = cipher.GetKey(); + secondaryKeyOffset -= cipherKey.Size(); + ConstBufferPtr secondaryKey = volume->GetEncryptionMode()->GetKey().GetRange (xts ? secondaryKeyOffset : 0, xts ? cipherKey.Size() : 16); + + SecureBuffer hexStr (3); + for (size_t i = 0; i < cipherKey.Size(); ++i) + { + sprintf ((char *) hexStr.Ptr(), "%02x", (int) cipherKey[i]); + dmCreateArgsBuf.GetRange (keyArgOffset + i * 2, 2).CopyFrom (hexStr.GetRange (0, 2)); + + if (lrw && i >= 16) + continue; + + sprintf ((char *) hexStr.Ptr(), "%02x", (int) secondaryKey[i]); + dmCreateArgsBuf.GetRange (keyArgOffset + cipherKey.Size() * 2 + i * 2, 2).CopyFrom (hexStr.GetRange (0, 2)); + } + + stringstream nativeDevName; + nativeDevName << "truecrypt" << options.SlotNumber; + + if (nativeDevCount != cipherCount - 1) + nativeDevName << "_" << cipherCount - nativeDevCount - 2; + + nativeDevPath = "/dev/mapper/" + nativeDevName.str(); + + execArgs.clear(); + execArgs.push_back ("create"); + execArgs.push_back (nativeDevName.str()); + + Process::Execute ("dmsetup", execArgs, -1, nullptr, &dmCreateArgsBuf); + + // Wait for the device to be created + for (int t = 0; true; t++) + { + try + { + FilesystemPath (nativeDevPath).GetType(); + break; + } + catch (...) + { + if (t > 20) + throw; + + Thread::Sleep (100); + } + } + + nativeDevCreated = true; + ++nativeDevCount; + } + + // Test whether the device mapper is able to read and decrypt the last sector + SecureBuffer lastSectorBuf (volume->GetSectorSize()); + uint64 lastSectorOffset = volume->GetSize() - volume->GetSectorSize(); + + File nativeDev; + nativeDev.Open (nativeDevPath); + nativeDev.ReadAt (lastSectorBuf, lastSectorOffset); + + SecureBuffer lastSectorBuf2 (volume->GetSectorSize()); + volume->ReadSectors (lastSectorBuf2, lastSectorOffset); + + if (memcmp (lastSectorBuf.Ptr(), lastSectorBuf2.Ptr(), volume->GetSectorSize()) != 0) + throw KernelCryptoServiceTestFailed (SRC_POS); + + // Mount filesystem + if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty()) + { + MountFilesystem (nativeDevPath, *options.MountPoint, + StringConverter::ToSingle (options.FilesystemType), + options.Protection == VolumeProtection::ReadOnly, + StringConverter::ToSingle (options.FilesystemOptions)); + + filesystemMounted = true; + } + + FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath, volumePath); + } + catch (...) + { + try + { + if (filesystemMounted) + DismountFilesystem (*options.MountPoint, true); + } + catch (...) { } + + try + { + if (nativeDevCreated) + { + make_shared_auto (VolumeInfo, vol); + vol->VirtualDevice = nativeDevPath; + DismountNativeVolume (vol); + } + } + catch (...) { } + + try + { + if (loopDevAttached) + DetachLoopDevice (volumePath); + } + catch (...) { } + + throw; + } + } + + auto_ptr Core (new CoreServiceProxy ); + auto_ptr CoreDirect (new CoreLinux); +} diff --git a/src/Core/Unix/Linux/CoreLinux.h b/src/Core/Unix/Linux/CoreLinux.h new file mode 100644 index 00000000..5758d651 --- /dev/null +++ b/src/Core/Unix/Linux/CoreLinux.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreLinux +#define TC_HEADER_Core_CoreLinux + +#include "System.h" +#include "Core/Unix/CoreUnix.h" + +namespace TrueCrypt +{ + class CoreLinux : public CoreUnix + { + public: + CoreLinux (); + virtual ~CoreLinux (); + + virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const; + + protected: + virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const; + virtual void DetachLoopDevice (const DevicePath &devicePath) const; + virtual void DismountNativeVolume (shared_ptr mountedVolume) const; + virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const; + virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const; + virtual void MountVolumeNative (shared_ptr volume, MountOptions &options, const DirectoryPath &auxMountPoint) const; + + private: + CoreLinux (const CoreLinux &); + CoreLinux &operator= (const CoreLinux &); + }; +} + +#endif // TC_HEADER_Core_CoreLinux diff --git a/src/Core/Unix/Linux/System.h b/src/Core/Unix/Linux/System.h new file mode 100644 index 00000000..20a4f82d --- /dev/null +++ b/src/Core/Unix/Linux/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Linux_System +#define TC_HEADER_Platform_Linux_System + +#endif // TC_HEADER_Platform_Linux_System diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.cpp b/src/Core/Unix/MacOSX/CoreMacOSX.cpp new file mode 100644 index 00000000..b7aa08c7 --- /dev/null +++ b/src/Core/Unix/MacOSX/CoreMacOSX.cpp @@ -0,0 +1,215 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CoreMacOSX.h" +#include "Driver/Fuse/FuseService.h" +#include "Core/Unix/CoreServiceProxy.h" + +namespace TrueCrypt +{ + CoreMacOSX::CoreMacOSX () + { + } + + CoreMacOSX::~CoreMacOSX () + { + } + + shared_ptr CoreMacOSX::DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo) + { + if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice()) + { + list args; + args.push_back ("detach"); + args.push_back (mountedVolume->VirtualDevice); + + if (ignoreOpenFiles) + args.push_back ("-force"); + + try + { + Process::Execute ("hdiutil", args); + } + catch (ExecutedProcessFailed &e) + { + if (!ignoreOpenFiles) + { + string err = e.GetErrorOutput(); + + if (err.find ("couldn't unmount") != string::npos + || err.find ("busy") != string::npos + || err.find ("49153") != string::npos) + { + throw MountedVolumeInUse (SRC_POS); + } + } + + throw; + } + } + + if (syncVolumeInfo || mountedVolume->Protection == VolumeProtection::HiddenVolumeReadOnly) + { + sync(); + VolumeInfoList ml = GetMountedVolumes (mountedVolume->Path); + + if (ml.size() > 0) + mountedVolume = ml.front(); + } + + list args; + args.push_back ("--"); + args.push_back (mountedVolume->AuxMountPoint); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("umount", args); + break; + } + catch (ExecutedProcessFailed&) + { + if (t > 10) + throw; + Thread::Sleep (200); + } + } + + try + { + mountedVolume->AuxMountPoint.Delete(); + } + catch (...) { } + + return mountedVolume; + } + + void CoreMacOSX::CheckFilesystem (shared_ptr mountedVolume, bool repair) const + { + list args; + args.push_back ("/Applications/Utilities/Disk Utility.app"); + Process::Execute ("open", args); + } + + void CoreMacOSX::MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const + { + // Check FUSE version + char fuseVersionString[MAXHOSTNAMELEN + 1] = { 0 }; + size_t fuseVersionStringLength = MAXHOSTNAMELEN; + + if (sysctlbyname ("macfuse.version.number", fuseVersionString, &fuseVersionStringLength, NULL, 0) != 0) + throw HigherFuseVersionRequired (SRC_POS); + + vector fuseVersion = StringConverter::Split (string (fuseVersionString), "."); + if (fuseVersion.size() < 2) + throw HigherFuseVersionRequired (SRC_POS); + + uint32 fuseVersionMajor = StringConverter::ToUInt32 (fuseVersion[0]); + uint32 fuseVersionMinor = StringConverter::ToUInt32 (fuseVersion[1]); + + if (fuseVersionMajor < 1 || (fuseVersionMajor == 1 && fuseVersionMinor < 3)) + throw HigherFuseVersionRequired (SRC_POS); + + // Mount volume image + string volImage = string (auxMountPoint) + FuseService::GetVolumeImagePath(); + + list args; + args.push_back ("attach"); + args.push_back (volImage); + args.push_back ("-plist"); + args.push_back ("-noautofsck"); + args.push_back ("-imagekey"); + args.push_back ("diskimage-class=CRawDiskImage"); + + if (!options.NoFilesystem && options.MountPoint && !options.MountPoint->IsEmpty()) + { + args.push_back ("-mount"); + args.push_back ("required"); + + // Let the system specify mount point except when the user specified a non-default one + if (string (*options.MountPoint).find (GetDefaultMountPointPrefix()) != 0) + { + args.push_back ("-mountpoint"); + args.push_back (*options.MountPoint); + } + } + else + args.push_back ("-nomount"); + + if (options.Protection == VolumeProtection::ReadOnly) + args.push_back ("-readonly"); + + string xml; + + while (true) + { + try + { + xml = Process::Execute ("hdiutil", args); + break; + } + catch (ExecutedProcessFailed &e) + { + if (e.GetErrorOutput().find ("noautofsck") != string::npos) + { + args.remove ("-noautofsck"); + continue; + } + + throw; + } + } + + size_t p = xml.find ("dev-entry"); + if (p == string::npos) + throw ParameterIncorrect (SRC_POS); + + p = xml.find ("", p); + if (p == string::npos) + throw ParameterIncorrect (SRC_POS); + p += 8; + + size_t e = xml.find ("", p); + if (e == string::npos) + throw ParameterIncorrect (SRC_POS); + + DevicePath virtualDev = StringConverter::Trim (xml.substr (p, e - p)); + + try + { + FuseService::SendAuxDeviceInfo (auxMountPoint, virtualDev); + } + catch (...) + { + try + { + list args; + args.push_back ("detach"); + args.push_back (volImage); + args.push_back ("-force"); + + Process::Execute ("hdiutil", args); + } + catch (ExecutedProcessFailed&) { } + throw; + } + } + + auto_ptr Core (new CoreServiceProxy ); + auto_ptr CoreDirect (new CoreMacOSX); +} diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.h b/src/Core/Unix/MacOSX/CoreMacOSX.h new file mode 100644 index 00000000..eee11d6f --- /dev/null +++ b/src/Core/Unix/MacOSX/CoreMacOSX.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreMacOSX +#define TC_HEADER_Core_CoreMacOSX + +#include "System.h" +#include "Core/Unix/FreeBSD/CoreFreeBSD.h" + +namespace TrueCrypt +{ + class CoreMacOSX : public CoreFreeBSD + { + public: + CoreMacOSX (); + virtual ~CoreMacOSX (); + + virtual void CheckFilesystem (shared_ptr mountedVolume, bool repair = false) const; + virtual shared_ptr DismountVolume (shared_ptr mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false); + virtual string GetDefaultMountPointPrefix () const { return "/Volumes/truecrypt"; } + + protected: + virtual void MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const; + + private: + CoreMacOSX (const CoreMacOSX &); + CoreMacOSX &operator= (const CoreMacOSX &); + }; +} + +#endif // TC_HEADER_Core_CoreMacOSX diff --git a/src/Core/Unix/MacOSX/System.h b/src/Core/Unix/MacOSX/System.h new file mode 100644 index 00000000..073e17a3 --- /dev/null +++ b/src/Core/Unix/MacOSX/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_MacOSX_System +#define TC_HEADER_Platform_MacOSX_System + +#endif // TC_HEADER_Platform_MacOSX_System diff --git a/src/Core/Unix/MountedFilesystem.h b/src/Core/Unix/MountedFilesystem.h new file mode 100644 index 00000000..6e704d3c --- /dev/null +++ b/src/Core/Unix/MountedFilesystem.h @@ -0,0 +1,27 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_Unix_MountedFilesystem +#define TC_HEADER_Core_Unix_MountedFilesystem + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + struct MountedFilesystem + { + public: + DevicePath Device; + DirectoryPath MountPoint; + string Type; + }; + + typedef list < shared_ptr > MountedFilesystemList; +} + +#endif // TC_HEADER_Core_Unix_MountedFilesystem diff --git a/src/Core/Unix/Solaris/CoreSolaris.cpp b/src/Core/Unix/Solaris/CoreSolaris.cpp new file mode 100644 index 00000000..63736db3 --- /dev/null +++ b/src/Core/Unix/Solaris/CoreSolaris.cpp @@ -0,0 +1,174 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include +#include "CoreSolaris.h" +#include "Core/Unix/CoreServiceProxy.h" + +namespace TrueCrypt +{ + CoreSolaris::CoreSolaris () + { + } + + CoreSolaris::~CoreSolaris () + { + } + + DevicePath CoreSolaris::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const + { + list args; + args.push_back ("-a"); + args.push_back (filePath); + + return StringConverter::Trim (Process::Execute ("lofiadm", args)); + } + + void CoreSolaris::DetachLoopDevice (const DevicePath &devicePath) const + { + list args; + args.push_back ("-d"); + args.push_back (devicePath); + + for (int t = 0; true; t++) + { + try + { + Process::Execute ("lofiadm", args); + break; + } + catch (ExecutedProcessFailed&) + { + if (t > 5) + throw; + Thread::Sleep (200); + } + } + } + + HostDeviceList CoreSolaris::GetHostDevices (bool pathListOnly) const + { + HostDeviceList devices; + + foreach_ref (const FilePath &devPath, Directory::GetFilePaths ("/dev/rdsk", false)) + { + string drivePath = devPath; + if (drivePath.rfind ("p0") == drivePath.size() - 2) + { + make_shared_auto (HostDevice, device); + device->Path = drivePath; + + try + { + device->Size = GetDeviceSize (device->Path); + } + catch (...) + { + device->Size = 0; + } + + if (device->Size == 0) + continue; + + device->MountPoint = GetDeviceMountPoint (device->Path); + device->SystemNumber = 0; + + devices.push_back (device); + + for (int partNumber = 1; partNumber <= 32; partNumber++) + { + stringstream partPath; + partPath << drivePath.substr (0, drivePath.size() - 1) << partNumber; + + if (FilesystemPath (partPath.str()).IsBlockDevice() || FilesystemPath (partPath.str()).IsCharacterDevice()) + { + make_shared_auto (HostDevice, partition); + partition->Path = partPath.str(); + + try + { + partition->Size = GetDeviceSize (partition->Path); + } + catch (...) + { + partition->Size = 0; + } + + if (partition->Size == 0) + continue; + + partition->MountPoint = GetDeviceMountPoint (partition->Path); + partition->SystemNumber = 0; + + device->Partitions.push_back (partition); + } + } + } + } + + return devices; + } + + MountedFilesystemList CoreSolaris::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const + { + MountedFilesystemList mountedFilesystems; + + FILE *mtab = fopen ("/etc/mnttab", "r"); + throw_sys_sub_if (!mtab, "/etc/mnttab"); + finally_do_arg (FILE *, mtab, { fclose (finally_arg); }); + + int getmntentResult; + struct mnttab entry; + while ((getmntentResult = getmntent (mtab, &entry)) == 0) + { + make_shared_auto (MountedFilesystem, mf); + + if (entry.mnt_special) + mf->Device = DevicePath (entry.mnt_special); + else + continue; + + if (entry.mnt_mountp) + mf->MountPoint = DirectoryPath (entry.mnt_mountp); + + if (entry.mnt_fstype) + mf->Type = entry.mnt_fstype; + + if ((devicePath.IsEmpty() || devicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint)) + mountedFilesystems.push_back (mf); + } + + throw_sys_if (getmntentResult > 0); + + return mountedFilesystems; + } + + void CoreSolaris::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const + { + try + { + // Try to mount FAT by default as mount is unable to probe filesystem type on Solaris + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType.empty() ? "pcfs" : filesystemType, readOnly, systemMountOptions); + } + catch (ExecutedProcessFailed&) + { + if (!filesystemType.empty()) + throw; + + CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions); + } + } + + auto_ptr Core (new CoreServiceProxy ); + auto_ptr CoreDirect (new CoreSolaris); +} diff --git a/src/Core/Unix/Solaris/CoreSolaris.h b/src/Core/Unix/Solaris/CoreSolaris.h new file mode 100644 index 00000000..76dd1945 --- /dev/null +++ b/src/Core/Unix/Solaris/CoreSolaris.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Core_CoreSolaris +#define TC_HEADER_Core_CoreSolaris + +#include "System.h" +#include "Core/Unix/CoreUnix.h" + +namespace TrueCrypt +{ + class CoreSolaris : public CoreUnix + { + public: + CoreSolaris (); + virtual ~CoreSolaris (); + + virtual HostDeviceList GetHostDevices (bool pathListOnly = false) const; + + protected: + virtual DevicePath AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const; + virtual void DetachLoopDevice (const DevicePath &devicePath) const; + virtual MountedFilesystemList GetMountedFilesystems (const DevicePath &devicePath = DevicePath(), const DirectoryPath &mountPoint = DirectoryPath()) const; + virtual void MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const; + + private: + CoreSolaris (const CoreSolaris &); + CoreSolaris &operator= (const CoreSolaris &); + }; +} + +#endif // TC_HEADER_Core_CoreSolaris diff --git a/src/Core/Unix/Solaris/System.h b/src/Core/Unix/Solaris/System.h new file mode 100644 index 00000000..039dd406 --- /dev/null +++ b/src/Core/Unix/Solaris/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Solaris_System +#define TC_HEADER_Platform_Solaris_System + +#endif // TC_HEADER_Platform_Solaris_System diff --git a/src/Core/Unix/System.h b/src/Core/Unix/System.h new file mode 100644 index 00000000..63d565b5 --- /dev/null +++ b/src/Core/Unix/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_System +#define TC_HEADER_Platform_Unix_System + +#endif // TC_HEADER_Platform_Unix_System diff --git a/src/Core/VolumeCreator.cpp b/src/Core/VolumeCreator.cpp new file mode 100644 index 00000000..6011efd0 --- /dev/null +++ b/src/Core/VolumeCreator.cpp @@ -0,0 +1,345 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Volume/EncryptionTest.h" +#include "Volume/EncryptionModeXTS.h" +#include "Core.h" + +#ifdef TC_UNIX +#include +#include +#include +#endif + +#include "VolumeCreator.h" +#include "FatFormatter.h" + +namespace TrueCrypt +{ + VolumeCreator::VolumeCreator () + : SizeDone (0) + { + } + + VolumeCreator::~VolumeCreator () + { + } + + void VolumeCreator::Abort () + { + AbortRequested = true; + } + + void VolumeCreator::CheckResult () + { + if (ThreadException) + ThreadException->Throw(); + } + + void VolumeCreator::CreationThread () + { + try + { + uint64 endOffset; + uint64 filesystemSize = Layout->GetDataSize (HostSize); + + if (filesystemSize < 1) + throw ParameterIncorrect (SRC_POS); + + DataStart = Layout->GetDataOffset (HostSize); + WriteOffset = DataStart; + endOffset = DataStart + Layout->GetDataSize (HostSize); + + VolumeFile->SeekAt (DataStart); + + // Create filesystem + if (Options->Filesystem == VolumeCreationOptions::FilesystemType::FAT) + { + if (filesystemSize < TC_MIN_FAT_FS_SIZE || filesystemSize > TC_MAX_FAT_SECTOR_COUNT * Options->SectorSize) + throw ParameterIncorrect (SRC_POS); + + struct WriteSectorCallback : public FatFormatter::WriteSectorCallback + { + WriteSectorCallback (VolumeCreator *creator) : Creator (creator), OutputBuffer (File::GetOptimalWriteSize()), OutputBufferWritePos (0) { } + + virtual bool operator() (const BufferPtr §or) + { + OutputBuffer.GetRange (OutputBufferWritePos, sector.Size()).CopyFrom (sector); + OutputBufferWritePos += sector.Size(); + + if (OutputBufferWritePos >= OutputBuffer.Size()) + FlushOutputBuffer(); + + return !Creator->AbortRequested; + } + + void FlushOutputBuffer () + { + if (OutputBufferWritePos > 0) + { + Creator->Options->EA->EncryptSectors (OutputBuffer.GetRange (0, OutputBufferWritePos), + Creator->WriteOffset / ENCRYPTION_DATA_UNIT_SIZE, OutputBufferWritePos / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + + Creator->VolumeFile->Write (OutputBuffer.GetRange (0, OutputBufferWritePos)); + + Creator->WriteOffset += OutputBufferWritePos; + Creator->SizeDone.Set (Creator->WriteOffset - Creator->DataStart); + + OutputBufferWritePos = 0; + } + } + + VolumeCreator *Creator; + SecureBuffer OutputBuffer; + size_t OutputBufferWritePos; + }; + + WriteSectorCallback sectorWriter (this); + FatFormatter::Format (sectorWriter, filesystemSize, Options->FilesystemClusterSize, Options->SectorSize); + sectorWriter.FlushOutputBuffer(); + } + + if (!Options->Quick) + { + // Empty sectors are encrypted with different key to randomize plaintext + Core->RandomizeEncryptionAlgorithmKey (Options->EA); + + SecureBuffer outputBuffer (File::GetOptimalWriteSize()); + uint64 dataFragmentLength = outputBuffer.Size(); + + while (!AbortRequested && WriteOffset < endOffset) + { + if (WriteOffset + dataFragmentLength > endOffset) + dataFragmentLength = endOffset - WriteOffset; + + outputBuffer.Zero(); + Options->EA->EncryptSectors (outputBuffer, WriteOffset / ENCRYPTION_DATA_UNIT_SIZE, dataFragmentLength / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + VolumeFile->Write (outputBuffer, (size_t) dataFragmentLength); + + WriteOffset += dataFragmentLength; + SizeDone.Set (WriteOffset - DataStart); + } + } + + if (!AbortRequested) + { + SizeDone.Set (Options->Size); + + // Backup header + SecureBuffer backupHeader (Layout->GetHeaderSize()); + + SecureBuffer backupHeaderSalt (VolumeHeader::GetSaltSize()); + RandomNumberGenerator::GetData (backupHeaderSalt); + + Options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, backupHeaderSalt); + + Layout->GetHeader()->EncryptNew (backupHeader, backupHeaderSalt, HeaderKey, Options->VolumeHeaderKdf); + + if (Options->Quick || Options->Type == VolumeType::Hidden) + VolumeFile->SeekEnd (Layout->GetBackupHeaderOffset()); + + VolumeFile->Write (backupHeader); + + if (Options->Type == VolumeType::Normal) + { + // Write random data to space reserved for hidden volume backup header + Core->RandomizeEncryptionAlgorithmKey (Options->EA); + Options->EA->Encrypt (backupHeader); + + VolumeFile->Write (backupHeader); + } + + VolumeFile->Flush(); + } + } + catch (Exception &e) + { + ThreadException.reset (e.CloneNew()); + } + catch (exception &e) + { + ThreadException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e))); + } + catch (...) + { + ThreadException.reset (new UnknownException (SRC_POS)); + } + + VolumeFile.reset(); + mProgressInfo.CreationInProgress = false; + } + + void VolumeCreator::CreateVolume (shared_ptr options) + { + EncryptionTest::TestAll(); + + { +#ifdef TC_UNIX + // Temporarily take ownership of a device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + if (!Core->HasAdminPrivileges() && options->Path.IsDevice()) + { + origDeviceOwner = FilesystemPath (wstring (options->Path)).GetOwner(); + Core->SetFileOwner (options->Path, UserId (getuid())); + } + + finally_do_arg2 (FilesystemPath, options->Path, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); +#endif + + VolumeFile.reset (new File); + VolumeFile->Open (options->Path, + (options->Path.IsDevice() || options->Type == VolumeType::Hidden) ? File::OpenReadWrite : File::CreateReadWrite, + File::ShareNone); + + HostSize = VolumeFile->Length(); + } + + try + { + // Sector size + if (options->Path.IsDevice()) + { + options->SectorSize = VolumeFile->GetDeviceSectorSize(); + + if (options->SectorSize < TC_MIN_VOLUME_SECTOR_SIZE + || options->SectorSize > TC_MAX_VOLUME_SECTOR_SIZE +#if !defined (TC_LINUX) + || options->SectorSize != TC_SECTOR_SIZE_LEGACY +#endif + || options->SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) + { + throw UnsupportedSectorSize (SRC_POS); + } + } + else + options->SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME; + + // Volume layout + switch (options->Type) + { + case VolumeType::Normal: + Layout.reset (new VolumeLayoutV2Normal()); + break; + + case VolumeType::Hidden: + Layout.reset (new VolumeLayoutV2Hidden()); + + if (HostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE) + throw ParameterIncorrect (SRC_POS); + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + // Volume header + shared_ptr header (Layout->GetHeader()); + SecureBuffer headerBuffer (Layout->GetHeaderSize()); + + VolumeHeaderCreationOptions headerOptions; + headerOptions.EA = options->EA; + headerOptions.Kdf = options->VolumeHeaderKdf; + headerOptions.Type = options->Type; + + headerOptions.SectorSize = options->SectorSize; + + if (options->Type == VolumeType::Hidden) + headerOptions.VolumeDataStart = HostSize - Layout->GetHeaderSize() * 2 - options->Size; + else + headerOptions.VolumeDataStart = Layout->GetHeaderSize() * 2; + + headerOptions.VolumeDataSize = Layout->GetMaxDataSize (options->Size); + + if (headerOptions.VolumeDataSize < 1) + throw ParameterIncorrect (SRC_POS); + + // Master data key + MasterKey.Allocate (options->EA->GetKeySize() * 2); + RandomNumberGenerator::GetData (MasterKey); + headerOptions.DataKey = MasterKey; + + // PKCS5 salt + SecureBuffer salt (VolumeHeader::GetSaltSize()); + RandomNumberGenerator::GetData (salt); + headerOptions.Salt = salt; + + // Header key + HeaderKey.Allocate (VolumeHeader::GetLargestSerializedKeySize()); + PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password); + options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, salt); + headerOptions.HeaderKey = HeaderKey; + + header->Create (headerBuffer, headerOptions); + + // Write new header + if (Layout->GetHeaderOffset() >= 0) + VolumeFile->SeekAt (Layout->GetHeaderOffset()); + else + VolumeFile->SeekEnd (Layout->GetHeaderOffset()); + + VolumeFile->Write (headerBuffer); + + if (options->Type == VolumeType::Normal) + { + // Write random data to space reserved for hidden volume header + Core->RandomizeEncryptionAlgorithmKey (options->EA); + options->EA->Encrypt (headerBuffer); + + VolumeFile->Write (headerBuffer); + } + + // Data area keys + options->EA->SetKey (MasterKey.GetRange (0, options->EA->GetKeySize())); + shared_ptr mode (new EncryptionModeXTS ()); + mode->SetKey (MasterKey.GetRange (options->EA->GetKeySize(), options->EA->GetKeySize())); + options->EA->SetMode (mode); + + Options = options; + AbortRequested = false; + + mProgressInfo.CreationInProgress = true; + + struct ThreadFunctor : public Functor + { + ThreadFunctor (VolumeCreator *creator) : Creator (creator) { } + virtual void operator() () + { + Creator->CreationThread (); + } + VolumeCreator *Creator; + }; + + Thread thread; + thread.Start (new ThreadFunctor (this)); + } + catch (...) + { + VolumeFile.reset(); + throw; + } + } + + VolumeCreator::KeyInfo VolumeCreator::GetKeyInfo () const + { + KeyInfo info; + info.HeaderKey = HeaderKey; + info.MasterKey = MasterKey; + return info; + } + + VolumeCreator::ProgressInfo VolumeCreator::GetProgressInfo () + { + mProgressInfo.SizeDone = SizeDone.Get(); + return mProgressInfo; + } +} diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h new file mode 100644 index 00000000..4e8cf61e --- /dev/null +++ b/src/Core/VolumeCreator.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeCreator +#define TC_HEADER_Volume_VolumeCreator + +#include "Platform/Platform.h" +#include "Volume/Volume.h" +#include "RandomNumberGenerator.h" + +namespace TrueCrypt +{ + + struct VolumeCreationOptions + { + VolumePath Path; + VolumeType::Enum Type; + uint64 Size; + shared_ptr Password; + shared_ptr Keyfiles; + shared_ptr VolumeHeaderKdf; + shared_ptr EA; + bool Quick; + + struct FilesystemType + { + enum Enum + { + Unknown = 0, + None, + FAT, + NTFS, + Ext2, + Ext3, + Ext4, + MacOsExt, + UFS + }; + + static Enum GetPlatformNative () + { +#ifdef TC_WINDOWS + return VolumeCreationOptions::FilesystemType::NTFS; +#elif defined (TC_LINUX) + return VolumeCreationOptions::FilesystemType::Ext3; +#elif defined (TC_MACOSX) + return VolumeCreationOptions::FilesystemType::MacOsExt; +#elif defined (TC_FREEBSD) || defined (TC_SOLARIS) + return VolumeCreationOptions::FilesystemType::UFS; +#else + return VolumeCreationOptions::FilesystemType::FAT; +#endif + } + }; + + FilesystemType::Enum Filesystem; + uint32 FilesystemClusterSize; + uint32 SectorSize; + }; + + class VolumeCreator + { + public: + + struct ProgressInfo + { + bool CreationInProgress; + uint64 TotalSize; + uint64 SizeDone; + }; + + struct KeyInfo + { + ConstBufferPtr HeaderKey; + ConstBufferPtr MasterKey; + }; + + VolumeCreator (); + virtual ~VolumeCreator (); + + void Abort (); + void CheckResult (); + void CreateVolume (shared_ptr options); + KeyInfo GetKeyInfo () const; + ProgressInfo GetProgressInfo (); + + protected: + void CreationThread (); + + volatile bool AbortRequested; + volatile bool CreationInProgress; + uint64 DataStart; + uint64 HostSize; + shared_ptr Options; + shared_ptr ThreadException; + uint64 VolumeSize; + + shared_ptr Layout; + shared_ptr VolumeFile; + SharedVal SizeDone; + uint64 WriteOffset; + ProgressInfo mProgressInfo; + + SecureBuffer HeaderKey; + shared_ptr PasswordKey; + SecureBuffer MasterKey; + + private: + VolumeCreator (const VolumeCreator &); + VolumeCreator &operator= (const VolumeCreator &); + }; +} + +#endif // TC_HEADER_Volume_VolumeCreator diff --git a/src/Driver/Fuse/Driver.make b/src/Driver/Fuse/Driver.make new file mode 100644 index 00000000..7e08e361 --- /dev/null +++ b/src/Driver/Fuse/Driver.make @@ -0,0 +1,16 @@ +# +# Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +NAME := Driver + +OBJS := +OBJS += FuseService.o + +CXXFLAGS += $(shell pkg-config fuse --cflags) + +include $(BUILD_INC)/Makefile.inc diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp new file mode 100644 index 00000000..fda56e0f --- /dev/null +++ b/src/Driver/Fuse/FuseService.cpp @@ -0,0 +1,592 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#define FUSE_USE_VERSION 25 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FuseService.h" +#include "Platform/FileStream.h" +#include "Platform/MemoryStream.h" +#include "Platform/Serializable.h" +#include "Platform/SystemLog.h" +#include "Platform/Unix/Pipe.h" +#include "Platform/Unix/Poller.h" +#include "Volume/EncryptionThreadPool.h" +#include "Core/Core.h" + +namespace TrueCrypt +{ + static int fuse_service_access (const char *path, int mask) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return 0; + } + + static void *fuse_service_init () + { + try + { + // Termination signals are handled by a separate process to allow clean dismount on shutdown + struct sigaction action; + Memory::Zero (&action, sizeof (action)); + action.sa_handler = SIG_IGN; + + sigaction (SIGINT, &action, nullptr); + sigaction (SIGQUIT, &action, nullptr); + sigaction (SIGTERM, &action, nullptr); + + if (!EncryptionThreadPool::IsRunning()) + EncryptionThreadPool::Start(); + } + catch (exception &e) + { + SystemLog::WriteException (e); + } + catch (...) + { + SystemLog::WriteException (UnknownException (SRC_POS)); + } + + return nullptr; + } + + static void fuse_service_destroy (void *userdata) + { + try + { + FuseService::Dismount(); + } + catch (exception &e) + { + SystemLog::WriteException (e); + } + catch (...) + { + SystemLog::WriteException (UnknownException (SRC_POS)); + } + } + + static int fuse_service_getattr (const char *path, struct stat *statData) + { + try + { + Memory::Zero (statData, sizeof(*statData)); + + statData->st_uid = FuseService::GetUserId(); + statData->st_gid = FuseService::GetGroupId(); + statData->st_atime = time (NULL); + statData->st_ctime = time (NULL); + statData->st_mtime = time (NULL); + + if (strcmp (path, "/") == 0) + { + statData->st_mode = S_IFDIR | 0500; + statData->st_nlink = 2; + } + else + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, FuseService::GetVolumeImagePath()) == 0) + { + statData->st_mode = S_IFREG | 0600; + statData->st_nlink = 1; + statData->st_size = FuseService::GetVolumeSize(); + } + else if (strcmp (path, FuseService::GetControlPath()) == 0) + { + statData->st_mode = S_IFREG | 0600; + statData->st_nlink = 1; + statData->st_size = FuseService::GetVolumeInfo()->Size(); + } + else + { + return -ENOENT; + } + } + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return 0; + } + + static int fuse_service_opendir (const char *path, struct fuse_file_info *fi) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, "/") != 0) + return -ENOENT; + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return 0; + } + + static int fuse_service_open (const char *path, struct fuse_file_info *fi) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, FuseService::GetVolumeImagePath()) == 0) + return 0; + + if (strcmp (path, FuseService::GetControlPath()) == 0) + { + fi->direct_io = 1; + return 0; + } + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + return -ENOENT; + } + + static int fuse_service_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, FuseService::GetVolumeImagePath()) == 0) + { + try + { + // Test for read beyond the end of the volume + if ((uint64) offset + size > FuseService::GetVolumeSize()) + size = FuseService::GetVolumeSize() - offset; + + size_t sectorSize = FuseService::GetVolumeSectorSize(); + if (size % sectorSize != 0 || offset % sectorSize != 0) + { + // Support for non-sector-aligned read operations is required by some loop device tools + // which may analyze the volume image before attaching it as a device + + uint64 alignedOffset = offset - (offset % sectorSize); + uint64 alignedSize = size + (offset % sectorSize); + + if (alignedSize % sectorSize != 0) + alignedSize += sectorSize - (alignedSize % sectorSize); + + SecureBuffer alignedBuffer (alignedSize); + + FuseService::ReadVolumeSectors (alignedBuffer, alignedOffset); + BufferPtr ((byte *) buf, size).CopyFrom (alignedBuffer.GetRange (offset % sectorSize, size)); + } + else + { + FuseService::ReadVolumeSectors (BufferPtr ((byte *) buf, size), offset); + } + } + catch (MissingVolumeData) + { + return 0; + } + + return size; + } + + if (strcmp (path, FuseService::GetControlPath()) == 0) + { + shared_ptr infoBuf = FuseService::GetVolumeInfo(); + BufferPtr outBuf ((byte *)buf, size); + + if (offset >= (off_t) infoBuf->Size()) + return 0; + + if (offset + size > infoBuf->Size()) + size = infoBuf->Size () - offset; + + outBuf.CopyFrom (infoBuf->GetRange (offset, size)); + return size; + } + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return -ENOENT; + } + + static int fuse_service_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, "/") != 0) + return -ENOENT; + + filler (buf, ".", NULL, 0); + filler (buf, "..", NULL, 0); + filler (buf, FuseService::GetVolumeImagePath() + 1, NULL, 0); + filler (buf, FuseService::GetControlPath() + 1, NULL, 0); + } + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return 0; + } + + static int fuse_service_write (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) + { + try + { + if (!FuseService::CheckAccessRights()) + return -EACCES; + + if (strcmp (path, FuseService::GetVolumeImagePath()) == 0) + { + FuseService::WriteVolumeSectors (BufferPtr ((byte *) buf, size), offset); + return size; + } + + if (strcmp (path, FuseService::GetControlPath()) == 0) + { + if (FuseService::AuxDeviceInfoReceived()) + return -EACCES; + + FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const byte *)buf, size)); + return size; + } + } +#ifdef TC_FREEBSD + // FreeBSD apparently retries failed write operations forever, which may lead to a system crash. + catch (VolumeReadOnly&) + { + return size; + } + catch (VolumeProtected&) + { + return size; + } +#endif + catch (...) + { + return FuseService::ExceptionToErrorCode(); + } + + return -ENOENT; + } + + bool FuseService::CheckAccessRights () + { + return fuse_get_context()->uid == 0 || fuse_get_context()->uid == UserId; + } + + void FuseService::CloseMountedVolume () + { + if (MountedVolume) + { + // This process will exit before the use count of MountedVolume reaches zero + if (MountedVolume->GetFile().use_count() > 1) + MountedVolume->GetFile()->Close(); + + if (MountedVolume.use_count() > 1) + delete MountedVolume.get(); + + MountedVolume.reset(); + } + } + + void FuseService::Dismount () + { + CloseMountedVolume(); + + if (EncryptionThreadPool::IsRunning()) + EncryptionThreadPool::Stop(); + } + + int FuseService::ExceptionToErrorCode () + { + try + { + throw; + } + catch (std::bad_alloc) + { + return -ENOMEM; + } + catch (ParameterIncorrect &e) + { + SystemLog::WriteException (e); + return -EINVAL; + } + catch (VolumeProtected&) + { + return -EPERM; + } + catch (VolumeReadOnly&) + { + return -EPERM; + } + catch (SystemException &e) + { + SystemLog::WriteException (e); + return -static_cast (e.GetErrorCode()); + } + catch (std::exception &e) + { + SystemLog::WriteException (e); + return -EINTR; + } + catch (...) + { + SystemLog::WriteException (UnknownException (SRC_POS)); + return -EINTR; + } + } + + shared_ptr FuseService::GetVolumeInfo () + { + shared_ptr stream (new MemoryStream); + + { + ScopeLock lock (OpenVolumeInfoMutex); + + OpenVolumeInfo.Set (*MountedVolume); + OpenVolumeInfo.SlotNumber = SlotNumber; + + OpenVolumeInfo.Serialize (stream); + } + + ConstBufferPtr infoBuf = dynamic_cast (*stream); + shared_ptr outBuf (new Buffer (infoBuf.Size())); + outBuf->CopyFrom (infoBuf); + + return outBuf; + } + + const char *FuseService::GetVolumeImagePath () + { +#ifdef TC_MACOSX + return "/volume.dmg"; +#else + return "/volume"; +#endif + } + + uint64 FuseService::GetVolumeSize () + { + if (!MountedVolume) + throw NotInitialized (SRC_POS); + + return MountedVolume->GetSize(); + } + + void FuseService::Mount (shared_ptr openVolume, VolumeSlotNumber slotNumber, const string &fuseMountPoint) + { + list args; + args.push_back (FuseService::GetDeviceType()); + args.push_back (fuseMountPoint); + +#ifdef TC_MACOSX + args.push_back ("-o"); + args.push_back ("noping_diskarb"); + args.push_back ("-o"); + args.push_back ("nobrowse"); + + if (getuid() == 0 || geteuid() == 0) +#endif + { + args.push_back ("-o"); + args.push_back ("allow_other"); + } + + ExecFunctor execFunctor (openVolume, slotNumber); + Process::Execute ("fuse", args, -1, &execFunctor); + + for (int t = 0; true; t++) + { + try + { + if (FilesystemPath (fuseMountPoint + FuseService::GetControlPath()).GetType() == FilesystemPathType::File) + break; + } + catch (...) + { + if (t > 50) + throw; + + Thread::Sleep (100); + } + } + } + + void FuseService::ReadVolumeSectors (const BufferPtr &buffer, uint64 byteOffset) + { + if (!MountedVolume) + throw NotInitialized (SRC_POS); + + MountedVolume->ReadSectors (buffer, byteOffset); + } + + void FuseService::ReceiveAuxDeviceInfo (const ConstBufferPtr &buffer) + { + shared_ptr stream (new MemoryStream (buffer)); + Serializer sr (stream); + + ScopeLock lock (OpenVolumeInfoMutex); + OpenVolumeInfo.VirtualDevice = sr.DeserializeString ("VirtualDevice"); + OpenVolumeInfo.LoopDevice = sr.DeserializeString ("LoopDevice"); + } + + void FuseService::SendAuxDeviceInfo (const DirectoryPath &fuseMountPoint, const DevicePath &virtualDevice, const DevicePath &loopDevice) + { + File fuseServiceControl; + fuseServiceControl.Open (string (fuseMountPoint) + GetControlPath(), File::OpenWrite); + + shared_ptr stream (new MemoryStream); + Serializer sr (stream); + + sr.Serialize ("VirtualDevice", string (virtualDevice)); + sr.Serialize ("LoopDevice", string (loopDevice)); + fuseServiceControl.Write (dynamic_cast (*stream)); + } + + void FuseService::WriteVolumeSectors (const ConstBufferPtr &buffer, uint64 byteOffset) + { + if (!MountedVolume) + throw NotInitialized (SRC_POS); + + MountedVolume->WriteSectors (buffer, byteOffset); + } + + void FuseService::OnSignal (int signal) + { + try + { + shared_ptr volume = Core->GetMountedVolume (SlotNumber); + + if (volume) + Core->DismountVolume (volume, true); + } + catch (...) { } + + _exit (0); + } + + void FuseService::ExecFunctor::operator() (int argc, char *argv[]) + { + struct timeval tv; + gettimeofday (&tv, NULL); + FuseService::OpenVolumeInfo.SerialInstanceNumber = (uint64)tv.tv_sec * 1000000ULL + tv.tv_usec; + + FuseService::MountedVolume = MountedVolume; + FuseService::SlotNumber = SlotNumber; + + FuseService::UserId = getuid(); + FuseService::GroupId = getgid(); + + if (getenv ("SUDO_UID")) + { + try + { + string s (getenv ("SUDO_UID")); + FuseService::UserId = static_cast (StringConverter::ToUInt64 (s)); + + if (getenv ("SUDO_GID")) + { + s = getenv ("SUDO_GID"); + FuseService::GroupId = static_cast (StringConverter::ToUInt64 (s)); + } + } + catch (...) { } + } + + static fuse_operations fuse_service_oper; + + fuse_service_oper.access = fuse_service_access; + fuse_service_oper.destroy = fuse_service_destroy; + fuse_service_oper.getattr = fuse_service_getattr; + fuse_service_oper.init = fuse_service_init; + fuse_service_oper.open = fuse_service_open; + fuse_service_oper.opendir = fuse_service_opendir; + fuse_service_oper.read = fuse_service_read; + fuse_service_oper.readdir = fuse_service_readdir; + fuse_service_oper.write = fuse_service_write; + + // Create a new session + setsid (); + + // Fork handler of termination signals + SignalHandlerPipe.reset (new Pipe); + + int forkedPid = fork(); + throw_sys_if (forkedPid == -1); + + if (forkedPid == 0) + { + CloseMountedVolume(); + + struct sigaction action; + Memory::Zero (&action, sizeof (action)); + action.sa_handler = OnSignal; + + sigaction (SIGINT, &action, nullptr); + sigaction (SIGQUIT, &action, nullptr); + sigaction (SIGTERM, &action, nullptr); + + // Wait for the exit of the main service + byte buf[1]; + if (read (SignalHandlerPipe->GetReadFD(), buf, sizeof (buf))) { } // Errors ignored + + _exit (0); + } + + SignalHandlerPipe->GetWriteFD(); + + _exit (fuse_main (argc, argv, &fuse_service_oper)); + } + + VolumeInfo FuseService::OpenVolumeInfo; + Mutex FuseService::OpenVolumeInfoMutex; + shared_ptr FuseService::MountedVolume; + VolumeSlotNumber FuseService::SlotNumber; + uid_t FuseService::UserId; + gid_t FuseService::GroupId; + auto_ptr FuseService::SignalHandlerPipe; +} diff --git a/src/Driver/Fuse/FuseService.h b/src/Driver/Fuse/FuseService.h new file mode 100644 index 00000000..5ff2dd72 --- /dev/null +++ b/src/Driver/Fuse/FuseService.h @@ -0,0 +1,73 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Driver_Fuse_FuseService +#define TC_HEADER_Driver_Fuse_FuseService + +#include "Platform/Platform.h" +#include "Platform/Unix/Pipe.h" +#include "Platform/Unix/Process.h" +#include "Volume/VolumeInfo.h" +#include "Volume/Volume.h" + +namespace TrueCrypt +{ + + class FuseService + { + protected: + struct ExecFunctor : public ProcessExecFunctor + { + ExecFunctor (shared_ptr openVolume, VolumeSlotNumber slotNumber) + : MountedVolume (openVolume), SlotNumber (slotNumber) + { + } + virtual void operator() (int argc, char *argv[]); + + protected: + shared_ptr MountedVolume; + VolumeSlotNumber SlotNumber; + }; + + friend class ExecFunctor; + + public: + static bool AuxDeviceInfoReceived () { return !OpenVolumeInfo.VirtualDevice.IsEmpty(); } + static bool CheckAccessRights (); + static void Dismount (); + static int ExceptionToErrorCode (); + static const char *GetControlPath () { return "/control"; } + static const char *GetVolumeImagePath (); + static string GetDeviceType () { return "truecrypt"; } + static uid_t GetGroupId () { return GroupId; } + static uid_t GetUserId () { return UserId; } + static shared_ptr GetVolumeInfo (); + static uint64 GetVolumeSize (); + static uint64 GetVolumeSectorSize () { return MountedVolume->GetSectorSize(); } + static void Mount (shared_ptr openVolume, VolumeSlotNumber slotNumber, const string &fuseMountPoint); + static void ReadVolumeSectors (const BufferPtr &buffer, uint64 byteOffset); + static void ReceiveAuxDeviceInfo (const ConstBufferPtr &buffer); + static void SendAuxDeviceInfo (const DirectoryPath &fuseMountPoint, const DevicePath &virtualDevice, const DevicePath &loopDevice = DevicePath()); + static void WriteVolumeSectors (const ConstBufferPtr &buffer, uint64 byteOffset); + + protected: + FuseService (); + static void CloseMountedVolume (); + static void OnSignal (int signal); + + static VolumeInfo OpenVolumeInfo; + static Mutex OpenVolumeInfoMutex; + static shared_ptr MountedVolume; + static VolumeSlotNumber SlotNumber; + static uid_t UserId; + static gid_t GroupId; + static auto_ptr SignalHandlerPipe; + }; +} + +#endif // TC_HEADER_Driver_Fuse_FuseService diff --git a/src/Main/Application.cpp b/src/Main/Application.cpp new file mode 100644 index 00000000..f6d692cb --- /dev/null +++ b/src/Main/Application.cpp @@ -0,0 +1,98 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#include "Main.h" +#include "Application.h" +#include "CommandLineInterface.h" +#ifndef TC_NO_GUI +#include "GraphicUserInterface.h" +#endif +#include "TextUserInterface.h" + +namespace TrueCrypt +{ + wxApp* Application::CreateConsoleApp () + { + mUserInterface = new TextUserInterface; + mUserInterfaceType = UserInterfaceType::Text; + return mUserInterface; + } + +#ifndef TC_NO_GUI + wxApp* Application::CreateGuiApp () + { + mUserInterface = new GraphicUserInterface; + mUserInterfaceType = UserInterfaceType::Graphic; + return mUserInterface; + } +#endif + + FilePath Application::GetConfigFilePath (const wxString &configFileName, bool createConfigDir) + { + wxStandardPaths stdPaths; + DirectoryPath configDir; + + if (!Core->IsInPortableMode()) + { +#ifdef TC_MACOSX + wxFileName configPath (L"~/Library/Application Support/TrueCrypt"); + configPath.Normalize(); + configDir = wstring (configPath.GetFullPath()); +#else + configDir = wstring (stdPaths.GetUserDataDir()); +#endif + } + else + configDir = GetExecutableDirectory(); + + if (createConfigDir && !configDir.IsDirectory()) + Directory::Create (configDir); + + FilePath filePath = wstring (wxFileName (wstring (configDir), configFileName).GetFullPath()); + return filePath; + } + + DirectoryPath Application::GetExecutableDirectory () + { + return wstring (wxFileName (wxStandardPaths().GetExecutablePath()).GetPath()); + } + + FilePath Application::GetExecutablePath () + { + return wstring (wxStandardPaths().GetExecutablePath()); + } + + void Application::Initialize (UserInterfaceType::Enum type) + { + switch (type) + { + case UserInterfaceType::Text: + { + wxAppInitializer wxTheAppInitializer((wxAppInitializerFunction) CreateConsoleApp); + break; + } + +#ifndef TC_NO_GUI + case UserInterfaceType::Graphic: + { + wxAppInitializer wxTheAppInitializer((wxAppInitializerFunction) CreateGuiApp); + break; + } +#endif + + default: + throw ParameterIncorrect (SRC_POS); + } + } + + int Application::ExitCode = 0; + UserInterface *Application::mUserInterface = nullptr; + UserInterfaceType::Enum Application::mUserInterfaceType; +} diff --git a/src/Main/Application.h b/src/Main/Application.h new file mode 100644 index 00000000..07ed3d03 --- /dev/null +++ b/src/Main/Application.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_AppMain +#define TC_HEADER_Main_AppMain + +#include "Main.h" +#include "UserInterface.h" +#include "UserInterfaceType.h" + +namespace TrueCrypt +{ + class Application + { + public: + static wxApp* CreateConsoleApp (); + static wxApp* CreateGuiApp (); + static FilePath GetConfigFilePath (const wxString &configFileName, bool createConfigDir = false); + static DirectoryPath GetExecutableDirectory (); + static FilePath GetExecutablePath (); + static int GetExitCode () { return ExitCode; } + static wstring GetName () { return L"TrueCrypt"; } + static UserInterface *GetUserInterface () { return mUserInterface; } + static UserInterfaceType::Enum GetUserInterfaceType () { return mUserInterfaceType; } + static void Initialize (UserInterfaceType::Enum type); + static void SetExitCode (int code) { ExitCode = code; } + + protected: + static int ExitCode; + static UserInterface *mUserInterface; + static UserInterfaceType::Enum mUserInterfaceType; + }; +} + +#endif // TC_HEADER_Main_AppMain diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp new file mode 100644 index 00000000..ab5f90b2 --- /dev/null +++ b/src/Main/CommandLineInterface.cpp @@ -0,0 +1,583 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#include +#include "Core/Core.h" +#include "Application.h" +#include "CommandLineInterface.h" +#include "LanguageStrings.h" +#include "UserInterfaceException.h" + +namespace TrueCrypt +{ + CommandLineInterface::CommandLineInterface (wxCmdLineParser &parser, UserInterfaceType::Enum interfaceType) : + ArgCommand (CommandId::None), + ArgFilesystem (VolumeCreationOptions::FilesystemType::Unknown), + ArgNoHiddenVolumeProtection (false), + ArgSize (0), + ArgVolumeType (VolumeType::Unknown), + StartBackgroundTask (false) + { + parser.SetSwitchChars (L"-"); + + parser.AddOption (L"", L"auto-mount", _("Auto mount device-hosted/favorite volumes")); + parser.AddSwitch (L"", L"backup-headers", _("Backup volume headers")); + parser.AddSwitch (L"", L"background-task", _("Start Background Task")); +#ifdef TC_WINDOWS + parser.AddSwitch (L"", L"cache", _("Cache passwords and keyfiles")); +#endif + parser.AddSwitch (L"C", L"change", _("Change password or keyfiles")); + parser.AddSwitch (L"c", L"create", _("Create new volume")); + parser.AddSwitch (L"", L"create-keyfile", _("Create new keyfile")); + parser.AddSwitch (L"", L"delete-token-keyfiles", _("Delete security token keyfiles")); + parser.AddSwitch (L"d", L"dismount", _("Dismount volume")); + parser.AddSwitch (L"", L"display-password", _("Display password while typing")); + parser.AddOption (L"", L"encryption", _("Encryption algorithm")); + parser.AddSwitch (L"", L"explore", _("Open explorer window for mounted volume")); + parser.AddSwitch (L"", L"export-token-keyfile",_("Export keyfile from security token")); + parser.AddOption (L"", L"filesystem", _("Filesystem type")); + parser.AddSwitch (L"f", L"force", _("Force mount/dismount/overwrite")); +#if !defined(TC_WINDOWS) && !defined(TC_MACOSX) + parser.AddOption (L"", L"fs-options", _("Filesystem mount options")); +#endif + parser.AddOption (L"", L"hash", _("Hash algorithm")); + parser.AddSwitch (L"h", L"help", _("Display detailed command line help"), wxCMD_LINE_OPTION_HELP); + parser.AddSwitch (L"", L"import-token-keyfiles", _("Import keyfiles to security token")); + parser.AddOption (L"k", L"keyfiles", _("Keyfiles")); + parser.AddSwitch (L"l", L"list", _("List mounted volumes")); + parser.AddSwitch (L"", L"list-token-keyfiles", _("List security token keyfiles")); + parser.AddSwitch (L"", L"load-preferences", _("Load user preferences")); + parser.AddSwitch (L"", L"mount", _("Mount volume interactively")); + parser.AddOption (L"m", L"mount-options", _("TrueCrypt volume mount options")); + parser.AddOption (L"", L"new-keyfiles", _("New keyfiles")); + parser.AddOption (L"", L"new-password", _("New password")); + parser.AddSwitch (L"", L"non-interactive", _("Do not interact with user")); + parser.AddOption (L"p", L"password", _("Password")); + parser.AddOption (L"", L"protect-hidden", _("Protect hidden volume")); + parser.AddOption (L"", L"protection-keyfiles", _("Keyfiles for protected hidden volume")); + parser.AddOption (L"", L"protection-password", _("Password for protected hidden volume")); + parser.AddOption (L"", L"random-source", _("Use file as source of random data")); + parser.AddSwitch (L"", L"restore-headers", _("Restore volume headers")); + parser.AddSwitch (L"", L"save-preferences", _("Save user preferences")); + parser.AddSwitch (L"", L"quick", _("Enable quick format")); + parser.AddOption (L"", L"size", _("Size in bytes")); + parser.AddOption (L"", L"slot", _("Volume slot number")); + parser.AddSwitch (L"", L"test", _("Test internal algorithms")); + parser.AddSwitch (L"t", L"text", _("Use text user interface")); + parser.AddOption (L"", L"token-lib", _("Security token library")); + parser.AddSwitch (L"v", L"verbose", _("Enable verbose output")); + parser.AddSwitch (L"", L"version", _("Display version information")); + parser.AddSwitch (L"", L"volume-properties", _("Display volume properties")); + parser.AddOption (L"", L"volume-type", _("Volume type")); + parser.AddParam ( _("Volume path"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); + parser.AddParam ( _("Mount point"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); + + wxString str; + bool param1IsVolume = false; + bool param1IsMountedVolumeSpec = false; + bool param1IsMountPoint = false; + bool param1IsFile = false; + + if (parser.Parse () > 0) + throw_err (_("Incorrect command line specified.")); + + if (parser.Found (L"help")) + { + ArgCommand = CommandId::Help; + return; + } + + if (parser.Found (L"text") && interfaceType != UserInterfaceType::Text) + { + wstring msg = wstring (_("Option -t or --text must be specified as the first argument.")); + wcerr << msg << endl; + throw_err (msg); + } + + if (parser.Found (L"version")) + { + ArgCommand = CommandId::DisplayVersion; + return; + } + + // Preferences + if (parser.Found (L"load-preferences")) + { + // Load preferences first to allow command line options to override them + Preferences.Load(); + ArgMountOptions = Preferences.DefaultMountOptions; + } + + // Commands + if (parser.Found (L"auto-mount", &str)) + { + CheckCommandSingle(); + + wxStringTokenizer tokenizer (str, L","); + while (tokenizer.HasMoreTokens()) + { + wxString token = tokenizer.GetNextToken(); + + if (token == L"devices") + { + if (ArgCommand == CommandId::AutoMountFavorites) + ArgCommand = CommandId::AutoMountDevicesFavorites; + else + ArgCommand = CommandId::AutoMountDevices; + + param1IsMountPoint = true; + } + else if (token == L"favorites") + { + if (ArgCommand == CommandId::AutoMountDevices) + ArgCommand = CommandId::AutoMountDevicesFavorites; + else + ArgCommand = CommandId::AutoMountFavorites; + } + else + { + throw_err (LangString["UNKNOWN_OPTION"] + L": " + token); + } + } + } + + if (parser.Found (L"backup-headers")) + { + CheckCommandSingle(); + ArgCommand = CommandId::BackupHeaders; + param1IsVolume = true; + } + + if (parser.Found (L"change")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ChangePassword; + param1IsVolume = true; + } + + if (parser.Found (L"create")) + { + CheckCommandSingle(); + ArgCommand = CommandId::CreateVolume; + param1IsVolume = true; + } + + if (parser.Found (L"create-keyfile")) + { + CheckCommandSingle(); + ArgCommand = CommandId::CreateKeyfile; + param1IsFile = true; + } + + if (parser.Found (L"delete-token-keyfiles")) + { + CheckCommandSingle(); + ArgCommand = CommandId::DeleteSecurityTokenKeyfiles; + } + + if (parser.Found (L"dismount")) + { + CheckCommandSingle(); + ArgCommand = CommandId::DismountVolumes; + param1IsMountedVolumeSpec = true; + } + + if (parser.Found (L"export-token-keyfile")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ExportSecurityTokenKeyfile; + } + + if (parser.Found (L"import-token-keyfiles")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ImportSecurityTokenKeyfiles; + } + + if (parser.Found (L"list")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ListVolumes; + param1IsMountedVolumeSpec = true; + } + + if (parser.Found (L"list-token-keyfiles")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ListSecurityTokenKeyfiles; + } + + if (parser.Found (L"mount")) + { + CheckCommandSingle(); + ArgCommand = CommandId::MountVolume; + param1IsVolume = true; + } + + if (parser.Found (L"save-preferences")) + { + CheckCommandSingle(); + ArgCommand = CommandId::SavePreferences; + } + + if (parser.Found (L"test")) + { + CheckCommandSingle(); + ArgCommand = CommandId::Test; + } + + if (parser.Found (L"volume-properties")) + { + CheckCommandSingle(); + ArgCommand = CommandId::DisplayVolumeProperties; + param1IsMountedVolumeSpec = true; + } + + // Options + if (parser.Found (L"background-task")) + StartBackgroundTask = true; + +#ifdef TC_WINDOWS + if (parser.Found (L"cache")) + ArgMountOptions.CachePassword = true; +#endif + ArgDisplayPassword = parser.Found (L"display-password"); + + if (parser.Found (L"encryption", &str)) + { + ArgEncryptionAlgorithm.reset(); + + foreach (shared_ptr ea, EncryptionAlgorithm::GetAvailableAlgorithms()) + { + if (!ea->IsDeprecated() && wxString (ea->GetName()).IsSameAs (str, false)) + ArgEncryptionAlgorithm = ea; + } + + if (!ArgEncryptionAlgorithm) + throw_err (LangString["UNKNOWN_OPTION"] + L": " + str); + } + + if (parser.Found (L"explore")) + Preferences.OpenExplorerWindowAfterMount = true; + + if (parser.Found (L"filesystem", &str)) + { + if (str.IsSameAs (L"none", false)) + { + ArgMountOptions.NoFilesystem = true; + ArgFilesystem = VolumeCreationOptions::FilesystemType::None; + } + else + { + ArgMountOptions.FilesystemType = wstring (str); + + if (str.IsSameAs (L"FAT", false)) + ArgFilesystem = VolumeCreationOptions::FilesystemType::FAT; + else + ArgFilesystem = VolumeCreationOptions::FilesystemType::None; + } + } + + ArgForce = parser.Found (L"force"); + +#if !defined(TC_WINDOWS) && !defined(TC_MACOSX) + if (parser.Found (L"fs-options", &str)) + ArgMountOptions.FilesystemOptions = str; +#endif + + if (parser.Found (L"hash", &str)) + { + ArgHash.reset(); + + foreach (shared_ptr hash, Hash::GetAvailableAlgorithms()) + { + if (wxString (hash->GetName()).IsSameAs (str, false)) + ArgHash = hash; + } + + if (!ArgHash) + throw_err (LangString["UNKNOWN_OPTION"] + L": " + str); + } + + if (parser.Found (L"keyfiles", &str)) + ArgKeyfiles = ToKeyfileList (str); + + if (parser.Found (L"mount-options", &str)) + { + wxStringTokenizer tokenizer (str, L","); + while (tokenizer.HasMoreTokens()) + { + wxString token = tokenizer.GetNextToken(); + + if (token == L"headerbak") + ArgMountOptions.UseBackupHeaders = true; + else if (token == L"nokernelcrypto") + ArgMountOptions.NoKernelCrypto = true; + else if (token == L"readonly" || token == L"ro") + ArgMountOptions.Protection = VolumeProtection::ReadOnly; + else if (token == L"system") + ArgMountOptions.PartitionInSystemEncryptionScope = true; + else if (token == L"timestamp" || token == L"ts") + ArgMountOptions.PreserveTimestamps = false; +#ifdef TC_WINDOWS + else if (token == L"removable" || token == L"rm") + ArgMountOptions.Removable = true; +#endif + else + throw_err (LangString["UNKNOWN_OPTION"] + L": " + token); + } + } + + if (parser.Found (L"new-keyfiles", &str)) + ArgNewKeyfiles = ToKeyfileList (str); + + if (parser.Found (L"new-password", &str)) + ArgNewPassword.reset (new VolumePassword (wstring (str))); + + if (parser.Found (L"non-interactive")) + { + if (interfaceType != UserInterfaceType::Text) + throw_err (L"--non-interactive is supported only in text mode"); + + Preferences.NonInteractive = true; + } + + if (parser.Found (L"password", &str)) + ArgPassword.reset (new VolumePassword (wstring (str))); + + if (parser.Found (L"protect-hidden", &str)) + { + if (str == L"yes") + { + if (ArgMountOptions.Protection != VolumeProtection::ReadOnly) + ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; + } + else if (str == L"no") + ArgNoHiddenVolumeProtection = true; + else + throw_err (LangString["UNKNOWN_OPTION"] + L": " + str); + } + + if (parser.Found (L"protection-keyfiles", &str)) + { + ArgMountOptions.ProtectionKeyfiles = ToKeyfileList (str); + ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; + } + + if (parser.Found (L"protection-password", &str)) + { + ArgMountOptions.ProtectionPassword.reset (new VolumePassword (wstring (str))); + ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; + } + + ArgQuick = parser.Found (L"quick"); + + if (parser.Found (L"random-source", &str)) + ArgRandomSourcePath = FilesystemPath (str); + + if (parser.Found (L"restore-headers")) + { + CheckCommandSingle(); + ArgCommand = CommandId::RestoreHeaders; + param1IsVolume = true; + } + + if (parser.Found (L"slot", &str)) + { + unsigned long number; + if (!str.ToULong (&number) || number < Core->GetFirstSlotNumber() || number > Core->GetLastSlotNumber()) + throw_err (LangString["PARAMETER_INCORRECT"] + L": " + str); + + ArgMountOptions.SlotNumber = number; + + if (param1IsMountedVolumeSpec) + { + shared_ptr volume = Core->GetMountedVolume (number); + if (!volume) + throw_err (_("No such volume is mounted.")); + + ArgVolumes.push_back (volume); + param1IsMountedVolumeSpec = false; + } + } + + if (parser.Found (L"size", &str)) + { + try + { + ArgSize = StringConverter::ToUInt64 (wstring (str)); + } + catch (...) + { + throw_err (LangString["PARAMETER_INCORRECT"] + L": " + str); + } + } + + if (parser.Found (L"token-lib", &str)) + Preferences.SecurityTokenModule = wstring (str); + + if (parser.Found (L"verbose")) + Preferences.Verbose = true; + + if (parser.Found (L"volume-type", &str)) + { + if (str.IsSameAs (L"normal", false)) + ArgVolumeType = VolumeType::Normal; + else if (str.IsSameAs (L"hidden", false)) + ArgVolumeType = VolumeType::Hidden; + else + throw_err (LangString["UNKNOWN_OPTION"] + L": " + str); + } + + // Parameters + if (parser.GetParamCount() > 0) + { + if (ArgCommand == CommandId::None) + { + ArgCommand = CommandId::MountVolume; + param1IsVolume = true; + } + + if (param1IsVolume) + { + wxFileName volPath (parser.GetParam (0)); + +#ifdef TC_WINDOWS + if (!parser.GetParam (0).StartsWith (L"\\Device\\")) +#endif + volPath.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); + + ArgVolumePath.reset (new VolumePath (wstring (volPath.GetFullPath()))); + } + + if (param1IsMountPoint || parser.GetParamCount() >= 2) + { + wstring s (parser.GetParam (param1IsMountPoint ? 0 : 1)); + + if (s.empty()) + ArgMountOptions.NoFilesystem = true; + + wxFileName mountPoint (wstring (Directory::AppendSeparator (s))); + mountPoint.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); + ArgMountPoint.reset (new DirectoryPath (wstring (mountPoint.GetPath()))); + } + + if (param1IsFile) + { + ArgFilePath.reset (new FilePath (parser.GetParam (0))); + } + } + + if (param1IsMountedVolumeSpec) + ArgVolumes = GetMountedVolumes (parser.GetParamCount() > 0 ? parser.GetParam (0) : wxString()); + + if (ArgCommand == CommandId::None && Application::GetUserInterfaceType() == UserInterfaceType::Text) + parser.Usage(); + } + + CommandLineInterface::~CommandLineInterface () + { + } + + void CommandLineInterface::CheckCommandSingle () const + { + if (ArgCommand != CommandId::None) + throw_err (_("Only a single command can be specified at a time.")); + } + + shared_ptr CommandLineInterface::ToKeyfileList (const wxString &arg) const + { + wxStringTokenizer tokenizer (arg, L",", wxTOKEN_RET_EMPTY_ALL); + + // Handle escaped separator + wxArrayString arr; + bool prevEmpty = false; + while (tokenizer.HasMoreTokens()) + { + wxString token = tokenizer.GetNextToken(); + + if (prevEmpty && token.empty() && tokenizer.HasMoreTokens()) + { + token = tokenizer.GetNextToken(); + if (!token.empty()) + { + arr.Add (token); + prevEmpty = true; + continue; + } + } + + if (token.empty() && !tokenizer.HasMoreTokens()) + break; + + if (prevEmpty || token.empty()) + { + if (arr.Count() < 1) + { + arr.Add (L""); + continue; + } + arr.Last() += token.empty() ? L',' : token; + } + else + arr.Add (token); + + prevEmpty = token.empty(); + } + + make_shared_auto (KeyfileList, keyfileList); + for (size_t i = 0; i < arr.GetCount(); i++) + { + if (!arr[i].empty()) + keyfileList->push_back (make_shared (wstring (arr[i]))); + } + + return keyfileList; + } + + VolumeInfoList CommandLineInterface::GetMountedVolumes (const wxString &mountedVolumeSpec) const + { + VolumeInfoList volumes = Core->GetMountedVolumes (); + VolumeInfoList filteredVolumes; + + wxFileName pathFilter; + if (!mountedVolumeSpec.empty()) + { + pathFilter = mountedVolumeSpec; + pathFilter.Normalize (wxPATH_NORM_ABSOLUTE | wxPATH_NORM_DOTS); + } + else + return volumes; + + foreach (shared_ptr volume, volumes) + { + if (mountedVolumeSpec.empty()) + { + filteredVolumes.push_back (volume); + } + else if (wxString (volume->Path) == pathFilter.GetFullPath()) + { + filteredVolumes.push_back (volume); + } + else if (wxString (volume->MountPoint) == pathFilter.GetFullPath() + || (wxString (volume->MountPoint) + wxFileName::GetPathSeparator()) == pathFilter.GetFullPath()) + { + filteredVolumes.push_back (volume); + } + } + + if (!mountedVolumeSpec.IsEmpty() && filteredVolumes.size() < 1) + throw_err (_("No such volume is mounted.")); + + return filteredVolumes; + } + + auto_ptr CmdLine; +} diff --git a/src/Main/CommandLineInterface.h b/src/Main/CommandLineInterface.h new file mode 100644 index 00000000..50f98f6c --- /dev/null +++ b/src/Main/CommandLineInterface.h @@ -0,0 +1,94 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_CommandInterface +#define TC_HEADER_Main_CommandInterface + +#include "System.h" +#include "Main.h" +#include "Volume/VolumeInfo.h" +#include "Core/MountOptions.h" +#include "Core/VolumeCreator.h" +#include "UserPreferences.h" +#include "UserInterfaceType.h" + +namespace TrueCrypt +{ + struct CommandId + { + enum Enum + { + None, + AutoMountDevices, + AutoMountDevicesFavorites, + AutoMountFavorites, + BackupHeaders, + ChangePassword, + CreateKeyfile, + CreateVolume, + DeleteSecurityTokenKeyfiles, + DismountVolumes, + DisplayVersion, + DisplayVolumeProperties, + ExportSecurityTokenKeyfile, + Help, + ImportSecurityTokenKeyfiles, + ListSecurityTokenKeyfiles, + ListVolumes, + MountVolume, + RestoreHeaders, + SavePreferences, + Test + }; + }; + + struct CommandLineInterface + { + public: + CommandLineInterface (wxCmdLineParser &parser, UserInterfaceType::Enum interfaceType); + virtual ~CommandLineInterface (); + + + CommandId::Enum ArgCommand; + bool ArgDisplayPassword; + shared_ptr ArgEncryptionAlgorithm; + shared_ptr ArgFilePath; + VolumeCreationOptions::FilesystemType::Enum ArgFilesystem; + bool ArgForce; + shared_ptr ArgHash; + shared_ptr ArgKeyfiles; + MountOptions ArgMountOptions; + shared_ptr ArgMountPoint; + shared_ptr ArgNewKeyfiles; + shared_ptr ArgNewPassword; + bool ArgNoHiddenVolumeProtection; + shared_ptr ArgPassword; + bool ArgQuick; + FilesystemPath ArgRandomSourcePath; + uint64 ArgSize; + shared_ptr ArgVolumePath; + VolumeInfoList ArgVolumes; + VolumeType::Enum ArgVolumeType; + + bool StartBackgroundTask; + UserPreferences Preferences; + + protected: + void CheckCommandSingle () const; + shared_ptr ToKeyfileList (const wxString &arg) const; + VolumeInfoList GetMountedVolumes (const wxString &filter) const; + + private: + CommandLineInterface (const CommandLineInterface &); + CommandLineInterface &operator= (const CommandLineInterface &); + }; + + extern auto_ptr CmdLine; +} + +#endif // TC_HEADER_Main_CommandInterface diff --git a/src/Main/FatalErrorHandler.cpp b/src/Main/FatalErrorHandler.cpp new file mode 100644 index 00000000..d84a717d --- /dev/null +++ b/src/Main/FatalErrorHandler.cpp @@ -0,0 +1,274 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include + +#include "Main.h" +#include "Application.h" +#include "UserInterface.h" +#include "GraphicUserInterface.h" +#include "Volume/Crc32.h" + +#ifdef TC_UNIX +#include +#endif + +#ifdef TC_MACOSX +# ifdef __ppc__ +# include +# else +# include +# endif +#elif defined (TC_BSD) +# include +#endif + +#include "FatalErrorHandler.h" + +namespace TrueCrypt +{ + static terminate_handler DefaultTerminateHandler; + + struct FatalErrorReport + { + bool UnhandledException; + }; + +#ifdef TC_UNIX + static void OnFatalProgramErrorSignal (int, siginfo_t *signalInfo, void *contextArg) + { + TC_UNUSED_VAR ucontext_t *context = (ucontext_t *) contextArg; + uint64 faultingInstructionAddress = 0; + +#ifdef TC_LINUX +# ifdef REG_EIP + faultingInstructionAddress = context->uc_mcontext.gregs[REG_EIP]; +# elif defined (REG_RIP) + faultingInstructionAddress = context->uc_mcontext.gregs[REG_RIP]; +# endif + +#elif defined (TC_MACOSX) +# ifdef __ppc__ + faultingInstructionAddress = context->uc_mcontext->ss.srr0; +# elif defined (__x86_64__) + faultingInstructionAddress = context->uc_mcontext->ss.rip; +# else + faultingInstructionAddress = context->uc_mcontext->ss.eip; +# endif + +#endif + wstringstream vars; + + vars << L"cpus=" << wxThread::GetCPUCount(); + vars << L"&cksum=" << hex << FatalErrorHandler::GetAppChecksum() << dec; + vars << L"&err=" << signalInfo->si_signo; + vars << L"&addr=" << hex << faultingInstructionAddress << dec; + vars << FatalErrorHandler::GetCallStack (16); + + wxString url = Gui->GetHomepageLinkURL (L"err-report", true, vars.str()); + url.Replace (L"=0x", L"="); + url.Replace (L"=0X0x", L"=0x"); + url.Replace (L"=0X", L"=0x"); + + wxString msg = L"A critical error has occurred and TrueCrypt must be terminated. If this is caused by a bug in TrueCrypt, we would like to fix it. To help us, you can send us an automatically generated error report containing the following items:\n\n- Program version\n- Operating system version\n- Hardware architecture\n- Checksum of TrueCrypt executable\n- Error category\n- Error address\n"; +#if wxUSE_STACKWALKER == 1 + msg += L"- TrueCrypt call stack\n"; +#endif + msg += L"\nIf you select 'Yes', the following URL (which contains the entire error report) will be opened in your default Internet browser.\n\n"; + +#ifdef __WXGTK__ + wxString fUrl = url; + fUrl.Replace (L"&st", L" &st"); + msg += fUrl; +#else + msg += url; +#endif + + msg += L"\n\nDo you want to send us the error report?"; + + if (Gui->AskYesNo (msg, true)) + wxLaunchDefaultBrowser (url, wxBROWSER_NEW_WINDOW); + + _exit (1); + } +#endif // TC_UNIX + + void FatalErrorHandler::Deregister() + { +#ifdef TC_UNIX + signal (SIGILL, SIG_DFL); + signal (SIGFPE, SIG_DFL); + signal (SIGSEGV, SIG_DFL); + signal (SIGBUS, SIG_DFL); + signal (SIGSYS, SIG_DFL); +#endif + +#ifndef TC_WINDOWS + std::set_terminate (DefaultTerminateHandler); +#endif + } + + uint32 FatalErrorHandler::GetAppChecksum () + { + uint32 checkSum = 0; + try + { + File executable; + executable.Open (Application::GetExecutablePath()); + + Buffer executableData (executable.Length()); + executable.ReadCompleteBuffer (executableData); + checkSum = Crc32::ProcessBuffer (executableData); + } + catch (...) { } + + return checkSum; + } + + wstring FatalErrorHandler::GetCallStack (int depth) + { +#if wxUSE_STACKWALKER == 1 + + class StackWalker : public wxStackWalker + { + public: + StackWalker () : FrameCount (0) { } + + void OnStackFrame (const wxStackFrame &frame) + { + if (FrameCount >= 32) + return; + + StackVars << L"&st" << FrameCount++ << L"="; + + wxString functionName = frame.GetName(); + if (!functionName.empty() && !frame.GetModule().empty()) + { + int p = functionName.Find (L"("); + if (p != wxNOT_FOUND) + functionName = functionName.Mid (0, p); + + for (size_t i = 0; i < functionName.size(); ++i) + { + if (!isalnum (functionName[i])) + functionName[i] = L'_'; + } + + while (functionName.Replace (L"__", L"_")); + + StackVars << wstring (functionName); + } + else + StackVars << "0X" << hex << frame.GetAddress() << dec; + } + + int FrameCount; + wstringstream StackVars; + }; + + StackWalker stackWalker; + stackWalker.Walk (2); + + return stackWalker.StackVars.str(); + +#else // wxUSE_STACKWALKER + + return wstring(); + +#endif // wxUSE_STACKWALKER + } + + void FatalErrorHandler::OnTerminate () + { + try + { + throw; + } + catch (UserAbort&) + { + } + catch (Exception &e) + { + wxString vars; + + wxString exName = StringConverter::ToWide (StringConverter::GetTypeName (typeid (e))); + if (exName.find (L"TrueCrypt::") != string::npos) + exName = exName.Mid (11); + + wxString exPos = StringConverter::ToWide (e.what()); + if (exPos.find (L"TrueCrypt::") != string::npos) + exPos = exPos.Mid (11); + + vars << L"cpus=" << wxThread::GetCPUCount(); + vars << wxString::Format (L"&cksum=%x", GetAppChecksum()); + vars << L"&exception=" << exName; + vars << L"&exlocation=" << exPos; + vars << FatalErrorHandler::GetCallStack (16); + + vars.Replace (L"::", L"."); + vars.Replace (L":", L"."); + + wxString url = Gui->GetHomepageLinkURL (L"err-report", true, vars); + url.Replace (L"=0x", L"="); + url.Replace (L"=0X0x", L"=0x"); + url.Replace (L"=0X", L"=0x"); + + wxString msg = L"An unhandled exception has occurred and TrueCrypt must be terminated. If this is caused by a bug in TrueCrypt, we would like to fix it. To help us, you can send us an automatically generated error report containing the following items:\n\n- Program version\n- Operating system version\n- Hardware architecture\n- Checksum of TrueCrypt executable\n- Error description\n- Error location\n"; +#if wxUSE_STACKWALKER == 1 + msg += L"- TrueCrypt call stack\n"; +#endif + msg += L"\nIf you select 'Yes', the following URL (which contains the entire error report) will be opened in your default Internet browser.\n\n"; + +#ifdef __WXGTK__ + wxString fUrl = url; + fUrl.Replace (L"&st", L" &st"); + msg += fUrl; +#else + msg += url; +#endif + + msg += L"\n\nDo you want to send us the error report?"; + + if (Gui->AskYesNo (msg, true)) + wxLaunchDefaultBrowser (url, wxBROWSER_NEW_WINDOW); + + } + catch (exception &e) + { + Gui->ShowError (e); + } + catch (...) + { + Gui->ShowError (_("Unknown exception occurred.")); + } + + _exit (1); + } + + void FatalErrorHandler::Register () + { +#ifndef TC_WINDOWS + // OnUnhandledException() seems to be called only on Windows + DefaultTerminateHandler = std::set_terminate (OnTerminate); +#endif + +#ifdef TC_UNIX + struct sigaction action; + Memory::Zero (&action, sizeof (action)); + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = OnFatalProgramErrorSignal; + + throw_sys_if (sigaction (SIGILL, &action, nullptr) == -1); + throw_sys_if (sigaction (SIGFPE, &action, nullptr) == -1); + throw_sys_if (sigaction (SIGSEGV, &action, nullptr) == -1); + throw_sys_if (sigaction (SIGBUS, &action, nullptr) == -1); + throw_sys_if (sigaction (SIGSYS, &action, nullptr) == -1); +#endif + } +} diff --git a/src/Main/FatalErrorHandler.h b/src/Main/FatalErrorHandler.h new file mode 100644 index 00000000..478b0ae8 --- /dev/null +++ b/src/Main/FatalErrorHandler.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_FatalErrorHandler +#define TC_HEADER_Main_FatalErrorHandler + +#include "System.h" + +namespace TrueCrypt +{ + class FatalErrorHandler + { + public: + static void Deregister(); + static uint32 GetAppChecksum (); + static wstring GetCallStack (int depth); + static void Register(); + + protected: + static void OnSignal (int signal); + static void OnTerminate (); + + private: + FatalErrorHandler (); + }; +} + +#endif // TC_HEADER_Main_FatalErrorHandler diff --git a/src/Main/FavoriteVolume.cpp b/src/Main/FavoriteVolume.cpp new file mode 100644 index 00000000..06831791 --- /dev/null +++ b/src/Main/FavoriteVolume.cpp @@ -0,0 +1,94 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Application.h" +#include "FavoriteVolume.h" +#include "Xml.h" + +namespace TrueCrypt +{ + FavoriteVolumeList FavoriteVolume::LoadList () + { + FavoriteVolumeList favorites; + + FilePath path = Application::GetConfigFilePath (GetFileName()); + + if (path.IsFile()) + { + foreach (XmlNode node, XmlParser (path).GetNodes (L"volume")) + { + VolumeSlotNumber slotNumber = 0; + wstring attr = wstring (node.Attributes[L"slotnumber"]); + if (!attr.empty()) + slotNumber = StringConverter::ToUInt64 (attr); + + bool readOnly = false; + attr = wstring (node.Attributes[L"readonly"]); + if (!attr.empty()) + readOnly = (StringConverter::ToUInt32 (attr) != 0 ? true : false); + + bool system = false; + attr = wstring (node.Attributes[L"system"]); + if (!attr.empty()) + system = (StringConverter::ToUInt32 (attr) != 0 ? true : false); + + favorites.push_back (shared_ptr ( + new FavoriteVolume ((wstring) node.InnerText, wstring (node.Attributes[L"mountpoint"]), slotNumber, readOnly, system))); + } + } + + return favorites; + } + + void FavoriteVolume::SaveList (const FavoriteVolumeList &favorites) + { + FilePath favoritesCfgPath = Application::GetConfigFilePath (GetFileName(), true); + + if (favorites.empty()) + { + if (favoritesCfgPath.IsFile()) + favoritesCfgPath.Delete(); + } + else + { + XmlNode favoritesXml (L"favorites"); + + foreach_ref (const FavoriteVolume &favorite, favorites) + { + XmlNode node (L"volume", wstring (favorite.Path)); + node.Attributes[L"mountpoint"] = wstring (favorite.MountPoint); + node.Attributes[L"slotnumber"] = StringConverter::FromNumber (favorite.SlotNumber); + node.Attributes[L"readonly"] = StringConverter::FromNumber (favorite.ReadOnly ? 1 : 0); + node.Attributes[L"system"] = StringConverter::FromNumber (favorite.System ? 1 : 0); + + favoritesXml.InnerNodes.push_back (node); + } + + XmlWriter favoritesWriter (favoritesCfgPath); + favoritesWriter.WriteNode (favoritesXml); + favoritesWriter.Close(); + } + } + + void FavoriteVolume::ToMountOptions (MountOptions &options) const + { + if (MountPoint.IsEmpty()) + { + options.MountPoint.reset(); + options.NoFilesystem = true; + } + else + options.MountPoint.reset (new DirectoryPath (MountPoint)); + + options.Path.reset (new VolumePath (Path)); + options.PartitionInSystemEncryptionScope = System; + options.Protection = (ReadOnly ? VolumeProtection::ReadOnly : VolumeProtection::None); + options.SlotNumber = SlotNumber; + } +} diff --git a/src/Main/FavoriteVolume.h b/src/Main/FavoriteVolume.h new file mode 100644 index 00000000..f16ca5b9 --- /dev/null +++ b/src/Main/FavoriteVolume.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_FavoriteVolume +#define TC_HEADER_Main_FavoriteVolume + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + struct FavoriteVolume; + typedef list < shared_ptr > FavoriteVolumeList; + + struct FavoriteVolume + { + public: + FavoriteVolume () + : ReadOnly (false), + System (false) + { + } + + FavoriteVolume (const VolumePath &path, const DirectoryPath &mountPoint, VolumeSlotNumber slotNumber, bool readOnly, bool system) + : MountPoint (mountPoint), + Path (path), + ReadOnly (readOnly), + SlotNumber (slotNumber), + System (system) + { + } + + static FavoriteVolumeList LoadList (); + static void SaveList (const FavoriteVolumeList &favorites); + void ToMountOptions (MountOptions &options) const; + + DirectoryPath MountPoint; + VolumePath Path; + bool ReadOnly; + VolumeSlotNumber SlotNumber; + bool System; + + protected: + static wxString GetFileName () { return L"Favorite Volumes.xml"; } + }; +} + +#endif // TC_HEADER_Main_FavoriteVolume diff --git a/src/Main/Forms/AboutDialog.cpp b/src/Main/Forms/AboutDialog.cpp new file mode 100644 index 00000000..736a669a --- /dev/null +++ b/src/Main/Forms/AboutDialog.cpp @@ -0,0 +1,66 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Volume/Version.h" +#include "Main/Application.h" +#include "Main/GraphicUserInterface.h" +#include "Main/Resources.h" +#include "AboutDialog.h" + +namespace TrueCrypt +{ + AboutDialog::AboutDialog (wxWindow* parent) : AboutDialogBase (parent) + { + LogoBitmap->SetBitmap (Resources::GetTextualLogoBitmap()); + + wxFont versionStaticTextFont = VersionStaticText->GetFont(); + versionStaticTextFont.SetWeight (wxFONTWEIGHT_BOLD); + VersionStaticText->SetFont (versionStaticTextFont); + + VersionStaticText->SetLabel (Application::GetName() + L" " + StringConverter::ToWide (Version::String())); + CopyrightStaticText->SetLabel (StringConverter::ToWide (TC_STR_RELEASED_BY)); + WebsiteHyperlink->SetLabel (L"www.truecrypt.org"); + + CreditsTextCtrl->SetMinSize (wxSize ( + Gui->GetCharWidth (CreditsTextCtrl) * 70, + Gui->GetCharHeight (CreditsTextCtrl) * 6 +#ifdef TC_WINDOWS + - 5 +#else + - 11 +#endif + )); + + Layout(); + Fit(); + Center(); + + CreditsTextCtrl->ChangeValue ( + L"Portions of this software are based in part on the works of the following people: " + L"Paul Le Roux, " + L"Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall, Niels Ferguson, " + L"Lars Knudsen, Ross Anderson, Eli Biham, " + L"Joan Daemen, Vincent Rijmen, " + L"Phillip Rogaway, " + L"Hans Dobbertin, Antoon Bosselaers, Bart Preneel, " + L"Paulo Barreto, Brian Gladman, Wei Dai, Peter Gutmann, and many others.\n\n" + + L"Portions of this software:\n" + L"Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\n" + L"Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\n" + L"Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\n" + + L"\nThis software as a whole:\n" + L"Copyright \xA9 2012 TrueCrypt Developers Association. All rights reserved.\n\n" + + L"This software uses wxWidgets library, which is copyright \xA9 1998-2011 Julian Smart, Robert Roebling et al.\n\n" + + L"A TrueCrypt Foundation Release"); + } +} diff --git a/src/Main/Forms/AboutDialog.h b/src/Main/Forms/AboutDialog.h new file mode 100644 index 00000000..94cca8bb --- /dev/null +++ b/src/Main/Forms/AboutDialog.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_AboutDialog +#define TC_HEADER_Main_Forms_AboutDialog + +#include "Forms.h" + +namespace TrueCrypt +{ + class AboutDialog : public AboutDialogBase + { + public: + AboutDialog (wxWindow* parent); + + void OnWebsiteHyperlinkClick (wxHyperlinkEvent& event) { Gui->OpenHomepageLink (this, L"main"); } + }; +} + +#endif // TC_HEADER_Main_Forms_AboutDialog diff --git a/src/Main/Forms/BenchmarkDialog.cpp b/src/Main/Forms/BenchmarkDialog.cpp new file mode 100644 index 00000000..a2c1418d --- /dev/null +++ b/src/Main/Forms/BenchmarkDialog.cpp @@ -0,0 +1,157 @@ +/* + Copyright (c) 2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Volume/EncryptionModeXTS.h" +#include "Main/GraphicUserInterface.h" +#include "BenchmarkDialog.h" + +namespace TrueCrypt +{ + BenchmarkDialog::BenchmarkDialog (wxWindow *parent) + : BenchmarkDialogBase (parent) + { + BenchmarkNoteStaticText->SetLabel (LangString["IDT_BOX_BENCHMARK_INFO"]); + BenchmarkNoteStaticText->Wrap (RightSizer->GetSize().GetWidth()); + + list bufferSizes; + bufferSizes.push_back (1 * BYTES_PER_MB); + bufferSizes.push_back (5 * BYTES_PER_MB); + bufferSizes.push_back (10 * BYTES_PER_MB); + bufferSizes.push_back (50 * BYTES_PER_MB); + bufferSizes.push_back (100 * BYTES_PER_MB); + bufferSizes.push_back (200 * BYTES_PER_MB); + bufferSizes.push_back (500 * BYTES_PER_MB); + bufferSizes.push_back (1 * BYTES_PER_GB); + + foreach (size_t size, bufferSizes) + { + BufferSizeChoice->Append (Gui->SizeToString (size), (void *) size); + } + + BufferSizeChoice->Select (1); + + list colPermilles; + BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (322); + + BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["ENCRYPTION"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + BenchmarkListCtrl->InsertColumn (ColumnDecryption, LangString["DECRYPTION"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + BenchmarkListCtrl->InsertColumn (ColumnMean, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false); + Gui->SetListCtrlHeight (BenchmarkListCtrl, 14); + Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles); + + Layout(); + Fit(); + Center(); + } + + void BenchmarkDialog::OnBenchmarkButtonClick (wxCommandEvent& event) + { + try + { + list results; + + wxBusyCursor busy; + Buffer buffer ((size_t) Gui->GetSelectedData (BufferSizeChoice)); + + EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); + foreach (shared_ptr ea, encryptionAlgorithms) + { + if (!ea->IsDeprecated()) + { + BenchmarkResult result; + result.AlgorithmName = ea->GetName(); + + Buffer key (ea->GetKeySize()); + ea->SetKey (key); + + shared_ptr xts (new EncryptionModeXTS); + xts->SetKey (key); + ea->SetMode (xts); + + wxLongLong startTime = wxGetLocalTimeMillis(); + + // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load). + do + { + ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + } + while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 20); + + uint64 size = 0; + uint64 time; + startTime = wxGetLocalTimeMillis(); + + do + { + ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + size += buffer.Size(); + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); + } + while (time < 100); + + result.EncryptionSpeed = size * 1000 / time; + + startTime = wxGetLocalTimeMillis(); + size = 0; + + do + { + ea->DecryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + size += buffer.Size(); + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); + } + while (time < 100); + + result.DecryptionSpeed = size * 1000 / time; + result.MeanSpeed = (result.EncryptionSpeed + result.DecryptionSpeed) / 2; + + bool inserted = false; + for (list ::iterator i = results.begin(); i != results.end(); ++i) + { + if (i->MeanSpeed < result.MeanSpeed) + { + results.insert (i, result); + inserted = true; + break; + } + } + + if (!inserted) + results.push_back (result); + } + } + + BenchmarkListCtrl->DeleteAllItems(); + + foreach (const BenchmarkResult &result, results) + { + vector fields (BenchmarkListCtrl->GetColumnCount()); + + fields[ColumnAlgorithm] = result.AlgorithmName; + fields[ColumnEncryption] = Gui->SpeedToString (result.EncryptionSpeed); + fields[ColumnDecryption] = Gui->SpeedToString (result.DecryptionSpeed); + fields[ColumnMean] = Gui->SpeedToString (result.MeanSpeed); + + Gui->AppendToListCtrl (BenchmarkListCtrl, fields); + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } +} diff --git a/src/Main/Forms/BenchmarkDialog.h b/src/Main/Forms/BenchmarkDialog.h new file mode 100644 index 00000000..3cd61511 --- /dev/null +++ b/src/Main/Forms/BenchmarkDialog.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_BenchmarkDialog +#define TC_HEADER_Main_Forms_BenchmarkDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class BenchmarkDialog : public BenchmarkDialogBase + { + public: + BenchmarkDialog (wxWindow *parent); + + protected: + enum + { + ColumnAlgorithm = 0, + ColumnEncryption, + ColumnDecryption, + ColumnMean + }; + + struct BenchmarkResult + { + wstring AlgorithmName; + uint64 EncryptionSpeed; + uint64 DecryptionSpeed; + uint64 MeanSpeed; + }; + + void OnBenchmarkButtonClick (wxCommandEvent& event); + }; +} + +#endif // TC_HEADER_Main_Forms_BenchmarkDialog diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp new file mode 100644 index 00000000..05d0143c --- /dev/null +++ b/src/Main/Forms/ChangePasswordDialog.cpp @@ -0,0 +1,195 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/Main.h" +#include "Main/GraphicUserInterface.h" +#include "ChangePasswordDialog.h" + +namespace TrueCrypt +{ + ChangePasswordDialog::ChangePasswordDialog (wxWindow* parent, shared_ptr volumePath, Mode::Enum mode, shared_ptr password, shared_ptr keyfiles, shared_ptr newPassword, shared_ptr newKeyfiles) + : ChangePasswordDialogBase (parent), DialogMode (mode), Path (volumePath) + { + bool enableNewPassword = false; + bool enableNewKeyfiles = false; + bool enablePkcs5Prf = false; + + switch (mode) + { + case Mode::ChangePasswordAndKeyfiles: + enableNewPassword = true; + enableNewKeyfiles = true; + enablePkcs5Prf = true; + SetTitle (_("Change Volume Password and Keyfiles")); + break; + + case Mode::ChangeKeyfiles: + enableNewKeyfiles = true; + SetTitle (_("Add/Remove Keyfiles to/from Volume")); + break; + + case Mode::RemoveAllKeyfiles: + SetTitle (_("Remove All Keyfiles from Volume")); + break; + + case Mode::ChangePkcs5Prf: + enablePkcs5Prf = true; + SetTitle (_("Change Header Key Derivation Algorithm")); + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + CurrentPasswordPanel = new VolumePasswordPanel (this, password, keyfiles); + CurrentPasswordPanel->UpdateEvent.Connect (EventConnector (this, &ChangePasswordDialog::OnPasswordPanelUpdate)); + CurrentPasswordPanelSizer->Add (CurrentPasswordPanel, 1, wxALL | wxEXPAND); + + NewPasswordPanel = new VolumePasswordPanel (this, newPassword, newKeyfiles, false, enableNewPassword, enableNewKeyfiles, enableNewPassword, enablePkcs5Prf); + NewPasswordPanel->UpdateEvent.Connect (EventConnector (this, &ChangePasswordDialog::OnPasswordPanelUpdate)); + NewPasswordPanelSizer->Add (NewPasswordPanel, 1, wxALL | wxEXPAND); + + if (mode == Mode::RemoveAllKeyfiles) + NewSizer->Show (false); + + Layout(); + Fit(); + Center(); + + OnPasswordPanelUpdate(); + CurrentPasswordPanel->SetFocusToPasswordTextCtrl(); + } + + ChangePasswordDialog::~ChangePasswordDialog () + { + CurrentPasswordPanel->UpdateEvent.Disconnect (this); + NewPasswordPanel->UpdateEvent.Disconnect (this); + } + + void ChangePasswordDialog::OnOKButtonClick (wxCommandEvent& event) + { + // Avoid a GTK bug + if (!OKButton->IsEnabled()) + return; + + try + { + shared_ptr newPassword; + if (DialogMode == Mode::ChangePasswordAndKeyfiles) + { + newPassword = NewPasswordPanel->GetPassword(); + newPassword->CheckPortability(); + + if (newPassword->Size() > 0 && newPassword->Size() < VolumePassword::WarningSizeThreshold + && !Gui->AskYesNo (LangString ["PASSWORD_LENGTH_WARNING"], false, true)) + { + NewPasswordPanel->SetFocusToPasswordTextCtrl(); + return; + } + } + else + newPassword = CurrentPasswordPanel->GetPassword(); + + shared_ptr newKeyfiles; + if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangeKeyfiles) + newKeyfiles = NewPasswordPanel->GetKeyfiles(); + else if (DialogMode != Mode::RemoveAllKeyfiles) + newKeyfiles = CurrentPasswordPanel->GetKeyfiles(); + + Gui->UserEnrichRandomPool (this, NewPasswordPanel->GetPkcs5Kdf() ? NewPasswordPanel->GetPkcs5Kdf()->GetHash() : shared_ptr ()); + + { +#ifdef TC_UNIX + // Temporarily take ownership of a device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + if (!Core->HasAdminPrivileges() && Path->IsDevice()) + { + origDeviceOwner = FilesystemPath (wstring (*Path)).GetOwner(); + Core->SetFileOwner (*Path, UserId (getuid())); + } + + finally_do_arg2 (FilesystemPath, *Path, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); +#endif + wxBusyCursor busy; + Core->ChangePassword (Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, + CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetKeyfiles(), + newPassword, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf()); + } + + switch (DialogMode) + { + case Mode::ChangePasswordAndKeyfiles: + Gui->ShowInfo ("PASSWORD_CHANGED"); + break; + + case Mode::ChangeKeyfiles: + case Mode::RemoveAllKeyfiles: + Gui->ShowInfo ("KEYFILE_CHANGED"); + break; + + case Mode::ChangePkcs5Prf: + Gui->ShowInfo ("PKCS5_PRF_CHANGED"); + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + EndModal (wxID_OK); + } + catch (UnportablePassword &e) + { + Gui->ShowError (e); + NewPasswordPanel->SetFocusToPasswordTextCtrl(); + } + catch (PasswordException &e) + { + Gui->ShowWarning (e); + CurrentPasswordPanel->SetFocusToPasswordTextCtrl(); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void ChangePasswordDialog::OnPasswordPanelUpdate () + { + bool ok = true; + + bool passwordEmpty = CurrentPasswordPanel->GetPassword()->IsEmpty(); + bool keyfilesEmpty = !CurrentPasswordPanel->GetKeyfiles() || CurrentPasswordPanel->GetKeyfiles()->empty(); + + if (passwordEmpty && keyfilesEmpty) + ok = false; + + if (DialogMode == Mode::RemoveAllKeyfiles && (passwordEmpty || keyfilesEmpty)) + ok = false; + + if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangeKeyfiles) + { + bool newKeyfilesEmpty = !NewPasswordPanel->GetKeyfiles() || NewPasswordPanel->GetKeyfiles()->empty(); + + if (DialogMode == Mode::ChangeKeyfiles + && ((passwordEmpty && newKeyfilesEmpty) || (keyfilesEmpty && newKeyfilesEmpty))) + ok = false; + + if (DialogMode == Mode::ChangePasswordAndKeyfiles + && ((NewPasswordPanel->GetPassword()->IsEmpty() && newKeyfilesEmpty) || !NewPasswordPanel->PasswordsMatch())) + ok = false; + } + + OKButton->Enable (ok); + } +} diff --git a/src/Main/Forms/ChangePasswordDialog.h b/src/Main/Forms/ChangePasswordDialog.h new file mode 100644 index 00000000..cc147602 --- /dev/null +++ b/src/Main/Forms/ChangePasswordDialog.h @@ -0,0 +1,48 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_ChangePasswordDialog +#define TC_HEADER_Main_Forms_ChangePasswordDialog + +#include "Forms.h" +#include "Main/Main.h" +#include "VolumePasswordPanel.h" + +namespace TrueCrypt +{ + class ChangePasswordDialog : public ChangePasswordDialogBase + { + public: + struct Mode + { + enum Enum + { + ChangePasswordAndKeyfiles, + ChangeKeyfiles, + RemoveAllKeyfiles, + ChangePkcs5Prf + }; + }; + + ChangePasswordDialog (wxWindow* parent, shared_ptr volumePath, Mode::Enum mode = Mode::ChangePasswordAndKeyfiles, shared_ptr password = shared_ptr (), shared_ptr keyfiles = shared_ptr (), shared_ptr newPassword = shared_ptr (), shared_ptr newKeyfiles = shared_ptr ()); + virtual ~ChangePasswordDialog (); + + protected: + void OnOKButtonClick (wxCommandEvent& event); + void OnPasswordPanelUpdate (); + void OnPasswordPanelUpdate (EventArgs &args) { OnPasswordPanelUpdate(); } + + Mode::Enum DialogMode; + + VolumePasswordPanel *CurrentPasswordPanel; + VolumePasswordPanel *NewPasswordPanel; + shared_ptr Path; + }; +} + +#endif // TC_HEADER_Main_Forms_ChangePasswordDialog diff --git a/src/Main/Forms/DeviceSelectionDialog.cpp b/src/Main/Forms/DeviceSelectionDialog.cpp new file mode 100644 index 00000000..86db68a1 --- /dev/null +++ b/src/Main/Forms/DeviceSelectionDialog.cpp @@ -0,0 +1,120 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Main/Resources.h" +#include "DeviceSelectionDialog.h" + +namespace TrueCrypt +{ + DeviceSelectionDialog::DeviceSelectionDialog (wxWindow* parent) + : DeviceSelectionDialogBase (parent) + { + wxBusyCursor busy; + + list colPermilles; + + DeviceListCtrl->InsertColumn (ColumnDevice, LangString["DEVICE"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (447); +#ifdef TC_WINDOWS + DeviceListCtrl->InsertColumn (ColumnDrive, LangString["DRIVE"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (91); +#endif + DeviceListCtrl->InsertColumn (ColumnSize, LangString["SIZE"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (153); +#ifdef TC_WINDOWS + DeviceListCtrl->InsertColumn (ColumnName, LangString["LABEL"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (307); +#else + DeviceListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (396); +#endif + + wxImageList *imageList = new wxImageList (16, 12, true); + imageList->Add (Resources::GetDriveIconBitmap(), Resources::GetDriveIconMaskBitmap()); + DeviceListCtrl->AssignImageList (imageList, wxIMAGE_LIST_SMALL); + + DeviceList = Core->GetHostDevices(); + + foreach_ref (HostDevice &device, DeviceList) + { + if (device.Size == 0) + continue; + + vector fields (DeviceListCtrl->GetColumnCount()); + + if (DeviceListCtrl->GetItemCount() > 0) + Gui->AppendToListCtrl (DeviceListCtrl, fields); + +#ifdef TC_WINDOWS + fields[ColumnDevice] = StringFormatter (L"{0} {1}:", _("Harddisk"), device.SystemNumber); + fields[ColumnDrive] = device.MountPoint; + fields[ColumnName] = device.Name; +#else + fields[ColumnDevice] = wstring (device.Path) + L":"; + fields[ColumnMountPoint] = device.MountPoint; +#endif + fields[ColumnSize] = Gui->SizeToString (device.Size); + Gui->AppendToListCtrl (DeviceListCtrl, fields, 0, &device); + + foreach_ref (HostDevice &partition, device.Partitions) + { + fields[ColumnDevice] = +#ifndef TC_WINDOWS + wstring (L" ") + +#endif + wstring (partition.Path); + +#ifdef TC_WINDOWS + fields[ColumnDrive] = partition.MountPoint; + fields[ColumnName] = partition.Name; +#else + fields[ColumnMountPoint] = partition.MountPoint; +#endif + fields[ColumnSize] = Gui->SizeToString (partition.Size); + Gui->AppendToListCtrl (DeviceListCtrl, fields, -1, &partition); + } + } + + Gui->SetListCtrlWidth (DeviceListCtrl, 73); + Gui->SetListCtrlHeight (DeviceListCtrl, 16); + Gui->SetListCtrlColumnWidths (DeviceListCtrl, colPermilles); + + Fit(); + Layout(); + Center(); + + StdButtonsOK->Disable(); + StdButtonsOK->SetDefault(); + } + + void DeviceSelectionDialog::OnListItemActivated (wxListEvent& event) + { + if (StdButtonsOK->IsEnabled()) + EndModal (wxID_OK); + } + + void DeviceSelectionDialog::OnListItemDeselected (wxListEvent& event) + { + if (DeviceListCtrl->GetSelectedItemCount() == 0) + StdButtonsOK->Disable(); + } + + void DeviceSelectionDialog::OnListItemSelected (wxListEvent& event) + { + HostDevice *device = (HostDevice *) (event.GetItem().GetData()); + if (device) + { + SelectedDevice = *device; + StdButtonsOK->Enable(); + } + else + StdButtonsOK->Disable(); + } +} diff --git a/src/Main/Forms/DeviceSelectionDialog.h b/src/Main/Forms/DeviceSelectionDialog.h new file mode 100644 index 00000000..df0b6184 --- /dev/null +++ b/src/Main/Forms/DeviceSelectionDialog.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_DeviceSelectionDialog +#define TC_HEADER_Main_Forms_DeviceSelectionDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class DeviceSelectionDialog : public DeviceSelectionDialogBase + { + public: + DeviceSelectionDialog (wxWindow* parent); + + HostDeviceList DeviceList; + HostDevice SelectedDevice; + + protected: + enum + { + ColumnDevice = 0, +#ifdef TC_WINDOWS + ColumnDrive, +#endif + ColumnSize, +#ifdef TC_WINDOWS + ColumnName +#else + ColumnMountPoint +#endif + }; + + void OnListItemActivated (wxListEvent& event); + void OnListItemDeselected (wxListEvent& event); + void OnListItemSelected (wxListEvent& event); + }; +} + +#endif // TC_HEADER_Main_Forms_DeviceSelectionDialog diff --git a/src/Main/Forms/EncryptionOptionsWizardPage.cpp b/src/Main/Forms/EncryptionOptionsWizardPage.cpp new file mode 100644 index 00000000..d321add2 --- /dev/null +++ b/src/Main/Forms/EncryptionOptionsWizardPage.cpp @@ -0,0 +1,137 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Volume/EncryptionTest.h" +#include "Volume/Hash.h" +#include "Main/GraphicUserInterface.h" +#include "BenchmarkDialog.h" +#include "EncryptionOptionsWizardPage.h" +#include "EncryptionTestDialog.h" + +namespace TrueCrypt +{ + EncryptionOptionsWizardPage::EncryptionOptionsWizardPage (wxPanel* parent) + : EncryptionOptionsWizardPageBase (parent) + { + + EncryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); + foreach (shared_ptr ea, EncryptionAlgorithms) + { + if (!ea->IsDeprecated()) + EncryptionAlgorithmChoice->Append (ea->GetName(), ea.get()); + } + + EncryptionAlgorithmChoice->Select (0); + + Hashes = Hash::GetAvailableAlgorithms(); + foreach (shared_ptr hash, Hashes) + { + if (!hash->IsDeprecated()) + HashChoice->Append (hash->GetName(), hash.get()); + } + + HashChoice->Select (0); + OnEncryptionAlgorithmSelected(); + + } + + shared_ptr EncryptionOptionsWizardPage::GetEncryptionAlgorithm () const + { + return Gui->GetSelectedData (EncryptionAlgorithmChoice)->GetNew(); + } + + shared_ptr EncryptionOptionsWizardPage::GetHash () const + { + return Gui->GetSelectedData (HashChoice)->GetNew(); + } + + void EncryptionOptionsWizardPage::OnBenchmarkButtonClick (wxCommandEvent& event) + { + BenchmarkDialog dialog (this); + dialog.ShowModal(); + } + + void EncryptionOptionsWizardPage::OnEncryptionAlgorithmSelected () + { + FreezeScope freeze (this); + + shared_ptr ea = GetEncryptionAlgorithm(); + CipherList ciphers = ea->GetCiphers(); + + if (ciphers.size() == 1) + { + EncryptionAlgorithmHyperlink->SetLabel (StringFormatter (LangString["MORE_INFO_ABOUT"], ea->GetName())); + + if (typeid (*ea) == typeid (AES)) + EncryptionAlgorithmStaticText->SetLabel (LangString["AES_HELP"]); + else if (typeid (*ea) == typeid (Serpent)) + EncryptionAlgorithmStaticText->SetLabel (LangString["SERPENT_HELP"]); + else if (typeid (*ea) == typeid (Twofish)) + EncryptionAlgorithmStaticText->SetLabel (LangString["TWOFISH_HELP"]); + else + EncryptionAlgorithmStaticText->SetLabel (L""); + } + else + { + if (ciphers.size() == 2) + { + EncryptionAlgorithmStaticText->SetLabel (StringFormatter (LangString["TWO_LAYER_CASCADE_HELP"], + ciphers[0]->GetName(), (int) ciphers[0]->GetKeySize() * 8, + ciphers[1]->GetName(), (int) ciphers[1]->GetKeySize() * 8)); + } + else if (ciphers.size() == 3) + { + EncryptionAlgorithmStaticText->SetLabel (StringFormatter (LangString["THREE_LAYER_CASCADE_HELP"], + ciphers[0]->GetName(), (int) ciphers[0]->GetKeySize() * 8, + ciphers[1]->GetName(), (int) ciphers[1]->GetKeySize() * 8, + ciphers[2]->GetName(), (int) ciphers[2]->GetKeySize() * 8)); + } + else + EncryptionAlgorithmStaticText->SetLabel (L""); + + EncryptionAlgorithmHyperlink->SetLabel (_("More information")); + } + + Layout(); + } + + void EncryptionOptionsWizardPage::OnEncryptionAlgorithmHyperlinkClick (wxHyperlinkEvent& event) + { + if (GetEncryptionAlgorithm()->GetCiphers().size() == 1) + Gui->OpenHomepageLink (this, wxString (GetEncryptionAlgorithm()->GetName()).Lower()); + else + Gui->OpenHomepageLink (this, L"cascades"); + } + + void EncryptionOptionsWizardPage::OnHashHyperlinkClick (wxHyperlinkEvent& event) + { + Gui->OpenHomepageLink (this, L"hashalgorithms"); + } + + void EncryptionOptionsWizardPage::OnTestButtonClick (wxCommandEvent& event) + { + EncryptionTestDialog dialog (this); + dialog.ShowModal(); + } + + void EncryptionOptionsWizardPage::SetEncryptionAlgorithm (shared_ptr algorithm) + { + if (algorithm) + { + EncryptionAlgorithmChoice->SetStringSelection (algorithm->GetName()); + OnEncryptionAlgorithmSelected (); + } + } + + void EncryptionOptionsWizardPage::SetHash (shared_ptr hash) + { + if (hash) + HashChoice->SetStringSelection (hash->GetName()); + } +} diff --git a/src/Main/Forms/EncryptionOptionsWizardPage.h b/src/Main/Forms/EncryptionOptionsWizardPage.h new file mode 100644 index 00000000..1c8b0d95 --- /dev/null +++ b/src/Main/Forms/EncryptionOptionsWizardPage.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_EncryptionOptionsWizardPage +#define TC_HEADER_Main_Forms_EncryptionOptionsWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class EncryptionOptionsWizardPage : public EncryptionOptionsWizardPageBase + { + public: + EncryptionOptionsWizardPage (wxPanel* parent); + + shared_ptr GetEncryptionAlgorithm () const; + shared_ptr GetHash () const; + bool IsValid () { return true; } + void SetPageText (const wxString &text) { } + void SetEncryptionAlgorithm (shared_ptr algorithm); + void SetHash (shared_ptr hash); + + protected: + void OnBenchmarkButtonClick (wxCommandEvent& event); + void OnEncryptionAlgorithmHyperlinkClick (wxHyperlinkEvent& event); + void OnEncryptionAlgorithmSelected (); + void OnEncryptionAlgorithmSelected (wxCommandEvent& event) { OnEncryptionAlgorithmSelected(); } + void OnHashHyperlinkClick (wxHyperlinkEvent& event); + void OnTestButtonClick (wxCommandEvent& event); + + EncryptionAlgorithmList EncryptionAlgorithms; + HashList Hashes; + }; +} + +#endif // TC_HEADER_Main_Forms_EncryptionOptionsWizardPage diff --git a/src/Main/Forms/EncryptionTestDialog.cpp b/src/Main/Forms/EncryptionTestDialog.cpp new file mode 100644 index 00000000..3e6fa6cc --- /dev/null +++ b/src/Main/Forms/EncryptionTestDialog.cpp @@ -0,0 +1,227 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Volume/EncryptionModeXTS.h" +#include "Volume/EncryptionTest.h" +#include "Main/GraphicUserInterface.h" +#include "EncryptionTestDialog.h" + +namespace TrueCrypt +{ + EncryptionTestDialog::EncryptionTestDialog (wxWindow* parent) + : EncryptionTestDialogBase (parent) + { + EncryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); + foreach (shared_ptr ea, EncryptionAlgorithms) + { + if (!ea->IsDeprecated()) + EncryptionAlgorithmChoice->Append (ea->GetName(), ea.get()); + } + + EncryptionAlgorithmChoice->Select (0); + Reset(); + + Fit(); + Layout(); + Center(); + } + + void EncryptionTestDialog::EncryptOrDecrypt (bool encrypt) + { + try + { + bool xts = XtsModeCheckBox->IsChecked(); + + shared_ptr ea = GetSelectedEncryptionAlgorithm(); + + Buffer key; + GetTextCtrlData (KeyTextCtrl, key); + + if (key.Size() != ea->GetKeySize()) + throw_err (LangString["TEST_KEY_SIZE"]); + + ea->SetKey (key); + + Buffer data; + GetTextCtrlData (encrypt ? PlainTextTextCtrl : CipherTextTextCtrl, data); + + if (data.Size() != ea->GetMaxBlockSize()) + throw_err (LangString[encrypt ? "TEST_PLAINTEXT_SIZE" : "TEST_CIPHERTEXT_SIZE"]); + + if (xts) + { + Buffer secondaryKey; + GetTextCtrlData (SecondaryKeyTextCtrl, secondaryKey); + + if (secondaryKey.Size() != ea->GetKeySize()) + throw_err (LangString["TEST_INCORRECT_SECONDARY_KEY_SIZE"]); + + uint64 dataUnitNumber; + size_t blockNumber; + + try + { + dataUnitNumber = StringConverter::ToUInt64 (wstring (DataUnitNumberTextCtrl->GetValue())); + } + catch (...) + { + DataUnitNumberTextCtrl->SetFocus(); + throw StringConversionFailed (SRC_POS); + } + + try + { + blockNumber = StringConverter::ToUInt32 (wstring (BlockNumberTextCtrl->GetValue())); + if (blockNumber > 31) + { + blockNumber = 31; + BlockNumberTextCtrl->SetValue (L"31"); + } + } + catch (...) + { + BlockNumberTextCtrl->SetFocus(); + throw StringConversionFailed (SRC_POS); + } + + shared_ptr xts (new EncryptionModeXTS); + xts->SetKey (secondaryKey); + ea->SetMode (xts); + + Buffer sector (ENCRYPTION_DATA_UNIT_SIZE); + BufferPtr block = sector.GetRange (blockNumber * ea->GetMaxBlockSize(), ea->GetMaxBlockSize()); + + block.CopyFrom (data); + + if (encrypt) + ea->EncryptSectors (sector, dataUnitNumber, 1, sector.Size()); + else + ea->DecryptSectors (sector, dataUnitNumber, 1, sector.Size()); + + data.CopyFrom (block); + } + else + { + if (encrypt) + ea->GetCiphers().front()->EncryptBlock (data); + else + ea->GetCiphers().front()->DecryptBlock (data); + } + + SetTextCtrlData (encrypt ? CipherTextTextCtrl : PlainTextTextCtrl, data); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + shared_ptr EncryptionTestDialog::GetSelectedEncryptionAlgorithm () const + { + return Gui->GetSelectedData (EncryptionAlgorithmChoice)->GetNew(); + } + + void EncryptionTestDialog::GetTextCtrlData (wxTextCtrl *textCtrl, Buffer &buffer) const + { + vector data; + string dataStr = StringConverter::ToSingle (wstring (textCtrl->GetValue())); + + for (size_t i = 0; i < dataStr.size() / 2; ++i) + { + unsigned int dataByte; + if (sscanf (dataStr.substr (i * 2, 2).c_str(), "%x", &dataByte) != 1) + { + textCtrl->SetFocus(); + throw StringConversionFailed (SRC_POS); + } + + data.push_back ((byte) dataByte); + } + + if (data.empty()) + return; + + buffer.CopyFrom (ConstBufferPtr (&data.front(), data.size())); + } + + void EncryptionTestDialog::OnAutoTestAllButtonClick (wxCommandEvent& event) + { + try + { + { + wxBusyCursor busy; + EncryptionTest::TestAll(); + } + + Gui->ShowInfo ("TESTS_PASSED"); + } + catch (Exception &e) + { + Gui->ShowError (e); + Gui->ShowError ("TESTS_FAILED"); + } + } + + void EncryptionTestDialog::OnEncryptionAlgorithmSelected () + { + shared_ptr ea = GetSelectedEncryptionAlgorithm(); + + KeySizeStaticText->SetLabel (StringFormatter (L"{0} {1}", (uint32) ea->GetKeySize() * 8, LangString["BITS"])); + + Buffer key (ea->GetKeySize()); + key.Zero(); + SetTextCtrlData (KeyTextCtrl, key); + SetTextCtrlData (SecondaryKeyTextCtrl, key); + + Buffer block (ea->GetMaxBlockSize()); + block.Zero(); + SetTextCtrlData (PlainTextTextCtrl, block); + SetTextCtrlData (CipherTextTextCtrl, block); + + if (ea->GetCiphers().size() > 1) + { + XtsModeCheckBox->Disable(); + XtsModeCheckBox->SetValue (true); + SecondaryKeyTextCtrl->Enable (true); + DataUnitNumberTextCtrl->Enable (true); + BlockNumberTextCtrl->Enable (true); + } + else + XtsModeCheckBox->Enable(); + } + + void EncryptionTestDialog::OnXtsModeCheckBoxClick (wxCommandEvent& event) + { + bool enabled = event.IsChecked(); + SecondaryKeyTextCtrl->Enable (enabled); + DataUnitNumberTextCtrl->Enable (enabled); + BlockNumberTextCtrl->Enable (enabled); + } + + void EncryptionTestDialog::SetTextCtrlData (wxTextCtrl *textCtrl, const BufferPtr &data) + { + wstring str; + for (size_t i = 0; i < data.Size(); i++) + { + char strBuf[3]; + sprintf (strBuf, "%02x", (int) data[i]); + str += StringConverter::ToWide (strBuf); + } + + textCtrl->SetValue (str); + } + + void EncryptionTestDialog::Reset () + { + OnEncryptionAlgorithmSelected(); + + DataUnitNumberTextCtrl->SetValue (L"0"); + BlockNumberTextCtrl->SetValue (L"0"); + } +} diff --git a/src/Main/Forms/EncryptionTestDialog.h b/src/Main/Forms/EncryptionTestDialog.h new file mode 100644 index 00000000..3466ac98 --- /dev/null +++ b/src/Main/Forms/EncryptionTestDialog.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_EncryptionTestDialog +#define TC_HEADER_Main_Forms_EncryptionTestDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class EncryptionTestDialog : public EncryptionTestDialogBase + { + public: + EncryptionTestDialog (wxWindow* parent); + + protected: + void EncryptOrDecrypt (bool encrypt); + shared_ptr GetSelectedEncryptionAlgorithm () const; + void GetTextCtrlData (wxTextCtrl *textCtrl, Buffer &buffer) const; + void OnAutoTestAllButtonClick (wxCommandEvent& event); + void OnDecryptButtonClick (wxCommandEvent& event) { EncryptOrDecrypt (false); } + void OnEncryptButtonClick (wxCommandEvent& event) { EncryptOrDecrypt (true); } + void OnEncryptionAlgorithmSelected (); + void OnEncryptionAlgorithmSelected (wxCommandEvent& event) { OnEncryptionAlgorithmSelected(); } + void OnResetButtonClick (wxCommandEvent& event) { Reset(); } + void OnXtsModeCheckBoxClick (wxCommandEvent& event); + void SetTextCtrlData (wxTextCtrl *textCtrl, const BufferPtr &data); + void Reset (); + + EncryptionAlgorithmList EncryptionAlgorithms; + }; +} + +#endif // TC_HEADER_Main_Forms_EncryptionTestDialog diff --git a/src/Main/Forms/FavoriteVolumesDialog.cpp b/src/Main/Forms/FavoriteVolumesDialog.cpp new file mode 100644 index 00000000..7592b3c9 --- /dev/null +++ b/src/Main/Forms/FavoriteVolumesDialog.cpp @@ -0,0 +1,118 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "FavoriteVolumesDialog.h" + +namespace TrueCrypt +{ + FavoriteVolumesDialog::FavoriteVolumesDialog (wxWindow* parent, const FavoriteVolumeList &favorites, size_t newItemCount) + : FavoriteVolumesDialogBase (parent), Favorites (favorites) + { + list colPermilles; + FavoritesListCtrl->InsertColumn (ColumnVolumePath, LangString["VOLUME"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (500); + FavoritesListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (500); + + FavoritesListCtrl->SetMinSize (wxSize (400, -1)); + Gui->SetListCtrlHeight (FavoritesListCtrl, 15); + Gui->SetListCtrlColumnWidths (FavoritesListCtrl, colPermilles); + + Layout(); + Fit(); + Center(); + +#ifdef TC_MACOSX + // wxMac cannot insert items to wxListCtrl due to a bug + MoveUpButton->Show (false); + MoveDownButton->Show (false); +#endif + + vector fields (FavoritesListCtrl->GetColumnCount()); + size_t itemCount = 0; + foreach (shared_ptr favorite, Favorites) + { + fields[ColumnVolumePath] = favorite->Path; + fields[ColumnMountPoint] = favorite->MountPoint; + Gui->AppendToListCtrl (FavoritesListCtrl, fields, -1, favorite.get()); + + if (++itemCount > Favorites.size() - newItemCount) + { + FavoritesListCtrl->SetItemState (itemCount - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + FavoritesListCtrl->EnsureVisible (itemCount - 1); + } + } + + UpdateButtons(); + FavoritesListCtrl->SetFocus(); + } + + void FavoriteVolumesDialog::OnMoveDownButtonClick (wxCommandEvent& event) + { + FreezeScope freeze (this); + foreach_reverse (long itemIndex, Gui->GetListCtrlSelectedItems (FavoritesListCtrl)) + { + if (itemIndex >= FavoritesListCtrl->GetItemCount() - 1) + break; + Gui->MoveListCtrlItem (FavoritesListCtrl, itemIndex, itemIndex + 1); + } + UpdateButtons(); + } + + void FavoriteVolumesDialog::OnMoveUpButtonClick (wxCommandEvent& event) + { + FreezeScope freeze (this); + foreach (long itemIndex, Gui->GetListCtrlSelectedItems (FavoritesListCtrl)) + { + if (itemIndex == 0) + break; + + Gui->MoveListCtrlItem (FavoritesListCtrl, itemIndex, itemIndex - 1); + } + UpdateButtons(); + } + + void FavoriteVolumesDialog::OnOKButtonClick (wxCommandEvent& event) + { + FavoriteVolumeList newFavorites; + + for (long i = 0; i < FavoritesListCtrl->GetItemCount(); i++) + { + newFavorites.push_back (make_shared ( + *reinterpret_cast (FavoritesListCtrl->GetItemData (i)))); + } + + Favorites = newFavorites; + EndModal (wxID_OK); + } + + void FavoriteVolumesDialog::OnRemoveAllButtonClick (wxCommandEvent& event) + { + FavoritesListCtrl->DeleteAllItems(); + UpdateButtons(); + } + + void FavoriteVolumesDialog::OnRemoveButtonClick (wxCommandEvent& event) + { + long offset = 0; + foreach (long item, Gui->GetListCtrlSelectedItems (FavoritesListCtrl)) + FavoritesListCtrl->DeleteItem (item - offset++); + } + + void FavoriteVolumesDialog::UpdateButtons () + { + bool selected = FavoritesListCtrl->GetSelectedItemCount() > 0; + + MoveDownButton->Enable (selected); + MoveUpButton->Enable (selected); + RemoveAllButton->Enable (FavoritesListCtrl->GetItemCount() > 0); + RemoveButton->Enable (selected); + } +} diff --git a/src/Main/Forms/FavoriteVolumesDialog.h b/src/Main/Forms/FavoriteVolumesDialog.h new file mode 100644 index 00000000..7ab940a6 --- /dev/null +++ b/src/Main/Forms/FavoriteVolumesDialog.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_FavoriteVolumesDialog +#define TC_HEADER_Main_Forms_FavoriteVolumesDialog + +#include "Forms.h" +#include "Main/Main.h" +#include "Main/FavoriteVolume.h" + +namespace TrueCrypt +{ + class FavoriteVolumesDialog : public FavoriteVolumesDialogBase + { + public: + FavoriteVolumesDialog (wxWindow* parent, const FavoriteVolumeList &favorites, size_t newItemCount = 0); + + FavoriteVolumeList GetFavorites () const { return Favorites; } + + protected: + void OnListItemDeselected (wxListEvent& event) { UpdateButtons (); } + void OnListItemSelected (wxListEvent& event) { UpdateButtons (); } + void OnMoveUpButtonClick (wxCommandEvent& event); + void OnMoveDownButtonClick (wxCommandEvent& event); + void OnOKButtonClick (wxCommandEvent& event); + void OnRemoveAllButtonClick (wxCommandEvent& event); + void OnRemoveButtonClick (wxCommandEvent& event); + void UpdateButtons (); + + enum + { + ColumnVolumePath = 0, + ColumnMountPoint + }; + + FavoriteVolumeList Favorites; + }; +} + +#endif // TC_HEADER_Main_Forms_FavoriteVolumesDialog diff --git a/src/Main/Forms/Forms.cpp b/src/Main/Forms/Forms.cpp new file mode 100644 index 00000000..5825381c --- /dev/null +++ b/src/Main/Forms/Forms.cpp @@ -0,0 +1,3062 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "System.h" + +#include "Forms.h" + +/////////////////////////////////////////////////////////////////////////// +using namespace TrueCrypt; + +MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( -1,496 ), wxDefaultSize ); + + MainMenuBar = new wxMenuBar( 0 ); + VolumesMenu = new wxMenu(); + wxMenuItem* CreateNewVolumeMenuItem; + CreateNewVolumeMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Create New Volume...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( CreateNewVolumeMenuItem ); + + VolumesMenu->AppendSeparator(); + + MountVolumeMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Mount Volume") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( MountVolumeMenuItem ); + + wxMenuItem* AutoMountDevicesMenuItem; + AutoMountDevicesMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Auto-Mount All Device-Hosted Volumes") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( AutoMountDevicesMenuItem ); + + VolumesMenu->AppendSeparator(); + + DismountVolumeMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Dismount Volume") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( DismountVolumeMenuItem ); + + DismountAllMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Dismount All Mounted Volumes") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( DismountAllMenuItem ); + + VolumesMenu->AppendSeparator(); + + wxMenuItem* ChangePasswordMenuItem; + ChangePasswordMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Change Volume Password...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( ChangePasswordMenuItem ); + + wxMenuItem* ChangePkcs5PrfMenuItem; + ChangePkcs5PrfMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Change Header Key Derivation Algorithm...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( ChangePkcs5PrfMenuItem ); + + wxMenuItem* ChangeKeyfilesMenuItem; + ChangeKeyfilesMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Add/Remove Keyfiles to/from Volume...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( ChangeKeyfilesMenuItem ); + + wxMenuItem* RemoveKeyfilesMenuItem; + RemoveKeyfilesMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Remove All Keyfiles from Volume...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( RemoveKeyfilesMenuItem ); + + VolumesMenu->AppendSeparator(); + + VolumePropertiesMenuItem = new wxMenuItem( VolumesMenu, wxID_ANY, wxString( _("Volume Properties...") ) , wxEmptyString, wxITEM_NORMAL ); + VolumesMenu->Append( VolumePropertiesMenuItem ); + + MainMenuBar->Append( VolumesMenu, _("&Volumes") ); + + FavoritesMenu = new wxMenu(); + AddToFavoritesMenuItem = new wxMenuItem( FavoritesMenu, wxID_ANY, wxString( _("Add Selected Volume to Favorites...") ) , wxEmptyString, wxITEM_NORMAL ); + FavoritesMenu->Append( AddToFavoritesMenuItem ); + + AddAllMountedToFavoritesMenuItem = new wxMenuItem( FavoritesMenu, wxID_ANY, wxString( _("Add All Mounted Volumes to Favorites...") ) , wxEmptyString, wxITEM_NORMAL ); + FavoritesMenu->Append( AddAllMountedToFavoritesMenuItem ); + + wxMenuItem* OrganizeFavoritesMenuItem; + OrganizeFavoritesMenuItem = new wxMenuItem( FavoritesMenu, wxID_ANY, wxString( _("Organize Favorite Volumes...") ) , wxEmptyString, wxITEM_NORMAL ); + FavoritesMenu->Append( OrganizeFavoritesMenuItem ); + + FavoritesMenu->AppendSeparator(); + + wxMenuItem* MountAllFavoritesMenuItem; + MountAllFavoritesMenuItem = new wxMenuItem( FavoritesMenu, wxID_ANY, wxString( _("Mount Favorite Volumes") ) , wxEmptyString, wxITEM_NORMAL ); + FavoritesMenu->Append( MountAllFavoritesMenuItem ); + + FavoritesMenu->AppendSeparator(); + + MainMenuBar->Append( FavoritesMenu, _("&Favorites") ); + + ToolsMenu = new wxMenu(); + wxMenuItem* BenchmarkMenuItem; + BenchmarkMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Benchmark...") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( BenchmarkMenuItem ); + + wxMenuItem* EncryptionTestMenuItem; + EncryptionTestMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Test Vectors...") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( EncryptionTestMenuItem ); + + ToolsMenu->AppendSeparator(); + + wxMenuItem* VolumeCreationWizardMenuItem; + VolumeCreationWizardMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Volume Creation Wizard") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( VolumeCreationWizardMenuItem ); + + ToolsMenu->AppendSeparator(); + + BackupVolumeHeadersMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Backup Volume Header...") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( BackupVolumeHeadersMenuItem ); + + RestoreVolumeHeaderMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Restore Volume Header...") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( RestoreVolumeHeaderMenuItem ); + + ToolsMenu->AppendSeparator(); + + wxMenuItem* CreateKeyfileMenuItem; + CreateKeyfileMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Keyfile Generator") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( CreateKeyfileMenuItem ); + + wxMenuItem* ManageSecurityTokenKeyfilesMenuItem; + ManageSecurityTokenKeyfilesMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Manage Security Token Keyfiles...") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( ManageSecurityTokenKeyfilesMenuItem ); + + wxMenuItem* CloseAllSecurityTokenSessionsMenuItem; + CloseAllSecurityTokenSessionsMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Close All Security Token Sessions") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( CloseAllSecurityTokenSessionsMenuItem ); + + ToolsMenu->AppendSeparator(); + + WipeCachedPasswordsMenuItem = new wxMenuItem( ToolsMenu, wxID_ANY, wxString( _("Wipe Cached Passwords") ) , wxEmptyString, wxITEM_NORMAL ); + ToolsMenu->Append( WipeCachedPasswordsMenuItem ); + + MainMenuBar->Append( ToolsMenu, _("T&ools") ); + + SettingsMenu = new wxMenu(); + HotkeysMenuItem = new wxMenuItem( SettingsMenu, wxID_ANY, wxString( _("Hotkeys...") ) , wxEmptyString, wxITEM_NORMAL ); + SettingsMenu->Append( HotkeysMenuItem ); + + wxMenuItem* DefaultKeyfilesMenuItem; + DefaultKeyfilesMenuItem = new wxMenuItem( SettingsMenu, wxID_ANY, wxString( _("Default Keyfiles...") ) , wxEmptyString, wxITEM_NORMAL ); + SettingsMenu->Append( DefaultKeyfilesMenuItem ); + + wxMenuItem* SecurityTokenPreferencesMenuItem; + SecurityTokenPreferencesMenuItem = new wxMenuItem( SettingsMenu, wxID_ANY, wxString( _("Security Tokens...") ) , wxEmptyString, wxITEM_NORMAL ); + SettingsMenu->Append( SecurityTokenPreferencesMenuItem ); + + SettingsMenu->AppendSeparator(); + + PreferencesMenuItem = new wxMenuItem( SettingsMenu, wxID_PREFERENCES, wxString( _("&Preferences...") ) , wxEmptyString, wxITEM_NORMAL ); + SettingsMenu->Append( PreferencesMenuItem ); + + MainMenuBar->Append( SettingsMenu, _("Settin&gs") ); + + HelpMenu = new wxMenu(); + wxMenuItem* UserGuideMenuItem; + UserGuideMenuItem = new wxMenuItem( HelpMenu, wxID_HELP, wxString( _("User's Guide") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( UserGuideMenuItem ); + + wxMenuItem* OnlineHelpMenuItem; + OnlineHelpMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Online Help") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( OnlineHelpMenuItem ); + + wxMenuItem* BeginnersTutorialMenuItem; + BeginnersTutorialMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Beginner's Tutorial") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( BeginnersTutorialMenuItem ); + + wxMenuItem* FaqMenuItem; + FaqMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Frequently Asked Questions") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( FaqMenuItem ); + + HelpMenu->AppendSeparator(); + + wxMenuItem* WebsiteMenuItem; + WebsiteMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("TrueCrypt Website") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( WebsiteMenuItem ); + + wxMenuItem* DownloadsMenuItem; + DownloadsMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Downloads") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( DownloadsMenuItem ); + + wxMenuItem* NewsMenuItem; + NewsMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("News") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( NewsMenuItem ); + + wxMenuItem* VersionHistoryMenuItem; + VersionHistoryMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Version History") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( VersionHistoryMenuItem ); + + HelpMenu->AppendSeparator(); + + wxMenuItem* ContactMenuItem; + ContactMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Contact") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( ContactMenuItem ); + + wxMenuItem* LegalNoticesMenuItem; + LegalNoticesMenuItem = new wxMenuItem( HelpMenu, wxID_ANY, wxString( _("Legal Notices") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( LegalNoticesMenuItem ); + + wxMenuItem* AboutMenuItem; + AboutMenuItem = new wxMenuItem( HelpMenu, wxID_ABOUT, wxString( _("About") ) , wxEmptyString, wxITEM_NORMAL ); + HelpMenu->Append( AboutMenuItem ); + + MainMenuBar->Append( HelpMenu, _("&Help") ); + + this->SetMenuBar( MainMenuBar ); + + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxVERTICAL ); + + MainPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer48; + bSizer48 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer1; + sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + SlotListCtrl = new wxListCtrl( MainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES|wxSUNKEN_BORDER ); + sbSizer1->Add( SlotListCtrl, 1, wxALL|wxEXPAND, 5 ); + + bSizer48->Add( sbSizer1, 1, wxEXPAND, 5 ); + + LowStaticBoxSizer = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + HigherButtonSizer = new wxBoxSizer( wxVERTICAL ); + + LowStaticBoxSizer->Add( HigherButtonSizer, 0, wxEXPAND|wxTOP, 2 ); + + wxGridSizer* gSizer1; + gSizer1 = new wxGridSizer( 1, 3, 0, 0 ); + + wxBoxSizer* bSizer17; + bSizer17 = new wxBoxSizer( wxVERTICAL ); + + bSizer17->SetMinSize( wxSize( 138,34 ) ); + CreateVolumeButton = new wxButton( MainPanel, wxID_ANY, _("&Create Volume"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer17->Add( CreateVolumeButton, 1, wxALL|wxEXPAND, 5 ); + + gSizer1->Add( bSizer17, 0, 0, 5 ); + + wxBoxSizer* bSizer18; + bSizer18 = new wxBoxSizer( wxVERTICAL ); + + bSizer18->SetMinSize( wxSize( 138,34 ) ); + VolumePropertiesButton = new wxButton( MainPanel, wxID_ANY, _("&Volume Properties..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer18->Add( VolumePropertiesButton, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + gSizer1->Add( bSizer18, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxVERTICAL ); + + bSizer19->SetMinSize( wxSize( 138,34 ) ); + WipeCacheButton = new wxButton( MainPanel, wxID_ANY, _("&Wipe Cache"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer19->Add( WipeCacheButton, 1, wxALL|wxALIGN_RIGHT|wxEXPAND, 5 ); + + gSizer1->Add( bSizer19, 0, wxALIGN_RIGHT, 5 ); + + LowStaticBoxSizer->Add( gSizer1, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + + LowStaticBoxSizer->Add( 0, 0, 0, 0, 5 ); + + VolumeStaticBoxSizer = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, _("Volume") ), wxVERTICAL ); + + VolumeGridBagSizer = new wxGridBagSizer( 0, 0 ); + VolumeGridBagSizer->AddGrowableCol( 1 ); + VolumeGridBagSizer->AddGrowableRow( 0 ); + VolumeGridBagSizer->SetFlexibleDirection( wxBOTH ); + VolumeGridBagSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + LogoBitmap = new wxStaticBitmap( MainPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER ); + LogoBitmap->SetMinSize( wxSize( 42,52 ) ); + + VolumeGridBagSizer->Add( LogoBitmap, wxGBPosition( 0, 0 ), wxGBSpan( 2, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + VolumePathComboBox = new wxComboBox( MainPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN ); + VolumeGridBagSizer->Add( VolumePathComboBox, wxGBPosition( 0, 1 ), wxGBSpan( 1, 2 ), wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer191; + bSizer191 = new wxBoxSizer( wxVERTICAL ); + + bSizer191->SetMinSize( wxSize( 138,34 ) ); + SelectFileButton = new wxButton( MainPanel, wxID_ANY, _("Select &File..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer191->Add( SelectFileButton, 1, wxALL|wxEXPAND, 5 ); + + VolumeGridBagSizer->Add( bSizer191, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 ); + + NoHistoryCheckBox = new wxCheckBox( MainPanel, wxID_ANY, _("&Never save history"), wxDefaultPosition, wxDefaultSize, 0 ); + + VolumeGridBagSizer->Add( NoHistoryCheckBox, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + bSizer20->SetMinSize( wxSize( 138,34 ) ); + VolumeToolsButton = new wxButton( MainPanel, wxID_ANY, _("Volume &Tools..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer20->Add( VolumeToolsButton, 1, wxALL|wxEXPAND, 5 ); + + VolumeGridBagSizer->Add( bSizer20, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_RIGHT, 5 ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + bSizer21->SetMinSize( wxSize( 138,34 ) ); + SelectDeviceButton = new wxButton( MainPanel, wxID_ANY, _("Select D&evice..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer21->Add( SelectDeviceButton, 1, wxEXPAND|wxALL, 5 ); + + VolumeGridBagSizer->Add( bSizer21, wxGBPosition( 1, 3 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 ); + + VolumeStaticBoxSizer->Add( VolumeGridBagSizer, 1, wxEXPAND|wxALL, 4 ); + + LowStaticBoxSizer->Add( VolumeStaticBoxSizer, 1, wxEXPAND, 5 ); + + + LowStaticBoxSizer->Add( 0, 0, 0, 0, 5 ); + + wxGridSizer* gSizer2; + gSizer2 = new wxGridSizer( 1, 4, 0, 0 ); + + wxStaticBoxSizer* sbSizer4; + sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + sbSizer4->SetMinSize( wxSize( 139,-1 ) ); + VolumeButton = new wxButton( MainPanel, wxID_ANY, _("&Mount"), wxDefaultPosition, wxDefaultSize, 0 ); + VolumeButton->SetDefault(); + VolumeButton->SetMinSize( wxSize( -1,32 ) ); + + sbSizer4->Add( VolumeButton, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP, 2 ); + + gSizer2->Add( sbSizer4, 1, wxEXPAND, 0 ); + + wxStaticBoxSizer* sbSizer41; + sbSizer41 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + MountAllDevicesButton = new wxButton( MainPanel, wxID_ANY, _("&Auto-Mount Devices"), wxDefaultPosition, wxDefaultSize, 0 ); + MountAllDevicesButton->SetMinSize( wxSize( -1,32 ) ); + + sbSizer41->Add( MountAllDevicesButton, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP, 2 ); + + gSizer2->Add( sbSizer41, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer42; + sbSizer42 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + DismountAllButton = new wxButton( MainPanel, wxID_ANY, _("Di&smount All"), wxDefaultPosition, wxDefaultSize, 0 ); + DismountAllButton->SetMinSize( wxSize( -1,32 ) ); + + sbSizer42->Add( DismountAllButton, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP, 2 ); + + gSizer2->Add( sbSizer42, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer43; + sbSizer43 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + ExitButton = new wxButton( MainPanel, wxID_ANY, _("E&xit"), wxDefaultPosition, wxDefaultSize, 0 ); + ExitButton->SetMinSize( wxSize( -1,32 ) ); + + sbSizer43->Add( ExitButton, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP, 2 ); + + gSizer2->Add( sbSizer43, 1, wxALIGN_RIGHT|wxEXPAND, 5 ); + + LowStaticBoxSizer->Add( gSizer2, 0, wxEXPAND, 5 ); + + bSizer48->Add( LowStaticBoxSizer, 0, wxEXPAND, 5 ); + + bSizer2->Add( bSizer48, 1, wxEXPAND, 5 ); + + MainPanel->SetSizer( bSizer2 ); + MainPanel->Layout(); + bSizer2->Fit( MainPanel ); + bSizer1->Add( MainPanel, 1, wxEXPAND, 0 ); + + this->SetSizer( bSizer1 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( MainFrameBase::OnActivate ) ); + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrameBase::OnClose ) ); + this->Connect( CreateNewVolumeMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ) ); + this->Connect( MountVolumeMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountVolumeMenuItemSelected ) ); + this->Connect( AutoMountDevicesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountAllDevicesButtonClick ) ); + this->Connect( DismountVolumeMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDismountVolumeMenuItemSelected ) ); + this->Connect( DismountAllMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDismountAllButtonClick ) ); + this->Connect( ChangePasswordMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangePasswordMenuItemSelected ) ); + this->Connect( ChangePkcs5PrfMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangePkcs5PrfMenuItemSelected ) ); + this->Connect( ChangeKeyfilesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangeKeyfilesMenuItemSelected ) ); + this->Connect( RemoveKeyfilesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnRemoveKeyfilesMenuItemSelected ) ); + this->Connect( VolumePropertiesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnVolumePropertiesButtonClick ) ); + this->Connect( AddToFavoritesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAddToFavoritesMenuItemSelected ) ); + this->Connect( AddAllMountedToFavoritesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAddAllMountedToFavoritesMenuItemSelected ) ); + this->Connect( OrganizeFavoritesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnOrganizeFavoritesMenuItemSelected ) ); + this->Connect( MountAllFavoritesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountAllFavoritesMenuItemSelected ) ); + this->Connect( BenchmarkMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBenchmarkMenuItemSelected ) ); + this->Connect( EncryptionTestMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnEncryptionTestMenuItemSelected ) ); + this->Connect( VolumeCreationWizardMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ) ); + this->Connect( BackupVolumeHeadersMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBackupVolumeHeadersMenuItemSelected ) ); + this->Connect( RestoreVolumeHeaderMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnRestoreVolumeHeaderMenuItemSelected ) ); + this->Connect( CreateKeyfileMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateKeyfileMenuItemSelected ) ); + this->Connect( ManageSecurityTokenKeyfilesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnManageSecurityTokenKeyfilesMenuItemSelected ) ); + this->Connect( CloseAllSecurityTokenSessionsMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCloseAllSecurityTokenSessionsMenuItemSelected ) ); + this->Connect( WipeCachedPasswordsMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnWipeCacheButtonClick ) ); + this->Connect( HotkeysMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnHotkeysMenuItemSelected ) ); + this->Connect( DefaultKeyfilesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDefaultKeyfilesMenuItemSelected ) ); + this->Connect( SecurityTokenPreferencesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnSecurityTokenPreferencesMenuItemSelected ) ); + this->Connect( PreferencesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnPreferencesMenuItemSelected ) ); + this->Connect( UserGuideMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnUserGuideMenuItemSelected ) ); + this->Connect( OnlineHelpMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnOnlineHelpMenuItemSelected ) ); + this->Connect( BeginnersTutorialMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBeginnersTutorialMenuItemSelected ) ); + this->Connect( FaqMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnFaqMenuItemSelected ) ); + this->Connect( WebsiteMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnWebsiteMenuItemSelected ) ); + this->Connect( DownloadsMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDownloadsMenuItemSelected ) ); + this->Connect( NewsMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnNewsMenuItemSelected ) ); + this->Connect( VersionHistoryMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnVersionHistoryMenuItemSelected ) ); + this->Connect( ContactMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnContactMenuItemSelected ) ); + this->Connect( LegalNoticesMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnLegalNoticesMenuItemSelected ) ); + this->Connect( AboutMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAboutMenuItemSelected ) ); + SlotListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( MainFrameBase::OnListItemActivated ), NULL, this ); + SlotListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( MainFrameBase::OnListItemDeselected ), NULL, this ); + SlotListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( MainFrameBase::OnListItemRightClick ), NULL, this ); + SlotListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( MainFrameBase::OnListItemSelected ), NULL, this ); + CreateVolumeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ), NULL, this ); + VolumePropertiesButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumePropertiesButtonClick ), NULL, this ); + WipeCacheButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnWipeCacheButtonClick ), NULL, this ); + LogoBitmap->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( MainFrameBase::OnLogoBitmapClick ), NULL, this ); + SelectFileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnSelectFileButtonClick ), NULL, this ); + NoHistoryCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainFrameBase::OnNoHistoryCheckBoxClick ), NULL, this ); + VolumeToolsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumeToolsButtonClick ), NULL, this ); + SelectDeviceButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnSelectDeviceButtonClick ), NULL, this ); + VolumeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumeButtonClick ), NULL, this ); + MountAllDevicesButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnMountAllDevicesButtonClick ), NULL, this ); + DismountAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnDismountAllButtonClick ), NULL, this ); + ExitButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnExitButtonClick ), NULL, this ); +} + +MainFrameBase::~MainFrameBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( MainFrameBase::OnActivate ) ); + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrameBase::OnClose ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountVolumeMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountAllDevicesButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDismountVolumeMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDismountAllButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangePasswordMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangePkcs5PrfMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnChangeKeyfilesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnRemoveKeyfilesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnVolumePropertiesButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAddToFavoritesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAddAllMountedToFavoritesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnOrganizeFavoritesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnMountAllFavoritesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBenchmarkMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnEncryptionTestMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBackupVolumeHeadersMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnRestoreVolumeHeaderMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCreateKeyfileMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnManageSecurityTokenKeyfilesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnCloseAllSecurityTokenSessionsMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnWipeCacheButtonClick ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnHotkeysMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDefaultKeyfilesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnSecurityTokenPreferencesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnPreferencesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnUserGuideMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnOnlineHelpMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnBeginnersTutorialMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnFaqMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnWebsiteMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnDownloadsMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnNewsMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnVersionHistoryMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnContactMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnLegalNoticesMenuItemSelected ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrameBase::OnAboutMenuItemSelected ) ); + SlotListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( MainFrameBase::OnListItemActivated ), NULL, this ); + SlotListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( MainFrameBase::OnListItemDeselected ), NULL, this ); + SlotListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( MainFrameBase::OnListItemRightClick ), NULL, this ); + SlotListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( MainFrameBase::OnListItemSelected ), NULL, this ); + CreateVolumeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnCreateVolumeButtonClick ), NULL, this ); + VolumePropertiesButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumePropertiesButtonClick ), NULL, this ); + WipeCacheButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnWipeCacheButtonClick ), NULL, this ); + LogoBitmap->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( MainFrameBase::OnLogoBitmapClick ), NULL, this ); + SelectFileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnSelectFileButtonClick ), NULL, this ); + NoHistoryCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainFrameBase::OnNoHistoryCheckBoxClick ), NULL, this ); + VolumeToolsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumeToolsButtonClick ), NULL, this ); + SelectDeviceButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnSelectDeviceButtonClick ), NULL, this ); + VolumeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnVolumeButtonClick ), NULL, this ); + MountAllDevicesButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnMountAllDevicesButtonClick ), NULL, this ); + DismountAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnDismountAllButtonClick ), NULL, this ); + ExitButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrameBase::OnExitButtonClick ), NULL, this ); +} + +WizardFrameBase::WizardFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer92; + bSizer92 = new wxBoxSizer( wxVERTICAL ); + + MainPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer27; + sbSizer27 = new wxStaticBoxSizer( new wxStaticBox( MainPanel, wxID_ANY, wxEmptyString ), wxHORIZONTAL ); + + WizardBitmap = new wxStaticBitmap( MainPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + sbSizer27->Add( WizardBitmap, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer126; + bSizer126 = new wxBoxSizer( wxHORIZONTAL ); + + PageTitleStaticText = new wxStaticText( MainPanel, wxID_ANY, _("Page Title"), wxDefaultPosition, wxDefaultSize, 0 ); + PageTitleStaticText->Wrap( -1 ); + PageTitleStaticText->SetFont( wxFont( 16, 70, 90, 90, false, wxT("Times New Roman") ) ); + + bSizer126->Add( PageTitleStaticText, 0, wxALL, 5 ); + + bSizer66->Add( bSizer126, 0, wxLEFT, 5 ); + + PageSizer = new wxBoxSizer( wxVERTICAL ); + + bSizer66->Add( PageSizer, 1, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + sbSizer27->Add( bSizer66, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer64->Add( sbSizer27, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer70; + bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer70->Add( 0, 0, 1, wxEXPAND, 5 ); + + HelpButton = new wxButton( MainPanel, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer70->Add( HelpButton, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer70->Add( 0, 0, 0, wxLEFT|wxALIGN_RIGHT, 5 ); + + PreviousButton = new wxButton( MainPanel, wxID_ANY, _("< &Prev"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer70->Add( PreviousButton, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + NextButton = new wxButton( MainPanel, wxID_ANY, _("&Next >"), wxDefaultPosition, wxDefaultSize, 0|wxWANTS_CHARS ); + NextButton->SetDefault(); + bSizer70->Add( NextButton, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer70->Add( 0, 0, 0, wxLEFT|wxALIGN_RIGHT, 5 ); + + CancelButton = new wxButton( MainPanel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer70->Add( CancelButton, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer64->Add( bSizer70, 0, wxEXPAND|wxALIGN_RIGHT|wxALL, 5 ); + + bSizer63->Add( bSizer64, 1, wxEXPAND, 5 ); + + MainPanel->SetSizer( bSizer63 ); + MainPanel->Layout(); + bSizer63->Fit( MainPanel ); + bSizer92->Add( MainPanel, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer92 ); + this->Layout(); + bSizer92->Fit( this ); + + // Connect Events + this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( WizardFrameBase::OnActivate ) ); + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( WizardFrameBase::OnClose ) ); + MainPanel->Connect( wxEVT_MOTION, wxMouseEventHandler( WizardFrameBase::OnMouseMotion ), NULL, this ); + HelpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnHelpButtonClick ), NULL, this ); + PreviousButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnPreviousButtonClick ), NULL, this ); + NextButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnNextButtonClick ), NULL, this ); + CancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnCancelButtonClick ), NULL, this ); +} + +WizardFrameBase::~WizardFrameBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_ACTIVATE, wxActivateEventHandler( WizardFrameBase::OnActivate ) ); + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( WizardFrameBase::OnClose ) ); + MainPanel->Disconnect( wxEVT_MOTION, wxMouseEventHandler( WizardFrameBase::OnMouseMotion ), NULL, this ); + HelpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnHelpButtonClick ), NULL, this ); + PreviousButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnPreviousButtonClick ), NULL, this ); + NextButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnNextButtonClick ), NULL, this ); + CancelButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WizardFrameBase::OnCancelButtonClick ), NULL, this ); +} + +AboutDialogBase::AboutDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer117; + bSizer117 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer120; + bSizer120 = new wxBoxSizer( wxVERTICAL ); + + bSizer120->SetMinSize( wxSize( -1,78 ) ); + m_panel14 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel14->SetBackgroundColour( wxColour( 10, 108, 206 ) ); + + wxBoxSizer* bSizer121; + bSizer121 = new wxBoxSizer( wxVERTICAL ); + + + bSizer121->Add( 0, 0, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer122; + bSizer122 = new wxBoxSizer( wxVERTICAL ); + + LogoBitmap = new wxStaticBitmap( m_panel14, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer122->Add( LogoBitmap, 0, wxALL, 10 ); + + bSizer121->Add( bSizer122, 0, wxEXPAND|wxLEFT, 8 ); + + m_panel14->SetSizer( bSizer121 ); + m_panel14->Layout(); + bSizer121->Fit( m_panel14 ); + bSizer120->Add( m_panel14, 1, wxEXPAND, 5 ); + + bSizer117->Add( bSizer120, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer118; + bSizer118 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer123; + bSizer123 = new wxBoxSizer( wxVERTICAL ); + + VersionStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + VersionStaticText->Wrap( -1 ); + bSizer123->Add( VersionStaticText, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + + bSizer123->Add( 0, 0, 0, wxTOP, 3 ); + + CopyrightStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + CopyrightStaticText->Wrap( -1 ); + bSizer123->Add( CopyrightStaticText, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizer123->Add( 0, 0, 0, wxTOP, 3 ); + + WebsiteHyperlink = new wxHyperlinkCtrl( this, wxID_ANY, wxEmptyString, wxT("."), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + + WebsiteHyperlink->SetHoverColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + WebsiteHyperlink->SetNormalColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + WebsiteHyperlink->SetVisitedColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + bSizer123->Add( WebsiteHyperlink, 0, wxALL, 5 ); + + bSizer118->Add( bSizer123, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer117->Add( bSizer118, 1, wxALL|wxEXPAND, 15 ); + + m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer117->Add( m_staticline3, 0, wxEXPAND|wxBOTTOM, 5 ); + + CreditsTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxSUNKEN_BORDER ); + bSizer117->Add( CreditsTextCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 10 ); + + + bSizer117->Add( 0, 0, 0, wxTOP, 5 ); + + m_staticline4 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer117->Add( m_staticline4, 0, wxEXPAND|wxTOP|wxBOTTOM, 3 ); + + m_staticline5 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer117->Add( m_staticline5, 0, wxEXPAND|wxBOTTOM, 5 ); + + wxBoxSizer* bSizer119; + bSizer119 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer119->Add( 0, 0, 1, wxEXPAND|wxALL, 5 ); + + wxButton* OKButton; + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer119->Add( OKButton, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer119->Add( 0, 0, 0, wxLEFT, 5 ); + + bSizer117->Add( bSizer119, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 6 ); + + bSizer116->Add( bSizer117, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer116 ); + this->Layout(); + bSizer116->Fit( this ); + + // Connect Events + WebsiteHyperlink->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( AboutDialogBase::OnWebsiteHyperlinkClick ), NULL, this ); +} + +AboutDialogBase::~AboutDialogBase() +{ + // Disconnect Events + WebsiteHyperlink->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( AboutDialogBase::OnWebsiteHyperlinkClick ), NULL, this ); +} + +BenchmarkDialogBase::BenchmarkDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer153; + bSizer153 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer154; + bSizer154 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer155; + bSizer155 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText54; + m_staticText54 = new wxStaticText( this, wxID_ANY, _("Buffer Size:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText54->Wrap( -1 ); + bSizer155->Add( m_staticText54, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxArrayString BufferSizeChoiceChoices; + BufferSizeChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, BufferSizeChoiceChoices, 0 ); + BufferSizeChoice->SetSelection( 0 ); + bSizer155->Add( BufferSizeChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer154->Add( bSizer155, 0, wxEXPAND, 5 ); + + wxStaticLine* m_staticline6; + m_staticline6 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer154->Add( m_staticline6, 0, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer( wxHORIZONTAL ); + + BenchmarkListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxSUNKEN_BORDER ); + bSizer156->Add( BenchmarkListCtrl, 1, wxALL|wxEXPAND, 5 ); + + RightSizer = new wxBoxSizer( wxVERTICAL ); + + BenchmarkButton = new wxButton( this, wxID_OK, _("Benchmark"), wxDefaultPosition, wxDefaultSize, 0 ); + BenchmarkButton->SetDefault(); + RightSizer->Add( BenchmarkButton, 0, wxALL|wxEXPAND, 5 ); + + wxButton* CancelButton; + CancelButton = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + RightSizer->Add( CancelButton, 0, wxALL|wxEXPAND, 5 ); + + + RightSizer->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + BenchmarkNoteStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + BenchmarkNoteStaticText->Wrap( -1 ); + RightSizer->Add( BenchmarkNoteStaticText, 1, wxALL|wxEXPAND, 5 ); + + bSizer156->Add( RightSizer, 0, wxEXPAND, 5 ); + + bSizer154->Add( bSizer156, 1, wxEXPAND, 5 ); + + bSizer153->Add( bSizer154, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer153 ); + this->Layout(); + bSizer153->Fit( this ); + + // Connect Events + BenchmarkButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BenchmarkDialogBase::OnBenchmarkButtonClick ), NULL, this ); +} + +BenchmarkDialogBase::~BenchmarkDialogBase() +{ + // Disconnect Events + BenchmarkButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BenchmarkDialogBase::OnBenchmarkButtonClick ), NULL, this ); +} + +ChangePasswordDialogBase::ChangePasswordDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer30; + bSizer30 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer31; + bSizer31 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer32; + bSizer32 = new wxBoxSizer( wxVERTICAL ); + + CurrentSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Current") ), wxVERTICAL ); + + CurrentPasswordPanelSizer = new wxBoxSizer( wxVERTICAL ); + + CurrentSizer->Add( CurrentPasswordPanelSizer, 0, wxALIGN_RIGHT, 5 ); + + bSizer32->Add( CurrentSizer, 0, wxEXPAND, 5 ); + + NewSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("New") ), wxVERTICAL ); + + NewPasswordPanelSizer = new wxBoxSizer( wxVERTICAL ); + + NewSizer->Add( NewPasswordPanelSizer, 0, wxALIGN_RIGHT, 5 ); + + bSizer32->Add( NewSizer, 0, wxTOP|wxEXPAND, 5 ); + + bSizer31->Add( bSizer32, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer33; + bSizer33 = new wxBoxSizer( wxVERTICAL ); + + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer33->Add( OKButton, 0, wxALL|wxEXPAND, 5 ); + + CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer33->Add( CancelButton, 0, wxALL|wxEXPAND, 5 ); + + bSizer31->Add( bSizer33, 0, 0, 5 ); + + bSizer30->Add( bSizer31, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer30 ); + this->Layout(); + bSizer30->Fit( this ); + + // Connect Events + OKButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ChangePasswordDialogBase::OnOKButtonClick ), NULL, this ); +} + +ChangePasswordDialogBase::~ChangePasswordDialogBase() +{ + // Disconnect Events + OKButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ChangePasswordDialogBase::OnOKButtonClick ), NULL, this ); +} + +DeviceSelectionDialogBase::DeviceSelectionDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer4; + bSizer4 = new wxBoxSizer( wxVERTICAL ); + + DeviceListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES|wxSUNKEN_BORDER ); + bSizer4->Add( DeviceListCtrl, 1, wxALL|wxEXPAND, 5 ); + + StdButtons = new wxStdDialogButtonSizer(); + StdButtonsOK = new wxButton( this, wxID_OK ); + StdButtons->AddButton( StdButtonsOK ); + StdButtonsCancel = new wxButton( this, wxID_CANCEL ); + StdButtons->AddButton( StdButtonsCancel ); + StdButtons->Realize(); + bSizer4->Add( StdButtons, 0, wxEXPAND|wxALL, 5 ); + + bSizer3->Add( bSizer4, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer3 ); + this->Layout(); + bSizer3->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + DeviceListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemActivated ), NULL, this ); + DeviceListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemDeselected ), NULL, this ); + DeviceListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemSelected ), NULL, this ); +} + +DeviceSelectionDialogBase::~DeviceSelectionDialogBase() +{ + // Disconnect Events + DeviceListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemActivated ), NULL, this ); + DeviceListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemDeselected ), NULL, this ); + DeviceListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( DeviceSelectionDialogBase::OnListItemSelected ), NULL, this ); +} + +EncryptionTestDialogBase::EncryptionTestDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer132; + bSizer132 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer133; + bSizer133 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer134; + bSizer134 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText41; + m_staticText41 = new wxStaticText( this, wxID_ANY, _("Encryption algorithm:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText41->Wrap( -1 ); + bSizer134->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxArrayString EncryptionAlgorithmChoiceChoices; + EncryptionAlgorithmChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, EncryptionAlgorithmChoiceChoices, 0 ); + EncryptionAlgorithmChoice->SetSelection( 0 ); + bSizer134->Add( EncryptionAlgorithmChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + XtsModeCheckBox = new wxCheckBox( this, wxID_ANY, _("XTS mode"), wxDefaultPosition, wxDefaultSize, 0 ); + XtsModeCheckBox->SetValue(true); + + bSizer134->Add( XtsModeCheckBox, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer133->Add( bSizer134, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + wxStaticBoxSizer* sbSizer38; + sbSizer38 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Key (hexadecimal)") ), wxVERTICAL ); + + KeyTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + KeyTextCtrl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier") ) ); + + sbSizer38->Add( KeyTextCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer135; + bSizer135 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText43; + m_staticText43 = new wxStaticText( this, wxID_ANY, _("Key size:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText43->Wrap( -1 ); + bSizer135->Add( m_staticText43, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + KeySizeStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + KeySizeStaticText->Wrap( -1 ); + bSizer135->Add( KeySizeStaticText, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 ); + + sbSizer38->Add( bSizer135, 0, wxEXPAND, 5 ); + + bSizer133->Add( sbSizer38, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer39; + sbSizer39 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("XTS mode") ), wxVERTICAL ); + + wxStaticText* m_staticText45; + m_staticText45 = new wxStaticText( this, wxID_ANY, _("Secondary key (hexadecimal)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText45->Wrap( -1 ); + sbSizer39->Add( m_staticText45, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + SecondaryKeyTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + SecondaryKeyTextCtrl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier") ) ); + + sbSizer39->Add( SecondaryKeyTextCtrl, 0, wxEXPAND|wxALL, 5 ); + + wxStaticText* m_staticText46; + m_staticText46 = new wxStaticText( this, wxID_ANY, _("Data unit number (64-bit, data unit size is 512 bytes)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText46->Wrap( -1 ); + sbSizer39->Add( m_staticText46, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + DataUnitNumberTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + sbSizer39->Add( DataUnitNumberTextCtrl, 0, wxALL, 5 ); + + wxStaticText* m_staticText47; + m_staticText47 = new wxStaticText( this, wxID_ANY, _("Block number:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText47->Wrap( -1 ); + sbSizer39->Add( m_staticText47, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + BlockNumberTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + sbSizer39->Add( BlockNumberTextCtrl, 0, wxALL, 5 ); + + bSizer133->Add( sbSizer39, 1, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer40; + sbSizer40 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Plaintext (hexadecimal)") ), wxVERTICAL ); + + PlainTextTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + PlainTextTextCtrl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier") ) ); + + sbSizer40->Add( PlainTextTextCtrl, 0, wxALL|wxEXPAND, 5 ); + + bSizer133->Add( sbSizer40, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer41; + sbSizer41 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Ciphertext (hexadecimal)") ), wxVERTICAL ); + + CipherTextTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + CipherTextTextCtrl->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier") ) ); + + sbSizer41->Add( CipherTextTextCtrl, 0, wxALL|wxEXPAND, 5 ); + + bSizer133->Add( sbSizer41, 0, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer136; + bSizer136 = new wxBoxSizer( wxHORIZONTAL ); + + EncryptButton = new wxButton( this, wxID_ANY, _("&Encrypt"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer136->Add( EncryptButton, 0, wxALL, 5 ); + + DecryptButton = new wxButton( this, wxID_ANY, _("&Decrypt"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer136->Add( DecryptButton, 0, wxALL, 5 ); + + AutoTestAllButton = new wxButton( this, wxID_ANY, _("&Auto-Test All"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer136->Add( AutoTestAllButton, 0, wxALL, 5 ); + + ResetButton = new wxButton( this, wxID_ANY, _("&Reset"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer136->Add( ResetButton, 0, wxALL, 5 ); + + CloseButton = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer136->Add( CloseButton, 0, wxALL, 5 ); + + bSizer133->Add( bSizer136, 0, wxEXPAND, 5 ); + + bSizer132->Add( bSizer133, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer132 ); + this->Layout(); + bSizer132->Fit( this ); + + // Connect Events + EncryptionAlgorithmChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( EncryptionTestDialogBase::OnEncryptionAlgorithmSelected ), NULL, this ); + XtsModeCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnXtsModeCheckBoxClick ), NULL, this ); + EncryptButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnEncryptButtonClick ), NULL, this ); + DecryptButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnDecryptButtonClick ), NULL, this ); + AutoTestAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnAutoTestAllButtonClick ), NULL, this ); + ResetButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnResetButtonClick ), NULL, this ); +} + +EncryptionTestDialogBase::~EncryptionTestDialogBase() +{ + // Disconnect Events + EncryptionAlgorithmChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( EncryptionTestDialogBase::OnEncryptionAlgorithmSelected ), NULL, this ); + XtsModeCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnXtsModeCheckBoxClick ), NULL, this ); + EncryptButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnEncryptButtonClick ), NULL, this ); + DecryptButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnDecryptButtonClick ), NULL, this ); + AutoTestAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnAutoTestAllButtonClick ), NULL, this ); + ResetButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionTestDialogBase::OnResetButtonClick ), NULL, this ); +} + +FavoriteVolumesDialogBase::FavoriteVolumesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer57; + bSizer57 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer60; + bSizer60 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxVERTICAL ); + + FavoritesListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES|wxSUNKEN_BORDER ); + bSizer58->Add( FavoritesListCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxGridSizer* gSizer5; + gSizer5 = new wxGridSizer( 1, 4, 0, 0 ); + + MoveUpButton = new wxButton( this, wxID_ANY, _("Move &Up"), wxDefaultPosition, wxDefaultSize, 0 ); + gSizer5->Add( MoveUpButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + MoveDownButton = new wxButton( this, wxID_ANY, _("Move &Down"), wxDefaultPosition, wxDefaultSize, 0 ); + gSizer5->Add( MoveDownButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + RemoveButton = new wxButton( this, wxID_ANY, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + gSizer5->Add( RemoveButton, 0, wxALIGN_RIGHT|wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + RemoveAllButton = new wxButton( this, wxID_ANY, _("Remove &All"), wxDefaultPosition, wxDefaultSize, 0 ); + gSizer5->Add( RemoveAllButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + bSizer58->Add( gSizer5, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxFlexGridSizer* fgSizer4; + fgSizer4 = new wxFlexGridSizer( 1, 5, 0, 0 ); + fgSizer4->AddGrowableCol( 2 ); + fgSizer4->SetFlexibleDirection( wxBOTH ); + fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer58->Add( fgSizer4, 0, wxEXPAND, 5 ); + + bSizer60->Add( bSizer58, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer59; + bSizer59 = new wxBoxSizer( wxVERTICAL ); + + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer59->Add( OKButton, 0, wxALL, 5 ); + + CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer59->Add( CancelButton, 0, wxALL, 5 ); + + bSizer60->Add( bSizer59, 0, wxEXPAND, 5 ); + + bSizer57->Add( bSizer60, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer57 ); + this->Layout(); + bSizer57->Fit( this ); + + // Connect Events + FavoritesListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( FavoriteVolumesDialogBase::OnListItemDeselected ), NULL, this ); + FavoritesListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( FavoriteVolumesDialogBase::OnListItemSelected ), NULL, this ); + MoveUpButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnMoveUpButtonClick ), NULL, this ); + MoveDownButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnMoveDownButtonClick ), NULL, this ); + RemoveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnRemoveButtonClick ), NULL, this ); + RemoveAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnRemoveAllButtonClick ), NULL, this ); + OKButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnOKButtonClick ), NULL, this ); +} + +FavoriteVolumesDialogBase::~FavoriteVolumesDialogBase() +{ + // Disconnect Events + FavoritesListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( FavoriteVolumesDialogBase::OnListItemDeselected ), NULL, this ); + FavoritesListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( FavoriteVolumesDialogBase::OnListItemSelected ), NULL, this ); + MoveUpButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnMoveUpButtonClick ), NULL, this ); + MoveDownButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnMoveDownButtonClick ), NULL, this ); + RemoveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnRemoveButtonClick ), NULL, this ); + RemoveAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnRemoveAllButtonClick ), NULL, this ); + OKButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FavoriteVolumesDialogBase::OnOKButtonClick ), NULL, this ); +} + +KeyfilesDialogBase::KeyfilesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxVERTICAL ); + + UpperSizer = new wxBoxSizer( wxHORIZONTAL ); + + PanelSizer = new wxBoxSizer( wxVERTICAL ); + + UpperSizer->Add( PanelSizer, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer22; + bSizer22 = new wxBoxSizer( wxVERTICAL ); + + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer22->Add( OKButton, 0, wxALL|wxEXPAND, 5 ); + + CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer22->Add( CancelButton, 0, wxALL|wxEXPAND, 5 ); + + WarningStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + WarningStaticText->Wrap( -1 ); + bSizer22->Add( WarningStaticText, 1, wxALL|wxEXPAND, 5 ); + + UpperSizer->Add( bSizer22, 0, wxEXPAND, 5 ); + + bSizer26->Add( UpperSizer, 1, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxVERTICAL ); + + KeyfilesNoteSizer = new wxBoxSizer( wxVERTICAL ); + + wxStaticLine* m_staticline1; + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + KeyfilesNoteSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); + + KeyfilesNoteStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + KeyfilesNoteStaticText->Wrap( -1 ); + KeyfilesNoteSizer->Add( KeyfilesNoteStaticText, 0, wxALL|wxEXPAND, 5 ); + + wxStaticLine* m_staticline2; + m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + KeyfilesNoteSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 ); + + bSizer23->Add( KeyfilesNoteSizer, 1, wxEXPAND, 5 ); + + wxFlexGridSizer* fgSizer2; + fgSizer2 = new wxFlexGridSizer( 1, 2, 0, 0 ); + fgSizer2->AddGrowableCol( 0 ); + fgSizer2->SetFlexibleDirection( wxBOTH ); + fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + KeyfilesHyperlink = new wxHyperlinkCtrl( this, wxID_ANY, _("More information on keyfiles"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + + KeyfilesHyperlink->SetHoverColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + KeyfilesHyperlink->SetNormalColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + KeyfilesHyperlink->SetVisitedColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + fgSizer2->Add( KeyfilesHyperlink, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + CreateKeyfileButtton = new wxButton( this, wxID_ANY, _("&Generate Random Keyfile..."), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer2->Add( CreateKeyfileButtton, 0, wxALL, 5 ); + + bSizer23->Add( fgSizer2, 0, wxEXPAND, 5 ); + + bSizer26->Add( bSizer23, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + this->SetSizer( bSizer26 ); + this->Layout(); + bSizer26->Fit( this ); + + // Connect Events + KeyfilesHyperlink->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( KeyfilesDialogBase::OnKeyfilesHyperlinkClick ), NULL, this ); + CreateKeyfileButtton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesDialogBase::OnCreateKeyfileButttonClick ), NULL, this ); +} + +KeyfilesDialogBase::~KeyfilesDialogBase() +{ + // Disconnect Events + KeyfilesHyperlink->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( KeyfilesDialogBase::OnKeyfilesHyperlinkClick ), NULL, this ); + CreateKeyfileButtton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesDialogBase::OnCreateKeyfileButttonClick ), NULL, this ); +} + +KeyfileGeneratorDialogBase::KeyfileGeneratorDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + MainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer144; + bSizer144 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer145; + bSizer145 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer145->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxStaticText* m_staticText49; + m_staticText49 = new wxStaticText( this, wxID_ANY, _("Mixing PRF:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText49->Wrap( -1 ); + bSizer145->Add( m_staticText49, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + wxArrayString HashChoiceChoices; + HashChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, HashChoiceChoices, 0 ); + HashChoice->SetSelection( 0 ); + bSizer145->Add( HashChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer145->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer144->Add( bSizer145, 0, wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer43; + sbSizer43 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + wxBoxSizer* bSizer147; + bSizer147 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText52; + m_staticText52 = new wxStaticText( this, wxID_ANY, _("Random Pool:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText52->Wrap( -1 ); + bSizer147->Add( m_staticText52, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + RandomPoolStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + RandomPoolStaticText->Wrap( -1 ); + RandomPoolStaticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier New") ) ); + + bSizer147->Add( RandomPoolStaticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + ShowRandomPoolCheckBox = new wxCheckBox( this, wxID_ANY, _("Show"), wxDefaultPosition, wxDefaultSize, 0 ); + ShowRandomPoolCheckBox->SetValue(true); + + bSizer147->Add( ShowRandomPoolCheckBox, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + sbSizer43->Add( bSizer147, 0, wxEXPAND|wxTOP, 5 ); + + + sbSizer43->Add( 0, 0, 1, wxEXPAND, 5 ); + + MouseStaticText = new wxStaticText( this, wxID_ANY, _("IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases the cryptographic strength of the keyfile."), wxDefaultPosition, wxDefaultSize, 0 ); + MouseStaticText->Wrap( -1 ); + sbSizer43->Add( MouseStaticText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + sbSizer43->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer144->Add( sbSizer43, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer146; + bSizer146 = new wxBoxSizer( wxHORIZONTAL ); + + GenerateButton = new wxButton( this, wxID_ANY, _("Generate and Save Keyfile..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer146->Add( GenerateButton, 0, wxALL, 5 ); + + + bSizer146->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxButton* m_button61; + m_button61 = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer146->Add( m_button61, 0, wxALL, 5 ); + + bSizer144->Add( bSizer146, 0, wxEXPAND, 5 ); + + MainSizer->Add( bSizer144, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( MainSizer ); + this->Layout(); + MainSizer->Fit( this ); + + // Connect Events + this->Connect( wxEVT_MOTION, wxMouseEventHandler( KeyfileGeneratorDialogBase::OnMouseMotion ) ); + HashChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnHashSelected ), NULL, this ); + ShowRandomPoolCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); + GenerateButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnGenerateButtonClick ), NULL, this ); +} + +KeyfileGeneratorDialogBase::~KeyfileGeneratorDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( KeyfileGeneratorDialogBase::OnMouseMotion ) ); + HashChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnHashSelected ), NULL, this ); + ShowRandomPoolCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); + GenerateButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnGenerateButtonClick ), NULL, this ); +} + +LegalNoticesDialogBase::LegalNoticesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer114; + bSizer114 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer115; + bSizer115 = new wxBoxSizer( wxVERTICAL ); + + LegalNoticesTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); + bSizer115->Add( LegalNoticesTextCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxButton* OKButton; + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer115->Add( OKButton, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizer114->Add( bSizer115, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer114 ); + this->Layout(); + bSizer114->Fit( this ); +} + +LegalNoticesDialogBase::~LegalNoticesDialogBase() +{ +} + +MountOptionsDialogBase::MountOptionsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer5; + bSizer5 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer14; + bSizer14 = new wxBoxSizer( wxHORIZONTAL ); + + PasswordSizer = new wxBoxSizer( wxVERTICAL ); + + bSizer14->Add( PasswordSizer, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer9; + bSizer9 = new wxBoxSizer( wxVERTICAL ); + + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer9->Add( OKButton, 0, wxALL|wxEXPAND, 5 ); + + CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer9->Add( CancelButton, 0, wxALL|wxEXPAND, 5 ); + + + bSizer9->Add( 0, 0, 1, wxTOP|wxEXPAND, 5 ); + + OptionsButton = new wxButton( this, wxID_ANY, _("Op&tions"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer9->Add( OptionsButton, 0, wxALL|wxEXPAND, 5 ); + + bSizer14->Add( bSizer9, 0, wxEXPAND, 5 ); + + bSizer19->Add( bSizer14, 0, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer6; + bSizer6 = new wxBoxSizer( wxVERTICAL ); + + OptionsPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + OptionsSizer = new wxStaticBoxSizer( new wxStaticBox( OptionsPanel, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + + OptionsSizer->Add( 0, 0, 0, wxTOP, 5 ); + + ReadOnlyCheckBox = new wxCheckBox( OptionsPanel, wxID_ANY, _("Mount volume as &read-only"), wxDefaultPosition, wxDefaultSize, 0 ); + + OptionsSizer->Add( ReadOnlyCheckBox, 0, wxALL, 5 ); + + RemovableCheckBox = new wxCheckBox( OptionsPanel, wxID_ANY, _("Mount volume as removable &medium"), wxDefaultPosition, wxDefaultSize, 0 ); + + OptionsSizer->Add( RemovableCheckBox, 0, wxALL, 5 ); + + PartitionInSystemEncryptionScopeCheckBox = new wxCheckBox( OptionsPanel, wxID_ANY, _("Mount partition &using system encryption (preboot authentication)"), wxDefaultPosition, wxDefaultSize, 0 ); + + OptionsSizer->Add( PartitionInSystemEncryptionScopeCheckBox, 0, wxALL, 5 ); + + ProtectionSizer = new wxStaticBoxSizer( new wxStaticBox( OptionsPanel, wxID_ANY, _("Hidden Volume Protection") ), wxVERTICAL ); + + ProtectionCheckBox = new wxCheckBox( OptionsPanel, wxID_ANY, _("&Protect hidden volume when mounting outer volume"), wxDefaultPosition, wxDefaultSize, 0 ); + + ProtectionSizer->Add( ProtectionCheckBox, 0, wxALL, 5 ); + + ProtectionPasswordSizer = new wxBoxSizer( wxVERTICAL ); + + ProtectionSizer->Add( ProtectionPasswordSizer, 1, wxEXPAND|wxLEFT, 5 ); + + ProtectionHyperlinkCtrl = new wxHyperlinkCtrl( OptionsPanel, wxID_ANY, _("What is hidden volume protection?"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + + ProtectionHyperlinkCtrl->SetHoverColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + ProtectionHyperlinkCtrl->SetNormalColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + ProtectionHyperlinkCtrl->SetVisitedColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + ProtectionSizer->Add( ProtectionHyperlinkCtrl, 0, wxALL, 5 ); + + OptionsSizer->Add( ProtectionSizer, 1, wxEXPAND|wxALL, 5 ); + + FilesystemSizer = new wxBoxSizer( wxVERTICAL ); + + m_panel8 = new wxPanel( OptionsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxStaticBoxSizer* sbSizer28; + sbSizer28 = new wxStaticBoxSizer( new wxStaticBox( m_panel8, wxID_ANY, _("Filesystem") ), wxVERTICAL ); + + wxBoxSizer* bSizer54; + bSizer54 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer55; + bSizer55 = new wxBoxSizer( wxVERTICAL ); + + NoFilesystemCheckBox = new wxCheckBox( m_panel8, wxID_ANY, _("Do ¬ mount"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer55->Add( NoFilesystemCheckBox, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + bSizer54->Add( bSizer55, 1, wxEXPAND, 5 ); + + FilesystemOptionsSizer = new wxGridBagSizer( 0, 0 ); + FilesystemOptionsSizer->AddGrowableCol( 1 ); + FilesystemOptionsSizer->SetFlexibleDirection( wxBOTH ); + FilesystemOptionsSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + FilesystemOptionsSizer->SetEmptyCellSize( wxSize( 0,0 ) ); + + FilesystemSpacer = new wxBoxSizer( wxVERTICAL ); + + FilesystemOptionsSizer->Add( FilesystemSpacer, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxEXPAND|wxTOP, 5 ); + + MountPointTextCtrlStaticText = new wxStaticText( m_panel8, wxID_ANY, _("Mount at directory:"), wxDefaultPosition, wxDefaultSize, 0 ); + MountPointTextCtrlStaticText->Wrap( -1 ); + FilesystemOptionsSizer->Add( MountPointTextCtrlStaticText, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + MountPointTextCtrl = new wxTextCtrl( m_panel8, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + FilesystemOptionsSizer->Add( MountPointTextCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + MountPointButton = new wxButton( m_panel8, wxID_ANY, _("Se&lect..."), wxDefaultPosition, wxDefaultSize, 0 ); + FilesystemOptionsSizer->Add( MountPointButton, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + FilesystemOptionsStaticText = new wxStaticText( m_panel8, wxID_ANY, _("Mount options:"), wxDefaultPosition, wxDefaultSize, 0 ); + FilesystemOptionsStaticText->Wrap( -1 ); + FilesystemOptionsSizer->Add( FilesystemOptionsStaticText, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxLEFT, 5 ); + + FilesystemOptionsTextCtrl = new wxTextCtrl( m_panel8, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + FilesystemOptionsSizer->Add( FilesystemOptionsTextCtrl, wxGBPosition( 2, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + bSizer54->Add( FilesystemOptionsSizer, 0, wxEXPAND, 5 ); + + sbSizer28->Add( bSizer54, 0, wxEXPAND|wxBOTTOM, 5 ); + + m_panel8->SetSizer( sbSizer28 ); + m_panel8->Layout(); + sbSizer28->Fit( m_panel8 ); + FilesystemSizer->Add( m_panel8, 0, wxEXPAND | wxALL, 5 ); + + OptionsSizer->Add( FilesystemSizer, 0, wxEXPAND, 5 ); + + OptionsPanel->SetSizer( OptionsSizer ); + OptionsPanel->Layout(); + OptionsSizer->Fit( OptionsPanel ); + bSizer6->Add( OptionsPanel, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer19->Add( bSizer6, 0, wxEXPAND, 5 ); + + bSizer5->Add( bSizer19, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer5 ); + this->Layout(); + bSizer5->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( MountOptionsDialogBase::OnInitDialog ) ); + OKButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnOKButtonClick ), NULL, this ); + OptionsButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnOptionsButtonClick ), NULL, this ); + ReadOnlyCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnReadOnlyCheckBoxClick ), NULL, this ); + ProtectionCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnProtectionCheckBoxClick ), NULL, this ); + ProtectionHyperlinkCtrl->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MountOptionsDialogBase::OnProtectionHyperlinkClick ), NULL, this ); + NoFilesystemCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnNoFilesystemCheckBoxClick ), NULL, this ); + MountPointButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnMountPointButtonClick ), NULL, this ); +} + +MountOptionsDialogBase::~MountOptionsDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( MountOptionsDialogBase::OnInitDialog ) ); + OKButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnOKButtonClick ), NULL, this ); + OptionsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnOptionsButtonClick ), NULL, this ); + ReadOnlyCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnReadOnlyCheckBoxClick ), NULL, this ); + ProtectionCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnProtectionCheckBoxClick ), NULL, this ); + ProtectionHyperlinkCtrl->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MountOptionsDialogBase::OnProtectionHyperlinkClick ), NULL, this ); + NoFilesystemCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnNoFilesystemCheckBoxClick ), NULL, this ); + MountPointButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MountOptionsDialogBase::OnMountPointButtonClick ), NULL, this ); +} + +NewSecurityTokenKeyfileDialogBase::NewSecurityTokenKeyfileDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer143; + bSizer143 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer144; + bSizer144 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer42; + sbSizer42 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer7; + fgSizer7 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer7->SetFlexibleDirection( wxBOTH ); + fgSizer7->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* m_staticText47; + m_staticText47 = new wxStaticText( this, wxID_ANY, _("Security token:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText47->Wrap( -1 ); + fgSizer7->Add( m_staticText47, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxArrayString SecurityTokenChoiceChoices; + SecurityTokenChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, SecurityTokenChoiceChoices, 0 ); + SecurityTokenChoice->SetSelection( 0 ); + fgSizer7->Add( SecurityTokenChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + wxStaticText* m_staticText48; + m_staticText48 = new wxStaticText( this, wxID_ANY, _("Keyfile name:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText48->Wrap( -1 ); + fgSizer7->Add( m_staticText48, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + KeyfileNameTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer7->Add( KeyfileNameTextCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 5 ); + + sbSizer42->Add( fgSizer7, 1, wxEXPAND|wxTOP, 5 ); + + bSizer144->Add( sbSizer42, 1, wxEXPAND|wxALL, 5 ); + + StdButtons = new wxStdDialogButtonSizer(); + StdButtonsOK = new wxButton( this, wxID_OK ); + StdButtons->AddButton( StdButtonsOK ); + StdButtonsCancel = new wxButton( this, wxID_CANCEL ); + StdButtons->AddButton( StdButtonsCancel ); + StdButtons->Realize(); + bSizer144->Add( StdButtons, 0, wxALIGN_RIGHT|wxALL, 5 ); + + bSizer143->Add( bSizer144, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer143 ); + this->Layout(); + bSizer143->Fit( this ); + + // Connect Events + KeyfileNameTextCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( NewSecurityTokenKeyfileDialogBase::OnKeyfileNameChanged ), NULL, this ); +} + +NewSecurityTokenKeyfileDialogBase::~NewSecurityTokenKeyfileDialogBase() +{ + // Disconnect Events + KeyfileNameTextCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( NewSecurityTokenKeyfileDialogBase::OnKeyfileNameChanged ), NULL, this ); +} + +PreferencesDialogBase::PreferencesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer32; + bSizer32 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer41; + bSizer41 = new wxBoxSizer( wxVERTICAL ); + + PreferencesNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + SecurityPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer44; + bSizer44 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer33; + bSizer33 = new wxBoxSizer( wxVERTICAL ); + + AutoDismountSizer = new wxStaticBoxSizer( new wxStaticBox( SecurityPage, wxID_ANY, _("Auto-Dismount") ), wxVERTICAL ); + + wxStaticBoxSizer* sbSizer13; + sbSizer13 = new wxStaticBoxSizer( new wxStaticBox( SecurityPage, wxID_ANY, _("Dismount All Volumes When") ), wxVERTICAL ); + + DismountOnLogOffCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("User logs off"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer13->Add( DismountOnLogOffCheckBox, 0, wxALL, 5 ); + + DismountOnScreenSaverCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Screen saver is launched"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer13->Add( DismountOnScreenSaverCheckBox, 0, wxALL, 5 ); + + DismountOnPowerSavingCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("System is entering power saving mode"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer13->Add( DismountOnPowerSavingCheckBox, 0, wxALL, 5 ); + + AutoDismountSizer->Add( sbSizer13, 0, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer34; + bSizer34 = new wxBoxSizer( wxHORIZONTAL ); + + DismountOnInactivityCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Auto-dismount volume after no data has been read/written to it for"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer34->Add( DismountOnInactivityCheckBox, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + DismountOnInactivitySpinCtrl = new wxSpinCtrl( SecurityPage, wxID_ANY, wxT("1"), wxDefaultPosition, wxSize( 60,-1 ), wxSP_ARROW_KEYS, 1, 9999, 1 ); + bSizer34->Add( DismountOnInactivitySpinCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxStaticText* m_staticText5; + m_staticText5 = new wxStaticText( SecurityPage, wxID_ANY, _("minutes"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText5->Wrap( -1 ); + bSizer34->Add( m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + AutoDismountSizer->Add( bSizer34, 0, wxEXPAND, 5 ); + + ForceAutoDismountCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Force auto-dismount even if volume contains open files or directories"), wxDefaultPosition, wxDefaultSize, 0 ); + + AutoDismountSizer->Add( ForceAutoDismountCheckBox, 0, wxALL, 5 ); + + bSizer33->Add( AutoDismountSizer, 0, wxEXPAND|wxALL, 5 ); + + FilesystemSecuritySizer = new wxStaticBoxSizer( new wxStaticBox( SecurityPage, wxID_ANY, _("Filesystem") ), wxVERTICAL ); + + PreserveTimestampsCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Preserve modification timestamp of file containers"), wxDefaultPosition, wxDefaultSize, 0 ); + + FilesystemSecuritySizer->Add( PreserveTimestampsCheckBox, 0, wxALL, 5 ); + + bSizer33->Add( FilesystemSecuritySizer, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer14; + sbSizer14 = new wxStaticBoxSizer( new wxStaticBox( SecurityPage, wxID_ANY, _("Password Cache") ), wxVERTICAL ); + + WipeCacheOnCloseCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Wipe after TrueCrypt window has been closed"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer14->Add( WipeCacheOnCloseCheckBox, 0, wxALL, 5 ); + + WipeCacheOnAutoDismountCheckBox = new wxCheckBox( SecurityPage, wxID_ANY, _("Wipe after volume has been auto-dismounted"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer14->Add( WipeCacheOnAutoDismountCheckBox, 0, wxALL, 5 ); + + bSizer33->Add( sbSizer14, 0, wxEXPAND|wxALL, 5 ); + + bSizer44->Add( bSizer33, 1, wxEXPAND|wxALL, 5 ); + + SecurityPage->SetSizer( bSizer44 ); + SecurityPage->Layout(); + bSizer44->Fit( SecurityPage ); + PreferencesNotebook->AddPage( SecurityPage, _("Security"), true ); + DefaultMountOptionsPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer46; + bSizer46 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer35; + bSizer35 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer15; + sbSizer15 = new wxStaticBoxSizer( new wxStaticBox( DefaultMountOptionsPage, wxID_ANY, _("Default Mount Options") ), wxVERTICAL ); + + MountReadOnlyCheckBox = new wxCheckBox( DefaultMountOptionsPage, wxID_ANY, _("Mount volumes as read-only"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer15->Add( MountReadOnlyCheckBox, 0, wxALL, 5 ); + + MountRemovableCheckBox = new wxCheckBox( DefaultMountOptionsPage, wxID_ANY, _("Mount volumes as removable media"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer15->Add( MountRemovableCheckBox, 0, wxALL, 5 ); + + CachePasswordsCheckBox = new wxCheckBox( DefaultMountOptionsPage, wxID_ANY, _("Cache passwords in memory"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer15->Add( CachePasswordsCheckBox, 0, wxALL, 5 ); + + bSizer35->Add( sbSizer15, 0, wxEXPAND|wxALL, 5 ); + + FilesystemSizer = new wxStaticBoxSizer( new wxStaticBox( DefaultMountOptionsPage, wxID_ANY, _("Filesystem") ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer3; + fgSizer3 = new wxFlexGridSizer( 1, 2, 0, 0 ); + fgSizer3->AddGrowableCol( 1 ); + fgSizer3->SetFlexibleDirection( wxBOTH ); + fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* m_staticText6; + m_staticText6 = new wxStaticText( DefaultMountOptionsPage, wxID_ANY, _("Mount options:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText6->Wrap( -1 ); + fgSizer3->Add( m_staticText6, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 ); + + FilesystemOptionsTextCtrl = new wxTextCtrl( DefaultMountOptionsPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer3->Add( FilesystemOptionsTextCtrl, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + FilesystemSizer->Add( fgSizer3, 1, wxEXPAND, 5 ); + + bSizer35->Add( FilesystemSizer, 0, wxEXPAND|wxALL, 5 ); + + bSizer46->Add( bSizer35, 1, wxEXPAND|wxALL, 5 ); + + DefaultMountOptionsPage->SetSizer( bSizer46 ); + DefaultMountOptionsPage->Layout(); + bSizer46->Fit( DefaultMountOptionsPage ); + PreferencesNotebook->AddPage( DefaultMountOptionsPage, _("Mount Options"), false ); + BackgroundTaskPanel = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer61; + bSizer61 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer18; + sbSizer18 = new wxStaticBoxSizer( new wxStaticBox( BackgroundTaskPanel, wxID_ANY, _("TrueCrypt Background Task") ), wxVERTICAL ); + + BackgroundTaskEnabledCheckBox = new wxCheckBox( BackgroundTaskPanel, wxID_ANY, _("Enabled"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer18->Add( BackgroundTaskEnabledCheckBox, 0, wxALL, 5 ); + + CloseBackgroundTaskOnNoVolumesCheckBox = new wxCheckBox( BackgroundTaskPanel, wxID_ANY, _("Exit when there are no mounted volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer18->Add( CloseBackgroundTaskOnNoVolumesCheckBox, 0, wxALL, 5 ); + + wxStaticBoxSizer* sbSizer26; + sbSizer26 = new wxStaticBoxSizer( new wxStaticBox( BackgroundTaskPanel, wxID_ANY, _("Task Icon Menu Items") ), wxVERTICAL ); + + BackgroundTaskMenuMountItemsEnabledCheckBox = new wxCheckBox( BackgroundTaskPanel, wxID_ANY, _("Mount Favorite Volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer26->Add( BackgroundTaskMenuMountItemsEnabledCheckBox, 0, wxALL, 5 ); + + BackgroundTaskMenuOpenItemsEnabledCheckBox = new wxCheckBox( BackgroundTaskPanel, wxID_ANY, _("Open Mounted Volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer26->Add( BackgroundTaskMenuOpenItemsEnabledCheckBox, 0, wxALL, 5 ); + + BackgroundTaskMenuDismountItemsEnabledCheckBox = new wxCheckBox( BackgroundTaskPanel, wxID_ANY, _("Dismount Mounted Volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer26->Add( BackgroundTaskMenuDismountItemsEnabledCheckBox, 0, wxALL, 5 ); + + sbSizer18->Add( sbSizer26, 1, wxEXPAND|wxALL, 5 ); + + bSizer62->Add( sbSizer18, 0, wxEXPAND|wxALL, 5 ); + + bSizer61->Add( bSizer62, 1, wxEXPAND|wxALL, 5 ); + + BackgroundTaskPanel->SetSizer( bSizer61 ); + BackgroundTaskPanel->Layout(); + bSizer61->Fit( BackgroundTaskPanel ); + PreferencesNotebook->AddPage( BackgroundTaskPanel, _("Background Task"), false ); + SystemIntegrationPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer49; + bSizer49 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer37; + bSizer37 = new wxBoxSizer( wxVERTICAL ); + + LogOnSizer = new wxStaticBoxSizer( new wxStaticBox( SystemIntegrationPage, wxID_ANY, _("Actions to Perform when User Logs On") ), wxVERTICAL ); + + StartOnLogonCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Start TrueCrypt Background Task"), wxDefaultPosition, wxDefaultSize, 0 ); + + LogOnSizer->Add( StartOnLogonCheckBox, 0, wxALL, 5 ); + + MountFavoritesOnLogonCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Mount favorite volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + LogOnSizer->Add( MountFavoritesOnLogonCheckBox, 0, wxALL, 5 ); + + MountDevicesOnLogonCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Mount all device-hosted TrueCrypt volumes"), wxDefaultPosition, wxDefaultSize, 0 ); + + LogOnSizer->Add( MountDevicesOnLogonCheckBox, 0, wxALL, 5 ); + + bSizer37->Add( LogOnSizer, 0, wxALL|wxEXPAND, 5 ); + + ExplorerSizer = new wxStaticBoxSizer( new wxStaticBox( SystemIntegrationPage, wxID_ANY, _("Filesystem Explorer") ), wxVERTICAL ); + + OpenExplorerWindowAfterMountCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Open Explorer window for successfully mounted volume"), wxDefaultPosition, wxDefaultSize, 0 ); + + ExplorerSizer->Add( OpenExplorerWindowAfterMountCheckBox, 0, wxALL, 5 ); + + CloseExplorerWindowsOnDismountCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Close all Explorer windows of volume being dismounted"), wxDefaultPosition, wxDefaultSize, 0 ); + + ExplorerSizer->Add( CloseExplorerWindowsOnDismountCheckBox, 0, wxALL, 5 ); + + bSizer37->Add( ExplorerSizer, 0, wxEXPAND|wxALL, 5 ); + + KernelServicesSizer = new wxStaticBoxSizer( new wxStaticBox( SystemIntegrationPage, wxID_ANY, _("Kernel Services") ), wxVERTICAL ); + + NoKernelCryptoCheckBox = new wxCheckBox( SystemIntegrationPage, wxID_ANY, _("Do not use kernel cryptographic services"), wxDefaultPosition, wxDefaultSize, 0 ); + + KernelServicesSizer->Add( NoKernelCryptoCheckBox, 0, wxALL, 5 ); + + bSizer37->Add( KernelServicesSizer, 0, wxEXPAND|wxALL, 5 ); + + bSizer49->Add( bSizer37, 1, wxEXPAND|wxALL, 5 ); + + SystemIntegrationPage->SetSizer( bSizer49 ); + SystemIntegrationPage->Layout(); + bSizer49->Fit( SystemIntegrationPage ); + PreferencesNotebook->AddPage( SystemIntegrationPage, _("System Integration"), false ); + PerformanceOptionsPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer151; + bSizer151 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer152; + bSizer152 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer44; + sbSizer44 = new wxStaticBoxSizer( new wxStaticBox( PerformanceOptionsPage, wxID_ANY, _("Hardware Acceleration") ), wxVERTICAL ); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText57; + m_staticText57 = new wxStaticText( PerformanceOptionsPage, wxID_ANY, _("Processor (CPU) in this computer supports hardware acceleration for AES:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText57->Wrap( -1 ); + bSizer158->Add( m_staticText57, 0, wxALL, 5 ); + + AesHwCpuSupportedStaticText = new wxStaticText( PerformanceOptionsPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0|wxSUNKEN_BORDER ); + AesHwCpuSupportedStaticText->Wrap( -1 ); + bSizer158->Add( AesHwCpuSupportedStaticText, 0, wxALL, 5 ); + + sbSizer44->Add( bSizer158, 1, wxEXPAND, 5 ); + + + sbSizer44->Add( 0, 0, 0, wxBOTTOM, 5 ); + + NoHardwareCryptoCheckBox = new wxCheckBox( PerformanceOptionsPage, wxID_ANY, _("Do not accelerate AES encryption/decryption by using the AES instructions of the processor"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer44->Add( NoHardwareCryptoCheckBox, 0, wxALL, 5 ); + + bSizer152->Add( sbSizer44, 0, wxEXPAND|wxALL, 5 ); + + bSizer151->Add( bSizer152, 1, wxALL|wxEXPAND, 5 ); + + PerformanceOptionsPage->SetSizer( bSizer151 ); + PerformanceOptionsPage->Layout(); + bSizer151->Fit( PerformanceOptionsPage ); + PreferencesNotebook->AddPage( PerformanceOptionsPage, _("Performance"), false ); + DefaultKeyfilesPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer40; + bSizer40 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer43; + bSizer43 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* bSizer42; + bSizer42 = new wxStaticBoxSizer( new wxStaticBox( DefaultKeyfilesPage, wxID_ANY, _("Default Keyfiles") ), wxVERTICAL ); + + DefaultKeyfilesSizer = new wxBoxSizer( wxVERTICAL ); + + bSizer42->Add( DefaultKeyfilesSizer, 1, wxEXPAND, 5 ); + + bSizer43->Add( bSizer42, 1, wxEXPAND|wxALL, 5 ); + + UseKeyfilesCheckBox = new wxCheckBox( DefaultKeyfilesPage, wxID_ANY, _("Use keyfiles by default"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer43->Add( UseKeyfilesCheckBox, 0, wxALL, 5 ); + + bSizer40->Add( bSizer43, 1, wxEXPAND|wxALL, 5 ); + + DefaultKeyfilesPage->SetSizer( bSizer40 ); + DefaultKeyfilesPage->Layout(); + bSizer40->Fit( DefaultKeyfilesPage ); + PreferencesNotebook->AddPage( DefaultKeyfilesPage, _("Keyfiles"), false ); + SecurityTokensPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer127; + bSizer127 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer128; + bSizer128 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer36; + sbSizer36 = new wxStaticBoxSizer( new wxStaticBox( SecurityTokensPage, wxID_ANY, _("PKCS #11 Library Path") ), wxVERTICAL ); + + wxBoxSizer* bSizer129; + bSizer129 = new wxBoxSizer( wxHORIZONTAL ); + + Pkcs11ModulePathTextCtrl = new wxTextCtrl( SecurityTokensPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer129->Add( Pkcs11ModulePathTextCtrl, 1, wxALL, 5 ); + + SelectPkcs11ModuleButton = new wxButton( SecurityTokensPage, wxID_ANY, _("Select &Library..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer129->Add( SelectPkcs11ModuleButton, 0, wxALL, 5 ); + + sbSizer36->Add( bSizer129, 1, wxEXPAND, 5 ); + + bSizer128->Add( sbSizer36, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer37; + sbSizer37 = new wxStaticBoxSizer( new wxStaticBox( SecurityTokensPage, wxID_ANY, _("Security Options") ), wxVERTICAL ); + + CloseSecurityTokenSessionsAfterMountCheckBox = new wxCheckBox( SecurityTokensPage, wxID_ANY, _("&Close token session (log out) after a volume is successfully mounted"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer37->Add( CloseSecurityTokenSessionsAfterMountCheckBox, 0, wxALL, 5 ); + + bSizer128->Add( sbSizer37, 0, wxEXPAND|wxALL, 5 ); + + bSizer127->Add( bSizer128, 1, wxEXPAND|wxALL, 5 ); + + SecurityTokensPage->SetSizer( bSizer127 ); + SecurityTokensPage->Layout(); + bSizer127->Fit( SecurityTokensPage ); + PreferencesNotebook->AddPage( SecurityTokensPage, _("Security Tokens"), false ); + HotkeysPage = new wxPanel( PreferencesNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer51; + bSizer51 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer38; + bSizer38 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer21; + sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( HotkeysPage, wxID_ANY, _("System-Wide Hotkeys") ), wxVERTICAL ); + + HotkeyListCtrl = new wxListCtrl( HotkeysPage, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES|wxSUNKEN_BORDER ); + sbSizer21->Add( HotkeyListCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer23; + sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( HotkeysPage, wxID_ANY, _("Shortcut") ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer4; + fgSizer4 = new wxFlexGridSizer( 2, 3, 0, 0 ); + fgSizer4->SetFlexibleDirection( wxBOTH ); + fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* m_staticText10; + m_staticText10 = new wxStaticText( HotkeysPage, wxID_ANY, _("Key to assign:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText10->Wrap( -1 ); + fgSizer4->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + HotkeyTextCtrl = new wxTextCtrl( HotkeysPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer4->Add( HotkeyTextCtrl, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + AssignHotkeyButton = new wxButton( HotkeysPage, wxID_ANY, _("Assign"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer4->Add( AssignHotkeyButton, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxGridSizer* gSizer4; + gSizer4 = new wxGridSizer( 1, 4, 0, 0 ); + + HotkeyControlCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Control"), wxDefaultPosition, wxDefaultSize, 0 ); + + gSizer4->Add( HotkeyControlCheckBox, 0, wxALL, 5 ); + + HotkeyShiftCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Shift"), wxDefaultPosition, wxDefaultSize, 0 ); + + gSizer4->Add( HotkeyShiftCheckBox, 0, wxALL, 5 ); + + HotkeyAltCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Alt"), wxDefaultPosition, wxDefaultSize, 0 ); + + gSizer4->Add( HotkeyAltCheckBox, 0, wxALL, 5 ); + + HotkeyWinCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Win"), wxDefaultPosition, wxDefaultSize, 0 ); + + gSizer4->Add( HotkeyWinCheckBox, 0, wxALL, 5 ); + + fgSizer4->Add( gSizer4, 1, wxEXPAND, 5 ); + + RemoveHotkeyButton = new wxButton( HotkeysPage, wxID_ANY, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer4->Add( RemoveHotkeyButton, 1, wxALL, 5 ); + + sbSizer23->Add( fgSizer4, 1, wxALIGN_RIGHT, 5 ); + + sbSizer21->Add( sbSizer23, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer24; + sbSizer24 = new wxStaticBoxSizer( new wxStaticBox( HotkeysPage, wxID_ANY, _("Options") ), wxVERTICAL ); + + BeepAfterHotkeyMountDismountCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Play system notification sound after mount/dismount"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer24->Add( BeepAfterHotkeyMountDismountCheckBox, 0, wxALL, 5 ); + + DisplayMessageAfterHotkeyDismountCheckBox = new wxCheckBox( HotkeysPage, wxID_ANY, _("Display confirmation message box after dismount"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer24->Add( DisplayMessageAfterHotkeyDismountCheckBox, 0, wxALL, 5 ); + + sbSizer21->Add( sbSizer24, 0, wxEXPAND|wxALL, 5 ); + + bSizer38->Add( sbSizer21, 1, wxEXPAND|wxALL, 5 ); + + bSizer51->Add( bSizer38, 1, wxEXPAND|wxALL, 5 ); + + HotkeysPage->SetSizer( bSizer51 ); + HotkeysPage->Layout(); + bSizer51->Fit( HotkeysPage ); + PreferencesNotebook->AddPage( HotkeysPage, _("Hotkeys"), false ); + + bSizer41->Add( PreferencesNotebook, 1, wxEXPAND | wxALL, 5 ); + + StdButtons = new wxStdDialogButtonSizer(); + StdButtonsOK = new wxButton( this, wxID_OK ); + StdButtons->AddButton( StdButtonsOK ); + StdButtonsCancel = new wxButton( this, wxID_CANCEL ); + StdButtons->AddButton( StdButtonsCancel ); + StdButtons->Realize(); + bSizer41->Add( StdButtons, 0, wxEXPAND|wxALL, 5 ); + + bSizer32->Add( bSizer41, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer32 ); + this->Layout(); + bSizer32->Fit( this ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PreferencesDialogBase::OnClose ) ); + DismountOnScreenSaverCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnDismountOnScreenSaverCheckBoxClick ), NULL, this ); + DismountOnPowerSavingCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnDismountOnPowerSavingCheckBoxClick ), NULL, this ); + ForceAutoDismountCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnForceAutoDismountCheckBoxClick ), NULL, this ); + PreserveTimestampsCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnPreserveTimestampsCheckBoxClick ), NULL, this ); + BackgroundTaskEnabledCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnBackgroundTaskEnabledCheckBoxClick ), NULL, this ); + NoKernelCryptoCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnNoKernelCryptoCheckBoxClick ), NULL, this ); + NoHardwareCryptoCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnNoHardwareCryptoCheckBoxClick ), NULL, this ); + SelectPkcs11ModuleButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnSelectPkcs11ModuleButtonClick ), NULL, this ); + HotkeyListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( PreferencesDialogBase::OnHotkeyListItemDeselected ), NULL, this ); + HotkeyListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( PreferencesDialogBase::OnHotkeyListItemSelected ), NULL, this ); + AssignHotkeyButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnAssignHotkeyButtonClick ), NULL, this ); + RemoveHotkeyButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnRemoveHotkeyButtonClick ), NULL, this ); + StdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnCancelButtonClick ), NULL, this ); + StdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnOKButtonClick ), NULL, this ); +} + +PreferencesDialogBase::~PreferencesDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( PreferencesDialogBase::OnClose ) ); + DismountOnScreenSaverCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnDismountOnScreenSaverCheckBoxClick ), NULL, this ); + DismountOnPowerSavingCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnDismountOnPowerSavingCheckBoxClick ), NULL, this ); + ForceAutoDismountCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnForceAutoDismountCheckBoxClick ), NULL, this ); + PreserveTimestampsCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnPreserveTimestampsCheckBoxClick ), NULL, this ); + BackgroundTaskEnabledCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnBackgroundTaskEnabledCheckBoxClick ), NULL, this ); + NoKernelCryptoCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnNoKernelCryptoCheckBoxClick ), NULL, this ); + NoHardwareCryptoCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnNoHardwareCryptoCheckBoxClick ), NULL, this ); + SelectPkcs11ModuleButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnSelectPkcs11ModuleButtonClick ), NULL, this ); + HotkeyListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( PreferencesDialogBase::OnHotkeyListItemDeselected ), NULL, this ); + HotkeyListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( PreferencesDialogBase::OnHotkeyListItemSelected ), NULL, this ); + AssignHotkeyButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnAssignHotkeyButtonClick ), NULL, this ); + RemoveHotkeyButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnRemoveHotkeyButtonClick ), NULL, this ); + StdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnCancelButtonClick ), NULL, this ); + StdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PreferencesDialogBase::OnOKButtonClick ), NULL, this ); +} + +RandomPoolEnrichmentDialogBase::RandomPoolEnrichmentDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + MainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer144; + bSizer144 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer145; + bSizer145 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer145->Add( 0, 0, 1, wxEXPAND, 5 ); + + wxStaticText* m_staticText49; + m_staticText49 = new wxStaticText( this, wxID_ANY, _("Mixing PRF:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText49->Wrap( -1 ); + bSizer145->Add( m_staticText49, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + wxArrayString HashChoiceChoices; + HashChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, HashChoiceChoices, 0 ); + HashChoice->SetSelection( 0 ); + bSizer145->Add( HashChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer145->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer144->Add( bSizer145, 0, wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer43; + sbSizer43 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + wxBoxSizer* bSizer147; + bSizer147 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* m_staticText52; + m_staticText52 = new wxStaticText( this, wxID_ANY, _("Random Pool:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText52->Wrap( -1 ); + bSizer147->Add( m_staticText52, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + RandomPoolStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + RandomPoolStaticText->Wrap( -1 ); + RandomPoolStaticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier New") ) ); + + bSizer147->Add( RandomPoolStaticText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + ShowRandomPoolCheckBox = new wxCheckBox( this, wxID_ANY, _("Show"), wxDefaultPosition, wxDefaultSize, 0 ); + ShowRandomPoolCheckBox->SetValue(true); + + bSizer147->Add( ShowRandomPoolCheckBox, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + sbSizer43->Add( bSizer147, 0, wxEXPAND|wxTOP, 5 ); + + + sbSizer43->Add( 0, 0, 1, wxEXPAND, 5 ); + + MouseStaticText = new wxStaticText( this, wxID_ANY, _("IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases security. When done, click 'Continue'."), wxDefaultPosition, wxDefaultSize, 0 ); + MouseStaticText->Wrap( -1 ); + sbSizer43->Add( MouseStaticText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + sbSizer43->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer144->Add( sbSizer43, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer146; + bSizer146 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer146->Add( 0, 0, 1, wxEXPAND, 5 ); + + ContinueButton = new wxButton( this, wxID_OK, _("&Continue"), wxDefaultPosition, wxDefaultSize, 0 ); + ContinueButton->SetDefault(); + bSizer146->Add( ContinueButton, 0, wxALL, 5 ); + + + bSizer146->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer144->Add( bSizer146, 0, wxEXPAND, 5 ); + + MainSizer->Add( bSizer144, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( MainSizer ); + this->Layout(); + MainSizer->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_MOTION, wxMouseEventHandler( RandomPoolEnrichmentDialogBase::OnMouseMotion ) ); + HashChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( RandomPoolEnrichmentDialogBase::OnHashSelected ), NULL, this ); + ShowRandomPoolCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( RandomPoolEnrichmentDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); +} + +RandomPoolEnrichmentDialogBase::~RandomPoolEnrichmentDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( RandomPoolEnrichmentDialogBase::OnMouseMotion ) ); + HashChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( RandomPoolEnrichmentDialogBase::OnHashSelected ), NULL, this ); + ShowRandomPoolCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( RandomPoolEnrichmentDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); +} + +SecurityTokenKeyfilesDialogBase::SecurityTokenKeyfilesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer138; + bSizer138 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer142; + bSizer142 = new wxBoxSizer( wxVERTICAL ); + + SecurityTokenKeyfileListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES|wxSUNKEN_BORDER ); + bSizer142->Add( SecurityTokenKeyfileListCtrl, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer141; + bSizer141 = new wxBoxSizer( wxHORIZONTAL ); + + ExportButton = new wxButton( this, wxID_ANY, _("&Export..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer141->Add( ExportButton, 0, wxALL, 5 ); + + DeleteButton = new wxButton( this, wxID_ANY, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer141->Add( DeleteButton, 0, wxALL, 5 ); + + + bSizer141->Add( 0, 0, 1, wxEXPAND|wxLEFT, 5 ); + + ImportButton = new wxButton( this, wxID_ANY, _("&Import Keyfile to Token..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer141->Add( ImportButton, 0, wxALL, 5 ); + + bSizer142->Add( bSizer141, 0, wxEXPAND, 5 ); + + bSizer138->Add( bSizer142, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer139; + bSizer139 = new wxBoxSizer( wxVERTICAL ); + + OKButton = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + OKButton->SetDefault(); + bSizer139->Add( OKButton, 0, wxALL, 5 ); + + CancelButton = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer139->Add( CancelButton, 0, wxALL, 5 ); + + bSizer138->Add( bSizer139, 0, wxEXPAND, 5 ); + + bSizer3->Add( bSizer138, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer3 ); + this->Layout(); + bSizer3->Fit( this ); + + // Connect Events + SecurityTokenKeyfileListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemActivated ), NULL, this ); + SecurityTokenKeyfileListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemDeselected ), NULL, this ); + SecurityTokenKeyfileListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemSelected ), NULL, this ); + ExportButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnExportButtonClick ), NULL, this ); + DeleteButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnDeleteButtonClick ), NULL, this ); + ImportButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnImportButtonClick ), NULL, this ); + OKButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnOKButtonClick ), NULL, this ); +} + +SecurityTokenKeyfilesDialogBase::~SecurityTokenKeyfilesDialogBase() +{ + // Disconnect Events + SecurityTokenKeyfileListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemActivated ), NULL, this ); + SecurityTokenKeyfileListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemDeselected ), NULL, this ); + SecurityTokenKeyfileListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( SecurityTokenKeyfilesDialogBase::OnListItemSelected ), NULL, this ); + ExportButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnExportButtonClick ), NULL, this ); + DeleteButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnDeleteButtonClick ), NULL, this ); + ImportButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnImportButtonClick ), NULL, this ); + OKButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SecurityTokenKeyfilesDialogBase::OnOKButtonClick ), NULL, this ); +} + +VolumePropertiesDialogBase::VolumePropertiesDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer49; + bSizer49 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer50; + bSizer50 = new wxBoxSizer( wxVERTICAL ); + + PropertiesListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES|wxSUNKEN_BORDER ); + bSizer50->Add( PropertiesListCtrl, 1, wxALL|wxEXPAND, 5 ); + + StdButtons = new wxStdDialogButtonSizer(); + StdButtonsOK = new wxButton( this, wxID_OK ); + StdButtons->AddButton( StdButtonsOK ); + StdButtons->Realize(); + bSizer50->Add( StdButtons, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizer49->Add( bSizer50, 1, wxEXPAND|wxALL, 5 ); + + this->SetSizer( bSizer49 ); + this->Layout(); + bSizer49->Fit( this ); +} + +VolumePropertiesDialogBase::~VolumePropertiesDialogBase() +{ +} + +EncryptionOptionsWizardPageBase::EncryptionOptionsWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer93; + bSizer93 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer94; + bSizer94 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer95; + bSizer95 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer29; + sbSizer29 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Encryption Algorithm") ), wxVERTICAL ); + + wxBoxSizer* bSizer96; + bSizer96 = new wxBoxSizer( wxHORIZONTAL ); + + wxArrayString EncryptionAlgorithmChoiceChoices; + EncryptionAlgorithmChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, EncryptionAlgorithmChoiceChoices, 0 ); + EncryptionAlgorithmChoice->SetSelection( 0 ); + bSizer96->Add( EncryptionAlgorithmChoice, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + TestButton = new wxButton( this, wxID_ANY, _("&Test"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer96->Add( TestButton, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + sbSizer29->Add( bSizer96, 0, wxEXPAND, 5 ); + + EncryptionAlgorithmStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + EncryptionAlgorithmStaticText->Wrap( -1 ); + sbSizer29->Add( EncryptionAlgorithmStaticText, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer97; + bSizer97 = new wxBoxSizer( wxHORIZONTAL ); + + EncryptionAlgorithmHyperlink = new wxHyperlinkCtrl( this, wxID_ANY, _("More information"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + + EncryptionAlgorithmHyperlink->SetHoverColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + EncryptionAlgorithmHyperlink->SetNormalColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + EncryptionAlgorithmHyperlink->SetVisitedColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + bSizer97->Add( EncryptionAlgorithmHyperlink, 0, wxALL, 5 ); + + + bSizer97->Add( 0, 0, 1, wxEXPAND, 5 ); + + BenchmarkButton = new wxButton( this, wxID_ANY, _("&Benchmark"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer97->Add( BenchmarkButton, 0, wxALL, 5 ); + + sbSizer29->Add( bSizer97, 0, wxEXPAND, 5 ); + + bSizer95->Add( sbSizer29, 1, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer30; + sbSizer30 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Hash Algorithm") ), wxHORIZONTAL ); + + wxArrayString HashChoiceChoices; + HashChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, HashChoiceChoices, 0 ); + HashChoice->SetSelection( 0 ); + sbSizer30->Add( HashChoice, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + HashHyperlink = new wxHyperlinkCtrl( this, wxID_ANY, _("Information on hash algorithms"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + + HashHyperlink->SetHoverColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + HashHyperlink->SetNormalColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + HashHyperlink->SetVisitedColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ); + sbSizer30->Add( HashHyperlink, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer95->Add( sbSizer30, 0, wxEXPAND|wxALL, 5 ); + + bSizer94->Add( bSizer95, 1, wxEXPAND, 5 ); + + bSizer93->Add( bSizer94, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer93 ); + this->Layout(); + bSizer93->Fit( this ); + + // Connect Events + EncryptionAlgorithmChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnEncryptionAlgorithmSelected ), NULL, this ); + TestButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnTestButtonClick ), NULL, this ); + EncryptionAlgorithmHyperlink->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( EncryptionOptionsWizardPageBase::OnEncryptionAlgorithmHyperlinkClick ), NULL, this ); + BenchmarkButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnBenchmarkButtonClick ), NULL, this ); + HashHyperlink->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( EncryptionOptionsWizardPageBase::OnHashHyperlinkClick ), NULL, this ); +} + +EncryptionOptionsWizardPageBase::~EncryptionOptionsWizardPageBase() +{ + // Disconnect Events + EncryptionAlgorithmChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnEncryptionAlgorithmSelected ), NULL, this ); + TestButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnTestButtonClick ), NULL, this ); + EncryptionAlgorithmHyperlink->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( EncryptionOptionsWizardPageBase::OnEncryptionAlgorithmHyperlinkClick ), NULL, this ); + BenchmarkButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( EncryptionOptionsWizardPageBase::OnBenchmarkButtonClick ), NULL, this ); + HashHyperlink->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( EncryptionOptionsWizardPageBase::OnHashHyperlinkClick ), NULL, this ); +} + +InfoWizardPageBase::InfoWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxVERTICAL ); + + InfoPageSizer = new wxBoxSizer( wxVERTICAL ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + InfoPageSizer->Add( InfoStaticText, 1, wxALL|wxEXPAND, 5 ); + + bSizer71->Add( InfoPageSizer, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer71 ); + this->Layout(); + bSizer71->Fit( this ); +} + +InfoWizardPageBase::~InfoWizardPageBase() +{ +} + +KeyfilesPanelBase::KeyfilesPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + KeyfilesListCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxSUNKEN_BORDER ); + bSizer21->Add( KeyfilesListCtrl, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer137; + bSizer137 = new wxBoxSizer( wxHORIZONTAL ); + + AddFilesButton = new wxButton( this, wxID_ANY, _("Add &Files..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer137->Add( AddFilesButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + AddDirectoryButton = new wxButton( this, wxID_ANY, _("Add &Path..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer137->Add( AddDirectoryButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + AddSecurityTokenSignatureButton = new wxButton( this, wxID_ANY, _("Add &Token Files..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer137->Add( AddSecurityTokenSignatureButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + RemoveButton = new wxButton( this, wxID_ANY, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer137->Add( RemoveButton, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + RemoveAllButton = new wxButton( this, wxID_ANY, _("Remove &All"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer137->Add( RemoveAllButton, 0, wxEXPAND|wxALL, 5 ); + + bSizer21->Add( bSizer137, 0, wxEXPAND, 5 ); + + bSizer20->Add( bSizer21, 1, wxEXPAND, 5 ); + + bSizer19->Add( bSizer20, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer19 ); + this->Layout(); + + // Connect Events + KeyfilesListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( KeyfilesPanelBase::OnListItemDeselected ), NULL, this ); + KeyfilesListCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( KeyfilesPanelBase::OnListItemSelected ), NULL, this ); + KeyfilesListCtrl->Connect( wxEVT_SIZE, wxSizeEventHandler( KeyfilesPanelBase::OnListSizeChanged ), NULL, this ); + AddFilesButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddFilesButtonClick ), NULL, this ); + AddDirectoryButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddDirectoryButtonClick ), NULL, this ); + AddSecurityTokenSignatureButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddSecurityTokenSignatureButtonClick ), NULL, this ); + RemoveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnRemoveButtonClick ), NULL, this ); + RemoveAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnRemoveAllButtonClick ), NULL, this ); +} + +KeyfilesPanelBase::~KeyfilesPanelBase() +{ + // Disconnect Events + KeyfilesListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler( KeyfilesPanelBase::OnListItemDeselected ), NULL, this ); + KeyfilesListCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( KeyfilesPanelBase::OnListItemSelected ), NULL, this ); + KeyfilesListCtrl->Disconnect( wxEVT_SIZE, wxSizeEventHandler( KeyfilesPanelBase::OnListSizeChanged ), NULL, this ); + AddFilesButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddFilesButtonClick ), NULL, this ); + AddDirectoryButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddDirectoryButtonClick ), NULL, this ); + AddSecurityTokenSignatureButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnAddSecurityTokenSignatureButtonClick ), NULL, this ); + RemoveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnRemoveButtonClick ), NULL, this ); + RemoveAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfilesPanelBase::OnRemoveAllButtonClick ), NULL, this ); +} + +ProgressWizardPageBase::ProgressWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer81; + bSizer81 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer82; + bSizer82 = new wxBoxSizer( wxVERTICAL ); + + ProgressSizer = new wxBoxSizer( wxHORIZONTAL ); + + ProgressGauge = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,-1 ), wxGA_HORIZONTAL|wxGA_SMOOTH ); + ProgressGauge->SetValue( 0 ); + ProgressSizer->Add( ProgressGauge, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + AbortButton = new wxButton( this, wxID_ANY, _("&Abort"), wxDefaultPosition, wxDefaultSize, 0 ); + AbortButton->Enable( false ); + + ProgressSizer->Add( AbortButton, 0, wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer82->Add( ProgressSizer, 0, wxEXPAND, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer82->Add( InfoStaticText, 0, wxALL|wxEXPAND, 5 ); + + bSizer81->Add( bSizer82, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer81 ); + this->Layout(); + bSizer81->Fit( this ); + + // Connect Events + AbortButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ProgressWizardPageBase::OnAbortButtonClick ), NULL, this ); +} + +ProgressWizardPageBase::~ProgressWizardPageBase() +{ + // Disconnect Events + AbortButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ProgressWizardPageBase::OnAbortButtonClick ), NULL, this ); +} + +SelectDirectoryWizardPageBase::SelectDirectoryWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer69; + bSizer69 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer70; + bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + + DirectoryTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer70->Add( DirectoryTextCtrl, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + BrowseButton = new wxButton( this, wxID_ANY, _("&Browse..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer70->Add( BrowseButton, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer70, 0, wxEXPAND, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( 300 ); + bSizer69->Add( InfoStaticText, 1, wxALL|wxEXPAND, 5 ); + + bSizer68->Add( bSizer69, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer68 ); + this->Layout(); + + // Connect Events + DirectoryTextCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SelectDirectoryWizardPageBase::OnDirectoryTextChanged ), NULL, this ); + BrowseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SelectDirectoryWizardPageBase::OnBrowseButtonClick ), NULL, this ); +} + +SelectDirectoryWizardPageBase::~SelectDirectoryWizardPageBase() +{ + // Disconnect Events + DirectoryTextCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SelectDirectoryWizardPageBase::OnDirectoryTextChanged ), NULL, this ); + BrowseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SelectDirectoryWizardPageBase::OnBrowseButtonClick ), NULL, this ); +} + +SingleChoiceWizardPageBase::SingleChoiceWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer77; + bSizer77 = new wxBoxSizer( wxVERTICAL ); + + + bSizer77->Add( 0, 0, 0, wxEXPAND|wxTOP, 5 ); + + OuterChoicesSizer = new wxBoxSizer( wxVERTICAL ); + + ChoicesSizer = new wxBoxSizer( wxVERTICAL ); + + OuterChoicesSizer->Add( ChoicesSizer, 0, wxEXPAND, 5 ); + + bSizer77->Add( OuterChoicesSizer, 0, wxEXPAND, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer77->Add( InfoStaticText, 1, wxALL|wxEXPAND, 5 ); + + bSizer71->Add( bSizer77, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer71 ); + this->Layout(); + bSizer71->Fit( this ); +} + +SingleChoiceWizardPageBase::~SingleChoiceWizardPageBase() +{ +} + +VolumeCreationProgressWizardPageBase::VolumeCreationProgressWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer104; + bSizer104 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer105; + bSizer105 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer31; + sbSizer31 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + KeySamplesUpperSizer = new wxBoxSizer( wxVERTICAL ); + + KeySamplesUpperInnerSizer = new wxBoxSizer( wxVERTICAL ); + + KeySamplesUpperSizer->Add( KeySamplesUpperInnerSizer, 1, wxEXPAND|wxTOP, 3 ); + + sbSizer31->Add( KeySamplesUpperSizer, 1, wxEXPAND, 30 ); + + wxFlexGridSizer* fgSizer5; + fgSizer5 = new wxFlexGridSizer( 3, 2, 0, 0 ); + fgSizer5->SetFlexibleDirection( wxBOTH ); + fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* m_staticText25; + m_staticText25 = new wxStaticText( this, wxID_ANY, _("Random Pool:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText25->Wrap( -1 ); + fgSizer5->Add( m_staticText25, 0, wxALL|wxALIGN_RIGHT|wxALIGN_BOTTOM, 5 ); + + wxBoxSizer* bSizer126; + bSizer126 = new wxBoxSizer( wxHORIZONTAL ); + + RandomPoolSampleStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + RandomPoolSampleStaticText->Wrap( -1 ); + RandomPoolSampleStaticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier New") ) ); + + bSizer126->Add( RandomPoolSampleStaticText, 0, wxEXPAND|wxTOP|wxRIGHT|wxALIGN_BOTTOM, 7 ); + + DisplayKeysCheckBox = new wxCheckBox( this, wxID_ANY, _("Show"), wxDefaultPosition, wxDefaultSize, 0 ); + DisplayKeysCheckBox->SetValue(true); + + bSizer126->Add( DisplayKeysCheckBox, 0, wxEXPAND|wxRIGHT, 5 ); + + fgSizer5->Add( bSizer126, 1, wxEXPAND|wxALIGN_BOTTOM, 5 ); + + wxStaticText* m_staticText28; + m_staticText28 = new wxStaticText( this, wxID_ANY, _("Header Key:"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_staticText28->Wrap( -1 ); + fgSizer5->Add( m_staticText28, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_BOTTOM, 5 ); + + HeaderKeySampleStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + HeaderKeySampleStaticText->Wrap( -1 ); + HeaderKeySampleStaticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier New") ) ); + + fgSizer5->Add( HeaderKeySampleStaticText, 0, wxALIGN_BOTTOM|wxEXPAND|wxTOP|wxRIGHT, 2 ); + + wxStaticText* m_staticText29; + m_staticText29 = new wxStaticText( this, wxID_ANY, _("Master Key:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText29->Wrap( -1 ); + fgSizer5->Add( m_staticText29, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_BOTTOM, 5 ); + + MasterKeySampleStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + MasterKeySampleStaticText->Wrap( -1 ); + MasterKeySampleStaticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Courier New") ) ); + + fgSizer5->Add( MasterKeySampleStaticText, 0, wxEXPAND|wxALIGN_BOTTOM|wxTOP|wxRIGHT, 2 ); + + sbSizer31->Add( fgSizer5, 0, wxEXPAND, 5 ); + + bSizer105->Add( sbSizer31, 0, wxALL|wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizer32; + sbSizer32 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + + wxBoxSizer* bSizer106; + bSizer106 = new wxBoxSizer( wxHORIZONTAL ); + + ProgressGauge = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL|wxGA_SMOOTH ); + bSizer106->Add( ProgressGauge, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + AbortButton = new wxButton( this, wxID_ANY, _("Abort"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer106->Add( AbortButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + sbSizer32->Add( bSizer106, 0, wxEXPAND, 5 ); + + wxGridSizer* gSizer6; + gSizer6 = new wxGridSizer( 1, 3, 0, 0 ); + + wxBoxSizer* bSizer108; + bSizer108 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( this, wxID_ANY, _("Done"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31->Wrap( -1 ); + bSizer108->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_panel12 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxSUNKEN_BORDER ); + wxBoxSizer* bSizer115; + bSizer115 = new wxBoxSizer( wxHORIZONTAL ); + + SizeDoneStaticText = new wxStaticText( m_panel12, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE ); + SizeDoneStaticText->Wrap( -1 ); + bSizer115->Add( SizeDoneStaticText, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 3 ); + + m_panel12->SetSizer( bSizer115 ); + m_panel12->Layout(); + bSizer115->Fit( m_panel12 ); + bSizer108->Add( m_panel12, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + gSizer6->Add( bSizer108, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer1081; + bSizer1081 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText311 = new wxStaticText( this, wxID_ANY, _("Speed"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText311->Wrap( -1 ); + bSizer1081->Add( m_staticText311, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_panel121 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER ); + wxBoxSizer* bSizer1151; + bSizer1151 = new wxBoxSizer( wxHORIZONTAL ); + + SpeedStaticText = new wxStaticText( m_panel121, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE ); + SpeedStaticText->Wrap( -1 ); + bSizer1151->Add( SpeedStaticText, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 ); + + m_panel121->SetSizer( bSizer1151 ); + m_panel121->Layout(); + bSizer1151->Fit( m_panel121 ); + bSizer1081->Add( m_panel121, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + gSizer6->Add( bSizer1081, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + wxBoxSizer* bSizer1082; + bSizer1082 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText312 = new wxStaticText( this, wxID_ANY, _("Left"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText312->Wrap( -1 ); + bSizer1082->Add( m_staticText312, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_panel122 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer1152; + bSizer1152 = new wxBoxSizer( wxHORIZONTAL ); + + TimeLeftStaticText = new wxStaticText( m_panel122, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT|wxST_NO_AUTORESIZE ); + TimeLeftStaticText->Wrap( -1 ); + bSizer1152->Add( TimeLeftStaticText, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 ); + + m_panel122->SetSizer( bSizer1152 ); + m_panel122->Layout(); + bSizer1152->Fit( m_panel122 ); + bSizer1082->Add( m_panel122, 1, wxALL|wxEXPAND, 5 ); + + gSizer6->Add( bSizer1082, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 ); + + sbSizer32->Add( gSizer6, 0, wxEXPAND|wxTOP, 2 ); + + bSizer105->Add( sbSizer32, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizer105->Add( 0, 0, 0, wxTOP|wxBOTTOM, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer105->Add( InfoStaticText, 0, wxALL, 5 ); + + bSizer104->Add( bSizer105, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer104 ); + this->Layout(); + bSizer104->Fit( this ); + + // Connect Events + DisplayKeysCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeCreationProgressWizardPageBase::OnDisplayKeysCheckBoxClick ), NULL, this ); + AbortButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeCreationProgressWizardPageBase::OnAbortButtonClick ), NULL, this ); +} + +VolumeCreationProgressWizardPageBase::~VolumeCreationProgressWizardPageBase() +{ + // Disconnect Events + DisplayKeysCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeCreationProgressWizardPageBase::OnDisplayKeysCheckBoxClick ), NULL, this ); + AbortButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeCreationProgressWizardPageBase::OnAbortButtonClick ), NULL, this ); +} + +VolumeLocationWizardPageBase::VolumeLocationWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer86; + bSizer86 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer87; + bSizer87 = new wxBoxSizer( wxVERTICAL ); + + + bSizer87->Add( 0, 0, 0, wxEXPAND|wxTOP, 5 ); + + wxBoxSizer* bSizer88; + bSizer88 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer89; + bSizer89 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer126; + bSizer126 = new wxBoxSizer( wxHORIZONTAL ); + + VolumePathComboBox = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN ); + bSizer126->Add( VolumePathComboBox, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizer90; + bSizer90 = new wxBoxSizer( wxVERTICAL ); + + SelectFileButton = new wxButton( this, wxID_ANY, _("Select &File..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer90->Add( SelectFileButton, 0, wxALL|wxEXPAND, 5 ); + + SelectDeviceButton = new wxButton( this, wxID_ANY, _("Select D&evice..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer90->Add( SelectDeviceButton, 0, wxALL|wxEXPAND, 5 ); + + bSizer126->Add( bSizer90, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer89->Add( bSizer126, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer91; + bSizer91 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer91->Add( 0, 0, 0, wxLEFT, 5 ); + + NoHistoryCheckBox = new wxCheckBox( this, wxID_ANY, _("&Never save history"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer91->Add( NoHistoryCheckBox, 0, wxALL|wxEXPAND, 5 ); + + bSizer89->Add( bSizer91, 0, wxEXPAND, 5 ); + + bSizer88->Add( bSizer89, 1, wxEXPAND, 5 ); + + bSizer87->Add( bSizer88, 0, wxEXPAND, 5 ); + + + bSizer87->Add( 0, 0, 0, wxEXPAND|wxBOTTOM, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer87->Add( InfoStaticText, 0, wxALL|wxEXPAND, 5 ); + + bSizer86->Add( bSizer87, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer86 ); + this->Layout(); + bSizer86->Fit( this ); + + // Connect Events + VolumePathComboBox->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnVolumePathTextChanged ), NULL, this ); + SelectFileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnSelectFileButtonClick ), NULL, this ); + SelectDeviceButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnSelectDeviceButtonClick ), NULL, this ); + NoHistoryCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnNoHistoryCheckBoxClick ), NULL, this ); +} + +VolumeLocationWizardPageBase::~VolumeLocationWizardPageBase() +{ + // Disconnect Events + VolumePathComboBox->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnVolumePathTextChanged ), NULL, this ); + SelectFileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnSelectFileButtonClick ), NULL, this ); + SelectDeviceButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnSelectDeviceButtonClick ), NULL, this ); + NoHistoryCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeLocationWizardPageBase::OnNoHistoryCheckBoxClick ), NULL, this ); +} + +VolumeFormatOptionsWizardPageBase::VolumeFormatOptionsWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer124; + bSizer124 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer125; + bSizer125 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer33; + sbSizer33 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Filesystem Options") ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer6; + fgSizer6 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer6->SetFlexibleDirection( wxBOTH ); + fgSizer6->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText43 = new wxStaticText( this, wxID_ANY, _("Filesystem type:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText43->Wrap( -1 ); + fgSizer6->Add( m_staticText43, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxArrayString FilesystemTypeChoiceChoices; + FilesystemTypeChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, FilesystemTypeChoiceChoices, 0 ); + FilesystemTypeChoice->SetSelection( 0 ); + fgSizer6->Add( FilesystemTypeChoice, 0, wxALL, 5 ); + + sbSizer33->Add( fgSizer6, 1, wxEXPAND, 5 ); + + bSizer125->Add( sbSizer33, 0, wxEXPAND|wxALL, 5 ); + + wxStaticBoxSizer* sbSizer34; + sbSizer34 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Volume Format Options") ), wxVERTICAL ); + + QuickFormatCheckBox = new wxCheckBox( this, wxID_ANY, _("Quick format"), wxDefaultPosition, wxDefaultSize, 0 ); + + sbSizer34->Add( QuickFormatCheckBox, 0, wxALL, 5 ); + + bSizer125->Add( sbSizer34, 0, wxEXPAND|wxALL, 5 ); + + + bSizer125->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer125->Add( InfoStaticText, 0, wxALL, 5 ); + + bSizer124->Add( bSizer125, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer124 ); + this->Layout(); + bSizer124->Fit( this ); + + // Connect Events + FilesystemTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( VolumeFormatOptionsWizardPageBase::OnFilesystemTypeSelected ), NULL, this ); + QuickFormatCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeFormatOptionsWizardPageBase::OnQuickFormatCheckBoxClick ), NULL, this ); +} + +VolumeFormatOptionsWizardPageBase::~VolumeFormatOptionsWizardPageBase() +{ + // Disconnect Events + FilesystemTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( VolumeFormatOptionsWizardPageBase::OnFilesystemTypeSelected ), NULL, this ); + QuickFormatCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumeFormatOptionsWizardPageBase::OnQuickFormatCheckBoxClick ), NULL, this ); +} + +VolumePasswordPanelBase::VolumePasswordPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer7; + bSizer7 = new wxBoxSizer( wxVERTICAL ); + + GridBagSizer = new wxGridBagSizer( 0, 0 ); + GridBagSizer->AddGrowableCol( 1 ); + GridBagSizer->SetFlexibleDirection( wxBOTH ); + GridBagSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + GridBagSizer->SetEmptyCellSize( wxSize( 0,0 ) ); + + PasswordStaticText = new wxStaticText( this, wxID_ANY, _("Password:"), wxDefaultPosition, wxDefaultSize, 0 ); + PasswordStaticText->Wrap( -1 ); + GridBagSizer->Add( PasswordStaticText, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxRIGHT, 5 ); + + PasswordTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD ); + PasswordTextCtrl->SetMaxLength( 1 ); + PasswordTextCtrl->SetMinSize( wxSize( 232,-1 ) ); + + GridBagSizer->Add( PasswordTextCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxBOTTOM|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + ConfirmPasswordStaticText = new wxStaticText( this, wxID_ANY, _("Confirm password:"), wxDefaultPosition, wxDefaultSize, 0 ); + ConfirmPasswordStaticText->Wrap( -1 ); + GridBagSizer->Add( ConfirmPasswordStaticText, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 ); + + ConfirmPasswordTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD ); + ConfirmPasswordTextCtrl->SetMaxLength( 1 ); + ConfirmPasswordTextCtrl->SetMinSize( wxSize( 232,-1 ) ); + + GridBagSizer->Add( ConfirmPasswordTextCtrl, wxGBPosition( 2, 1 ), wxGBSpan( 1, 2 ), wxBOTTOM|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + CacheCheckBox = new wxCheckBox( this, wxID_ANY, _("Cach&e passwords and keyfiles in memory "), wxDefaultPosition, wxDefaultSize, 0 ); + + GridBagSizer->Add( CacheCheckBox, wxGBPosition( 3, 1 ), wxGBSpan( 1, 2 ), wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + DisplayPasswordCheckBox = new wxCheckBox( this, wxID_ANY, _("&Display password"), wxDefaultPosition, wxDefaultSize, 0 ); + + GridBagSizer->Add( DisplayPasswordCheckBox, wxGBPosition( 4, 1 ), wxGBSpan( 1, 2 ), wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + UseKeyfilesCheckBox = new wxCheckBox( this, wxID_ANY, _("U&se keyfiles"), wxDefaultPosition, wxDefaultSize, 0 ); + + GridBagSizer->Add( UseKeyfilesCheckBox, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), wxTOP|wxRIGHT|wxLEFT, 5 ); + + KeyfilesButton = new wxButton( this, wxID_ANY, _("&Keyfiles..."), wxDefaultPosition, wxDefaultSize, 0 ); + GridBagSizer->Add( KeyfilesButton, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_RIGHT|wxALIGN_BOTTOM|wxLEFT, 5 ); + + Pkcs5PrfSizer = new wxBoxSizer( wxVERTICAL ); + + GridBagSizer->Add( Pkcs5PrfSizer, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + Pkcs5PrfStaticText = new wxStaticText( this, wxID_ANY, _("PKCS-5 PRF:"), wxDefaultPosition, wxDefaultSize, 0 ); + Pkcs5PrfStaticText->Wrap( -1 ); + GridBagSizer->Add( Pkcs5PrfStaticText, wxGBPosition( 7, 0 ), wxGBSpan( 1, 1 ), wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + wxString Pkcs5PrfChoiceChoices[] = { _("Unchanged") }; + int Pkcs5PrfChoiceNChoices = sizeof( Pkcs5PrfChoiceChoices ) / sizeof( wxString ); + Pkcs5PrfChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, Pkcs5PrfChoiceNChoices, Pkcs5PrfChoiceChoices, 0 ); + Pkcs5PrfChoice->SetSelection( 0 ); + GridBagSizer->Add( Pkcs5PrfChoice, wxGBPosition( 7, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + PasswordPlaceholderSizer = new wxBoxSizer( wxVERTICAL ); + + GridBagSizer->Add( PasswordPlaceholderSizer, wxGBPosition( 8, 1 ), wxGBSpan( 1, 2 ), wxTOP|wxEXPAND, 5 ); + + bSizer7->Add( GridBagSizer, 1, wxALL|wxEXPAND, 5 ); + + this->SetSizer( bSizer7 ); + this->Layout(); + bSizer7->Fit( this ); + + // Connect Events + PasswordTextCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumePasswordPanelBase::OnTextChanged ), NULL, this ); + ConfirmPasswordTextCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumePasswordPanelBase::OnTextChanged ), NULL, this ); + DisplayPasswordCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnDisplayPasswordCheckBoxClick ), NULL, this ); + UseKeyfilesCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnUseKeyfilesCheckBoxClick ), NULL, this ); + KeyfilesButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonClick ), NULL, this ); + KeyfilesButton->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonRightDown ), NULL, this ); + KeyfilesButton->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonRightClick ), NULL, this ); +} + +VolumePasswordPanelBase::~VolumePasswordPanelBase() +{ + // Disconnect Events + PasswordTextCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumePasswordPanelBase::OnTextChanged ), NULL, this ); + ConfirmPasswordTextCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumePasswordPanelBase::OnTextChanged ), NULL, this ); + DisplayPasswordCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnDisplayPasswordCheckBoxClick ), NULL, this ); + UseKeyfilesCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnUseKeyfilesCheckBoxClick ), NULL, this ); + KeyfilesButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonClick ), NULL, this ); + KeyfilesButton->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonRightDown ), NULL, this ); + KeyfilesButton->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( VolumePasswordPanelBase::OnKeyfilesButtonRightClick ), NULL, this ); +} + +VolumePasswordWizardPageBase::VolumePasswordWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer101; + bSizer101 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer102; + bSizer102 = new wxBoxSizer( wxVERTICAL ); + + PasswordPanelSizer = new wxBoxSizer( wxVERTICAL ); + + bSizer102->Add( PasswordPanelSizer, 0, wxEXPAND, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer102->Add( InfoStaticText, 0, wxALL|wxEXPAND, 5 ); + + bSizer101->Add( bSizer102, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer101 ); + this->Layout(); + bSizer101->Fit( this ); +} + +VolumePasswordWizardPageBase::~VolumePasswordWizardPageBase() +{ +} + +VolumeSizeWizardPageBase::VolumeSizeWizardPageBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : WizardPage( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer98; + bSizer98 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer99; + bSizer99 = new wxBoxSizer( wxVERTICAL ); + + + bSizer99->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + wxBoxSizer* bSizer100; + bSizer100 = new wxBoxSizer( wxHORIZONTAL ); + + VolumeSizeTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer100->Add( VolumeSizeTextCtrl, 0, wxALL, 5 ); + + wxArrayString VolumeSizePrefixChoiceChoices; + VolumeSizePrefixChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, VolumeSizePrefixChoiceChoices, 0 ); + VolumeSizePrefixChoice->SetSelection( 0 ); + bSizer100->Add( VolumeSizePrefixChoice, 0, wxALL, 5 ); + + bSizer99->Add( bSizer100, 0, wxEXPAND, 5 ); + + + bSizer99->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + FreeSpaceStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + FreeSpaceStaticText->Wrap( -1 ); + bSizer99->Add( FreeSpaceStaticText, 0, wxALL|wxEXPAND, 5 ); + + + bSizer99->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + + InfoStaticText = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + InfoStaticText->Wrap( -1 ); + bSizer99->Add( InfoStaticText, 0, wxALL|wxEXPAND, 5 ); + + bSizer98->Add( bSizer99, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer98 ); + this->Layout(); + bSizer98->Fit( this ); + + // Connect Events + VolumeSizeTextCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumeSizeWizardPageBase::OnVolumeSizeTextChanged ), NULL, this ); + VolumeSizePrefixChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( VolumeSizeWizardPageBase::OnVolumeSizePrefixSelected ), NULL, this ); +} + +VolumeSizeWizardPageBase::~VolumeSizeWizardPageBase() +{ + // Disconnect Events + VolumeSizeTextCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( VolumeSizeWizardPageBase::OnVolumeSizeTextChanged ), NULL, this ); + VolumeSizePrefixChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( VolumeSizeWizardPageBase::OnVolumeSizePrefixSelected ), NULL, this ); +} diff --git a/src/Main/Forms/Forms.h b/src/Main/Forms/Forms.h new file mode 100644 index 00000000..cbc6f6e1 --- /dev/null +++ b/src/Main/Forms/Forms.h @@ -0,0 +1,1023 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __Forms__ +#define __Forms__ + +#include + +class WizardPage; + +#include "WizardPage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +namespace TrueCrypt +{ + /////////////////////////////////////////////////////////////////////////////// + /// Class MainFrameBase + /////////////////////////////////////////////////////////////////////////////// + class MainFrameBase : public wxFrame + { + private: + + protected: + wxMenuBar* MainMenuBar; + wxMenu* VolumesMenu; + wxMenuItem* MountVolumeMenuItem; + wxMenuItem* DismountVolumeMenuItem; + wxMenuItem* DismountAllMenuItem; + wxMenuItem* VolumePropertiesMenuItem; + wxMenu* FavoritesMenu; + wxMenuItem* AddToFavoritesMenuItem; + wxMenuItem* AddAllMountedToFavoritesMenuItem; + wxMenu* ToolsMenu; + wxMenuItem* BackupVolumeHeadersMenuItem; + wxMenuItem* RestoreVolumeHeaderMenuItem; + wxMenuItem* WipeCachedPasswordsMenuItem; + wxMenu* SettingsMenu; + wxMenuItem* HotkeysMenuItem; + wxMenuItem* PreferencesMenuItem; + wxMenu* HelpMenu; + wxPanel* MainPanel; + wxListCtrl* SlotListCtrl; + wxStaticBoxSizer* LowStaticBoxSizer; + wxBoxSizer* HigherButtonSizer; + wxButton* CreateVolumeButton; + wxButton* VolumePropertiesButton; + wxButton* WipeCacheButton; + + wxStaticBoxSizer* VolumeStaticBoxSizer; + wxGridBagSizer* VolumeGridBagSizer; + wxStaticBitmap* LogoBitmap; + wxComboBox* VolumePathComboBox; + wxButton* SelectFileButton; + wxCheckBox* NoHistoryCheckBox; + wxButton* VolumeToolsButton; + wxButton* SelectDeviceButton; + + wxButton* VolumeButton; + wxButton* MountAllDevicesButton; + wxButton* DismountAllButton; + wxButton* ExitButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnActivate( wxActivateEvent& event ){ event.Skip(); } + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnCreateVolumeButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMountVolumeMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMountAllDevicesButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDismountVolumeMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDismountAllButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangePasswordMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangePkcs5PrfMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangeKeyfilesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveKeyfilesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnVolumePropertiesButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAddToFavoritesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAddAllMountedToFavoritesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOrganizeFavoritesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMountAllFavoritesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnBenchmarkMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnEncryptionTestMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnBackupVolumeHeadersMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRestoreVolumeHeaderMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCreateKeyfileMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnManageSecurityTokenKeyfilesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCloseAllSecurityTokenSessionsMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnWipeCacheButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnHotkeysMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDefaultKeyfilesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSecurityTokenPreferencesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnPreferencesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUserGuideMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOnlineHelpMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnBeginnersTutorialMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnFaqMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnWebsiteMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDownloadsMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNewsMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnVersionHistoryMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnContactMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnLegalNoticesMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAboutMenuItemSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemRightClick( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnLogoBitmapClick( wxMouseEvent& event ){ event.Skip(); } + virtual void OnSelectFileButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNoHistoryCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnVolumeToolsButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSelectDeviceButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnVolumeButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnExitButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + MainFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("TrueCrypt"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,496 ), long style = wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxTAB_TRAVERSAL ); + ~MainFrameBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class WizardFrameBase + /////////////////////////////////////////////////////////////////////////////// + class WizardFrameBase : public wxFrame + { + private: + + protected: + wxPanel* MainPanel; + wxStaticBitmap* WizardBitmap; + wxStaticText* PageTitleStaticText; + wxBoxSizer* PageSizer; + + wxButton* HelpButton; + + wxButton* PreviousButton; + wxButton* NextButton; + + wxButton* CancelButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnActivate( wxActivateEvent& event ){ event.Skip(); } + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnMouseMotion( wxMouseEvent& event ){ event.Skip(); } + virtual void OnHelpButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnPreviousButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNextButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + WizardFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxTAB_TRAVERSAL ); + ~WizardFrameBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class AboutDialogBase + /////////////////////////////////////////////////////////////////////////////// + class AboutDialogBase : public wxDialog + { + private: + + protected: + wxPanel* m_panel14; + + wxStaticBitmap* LogoBitmap; + wxStaticText* VersionStaticText; + + wxStaticText* CopyrightStaticText; + + wxHyperlinkCtrl* WebsiteHyperlink; + wxStaticLine* m_staticline3; + wxTextCtrl* CreditsTextCtrl; + + wxStaticLine* m_staticline4; + wxStaticLine* m_staticline5; + + + + // Virtual event handlers, overide them in your derived class + virtual void OnWebsiteHyperlinkClick( wxHyperlinkEvent& event ){ event.Skip(); } + + + public: + AboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~AboutDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class BenchmarkDialogBase + /////////////////////////////////////////////////////////////////////////////// + class BenchmarkDialogBase : public wxDialog + { + private: + + protected: + wxChoice* BufferSizeChoice; + wxListCtrl* BenchmarkListCtrl; + wxBoxSizer* RightSizer; + wxButton* BenchmarkButton; + + wxStaticText* BenchmarkNoteStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnBenchmarkButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + BenchmarkDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("TrueCrypt - Encryption Algorithm Benchmark"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~BenchmarkDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class ChangePasswordDialogBase + /////////////////////////////////////////////////////////////////////////////// + class ChangePasswordDialogBase : public wxDialog + { + private: + + protected: + wxStaticBoxSizer* CurrentSizer; + wxBoxSizer* CurrentPasswordPanelSizer; + wxStaticBoxSizer* NewSizer; + wxBoxSizer* NewPasswordPanelSizer; + wxButton* OKButton; + wxButton* CancelButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnOKButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + ChangePasswordDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~ChangePasswordDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class DeviceSelectionDialogBase + /////////////////////////////////////////////////////////////////////////////// + class DeviceSelectionDialogBase : public wxDialog + { + private: + + protected: + wxListCtrl* DeviceListCtrl; + wxStdDialogButtonSizer* StdButtons; + wxButton* StdButtonsOK; + wxButton* StdButtonsCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + + + public: + DeviceSelectionDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select a Partition or Device"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~DeviceSelectionDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class EncryptionTestDialogBase + /////////////////////////////////////////////////////////////////////////////// + class EncryptionTestDialogBase : public wxDialog + { + private: + + protected: + wxChoice* EncryptionAlgorithmChoice; + wxCheckBox* XtsModeCheckBox; + wxTextCtrl* KeyTextCtrl; + wxStaticText* KeySizeStaticText; + wxTextCtrl* SecondaryKeyTextCtrl; + wxTextCtrl* DataUnitNumberTextCtrl; + wxTextCtrl* BlockNumberTextCtrl; + wxTextCtrl* PlainTextTextCtrl; + wxTextCtrl* CipherTextTextCtrl; + wxButton* EncryptButton; + wxButton* DecryptButton; + wxButton* AutoTestAllButton; + wxButton* ResetButton; + wxButton* CloseButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnEncryptionAlgorithmSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnXtsModeCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnEncryptButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDecryptButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAutoTestAllButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnResetButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + EncryptionTestDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("TrueCrypt - Test Vectors"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~EncryptionTestDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class FavoriteVolumesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class FavoriteVolumesDialogBase : public wxDialog + { + private: + + protected: + wxListCtrl* FavoritesListCtrl; + wxButton* MoveUpButton; + wxButton* MoveDownButton; + wxButton* RemoveButton; + wxButton* RemoveAllButton; + + wxButton* OKButton; + wxButton* CancelButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnMoveUpButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMoveDownButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveAllButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOKButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + FavoriteVolumesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Favorite Volumes"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~FavoriteVolumesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class KeyfilesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class KeyfilesDialogBase : public wxDialog + { + private: + + protected: + wxBoxSizer* UpperSizer; + wxBoxSizer* PanelSizer; + wxButton* OKButton; + wxButton* CancelButton; + wxStaticText* WarningStaticText; + wxBoxSizer* KeyfilesNoteSizer; + wxStaticText* KeyfilesNoteStaticText; + wxHyperlinkCtrl* KeyfilesHyperlink; + wxButton* CreateKeyfileButtton; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyfilesHyperlinkClick( wxHyperlinkEvent& event ){ event.Skip(); } + virtual void OnCreateKeyfileButttonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + KeyfilesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Keyfiles"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~KeyfilesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class KeyfileGeneratorDialogBase + /////////////////////////////////////////////////////////////////////////////// + class KeyfileGeneratorDialogBase : public wxDialog + { + private: + + protected: + wxBoxSizer* MainSizer; + + wxChoice* HashChoice; + + wxStaticText* RandomPoolStaticText; + wxCheckBox* ShowRandomPoolCheckBox; + + wxStaticText* MouseStaticText; + + wxButton* GenerateButton; + + + // Virtual event handlers, overide them in your derived class + virtual void OnMouseMotion( wxMouseEvent& event ){ event.Skip(); } + virtual void OnHashSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowRandomPoolCheckBoxClicked( wxCommandEvent& event ){ event.Skip(); } + virtual void OnGenerateButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + KeyfileGeneratorDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~KeyfileGeneratorDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class LegalNoticesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class LegalNoticesDialogBase : public wxDialog + { + private: + + protected: + wxTextCtrl* LegalNoticesTextCtrl; + + public: + LegalNoticesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("TrueCrypt - Legal Notices"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~LegalNoticesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class MountOptionsDialogBase + /////////////////////////////////////////////////////////////////////////////// + class MountOptionsDialogBase : public wxDialog + { + private: + + protected: + wxBoxSizer* PasswordSizer; + wxButton* OKButton; + wxButton* CancelButton; + + wxButton* OptionsButton; + wxPanel* OptionsPanel; + wxStaticBoxSizer* OptionsSizer; + + wxCheckBox* ReadOnlyCheckBox; + wxCheckBox* RemovableCheckBox; + wxCheckBox* PartitionInSystemEncryptionScopeCheckBox; + wxStaticBoxSizer* ProtectionSizer; + wxCheckBox* ProtectionCheckBox; + wxBoxSizer* ProtectionPasswordSizer; + wxHyperlinkCtrl* ProtectionHyperlinkCtrl; + wxBoxSizer* FilesystemSizer; + wxPanel* m_panel8; + wxCheckBox* NoFilesystemCheckBox; + wxGridBagSizer* FilesystemOptionsSizer; + wxBoxSizer* FilesystemSpacer; + wxStaticText* MountPointTextCtrlStaticText; + wxTextCtrl* MountPointTextCtrl; + wxButton* MountPointButton; + wxStaticText* FilesystemOptionsStaticText; + wxTextCtrl* FilesystemOptionsTextCtrl; + + // Virtual event handlers, overide them in your derived class + virtual void OnInitDialog( wxInitDialogEvent& event ){ event.Skip(); } + virtual void OnOKButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOptionsButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnReadOnlyCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnProtectionCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnProtectionHyperlinkClick( wxHyperlinkEvent& event ){ event.Skip(); } + virtual void OnNoFilesystemCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMountPointButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + MountOptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Enter TrueCrypt Volume Password"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~MountOptionsDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class NewSecurityTokenKeyfileDialogBase + /////////////////////////////////////////////////////////////////////////////// + class NewSecurityTokenKeyfileDialogBase : public wxDialog + { + private: + + protected: + wxChoice* SecurityTokenChoice; + wxTextCtrl* KeyfileNameTextCtrl; + wxStdDialogButtonSizer* StdButtons; + wxButton* StdButtonsOK; + wxButton* StdButtonsCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyfileNameChanged( wxCommandEvent& event ){ event.Skip(); } + + + public: + NewSecurityTokenKeyfileDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("New Security Token Keyfile Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~NewSecurityTokenKeyfileDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class PreferencesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class PreferencesDialogBase : public wxDialog + { + private: + + protected: + wxNotebook* PreferencesNotebook; + wxPanel* SecurityPage; + wxStaticBoxSizer* AutoDismountSizer; + wxCheckBox* DismountOnLogOffCheckBox; + wxCheckBox* DismountOnScreenSaverCheckBox; + wxCheckBox* DismountOnPowerSavingCheckBox; + wxCheckBox* DismountOnInactivityCheckBox; + wxSpinCtrl* DismountOnInactivitySpinCtrl; + wxCheckBox* ForceAutoDismountCheckBox; + wxStaticBoxSizer* FilesystemSecuritySizer; + wxCheckBox* PreserveTimestampsCheckBox; + wxCheckBox* WipeCacheOnCloseCheckBox; + wxCheckBox* WipeCacheOnAutoDismountCheckBox; + wxPanel* DefaultMountOptionsPage; + wxCheckBox* MountReadOnlyCheckBox; + wxCheckBox* MountRemovableCheckBox; + wxCheckBox* CachePasswordsCheckBox; + wxStaticBoxSizer* FilesystemSizer; + wxTextCtrl* FilesystemOptionsTextCtrl; + wxPanel* BackgroundTaskPanel; + wxCheckBox* BackgroundTaskEnabledCheckBox; + wxCheckBox* CloseBackgroundTaskOnNoVolumesCheckBox; + wxCheckBox* BackgroundTaskMenuMountItemsEnabledCheckBox; + wxCheckBox* BackgroundTaskMenuOpenItemsEnabledCheckBox; + wxCheckBox* BackgroundTaskMenuDismountItemsEnabledCheckBox; + wxPanel* SystemIntegrationPage; + wxStaticBoxSizer* LogOnSizer; + wxCheckBox* StartOnLogonCheckBox; + wxCheckBox* MountFavoritesOnLogonCheckBox; + wxCheckBox* MountDevicesOnLogonCheckBox; + wxStaticBoxSizer* ExplorerSizer; + wxCheckBox* OpenExplorerWindowAfterMountCheckBox; + wxCheckBox* CloseExplorerWindowsOnDismountCheckBox; + wxStaticBoxSizer* KernelServicesSizer; + wxCheckBox* NoKernelCryptoCheckBox; + wxPanel* PerformanceOptionsPage; + wxStaticText* AesHwCpuSupportedStaticText; + + wxCheckBox* NoHardwareCryptoCheckBox; + wxBoxSizer* DefaultKeyfilesSizer; + wxCheckBox* UseKeyfilesCheckBox; + wxTextCtrl* Pkcs11ModulePathTextCtrl; + wxButton* SelectPkcs11ModuleButton; + wxCheckBox* CloseSecurityTokenSessionsAfterMountCheckBox; + wxListCtrl* HotkeyListCtrl; + wxTextCtrl* HotkeyTextCtrl; + wxButton* AssignHotkeyButton; + + wxCheckBox* HotkeyControlCheckBox; + wxCheckBox* HotkeyShiftCheckBox; + wxCheckBox* HotkeyAltCheckBox; + wxCheckBox* HotkeyWinCheckBox; + wxButton* RemoveHotkeyButton; + wxCheckBox* BeepAfterHotkeyMountDismountCheckBox; + wxCheckBox* DisplayMessageAfterHotkeyDismountCheckBox; + wxStdDialogButtonSizer* StdButtons; + wxButton* StdButtonsOK; + wxButton* StdButtonsCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnDismountOnScreenSaverCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDismountOnPowerSavingCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnForceAutoDismountCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnPreserveTimestampsCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnBackgroundTaskEnabledCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNoKernelCryptoCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNoHardwareCryptoCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSelectPkcs11ModuleButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnHotkeyListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnHotkeyListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnAssignHotkeyButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveHotkeyButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOKButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxPanel* DefaultKeyfilesPage; + wxPanel* SecurityTokensPage; + wxPanel* HotkeysPage; + PreferencesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Preferences"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~PreferencesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class RandomPoolEnrichmentDialogBase + /////////////////////////////////////////////////////////////////////////////// + class RandomPoolEnrichmentDialogBase : public wxDialog + { + private: + + protected: + wxBoxSizer* MainSizer; + + wxChoice* HashChoice; + + wxStaticText* RandomPoolStaticText; + wxCheckBox* ShowRandomPoolCheckBox; + + wxStaticText* MouseStaticText; + + + wxButton* ContinueButton; + + + // Virtual event handlers, overide them in your derived class + virtual void OnMouseMotion( wxMouseEvent& event ){ event.Skip(); } + virtual void OnHashSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowRandomPoolCheckBoxClicked( wxCommandEvent& event ){ event.Skip(); } + + + public: + RandomPoolEnrichmentDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("TrueCrypt - Random Pool Enrichment"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~RandomPoolEnrichmentDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class SecurityTokenKeyfilesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class SecurityTokenKeyfilesDialogBase : public wxDialog + { + private: + + protected: + wxListCtrl* SecurityTokenKeyfileListCtrl; + wxButton* ExportButton; + wxButton* DeleteButton; + + wxButton* ImportButton; + wxButton* OKButton; + wxButton* CancelButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnExportButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDeleteButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnImportButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOKButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + SecurityTokenKeyfilesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Security Token Keyfiles"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~SecurityTokenKeyfilesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumePropertiesDialogBase + /////////////////////////////////////////////////////////////////////////////// + class VolumePropertiesDialogBase : public wxDialog + { + private: + + protected: + wxListCtrl* PropertiesListCtrl; + wxStdDialogButtonSizer* StdButtons; + wxButton* StdButtonsOK; + + public: + VolumePropertiesDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Volume Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~VolumePropertiesDialogBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class EncryptionOptionsWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class EncryptionOptionsWizardPageBase : public WizardPage + { + private: + + protected: + wxChoice* EncryptionAlgorithmChoice; + wxButton* TestButton; + wxStaticText* EncryptionAlgorithmStaticText; + wxHyperlinkCtrl* EncryptionAlgorithmHyperlink; + + wxButton* BenchmarkButton; + wxChoice* HashChoice; + wxHyperlinkCtrl* HashHyperlink; + + // Virtual event handlers, overide them in your derived class + virtual void OnEncryptionAlgorithmSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnTestButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnEncryptionAlgorithmHyperlinkClick( wxHyperlinkEvent& event ){ event.Skip(); } + virtual void OnBenchmarkButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnHashHyperlinkClick( wxHyperlinkEvent& event ){ event.Skip(); } + + + public: + EncryptionOptionsWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~EncryptionOptionsWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class InfoWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class InfoWizardPageBase : public WizardPage + { + private: + + protected: + wxBoxSizer* InfoPageSizer; + wxStaticText* InfoStaticText; + + public: + InfoWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~InfoWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class KeyfilesPanelBase + /////////////////////////////////////////////////////////////////////////////// + class KeyfilesPanelBase : public wxPanel + { + private: + + protected: + wxListCtrl* KeyfilesListCtrl; + wxButton* AddFilesButton; + wxButton* AddDirectoryButton; + wxButton* AddSecurityTokenSignatureButton; + wxButton* RemoveButton; + wxButton* RemoveAllButton; + + // Virtual event handlers, overide them in your derived class + virtual void OnListItemDeselected( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnListSizeChanged( wxSizeEvent& event ){ event.Skip(); } + virtual void OnAddFilesButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAddDirectoryButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAddSecurityTokenSignatureButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveAllButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + KeyfilesPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxTAB_TRAVERSAL ); + ~KeyfilesPanelBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class ProgressWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class ProgressWizardPageBase : public WizardPage + { + private: + + protected: + wxBoxSizer* ProgressSizer; + wxGauge* ProgressGauge; + wxButton* AbortButton; + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnAbortButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + ProgressWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~ProgressWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class SelectDirectoryWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class SelectDirectoryWizardPageBase : public WizardPage + { + private: + + protected: + wxTextCtrl* DirectoryTextCtrl; + wxButton* BrowseButton; + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnDirectoryTextChanged( wxCommandEvent& event ){ event.Skip(); } + virtual void OnBrowseButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + SelectDirectoryWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 200,65 ), long style = wxTAB_TRAVERSAL ); + ~SelectDirectoryWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class SingleChoiceWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class SingleChoiceWizardPageBase : public WizardPage + { + private: + + protected: + + wxBoxSizer* OuterChoicesSizer; + wxBoxSizer* ChoicesSizer; + wxStaticText* InfoStaticText; + + public: + SingleChoiceWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~SingleChoiceWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumeCreationProgressWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class VolumeCreationProgressWizardPageBase : public WizardPage + { + private: + + protected: + wxBoxSizer* KeySamplesUpperSizer; + wxBoxSizer* KeySamplesUpperInnerSizer; + wxStaticText* RandomPoolSampleStaticText; + wxCheckBox* DisplayKeysCheckBox; + wxStaticText* HeaderKeySampleStaticText; + wxStaticText* MasterKeySampleStaticText; + wxGauge* ProgressGauge; + wxButton* AbortButton; + wxStaticText* m_staticText31; + wxPanel* m_panel12; + wxStaticText* SizeDoneStaticText; + wxStaticText* m_staticText311; + wxPanel* m_panel121; + wxStaticText* SpeedStaticText; + wxStaticText* m_staticText312; + wxPanel* m_panel122; + wxStaticText* TimeLeftStaticText; + + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnDisplayKeysCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnAbortButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + VolumeCreationProgressWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumeCreationProgressWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumeLocationWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class VolumeLocationWizardPageBase : public WizardPage + { + private: + + protected: + + wxComboBox* VolumePathComboBox; + wxButton* SelectFileButton; + wxButton* SelectDeviceButton; + + wxCheckBox* NoHistoryCheckBox; + + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnVolumePathTextChanged( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSelectFileButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSelectDeviceButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnNoHistoryCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + VolumeLocationWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumeLocationWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumeFormatOptionsWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class VolumeFormatOptionsWizardPageBase : public WizardPage + { + private: + + protected: + wxStaticText* m_staticText43; + wxChoice* FilesystemTypeChoice; + wxCheckBox* QuickFormatCheckBox; + + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnFilesystemTypeSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnQuickFormatCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + VolumeFormatOptionsWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumeFormatOptionsWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumePasswordPanelBase + /////////////////////////////////////////////////////////////////////////////// + class VolumePasswordPanelBase : public wxPanel + { + private: + + protected: + wxGridBagSizer* GridBagSizer; + wxStaticText* PasswordStaticText; + wxTextCtrl* PasswordTextCtrl; + wxStaticText* ConfirmPasswordStaticText; + wxTextCtrl* ConfirmPasswordTextCtrl; + wxCheckBox* CacheCheckBox; + wxCheckBox* DisplayPasswordCheckBox; + wxCheckBox* UseKeyfilesCheckBox; + wxButton* KeyfilesButton; + wxBoxSizer* Pkcs5PrfSizer; + wxStaticText* Pkcs5PrfStaticText; + wxChoice* Pkcs5PrfChoice; + wxBoxSizer* PasswordPlaceholderSizer; + + // Virtual event handlers, overide them in your derived class + virtual void OnTextChanged( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDisplayPasswordCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUseKeyfilesCheckBoxClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKeyfilesButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKeyfilesButtonRightDown( wxMouseEvent& event ){ event.Skip(); } + virtual void OnKeyfilesButtonRightClick( wxMouseEvent& event ){ event.Skip(); } + + + public: + VolumePasswordPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumePasswordPanelBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumePasswordWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class VolumePasswordWizardPageBase : public WizardPage + { + private: + + protected: + wxBoxSizer* PasswordPanelSizer; + wxStaticText* InfoStaticText; + + public: + VolumePasswordWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumePasswordWizardPageBase(); + + }; + + /////////////////////////////////////////////////////////////////////////////// + /// Class VolumeSizeWizardPageBase + /////////////////////////////////////////////////////////////////////////////// + class VolumeSizeWizardPageBase : public WizardPage + { + private: + + protected: + + wxTextCtrl* VolumeSizeTextCtrl; + wxChoice* VolumeSizePrefixChoice; + + wxStaticText* FreeSpaceStaticText; + + wxStaticText* InfoStaticText; + + // Virtual event handlers, overide them in your derived class + virtual void OnVolumeSizeTextChanged( wxCommandEvent& event ){ event.Skip(); } + virtual void OnVolumeSizePrefixSelected( wxCommandEvent& event ){ event.Skip(); } + + + public: + VolumeSizeWizardPageBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~VolumeSizeWizardPageBase(); + + }; + +} // namespace TrueCrypt + +#endif //__Forms__ diff --git a/src/Main/Forms/InfoWizardPage.cpp b/src/Main/Forms/InfoWizardPage.cpp new file mode 100644 index 00000000..286ba476 --- /dev/null +++ b/src/Main/Forms/InfoWizardPage.cpp @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "InfoWizardPage.h" + +namespace TrueCrypt +{ + InfoWizardPage::InfoWizardPage (wxPanel *parent, const wxString &actionButtonText, shared_ptr actionFunctor) + : InfoWizardPageBase (parent) + { + if (!actionButtonText.empty()) + { + wxButton *actionButton = new wxButton (this, wxID_ANY, actionButtonText); + ActionFunctor = actionFunctor; + actionButton->Connect (wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (InfoWizardPage::OnActionButtonClick), nullptr, this); + + InfoPageSizer->Add (actionButton, 0, wxALL, 5); + } + + InfoStaticText->SetFocus(); + } + + void InfoWizardPage::SetMaxStaticTextWidth (int width) + { + InfoStaticText->Wrap (width); + } +} diff --git a/src/Main/Forms/InfoWizardPage.h b/src/Main/Forms/InfoWizardPage.h new file mode 100644 index 00000000..a3938b03 --- /dev/null +++ b/src/Main/Forms/InfoWizardPage.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_InfoWizardPage +#define TC_HEADER_Main_Forms_InfoWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class InfoWizardPage : public InfoWizardPageBase + { + public: + InfoWizardPage (wxPanel *parent, const wxString &actionButtonText = wxEmptyString, shared_ptr actionFunctor = shared_ptr ()); + + bool IsValid () { return true; } + void SetMaxStaticTextWidth (int width); + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + + protected: + virtual void OnActionButtonClick (wxCommandEvent& event) { (*ActionFunctor)(); } + + shared_ptr ActionFunctor; + }; +} + +#endif // TC_HEADER_Main_Forms_InfoWizardPage diff --git a/src/Main/Forms/KeyfileGeneratorDialog.cpp b/src/Main/Forms/KeyfileGeneratorDialog.cpp new file mode 100644 index 00000000..c217d40a --- /dev/null +++ b/src/Main/Forms/KeyfileGeneratorDialog.cpp @@ -0,0 +1,118 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Volume/Hash.h" +#include "KeyfileGeneratorDialog.h" + +namespace TrueCrypt +{ + KeyfileGeneratorDialog::KeyfileGeneratorDialog (wxWindow* parent) : KeyfileGeneratorDialogBase (parent) + { + RandomNumberGenerator::Start(); + + Hashes = Hash::GetAvailableAlgorithms(); + foreach (shared_ptr hash, Hashes) + { + if (!hash->IsDeprecated()) + HashChoice->Append (hash->GetName(), hash.get()); + } + + HashChoice->Select (0); + RandomNumberGenerator::SetHash (Gui->GetSelectedData (HashChoice)->GetNew()); + + ShowBytes (RandomPoolStaticText, RandomNumberGenerator::PeekPool().GetRange (0, 24)); + MouseStaticText->Wrap (Gui->GetCharWidth (MouseStaticText) * 70); + + MainSizer->SetMinSize (wxSize (-1, Gui->GetCharHeight (this) * 24)); + + Layout(); + Fit(); + Center(); + + foreach (wxWindow *c, this->GetChildren()) + c->Connect (wxEVT_MOTION, wxMouseEventHandler (KeyfileGeneratorDialog::OnMouseMotion), nullptr, this); + } + + KeyfileGeneratorDialog::~KeyfileGeneratorDialog () + { + } + + void KeyfileGeneratorDialog::OnGenerateButtonClick (wxCommandEvent& event) + { + try + { + FilePathList files = Gui->SelectFiles (Gui->GetActiveWindow(), wxEmptyString, true); + + if (files.empty()) + return; + + SecureBuffer keyfileBuffer (VolumePassword::MaxSize); + RandomNumberGenerator::GetData (keyfileBuffer); + + { + File keyfile; + keyfile.Open (*files.front(), File::CreateWrite); + keyfile.Write (keyfileBuffer); + } + + Gui->ShowInfo ("KEYFILE_CREATED"); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void KeyfileGeneratorDialog::OnHashSelected (wxCommandEvent& event) + { + RandomNumberGenerator::SetHash (Gui->GetSelectedData (HashChoice)->GetNew()); + } + + void KeyfileGeneratorDialog::OnMouseMotion (wxMouseEvent& event) + { + event.Skip(); + + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&event), sizeof (event))); + + long coord = event.GetX(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + coord = event.GetY(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + + if (ShowRandomPoolCheckBox->IsChecked()) + ShowBytes (RandomPoolStaticText, RandomNumberGenerator::PeekPool().GetRange (0, 24)); + } + + void KeyfileGeneratorDialog::OnShowRandomPoolCheckBoxClicked (wxCommandEvent& event) + { + if (!event.IsChecked()) + RandomPoolStaticText->SetLabel (L""); + } + + void KeyfileGeneratorDialog::ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots) + { + wxString str; + + for (size_t i = 0; i < buffer.Size(); ++i) + { + str += wxString::Format (L"%02X", buffer[i]); + } + + if (appendDots) + str += L".."; + + textCtrl->SetLabel (str.c_str()); + + for (size_t i = 0; i < str.size(); ++i) + { + str[i] = L'X'; + } + } +} diff --git a/src/Main/Forms/KeyfileGeneratorDialog.h b/src/Main/Forms/KeyfileGeneratorDialog.h new file mode 100644 index 00000000..bc4748f2 --- /dev/null +++ b/src/Main/Forms/KeyfileGeneratorDialog.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_KeyfileGeneratorDialog +#define TC_HEADER_Main_Forms_KeyfileGeneratorDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class KeyfileGeneratorDialog : public KeyfileGeneratorDialogBase + { + public: + KeyfileGeneratorDialog (wxWindow* parent); + ~KeyfileGeneratorDialog (); + + protected: + void OnGenerateButtonClick (wxCommandEvent& event); + void OnHashSelected (wxCommandEvent& event); + void OnMouseMotion (wxMouseEvent& event); + void OnShowRandomPoolCheckBoxClicked (wxCommandEvent& event); + void ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots = true); + + HashList Hashes; + }; +} + +#endif // TC_HEADER_Main_Forms_KeyfileGeneratorDialog diff --git a/src/Main/Forms/KeyfilesDialog.cpp b/src/Main/Forms/KeyfilesDialog.cpp new file mode 100644 index 00000000..267f8554 --- /dev/null +++ b/src/Main/Forms/KeyfilesDialog.cpp @@ -0,0 +1,44 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "KeyfilesDialog.h" + +namespace TrueCrypt +{ + KeyfilesDialog::KeyfilesDialog (wxWindow* parent, shared_ptr keyfiles) + : KeyfilesDialogBase (parent), Keyfiles (keyfiles) + { + mKeyfilesPanel = new KeyfilesPanel (this, keyfiles); + PanelSizer->Add (mKeyfilesPanel, 1, wxALL | wxEXPAND); + + WarningStaticText->SetLabel (LangString["IDT_KEYFILE_WARNING"]); + WarningStaticText->Wrap (Gui->GetCharWidth (this) * 15); + + Layout(); + Fit(); + + KeyfilesNoteStaticText->SetLabel (LangString["KEYFILES_NOTE"]); + KeyfilesNoteStaticText->Wrap (UpperSizer->GetSize().GetWidth() - Gui->GetCharWidth (this) * 2); + + Layout(); + Fit(); + Center(); + } + + void KeyfilesDialog::OnCreateKeyfileButttonClick (wxCommandEvent& event) + { + Gui->CreateKeyfile(); + } + + void KeyfilesDialog::OnKeyfilesHyperlinkClick (wxHyperlinkEvent& event) + { + Gui->OpenHomepageLink (this, L"keyfiles"); + } +} diff --git a/src/Main/Forms/KeyfilesDialog.h b/src/Main/Forms/KeyfilesDialog.h new file mode 100644 index 00000000..722cc8ba --- /dev/null +++ b/src/Main/Forms/KeyfilesDialog.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_KeyfilesDialog +#define TC_HEADER_Main_Forms_KeyfilesDialog + +#include "Forms.h" +#include "Main/Main.h" +#include "KeyfilesPanel.h" + +namespace TrueCrypt +{ + class KeyfilesDialog : public KeyfilesDialogBase + { + public: + KeyfilesDialog (wxWindow* parent, shared_ptr keyfiles); + shared_ptr GetKeyfiles () const { return mKeyfilesPanel->GetKeyfiles(); } + + protected: + void OnCreateKeyfileButttonClick (wxCommandEvent& event); + void OnKeyfilesHyperlinkClick (wxHyperlinkEvent& event); + + shared_ptr Keyfiles; + KeyfilesPanel *mKeyfilesPanel; + }; +} + +#endif // TC_HEADER_Main_Forms_KeyfilesDialog diff --git a/src/Main/Forms/KeyfilesPanel.cpp b/src/Main/Forms/KeyfilesPanel.cpp new file mode 100644 index 00000000..506e008a --- /dev/null +++ b/src/Main/Forms/KeyfilesPanel.cpp @@ -0,0 +1,160 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "KeyfilesPanel.h" +#include "SecurityTokenKeyfilesDialog.h" + +namespace TrueCrypt +{ + KeyfilesPanel::KeyfilesPanel (wxWindow* parent, shared_ptr keyfiles) + : KeyfilesPanelBase (parent) + { + KeyfilesListCtrl->InsertColumn (0, LangString["KEYFILE"], wxLIST_FORMAT_LEFT, 1); + Gui->SetListCtrlHeight (KeyfilesListCtrl, 10); + + Layout(); + Fit(); + + if (keyfiles) + { + foreach_ref (const Keyfile &k, *keyfiles) + { + vector fields; + fields.push_back (FilesystemPath (k)); + Gui->AppendToListCtrl (KeyfilesListCtrl, fields); + } + } + + class FileDropTarget : public wxFileDropTarget + { + public: + FileDropTarget (KeyfilesPanel *panel) : Panel (panel) { } + + wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def) + { + return wxDragLink; + } + + bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames) + { + foreach (const wxString &f, filenames) + Panel->AddKeyfile (make_shared (wstring (f))); + return true; + } + + protected: + KeyfilesPanel *Panel; + }; + + SetDropTarget (new FileDropTarget (this)); + KeyfilesListCtrl->SetDropTarget (new FileDropTarget (this)); +#ifdef TC_MACOSX + foreach (wxWindow *c, GetChildren()) + c->SetDropTarget (new FileDropTarget (this)); +#endif + + UpdateButtons(); + } + + void KeyfilesPanel::AddKeyfile (shared_ptr keyfile) + { + vector fields; + fields.push_back (FilesystemPath (*keyfile)); + Gui->AppendToListCtrl (KeyfilesListCtrl, fields); + UpdateButtons(); + } + + shared_ptr KeyfilesPanel::GetKeyfiles () const + { + make_shared_auto (KeyfileList, keyfiles); + + for (long i = 0; i < KeyfilesListCtrl->GetItemCount(); i++) + keyfiles->push_back (make_shared (wstring (KeyfilesListCtrl->GetItemText (i)))); + + return keyfiles; + } + + void KeyfilesPanel::OnAddDirectoryButtonClick (wxCommandEvent& event) + { + DirectoryPath dir = Gui->SelectDirectory (this, LangString["SELECT_KEYFILE_PATH"]); + if (!dir.IsEmpty()) + { + vector fields; + fields.push_back (dir); + Gui->AppendToListCtrl (KeyfilesListCtrl, fields); + UpdateButtons(); + } + } + + void KeyfilesPanel::OnAddFilesButtonClick (wxCommandEvent& event) + { + FilePathList files = Gui->SelectFiles (this, LangString["SELECT_KEYFILES"], false, true); + + foreach_ref (const FilePath &f, files) + { + vector fields; + fields.push_back (f); + Gui->AppendToListCtrl (KeyfilesListCtrl, fields); + } + UpdateButtons(); + } + + void KeyfilesPanel::OnAddSecurityTokenSignatureButtonClick (wxCommandEvent& event) + { + try + { + SecurityTokenKeyfilesDialog dialog (this); + if (dialog.ShowModal() == wxID_OK) + { + foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) + { + vector fields; + fields.push_back (path); + Gui->AppendToListCtrl (KeyfilesListCtrl, fields); + } + + UpdateButtons(); + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void KeyfilesPanel::OnListSizeChanged (wxSizeEvent& event) + { + list colPermilles; + colPermilles.push_back (1000); + Gui->SetListCtrlColumnWidths (KeyfilesListCtrl, colPermilles); + event.Skip(); + } + + void KeyfilesPanel::OnRemoveAllButtonClick (wxCommandEvent& event) + { + KeyfilesListCtrl->DeleteAllItems(); + UpdateButtons(); + } + + void KeyfilesPanel::OnRemoveButtonClick (wxCommandEvent& event) + { + long offset = 0; + foreach (long item, Gui->GetListCtrlSelectedItems (KeyfilesListCtrl)) + KeyfilesListCtrl->DeleteItem (item - offset++); + + UpdateButtons(); + } + + void KeyfilesPanel::UpdateButtons () + { + RemoveAllButton->Enable (KeyfilesListCtrl->GetItemCount() > 0); + RemoveButton->Enable (KeyfilesListCtrl->GetSelectedItemCount() > 0); + } +} diff --git a/src/Main/Forms/KeyfilesPanel.h b/src/Main/Forms/KeyfilesPanel.h new file mode 100644 index 00000000..c7617453 --- /dev/null +++ b/src/Main/Forms/KeyfilesPanel.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_KeyfilesPanel +#define TC_HEADER_Main_Forms_KeyfilesPanel + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class KeyfilesPanel : public KeyfilesPanelBase + { + public: + KeyfilesPanel (wxWindow* parent, shared_ptr keyfiles); + void AddKeyfile (shared_ptr keyfile); + shared_ptr GetKeyfiles () const; + + protected: + void OnAddFilesButtonClick (wxCommandEvent& event); + void OnAddDirectoryButtonClick (wxCommandEvent& event); + void OnAddSecurityTokenSignatureButtonClick (wxCommandEvent& event); + void OnListItemDeselected (wxListEvent& event) { UpdateButtons(); } + void OnListItemSelected (wxListEvent& event) { UpdateButtons(); } + void OnListSizeChanged (wxSizeEvent& event); + void OnRemoveButtonClick (wxCommandEvent& event); + void OnRemoveAllButtonClick (wxCommandEvent& event); + void UpdateButtons (); + }; +} + +#endif // TC_HEADER_Main_Forms_KeyfilesPanel diff --git a/src/Main/Forms/LegalNoticesDialog.cpp b/src/Main/Forms/LegalNoticesDialog.cpp new file mode 100644 index 00000000..8029965d --- /dev/null +++ b/src/Main/Forms/LegalNoticesDialog.cpp @@ -0,0 +1,28 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "LegalNoticesDialog.h" +#include "Main/GraphicUserInterface.h" +#include "Main/Resources.h" + +namespace TrueCrypt +{ + LegalNoticesDialog::LegalNoticesDialog (wxWindow* parent) : LegalNoticesDialogBase (parent) + { + LegalNoticesTextCtrl->SetMinSize (wxSize ( + Gui->GetCharWidth (LegalNoticesTextCtrl) * 88, + Gui->GetCharHeight (LegalNoticesTextCtrl) * 28)); + + Layout(); + Fit(); + Center(); + + LegalNoticesTextCtrl->ChangeValue (StringConverter::ToWide (Resources::GetLegalNotices())); + } +} diff --git a/src/Main/Forms/LegalNoticesDialog.h b/src/Main/Forms/LegalNoticesDialog.h new file mode 100644 index 00000000..609ed83a --- /dev/null +++ b/src/Main/Forms/LegalNoticesDialog.h @@ -0,0 +1,23 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_LegalNoticesDialog +#define TC_HEADER_Main_Forms_LegalNoticesDialog + +#include "Forms.h" + +namespace TrueCrypt +{ + class LegalNoticesDialog : public LegalNoticesDialogBase + { + public: + LegalNoticesDialog (wxWindow* parent); + }; +} + +#endif // TC_HEADER_Main_Forms_LegalNoticesDialog diff --git a/src/Main/Forms/MainFrame.cpp b/src/Main/Forms/MainFrame.cpp new file mode 100644 index 00000000..cf313a8e --- /dev/null +++ b/src/Main/Forms/MainFrame.cpp @@ -0,0 +1,1585 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" + +#ifdef TC_UNIX +#include +#include +#include +#include +#endif + +#include "Common/SecurityToken.h" +#include "Main/Main.h" +#include "Main/Resources.h" +#include "Main/Application.h" +#include "Main/GraphicUserInterface.h" +#include "Main/VolumeHistory.h" +#include "Main/Xml.h" +#include "MainFrame.h" +#include "AboutDialog.h" +#include "BenchmarkDialog.h" +#include "ChangePasswordDialog.h" +#include "EncryptionTestDialog.h" +#include "FavoriteVolumesDialog.h" +#include "LegalNoticesDialog.h" +#include "PreferencesDialog.h" +#include "SecurityTokenKeyfilesDialog.h" +#include "VolumeCreationWizard.h" +#include "VolumePropertiesDialog.h" + +namespace TrueCrypt +{ + MainFrame::MainFrame (wxWindow* parent) : MainFrameBase (parent), + ListItemRightClickEventPending (false), + SelectedItemIndex (-1), + SelectedSlotNumber (0), + ShowRequestFifo (-1) + { + wxBusyCursor busy; + + SetName (Application::GetName()); + SetTitle (Application::GetName()); + SetIcon (Resources::GetTrueCryptIcon()); + +#if defined(TC_UNIX) && !defined(TC_MACOSX) + try + { + string fifoPath = GetShowRequestFifoPath(); + + remove (fifoPath.c_str()); + throw_sys_if (mkfifo (fifoPath.c_str(), S_IRUSR | S_IWUSR) == -1); + + ShowRequestFifo = open (fifoPath.c_str(), O_RDONLY | O_NONBLOCK); + throw_sys_if (ShowRequestFifo == -1); + } + catch (...) + { +#ifdef DEBUG + throw; +#endif + } +#endif + + InitControls(); + InitPreferences(); + InitTaskBarIcon(); + InitEvents(); + InitMessageFilter(); + + if (!GetPreferences().SecurityTokenModule.IsEmpty() && !SecurityToken::IsInitialized()) + { + try + { + Gui->InitSecurityTokenLibrary(); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + } + + MainFrame::~MainFrame () + { +#if defined(TC_UNIX) && !defined(TC_MACOSX) + if (ShowRequestFifo != -1) + { + try + { + close (ShowRequestFifo); + remove (string (GetShowRequestFifoPath()).c_str()); + } + catch (...) { } + } +#endif + + Core->VolumeMountedEvent.Disconnect (this); + Core->VolumeDismountedEvent.Disconnect (this); + Gui->OpenVolumeSystemRequestEvent.Disconnect (this); + Gui->PreferencesUpdatedEvent.Disconnect (this); + + VolumeHistory::DisconnectComboBox (VolumePathComboBox); + +#ifdef TC_WINDOWS + Hotkey::UnregisterList (this, GetPreferences().Hotkeys); +#endif + } + + void MainFrame::AddToFavorites (const VolumeInfoList &volumes) + { + try + { + FavoriteVolumeList newFavorites; + + // Delete duplicates + foreach (shared_ptr favorite, FavoriteVolume::LoadList()) + { + bool mounted = false; + foreach_ref (const VolumeInfo &volume, volumes) + { + if (volume.Path == favorite->Path) + { + mounted = true; + break; + } + } + if (!mounted) + newFavorites.push_back (favorite); + } + + size_t newItemCount = 0; + foreach_ref (const VolumeInfo &volume, volumes) + { + newFavorites.push_back (shared_ptr (new FavoriteVolume (volume.Path, volume.MountPoint, volume.SlotNumber, volume.Protection == VolumeProtection::ReadOnly, volume.SystemEncryption))); + ++newItemCount; + } + + OrganizeFavorites (newFavorites, newItemCount); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + bool MainFrame::CanExit () const + { + return Gui->IsTheOnlyTopLevelWindow (this); + } + + void MainFrame::ChangePassword (ChangePasswordDialog::Mode::Enum mode) + { + if (!CheckVolumePathNotEmpty ()) + return; + + shared_ptr volumePath = GetSelectedVolumePath(); + +#ifdef TC_WINDOWS + if (Core->IsVolumeMounted (*volumePath)) + { + Gui->ShowInfo (LangString [mode == ChangePasswordDialog::Mode::ChangePkcs5Prf ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE"]); + return; + } +#endif + + ChangePasswordDialog dialog (this, volumePath, mode); + dialog.ShowModal(); + } + + void MainFrame::CheckFilesystem (bool repair) + { + shared_ptr selectedVolume = GetSelectedVolume(); + if (selectedVolume) + { + try + { +#ifdef TC_WINDOWS + string mountPoint = selectedVolume->MountPoint; + + wstring args = StringFormatter (repair ? L"/C echo {0} & chkdsk {1} /F /X & pause" : L"/C echo {0} & chkdsk {1} & pause", + StringFormatter (LangString[repair ? "REPAIRING_FS" : "CHECKING_FS"], mountPoint), mountPoint); + + ShellExecute (static_cast (GetHandle()), + L"runas", + L"cmd.exe", args.c_str(), nullptr, SW_SHOW); +#else +# ifdef TC_MACOSX + Gui->ShowInfo (_("Disk Utility will be launched after you press 'OK'.\n\nPlease select your volume in the Disk Utility window and press 'Verify Disk' or 'Repair Disk' button on the 'First Aid' page.")); +# endif + Core->CheckFilesystem (selectedVolume, repair); + UpdateVolumeList(); +#endif + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + } + + bool MainFrame::CheckVolumePathNotEmpty () const + { + if (VolumePathComboBox->GetValue().empty()) + { + Gui->ShowInfo ("NO_VOLUME_SELECTED"); + return false; + } + return true; + } + + void MainFrame::DismountVolume (shared_ptr volume) + { + try + { + if (!volume) + volume = GetSelectedVolume(); + + if (volume) + Gui->DismountVolume (volume); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + shared_ptr MainFrame::GetSelectedVolume () const + { + return Core->GetMountedVolume (SelectedSlotNumber); + } + + void MainFrame::InitControls () + { + LogoBitmap->SetBitmap (Resources::GetLogoBitmap()); + + list colPermilles; + +#ifndef TC_WINDOWS + SettingsMenu->Remove (HotkeysMenuItem); +#endif + +#ifdef TC_MACOSX + SettingsMenu->Remove (PreferencesMenuItem); + SettingsMenu->AppendSeparator(); + SettingsMenu->Append (PreferencesMenuItem); + + LowStaticBoxSizer->Detach (HigherButtonSizer); + VolumeStaticBoxSizer->Detach (VolumeGridBagSizer); + VolumeStaticBoxSizer->Add (VolumeGridBagSizer, 1, wxEXPAND, 0); + + ExitButton->SetLabel (_("Close")); + MountAllDevicesButton->SetLabel (_("Mount All Devices")); +#endif + +#ifdef TC_WINDOWS + SlotListCtrl->InsertColumn (ColumnSlot, LangString["DRIVE"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (75); +#else + SlotListCtrl->InsertColumn (ColumnSlot, _("Slot"), wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (82); +#endif + + SlotListCtrl->InsertColumn (ColumnPath, LangString["VOLUME"], wxLIST_FORMAT_LEFT, 1); +#ifdef TC_WINDOWS + colPermilles.push_back (487); +#else + colPermilles.push_back (429); +#endif + + SlotListCtrl->InsertColumn (ColumnSize, LangString["SIZE"], wxLIST_FORMAT_RIGHT, 1); +#ifdef TC_WINDOWS + colPermilles.push_back (126); +#else + colPermilles.push_back (130); +#endif + +#ifdef TC_WINDOWS + SlotListCtrl->InsertColumn (ColumnEA, LangString["ENCRYPTION_ALGORITHM_LV"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (233); +#else + SlotListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (259); +#endif + + SlotListCtrl->InsertColumn (ColumnType, LangString["TYPE"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (100); + + wxImageList *imageList = new wxImageList (16, 12, true); + imageList->Add (Resources::GetDriveIconBitmap(), Resources::GetDriveIconMaskBitmap()); + SlotListCtrl->AssignImageList (imageList, wxIMAGE_LIST_SMALL); + + SetMinSize (wxSize (-1, -1)); + + size_t slotListRowCount = 12; + +#ifndef TC_WINDOWS + int screenHeight = wxSystemSettings::GetMetric (wxSYS_SCREEN_Y); + + if (screenHeight < 480) + slotListRowCount = 1; + else if (screenHeight <= 600) + slotListRowCount = slotListRowCount * screenHeight / 1000; +#endif + + Gui->SetListCtrlHeight (SlotListCtrl, slotListRowCount); + +#ifdef __WXGTK__ + wxSize size (-1, (int) ((double) Gui->GetCharHeight (this) * 1.53)); + CreateVolumeButton->SetMinSize (size); + VolumePropertiesButton->SetMinSize (size); + WipeCacheButton->SetMinSize (size); + VolumePathComboBox->SetMinSize (size); + SelectFileButton->SetMinSize (size); + SelectDeviceButton->SetMinSize (size); + VolumeToolsButton->SetMinSize (size); + size = wxSize (-1, 38); + VolumeButton->SetMinSize (size); +#endif + Fit(); + Layout(); + Center(); + + VolumePathComboBox->SetMinSize (VolumePathComboBox->GetSize()); + VolumePathComboBox->SetMaxSize (VolumePathComboBox->GetSize()); + + SetMinSize (GetSize()); + SetMaxSize (GetSize()); + + Gui->SetListCtrlColumnWidths (SlotListCtrl, colPermilles); + + UpdateVolumeList(); + UpdateWipeCacheButton(); + } + + void MainFrame::InitEvents () + { + Core->VolumeMountedEvent.Connect (EventConnector (this, &MainFrame::OnVolumeMounted)); + Core->VolumeDismountedEvent.Connect (EventConnector (this, &MainFrame::OnVolumeDismounted)); + Gui->OpenVolumeSystemRequestEvent.Connect (EventConnector (this, &MainFrame::OnOpenVolumeSystemRequestEvent)); + Gui->PreferencesUpdatedEvent.Connect (EventConnector (this, &MainFrame::OnPreferencesUpdated)); + + // Drag & drop + class FileDropTarget : public wxFileDropTarget + { + public: + FileDropTarget (MainFrame *frame) : Frame (frame) { } + + wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def) + { + wxPoint p; + wxWindow *w = wxFindWindowAtPointer (p); + if (w == Frame || wxGetTopLevelParent (w) == Frame) + return wxDragLink; + return wxDragNone; + } + + bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames) + { + if (!filenames.empty()) + Frame->SetVolumePath (wstring (filenames.front())); + return true; + } + + MainFrame *Frame; + }; + + SetDropTarget (new FileDropTarget (this)); +#ifdef TC_MACOSX + foreach (wxWindow *c, MainPanel->GetChildren()) + c->SetDropTarget (new FileDropTarget (this)); +#endif + + // Volume history + VolumeHistory::ConnectComboBox (VolumePathComboBox); + +#ifdef TC_WINDOWS + // Hotkeys + Hotkey::RegisterList (this, GetPreferences().Hotkeys); + Connect (wxEVT_HOTKEY, wxKeyEventHandler (MainFrame::OnHotkey)); +#endif + + // Timer + class Timer : public wxTimer + { + public: + Timer (MainFrame *frame) : Frame (frame) { } + + void Notify() + { + Frame->OnTimer(); + } + + MainFrame *Frame; + }; + + mTimer.reset (dynamic_cast (new Timer (this))); + mTimer->Start (2000); + } + +#ifdef TC_WINDOWS +#include + static WNDPROC MainFrameWndProc; + static LRESULT CALLBACK MainFrameWndProcFilter (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) + { + if (message == WM_DEVICECHANGE && !Core->IsDeviceChangeInProgress()) + { + MainFrame *frame = dynamic_cast (Gui->GetMainFrame()); + PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam; + + if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) + { + PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam; + for (wchar_t driveNo = 0; driveNo < 26; ++driveNo) + { + if (vol->dbcv_unitmask & (1 << driveNo)) + frame->OnDeviceChange (wstring (StringFormatter (L"{0}:\\", wchar_t (L'A' + driveNo)))); + } + } + else + { + frame->OnDeviceChange (); + } + } + + return CallWindowProc (MainFrameWndProc, hwnd, message, wParam, lParam); + } +#endif + + void MainFrame::InitMessageFilter () + { +#ifdef TC_WINDOWS + HWND mainFrameHwnd = static_cast (GetHandle()); + MainFrameWndProc = (WNDPROC) GetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC); + SetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC, (LONG_PTR) MainFrameWndProcFilter); +#endif + } + + void MainFrame::InitPreferences () + { + try + { + LoadPreferences(); + + VolumeSlotNumber lastSelectedSlotNumber = GetPreferences().LastSelectedSlotNumber; + if (Core->IsSlotNumberValid (lastSelectedSlotNumber)) + { + long slotIndex = SlotNumberToItemIndex (lastSelectedSlotNumber); + if (slotIndex >= 0) + { + SlotListCtrl->SetItemState (slotIndex, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + SlotListCtrl->EnsureVisible (slotIndex); + } + } + + LoadFavoriteVolumes(); + VolumeHistory::Load(); + + if (VolumePathComboBox->GetValue().empty() && !VolumeHistory::Get().empty()) + SetVolumePath (VolumeHistory::Get().front()); + } + catch (exception &e) + { + Gui->ShowError (e); + Gui->ShowError (_("Error while loading configuration files located in ") + wstring (Application::GetConfigFilePath (L""))); + } + } + + void MainFrame::InitTaskBarIcon () + { + class TaskBarIcon : public wxTaskBarIcon + { + public: + TaskBarIcon (MainFrame *frame) : Busy (false), Frame (frame) + { + Connect (wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler (TaskBarIcon::OnLeftButtonDown)); + } + + wxMenu *CreatePopupMenu () + { + auto_ptr popup (new wxMenu); + + Gui->AppendToMenu (*popup, LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"], this, wxCommandEventHandler (TaskBarIcon::OnShowHideMenuItemSelected)); + + popup->AppendSeparator(); + Gui->AppendToMenu (*popup, _("Mount All Favorite Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnMountAllFavoritesMenuItemSelected))->Enable (!Busy); + Gui->AppendToMenu (*popup, _("Dismount All Mounted Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnDismountAllMenuItemSelected))->Enable (!Busy); + + // Favorite volumes + if (Gui->GetPreferences().BackgroundTaskMenuMountItemsEnabled && !Frame->FavoriteVolumesMenuMap.empty()) + { + popup->AppendSeparator(); + typedef pair FavMapPair; + foreach (FavMapPair fp, Frame->FavoriteVolumesMenuMap) + { + Gui->AppendToMenu (*popup, LangString["MOUNT"] + L" " + wstring (fp.second.Path) + (fp.second.MountPoint.IsEmpty() ? L"" : L" " + wstring (fp.second.MountPoint)), + this, wxCommandEventHandler (TaskBarIcon::OnFavoriteVolumeMenuItemSelected), fp.first)->Enable (!Busy); + } + } + + // Mounted volumes + VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); + if (!mountedVolumes.empty()) + { + if (Gui->GetPreferences().BackgroundTaskMenuOpenItemsEnabled) + { + popup->AppendSeparator(); + OpenMap.clear(); + foreach (shared_ptr volume, mountedVolumes) + { + if (!volume->MountPoint.IsEmpty()) + { + wxString label = LangString["OPEN"] + L" " + wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")"; + wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnOpenMenuItemSelected)); + OpenMap[item->GetId()] = volume; + } + } + } + + if (Gui->GetPreferences().BackgroundTaskMenuDismountItemsEnabled) + { + popup->AppendSeparator(); + DismountMap.clear(); + foreach (shared_ptr volume, mountedVolumes) + { + wxString label = LangString["DISMOUNT"] + L" "; + + if (!volume->MountPoint.IsEmpty()) + label += wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")"; + else + label += wstring (volume->Path); + + wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnDismountMenuItemSelected)); + item->Enable (!Busy); + DismountMap[item->GetId()] = volume; + } + } + } + + popup->AppendSeparator(); + Gui->AppendToMenu (*popup, _("Preferences..."), this, wxCommandEventHandler (TaskBarIcon::OnPreferencesMenuItemSelected))->Enable (!Busy); +#ifndef TC_MACOSX + popup->AppendSeparator(); + Gui->AppendToMenu (*popup, _("Exit"), this, wxCommandEventHandler (TaskBarIcon::OnExitMenuItemSelected))->Enable (!Busy && Frame->CanExit()); +#endif + return popup.release(); + } + + void OnDismountAllMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnDismountAllButtonClick (event); Busy = false; } + void OnDismountMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->DismountVolume (DismountMap[event.GetId()]); Busy = false; } + void OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnFavoriteVolumeMenuItemSelected (event); Busy = false; } + void OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->MountAllFavorites (); Busy = false; } + + void OnExitMenuItemSelected (wxCommandEvent& event) + { + Busy = true; + if (Core->GetMountedVolumes().empty() || Gui->AskYesNo (LangString ["CONFIRM_EXIT"], false, true)) + Frame->Close (true); + Busy = false; + } + + void OnLeftButtonDown (wxTaskBarIconEvent& event) { Gui->SetBackgroundMode (false); } + void OnOpenMenuItemSelected (wxCommandEvent& event) { Gui->OpenExplorerWindow (OpenMap[event.GetId()]->MountPoint); } + void OnPreferencesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnPreferencesMenuItemSelected (event); Busy = false; } + void OnShowHideMenuItemSelected (wxCommandEvent& event) { Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); } + + bool Busy; + map < int, shared_ptr > DismountMap; + MainFrame *Frame; + map < int, shared_ptr > OpenMap; + }; + + mTaskBarIcon.reset (new TaskBarIcon (this)); + ShowTaskBarIcon (GetPreferences().BackgroundTaskEnabled); + } + + void MainFrame::LoadFavoriteVolumes () + { + typedef pair FavMapPair; + foreach (FavMapPair p, FavoriteVolumesMenuMap) + { + FavoritesMenu->Delete (p.first); + } + FavoriteVolumesMenuMap.clear(); + + foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList()) + { + wstring label = wstring (favorite.Path); + if (!favorite.MountPoint.IsEmpty()) + label += wstring (L" ") + wstring (favorite.MountPoint); + + wxMenuItem *item = Gui->AppendToMenu (*FavoritesMenu, label, this, wxCommandEventHandler (MainFrame::OnFavoriteVolumeMenuItemSelected)); + FavoriteVolumesMenuMap[item->GetId()] = favorite; + } + } + + void MainFrame::LoadPreferences () + { + UserPreferences prefs; + prefs.Load(); + Gui->SetPreferences (prefs); + NoHistoryCheckBox->SetValue (!prefs.SaveHistory); + } + + void MainFrame::MountAllDevices () + { + try + { + MountOptions mountOptions (GetPreferences().DefaultMountOptions); + + if (SlotListCtrl->GetSelectedItemCount() == 1) + mountOptions.SlotNumber = SelectedSlotNumber; + + Gui->MountAllDeviceHostedVolumes (mountOptions); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::MountAllFavorites () + { + try + { + MountOptions mountOptions (GetPreferences().DefaultMountOptions); + Gui->MountAllFavoriteVolumes (mountOptions); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::MountVolume () + { + if (!IsFreeSlotSelected()) + { + Gui->ShowWarning (_("Please select a free drive slot from the list.")); + return; + } + + if (!CheckVolumePathNotEmpty()) + return; + + MountOptions mountOptions (GetPreferences().DefaultMountOptions); + mountOptions.SlotNumber = SelectedSlotNumber; + mountOptions.Path = GetSelectedVolumePath(); + + try + { + if (Gui->MountVolume (mountOptions) && GetPreferences().SaveHistory) + VolumeHistory::Add (*mountOptions.Path); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnAboutMenuItemSelected (wxCommandEvent& event) + { + AboutDialog dialog (this); + dialog.ShowModal(); + } + + void MainFrame::OnActivate (wxActivateEvent& event) + { + Gui->SetActiveFrame (this); + +#ifdef TC_MACOSX + if (event.GetActive() && Gui->IsInBackgroundMode()) + Gui->SetBackgroundMode (false); +#endif + event.Skip(); + } + + void MainFrame::OnAddAllMountedToFavoritesMenuItemSelected (wxCommandEvent& event) + { + AddToFavorites (MountedVolumes); + } + + void MainFrame::OnAddToFavoritesMenuItemSelected (wxCommandEvent& event) + { + shared_ptr selectedVolume = GetSelectedVolume(); + if (selectedVolume) + { + VolumeInfoList volumes; + volumes.push_back (selectedVolume); + AddToFavorites (volumes); + } + } + + void MainFrame::OnBackupVolumeHeadersMenuItemSelected (wxCommandEvent& event) + { + if (!CheckVolumePathNotEmpty ()) + return; + + try + { + Gui->BackupVolumeHeaders (GetSelectedVolumePath()); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnBenchmarkMenuItemSelected (wxCommandEvent& event) + { + BenchmarkDialog dialog (this); + dialog.ShowModal(); + } + + void MainFrame::OnClearSlotSelectionMenuItemSelected (wxCommandEvent& event) + { + Gui->ClearListCtrlSelection (SlotListCtrl); + UpdateControls(); + } + + void MainFrame::OnClose (wxCloseEvent& event) + { + if (GetPreferences().WipeCacheOnClose) + Core->WipePasswordCache(); + +#ifdef TC_MACOSX + if (!event.CanVeto() && GetPreferences().DismountOnLogOff) + { + try + { + Gui->DismountVolumes (Core->GetMountedVolumes(), GetPreferences().ForceAutoDismount, false); + } + catch (...) { } + } +#endif + + if (!Gui->IsTheOnlyTopLevelWindow (this)) + { + // Bring first frame to foreground + wxFrame *frame = nullptr; + foreach (wxWindow *window, wxTopLevelWindows) + { + if (window != this + && dynamic_cast (window) + && StringConverter::GetTypeName (typeid (*window)).find ("wxTaskBarIcon") == string::npos) + { + frame = dynamic_cast (window); + if (window->IsShown()) + break; + } + } + + if (frame) + { + frame->Show(); + if (frame->IsIconized()) + frame->Iconize(false); + frame->Raise(); + } + } + else if (event.CanVeto() && GetPreferences().BackgroundTaskEnabled + && (!GetPreferences().CloseBackgroundTaskOnNoVolumes || !MountedVolumes.empty())) + { + // Enter background mode + if (!Gui->IsInBackgroundMode()) + Gui->SetBackgroundMode (true); + } + else + { +#ifdef __WXGTK__ + Show(); +#endif + SavePreferences(); + + Destroy(); + } + + // Cancel close - veto is not used to prevent aborting log off procedure on Windows + return; + } + + void MainFrame::OnCloseAllSecurityTokenSessionsMenuItemSelected (wxCommandEvent& event) + { + try + { + { + wxBusyCursor busy; + SecurityToken::CloseAllSessions(); + } + Gui->ShowInfo ("ALL_TOKEN_SESSIONS_CLOSED"); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnCreateVolumeButtonClick (wxCommandEvent& event) + { + try + { + (new VolumeCreationWizard (nullptr))->Show(); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnDefaultKeyfilesMenuItemSelected (wxCommandEvent& event) + { + PreferencesDialog dialog (this); + dialog.SelectPage (dialog.DefaultKeyfilesPage); + dialog.ShowModal(); + } + + void MainFrame::OnDeviceChange (const DirectoryPath &mountPoint) + { + // Check if any host device has been removed and force dismount of volumes accordingly + VolumeInfoList removedVolumes; + foreach (shared_ptr volume, Core->GetMountedVolumes()) + { + // File-hosted volumes + if (!volume->Path.IsDevice() && !mountPoint.IsEmpty()) + { + if (wxString (volume->Path).Upper().StartsWith (wstring (mountPoint).c_str())) + { + removedVolumes.push_back (volume); + continue; + } + } + + // Device-hosted volumes + if (volume->Path.IsDevice() && !Core->IsDevicePresent (volume->Path)) + removedVolumes.push_back (volume); + } + + if (!removedVolumes.empty()) + Gui->AutoDismountVolumes (removedVolumes, true); + } + + void MainFrame::OnDismountAllButtonClick (wxCommandEvent& event) + { + Gui->DismountAllVolumes(); + } + + void MainFrame::OnEncryptionTestMenuItemSelected (wxCommandEvent& event) + { + EncryptionTestDialog dialog (this); + dialog.ShowModal(); + } + + void MainFrame::OnExitButtonClick (wxCommandEvent& event) + { + Close(); + } + + void MainFrame::OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) + { + FavoriteVolume favorite = FavoriteVolumesMenuMap[event.GetId()]; + if (!favorite.Path.IsEmpty()) + { + SetVolumePath (favorite.Path); + + MountOptions mountOptions (GetPreferences().DefaultMountOptions); + favorite.ToMountOptions (mountOptions); + + shared_ptr volume = Gui->MountVolume (mountOptions); + if (volume) + SlotListCtrl->EnsureVisible (SlotNumberToItemIndex (volume->SlotNumber)); + } + } + + void MainFrame::OnHiddenVolumeProtectionTriggered (shared_ptr protectedVolume) + { + Gui->ShowWarningTopMost (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (protectedVolume->Path))); + } + + void MainFrame::OnHotkey (wxKeyEvent& event) + { +#ifdef TC_WINDOWS + switch (event.GetId()) + { + case Hotkey::Id::CloseAllSecurityTokenSessions: + try + { + SecurityToken::CloseAllSessions(); + Gui->ShowInfo ("ALL_TOKEN_SESSIONS_CLOSED"); + } + catch (exception &e) { Gui->ShowError (e); } + break; + + case Hotkey::Id::DismountAll: + case Hotkey::Id::DismountAllWipeCache: + { + if (event.GetId() == Hotkey::Id::DismountAllWipeCache) + WipeCache(); + + size_t mountedCount = Core->GetMountedVolumes().size(); + Gui->DismountAllVolumes(); + size_t newMountedCount = Core->GetMountedVolumes().size(); + + if (newMountedCount < mountedCount) + { + if (newMountedCount == 0 && GetPreferences().DisplayMessageAfterHotkeyDismount) + Gui->ShowInfo ("MOUNTED_VOLUMES_DISMOUNTED"); + else if (GetPreferences().BeepAfterHotkeyMountDismount) + MessageBeep((UINT) -1); + } + } + break; + + case Hotkey::Id::ForceDismountAllWipeCache: + case Hotkey::Id::ForceDismountAllWipeCacheExit: + { + bool mounted = !Core->GetMountedVolumes().empty(); + + WipeCache(); + Gui->DismountAllVolumes (true, true); + + if (mounted && GetPreferences().DisplayMessageAfterHotkeyDismount) + Gui->ShowInfo ("VOLUMES_DISMOUNTED_CACHE_WIPED"); + else if (mounted && GetPreferences().BeepAfterHotkeyMountDismount) + MessageBeep((UINT) -1); + + if (event.GetId() == Hotkey::Id::ForceDismountAllWipeCacheExit) + Close (true); + } + break; + + case Hotkey::Id::MountAllDevices: + case Hotkey::Id::MountAllFavorites: + { + size_t mountedCount = Core->GetMountedVolumes().size(); + + if (event.GetId() == Hotkey::Id::MountAllDevices) + MountAllDevices(); + else + MountAllFavorites(); + + if (Core->GetMountedVolumes().size() > mountedCount && GetPreferences().BeepAfterHotkeyMountDismount) + MessageBeep((UINT) -1); + } + break; + + case Hotkey::Id::ShowHideApplication: + Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); + break; + + case Hotkey::Id::WipeCache: + WipeCache(); + Gui->ShowInfo ("PASSWORD_CACHE_WIPED"); + break; + + default: + assert (false); + break; + } +#endif // TC_WINDOWS + } + + void MainFrame::OnHotkeysMenuItemSelected (wxCommandEvent& event) + { + PreferencesDialog dialog (this); + dialog.SelectPage (dialog.HotkeysPage); + dialog.ShowModal(); + } + + void MainFrame::OnLegalNoticesMenuItemSelected (wxCommandEvent& event) + { + LegalNoticesDialog dialog (this); + dialog.ShowModal(); + } + + void MainFrame::OnListChanged () + { + OnListItemSelectionChanged(); + UpdateControls(); + } + + void MainFrame::OnListItemActivated (wxListEvent& event) + { + if (IsMountedSlotSelected()) + OpenSelectedVolume(); + else + MountVolume(); + } + + void MainFrame::OnListItemDeleted (long itemIndex) + { + if (SelectedItemIndex > itemIndex) + --SelectedItemIndex; + } + + void MainFrame::OnListItemDeselected (wxListEvent& event) + { + OnListItemSelectionChanged(); + } + + void MainFrame::OnListItemInserted (long itemIndex) + { + if (SelectedItemIndex >= itemIndex) + ++SelectedItemIndex; + } + + void MainFrame::OnListItemRightClick (wxListEvent& event) + { +#ifdef TC_MACOSX + if (SelectedItemIndex != event.GetIndex()) + { + SelectedItemIndex = event.GetIndex(); + OnListItemSelectionChanged(); + } + + if (!ListItemRightClickEventPending) + { + ListItemRightClickEventPending = true; + SlotListCtrl->AddPendingEvent (event); + return; + } + + ListItemRightClickEventPending = false; +#endif + + wxMenu popup; + if (IsMountedSlotSelected()) + { + Gui->AppendToMenu (popup, LangString["DISMOUNT"], this, wxCommandEventHandler (MainFrame::OnDismountVolumeMenuItemSelected)); + Gui->AppendToMenu (popup, LangString["OPEN"], this, wxCommandEventHandler (MainFrame::OnOpenVolumeMenuItemSelected)); + Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected)); + + popup.AppendSeparator(); + Gui->AppendToMenu (popup, _("Add to Favorites..."), this, wxCommandEventHandler (MainFrame::OnAddToFavoritesMenuItemSelected)); + + popup.AppendSeparator(); + Gui->AppendToMenu (popup, LangString["IDPM_CHECK_FILESYS"], this, wxCommandEventHandler (MainFrame::OnCheckFilesystemMenuItemSelected)); + Gui->AppendToMenu (popup, LangString["IDPM_REPAIR_FILESYS"], this, wxCommandEventHandler (MainFrame::OnRepairFilesystemMenuItemSelected)); + + popup.AppendSeparator(); + Gui->AppendToMenu (popup, LangString["IDPM_PROPERTIES"], this, wxCommandEventHandler (MainFrame::OnVolumePropertiesButtonClick)); + + PopupMenu (&popup); + } + else if (IsFreeSlotSelected()) + { + Gui->AppendToMenu (popup, _("Mount Volume"), this, wxCommandEventHandler (MainFrame::OnMountVolumeMenuItemSelected)); + + popup.AppendSeparator(); + + Gui->AppendToMenu (popup, LangString["SELECT_FILE_AND_MOUNT"], this, wxCommandEventHandler (MainFrame::OnSelectFileAndMountMenuItemSelected)); + Gui->AppendToMenu (popup, LangString["SELECT_DEVICE_AND_MOUNT"], this, wxCommandEventHandler (MainFrame::OnSelectDeviceAndMountMenuItemSelected)); + + popup.AppendSeparator(); + + Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected)); + + PopupMenu (&popup); + } + } + + void MainFrame::OnListItemSelected (wxListEvent& event) + { + SelectedItemIndex = event.GetIndex(); + OnListItemSelectionChanged(); + } + + void MainFrame::OnListItemSelectionChanged () + { + if (SlotListCtrl->GetSelectedItemCount() < 1) + SelectedItemIndex = -1; + + if (SelectedItemIndex >= 0) + SelectedSlotNumber = (VolumeSlotNumber) SlotListCtrl->GetItemData (SelectedItemIndex); + else + SelectedSlotNumber = 0; + + UpdateControls(); + } + + void MainFrame::OnManageSecurityTokenKeyfilesMenuItemSelected (wxCommandEvent& event) + { + try + { + SecurityTokenKeyfilesDialog dialog (this, false); + dialog.ShowModal(); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnMountAllDevicesButtonClick (wxCommandEvent& event) + { + MountAllDevices(); + } + + void MainFrame::OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) + { + MountAllFavorites(); + } + + void MainFrame::OnNoHistoryCheckBoxClick (wxCommandEvent& event) + { + UserPreferences prefs = GetPreferences(); + prefs.SaveHistory = !event.IsChecked(); + Gui->SetPreferences (prefs); + + if (event.IsChecked()) + { + try + { + VolumeHistory::Clear(); + } + catch (exception &e) { Gui->ShowError (e); } + } + } + + void MainFrame::OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event) + { + try + { + OrganizeFavorites (FavoriteVolume::LoadList()); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnPreferencesMenuItemSelected (wxCommandEvent& event) + { + PreferencesDialog dialog (this); + dialog.ShowModal(); + } + + void MainFrame::OnPreferencesUpdated (EventArgs &args) + { + const UserPreferences &prefs = GetPreferences(); + + NoHistoryCheckBox->SetValue (!prefs.SaveHistory); + + ShowTaskBarIcon (prefs.BackgroundTaskEnabled); + if (Gui->IsInBackgroundMode() && !prefs.BackgroundTaskEnabled) + Close (true); + + SavePreferences(); + } + + void MainFrame::OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event) + { + if (!CheckVolumePathNotEmpty ()) + return; + + try + { + Gui->RestoreVolumeHeaders (GetSelectedVolumePath()); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnSecurityTokenPreferencesMenuItemSelected (wxCommandEvent& event) + { + PreferencesDialog dialog (this); + dialog.SelectPage (dialog.SecurityTokensPage); + dialog.ShowModal(); + } + + + void MainFrame::OnSelectDeviceAndMountMenuItemSelected (wxCommandEvent& event) + { + DevicePath path = Gui->SelectDevice (this); + + if (!path.IsEmpty()) + { + SetVolumePath (path); + OnMountVolumeMenuItemSelected (event); + } + } + + void MainFrame::OnSelectDeviceButtonClick (wxCommandEvent& event) + { + DevicePath path = Gui->SelectDevice (this); + + if (!path.IsEmpty()) + SetVolumePath (path); + } + + void MainFrame::OnSelectFileAndMountMenuItemSelected (wxCommandEvent& event) + { + FilePath path = Gui->SelectVolumeFile (this); + + if (!path.IsEmpty()) + { + SetVolumePath (path); + OnMountVolumeMenuItemSelected (event); + } + } + + void MainFrame::OnSelectFileButtonClick (wxCommandEvent& event) + { + FilePath path = Gui->SelectVolumeFile (this); + if (!path.IsEmpty()) + SetVolumePath (path); + } + + void MainFrame::OnTimer () + { + try + { + UpdateVolumeList(); + UpdateWipeCacheButton(); + + if (GetPreferences().BackgroundTaskEnabled) + { + // Inactivity auto-dismount + if (GetPreferences().DismountOnInactivity) + { + VolumeInfoList inactiveVolumes; + wxLongLong currentTime = wxGetLocalTimeMillis().GetValue(); + + map newActivityTimeMap; + + foreach (shared_ptr volume, MountedVolumes) + { + if (VolumeActivityMap.find (volume->Path) != VolumeActivityMap.end() + && VolumeActivityMap[volume->Path].SerialInstanceNumber == volume->SerialInstanceNumber) + { + VolumeActivityMapEntry ae = VolumeActivityMap[volume->Path]; + + if (volume->TotalDataRead != ae.TotalDataRead || volume->TotalDataWritten != ae.TotalDataWritten) + { + ae.LastActivityTime = currentTime; + ae.TotalDataRead = volume->TotalDataRead; + ae.TotalDataWritten = volume->TotalDataWritten; + } + else if ((currentTime - ae.LastActivityTime) > GetPreferences().MaxVolumeIdleTime * 1000LL * 60) + { + inactiveVolumes.push_back (volume); + } + + newActivityTimeMap[volume->Path] = ae; + } + else + { + newActivityTimeMap[volume->Path] = VolumeActivityMapEntry (*volume, currentTime); + } + } + + VolumeActivityMap = newActivityTimeMap; + + if (!inactiveVolumes.empty()) + Gui->AutoDismountVolumes (inactiveVolumes); + } + + // Screen saver auto-dismount + if (GetPreferences().DismountOnScreenSaver) + { +#ifdef TC_WINDOWS + bool running; + if (SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0) != 0) + { + static bool previousState = false; + if (running && !previousState) + { + previousState = true; + Gui->OnAutoDismountAllEvent(); + } + else + { + previousState = running; + } + } +#endif + } + } + + if (Gui->IsInBackgroundMode()) + { + if (!GetPreferences().BackgroundTaskEnabled) + { + Close (true); + } + else if (MountedVolumes.empty() && (GetPreferences().CloseBackgroundTaskOnNoVolumes || Core->IsInPortableMode())) + { + Close (true); + } + } + +#if defined(TC_UNIX) && !defined(TC_MACOSX) + try + { + byte buf[128]; + if (read (ShowRequestFifo, buf, sizeof (buf)) > 0 && Gui->IsInBackgroundMode()) + Gui->SetBackgroundMode (false); + } + catch (...) + { +#ifdef DEBUG + throw; +#endif + } +#endif + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void MainFrame::OnVolumeButtonClick (wxCommandEvent& event) + { + if (IsMountedSlotSelected()) + DismountVolume(); + else + MountVolume(); + } + + void MainFrame::OnVolumePropertiesButtonClick (wxCommandEvent& event) + { + shared_ptr selectedVolume = GetSelectedVolume(); + if (selectedVolume) + { + VolumePropertiesDialog dialog (this, *selectedVolume); + dialog.ShowModal(); + } + } + + void MainFrame::OnVolumeToolsButtonClick (wxCommandEvent& event) + { + if (!CheckVolumePathNotEmpty()) + return; + + wxMenu popup; + + Gui->AppendToMenu (popup, _("Change Volume Password..."), this, wxCommandEventHandler (MainFrame::OnChangePasswordMenuItemSelected)); + + popup.AppendSeparator (); + + Gui->AppendToMenu (popup, _("Add/Remove Keyfiles to/from Volume..."), this, wxCommandEventHandler (MainFrame::OnChangeKeyfilesMenuItemSelected)); + Gui->AppendToMenu (popup, _("Remove All Keyfiles from Volume..."), this, wxCommandEventHandler (MainFrame::OnRemoveKeyfilesMenuItemSelected)); + + popup.AppendSeparator (); + + Gui->AppendToMenu (popup, _("Change Header Key Derivation Algorithm..."), this, wxCommandEventHandler (MainFrame::OnChangePkcs5PrfMenuItemSelected)); + + popup.AppendSeparator (); + + Gui->AppendToMenu (popup, _("Backup Volume Header..."), this, wxCommandEventHandler (MainFrame::OnBackupVolumeHeadersMenuItemSelected)); + Gui->AppendToMenu (popup, _("Restore Volume Header..."), this, wxCommandEventHandler (MainFrame::OnRestoreVolumeHeaderMenuItemSelected)); + + PopupMenu (&popup, VolumeToolsButton->GetPosition().x + 2, VolumeToolsButton->GetPosition().y + 2); + } + + void MainFrame::OnWipeCacheButtonClick (wxCommandEvent& event) + { + WipeCache(); + Gui->ShowInfo ("PASSWORD_CACHE_WIPED"); + } + + void MainFrame::OpenSelectedVolume () const + { + shared_ptr selectedVolume = GetSelectedVolume(); + if (selectedVolume) + { + try + { + wxBusyCursor busy; + Gui->OpenExplorerWindow (selectedVolume->MountPoint); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + } + + void MainFrame::OrganizeFavorites (const FavoriteVolumeList &favorites, size_t newItemCount) + { + FavoriteVolumesDialog dialog (this, favorites, newItemCount); + + if (dialog.ShowModal() == wxID_OK) + { + FavoriteVolume::SaveList (dialog.GetFavorites()); + LoadFavoriteVolumes(); + } + } + + void MainFrame::SavePreferences () const + { + try + { + UserPreferences prefs = GetPreferences(); + prefs.LastSelectedSlotNumber = SelectedSlotNumber; + prefs.Save(); + + VolumeHistory::Save(); + } + catch (exception &e) + { + if (!Core->IsInPortableMode()) + Gui->ShowError (e); + } + } + + void MainFrame::ShowTaskBarIcon (bool show) + { + if (!show && mTaskBarIcon->IsIconInstalled()) + { + mTaskBarIcon->RemoveIcon(); + } + else if (show && !mTaskBarIcon->IsIconInstalled()) + { +#ifndef TC_MACOSX + mTaskBarIcon->SetIcon (Resources::GetTrueCryptIcon(), L"TrueCrypt"); +#endif + } + } + + long MainFrame::SlotNumberToItemIndex (uint32 slotNumber) const + { + for (long itemIndex = 0; itemIndex < SlotListCtrl->GetItemCount(); itemIndex++) + { + wxListItem item; + item.SetId (itemIndex); + if (slotNumber == (uint32) SlotListCtrl->GetItemData (item)) + return itemIndex; + } + return -1; + } + + void MainFrame::UpdateControls () + { + bool mounted = IsMountedSlotSelected(); + + VolumeButton->SetLabel (mounted ? LangString["DISMOUNT"] : wxString (_("Mount"))); + VolumePropertiesButton->Enable (mounted); + + DismountVolumeMenuItem->Enable (mounted); + MountVolumeMenuItem->Enable (!mounted); + VolumePropertiesMenuItem->Enable (mounted); + AddToFavoritesMenuItem->Enable (mounted); + AddAllMountedToFavoritesMenuItem->Enable (!MountedVolumes.empty()); + UpdateWipeCacheButton(); + } + + void MainFrame::UpdateVolumeList () + { + static Mutex mutex; + ScopeLock lock (mutex); + + bool listChanged = false; + + MountedVolumes = Core->GetMountedVolumes(); + + map < VolumeSlotNumber, shared_ptr > mountedVolumesMap; + foreach (shared_ptr volume, MountedVolumes) + { + mountedVolumesMap[volume->SlotNumber] = volume; + } + + VolumeInfoList protectionTriggeredVolumes; + + // Update list + long prevItemIndex = -1; + for (VolumeSlotNumber slotNumber = Core->GetFirstSlotNumber(); slotNumber <= Core->GetLastSlotNumber(); ++slotNumber) + { + long itemIndex = SlotNumberToItemIndex (slotNumber); + vector fields (SlotListCtrl->GetColumnCount()); + + if (mountedVolumesMap.find (slotNumber) != mountedVolumesMap.end()) + { + shared_ptr volume = mountedVolumesMap[slotNumber]; + +#ifdef TC_WINDOWS + fields[ColumnSlot] = volume->MountPoint; + fields[ColumnEA] = volume->EncryptionAlgorithmName; +#else + fields[ColumnSlot] = StringConverter::FromNumber (slotNumber); + fields[ColumnMountPoint] = volume->MountPoint; +#endif + fields[ColumnPath] = volume->Path; + fields[ColumnSize] = Gui->SizeToString (volume->Size); + fields[ColumnType] = Gui->VolumeTypeToString (volume->Type, volume->Protection); + + if (volume->HiddenVolumeProtectionTriggered) + { + fields[ColumnType] += L"(!)"; + } + + bool slotUpdated = false; + if (itemIndex == -1) + { + Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) volume->SlotNumber); + OnListItemInserted (prevItemIndex); + + listChanged |= true; + slotUpdated = true; + } + else + { + if (Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields)) + { + listChanged = true; + slotUpdated = true; + } + prevItemIndex = itemIndex; + } + + if (slotUpdated && volume->HiddenVolumeProtectionTriggered) + protectionTriggeredVolumes.push_back (volume); + } + else + { +#ifdef TC_WINDOWS + fields[ColumnSlot] = Core->SlotNumberToMountPoint (slotNumber); +#else + fields[ColumnSlot] = StringConverter::FromNumber (slotNumber); +#endif + +#ifdef TC_WINDOWS + if (Core->IsMountPointAvailable (fields[ColumnSlot])) +#else + if (true) +#endif + { + if (itemIndex == -1) + { + Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) slotNumber); + OnListItemInserted (prevItemIndex); + listChanged |= true; + } + else + { + listChanged |= Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields); + prevItemIndex = itemIndex; + } + } + else if (itemIndex != -1) + { + SlotListCtrl->DeleteItem (itemIndex); + OnListItemDeleted (itemIndex); + listChanged = true; + } + } + } + + if (listChanged) + OnListChanged(); + + foreach (shared_ptr volume, protectionTriggeredVolumes) + OnHiddenVolumeProtectionTriggered (volume); + } + + void MainFrame::UpdateWipeCacheButton () + { + bool enabled = WipeCacheButton->IsEnabled(); + bool empty = Core->IsPasswordCacheEmpty(); + + if (empty && enabled) + { + WipeCacheButton->Disable(); + WipeCachedPasswordsMenuItem->Enable (false); + } + else if (!empty && !enabled) + { + WipeCacheButton->Enable(); + WipeCachedPasswordsMenuItem->Enable(); + } + } + + void MainFrame::WipeCache () + { + Core->WipePasswordCache(); + UpdateWipeCacheButton(); + } +} diff --git a/src/Main/Forms/MainFrame.h b/src/Main/Forms/MainFrame.h new file mode 100644 index 00000000..5b775abc --- /dev/null +++ b/src/Main/Forms/MainFrame.h @@ -0,0 +1,173 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_MainFrame +#define TC_HEADER_Main_Forms_MainFrame + +#include "Forms.h" +#include "ChangePasswordDialog.h" + +namespace TrueCrypt +{ + struct FavoriteVolume; + + class MainFrame : public MainFrameBase + { + public: + MainFrame (wxWindow* parent); + virtual ~MainFrame (); + + void OnDeviceChange (const DirectoryPath &mountPoint = DirectoryPath()); +#ifdef TC_UNIX + static FilePath GetShowRequestFifoPath () { return Application::GetConfigFilePath (L".show-request-queue", true); } +#endif + + protected: + enum + { + ColumnSlot = 0, + ColumnPath, + ColumnSize, +#ifdef TC_WINDOWS + ColumnEA, +#else + ColumnMountPoint, +#endif + ColumnType + }; + + void AddToFavorites (const VolumeInfoList &volumes); + bool CanExit () const; + void ChangePassword (ChangePasswordDialog::Mode::Enum mode = ChangePasswordDialog::Mode::ChangePasswordAndKeyfiles); + void CheckFilesystem (bool repair = false); + bool CheckVolumePathNotEmpty () const; + void DismountVolume (shared_ptr volume = shared_ptr ()); + const UserPreferences &GetPreferences () const { return Gui->GetPreferences(); } + shared_ptr GetSelectedVolume () const; + shared_ptr GetSelectedVolumePath () const { return make_shared (wstring (VolumePathComboBox->GetValue())); } + void InitControls (); + void InitEvents (); + void InitMessageFilter (); + void InitPreferences (); + void InitTaskBarIcon (); + bool IsFreeSlotSelected () const { return SlotListCtrl->GetSelectedItemCount() == 1 && Gui->GetListCtrlSubItemText (SlotListCtrl, SelectedItemIndex, ColumnPath).empty(); } + bool IsMountedSlotSelected () const { return SlotListCtrl->GetSelectedItemCount() == 1 && !Gui->GetListCtrlSubItemText (SlotListCtrl, SelectedItemIndex, ColumnPath).empty(); } + void LoadFavoriteVolumes (); + void LoadPreferences (); + void MountAllDevices (); + void MountAllFavorites (); + void MountVolume (); + void OnAboutMenuItemSelected (wxCommandEvent& event); + void OnActivate (wxActivateEvent& event); + void OnAddAllMountedToFavoritesMenuItemSelected (wxCommandEvent& event); + void OnAddToFavoritesMenuItemSelected (wxCommandEvent& event); + void OnBackupVolumeHeadersMenuItemSelected (wxCommandEvent& event); + void OnBeginnersTutorialMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"tutorial"); } + void OnBenchmarkMenuItemSelected (wxCommandEvent& event); + void OnChangeKeyfilesMenuItemSelected (wxCommandEvent& event) { ChangePassword (ChangePasswordDialog::Mode::ChangeKeyfiles); } + void OnChangePasswordMenuItemSelected (wxCommandEvent& event) { ChangePassword (); } + void OnChangePkcs5PrfMenuItemSelected (wxCommandEvent& event) { ChangePassword (ChangePasswordDialog::Mode::ChangePkcs5Prf); } + void OnCheckFilesystemMenuItemSelected( wxCommandEvent& event ) { CheckFilesystem (); } + void OnClearSlotSelectionMenuItemSelected (wxCommandEvent& event); + void OnClose (wxCloseEvent& event); + void OnCloseAllSecurityTokenSessionsMenuItemSelected (wxCommandEvent& event); + void OnContactMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"contact"); } + void OnCreateKeyfileMenuItemSelected (wxCommandEvent& event) { Gui->CreateKeyfile(); } + void OnCreateVolumeButtonClick (wxCommandEvent& event); + void OnDefaultKeyfilesMenuItemSelected (wxCommandEvent& event); + void OnDismountAllButtonClick (wxCommandEvent& event); + void OnDismountVolumeMenuItemSelected (wxCommandEvent& event) { DismountVolume(); } + void OnDownloadsMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"downloads"); } + void OnEncryptionTestMenuItemSelected (wxCommandEvent& event); + void OnExitButtonClick (wxCommandEvent& event); + void OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event); + void OnFaqMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"faq"); } + void OnHiddenVolumeProtectionTriggered (shared_ptr protectedVolume); + void OnHotkey (wxKeyEvent& event); + void OnHotkeysMenuItemSelected (wxCommandEvent& event); + void OnLegalNoticesMenuItemSelected (wxCommandEvent& event); + void OnListChanged (); + void OnListItemActivated (wxListEvent& event); + void OnListItemDeleted (long itemIndex); + void OnListItemDeselected (wxListEvent& event); + void OnListItemInserted (long itemIndex); + void OnListItemRightClick (wxListEvent& event); + void OnListItemSelected (wxListEvent& event); + void OnListItemSelectionChanged (); + void OnLogoBitmapClick (wxMouseEvent &event) { wxCommandEvent ev; OnAboutMenuItemSelected (ev); } + void OnManageSecurityTokenKeyfilesMenuItemSelected (wxCommandEvent& event); + void OnMountAllDevicesButtonClick (wxCommandEvent& event); + void OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event); + void OnMountVolumeMenuItemSelected (wxCommandEvent& event) { MountVolume(); } + void OnNewsMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"news"); } + void OnNoHistoryCheckBoxClick (wxCommandEvent& event); + void OnOnlineHelpMenuItemSelected (wxCommandEvent& event) { Gui->OpenOnlineHelp (this); } + void OnOpenVolumeMenuItemSelected (wxCommandEvent& event) { OpenSelectedVolume(); } + void OnOpenVolumeSystemRequestEvent (EventArgs &args) { SetVolumePath (wstring (dynamic_cast (args).mVolumePath)); } + void OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event); + void OnPreferencesMenuItemSelected (wxCommandEvent& event); + void OnPreferencesUpdated (EventArgs &args); + void OnRemoveKeyfilesMenuItemSelected (wxCommandEvent& event) { ChangePassword (ChangePasswordDialog::Mode::RemoveAllKeyfiles); } + void OnRepairFilesystemMenuItemSelected( wxCommandEvent& event ) { CheckFilesystem (true); } + void OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event); + void OnSecurityTokenPreferencesMenuItemSelected (wxCommandEvent& event); + void OnSelectDeviceAndMountMenuItemSelected (wxCommandEvent& event); + void OnSelectDeviceButtonClick (wxCommandEvent& event); + void OnSelectFileAndMountMenuItemSelected (wxCommandEvent& event); + void OnSelectFileButtonClick (wxCommandEvent& event); + void OnTimer (); + void OnVersionHistoryMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"history"); } + void OnVolumePropertiesButtonClick (wxCommandEvent& event); + void OnVolumeToolsButtonClick (wxCommandEvent& event); + void OnVolumeButtonClick (wxCommandEvent& event); + void OnVolumeDismounted (EventArgs &args) { UpdateVolumeList(); } + void OnVolumeMounted (EventArgs &args) { UpdateVolumeList(); } + void OnUserGuideMenuItemSelected (wxCommandEvent& event) { Gui->OpenUserGuide (this); } + void OnWebsiteMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"website"); } + void OnWipeCacheButtonClick (wxCommandEvent& event); + void OrganizeFavorites (const FavoriteVolumeList &favorites, size_t newItemCount = 0); + void OpenSelectedVolume () const; + void SavePreferences () const; + long SlotNumberToItemIndex (uint32 slotNumber) const; + void SetVolumePath (const VolumePath &path) { VolumePathComboBox->SetValue (wstring (path)); } + void ShowTaskBarIcon (bool show = true); + void UpdateControls (); + void UpdateVolumeList (); + void UpdateWipeCacheButton (); + void WipeCache (); + + struct VolumeActivityMapEntry + { + VolumeActivityMapEntry () { } + + VolumeActivityMapEntry (const VolumeInfo &volume, wxLongLong lastActivityTime) + : LastActivityTime (lastActivityTime), + SerialInstanceNumber (volume.SerialInstanceNumber), + TotalDataRead (volume.TotalDataRead), + TotalDataWritten (volume.TotalDataWritten) + { } + + wxLongLong LastActivityTime; + uint64 SerialInstanceNumber; + uint64 TotalDataRead; + uint64 TotalDataWritten; + }; + + map FavoriteVolumesMenuMap; + bool ListItemRightClickEventPending; + VolumeInfoList MountedVolumes; + auto_ptr mTaskBarIcon; + auto_ptr mTimer; + long SelectedItemIndex; + VolumeSlotNumber SelectedSlotNumber; + int ShowRequestFifo; + map VolumeActivityMap; + }; +} + +#endif // TC_HEADER_Main_Forms_MainFrame diff --git a/src/Main/Forms/MountOptionsDialog.cpp b/src/Main/Forms/MountOptionsDialog.cpp new file mode 100644 index 00000000..f4fea7a6 --- /dev/null +++ b/src/Main/Forms/MountOptionsDialog.cpp @@ -0,0 +1,174 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/Main.h" +#include "Main/GraphicUserInterface.h" +#include "MountOptionsDialog.h" + +namespace TrueCrypt +{ + MountOptionsDialog::MountOptionsDialog (wxWindow *parent, MountOptions &options, const wxString &title, bool disableMountOptions) + : MountOptionsDialogBase (parent, wxID_ANY, wxString() +#ifdef __WXGTK__ // GTK apparently needs wxRESIZE_BORDER to support dynamic resizing + , wxDefaultPosition, wxSize (-1,-1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER +#endif + ), Options (options) + { + if (!title.empty()) + this->SetTitle (title); + else if (options.Path && !options.Path->IsEmpty()) + this->SetTitle (StringFormatter (LangString["ENTER_PASSWORD_FOR"], wstring (*options.Path))); + else + this->SetTitle (LangString["ENTER_TC_VOL_PASSWORD"]); + + if (disableMountOptions) + OptionsButton->Show (false); + + PasswordPanel = new VolumePasswordPanel (this, options.Password, options.Keyfiles, !disableMountOptions); + PasswordPanel->SetCacheCheckBoxValidator (wxGenericValidator (&Options.CachePassword)); + + PasswordSizer->Add (PasswordPanel, 1, wxALL | wxEXPAND); + +#ifdef __WXGTK__ + FilesystemOptionsSizer->Remove (FilesystemSpacer); + OptionsPanel->Show (false); + Fit(); + Layout(); + SetMinSize (GetSize()); +#endif + + NoFilesystemCheckBox->SetValidator (wxGenericValidator (&Options.NoFilesystem)); + RemovableCheckBox->SetValidator (wxGenericValidator (&Options.Removable)); + PartitionInSystemEncryptionScopeCheckBox->SetValidator (wxGenericValidator (&Options.PartitionInSystemEncryptionScope)); + + TransferDataToWindow(); + + if (Options.MountPoint && !Options.MountPoint->IsEmpty()) + MountPointTextCtrl->SetValue (wstring (*Options.MountPoint)); + + FilesystemOptionsTextCtrl->SetValue (Options.FilesystemOptions); + + ReadOnlyCheckBox->SetValue (Options.Protection == VolumeProtection::ReadOnly); + ProtectionCheckBox->SetValue (Options.Protection == VolumeProtection::HiddenVolumeReadOnly); + + OptionsButtonLabel = OptionsButton->GetLabel(); + OptionsButton->SetLabel (OptionsButtonLabel + L" >"); + OptionsPanel->Show (false); + + ProtectionPasswordPanel = new VolumePasswordPanel (OptionsPanel, options.ProtectionPassword, options.ProtectionKeyfiles, false, true, true, false, false, _("P&assword to hidden volume:")); + ProtectionPasswordSizer->Add (ProtectionPasswordPanel, 1, wxALL | wxEXPAND); + + UpdateDialog(); + Center(); + } + + void MountOptionsDialog::OnInitDialog (wxInitDialogEvent& event) + { + PasswordPanel->SetFocusToPasswordTextCtrl(); + } + + void MountOptionsDialog::OnMountPointButtonClick (wxCommandEvent& event) + { + DirectoryPath dir = Gui->SelectDirectory (this, wxEmptyString, false); + if (!dir.IsEmpty()) + MountPointTextCtrl->SetValue (wstring (dir)); + } + + void MountOptionsDialog::OnOKButtonClick (wxCommandEvent& event) + { + TransferDataFromWindow(); + + Options.Password = PasswordPanel->GetPassword(); + Options.Keyfiles = PasswordPanel->GetKeyfiles(); + + if (ReadOnlyCheckBox->IsChecked()) + { + Options.Protection = VolumeProtection::ReadOnly; + } + else if (ProtectionCheckBox->IsChecked()) + { + Options.Protection = VolumeProtection::HiddenVolumeReadOnly; + Options.ProtectionPassword = ProtectionPasswordPanel->GetPassword(); + Options.ProtectionKeyfiles = ProtectionPasswordPanel->GetKeyfiles(); + } + else + { + Options.Protection = VolumeProtection::None; + } + + wstring mountPoint (MountPointTextCtrl->GetValue()); + if (!mountPoint.empty()) + Options.MountPoint = make_shared (mountPoint); + + Options.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); + + try + { + if (Options.Password) + Options.Password->CheckPortability(); + } + catch (UnportablePassword &) + { + Gui->ShowWarning (LangString ["UNSUPPORTED_CHARS_IN_PWD_RECOM"]); + } + + EndModal (wxID_OK); + } + + void MountOptionsDialog::OnOptionsButtonClick (wxCommandEvent& event) + { + FreezeScope freeze (this); + OptionsPanel->Show (!OptionsPanel->IsShown()); + UpdateDialog(); + OptionsButton->SetLabel (OptionsButtonLabel + (OptionsPanel->IsShown() ? L" <" : L" >")); + } + + void MountOptionsDialog::OnProtectionCheckBoxClick (wxCommandEvent& event) + { + FreezeScope freeze (this); + ProtectionPasswordPanel->Show (event.IsChecked()); + Fit(); + Layout(); + ProtectionPasswordPanel->SetFocusToPasswordTextCtrl(); + } + + void MountOptionsDialog::OnProtectionHyperlinkClick (wxHyperlinkEvent& event) + { + Gui->OpenHomepageLink (this, L"hiddenvolprotection"); + } + + void MountOptionsDialog::UpdateDialog () + { + FreezeScope freeze (this); + +#ifdef TC_WINDOWS + FilesystemSizer->Show (false); +#else + FilesystemOptionsSizer->Show (!NoFilesystemCheckBox->IsChecked()); + +# ifdef TC_MACOSX + FilesystemOptionsStaticText->Show (false); + FilesystemOptionsTextCtrl->Show (false); +# endif + + if (!Options.Path || Options.Path->IsEmpty()) + { + MountPointTextCtrlStaticText->Show (false); + MountPointTextCtrl->Show (false); + MountPointButton->Show (false); + } + RemovableCheckBox->Show (false); +#endif + ProtectionSizer->Show (!ReadOnlyCheckBox->IsChecked()); + ProtectionPasswordPanel->Show (!ReadOnlyCheckBox->IsChecked() && ProtectionCheckBox->IsChecked()); + + Fit(); + Layout(); + } +} diff --git a/src/Main/Forms/MountOptionsDialog.h b/src/Main/Forms/MountOptionsDialog.h new file mode 100644 index 00000000..c5ef8097 --- /dev/null +++ b/src/Main/Forms/MountOptionsDialog.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_MountOptionsDialog +#define TC_HEADER_Main_Forms_MountOptionsDialog + +#include "Forms.h" +#include "Main/Main.h" +#include "VolumePasswordPanel.h" + +namespace TrueCrypt +{ + class MountOptionsDialog : public MountOptionsDialogBase + { + public: + MountOptionsDialog (wxWindow* parent, MountOptions &options, const wxString &title = wxEmptyString, bool disableMountOptions = false); + void OnShow (); + + protected: + void OnInitDialog (wxInitDialogEvent& event); + void OnMountPointButtonClick (wxCommandEvent& event); + void OnNoFilesystemCheckBoxClick (wxCommandEvent& event) { UpdateDialog(); } + void OnOKButtonClick (wxCommandEvent& event); + void OnOptionsButtonClick (wxCommandEvent& event); + void OnProtectionCheckBoxClick (wxCommandEvent& event); + void OnProtectionHyperlinkClick (wxHyperlinkEvent& event); + void OnReadOnlyCheckBoxClick (wxCommandEvent& event) { UpdateDialog(); } + void UpdateDialog (); + + MountOptions &Options; + wxString OptionsButtonLabel; + VolumePasswordPanel *PasswordPanel; + VolumePasswordPanel *ProtectionPasswordPanel; + }; +} + +#endif // TC_HEADER_Main_Forms_MountOptionsDialog diff --git a/src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp b/src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp new file mode 100644 index 00000000..ed728254 --- /dev/null +++ b/src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp @@ -0,0 +1,45 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "NewSecurityTokenKeyfileDialog.h" + +namespace TrueCrypt +{ + NewSecurityTokenKeyfileDialog::NewSecurityTokenKeyfileDialog (wxWindow* parent, const wstring &keyfileName) : NewSecurityTokenKeyfileDialogBase (parent) + { + list tokens = SecurityToken::GetAvailableTokens(); + + if (tokens.empty()) + throw_err (LangString ["NO_TOKENS_FOUND"]); + + foreach (const SecurityTokenInfo &token, tokens) + { + wstringstream tokenLabel; + tokenLabel << L"[" << token.SlotId << L"] " << token.Label; + + SecurityTokenChoice->Append (tokenLabel.str(), (void *) token.SlotId); + } + + SecurityTokenChoice->Select (0); + KeyfileNameTextCtrl->SetValue (keyfileName); + + KeyfileNameTextCtrl->SetMinSize (wxSize (Gui->GetCharWidth (KeyfileNameTextCtrl) * 32, -1)); + + Fit(); + Layout(); + Center(); + } + + void NewSecurityTokenKeyfileDialog::OnKeyfileNameChanged (wxCommandEvent& event) + { + StdButtonsOK->Enable (!KeyfileNameTextCtrl->GetValue().empty()); + event.Skip(); + } +} diff --git a/src/Main/Forms/NewSecurityTokenKeyfileDialog.h b/src/Main/Forms/NewSecurityTokenKeyfileDialog.h new file mode 100644 index 00000000..11891dbb --- /dev/null +++ b/src/Main/Forms/NewSecurityTokenKeyfileDialog.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_NewSecurityTokenKeyfileDialog +#define TC_HEADER_Main_Forms_NewSecurityTokenKeyfileDialog + +#include "Forms.h" +#include "Common/SecurityToken.h" + +namespace TrueCrypt +{ + class NewSecurityTokenKeyfileDialog : public NewSecurityTokenKeyfileDialogBase + { + public: + NewSecurityTokenKeyfileDialog (wxWindow* parent, const wstring &keyfileName); + + wstring GetKeyfileName () const { return wstring (KeyfileNameTextCtrl->GetValue()); } + CK_SLOT_ID GetSelectedSlotId () const { return reinterpret_cast (SecurityTokenChoice->GetClientData (SecurityTokenChoice->GetSelection())); } + + protected: + void OnKeyfileNameChanged (wxCommandEvent& event); + }; +} + +#endif // TC_HEADER_Main_Forms_NewSecurityTokenKeyfileDialog diff --git a/src/Main/Forms/PreferencesDialog.cpp b/src/Main/Forms/PreferencesDialog.cpp new file mode 100644 index 00000000..b10a5cdd --- /dev/null +++ b/src/Main/Forms/PreferencesDialog.cpp @@ -0,0 +1,488 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#ifdef TC_WINDOWS +#include +#endif +#include "Common/SecurityToken.h" +#include "Main/Main.h" +#include "Main/Application.h" +#include "Main/GraphicUserInterface.h" +#include "Volume/Cipher.h" +#include "PreferencesDialog.h" + +namespace TrueCrypt +{ + PreferencesDialog::PreferencesDialog (wxWindow* parent) + : PreferencesDialogBase (parent), + LastVirtualKeyPressed (0), + Preferences (Gui->GetPreferences()), + RestoreValidatorBell (false) + { +#define TC_CHECK_BOX_VALIDATOR(NAME) (TC_JOIN(NAME,CheckBox))->SetValidator (wxGenericValidator (&Preferences.NAME)); + +#ifdef TC_MACOSX + PreferencesNotebook->SetMinSize (wxSize (Gui->GetCharWidth (PreferencesNotebook) * 108, -1)); +#endif + // Security + TC_CHECK_BOX_VALIDATOR (DismountOnLogOff); + TC_CHECK_BOX_VALIDATOR (DismountOnPowerSaving); + TC_CHECK_BOX_VALIDATOR (DismountOnScreenSaver); + TC_CHECK_BOX_VALIDATOR (DismountOnInactivity); + DismountOnInactivitySpinCtrl->SetValidator (wxGenericValidator (&Preferences.MaxVolumeIdleTime)); + TC_CHECK_BOX_VALIDATOR (ForceAutoDismount); + PreserveTimestampsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.PreserveTimestamps)); + TC_CHECK_BOX_VALIDATOR (WipeCacheOnAutoDismount); + TC_CHECK_BOX_VALIDATOR (WipeCacheOnClose); + + // Mount options + CachePasswordsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.CachePassword)); + MountReadOnlyCheckBox->SetValue (Preferences.DefaultMountOptions.Protection == VolumeProtection::ReadOnly); + MountRemovableCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.Removable)); + + FilesystemOptionsTextCtrl->SetValue (Preferences.DefaultMountOptions.FilesystemOptions); + + // Keyfiles + TC_CHECK_BOX_VALIDATOR (UseKeyfiles); + + DefaultKeyfilesPanel = new KeyfilesPanel (DefaultKeyfilesPage, make_shared (Preferences.DefaultKeyfiles)); + DefaultKeyfilesSizer->Add (DefaultKeyfilesPanel, 1, wxALL | wxEXPAND); + DefaultKeyfilesSizer->Layout(); + + TC_CHECK_BOX_VALIDATOR (BackgroundTaskEnabled); + TC_CHECK_BOX_VALIDATOR (CloseBackgroundTaskOnNoVolumes); + CloseBackgroundTaskOnNoVolumesCheckBox->Show (!Core->IsInPortableMode()); + TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuDismountItemsEnabled); + TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuMountItemsEnabled); + TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuOpenItemsEnabled); + + // Encryption + AesHwCpuSupportedStaticText->SetLabel ( +#ifdef TC_AES_HW_CPU + (is_aes_hw_cpu_supported() ? LangString["UISTR_YES"] : LangString["UISTR_NO"])); +#else + LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"]); +#endif + NoHardwareCryptoCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.NoHardwareCrypto)); + + // Security tokens + Pkcs11ModulePathTextCtrl->SetValue (wstring (Preferences.SecurityTokenModule)); + TC_CHECK_BOX_VALIDATOR (CloseSecurityTokenSessionsAfterMount); + + // System integration + TC_CHECK_BOX_VALIDATOR (StartOnLogon); + TC_CHECK_BOX_VALIDATOR (MountDevicesOnLogon); + TC_CHECK_BOX_VALIDATOR (MountFavoritesOnLogon); + + TC_CHECK_BOX_VALIDATOR (CloseExplorerWindowsOnDismount); + TC_CHECK_BOX_VALIDATOR (OpenExplorerWindowAfterMount); + + NoKernelCryptoCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.NoKernelCrypto)); + +#ifdef TC_WINDOWS + // Hotkeys + TC_CHECK_BOX_VALIDATOR (BeepAfterHotkeyMountDismount); + TC_CHECK_BOX_VALIDATOR (DisplayMessageAfterHotkeyDismount); +#endif + + TransferDataToWindow(); // Code below relies on TransferDataToWindow() called at this point + +#if defined (TC_WINDOWS) || defined (TC_MACOSX) + FilesystemSizer->Show (false); +#else + // Auto-dismount is not supported on Linux as dismount may require the user to enter admin password + AutoDismountSizer->Show (false); + WipeCacheOnAutoDismountCheckBox->Show (false); +#endif + +#ifndef TC_WINDOWS + LogOnSizer->Show (false); + MountRemovableCheckBox->Show (false); + CloseExplorerWindowsOnDismountCheckBox->Show (false); +#endif + +#ifndef wxHAS_POWER_EVENTS + DismountOnPowerSavingCheckBox->Show (false); +#endif + +#ifdef TC_MACOSX + DismountOnScreenSaverCheckBox->Show (false); + DismountOnLogOffCheckBox->SetLabel (_("TrueCrypt quits")); + OpenExplorerWindowAfterMountCheckBox->SetLabel (_("Open Finder window for successfully mounted volume")); + + MountRemovableCheckBox->Show (false); + FilesystemSizer->Show (false); + LogOnSizer->Show (false); + CloseExplorerWindowsOnDismountCheckBox->Show (false); +#endif + +#ifndef TC_LINUX + KernelServicesSizer->Show (false); +#endif + +#ifdef TC_WINDOWS + // Hotkeys + list colPermilles; + HotkeyListCtrl->InsertColumn (ColumnHotkeyDescription, LangString["ACTION"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (642); + HotkeyListCtrl->InsertColumn (ColumnHotkey, LangString["SHORTCUT"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (358); + + vector fields (HotkeyListCtrl->GetColumnCount()); + + UnregisteredHotkeys = Preferences.Hotkeys; + Hotkey::UnregisterList (Gui->GetMainFrame(), UnregisteredHotkeys); + + foreach (shared_ptr hotkey, Preferences.Hotkeys) + { + fields[ColumnHotkeyDescription] = hotkey->Description; + fields[ColumnHotkey] = hotkey->GetShortcutString(); + Gui->AppendToListCtrl (HotkeyListCtrl, fields, -1, hotkey.get()); + } + + Gui->SetListCtrlHeight (HotkeyListCtrl, 5); + + Layout(); + Fit(); + Gui->SetListCtrlColumnWidths (HotkeyListCtrl, colPermilles); + + RestoreValidatorBell = !wxTextValidator::IsSilent(); + wxTextValidator::SetBellOnError (true); + HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_INCLUDE_CHAR_LIST)); + + UpdateHotkeyButtons(); +#endif + + // Page setup + for (size_t page = 0; page < PreferencesNotebook->GetPageCount(); page++) + { + wxNotebookPage *np = PreferencesNotebook->GetPage (page); + if (np == HotkeysPage) + { +#ifndef TC_WINDOWS + PreferencesNotebook->RemovePage (page--); + continue; +#endif + } + + np->Layout(); + } + + Layout(); + Fit(); + Center(); + + StdButtonsOK->SetDefault(); + +#ifdef TC_WINDOWS + // Hotkey timer + class Timer : public wxTimer + { + public: + Timer (PreferencesDialog *dialog) : Dialog (dialog) { } + + void Notify() + { + Dialog->OnTimer(); + } + + PreferencesDialog *Dialog; + }; + + mTimer.reset (dynamic_cast (new Timer (this))); + mTimer->Start (25); +#endif + } + + PreferencesDialog::~PreferencesDialog () + { + if (RestoreValidatorBell) + wxTextValidator::SetBellOnError (false); + } + + void PreferencesDialog::SelectPage (wxPanel *page) + { + for (size_t pageIndex = 0; pageIndex < PreferencesNotebook->GetPageCount(); pageIndex++) + { + if (PreferencesNotebook->GetPage (pageIndex) == page) + PreferencesNotebook->ChangeSelection (pageIndex); + } + } + + void PreferencesDialog::OnAssignHotkeyButtonClick (wxCommandEvent& event) + { +#ifdef TC_WINDOWS + foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) + { + Hotkey *hotkey = reinterpret_cast (HotkeyListCtrl->GetItemData (item)); + + int mods = 0; + mods |= HotkeyShiftCheckBox->IsChecked() ? wxMOD_SHIFT : 0; + mods |= HotkeyControlCheckBox->IsChecked() ? wxMOD_CONTROL : 0; + mods |= HotkeyAltCheckBox->IsChecked() ? wxMOD_ALT : 0; + mods |= HotkeyWinCheckBox->IsChecked() ? wxMOD_WIN : 0; + + // F1 is help and F12 is reserved for use by the debugger at all times + if (mods == 0 && (LastVirtualKeyPressed == VK_F1 || LastVirtualKeyPressed == VK_F12)) + { + Gui->ShowError ("CANNOT_USE_RESERVED_KEY"); + return; + } + + // Test if the hotkey can be registered + if (!this->RegisterHotKey (hotkey->Id, mods, LastVirtualKeyPressed)) + { + Gui->ShowError (SystemException (SRC_POS)); + return; + } + UnregisterHotKey (hotkey->Id); + + foreach_ref (const Hotkey &h, Preferences.Hotkeys) + { + if (h.Id != hotkey->Id && h.VirtualKeyCode == LastVirtualKeyPressed && h.VirtualKeyModifiers == mods) + { + Gui->ShowError ("SHORTCUT_ALREADY_IN_USE"); + return; + } + } + + hotkey->VirtualKeyCode = LastVirtualKeyPressed; + hotkey->VirtualKeyModifiers = mods; + + vector fields (HotkeyListCtrl->GetColumnCount()); + fields[ColumnHotkeyDescription] = hotkey->Description; + fields[ColumnHotkey] = hotkey->GetShortcutString(); + Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields); + + UpdateHotkeyButtons(); + } +#endif // TC_WINDOWS + } + + void PreferencesDialog::OnBackgroundTaskEnabledCheckBoxClick (wxCommandEvent& event) + { + if (!event.IsChecked()) + BackgroundTaskEnabledCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_BACKGROUND_TASK_DISABLED"], false, true)); + } + + void PreferencesDialog::OnNoHardwareCryptoCheckBoxClick (wxCommandEvent& event) + { + if (event.IsChecked()) + { + if (Gui->AskYesNo (LangString["CONFIRM_SETTING_DEGRADES_PERFORMANCE"], true, true)) + { +#ifdef TC_LINUX + Gui->ShowWarning (_("Please note that this setting takes effect only if use of the kernel cryptographic services is disabled.")); +#endif + } + else + NoHardwareCryptoCheckBox->SetValue (false); + } + + Gui->ShowWarning (_("Please note that any currently mounted volumes need to be remounted before they can use this setting.")); + } + + void PreferencesDialog::OnNoKernelCryptoCheckBoxClick (wxCommandEvent& event) + { + if (event.IsChecked()) + NoKernelCryptoCheckBox->SetValue (Gui->AskYesNo (_("Disabling the use of kernel cryptographic services can degrade performance.\n\nAre you sure?"), false, true)); + } + + void PreferencesDialog::OnClose (wxCloseEvent& event) + { +#ifdef TC_WINDOWS + Hotkey::RegisterList (Gui->GetMainFrame(), UnregisteredHotkeys); +#endif + event.Skip(); + } + + void PreferencesDialog::OnDismountOnPowerSavingCheckBoxClick (wxCommandEvent& event) + { + if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked()) + Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT"); + } + + void PreferencesDialog::OnDismountOnScreenSaverCheckBoxClick (wxCommandEvent& event) + { + if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked()) + Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT"); + } + + void PreferencesDialog::OnForceAutoDismountCheckBoxClick (wxCommandEvent& event) + { + if (!event.IsChecked()) + ForceAutoDismountCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_NO_FORCED_AUTODISMOUNT"], false, true)); + } + + void PreferencesDialog::OnHotkeyListItemDeselected (wxListEvent& event) + { + UpdateHotkeyButtons(); + } + + void PreferencesDialog::OnHotkeyListItemSelected (wxListEvent& event) + { + UpdateHotkeyButtons(); + HotkeyTextCtrl->ChangeValue (LangString ["PRESS_A_KEY_TO_ASSIGN"]); + AssignHotkeyButton->Enable (false); + } + + void PreferencesDialog::OnOKButtonClick (wxCommandEvent& event) + { +#ifdef TC_WINDOWS + HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_NONE)); +#endif + if (!Validate()) + return; + + TransferDataFromWindow(); + + Preferences.DefaultMountOptions.Protection = MountReadOnlyCheckBox->IsChecked() ? VolumeProtection::ReadOnly : VolumeProtection::None; + Preferences.DefaultMountOptions.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); + Preferences.DefaultKeyfiles = *DefaultKeyfilesPanel->GetKeyfiles(); + + bool securityTokenModuleChanged = (Preferences.SecurityTokenModule != wstring (Pkcs11ModulePathTextCtrl->GetValue())); + Preferences.SecurityTokenModule = wstring (Pkcs11ModulePathTextCtrl->GetValue()); + + Gui->SetPreferences (Preferences); + + try + { + if (securityTokenModuleChanged) + { + if (Preferences.SecurityTokenModule.IsEmpty()) + { + if (SecurityToken::IsInitialized()) + SecurityToken::CloseLibrary (); + } + else + { + Gui->InitSecurityTokenLibrary(); + } + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + +#ifdef TC_WINDOWS + // Hotkeys + Hotkey::RegisterList (Gui->GetMainFrame(), Preferences.Hotkeys); +#endif + + EndModal (wxID_OK); + } + + void PreferencesDialog::OnPreserveTimestampsCheckBoxClick (wxCommandEvent& event) + { +#ifdef TC_LINUX + if (!event.IsChecked()) + Gui->ShowInfo (_("Please note that disabling this option may have no effect on volumes mounted using kernel cryptographic services.")); +#endif + } + + void PreferencesDialog::OnRemoveHotkeyButtonClick (wxCommandEvent& event) + { +#ifdef TC_WINDOWS + foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) + { + Hotkey *hotkey = reinterpret_cast (HotkeyListCtrl->GetItemData (item)); + hotkey->VirtualKeyCode = 0; + hotkey->VirtualKeyModifiers = 0; + + vector fields (HotkeyListCtrl->GetColumnCount()); + fields[ColumnHotkeyDescription] = hotkey->Description; + fields[ColumnHotkey] = hotkey->GetShortcutString(); + Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields); + + UpdateHotkeyButtons(); + } +#endif + } + + void PreferencesDialog::OnSelectPkcs11ModuleButtonClick (wxCommandEvent& event) + { + list < pair > extensions; + wxString libExtension; + libExtension = wxDynamicLibrary::CanonicalizeName (L"x"); + +#ifdef TC_MACOSX + extensions.push_back (make_pair (L"dylib", LangString["DLL_FILES"])); +#endif + if (!libExtension.empty()) + { + extensions.push_back (make_pair (libExtension.Mid (libExtension.find (L'.') + 1), LangString["DLL_FILES"])); + extensions.push_back (make_pair (L"*", L"")); + } + + string libDir; + +#ifdef TC_WINDOWS + + char sysDir[TC_MAX_PATH]; + GetSystemDirectoryA (sysDir, sizeof (sysDir)); + libDir = sysDir; + +#elif defined (TC_MACOSX) + libDir = "/usr/local/lib"; +#elif defined (TC_UNIX) + libDir = "/usr/lib"; +#endif + + Gui->ShowInfo ("SELECT_PKCS11_MODULE_HELP"); + + FilePathList files = Gui->SelectFiles (this, LangString["SELECT_PKCS11_MODULE"], false, false, extensions, libDir); + if (!files.empty()) + Pkcs11ModulePathTextCtrl->SetValue (wstring (*files.front())); + } + + void PreferencesDialog::OnTimer () + { +#ifdef TC_WINDOWS + for (UINT vKey = 0; vKey <= 0xFF; vKey++) + { + if (GetAsyncKeyState (vKey) < 0) + { + bool shift = wxGetKeyState (WXK_SHIFT); + bool control = wxGetKeyState (WXK_CONTROL); + bool alt = wxGetKeyState (WXK_ALT); + bool win = wxGetKeyState (WXK_WINDOWS_LEFT) || wxGetKeyState (WXK_WINDOWS_RIGHT); + + if (!Hotkey::GetVirtualKeyCodeString (vKey).empty()) // If the key is allowed and its name has been resolved + { + LastVirtualKeyPressed = vKey; + + HotkeyShiftCheckBox->SetValue (shift); + HotkeyControlCheckBox->SetValue (control); + HotkeyAltCheckBox->SetValue (alt); + HotkeyWinCheckBox->SetValue (win); + + HotkeyTextCtrl->ChangeValue (Hotkey::GetVirtualKeyCodeString (LastVirtualKeyPressed)); + UpdateHotkeyButtons(); + return; + } + } + } +#endif + } + + void PreferencesDialog::UpdateHotkeyButtons() + { + AssignHotkeyButton->Enable (!HotkeyTextCtrl->IsEmpty() && HotkeyListCtrl->GetSelectedItemCount() > 0); + + bool remove = false; + foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl)) + { + if (reinterpret_cast (HotkeyListCtrl->GetItemData (item))->VirtualKeyCode != 0) + remove = true; + } + RemoveHotkeyButton->Enable (remove); + } +} diff --git a/src/Main/Forms/PreferencesDialog.h b/src/Main/Forms/PreferencesDialog.h new file mode 100644 index 00000000..412d7c44 --- /dev/null +++ b/src/Main/Forms/PreferencesDialog.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_PreferencesDialog +#define TC_HEADER_Main_Forms_PreferencesDialog + +#include "Forms.h" +#include "Main/Main.h" +#include "KeyfilesPanel.h" + +namespace TrueCrypt +{ + class PreferencesDialog : public PreferencesDialogBase + { + public: + PreferencesDialog (wxWindow* parent); + ~PreferencesDialog (); + + void SelectPage (wxPanel *page); + + protected: + void OnAssignHotkeyButtonClick (wxCommandEvent& event); + void OnBackgroundTaskEnabledCheckBoxClick (wxCommandEvent& event); + void OnCancelButtonClick (wxCommandEvent& event) { Close(); } + void OnClose (wxCloseEvent& event); + void OnDismountOnPowerSavingCheckBoxClick (wxCommandEvent& event); + void OnDismountOnScreenSaverCheckBoxClick (wxCommandEvent& event); + void OnForceAutoDismountCheckBoxClick (wxCommandEvent& event); + void OnHotkeyListItemDeselected (wxListEvent& event); + void OnHotkeyListItemSelected (wxListEvent& event); + void OnNoHardwareCryptoCheckBoxClick (wxCommandEvent& event); + void OnNoKernelCryptoCheckBoxClick (wxCommandEvent& event); + void OnOKButtonClick (wxCommandEvent& event); + void OnPreserveTimestampsCheckBoxClick (wxCommandEvent& event); + void OnRemoveHotkeyButtonClick (wxCommandEvent& event); + void OnSelectPkcs11ModuleButtonClick (wxCommandEvent& event); + void OnTimer (); + void UpdateHotkeyButtons(); + + enum + { + ColumnHotkeyDescription = 0, + ColumnHotkey + }; + + KeyfilesPanel *DefaultKeyfilesPanel; + int LastVirtualKeyPressed; + auto_ptr mTimer; + UserPreferences Preferences; + bool RestoreValidatorBell; + HotkeyList UnregisteredHotkeys; + }; +} + +#endif // TC_HEADER_Main_Forms_PreferencesDialog diff --git a/src/Main/Forms/ProgressWizardPage.cpp b/src/Main/Forms/ProgressWizardPage.cpp new file mode 100644 index 00000000..113d9872 --- /dev/null +++ b/src/Main/Forms/ProgressWizardPage.cpp @@ -0,0 +1,80 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "ProgressWizardPage.h" + +namespace TrueCrypt +{ + ProgressWizardPage::ProgressWizardPage (wxPanel* parent, bool enableAbort) + : ProgressWizardPageBase (parent), + PreviousGaugeValue (0), + ProgressBarRange (1), + RealProgressBarRange (1) + { +#ifdef TC_MACOSX + ProgressGauge->SetMinSize (wxSize (-1, 12)); // OS X apparently supports only up to 12px thick progress bars +#else + ProgressGauge->SetMinSize (wxSize (-1, Gui->GetCharHeight (this) * 2)); +#endif + + ProgressValue.Set (0); + ProgressGauge->SetValue (0); + + AbortButton->Show (enableAbort); + + class Timer : public wxTimer + { + public: + Timer (ProgressWizardPage *page) : Page (page) { } + + void Notify() + { + Page->OnTimer(); + } + + ProgressWizardPage *Page; + }; + + mTimer.reset (dynamic_cast (new Timer (this))); + mTimer->Start (30); + } + + void ProgressWizardPage::OnAbortButtonClick (wxCommandEvent& event) + { + AbortEvent.Raise(); + } + + void ProgressWizardPage::OnTimer () + { + uint64 value = ProgressValue.Get(); + int gaugeValue = static_cast (value * RealProgressBarRange / ProgressBarRange); + + if (value == ProgressBarRange) + gaugeValue = RealProgressBarRange; // Prevent round-off error + + if (gaugeValue != PreviousGaugeValue) + { + ProgressGauge->SetValue (gaugeValue); + PreviousGaugeValue = gaugeValue; + } + } + + void ProgressWizardPage::SetMaxStaticTextWidth (int width) + { + InfoStaticText->Wrap (width); + } + + void ProgressWizardPage::SetProgressRange (uint64 progressBarRange) + { + ProgressBarRange = progressBarRange; + RealProgressBarRange = ProgressGauge->GetSize().GetWidth(); + ProgressGauge->SetRange (RealProgressBarRange); + } +} diff --git a/src/Main/Forms/ProgressWizardPage.h b/src/Main/Forms/ProgressWizardPage.h new file mode 100644 index 00000000..541edd66 --- /dev/null +++ b/src/Main/Forms/ProgressWizardPage.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_ProgressWizardPage +#define TC_HEADER_Main_Forms_ProgressWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class ProgressWizardPage : public ProgressWizardPageBase + { + public: + ProgressWizardPage (wxPanel* parent, bool enableAbort = false); + ~ProgressWizardPage () { } + + void EnableAbort (bool enable = true) { AbortButton->Enable (enable); } + bool IsValid () { return true; } + void SetMaxStaticTextWidth (int width); + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + void SetProgressRange (uint64 progressBarRange); + + Event AbortEvent; + SharedVal ProgressValue; + + protected: + void OnAbortButtonClick (wxCommandEvent& event); + void OnTimer (); + + auto_ptr mTimer; + int PreviousGaugeValue; + uint64 ProgressBarRange; + int RealProgressBarRange; + }; +} + +#endif // TC_HEADER_Main_Forms_ProgressWizardPage diff --git a/src/Main/Forms/RandomPoolEnrichmentDialog.cpp b/src/Main/Forms/RandomPoolEnrichmentDialog.cpp new file mode 100644 index 00000000..44e45db8 --- /dev/null +++ b/src/Main/Forms/RandomPoolEnrichmentDialog.cpp @@ -0,0 +1,93 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Volume/Hash.h" +#include "RandomPoolEnrichmentDialog.h" + +namespace TrueCrypt +{ + RandomPoolEnrichmentDialog::RandomPoolEnrichmentDialog (wxWindow* parent) : RandomPoolEnrichmentDialogBase (parent) + { + RandomNumberGenerator::Start(); + + Hashes = Hash::GetAvailableAlgorithms(); + foreach (shared_ptr hash, Hashes) + { + if (!hash->IsDeprecated()) + { + HashChoice->Append (hash->GetName(), hash.get()); + + if (typeid (*hash) == typeid (*RandomNumberGenerator::GetHash())) + HashChoice->Select (HashChoice->GetCount() - 1); + } + } + + ShowBytes (RandomPoolStaticText, RandomNumberGenerator::PeekPool().GetRange (0, 24)); + MouseStaticText->Wrap (Gui->GetCharWidth (MouseStaticText) * 70); + + MainSizer->SetMinSize (wxSize (-1, Gui->GetCharHeight (this) * 24)); + + Layout(); + Fit(); + Center(); + + foreach (wxWindow *c, this->GetChildren()) + c->Connect (wxEVT_MOTION, wxMouseEventHandler (RandomPoolEnrichmentDialog::OnMouseMotion), nullptr, this); + } + + RandomPoolEnrichmentDialog::~RandomPoolEnrichmentDialog () + { + } + + void RandomPoolEnrichmentDialog::OnHashSelected (wxCommandEvent& event) + { + RandomNumberGenerator::SetHash (Gui->GetSelectedData (HashChoice)->GetNew()); + } + + void RandomPoolEnrichmentDialog::OnMouseMotion (wxMouseEvent& event) + { + event.Skip(); + + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&event), sizeof (event))); + + long coord = event.GetX(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + coord = event.GetY(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + + if (ShowRandomPoolCheckBox->IsChecked()) + ShowBytes (RandomPoolStaticText, RandomNumberGenerator::PeekPool().GetRange (0, 24)); + } + + void RandomPoolEnrichmentDialog::OnShowRandomPoolCheckBoxClicked (wxCommandEvent& event) + { + if (!event.IsChecked()) + RandomPoolStaticText->SetLabel (L""); + } + + void RandomPoolEnrichmentDialog::ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer) + { + wxString str; + + for (size_t i = 0; i < buffer.Size(); ++i) + { + str += wxString::Format (L"%02X", buffer[i]); + } + + str += L".."; + + textCtrl->SetLabel (str.c_str()); + + for (size_t i = 0; i < str.size(); ++i) + { + str[i] = L'X'; + } + } +} diff --git a/src/Main/Forms/RandomPoolEnrichmentDialog.h b/src/Main/Forms/RandomPoolEnrichmentDialog.h new file mode 100644 index 00000000..8a951bcb --- /dev/null +++ b/src/Main/Forms/RandomPoolEnrichmentDialog.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_RandomPoolEnrichmentDialog +#define TC_HEADER_Main_Forms_RandomPoolEnrichmentDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class RandomPoolEnrichmentDialog : public RandomPoolEnrichmentDialogBase + { + public: + RandomPoolEnrichmentDialog (wxWindow* parent); + ~RandomPoolEnrichmentDialog (); + + protected: + void OnHashSelected (wxCommandEvent& event); + void OnMouseMotion (wxMouseEvent& event); + void OnShowRandomPoolCheckBoxClicked (wxCommandEvent& event); + void ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer); + + HashList Hashes; + }; +} + +#endif // TC_HEADER_Main_Forms_RandomPoolEnrichmentDialog diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp new file mode 100644 index 00000000..5978b0b1 --- /dev/null +++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp @@ -0,0 +1,197 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Common/SecurityToken.h" +#include "NewSecurityTokenKeyfileDialog.h" +#include "SecurityTokenKeyfilesDialog.h" + +namespace TrueCrypt +{ + SecurityTokenKeyfilesDialog::SecurityTokenKeyfilesDialog (wxWindow* parent, bool selectionMode) + : SecurityTokenKeyfilesDialogBase (parent) + { + if (selectionMode) + SetTitle (LangString["SELECT_TOKEN_KEYFILES"]); + + list colPermilles; + + SecurityTokenKeyfileListCtrl->InsertColumn (ColumnSecurityTokenSlotId, LangString["TOKEN_SLOT_ID"], wxLIST_FORMAT_CENTER, 1); + colPermilles.push_back (102); + SecurityTokenKeyfileListCtrl->InsertColumn (ColumnSecurityTokenLabel, LangString["TOKEN_NAME"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (368); + SecurityTokenKeyfileListCtrl->InsertColumn (ColumnSecurityTokenKeyfileLabel, LangString["TOKEN_DATA_OBJECT_LABEL"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (529); + + FillSecurityTokenKeyfileListCtrl(); + + Gui->SetListCtrlWidth (SecurityTokenKeyfileListCtrl, 65); + Gui->SetListCtrlHeight (SecurityTokenKeyfileListCtrl, 16); + Gui->SetListCtrlColumnWidths (SecurityTokenKeyfileListCtrl, colPermilles); + + Fit(); + Layout(); + Center(); + + DeleteButton->Disable(); + ExportButton->Disable(); + OKButton->Disable(); + OKButton->SetDefault(); + } + + void SecurityTokenKeyfilesDialog::FillSecurityTokenKeyfileListCtrl () + { + wxBusyCursor busy; + + SecurityTokenKeyfileListCtrl->DeleteAllItems(); + SecurityTokenKeyfileList = SecurityToken::GetAvailableKeyfiles(); + + size_t i = 0; + foreach (const SecurityTokenKeyfile &key, SecurityTokenKeyfileList) + { + vector fields (SecurityTokenKeyfileListCtrl->GetColumnCount()); + + fields[ColumnSecurityTokenSlotId] = StringConverter::ToWide ((uint64) key.SlotId); + fields[ColumnSecurityTokenLabel] = key.Token.Label; + fields[ColumnSecurityTokenKeyfileLabel] = key.Id; + + Gui->AppendToListCtrl (SecurityTokenKeyfileListCtrl, fields, 0, &SecurityTokenKeyfileList[i++]); + } + } + + void SecurityTokenKeyfilesDialog::OnDeleteButtonClick (wxCommandEvent& event) + { + try + { + if (!Gui->AskYesNo (LangString["CONFIRM_SEL_FILES_DELETE"])) + return; + + wxBusyCursor busy; + + foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl)) + { + SecurityToken::DeleteKeyfile (*reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item))); + } + + FillSecurityTokenKeyfileListCtrl(); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void SecurityTokenKeyfilesDialog::OnExportButtonClick (wxCommandEvent& event) + { + try + { + foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl)) + { + SecurityTokenKeyfile *keyfile = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item)); + + FilePathList files = Gui->SelectFiles (this, wxEmptyString, true); + + if (!files.empty()) + { + wxBusyCursor busy; + + vector keyfileData; + SecurityToken::GetKeyfileData (*keyfile, keyfileData); + + BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); + finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); + + File keyfile; + keyfile.Open (*files.front(), File::CreateWrite); + keyfile.Write (keyfileDataBuf); + } + else + break; + + Gui->ShowInfo ("KEYFILE_EXPORTED"); + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void SecurityTokenKeyfilesDialog::OnImportButtonClick (wxCommandEvent& event) + { + try + { + FilePathList keyfilePaths = Gui->SelectFiles (this, LangString["SELECT_KEYFILES"], false); + + if (keyfilePaths.empty()) + return; + + FilePath keyfilePath = *keyfilePaths.front(); + + File keyfile; + keyfile.Open (keyfilePath, File::OpenRead, File::ShareReadWrite, File::PreserveTimestamps); + + if (keyfile.Length() > 0) + { + vector keyfileData (keyfile.Length()); + BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); + + keyfile.ReadCompleteBuffer (keyfileDataBuf); + finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); + + NewSecurityTokenKeyfileDialog newKeyfileDialog (this, keyfilePath.ToBaseName()); + + if (newKeyfileDialog.ShowModal() == wxID_OK) + { + wxBusyCursor busy; + SecurityToken::CreateKeyfile (newKeyfileDialog.GetSelectedSlotId(), keyfileData, StringConverter::ToSingle (newKeyfileDialog.GetKeyfileName())); + + FillSecurityTokenKeyfileListCtrl(); + } + } + else + throw InsufficientData (SRC_POS, keyfilePath); + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void SecurityTokenKeyfilesDialog::OnListItemDeselected (wxListEvent& event) + { + if (SecurityTokenKeyfileListCtrl->GetSelectedItemCount() == 0) + { + DeleteButton->Disable(); + ExportButton->Disable(); + OKButton->Disable(); + } + } + + void SecurityTokenKeyfilesDialog::OnListItemSelected (wxListEvent& event) + { + if (event.GetItem().GetData() != (wxUIntPtr) nullptr) + { + DeleteButton->Enable(); + ExportButton->Enable(); + OKButton->Enable(); + } + } + + void SecurityTokenKeyfilesDialog::OnOKButtonClick () + { + foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl)) + { + SecurityTokenKeyfile *key = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item)); + SelectedSecurityTokenKeyfilePaths.push_back (*key); + } + + EndModal (wxID_OK); + } +} diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.h b/src/Main/Forms/SecurityTokenKeyfilesDialog.h new file mode 100644 index 00000000..2fd78349 --- /dev/null +++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog +#define TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog + +#include "Forms.h" +#include "Common/SecurityToken.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class SecurityTokenKeyfilesDialog : public SecurityTokenKeyfilesDialogBase + { + public: + SecurityTokenKeyfilesDialog (wxWindow* parent, bool selectionMode = true); + list GetSelectedSecurityTokenKeyfilePaths() const { return SelectedSecurityTokenKeyfilePaths; } + + protected: + enum + { + ColumnSecurityTokenSlotId = 0, + ColumnSecurityTokenLabel, + ColumnSecurityTokenKeyfileLabel, + }; + + void FillSecurityTokenKeyfileListCtrl (); + void OnDeleteButtonClick (wxCommandEvent& event); + void OnExportButtonClick (wxCommandEvent& event); + void OnImportButtonClick (wxCommandEvent& event); + void OnListItemActivated (wxListEvent& event) { OnOKButtonClick(); } + void OnListItemDeselected (wxListEvent& event); + void OnListItemSelected (wxListEvent& event); + void OnOKButtonClick (); + void OnOKButtonClick (wxCommandEvent& event) { OnOKButtonClick(); } + + vector SecurityTokenKeyfileList; + list SelectedSecurityTokenKeyfilePaths; + }; +} + +#endif // TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog diff --git a/src/Main/Forms/SelectDirectoryWizardPage.cpp b/src/Main/Forms/SelectDirectoryWizardPage.cpp new file mode 100644 index 00000000..a6a3ab02 --- /dev/null +++ b/src/Main/Forms/SelectDirectoryWizardPage.cpp @@ -0,0 +1,32 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "SelectDirectoryWizardPage.h" + +namespace TrueCrypt +{ + bool SelectDirectoryWizardPage::IsValid () + { + if (!DirectoryTextCtrl->IsEmpty()) + { + return FilesystemPath (DirectoryTextCtrl->GetValue()).IsDirectory(); + } + + return false; + } + + void SelectDirectoryWizardPage::OnBrowseButtonClick (wxCommandEvent& event) + { + DirectoryPath dir = Gui->SelectDirectory (this); + + if (!dir.IsEmpty()) + DirectoryTextCtrl->SetValue (wstring (dir)); + } +} diff --git a/src/Main/Forms/SelectDirectoryWizardPage.h b/src/Main/Forms/SelectDirectoryWizardPage.h new file mode 100644 index 00000000..52335fc5 --- /dev/null +++ b/src/Main/Forms/SelectDirectoryWizardPage.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_SelectDirectoryWizardPage +#define TC_HEADER_Main_Forms_SelectDirectoryWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class SelectDirectoryWizardPage : public SelectDirectoryWizardPageBase + { + public: + SelectDirectoryWizardPage (wxPanel* parent) : SelectDirectoryWizardPageBase (parent) { } + + DirectoryPath GetDirectory () const { return DirectoryPath (DirectoryTextCtrl->GetValue()); } + bool IsValid (); + void SetDirectory (const DirectoryPath &path) { DirectoryTextCtrl->SetValue (wstring (path)); } + void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + + protected: + void OnBrowseButtonClick (wxCommandEvent& event); + void OnDirectoryTextChanged (wxCommandEvent& event) { PageUpdatedEvent.Raise(); } + }; +} + +#endif // TC_HEADER_Main_Forms_SelectDirectoryWizardPage diff --git a/src/Main/Forms/SingleChoiceWizardPage.h b/src/Main/Forms/SingleChoiceWizardPage.h new file mode 100644 index 00000000..43536eca --- /dev/null +++ b/src/Main/Forms/SingleChoiceWizardPage.h @@ -0,0 +1,116 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_SingleChoiceWizardPage +#define TC_HEADER_Main_Forms_SingleChoiceWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + template + class SingleChoiceWizardPage : public SingleChoiceWizardPageBase + { + public: + SingleChoiceWizardPage (wxPanel* parent, const wxString &groupBoxText = wxEmptyString, bool choiceTextBold = false) + : SingleChoiceWizardPageBase (parent), + ChoiceTextBold (choiceTextBold) + { + if (!groupBoxText.empty()) + { + OuterChoicesSizer->Remove (ChoicesSizer); + ChoicesSizer = new wxStaticBoxSizer (wxVERTICAL, this, groupBoxText); + OuterChoicesSizer->Add (ChoicesSizer, 0, wxEXPAND, 5); + } + } + + void AddChoice (ChoiceType choice, const wxString &choiceText, const wxString &infoText = wxEmptyString, const wchar_t *infoLinkId = nullptr, const wxString &infoLinkText = wxEmptyString) + { + assert (RadioButtonMap.find (choice) == RadioButtonMap.end()); + + wxRadioButton *radioButton = new wxRadioButton (this, wxID_ANY, choiceText); + if (RadioButtonMap.empty()) + radioButton->SetValue (true); + + RadioButtonMap[choice] = radioButton; + + if (ChoiceTextBold) + { + wxFont buttonFont = radioButton->GetFont(); + buttonFont.SetWeight (wxFONTWEIGHT_BOLD); + radioButton->SetFont (buttonFont); + } + + ChoicesSizer->Add (radioButton, 0, wxALL, 5); + + wxBoxSizer *infoSizer = new wxBoxSizer (wxVERTICAL); + + wxStaticText *infoStaticText = new wxStaticText (this, wxID_ANY, infoText, wxDefaultPosition, wxDefaultSize, 0); + ChoiceInfoTexts.push_back (infoStaticText); + + infoSizer->Add (infoStaticText, 0, wxALL, 5); + ChoicesSizer->Add (infoSizer, 0, wxEXPAND | wxLEFT, Gui->GetCharWidth (this) * 3); + + if (infoLinkId) + { + wxHyperlinkCtrl *hyperlink = Gui->CreateHyperlink (this, infoLinkId, infoLinkText); + infoSizer->Add (hyperlink, 0, wxALL, 5); + hyperlink->Connect (wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler (SingleChoiceWizardPage::OnChoiceHyperlinkClick), nullptr, this); + } + + ChoicesSizer->Add (1, Gui->GetCharHeight (this) * 1, 0, wxEXPAND, 5); + } + + ChoiceType GetSelection () const + { + typedef pair MapPair; + foreach (MapPair p, RadioButtonMap) + { + if (p.second->GetValue()) + return p.first; + } + + throw NoItemSelected (SRC_POS); + } + + bool IsValid () + { + return true; + } + + void SetMaxStaticTextWidth (int width) + { + InfoStaticText->Wrap (width); + + foreach (wxStaticText *infoText, ChoiceInfoTexts) + infoText->Wrap (width - Gui->GetCharWidth (this) * 3); + } + + void SetPageText (const wxString &text) + { + InfoStaticText->SetLabel (text); + } + + void SetSelection (ChoiceType choice) + { + RadioButtonMap[choice]->SetValue (true); + } + + protected: + void OnChoiceHyperlinkClick (wxHyperlinkEvent &event) + { + Gui->OpenHomepageLink (this, event.GetURL()); + } + + bool ChoiceTextBold; + list ChoiceInfoTexts; + map RadioButtonMap; + }; +} + +#endif // TC_HEADER_Main_Forms_SingleChoiceWizardPage diff --git a/src/Main/Forms/TrueCrypt.fbp b/src/Main/Forms/TrueCrypt.fbp new file mode 100644 index 00000000..9d8fb6f9 --- /dev/null +++ b/src/Main/Forms/TrueCrypt.fbp @@ -0,0 +1,17436 @@ + + + + + + C++ + 1 + UTF-8 + connect + Forms + 1000 + none + 1 + TrueCrypt + "TrueCrypt" + . + #include "System.h" + 1 + 1 + 0 + + + wxBOTH + + 1 + + + + 0 + wxID_ANY + + -1,496 + MainFrameBase + + -1,496 + wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU + + TrueCrypt + + + + wxTAB_TRAVERSAL + 1 + OnActivate + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + MainMenuBar + + + MainMenuBar + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &Volumes + VolumesMenu + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Create New Volume... + CreateNewVolumeMenuItem + none + + + OnCreateVolumeButtonClick + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Mount Volume + MountVolumeMenuItem + protected + + + OnMountVolumeMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Auto-Mount All Device-Hosted Volumes + AutoMountDevicesMenuItem + none + + + OnMountAllDevicesButtonClick + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Dismount Volume + DismountVolumeMenuItem + protected + + + OnDismountVolumeMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Dismount All Mounted Volumes + DismountAllMenuItem + protected + + + OnDismountAllButtonClick + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Change Volume Password... + ChangePasswordMenuItem + none + + + OnChangePasswordMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Change Header Key Derivation Algorithm... + ChangePkcs5PrfMenuItem + none + + + OnChangePkcs5PrfMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Add/Remove Keyfiles to/from Volume... + ChangeKeyfilesMenuItem + none + + + OnChangeKeyfilesMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Remove All Keyfiles from Volume... + RemoveKeyfilesMenuItem + none + + + OnRemoveKeyfilesMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Volume Properties... + VolumePropertiesMenuItem + protected + + + OnVolumePropertiesButtonClick + + + + + &Favorites + FavoritesMenu + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Add Selected Volume to Favorites... + AddToFavoritesMenuItem + protected + + + OnAddToFavoritesMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Add All Mounted Volumes to Favorites... + AddAllMountedToFavoritesMenuItem + protected + + + OnAddAllMountedToFavoritesMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Organize Favorite Volumes... + OrganizeFavoritesMenuItem + none + + + OnOrganizeFavoritesMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Mount Favorite Volumes + MountAllFavoritesMenuItem + none + + + OnMountAllFavoritesMenuItemSelected + + + + none + + + + T&ools + ToolsMenu + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Benchmark... + BenchmarkMenuItem + none + + + OnBenchmarkMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Test Vectors... + EncryptionTestMenuItem + none + + + OnEncryptionTestMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Volume Creation Wizard + VolumeCreationWizardMenuItem + none + + + OnCreateVolumeButtonClick + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Backup Volume Header... + BackupVolumeHeadersMenuItem + protected + + + OnBackupVolumeHeadersMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Restore Volume Header... + RestoreVolumeHeaderMenuItem + protected + + + OnRestoreVolumeHeaderMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Keyfile Generator + CreateKeyfileMenuItem + none + + + OnCreateKeyfileMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Manage Security Token Keyfiles... + ManageSecurityTokenKeyfilesMenuItem + none + + + OnManageSecurityTokenKeyfilesMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Close All Security Token Sessions + CloseAllSecurityTokenSessionsMenuItem + none + + + OnCloseAllSecurityTokenSessionsMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Wipe Cached Passwords + WipeCachedPasswordsMenuItem + protected + + + OnWipeCacheButtonClick + + + + + Settin&gs + SettingsMenu + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Hotkeys... + HotkeysMenuItem + protected + + + OnHotkeysMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Default Keyfiles... + DefaultKeyfilesMenuItem + none + + + OnDefaultKeyfilesMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Security Tokens... + SecurityTokenPreferencesMenuItem + none + + + OnSecurityTokenPreferencesMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_PREFERENCES + wxITEM_NORMAL + &Preferences... + PreferencesMenuItem + protected + + + OnPreferencesMenuItemSelected + + + + + &Help + HelpMenu + protected + + + 0 + 1 + + wxID_HELP + wxITEM_NORMAL + User's Guide + UserGuideMenuItem + none + + + OnUserGuideMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Online Help + OnlineHelpMenuItem + none + + + OnOnlineHelpMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Beginner's Tutorial + BeginnersTutorialMenuItem + none + + + OnBeginnersTutorialMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Frequently Asked Questions + FaqMenuItem + none + + + OnFaqMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + TrueCrypt Website + WebsiteMenuItem + none + + + OnWebsiteMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Downloads + DownloadsMenuItem + none + + + OnDownloadsMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + News + NewsMenuItem + none + + + OnNewsMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Version History + VersionHistoryMenuItem + none + + + OnVersionHistoryMenuItemSelected + + + + none + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Contact + ContactMenuItem + none + + + OnContactMenuItemSelected + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + Legal Notices + LegalNoticesMenuItem + none + + + OnLegalNoticesMenuItemSelected + + + + + 0 + 1 + + wxID_ABOUT + wxITEM_NORMAL + About + AboutMenuItem + none + + + OnAboutMenuItemSelected + + + + + + + bSizer1 + wxVERTICAL + none + + 0 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + MainPanel + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer2 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer48 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + wxID_ANY + + + sbSizer1 + wxVERTICAL + none + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + SlotListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + OnListItemDeselected + + + OnListItemRightClick + OnListItemSelected + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + wxID_ANY + + + LowStaticBoxSizer + wxVERTICAL + protected + + + 2 + wxEXPAND|wxTOP + 0 + + + HigherButtonSizer + wxVERTICAL + protected + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 3 + 0 + + gSizer1 + none + 1 + 0 + + 5 + + 0 + + 138,34 + bSizer17 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + &Create Volume + + -1,-1 + CreateVolumeButton + protected + + + + + + + + + OnCreateVolumeButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + 138,34 + bSizer18 + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + &Volume Properties... + + -1,-1 + VolumePropertiesButton + protected + + + + + + + + + OnVolumePropertiesButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + 138,34 + bSizer19 + wxVERTICAL + none + + 5 + wxALL|wxALIGN_RIGHT|wxEXPAND + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + &Wipe Cache + + -1,-1 + WipeCacheButton + protected + + + + + + + + + OnWipeCacheButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + wxID_ANY + Volume + + VolumeStaticBoxSizer + wxVERTICAL + protected + + + 4 + wxEXPAND|wxALL + 1 + + + wxBOTH + 1 + 0 + 0 + + VolumeGridBagSizer + wxFLEX_GROWMODE_SPECIFIED + protected + 0 + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + 2 + + + + + 1 + + + 0 + wxID_ANY + + 42,52 + LogoBitmap + protected + + + + + + + wxSUNKEN_BORDER + + + + + + + + + OnLogoBitmapClick + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxEXPAND|wxALL + 0 + 1 + + + + + 1 + + + 0 + wxID_ANY + + + VolumePathComboBox + protected + + + wxCB_DROPDOWN + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 3 + wxEXPAND + 0 + 1 + + 138,34 + bSizer191 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Select &File... + + -1,-1 + SelectFileButton + protected + + + + + + + + + OnSelectFileButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 1 + wxBOTTOM|wxRIGHT|wxLEFT + 1 + 1 + + + 0 + + 1 + + + 0 + wxID_ANY + &Never save history + + + NoHistoryCheckBox + protected + + + + + + + + + + OnNoHistoryCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 2 + wxALIGN_RIGHT + 1 + 1 + + 138,34 + bSizer20 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Volume &Tools... + + -1,-1 + VolumeToolsButton + protected + + + + + + + + + OnVolumeToolsButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 3 + wxEXPAND + 1 + 1 + + 138,34 + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Select D&evice... + + -1,-1 + SelectDeviceButton + protected + + + + + + + + + OnSelectDeviceButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 0 + + 4 + 0 + + gSizer2 + none + 1 + 0 + + 0 + wxEXPAND + 1 + + wxID_ANY + + 139,-1 + sbSizer4 + wxVERTICAL + none + + + 2 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP + 1 + + + + 1 + 1 + + + 0 + wxID_ANY + &Mount + + -1,32 + VolumeButton + protected + + + + + + + + + OnVolumeButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND + 1 + + wxID_ANY + + -1,-1 + sbSizer41 + wxVERTICAL + none + + + 2 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + &Auto-Mount Devices + + -1,32 + MountAllDevicesButton + protected + + + + + + + + + OnMountAllDevicesButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND + 1 + + wxID_ANY + + -1,-1 + sbSizer42 + wxVERTICAL + none + + + 2 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Di&smount All + + -1,32 + DismountAllButton + protected + + + + + + + + + OnDismountAllButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND + 1 + + wxID_ANY + + -1,-1 + sbSizer43 + wxVERTICAL + none + + + 2 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + E&xit + + -1,32 + ExitButton + protected + + + + + + + + + OnExitButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + WizardFrameBase + + -1,-1 + wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU + + + + + + wxTAB_TRAVERSAL + 1 + OnActivate + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer92 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + MainPanel + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + OnMouseMotion + + + + + + + + + + + + bSizer63 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + wxID_ANY + + + sbSizer27 + wxHORIZONTAL + none + + + 5 + wxALL|wxEXPAND + 0 + + + + + 1 + + + 0 + wxID_ANY + + + WizardBitmap + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + + bSizer66 + wxVERTICAL + none + + 5 + wxLEFT + 0 + + + bSizer126 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + + Times New Roman,90,90,16,70,0 + 0 + wxID_ANY + Page Title + + + PageTitleStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 1 + + + PageSizer + wxVERTICAL + protected + + + + + + + + 5 + wxEXPAND|wxALIGN_RIGHT|wxALL + 0 + + + bSizer70 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_HELP + &Help + + + HelpButton + protected + + + + + + + + + OnHelpButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT|wxALIGN_RIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + < &Prev + + + PreviousButton + protected + + + + + + + + + OnPreviousButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + 1 + + + 0 + wxID_ANY + &Next > + + + NextButton + protected + + + + + + + + wxWANTS_CHARS + OnNextButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT|wxALIGN_RIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + OnCancelButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + AboutDialogBase + + + wxDEFAULT_DIALOG_STYLE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer116 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer117 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + -1,78 + bSizer120 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 10,108,206 + + 1 + + + 0 + wxID_ANY + + + m_panel14 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer121 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + 0 + protected + 0 + + + + 8 + wxEXPAND|wxLEFT + 0 + + + bSizer122 + wxVERTICAL + none + + 10 + wxALL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + LogoBitmap + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15 + wxALL|wxEXPAND + 1 + + + bSizer118 + wxVERTICAL + none + + 5 + wxEXPAND|wxLEFT + 1 + + + bSizer123 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + VersionStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + CopyrightStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxSYS_COLOUR_WINDOWTEXT + wxID_ANY + + + + WebsiteHyperlink + wxSYS_COLOUR_WINDOWTEXT + protected + + + wxHL_DEFAULT_STYLE + + + . + wxSYS_COLOUR_WINDOWTEXT + + + + + + + OnWebsiteHyperlinkClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline3 + protected + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + CreditsTextCtrl + protected + + + wxTE_MULTILINE|wxTE_READONLY + + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP + 0 + + 0 + protected + 0 + + + + 3 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline4 + protected + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline5 + protected + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + bSizer119 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALL + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT + 0 + + 0 + protected + 0 + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + BenchmarkDialogBase + + + wxDEFAULT_DIALOG_STYLE + + TrueCrypt - Encryption Algorithm Benchmark + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer153 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer154 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer155 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Buffer Size: + + + m_staticText54 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + BufferSizeChoice + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline6 + none + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer156 + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + BenchmarkListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + RightSizer + wxVERTICAL + protected + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + 1 + + + 0 + wxID_OK + Benchmark + + + BenchmarkButton + protected + + + + + + + + + OnBenchmarkButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Close + + + CancelButton + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + + BenchmarkNoteStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + ChangePasswordDialogBase + + + wxDEFAULT_DIALOG_STYLE + + + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer30 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer31 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer32 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + wxID_ANY + Current + + CurrentSizer + wxVERTICAL + protected + + + 5 + wxALIGN_RIGHT + 0 + + + CurrentPasswordPanelSizer + wxVERTICAL + protected + + + + + + 5 + wxTOP|wxEXPAND + 0 + + wxID_ANY + New + + NewSizer + wxVERTICAL + protected + + + 5 + wxALIGN_RIGHT + 0 + + + NewPasswordPanelSizer + wxVERTICAL + protected + + + + + + + + 5 + + 0 + + + bSizer33 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + protected + + + + + + + + + OnOKButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxBOTH + + 1 + + + + 0 + wxID_ANY + + -1,-1 + DeviceSelectionDialogBase + + -1,-1 + wxDEFAULT_DIALOG_STYLE + + Select a Partition or Device + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer3 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer4 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + DeviceListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + OnListItemDeselected + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + StdButtons + protected + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + EncryptionTestDialogBase + + + wxDEFAULT_DIALOG_STYLE + + TrueCrypt - Test Vectors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer132 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer133 + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer134 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Encryption algorithm: + + + m_staticText41 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + EncryptionAlgorithmChoice + protected + + 0 + + + + + + + + OnEncryptionAlgorithmSelected + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 1 + + 1 + + + 0 + wxID_ANY + XTS mode + + + XtsModeCheckBox + protected + + + + + + + + + + OnXtsModeCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Key (hexadecimal) + + sbSizer38 + wxVERTICAL + none + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + Courier,90,90,-1,70,0 + 0 + wxID_ANY + + 0 + + KeyTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer135 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Key size: + + + m_staticText43 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + KeySizeStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + XTS mode + + sbSizer39 + wxVERTICAL + none + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Secondary key (hexadecimal) + + + m_staticText45 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + + 1 + + Courier,90,90,-1,70,0 + 0 + wxID_ANY + + 0 + + SecondaryKeyTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Data unit number (64-bit, data unit size is 512 bytes) + + + m_staticText46 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + DataUnitNumberTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Block number: + + + m_staticText47 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + BlockNumberTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Plaintext (hexadecimal) + + sbSizer40 + wxVERTICAL + none + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + Courier,90,90,-1,70,0 + 0 + wxID_ANY + + 0 + + PlainTextTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Ciphertext (hexadecimal) + + sbSizer41 + wxVERTICAL + none + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + Courier,90,90,-1,70,0 + 0 + wxID_ANY + + 0 + + CipherTextTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer136 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Encrypt + + + EncryptButton + protected + + + + + + + + + OnEncryptButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Decrypt + + + DecryptButton + protected + + + + + + + + + OnDecryptButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Auto-Test All + + + AutoTestAllButton + protected + + + + + + + + + OnAutoTestAllButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Reset + + + ResetButton + protected + + + + + + + + + OnResetButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Close + + + CloseButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + FavoriteVolumesDialogBase + + + wxDEFAULT_DIALOG_STYLE + + Favorite Volumes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer57 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer60 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bSizer58 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + FavoritesListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemDeselected + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 4 + 0 + + gSizer5 + none + 1 + 0 + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Move &Up + + + MoveUpButton + protected + + + + + + + + + OnMoveUpButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Move &Down + + + MoveDownButton + protected + + + + + + + + + OnMoveDownButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Remove + + + RemoveButton + protected + + + + + + + + + OnRemoveButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Remove &All + + + RemoveAllButton + protected + + + + + + + + + OnRemoveAllButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 5 + wxBOTH + 2 + + 0 + + fgSizer4 + wxFLEX_GROWMODE_SPECIFIED + none + 1 + 0 + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer59 + wxVERTICAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + protected + + + + + + + + + OnOKButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + KeyfilesDialogBase + + + wxDEFAULT_DIALOG_STYLE + + Select Keyfiles + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer26 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 1 + + + UpperSizer + wxHORIZONTAL + protected + + 5 + wxEXPAND + 1 + + + PanelSizer + wxVERTICAL + protected + + + + 5 + wxEXPAND + 0 + + + bSizer22 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + WarningStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + bSizer23 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + KeyfilesNoteSizer + wxVERTICAL + protected + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline1 + none + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + + KeyfilesNoteStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline2 + none + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + 0 + + 0 + + fgSizer2 + wxFLEX_GROWMODE_SPECIFIED + none + 1 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxSYS_COLOUR_WINDOWTEXT + wxID_ANY + More information on keyfiles + + + KeyfilesHyperlink + wxSYS_COLOUR_WINDOWTEXT + protected + + + wxHL_DEFAULT_STYLE + + + + wxSYS_COLOUR_WINDOWTEXT + + + + + + + OnKeyfilesHyperlinkClick + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Generate Random Keyfile... + + + CreateKeyfileButtton + protected + + + + + + + + + OnCreateKeyfileButttonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + KeyfileGeneratorDialogBase + + + wxDEFAULT_DIALOG_STYLE + + + + + + + + + + + + + + + + + + + + + + + + + + + OnMouseMotion + + + + + + + + + + + + MainSizer + wxVERTICAL + protected + + 5 + wxEXPAND|wxALL + 1 + + + bSizer144 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer145 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Mixing PRF: + + + m_staticText49 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + HashChoice + protected + + 0 + + + + + + + + OnHashSelected + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + wxID_ANY + + + sbSizer43 + wxVERTICAL + none + + + 5 + wxEXPAND|wxTOP + 0 + + + bSizer147 + wxHORIZONTAL + none + + 5 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Random Pool: + + + m_staticText52 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + Courier New,90,90,-1,70,0 + 0 + wxID_ANY + + + + RandomPoolStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 1 + + 1 + + + 0 + wxID_ANY + Show + + + ShowRandomPoolCheckBox + protected + + + + + + + + + + OnShowRandomPoolCheckBoxClicked + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 0 + wxID_ANY + IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases the cryptographic strength of the keyfile. + + + MouseStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer146 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Generate and Save Keyfile... + + + GenerateButton + protected + + + + + + + + + OnGenerateButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Close + + + m_button61 + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + LegalNoticesDialogBase + + + wxDEFAULT_DIALOG_STYLE + + TrueCrypt - Legal Notices + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer114 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer115 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + LegalNoticesTextCtrl + protected + + + wxTE_MULTILINE|wxTE_READONLY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxBOTH + + 1 + + + + 0 + wxID_ANY + + + MountOptionsDialogBase + + -1,-1 + wxDEFAULT_DIALOG_STYLE + + Enter TrueCrypt Volume Password + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + OnInitDialog + + + + + + + + + + + + + + + + + + + + + + + bSizer5 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer19 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + + bSizer14 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + PasswordSizer + wxVERTICAL + protected + + + + 5 + wxEXPAND + 0 + + + bSizer9 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + protected + + + + + + + + + OnOKButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Op&tions + + + OptionsButton + protected + + + + + + + + + OnOptionsButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer6 + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + + + 1 + + + 0 + wxID_ANY + + + OptionsPanel + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + wxID_ANY + + + OptionsSizer + wxVERTICAL + protected + + + 5 + wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount volume as &read-only + + + ReadOnlyCheckBox + protected + + + + + + + + + + OnReadOnlyCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount volume as removable &medium + + + RemovableCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount partition &using system encryption (preboot authentication) + + + PartitionInSystemEncryptionScopeCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + Hidden Volume Protection + + ProtectionSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Protect hidden volume when mounting outer volume + + + ProtectionCheckBox + protected + + + + + + + + + + OnProtectionCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + + ProtectionPasswordSizer + wxVERTICAL + protected + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxSYS_COLOUR_WINDOWTEXT + wxID_ANY + What is hidden volume protection? + + + ProtectionHyperlinkCtrl + wxSYS_COLOUR_WINDOWTEXT + protected + + + wxHL_DEFAULT_STYLE + + + + wxSYS_COLOUR_WINDOWTEXT + + + + + + + OnProtectionHyperlinkClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + FilesystemSizer + wxVERTICAL + protected + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel8 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + wxID_ANY + Filesystem + + sbSizer28 + wxVERTICAL + none + + + 5 + wxEXPAND|wxBOTTOM + 0 + + + bSizer54 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer55 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Do &not mount + + + NoFilesystemCheckBox + protected + + + + + + + + + + OnNoFilesystemCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0,0 + wxBOTH + 1 + + 0 + + FilesystemOptionsSizer + wxFLEX_GROWMODE_SPECIFIED + protected + 0 + + 5 + 1 + 0 + wxEXPAND|wxTOP + 0 + 1 + + + FilesystemSpacer + wxVERTICAL + protected + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 1 + 1 + + + + 1 + + + 0 + wxID_ANY + Mount at directory: + + + MountPointTextCtrlStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 1 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + MountPointTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 1 + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Se&lect... + + + MountPointButton + protected + + + + + + + + + OnMountPointButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxLEFT + 2 + 1 + + + + 1 + + + 0 + wxID_ANY + Mount options: + + + FilesystemOptionsStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 2 + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + FilesystemOptionsTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + NewSecurityTokenKeyfileDialogBase + + + wxDEFAULT_DIALOG_STYLE + + New Security Token Keyfile Properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer143 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer144 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + + + sbSizer42 + wxVERTICAL + none + + + 5 + wxEXPAND|wxTOP + 1 + + 2 + wxBOTH + + + 0 + + fgSizer7 + wxFLEX_GROWMODE_SPECIFIED + none + 2 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Security token: + + + m_staticText47 + none + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + + + + 1 + + + 0 + wxID_ANY + + + SecurityTokenChoice + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Keyfile name: + + + m_staticText48 + none + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + KeyfileNameTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnKeyfileNameChanged + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + StdButtons + protected + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + PreferencesDialogBase + + + wxDEFAULT_DIALOG_STYLE + + Preferences + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer32 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer41 + wxVERTICAL + none + + 5 + wxEXPAND | wxALL + 1 + + + + + 1 + + + 0 + wxID_ANY + + + PreferencesNotebook + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Security + 1 + + + + 1 + + + 0 + wxID_ANY + + + SecurityPage + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer44 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer33 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Auto-Dismount + + AutoDismountSizer + wxVERTICAL + protected + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Dismount All Volumes When + + sbSizer13 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + User logs off + + + DismountOnLogOffCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Screen saver is launched + + + DismountOnScreenSaverCheckBox + protected + + + + + + + + + + OnDismountOnScreenSaverCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + System is entering power saving mode + + + DismountOnPowerSavingCheckBox + protected + + + + + + + + + + OnDismountOnPowerSavingCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer34 + wxHORIZONTAL + none + + 5 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Auto-dismount volume after no data has been read/written to it for + + + DismountOnInactivityCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + 1 + 9999 + + 1 + + DismountOnInactivitySpinCtrl + protected + + 60,-1 + wxSP_ARROW_KEYS + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT + 1 + + + + 1 + + + 0 + wxID_ANY + minutes + + + m_staticText5 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Force auto-dismount even if volume contains open files or directories + + + ForceAutoDismountCheckBox + protected + + + + + + + + + + OnForceAutoDismountCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Filesystem + + FilesystemSecuritySizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Preserve modification timestamp of file containers + + + PreserveTimestampsCheckBox + protected + + + + + + + + + + OnPreserveTimestampsCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Password Cache + + sbSizer14 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Wipe after TrueCrypt window has been closed + + + WipeCacheOnCloseCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Wipe after volume has been auto-dismounted + + + WipeCacheOnAutoDismountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mount Options + 0 + + + + 1 + + + 0 + wxID_ANY + + + DefaultMountOptionsPage + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer46 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer35 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Default Mount Options + + sbSizer15 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount volumes as read-only + + + MountReadOnlyCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount volumes as removable media + + + MountRemovableCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Cache passwords in memory + + + CachePasswordsCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Filesystem + + FilesystemSizer + wxVERTICAL + protected + + + 5 + wxEXPAND + 1 + + 2 + wxBOTH + 1 + + 0 + + fgSizer3 + wxFLEX_GROWMODE_SPECIFIED + none + 1 + 0 + + 5 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT + 0 + + + + 1 + + + 0 + wxID_ANY + Mount options: + + + m_staticText6 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + FilesystemOptionsTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Background Task + 0 + + + + 1 + + + 0 + wxID_ANY + + + BackgroundTaskPanel + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer61 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer62 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + TrueCrypt Background Task + + sbSizer18 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Enabled + + + BackgroundTaskEnabledCheckBox + protected + + + + + + + + + + OnBackgroundTaskEnabledCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Exit when there are no mounted volumes + + + CloseBackgroundTaskOnNoVolumesCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + Task Icon Menu Items + + sbSizer26 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount Favorite Volumes + + + BackgroundTaskMenuMountItemsEnabledCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Open Mounted Volumes + + + BackgroundTaskMenuOpenItemsEnabledCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Dismount Mounted Volumes + + + BackgroundTaskMenuDismountItemsEnabledCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + System Integration + 0 + + + + 1 + + + 0 + wxID_ANY + + + SystemIntegrationPage + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer49 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer37 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + wxID_ANY + Actions to Perform when User Logs On + + LogOnSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Start TrueCrypt Background Task + + + StartOnLogonCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount favorite volumes + + + MountFavoritesOnLogonCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Mount all device-hosted TrueCrypt volumes + + + MountDevicesOnLogonCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Filesystem Explorer + + ExplorerSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Open Explorer window for successfully mounted volume + + + OpenExplorerWindowAfterMountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Close all Explorer windows of volume being dismounted + + + CloseExplorerWindowsOnDismountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Kernel Services + + KernelServicesSizer + wxVERTICAL + protected + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Do not use kernel cryptographic services + + + NoKernelCryptoCheckBox + protected + + + + + + + + + + OnNoKernelCryptoCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Performance + 0 + + + + 1 + + + 0 + wxID_ANY + + + PerformanceOptionsPage + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer151 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + bSizer152 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Hardware Acceleration + + sbSizer44 + wxVERTICAL + none + + + 5 + wxEXPAND + 1 + + + bSizer158 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Processor (CPU) in this computer supports hardware acceleration for AES: + + + m_staticText57 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + + AesHwCpuSupportedStaticText + protected + + + + + + + + wxSUNKEN_BORDER + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Do not accelerate AES encryption/decryption by using the AES instructions of the processor + + + NoHardwareCryptoCheckBox + protected + + + + + + + + + + OnNoHardwareCryptoCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Keyfiles + 0 + + + + 1 + + + 0 + wxID_ANY + + + DefaultKeyfilesPage + public + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer40 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer43 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + Default Keyfiles + + bSizer42 + wxVERTICAL + none + + + 5 + wxEXPAND + 1 + + + DefaultKeyfilesSizer + wxVERTICAL + protected + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Use keyfiles by default + + + UseKeyfilesCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Security Tokens + 0 + + + + 1 + + + 0 + wxID_ANY + + + SecurityTokensPage + public + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer127 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer128 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + PKCS #11 Library Path + + sbSizer36 + wxVERTICAL + none + + + 5 + wxEXPAND + 1 + + + bSizer129 + wxHORIZONTAL + none + + 5 + wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + Pkcs11ModulePathTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Select &Library... + + + SelectPkcs11ModuleButton + protected + + + + + + + + + OnSelectPkcs11ModuleButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Security Options + + sbSizer37 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Close token session (log out) after a volume is successfully mounted + + + CloseSecurityTokenSessionsAfterMountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hotkeys + 0 + + + + 1 + + + 0 + wxID_ANY + + + HotkeysPage + public + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer51 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer38 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + System-Wide Hotkeys + + sbSizer21 + wxVERTICAL + none + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + HotkeyListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + OnHotkeyListItemDeselected + + + + OnHotkeyListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Shortcut + + sbSizer23 + wxVERTICAL + none + + + 5 + wxALIGN_RIGHT + 1 + + 3 + wxBOTH + + + 0 + + fgSizer4 + wxFLEX_GROWMODE_SPECIFIED + none + 2 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Key to assign: + + + m_staticText10 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + HotkeyTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Assign + + + AssignHotkeyButton + protected + + + + + + + + + OnAssignHotkeyButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 1 + + 4 + 0 + + gSizer4 + none + 1 + 0 + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Control + + + HotkeyControlCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Shift + + + HotkeyShiftCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Alt + + + HotkeyAltCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Win + + + HotkeyWinCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + Remove + + + RemoveHotkeyButton + protected + + + + + + + + + OnRemoveHotkeyButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Options + + sbSizer24 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Play system notification sound after mount/dismount + + + BeepAfterHotkeyMountDismountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Display confirmation message box after dismount + + + DisplayMessageAfterHotkeyDismountCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + StdButtons + protected + + OnCancelButtonClick + + + + OnOKButtonClick + + + + + + + + + + + wxBOTH + + 1 + + + + 0 + wxID_ANY + + + RandomPoolEnrichmentDialogBase + + + wxDEFAULT_DIALOG_STYLE + + TrueCrypt - Random Pool Enrichment + + + + + + + + + + + + + + + + + + + + + + + + + OnMouseMotion + + + + + + + + + + + + MainSizer + wxVERTICAL + protected + + 5 + wxEXPAND|wxALL + 1 + + + bSizer144 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer145 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Mixing PRF: + + + m_staticText49 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + HashChoice + protected + + 0 + + + + + + + + OnHashSelected + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + wxID_ANY + + + sbSizer43 + wxVERTICAL + none + + + 5 + wxEXPAND|wxTOP + 0 + + + bSizer147 + wxHORIZONTAL + none + + 5 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Random Pool: + + + m_staticText52 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + Courier New,90,90,-1,70,0 + 0 + wxID_ANY + + + + RandomPoolStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 1 + + 1 + + + 0 + wxID_ANY + Show + + + ShowRandomPoolCheckBox + protected + + + + + + + + + + OnShowRandomPoolCheckBoxClicked + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 0 + wxID_ANY + IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases security. When done, click 'Continue'. + + + MouseStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer146 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + 1 + + + 0 + wxID_OK + &Continue + + + ContinueButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + -1,-1 + SecurityTokenKeyfilesDialogBase + + -1,-1 + wxDEFAULT_DIALOG_STYLE + + Security Token Keyfiles + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer3 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer138 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bSizer142 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + SecurityTokenKeyfileListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + OnListItemDeselected + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer141 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Export... + + + ExportButton + protected + + + + + + + + + OnExportButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Delete + + + DeleteButton + protected + + + + + + + + + OnDeleteButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Import Keyfile to Token... + + + ImportButton + protected + + + + + + + + + OnImportButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer139 + wxVERTICAL + none + + 5 + wxALL + 0 + + + + 1 + 1 + + + 0 + wxID_OK + OK + + + OKButton + protected + + + + + + + + + OnOKButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + + CancelButton + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + VolumePropertiesDialogBase + + + wxDEFAULT_DIALOG_STYLE + + Volume Properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer49 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + bSizer50 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + PropertiesListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VRULES + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + + StdButtons + protected + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + EncryptionOptionsWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer93 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer94 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer95 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + Encryption Algorithm + + sbSizer29 + wxVERTICAL + none + + + 5 + wxEXPAND + 0 + + + bSizer96 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + + 1 + + + 0 + wxID_ANY + + + EncryptionAlgorithmChoice + protected + + 0 + + + + + + + + OnEncryptionAlgorithmSelected + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Test + + + TestButton + protected + + + + + + + + + OnTestButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + EncryptionAlgorithmStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer97 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxSYS_COLOUR_WINDOWTEXT + wxID_ANY + More information + + + EncryptionAlgorithmHyperlink + wxSYS_COLOUR_WINDOWTEXT + protected + + + wxHL_DEFAULT_STYLE + + + + wxSYS_COLOUR_WINDOWTEXT + + + + + + + OnEncryptionAlgorithmHyperlinkClick + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Benchmark + + + BenchmarkButton + protected + + + + + + + + + OnBenchmarkButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Hash Algorithm + + sbSizer30 + wxHORIZONTAL + none + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + + 1 + + + 0 + wxID_ANY + + + HashChoice + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxSYS_COLOUR_WINDOWTEXT + wxID_ANY + Information on hash algorithms + + + HashHyperlink + wxSYS_COLOUR_WINDOWTEXT + protected + + + wxHL_DEFAULT_STYLE + + + + wxSYS_COLOUR_WINDOWTEXT + + + + + + + OnHashHyperlinkClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + InfoWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer71 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + InfoPageSizer + wxVERTICAL + protected + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + KeyfilesPanelBase + + 500,300 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer19 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer20 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + KeyfilesListCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemDeselected + + + + OnListItemSelected + + + + + + + + + + + + + OnListSizeChanged + + + + + 5 + wxEXPAND + 0 + + + bSizer137 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Add &Files... + + + AddFilesButton + protected + + + + + + + + + OnAddFilesButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Add &Path... + + + AddDirectoryButton + protected + + + + + + + + + OnAddDirectoryButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Add &Token Files... + + + AddSecurityTokenSignatureButton + protected + + + + + + + + + OnAddSecurityTokenSignatureButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Remove + + + RemoveButton + protected + + + + + + + + + OnRemoveButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Remove &All + + + RemoveAllButton + protected + + + + + + + + + OnRemoveAllButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + ProgressWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer81 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer82 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + ProgressSizer + wxHORIZONTAL + protected + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + ProgressGauge + protected + + 100 + -1,-1 + wxGA_HORIZONTAL|wxGA_SMOOTH + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 0 + + + 0 + wxID_ANY + &Abort + + + AbortButton + protected + + + + + + + + + OnAbortButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + SelectDirectoryWizardPageBase + + 200,65 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer69 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer70 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + DirectoryTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnDirectoryTextChanged + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Browse... + + + BrowseButton + protected + + + + + + + + + OnBrowseButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + 300 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + SingleChoiceWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer71 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer77 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + OuterChoicesSizer + wxVERTICAL + protected + + 5 + wxEXPAND + 0 + + + ChoicesSizer + wxVERTICAL + protected + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumeCreationProgressWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer104 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer105 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + wxID_ANY + + + sbSizer31 + wxVERTICAL + none + + + 30 + wxEXPAND + 1 + + + KeySamplesUpperSizer + wxVERTICAL + protected + + 3 + wxEXPAND|wxTOP + 1 + + + KeySamplesUpperInnerSizer + wxVERTICAL + protected + + + + + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + + + 0 + + fgSizer5 + wxFLEX_GROWMODE_SPECIFIED + none + 3 + 0 + + 5 + wxALL|wxALIGN_RIGHT|wxALIGN_BOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + Random Pool: + + + m_staticText25 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_BOTTOM + 1 + + + bSizer126 + wxHORIZONTAL + none + + 7 + wxEXPAND|wxTOP|wxRIGHT|wxALIGN_BOTTOM + 0 + + + + 1 + + Courier New,90,90,-1,70,0 + 0 + wxID_ANY + + + + RandomPoolSampleStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT + 0 + + + 1 + + 1 + + + 0 + wxID_ANY + Show + + + DisplayKeysCheckBox + protected + + + + + + + + + + OnDisplayKeysCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_BOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + Header Key: + + + m_staticText28 + none + + -1,-1 + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + wxALIGN_BOTTOM|wxEXPAND|wxTOP|wxRIGHT + 0 + + + + 1 + + Courier New,90,90,-1,70,0 + 0 + wxID_ANY + + + + HeaderKeySampleStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_BOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + Master Key: + + + m_staticText29 + none + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + wxEXPAND|wxALIGN_BOTTOM|wxTOP|wxRIGHT + 0 + + + + 1 + + Courier New,90,90,-1,70,0 + 0 + wxID_ANY + + + + MasterKeySampleStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + wxID_ANY + + + sbSizer32 + wxVERTICAL + none + + + 5 + wxEXPAND + 0 + + + bSizer106 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + ProgressGauge + protected + + 100 + + wxGA_HORIZONTAL|wxGA_SMOOTH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Abort + + + AbortButton + protected + + + + + + + + + OnAbortButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + wxEXPAND|wxTOP + 0 + + 3 + 0 + + gSizer6 + none + 1 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + + bSizer108 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Done + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + m_panel12 + protected + + -1,-1 + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer115 + wxHORIZONTAL + none + + 3 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + + SizeDoneStaticText + protected + + + wxALIGN_RIGHT|wxST_NO_AUTORESIZE + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL + 1 + + + bSizer1081 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Speed + + + m_staticText311 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel121 + protected + + + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer1151 + wxHORIZONTAL + none + + 3 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + SpeedStaticText + protected + + + wxALIGN_RIGHT|wxST_NO_AUTORESIZE + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT + 1 + + + bSizer1082 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Left + + + m_staticText312 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel122 + protected + + + + + + + wxSUNKEN_BORDER|wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer1152 + wxHORIZONTAL + none + + 3 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + + TimeLeftStaticText + protected + + + wxALIGN_RIGHT|wxST_NO_AUTORESIZE + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumeLocationWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer86 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer87 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + bSizer88 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bSizer89 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer126 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + VolumePathComboBox + protected + + + wxCB_DROPDOWN + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnVolumePathTextChanged + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bSizer90 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Select &File... + + -1,-1 + SelectFileButton + protected + + + + + + + + + OnSelectFileButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Select D&evice... + + -1,-1 + SelectDeviceButton + protected + + + + + + + + + OnSelectDeviceButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer91 + wxHORIZONTAL + none + + 5 + wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Never save history + + + NoHistoryCheckBox + protected + + + + + + + + + + OnNoHistoryCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumeFormatOptionsWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer124 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer125 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Filesystem Options + + sbSizer33 + wxVERTICAL + none + + + 5 + wxEXPAND + 1 + + 2 + wxBOTH + + + 0 + + fgSizer6 + wxFLEX_GROWMODE_SPECIFIED + none + 2 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Filesystem type: + + + m_staticText43 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + FilesystemTypeChoice + protected + + 0 + + + + + + + + OnFilesystemTypeSelected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + wxID_ANY + Volume Format Options + + sbSizer34 + wxVERTICAL + none + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Quick format + + + QuickFormatCheckBox + protected + + + + + + + + + + OnQuickFormatCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumePasswordPanelBase + + -1,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer7 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + 0,0 + wxBOTH + 1 + + 0 + + GridBagSizer + wxFLEX_GROWMODE_SPECIFIED + protected + 0 + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxBOTTOM|wxRIGHT + 1 + 1 + + + + 1 + + + 0 + wxID_ANY + Password: + + + PasswordStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxBOTTOM|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + 1 + + + + 1 + + + 0 + wxID_ANY + + 1 + 232,-1 + PasswordTextCtrl + protected + + + wxTE_PASSWORD + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnTextChanged + + + + + + + + 5 + 1 + 0 + wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT + 2 + 1 + + + + 1 + + + 0 + wxID_ANY + Confirm password: + + + ConfirmPasswordStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxBOTTOM|wxALIGN_CENTER_VERTICAL|wxEXPAND + 2 + 1 + + + + 1 + + + 0 + wxID_ANY + + 1 + 232,-1 + ConfirmPasswordTextCtrl + protected + + + wxTE_PASSWORD + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnTextChanged + + + + + + + + 5 + 2 + 1 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL + 3 + 1 + + + 0 + + 1 + + + 0 + wxID_ANY + Cach&e passwords and keyfiles in memory + + + CacheCheckBox + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL + 4 + 1 + + + 0 + + 1 + + + 0 + wxID_ANY + &Display password + + + DisplayPasswordCheckBox + protected + + + + + + + + + + OnDisplayPasswordCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 1 + wxTOP|wxRIGHT|wxLEFT + 5 + 1 + + + 0 + + 1 + + + 0 + wxID_ANY + U&se keyfiles + + + UseKeyfilesCheckBox + protected + + + + + + + + + + OnUseKeyfilesCheckBoxClick + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 1 + 2 + wxALIGN_RIGHT|wxALIGN_BOTTOM|wxLEFT + 5 + 1 + + + + 0 + 1 + + + 0 + wxID_ANY + &Keyfiles... + + + KeyfilesButton + protected + + + + + + + + + OnKeyfilesButtonClick + + + + + + + + + + + + + + + + + + + OnKeyfilesButtonRightDown + OnKeyfilesButtonRightClick + + + + + + + 5 + 1 + 1 + wxEXPAND|wxTOP|wxBOTTOM + 6 + 1 + + + Pkcs5PrfSizer + wxVERTICAL + protected + + + + 5 + 1 + 0 + wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxRIGHT + 7 + 1 + + + + 1 + + + 0 + wxID_ANY + PKCS-5 PRF: + + + Pkcs5PrfStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxALIGN_CENTER_VERTICAL|wxLEFT + 7 + 1 + + + "Unchanged" + + 1 + + + 0 + wxID_ANY + -1,-1 + -1,-1 + Pkcs5PrfChoice + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + 2 + 1 + wxTOP|wxEXPAND + 8 + 1 + + + PasswordPlaceholderSizer + wxVERTICAL + protected + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumePasswordWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer101 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer102 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + PasswordPanelSizer + wxVERTICAL + protected + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + VolumeSizeWizardPageBase + + -1,-1 + WizardPage; WizardPage.h + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer98 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + bSizer99 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + bSizer100 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + VolumeSizeTextCtrl + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnVolumeSizeTextChanged + + + + + + + + 5 + wxALL + 0 + + + + + 1 + + + 0 + wxID_ANY + + + VolumeSizePrefixChoice + protected + + 0 + + + + + + + + OnVolumeSizePrefixSelected + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + FreeSpaceStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM + 0 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + InfoStaticText + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Main/Forms/VolumeCreationProgressWizardPage.cpp b/src/Main/Forms/VolumeCreationProgressWizardPage.cpp new file mode 100644 index 00000000..12b11591 --- /dev/null +++ b/src/Main/Forms/VolumeCreationProgressWizardPage.cpp @@ -0,0 +1,183 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "VolumeCreationProgressWizardPage.h" + +namespace TrueCrypt +{ + VolumeCreationProgressWizardPage::VolumeCreationProgressWizardPage (wxPanel* parent, bool displayKeyInfo) + : VolumeCreationProgressWizardPageBase (parent), + PreviousGaugeValue (0), + ProgressBarRange (1), + RealProgressBarRange (1), + VolumeCreatorRunning (false) + { + DisplayKeysCheckBox->SetValue (displayKeyInfo); +#ifdef TC_WINDOWS + DisplayKeysCheckBox->SetLabel (L""); +#endif + +#ifdef TC_MACOSX + ProgressGauge->SetMinSize (wxSize (-1, 12)); // OS X apparently supports only up to 12px thick progress bars + KeySamplesUpperSizer->Remove (KeySamplesUpperInnerSizer); +#else + ProgressGauge->SetMinSize (wxSize (-1, Gui->GetCharHeight (this) * 2)); +#endif + + if (DisplayKeysCheckBox->IsChecked()) + ShowBytes (RandomPoolSampleStaticText, RandomNumberGenerator::PeekPool(), true); + else + ShowAsterisks (RandomPoolSampleStaticText); + + class Timer : public wxTimer + { + public: + Timer (VolumeCreationProgressWizardPage *page) : Page (page) { } + + void Notify() + { + Page->OnRandomPoolTimer(); + } + + VolumeCreationProgressWizardPage *Page; + }; + + RandomPoolTimer.reset (dynamic_cast (new Timer (this))); + RandomPoolTimer->Start (30); + + AbortButton->Disable(); + ProgressGauge->SetValue (0); + + } + + void VolumeCreationProgressWizardPage::OnAbortButtonClick (wxCommandEvent& event) + { + AbortEvent.Raise(); + } + + void VolumeCreationProgressWizardPage::OnDisplayKeysCheckBoxClick (wxCommandEvent& event) + { + if (!event.IsChecked()) + { + ShowAsterisks (RandomPoolSampleStaticText); + ShowAsterisks (HeaderKeySampleStaticText); + ShowAsterisks (MasterKeySampleStaticText); + } + else + { + RandomPoolSampleStaticText->SetLabel (L""); + HeaderKeySampleStaticText->SetLabel (L""); + MasterKeySampleStaticText->SetLabel (L""); + } + } + + void VolumeCreationProgressWizardPage::OnRandomPoolTimer () + { + if (!VolumeCreatorRunning && DisplayKeysCheckBox->IsChecked()) + ShowBytes (RandomPoolSampleStaticText, RandomNumberGenerator::PeekPool(), true); + } + + void VolumeCreationProgressWizardPage::SetKeyInfo (const VolumeCreator::KeyInfo &keyInfo) + { + if (DisplayKeysCheckBox->IsChecked()) + { + ShowBytes (RandomPoolSampleStaticText, RandomNumberGenerator::PeekPool(), true); + ShowBytes (HeaderKeySampleStaticText, keyInfo.HeaderKey); + ShowBytes (MasterKeySampleStaticText, keyInfo.MasterKey); + } + } + + void VolumeCreationProgressWizardPage::ShowAsterisks (wxStaticText *textCtrl) + { + wxString str; + for (size_t i = 0; i < MaxDisplayedKeyBytes + 1; ++i) + { + str += L"**"; + } + + textCtrl->SetLabel (str.c_str()); + } + + void VolumeCreationProgressWizardPage::ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots) + { + wxString str; + + for (size_t i = 0; i < MaxDisplayedKeyBytes && i < buffer.Size(); ++i) + { + str += wxString::Format (L"%02X", buffer[i]); + } + + if (appendDots) + str += L".."; + + textCtrl->SetLabel (str.c_str()); + + for (size_t i = 0; i < str.size(); ++i) + { + str[i] = L'X'; + } + } + + void VolumeCreationProgressWizardPage::SetProgressValue (uint64 value) + { + int gaugeValue = static_cast (value * RealProgressBarRange / ProgressBarRange); + + if (value == ProgressBarRange) + gaugeValue = RealProgressBarRange; // Prevent round-off error + + if (gaugeValue != PreviousGaugeValue) + { + ProgressGauge->SetValue (gaugeValue); + PreviousGaugeValue = gaugeValue; + } + + if (value != 0) + { + SizeDoneStaticText->SetLabel (wxString::Format (L"%7.3f%%", 100.0 - double (ProgressBarRange - value) / (double (ProgressBarRange) / 100.0))); + + wxLongLong timeDiff = wxGetLocalTimeMillis() - StartTime; + if (timeDiff.GetValue() > 0) + { + uint64 speed = value * 1000 / timeDiff.GetValue(); + + if (ProgressBarRange != value) + SpeedStaticText->SetLabel (Gui->SpeedToString (speed)); + + TimeLeftStaticText->SetLabel (speed > 0 ? Gui->TimeSpanToString ((ProgressBarRange - value) / speed) : L""); + } + } + else + { + SizeDoneStaticText->SetLabel (L""); + SpeedStaticText->SetLabel (L""); + TimeLeftStaticText->SetLabel (L""); + } + } + + void VolumeCreationProgressWizardPage::SetMaxStaticTextWidth (int width) + { + InfoStaticText->Wrap (width); + } + + void VolumeCreationProgressWizardPage::SetProgressState (bool volumeCreatorRunning) + { + if (volumeCreatorRunning) + StartTime = wxGetLocalTimeMillis(); + + VolumeCreatorRunning = volumeCreatorRunning; + } + + void VolumeCreationProgressWizardPage::SetProgressRange (uint64 progressBarRange) + { + ProgressBarRange = progressBarRange; + RealProgressBarRange = ProgressGauge->GetSize().GetWidth(); + ProgressGauge->SetRange (RealProgressBarRange); + } +} diff --git a/src/Main/Forms/VolumeCreationProgressWizardPage.h b/src/Main/Forms/VolumeCreationProgressWizardPage.h new file mode 100644 index 00000000..a33b3623 --- /dev/null +++ b/src/Main/Forms/VolumeCreationProgressWizardPage.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumeCreationProgressWizardPage +#define TC_HEADER_Main_Forms_VolumeCreationProgressWizardPage + +#include "Forms.h" +#include "Core/VolumeCreator.h" + +namespace TrueCrypt +{ + class VolumeCreationProgressWizardPage : public VolumeCreationProgressWizardPageBase + { + public: + VolumeCreationProgressWizardPage (wxPanel* parent, bool displayKeyInfo); + ~VolumeCreationProgressWizardPage () { } + + void EnableAbort (bool enable = true) { AbortButton->Enable (enable); } + bool IsKeyInfoDisplayed () const { return DisplayKeysCheckBox->GetValue(); } + bool IsValid () { return true; } + void OnRandomPoolTimer (); + void SetKeyInfo (const VolumeCreator::KeyInfo &keyInfo); + void SetMaxStaticTextWidth (int width); + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + void SetProgressRange (uint64 progressBarRange); + void SetProgressValue (uint64 value); + void SetProgressState (bool volumeCreatorRunning); + + Event AbortEvent; + + protected: + void OnAbortButtonClick (wxCommandEvent& event); + void OnDisplayKeysCheckBoxClick (wxCommandEvent& event); + void ShowAsterisks (wxStaticText *textCtrl); + void ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots = true); + + static const size_t MaxDisplayedKeyBytes = 13; + + int PreviousGaugeValue; + uint64 ProgressBarRange; + auto_ptr RandomPoolTimer; + int RealProgressBarRange; + wxLongLong StartTime; + bool VolumeCreatorRunning; + }; +} + +#endif // TC_HEADER_Main_Forms_VolumeCreationProgressWizardPage diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp new file mode 100644 index 00000000..1219fc20 --- /dev/null +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -0,0 +1,984 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Platform/SystemInfo.h" +#ifdef TC_UNIX +#include +#include "Platform/Unix/Process.h" +#endif +#include "Core/RandomNumberGenerator.h" +#include "Core/VolumeCreator.h" +#include "Main/Application.h" +#include "Main/GraphicUserInterface.h" +#include "Main/Resources.h" +#include "VolumeCreationWizard.h" +#include "EncryptionOptionsWizardPage.h" +#include "InfoWizardPage.h" +#include "ProgressWizardPage.h" +#include "SingleChoiceWizardPage.h" +#include "VolumeCreationProgressWizardPage.h" +#include "VolumeFormatOptionsWizardPage.h" +#include "VolumeLocationWizardPage.h" +#include "VolumePasswordWizardPage.h" +#include "VolumeSizeWizardPage.h" + +namespace TrueCrypt +{ + VolumeCreationWizard::VolumeCreationWizard (wxWindow* parent) + : WizardFrame (parent), + CrossPlatformSupport (true), + DisplayKeyInfo (true), + LargeFilesSupport (false), + QuickFormatEnabled (false), + SelectedFilesystemClusterSize (0), + SelectedFilesystemType (VolumeCreationOptions::FilesystemType::FAT), + SelectedVolumeHostType (VolumeHostType::File), + SelectedVolumeType (VolumeType::Normal), + SectorSize (0), + VolumeSize (0) + { + RandomNumberGenerator::Start(); + + SetTitle (LangString["INTRO_TITLE"]); + SetImage (Resources::GetVolumeCreationWizardBitmap (Gui->GetCharHeight (this) * 21)); + SetMaxStaticTextWidth (55); + + SetStep (Step::VolumeHostType); + + class Timer : public wxTimer + { + public: + Timer (VolumeCreationWizard *wizard) : Wizard (wizard) { } + + void Notify() + { + Wizard->OnRandomPoolUpdateTimer(); + } + + VolumeCreationWizard *Wizard; + }; + + RandomPoolUpdateTimer.reset (dynamic_cast (new Timer (this))); + RandomPoolUpdateTimer->Start (200); + } + + VolumeCreationWizard::~VolumeCreationWizard () + { + } + + WizardPage *VolumeCreationWizard::GetPage (WizardStep step) + { + switch (step) + { + case Step::VolumeHostType: + { + ClearHistory(); + + OuterVolume = false; + LargeFilesSupport = false; + QuickFormatEnabled = false; + + SingleChoiceWizardPage *page = new SingleChoiceWizardPage (GetPageParent(), wxEmptyString, true); + page->SetMinSize (wxSize (Gui->GetCharWidth (this) * 58, Gui->GetCharHeight (this) * 18 + 5)); + + page->SetPageTitle (LangString["INTRO_TITLE"]); + + page->AddChoice (VolumeHostType::File, LangString["IDC_FILE_CONTAINER"], LangString["IDT_FILE_CONTAINER"], L"introcontainer", LangString["IDC_MORE_INFO_ON_CONTAINERS"]); + page->AddChoice (VolumeHostType::Device, _("Create a volume within a partition/&drive"), _("Formats and encrypts a non-system partition, entire external or secondary drive, entire USB stick, etc.")); + + page->SetSelection (SelectedVolumeHostType); + return page; + } + + case Step::VolumeType: + { + SingleChoiceWizardPage *page = new SingleChoiceWizardPage (GetPageParent(), wxEmptyString, true); + page->SetPageTitle (LangString["VOLUME_TYPE_TITLE"]); + + page->AddChoice (VolumeType::Normal, LangString["IDC_STD_VOL"], LangString["NORMAL_VOLUME_TYPE_HELP"]); + page->AddChoice (VolumeType::Hidden, LangString["IDC_HIDDEN_VOL"], LangString["HIDDEN_VOLUME_TYPE_HELP"], L"hiddenvolume", LangString["IDC_HIDDEN_VOL_HELP"]); + + page->SetSelection (SelectedVolumeType); + return page; + } + + case Step::VolumeLocation: + { + VolumeLocationWizardPage *page = new VolumeLocationWizardPage (GetPageParent(), SelectedVolumeHostType); + page->SetPageTitle (LangString["VOLUME_LOCATION"]); + + if (SelectedVolumeType == VolumeType::Hidden) + page->SetPageText (LangString[SelectedVolumeHostType == VolumeHostType::File ? "FILE_HELP_HIDDEN_HOST_VOL" : "DEVICE_HELP_HIDDEN_HOST_VOL"]); + else + page->SetPageText (LangString[SelectedVolumeHostType == VolumeHostType::File ? "FILE_HELP" : "DEVICE_HELP_NO_INPLACE"]); + + page->SetVolumePath (SelectedVolumePath); + return page; + } + + case Step::EncryptionOptions: + { + EncryptionOptionsWizardPage *page = new EncryptionOptionsWizardPage (GetPageParent()); + + if (OuterVolume) + page->SetPageTitle (LangString["CIPHER_HIDVOL_HOST_TITLE"]); + else if (SelectedVolumeType == VolumeType::Hidden) + page->SetPageTitle (LangString["CIPHER_HIDVOL_TITLE"]); + else + page->SetPageTitle (LangString["CIPHER_TITLE"]); + + page->SetEncryptionAlgorithm (SelectedEncryptionAlgorithm); + page->SetHash (SelectedHash); + return page; + } + + case Step::VolumeSize: + { + wxString freeSpaceText; + wxString pageTitle; + wxString pageText; + + if (OuterVolume) + { + pageTitle = LangString["SIZE_HIDVOL_HOST_TITLE"]; + pageText = LangString["SIZE_HELP_HIDDEN_HOST_VOL"]; + } + else if (SelectedVolumeType == VolumeType::Hidden) + { + pageTitle = LangString["SIZE_HIDVOL_TITLE"]; + pageText = LangString["SIZE_HELP_HIDDEN_VOL"] + L"\n\n" + _("Please note that if your operating system does not allocate files from the beginning of the free space, the maximum possible hidden volume size may be much smaller than the size of the free space on the outer volume. This not a bug in TrueCrypt but a limitation of the operating system."); + freeSpaceText = StringFormatter (_("Maximum possible hidden volume size for this volume is {0}."), Gui->SizeToString (MaxHiddenVolumeSize)); + } + else + { + pageTitle = LangString["SIZE_TITLE"]; + pageText = LangString["VOLUME_SIZE_HELP"]; + } + + VolumeSizeWizardPage *page = new VolumeSizeWizardPage (GetPageParent(), SelectedVolumePath, SectorSize, freeSpaceText); + + page->SetPageTitle (pageTitle); + page->SetPageText (pageText); + + if (!OuterVolume && SelectedVolumeType == VolumeType::Hidden) + page->SetMaxVolumeSize (MaxHiddenVolumeSize); + else + page->SetVolumeSize (VolumeSize); + + if (OuterVolume) + page->SetMinVolumeSize (TC_MIN_HIDDEN_VOLUME_HOST_SIZE); + else if (SelectedVolumeType == VolumeType::Hidden) + page->SetMinVolumeSize (TC_MIN_HIDDEN_VOLUME_SIZE); + else + page->SetMinVolumeSize (TC_MIN_VOLUME_SIZE); + + return page; + } + + case Step::VolumePassword: + { + VolumePasswordWizardPage *page = new VolumePasswordWizardPage (GetPageParent(), Password, Keyfiles); + + if (OuterVolume) + page->SetPageTitle (LangString["PASSWORD_HIDVOL_HOST_TITLE"]); + else if (SelectedVolumeType == VolumeType::Hidden) + page->SetPageTitle (LangString["PASSWORD_HIDVOL_TITLE"]); + else + page->SetPageTitle (LangString["PASSWORD_TITLE"]); + + page->SetPageText (LangString[OuterVolume ? "PASSWORD_HIDDENVOL_HOST_HELP" : "PASSWORD_HELP"]); + return page; + } + + case Step::LargeFilesSupport: + { + SingleChoiceWizardPage *page = new SingleChoiceWizardPage (GetPageParent(), wxEmptyString, true); + page->SetPageTitle (LangString["FILESYS_PAGE_TITLE"]); + + page->AddChoice (false, _("I will not store files larger than 4 GB on the volume"), + _("Choose this option if you do not need to store files larger than 4 GB (4,294,967,296 bytes) on the volume.")); + + page->AddChoice (true, _("I will store files larger than 4 GB on the volume"), + _("Choose this option if you need to store files larger than 4 GB (4,294,967,296 bytes) on the volume.")); + + page->SetSelection (LargeFilesSupport); + return page; + } + + case Step::FormatOptions: + { + VolumeFormatOptionsWizardPage *page = new VolumeFormatOptionsWizardPage (GetPageParent(), VolumeSize, SectorSize, + SelectedVolumePath.IsDevice() && (OuterVolume || SelectedVolumeType != VolumeType::Hidden), OuterVolume, LargeFilesSupport); + + page->SetPageTitle (_("Format Options")); + page->SetFilesystemType (SelectedFilesystemType); + + if (!OuterVolume && SelectedVolumeType == VolumeType::Hidden) + QuickFormatEnabled = true; + page->SetQuickFormat (QuickFormatEnabled); + + return page; + } + + case Step::CrossPlatformSupport: + { + SingleChoiceWizardPage *page = new SingleChoiceWizardPage (GetPageParent(), wxEmptyString, true); + page->SetPageTitle (_("Cross-Platform Support")); + + page->AddChoice (true, _("I will mount the volume on other platforms"), + _("Choose this option if you need to use the volume on other platforms.")); + + page->AddChoice (false, StringFormatter (_("I will mount the volume only on {0}"), SystemInfo::GetPlatformName()), + _("Choose this option if you do not need to use the volume on other platforms.")); + + page->SetSelection (CrossPlatformSupport); + return page; + } + + case Step::CreationProgress: + { + VolumeCreationProgressWizardPage *page = new VolumeCreationProgressWizardPage (GetPageParent(), DisplayKeyInfo); + + if (OuterVolume) + page->SetPageTitle (LangString["FORMAT_HIDVOL_HOST_TITLE"]); + else if (SelectedVolumeType == VolumeType::Hidden) + page->SetPageTitle (LangString["FORMAT_HIDVOL_TITLE"]); + else + page->SetPageTitle (LangString["FORMAT_TITLE"]); + + page->SetPageText (LangString["FORMAT_HELP"]); + page->AbortEvent.Connect (EventConnector (this, &VolumeCreationWizard::OnAbortButtonClick)); + page->SetNextButtonText (LangString["FORMAT"]); + return page; + } + + case Step::VolumeCreatedInfo: + { + InfoWizardPage *page = new InfoWizardPage (GetPageParent()); + page->SetPageTitle (LangString["FORMAT_FINISHED_TITLE"]); + page->SetPageText (LangString["FORMAT_FINISHED_HELP"]); + + SetCancelButtonText (_("Exit")); + return page; + } + + case Step::OuterVolumeContents: + { + ClearHistory(); + + MountOptions mountOptions; + mountOptions.Keyfiles = Keyfiles; + mountOptions.Password = Password; + mountOptions.Path = make_shared (SelectedVolumePath); + + try + { + wxBusyCursor busy; + Gui->SetActiveFrame (this); + MountedOuterVolume = Core->MountVolume (mountOptions); + } + catch (exception &e) + { + Gui->SetActiveFrame (this); + Gui->ShowError (e); + + Close(); + return new InfoWizardPage (GetPageParent()); + } + + struct OpenOuterVolumeFunctor : public Functor + { + OpenOuterVolumeFunctor (const DirectoryPath &outerVolumeMountPoint) : OuterVolumeMountPoint (outerVolumeMountPoint) { } + + virtual void operator() () + { + Gui->OpenExplorerWindow (OuterVolumeMountPoint); + } + + DirectoryPath OuterVolumeMountPoint; + }; + + InfoWizardPage *page = new InfoWizardPage (GetPageParent(), _("Open Outer Volume"), + shared_ptr (new OpenOuterVolumeFunctor (MountedOuterVolume->MountPoint))); + + page->SetPageTitle (LangString["HIDVOL_HOST_FILLING_TITLE"]); + + page->SetPageText (StringFormatter ( + _("Outer volume has been successfully created and mounted as '{0}'. To this volume you should now copy some sensitive-looking files that you actually do NOT want to hide. The files will be there for anyone forcing you to disclose your password. You will reveal only the password for this outer volume, not for the hidden one. The files that you really care about will be stored in the hidden volume, which will be created later on. When you finish copying, click Next. Do not dismount the volume.\n\nNote: After you click Next, the outer volume will be analyzed to determine the size of uninterrupted area of free space whose end is aligned with the end of the volume. This area will accommodate the hidden volume, so it will limit its maximum possible size. The procedure ensures no data on the outer volume are overwritten by the hidden volume."), + wstring (MountedOuterVolume->MountPoint))); + + return page; + } + + case Step::HiddenVolume: + { + ClearHistory(); + OuterVolume = false; + LargeFilesSupport = false; + + InfoWizardPage *page = new InfoWizardPage (GetPageParent()); + page->SetPageTitle (LangString["HIDVOL_PRE_CIPHER_TITLE"]); + page->SetPageText (LangString["HIDVOL_PRE_CIPHER_HELP"]); + + return page; + } + + default: + throw ParameterIncorrect (SRC_POS); + } + } + + void VolumeCreationWizard::OnAbortButtonClick (EventArgs &args) + { + AbortRequested = true; + } + + void VolumeCreationWizard::OnMouseMotion (wxMouseEvent& event) + { + event.Skip(); + if (!IsWorkInProgress() && RandomNumberGenerator::IsRunning()) + { + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&event), sizeof (event))); + + long coord = event.GetX(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + coord = event.GetY(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&coord), sizeof (coord))); + } + } + + void VolumeCreationWizard::OnProgressTimer () + { + if (!IsWorkInProgress()) + return; + + if (AbortRequested && !AbortConfirmationPending) + { + AbortConfirmationPending = true; + if (Gui->AskYesNo (LangString ["FORMAT_ABORT"], true)) + { + if (IsWorkInProgress() && Creator.get() != nullptr) + { + CreationAborted = true; + Creator->Abort(); + } + } + AbortRequested = false; + AbortConfirmationPending = false; + } + + VolumeCreator::ProgressInfo progress = Creator->GetProgressInfo(); + + VolumeCreationProgressWizardPage *page = dynamic_cast (GetCurrentPage()); + page->SetProgressValue (progress.SizeDone); + + if (!progress.CreationInProgress && !AbortConfirmationPending) + { + SetWorkInProgress (false); + OnVolumeCreatorFinished (); + } + } + + void VolumeCreationWizard::OnRandomPoolUpdateTimer () + { + if (!IsWorkInProgress()) + { + wxLongLong time = wxGetLocalTimeMillis(); + RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast (&time), sizeof (time))); + } + } + + void VolumeCreationWizard::OnVolumeCreatorFinished () + { + VolumeCreationProgressWizardPage *page = dynamic_cast (GetCurrentPage()); + + ProgressTimer.reset(); + page->SetProgressState (false); + + Gui->EndInteractiveBusyState (this); + SetWorkInProgress (false); + UpdateControls(); + + try + { + if (!CreationAborted) + { + Creator->CheckResult(); + +#ifdef TC_UNIX + // Format non-FAT filesystem + const char *fsFormatter = nullptr; + + switch (SelectedFilesystemType) + { + case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break; + case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break; + case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break; + case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break; + case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break; + default: break; + } + + if (fsFormatter) + { + wxBusyCursor busy; + + MountOptions mountOptions (Gui->GetPreferences().DefaultMountOptions); + mountOptions.Path = make_shared (SelectedVolumePath); + mountOptions.NoFilesystem = true; + mountOptions.Protection = VolumeProtection::None; + mountOptions.Password = Password; + mountOptions.Keyfiles = Keyfiles; + + shared_ptr volume = Core->MountVolume (mountOptions); + finally_do_arg (shared_ptr , volume, { Core->DismountVolume (finally_arg, true); }); + + Thread::Sleep (2000); // Try to prevent race conditions caused by OS + + // Temporarily take ownership of the device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + DevicePath virtualDevice = volume->VirtualDevice; +#ifdef TC_MACOSX + string virtualDeviceStr = virtualDevice; + if (virtualDeviceStr.find ("/dev/rdisk") != 0) + virtualDevice = "/dev/r" + virtualDeviceStr.substr (5); +#endif + try + { + File file; + file.Open (virtualDevice, File::OpenReadWrite); + } + catch (...) + { + if (!Core->HasAdminPrivileges()) + { + origDeviceOwner = virtualDevice.GetOwner(); + Core->SetFileOwner (virtualDevice, UserId (getuid())); + } + } + + finally_do_arg2 (FilesystemPath, virtualDevice, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); + + // Create filesystem + list args; + + if (SelectedFilesystemType == VolumeCreationOptions::FilesystemType::MacOsExt && VolumeSize >= 10 * BYTES_PER_MB) + args.push_back ("-J"); + + args.push_back (string (virtualDevice)); + + Process::Execute (fsFormatter, args); + } +#endif // TC_UNIX + + if (OuterVolume) + { + SetStep (Step::OuterVolumeContents); + } + else + { + Gui->ShowInfo (SelectedVolumeType == VolumeType::Hidden ? "HIDVOL_FORMAT_FINISHED_HELP" : "FORMAT_FINISHED_INFO"); + SetStep (Step::VolumeCreatedInfo); + } + + return; + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + + page->SetProgressValue (0); + if (SelectedVolumeType == VolumeType::Normal && !SelectedVolumePath.IsDevice()) + { + try + { + FilePath (wstring (SelectedVolumePath)).Delete(); + } + catch (...) { } + } + } + + WizardFrame::WizardStep VolumeCreationWizard::ProcessPageChangeRequest (bool forward) + { + switch (GetCurrentStep()) + { + case Step::VolumeHostType: + { + SingleChoiceWizardPage *page = dynamic_cast *> (GetCurrentPage()); + + try + { + SelectedVolumeHostType = page->GetSelection(); + } + catch (NoItemSelected &) + { + return GetCurrentStep(); + } + + return Step::VolumeType; + } + + case Step::VolumeType: + { + SingleChoiceWizardPage *page = dynamic_cast *> (GetCurrentPage()); + + try + { + SelectedVolumeType = page->GetSelection(); + } + catch (NoItemSelected &) + { + return GetCurrentStep(); + } + + if (SelectedVolumeType == VolumeType::Hidden) + OuterVolume = true; + + return Step::VolumeLocation; + } + + case Step::VolumeLocation: + { + VolumeLocationWizardPage *page = dynamic_cast (GetCurrentPage()); + SelectedVolumePath = page->GetVolumePath(); + VolumeSize = 0; + + if (forward) + { + if (Core->IsVolumeMounted (SelectedVolumePath)) + { + Gui->ShowInfo ("DISMOUNT_FIRST"); + return GetCurrentStep(); + } + + if (SelectedVolumePath.IsDevice()) + { + if (!DeviceWarningConfirmed && !Gui->AskYesNo (LangString["FORMAT_DEVICE_FOR_ADVANCED_ONLY"])) + return GetCurrentStep(); + + DeviceWarningConfirmed = true; + + foreach_ref (const HostDevice &drive, Core->GetHostDevices()) + { + if (drive.Path == SelectedVolumePath && !drive.Partitions.empty()) + { + foreach_ref (const HostDevice &partition, drive.Partitions) + { + if (partition.MountPoint == "/") + { + Gui->ShowError (_("Error: You are trying to encrypt a system drive.\n\nTrueCrypt can encrypt a system drive only under Windows.")); + return GetCurrentStep(); + } + } + + Gui->ShowError ("DEVICE_PARTITIONS_ERR"); + return GetCurrentStep(); + } + } + + try + { + SectorSize = Core->GetDeviceSectorSize (SelectedVolumePath); + VolumeSize = Core->GetDeviceSize (SelectedVolumePath); + } + catch (UserAbort&) + { + return Step::VolumeLocation; + } + catch (exception &e) + { + Gui->ShowError (e); + Gui->ShowError ("CANNOT_CALC_SPACE"); + return GetCurrentStep(); + } + + DirectoryPath mountPoint; + try + { + mountPoint = Core->GetDeviceMountPoint (SelectedVolumePath); + + if (!mountPoint.IsEmpty()) + { + if (mountPoint == "/") + { + Gui->ShowError (_("Error: You are trying to encrypt a system partition.\n\nTrueCrypt can encrypt system partitions only under Windows.")); + return GetCurrentStep(); + } + + if (!Gui->AskYesNo (StringFormatter (_("WARNING: Formatting of the device will destroy all data on filesystem '{0}'.\n\nDo you want to continue?"), wstring (mountPoint)), false, true)) + return GetCurrentStep(); + + try + { + Core->DismountFilesystem (mountPoint, true); + } + catch (exception &e) + { + Gui->ShowError (e); + Gui->ShowError (StringFormatter (_("The filesystem of the selected device is currently mounted. Please dismount '{0}' before proceeding."), wstring (mountPoint))); + return GetCurrentStep(); + } + } + } + catch (...) { } + } + else + SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME; + } + + return Step::EncryptionOptions; + } + + case Step::EncryptionOptions: + { + EncryptionOptionsWizardPage *page = dynamic_cast (GetCurrentPage()); + SelectedEncryptionAlgorithm = page->GetEncryptionAlgorithm (); + SelectedHash = page->GetHash (); + + if (forward) + RandomNumberGenerator::SetHash (SelectedHash); + + if (SelectedVolumePath.IsDevice() && (OuterVolume || SelectedVolumeType != VolumeType::Hidden)) + return Step::VolumePassword; + else + return Step::VolumeSize; + } + + case Step::VolumeSize: + { + VolumeSizeWizardPage *page = dynamic_cast (GetCurrentPage()); + + try + { + VolumeSize = page->GetVolumeSize(); + } + catch (Exception &e) + { + if (forward) + { + Gui->ShowError (e); + return GetCurrentStep(); + } + } + + if (forward + && !OuterVolume && SelectedVolumeType == VolumeType::Hidden + && (double) VolumeSize / MaxHiddenVolumeSize > 0.85) + { + if (!Gui->AskYesNo (LangString["FREE_SPACE_FOR_WRITING_TO_OUTER_VOLUME"])) + return GetCurrentStep(); + } + + if (forward + && SelectedVolumeHostType == VolumeHostType::File + && VolumeSize > 4 * BYTES_PER_GB + && (OuterVolume || SelectedVolumeType != VolumeType::Hidden) + && !Core->FilesystemSupportsLargeFiles (SelectedVolumePath)) + { + Gui->ShowWarning (LangString["VOLUME_TOO_LARGE_FOR_FAT32"]); + } + + return Step::VolumePassword; + } + + case Step::VolumePassword: + { + VolumePasswordWizardPage *page = dynamic_cast (GetCurrentPage()); + Password = page->GetPassword(); + Keyfiles = page->GetKeyfiles(); + + if (forward && Password && !Password->IsEmpty()) + { + try + { + Password->CheckPortability(); + } + catch (UnportablePassword &e) + { + Gui->ShowError (e); + return GetCurrentStep(); + } + + if (Password->Size() < VolumePassword::WarningSizeThreshold + && !Gui->AskYesNo (LangString["PASSWORD_LENGTH_WARNING"], false, true)) + { + return GetCurrentStep(); + } + } + + if (forward && OuterVolume) + { + // Use FAT to prevent problems with free space + QuickFormatEnabled = false; + SelectedFilesystemType = VolumeCreationOptions::FilesystemType::FAT; + return Step::CreationProgress; + } + + if (VolumeSize > 4 * BYTES_PER_GB) + { + if (VolumeSize <= TC_MAX_FAT_SECTOR_COUNT * SectorSize) + return Step::LargeFilesSupport; + else + SelectedFilesystemType = VolumeCreationOptions::FilesystemType::GetPlatformNative(); + } + + return Step::FormatOptions; + } + + case Step::LargeFilesSupport: + { + SingleChoiceWizardPage *page = dynamic_cast *> (GetCurrentPage()); + + try + { + LargeFilesSupport = page->GetSelection(); + } + catch (NoItemSelected &) + { + return GetCurrentStep(); + } + + if (LargeFilesSupport) + SelectedFilesystemType = VolumeCreationOptions::FilesystemType::GetPlatformNative(); + else + SelectedFilesystemType = VolumeCreationOptions::FilesystemType::FAT; + + return Step::FormatOptions; + } + + case Step::FormatOptions: + { + VolumeFormatOptionsWizardPage *page = dynamic_cast (GetCurrentPage()); + SelectedFilesystemType = page->GetFilesystemType(); + QuickFormatEnabled = page->IsQuickFormatEnabled(); + + if (SelectedFilesystemType != VolumeCreationOptions::FilesystemType::None + && SelectedFilesystemType != VolumeCreationOptions::FilesystemType::FAT) + return Step::CrossPlatformSupport; + + return Step::CreationProgress; + } + + case Step::CrossPlatformSupport: + { + SingleChoiceWizardPage *page = dynamic_cast *> (GetCurrentPage()); + + try + { + CrossPlatformSupport = page->GetSelection(); + } + catch (NoItemSelected &) + { + return GetCurrentStep(); + } + + if (forward && CrossPlatformSupport) + Gui->ShowWarning (StringFormatter (_("Please note that the volume will not be formatted with a FAT filesystem and, therefore, you may be required to install additional filesystem drivers on platforms other than {0}, which will enable you to mount the volume."), SystemInfo::GetPlatformName())); + + return Step::CreationProgress; + } + + case Step::CreationProgress: + { + VolumeCreationProgressWizardPage *page = dynamic_cast (GetCurrentPage()); + + DisplayKeyInfo = page->IsKeyInfoDisplayed(); + + if (forward) + { + if (SelectedVolumeType != VolumeType::Hidden || OuterVolume) + { + if (OuterVolume && VolumeSize > TC_MAX_FAT_SECTOR_COUNT * SectorSize) + { + uint64 limit = TC_MAX_FAT_SECTOR_COUNT * SectorSize / BYTES_PER_TB; + wstring err = StringFormatter (_("Error: The hidden volume to be created is larger than {0} TB ({1} GB).\n\nPossible solutions:\n- Create a container/partition smaller than {0} TB.\n"), limit, limit * 1024); + + if (SectorSize < 4096) + { + err += _("- Use a drive with 4096-byte sectors to be able to create partition/device-hosted hidden volumes up to 16 TB in size"); +#if defined (TC_LINUX) + err += _(".\n"); +#else + err += _(" (not supported by components available on this platform).\n"); +#endif + } + + Gui->ShowError (err); + return GetCurrentStep(); + } + + if (SelectedVolumePath.IsDevice()) + { + wxString confirmMsg = LangString["OVERWRITEPROMPT_DEVICE"]; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!Gui->AskYesNo (wxString::Format (confirmMsg, wxString (_("DEVICE")).c_str(), wstring (SelectedVolumePath).c_str(), L""), false, true)) + return GetCurrentStep(); + } + else if (FilesystemPath (wstring (SelectedVolumePath)).IsFile()) + { + wxString confirmMsg = LangString["OVERWRITEPROMPT"]; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (SelectedVolumePath).c_str(), false, true))) + return GetCurrentStep(); + } + } + + AbortRequested = false; + AbortConfirmationPending = false; + CreationAborted = false; + SetWorkInProgress (true); + UpdateControls(); + + Gui->BeginInteractiveBusyState (this); + + try + { + make_shared_auto (VolumeCreationOptions, options); + + options->Filesystem = SelectedFilesystemType; + options->FilesystemClusterSize = SelectedFilesystemClusterSize; + options->SectorSize = SectorSize; + options->EA = SelectedEncryptionAlgorithm; + options->Password = Password; + options->Keyfiles = Keyfiles; + options->Path = SelectedVolumePath; + options->Quick = QuickFormatEnabled; + options->Size = VolumeSize; + options->Type = OuterVolume ? VolumeType::Normal : SelectedVolumeType; + options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash); + + Creator.reset (new VolumeCreator); + Creator->CreateVolume (options); + + page->SetKeyInfo (Creator->GetKeyInfo()); + + class Timer : public wxTimer + { + public: + Timer (VolumeCreationWizard *wizard) : Wizard (wizard) { } + + void Notify() + { + Wizard->OnProgressTimer(); + } + + VolumeCreationWizard *Wizard; + }; + + page->SetProgressRange (options->Size); + page->SetProgressState (true); + ProgressTimer.reset (dynamic_cast (new Timer (this))); + ProgressTimer->Start (50); + } + catch (Exception &e) + { + CreationAborted = true; + OnVolumeCreatorFinished(); + Gui->ShowError (e); + } + } + + return GetCurrentStep(); + } + + case Step::VolumeCreatedInfo: + Creator.reset(); + SetCancelButtonText (L""); + + return Step::VolumeHostType; + + case Step::OuterVolumeContents: + try + { + // Determine maximum size of the hidden volume. Scan cluster table offline as a live filesystem test would + // require using FUSE and loop device which cannot be used for devices with sectors larger than 512. + + wxBusyCursor busy; + MaxHiddenVolumeSize = 0; + + Gui->SetActiveFrame (this); + + if (MountedOuterVolume) + { + Core->DismountVolume (MountedOuterVolume); + MountedOuterVolume.reset(); + } + +#ifdef TC_UNIX + // Temporarily take ownership of a device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + if (!Core->HasAdminPrivileges() && SelectedVolumePath.IsDevice()) + { + origDeviceOwner = FilesystemPath (wstring (SelectedVolumePath)).GetOwner(); + Core->SetFileOwner (SelectedVolumePath, UserId (getuid())); + } + + finally_do_arg2 (FilesystemPath, SelectedVolumePath, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); +#endif + + shared_ptr outerVolume = Core->OpenVolume (make_shared (SelectedVolumePath), true, Password, Keyfiles, VolumeProtection::ReadOnly); + MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume); + + // Add a reserve (in case the user mounts the outer volume and creates new files + // on it by accident or OS writes some new data behind his or her back, such as + // System Restore etc.) + + uint64 reservedSize = outerVolume->GetSize() / 200; + if (reservedSize > 10 * BYTES_PER_MB) + reservedSize = 10 * BYTES_PER_MB; + + if (MaxHiddenVolumeSize < reservedSize) + MaxHiddenVolumeSize = 0; + else + MaxHiddenVolumeSize -= reservedSize; + + MaxHiddenVolumeSize -= MaxHiddenVolumeSize % outerVolume->GetSectorSize(); // Must be a multiple of the sector size + } + catch (exception &e) + { + Gui->SetActiveFrame (this); + Gui->ShowError (e); + return GetCurrentStep(); + } + + return Step::HiddenVolume; + + case Step::HiddenVolume: + return Step::EncryptionOptions; + + default: + throw ParameterIncorrect (SRC_POS); + } + } + + void VolumeCreationWizard::UpdateControls () + { + VolumeCreationProgressWizardPage *page = dynamic_cast (GetCurrentPage()); + if (page) + { + page->EnableAbort (IsWorkInProgress()); + } + } + + bool VolumeCreationWizard::DeviceWarningConfirmed; +} diff --git a/src/Main/Forms/VolumeCreationWizard.h b/src/Main/Forms/VolumeCreationWizard.h new file mode 100644 index 00000000..fb2a8ddd --- /dev/null +++ b/src/Main/Forms/VolumeCreationWizard.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumeCreationWizard +#define TC_HEADER_Main_Forms_VolumeCreationWizard + +#include "WizardFrame.h" +#include "Core/VolumeCreator.h" + +namespace TrueCrypt +{ + class VolumeCreationWizard : public WizardFrame + { + public: + VolumeCreationWizard (wxWindow* parent); + ~VolumeCreationWizard (); + + protected: + struct Step + { + enum Enum + { + VolumeHostType, + VolumeType, + VolumeLocation, + EncryptionOptions, + VolumeSize, + VolumePassword, + LargeFilesSupport, + FormatOptions, + CrossPlatformSupport, + CreationProgress, + VolumeCreatedInfo, + OuterVolumeContents, + HiddenVolume + }; + }; + + void CreateVolume (); + WizardPage *GetPage (WizardStep step); + void OnAbortButtonClick (EventArgs &args); + void OnMouseMotion (wxMouseEvent& event); + void OnProgressTimer (); + void OnRandomPoolUpdateTimer (); + void OnThreadExiting (wxCommandEvent& event); + void OnVolumeCreatorFinished (); + WizardStep ProcessPageChangeRequest (bool forward); + + volatile bool AbortConfirmationPending; + volatile bool AbortRequested; + volatile bool CreationAborted; + auto_ptr Creator; + bool CrossPlatformSupport; + static bool DeviceWarningConfirmed; + bool DisplayKeyInfo; + auto_ptr ProgressTimer; + auto_ptr RandomPoolUpdateTimer; + shared_ptr Keyfiles; + bool LargeFilesSupport; + uint64 MaxHiddenVolumeSize; + shared_ptr MountedOuterVolume; + bool OuterVolume; + bool QuickFormatEnabled; + shared_ptr SelectedEncryptionAlgorithm; + uint32 SelectedFilesystemClusterSize; + VolumeCreationOptions::FilesystemType::Enum SelectedFilesystemType; + VolumePath SelectedVolumePath; + VolumeHostType::Enum SelectedVolumeHostType; + VolumeType::Enum SelectedVolumeType; + shared_ptr Password; + uint32 SectorSize; + shared_ptr SelectedHash; + uint64 VolumeSize; + + private: + void UpdateControls (); + }; +} + +#endif // TC_HEADER_Main_Forms_VolumeCreationWizard diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp new file mode 100644 index 00000000..656c7626 --- /dev/null +++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.cpp @@ -0,0 +1,81 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "VolumeFormatOptionsWizardPage.h" + +namespace TrueCrypt +{ + VolumeFormatOptionsWizardPage::VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 volumeSize, uint32 sectorSize, bool enableQuickFormatButton, bool disableNoneFilesystem, bool disable32bitFilesystems) + : VolumeFormatOptionsWizardPageBase (parent) + { + InfoStaticText->SetLabel (_( + "In order to enable your operating system to mount your new volume, it has to be formatted with a filesystem. Please select a filesystem type.\n\nIf your volume is going to be hosted on a device or partition, you can use 'Quick format' to skip encryption of free space of the volume.")); + + if (!disableNoneFilesystem) + FilesystemTypeChoice->Append (LangString["NONE"], (void *) VolumeCreationOptions::FilesystemType::None); + + if (!disable32bitFilesystems && volumeSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize) + FilesystemTypeChoice->Append (L"FAT", (void *) VolumeCreationOptions::FilesystemType::FAT); + +#ifdef TC_WINDOWS + FilesystemTypeChoice->Append (L"NTFS", (void *) VolumeCreationOptions::FilesystemType::NTFS); +#elif defined (TC_LINUX) + FilesystemTypeChoice->Append (L"Linux Ext2", (void *) VolumeCreationOptions::FilesystemType::Ext2); + FilesystemTypeChoice->Append (L"Linux Ext3", (void *) VolumeCreationOptions::FilesystemType::Ext3); + FilesystemTypeChoice->Append (L"Linux Ext4", (void *) VolumeCreationOptions::FilesystemType::Ext4); +#elif defined (TC_MACOSX) + FilesystemTypeChoice->Append (L"Mac OS Extended", (void *) VolumeCreationOptions::FilesystemType::MacOsExt); +#elif defined (TC_FREEBSD) || defined (TC_SOLARIS) + FilesystemTypeChoice->Append (L"UFS", (void *) VolumeCreationOptions::FilesystemType::UFS); +#endif + + if (!disable32bitFilesystems && volumeSize <= TC_MAX_FAT_SECTOR_COUNT * sectorSize) + SetFilesystemType (VolumeCreationOptions::FilesystemType::FAT); + else + SetFilesystemType (VolumeCreationOptions::FilesystemType::GetPlatformNative()); + + QuickFormatCheckBox->Enable (enableQuickFormatButton); + } + + VolumeCreationOptions::FilesystemType::Enum VolumeFormatOptionsWizardPage::GetFilesystemType () const + { + return (VolumeCreationOptions::FilesystemType::Enum) reinterpret_cast (Gui->GetSelectedData (FilesystemTypeChoice)); + } + + void VolumeFormatOptionsWizardPage::OnFilesystemTypeSelected (wxCommandEvent& event) + { + } + + void VolumeFormatOptionsWizardPage::OnQuickFormatCheckBoxClick (wxCommandEvent& event) + { + if (event.IsChecked()) + { + QuickFormatCheckBox->SetValue (Gui->AskYesNo (LangString["WARN_QUICK_FORMAT"], false, true)); + } + } + + void VolumeFormatOptionsWizardPage::SetFilesystemType (VolumeCreationOptions::FilesystemType::Enum type) + { + switch (type) + { + case VolumeCreationOptions::FilesystemType::None: FilesystemTypeChoice->SetStringSelection (LangString["NONE"]); break; + case VolumeCreationOptions::FilesystemType::FAT: FilesystemTypeChoice->SetStringSelection (L"FAT"); break; + case VolumeCreationOptions::FilesystemType::NTFS: FilesystemTypeChoice->SetStringSelection (L"NTFS"); break; + case VolumeCreationOptions::FilesystemType::Ext2: FilesystemTypeChoice->SetStringSelection (L"Linux Ext2"); break; + case VolumeCreationOptions::FilesystemType::Ext3: FilesystemTypeChoice->SetStringSelection (L"Linux Ext3"); break; + case VolumeCreationOptions::FilesystemType::Ext4: FilesystemTypeChoice->SetStringSelection (L"Linux Ext4"); break; + case VolumeCreationOptions::FilesystemType::MacOsExt: FilesystemTypeChoice->SetStringSelection (L"Mac OS Extended"); break; + case VolumeCreationOptions::FilesystemType::UFS: FilesystemTypeChoice->SetStringSelection (L"UFS"); break; + + default: + throw ParameterIncorrect (SRC_POS); + } + } +} diff --git a/src/Main/Forms/VolumeFormatOptionsWizardPage.h b/src/Main/Forms/VolumeFormatOptionsWizardPage.h new file mode 100644 index 00000000..ae724c66 --- /dev/null +++ b/src/Main/Forms/VolumeFormatOptionsWizardPage.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumeFormatOptionsWizardPage +#define TC_HEADER_Main_Forms_VolumeFormatOptionsWizardPage + +#include "Forms.h" +#include "Core/VolumeCreator.h" + +namespace TrueCrypt +{ + class VolumeFormatOptionsWizardPage : public VolumeFormatOptionsWizardPageBase + { + public: + VolumeFormatOptionsWizardPage (wxPanel* parent, uint64 volumeSize, uint32 sectorSize, bool enableQuickFormatButton = true, bool disableNoneFilesystem = false, bool disable32bitFilesystems = false); + + VolumeCreationOptions::FilesystemType::Enum GetFilesystemType () const; + bool IsValid () { return true; } + bool IsQuickFormatEnabled () const { return QuickFormatCheckBox->IsChecked(); } + void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } + void SetFilesystemType (VolumeCreationOptions::FilesystemType::Enum type); + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + void SetQuickFormat (bool enabled) { QuickFormatCheckBox->SetValue (enabled); } + + protected: + void OnFilesystemTypeSelected (wxCommandEvent& event); + void OnQuickFormatCheckBoxClick (wxCommandEvent& event); + }; +} + +#endif // TC_HEADER_Main_Forms_VolumeFormatOptionsWizardPage diff --git a/src/Main/Forms/VolumeLocationWizardPage.cpp b/src/Main/Forms/VolumeLocationWizardPage.cpp new file mode 100644 index 00000000..c3992827 --- /dev/null +++ b/src/Main/Forms/VolumeLocationWizardPage.cpp @@ -0,0 +1,98 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Main/VolumeHistory.h" +#include "VolumeLocationWizardPage.h" + +namespace TrueCrypt +{ + VolumeLocationWizardPage::VolumeLocationWizardPage (wxPanel* parent, VolumeHostType::Enum hostType, bool selectExisting) + : VolumeLocationWizardPageBase (parent), + SelectExisting (selectExisting) + { + switch (hostType) + { + case VolumeHostType::Device: + SelectFileButton->Show (false); + break; + + case VolumeHostType::File: + SelectDeviceButton->Show (false); + break; + + default: + break; + } + + Gui->PreferencesUpdatedEvent.Connect (EventConnector (this, &VolumeLocationWizardPage::OnPreferencesUpdated)); + VolumeHistory::ConnectComboBox (VolumePathComboBox); + + NoHistoryCheckBox->SetValue (!Gui->GetPreferences().SaveHistory); + } + + VolumeLocationWizardPage::~VolumeLocationWizardPage () + { + Gui->PreferencesUpdatedEvent.Disconnect (this); + VolumeHistory::DisconnectComboBox (VolumePathComboBox); + } + + void VolumeLocationWizardPage::OnNoHistoryCheckBoxClick (wxCommandEvent& event) + { + UserPreferences prefs = Gui->GetPreferences(); + prefs.SaveHistory = !event.IsChecked(); + Gui->SetPreferences (prefs); + + if (event.IsChecked()) + { + try + { + VolumeHistory::Clear(); + } + catch (exception &e) { Gui->ShowError (e); } + } + } + + void VolumeLocationWizardPage::OnPageChanging (bool forward) + { + if (forward) + { + VolumePath path = GetVolumePath(); + if (!path.IsEmpty()) + VolumeHistory::Add (path); + } + } + + void VolumeLocationWizardPage::OnPreferencesUpdated (EventArgs &args) + { + NoHistoryCheckBox->SetValue (!Gui->GetPreferences().SaveHistory); + } + + void VolumeLocationWizardPage::OnSelectFileButtonClick (wxCommandEvent& event) + { + FilePath path = Gui->SelectVolumeFile (this, !SelectExisting); + + if (!path.IsEmpty()) + SetVolumePath (path); + } + + void VolumeLocationWizardPage::OnSelectDeviceButtonClick (wxCommandEvent& event) + { + DevicePath path = Gui->SelectDevice (this); + + if (!path.IsEmpty()) + SetVolumePath (path); + } + + void VolumeLocationWizardPage::SetVolumePath (const VolumePath &path) + { + VolumePathComboBox->SetValue (wstring (path)); + PageUpdatedEvent.Raise(); + } +} diff --git a/src/Main/Forms/VolumeLocationWizardPage.h b/src/Main/Forms/VolumeLocationWizardPage.h new file mode 100644 index 00000000..8634f239 --- /dev/null +++ b/src/Main/Forms/VolumeLocationWizardPage.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumeLocationWizardPage +#define TC_HEADER_Main_Forms_VolumeLocationWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class VolumeLocationWizardPage : public VolumeLocationWizardPageBase + { + public: + VolumeLocationWizardPage (wxPanel* parent, VolumeHostType::Enum hostType = VolumeHostType::Unknown, bool selectExisting = false); + ~VolumeLocationWizardPage (); + + VolumePath GetVolumePath () const { return VolumePath (wstring (VolumePathComboBox->GetValue())); } + bool IsValid () { return !VolumePathComboBox->GetValue().IsEmpty(); } + void OnPageChanging (bool forward); + void SetVolumePath (const VolumePath &path); + void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + + protected: + void OnVolumePathTextChanged (wxCommandEvent& event) { PageUpdatedEvent.Raise(); } + void OnNoHistoryCheckBoxClick (wxCommandEvent& event); + void OnSelectDeviceButtonClick (wxCommandEvent& event); + void OnSelectFileButtonClick (wxCommandEvent& event); + void OnPreferencesUpdated (EventArgs &args); + + bool SelectExisting; + }; +} + +#endif // TC_HEADER_Main_Forms_VolumeLocationWizardPage diff --git a/src/Main/Forms/VolumePasswordPanel.cpp b/src/Main/Forms/VolumePasswordPanel.cpp new file mode 100644 index 00000000..25767f96 --- /dev/null +++ b/src/Main/Forms/VolumePasswordPanel.cpp @@ -0,0 +1,310 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "KeyfilesDialog.h" +#include "VolumePasswordPanel.h" +#include "SecurityTokenKeyfilesDialog.h" + +namespace TrueCrypt +{ + VolumePasswordPanel::VolumePasswordPanel (wxWindow* parent, shared_ptr password, shared_ptr keyfiles, bool enableCache, bool enablePassword, bool enableKeyfiles, bool enableConfirmation, bool enablePkcs5Prf, const wxString &passwordLabel) + : VolumePasswordPanelBase (parent), Keyfiles (new KeyfileList) + { + if (keyfiles) + { + *Keyfiles = *keyfiles; + UseKeyfilesCheckBox->SetValue (!Keyfiles->empty()); + } + else + { + *Keyfiles = Gui->GetPreferences().DefaultKeyfiles; + UseKeyfilesCheckBox->SetValue (Gui->GetPreferences().UseKeyfiles && !Keyfiles->empty()); + } + + PasswordTextCtrl->SetMaxLength (VolumePassword::MaxSize); + ConfirmPasswordTextCtrl->SetMaxLength (VolumePassword::MaxSize); + + if (!passwordLabel.empty()) + { + PasswordStaticText->SetLabel (passwordLabel); + GridBagSizer->Detach (PasswordStaticText); + GridBagSizer->Add (PasswordStaticText, wxGBPosition (0, 1), wxGBSpan (1, 1), wxALIGN_CENTER_VERTICAL | wxBOTTOM, Gui->GetDefaultBorderSize()); + } + + CacheCheckBox->Show (enableCache); + + if (!enablePassword && enableKeyfiles) + { + Layout(); + Fit(); + PasswordPlaceholderSizer->SetMinSize (wxSize (PasswordTextCtrl->GetSize().GetWidth(), -1)); + } + else if (!enablePkcs5Prf) + { + GridBagSizer->Remove (PasswordPlaceholderSizer); + } + + PasswordStaticText->Show (enablePassword); + PasswordTextCtrl->Show (enablePassword); + DisplayPasswordCheckBox->Show (enablePassword); + + ConfirmPasswordStaticText->Show (enableConfirmation); + ConfirmPasswordTextCtrl->Show (enableConfirmation); + + UseKeyfilesCheckBox->Show (enableKeyfiles); + KeyfilesButton->Show (enableKeyfiles); + + Pkcs5PrfStaticText->Show (enablePkcs5Prf); + Pkcs5PrfChoice->Show (enablePkcs5Prf); + + if (enablePkcs5Prf) + { + foreach_ref (const Pkcs5Kdf &kdf, Pkcs5Kdf::GetAvailableAlgorithms()) + { + if (!kdf.IsDeprecated()) + Pkcs5PrfChoice->Append (kdf.GetName()); + } + Pkcs5PrfChoice->Select (0); + } + + if (!enablePkcs5Prf || (!enablePassword && !enableKeyfiles)) + { + GridBagSizer->Remove (Pkcs5PrfSizer); + } + + // Keyfiles drag & drop + class FileDropTarget : public wxFileDropTarget + { + public: + FileDropTarget (VolumePasswordPanel *panel) : Panel (panel) { } + + wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def) + { + return wxDragLink; + } + + bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames) + { + foreach (const wxString &f, filenames) + Panel->AddKeyfile (make_shared (wstring (f))); + + return true; + } + + protected: + VolumePasswordPanel *Panel; + }; + + if (enableKeyfiles) + { + SetDropTarget (new FileDropTarget (this)); +#ifdef TC_MACOSX + foreach (wxWindow *c, GetChildren()) + c->SetDropTarget (new FileDropTarget (this)); +#endif + } + + Layout(); + Fit(); + } + + VolumePasswordPanel::~VolumePasswordPanel () + { + WipeTextCtrl (PasswordTextCtrl); + WipeTextCtrl (ConfirmPasswordTextCtrl); + } + + void VolumePasswordPanel::AddKeyfile (shared_ptr keyfile) + { + if (!Keyfiles) + Keyfiles.reset (new KeyfileList); + + Keyfiles->push_back (keyfile); + UseKeyfilesCheckBox->SetValue (true); + } + + void VolumePasswordPanel::DisplayPassword (bool display, wxTextCtrl **textCtrl, int row) + { + FreezeScope freeze (this); + + wxTextCtrl *newTextCtrl = new wxTextCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, display ? 0 : wxTE_PASSWORD); + newTextCtrl->SetMaxLength (VolumePassword::MaxSize); + newTextCtrl->SetValue ((*textCtrl)->GetValue()); + newTextCtrl->SetMinSize ((*textCtrl)->GetSize()); + + GridBagSizer->Detach ((*textCtrl)); + GridBagSizer->Add (newTextCtrl, wxGBPosition (row, 1), wxGBSpan (1, 2), wxEXPAND|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 5); + (*textCtrl)->Show (false); + WipeTextCtrl (*textCtrl); + + Fit(); + Layout(); + newTextCtrl->SetMinSize ((*textCtrl)->GetMinSize()); + + newTextCtrl->Connect (wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (VolumePasswordPanel::OnTextChanged), nullptr, this); + *textCtrl = newTextCtrl; + } + + shared_ptr VolumePasswordPanel::GetPassword () const + { + return GetPassword (PasswordTextCtrl); + } + + shared_ptr VolumePasswordPanel::GetPassword (wxTextCtrl *textCtrl) const + { + shared_ptr password; + wchar_t passwordBuf[VolumePassword::MaxSize + 1]; + finally_do_arg (BufferPtr, BufferPtr (reinterpret_cast (passwordBuf), sizeof (passwordBuf)), { finally_arg.Erase(); }); + +#ifdef TC_WINDOWS + int len = GetWindowText (static_cast (textCtrl->GetHandle()), passwordBuf, VolumePassword::MaxSize + 1); + password.reset (new VolumePassword (passwordBuf, len)); +#else + wxString passwordStr (textCtrl->GetValue()); // A copy of the password is created here by wxWidgets, which cannot be erased + for (size_t i = 0; i < passwordStr.size() && i < VolumePassword::MaxSize; ++i) + { + passwordBuf[i] = (wchar_t) passwordStr[i]; + passwordStr[i] = L'X'; + } + password.reset (new VolumePassword (passwordBuf, passwordStr.size() <= VolumePassword::MaxSize ? passwordStr.size() : VolumePassword::MaxSize)); +#endif + return password; + } + + shared_ptr VolumePasswordPanel::GetPkcs5Kdf () const + { + try + { + return Pkcs5Kdf::GetAlgorithm (wstring (Pkcs5PrfChoice->GetStringSelection())); + } + catch (ParameterIncorrect&) + { + return shared_ptr (); + } + } + + void VolumePasswordPanel::OnAddKeyfileDirMenuItemSelected (wxCommandEvent& event) + { + try + { + DirectoryPath dir = Gui->SelectDirectory (this, LangString["SELECT_KEYFILE_PATH"]); + + if (!dir.IsEmpty()) + { + Keyfiles->push_back (make_shared (dir)); + + UseKeyfilesCheckBox->SetValue (!Keyfiles->empty()); + OnUpdate(); + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void VolumePasswordPanel::OnAddKeyfilesMenuItemSelected (wxCommandEvent& event) + { + try + { + FilePathList files = Gui->SelectFiles (this, LangString["SELECT_KEYFILES"], false, true); + + if (!files.empty()) + { + foreach_ref (const FilePath &f, files) + Keyfiles->push_back (make_shared (f)); + + UseKeyfilesCheckBox->SetValue (!Keyfiles->empty()); + OnUpdate(); + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void VolumePasswordPanel::OnAddSecurityTokenSignatureMenuItemSelected (wxCommandEvent& event) + { + try + { + SecurityTokenKeyfilesDialog dialog (this); + if (dialog.ShowModal() == wxID_OK) + { + foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) + { + Keyfiles->push_back (make_shared (wstring (path))); + } + + if (!dialog.GetSelectedSecurityTokenKeyfilePaths().empty()) + { + UseKeyfilesCheckBox->SetValue (!Keyfiles->empty()); + OnUpdate(); + } + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + } + + void VolumePasswordPanel::OnDisplayPasswordCheckBoxClick (wxCommandEvent& event) + { + DisplayPassword (event.IsChecked(), &PasswordTextCtrl, 1); + + if (ConfirmPasswordTextCtrl->IsShown()) + DisplayPassword (event.IsChecked(), &ConfirmPasswordTextCtrl, 2); + + OnUpdate(); + } + + void VolumePasswordPanel::OnKeyfilesButtonClick (wxCommandEvent& event) + { + KeyfilesDialog dialog (GetParent(), Keyfiles); + + if (dialog.ShowModal() == wxID_OK) + { + Keyfiles = dialog.GetKeyfiles(); + + UseKeyfilesCheckBox->SetValue (!Keyfiles->empty()); + OnUpdate(); + } + } + + void VolumePasswordPanel::OnKeyfilesButtonRightClick (wxMouseEvent& event) + { + wxMenu popup; + Gui->AppendToMenu (popup, LangString["IDC_KEYADD"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddKeyfilesMenuItemSelected)); + Gui->AppendToMenu (popup, LangString["IDC_ADD_KEYFILE_PATH"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddKeyfileDirMenuItemSelected)); + Gui->AppendToMenu (popup, LangString["IDC_TOKEN_FILES_ADD"], this, wxCommandEventHandler (VolumePasswordPanel::OnAddSecurityTokenSignatureMenuItemSelected)); + + PopupMenu (&popup, KeyfilesButton->GetPosition().x + 2, KeyfilesButton->GetPosition().y + 2); + } + + void VolumePasswordPanel::OnKeyfilesButtonRightDown (wxMouseEvent& event) + { +#ifndef TC_MACOSX + event.Skip(); +#endif + } + + bool VolumePasswordPanel::PasswordsMatch () const + { + assert (ConfirmPasswordStaticText->IsShown()); + return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl); + } + + void VolumePasswordPanel::WipeTextCtrl (wxTextCtrl *textCtrl) + { + textCtrl->SetValue (wxString (L'X', textCtrl->GetLineLength(0))); + GetPassword (textCtrl); + } +} diff --git a/src/Main/Forms/VolumePasswordPanel.h b/src/Main/Forms/VolumePasswordPanel.h new file mode 100644 index 00000000..8488cbd1 --- /dev/null +++ b/src/Main/Forms/VolumePasswordPanel.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_PasswordPanel +#define TC_HEADER_Main_Forms_PasswordPanel + +#include "Forms.h" +#include "Platform/Functor.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class VolumePasswordPanel : public VolumePasswordPanelBase + { + public: + VolumePasswordPanel (wxWindow* parent, shared_ptr password, shared_ptr keyfiles, bool enableCache = false, bool enablePassword = true, bool enableKeyfiles = true, bool enableConfirmation = false, bool enablePkcs5Prf = false, const wxString &passwordLabel = wxString()); + virtual ~VolumePasswordPanel (); + + void AddKeyfile (shared_ptr keyfile); + shared_ptr GetKeyfiles () const { return UseKeyfilesCheckBox->IsChecked() ? Keyfiles : shared_ptr (); } + shared_ptr GetPassword () const; + shared_ptr GetPkcs5Kdf () const; + void SetCacheCheckBoxValidator (const wxGenericValidator &validator) { CacheCheckBox->SetValidator (validator); } + void SetFocusToPasswordTextCtrl () { PasswordTextCtrl->SetSelection (-1, -1); PasswordTextCtrl->SetFocus(); } + bool PasswordsMatch () const; + + Event UpdateEvent; + + protected: + void DisplayPassword (bool display, wxTextCtrl **textCtrl, int row); + shared_ptr GetPassword (wxTextCtrl *textCtrl) const; + void OnAddKeyfileDirMenuItemSelected (wxCommandEvent& event); + void OnAddKeyfilesMenuItemSelected (wxCommandEvent& event); + void OnAddSecurityTokenSignatureMenuItemSelected (wxCommandEvent& event); + void OnDisplayPasswordCheckBoxClick (wxCommandEvent& event); + void OnKeyfilesButtonClick (wxCommandEvent& event); + void OnKeyfilesButtonRightClick (wxMouseEvent& event); + void OnKeyfilesButtonRightDown (wxMouseEvent& event); + void OnTextChanged (wxCommandEvent& event) { OnUpdate(); } + void OnUpdate () { UpdateEvent.Raise(); } + void OnUseKeyfilesCheckBoxClick (wxCommandEvent& event) { OnUpdate(); } + void WipeTextCtrl (wxTextCtrl *textCtrl); + + shared_ptr Keyfiles; + shared_ptr UpdateCallback; + }; +} + +#endif // TC_HEADER_Main_Forms_PasswordPanel diff --git a/src/Main/Forms/VolumePasswordWizardPage.cpp b/src/Main/Forms/VolumePasswordWizardPage.cpp new file mode 100644 index 00000000..fd4eaf2c --- /dev/null +++ b/src/Main/Forms/VolumePasswordWizardPage.cpp @@ -0,0 +1,39 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "VolumePasswordWizardPage.h" + +namespace TrueCrypt +{ + VolumePasswordWizardPage::VolumePasswordWizardPage (wxPanel* parent, shared_ptr password, shared_ptr keyfiles, bool enableConfirmation) + : VolumePasswordWizardPageBase (parent), ConfirmationMode (enableConfirmation) + { + PasswordPanel = new VolumePasswordPanel (this, password, keyfiles, false, true, true, enableConfirmation); + PasswordPanel->UpdateEvent.Connect (EventConnector (this, &VolumePasswordWizardPage::OnPasswordPanelUpdate)); + + PasswordPanelSizer->Add (PasswordPanel, 1, wxALL | wxEXPAND); + } + + VolumePasswordWizardPage::~VolumePasswordWizardPage () + { + PasswordPanel->UpdateEvent.Disconnect (this); + } + + bool VolumePasswordWizardPage::IsValid () + { + if (ConfirmationMode && !PasswordPanel->PasswordsMatch()) + return false; + + shared_ptr keyfiles (GetKeyfiles()); + shared_ptr password (GetPassword()); + + return (password && !GetPassword()->IsEmpty()) || (keyfiles && !keyfiles->empty()); + } +} diff --git a/src/Main/Forms/VolumePasswordWizardPage.h b/src/Main/Forms/VolumePasswordWizardPage.h new file mode 100644 index 00000000..d26cc010 --- /dev/null +++ b/src/Main/Forms/VolumePasswordWizardPage.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumePasswordWizardPage +#define TC_HEADER_Main_Forms_VolumePasswordWizardPage + +#include "Forms.h" +#include "VolumePasswordPanel.h" + +namespace TrueCrypt +{ + class VolumePasswordWizardPage : public VolumePasswordWizardPageBase + { + public: + VolumePasswordWizardPage (wxPanel* parent, shared_ptr password, shared_ptr keyfiles, bool enableConfirmation = true); + ~VolumePasswordWizardPage (); + + shared_ptr GetKeyfiles () const { return PasswordPanel->GetKeyfiles(); } + shared_ptr GetPassword () const { return PasswordPanel->GetPassword(); } + bool IsValid (); + void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + + protected: + void OnPasswordPanelUpdate (EventArgs &args) { PageUpdatedEvent.Raise(); } + + bool ConfirmationMode; + VolumePasswordPanel *PasswordPanel; + }; +} + +#endif // TC_HEADER_Main_Forms_VolumePasswordWizardPage diff --git a/src/Main/Forms/VolumePropertiesDialog.cpp b/src/Main/Forms/VolumePropertiesDialog.cpp new file mode 100644 index 00000000..65685ba0 --- /dev/null +++ b/src/Main/Forms/VolumePropertiesDialog.cpp @@ -0,0 +1,97 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/Main.h" +#include "Main/GraphicUserInterface.h" +#include "VolumePropertiesDialog.h" + +namespace TrueCrypt +{ + VolumePropertiesDialog::VolumePropertiesDialog (wxWindow* parent, const VolumeInfo &volumeInfo) + : VolumePropertiesDialogBase (parent) + { + list colPermilles; + + PropertiesListCtrl->InsertColumn (0, LangString["PROPERTY"], wxLIST_FORMAT_LEFT, 208); + colPermilles.push_back (500); + PropertiesListCtrl->InsertColumn (1, LangString["VALUE"], wxLIST_FORMAT_LEFT, 192); + colPermilles.push_back (500); + + Gui->SetListCtrlWidth (PropertiesListCtrl, 70, false); + Gui->SetListCtrlHeight (PropertiesListCtrl, 17); + Gui->SetListCtrlColumnWidths (PropertiesListCtrl, colPermilles, false); + + AppendToList ("LOCATION", wstring (volumeInfo.Path)); +#ifndef TC_WINDOWS + AppendToList ("VIRTUAL_DEVICE", wstring (volumeInfo.VirtualDevice)); +#endif + AppendToList ("SIZE", Gui->SizeToString (volumeInfo.Size)); + AppendToList ("TYPE", Gui->VolumeTypeToString (volumeInfo.Type, volumeInfo.Protection)); + AppendToList ("READ_ONLY", LangString [volumeInfo.Protection == VolumeProtection::ReadOnly ? "UISTR_YES" : "UISTR_NO"]); + + wxString protection; + if (volumeInfo.Type == VolumeType::Hidden) + protection = LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"]; + else if (volumeInfo.HiddenVolumeProtectionTriggered) + protection = LangString["HID_VOL_DAMAGE_PREVENTED"]; + else + protection = LangString [volumeInfo.Protection == VolumeProtection::HiddenVolumeReadOnly ? "UISTR_YES" : "UISTR_NO"]; + + AppendToList ("HIDDEN_VOL_PROTECTION", protection); + AppendToList ("ENCRYPTION_ALGORITHM", volumeInfo.EncryptionAlgorithmName); + AppendToList ("KEY_SIZE", StringFormatter (L"{0} {1}", volumeInfo.EncryptionAlgorithmKeySize * 8, LangString ["BITS"])); + + if (volumeInfo.EncryptionModeName == L"XTS") + AppendToList ("SECONDARY_KEY_SIZE_XTS", StringFormatter (L"{0} {1}", volumeInfo.EncryptionAlgorithmKeySize * 8, LangString ["BITS"])); + + wstringstream blockSize; + blockSize << volumeInfo.EncryptionAlgorithmBlockSize * 8; + if (volumeInfo.EncryptionAlgorithmBlockSize != volumeInfo.EncryptionAlgorithmMinBlockSize) + blockSize << L"/" << volumeInfo.EncryptionAlgorithmMinBlockSize * 8; + + AppendToList ("BLOCK_SIZE", blockSize.str() + L" " + LangString ["BITS"]); + AppendToList ("MODE_OF_OPERATION", volumeInfo.EncryptionModeName); + AppendToList ("PKCS5_PRF", volumeInfo.Pkcs5PrfName); + +#if 0 + AppendToList ("PKCS5_ITERATIONS", StringConverter::FromNumber (volumeInfo.Pkcs5IterationCount)); + AppendToList ("VOLUME_CREATE_DATE", Gui->VolumeTimeToString (volumeInfo.VolumeCreationTime)); + AppendToList ("VOLUME_HEADER_DATE", Gui->VolumeTimeToString (volumeInfo.HeaderCreationTime)); +#endif + + AppendToList ("VOLUME_FORMAT_VERSION", StringConverter::ToWide (volumeInfo.MinRequiredProgramVersion < 0x600 ? 1 : 2)); + AppendToList ("BACKUP_HEADER", LangString[volumeInfo.MinRequiredProgramVersion >= 0x600 ? "UISTR_YES" : "UISTR_NO"]); + +#ifdef TC_LINUX + if (string (volumeInfo.VirtualDevice).find ("/dev/mapper/truecrypt") != 0) + { +#endif + AppendToList ("TOTAL_DATA_READ", Gui->SizeToString (volumeInfo.TotalDataRead)); + AppendToList ("TOTAL_DATA_WRITTEN", Gui->SizeToString (volumeInfo.TotalDataWritten)); +#ifdef TC_LINUX + } +#endif + + Layout(); + Fit(); + Center(); + + StdButtonsOK->SetDefault(); + } + + void VolumePropertiesDialog::AppendToList (const string &name, const wxString &value) + { + vector fields (PropertiesListCtrl->GetColumnCount()); + + fields[0] = LangString[name]; + fields[1] = value; + + Gui->AppendToListCtrl (PropertiesListCtrl, fields); + } +} diff --git a/src/Main/Forms/VolumePropertiesDialog.h b/src/Main/Forms/VolumePropertiesDialog.h new file mode 100644 index 00000000..d651b6b5 --- /dev/null +++ b/src/Main/Forms/VolumePropertiesDialog.h @@ -0,0 +1,26 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumePropertiesDialog +#define TC_HEADER_Main_Forms_VolumePropertiesDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class VolumePropertiesDialog : public VolumePropertiesDialogBase + { + public: + VolumePropertiesDialog (wxWindow* parent, const VolumeInfo &volumeInfo); + + void AppendToList (const string &name, const wxString &value); + }; +} + +#endif // TC_HEADER_Main_Forms_VolumePropertiesDialog diff --git a/src/Main/Forms/VolumeSizeWizardPage.cpp b/src/Main/Forms/VolumeSizeWizardPage.cpp new file mode 100644 index 00000000..42abfbe6 --- /dev/null +++ b/src/Main/Forms/VolumeSizeWizardPage.cpp @@ -0,0 +1,137 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "VolumeSizeWizardPage.h" + +namespace TrueCrypt +{ + VolumeSizeWizardPage::VolumeSizeWizardPage (wxPanel* parent, const VolumePath &volumePath, uint32 sectorSize, const wxString &freeSpaceText) + : VolumeSizeWizardPageBase (parent), + MaxVolumeSize (0), + MaxVolumeSizeValid (false), + MinVolumeSize (1), + SectorSize (sectorSize) + { + VolumeSizePrefixChoice->Append (LangString["KB"], reinterpret_cast (1024)); + VolumeSizePrefixChoice->Append (LangString["MB"], reinterpret_cast (1024 * 1024)); + VolumeSizePrefixChoice->Append (LangString["GB"], reinterpret_cast (1024 * 1024 * 1024)); + VolumeSizePrefixChoice->Select (Prefix::MB); + + wxLongLong diskSpace = 0; + if (!wxGetDiskSpace (wxFileName (wstring (volumePath)).GetPath(), nullptr, &diskSpace)) + { + VolumeSizeTextCtrl->Disable(); + VolumeSizeTextCtrl->SetValue (L""); + } + + FreeSpaceStaticText->SetFont (Gui->GetDefaultBoldFont (this)); + + if (!freeSpaceText.empty()) + { + FreeSpaceStaticText->SetLabel (freeSpaceText); + } + else + { +#ifdef TC_WINDOWS + wxString drive = wxFileName (wstring (volumePath)).GetVolume(); + if (!drive.empty()) + { + FreeSpaceStaticText->SetLabel (StringFormatter (_("Free space on drive {0}: is {1}."), + drive, Gui->SizeToString (diskSpace.GetValue()))); + } + else +#endif + { + FreeSpaceStaticText->SetLabel (StringFormatter (_("Free space available: {0}"), + Gui->SizeToString (diskSpace.GetValue()))); + } + } + + VolumeSizeTextCtrl->SetMinSize (wxSize (Gui->GetCharWidth (VolumeSizeTextCtrl) * 20, -1)); + + wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST); // wxFILTER_NUMERIC does not exclude - . , etc. + const wxChar *valArr[] = { L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9" }; + validator.SetIncludes (wxArrayString (array_capacity (valArr), (const wxChar **) &valArr)); + VolumeSizeTextCtrl->SetValidator (validator); + } + + uint64 VolumeSizeWizardPage::GetVolumeSize () const + { + uint64 prefixMult = 1; + int selection = VolumeSizePrefixChoice->GetSelection(); + if (selection == wxNOT_FOUND) + return 0; + + prefixMult = reinterpret_cast (VolumeSizePrefixChoice->GetClientData (selection)); + + uint64 val = StringConverter::ToUInt64 (wstring (VolumeSizeTextCtrl->GetValue())); + if (val <= 0x7fffFFFFffffFFFFull / prefixMult) + { + val *= prefixMult; + + uint32 sectorSizeRem = val % SectorSize; + + if (sectorSizeRem != 0) + val += SectorSize - sectorSizeRem; + + return val; + } + else + return 0; + } + + bool VolumeSizeWizardPage::IsValid () + { + if (!VolumeSizeTextCtrl->IsEmpty() && Validate()) + { + try + { + if (GetVolumeSize() >= MinVolumeSize && (!MaxVolumeSizeValid || GetVolumeSize() <= MaxVolumeSize)) + return true; + } + catch (...) { } + } + return false; + } + + void VolumeSizeWizardPage::SetMaxStaticTextWidth (int width) + { + FreeSpaceStaticText->Wrap (width); + InfoStaticText->Wrap (width); + } + + void VolumeSizeWizardPage::SetVolumeSize (uint64 size) + { + if (size == 0) + { + VolumeSizePrefixChoice->Select (Prefix::MB); + VolumeSizeTextCtrl->SetValue (L""); + return; + } + + if (size % (1024 * 1024 * 1024) == 0) + { + size /= 1024 * 1024 * 1024; + VolumeSizePrefixChoice->Select (Prefix::GB); + } + else if (size % (1024 * 1024) == 0) + { + size /= 1024 * 1024; + VolumeSizePrefixChoice->Select (Prefix::MB); + } + else + { + size /= 1024; + VolumeSizePrefixChoice->Select (Prefix::KB); + } + + VolumeSizeTextCtrl->SetValue (StringConverter::FromNumber (size)); + } +} diff --git a/src/Main/Forms/VolumeSizeWizardPage.h b/src/Main/Forms/VolumeSizeWizardPage.h new file mode 100644 index 00000000..d6f19428 --- /dev/null +++ b/src/Main/Forms/VolumeSizeWizardPage.h @@ -0,0 +1,51 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_VolumeSizeWizardPage +#define TC_HEADER_Main_Forms_VolumeSizeWizardPage + +#include "Forms.h" + +namespace TrueCrypt +{ + class VolumeSizeWizardPage : public VolumeSizeWizardPageBase + { + public: + VolumeSizeWizardPage (wxPanel* parent, const VolumePath &volumePath, uint32 sectorSize, const wxString &freeSpaceText = wxEmptyString); + + uint64 GetVolumeSize () const; + bool IsValid (); + void SetMaxStaticTextWidth (int width); + void SetMaxVolumeSize (uint64 size) { MaxVolumeSize = size; MaxVolumeSizeValid = true; } + void SetMinVolumeSize (uint64 size) { MinVolumeSize = size; } + void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } + void SetVolumeSize (uint64 size); + + protected: + struct Prefix + { + enum + { + KB = 0, + MB, + GB + }; + }; + + void OnBrowseButtonClick (wxCommandEvent& event); + void OnVolumeSizePrefixSelected (wxCommandEvent& event) { PageUpdatedEvent.Raise(); } + void OnVolumeSizeTextChanged (wxCommandEvent& event) { PageUpdatedEvent.Raise(); } + + uint64 MaxVolumeSize; + bool MaxVolumeSizeValid; + uint64 MinVolumeSize; + uint32 SectorSize; + }; +} + +#endif // TC_HEADER_Main_Forms_VolumeSizeWizardPage diff --git a/src/Main/Forms/WizardFrame.cpp b/src/Main/Forms/WizardFrame.cpp new file mode 100644 index 00000000..9941be81 --- /dev/null +++ b/src/Main/Forms/WizardFrame.cpp @@ -0,0 +1,189 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/GraphicUserInterface.h" +#include "Main/Resources.h" +#include "WizardFrame.h" + +namespace TrueCrypt +{ + WizardFrame::WizardFrame (wxWindow* parent) + : WizardFrameBase (parent), + CurrentPage (nullptr), + CurrentStep (-1), + MaxStaticTextWidth (-1), + WorkInProgress (false) + { + SetIcon (Resources::GetTrueCryptIcon()); + + PageTitleStaticText->SetFont (wxFont ( +#ifdef TC_WINDOWS + 16 +#elif defined(TC_MACOSX) + 18 +#elif defined(__WXGTK__) + 14 +#endif + * Gui->GetCharHeight (this) / 13, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Times New Roman")); + + UpdateControls(); + this->SetDefaultItem (NextButton); + NextButton->SetFocus(); + + foreach (wxWindow *c, MainPanel->GetChildren()) + c->Connect (wxEVT_MOTION, wxMouseEventHandler (WizardFrame::OnMouseMotion), nullptr, this); + } + + WizardFrame::~WizardFrame () + { + if (CurrentPage) + CurrentPage->Destroy(); + } + + void WizardFrame::ClearHistory () + { + StepHistory.clear(); + UpdateControls(); + } + + void WizardFrame::OnActivate (wxActivateEvent& event) + { + Gui->SetActiveFrame (this); + event.Skip(); + } + + void WizardFrame::OnClose (wxCloseEvent& event) + { + if (WorkInProgress) + return; + + Gui->SetActiveFrame (nullptr); + event.Skip(); + } + + void WizardFrame::OnHelpButtonClick (wxCommandEvent& event) + { + Gui->OpenUserGuide (this); + } + + void WizardFrame::OnNextButtonClick (wxCommandEvent& event) + { + if (CurrentPage->IsValid()) + { + WizardStep nextStep = ProcessPageChangeRequest (true); + if (nextStep != CurrentStep) + SetStep (nextStep); + } + } + + void WizardFrame::OnPreviousButtonClick (wxCommandEvent& event) + { + ProcessPageChangeRequest (false); + + if (!StepHistory.empty()) + { + WizardStep prevStep = *StepHistory.rbegin(); + StepHistory.pop_back(); + SetStep (prevStep, false); + } + } + + void WizardFrame::SetCancelButtonText (const wxString &text) + { + CancelButton->SetLabel (text.empty() ? wxString (_("Cancel")) : text); + } + + void WizardFrame::SetImage (const wxBitmap &bitmap) + { + WizardBitmap->SetBitmap (bitmap); + } + + void WizardFrame::SetMaxStaticTextWidth (size_t charCount) + { + MaxStaticTextWidth = Gui->GetCharWidth (this) * charCount; + } + + void WizardFrame::SetStep (WizardStep newStep) + { + SetStep (newStep, true); + } + + void WizardFrame::SetStep (WizardStep newStep, bool forward) + { + bool init = false; + FreezeScope freeze (this); + +#ifdef TC_WINDOWS + HelpButton->Disable(); // Prevent Help button from getting default focus + NextButton->Enable(); +#endif + if (CurrentPage) + { + if (forward) + StepHistory.push_back (CurrentStep); + + CurrentPage->OnPageChanging (forward); + CurrentPage->Destroy(); + CurrentPage = nullptr; + } + else + init = true; + + CurrentStep = newStep; + CurrentPage = GetPage (newStep); + + CurrentPage->PageUpdatedEvent.Connect (EventConnector (this, &WizardFrame::OnPageUpdated)); + + CurrentPage->Connect (wxEVT_MOTION, wxMouseEventHandler (WizardFrame::OnMouseMotion), nullptr, this); + foreach (wxWindow *c, CurrentPage->GetChildren()) + c->Connect (wxEVT_MOTION, wxMouseEventHandler (WizardFrame::OnMouseMotion), nullptr, this); + + if (MaxStaticTextWidth > 0) + CurrentPage->SetMaxStaticTextWidth (MaxStaticTextWidth); + + PageTitleStaticText->SetLabel (CurrentPage->GetPageTitle()); + PageSizer->Add (CurrentPage, 1, wxALL | wxEXPAND); + + if (init) + { + Fit(); + Layout(); + Center(); + } + else + MainPanel->Layout(); + + CurrentPage->SetFocus(); + + wxString nextButtonText = CurrentPage->GetNextButtonText(); + if (nextButtonText.empty()) + NextButton->SetLabel (_("&Next >")); + else + NextButton->SetLabel (nextButtonText); + +#ifdef TC_WINDOWS + HelpButton->Enable(); +#endif + UpdateControls(); + } + + void WizardFrame::SetWorkInProgress (bool state) + { + WorkInProgress = state; + UpdateControls(); + } + + void WizardFrame::UpdateControls () + { + CancelButton->Enable (!WorkInProgress); + HelpButton->Enable (!WorkInProgress); + NextButton->Enable (!WorkInProgress && CurrentPage != nullptr && CurrentPage->IsValid()); + PreviousButton->Enable (!WorkInProgress && !StepHistory.empty()); + } +} diff --git a/src/Main/Forms/WizardFrame.h b/src/Main/Forms/WizardFrame.h new file mode 100644 index 00000000..d9f9ceb0 --- /dev/null +++ b/src/Main/Forms/WizardFrame.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_WizardFrame +#define TC_HEADER_Main_Forms_WizardFrame + +#include "Forms.h" +#include "Main/Main.h" + +namespace TrueCrypt +{ + class WizardFrame : public WizardFrameBase + { + public: + WizardFrame (wxWindow* parent); + virtual ~WizardFrame (); + + protected: + typedef int WizardStep; + + void ClearHistory (); + virtual WizardPage *GetPage (WizardStep step) = 0; + WizardPage *GetCurrentPage () const { return CurrentPage; } + WizardStep GetCurrentStep () const { return CurrentStep; } + wxPanel *GetPageParent () const { return MainPanel; } + bool IsWorkInProgress() const { return WorkInProgress; } + virtual void OnCancelButtonClick (wxCommandEvent& event) { Close(); } + virtual void OnClose (wxCloseEvent& event); + virtual void OnHelpButtonClick (wxCommandEvent& event); + virtual WizardStep ProcessPageChangeRequest (bool forward) = 0; + void SetCancelButtonText (const wxString &text); + void SetImage (const wxBitmap &bitmap); + void SetMaxStaticTextWidth (size_t charCount); + void SetStep (WizardStep newStep); + void SetWorkInProgress (bool state); + + private: + void OnActivate (wxActivateEvent& event); + void OnNextButtonClick (wxCommandEvent& event); + void OnPageUpdated (EventArgs &args) { UpdateControls(); } + void OnPreviousButtonClick (wxCommandEvent& event); + void SetStep (WizardStep newStep, bool forward); + void UpdateControls (); + + WizardPage *CurrentPage; + WizardStep CurrentStep; + int MaxStaticTextWidth; + list StepHistory; + bool WorkInProgress; + }; +} + +#endif // TC_HEADER_Main_Forms_WizardFrame diff --git a/src/Main/Forms/WizardPage.h b/src/Main/Forms/WizardPage.h new file mode 100644 index 00000000..e00b8605 --- /dev/null +++ b/src/Main/Forms/WizardPage.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_WizardPage +#define TC_HEADER_Main_Forms_WizardPage + +#include "Main/Main.h" + +namespace TrueCrypt +{ + class WizardPage : public wxPanel + { + public: + WizardPage (wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxPanel (parent, id, pos, size, style) + { } + virtual ~WizardPage () { } + + wxString GetPageTitle () const { return PageTitle; } + virtual bool IsValid () = 0; + virtual void OnPageChanging (bool forward) { } + wxString GetNextButtonText () const { return NextButtonText; } + void SetNextButtonText (const wxString &text) { NextButtonText = text; } + virtual void SetMaxStaticTextWidth (int width) { } + void SetPageTitle (const wxString &title) { PageTitle = title; } + virtual void SetPageText (const wxString &text) = 0; + + Event PageUpdatedEvent; + + protected: + wxString PageTitle; + wxString NextButtonText; + }; +} + +#endif // TC_HEADER_Main_Forms_WizardPage diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp new file mode 100644 index 00000000..04426bd4 --- /dev/null +++ b/src/Main/GraphicUserInterface.cpp @@ -0,0 +1,1690 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" + +#ifdef TC_UNIX +#include +#include +#include +#include +#include +#include +#include +#include +#include "Platform/Unix/Process.h" +#endif + +#include "Common/SecurityToken.h" +#include "Application.h" +#include "GraphicUserInterface.h" +#include "FatalErrorHandler.h" +#include "Forms/DeviceSelectionDialog.h" +#include "Forms/KeyfileGeneratorDialog.h" +#include "Forms/MainFrame.h" +#include "Forms/MountOptionsDialog.h" +#include "Forms/RandomPoolEnrichmentDialog.h" +#include "Forms/SecurityTokenKeyfilesDialog.h" + +namespace TrueCrypt +{ + GraphicUserInterface::GraphicUserInterface () : + ActiveFrame (nullptr), + BackgroundMode (false), + mMainFrame (nullptr) + { +#ifdef TC_UNIX + signal (SIGHUP, OnSignal); + signal (SIGINT, OnSignal); + signal (SIGQUIT, OnSignal); + signal (SIGTERM, OnSignal); +#endif + +#ifdef TC_MACOSX + wxApp::s_macHelpMenuTitleName = _("&Help"); +#endif + } + + GraphicUserInterface::~GraphicUserInterface () + { + try + { + if (RandomNumberGenerator::IsRunning()) + RandomNumberGenerator::Stop(); + } + catch (...) { } + + FatalErrorHandler::Deregister(); + +#ifdef TC_UNIX + signal (SIGHUP, SIG_DFL); + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGTERM, SIG_DFL); +#endif + } + + void GraphicUserInterface::AppendToListCtrl (wxListCtrl *listCtrl, const vector &itemFields, int imageIndex, void *itemDataPtr) const + { + InsertToListCtrl (listCtrl, listCtrl->GetItemCount(), itemFields, imageIndex, itemDataPtr); + } + + wxMenuItem *GraphicUserInterface::AppendToMenu (wxMenu &menu, const wxString &label, wxEvtHandler *handler, wxObjectEventFunction handlerFunction, int itemId) const + { + wxMenuItem *item = new wxMenuItem (&menu, itemId, label); + menu.Append (item); + + if (handler) + handler->Connect (item->GetId(), wxEVT_COMMAND_MENU_SELECTED, handlerFunction); + + return item; + } + + bool GraphicUserInterface::AskYesNo (const wxString &message, bool defaultYes, bool warning) const + { + return ShowMessage (message, + wxYES_NO | (warning ? wxICON_EXCLAMATION : wxICON_QUESTION) | (defaultYes ? wxYES_DEFAULT : wxNO_DEFAULT) + ) == wxYES; + } + + void GraphicUserInterface::AutoDismountVolumes (VolumeInfoList mountedVolumes, bool alwaysForce) + { + size_t mountedVolumeCount = Core->GetMountedVolumes().size(); + try + { + wxBusyCursor busy; + DismountVolumes (mountedVolumes, alwaysForce ? true : GetPreferences().ForceAutoDismount, false); + } + catch (...) { } + + if (Core->GetMountedVolumes().size() < mountedVolumeCount) + OnVolumesAutoDismounted(); + } + + void GraphicUserInterface::BackupVolumeHeaders (shared_ptr volumePath) const + { + wxWindow *parent = GetActiveWindow(); + + if (!volumePath || volumePath->IsEmpty()) + volumePath = make_shared (SelectVolumeFile (GetActiveWindow())); + + if (volumePath->IsEmpty()) + throw UserAbort (SRC_POS); + +#ifdef TC_WINDOWS + if (Core->IsVolumeMounted (*volumePath)) + { + ShowInfo ("DISMOUNT_FIRST"); + return; + } +#endif + +#ifdef TC_UNIX + // Temporarily take ownership of a device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + if (!Core->HasAdminPrivileges() && volumePath->IsDevice()) + { + origDeviceOwner = FilesystemPath (wstring (*volumePath)).GetOwner(); + Core->SetFileOwner (*volumePath, UserId (getuid())); + } + + finally_do_arg2 (FilesystemPath, *volumePath, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); +#endif + + ShowInfo ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO"); + + shared_ptr normalVolume; + shared_ptr hiddenVolume; + + MountOptions normalVolumeMountOptions; + MountOptions hiddenVolumeMountOptions; + + normalVolumeMountOptions.Path = volumePath; + hiddenVolumeMountOptions.Path = volumePath; + + VolumeType::Enum volumeType = VolumeType::Normal; + + // Open both types of volumes + while (true) + { + shared_ptr volume; + MountOptions *options = (volumeType == VolumeType::Hidden ? &hiddenVolumeMountOptions : &normalVolumeMountOptions); + + MountOptionsDialog dialog (parent, *options, + LangString[volumeType == VolumeType::Hidden ? "ENTER_HIDDEN_VOL_PASSWORD" : "ENTER_NORMAL_VOL_PASSWORD"], + true); + + while (!volume) + { + dialog.Hide(); + if (dialog.ShowModal() != wxID_OK) + return; + + try + { + wxBusyCursor busy; + volume = Core->OpenVolume ( + options->Path, + options->PreserveTimestamps, + options->Password, + options->Keyfiles, + options->Protection, + options->ProtectionPassword, + options->ProtectionKeyfiles, + true, + volumeType, + options->UseBackupHeaders + ); + } + catch (PasswordException &e) + { + ShowWarning (e); + } + } + + if (volumeType == VolumeType::Hidden) + hiddenVolume = volume; + else + normalVolume = volume; + + // Ask whether a hidden volume is present + if (volumeType == VolumeType::Normal) + { + wxArrayString choices; + choices.Add (LangString["VOLUME_CONTAINS_HIDDEN"]); + choices.Add (LangString["VOLUME_DOES_NOT_CONTAIN_HIDDEN"]); + + wxSingleChoiceDialog choiceDialog (parent, LangString["DOES_VOLUME_CONTAIN_HIDDEN"], Application::GetName(), choices); + choiceDialog.SetSize (wxSize (Gui->GetCharWidth (&choiceDialog) * 60, -1)); + choiceDialog.SetSelection (-1); + + if (choiceDialog.ShowModal() != wxID_OK) + return; + + switch (choiceDialog.GetSelection()) + { + case 0: + volumeType = VolumeType::Hidden; + continue; + + case 1: + break; + + default: + return; + } + } + + break; + } + + if (hiddenVolume) + { + if (typeid (*normalVolume->GetLayout()) == typeid (VolumeLayoutV1Normal) && typeid (*hiddenVolume->GetLayout()) != typeid (VolumeLayoutV1Hidden)) + throw ParameterIncorrect (SRC_POS); + + if (typeid (*normalVolume->GetLayout()) == typeid (VolumeLayoutV2Normal) && typeid (*hiddenVolume->GetLayout()) != typeid (VolumeLayoutV2Hidden)) + throw ParameterIncorrect (SRC_POS); + } + + // Ask user to select backup file path + wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_BAK"]; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true)) + return; + + FilePathList files = SelectFiles (parent, wxEmptyString, true, false); + if (files.empty()) + return; + + File backupFile; + backupFile.Open (*files.front(), File::CreateWrite); + + RandomNumberGenerator::Start(); + UserEnrichRandomPool (nullptr); + + { + wxBusyCursor busy; + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Keyfiles); + + backupFile.Write (newHeaderBuffer); + + if (hiddenVolume) + { + // Re-encrypt hidden volume header + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Keyfiles); + } + else + { + // Store random data in place of hidden volume header + shared_ptr ea = normalVolume->GetEncryptionAlgorithm(); + Core->RandomizeEncryptionAlgorithmKey (ea); + ea->Encrypt (newHeaderBuffer); + } + + backupFile.Write (newHeaderBuffer); + } + + ShowWarning ("VOL_HEADER_BACKED_UP"); + } + + void GraphicUserInterface::BeginInteractiveBusyState (wxWindow *window) + { + static auto_ptr arrowWaitCursor; + + if (arrowWaitCursor.get() == nullptr) + arrowWaitCursor.reset (new wxCursor (wxCURSOR_ARROWWAIT)); + + window->SetCursor (*arrowWaitCursor); + } + + void GraphicUserInterface::CreateKeyfile (shared_ptr keyfilePath) const + { + try + { + KeyfileGeneratorDialog dialog (GetActiveWindow()); + dialog.ShowModal(); + } + catch (exception &e) + { + ShowError (e); + } + } + + void GraphicUserInterface::ClearListCtrlSelection (wxListCtrl *listCtrl) const + { + foreach (long item, GetListCtrlSelectedItems (listCtrl)) + listCtrl->SetItemState (item, 0, wxLIST_STATE_SELECTED); + } + + wxHyperlinkCtrl *GraphicUserInterface::CreateHyperlink (wxWindow *parent, const wxString &linkUrl, const wxString &linkText) const + { + wxHyperlinkCtrl *hyperlink = new wxHyperlinkCtrl (parent, wxID_ANY, linkText, linkUrl, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE); + + wxColour color = wxSystemSettings::GetColour (wxSYS_COLOUR_WINDOWTEXT); + hyperlink->SetHoverColour (color); + hyperlink->SetNormalColour (color); + hyperlink->SetVisitedColour (color); + + return hyperlink; + } + + void GraphicUserInterface::DoShowError (const wxString &message) const + { + ShowMessage (message, wxOK | wxICON_ERROR); + } + + void GraphicUserInterface::DoShowInfo (const wxString &message) const + { + ShowMessage (message, wxOK | wxICON_INFORMATION); + } + + void GraphicUserInterface::DoShowString (const wxString &str) const + { + ShowMessage (str, wxOK); + } + + void GraphicUserInterface::DoShowWarning (const wxString &message) const + { + ShowMessage (message, wxOK +#ifndef TC_MACOSX + | wxICON_EXCLAMATION +#endif + ); + } + + void GraphicUserInterface::EndInteractiveBusyState (wxWindow *window) const + { + static auto_ptr arrowCursor; + + if (arrowCursor.get() == nullptr) + arrowCursor.reset (new wxCursor (wxCURSOR_ARROW)); + + window->SetCursor (*arrowCursor); + } + + wxTopLevelWindow *GraphicUserInterface::GetActiveWindow () const + { +#ifdef TC_WINDOWS + return dynamic_cast (wxGetActiveWindow()); +#endif + +#ifdef __WXGTK__ + // GTK for some reason unhides a hidden window if it is a parent of a new window + if (IsInBackgroundMode()) + return nullptr; +#endif + if (wxTopLevelWindows.size() == 1) + return dynamic_cast (wxTopLevelWindows.front()); + +#ifdef __WXGTK__ + wxLongLong startTime = wxGetLocalTimeMillis(); + do + { +#endif + foreach (wxWindow *window, wxTopLevelWindows) + { + wxTopLevelWindow *topLevelWin = dynamic_cast (window); + if (topLevelWin && topLevelWin->IsActive() && topLevelWin->IsShown()) + return topLevelWin; + } +#ifdef __WXGTK__ + Yield(); // GTK does a lot of operations asynchronously, which makes it prone to many race conditions + } while (wxGetLocalTimeMillis() - startTime < 500); +#endif + + return dynamic_cast (ActiveFrame ? ActiveFrame : GetTopWindow()); + } + + shared_ptr GraphicUserInterface::GetAdminPasswordRequestHandler () + { + struct AdminPasswordRequestHandler : public GetStringFunctor + { + virtual void operator() (string &passwordStr) + { + wxPasswordEntryDialog dialog (Gui->GetActiveWindow(), _("Enter your user password or administrator password:"), _("Administrator privileges required")); + + if (dialog.ShowModal() != wxID_OK) + throw UserAbort (SRC_POS); + + wstring wPassword (dialog.GetValue()); // A copy of the password is created here by wxWidgets, which cannot be erased + finally_do_arg (wstring *, &wPassword, { StringConverter::Erase (*finally_arg); }); + + StringConverter::ToSingle (wPassword, passwordStr); + } + }; + + return shared_ptr (new AdminPasswordRequestHandler); + } + + int GraphicUserInterface::GetCharHeight (wxWindow *window) const + { + int width; + int height; + window->GetTextExtent (L"a", &width, &height); + + if (height < 1) + return 14; + + return height; + } + + int GraphicUserInterface::GetCharWidth (wxWindow *window) const + { + int width; + int height; + window->GetTextExtent (L"a", &width, &height); + + if (width < 1) + return 7; + + return width; + } + + wxFont GraphicUserInterface::GetDefaultBoldFont (wxWindow *window) const + { + return wxFont ( +#ifdef __WXGTK__ + 9 +#elif defined(TC_MACOSX) + 13 +#else + 10 +#endif + * GetCharHeight (window) / 13, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, +#ifdef __WXGTK__ + wxFONTWEIGHT_BOLD, false); +#elif defined(TC_MACOSX) + wxFONTWEIGHT_NORMAL, false); +#else + wxFONTWEIGHT_BOLD, false, L"Arial"); +#endif + } + + list GraphicUserInterface::GetListCtrlSelectedItems (wxListCtrl *listCtrl) const + { + list selectedItems; + + long item = -1; + while ((item = listCtrl->GetNextItem (item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1) + selectedItems.push_back (item); + + return selectedItems; + } + + wxString GraphicUserInterface::GetListCtrlSubItemText (wxListCtrl *listCtrl, long itemIndex, int columnIndex) const + { + wxListItem item; + item.SetId (itemIndex); + item.SetColumn (columnIndex); + item.SetText (L""); + + if (!listCtrl->GetItem (item)) + throw ParameterIncorrect (SRC_POS); + + return item.GetText(); + } + + int GraphicUserInterface::GetScrollbarWidth (wxWindow *window, bool noScrollBar) const + { + int offset = 0; +#ifdef TC_WINDOWS + offset = 4; +#elif defined (__WXGTK__) + offset = 7; +#elif defined (TC_MACOSX) + offset = 9; +#endif + if (noScrollBar) + return offset; + + int width = wxSystemSettings::GetMetric (wxSYS_VSCROLL_X, window); + + if (width == -1) + return 24; + + return width + offset; + } + + void GraphicUserInterface::InitSecurityTokenLibrary () const + { + if (Preferences.SecurityTokenModule.IsEmpty()) + throw_err (LangString ["NO_PKCS11_MODULE_SPECIFIED"]); + + struct PinRequestHandler : public GetPinFunctor + { + virtual void operator() (string &passwordStr) + { + if (Gui->GetPreferences().NonInteractive) + throw MissingArgument (SRC_POS); + + wxPasswordEntryDialog dialog (Gui->GetActiveWindow(), wxString::Format (LangString["ENTER_TOKEN_PASSWORD"], StringConverter::ToWide (passwordStr).c_str()), LangString["IDD_TOKEN_PASSWORD"]); + dialog.SetSize (wxSize (Gui->GetCharWidth (&dialog) * 50, -1)); + + if (dialog.ShowModal() != wxID_OK) + throw UserAbort (SRC_POS); + + wstring wPassword (dialog.GetValue()); // A copy of the password is created here by wxWidgets, which cannot be erased + finally_do_arg (wstring *, &wPassword, { StringConverter::Erase (*finally_arg); }); + + StringConverter::ToSingle (wPassword, passwordStr); + } + }; + + struct WarningHandler : public SendExceptionFunctor + { + virtual void operator() (const Exception &e) + { + Gui->ShowError (e); + } + }; + + try + { + SecurityToken::InitLibrary (Preferences.SecurityTokenModule, auto_ptr (new PinRequestHandler), auto_ptr (new WarningHandler)); + } + catch (Exception &e) + { + ShowError (e); + throw_err (LangString ["PKCS11_MODULE_INIT_FAILED"]); + } + } + + void GraphicUserInterface::InsertToListCtrl (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields, int imageIndex, void *itemDataPtr) const + { + wxListItem item; + item.SetData (itemDataPtr); + item.SetId (itemIndex); + item.SetImage (imageIndex); + int col = 0; + foreach (wxString field, itemFields) + { + item.SetColumn (col++); + item.SetText (field); + if (col == 1) + { + throw_sys_if (listCtrl->InsertItem (item) == -1); + item.SetImage (-1); + continue; + } + + listCtrl->SetItem (item); + } + } + + bool GraphicUserInterface::IsTheOnlyTopLevelWindow (const wxWindow *window) const + { + foreach (wxWindow *w, wxTopLevelWindows) + { + if (w != window + && (dynamic_cast (w) || dynamic_cast (w)) + && StringConverter::GetTypeName (typeid (*w)).find ("wxTaskBarIcon") == string::npos) + { + return false; + } + } + return true; + } + + void GraphicUserInterface::ListSecurityTokenKeyfiles () const + { + SecurityTokenKeyfilesDialog dialog (nullptr); + dialog.ShowModal(); + } + +#ifdef TC_MACOSX + void GraphicUserInterface::MacOpenFile (const wxString &fileName) + { + OpenVolumeSystemRequestEventArgs eventArgs (fileName); + OpenVolumeSystemRequestEvent.Raise (eventArgs); + } +#endif + + void GraphicUserInterface::MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const + { + if (itemIndex == newItemIndex || newItemIndex < 0 + || (newItemIndex > itemIndex && newItemIndex == listCtrl->GetItemCount())) + return; + + wxListItem item; + item.SetId (itemIndex); + item.SetData ((void *) nullptr); + item.SetImage (-1); + + if (!listCtrl->GetItem (item)) + throw ParameterIncorrect (SRC_POS); + + int itemState = listCtrl->GetItemState (itemIndex, wxLIST_STATE_SELECTED); + + vector itemFields (listCtrl->GetColumnCount()); + for (size_t col = 0; col < itemFields.size(); ++col) + { + itemFields[col] = GetListCtrlSubItemText (listCtrl, itemIndex, col); + } + + listCtrl->DeleteItem (itemIndex); + + if (newItemIndex > listCtrl->GetItemCount() - 1) + AppendToListCtrl (listCtrl, itemFields, item.GetImage(), (void *) item.GetData()); + else + InsertToListCtrl (listCtrl, newItemIndex, itemFields, item.GetImage(), (void *) item.GetData()); + + item.SetId (newItemIndex); + listCtrl->SetItemState (item, itemState, wxLIST_STATE_SELECTED); + } + + VolumeInfoList GraphicUserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const + { + MountOptionsDialog dialog (GetTopWindow(), options); + while (true) + { + options.Path.reset(); + + if (dialog.ShowModal() != wxID_OK) + return VolumeInfoList(); + + VolumeInfoList mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (options); + + if (!mountedVolumes.empty()) + return mountedVolumes; + } + } + + shared_ptr GraphicUserInterface::MountVolume (MountOptions &options) const + { + CheckRequirementsForMountingVolume(); + + shared_ptr volume; + + if (!options.Path || options.Path->IsEmpty()) + options.Path = make_shared (SelectVolumeFile (GetActiveWindow())); + + if (options.Path->IsEmpty()) + throw UserAbort (SRC_POS); + + if (Core->IsVolumeMounted (*options.Path)) + { + ShowInfo (StringFormatter (LangString["VOLUME_ALREADY_MOUNTED"], wstring (*options.Path))); + return volume; + } + + try + { + if ((!options.Password || options.Password->IsEmpty()) + && (!options.Keyfiles || options.Keyfiles->empty()) + && !Core->IsPasswordCacheEmpty()) + { + // Cached password + try + { + wxBusyCursor busy; + return UserInterface::MountVolume (options); + } + catch (PasswordException&) { } + } + + if (!options.Keyfiles && GetPreferences().UseKeyfiles && !GetPreferences().DefaultKeyfiles.empty()) + options.Keyfiles = make_shared (GetPreferences().DefaultKeyfiles); + + if ((options.Password && !options.Password->IsEmpty()) + || (options.Keyfiles && !options.Keyfiles->empty())) + { + try + { + wxBusyCursor busy; + return UserInterface::MountVolume (options); + } + catch (PasswordException&) { } + } + + VolumePassword password; + KeyfileList keyfiles; + + MountOptionsDialog dialog (GetTopWindow(), options); + int incorrectPasswordCount = 0; + + while (!volume) + { + dialog.Hide(); + if (dialog.ShowModal() != wxID_OK) + return volume; + + try + { + wxBusyCursor busy; + volume = UserInterface::MountVolume (options); + } + catch (PasswordIncorrect &e) + { + if (++incorrectPasswordCount > 2 && !options.UseBackupHeaders) + { + // Try to mount the volume using the backup header + options.UseBackupHeaders = true; + + try + { + volume = UserInterface::MountVolume (options); + ShowWarning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK"); + } + catch (...) + { + options.UseBackupHeaders = false; + ShowWarning (e); + } + } + else + ShowWarning (e); + } + catch (PasswordException &e) + { + ShowWarning (e); + } + } + } + catch (exception &e) + { + ShowError (e); + } + +#ifdef TC_LINUX + if (volume && !Preferences.NonInteractive && !Preferences.DisableKernelEncryptionModeWarning + && volume->EncryptionModeName != L"XTS" + && (volume->EncryptionModeName != L"LRW" || volume->EncryptionAlgorithmMinBlockSize != 16 || volume->EncryptionAlgorithmKeySize != 32) + && !AskYesNo (LangString["ENCRYPTION_MODE_NOT_SUPPORTED_BY_KERNEL"] + _("\n\nDo you want to show this message next time you mount such a volume?"), true, true)) + { + UserPreferences prefs = GetPreferences(); + prefs.DisableKernelEncryptionModeWarning = true; + Gui->SetPreferences (prefs); + } +#endif + return volume; + } + + void GraphicUserInterface::OnAutoDismountAllEvent () + { + VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); + + if (!mountedVolumes.empty()) + { + wxBusyCursor busy; + AutoDismountVolumes (mountedVolumes); + } + } + + bool GraphicUserInterface::OnInit () + { + Gui = this; + InterfaceType = UserInterfaceType::Graphic; + try + { + FatalErrorHandler::Register(); + Init(); + + if (ProcessCommandLine() && !CmdLine->StartBackgroundTask) + { + Yield(); + Application::SetExitCode (0); + return false; + } + + // Check if another instance is already running and bring its windows to foreground +#ifndef TC_MACOSX +#ifdef TC_WINDOWS + const wxString serverName = Application::GetName() + L"-" + wxGetUserId(); + class Connection : public wxDDEConnection + { + public: + Connection () { } + + bool OnExecute (const wxString& topic, wxChar *data, int size, wxIPCFormat format) + { + if (topic == L"raise") + { + if (Gui->IsInBackgroundMode()) + Gui->SetBackgroundMode (false); + + Gui->mMainFrame->Show (true); + Gui->mMainFrame->Raise (); + return true; + } + return false; + } + }; +#endif + + wxLogLevel logLevel = wxLog::GetLogLevel(); + wxLog::SetLogLevel (wxLOG_Error); + + SingleInstanceChecker.reset (new wxSingleInstanceChecker (wxString (L".") + Application::GetName() + L"-lock-" + wxGetUserId())); + + wxLog::SetLogLevel (logLevel); + + if (SingleInstanceChecker->IsAnotherRunning()) + { +#ifdef TC_WINDOWS + class Client: public wxDDEClient + { + public: + Client() {}; + wxConnectionBase *OnMakeConnection () { return new Connection; } + }; + + auto_ptr client (new Client); + auto_ptr connection (client->MakeConnection (L"localhost", serverName, L"raise")); + + if (connection.get() && connection->Execute (nullptr)) + { + connection->Disconnect(); + Application::SetExitCode (0); + return false; + } +#endif + +#if defined(TC_UNIX) && !defined(TC_MACOSX) + try + { + int showFifo = open (string (MainFrame::GetShowRequestFifoPath()).c_str(), O_WRONLY | O_NONBLOCK); + throw_sys_if (showFifo == -1); + + byte buf[1] = { 1 }; + if (write (showFifo, buf, 1) == 1) + { + close (showFifo); + Application::SetExitCode (0); + return false; + } + + close (showFifo); + } + catch (...) + { +#ifdef DEBUG + throw; +#endif + } +#endif + + wxLog::FlushActive(); + Application::SetExitCode (1); + Gui->ShowInfo (_("TrueCrypt is already running.")); + return false; + } + +#ifdef TC_WINDOWS + class Server : public wxDDEServer + { + public: + wxConnectionBase *OnAcceptConnection (const wxString &topic) + { + if (topic == L"raise") + return new Connection; + return nullptr; + } + }; + + DDEServer.reset (new Server); + if (!DDEServer->Create (serverName)) + wxLog::FlushActive(); +#endif +#endif // !TC_MACOSX + + Connect (wxEVT_END_SESSION, wxCloseEventHandler (GraphicUserInterface::OnEndSession)); +#ifdef wxHAS_POWER_EVENTS + Gui->Connect (wxEVT_POWER_SUSPENDING, wxPowerEventHandler (GraphicUserInterface::OnPowerSuspending)); +#endif + + mMainFrame = new MainFrame (nullptr); + + if (CmdLine->StartBackgroundTask) + { + UserPreferences prefs = GetPreferences (); + prefs.BackgroundTaskEnabled = true; + SetPreferences (prefs); + mMainFrame->Close(); + } + else + { + mMainFrame->Show (true); + } + + SetTopWindow (mMainFrame); + } + catch (exception &e) + { + ShowError (e); + return false; + } + + return true; + } + + void GraphicUserInterface::OnLogOff () + { + VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); + if (GetPreferences().BackgroundTaskEnabled && GetPreferences().DismountOnLogOff + && !mountedVolumes.empty()) + { + wxLongLong startTime = wxGetLocalTimeMillis(); + bool timeOver = false; + + wxBusyCursor busy; + while (!timeOver && !mountedVolumes.empty()) + { + try + { + timeOver = (wxGetLocalTimeMillis() - startTime >= 4000); + + DismountVolumes (mountedVolumes, !timeOver ? false : GetPreferences().ForceAutoDismount, timeOver); + OnVolumesAutoDismounted(); + + break; + } + catch (UserAbort&) + { + return; + } + catch (...) + { + Thread::Sleep (500); + } + + VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); + } + + } + } + +#ifdef wxHAS_POWER_EVENTS + void GraphicUserInterface::OnPowerSuspending (wxPowerEvent& event) + { + size_t volumeCount = Core->GetMountedVolumes().size(); + if (GetPreferences().BackgroundTaskEnabled && GetPreferences().DismountOnPowerSaving && volumeCount > 0) + { + OnAutoDismountAllEvent(); + + if (Core->GetMountedVolumes().size() < volumeCount) + ShowInfoTopMost (LangString["MOUNTED_VOLUMES_AUTO_DISMOUNTED"]); + } + } +#endif + + void GraphicUserInterface::OnSignal (int signal) + { +#ifdef TC_UNIX + Gui->SingleInstanceChecker.reset(); + _exit (1); +#endif + } + + void GraphicUserInterface::OnVolumesAutoDismounted () + { + if (GetPreferences().WipeCacheOnAutoDismount) + { + Core->WipePasswordCache(); + SecurityToken::CloseAllSessions(); + } + } + + void GraphicUserInterface::OpenDocument (wxWindow *parent, const wxFileName &document) + { + if (!document.FileExists()) + throw ParameterIncorrect (SRC_POS); + +#ifdef TC_WINDOWS + + if (int (ShellExecute (GetTopWindow() ? static_cast (GetTopWindow()->GetHandle()) : nullptr, L"open", + document.GetFullPath().c_str(), nullptr, nullptr, SW_SHOWNORMAL)) >= 32) + return; + +#else + wxMimeTypesManager mimeMgr; + wxFileType *fileType = mimeMgr.GetFileTypeFromExtension (document.GetExt()); + if (fileType) + { + try + { +#ifdef TC_MACOSX + if (wxExecute (fileType->GetOpenCommand (document.GetFullPath())) != 0) + return; +#else + if (wxExecute (fileType->GetOpenCommand (L"\"" + document.GetFullPath() + L"\"")) != 0) + return; +#endif + } + catch (TimeOut&) { } + } +#endif + } + + wxString GraphicUserInterface::GetHomepageLinkURL (const wxString &linkId, bool secure, const wxString &extraVars) const + { + wxString url = wxString (StringConverter::ToWide (secure ? TC_APPLINK_SECURE : TC_APPLINK)) + L"&dest=" + linkId; + wxString os, osVersion, architecture; + +#ifdef TC_WINDOWS + + os = L"Windows"; + +#elif defined (TC_UNIX) + struct utsname unameData; + if (uname (&unameData) != -1) + { + os = StringConverter::ToWide (unameData.sysname); + osVersion = StringConverter::ToWide (unameData.release); + architecture = StringConverter::ToWide (unameData.machine); + + if (os == L"Darwin") + os = L"MacOSX"; + } + else + os = L"Unknown"; +#else + os = L"Unknown"; +#endif + + os.Replace (L" ", L"-"); + url += L"&os="; + url += os; + + osVersion.Replace (L" ", L"-"); + url += L"&osver="; + url += osVersion; + + architecture.Replace (L" ", L"-"); + url += L"&arch="; + url += architecture; + + if (!extraVars.empty()) + { + url += L"&"; + url += extraVars; + } + + return url; + } + + void GraphicUserInterface::OpenHomepageLink (wxWindow *parent, const wxString &linkId, const wxString &extraVars) + { + wxString url; + + BeginInteractiveBusyState (parent); + wxLaunchDefaultBrowser (GetHomepageLinkURL (linkId, false, extraVars), wxBROWSER_NEW_WINDOW); + Thread::Sleep (200); + EndInteractiveBusyState (parent); + } + + void GraphicUserInterface::OpenOnlineHelp (wxWindow *parent) + { + OpenHomepageLink (parent, L"help"); + } + + void GraphicUserInterface::OpenUserGuide (wxWindow *parent) + { + try + { + wxString docPath = wstring (Application::GetExecutableDirectory()); + +#ifdef TC_RESOURCE_DIR + docPath = StringConverter::ToWide (string (TC_TO_STRING (TC_RESOURCE_DIR)) + "/doc/TrueCrypt User Guide.pdf"); +#elif defined (TC_WINDOWS) + docPath += L"\\TrueCrypt User Guide.pdf"; +#elif defined (TC_MACOSX) + docPath += L"/../Resources/TrueCrypt User Guide.pdf"; +#elif defined (TC_UNIX) + docPath = L"/usr/share/truecrypt/doc/TrueCrypt User Guide.pdf"; +#else +# error TC_RESOURCE_DIR undefined +#endif + + wxFileName docFile = docPath; + docFile.Normalize(); + + try + { + Gui->OpenDocument (parent, docFile); + } + catch (...) + { + if (Gui->AskYesNo (LangString ["HELP_READER_ERROR"], true)) + OpenOnlineHelp (parent); + } + } + catch (Exception &e) + { + Gui->ShowError (e); + } + } + + void GraphicUserInterface::RestoreVolumeHeaders (shared_ptr volumePath) const + { + wxWindow *parent = GetActiveWindow(); + + if (!volumePath || volumePath->IsEmpty()) + volumePath = make_shared (SelectVolumeFile (GetActiveWindow())); + + if (volumePath->IsEmpty()) + throw UserAbort (SRC_POS); + +#ifdef TC_WINDOWS + if (Core->IsVolumeMounted (*volumePath)) + { + ShowInfo ("DISMOUNT_FIRST"); + return; + } +#endif + +#ifdef TC_UNIX + // Temporarily take ownership of a device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + if (!Core->HasAdminPrivileges() && volumePath->IsDevice()) + { + origDeviceOwner = FilesystemPath (wstring (*volumePath)).GetOwner(); + Core->SetFileOwner (*volumePath, UserId (getuid())); + } + + finally_do_arg2 (FilesystemPath, *volumePath, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); +#endif + + // Ask whether to restore internal or external backup + bool restoreInternalBackup; + wxArrayString choices; + choices.Add (LangString["HEADER_RESTORE_INTERNAL"]); + choices.Add (LangString["HEADER_RESTORE_EXTERNAL"]); + + wxSingleChoiceDialog choiceDialog (parent, LangString["HEADER_RESTORE_EXTERNAL_INTERNAL"], Application::GetName(), choices); + choiceDialog.SetSize (wxSize (Gui->GetCharWidth (&choiceDialog) * 80, -1)); + choiceDialog.SetSelection (-1); + + if (choiceDialog.ShowModal() != wxID_OK) + return; + + switch (choiceDialog.GetSelection()) + { + case 0: + restoreInternalBackup = true; + break; + + case 1: + restoreInternalBackup = false; + break; + + default: + return; + } + + if (restoreInternalBackup) + { + // Restore header from the internal backup + shared_ptr volume; + MountOptions options; + options.Path = volumePath; + + MountOptionsDialog dialog (parent, options, wxEmptyString, true); + + while (!volume) + { + dialog.Hide(); + if (dialog.ShowModal() != wxID_OK) + return; + + try + { + wxBusyCursor busy; + volume = Core->OpenVolume ( + options.Path, + options.PreserveTimestamps, + options.Password, + options.Keyfiles, + options.Protection, + options.ProtectionPassword, + options.ProtectionKeyfiles, + options.SharedAccessAllowed, + VolumeType::Unknown, + true + ); + } + catch (PasswordException &e) + { + ShowWarning (e); + } + } + + shared_ptr layout = volume->GetLayout(); + if (typeid (*layout) == typeid (VolumeLayoutV1Normal) || typeid (*layout) == typeid (VolumeLayoutV1Hidden)) + { + ShowError ("VOLUME_HAS_NO_BACKUP_HEADER"); + return; + } + + RandomNumberGenerator::Start(); + UserEnrichRandomPool (nullptr); + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Keyfiles); + + // Write volume header + int headerOffset = volume->GetLayout()->GetHeaderOffset(); + shared_ptr volumeFile = volume->GetFile(); + + if (headerOffset >= 0) + volumeFile->SeekAt (headerOffset); + else + volumeFile->SeekEnd (headerOffset); + + volumeFile->Write (newHeaderBuffer); + } + else + { + // Restore header from an external backup + + wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_RESTORE"]; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true, true)) + return; + + FilePathList files = SelectFiles (parent, wxEmptyString, false, false); + if (files.empty()) + return; + + File backupFile; + backupFile.Open (*files.front(), File::OpenRead); + + uint64 headerSize; + bool legacyBackup; + + // Determine the format of the backup file + switch (backupFile.Length()) + { + case TC_VOLUME_HEADER_GROUP_SIZE: + headerSize = TC_VOLUME_HEADER_SIZE; + legacyBackup = false; + break; + + case TC_VOLUME_HEADER_SIZE_LEGACY * 2: + headerSize = TC_VOLUME_HEADER_SIZE_LEGACY; + legacyBackup = true; + break; + + default: + ShowError ("HEADER_BACKUP_SIZE_INCORRECT"); + return; + } + + // Open the volume header stored in the backup file + MountOptions options; + + MountOptionsDialog dialog (parent, options, LangString["ENTER_HEADER_BACKUP_PASSWORD"], true); + shared_ptr decryptedLayout; + + while (!decryptedLayout) + { + dialog.Hide(); + if (dialog.ShowModal() != wxID_OK) + return; + + try + { + wxBusyCursor busy; + + // Test volume layouts + foreach (shared_ptr layout, VolumeLayout::GetAvailableLayouts ()) + { + if (layout->HasDriveHeader()) + continue; + + if (!legacyBackup && (typeid (*layout) == typeid (VolumeLayoutV1Normal) || typeid (*layout) == typeid (VolumeLayoutV1Hidden))) + continue; + + if (legacyBackup && (typeid (*layout) == typeid (VolumeLayoutV2Normal) || typeid (*layout) == typeid (VolumeLayoutV2Hidden))) + continue; + + SecureBuffer headerBuffer (layout->GetHeaderSize()); + backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0); + + // Decrypt header + shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedKeyDerivationFunctions(), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes())) + { + decryptedLayout = layout; + break; + } + } + + if (!decryptedLayout) + throw PasswordIncorrect (SRC_POS); + } + catch (PasswordException &e) + { + ShowWarning (e); + } + } + + File volumeFile; + volumeFile.Open (*volumePath, File::OpenReadWrite, File::ShareNone, File::PreserveTimestamps); + + RandomNumberGenerator::Start(); + UserEnrichRandomPool (nullptr); + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + + // Write volume header + int headerOffset = decryptedLayout->GetHeaderOffset(); + if (headerOffset >= 0) + volumeFile.SeekAt (headerOffset); + else + volumeFile.SeekEnd (headerOffset); + + volumeFile.Write (newHeaderBuffer); + + if (decryptedLayout->HasBackupHeader()) + { + // Re-encrypt backup volume header + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + + // Write backup volume header + headerOffset = decryptedLayout->GetBackupHeaderOffset(); + if (headerOffset >= 0) + volumeFile.SeekAt (headerOffset); + else + volumeFile.SeekEnd (headerOffset); + + volumeFile.Write (newHeaderBuffer); + } + } + + ShowInfo ("VOL_HEADER_RESTORED"); + } + + DevicePath GraphicUserInterface::SelectDevice (wxWindow *parent) const + { + try + { + DeviceSelectionDialog dialog (parent); + if (dialog.ShowModal() == wxID_OK) + { + return dialog.SelectedDevice.Path; + } + } + catch (exception &e) + { + Gui->ShowError (e); + } + + return DevicePath(); + } + + DirectoryPath GraphicUserInterface::SelectDirectory (wxWindow *parent, const wxString &message, bool existingOnly) const + { + return DirectoryPath (::wxDirSelector (!message.empty() ? message : +#ifdef __WXGTK__ + wxDirSelectorPromptStr, +#else + L"", +#endif + L"", wxDD_DEFAULT_STYLE | (existingOnly ? wxDD_DIR_MUST_EXIST : 0), wxDefaultPosition, parent)); + } + + FilePathList GraphicUserInterface::SelectFiles (wxWindow *parent, const wxString &caption, bool saveMode, bool allowMultiple, const list < pair > &fileExtensions, const DirectoryPath &directory) const + { + FilePathList files; + + long style; + if (saveMode) + style = wxFD_SAVE | wxFD_OVERWRITE_PROMPT; + else + style = wxFD_OPEN | wxFD_FILE_MUST_EXIST | (allowMultiple ? wxFD_MULTIPLE : 0); + + wxString wildcards = L"*.*"; + +#ifndef __WXGTK__ + if (!fileExtensions.empty()) +#endif + { + wildcards = LangString["ALL_FILES"] + +#ifdef TC_WINDOWS + L" (*.*)|*.*"; +#else + L"|*"; +#endif + typedef pair StringPair; + foreach (StringPair p, fileExtensions) + { + if (p.first == L"*" || p.first == L"*.*") + { + wildcards += L"|" + wildcards.substr (0, wildcards.find (L"*|") + 1); + wildcards = wildcards.substr (wildcards.find (L"*|") + 2); + continue; + } + + wildcards += wxString (L"|") + p.second + L" (*." + p.first + L")|*." + p.first; + } + } + + wxFileDialog dialog (parent, !caption.empty() ? caption : LangString ["OPEN_TITLE"], wstring (directory), wxString(), wildcards, style); + + if (dialog.ShowModal() == wxID_OK) + { + if (!allowMultiple) + files.push_back (make_shared (dialog.GetPath())); + else + { + wxArrayString paths; + dialog.GetPaths (paths); + + foreach (const wxString &path, paths) + files.push_back (make_shared (path)); + } + } + + return files; + } + + FilePath GraphicUserInterface::SelectVolumeFile (wxWindow *parent, bool saveMode, const DirectoryPath &directory) const + { + list < pair > extensions; + extensions.push_back (make_pair (L"tc", LangString["TC_VOLUMES"])); + + FilePathList selFiles = Gui->SelectFiles (parent, LangString[saveMode ? "OPEN_NEW_VOLUME" : "OPEN_VOL_TITLE"], saveMode, false, extensions, directory); + + if (!selFiles.empty()) + return *selFiles.front(); + else + return FilePath(); + } + + void GraphicUserInterface::SetBackgroundMode (bool state) + { +#ifdef TC_MACOSX + // Hiding an iconized window on OS X apparently cannot be reversed + if (state && mMainFrame->IsIconized()) + mMainFrame->Iconize (false); +#endif + mMainFrame->Show (!state); + if (!state) + { + if (mMainFrame->IsIconized()) + mMainFrame->Iconize (false); + + mMainFrame->Raise(); + } + + BackgroundMode = state; + } + + void GraphicUserInterface::SetListCtrlColumnWidths (wxListCtrl *listCtrl, list columnWidthPermilles, bool hasVerticalScrollbar) const + { +#ifdef TC_MACOSX + hasVerticalScrollbar = true; +#endif + int listWidth = listCtrl->GetSize().GetWidth(); + int minListWidth = listCtrl->GetMinSize().GetWidth(); + if (minListWidth > listWidth) + listWidth = minListWidth; + + listWidth -= GetScrollbarWidth (listCtrl, !hasVerticalScrollbar); + + int col = 0; + int totalColWidth = 0; + foreach (int colWidth, columnWidthPermilles) + { + int width = listWidth * colWidth / 1000; + totalColWidth += width; + + if (col == listCtrl->GetColumnCount() - 1) + width += listWidth - totalColWidth; + + listCtrl->SetColumnWidth (col++, width); + } + } + + void GraphicUserInterface::SetListCtrlHeight (wxListCtrl *listCtrl, size_t rowCount) const + { + wxRect itemRect; + if (listCtrl->GetItemCount() == 0) + { + bool addedCols = false; + if (listCtrl->GetColumnCount() == 0) + { + listCtrl->InsertColumn (0, L".", wxLIST_FORMAT_LEFT, 1); + addedCols = true; + } + vector f; + f.push_back (L"."); + AppendToListCtrl (listCtrl, f); + listCtrl->GetItemRect (0, itemRect); + + if (addedCols) + listCtrl->ClearAll(); + else + listCtrl->DeleteAllItems(); + } + else + listCtrl->GetItemRect (0, itemRect); + + int headerHeight = itemRect.y; +#ifdef TC_WINDOWS + headerHeight += 4; +#elif defined (TC_MACOSX) + headerHeight += 7; +#elif defined (__WXGTK__) + headerHeight += 5; +#endif + int rowHeight = itemRect.height; +#ifdef TC_MACOSX + rowHeight += 1; +#endif + listCtrl->SetMinSize (wxSize (listCtrl->GetMinSize().GetWidth(), rowHeight * rowCount + headerHeight)); + } + + void GraphicUserInterface::SetListCtrlWidth (wxListCtrl *listCtrl, size_t charCount, bool hasVerticalScrollbar) const + { + int width = GetCharWidth (listCtrl) * charCount; +#ifdef TC_MACOSX + if (!hasVerticalScrollbar) + width += GetScrollbarWidth (listCtrl); +#endif + listCtrl->SetMinSize (wxSize (width, listCtrl->GetMinSize().GetHeight())); + } + + void GraphicUserInterface::ShowErrorTopMost (const wxString &message) const + { + ShowMessage (message, wxOK | wxICON_ERROR, true); + } + + void GraphicUserInterface::ShowInfoTopMost (const wxString &message) const + { + ShowMessage (message, wxOK | wxICON_INFORMATION, true); + } + + int GraphicUserInterface::ShowMessage (const wxString &message, long style, bool topMost) const + { + wxString caption = Application::GetName(); + wxString subMessage = message; + +#ifdef TC_MACOSX + size_t p = message.find (L"\n"); + if (p != string::npos) + { + // Divide message to caption and info message + caption = message.substr (0, p); + + p = message.find_first_not_of (L'\n', p); + if (p != string::npos) + subMessage = message.substr (p); + else + subMessage.clear(); + + if (subMessage.EndsWith (L"?")) + { + // Move question to caption + caption += wstring (L" "); + p = subMessage.find_last_of (L".\n"); + if (p != string::npos) + { + if (caption.EndsWith (L": ")) + caption[caption.size() - 2] = L'.'; + + caption += subMessage.substr (subMessage.find_first_not_of (L"\n ", p + 1)); + subMessage = subMessage.substr (0, p + 1); + } + else + { + caption += subMessage.substr (subMessage.find_first_not_of (L"\n")); + subMessage.clear(); + } + } + } + else if (message.size() < 160) + { + caption = message; + subMessage.clear(); + } + else + { + if (style & wxICON_EXCLAMATION) + caption = wxString (_("Warning")) + L':'; + else if (style & wxICON_ERROR || style & wxICON_HAND) + caption = wxString (_("Error")) + L':'; + else + caption.clear(); + } +#endif + if (topMost) + { + if (!IsActive()) + mMainFrame->RequestUserAttention (wxUSER_ATTENTION_ERROR); + + style |= wxSTAY_ON_TOP; + } + + return wxMessageBox (subMessage, caption, style, GetActiveWindow()); + } + + void GraphicUserInterface::ShowWarningTopMost (const wxString &message) const + { + ShowMessage (message, wxOK +#ifndef TC_MACOSX + | wxICON_EXCLAMATION +#endif + , true); + } + + void GraphicUserInterface::ThrowTextModeRequired () const + { + Gui->ShowError (_("This feature is currently supported only in text mode.")); + throw UserAbort (SRC_POS); + } + + bool GraphicUserInterface::UpdateListCtrlItem (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields) const + { + bool changed = false; + wxListItem item; + item.SetId (itemIndex); + item.SetText (L""); + + int col = 0; + foreach (wxString field, itemFields) + { + item.SetColumn (col++); + + if (!listCtrl->GetItem (item)) + throw ParameterIncorrect (SRC_POS); + + if (item.GetText() != field) + { + item.SetText (field); + listCtrl->SetItem (item); + changed = true; + } + } + return changed; + } + + void GraphicUserInterface::UserEnrichRandomPool (wxWindow *parent, shared_ptr hash) const + { + RandomNumberGenerator::Start(); + + if (hash) + RandomNumberGenerator::SetHash (hash); + + if (!RandomNumberGenerator::IsEnrichedByUser()) + { + RandomPoolEnrichmentDialog dialog (parent); + RandomNumberGenerator::SetEnrichedByUserStatus (dialog.ShowModal() == wxID_OK); + } + } + + void GraphicUserInterface::Yield () const + { +#ifndef TC_WINDOWS + wxSafeYield (nullptr, true); +#endif + } + + DEFINE_EVENT_TYPE (TC_EVENT_THREAD_EXITING); + + GraphicUserInterface *Gui = nullptr; +} diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h new file mode 100644 index 00000000..f22b0af3 --- /dev/null +++ b/src/Main/GraphicUserInterface.h @@ -0,0 +1,160 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_GraphicUserInterface +#define TC_HEADER_Main_GraphicUserInterface + +#include "System.h" +#include +#include "Main.h" +#include "UserInterface.h" + +namespace TrueCrypt +{ + class GraphicUserInterface : public UserInterface + { + public: + GraphicUserInterface (); + virtual ~GraphicUserInterface (); + + virtual void AppendToListCtrl (wxListCtrl *listCtrl, const vector &itemFields, int imageIndex = -1, void *itemDataPtr = nullptr) const; + virtual wxMenuItem *AppendToMenu (wxMenu &menu, const wxString &label, wxEvtHandler *handler = nullptr, wxObjectEventFunction handlerFunction = nullptr, int itemId = wxID_ANY) const; + virtual bool AskYesNo (const wxString &message, bool defaultYes = false, bool warning = false) const; + virtual void AutoDismountVolumes (VolumeInfoList mountedVolumes, bool alwaysForce = true); + virtual void BackupVolumeHeaders (shared_ptr volumePath) const; + virtual void BeginBusyState () const { wxBeginBusyCursor(); } + virtual void BeginInteractiveBusyState (wxWindow *window); + virtual void ChangePassword (shared_ptr volumePath = shared_ptr (), shared_ptr password = shared_ptr (), shared_ptr keyfiles = shared_ptr (), shared_ptr newPassword = shared_ptr (), shared_ptr newKeyfiles = shared_ptr (), shared_ptr newHash = shared_ptr ()) const { ThrowTextModeRequired(); } + wxHyperlinkCtrl *CreateHyperlink (wxWindow *parent, const wxString &linkUrl, const wxString &linkText) const; + virtual void CreateKeyfile (shared_ptr keyfilePath = shared_ptr ()) const; + virtual void CreateVolume (shared_ptr options) const { ThrowTextModeRequired(); } + virtual void ClearListCtrlSelection (wxListCtrl *listCtrl) const; + virtual void DeleteSecurityTokenKeyfiles () const { ThrowTextModeRequired(); } + virtual void DoShowError (const wxString &message) const; + virtual void DoShowInfo (const wxString &message) const; + virtual void DoShowString (const wxString &str) const; + virtual void DoShowWarning (const wxString &message) const; + virtual void EndBusyState () const { wxEndBusyCursor(); } + virtual void EndInteractiveBusyState (wxWindow *window) const; + virtual void ExportSecurityTokenKeyfile () const { ThrowTextModeRequired(); } + virtual wxTopLevelWindow *GetActiveWindow () const; + virtual shared_ptr GetAdminPasswordRequestHandler (); + virtual int GetCharHeight (wxWindow *window) const; + virtual int GetCharWidth (wxWindow *window) const; + virtual int GetDefaultBorderSize () const { return 5; } + virtual wxFont GetDefaultBoldFont (wxWindow *window) const; + virtual wxString GetHomepageLinkURL (const wxString &linkId, bool secure = false, const wxString &extraVars = wxEmptyString) const; + virtual wxFrame *GetMainFrame () const { return mMainFrame; } + virtual int GetScrollbarWidth (wxWindow *window, bool noScrollBar = false) const; + virtual list GetListCtrlSelectedItems (wxListCtrl *listCtrl) const; + virtual wxString GetListCtrlSubItemText (wxListCtrl *listCtrl, long itemIndex, int columnIndex) const; + virtual void ImportSecurityTokenKeyfiles () const { ThrowTextModeRequired(); } + virtual void InitSecurityTokenLibrary () const; + virtual void InsertToListCtrl (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields, int imageIndex = -1, void *itemDataPtr = nullptr) const; + virtual bool IsInBackgroundMode () const { return BackgroundMode; } + virtual bool IsTheOnlyTopLevelWindow (const wxWindow *window) const; + virtual void ListSecurityTokenKeyfiles () const; + virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; + virtual shared_ptr MountVolume (MountOptions &options) const; + virtual void MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const; + virtual void OnAutoDismountAllEvent (); + virtual bool OnInit (); + virtual void OnLogOff (); + virtual void OpenDocument (wxWindow *parent, const wxFileName &document); + virtual void OpenHomepageLink (wxWindow *parent, const wxString &linkId, const wxString &extraVars = wxEmptyString); + virtual void OpenOnlineHelp (wxWindow *parent); + virtual void OpenUserGuide (wxWindow *parent); + virtual void RestoreVolumeHeaders (shared_ptr volumePath) const; + virtual DevicePath SelectDevice (wxWindow *parent) const; + virtual DirectoryPath SelectDirectory (wxWindow *parent, const wxString &message = wxEmptyString, bool existingOnly = true) const; + virtual FilePathList SelectFiles (wxWindow *parent, const wxString &caption, bool saveMode = false, bool allowMultiple = false, const list < pair > &fileExtensions = (list < pair > ()), const DirectoryPath &directory = DirectoryPath()) const; + virtual FilePath SelectVolumeFile (wxWindow *parent, bool saveMode = false, const DirectoryPath &directory = DirectoryPath()) const; + virtual void SetActiveFrame (wxFrame *frame) { ActiveFrame = frame; } + virtual void SetBackgroundMode (bool state); + virtual void SetListCtrlColumnWidths (wxListCtrl *listCtrl, list columnWidthPermilles, bool hasVerticalScrollbar = true) const; + virtual void SetListCtrlHeight (wxListCtrl *listCtrl, size_t rowCount) const; + virtual void SetListCtrlWidth (wxListCtrl *listCtrl, size_t charCount, bool hasVerticalScrollbar = true) const; + virtual void ShowErrorTopMost (char *langStringId) const { ShowErrorTopMost (LangString[langStringId]); } + virtual void ShowErrorTopMost (const wxString &message) const; + virtual void ShowInfoTopMost (char *langStringId) const { ShowInfoTopMost (LangString[langStringId]); } + virtual void ShowInfoTopMost (const wxString &message) const; + virtual void ShowWarningTopMost (char *langStringId) const { ShowWarningTopMost (LangString[langStringId]); } + virtual void ShowWarningTopMost (const wxString &message) const; + virtual bool UpdateListCtrlItem (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields) const; + virtual void UserEnrichRandomPool (wxWindow *parent, shared_ptr hash = shared_ptr ()) const; + virtual void Yield () const; + +#ifdef TC_MACOSX + virtual void MacOpenFile (const wxString &fileName); +#endif + + template + T *GetSelectedData (wxControlWithItems *control) const + { + int sel = control->GetSelection(); + if (sel == wxNOT_FOUND) + return nullptr; + + return reinterpret_cast (control->GetClientData (sel)); + } + + Event OpenVolumeSystemRequestEvent; + + protected: + virtual void OnEndSession (wxCloseEvent& event) { OnLogOff(); } +#ifdef wxHAS_POWER_EVENTS + virtual void OnPowerSuspending (wxPowerEvent& event); +#endif + static void OnSignal (int signal); + virtual void OnVolumesAutoDismounted (); + virtual int ShowMessage (const wxString &message, long style, bool topMost = false) const; + void ThrowTextModeRequired () const; + + wxFrame *ActiveFrame; + bool BackgroundMode; +#ifdef TC_WINDOWS + auto_ptr DDEServer; +#endif + wxFrame *mMainFrame; + auto_ptr SingleInstanceChecker; + + private: + GraphicUserInterface (const GraphicUserInterface &); + GraphicUserInterface &operator= (const GraphicUserInterface &); + }; + + + struct OpenVolumeSystemRequestEventArgs : public EventArgs + { + OpenVolumeSystemRequestEventArgs (const wxString &volumePath) : mVolumePath (volumePath) { } + wxString mVolumePath; + }; + + + class FreezeScope + { + public: + FreezeScope (wxWindow *window) : Window (window) + { + Window->Freeze(); + } + + ~FreezeScope () + { + Window->Thaw(); + } + + wxWindow *Window; + }; + + DECLARE_EVENT_TYPE (TC_EVENT_THREAD_EXITING, -1); + + extern GraphicUserInterface *Gui; +} + +#endif // TC_HEADER_Main_GraphicUserInterface diff --git a/src/Main/Hotkey.cpp b/src/Main/Hotkey.cpp new file mode 100644 index 00000000..95e7fa07 --- /dev/null +++ b/src/Main/Hotkey.cpp @@ -0,0 +1,241 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Application.h" +#include "LanguageStrings.h" +#include "GraphicUserInterface.h" +#include "Hotkey.h" +#include "Xml.h" + +namespace TrueCrypt +{ + HotkeyList Hotkey::GetAvailableHotkeys () + { + HotkeyList hotkeys; +#ifdef TC_WINDOWS + +#define TC_HOTKEY(ID,LANG) hotkeys.push_back (shared_ptr (new Hotkey (Id::##ID, L###ID, LangString[LANG]))) + + TC_HOTKEY (CloseAllSecurityTokenSessions, "IDM_CLOSE_ALL_TOKEN_SESSIONS"); + TC_HOTKEY (DismountAll, "HK_DISMOUNT_ALL"); + TC_HOTKEY (DismountAllWipeCache, "HK_DISMOUNT_ALL_AND_WIPE"); + TC_HOTKEY (ForceDismountAllWipeCache, "HK_FORCE_DISMOUNT_ALL_AND_WIPE"); + TC_HOTKEY (ForceDismountAllWipeCacheExit, "HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT"); + TC_HOTKEY (MountAllDevices, "HK_AUTOMOUNT_DEVICES"); + TC_HOTKEY (MountAllFavorites, "HK_MOUNT_FAVORITE_VOLUMES"); + TC_HOTKEY (ShowHideApplication, "HK_SHOW_HIDE_MAIN_WINDOW"); + TC_HOTKEY (WipeCache, "HK_WIPE_CACHE"); + +#endif + return hotkeys; + } + + wxString Hotkey::GetShortcutString () const + { + wxString keyStr = Hotkey::GetVirtualKeyCodeString (VirtualKeyCode); + if (keyStr.empty()) + return L""; + + wxString str; + + if (VirtualKeyModifiers & wxMOD_SHIFT) + str += LangString["VK_SHIFT"] + L"+"; + + if (VirtualKeyModifiers & wxMOD_CONTROL) + str += LangString["VK_CONTROL"] + L"+"; + + if (VirtualKeyModifiers & wxMOD_ALT) + str += LangString["VK_ALT"] + L"+"; + + if (VirtualKeyModifiers & wxMOD_WIN ) + str += LangString["VK_WIN"] + L"+"; + + return str + keyStr; + } + + wxString Hotkey::GetVirtualKeyCodeString (int virtualKeyCode) + { +#ifdef TC_WINDOWS + // ASCII characters + if (virtualKeyCode >= 0x30 && virtualKeyCode <= 0x5a) + return StringFormatter (L"{0}", char (virtualKeyCode)); + + // OEM-specific + if (virtualKeyCode >= 0xE9 && virtualKeyCode <= 0xF5) + return StringFormatter (L"OEM-{0}", virtualKeyCode); + + // F1-F24 + if (virtualKeyCode >= VK_F1 && virtualKeyCode <= VK_F24) + return StringFormatter (L"F{0}", virtualKeyCode - VK_F1 + 1); + + // Numpad numbers + if (virtualKeyCode >= VK_NUMPAD0 && virtualKeyCode <= VK_NUMPAD9) + return StringFormatter (L"{0} {1}", LangString["VK_NUMPAD"], virtualKeyCode - VK_NUMPAD0); + + switch (virtualKeyCode) + { + case VK_MULTIPLY: return LangString["VK_NUMPAD"] + L" *"; + case VK_ADD: return LangString["VK_NUMPAD"] + L" +"; + case VK_SEPARATOR: return LangString["VK_NUMPAD"] + L" Separator"; + case VK_SUBTRACT: return LangString["VK_NUMPAD"] + L" -"; + case VK_DECIMAL: return LangString["VK_NUMPAD"] + L" ."; + case VK_DIVIDE: return LangString["VK_NUMPAD"] + L" /"; + case VK_OEM_1: return L"OEM 1 (';')"; + case VK_OEM_PLUS: return L"+"; + case VK_OEM_COMMA: return L","; + case VK_OEM_MINUS: return L"-"; + case VK_OEM_PERIOD: return L"."; + case VK_OEM_2: return L"OEM 2 ('/')"; + case VK_OEM_3: return L"OEM 3 (`)"; + case VK_OEM_4: return L"OEM 4 ('[')"; + case VK_OEM_5: return L"OEM 5 ('\\')"; + case VK_OEM_6: return L"OEM 6 (']')"; + case VK_OEM_7: return L"OEM 7 (')"; + case VK_OEM_8: return L"OEM 8"; + case VK_OEM_AX: return L"OEM AX"; + case VK_OEM_102: return L"OEM 102"; + case VK_ICO_HELP: return L"ICO_HELP"; + case VK_ICO_00: return L"ICO_00"; + case VK_ICO_CLEAR: return L"ICO_CLEAR"; + case VK_ATTN: return L"Attn"; + case VK_CRSEL: return L"CrSel"; + case VK_EXSEL: return L"ExSel"; + case VK_EREOF: return L"Erase EOF"; + case VK_PA1: return L"PA1"; + case VK_OEM_CLEAR: return L"OEM Clear"; + + case 0: + case 1: + case 0xFF: + break; + + default: + { + string langStrId = StringConverter::ToSingle (wstring (wxString::Format (L"VKEY_%02X", virtualKeyCode))); + if (LangString.Exists (langStrId)) + return LangString[langStrId]; + } + } +#endif // TC_WINDOWS + return L""; + } + + HotkeyList Hotkey::LoadList () + { + HotkeyList hotkeys = GetAvailableHotkeys(); + + FilePath path = Application::GetConfigFilePath (GetFileName()); + if (path.IsFile()) + { + foreach (XmlNode node, XmlParser (path).GetNodes (L"hotkey")) + { + wstring keyName (node.Attributes[L"name"]); + + foreach (shared_ptr hotkey, hotkeys) + { + if (hotkey->Name == keyName) + { + hotkey->VirtualKeyCode = StringConverter::ToUInt32 (wstring (node.Attributes[L"vkeycode"])); + hotkey->VirtualKeyModifiers = 0; + + if (node.Attributes[L"modshift"] == L"1") + hotkey->VirtualKeyModifiers |= wxMOD_SHIFT; + + if (node.Attributes[L"modcontrol"] == L"1") + hotkey->VirtualKeyModifiers |= wxMOD_CONTROL; + + if (node.Attributes[L"modalt"] == L"1") + hotkey->VirtualKeyModifiers |= wxMOD_ALT; + + if (node.Attributes[L"modwin"] == L"1") + hotkey->VirtualKeyModifiers |= wxMOD_WIN; + + break; + } + } + } + } + + return hotkeys; + } + + void Hotkey::RegisterList (wxWindow *handler, const HotkeyList &hotkeys) + { +#ifdef TC_WINDOWS + bool res = true; + foreach (shared_ptr hotkey, hotkeys) + { + if (hotkey->VirtualKeyCode != 0) + { + if (!handler->RegisterHotKey (hotkey->Id, hotkey->VirtualKeyModifiers, hotkey->VirtualKeyCode)) + res = false; + } + } + + if (!res) + Gui->ShowWarning ("HOTKEY_REGISTRATION_ERROR"); +#endif + } + + void Hotkey::SaveList (const HotkeyList &hotkeys) + { + FilePath hotkeysCfgPath = Application::GetConfigFilePath (GetFileName(), true); + + bool noHotkey = true; + XmlNode hotkeysXml (L"hotkeys"); + foreach_ref (const Hotkey &hotkey, hotkeys) + { + if (hotkey.VirtualKeyCode == 0) + continue; + + noHotkey = false; + XmlNode node (L"hotkey"); + node.Attributes[L"name"] = wstring (hotkey.Name); + + node.Attributes[L"vkeycode"] = StringConverter::FromNumber (hotkey.VirtualKeyCode); + + if (hotkey.VirtualKeyModifiers & wxMOD_SHIFT) + node.Attributes[L"modshift"] = L"1"; + + if (hotkey.VirtualKeyModifiers & wxMOD_CONTROL) + node.Attributes[L"modcontrol"] = L"1"; + + if (hotkey.VirtualKeyModifiers & wxMOD_ALT) + node.Attributes[L"modalt"] = L"1"; + + if (hotkey.VirtualKeyModifiers & wxMOD_WIN ) + node.Attributes[L"modwin"] = L"1"; + + hotkeysXml.InnerNodes.push_back (node); + } + + if (noHotkey) + { + if (hotkeysCfgPath.IsFile()) + hotkeysCfgPath.Delete(); + } + else + { + XmlWriter hotkeysWriter (hotkeysCfgPath); + hotkeysWriter.WriteNode (hotkeysXml); + hotkeysWriter.Close(); + } + } + + void Hotkey::UnregisterList (wxWindow *handler, const HotkeyList &hotkeys) + { +#ifdef TC_WINDOWS + foreach (shared_ptr hotkey, hotkeys) + { + if (hotkey->VirtualKeyCode != 0) + handler->UnregisterHotKey (hotkey->Id); + } +#endif + } +} diff --git a/src/Main/Hotkey.h b/src/Main/Hotkey.h new file mode 100644 index 00000000..be8603a3 --- /dev/null +++ b/src/Main/Hotkey.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Hotkey +#define TC_HEADER_Main_Hotkey + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + struct Hotkey; + typedef list < shared_ptr > HotkeyList; + + struct Hotkey + { + public: + struct Id + { + enum + { + CloseAllSecurityTokenSessions = 0, + DismountAll, + DismountAllWipeCache, + ForceDismountAllWipeCache, + ForceDismountAllWipeCacheExit, + MountAllDevices, + MountAllFavorites, + ShowHideApplication, + WipeCache + }; + }; + + Hotkey (int id, const wstring &name, const wxString &description, int virtualKeyCode = 0, int virtualKeyModifiers = 0) + : Description (description), Id (id), Name (name), VirtualKeyCode (virtualKeyCode), VirtualKeyModifiers (virtualKeyModifiers) { } + + virtual ~Hotkey () { } + + static HotkeyList GetAvailableHotkeys (); + wxString GetShortcutString () const; + static wxString GetVirtualKeyCodeString (int virtualKeyCode); + static HotkeyList LoadList (); + static void RegisterList (wxWindow *handler, const HotkeyList &hotkeys); + static void SaveList (const HotkeyList &hotkeys); + static void UnregisterList (wxWindow *handler, const HotkeyList &hotkeys); + + wxString Description; + int Id; + wstring Name; + int VirtualKeyCode; + int VirtualKeyModifiers; + + protected: + static wxString GetFileName () { return L"Hotkeys.xml"; } + }; +} + +#endif // TC_HEADER_Main_Hotkey diff --git a/src/Main/LanguageStrings.cpp b/src/Main/LanguageStrings.cpp new file mode 100644 index 00000000..873e6ede --- /dev/null +++ b/src/Main/LanguageStrings.cpp @@ -0,0 +1,86 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Resources.h" +#include "LanguageStrings.h" +#include "Xml.h" + +namespace TrueCrypt +{ + LanguageStrings::LanguageStrings () + { + } + + LanguageStrings::~LanguageStrings () + { + } + + wxString LanguageStrings::operator[] (const string &key) const + { + if (Map.count (key) > 0) + return wxString (Map.find (key)->second); + + return wxString (L"?") + StringConverter::ToWide (key) + L"?"; + } + + wstring LanguageStrings::Get (const string &key) const + { + return wstring (LangString[key]); + } + + void LanguageStrings::Init () + { + foreach (XmlNode node, XmlParser (Resources::GetLanguageXml()).GetNodes (L"string")) + { + wxString text = node.InnerText; + text.Replace (L"\\n", L"\n"); + Map[StringConverter::ToSingle (wstring (node.Attributes[L"key"]))] = text; + } + + foreach (XmlNode node, XmlParser (Resources::GetLanguageXml()).GetNodes (L"control")) + { + wxString text = node.InnerText; + text.Replace (L"\\n", L"\n"); + Map[StringConverter::ToSingle (wstring (node.Attributes[L"key"]))] = text; + } + + Map["EXCEPTION_OCCURRED"] = _("Exception occurred"); + Map["MOUNT"] = _("Mount"); + Map["MOUNT_POINT"] = _("Mount Directory"); + Map["NO"] = _("No"); + Map["NO_VOLUMES_MOUNTED"] = _("No volumes mounted."); + Map["OPEN_NEW_VOLUME"] = _("Specify a New TrueCrypt Volume"); + Map["PARAMETER_INCORRECT"] = _("Parameter incorrrect"); + Map["SELECT_KEYFILES"] = _("Select Keyfiles"); + Map["START_TC"] = _("Start TrueCrypt"); + Map["VOLUME_ALREADY_MOUNTED"] = _("The volume \"{0}\" is already mounted."); + Map["UNKNOWN_OPTION"] = _("Unknown option"); + Map["VOLUME_LOCATION"] = _("Volume Location"); + Map["YES"] = _("Yes"); + Map["VOLUME_HOST_IN_USE"] = _("WARNING: The host file/device \"{0}\" is already in use!\n\nIgnoring this can cause undesired results including system instability. All applications that might be using the host file/device should be closed before mounting the volume.\n\nContinue mounting?"); + Map["VIRTUAL_DEVICE"] = _("Virtual Device"); + Map["CONFIRM_BACKGROUND_TASK_DISABLED"] = _("WARNING: If the TrueCrypt Background Task is disabled, the following functions, depending on the platform, will be disabled whenever you exit TrueCrypt:\n\n1) Auto-dismount (e.g., upon logoff, time-out, etc.)\n2) Notifications (e.g., when damage to hidden volume is prevented)\n3) Tray icon\n\nNote: You may shut down the Background Task anytime by right-clicking the TrueCrypt tray icon and selecting 'Exit'.\n\nAre you sure you want to disable the TrueCrypt Background Task?"); + Map["CONFIRM_EXIT"] = _("WARNING: If TrueCrypt exits now, the following functions, depending on the platform, will be disabled:\n\n1) Auto-dismount (e.g., upon logoff, time-out, etc.)\n2) Notifications (e.g., when damage to hidden volume is prevented)\n3) Tray icon\n\nNote: If you do not wish TrueCrypt to continue running in background after you close its window, disable the Background Task in the Preferences.\n\nAre you sure you want TrueCrypt to exit?"); + Map["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"] = _("WARNING: Data were attempted to be saved to the hidden volume area of the volume \"{0}\"!\n\nTrueCrypt prevented these data from being saved in order to protect the hidden volume. This may have caused filesystem corruption on the outer volume and the operating system may have reported a write error (\"Delayed Write Failed\", \"The parameter is incorrect\", etc.). The entire volume (both the outer and the hidden part) will be write-protected until it is dismounted.\n\nWe strongly recommend that you restart the operating system now."); + Map["ENTER_PASSWORD"] = _("Enter password"); + Map["ENTER_PASSWORD_FOR"] = _("Enter password for \"{0}\""); + Map["ENTER_TC_VOL_PASSWORD"] = _("Enter TrueCrypt Volume Password"); + Map["SELECT_KEYFILE_PATH"] = _("Select Keyfile Search Path"); + Map["MORE_INFO_ABOUT"] = _("More information on {0}"); + Map["TWO_LAYER_CASCADE_HELP"] = _("Two ciphers in a cascade operating in XTS mode. Each block is first encrypted with {0} ({1}-bit key) and then with {2} ({3}-bit key). Each cipher uses its own key. All keys are mutually independent."); + Map["THREE_LAYER_CASCADE_HELP"] = _("Three ciphers in a cascade operating in XTS mode. Each block is first encrypted with {0} ({1}-bit key), then with {2} ({3}-bit key), and finally with {4} ({5}-bit key). Each cipher uses its own key. All keys are mutually independent."); + Map["CHECKING_FS"] = _("Checking the file system on the TrueCrypt volume mounted as {0}..."); + Map["REPAIRING_FS"] = _("Attempting to repair the file system on the TrueCrypt volume mounted as {0}..."); + Map["UNMOUNT_LOCK_FAILED"] = _("Volume \"{0}\" contains files or folders being used by applications or system.\n\nForce dismount?"); + Map["VOLUME_SIZE_HELP"] = _("Please specify the size of the container to create. Note that the minimum possible size of a volume is 292 KB."); + Map["ENCRYPTION_MODE_NOT_SUPPORTED_BY_KERNEL"] = _("The volume you have mounted uses a mode of operation that is not supported by the Linux kernel. You may experience slow performance when using this volume. To achieve full performance, you should move the data from this volume to a new volume created by TrueCrypt 5.0 or later."); + } + + LanguageStrings LangString; +} diff --git a/src/Main/LanguageStrings.h b/src/Main/LanguageStrings.h new file mode 100644 index 00000000..fa94a091 --- /dev/null +++ b/src/Main/LanguageStrings.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_LanguageStrings +#define TC_HEADER_Main_LanguageStrings + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + class LanguageStrings + { + public: + LanguageStrings (); + virtual ~LanguageStrings (); + + wxString operator[] (const string &key) const; + + bool Exists (const string &key) const { return Map.find (key) != Map.end(); } + wstring Get (const string &key) const; + void Init (); + + protected: + map Map; + + private: + LanguageStrings (const LanguageStrings &); + LanguageStrings &operator= (const LanguageStrings &); + }; + + extern LanguageStrings LangString; +} + +#endif // TC_HEADER_Main_LanguageStrings diff --git a/src/Main/Main.h b/src/Main/Main.h new file mode 100644 index 00000000..156a45ba --- /dev/null +++ b/src/Main/Main.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Main +#define TC_HEADER_Main_Main + +#include "System.h" +#include "Platform/Platform.h" +#include "Core/Core.h" +#include "Main/StringFormatter.h" + +#endif // TC_HEADER_Main_Main diff --git a/src/Main/Main.make b/src/Main/Main.make new file mode 100644 index 00000000..565ed400 --- /dev/null +++ b/src/Main/Main.make @@ -0,0 +1,145 @@ +# +# Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +OBJS := +OBJS += Application.o +OBJS += CommandLineInterface.o +OBJS += FavoriteVolume.o +OBJS += LanguageStrings.o +OBJS += StringFormatter.o +OBJS += TextUserInterface.o +OBJS += UserInterface.o +OBJS += UserPreferences.o +OBJS += Xml.o +OBJS += Unix/Main.o +OBJS += Resources.o + +ifndef TC_NO_GUI +OBJS += FatalErrorHandler.o +OBJS += GraphicUserInterface.o +OBJS += VolumeHistory.o +OBJS += Forms/AboutDialog.o +OBJS += Forms/BenchmarkDialog.o +OBJS += Forms/ChangePasswordDialog.o +OBJS += Forms/DeviceSelectionDialog.o +OBJS += Forms/EncryptionOptionsWizardPage.o +OBJS += Forms/EncryptionTestDialog.o +OBJS += Forms/FavoriteVolumesDialog.o +OBJS += Forms/Forms.o +OBJS += Forms/InfoWizardPage.o +OBJS += Forms/KeyfileGeneratorDialog.o +OBJS += Forms/KeyfilesDialog.o +OBJS += Forms/KeyfilesPanel.o +OBJS += Forms/LegalNoticesDialog.o +OBJS += Forms/MainFrame.o +OBJS += Forms/MountOptionsDialog.o +OBJS += Forms/NewSecurityTokenKeyfileDialog.o +OBJS += Forms/PreferencesDialog.o +OBJS += Forms/ProgressWizardPage.o +OBJS += Forms/RandomPoolEnrichmentDialog.o +OBJS += Forms/SecurityTokenKeyfilesDialog.o +OBJS += Forms/SelectDirectoryWizardPage.o +OBJS += Forms/VolumePasswordPanel.o +OBJS += Forms/VolumePropertiesDialog.o +OBJS += Forms/VolumeCreationProgressWizardPage.o +OBJS += Forms/VolumeCreationWizard.o +OBJS += Forms/VolumeFormatOptionsWizardPage.o +OBJS += Forms/VolumeLocationWizardPage.o +OBJS += Forms/VolumePasswordWizardPage.o +OBJS += Forms/VolumeSizeWizardPage.o +OBJS += Forms/WizardFrame.o +endif + +ifndef DISABLE_PRECOMPILED_HEADERS +PCH := SystemPrecompiled.h.gch +endif + +RESOURCES := +RESOURCES += ../License.txt.h +RESOURCES += ../Common/Language.xml.h +ifndef TC_NO_GUI +RESOURCES += ../Common/Textual_logo_96dpi.bmp.h +RESOURCES += ../Format/TrueCrypt_Wizard.bmp.h +RESOURCES += ../Mount/Drive_icon_96dpi.bmp.h +RESOURCES += ../Mount/Drive_icon_mask_96dpi.bmp.h +RESOURCES += ../Mount/Logo_96dpi.bmp.h +endif + +CXXFLAGS += -I$(BASE_DIR)/Main + + +#------ wxWidgets configuration ------ + +ifdef TC_NO_GUI +WX_CONFIG_LIBS := base +else +WX_CONFIG_LIBS := adv,core,base +endif + +ifeq "$(TC_BUILD_CONFIG)" "Release" + +CXXFLAGS += $(shell $(WX_CONFIG) $(WX_CONFIG_ARGS) --cxxflags) +WX_LIBS = $(shell $(WX_CONFIG) $(WX_CONFIG_ARGS) --libs $(WX_CONFIG_LIBS)) + +else + +CXXFLAGS += $(shell $(WX_CONFIG) --debug $(WX_CONFIG_ARGS) --cxxflags) +WX_LIBS = $(shell $(WX_CONFIG) --debug $(WX_CONFIG_ARGS) --libs $(WX_CONFIG_LIBS)) + +endif + + +#------ FUSE configuration ------ + +FUSE_LIBS = $(shell pkg-config fuse --libs) + + +#------ Executable ------ + +TC_VERSION = $(shell grep VERSION_STRING ../Common/Tcdefs.h | head -n 1 | cut -d'"' -f 2) + +$(APPNAME): $(LIBS) $(OBJS) + @echo Linking $@ + $(CXX) -o $(APPNAME) $(LFLAGS) $(OBJS) $(LIBS) $(FUSE_LIBS) $(WX_LIBS) + +ifeq "$(TC_BUILD_CONFIG)" "Release" +ifndef NOSTRIP + strip $(APPNAME) +endif + +ifndef NOTEST + ./$(APPNAME) --text --test >/dev/null || exit 1 +endif + +ifeq "$(PLATFORM_UNSUPPORTED)" "1" + @echo; echo "WARNING: This platform may be unsupported. To avoid possible serious problems, please read the chapter pertaining to $(PLATFORM) in Readme.txt."; echo +endif +endif + +ifeq "$(PLATFORM)" "MacOSX" + mkdir -p $(APPNAME).app/Contents/MacOS $(APPNAME).app/Contents/Resources + -rm -f $(APPNAME).app/Contents/MacOS/$(APPNAME) + +ifeq "$(TC_BUILD_CONFIG)" "Release" + cp $(PWD)/Main/$(APPNAME) $(APPNAME).app/Contents/MacOS/$(APPNAME) +else + -ln -sf $(PWD)/Main/$(APPNAME) $(APPNAME).app/Contents/MacOS/$(APPNAME) +endif + + cp $(PWD)/Resources/Icons/TrueCrypt.icns $(APPNAME).app/Contents/Resources + + echo -n APPLTRUE >$(APPNAME).app/Contents/PkgInfo + sed -e 's/_VERSION_/$(patsubst %a,%.1,$(patsubst %b,%.2,$(TC_VERSION)))/' ../Build/Resources/MacOSX/Info.plist.xml >$(APPNAME).app/Contents/Info.plist +endif + + +$(OBJS): $(PCH) + +Resources.o: $(RESOURCES) + +include $(BUILD_INC)/Makefile.inc diff --git a/src/Main/Resources.cpp b/src/Main/Resources.cpp new file mode 100644 index 00000000..2891134c --- /dev/null +++ b/src/Main/Resources.cpp @@ -0,0 +1,184 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Platform/Platform.h" +#include "Resources.h" + +#ifdef TC_WINDOWS +#include "Main/resource.h" +#endif + +namespace TrueCrypt +{ + +#ifdef TC_WINDOWS + static ConstBufferPtr GetWindowsResource (const wchar_t *resourceType, const wchar_t *resourceName) + { + HGLOBAL hResL; + HRSRC hRes; + + hRes = FindResource (NULL, resourceName, resourceType); + throw_sys_if (!hRes); + hResL = LoadResource (NULL, hRes); + throw_sys_if (!hResL); + + const byte *resPtr = (const byte *) LockResource (hResL); + throw_sys_if (!resPtr); + + return ConstBufferPtr (resPtr, SizeofResource (NULL, hRes)); + } +#endif // TC_WINDOWS + + + string Resources::GetLanguageXml () + { +#ifdef TC_WINDOWS + ConstBufferPtr res = GetWindowsResource (L"XML", L"IDR_LANGUAGE"); + Buffer strBuf (res.Size() + 1); + strBuf.Zero(); + strBuf.CopyFrom (res); + return string (reinterpret_cast (strBuf.Ptr())); +#else + static const char LanguageXml[] = + { +# include "Common/Language.xml.h" + , 0 + }; + + return string (LanguageXml); +#endif + } + + string Resources::GetLegalNotices () + { +#ifdef TC_WINDOWS + ConstBufferPtr res = GetWindowsResource (L"TEXT", L"IDR_LICENSE"); + Buffer strBuf (res.Size() + 1); + strBuf.Zero(); + strBuf.CopyFrom (res); + return string (reinterpret_cast (strBuf.Ptr())); +#else + static const char License[] = + { +# include "License.txt.h" + , 0 + }; + + return string (License); +#endif + } + + +#ifndef TC_NO_GUI + + wxBitmap Resources::GetDriveIconBitmap () + { +#ifdef TC_WINDOWS + return wxBitmap (L"IDB_DRIVE_ICON", wxBITMAP_TYPE_BMP_RESOURCE).ConvertToImage().Resize (wxSize (16, 12), wxPoint (0, 0)); +#else + static const byte DriveIcon[] = + { +# include "Mount/Drive_icon_96dpi.bmp.h" + }; + + wxMemoryInputStream stream (DriveIcon, sizeof (DriveIcon)); + return wxBitmap (wxImage (stream).Resize (wxSize (16, 12), wxPoint (0, 0))); +#endif + } + + wxBitmap Resources::GetDriveIconMaskBitmap () + { +#ifdef TC_WINDOWS + wxImage image = wxBitmap (L"IDB_DRIVE_ICON_MASK", wxBITMAP_TYPE_BMP_RESOURCE).ConvertToImage().Resize (wxSize (16, 12), wxPoint (0, 0)); + return wxBitmap (image.ConvertToMono (0, 0, 0), 1); +#else + static const byte DriveIconMask[] = + { +# include "Mount/Drive_icon_mask_96dpi.bmp.h" + }; + + wxMemoryInputStream stream (DriveIconMask, sizeof (DriveIconMask)); + wxImage image (stream); + image.Resize (wxSize (16, 12), wxPoint (0, 0)); + +# ifdef __WXGTK__ + return wxBitmap (image.ConvertToMono (0, 0, 0), 1); +# else + return wxBitmap (image); +# endif +#endif + } + + + wxBitmap Resources::GetLogoBitmap () + { +#ifdef TC_WINDOWS + return wxBitmap (L"IDB_LOGO", wxBITMAP_TYPE_BMP_RESOURCE); +#else + static const byte Logo[] = + { +# include "Mount/Logo_96dpi.bmp.h" + }; + + wxMemoryInputStream stream (Logo, sizeof (Logo)); + return wxBitmap (wxImage (stream)); +#endif + } + + wxBitmap Resources::GetTextualLogoBitmap () + { +#ifdef TC_WINDOWS + return wxBitmap (L"IDB_TEXTUAL_LOGO", wxBITMAP_TYPE_BMP_RESOURCE); +#else + static const byte Logo[] = + { +# include "Common/Textual_logo_96dpi.bmp.h" + }; + + wxMemoryInputStream stream (Logo, sizeof (Logo)); + return wxBitmap (wxImage (stream)); +#endif + } + + wxIcon Resources::GetTrueCryptIcon () + { +#ifdef TC_WINDOWS + return wxIcon (L"IDI_TRUECRYPT_ICON", wxBITMAP_TYPE_ICO_RESOURCE, 16, 16); +#else +# include "Resources/Icons/TrueCrypt-16x16.xpm" + return wxIcon (TrueCryptIcon16x16); +#endif + } + + wxBitmap Resources::GetVolumeCreationWizardBitmap (int height) + { +#ifdef TC_WINDOWS + return wxBitmap (L"IDB_VOLUME_WIZARD_BITMAP", wxBITMAP_TYPE_BMP_RESOURCE); +#else + static const byte VolumeWizardIcon[] = + { +# include "Format/TrueCrypt_Wizard.bmp.h" + }; + + wxMemoryInputStream stream (VolumeWizardIcon, sizeof (VolumeWizardIcon)); + + wxImage image (stream); + if (height != -1) + { + double scaleFactor = double (height) / double (image.GetHeight()); + image.Rescale (int (image.GetWidth() * scaleFactor), int (image.GetHeight() * scaleFactor), wxIMAGE_QUALITY_HIGH); + } + + return wxBitmap (image); +#endif + } + +#endif // !TC_NO_GUI + +} diff --git a/src/Main/Resources.h b/src/Main/Resources.h new file mode 100644 index 00000000..a071253f --- /dev/null +++ b/src/Main/Resources.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Resources +#define TC_HEADER_Main_Resources + +#include "System.h" +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + class Resources + { + public: + static string GetLanguageXml (); + static string GetLegalNotices (); +#ifndef TC_NO_GUI + static wxBitmap GetDriveIconBitmap (); + static wxBitmap GetDriveIconMaskBitmap (); + static wxBitmap GetLogoBitmap (); + static wxBitmap GetTextualLogoBitmap (); + static wxIcon GetTrueCryptIcon (); + static wxBitmap GetVolumeCreationWizardBitmap (int height = -1); +#endif + }; +} + +#endif // TC_HEADER_Main_Resources diff --git a/src/Main/StringFormatter.cpp b/src/Main/StringFormatter.cpp new file mode 100644 index 00000000..5adb4c63 --- /dev/null +++ b/src/Main/StringFormatter.cpp @@ -0,0 +1,88 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "StringFormatter.h" +#include "UserInterfaceException.h" + +namespace TrueCrypt +{ + StringFormatter::StringFormatter (const wxString &format, StringFormatterArg arg0, StringFormatterArg arg1, StringFormatterArg arg2, StringFormatterArg arg3, StringFormatterArg arg4, StringFormatterArg arg5, StringFormatterArg arg6, StringFormatterArg arg7, StringFormatterArg arg8, StringFormatterArg arg9) + { + bool numberExpected = false; + bool endTagExpected = false; + foreach (wchar_t c, wstring (format)) + { + if (numberExpected) + { + endTagExpected = true; + bool err = false; + + switch (c) + { + case L'{': FormattedString += L'{'; endTagExpected = false; break; // Escaped { + + case L'0': FormattedString += arg0; err = arg0.IsEmpty(); break; + case L'1': FormattedString += arg1; err = arg1.IsEmpty(); break; + case L'2': FormattedString += arg2; err = arg2.IsEmpty(); break; + case L'3': FormattedString += arg3; err = arg3.IsEmpty(); break; + case L'4': FormattedString += arg4; err = arg4.IsEmpty(); break; + case L'5': FormattedString += arg5; err = arg5.IsEmpty(); break; + case L'6': FormattedString += arg6; err = arg6.IsEmpty(); break; + case L'7': FormattedString += arg7; err = arg7.IsEmpty(); break; + case L'8': FormattedString += arg8; err = arg8.IsEmpty(); break; + case L'9': FormattedString += arg9; err = arg9.IsEmpty(); break; + + default: err = true; break; + } + + if (err) + throw StringFormatterException (SRC_POS, wstring (format)); + + numberExpected = false; + } + else if (endTagExpected) + { + if (c != L'}') + throw StringFormatterException (SRC_POS, wstring (format)); + + endTagExpected = false; + } + else if (c == L'{') + { + numberExpected = true; + } + else if (c == L'}') + { + FormattedString += c; + endTagExpected = true; + } + else + FormattedString += c; + } + + if (numberExpected + || endTagExpected + || (!arg0.WasReferenced() && !arg0.IsEmpty()) + || (!arg1.WasReferenced() && !arg1.IsEmpty()) + || (!arg2.WasReferenced() && !arg2.IsEmpty()) + || (!arg3.WasReferenced() && !arg3.IsEmpty()) + || (!arg4.WasReferenced() && !arg4.IsEmpty()) + || (!arg5.WasReferenced() && !arg5.IsEmpty()) + || (!arg6.WasReferenced() && !arg6.IsEmpty()) + || (!arg7.WasReferenced() && !arg7.IsEmpty()) + || (!arg8.WasReferenced() && !arg8.IsEmpty()) + || (!arg9.WasReferenced() && !arg9.IsEmpty()) + ) + throw StringFormatterException (SRC_POS, wstring (format)); + } + + StringFormatter::~StringFormatter () + { + } +} diff --git a/src/Main/StringFormatter.h b/src/Main/StringFormatter.h new file mode 100644 index 00000000..aa09131f --- /dev/null +++ b/src/Main/StringFormatter.h @@ -0,0 +1,64 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_StringFormatter +#define TC_HEADER_Main_StringFormatter + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + class StringFormatterArg + { + public: + StringFormatterArg () : Empty (true) { } + + StringFormatterArg (const char c) : Empty (false) { string s; s += c; StringArg = StringConverter::ToWide (s); } + StringFormatterArg (const wchar_t c) : Empty (false), Referenced (false), StringArg (c) { } + StringFormatterArg (const char *str) : Empty (false), Referenced (false), StringArg (StringConverter::ToWide (str)) { } + StringFormatterArg (const wchar_t *str) : Empty (false), Referenced (false), StringArg (str) { } + StringFormatterArg (const string &str) : Empty (false), Referenced (false), StringArg (StringConverter::ToWide (str)) { } + StringFormatterArg (const wstring &str) : Empty (false), Referenced (false), StringArg (str) { } + StringFormatterArg (const wxString &str) : Empty (false), Referenced (false), StringArg (str) { } + StringFormatterArg (int32 number) : Empty (false), Referenced (false), StringArg (StringConverter::FromNumber (number)) { } + StringFormatterArg (uint32 number) : Empty (false), Referenced (false), StringArg (StringConverter::FromNumber (number)) { } + StringFormatterArg (int64 number) : Empty (false), Referenced (false), StringArg (StringConverter::FromNumber (number)) { } + StringFormatterArg (uint64 number) : Empty (false), Referenced (false), StringArg (StringConverter::FromNumber (number)) { } + + operator wxString () { Referenced = true; return StringArg; } + + bool IsEmpty () const { return Empty; } + bool WasReferenced() const { return Referenced; } + + protected: + bool Empty; + bool Referenced; + wxString StringArg; + }; + + class StringFormatter + { + public: + StringFormatter (const wxString &format, StringFormatterArg arg0 = StringFormatterArg(), StringFormatterArg arg1 = StringFormatterArg(), StringFormatterArg arg2 = StringFormatterArg(), StringFormatterArg arg3 = StringFormatterArg(), StringFormatterArg arg4 = StringFormatterArg(), StringFormatterArg arg5 = StringFormatterArg(), StringFormatterArg arg6 = StringFormatterArg(), StringFormatterArg arg7 = StringFormatterArg(), StringFormatterArg arg8 = StringFormatterArg(), StringFormatterArg arg9 = StringFormatterArg()); + virtual ~StringFormatter (); + + operator wstring () const { return wstring (FormattedString); } + operator wxString () const { return FormattedString; } + operator StringFormatterArg () const { return FormattedString; } + + protected: + wxString FormattedString; + + private: + StringFormatter (const StringFormatter &); + StringFormatter &operator= (const StringFormatter &); + }; +} + +#endif // TC_HEADER_Main_StringFormatter diff --git a/src/Main/System.cpp b/src/Main/System.cpp new file mode 100644 index 00000000..e07c5f37 --- /dev/null +++ b/src/Main/System.cpp @@ -0,0 +1,10 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +// Precompiled header +#include "System.h" \ No newline at end of file diff --git a/src/Main/System.h b/src/Main/System.h new file mode 100644 index 00000000..0a7b69f1 --- /dev/null +++ b/src/Main/System.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_System +#define TC_HEADER_Main_System + +#ifndef TC_WINDOWS + +#include "SystemPrecompiled.h" + +#else + +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#ifndef TC_LOCAL_WIN32_WINNT_OVERRIDE +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0501 +# endif +#endif + +#ifndef _WIN32_WINDOWS +#define _WIN32_WINDOWS 0x0410 +#endif + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif + +#define WIN32_LEAN_AND_MEAN + +#ifndef UNICODE +#define UNICODE +#endif + +#ifndef _UNICODE +#define _UNICODE +#endif _UNICODE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#endif + +#endif // TC_HEADER_Main_System diff --git a/src/Main/SystemPrecompiled.h b/src/Main/SystemPrecompiled.h new file mode 100644 index 00000000..956760ff --- /dev/null +++ b/src/Main/SystemPrecompiled.h @@ -0,0 +1,29 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include + +#ifndef TC_NO_GUI +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp new file mode 100644 index 00000000..d9e93e6f --- /dev/null +++ b/src/Main/TextUserInterface.cpp @@ -0,0 +1,1552 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#ifdef TC_UNIX +#include +#include +#include +#include +#include +#include "Platform/Unix/Process.h" +#endif + +#include "Common/SecurityToken.h" +#include "Core/RandomNumberGenerator.h" +#include "Application.h" +#include "TextUserInterface.h" + +namespace TrueCrypt +{ + TextUserInterface::TextUserInterface () + { +#ifdef TC_UNIX + signal (SIGHUP, OnSignal); + signal (SIGINT, OnSignal); + signal (SIGQUIT, OnSignal); + signal (SIGTERM, OnSignal); + + struct stat statBuf; + if (fstat (0, &statBuf) != -1) +#endif + { + FInputStream.reset (new wxFFileInputStream (stdin)); + TextInputStream.reset (new wxTextInputStream (*FInputStream)); + } + } + + TextUserInterface::~TextUserInterface () + { + try + { + if (RandomNumberGenerator::IsRunning()) + RandomNumberGenerator::Stop(); + } + catch (...) { } + +#ifdef TC_UNIX + signal (SIGHUP, SIG_DFL); + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGTERM, SIG_DFL); +#endif + } + + FilePath TextUserInterface::AskFilePath (const wxString &message) const + { + return AskString (!message.empty() ? message : wxString (_("Enter filename: "))); + } + + shared_ptr TextUserInterface::AskKeyfiles (const wxString &message) const + { + wxString msg = _("Enter keyfile"); + if (!message.empty()) + msg = message; + + make_shared_auto (KeyfileList, keyfiles); + + wxString s; + wxString m = msg + L" [" + _("none") + L"]: "; + while (!(s = AskString (m)).empty()) + { + keyfiles->push_back (make_shared (wstring (s))); + m = msg + L" [" + _("finish") + L"]: "; + } + + return keyfiles; + } + + shared_ptr TextUserInterface::AskPassword (const wxString &message, bool verify) const + { + wxString msg = LangString["ENTER_PASSWORD"] + L": "; + if (!message.empty()) + msg = message + L": "; + + SetTerminalEcho (false); + finally_do ({ TextUserInterface::SetTerminalEcho (true); }); + + wchar_t passwordBuf[4096]; + finally_do_arg (BufferPtr, BufferPtr (reinterpret_cast (passwordBuf), sizeof (passwordBuf)), { finally_arg.Erase(); }); + + make_shared_auto (VolumePassword, password); + + bool verPhase = false; + while (true) + { + ShowString (verPhase ? wxString (_("Re-enter password: ")) : msg); + + wxString passwordStr; + ReadInputStreamLine (passwordStr); + + size_t length = passwordStr.size(); + + ShowString (L"\n"); + + if (!verPhase && length < 1) + { + password->Set (passwordBuf, 0); + return password; + } + + for (size_t i = 0; i < length && i < VolumePassword::MaxSize; ++i) + { + passwordBuf[i] = (wchar_t) passwordStr[i]; + const_cast (passwordStr.c_str())[i] = L'X'; + } + + if (verify && verPhase) + { + make_shared_auto (VolumePassword, verPassword); + verPassword->Set (passwordBuf, length); + + if (*password != *verPassword) + { + ShowInfo (_("Passwords do not match.")); + ShowString (L"\n"); + verPhase = false; + continue; + } + } + + password->Set (passwordBuf, length); + + if (!verPhase) + { + try + { + password->CheckPortability(); + } + catch (UnportablePassword &e) + { + if (verify) + { + ShowError (e); + verPhase = false; + continue; + } + + ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); + } + + if (verify) + { + if (password->Size() < VolumePassword::WarningSizeThreshold) + { + SetTerminalEcho (true); + finally_do ({ TextUserInterface::SetTerminalEcho (false); }); + + if (!AskYesNo (LangString ["PASSWORD_LENGTH_WARNING"], false, true)) + { + ShowString (L"\n"); + continue; + } + ShowString (L"\n"); + } + } + } + + if (!verify || verPhase) + return password; + + if (!verPhase) + verPhase = true; + } + + return password; + } + + ssize_t TextUserInterface::AskSelection (ssize_t optionCount, ssize_t defaultOption) const + { + while (true) + { + wstring selectionStr = AskString (defaultOption == -1 ? wxString (_("Select: ")) : wxString (wstring (StringFormatter (_("Select [{0}]: "), (uint32) defaultOption)))); + ssize_t selection; + + if (selectionStr.empty() && defaultOption != -1) + return defaultOption; + + try + { + selection = StringConverter::ToUInt32 (selectionStr); + } + catch (...) + { + continue; + } + + if (selection > 0 && selection <= optionCount) + return selection; + } + } + + wstring TextUserInterface::AskString (const wxString &message) const + { + ShowString (message); + return wstring (ReadInputStreamLine()); + } + + bool TextUserInterface::AskYesNo (const wxString &message, bool defaultYes, bool warning) const + { + while (true) + { + wxString s = AskString (StringFormatter (L"{0} (y={1}/n={2}) [{3}]: ", + message, LangString["YES"], LangString["NO"], LangString[defaultYes ? "YES" : "NO"])); + + if (s.IsSameAs (L'n', false) || s.IsSameAs (L"no", false) || (!defaultYes && s.empty())) + return false; + + if (s.IsSameAs (L'y', false) || s.IsSameAs (L"yes", false) || (defaultYes && s.empty())) + return true; + }; + } + + shared_ptr TextUserInterface::AskVolumePath (const wxString &message) const + { + return make_shared (AskString (message.empty() ? wxString (_("Enter volume path: ")) : message)); + } + + void TextUserInterface::BackupVolumeHeaders (shared_ptr volumePath) const + { + if (!volumePath) + volumePath = AskVolumePath(); + + if (!volumePath) + throw UserAbort (SRC_POS); + +#ifdef TC_WINDOWS + if (Core->IsVolumeMounted (*volumePath)) + throw_err (LangString["DISMOUNT_FIRST"]); +#endif + + ShowInfo ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO"); + + shared_ptr normalVolume; + shared_ptr hiddenVolume; + + MountOptions normalVolumeMountOptions; + MountOptions hiddenVolumeMountOptions; + + normalVolumeMountOptions.Path = volumePath; + hiddenVolumeMountOptions.Path = volumePath; + + VolumeType::Enum volumeType = VolumeType::Normal; + + // Open both types of volumes + while (true) + { + shared_ptr volume; + MountOptions *options = (volumeType == VolumeType::Hidden ? &hiddenVolumeMountOptions : &normalVolumeMountOptions); + + while (!volume) + { + ShowString (L"\n"); + options->Password = AskPassword (LangString[volumeType == VolumeType::Hidden ? "ENTER_HIDDEN_VOL_PASSWORD" : "ENTER_NORMAL_VOL_PASSWORD"]); + options->Keyfiles = AskKeyfiles(); + + try + { + volume = Core->OpenVolume ( + options->Path, + options->PreserveTimestamps, + options->Password, + options->Keyfiles, + options->Protection, + options->ProtectionPassword, + options->ProtectionKeyfiles, + true, + volumeType, + options->UseBackupHeaders + ); + } + catch (PasswordException &e) + { + ShowInfo (e); + } + } + + if (volumeType == VolumeType::Hidden) + hiddenVolume = volume; + else + normalVolume = volume; + + // Ask whether a hidden volume is present + if (volumeType == VolumeType::Normal && AskYesNo (L"\n" + LangString["DOES_VOLUME_CONTAIN_HIDDEN"])) + { + volumeType = VolumeType::Hidden; + continue; + } + + break; + } + + if (hiddenVolume) + { + if (typeid (*normalVolume->GetLayout()) == typeid (VolumeLayoutV1Normal) && typeid (*hiddenVolume->GetLayout()) != typeid (VolumeLayoutV1Hidden)) + throw ParameterIncorrect (SRC_POS); + + if (typeid (*normalVolume->GetLayout()) == typeid (VolumeLayoutV2Normal) && typeid (*hiddenVolume->GetLayout()) != typeid (VolumeLayoutV2Hidden)) + throw ParameterIncorrect (SRC_POS); + } + + // Ask user to select backup file path + wxString confirmMsg = L"\n" + LangString["CONFIRM_VOL_HEADER_BAK"] + L"\n"; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true)) + return; + + ShowString (L"\n"); + + FilePath filePath = AskFilePath(); + if (filePath.IsEmpty()) + throw UserAbort (SRC_POS); + + File backupFile; + backupFile.Open (filePath, File::CreateWrite); + + RandomNumberGenerator::Start(); + UserEnrichRandomPool(); + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Keyfiles); + + backupFile.Write (newHeaderBuffer); + + if (hiddenVolume) + { + // Re-encrypt hidden volume header + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Keyfiles); + } + else + { + // Store random data in place of hidden volume header + shared_ptr ea = normalVolume->GetEncryptionAlgorithm(); + Core->RandomizeEncryptionAlgorithmKey (ea); + ea->Encrypt (newHeaderBuffer); + } + + backupFile.Write (newHeaderBuffer); + + ShowString (L"\n"); + ShowInfo ("VOL_HEADER_BACKED_UP"); + } + + void TextUserInterface::ChangePassword (shared_ptr volumePath, shared_ptr password, shared_ptr keyfiles, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newHash) const + { + shared_ptr volume; + + // Volume path + if (!volumePath.get()) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + volumePath = AskVolumePath (); + } + + if (volumePath->IsEmpty()) + throw UserAbort (SRC_POS); + + bool passwordInteractive = !password.get(); + bool keyfilesInteractive = !keyfiles.get(); + + while (true) + { + // Current password + if (!passwordInteractive) + { + try + { + password->CheckPortability(); + } + catch (UnportablePassword &) + { + ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); + } + } + else if (!Preferences.NonInteractive) + { + password = AskPassword (); + } + + // Current keyfiles + try + { + if (keyfilesInteractive) + { + // Ask for keyfiles only if required + try + { + keyfiles.reset (new KeyfileList); + volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, keyfiles); + } + catch (PasswordException&) + { + if (!Preferences.NonInteractive) + keyfiles = AskKeyfiles (); + } + } + + if (!volume.get()) + volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, keyfiles); + } + catch (PasswordException &e) + { + if (Preferences.NonInteractive || !passwordInteractive || !keyfilesInteractive) + throw; + + ShowInfo (e); + continue; + } + + break; + } + + // New password + if (newPassword.get()) + newPassword->CheckPortability(); + else if (!Preferences.NonInteractive) + newPassword = AskPassword (_("Enter new password"), true); + + // New keyfiles + if (!newKeyfiles.get() && !Preferences.NonInteractive) + { + if (keyfiles.get() && keyfiles->size() > 0 && AskYesNo (_("Keep current keyfiles?"), true)) + newKeyfiles = keyfiles; + else + newKeyfiles = AskKeyfiles (_("Enter new keyfile")); + } + + UserEnrichRandomPool(); + + Core->ChangePassword (volume, newPassword, newKeyfiles, + newHash ? Pkcs5Kdf::GetAlgorithm (*newHash) : shared_ptr ()); + + ShowInfo ("PASSWORD_CHANGED"); + } + + void TextUserInterface::CreateKeyfile (shared_ptr keyfilePath) const + { + FilePath path; + + RandomNumberGenerator::Start(); + UserEnrichRandomPool(); + + if (keyfilePath) + { + Core->CreateKeyfile (*keyfilePath); + } + else + { + wstring fileName = AskFilePath(); + if (fileName.empty()) + return; + + Core->CreateKeyfile (fileName); + } + + ShowInfo ("KEYFILE_CREATED"); + } + + void TextUserInterface::CreateVolume (shared_ptr options) const + { + // Volume type + if (options->Type == VolumeType::Unknown) + { + if (Preferences.NonInteractive) + { + options->Type = VolumeType::Normal; + } + else + { + ShowString (_("Volume type:\n 1) Normal\n 2) Hidden\n")); + + switch (AskSelection (2, 1)) + { + case 1: + options->Type = VolumeType::Normal; + break; + + case 2: + options->Type = VolumeType::Hidden; + break; + } + } + } + + shared_ptr layout; + if (options->Type == VolumeType::Hidden) + layout.reset (new VolumeLayoutV2Hidden); + else + layout.reset (new VolumeLayoutV2Normal); + + if (!Preferences.NonInteractive && options->Type == VolumeType::Hidden) + ShowInfo (_("\nIMPORTANT: Inexperienced users should use the graphical user interface to create a hidden volume. When using the text interface, the procedure described in the command line help must be followed to create a hidden volume.")); + + // Volume path + if (options->Path.IsEmpty()) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + do + { + ShowString (L"\n"); + options->Path = VolumePath (*AskVolumePath()); + } while (options->Path.IsEmpty()); + } + + // Sector size + if (options->Path.IsDevice()) + options->SectorSize = Core->GetDeviceSectorSize (options->Path); + else + options->SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME; + + // Volume size + uint64 hostSize = 0; + + if (options->Type == VolumeType::Hidden) + { + FilesystemPath fsPath (wstring (options->Path)); + + if (fsPath.IsFile()) + { + File file; + file.Open (fsPath); + hostSize = file.Length(); + } + else if (fsPath.IsDevice()) + { + hostSize = Core->GetDeviceSize (fsPath); + } + else + { + throw_err (_("Hidden volume can be created only in an existing file or device.")); + } + + if (hostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE) + throw_err (StringFormatter (_("Minimum outer volume size is {0}."), SizeToString (TC_MIN_HIDDEN_VOLUME_HOST_SIZE))); + } + + uint64 minVolumeSize = options->Type == VolumeType::Hidden ? TC_MIN_HIDDEN_VOLUME_SIZE : TC_MIN_VOLUME_SIZE; + uint64 maxVolumeSize = options->Type == VolumeType::Hidden ? VolumeLayoutV2Normal().GetMaxDataSize (hostSize) - TC_MIN_FAT_FS_SIZE : TC_MAX_VOLUME_SIZE_GENERAL; + + if (options->Path.IsDevice() && options->Type != VolumeType::Hidden) + { + if (options->Size != 0) + throw_err (_("Volume size cannot be changed for device-hosted volumes.")); + + options->Size = Core->GetDeviceSize (options->Path); + } + else + { + options->Quick = false; + + uint32 sectorSizeRem = options->Size % options->SectorSize; + if (sectorSizeRem != 0) + options->Size += options->SectorSize - sectorSizeRem; + + while (options->Size == 0) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + wstring sizeStr = AskString (options->Type == VolumeType::Hidden ? _("\nEnter hidden volume size (sizeK/size[M]/sizeG): ") : _("\nEnter volume size (sizeK/size[M]/sizeG): ")); + int multiplier = 1024 * 1024; + + if (sizeStr.find (L"K") != string::npos) + { + multiplier = 1024; + sizeStr.resize (sizeStr.size() - 1); + } + else if (sizeStr.find (L"M") != string::npos) + { + sizeStr.resize (sizeStr.size() - 1); + } + else if (sizeStr.find (L"G") != string::npos) + { + multiplier = 1024 * 1024 * 1024; + sizeStr.resize (sizeStr.size() - 1); + } + + try + { + options->Size = StringConverter::ToUInt64 (sizeStr); + options->Size *= multiplier; + + sectorSizeRem = options->Size % options->SectorSize; + if (sectorSizeRem != 0) + options->Size += options->SectorSize - sectorSizeRem; + } + catch (...) + { + options->Size = 0; + continue; + } + + if (options->Size < minVolumeSize) + { + ShowError (StringFormatter (_("Minimum volume size is {0}."), SizeToString (minVolumeSize))); + options->Size = 0; + } + + if (options->Size > maxVolumeSize) + { + ShowError (StringFormatter (_("Maximum volume size is {0}."), SizeToString (maxVolumeSize))); + options->Size = 0; + } + } + } + + if (options->Size < minVolumeSize || options->Size > maxVolumeSize) + throw_err (_("Incorrect volume size")); + + if (options->Type == VolumeType::Hidden) + options->Quick = true; + + // Encryption algorithm + if (!options->EA) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + ShowInfo (wxString (L"\n") + LangString["ENCRYPTION_ALGORITHM_LV"] + L":"); + + vector < shared_ptr > encryptionAlgorithms; + foreach (shared_ptr ea, EncryptionAlgorithm::GetAvailableAlgorithms()) + { + if (!ea->IsDeprecated()) + { + ShowString (StringFormatter (L" {0}) {1}\n", (uint32) encryptionAlgorithms.size() + 1, ea->GetName())); + encryptionAlgorithms.push_back (ea); + } + } + + + options->EA = encryptionAlgorithms[AskSelection (encryptionAlgorithms.size(), 1) - 1]; + } + + // Hash algorithm + if (!options->VolumeHeaderKdf) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + ShowInfo (_("\nHash algorithm:")); + + vector < shared_ptr > hashes; + foreach (shared_ptr hash, Hash::GetAvailableAlgorithms()) + { + if (!hash->IsDeprecated()) + { + ShowString (StringFormatter (L" {0}) {1}\n", (uint32) hashes.size() + 1, hash->GetName())); + hashes.push_back (hash); + } + } + + shared_ptr selectedHash = hashes[AskSelection (hashes.size(), 1) - 1]; + RandomNumberGenerator::SetHash (selectedHash); + options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*selectedHash); + + } + + // Filesystem + options->FilesystemClusterSize = 0; + + if (options->Filesystem == VolumeCreationOptions::FilesystemType::Unknown) + { + if (Preferences.NonInteractive) + { + options->Filesystem = VolumeCreationOptions::FilesystemType::GetPlatformNative(); + } + else + { + ShowInfo (_("\nFilesystem:")); + + vector filesystems; + + ShowInfo (L" 1) " + LangString["NONE"]); filesystems.push_back (VolumeCreationOptions::FilesystemType::None); + ShowInfo (L" 2) FAT"); filesystems.push_back (VolumeCreationOptions::FilesystemType::FAT); + +#if defined (TC_LINUX) + ShowInfo (L" 3) Linux Ext2"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Ext2); + ShowInfo (L" 4) Linux Ext3"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Ext3); + ShowInfo (L" 5) Linux Ext4"); filesystems.push_back (VolumeCreationOptions::FilesystemType::Ext4); +#elif defined (TC_MACOSX) + ShowInfo (L" 3) Mac OS Extended"); filesystems.push_back (VolumeCreationOptions::FilesystemType::MacOsExt); +#elif defined (TC_FREEBSD) || defined (TC_SOLARIS) + ShowInfo (L" 3) UFS"); filesystems.push_back (VolumeCreationOptions::FilesystemType::UFS); +#endif + + options->Filesystem = filesystems[AskSelection (filesystems.size(), 2) - 1]; + } + } + + uint64 filesystemSize = layout->GetMaxDataSize (options->Size); + + if (options->Filesystem == VolumeCreationOptions::FilesystemType::FAT + && (filesystemSize < TC_MIN_FAT_FS_SIZE || filesystemSize > TC_MAX_FAT_SECTOR_COUNT * options->SectorSize)) + { + throw_err (_("Specified volume size cannot be used with FAT filesystem.")); + } + + // Password + if (!options->Password && !Preferences.NonInteractive) + { + ShowString (L"\n"); + options->Password = AskPassword (_("Enter password"), true); + } + + if (options->Password) + options->Password->CheckPortability(); + + // Keyfiles + if (!options->Keyfiles && !Preferences.NonInteractive) + { + ShowString (L"\n"); + options->Keyfiles = AskKeyfiles (_("Enter keyfile path")); + } + + if ((!options->Keyfiles || options->Keyfiles->empty()) + && (!options->Password || options->Password->IsEmpty())) + { + throw_err (_("Password cannot be empty when no keyfile is specified")); + } + + // Random data + RandomNumberGenerator::Start(); + UserEnrichRandomPool(); + + ShowString (L"\n"); + wxLongLong startTime = wxGetLocalTimeMillis(); + + VolumeCreator creator; + creator.CreateVolume (options); + + bool volumeCreated = false; + while (!volumeCreated) + { + VolumeCreator::ProgressInfo progress = creator.GetProgressInfo(); + + wxLongLong timeDiff = wxGetLocalTimeMillis() - startTime; + if (timeDiff.GetValue() > 0) + { + uint64 speed = progress.SizeDone * 1000 / timeDiff.GetValue(); + + volumeCreated = !progress.CreationInProgress; + + ShowString (wxString::Format (L"\rDone: %7.3f%% Speed: %9s Left: %s ", + 100.0 - double (options->Size - progress.SizeDone) / (double (options->Size) / 100.0), + speed > 0 ? SpeedToString (speed).c_str() : L" ", + speed > 0 ? TimeSpanToString ((options->Size - progress.SizeDone) / speed).c_str() : L"")); + } + + Thread::Sleep (100); + } + + ShowString (L"\n\n"); + creator.CheckResult(); + +#ifdef TC_UNIX + if (options->Filesystem != VolumeCreationOptions::FilesystemType::None + && options->Filesystem != VolumeCreationOptions::FilesystemType::FAT) + { + const char *fsFormatter = nullptr; + + switch (options->Filesystem) + { + case VolumeCreationOptions::FilesystemType::Ext2: fsFormatter = "mkfs.ext2"; break; + case VolumeCreationOptions::FilesystemType::Ext3: fsFormatter = "mkfs.ext3"; break; + case VolumeCreationOptions::FilesystemType::Ext4: fsFormatter = "mkfs.ext4"; break; + case VolumeCreationOptions::FilesystemType::MacOsExt: fsFormatter = "newfs_hfs"; break; + case VolumeCreationOptions::FilesystemType::UFS: fsFormatter = "newfs" ; break; + default: throw ParameterIncorrect (SRC_POS); + } + + MountOptions mountOptions (GetPreferences().DefaultMountOptions); + mountOptions.Path = make_shared (options->Path); + mountOptions.NoFilesystem = true; + mountOptions.Protection = VolumeProtection::None; + mountOptions.Password = options->Password; + mountOptions.Keyfiles = options->Keyfiles; + + shared_ptr volume = Core->MountVolume (mountOptions); + finally_do_arg (shared_ptr , volume, { Core->DismountVolume (finally_arg, true); }); + + Thread::Sleep (2000); // Try to prevent race conditions caused by OS + + // Temporarily take ownership of the device if the user is not an administrator + UserId origDeviceOwner ((uid_t) -1); + + DevicePath virtualDevice = volume->VirtualDevice; +#ifdef TC_MACOSX + string virtualDeviceStr = virtualDevice; + if (virtualDeviceStr.find ("/dev/rdisk") != 0) + virtualDevice = "/dev/r" + virtualDeviceStr.substr (5); +#endif + try + { + File file; + file.Open (virtualDevice, File::OpenReadWrite); + } + catch (...) + { + if (!Core->HasAdminPrivileges()) + { + origDeviceOwner = virtualDevice.GetOwner(); + Core->SetFileOwner (virtualDevice, UserId (getuid())); + } + } + + finally_do_arg2 (FilesystemPath, virtualDevice, UserId, origDeviceOwner, + { + if (finally_arg2.SystemId != (uid_t) -1) + Core->SetFileOwner (finally_arg, finally_arg2); + }); + + // Create filesystem + list args; + + if (options->Filesystem == VolumeCreationOptions::FilesystemType::MacOsExt && options->Size >= 10 * BYTES_PER_MB) + args.push_back ("-J"); + + args.push_back (string (virtualDevice)); + + Process::Execute (fsFormatter, args); + } +#endif // TC_UNIX + + ShowInfo (options->Type == VolumeType::Hidden ? "HIDVOL_FORMAT_FINISHED_HELP" : "FORMAT_FINISHED_INFO"); + } + + void TextUserInterface::DeleteSecurityTokenKeyfiles () const + { + shared_ptr keyfiles = AskKeyfiles(); + if (keyfiles->empty()) + throw UserAbort(); + + foreach_ref (const Keyfile &keyfile, *keyfiles) + { + SecurityToken::DeleteKeyfile (SecurityTokenKeyfilePath (FilePath (keyfile))); + } + } + + void TextUserInterface::DoShowError (const wxString &message) const + { + wcerr << L"Error: " << static_cast (message) << endl; + } + + void TextUserInterface::DoShowInfo (const wxString &message) const + { + wcout << static_cast (message) << endl; + } + + void TextUserInterface::DoShowString (const wxString &str) const + { + wcout << str.c_str(); + } + + void TextUserInterface::DoShowWarning (const wxString &message) const + { + wcerr << L"Warning: " << static_cast (message) << endl; + } + + void TextUserInterface::ExportSecurityTokenKeyfile () const + { + wstring keyfilePath = AskString (_("Enter security token keyfile path: ")); + + if (keyfilePath.empty()) + throw UserAbort (SRC_POS); + + SecurityTokenKeyfile tokenKeyfile (keyfilePath); + + vector keyfileData; + SecurityToken::GetKeyfileData (tokenKeyfile, keyfileData); + + BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); + finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); + + FilePath exportFilePath = AskFilePath(); + + if (exportFilePath.IsEmpty()) + throw UserAbort (SRC_POS); + + File keyfile; + keyfile.Open (exportFilePath, File::CreateWrite); + keyfile.Write (keyfileDataBuf); + } + + shared_ptr TextUserInterface::GetAdminPasswordRequestHandler () + { + struct AdminPasswordRequestHandler : public GetStringFunctor + { + AdminPasswordRequestHandler (TextUserInterface *userInterface) : UI (userInterface) { } + virtual void operator() (string &passwordStr) + { + UI->ShowString (_("Enter your user password or administrator password: ")); + + TextUserInterface::SetTerminalEcho (false); + finally_do ({ TextUserInterface::SetTerminalEcho (true); }); + + wstring wPassword (UI->ReadInputStreamLine()); + finally_do_arg (wstring *, &wPassword, { StringConverter::Erase (*finally_arg); }); + + UI->ShowString (L"\n"); + + StringConverter::ToSingle (wPassword, passwordStr); + } + TextUserInterface *UI; + }; + + return shared_ptr (new AdminPasswordRequestHandler (this)); + } + + void TextUserInterface::ImportSecurityTokenKeyfiles () const + { + list tokens = SecurityToken::GetAvailableTokens(); + + if (tokens.empty()) + throw_err (LangString ["NO_TOKENS_FOUND"]); + + CK_SLOT_ID slotId; + + if (tokens.size() == 1) + { + slotId = tokens.front().SlotId; + } + else + { + foreach (const SecurityTokenInfo &token, tokens) + { + wstringstream tokenLabel; + tokenLabel << L"[" << token.SlotId << L"] " << LangString["TOKEN_SLOT_ID"].c_str() << L" " << token.SlotId << L" " << token.Label; + + ShowInfo (tokenLabel.str()); + } + + slotId = (CK_SLOT_ID) AskSelection (tokens.back().SlotId, tokens.front().SlotId); + } + + shared_ptr keyfiles = AskKeyfiles(); + if (keyfiles->empty()) + throw UserAbort(); + + foreach_ref (const Keyfile &keyfilePath, *keyfiles) + { + File keyfile; + keyfile.Open (keyfilePath, File::OpenRead, File::ShareReadWrite, File::PreserveTimestamps); + + if (keyfile.Length() > 0) + { + vector keyfileData (keyfile.Length()); + BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); + + keyfile.ReadCompleteBuffer (keyfileDataBuf); + finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); + + SecurityToken::CreateKeyfile (slotId, keyfileData, string (FilePath (keyfilePath).ToBaseName())); + } + else + throw InsufficientData (SRC_POS, FilePath (keyfilePath)); + } + } + + void TextUserInterface::InitSecurityTokenLibrary () const + { + if (Preferences.SecurityTokenModule.IsEmpty()) + throw_err (LangString ["NO_PKCS11_MODULE_SPECIFIED"]); + + struct PinRequestHandler : public GetPinFunctor + { + PinRequestHandler (const TextUserInterface *userInterface) : UI (userInterface) { } + + virtual void operator() (string &passwordStr) + { + if (UI->GetPreferences().NonInteractive) + throw MissingArgument (SRC_POS); + + UI->ShowString (wxString::Format (LangString["ENTER_TOKEN_PASSWORD"], StringConverter::ToWide (passwordStr).c_str()) + L" "); + + TextUserInterface::SetTerminalEcho (false); + finally_do ({ TextUserInterface::SetTerminalEcho (true); }); + + wstring wPassword (UI->ReadInputStreamLine()); + finally_do_arg (wstring *, &wPassword, { StringConverter::Erase (*finally_arg); }); + + UI->ShowString (L"\n"); + + StringConverter::ToSingle (wPassword, passwordStr); + } + + const TextUserInterface *UI; + }; + + struct WarningHandler : public SendExceptionFunctor + { + WarningHandler (const TextUserInterface *userInterface) : UI (userInterface) { } + + virtual void operator() (const Exception &e) + { + UI->ShowError (e); + } + + const TextUserInterface *UI; + }; + + try + { + SecurityToken::InitLibrary (Preferences.SecurityTokenModule, auto_ptr (new PinRequestHandler (this)), auto_ptr (new WarningHandler (this))); + } + catch (Exception &e) + { + ShowError (e); + throw_err (LangString ["PKCS11_MODULE_INIT_FAILED"]); + } + } + + void TextUserInterface::ListSecurityTokenKeyfiles () const + { + foreach (const SecurityTokenKeyfile &keyfile, SecurityToken::GetAvailableKeyfiles()) + { + ShowString (wstring (SecurityTokenKeyfilePath (keyfile))); + ShowString (L"\n"); + } + } + + VolumeInfoList TextUserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const + { + while (true) + { + if (!options.Password) + options.Password = AskPassword(); + + if (!options.Keyfiles) + options.Keyfiles = AskKeyfiles(); + + VolumeInfoList mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (options); + + if (!mountedVolumes.empty()) + return mountedVolumes; + + options.Password.reset(); + } + } + + shared_ptr TextUserInterface::MountVolume (MountOptions &options) const + { + shared_ptr volume; + + CheckRequirementsForMountingVolume(); + + // Volume path + while (!options.Path || options.Path->IsEmpty()) + { + if (Preferences.NonInteractive) + throw MissingArgument (SRC_POS); + + options.Path = AskVolumePath (); + } + + if (Core->IsVolumeMounted (*options.Path)) + { + ShowInfo (StringFormatter (LangString["VOLUME_ALREADY_MOUNTED"], wstring (*options.Path))); + return volume; + } + + // Mount point + if (!options.MountPoint && !options.NoFilesystem) + options.MountPoint.reset (new DirectoryPath (AskString (_("Enter mount directory [default]: ")))); + + VolumePassword password; + KeyfileList keyfiles; + + if ((!options.Password || options.Password->IsEmpty()) + && (!options.Keyfiles || options.Keyfiles->empty()) + && !Core->IsPasswordCacheEmpty()) + { + // Cached password + try + { + volume = UserInterface::MountVolume (options); + } + catch (PasswordException&) { } + } + + int incorrectPasswordCount = 0; + + while (!volume) + { + // Password + if (!options.Password) + { + options.Password = AskPassword (StringFormatter (_("Enter password for {0}"), wstring (*options.Path))); + } + else + { + try + { + if (options.Password) + options.Password->CheckPortability(); + } + catch (UnportablePassword &) + { + ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); + } + } + + // Keyfiles + if (!options.Keyfiles) + options.Keyfiles = AskKeyfiles(); + + // Hidden volume protection + if (options.Protection == VolumeProtection::None + && !CmdLine->ArgNoHiddenVolumeProtection + && AskYesNo (_("Protect hidden volume (if any)?"))) + options.Protection = VolumeProtection::HiddenVolumeReadOnly; + + if (options.Protection == VolumeProtection::HiddenVolumeReadOnly) + { + if (!options.ProtectionPassword) + options.ProtectionPassword = AskPassword (_("Enter password for hidden volume")); + if (!options.ProtectionKeyfiles) + options.ProtectionKeyfiles = AskKeyfiles (_("Enter keyfile for hidden volume")); + } + + try + { + volume = UserInterface::MountVolume (options); + } + catch (ProtectionPasswordIncorrect &e) + { + ShowInfo (e); + options.ProtectionPassword.reset(); + } + catch (PasswordIncorrect &e) + { + if (++incorrectPasswordCount > 2 && !options.UseBackupHeaders) + { + // Try to mount the volume using the backup header + options.UseBackupHeaders = true; + + try + { + volume = UserInterface::MountVolume (options); + ShowWarning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK"); + } + catch (...) + { + options.UseBackupHeaders = false; + ShowInfo (e); + options.Password.reset(); + } + } + else + { + ShowInfo (e); + options.Password.reset(); + } + + ShowString (L"\n"); + } + catch (PasswordException &e) + { + ShowInfo (e); + options.Password.reset(); + } + } + +#ifdef TC_LINUX + if (!Preferences.NonInteractive && !Preferences.DisableKernelEncryptionModeWarning + && volume->EncryptionModeName != L"XTS" + && (volume->EncryptionModeName != L"LRW" || volume->EncryptionAlgorithmMinBlockSize != 16 || volume->EncryptionAlgorithmKeySize != 32)) + { + ShowWarning (LangString["ENCRYPTION_MODE_NOT_SUPPORTED_BY_KERNEL"]); + } +#endif + + return volume; + } + + bool TextUserInterface::OnInit () + { + try + { + DefaultMessageOutput = new wxMessageOutputStderr; + wxMessageOutput::Set (DefaultMessageOutput); + + InterfaceType = UserInterfaceType::Text; + Init(); + } + catch (exception &e) + { + ShowError (e); + return false; + } + return true; + } + + int TextUserInterface::OnRun() + { + try + { + if (ProcessCommandLine ()) + { + Application::SetExitCode (0); + return 0; + } + } + catch (exception &e) + { + ShowError (e); + } + + Application::SetExitCode (1); + return 1; + } + + void TextUserInterface::OnSignal (int signal) + { +#ifdef TC_UNIX + try + { + SetTerminalEcho (true); + } + catch (...) { } + _exit (1); +#endif + } + + void TextUserInterface::ReadInputStreamLine (wxString &line) const + { + if (!TextInputStream.get() || feof (stdin) || ferror (stdin)) + throw UserAbort (SRC_POS); + + line = TextInputStream->ReadLine(); + + if (ferror (stdin) || (line.empty() && feof (stdin))) + throw UserAbort (SRC_POS); + } + + wxString TextUserInterface::ReadInputStreamLine () const + { + wxString line; + ReadInputStreamLine (line); + return line; + } + + void TextUserInterface::RestoreVolumeHeaders (shared_ptr volumePath) const + { + if (!volumePath) + volumePath = AskVolumePath(); + + if (!volumePath) + throw UserAbort (SRC_POS); + +#ifdef TC_WINDOWS + if (Core->IsVolumeMounted (*volumePath)) + throw_err (LangString["DISMOUNT_FIRST"]); +#endif + + // Ask whether to restore internal or external backup + bool restoreInternalBackup; + + ShowInfo (LangString["HEADER_RESTORE_EXTERNAL_INTERNAL"]); + ShowInfo (L"\n1) " + LangString["HEADER_RESTORE_INTERNAL"]); + ShowInfo (L"2) " + LangString["HEADER_RESTORE_EXTERNAL"] + L"\n"); + + switch (AskSelection (2)) + { + case 1: + restoreInternalBackup = true; + break; + + case 2: + restoreInternalBackup = false; + break; + + default: + throw UserAbort (SRC_POS); + } + + if (restoreInternalBackup) + { + // Restore header from the internal backup + shared_ptr volume; + MountOptions options; + options.Path = volumePath; + + while (!volume) + { + ShowString (L"\n"); + options.Password = AskPassword(); + options.Keyfiles = AskKeyfiles(); + + try + { + volume = Core->OpenVolume ( + options.Path, + options.PreserveTimestamps, + options.Password, + options.Keyfiles, + options.Protection, + options.ProtectionPassword, + options.ProtectionKeyfiles, + options.SharedAccessAllowed, + VolumeType::Unknown, + true + ); + } + catch (PasswordException &e) + { + ShowInfo (e); + } + } + + shared_ptr layout = volume->GetLayout(); + if (typeid (*layout) == typeid (VolumeLayoutV1Normal) || typeid (*layout) == typeid (VolumeLayoutV1Hidden)) + { + throw_err (LangString ["VOLUME_HAS_NO_BACKUP_HEADER"]); + } + + RandomNumberGenerator::Start(); + UserEnrichRandomPool(); + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Keyfiles); + + // Write volume header + int headerOffset = volume->GetLayout()->GetHeaderOffset(); + shared_ptr volumeFile = volume->GetFile(); + + if (headerOffset >= 0) + volumeFile->SeekAt (headerOffset); + else + volumeFile->SeekEnd (headerOffset); + + volumeFile->Write (newHeaderBuffer); + } + else + { + // Restore header from an external backup + + wxString confirmMsg = L"\n\n" + LangString["CONFIRM_VOL_HEADER_RESTORE"]; + confirmMsg.Replace (L"%hs", L"%s"); + + if (!AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true, true)) + return; + + ShowString (L"\n"); + + FilePath filePath = AskFilePath(); + if (filePath.IsEmpty()) + throw UserAbort (SRC_POS); + + File backupFile; + backupFile.Open (filePath, File::OpenRead); + + uint64 headerSize; + bool legacyBackup; + + // Determine the format of the backup file + switch (backupFile.Length()) + { + case TC_VOLUME_HEADER_GROUP_SIZE: + headerSize = TC_VOLUME_HEADER_SIZE; + legacyBackup = false; + break; + + case TC_VOLUME_HEADER_SIZE_LEGACY * 2: + headerSize = TC_VOLUME_HEADER_SIZE_LEGACY; + legacyBackup = true; + break; + + default: + throw_err (LangString ["HEADER_BACKUP_SIZE_INCORRECT"]); + } + + // Open the volume header stored in the backup file + MountOptions options; + + shared_ptr decryptedLayout; + + while (!decryptedLayout) + { + options.Password = AskPassword (L"\n" + LangString["ENTER_HEADER_BACKUP_PASSWORD"]); + options.Keyfiles = AskKeyfiles(); + + try + { + // Test volume layouts + foreach (shared_ptr layout, VolumeLayout::GetAvailableLayouts ()) + { + if (layout->HasDriveHeader()) + continue; + + if (!legacyBackup && (typeid (*layout) == typeid (VolumeLayoutV1Normal) || typeid (*layout) == typeid (VolumeLayoutV1Hidden))) + continue; + + if (legacyBackup && (typeid (*layout) == typeid (VolumeLayoutV2Normal) || typeid (*layout) == typeid (VolumeLayoutV2Hidden))) + continue; + + SecureBuffer headerBuffer (layout->GetHeaderSize()); + backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0); + + // Decrypt header + shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedKeyDerivationFunctions(), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes())) + { + decryptedLayout = layout; + break; + } + } + + if (!decryptedLayout) + throw PasswordIncorrect (SRC_POS); + } + catch (PasswordException &e) + { + ShowWarning (e); + } + } + + File volumeFile; + volumeFile.Open (*volumePath, File::OpenReadWrite, File::ShareNone, File::PreserveTimestamps); + + RandomNumberGenerator::Start(); + UserEnrichRandomPool(); + + // Re-encrypt volume header + SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize()); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + + // Write volume header + int headerOffset = decryptedLayout->GetHeaderOffset(); + if (headerOffset >= 0) + volumeFile.SeekAt (headerOffset); + else + volumeFile.SeekEnd (headerOffset); + + volumeFile.Write (newHeaderBuffer); + + if (decryptedLayout->HasBackupHeader()) + { + // Re-encrypt backup volume header + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + + // Write backup volume header + headerOffset = decryptedLayout->GetBackupHeaderOffset(); + if (headerOffset >= 0) + volumeFile.SeekAt (headerOffset); + else + volumeFile.SeekEnd (headerOffset); + + volumeFile.Write (newHeaderBuffer); + } + } + + ShowString (L"\n"); + ShowInfo ("VOL_HEADER_RESTORED"); + } + + void TextUserInterface::SetTerminalEcho (bool enable) + { + if (CmdLine->ArgDisplayPassword) + return; + +#ifdef TC_UNIX + struct termios termAttr; + if (tcgetattr (0, &termAttr) == 0) + { + if (!enable) + { + termAttr.c_lflag &= ~ECHO; + throw_sys_if (tcsetattr (0, TCSANOW, &termAttr) != 0); + } + else + { + termAttr.c_lflag |= ECHO; + throw_sys_if (tcsetattr (0, TCSANOW, &termAttr) != 0); + } + } +#endif + } + + void TextUserInterface::UserEnrichRandomPool () const + { + RandomNumberGenerator::Start(); + + if (RandomNumberGenerator::IsEnrichedByUser()) + return; + + if (CmdLine->ArgHash) + RandomNumberGenerator::SetHash (CmdLine->ArgHash); + + if (!CmdLine->ArgRandomSourcePath.IsEmpty()) + { + SecureBuffer buffer (RandomNumberGenerator::PoolSize); + File randSourceFile; + + randSourceFile.Open (CmdLine->ArgRandomSourcePath, File::OpenRead); + + for (size_t i = 0; i < buffer.Size(); ++i) + { + if (randSourceFile.Read (buffer.GetRange (i, 1)) < 1) + break; + } + + RandomNumberGenerator::AddToPool (buffer); + RandomNumberGenerator::SetEnrichedByUserStatus (true); + } + else if (!Preferences.NonInteractive) + { + int randCharsRequired = RandomNumberGenerator::PoolSize; + ShowInfo (StringFormatter (_("\nPlease type at least {0} randomly chosen characters and then press Enter:"), randCharsRequired)); + + SetTerminalEcho (false); + finally_do ({ TextUserInterface::SetTerminalEcho (true); }); + + while (randCharsRequired > 0) + { + wstring randStr = AskString(); + RandomNumberGenerator::AddToPool (ConstBufferPtr ((byte *) randStr.c_str(), randStr.size() * sizeof (wchar_t))); + + randCharsRequired -= randStr.size(); + + if (randCharsRequired > 0) + ShowInfo (StringFormatter (_("Characters remaining: {0}"), randCharsRequired)); + } + + ShowString (L"\n"); + RandomNumberGenerator::SetEnrichedByUserStatus (true); + } + } + + wxMessageOutput *DefaultMessageOutput; +} diff --git a/src/Main/TextUserInterface.h b/src/Main/TextUserInterface.h new file mode 100644 index 00000000..942c45fd --- /dev/null +++ b/src/Main/TextUserInterface.h @@ -0,0 +1,78 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_TextUserInterface +#define TC_HEADER_Main_TextUserInterface + +#include "System.h" +#include "Main.h" +#include "UserInterface.h" + +namespace TrueCrypt +{ + class TextUserInterface : public UserInterface + { + public: + TextUserInterface (); + virtual ~TextUserInterface (); + + virtual FilePath AskFilePath (const wxString &message = wxEmptyString) const; + virtual shared_ptr AskKeyfiles (const wxString &message = L"") const; + virtual shared_ptr AskPassword (const wxString &message = L"", bool verify = false) const; + virtual ssize_t AskSelection (ssize_t optionCount, ssize_t defaultOption = -1) const; + virtual wstring AskString (const wxString &message = wxEmptyString) const; + virtual shared_ptr AskVolumePath (const wxString &message = L"") const; + virtual bool AskYesNo (const wxString &message, bool defaultYes = false, bool warning = false) const; + virtual void BackupVolumeHeaders (shared_ptr volumePath) const; + virtual void BeginBusyState () const { } + virtual void ChangePassword (shared_ptr volumePath = shared_ptr (), shared_ptr password = shared_ptr (), shared_ptr keyfiles = shared_ptr (), shared_ptr newPassword = shared_ptr (), shared_ptr newKeyfiles = shared_ptr (), shared_ptr newHash = shared_ptr ()) const; + virtual void CreateKeyfile (shared_ptr keyfilePath = shared_ptr ()) const; + virtual void CreateVolume (shared_ptr options) const; + virtual void DeleteSecurityTokenKeyfiles () const; + virtual void DoShowError (const wxString &message) const; + virtual void DoShowInfo (const wxString &message) const; + virtual void DoShowString (const wxString &str) const; + virtual void DoShowWarning (const wxString &message) const; + virtual void EndBusyState () const { } + virtual void ExportSecurityTokenKeyfile () const; + virtual shared_ptr GetAdminPasswordRequestHandler (); + virtual void ImportSecurityTokenKeyfiles () const; +#ifndef TC_NO_GUI + virtual bool Initialize (int &argc, wxChar **argv) { return wxAppBase::Initialize(argc, argv); } +#endif + virtual void InitSecurityTokenLibrary () const; + virtual void ListSecurityTokenKeyfiles () const; + virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; + virtual shared_ptr MountVolume (MountOptions &options) const; + virtual bool OnInit (); +#ifndef TC_NO_GUI + virtual bool OnInitGui () { return true; } +#endif + virtual int OnRun(); + virtual void RestoreVolumeHeaders (shared_ptr volumePath) const; + static void SetTerminalEcho (bool enable); + virtual void UserEnrichRandomPool () const; + virtual void Yield () const { } + + protected: + static void OnSignal (int signal); + virtual void ReadInputStreamLine (wxString &line) const; + virtual wxString ReadInputStreamLine () const; + + auto_ptr FInputStream; + auto_ptr TextInputStream; + + private: + TextUserInterface (const TextUserInterface &); + TextUserInterface &operator= (const TextUserInterface &); + }; + + extern wxMessageOutput *DefaultMessageOutput; +} + +#endif // TC_HEADER_Main_TextUserInterface diff --git a/src/Main/Unix/Main.cpp b/src/Main/Unix/Main.cpp new file mode 100644 index 00000000..382fdaf6 --- /dev/null +++ b/src/Main/Unix/Main.cpp @@ -0,0 +1,127 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include + +#include "Platform/Platform.h" +#include "Platform/SystemLog.h" +#include "Volume/EncryptionThreadPool.h" +#include "Core/Unix/CoreService.h" +#include "Main/Application.h" +#include "Main/Main.h" +#include "Main/UserInterface.h" + +#if defined (TC_MACOSX) && !defined (TC_NO_GUI) +#include +#endif + +using namespace TrueCrypt; + +int main (int argc, char **argv) +{ + try + { + // Make sure all required commands can be executed via default search path + string sysPathStr = "/usr/sbin:/sbin:/usr/bin:/bin"; + + char *sysPath = getenv ("PATH"); + if (sysPath) + { + sysPathStr += ":"; + sysPathStr += sysPath; + } + + setenv ("PATH", sysPathStr.c_str(), 1); + + if (argc > 1 && strcmp (argv[1], TC_CORE_SERVICE_CMDLINE_OPTION) == 0) + { + // Process elevated requests + try + { + CoreService::ProcessElevatedRequests(); + return 0; + } + catch (exception &e) + { +#ifdef DEBUG + SystemLog::WriteException (e); +#endif + } + catch (...) { } + return 1; + } + + // Start core service + CoreService::Start(); + finally_do ({ CoreService::Stop(); }); + + // Start encryption thread pool + EncryptionThreadPool::Start(); + finally_do ({ EncryptionThreadPool::Stop(); }); + +#ifdef TC_NO_GUI + bool forceTextUI = true; +#else + bool forceTextUI = false; +#endif + +#ifdef __WXGTK__ + if (!getenv ("DISPLAY")) + forceTextUI = true; +#endif + + // Initialize application + if (forceTextUI || (argc > 1 && (strcmp (argv[1], "-t") == 0 || strcmp (argv[1], "--text") == 0))) + { + Application::Initialize (UserInterfaceType::Text); + } + else + { +#if defined (TC_MACOSX) && !defined (TC_NO_GUI) + if (argc > 1 && !(argc == 2 && strstr (argv[1], "-psn_") == argv[1])) + { + ProcessSerialNumber p; + if (GetCurrentProcess (&p) == noErr) + { + TransformProcessType (&p, kProcessTransformToForegroundApplication); + SetFrontProcess (&p); + } + } +#endif + Application::Initialize (UserInterfaceType::Graphic); + } + + Application::SetExitCode (1); + + // Start application + if (::wxEntry (argc, argv) == 0) + Application::SetExitCode (0); + } + catch (ErrorMessage &e) + { + wcerr << wstring (e) << endl; + } + catch (SystemException &e) + { + wstringstream s; + if (e.GetSubject().empty()) + s << e.what() << endl << e.SystemText(); + else + s << e.what() << endl << e.SystemText() << endl << e.GetSubject(); + wcerr << s.str() << endl; + } + catch (exception &e) + { + stringstream s; + s << StringConverter::GetTypeName (typeid (e)) << endl << e.what(); + cerr << s.str() << endl; + } + + return Application::GetExitCode(); +} diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp new file mode 100644 index 00000000..9e8179f1 --- /dev/null +++ b/src/Main/UserInterface.cpp @@ -0,0 +1,1494 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#include +#include +#include +#include "Platform/PlatformTest.h" +#ifdef TC_UNIX +#include +#include "Platform/Unix/Process.h" +#endif +#include "Platform/SystemInfo.h" +#include "Common/SecurityToken.h" +#include "Volume/EncryptionTest.h" +#include "Application.h" +#include "FavoriteVolume.h" +#include "UserInterface.h" + +namespace TrueCrypt +{ + UserInterface::UserInterface () + { + } + + UserInterface::~UserInterface () + { + Core->WarningEvent.Disconnect (this); + Core->VolumeMountedEvent.Disconnect (this); + + try + { + if (SecurityToken::IsInitialized()) + SecurityToken::CloseLibrary(); + } + catch (...) { } + } + + void UserInterface::CheckRequirementsForMountingVolume () const + { +#ifdef TC_LINUX + if (!Preferences.NonInteractive) + { + if (!SystemInfo::IsVersionAtLeast (2, 6, 24)) + ShowWarning (_("Your system uses an old version of the Linux kernel.\n\nDue to a bug in the Linux kernel, your system may stop responding when writing data to a TrueCrypt volume. This problem can be solved by upgrading the kernel to version 2.6.24 or later.")); + } +#endif // TC_LINUX + } + + void UserInterface::CloseExplorerWindows (shared_ptr mountedVolume) const + { +#ifdef TC_WINDOWS + struct Args + { + HWND ExplorerWindow; + string DriveRootPath; + }; + + struct Enumerator + { + static BOOL CALLBACK ChildWindows (HWND hwnd, LPARAM argsLP) + { + Args *args = reinterpret_cast (argsLP); + + char s[4096]; + SendMessageA (hwnd, WM_GETTEXT, sizeof (s), (LPARAM) s); + + if (strstr (s, args->DriveRootPath.c_str()) != NULL) + { + PostMessage (args->ExplorerWindow, WM_CLOSE, 0, 0); + return FALSE; + } + + return TRUE; + } + + static BOOL CALLBACK TopLevelWindows (HWND hwnd, LPARAM argsLP) + { + Args *args = reinterpret_cast (argsLP); + + char s[4096]; + GetClassNameA (hwnd, s, sizeof s); + if (strcmp (s, "CabinetWClass") == 0) + { + GetWindowTextA (hwnd, s, sizeof s); + if (strstr (s, args->DriveRootPath.c_str()) != NULL) + { + PostMessage (hwnd, WM_CLOSE, 0, 0); + return TRUE; + } + + args->ExplorerWindow = hwnd; + EnumChildWindows (hwnd, ChildWindows, argsLP); + } + + return TRUE; + } + }; + + Args args; + + string mountPoint = mountedVolume->MountPoint; + if (mountPoint.size() < 2 || mountPoint[1] != ':') + return; + + args.DriveRootPath = string() + mountPoint[0] + string (":\\"); + + EnumWindows (Enumerator::TopLevelWindows, (LPARAM) &args); +#endif + } + + void UserInterface::DismountAllVolumes (bool ignoreOpenFiles, bool interactive) const + { + try + { + VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); + + if (mountedVolumes.size() < 1) + ShowInfo (LangString["NO_VOLUMES_MOUNTED"]); + + BusyScope busy (this); + DismountVolumes (mountedVolumes, ignoreOpenFiles, interactive); + } + catch (exception &e) + { + ShowError (e); + } + } + + void UserInterface::DismountVolume (shared_ptr volume, bool ignoreOpenFiles, bool interactive) const + { + VolumeInfoList volumes; + volumes.push_back (volume); + + DismountVolumes (volumes, ignoreOpenFiles, interactive); + } + + void UserInterface::DismountVolumes (VolumeInfoList volumes, bool ignoreOpenFiles, bool interactive) const + { + BusyScope busy (this); + + volumes.sort (VolumeInfo::FirstVolumeMountedAfterSecond); + + wxString message; + bool twoPassMode = volumes.size() > 1; + bool volumesInUse = false; + bool firstPass = true; + +#ifdef TC_WINDOWS + if (Preferences.CloseExplorerWindowsOnDismount) + { + foreach (shared_ptr volume, volumes) + CloseExplorerWindows (volume); + } +#endif + while (!volumes.empty()) + { + VolumeInfoList volumesLeft; + foreach (shared_ptr volume, volumes) + { + try + { + BusyScope busy (this); + volume = Core->DismountVolume (volume, ignoreOpenFiles); + } + catch (MountedVolumeInUse&) + { + if (!firstPass) + throw; + + if (twoPassMode || !interactive) + { + volumesInUse = true; + volumesLeft.push_back (volume); + continue; + } + else + { + if (AskYesNo (StringFormatter (LangString["UNMOUNT_LOCK_FAILED"], wstring (volume->Path)), true, true)) + { + BusyScope busy (this); + volume = Core->DismountVolume (volume, true); + } + else + throw UserAbort (SRC_POS); + } + } + catch (...) + { + if (twoPassMode && firstPass) + volumesLeft.push_back (volume); + else + throw; + } + + if (volume->HiddenVolumeProtectionTriggered) + ShowWarning (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (volume->Path))); + + if (Preferences.Verbose) + { + if (!message.IsEmpty()) + message += L'\n'; + message += StringFormatter (_("Volume \"{0}\" has been dismounted."), wstring (volume->Path)); + } + } + + if (twoPassMode && firstPass) + { + volumes = volumesLeft; + + if (volumesInUse && interactive) + { + if (AskYesNo (LangString["UNMOUNTALL_LOCK_FAILED"], true, true)) + ignoreOpenFiles = true; + else + throw UserAbort (SRC_POS); + } + } + else + break; + + firstPass = false; + } + + if (Preferences.Verbose && !message.IsEmpty()) + ShowInfo (message); + } + + void UserInterface::DisplayVolumeProperties (const VolumeInfoList &volumes) const + { + if (volumes.size() < 1) + throw_err (LangString["NO_VOLUMES_MOUNTED"]); + + wxString prop; + + foreach_ref (const VolumeInfo &volume, volumes) + { + prop << _("Slot") << L": " << StringConverter::FromNumber (volume.SlotNumber) << L'\n'; + prop << LangString["VOLUME"] << L": " << wstring (volume.Path) << L'\n'; +#ifndef TC_WINDOWS + prop << LangString["VIRTUAL_DEVICE"] << L": " << wstring (volume.VirtualDevice) << L'\n'; +#endif + prop << LangString["MOUNT_POINT"] << L": " << wstring (volume.MountPoint) << L'\n'; + prop << LangString["SIZE"] << L": " << SizeToString (volume.Size) << L'\n'; + prop << LangString["TYPE"] << L": " << VolumeTypeToString (volume.Type, volume.Protection) << L'\n'; + + prop << LangString["READ_ONLY"] << L": " << LangString [volume.Protection == VolumeProtection::ReadOnly ? "UISTR_YES" : "UISTR_NO"] << L'\n'; + + wxString protection; + if (volume.Type == VolumeType::Hidden) + protection = LangString["NOT_APPLICABLE_OR_NOT_AVAILABLE"]; + else if (volume.HiddenVolumeProtectionTriggered) + protection = LangString["HID_VOL_DAMAGE_PREVENTED"]; + else + protection = LangString [volume.Protection == VolumeProtection::HiddenVolumeReadOnly ? "UISTR_YES" : "UISTR_NO"]; + + prop << LangString["HIDDEN_VOL_PROTECTION"] << L": " << protection << L'\n'; + prop << LangString["ENCRYPTION_ALGORITHM"] << L": " << volume.EncryptionAlgorithmName << L'\n'; + prop << LangString["KEY_SIZE"] << L": " << StringFormatter (L"{0} {1}", volume.EncryptionAlgorithmKeySize * 8, LangString ["BITS"]) << L'\n'; + + if (volume.EncryptionModeName == L"XTS") + prop << LangString["SECONDARY_KEY_SIZE_XTS"] << L": " << StringFormatter (L"{0} {1}", volume.EncryptionAlgorithmKeySize * 8, LangString ["BITS"]) << L'\n';; + + wstringstream blockSize; + blockSize << volume.EncryptionAlgorithmBlockSize * 8; + if (volume.EncryptionAlgorithmBlockSize != volume.EncryptionAlgorithmMinBlockSize) + blockSize << L"/" << volume.EncryptionAlgorithmMinBlockSize * 8; + + prop << LangString["BLOCK_SIZE"] << L": " << blockSize.str() + L" " + LangString ["BITS"] << L'\n'; + prop << LangString["MODE_OF_OPERATION"] << L": " << volume.EncryptionModeName << L'\n'; + prop << LangString["PKCS5_PRF"] << L": " << volume.Pkcs5PrfName << L'\n'; + + prop << LangString["VOLUME_FORMAT_VERSION"] << L": " << (volume.MinRequiredProgramVersion < 0x600 ? 1 : 2) << L'\n'; + prop << LangString["BACKUP_HEADER"] << L": " << LangString[volume.MinRequiredProgramVersion >= 0x600 ? "UISTR_YES" : "UISTR_NO"] << L'\n'; + +#ifdef TC_LINUX + if (string (volume.VirtualDevice).find ("/dev/mapper/truecrypt") != 0) + { +#endif + prop << LangString["TOTAL_DATA_READ"] << L": " << SizeToString (volume.TotalDataRead) << L'\n'; + prop << LangString["TOTAL_DATA_WRITTEN"] << L": " << SizeToString (volume.TotalDataWritten) << L'\n'; +#ifdef TC_LINUX + } +#endif + + prop << L'\n'; + } + + ShowString (prop); + } + + wxString UserInterface::ExceptionToMessage (const exception &ex) const + { + wxString message; + + const Exception *e = dynamic_cast (&ex); + if (e) + { + message = ExceptionToString (*e); + + // System exception + const SystemException *sysEx = dynamic_cast (&ex); + if (sysEx) + { + if (!message.IsEmpty()) + { + message += L"\n\n"; + } + + message += wxString (sysEx->SystemText()).Trim (true); + } + + if (!message.IsEmpty()) + { + // Subject + if (!e->GetSubject().empty()) + { + message = message.Trim (true); + + if (message.EndsWith (L".")) + message.Truncate (message.size() - 1); + + if (!message.EndsWith (L":")) + message << L":\n"; + else + message << L"\n"; + + message << e->GetSubject(); + } + +#ifdef TC_UNIX + if (sysEx && sysEx->GetErrorCode() == EIO) + message << L"\n\n" << LangString["ERR_HARDWARE_ERROR"]; +#endif + +#ifdef DEBUG + if (sysEx && sysEx->what()) + message << L"\n\n" << StringConverter::ToWide (sysEx->what()); +#endif + return message; + } + } + + // bad_alloc + const bad_alloc *outOfMemory = dynamic_cast (&ex); + if (outOfMemory) + return _("Out of memory."); + + // Unresolved exceptions + string typeName (StringConverter::GetTypeName (typeid (ex))); + size_t pos = typeName.find ("TrueCrypt::"); + if (pos != string::npos) + { + return StringConverter::ToWide (typeName.substr (pos + string ("TrueCrypt::").size())) + + L" at " + StringConverter::ToWide (ex.what()); + } + + return StringConverter::ToWide (typeName) + L" at " + StringConverter::ToWide (ex.what()); + } + + wxString UserInterface::ExceptionToString (const Exception &ex) const + { + // Error messages + const ErrorMessage *errMsgEx = dynamic_cast (&ex); + if (errMsgEx) + return wstring (*errMsgEx).c_str(); + + // ExecutedProcessFailed + const ExecutedProcessFailed *execEx = dynamic_cast (&ex); + if (execEx) + { + wstring errOutput; + + // ElevationFailed + if (dynamic_cast (&ex)) + errOutput += wxString (_("Failed to obtain administrator privileges")) + (StringConverter::Trim (execEx->GetErrorOutput()).empty() ? L". " : L": "); + + errOutput += StringConverter::ToWide (execEx->GetErrorOutput()); + + if (errOutput.empty()) + return errOutput + StringFormatter (_("Command \"{0}\" returned error {1}."), execEx->GetCommand(), execEx->GetExitCode()); + + return wxString (errOutput).Trim (true); + } + + // PasswordIncorrect + if (dynamic_cast (&ex)) + { + wxString message = ExceptionTypeToString (typeid (ex)); + +#ifndef TC_NO_GUI + if (Application::GetUserInterfaceType() == UserInterfaceType::Graphic && wxGetKeyState (WXK_CAPITAL)) + message += wxString (L"\n\n") + LangString["CAPSLOCK_ON"]; +#endif + if (Keyfile::WasHiddenFilePresentInKeyfilePath()) + { +#ifdef TC_UNIX + message += _("\n\nWarning: Hidden files are present in a keyfile path. If you need to use them as keyfiles, remove the leading dot from their filenames. Hidden files are visible only if enabled in system options."); +#else + message += LangString["HIDDEN_FILES_PRESENT_IN_KEYFILE_PATH"]; +#endif + } + + return message; + } + + // PKCS#11 Exception + if (dynamic_cast (&ex)) + { + string errorString = string (dynamic_cast (ex)); + + if (LangString.Exists (errorString)) + return LangString[errorString]; + + if (errorString.find ("CKR_") == 0) + { + errorString = errorString.substr (4); + for (size_t i = 0; i < errorString.size(); ++i) + { + if (errorString[i] == '_') + errorString[i] = ' '; + } + } + + return LangString["SECURITY_TOKEN_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString); + } + + // Other library exceptions + return ExceptionTypeToString (typeid (ex)); + } + + wxString UserInterface::ExceptionTypeToString (const std::type_info &ex) const + { +#define EX2MSG(exception, message) do { if (ex == typeid (exception)) return (message); } while (false) + EX2MSG (DriveLetterUnavailable, LangString["DRIVE_LETTER_UNAVAILABLE"]); + EX2MSG (EncryptedSystemRequired, _("This operation must be performed only when the system hosted on the volume is running.")); + EX2MSG (ExternalException, LangString["EXCEPTION_OCCURRED"]); + EX2MSG (InsufficientData, _("Not enough data available.")); + EX2MSG (InvalidSecurityTokenKeyfilePath, LangString["INVALID_TOKEN_KEYFILE_PATH"]); + EX2MSG (HigherVersionRequired, LangString["NEW_VERSION_REQUIRED"]); + EX2MSG (KernelCryptoServiceTestFailed, _("Kernel cryptographic service test failed. The cryptographic service of your kernel most likely does not support volumes larger than 2 TB.\n\nPossible solutions:\n- Upgrade the Linux kernel to version 2.6.33 or later.\n- Disable use of the kernel cryptographic services (Settings > Preferences > System Integration) or use 'nokernelcrypto' mount option on the command line.")); + EX2MSG (KeyfilePathEmpty, LangString["ERR_KEYFILE_PATH_EMPTY"]); + EX2MSG (LoopDeviceSetupFailed, _("Failed to set up a loop device.")); + EX2MSG (MissingArgument, _("A required argument is missing.")); + EX2MSG (MissingVolumeData, _("Volume data missing.")); + EX2MSG (MountPointRequired, _("Mount point required.")); + EX2MSG (MountPointUnavailable, _("Mount point is already in use.")); + EX2MSG (NoDriveLetterAvailable, LangString["NO_FREE_DRIVES"]); + EX2MSG (PasswordEmpty, _("No password or keyfile specified.")); + EX2MSG (PasswordIncorrect, LangString["PASSWORD_WRONG"]); + EX2MSG (PasswordKeyfilesIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"]); + EX2MSG (PasswordOrKeyboardLayoutIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"] + _("\n\nNote that pre-boot authentication passwords need to be typed in the pre-boot environment where non-US keyboard layouts are not available. Therefore, pre-boot authentication passwords must always be typed using the standard US keyboard layout (otherwise, the password will be typed incorrectly in most cases). However, note that you do NOT need a real US keyboard; you just need to change the keyboard layout in your operating system.")); + EX2MSG (PasswordOrMountOptionsIncorrect, LangString["PASSWORD_OR_KEYFILE_OR_MODE_WRONG"] + _("\n\nNote: If you are attempting to mount a partition located on an encrypted system drive without pre-boot authentication or to mount the encrypted system partition of an operating system that is not running, you can do so by selecting 'Options >' > 'Mount partition using system encryption'.")); + EX2MSG (PasswordTooLong, StringFormatter (_("Password is longer than {0} characters."), (int) VolumePassword::MaxSize)); + EX2MSG (PartitionDeviceRequired, _("Partition device required.")); + EX2MSG (ProtectionPasswordIncorrect, _("Incorrect password to the protected hidden volume or the hidden volume does not exist.")); + EX2MSG (ProtectionPasswordKeyfilesIncorrect,_("Incorrect keyfile(s) and/or password to the protected hidden volume or the hidden volume does not exist.")); + EX2MSG (RootDeviceUnavailable, LangString["NODRIVER"]); + EX2MSG (SecurityTokenKeyfileAlreadyExists, LangString["TOKEN_KEYFILE_ALREADY_EXISTS"]); + EX2MSG (SecurityTokenKeyfileNotFound, LangString["TOKEN_KEYFILE_NOT_FOUND"]); + EX2MSG (SecurityTokenLibraryNotInitialized, LangString["PKCS11_MODULE_INIT_FAILED"]); + EX2MSG (StringConversionFailed, _("Invalid characters encountered.")); + EX2MSG (StringFormatterException, _("Error while parsing formatted string.")); + EX2MSG (TemporaryDirectoryFailure, _("Failed to create a file or directory in a temporary directory.\n\nPlease make sure that the temporary directory exists, its security permissions allow you to access it, and there is sufficient disk space.")); + EX2MSG (UnportablePassword, LangString["UNSUPPORTED_CHARS_IN_PWD"]); + +#if defined (TC_LINUX) + EX2MSG (UnsupportedSectorSize, LangString["SECTOR_SIZE_UNSUPPORTED"]); + EX2MSG (UnsupportedSectorSizeHiddenVolumeProtection, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, outer volumes hosted on the drive cannot be mounted using hidden volume protection.\n\nPossible solutions:\n- Use a drive with 512-byte sectors.\n- Create a file-hosted volume (container) on the drive.\n- Backup the contents of the hidden volume and then update the outer volume.")); + EX2MSG (UnsupportedSectorSizeNoKernelCrypto, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, partition/device-hosted volumes on the drive can only be mounted using kernel cryptographic services.\n\nPossible solutions:\n- Enable use of the kernel cryptographic services (Preferences > System Integration).\n- Use a drive with 512-byte sectors.\n- Create a file-hosted volume (container) on the drive.")); +#else + EX2MSG (UnsupportedSectorSize, _("Error: The drive uses a sector size other than 512 bytes.\n\nDue to limitations of components available on your platform, partition/device-hosted volumes cannot be created/used on the drive.\n\nPossible solutions:\n- Create a file-hosted volume (container) on the drive.\n- Use a drive with 512-byte sectors.\n- Use TrueCrypt on another platform.")); +#endif + + EX2MSG (VolumeAlreadyMounted, LangString["VOL_ALREADY_MOUNTED"]); + EX2MSG (VolumeEncryptionNotCompleted, LangString["ERR_ENCRYPTION_NOT_COMPLETED"]); + EX2MSG (VolumeHostInUse, _("The host file/device is already in use.")); + EX2MSG (VolumeSlotUnavailable, _("Volume slot unavailable.")); + +#ifdef TC_MACOSX + EX2MSG (HigherFuseVersionRequired, _("TrueCrypt requires MacFUSE 1.3 or later.")); +#endif + +#undef EX2MSG + return L""; + } + + void UserInterface::Init () + { + SetAppName (Application::GetName()); + SetClassName (Application::GetName()); + + LangString.Init(); + Core->Init(); + + wxCmdLineParser parser; + parser.SetCmdLine (argc, argv); + CmdLine.reset (new CommandLineInterface (parser, InterfaceType)); + SetPreferences (CmdLine->Preferences); + + Core->SetApplicationExecutablePath (Application::GetExecutablePath()); + + if (!Preferences.NonInteractive) + { + Core->SetAdminPasswordCallback (GetAdminPasswordRequestHandler()); + } + else + { + struct AdminPasswordRequestHandler : public GetStringFunctor + { + virtual void operator() (string &str) + { + throw ElevationFailed (SRC_POS, "sudo", 1, ""); + } + }; + + Core->SetAdminPasswordCallback (shared_ptr (new AdminPasswordRequestHandler)); + } + + Core->WarningEvent.Connect (EventConnector (this, &UserInterface::OnWarning)); + Core->VolumeMountedEvent.Connect (EventConnector (this, &UserInterface::OnVolumeMounted)); + + if (!CmdLine->Preferences.SecurityTokenModule.IsEmpty() && !SecurityToken::IsInitialized()) + { + try + { + InitSecurityTokenLibrary(); + } + catch (exception &e) + { + if (Preferences.NonInteractive) + throw; + + ShowError (e); + } + } + } + + void UserInterface::ListMountedVolumes (const VolumeInfoList &volumes) const + { + if (volumes.size() < 1) + throw_err (LangString["NO_VOLUMES_MOUNTED"]); + + wxString message; + + foreach_ref (const VolumeInfo &volume, volumes) + { + message << volume.SlotNumber << L": " << StringConverter::QuoteSpaces (volume.Path); + + if (!volume.VirtualDevice.IsEmpty()) + message << L' ' << wstring (volume.VirtualDevice); + else + message << L" - "; + + if (!volume.MountPoint.IsEmpty()) + message << L' ' << StringConverter::QuoteSpaces (volume.MountPoint); + else + message << L" - "; + + message << L'\n'; + } + + ShowString (message); + } + + VolumeInfoList UserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const + { + BusyScope busy (this); + + VolumeInfoList newMountedVolumes; + + if (!options.MountPoint) + options.MountPoint.reset (new DirectoryPath); + + Core->CoalesceSlotNumberAndMountPoint (options); + + bool sharedAccessAllowed = options.SharedAccessAllowed; + bool someVolumesShared = false; + + HostDeviceList devices; + foreach (shared_ptr device, Core->GetHostDevices (true)) + { + devices.push_back (device); + + foreach (shared_ptr partition, device->Partitions) + devices.push_back (partition); + } + + set mountedVolumes; + foreach_ref (const VolumeInfo &v, Core->GetMountedVolumes()) + mountedVolumes.insert (v.Path); + + bool protectedVolumeMounted = false; + bool legacyVolumeMounted = false; + + foreach_ref (const HostDevice &device, devices) + { + if (mountedVolumes.find (wstring (device.Path)) != mountedVolumes.end()) + continue; + + Yield(); + options.SlotNumber = Core->GetFirstFreeSlotNumber (options.SlotNumber); + options.MountPoint.reset (new DirectoryPath); + options.Path.reset (new VolumePath (device.Path)); + + try + { + try + { + options.SharedAccessAllowed = sharedAccessAllowed; + newMountedVolumes.push_back (Core->MountVolume (options)); + } + catch (VolumeHostInUse&) + { + if (!sharedAccessAllowed) + { + try + { + options.SharedAccessAllowed = true; + newMountedVolumes.push_back (Core->MountVolume (options)); + someVolumesShared = true; + } + catch (VolumeHostInUse&) + { + continue; + } + } + else + continue; + } + + if (newMountedVolumes.back()->Protection == VolumeProtection::HiddenVolumeReadOnly) + protectedVolumeMounted = true; + + if (newMountedVolumes.back()->EncryptionAlgorithmMinBlockSize == 8) + legacyVolumeMounted = true; + } + catch (DriverError&) { } + catch (MissingVolumeData&) { } + catch (PasswordException&) { } + catch (SystemException&) { } + catch (ExecutedProcessFailed&) { } + } + + if (newMountedVolumes.empty()) + { + ShowWarning (LangString [options.Keyfiles && !options.Keyfiles->empty() ? "PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT" : "PASSWORD_WRONG_AUTOMOUNT"]); + } + else + { + if (someVolumesShared) + ShowWarning ("DEVICE_IN_USE_INFO"); + + if (legacyVolumeMounted) + ShowWarning ("WARN_64_BIT_BLOCK_CIPHER"); + + if (protectedVolumeMounted) + ShowInfo (LangString[newMountedVolumes.size() > 1 ? "HIDVOL_PROT_WARN_AFTER_MOUNT_PLURAL" : "HIDVOL_PROT_WARN_AFTER_MOUNT"]); + } + + if (!newMountedVolumes.empty() && GetPreferences().CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + + return newMountedVolumes; + } + + VolumeInfoList UserInterface::MountAllFavoriteVolumes (MountOptions &options) + { + BusyScope busy (this); + + VolumeInfoList newMountedVolumes; + foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList()) + { + shared_ptr mountedVolume = Core->GetMountedVolume (favorite.Path); + if (mountedVolume) + { + if (mountedVolume->MountPoint != favorite.MountPoint) + ShowInfo (StringFormatter (LangString["VOLUME_ALREADY_MOUNTED"], wstring (favorite.Path))); + continue; + } + + favorite.ToMountOptions (options); + + if (Preferences.NonInteractive) + { + BusyScope busy (this); + newMountedVolumes.push_back (Core->MountVolume (options)); + } + else + { + try + { + BusyScope busy (this); + newMountedVolumes.push_back (Core->MountVolume (options)); + } + catch (...) + { + UserPreferences prefs = GetPreferences(); + if (prefs.CloseSecurityTokenSessionsAfterMount) + Preferences.CloseSecurityTokenSessionsAfterMount = false; + + shared_ptr volume = MountVolume (options); + + if (prefs.CloseSecurityTokenSessionsAfterMount) + Preferences.CloseSecurityTokenSessionsAfterMount = true; + + if (!volume) + break; + newMountedVolumes.push_back (volume); + } + } + } + + if (!newMountedVolumes.empty() && GetPreferences().CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + + return newMountedVolumes; + } + + shared_ptr UserInterface::MountVolume (MountOptions &options) const + { + shared_ptr volume; + + try + { + volume = Core->MountVolume (options); + } + catch (VolumeHostInUse&) + { + if (options.SharedAccessAllowed) + throw_err (LangString["FILE_IN_USE_FAILED"]); + + if (!AskYesNo (StringFormatter (LangString["VOLUME_HOST_IN_USE"], wstring (*options.Path)), false, true)) + throw UserAbort (SRC_POS); + + try + { + options.SharedAccessAllowed = true; + volume = Core->MountVolume (options); + } + catch (VolumeHostInUse&) + { + throw_err (LangString["FILE_IN_USE_FAILED"]); + } + } + + if (volume->EncryptionAlgorithmMinBlockSize == 8) + ShowWarning ("WARN_64_BIT_BLOCK_CIPHER"); + + if (VolumeHasUnrecommendedExtension (*options.Path)) + ShowWarning ("EXE_FILE_EXTENSION_MOUNT_WARNING"); + + if (options.Protection == VolumeProtection::HiddenVolumeReadOnly) + ShowInfo ("HIDVOL_PROT_WARN_AFTER_MOUNT"); + + if (GetPreferences().CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + + return volume; + } + + void UserInterface::OnUnhandledException () + { + try + { + throw; + } + catch (UserAbort&) + { + } + catch (exception &e) + { + ShowError (e); + } + catch (...) + { + ShowError (_("Unknown exception occurred.")); + } + + Yield(); + Application::SetExitCode (1); + } + + void UserInterface::OnVolumeMounted (EventArgs &args) + { + shared_ptr mountedVolume = (dynamic_cast (args)).mVolume; + + if (Preferences.OpenExplorerWindowAfterMount && !mountedVolume->MountPoint.IsEmpty()) + OpenExplorerWindow (mountedVolume->MountPoint); + } + + void UserInterface::OnWarning (EventArgs &args) + { + ExceptionEventArgs &e = dynamic_cast (args); + ShowWarning (e.mException); + } + + void UserInterface::OpenExplorerWindow (const DirectoryPath &path) + { + if (path.IsEmpty()) + return; + + list args; + +#ifdef TC_WINDOWS + + wstring p (Directory::AppendSeparator (path)); + SHFILEINFO fInfo; + SHGetFileInfo (p.c_str(), 0, &fInfo, sizeof (fInfo), 0); // Force explorer to discover the drive + ShellExecute (GetTopWindow() ? static_cast (GetTopWindow()->GetHandle()) : nullptr, L"open", p.c_str(), nullptr, nullptr, SW_SHOWNORMAL); + +#elif defined (TC_MACOSX) + + args.push_back (string (path)); + try + { + Process::Execute ("open", args); + } + catch (exception &e) { ShowError (e); } + +#else + // MIME handler for directory seems to be unavailable through wxWidgets + wxString desktop = GetTraits()->GetDesktopEnvironment(); + + if (desktop == L"GNOME" || desktop.empty()) + { + args.push_back ("--no-default-window"); + args.push_back ("--no-desktop"); + args.push_back (string (path)); + try + { + Process::Execute ("nautilus", args, 2000); + } + catch (TimeOut&) { } + catch (exception &e) { ShowError (e); } + } + else if (desktop == L"KDE") + { + try + { + args.push_back (string (path)); + Process::Execute ("dolphin", args, 2000); + } + catch (TimeOut&) { } + catch (exception&) + { + args.clear(); + args.push_back ("openURL"); + args.push_back (string (path)); + try + { + Process::Execute ("kfmclient", args, 2000); + } + catch (TimeOut&) { } + catch (exception &e) { ShowError (e); } + } + } +#endif + } + + bool UserInterface::ProcessCommandLine () + { + CommandLineInterface &cmdLine = *CmdLine; + + switch (cmdLine.ArgCommand) + { + case CommandId::None: + return false; + + case CommandId::AutoMountDevices: + case CommandId::AutoMountFavorites: + case CommandId::AutoMountDevicesFavorites: + case CommandId::MountVolume: + { + cmdLine.ArgMountOptions.Path = cmdLine.ArgVolumePath; + cmdLine.ArgMountOptions.MountPoint = cmdLine.ArgMountPoint; + cmdLine.ArgMountOptions.Password = cmdLine.ArgPassword; + cmdLine.ArgMountOptions.Keyfiles = cmdLine.ArgKeyfiles; + cmdLine.ArgMountOptions.SharedAccessAllowed = cmdLine.ArgForce; + + VolumeInfoList mountedVolumes; + switch (cmdLine.ArgCommand) + { + case CommandId::AutoMountDevices: + case CommandId::AutoMountFavorites: + case CommandId::AutoMountDevicesFavorites: + { + if (cmdLine.ArgCommand == CommandId::AutoMountDevices || cmdLine.ArgCommand == CommandId::AutoMountDevicesFavorites) + { + if (Preferences.NonInteractive) + mountedVolumes = UserInterface::MountAllDeviceHostedVolumes (cmdLine.ArgMountOptions); + else + mountedVolumes = MountAllDeviceHostedVolumes (cmdLine.ArgMountOptions); + } + + if (cmdLine.ArgCommand == CommandId::AutoMountFavorites || cmdLine.ArgCommand == CommandId::AutoMountDevicesFavorites) + { + foreach (shared_ptr v, MountAllFavoriteVolumes(cmdLine.ArgMountOptions)) + mountedVolumes.push_back (v); + } + } + break; + + + break; + + case CommandId::MountVolume: + if (Preferences.OpenExplorerWindowAfterMount) + { + // Open explorer window for an already mounted volume + shared_ptr mountedVolume = Core->GetMountedVolume (*cmdLine.ArgMountOptions.Path); + if (mountedVolume && !mountedVolume->MountPoint.IsEmpty()) + { + OpenExplorerWindow (mountedVolume->MountPoint); + break; + } + } + + if (Preferences.NonInteractive) + { + // Volume path + if (!cmdLine.ArgMountOptions.Path) + throw MissingArgument (SRC_POS); + + mountedVolumes.push_back (Core->MountVolume (cmdLine.ArgMountOptions)); + } + else + { + shared_ptr volume = MountVolume (cmdLine.ArgMountOptions); + if (!volume) + { + Application::SetExitCode (1); + throw UserAbort (SRC_POS); + } + mountedVolumes.push_back (volume); + } + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + if (Preferences.Verbose && !mountedVolumes.empty()) + { + wxString message; + foreach_ref (const VolumeInfo &volume, mountedVolumes) + { + if (!message.IsEmpty()) + message += L'\n'; + message += StringFormatter (_("Volume \"{0}\" has been mounted."), wstring (volume.Path)); + } + ShowInfo (message); + } + } + return true; + + case CommandId::BackupHeaders: + BackupVolumeHeaders (cmdLine.ArgVolumePath); + return true; + + case CommandId::ChangePassword: + ChangePassword (cmdLine.ArgVolumePath, cmdLine.ArgPassword, cmdLine.ArgKeyfiles, cmdLine.ArgNewPassword, cmdLine.ArgNewKeyfiles, cmdLine.ArgHash); + return true; + + case CommandId::CreateKeyfile: + CreateKeyfile (cmdLine.ArgFilePath); + return true; + + case CommandId::CreateVolume: + { + make_shared_auto (VolumeCreationOptions, options); + + if (cmdLine.ArgHash) + { + options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*cmdLine.ArgHash); + RandomNumberGenerator::SetHash (cmdLine.ArgHash); + } + + options->EA = cmdLine.ArgEncryptionAlgorithm; + options->Filesystem = cmdLine.ArgFilesystem; + options->Keyfiles = cmdLine.ArgKeyfiles; + options->Password = cmdLine.ArgPassword; + options->Quick = cmdLine.ArgQuick; + options->Size = cmdLine.ArgSize; + options->Type = cmdLine.ArgVolumeType; + + if (cmdLine.ArgVolumePath) + options->Path = VolumePath (*cmdLine.ArgVolumePath); + + CreateVolume (options); + return true; + } + + case CommandId::DeleteSecurityTokenKeyfiles: + DeleteSecurityTokenKeyfiles(); + return true; + + case CommandId::DismountVolumes: + DismountVolumes (cmdLine.ArgVolumes, cmdLine.ArgForce, !Preferences.NonInteractive); + return true; + + case CommandId::DisplayVersion: + ShowString (Application::GetName() + L" " + StringConverter::ToWide (Version::String()) + L"\n"); + return true; + + case CommandId::DisplayVolumeProperties: + DisplayVolumeProperties (cmdLine.ArgVolumes); + return true; + + case CommandId::Help: + { + wstring helpText = StringConverter::ToWide ( + "Synopsis:\n" + "\n" + "truecrypt [OPTIONS] COMMAND\n" + "truecrypt [OPTIONS] VOLUME_PATH [MOUNT_DIRECTORY]\n" + "\n" + "\n" + "Commands:\n" + "\n" + "--auto-mount=devices|favorites\n" + " Auto mount device-hosted or favorite volumes.\n" + "\n" + "--backup-headers[=VOLUME_PATH]\n" + " Backup volume headers to a file. All required options are requested from the\n" + " user.\n" + "\n" + "-c, --create[=VOLUME_PATH]\n" + " Create a new volume. Most options are requested from the user if not specified\n" + " on command line. See also options --encryption, -k, --filesystem, --hash, -p,\n" + " --random-source, --quick, --size, --volume-type. Note that passing some of the\n" + " options may affect security of the volume (see option -p for more information).\n" + "\n" + " Inexperienced users should use the graphical user interface to create a hidden\n" + " volume. When using the text user interface, the following procedure must be\n" + " followed to create a hidden volume:\n" + " 1) Create an outer volume with no filesystem.\n" + " 2) Create a hidden volume within the outer volume.\n" + " 3) Mount the outer volume using hidden volume protection.\n" + " 4) Create a filesystem on the virtual device of the outer volume.\n" + " 5) Mount the new filesystem and fill it with data.\n" + " 6) Dismount the outer volume.\n" + " If at any step the hidden volume protection is triggered, start again from 1).\n" + "\n" + "--create-keyfile[=FILE_PATH]\n" + " Create a new keyfile containing pseudo-random data.\n" + "\n" + "-C, --change[=VOLUME_PATH]\n" + " Change a password and/or keyfile(s) of a volume. Most options are requested\n" + " from the user if not specified on command line. PKCS-5 PRF HMAC hash\n" + " algorithm can be changed with option --hash. See also options -k,\n" + " --new-keyfiles, --new-password, -p, --random-source.\n" + "\n" + "-d, --dismount[=MOUNTED_VOLUME]\n" + " Dismount a mounted volume. If MOUNTED_VOLUME is not specified, all\n" + " volumes are dismounted. See below for description of MOUNTED_VOLUME.\n" + "\n" + "--delete-token-keyfiles\n" + " Delete keyfiles from security tokens. See also command --list-token-keyfiles.\n" + "\n" + "--export-token-keyfile\n" + " Export a keyfile from a security token. See also command --list-token-keyfiles.\n" + "\n" + "--import-token-keyfiles\n" + " Import keyfiles to a security token. See also option --token-lib.\n" + "\n" + "-l, --list[=MOUNTED_VOLUME]\n" + " Display a list of mounted volumes. If MOUNTED_VOLUME is not specified, all\n" + " volumes are listed. By default, the list contains only volume path, virtual\n" + " device, and mount point. A more detailed list can be enabled by verbose\n" + " output option (-v). See below for description of MOUNTED_VOLUME.\n" + "\n" + "--list-token-keyfiles\n" + " Display a list of all available security token keyfiles. See also command\n" + " --import-token-keyfiles.\n" + "\n" + "--mount[=VOLUME_PATH]\n" + " Mount a volume. Volume path and other options are requested from the user\n" + " if not specified on command line.\n" + "\n" + "--restore-headers[=VOLUME_PATH]\n" + " Restore volume headers from the embedded or an external backup. All required\n" + " options are requested from the user.\n" + "\n" + "--save-preferences\n" + " Save user preferences.\n" + "\n" + "--test\n" + " Test internal algorithms used in the process of encryption and decryption.\n" + "\n" + "--version\n" + " Display program version.\n" + "\n" + "--volume-properties[=MOUNTED_VOLUME]\n" + " Display properties of a mounted volume. See below for description of\n" + " MOUNTED_VOLUME.\n" + "\n" + "MOUNTED_VOLUME:\n" + " Specifies a mounted volume. One of the following forms can be used:\n" + " 1) Path to the encrypted TrueCrypt volume.\n" + " 2) Mount directory of the volume's filesystem (if mounted).\n" + " 3) Slot number of the mounted volume (requires --slot).\n" + "\n" + "\n" + "Options:\n" + "\n" + "--display-password\n" + " Display password characters while typing.\n" + "\n" + "--encryption=ENCRYPTION_ALGORITHM\n" + " Use specified encryption algorithm when creating a new volume.\n" + "\n" + "--filesystem=TYPE\n" + " Filesystem type to mount. The TYPE argument is passed to mount(8) command\n" + " with option -t. Default type is 'auto'. When creating a new volume, this\n" + " option specifies the filesystem to be created on the new volume (only 'FAT'\n" + " and 'none' TYPE is allowed). Filesystem type 'none' disables mounting or\n" + " creating a filesystem.\n" + "\n" + "--force\n" + " Force mounting of a volume in use, dismounting of a volume in use, or\n" + " overwriting a file. Note that this option has no effect on some platforms.\n" + "\n" + "--fs-options=OPTIONS\n" + " Filesystem mount options. The OPTIONS argument is passed to mount(8)\n" + " command with option -o when a filesystem on a TrueCrypt volume is mounted.\n" + " This option is not available on some platforms.\n" + "\n" + "--hash=HASH\n" + " Use specified hash algorithm when creating a new volume or changing password\n" + " and/or keyfiles. This option also specifies the mixing PRF of the random\n" + " number generator.\n" + "\n" + "-k, --keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n" + " Use specified keyfiles when mounting a volume or when changing password\n" + " and/or keyfiles. When a directory is specified, all files inside it will be\n" + " used (non-recursively). Multiple keyfiles must be separated by comma.\n" + " Use double comma (,,) to specify a comma contained in keyfile's name.\n" + " Keyfile stored on a security token must be specified as\n" + " token://slot/SLOT_NUMBER/file/FILENAME. An empty keyfile (-k \"\") disables\n" + " interactive requests for keyfiles. See also options --import-token-keyfiles,\n" + " --list-token-keyfiles, --new-keyfiles, --protection-keyfiles.\n" + "\n" + "--load-preferences\n" + " Load user preferences.\n" + "\n" + "-m, --mount-options=OPTION1[,OPTION2,OPTION3,...]\n" + " Specifies comma-separated mount options for a TrueCrypt volume:\n" + " headerbak: Use backup headers when mounting a volume.\n" + " nokernelcrypto: Do not use kernel cryptographic services.\n" + " readonly|ro: Mount volume as read-only.\n" + " system: Mount partition using system encryption.\n" + " timestamp|ts: Do not restore host-file modification timestamp when a volume\n" + " is dismounted (note that the operating system under certain circumstances\n" + " does not alter host-file timestamps, which may be mistakenly interpreted\n" + " to mean that this option does not work).\n" + " See also option --fs-options.\n" + "\n" + "--new-keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n" + " Add specified keyfiles to a volume. This option can only be used with command\n" + " -C.\n" + "\n" + "--new-password=PASSWORD\n" + " Specifies a new password. This option can only be used with command -C.\n" + "\n" + "-p, --password=PASSWORD\n" + " Use specified password to mount/open a volume. An empty password can also be\n" + " specified (-p \"\"). Note that passing a password on the command line is\n" + " potentially insecure as the password may be visible in the process list\n" + " (see ps(1)) and/or stored in a command history file or system logs.\n" + "\n" + "--protect-hidden=yes|no\n" + " Write-protect a hidden volume when mounting an outer volume. Before mounting\n" + " the outer volume, the user will be prompted for a password to open the hidden\n" + " volume. The size and position of the hidden volume is then determined and the\n" + " outer volume is mounted with all sectors belonging to the hidden volume\n" + " protected against write operations. When a write to the protected area is\n" + " prevented, the whole volume is switched to read-only mode. Verbose list\n" + " (-v -l) can be used to query the state of the hidden volume protection.\n" + " Warning message is displayed when a volume switched to read-only is being\n" + " dismounted.\n" + "\n" + "--protection-keyfiles=KEYFILE1[,KEYFILE2,KEYFILE3,...]\n" + " Use specified keyfiles to open a hidden volume to be protected. This option\n" + " may be used only when mounting an outer volume with hidden volume protected.\n" + " See also options -k and --protect-hidden.\n" + "\n" + "--protection-password=PASSWORD\n" + " Use specified password to open a hidden volume to be protected. This option\n" + " may be used only when mounting an outer volume with hidden volume protected.\n" + " See also options -p and --protect-hidden.\n" + "\n" + "--quick\n" + " Do not encrypt free space when creating a device-hosted volume. This option\n" + " must not be used when creating an outer volume.\n" + "\n" + "--random-source=FILE\n" + " Use FILE as a source of random data (e.g., when creating a volume) instead\n" + " of requiring the user to type random characters.\n" + "\n" + "--slot=SLOT\n" + " Use specified slot number when mounting, dismounting, or listing a volume.\n" + "\n" + "--size=SIZE\n" + " Use specified size in bytes when creating a new volume.\n" + "\n" + "-t, --text\n" + " Use text user interface. Graphical user interface is used by default if\n" + " available. This option must be specified as the first argument.\n" + "\n" + "--token-lib=LIB_PATH\n" + " Use specified PKCS #11 security token library.\n" + "\n" + "--volume-type=TYPE\n" + " Use specified volume type when creating a new volume. TYPE can be 'normal'\n" + " or 'hidden'. See option -c for more information on creating hidden volumes.\n" + "\n" + "-v, --verbose\n" + " Enable verbose output.\n" + "\n" + "\n" + "IMPORTANT:\n" + "\n" + "If you want to use TrueCrypt, you must follow the security requirements and\n" + "security precautions listed in chapter 'Security Requirements and Precautions'\n" + "in the TrueCrypt documentation (file 'TrueCrypt User Guide.pdf').\n" + "\n" + "\nExamples:\n\n" + "Create a new volume:\n" + "truecrypt -t -c\n" + "\n" + "Mount a volume:\n" + "truecrypt volume.tc /media/truecrypt1\n" + "\n" + "Mount a volume as read-only, using keyfiles:\n" + "truecrypt -m ro -k keyfile1,keyfile2 volume.tc\n" + "\n" + "Mount a volume without mounting its filesystem:\n" + "truecrypt --filesystem=none volume.tc\n" + "\n" + "Mount a volume prompting only for its password:\n" + "truecrypt -t -k \"\" --protect-hidden=no volume.tc /media/truecrypt1\n" + "\n" + "Dismount a volume:\n" + "truecrypt -d volume.tc\n" + "\n" + "Dismount all mounted volumes:\n" + "truecrypt -d\n" + ); + +#ifndef TC_NO_GUI + if (Application::GetUserInterfaceType() == UserInterfaceType::Graphic) + { + wxDialog dialog (nullptr, wxID_ANY, _("TrueCrypt Command Line Help"), wxDefaultPosition); + + wxTextCtrl *textCtrl = new wxTextCtrl (&dialog, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY); + textCtrl->SetFont (wxFont (wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Courier")); + textCtrl->SetValue (helpText); + + int fontWidth, fontHeight; + textCtrl->GetTextExtent (L"A", &fontWidth, &fontHeight); + dialog.SetSize (wxSize (fontWidth * 85, fontHeight * 29)); + + wxBoxSizer *sizer = new wxBoxSizer (wxVERTICAL); + sizer->Add (textCtrl, 1, wxALL | wxEXPAND, 5); + sizer->Add (new wxButton (&dialog, wxID_OK, _("OK")), 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5); + + dialog.SetSizer (sizer); + dialog.Layout(); + dialog.ShowModal(); + } + else +#endif // !TC_NO_GUI + { + ShowString (L"\n\n"); + ShowString (helpText); + } + } + return true; + + case CommandId::ExportSecurityTokenKeyfile: + ExportSecurityTokenKeyfile(); + return true; + + case CommandId::ImportSecurityTokenKeyfiles: + ImportSecurityTokenKeyfiles(); + return true; + + case CommandId::ListSecurityTokenKeyfiles: + ListSecurityTokenKeyfiles(); + return true; + + case CommandId::ListVolumes: + if (Preferences.Verbose) + DisplayVolumeProperties (cmdLine.ArgVolumes); + else + ListMountedVolumes (cmdLine.ArgVolumes); + return true; + + case CommandId::RestoreHeaders: + RestoreVolumeHeaders (cmdLine.ArgVolumePath); + return true; + + case CommandId::SavePreferences: + Preferences.Save(); + return true; + + case CommandId::Test: + Test(); + return true; + + default: + throw ParameterIncorrect (SRC_POS); + } + + return false; + } + + void UserInterface::SetPreferences (const UserPreferences &preferences) + { + Preferences = preferences; + + Cipher::EnableHwSupport (!preferences.DefaultMountOptions.NoHardwareCrypto); + + PreferencesUpdatedEvent.Raise(); + } + + void UserInterface::ShowError (const exception &ex) const + { + if (!dynamic_cast (&ex)) + DoShowError (ExceptionToMessage (ex)); + } + + wxString UserInterface::SizeToString (uint64 size) const + { + wstringstream s; + if (size > 1024ULL*1024*1024*1024*1024*99) + s << size/1024/1024/1024/1024/1024 << L" " << LangString["PB"].c_str(); + else if (size > 1024ULL*1024*1024*1024*1024) + return wxString::Format (L"%.1f %s", (double)(size/1024.0/1024/1024/1024/1024), LangString["PB"].c_str()); + else if (size > 1024ULL*1024*1024*1024*99) + s << size/1024/1024/1024/1024 << L" " << LangString["TB"].c_str(); + else if (size > 1024ULL*1024*1024*1024) + return wxString::Format (L"%.1f %s", (double)(size/1024.0/1024/1024/1024), LangString["TB"].c_str()); + else if (size > 1024ULL*1024*1024*99) + s << size/1024/1024/1024 << L" " << LangString["GB"].c_str(); + else if (size > 1024ULL*1024*1024) + return wxString::Format (L"%.1f %s", (double)(size/1024.0/1024/1024), LangString["GB"].c_str()); + else if (size > 1024ULL*1024*99) + s << size/1024/1024 << L" " << LangString["MB"].c_str(); + else if (size > 1024ULL*1024) + return wxString::Format (L"%.1f %s", (double)(size/1024.0/1024), LangString["MB"].c_str()); + else if (size > 1024ULL) + s << size/1024 << L" " << LangString["KB"].c_str(); + else + s << size << L" " << LangString["BYTE"].c_str(); + + return s.str(); + } + + wxString UserInterface::SpeedToString (uint64 speed) const + { + wstringstream s; + + if (speed > 1024ULL*1024*1024*1024*1024*99) + s << speed/1024/1024/1024/1024/1024 << L" " << LangString["PB_PER_SEC"].c_str(); + else if (speed > 1024ULL*1024*1024*1024*1024) + return wxString::Format (L"%.1f %s", (double)(speed/1024.0/1024/1024/1024/1024), LangString["PB_PER_SEC"].c_str()); + else if (speed > 1024ULL*1024*1024*1024*99) + s << speed/1024/1024/1024/1024 << L" " << LangString["TB_PER_SEC"].c_str(); + else if (speed > 1024ULL*1024*1024*1024) + return wxString::Format (L"%.1f %s", (double)(speed/1024.0/1024/1024/1024), LangString["TB_PER_SEC"].c_str()); + else if (speed > 1024ULL*1024*1024*99) + s << speed/1024/1024/1024 << L" " << LangString["GB_PER_SEC"].c_str(); + else if (speed > 1024ULL*1024*999) + return wxString::Format (L"%.1f %s", (double)(speed/1024.0/1024/1024), LangString["GB_PER_SEC"].c_str()); + else if (speed > 1024ULL*1024*9) + s << speed/1024/1024 << L" " << LangString["MB_PER_SEC"].c_str(); + else if (speed > 1024ULL*999) + return wxString::Format (L"%.1f %s", (double)(speed/1024.0/1024), LangString["MB_PER_SEC"].c_str()); + else if (speed > 1024ULL) + s << speed/1024 << L" " << LangString["KB_PER_SEC"].c_str(); + else + s << speed << L" " << LangString["B_PER_SEC"].c_str(); + + return s.str(); + } + + void UserInterface::Test () const + { + if (!PlatformTest::TestAll()) + throw TestFailed (SRC_POS); + + EncryptionTest::TestAll(); + + // StringFormatter + if (StringFormatter (L"{9} {8} {7} {6} {5} {4} {3} {2} {1} {0} {{0}}", "1", L"2", '3', L'4', 5, 6, 7, 8, 9, 10) != L"10 9 8 7 6 5 4 3 2 1 {0}") + throw TestFailed (SRC_POS); + try + { + StringFormatter (L"{0} {1}", 1); + throw TestFailed (SRC_POS); + } + catch (StringFormatterException&) { } + + try + { + StringFormatter (L"{0} {1} {1}", 1, 2, 3); + throw TestFailed (SRC_POS); + } + catch (StringFormatterException&) { } + + try + { + StringFormatter (L"{0} 1}", 1, 2); + throw TestFailed (SRC_POS); + } + catch (StringFormatterException&) { } + + try + { + StringFormatter (L"{0} {1", 1, 2); + throw TestFailed (SRC_POS); + } + catch (StringFormatterException&) { } + + ShowInfo ("TESTS_PASSED"); + } + + wxString UserInterface::TimeSpanToString (uint64 seconds) const + { + wstringstream s; + + if (seconds >= 60 * 60 * 24 * 2) + s << seconds / (60 * 24 * 60) << L" " << LangString["DAYS"].c_str(); + else if (seconds >= 120 * 60) + s << seconds / (60 * 60) << L" " << LangString["HOURS"].c_str(); + else if (seconds >= 120) + s << seconds / 60 << L" " << LangString["MINUTES"].c_str(); + else + s << seconds << L" " << LangString["SECONDS"].c_str(); + + return s.str(); + } + + bool UserInterface::VolumeHasUnrecommendedExtension (const VolumePath &path) const + { + wxString ext = wxFileName (wxString (wstring (path)).Lower()).GetExt(); + return ext.IsSameAs (L"exe") || ext.IsSameAs (L"sys") || ext.IsSameAs (L"dll"); + } + + wxString UserInterface::VolumeTimeToString (VolumeTime volumeTime) const + { + wxString dateStr = VolumeTimeToDateTime (volumeTime).Format(); + +#ifdef TC_WINDOWS + + FILETIME ft; + *(unsigned __int64 *)(&ft) = volumeTime; + SYSTEMTIME st; + FileTimeToSystemTime (&ft, &st); + + wchar_t wstr[1024]; + if (GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 0, wstr, array_capacity (wstr)) != 0) + { + dateStr = wstr; + GetTimeFormat (LOCALE_USER_DEFAULT, 0, &st, 0, wstr, array_capacity (wstr)); + dateStr += wxString (L" ") + wstr; + } +#endif + return dateStr; + } + + wxString UserInterface::VolumeTypeToString (VolumeType::Enum type, VolumeProtection::Enum protection) const + { + switch (type) + { + case VolumeType::Normal: + return LangString[protection == VolumeProtection::HiddenVolumeReadOnly ? "OUTER" : "NORMAL"]; + + case VolumeType::Hidden: + return LangString["HIDDEN"]; + + default: + return L"?"; + } + } +} diff --git a/src/Main/UserInterface.h b/src/Main/UserInterface.h new file mode 100644 index 00000000..ca33def2 --- /dev/null +++ b/src/Main/UserInterface.h @@ -0,0 +1,111 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_UserInterface +#define TC_HEADER_Main_UserInterface + +#include "System.h" +#include "Core/Core.h" +#include "Main.h" +#include "CommandLineInterface.h" +#include "FavoriteVolume.h" +#include "LanguageStrings.h" +#include "UserPreferences.h" +#include "UserInterfaceException.h" +#include "UserInterfaceType.h" + +namespace TrueCrypt +{ + class UserInterface : public wxApp + { + public: + virtual ~UserInterface (); + + virtual bool AskYesNo (const wxString &message, bool defaultYes = false, bool warning = false) const = 0; + virtual void BackupVolumeHeaders (shared_ptr volumePath) const = 0; + virtual void BeginBusyState () const = 0; + virtual void ChangePassword (shared_ptr volumePath = shared_ptr (), shared_ptr password = shared_ptr (), shared_ptr keyfiles = shared_ptr (), shared_ptr newPassword = shared_ptr (), shared_ptr newKeyfiles = shared_ptr (), shared_ptr newHash = shared_ptr ()) const = 0; + virtual void CheckRequirementsForMountingVolume () const; + virtual void CloseExplorerWindows (shared_ptr mountedVolume) const; + virtual void CreateKeyfile (shared_ptr keyfilePath = shared_ptr ()) const = 0; + virtual void CreateVolume (shared_ptr options) const = 0; + virtual void DeleteSecurityTokenKeyfiles () const = 0; + virtual void DismountAllVolumes (bool ignoreOpenFiles = false, bool interactive = true) const; + virtual void DismountVolume (shared_ptr volume, bool ignoreOpenFiles = false, bool interactive = true) const; + virtual void DismountVolumes (VolumeInfoList volumes, bool ignoreOpenFiles = false, bool interactive = true) const; + virtual void DisplayVolumeProperties (const VolumeInfoList &volumes) const; + virtual void DoShowError (const wxString &message) const = 0; + virtual void DoShowInfo (const wxString &message) const = 0; + virtual void DoShowString (const wxString &str) const = 0; + virtual void DoShowWarning (const wxString &message) const = 0; + virtual void EndBusyState () const = 0; + virtual wxString ExceptionToMessage (const exception &ex) const; + virtual void ExportSecurityTokenKeyfile () const = 0; + virtual shared_ptr GetAdminPasswordRequestHandler () = 0; + virtual const UserPreferences &GetPreferences () const { return Preferences; } + virtual void ImportSecurityTokenKeyfiles () const = 0; + virtual void Init (); + virtual void InitSecurityTokenLibrary () const = 0; + virtual void ListMountedVolumes (const VolumeInfoList &volumes) const; + virtual void ListSecurityTokenKeyfiles () const = 0; + virtual shared_ptr MountVolume (MountOptions &options) const; + virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; + virtual VolumeInfoList MountAllFavoriteVolumes (MountOptions &options); + virtual void OpenExplorerWindow (const DirectoryPath &path); + virtual void RestoreVolumeHeaders (shared_ptr volumePath) const = 0; + virtual void SetPreferences (const UserPreferences &preferences); + virtual void ShowError (const exception &ex) const; + virtual void ShowError (const char *langStringId) const { DoShowError (LangString[langStringId]); } + virtual void ShowError (const wxString &message) const { DoShowError (message); } + virtual void ShowInfo (const exception &ex) const { DoShowInfo (ExceptionToMessage (ex)); } + virtual void ShowInfo (const char *langStringId) const { DoShowInfo (LangString[langStringId]); } + virtual void ShowInfo (const wxString &message) const { DoShowInfo (message); } + virtual void ShowWarning (const exception &ex) const { DoShowWarning (ExceptionToMessage (ex)); } + virtual void ShowWarning (const char *langStringId) const { DoShowWarning (LangString[langStringId]); } + virtual void ShowString (const wxString &str) const { DoShowString (str); } + virtual void ShowWarning (const wxString &message) const { DoShowWarning (message); } + virtual wxString SizeToString (uint64 size) const; + virtual wxString SpeedToString (uint64 speed) const; + virtual void Test () const; + virtual wxString TimeSpanToString (uint64 seconds) const; + virtual bool VolumeHasUnrecommendedExtension (const VolumePath &path) const; + virtual void Yield () const = 0; + virtual wxDateTime VolumeTimeToDateTime (VolumeTime volumeTime) const { return wxDateTime ((time_t) (volumeTime / 1000ULL / 1000 / 10 - 134774ULL * 24 * 3600)); } + virtual wxString VolumeTimeToString (VolumeTime volumeTime) const; + virtual wxString VolumeTypeToString (VolumeType::Enum type, VolumeProtection::Enum protection) const; + + Event PreferencesUpdatedEvent; + + struct BusyScope + { + BusyScope (const UserInterface *userInterface) : UI (userInterface) { UI->BeginBusyState (); } + ~BusyScope () { UI->EndBusyState (); } + const UserInterface *UI; + }; + + protected: + UserInterface (); + virtual bool OnExceptionInMainLoop () { throw; } + virtual void OnUnhandledException (); + virtual void OnVolumeMounted (EventArgs &args); + virtual void OnWarning (EventArgs &args); + virtual bool ProcessCommandLine (); + + virtual wxString ExceptionToString (const Exception &ex) const; + virtual wxString ExceptionTypeToString (const std::type_info &ex) const; + + UserPreferences Preferences; + UserInterfaceType::Enum InterfaceType; + + private: + UserInterface (const UserInterface &); + UserInterface &operator= (const UserInterface &); + }; +} + +#endif // TC_HEADER_Main_UserInterface diff --git a/src/Main/UserInterfaceException.h b/src/Main/UserInterfaceException.h new file mode 100644 index 00000000..625fc37d --- /dev/null +++ b/src/Main/UserInterfaceException.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_UserInterfaceException +#define TC_HEADER_Main_UserInterfaceException + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + TC_EXCEPTION_DECL (UserInterfaceException, Exception); + TC_EXCEPTION_DECL (MissingArgument, UserInterfaceException); + TC_EXCEPTION_DECL (NoItemSelected, UserInterfaceException); + TC_EXCEPTION_DECL (StringFormatterException, UserInterfaceException); + + struct ErrorMessage : public UserInterfaceException + { + ErrorMessage (const string &exceptionMessage, const wxString &errorMessage) : UserInterfaceException (exceptionMessage), Text (errorMessage) { } + virtual ~ErrorMessage () throw () { } + + operator wstring () const { return wstring (Text); } + operator wxString () const { return Text; } + + protected: + wxString Text; + }; + +#define throw_err(message) throw ErrorMessage (SRC_POS, (message)) +} + +#endif // TC_HEADER_Main_UserInterfaceException diff --git a/src/Main/UserInterfaceType.h b/src/Main/UserInterfaceType.h new file mode 100644 index 00000000..fe1571d1 --- /dev/null +++ b/src/Main/UserInterfaceType.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_UserInterfaceType +#define TC_HEADER_Main_UserInterfaceType + +namespace TrueCrypt +{ + struct UserInterfaceType + { + enum Enum + { + Unknown, + Graphic, + Text + }; + }; +} + +#endif // TC_HEADER_Main_UserInterfaceType diff --git a/src/Main/UserPreferences.cpp b/src/Main/UserPreferences.cpp new file mode 100644 index 00000000..e0e82336 --- /dev/null +++ b/src/Main/UserPreferences.cpp @@ -0,0 +1,235 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Main/Application.h" +#include "UserPreferences.h" +#include "Xml.h" + +namespace TrueCrypt +{ + void UserPreferences::SetValue (const wxString &cfgText, bool &cfgVar) + { + if (cfgText == L"0") + cfgVar = false; + else if (cfgText == L"1") + cfgVar = true; + } + + void UserPreferences::SetValue (const wxString &cfgText, int &cfgVar) + { + if (cfgText.empty()) + cfgVar = 0; + else + cfgVar = StringConverter::ToUInt32 (wstring (cfgText)); + } + + void UserPreferences::SetValue (const wxString &cfgText, uint64 &cfgVar) + { + if (cfgText.empty()) + cfgVar = 0; + else + cfgVar = StringConverter::ToUInt64 (wstring (cfgText)); + } + + void UserPreferences::SetValue (const wxString &cfgText, wstring &cfgVar) + { + cfgVar = cfgText; + } + + void UserPreferences::SetValue (const wxString &cfgText, wxString &cfgVar) + { + cfgVar = cfgText; + } + + void UserPreferences::SetValue (const wxString &cfgText, FilesystemPath &cfgVar) + { + cfgVar = wstring (cfgText); + } + + void UserPreferences::Load() + { + // Preferences + FilePath cfgPath = Application::GetConfigFilePath (GetPreferencesFileName()); + if (cfgPath.IsFile()) + { + map configMap; + foreach (XmlNode node, XmlParser (cfgPath).GetNodes (L"config")) + { + configMap[node.Attributes[L"key"]] = node.InnerText; + } + +#define TC_CONFIG_SET(NAME) SetValue (configMap[L###NAME], NAME) + + TC_CONFIG_SET (BackgroundTaskEnabled); + TC_CONFIG_SET (BackgroundTaskMenuDismountItemsEnabled); + TC_CONFIG_SET (BackgroundTaskMenuMountItemsEnabled); + TC_CONFIG_SET (BackgroundTaskMenuOpenItemsEnabled); + TC_CONFIG_SET (BeepAfterHotkeyMountDismount); + SetValue (configMap[L"CachePasswords"], DefaultMountOptions.CachePassword); + TC_CONFIG_SET (CloseBackgroundTaskOnNoVolumes); + TC_CONFIG_SET (CloseExplorerWindowsOnDismount); + TC_CONFIG_SET (CloseSecurityTokenSessionsAfterMount); + TC_CONFIG_SET (DisableKernelEncryptionModeWarning); + TC_CONFIG_SET (DismountOnInactivity); + TC_CONFIG_SET (DismountOnLogOff); + TC_CONFIG_SET (DismountOnPowerSaving); + TC_CONFIG_SET (DismountOnScreenSaver); + TC_CONFIG_SET (DisplayMessageAfterHotkeyDismount); + TC_CONFIG_SET (BackgroundTaskEnabled); + SetValue (configMap[L"FilesystemOptions"], DefaultMountOptions.FilesystemOptions); + TC_CONFIG_SET (ForceAutoDismount); + TC_CONFIG_SET (LastSelectedSlotNumber); + TC_CONFIG_SET (MaxVolumeIdleTime); + TC_CONFIG_SET (MountDevicesOnLogon); + TC_CONFIG_SET (MountFavoritesOnLogon); + + bool readOnly; + SetValue (configMap[L"MountVolumesReadOnly"], readOnly); + DefaultMountOptions.Protection = readOnly ? VolumeProtection::ReadOnly : VolumeProtection::None; + + SetValue (configMap[L"MountVolumesRemovable"], DefaultMountOptions.Removable); + SetValue (configMap[L"NoHardwareCrypto"], DefaultMountOptions.NoHardwareCrypto); + SetValue (configMap[L"NoKernelCrypto"], DefaultMountOptions.NoKernelCrypto); + TC_CONFIG_SET (OpenExplorerWindowAfterMount); + SetValue (configMap[L"PreserveTimestamps"], DefaultMountOptions.PreserveTimestamps); + TC_CONFIG_SET (SaveHistory); + SetValue (configMap[L"SecurityTokenLibrary"], SecurityTokenModule); + TC_CONFIG_SET (StartOnLogon); + TC_CONFIG_SET (UseKeyfiles); + TC_CONFIG_SET (WipeCacheOnAutoDismount); + TC_CONFIG_SET (WipeCacheOnClose); + } + + // Default keyfiles + cfgPath = Application::GetConfigFilePath (GetDefaultKeyfilesFileName()); + if (cfgPath.IsFile()) + { + foreach (const XmlNode &node, XmlParser (cfgPath).GetNodes (L"keyfile")) + { + DefaultKeyfiles.push_back (make_shared ((wstring) node.InnerText)); + } + } + +#ifdef TC_WINDOWS + // Hotkeys + Hotkeys = Hotkey::LoadList(); +#endif + } + + void UserPreferences::Save() const + { + // Preferences + class ConfigXmlFormatter + { + public: + void AddEntry (const wchar_t *key, const wxString &value) + { + if (!value.empty()) + { + XmlNode config (L"config"); + config.Attributes[L"key"] = key; + config.InnerText = value; + XmlConfig.InnerNodes.push_back (config); + } + } + + void AddEntry (const wchar_t *key, bool value) + { + AddEntry (key, wxString (value ? L"1" : L"0")); + } + + void AddEntry (const wchar_t *key, int value) + { + wstringstream s; + s << value; + AddEntry (key, s.str()); + } + + void AddEntry (const wchar_t *key, uint64 value) + { + wstringstream s; + s << value; + AddEntry (key, s.str()); + } + + XmlNode XmlConfig; + }; + + ConfigXmlFormatter formatter; + formatter.XmlConfig.Name = L"configuration"; + +#define TC_CONFIG_ADD(NAME) formatter.AddEntry (L###NAME, NAME) + + TC_CONFIG_ADD (BackgroundTaskEnabled); + TC_CONFIG_ADD (BackgroundTaskMenuDismountItemsEnabled); + TC_CONFIG_ADD (BackgroundTaskMenuMountItemsEnabled); + TC_CONFIG_ADD (BackgroundTaskMenuOpenItemsEnabled); + TC_CONFIG_ADD (BeepAfterHotkeyMountDismount); + formatter.AddEntry (L"CachePasswords", DefaultMountOptions.CachePassword); + TC_CONFIG_ADD (CloseBackgroundTaskOnNoVolumes); + TC_CONFIG_ADD (CloseExplorerWindowsOnDismount); + TC_CONFIG_ADD (CloseSecurityTokenSessionsAfterMount); + TC_CONFIG_ADD (DisableKernelEncryptionModeWarning); + TC_CONFIG_ADD (DismountOnInactivity); + TC_CONFIG_ADD (DismountOnLogOff); + TC_CONFIG_ADD (DismountOnPowerSaving); + TC_CONFIG_ADD (DismountOnScreenSaver); + TC_CONFIG_ADD (DisplayMessageAfterHotkeyDismount); + TC_CONFIG_ADD (BackgroundTaskEnabled); + formatter.AddEntry (L"FilesystemOptions", DefaultMountOptions.FilesystemOptions); + TC_CONFIG_ADD (ForceAutoDismount); + TC_CONFIG_ADD (LastSelectedSlotNumber); + TC_CONFIG_ADD (MaxVolumeIdleTime); + TC_CONFIG_ADD (MountDevicesOnLogon); + TC_CONFIG_ADD (MountFavoritesOnLogon); + formatter.AddEntry (L"MountVolumesReadOnly", DefaultMountOptions.Protection == VolumeProtection::ReadOnly); + formatter.AddEntry (L"MountVolumesRemovable", DefaultMountOptions.Removable); + formatter.AddEntry (L"NoHardwareCrypto", DefaultMountOptions.NoHardwareCrypto); + formatter.AddEntry (L"NoKernelCrypto", DefaultMountOptions.NoKernelCrypto); + TC_CONFIG_ADD (OpenExplorerWindowAfterMount); + formatter.AddEntry (L"PreserveTimestamps", DefaultMountOptions.PreserveTimestamps); + TC_CONFIG_ADD (SaveHistory); + formatter.AddEntry (L"SecurityTokenLibrary", wstring (SecurityTokenModule)); + TC_CONFIG_ADD (StartOnLogon); + TC_CONFIG_ADD (UseKeyfiles); + TC_CONFIG_ADD (WipeCacheOnAutoDismount); + TC_CONFIG_ADD (WipeCacheOnClose); + + XmlWriter writer (Application::GetConfigFilePath (GetPreferencesFileName(), true)); + writer.WriteNode (formatter.XmlConfig); + writer.Close(); + + // Default keyfiles + FilePath keyfilesCfgPath = Application::GetConfigFilePath (GetDefaultKeyfilesFileName(), true); + + if (DefaultKeyfiles.empty()) + { + if (keyfilesCfgPath.IsFile()) + keyfilesCfgPath.Delete(); + } + else + { + XmlNode keyfilesXml (L"defaultkeyfiles"); + + foreach_ref (const Keyfile &keyfile, DefaultKeyfiles) + { + keyfilesXml.InnerNodes.push_back (XmlNode (L"keyfile", wxString (FilesystemPath (keyfile)))); + } + + XmlWriter keyfileWriter (keyfilesCfgPath); + keyfileWriter.WriteNode (keyfilesXml); + keyfileWriter.Close(); + } + +#ifdef TC_WINDOWS + // Hotkeys + Hotkey::SaveList (Hotkeys); +#endif + } +} diff --git a/src/Main/UserPreferences.h b/src/Main/UserPreferences.h new file mode 100644 index 00000000..0f862ce6 --- /dev/null +++ b/src/Main/UserPreferences.h @@ -0,0 +1,107 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_UserPreferences +#define TC_HEADER_Main_UserPreferences + +#include "System.h" +#include "Main.h" +#include "Hotkey.h" + +namespace TrueCrypt +{ + struct UserPreferences + { + UserPreferences () + : + BackgroundTaskEnabled (true), + BackgroundTaskMenuDismountItemsEnabled (true), + BackgroundTaskMenuMountItemsEnabled (true), + BackgroundTaskMenuOpenItemsEnabled (true), + BeepAfterHotkeyMountDismount (false), + CloseBackgroundTaskOnNoVolumes (true), + CloseExplorerWindowsOnDismount (true), + CloseSecurityTokenSessionsAfterMount (false), + DisableKernelEncryptionModeWarning (false), + DismountOnInactivity (false), + DismountOnLogOff (true), + DismountOnPowerSaving (false), + DismountOnScreenSaver (false), + DisplayMessageAfterHotkeyDismount (false), + ForceAutoDismount (true), + LastSelectedSlotNumber (0), + MaxVolumeIdleTime (60), + MountDevicesOnLogon (false), + MountFavoritesOnLogon (false), + NonInteractive (false), + OpenExplorerWindowAfterMount (false), + SaveHistory (false), + StartOnLogon (false), + UseKeyfiles (false), + Verbose (false), + WipeCacheOnAutoDismount (true), + WipeCacheOnClose (false) + { + } + + virtual ~UserPreferences () + { + } + void Load(); + void Save() const; + + HotkeyList Hotkeys; + KeyfileList DefaultKeyfiles; + MountOptions DefaultMountOptions; + + bool BackgroundTaskEnabled; + bool BackgroundTaskMenuDismountItemsEnabled; + bool BackgroundTaskMenuMountItemsEnabled; + bool BackgroundTaskMenuOpenItemsEnabled; + bool BeepAfterHotkeyMountDismount; + bool CloseBackgroundTaskOnNoVolumes; + bool CloseExplorerWindowsOnDismount; + bool CloseSecurityTokenSessionsAfterMount; + bool DisableKernelEncryptionModeWarning; + bool DismountOnInactivity; + bool DismountOnLogOff; + bool DismountOnPowerSaving; + bool DismountOnScreenSaver; + bool DisplayMessageAfterHotkeyDismount; + bool ForceAutoDismount; + uint64 LastSelectedSlotNumber; + int32 MaxVolumeIdleTime; + bool MountDevicesOnLogon; + bool MountFavoritesOnLogon; + bool NonInteractive; + bool OpenExplorerWindowAfterMount; + bool SaveHistory; + FilePath SecurityTokenModule; + bool StartOnLogon; + bool UseKeyfiles; + bool Verbose; + bool WipeCacheOnAutoDismount; + bool WipeCacheOnClose; + + protected: + wxString GetDefaultKeyfilesFileName () const { return L"Default Keyfiles.xml"; } +#ifdef TC_PROTOTYPE + wxString GetPreferencesFileName () const { return L"Configuration_Debug.xml"; } +#else + wxString GetPreferencesFileName () const { return L"Configuration.xml"; } +#endif + void SetValue (const wxString &cfgText, bool &cfgVar); + void SetValue (const wxString &cfgText, int &cfgVar); + void SetValue (const wxString &cfgText, uint64 &cfgVar); + void SetValue (const wxString &cfgText, wstring &cfgVar); + void SetValue (const wxString &cfgText, wxString &cfgVar); + void SetValue (const wxString &cfgText, FilesystemPath &cfgVar); + }; +} + +#endif // TC_HEADER_Main_UserPreferences diff --git a/src/Main/VolumeHistory.cpp b/src/Main/VolumeHistory.cpp new file mode 100644 index 00000000..5bdac903 --- /dev/null +++ b/src/Main/VolumeHistory.cpp @@ -0,0 +1,152 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Application.h" +#include "GraphicUserInterface.h" +#include "Xml.h" +#include "VolumeHistory.h" + +namespace TrueCrypt +{ + VolumeHistory::VolumeHistory () + { + } + + VolumeHistory::~VolumeHistory () + { + } + + void VolumeHistory::Add (const VolumePath &newPath) + { + if (Gui->GetPreferences().SaveHistory) + { + ScopeLock lock (AccessMutex); + + VolumePathList::iterator iter = VolumePaths.begin(); + foreach (const VolumePath &path, VolumePaths) + { + if (newPath == path) + { + VolumePaths.erase (iter); + break; + } + iter++; + } + + VolumePaths.push_front (newPath); + if (VolumePaths.size() > MaxSize) + VolumePaths.pop_back(); + + foreach (wxComboBox *comboBox, ConnectedComboBoxes) + { + UpdateComboBox (comboBox); + } + } + } + + void VolumeHistory::Clear () + { + VolumePaths.clear(); + foreach (wxComboBox *comboBox, ConnectedComboBoxes) + { + UpdateComboBox (comboBox); + } + + Save(); + } + + void VolumeHistory::ConnectComboBox (wxComboBox *comboBox) + { + ScopeLock lock (AccessMutex); + ConnectedComboBoxes.push_back (comboBox); + + UpdateComboBox (comboBox); + } + + void VolumeHistory::DisconnectComboBox (wxComboBox *comboBox) + { + ScopeLock lock (AccessMutex); + + for (list::iterator iter = ConnectedComboBoxes.begin(); iter != ConnectedComboBoxes.end(); ++iter) + { + if (comboBox == *iter) + { + ConnectedComboBoxes.erase (iter); + break; + } + } + } + + void VolumeHistory::Load () + { + ScopeLock lock (AccessMutex); + FilePath historyCfgPath = Application::GetConfigFilePath (GetFileName()); + + if (historyCfgPath.IsFile()) + { + if (!Gui->GetPreferences().SaveHistory) + { + historyCfgPath.Delete(); + } + else + { + foreach_reverse (const XmlNode &node, XmlParser (historyCfgPath).GetNodes (L"volume")) + { + Add (wstring (node.InnerText)); + } + } + } + } + + void VolumeHistory::Save () + { + ScopeLock lock (AccessMutex); + FilePath historyCfgPath = Application::GetConfigFilePath (GetFileName(), true); + + if (!Gui->GetPreferences().SaveHistory || VolumePaths.empty()) + { + if (historyCfgPath.IsFile()) + historyCfgPath.Delete(); + } + else + { + XmlNode historyXml (L"history"); + + foreach (const VolumePath &path, VolumePaths) + { + historyXml.InnerNodes.push_back (XmlNode (L"volume", wstring (path))); + } + + XmlWriter historyWriter (historyCfgPath); + historyWriter.WriteNode (historyXml); + historyWriter.Close(); + } + } + + void VolumeHistory::UpdateComboBox (wxComboBox *comboBox) + { + wxString curValue = comboBox->GetValue(); + + comboBox->Freeze(); + comboBox->Clear(); + + foreach (const VolumePath &path, VolumePaths) + { + comboBox->Append (wstring (path)); + } + + comboBox->SetValue (curValue); + comboBox->Thaw(); + } + + list VolumeHistory::ConnectedComboBoxes; + VolumePathList VolumeHistory::VolumePaths; + Mutex VolumeHistory::AccessMutex; + +} diff --git a/src/Main/VolumeHistory.h b/src/Main/VolumeHistory.h new file mode 100644 index 00000000..d2fc3fc0 --- /dev/null +++ b/src/Main/VolumeHistory.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_VolumeHistory +#define TC_HEADER_Main_VolumeHistory + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + class VolumeHistory + { + public: + VolumeHistory (); + virtual ~VolumeHistory (); + + static void Add (const VolumePath &path); + static void Clear (); + static void ConnectComboBox (wxComboBox *comboBox); + static void DisconnectComboBox (wxComboBox *comboBox); + static VolumePathList Get () { return VolumePaths; } + static void Load (); + static void Save (); + + protected: + static void UpdateComboBox (wxComboBox *comboBox); + static wxString GetFileName () { return L"History.xml"; } + + static const unsigned int MaxSize = 10; + static list ConnectedComboBoxes; + static VolumePathList VolumePaths; + static Mutex AccessMutex; + + private: + VolumeHistory (const VolumeHistory &); + VolumeHistory &operator= (const VolumeHistory &); + }; +} + +#endif // TC_HEADER_Main_VolumeHistory diff --git a/src/Main/Xml.cpp b/src/Main/Xml.cpp new file mode 100644 index 00000000..d70c0f76 --- /dev/null +++ b/src/Main/Xml.cpp @@ -0,0 +1,178 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#include "Platform/FileStream.h" +#include "Xml.h" + +namespace TrueCrypt +{ + XmlParser::XmlParser (const FilePath &fileName) + { + make_shared_auto (File, file); + file->Open (fileName); + FileStream stream (file); + + XmlText = wxString::FromUTF8 (stream.ReadToEnd().c_str()); + } + + wxString XmlParser::ConvertEscapedChars (wxString xmlString) const + { + xmlString.Replace (L"<", L"<"); + xmlString.Replace (L">", L">"); + xmlString.Replace (L"&", L"&"); + xmlString.Replace (L""", L"\""); + return xmlString; + } + + XmlNodeList XmlParser::GetNodes (const wxString &nodeName) const + { + XmlNodeList nodeList; + + size_t nodePos = 0; + while ((nodePos = XmlText.find (L"<" + nodeName, nodePos)) != string::npos) + { + XmlNode xmlNode; + xmlNode.Name = nodeName; + + size_t nodeEnd = XmlText.find (L">", nodePos); + if (nodeEnd == string::npos) + throw ParameterIncorrect (SRC_POS); + + wxString nodeTagText = XmlText.substr (nodePos + 1, nodeEnd - nodePos - 1); + nodePos = nodeEnd; + + if (nodeTagText.size() > nodeName.size() && nodeTagText[nodeName.size()] != L' ' && nodeTagText[nodeName.size()] != L'/') + continue; + + nodeTagText = nodeTagText.substr (nodeName.size()); + + + // Attributes + wxStringTokenizer tokenizer (nodeTagText, L"\"", wxTOKEN_RET_EMPTY); + while (tokenizer.HasMoreTokens()) + { + wxString attributeName = tokenizer.GetNextToken(); + attributeName.Replace (L" ", L"", true); + attributeName.Replace (L"=", L""); + + if (!attributeName.empty() && tokenizer.HasMoreTokens()) + { + wxString attributeText = tokenizer.GetNextToken(); + xmlNode.Attributes[attributeName] = ConvertEscapedChars (attributeText); + } + } + + // Inner text + if (!nodeTagText.EndsWith (L"/")) + { + size_t innerTextPos = nodeEnd + 1; + size_t innerTextEnd = XmlText.find (L"", innerTextPos); + if (innerTextEnd == string::npos) + throw ParameterIncorrect (SRC_POS); + + xmlNode.InnerText = ConvertEscapedChars (XmlText.substr (innerTextPos, innerTextEnd - innerTextPos)); + nodePos = innerTextEnd; + } + + nodeList.push_back (xmlNode); + } + + return nodeList; + } + + XmlWriter::XmlWriter (const FilePath &fileName) + { + MemOutStream.reset (new wxMemoryOutputStream); + TextOutStream.reset (new wxTextOutputStream (*MemOutStream)); + OutFile.Open (fileName, File::CreateWrite); + + *TextOutStream << L"" << endl << L"" << endl; + CurrentIndentLevel = 0; + } + + void XmlWriter::Close() + { + if (MemOutStream.get()) + { + *TextOutStream << L"" << endl; + + wxStreamBuffer *buf = MemOutStream->GetOutputStreamBuffer(); + OutFile.Write (ConstBufferPtr (reinterpret_cast (buf->GetBufferStart()), buf->GetBufferSize())); + OutFile.Close(); + + TextOutStream.reset(); + MemOutStream.reset(); + } + } + + wxString XmlWriter::EscapeChars (wxString rawString) const + { + rawString.Replace (L"<", L"<"); + rawString.Replace (L">", L">"); + rawString.Replace (L"&", L"&"); + rawString.Replace (L"\"", L"""); + return rawString; + } + + void XmlWriter::WriteNode (const XmlNode &xmlNode) + { + XmlNodeList nodes; + nodes.push_back (xmlNode); + WriteNodes (nodes); + } + + void XmlWriter::WriteNodes (const XmlNodeList &xmlNodes) + { + CurrentIndentLevel++; + wxString indent; + for (int i = 0; i < CurrentIndentLevel; ++i) + indent += L"\t"; + + foreach (const XmlNode &node, xmlNodes) + { + *TextOutStream << indent << L"<" << node.Name; + + typedef pair AttribPair; + foreach (AttribPair attrib, node.Attributes) + { + *TextOutStream << L" " << attrib.first << L"=\"" << EscapeChars (attrib.second) << L"\""; + } + + if (!node.InnerNodes.empty()) + { + *TextOutStream << L">" << endl; + WriteNodes (node.InnerNodes); + *TextOutStream << indent; + } + else if (!node.InnerText.empty()) + { + *TextOutStream << L">" << EscapeChars (node.InnerText); + } + else + { + *TextOutStream << L"/>" << endl; + continue; + } + + *TextOutStream << L"" << endl; + } + + CurrentIndentLevel--; + } + + XmlWriter::~XmlWriter () + { + try + { + Close(); + } + catch (...) { } + } +} diff --git a/src/Main/Xml.h b/src/Main/Xml.h new file mode 100644 index 00000000..9f615af2 --- /dev/null +++ b/src/Main/Xml.h @@ -0,0 +1,75 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Xml +#define TC_HEADER_Main_Xml + +#include "System.h" +#include "Main.h" + +namespace TrueCrypt +{ + struct XmlNode; + typedef list XmlNodeList; + + struct XmlNode + { + XmlNode () { } + XmlNode (const wxString &name) : Name (name) { } + XmlNode (const wxString &name, const wxString &innerText) : InnerText (innerText), Name (name) { } + XmlNode (const wxString &name, const XmlNodeList &innerNodes) : InnerNodes (innerNodes), Name (name) { } + + map Attributes; + XmlNodeList InnerNodes; + wxString InnerText; + wxString Name; + }; + + class XmlParser + { + public: + XmlParser (const FilePath &fileName); + XmlParser (const string &xmlTextUtf8) : XmlText (wxString::FromUTF8 (xmlTextUtf8.c_str())) { } + XmlParser (const wxString &xmlText) : XmlText (xmlText) { } + virtual ~XmlParser () { } + + wxString ConvertEscapedChars (wxString xmlString) const; + XmlNodeList GetNodes (const wxString &nodeName) const; + + protected: + wxString XmlText; + + private: + XmlParser (const XmlParser &); + XmlParser &operator= (const XmlParser &); + }; + + class XmlWriter + { + public: + XmlWriter (const FilePath &fileName); + virtual ~XmlWriter (); + + void Close(); + wxString EscapeChars (wxString rawString) const; + void WriteNode (const XmlNode &xmlNode); + void WriteNodes (const XmlNodeList &xmlNodes); + + protected: + int CurrentIndentLevel; + auto_ptr MemOutStream; + auto_ptr TextOutStream; + File OutFile; + + private: + XmlWriter (const XmlWriter &); + XmlWriter &operator= (const XmlWriter &); + }; +} + +#endif // TC_HEADER_Main_Xml diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 00000000..265bb6f2 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,298 @@ +# +# Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +#------ Command line arguments ------ +# DEBUG: Disable optimizations and enable debugging checks +# DEBUGGER: Enable debugging information for use by debuggers +# NOASM: Exclude modules requiring assembler +# NOGUI: Disable graphical user interface (build console-only application) +# NOSTRIP: Do not strip release binary +# NOTEST: Do not test release binary +# RESOURCEDIR: Run-time resource directory +# VERBOSE: Enable verbose messages +# WXSTATIC: Use static wxWidgets library + +#------ Targets ------ +# all +# clean +# wxbuild: Configure and build wxWidgets - source code must be located at $(WX_ROOT) + + +#------ Build configuration ------ + +export APPNAME := truecrypt +export BASE_DIR := $(CURDIR) +export BUILD_INC := $(BASE_DIR)/Build/Include + +export AR ?= ar +export CC ?= gcc +export CXX ?= g++ +export AS := nasm +export RANLIB ?= ranlib + +export CFLAGS := -Wall +export CXXFLAGS := -Wall -Wno-unused-parameter +C_CXX_FLAGS := -MMD -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES -I$(BASE_DIR) -I$(BASE_DIR)/Crypto +export ASFLAGS := -Ox -D __GNUC__ +export LFLAGS := + +export PKG_CONFIG_PATH ?= /usr/local/lib/pkgconfig + +export WX_CONFIG ?= wx-config +export WX_CONFIG_ARGS := --unicode +WX_CONFIGURE_FLAGS := +export WXCONFIG_CFLAGS := +export WXCONFIG_CXXFLAGS := +WX_ROOT ?= .. + + +export TC_BUILD_CONFIG := Release + +ifeq "$(origin DEBUG)" "command line" + ifneq "$(DEBUG)" "0" + TC_BUILD_CONFIG := Debug + endif +endif + +ifeq "$(origin NOGUI)" "command line" + export TC_NO_GUI := 1 + C_CXX_FLAGS += -DTC_NO_GUI + WX_CONFIGURE_FLAGS += --disable-gui +endif + +ifdef PKCS11_INC + C_CXX_FLAGS += -I$(PKCS11_INC) +endif + +ifeq "$(origin RESOURCEDIR)" "command line" + C_CXX_FLAGS += -DTC_RESOURCE_DIR="$(RESOURCEDIR)" +endif + +ifneq "$(origin VERBOSE)" "command line" + MAKEFLAGS += -s +endif + +ifeq "$(origin WXSTATIC)" "command line" + WX_CONFIG = $(WX_BUILD_DIR)/wx-config + WX_CONFIG_ARGS += --static +endif + + +#------ Release configuration ------ + +ifeq "$(TC_BUILD_CONFIG)" "Release" + + C_CXX_FLAGS += -O2 -fno-strict-aliasing # Do not enable strict aliasing + export WX_BUILD_DIR ?= $(BASE_DIR)/wxrelease + WX_CONFIGURE_FLAGS += --disable-debug_flag --disable-debug_gdb --disable-debug_info + +else + +#------ Debug configuration ------ + + C_CXX_FLAGS += -DDEBUG + CXXFLAGS += -fno-default-inline -Wno-unused-function -Wno-unused-variable + export WX_BUILD_DIR ?= $(BASE_DIR)/wxdebug + WX_CONFIGURE_FLAGS += --enable-debug_flag --disable-debug_gdb --disable-debug_info + +endif + + +#------ Debugger configuration ------ + +ifeq "$(origin DEBUGGER)" "command line" + + C_CXX_FLAGS += -ggdb + WX_CONFIGURE_FLAGS += --enable-debug_gdb --enable-debug_info + +endif + + +#------ Platform configuration ------ + +export PLATFORM := "Unknown" +export PLATFORM_UNSUPPORTED := 0 + +export CPU_ARCH ?= unknown + +ARCH = $(shell uname -p) +ifeq "$(ARCH)" "unknown" + ARCH = $(shell uname -m) +endif + +ifneq (,$(filter i386 i486 i586 i686 x86,$(ARCH))) + CPU_ARCH = x86 + ASM_OBJ_FORMAT = elf32 +else ifneq (,$(filter x86_64 x86-64 amd64 x64,$(ARCH))) + CPU_ARCH = x64 + ASM_OBJ_FORMAT = elf64 +endif + +ifeq "$(origin NOASM)" "command line" + CPU_ARCH = unknown +endif + +ifeq "$(CPU_ARCH)" "x86" + C_CXX_FLAGS += -D TC_ARCH_X86 +else ifeq "$(CPU_ARCH)" "x64" + C_CXX_FLAGS += -D TC_ARCH_X64 +endif + + +#------ Linux configuration ------ + +ifeq "$(shell uname -s)" "Linux" + + PLATFORM := Linux + C_CXX_FLAGS += -DTC_UNIX -DTC_LINUX + + ifeq "$(TC_BUILD_CONFIG)" "Release" + C_CXX_FLAGS += -fdata-sections -ffunction-sections + LFLAGS += -Wl,--gc-sections + + ifneq "$(shell ld --help 2>&1 | grep sysv | wc -l)" "0" + LFLAGS += -Wl,--hash-style=sysv + endif + + WXCONFIG_CFLAGS += -fdata-sections -ffunction-sections + WXCONFIG_CXXFLAGS += -fdata-sections -ffunction-sections + endif + +endif + + +#------ Mac OS X configuration ------ + +ifeq "$(shell uname -s)" "Darwin" + + PLATFORM := MacOSX + APPNAME := TrueCrypt + + TC_OSX_SDK ?= /Developer/SDKs/MacOSX10.4u.sdk + CC := gcc-4.0 + CXX := g++-4.0 + + C_CXX_FLAGS += -DTC_UNIX -DTC_BSD -DTC_MACOSX -mmacosx-version-min=10.4 -isysroot $(TC_OSX_SDK) + LFLAGS += -mmacosx-version-min=10.4 -Wl,-syslibroot $(TC_OSX_SDK) + WX_CONFIGURE_FLAGS += --with-macosx-version-min=10.4 --with-macosx-sdk=$(TC_OSX_SDK) + + ifeq "$(CPU_ARCH)" "x64" + CPU_ARCH = x86 + endif + + ASM_OBJ_FORMAT = macho + ASFLAGS += --prefix _ + + ifeq "$(TC_BUILD_CONFIG)" "Release" + + export DISABLE_PRECOMPILED_HEADERS := 1 + + S := $(C_CXX_FLAGS) + C_CXX_FLAGS = $(subst -MMD,,$(S)) + + C_CXX_FLAGS += -gfull -arch i386 -arch ppc + LFLAGS += -Wl,-dead_strip -arch i386 -arch ppc + + WX_CONFIGURE_FLAGS += --enable-universal_binary + WXCONFIG_CFLAGS += -gfull + WXCONFIG_CXXFLAGS += -gfull + + else + + WX_CONFIGURE_FLAGS += --disable-universal_binary + + endif + +endif + + +#------ FreeBSD configuration ------ + +ifeq "$(shell uname -s)" "FreeBSD" + + PLATFORM := FreeBSD + PLATFORM_UNSUPPORTED := 1 + C_CXX_FLAGS += -DTC_UNIX -DTC_BSD -DTC_FREEBSD + +endif + + +#------ Solaris configuration ------ + +ifeq "$(shell uname -s)" "SunOS" + + PLATFORM := Solaris + PLATFORM_UNSUPPORTED := 1 + C_CXX_FLAGS += -DTC_UNIX -DTC_SOLARIS + WX_CONFIGURE_FLAGS += --with-gtk + +endif + + +#------ Common configuration ------ + +CFLAGS := $(C_CXX_FLAGS) $(CFLAGS) $(TC_EXTRA_CFLAGS) +CXXFLAGS := $(C_CXX_FLAGS) $(CXXFLAGS) $(TC_EXTRA_CXXFLAGS) +ASFLAGS += -f $(ASM_OBJ_FORMAT) +LFLAGS := $(LFLAGS) $(TC_EXTRA_LFLAGS) + +WX_CONFIGURE_FLAGS += --enable-unicode -disable-shared --disable-dependency-tracking --disable-compat26 --enable-exceptions --enable-std_string --enable-dataobj --enable-mimetype \ + --disable-protocol --disable-protocols --disable-url --disable-ipc --disable-sockets --disable-fs_inet --disable-ole --disable-docview --disable-clipboard \ + --disable-help --disable-html --disable-mshtmlhelp --disable-htmlhelp --disable-mdi --disable-metafile --disable-webkit \ + --disable-xrc --disable-aui --disable-postscript --disable-printarch \ + --disable-arcstream --disable-fs_archive --disable-fs_zip --disable-tarstream --disable-zipstream \ + --disable-animatectrl --disable-bmpcombobox --disable-calendar --disable-caret --disable-checklst --disable-collpane --disable-colourpicker --disable-comboctrl \ + --disable-datepick --disable-display --disable-dirpicker --disable-filepicker --disable-fontpicker --disable-grid --disable-dataviewctrl \ + --disable-listbook --disable-odcombobox --disable-sash --disable-searchctrl --disable-slider --disable-splitter --disable-togglebtn \ + --disable-toolbar --disable-tbarnative --disable-treebook --disable-toolbook --disable-tipwindow --disable-popupwin \ + --disable-commondlg --disable-aboutdlg --disable-coldlg --disable-finddlg --disable-fontdlg --disable-numberdlg --disable-splash \ + --disable-tipdlg --disable-progressdlg --disable-wizarddlg --disable-miniframe --disable-tooltips --disable-splines --disable-palette \ + --disable-richtext --disable-dialupman --disable-debugreport --disable-filesystem \ + --disable-graphics_ctx --disable-sound --disable-mediactrl --disable-joystick --disable-apple_ieee \ + --disable-gif --disable-pcx --disable-tga --disable-iff --disable-gif --disable-pnm \ + --without-expat --without-libtiff --without-libjpeg --without-libpng -without-regex --without-zlib + + +#------ Project build ------ + +PROJ_DIRS := Platform Volume Driver/Fuse Core Main + +.PHONY: all clean wxbuild + +all clean: + @if pwd | grep -q ' '; then echo 'Error: source code is stored in a path containing spaces' >&2; exit 1; fi + + @for DIR in $(PROJ_DIRS); do \ + PROJ=$$(echo $$DIR | cut -d/ -f1); \ + $(MAKE) -C $$DIR -f $$PROJ.make NAME=$$PROJ $(MAKECMDGOALS) || exit $?; \ + export LIBS="$(BASE_DIR)/$$DIR/$$PROJ.a $$LIBS"; \ + done + + +#------ wxWidgets build ------ + +ifeq "$(MAKECMDGOALS)" "wxbuild" +CFLAGS := +CXXFLAGS := +LFLAGS := +endif + +wxbuild: + +ifneq "$(shell test -f $(WX_ROOT)/configure || test -f $(WX_BUILD_DIR)/../configure && echo 1)" "1" + @echo 'Error: WX_ROOT must point to wxWidgets source code directory' >&2 + @exit 1 +endif + + rm -rf "$(WX_BUILD_DIR)" + mkdir -p "$(WX_BUILD_DIR)" + @echo Configuring wxWidgets library... + cd "$(WX_BUILD_DIR)" && "$(WX_ROOT)/configure" $(WX_CONFIGURE_FLAGS) >/dev/null + + @echo Building wxWidgets library... + cd "$(WX_BUILD_DIR)" && $(MAKE) diff --git a/src/Platform/Unix/Directory.cpp b/src/Platform/Unix/Directory.cpp new file mode 100644 index 00000000..0a0088a2 --- /dev/null +++ b/src/Platform/Unix/Directory.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include "System.h" +#include "Platform/Directory.h" +#include "Platform/Finally.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + static Mutex ReadDirMutex; // readdir_r() may be unsafe on some systems + + void Directory::Create (const DirectoryPath &path) + { + string p = path; + throw_sys_sub_if (mkdir (p.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) == -1, p); + } + + DirectoryPath Directory::AppendSeparator (const DirectoryPath &path) + { + wstring p (path); + + if (p.find_last_of (L'/') + 1 != p.size()) + return p + L'/'; + + return p; + } + + FilePathList Directory::GetFilePaths (const DirectoryPath &path, bool regularFilesOnly) + { + DIR *dir = opendir (string (path).c_str()); + throw_sys_sub_if (!dir, wstring (path)); + finally_do_arg (DIR*, dir, { closedir (finally_arg); }); + + ScopeLock lock (ReadDirMutex); + + FilePathList files; + struct dirent *dirEntry; + errno = 0; + while ((dirEntry = readdir (dir)) != nullptr) + { + shared_ptr filePath (new FilePath (string (AppendSeparator (path)) + string (dirEntry->d_name))); + + if (!regularFilesOnly || filePath->IsFile()) + files.push_back (filePath); + + errno = 0; + } + + throw_sys_sub_if (errno != 0, wstring (path)); + return files; + } +} diff --git a/src/Platform/Unix/File.cpp b/src/Platform/Unix/File.cpp new file mode 100644 index 00000000..d69cb1df --- /dev/null +++ b/src/Platform/Unix/File.cpp @@ -0,0 +1,348 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include + +#ifdef TC_LINUX +#include +#endif + +#ifdef TC_BSD +#include +#endif + +#ifdef TC_SOLARIS +#include +#include +#endif + +#include +#include +#include + +#include "Platform/File.h" +#include "Platform/TextReader.h" + +namespace TrueCrypt +{ +#if 0 +# define TC_TRACE_FILE_OPERATIONS + + static void TraceFileOperation (int fileHandle, FilePath filePath, bool write, uint64 length, int64 position = -1) + { + string path = filePath; + if (path.empty() || path.find ("truecrypt_aux_mnt") != string::npos) + return; + + stringstream s; + s << path << ": " << (write ? "W " : "R ") << (position == -1 ? lseek (fileHandle, 0, SEEK_CUR) : position) << " (" << length << ")"; + SystemLog::WriteError (s.str()); + } +#endif + + void File::Close () + { + if_debug (ValidateState()); + + if (!SharedHandle) + { + close (FileHandle); + FileIsOpen = false; + + if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile()) + { + struct utimbuf u; + u.actime = AccTime; + u.modtime = ModTime; + + try + { + throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path)); + } + catch (...) // Suppress errors to allow using read-only files + { +#ifdef DEBUG + throw; +#endif + } + } + } + } + + void File::Delete () + { + Close(); + Path.Delete(); + } + + + void File::Flush () const + { + if_debug (ValidateState()); + throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path)); + } + + uint32 File::GetDeviceSectorSize () const + { + if (Path.IsDevice()) + { +#ifdef TC_LINUX + int blockSize; + throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path)); + return blockSize; + +#elif defined (TC_MACOSX) + uint32 blockSize; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); + return blockSize; + +#elif defined (TC_FREEBSD) + u_int sectorSize; + throw_sys_sub_if (ioctl (FileHandle, DIOCGSECTORSIZE, §orSize) == -1, wstring (Path)); + return (uint32) sectorSize; + +#elif defined (TC_SOLARIS) + struct dk_minfo mediaInfo; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGMEDIAINFO, &mediaInfo) == -1, wstring (Path)); + return mediaInfo.dki_lbsize; + +#else +# error GetDeviceSectorSize() +#endif + } + else + throw ParameterIncorrect (SRC_POS); + } + + uint64 File::GetPartitionDeviceStartOffset () const + { +#ifdef TC_LINUX + + // HDIO_GETGEO ioctl is limited by the size of long + TextReader tr ("/sys/block/" + string (Path.ToHostDriveOfPartition().ToBaseName()) + "/" + string (Path.ToBaseName()) + "/start"); + + string line; + tr.ReadLine (line); + return StringConverter::ToUInt64 (line) * GetDeviceSectorSize(); + +#elif defined (TC_MACOSX) + +#ifndef DKIOCGETBASE +# define DKIOCGETBASE _IOR('d', 73, uint64) +#endif + uint64 offset; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBASE, &offset) == -1, wstring (Path)); + return offset; + +#elif defined (TC_SOLARIS) + + struct extpart_info partInfo; + throw_sys_sub_if (ioctl (FileHandle, DKIOCEXTPARTINFO, &partInfo) == -1, wstring (Path)); + return partInfo.p_start * GetDeviceSectorSize(); + +#else + throw NotImplemented (SRC_POS); +#endif + } + + uint64 File::Length () const + { + if_debug (ValidateState()); + + // BSD does not support seeking to the end of a device +#ifdef TC_BSD + if (Path.IsBlockDevice() || Path.IsCharacterDevice()) + { +# ifdef TC_MACOSX + uint32 blockSize; + uint64 blockCount; + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path)); + throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path)); + return blockCount * blockSize; +# else + uint64 mediaSize; + throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path)); + return mediaSize; +# endif + } +#endif + off_t current = lseek (FileHandle, 0, SEEK_CUR); + throw_sys_sub_if (current == -1, wstring (Path)); + SeekEnd (0); + uint64 length = lseek (FileHandle, 0, SEEK_CUR); + SeekAt (current); + return length; + } + + void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags) + { +#ifdef TC_LINUX + int sysFlags = O_LARGEFILE; +#else + int sysFlags = 0; +#endif + + switch (mode) + { + case CreateReadWrite: + sysFlags |= O_CREAT | O_TRUNC | O_RDWR; + break; + + case CreateWrite: + sysFlags |= O_CREAT | O_TRUNC | O_WRONLY; + break; + + case OpenRead: + sysFlags |= O_RDONLY; + break; + + case OpenWrite: + sysFlags |= O_WRONLY; + break; + + case OpenReadWrite: + sysFlags |= O_RDWR; + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + if ((flags & File::PreserveTimestamps) && path.IsFile()) + { + struct stat statData; + throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path)); + AccTime = statData.st_atime; + ModTime = statData.st_mtime; + } + + FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR); + throw_sys_sub_if (FileHandle == -1, wstring (path)); + +#if 0 // File locking is disabled to avoid remote filesystem locking issues + try + { + struct flock fl; + memset (&fl, 0, sizeof (fl)); + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + + switch (shareMode) + { + case ShareNone: + fl.l_type = F_WRLCK; + if (fcntl (FileHandle, F_SETLK, &fl) == -1) + throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path)); + break; + + case ShareRead: + fl.l_type = F_RDLCK; + if (fcntl (FileHandle, F_SETLK, &fl) == -1) + throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path)); + break; + + case ShareReadWrite: + fl.l_type = (mode == OpenRead ? F_RDLCK : F_WRLCK); + if (fcntl (FileHandle, F_GETLK, &fl) != -1 && fl.l_type != F_UNLCK) + { + errno = EAGAIN; + throw SystemException (SRC_POS, wstring (path)); + } + break; + + case ShareReadWriteIgnoreLock: + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + } + catch (...) + { + close (FileHandle); + throw; + } +#endif // 0 + + Path = path; + mFileOpenFlags = flags; + FileIsOpen = true; + } + + uint64 File::Read (const BufferPtr &buffer) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, false, buffer.Size()); +#endif + ssize_t bytesRead = read (FileHandle, buffer, buffer.Size()); + throw_sys_sub_if (bytesRead == -1, wstring (Path)); + + return bytesRead; + } + + uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, false, buffer.Size(), position); +#endif + ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position); + throw_sys_sub_if (bytesRead == -1, wstring (Path)); + + return bytesRead; + } + + void File::SeekAt (uint64 position) const + { + if_debug (ValidateState()); + throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path)); + } + + void File::SeekEnd (int offset) const + { + if_debug (ValidateState()); + + // BSD does not support seeking to the end of a device +#ifdef TC_BSD + if (Path.IsBlockDevice() || Path.IsCharacterDevice()) + { + SeekAt (Length() + offset); + return; + } +#endif + + throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path)); + } + + void File::Write (const ConstBufferPtr &buffer) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, true, buffer.Size()); +#endif + throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != (ssize_t) buffer.Size(), wstring (Path)); + } + + void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const + { + if_debug (ValidateState()); + +#ifdef TC_TRACE_FILE_OPERATIONS + TraceFileOperation (FileHandle, Path, true, buffer.Size(), position); +#endif + throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != (ssize_t) buffer.Size(), wstring (Path)); + } +} diff --git a/src/Platform/Unix/FilesystemPath.cpp b/src/Platform/Unix/FilesystemPath.cpp new file mode 100644 index 00000000..ef52fe8a --- /dev/null +++ b/src/Platform/Unix/FilesystemPath.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/FilesystemPath.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" +#include +#include + +namespace TrueCrypt +{ + void FilesystemPath::Delete () const + { + throw_sys_sub_if (remove (string (*this).c_str()) == -1, Path); + } + + UserId FilesystemPath::GetOwner () const + { + struct stat statData; + throw_sys_if (stat (StringConverter::ToSingle (Path).c_str(), &statData) == -1); + + UserId owner; + owner.SystemId = statData.st_uid; + return owner; + } + + FilesystemPathType::Enum FilesystemPath::GetType () const + { + // Strip trailing directory separator + wstring path = Path; + size_t pos = path.find_last_not_of (L'/'); + if (path.size() > 2 && pos != path.size() - 1) + path = path.substr (0, pos + 1); + + struct stat statData; + throw_sys_sub_if (stat (StringConverter::ToSingle (path).c_str(), &statData) != 0, Path); + + if (S_ISREG (statData.st_mode)) return FilesystemPathType::File; + if (S_ISDIR (statData.st_mode)) return FilesystemPathType::Directory; + if (S_ISCHR (statData.st_mode)) return FilesystemPathType::CharacterDevice; + if (S_ISBLK (statData.st_mode)) return FilesystemPathType::BlockDevice; + if (S_ISLNK (statData.st_mode)) return FilesystemPathType::SymbolickLink; + + return FilesystemPathType::Unknown; + } + + FilesystemPath FilesystemPath::ToBaseName () const + { + wstring path = Path; + size_t pos = path.find_last_of (L'/'); + + if (pos == string::npos) + return Path; + + return Path.substr (pos + 1); + } + + FilesystemPath FilesystemPath::ToHostDriveOfPartition () const + { + DevicePath path; + +#ifdef TC_LINUX + + path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)); + +#elif defined (TC_MACOSX) + + string pathStr = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)); + path = pathStr.substr (0, pathStr.size() - 1); + +#elif defined (TC_FREEBSD) + + string pathStr = StringConverter::ToSingle (Path); + size_t p = pathStr.rfind ("s"); + if (p == string::npos) + throw PartitionDeviceRequired (SRC_POS); + path = pathStr.substr (0, p); + +#elif defined (TC_SOLARIS) + + path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path)) + "0"; + +#else + throw NotImplemented (SRC_POS); +#endif + if (!path.IsDevice()) + throw PartitionDeviceRequired (SRC_POS); + + return path; + } +} diff --git a/src/Platform/Unix/Mutex.cpp b/src/Platform/Unix/Mutex.cpp new file mode 100644 index 00000000..aae5d78d --- /dev/null +++ b/src/Platform/Unix/Mutex.cpp @@ -0,0 +1,62 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Platform/Mutex.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Mutex::Mutex () + { + pthread_mutexattr_t attributes; + + int status = pthread_mutexattr_init (&attributes); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_mutex_init (&SystemMutex, &attributes); + if (status != 0) + throw SystemException (SRC_POS, status); + + Initialized = true; + } + + Mutex::~Mutex () + { + Initialized = false; +#ifdef DEBUG + int status = +#endif + pthread_mutex_destroy (&SystemMutex); + +#ifdef DEBUG + if (status != 0) + SystemLog::WriteException (SystemException (SRC_POS, status)); +#endif + } + + void Mutex::Lock () + { + assert (Initialized); + int status = pthread_mutex_lock (&SystemMutex); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Mutex::Unlock () + { + int status = pthread_mutex_unlock (&SystemMutex); + if (status != 0) + throw SystemException (SRC_POS, status); + } +} diff --git a/src/Platform/Unix/Pipe.cpp b/src/Platform/Unix/Pipe.cpp new file mode 100644 index 00000000..d3465408 --- /dev/null +++ b/src/Platform/Unix/Pipe.cpp @@ -0,0 +1,65 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Pipe.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Pipe::Pipe () + { + int fd[2]; + throw_sys_if (pipe (fd) == -1); + ReadFileDescriptor = fd[0]; + WriteFileDescriptor = fd[1]; + } + + Pipe::~Pipe () + { + try + { + Close(); + } + catch (...) { } + } + + void Pipe::Close () + { + if (ReadFileDescriptor != -1) + close (ReadFileDescriptor); + if (WriteFileDescriptor != -1) + close (WriteFileDescriptor); + } + + int Pipe::GetReadFD () + { + assert (ReadFileDescriptor != -1); + + if (WriteFileDescriptor != -1) + { + close (WriteFileDescriptor); + WriteFileDescriptor = -1; + } + + return ReadFileDescriptor; + } + + int Pipe::GetWriteFD () + { + assert (WriteFileDescriptor != -1); + + if (ReadFileDescriptor != -1) + { + close (ReadFileDescriptor); + ReadFileDescriptor = -1; + } + + return WriteFileDescriptor; + } +} diff --git a/src/Platform/Unix/Pipe.h b/src/Platform/Unix/Pipe.h new file mode 100644 index 00000000..9aa5bf9e --- /dev/null +++ b/src/Platform/Unix/Pipe.h @@ -0,0 +1,38 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Pipe +#define TC_HEADER_Platform_Unix_Pipe + +#include "Platform/PlatformBase.h" + +namespace TrueCrypt +{ + class Pipe + { + public: + Pipe (); + virtual ~Pipe (); + + void Close (); + int GetReadFD (); + int GetWriteFD (); + int PeekReadFD () const { return ReadFileDescriptor; } + int PeekWriteFD () const { return WriteFileDescriptor; } + + protected: + int ReadFileDescriptor; + int WriteFileDescriptor; + + private: + Pipe (const Pipe &); + Pipe &operator= (const Pipe &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Pipe diff --git a/src/Platform/Unix/Poller.cpp b/src/Platform/Unix/Poller.cpp new file mode 100644 index 00000000..3950eab0 --- /dev/null +++ b/src/Platform/Unix/Poller.cpp @@ -0,0 +1,57 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Poller.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + Poller::Poller (int fileDescriptor1, int fileDescriptor2, int fileDescriptor3, int fileDescriptor4) + { + FileDescriptors.push_back (fileDescriptor1); + + if (fileDescriptor2 != -1) + FileDescriptors.push_back (fileDescriptor2); + + if (fileDescriptor3 != -1) + FileDescriptors.push_back (fileDescriptor3); + + if (fileDescriptor4 != -1) + FileDescriptors.push_back (fileDescriptor4); + } + + list Poller::WaitForData (int timeOut) const + { + vector pfd (FileDescriptors.size()); + for (size_t i = 0; i < FileDescriptors.size(); i++) + { + pfd[i].fd = FileDescriptors[i]; + pfd[i].events = POLLIN; + } + + list descList; + + int pollRes = poll (&pfd[0], pfd.size(), timeOut); + + if (pollRes == 0 && timeOut != -1) + throw TimeOut (SRC_POS); + + if (pollRes > 0) + { + for (size_t i = 0; i < pfd.size(); i++) + { + if (pfd[i].revents & POLLIN) + descList.push_back (pfd[i].fd); + } + } + + return descList; + } +} diff --git a/src/Platform/Unix/Poller.h b/src/Platform/Unix/Poller.h new file mode 100644 index 00000000..131e469f --- /dev/null +++ b/src/Platform/Unix/Poller.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Poller +#define TC_HEADER_Platform_Unix_Poller + +#include "Platform/PlatformBase.h" + +namespace TrueCrypt +{ + class Poller + { + public: + Poller (int fileDescriptor1, int fileDescriptor2 = -1, int fileDescriptor3 = -1, int fileDescriptor4 = -1); + virtual ~Poller () { } + + list WaitForData (int timeOut = -1) const; + + protected: + vector FileDescriptors; + + private: + Poller (const Poller &); + Poller &operator= (const Poller &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Poller diff --git a/src/Platform/Unix/Process.cpp b/src/Platform/Unix/Process.cpp new file mode 100644 index 00000000..d99dff87 --- /dev/null +++ b/src/Platform/Unix/Process.cpp @@ -0,0 +1,202 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include +#include +#include "Process.h" +#include "Platform/Exception.h" +#include "Platform/FileStream.h" +#include "Platform/ForEach.h" +#include "Platform/MemoryStream.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" +#include "Platform/Unix/Pipe.h" +#include "Platform/Unix/Poller.h" + +namespace TrueCrypt +{ + string Process::Execute (const string &processName, const list &arguments, int timeOut, ProcessExecFunctor *execFunctor, const Buffer *inputData) + { + char *args[32]; + if (array_capacity (args) <= arguments.size()) + throw ParameterTooLarge (SRC_POS); + +#if 0 + stringstream dbg; + dbg << "exec " << processName; + foreach (const string &at, arguments) + dbg << " " << at; + trace_msg (dbg.str()); +#endif + + Pipe inPipe, outPipe, errPipe, exceptionPipe; + + int forkedPid = fork(); + throw_sys_if (forkedPid == -1); + + if (forkedPid == 0) + { + try + { + try + { + int argIndex = 0; + if (!execFunctor) + args[argIndex++] = const_cast (processName.c_str()); + + foreach (const string &arg, arguments) + { + args[argIndex++] = const_cast (arg.c_str()); + } + args[argIndex] = nullptr; + + if (inputData) + { + throw_sys_if (dup2 (inPipe.GetReadFD(), STDIN_FILENO) == -1); + } + else + { + inPipe.Close(); + int nullDev = open ("/dev/null", 0); + throw_sys_sub_if (nullDev == -1, "/dev/null"); + throw_sys_if (dup2 (nullDev, STDIN_FILENO) == -1); + } + + throw_sys_if (dup2 (outPipe.GetWriteFD(), STDOUT_FILENO) == -1); + throw_sys_if (dup2 (errPipe.GetWriteFD(), STDERR_FILENO) == -1); + exceptionPipe.GetWriteFD(); + + if (execFunctor) + { + (*execFunctor)(argIndex, args); + } + else + { + execvp (args[0], args); + throw SystemException (SRC_POS, args[0]); + } + } + catch (Exception &) + { + throw; + } + catch (exception &e) + { + throw ExternalException (SRC_POS, StringConverter::ToExceptionString (e)); + } + catch (...) + { + throw UnknownException (SRC_POS); + } + } + catch (Exception &e) + { + try + { + shared_ptr outputStream (new FileStream (exceptionPipe.GetWriteFD())); + e.Serialize (outputStream); + } + catch (...) { } + } + + _exit (1); + } + + throw_sys_if (fcntl (outPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + throw_sys_if (fcntl (errPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + throw_sys_if (fcntl (exceptionPipe.GetReadFD(), F_SETFL, O_NONBLOCK) == -1); + + vector buffer (4096), stdOutput (4096), errOutput (4096), exOutput (4096); + buffer.clear (); + stdOutput.clear (); + errOutput.clear (); + exOutput.clear (); + + Poller poller (outPipe.GetReadFD(), errPipe.GetReadFD(), exceptionPipe.GetReadFD()); + int status, waitRes; + + if (inputData) + throw_sys_if (write (inPipe.GetWriteFD(), inputData->Ptr(), inputData->Size()) == -1 && errno != EPIPE); + + inPipe.Close(); + + int timeTaken = 0; + do + { + const int pollTimeout = 200; + try + { + ssize_t bytesRead = 0; + foreach (int fd, poller.WaitForData (pollTimeout)) + { + bytesRead = read (fd, &buffer[0], buffer.capacity()); + if (bytesRead > 0) + { + if (fd == outPipe.GetReadFD()) + stdOutput.insert (stdOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + else if (fd == errPipe.GetReadFD()) + errOutput.insert (errOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + else if (fd == exceptionPipe.GetReadFD()) + exOutput.insert (exOutput.end(), buffer.begin(), buffer.begin() + bytesRead); + } + } + + if (bytesRead == 0) + { + waitRes = waitpid (forkedPid, &status, 0); + break; + } + } + catch (TimeOut&) + { + timeTaken += pollTimeout; + if (timeOut >= 0 && timeTaken >= timeOut) + throw; + } + } while ((waitRes = waitpid (forkedPid, &status, WNOHANG)) == 0); + throw_sys_if (waitRes == -1); + + if (!exOutput.empty()) + { + auto_ptr deserializedObject; + Exception *deserializedException = nullptr; + + try + { + shared_ptr stream (new MemoryStream (ConstBufferPtr ((byte *) &exOutput[0], exOutput.size()))); + deserializedObject.reset (Serializable::DeserializeNew (stream)); + deserializedException = dynamic_cast (deserializedObject.get()); + } + catch (...) { } + + if (deserializedException) + deserializedException->Throw(); + } + + int exitCode = (WIFEXITED (status) ? WEXITSTATUS (status) : 1); + if (exitCode != 0) + { + string strErrOutput; + + if (!errOutput.empty()) + strErrOutput.insert (strErrOutput.begin(), errOutput.begin(), errOutput.end()); + + throw ExecutedProcessFailed (SRC_POS, processName, exitCode, strErrOutput); + } + + string strOutput; + + if (!stdOutput.empty()) + strOutput.insert (strOutput.begin(), stdOutput.begin(), stdOutput.end()); + + return strOutput; + } +} diff --git a/src/Platform/Unix/Process.h b/src/Platform/Unix/Process.h new file mode 100644 index 00000000..dd878ddd --- /dev/null +++ b/src/Platform/Unix/Process.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_Process +#define TC_HEADER_Platform_Unix_Process + +#include "Platform/PlatformBase.h" +#include "Platform/Buffer.h" +#include "Platform/Functor.h" + +namespace TrueCrypt +{ + struct ProcessExecFunctor + { + virtual ~ProcessExecFunctor () { } + virtual void operator() (int argc, char *argv[]) = 0; + }; + + class Process + { + public: + Process (); + virtual ~Process (); + + static string Execute (const string &processName, const list &arguments, int timeOut = -1, ProcessExecFunctor *execFunctor = nullptr, const Buffer *inputData = nullptr); + + protected: + + private: + Process (const Process &); + Process &operator= (const Process &); + }; +} + +#endif // TC_HEADER_Platform_Unix_Process diff --git a/src/Platform/Unix/SyncEvent.cpp b/src/Platform/Unix/SyncEvent.cpp new file mode 100644 index 00000000..fbf8300f --- /dev/null +++ b/src/Platform/Unix/SyncEvent.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Exception.h" +#include "Platform/SyncEvent.h" +#include "Platform/SystemException.h" + +namespace TrueCrypt +{ + SyncEvent::SyncEvent () + { + int status = pthread_cond_init (&SystemSyncEvent, nullptr); + if (status != 0) + throw SystemException (SRC_POS, status); + + Signaled = false; + Initialized = true; + } + + SyncEvent::~SyncEvent () + { +#ifdef DEBUG + int status = +#endif + pthread_cond_destroy (&SystemSyncEvent); + +#ifdef DEBUG + if (status != 0) + SystemLog::WriteException (SystemException (SRC_POS, status)); +#endif + + Initialized = false; + } + + void SyncEvent::Signal () + { + assert (Initialized); + + ScopeLock lock (EventMutex); + + Signaled = true; + + int status = pthread_cond_signal (&SystemSyncEvent); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void SyncEvent::Wait () + { + assert (Initialized); + + ScopeLock lock (EventMutex); + + while (!Signaled) + { + int status = pthread_cond_wait (&SystemSyncEvent, EventMutex.GetSystemHandle()); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + Signaled = false; + } +} diff --git a/src/Platform/Unix/System.h b/src/Platform/Unix/System.h new file mode 100644 index 00000000..63d565b5 --- /dev/null +++ b/src/Platform/Unix/System.h @@ -0,0 +1,12 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Platform_Unix_System +#define TC_HEADER_Platform_Unix_System + +#endif // TC_HEADER_Platform_Unix_System diff --git a/src/Platform/Unix/SystemException.cpp b/src/Platform/Unix/SystemException.cpp new file mode 100644 index 00000000..b29c9b50 --- /dev/null +++ b/src/Platform/Unix/SystemException.cpp @@ -0,0 +1,66 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Platform/SerializerFactory.h" +#include "Platform/SystemException.h" +#include "Platform/StringConverter.h" + +namespace TrueCrypt +{ + SystemException::SystemException () + : ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message) + : Exception (message), ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message, const string &subject) + : Exception (message, StringConverter::ToWide (subject)), ErrorCode (errno) + { + } + + SystemException::SystemException (const string &message, const wstring &subject) + : Exception (message, subject), ErrorCode (errno) + { + } + + void SystemException::Deserialize (shared_ptr stream) + { + Exception::Deserialize (stream); + Serializer sr (stream); + sr.Deserialize ("ErrorCode", ErrorCode); + } + + bool SystemException::IsError () const + { + return ErrorCode != 0; + } + + void SystemException::Serialize (shared_ptr stream) const + { + Exception::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("ErrorCode", ErrorCode); + } + + wstring SystemException::SystemText () const + { + return StringConverter::ToWide (strerror ((int) ErrorCode)); + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SystemException); +} diff --git a/src/Platform/Unix/SystemInfo.cpp b/src/Platform/Unix/SystemInfo.cpp new file mode 100644 index 00000000..d0ea6e61 --- /dev/null +++ b/src/Platform/Unix/SystemInfo.cpp @@ -0,0 +1,69 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/SystemException.h" +#include "Platform/SystemInfo.h" +#include + +namespace TrueCrypt +{ + wstring SystemInfo::GetPlatformName () + { +#ifdef TC_LINUX + return L"Linux"; +#elif defined (TC_MACOSX) + return L"Mac OS X"; +#elif defined (TC_FREEBSD) + return L"FreeBSD"; +#elif defined (TC_SOLARIS) + return L"Solaris"; +#else +# error GetPlatformName() undefined +#endif + + } + + vector SystemInfo::GetVersion () + { + struct utsname unameData; + throw_sys_if (uname (&unameData) == -1); + + vector versionStrings = StringConverter::Split (unameData.release, "."); + vector version; + + for (size_t i = 0; i < versionStrings.size(); ++i) + { + string s = versionStrings[i]; + + size_t p = s.find_first_not_of ("0123456789"); + if (p != string::npos) + s = s.substr (0, p); + + if (s.empty()) + break; + + version.push_back (StringConverter::ToUInt32 (s)); + } + + return version; + } + + bool SystemInfo::IsVersionAtLeast (int versionNumber1, int versionNumber2, int versionNumber3) + { + vector osVersionNumbers = GetVersion(); + + if (osVersionNumbers.size() < 2) + throw ParameterIncorrect (SRC_POS); + + if (osVersionNumbers.size() < 3) + osVersionNumbers[2] = 0; + + return (osVersionNumbers[0] * 10000000 + osVersionNumbers[1] * 10000 + osVersionNumbers[2]) >= + (versionNumber1 * 10000000 + versionNumber2 * 10000 + versionNumber3); + } +} diff --git a/src/Platform/Unix/SystemLog.cpp b/src/Platform/Unix/SystemLog.cpp new file mode 100644 index 00000000..eea94e0c --- /dev/null +++ b/src/Platform/Unix/SystemLog.cpp @@ -0,0 +1,27 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Platform/SystemLog.h" + +namespace TrueCrypt +{ + void SystemLog::WriteDebug (const string &debugMessage) + { + openlog ("truecrypt", LOG_PID, LOG_USER); + syslog (LOG_DEBUG, "%s", debugMessage.c_str()); + closelog(); + } + + void SystemLog::WriteError (const string &errorMessage) + { + openlog ("truecrypt", LOG_PID, LOG_USER); + syslog (LOG_ERR, "%s", errorMessage.c_str()); + closelog(); + } +} diff --git a/src/Platform/Unix/Thread.cpp b/src/Platform/Unix/Thread.cpp new file mode 100644 index 00000000..7afe6832 --- /dev/null +++ b/src/Platform/Unix/Thread.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include "Platform/SystemException.h" +#include "Platform/Thread.h" +#include "Platform/SystemLog.h" + +namespace TrueCrypt +{ + void Thread::Join () const + { + int status = pthread_join (SystemHandle, nullptr); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Thread::Start (ThreadProcPtr threadProc, void *parameter) + { + pthread_attr_t attr; + size_t stackSize = 0; + int status; + + status = pthread_attr_init (&attr); + if (status != 0) + throw SystemException (SRC_POS, status); + + status = pthread_attr_getstacksize (&attr, &stackSize); + if (status != 0) + throw SystemException (SRC_POS, status); + + if (stackSize < MinThreadStackSize) + { + status = pthread_attr_setstacksize (&attr, MinThreadStackSize); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + status = pthread_create (&SystemHandle, nullptr, threadProc, parameter); + if (status != 0) + throw SystemException (SRC_POS, status); + } + + void Thread::Sleep (uint32 milliSeconds) + { + ::usleep (milliSeconds * 1000); + } +} diff --git a/src/Platform/Unix/Time.cpp b/src/Platform/Unix/Time.cpp new file mode 100644 index 00000000..01313d53 --- /dev/null +++ b/src/Platform/Unix/Time.cpp @@ -0,0 +1,23 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Time.h" +#include +#include + +namespace TrueCrypt +{ + uint64 Time::GetCurrent () + { + struct timeval tv; + gettimeofday (&tv, NULL); + + // Unix time => Windows file time + return ((uint64) tv.tv_sec + 134774LL * 24 * 3600) * 1000LL * 1000 * 10; + } +} diff --git a/src/Resources/Icons/TrueCrypt-16x16.xpm b/src/Resources/Icons/TrueCrypt-16x16.xpm new file mode 100644 index 0000000000000000000000000000000000000000..c4b5664c6be8bd24c4a7dd82acad75ce7193471e GIT binary patch literal 4396 zcmYM%Ygg1d6b9h${E8^zWq{DMY106*%%xG`co0R6x=;bRBaAa3AaZ{DN%uRo;$=N# zXJ=<8EzZJ##n-RcU}0)}v3+s0%XZJt#use&aC^iCo1@D;H@X>KyiDH})wQTTZ?UKB zc4}de;!ZDroQ>J&{A%3de3br4v&Qqoz0v&e=z8z8&3a!{Ed9<4!SefaQ}-ETyKLul zd-tRjZ#A9eS&_-s5iYYTt6QJLRi;GNdL34o7Dek>*ko2v_Ghrqf>7=FbU&_JKY(4< zh|qe5EHWVkt@jYlMIk7D01F{S)5brAr6`4IJr8SPgm1kBJK+$&*xAD?a3j)J8$Uk z>8q`08#cKusGnn4<-VkPzfZuq$Lm`#pf0LMiegxyTBwDBm$$OQGm|PGBc< zjGuNEiuU)LEDLEB)q9QcvIsTh--TW}M9^?vH+YfaCK>E;_l>%Z+y_tV2cT2r?51hUMf z)wG}Ia3-Cm{=DeyHLbS_S2Cc!HQ1)>NcH^#mt~H8uehBXcl-|<%U;A-7zi<6G&3{BLi_#k!-|8IT&u~>`hT?BwT`5E7aRhHte6h9!VENzdTho^9^yrKH$J2%L;1Pj$*y+v}`Z|>+k zR^Y0V@Eq(b>!_d0uuG=;1i2DbaJ1jNvv>476mV8~#LM1Pe+lPlK0SXGT&N8BRA=F6 ze>JR>baY<28!xb425VJey`OMUjiY{Cb>qs@{5{yJ%G3TwowcX^T>PEy=|0?$Q@_2V z^SHKy(Yxq|eKN;VFn_45^8M)Saa=(AT zqPD2-6`a+Lr}Ow1cDllO+HStYeR~fZU83I(4q7|f-zQjVf%OfXep(>^Ti9yl>HX#5 zT9=;s9bm01PtVu$KA!sf0&cWMKUZO&O#NAdovxAZpDx~F{nun&=+Mx8dkJeJ(eHPi zOT>SKy-}X-*Cycdw9?}Am7v8)USEiID!5x!7BZSk@~*~YnS7^ zS77f-+_yQ{xyk)lhU@eJfzDHO^C$W8&P7AdN72pCQJ;hxSHNXAUN%&3)s0t}ugI=& z>44gwuQgn|&`^IgTsj}<`N-gqK2Fei{)DZUf$sAa?0p{S{_l}};Z>mfJAzB^;fu~L z(D~oM>1hx2yj;T82joA3)6)@X{UIEhD$x0FlN;HnK=*6hSqHj5-(l4ljPJv`X)ynQ z9MZ=j_zKH|%9Ii`m@Uh;9gir-Q_j-5@`T4CdO5f@_>XH(2&{GDpP1J%F?~c-+ Rxs+i#{e8~vPu(p|{SR?Xeii@# literal 0 HcmV?d00001 diff --git a/src/Resources/Icons/TrueCrypt-48x48.xpm b/src/Resources/Icons/TrueCrypt-48x48.xpm new file mode 100644 index 0000000000000000000000000000000000000000..26837fbcc43fbc18d6477851bf69aa92bd2138bc GIT binary patch literal 8073 zcmai&Yg-dZ6NbO2;XC z**8zj&p#e_%+>Jl;@BJ?4L==UnA5@8$=Uf>myO?kJvx8;b$ESrBHP{%Q^Ws$7Mt$< zMOoR-l`&(?z&!BuKL+m`>*TH%S1R{Kj{VGQ5|z(%JPEQaRe4Kfzlr0zP@!`!x^GgE<0^|A7w=5R ziC*PoPvkPHqISP;B70u9N?m-ebbcD;Rjm6Rsoca-ovVDV^P?cnoPIJ7`vA1v??&X1 z-5R(4Qs;Xh;N}lS_Pwwy+x;YNMx@Hqry}9L}jm=B+lL+B4d5GcJj53=Ruvj zcu{|h=TT8Pd%wH&ei6IWTduA{X6qg7>D*52J4B z_Af;Cx`CHE`K8Edmgj9gmOAdC-|2hZ${?!xbCIJs&D!`r7dh!>d7Cel$eEWn?S74} z7kzI1s>r?{R)wqgry|!82)Ot@6FH6Zv|ZoR^^*UtKG$`98l{zs&$fSa#kvaZTDp8FzuMd;@)pWlewO=1{H@%$-rO*XglZ$(b?ylCV9OXM<~)Vo#w z4uhn0@w3X`Ra3Y2Smp1mED~q0RsIgLBx&a>f5V?~ruJCn@60ber_U;X7hc)&i=FVd z7ixZ3he{M{r?;rz8Ne^cIWz4ABN@6~R; z@^|8qK$<^R`J4Q$3pZc++mm|Me6-5n@L`#{^~&E-krpn0tnzn~V6NLw`P<7w{uex~ z@^@O~Wg8FWZ}=rC+_>X!sekQHR{1+hfA6pS?RkD2x&0k~$5B{nK3e5(@)rYDpYnGS zW@T%S@;BMg_9N@~yNDXsU#;?YoM%w1u2=rf6T<1@q5O^ib?Wd{{?>X|zO|0OrGIOE zS>gYtLn*ATewr~C~cfr!e=-&xH8$>F8^Eoij!mA}CwO1FKUw8(@bp55zw&pUmhE}RDu2uAu5$UU{9Qx; ztv$-$YQNL3{9V<*`AYd)?REK}{N2zl+V#rcG@nVnDSu;MkUM?K-+A+!uav*LRpPb& zDSwxFHHoM4H|-P3)_5v^!yjel;;sBG=ZW0O%HN!hCip0S7jZe+Px)KV7Y={rZ}>IJ z9RDbP6TdK0zV9o4N8L1b=bOIrxAL9VOJDh0_^s6SedX^o$YD&ex3Byihm-Sp-|=@- z5CR=n{#L%y{Oc=!(~jHoNniO}`APGsul%j{I{TErgKiSIeC`W>Z=RhVu{k#hy=08_ zmeKD_9y4zvGwiR}hPQ@i&dwpt*)?-$M*S5tw6&S%o5f!Y>R7{$ z*SfRpC^3q$sLyvDnXwI~`N3SeJvNe2<{O_wy5W@#IWs)9 z7v_z5W>4*oePz$=`~Cx4arQaFp98x=jF-SHA)<}lLd(un9lqc}48}y^+PtyzcGkxB zjs0%Fn+x;KuISra)3=Z0&F8bCvmikrgxVgM4T!TG>p%xS?MzNy*)(7 z7h?0sK4Iq%_QXE6PkDR9sp<#16Rdiuh!JITX5ZPhX?`%)fO*HhCJ%kQmQ2lve`;P> zpOFnt4lm3aeEq@xWxug|2G&=0iR#f@03YzMi}qlujsyH1;0rZG2CWc@SL`rm_hX_x zLSskbPCPub0PbX*jZJO`MD?fS9P182+3}j^QeyQVcnsKs>;;(xaFxs&61Q`D*%g?+A!=LbiOoOuTs%R~f)Tr} zm3^0CmGe7eb%4bKc89aEe#YELMw-9PNBh()5}iqPub78+lket0YC-Bl*a6>1tRM9s z!Y)(m9G>Omi)B)U8Ebv1U{~k%3bfnm=DxHfNQ0IS4 zKA4m|rem3oIR%4xvk%sn=A5oDCO>-g`-iNZ%2&*fsoVtYB09|ijCf=No*@>?8Rt1S z+Y4AdLBo4KR}8g8OkZIaJfxlox8K3L%oA?k1o?UV{Y*S&$@CQ>eg@*l=2nqDG|!1& z(l^BL7WR6nta89QIyCm(;?>k1MO@_uD7|%u9wl0Sl7~GQaf7$9$;~gi)f?AW1I_MbGtJKCSccL?Jl)k2H_t{#~Y zkd1rTF^6@x)APz4l0z}pBye|+PO-rgz(4Eo?EyYMhyT8tKk=mprwBWKAqV9=u_>I* zJN<*K+A{vMSb?;3%^Ktz{M{ld17a{DW8bmQ6&*#`{w@2@z+X50SI86s$kJ(91dm}tvM$4`uu>^Omqrc0k`!9HW3qMcE?AUA*(Iaz&9V1~mbj)Gh z9W^MCyJZusUI`oV(=TGJZ5{4X8gwaGc;k~j~k zjTNfQfO!nYJaDYz_V3)K$OiKco-9G{jL{=Ff^(u;M~|9bA6U;B5iItILTMvu_m&oV=8duqUo7oF^)MG981?jcq^K{Ht!DCfUfy(W|y94TCS&*jk(ze6yz{Y!e z&f37ARn6xkc!3)gYv=Id-1Mg96*-h>eSinn91-^uYI0c_{fT*O3$62y+(O1M$tNmh zn=D`N&w|{RR26va*e`e1$3C`PNe(je28{#oSwz!?ePsTIyApma{nvyVs~IA+4-VUS zGDEF?(aNO;!Rh=CPTVJ=SLoRz!?+(wwor+$>495BpB~9s>xf=8lv?H#bt`u*sd=7& z98a)m4h?tYu5c$0H)DKG;90pDa%SRb$TYc!x_eB+xZJ3PXXQR$!`FhP+~47nyD*oX zSVyOItHEDy-FP5c_+!NJyWRO66V0o`4{;rt>b``o)e+*QV63`+JS_%l_)m*iSqU_&4S67r&-HFt7Q| zhH;f;#tUYob{l){s6leVCl`0&hi!CS@^{aC=PC91&W_*Jg08ax9s0)3tyRpEuC+M* z3`cg1V1+Yc!!H1^9S?8%Dd!Xz>>Ergaw*^QDblula(ej6yPRPBJMV*%BlBSQj(KC5 ttu-Q&-0`RvSgFVNXP_ddT6y?YflvAK8C&Fc1o 0) + { + Decrypt (data); + data += GetBlockSize(); + } + } + + void Cipher::EncryptBlock (byte *data) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + + Encrypt (data); + } + + void Cipher::EncryptBlocks (byte *data, size_t blockCount) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + + while (blockCount-- > 0) + { + Encrypt (data); + data += GetBlockSize(); + } + } + + CipherList Cipher::GetAvailableCiphers () + { + CipherList l; + + l.push_back (shared_ptr (new CipherAES ())); + l.push_back (shared_ptr (new CipherSerpent ())); + l.push_back (shared_ptr (new CipherTwofish ())); + l.push_back (shared_ptr (new CipherBlowfish ())); + l.push_back (shared_ptr (new CipherCast5 ())); + l.push_back (shared_ptr (new CipherTripleDES ())); + + return l; + } + + void Cipher::SetKey (const ConstBufferPtr &key) + { + if (key.Size() != GetKeySize ()) + throw ParameterIncorrect (SRC_POS); + + if (!Initialized) + ScheduledKey.Allocate (GetScheduledKeySize ()); + + SetCipherKey (key); + Key.CopyFrom (key); + Initialized = true; + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (CipherException); + + + // AES + void CipherAES::Decrypt (byte *data) const + { +#ifdef TC_AES_HW_CPU + if (IsHwSupportAvailable()) + aes_hw_cpu_decrypt (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data); + else +#endif + aes_decrypt (data, data, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))); + } + + void CipherAES::DecryptBlocks (byte *data, size_t blockCount) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + +#ifdef TC_AES_HW_CPU + if ((blockCount & (32 - 1)) == 0 + && IsHwSupportAvailable()) + { + while (blockCount > 0) + { + aes_hw_cpu_decrypt_32_blocks (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data); + + data += 32 * GetBlockSize(); + blockCount -= 32; + } + } + else +#endif + Cipher::DecryptBlocks (data, blockCount); + } + + void CipherAES::Encrypt (byte *data) const + { +#ifdef TC_AES_HW_CPU + if (IsHwSupportAvailable()) + aes_hw_cpu_encrypt (ScheduledKey.Ptr(), data); + else +#endif + aes_encrypt (data, data, (aes_encrypt_ctx *) ScheduledKey.Ptr()); + } + + void CipherAES::EncryptBlocks (byte *data, size_t blockCount) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + +#ifdef TC_AES_HW_CPU + if ((blockCount & (32 - 1)) == 0 + && IsHwSupportAvailable()) + { + while (blockCount > 0) + { + aes_hw_cpu_encrypt_32_blocks (ScheduledKey.Ptr(), data); + + data += 32 * GetBlockSize(); + blockCount -= 32; + } + } + else +#endif + Cipher::EncryptBlocks (data, blockCount); + } + + size_t CipherAES::GetScheduledKeySize () const + { + return sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx); + } + + bool CipherAES::IsHwSupportAvailable () const + { +#ifdef TC_AES_HW_CPU + static bool state = false; + static bool stateValid = false; + + if (!stateValid) + { + state = is_aes_hw_cpu_supported() ? true : false; + stateValid = true; + } + return state && HwSupportEnabled; +#else + return false; +#endif + } + + void CipherAES::SetCipherKey (const byte *key) + { + if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ScheduledKey.Ptr()) != EXIT_SUCCESS) + throw CipherInitError (SRC_POS); + + if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS) + throw CipherInitError (SRC_POS); + } + + + // Blowfish + void CipherBlowfish::Decrypt (byte *data) const + { + BlowfishEncryptLE (data, data, (BF_KEY *) ScheduledKey.Ptr(), 0); + } + + void CipherBlowfish::Encrypt (byte *data) const + { + BlowfishEncryptLE (data, data, (BF_KEY *) ScheduledKey.Ptr(), 1); + } + + size_t CipherBlowfish::GetScheduledKeySize () const + { + return sizeof (BF_KEY); + } + + void CipherBlowfish::SetCipherKey (const byte *key) + { + BlowfishSetKey ((BF_KEY *) ScheduledKey.Ptr(), static_cast (GetKeySize ()), (unsigned char *) key); + } + + + // CAST5 + void CipherCast5::Decrypt (byte *data) const + { + Cast5Decrypt (data, data, (CAST_KEY *) ScheduledKey.Ptr()); + } + + void CipherCast5::Encrypt (byte *data) const + { + Cast5Encrypt (data, data, (CAST_KEY *) ScheduledKey.Ptr()); + } + + size_t CipherCast5::GetScheduledKeySize () const + { + return sizeof (CAST_KEY); + } + + void CipherCast5::SetCipherKey (const byte *key) + { + Cast5SetKey ((CAST_KEY *) ScheduledKey.Ptr(), static_cast (GetKeySize ()), (unsigned char *) key); + } + + + // Serpent + void CipherSerpent::Decrypt (byte *data) const + { + serpent_decrypt (data, data, ScheduledKey); + } + + void CipherSerpent::Encrypt (byte *data) const + { + serpent_encrypt (data, data, ScheduledKey); + } + + size_t CipherSerpent::GetScheduledKeySize () const + { + return 140*4; + } + + void CipherSerpent::SetCipherKey (const byte *key) + { + serpent_set_key (key, static_cast (GetKeySize ()), ScheduledKey); + } + + + // Triple-DES + void CipherTripleDES::Decrypt (byte *data) const + { + TripleDesEncrypt (data, data, (TDES_KEY *) ScheduledKey.Ptr(), 0); + } + + void CipherTripleDES::Encrypt (byte *data) const + { + TripleDesEncrypt (data, data, (TDES_KEY *) ScheduledKey.Ptr(), 1); + } + + size_t CipherTripleDES::GetScheduledKeySize () const + { + return sizeof (TDES_KEY); + } + + void CipherTripleDES::SetCipherKey (const byte *key) + { + TripleDesSetKey (key, GetKeySize(), (TDES_KEY *) ScheduledKey.Ptr()); + } + + + // Twofish + void CipherTwofish::Decrypt (byte *data) const + { + twofish_decrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data); + } + + void CipherTwofish::Encrypt (byte *data) const + { + twofish_encrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data); + } + + size_t CipherTwofish::GetScheduledKeySize () const + { + return TWOFISH_KS; + } + + void CipherTwofish::SetCipherKey (const byte *key) + { + twofish_set_key ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *) key, static_cast (GetKeySize ()) * 8); + } + + + bool Cipher::HwSupportEnabled = true; +} diff --git a/src/Volume/Cipher.h b/src/Volume/Cipher.h new file mode 100644 index 00000000..25fc82c9 --- /dev/null +++ b/src/Volume/Cipher.h @@ -0,0 +1,129 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Ciphers +#define TC_HEADER_Encryption_Ciphers + +#include "Platform/Platform.h" + + +namespace TrueCrypt +{ + class Cipher; + typedef vector < shared_ptr > CipherList; + + class Cipher + { + public: + virtual ~Cipher (); + + virtual void DecryptBlock (byte *data) const; + virtual void DecryptBlocks (byte *data, size_t blockCount) const; + static void EnableHwSupport (bool enable) { HwSupportEnabled = enable; } + virtual void EncryptBlock (byte *data) const; + virtual void EncryptBlocks (byte *data, size_t blockCount) const; + static CipherList GetAvailableCiphers (); + virtual size_t GetBlockSize () const = 0; + virtual const SecureBuffer &GetKey () const { return Key; } + virtual size_t GetKeySize () const = 0; + virtual wstring GetName () const = 0; + virtual shared_ptr GetNew () const = 0; + virtual bool IsHwSupportAvailable () const { return false; } + static bool IsHwSupportEnabled () { return HwSupportEnabled; } + virtual void SetKey (const ConstBufferPtr &key); + + static const int MaxBlockSize = 16; + + protected: + Cipher (); + + virtual void Decrypt (byte *data) const = 0; + virtual void Encrypt (byte *data) const = 0; + virtual size_t GetScheduledKeySize () const = 0; + virtual void SetCipherKey (const byte *key) = 0; + + static bool HwSupportEnabled; + bool Initialized; + SecureBuffer Key; + SecureBuffer ScheduledKey; + + private: + Cipher (const Cipher &); + Cipher &operator= (const Cipher &); + }; + + struct CipherException : public Exception + { + protected: + CipherException () { } + CipherException (const string &message) : Exception (message) { } + CipherException (const string &message, const wstring &subject) : Exception (message, subject) { } + }; + + +#define TC_CIPHER(NAME, BLOCK_SIZE, KEY_SIZE) \ + class TC_JOIN (Cipher,NAME) : public Cipher \ + { \ + public: \ + TC_JOIN (Cipher,NAME) () { } \ + virtual ~TC_JOIN (Cipher,NAME) () { } \ +\ + virtual size_t GetBlockSize () const { return BLOCK_SIZE; }; \ + virtual size_t GetKeySize () const { return KEY_SIZE; }; \ + virtual wstring GetName () const { return L###NAME; }; \ + virtual shared_ptr GetNew () const { return shared_ptr (new TC_JOIN (Cipher,NAME)()); } \ + TC_CIPHER_ADD_METHODS \ +\ + protected: \ + virtual void Decrypt (byte *data) const; \ + virtual void Encrypt (byte *data) const; \ + virtual size_t GetScheduledKeySize () const; \ + virtual void SetCipherKey (const byte *key); \ +\ + private: \ + TC_JOIN (Cipher,NAME) (const TC_JOIN (Cipher,NAME) &); \ + TC_JOIN (Cipher,NAME) &operator= (const TC_JOIN (Cipher,NAME) &); \ + } + +#define TC_CIPHER_ADD_METHODS \ + virtual void DecryptBlocks (byte *data, size_t blockCount) const; \ + virtual void EncryptBlocks (byte *data, size_t blockCount) const; \ + virtual bool IsHwSupportAvailable () const; + + TC_CIPHER (AES, 16, 32); + +#undef TC_CIPHER_ADD_METHODS +#define TC_CIPHER_ADD_METHODS + + TC_CIPHER (Blowfish, 8, 56); + TC_CIPHER (Cast5, 8, 16); + TC_CIPHER (Serpent, 16, 32); + TC_CIPHER (TripleDES, 8, 24); + TC_CIPHER (Twofish, 16, 32); + +#undef TC_CIPHER + + +#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,CipherException) + +#undef TC_EXCEPTION_SET +#define TC_EXCEPTION_SET \ + TC_EXCEPTION (CipherInitError); \ + TC_EXCEPTION (WeakKeyDetected); + + TC_EXCEPTION_SET; + +#undef TC_EXCEPTION + +#if (defined (TC_ARCH_X86) || defined (TC_ARCH_X64)) && !defined (__ppc__) +# define TC_AES_HW_CPU +#endif + +} + +#endif // TC_HEADER_Encryption_Ciphers diff --git a/src/Volume/Crc32.h b/src/Volume/Crc32.h new file mode 100644 index 00000000..d4392275 --- /dev/null +++ b/src/Volume/Crc32.h @@ -0,0 +1,44 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Crc32 +#define TC_HEADER_Encryption_Crc32 + +#include "Platform/Platform.h" +#include "Common/Crc.h" + +namespace TrueCrypt +{ + class Crc32 + { + public: + Crc32 () : CrcValue (0xffffFFFF) { }; + virtual ~Crc32 () { }; + + uint32 Get () const { return CrcValue ^ 0xffffFFFF; } + + uint32 Process (byte data) + { + return CrcValue = crc_32_tab[(byte) (CrcValue ^ data)] ^ (CrcValue >> 8); + } + + static uint32 ProcessBuffer (const ConstBufferPtr &buffer) + { + return ::GetCrc32 (const_cast (buffer.Get()), static_cast (buffer.Size())); + } + + protected: + uint32 CrcValue; + + private: + Crc32 (const Crc32 &); + Crc32 &operator= (const Crc32 &); + }; +} + +#endif // TC_HEADER_Encryption_Crc32 diff --git a/src/Volume/EncryptionAlgorithm.cpp b/src/Volume/EncryptionAlgorithm.cpp new file mode 100644 index 00000000..5ca27bab --- /dev/null +++ b/src/Volume/EncryptionAlgorithm.cpp @@ -0,0 +1,345 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "EncryptionAlgorithm.h" +#include "EncryptionModeCBC.h" +#include "EncryptionModeLRW.h" +#include "EncryptionModeXTS.h" + +namespace TrueCrypt +{ + EncryptionAlgorithm::EncryptionAlgorithm () : Deprecated (false) + { + } + + EncryptionAlgorithm::~EncryptionAlgorithm () + { + } + + void EncryptionAlgorithm::Decrypt (byte *data, uint64 length) const + { + if_debug (ValidateState ()); + Mode->Decrypt (data, length); + } + + void EncryptionAlgorithm::Decrypt (const BufferPtr &data) const + { + Decrypt (data, data.Size()); + } + + void EncryptionAlgorithm::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState()); + Mode->DecryptSectors (data, sectorIndex, sectorCount, sectorSize); + } + + void EncryptionAlgorithm::Encrypt (byte *data, uint64 length) const + { + if_debug (ValidateState()); + Mode->Encrypt (data, length); + } + + void EncryptionAlgorithm::Encrypt (const BufferPtr &data) const + { + Encrypt (data, data.Size()); + } + + void EncryptionAlgorithm::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState ()); + Mode->EncryptSectors (data, sectorIndex, sectorCount, sectorSize); + } + + EncryptionAlgorithmList EncryptionAlgorithm::GetAvailableAlgorithms () + { + EncryptionAlgorithmList l; + + l.push_back (shared_ptr (new AES ())); + l.push_back (shared_ptr (new Serpent ())); + l.push_back (shared_ptr (new Twofish ())); + l.push_back (shared_ptr (new AESTwofish ())); + l.push_back (shared_ptr (new AESTwofishSerpent ())); + l.push_back (shared_ptr (new SerpentAES ())); + l.push_back (shared_ptr (new SerpentTwofishAES ())); + l.push_back (shared_ptr (new TwofishSerpent ())); + + l.push_back (shared_ptr (new AESBlowfish ())); + l.push_back (shared_ptr (new AESBlowfishSerpent ())); + l.push_back (shared_ptr (new Blowfish ())); + l.push_back (shared_ptr (new Cast5 ())); + l.push_back (shared_ptr (new TripleDES ())); + return l; + } + + size_t EncryptionAlgorithm::GetLargestKeySize (const EncryptionAlgorithmList &algorithms) + { + size_t largestKeySize = 0; + + foreach_ref (const EncryptionAlgorithm &ea, algorithms) + { + if (ea.GetKeySize() > largestKeySize) + largestKeySize = ea.GetKeySize(); + } + + return largestKeySize; + } + + size_t EncryptionAlgorithm::GetKeySize () const + { + if (Ciphers.size() < 1) + throw NotInitialized (SRC_POS); + + size_t keySize = 0; + + foreach_ref (const Cipher &c, Ciphers) + keySize += c.GetKeySize(); + + return keySize; + } + + size_t EncryptionAlgorithm::GetMaxBlockSize () const + { + size_t blockSize = 0; + + foreach_ref (const Cipher &c, Ciphers) + if (c.GetBlockSize() > blockSize) + blockSize = c.GetBlockSize(); + + return blockSize; + } + + size_t EncryptionAlgorithm::GetMinBlockSize () const + { + size_t blockSize = 0; + + foreach_ref (const Cipher &c, Ciphers) + if (blockSize == 0 || c.GetBlockSize() < blockSize) + blockSize = c.GetBlockSize(); + + return blockSize; + } + + shared_ptr EncryptionAlgorithm::GetMode () const + { + if (Mode.get() == nullptr) + throw NotInitialized (SRC_POS); + + return Mode; + } + + wstring EncryptionAlgorithm::GetName () const + { + if (Ciphers.size() < 1) + throw NotInitialized (SRC_POS); + + wstring name; + + foreach_reverse_ref (const Cipher &c, Ciphers) + { + if (name.empty()) + name = c.GetName(); + else + name += wstring (L"-") + c.GetName(); + } + + return name; + } + + bool EncryptionAlgorithm::IsModeSupported (const EncryptionMode &mode) const + { + bool supported = false; + + foreach_ref (const EncryptionMode &em, SupportedModes) + { + if (typeid (mode) == typeid (em)) + { + supported = true; + break; + } + } + + return supported; + } + + + bool EncryptionAlgorithm::IsModeSupported (const shared_ptr mode) const + { + return IsModeSupported (*mode); + } + + void EncryptionAlgorithm::SetMode (shared_ptr mode) + { + if (!IsModeSupported (*mode)) + throw ParameterIncorrect (SRC_POS); + + mode->SetCiphers (Ciphers); + Mode = mode; + } + + void EncryptionAlgorithm::SetKey (const ConstBufferPtr &key) + { + if (Ciphers.size() < 1) + throw NotInitialized (SRC_POS); + + if (GetKeySize() != key.Size()) + throw ParameterIncorrect (SRC_POS); + + size_t keyOffset = 0; + foreach_ref (Cipher &c, Ciphers) + { + c.SetKey (key.GetRange (keyOffset, c.GetKeySize())); + keyOffset += c.GetKeySize(); + } + } + + void EncryptionAlgorithm::ValidateState () const + { + if (Ciphers.size() < 1 || Mode.get() == nullptr) + throw NotInitialized (SRC_POS); + } + + // AES + AES::AES () + { + Ciphers.push_back (shared_ptr (new CipherAES())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // AES-Blowfish + AESBlowfish::AESBlowfish () + { + Deprecated = true; + + Ciphers.push_back (shared_ptr (new CipherBlowfish ())); + Ciphers.push_back (shared_ptr (new CipherAES ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // AES-Blowfish-Serpent + AESBlowfishSerpent::AESBlowfishSerpent () + { + Deprecated = true; + + Ciphers.push_back (shared_ptr (new CipherSerpent ())); + Ciphers.push_back (shared_ptr (new CipherBlowfish ())); + Ciphers.push_back (shared_ptr (new CipherAES ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // AES-Twofish + AESTwofish::AESTwofish () + { + Ciphers.push_back (shared_ptr (new CipherTwofish ())); + Ciphers.push_back (shared_ptr (new CipherAES ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // AES-Twofish-Serpent + AESTwofishSerpent::AESTwofishSerpent () + { + Ciphers.push_back (shared_ptr (new CipherSerpent ())); + Ciphers.push_back (shared_ptr (new CipherTwofish ())); + Ciphers.push_back (shared_ptr (new CipherAES ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Blowfish + Blowfish::Blowfish () + { + Deprecated = true; + Ciphers.push_back (shared_ptr (new CipherBlowfish())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // CAST5 + Cast5::Cast5 () + { + Deprecated = true; + Ciphers.push_back (shared_ptr (new CipherCast5())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Serpent + Serpent::Serpent () + { + Ciphers.push_back (shared_ptr (new CipherSerpent())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Serpent-AES + SerpentAES::SerpentAES () + { + Ciphers.push_back (shared_ptr (new CipherAES ())); + Ciphers.push_back (shared_ptr (new CipherSerpent ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Triple-DES + TripleDES::TripleDES () + { + Deprecated = true; + Ciphers.push_back (shared_ptr (new CipherTripleDES())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Twofish + Twofish::Twofish () + { + Ciphers.push_back (shared_ptr (new CipherTwofish())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Twofish-Serpent + TwofishSerpent::TwofishSerpent () + { + Ciphers.push_back (shared_ptr (new CipherSerpent ())); + Ciphers.push_back (shared_ptr (new CipherTwofish ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + // Serpent-Twofish-AES + SerpentTwofishAES::SerpentTwofishAES () + { + Ciphers.push_back (shared_ptr (new CipherAES ())); + Ciphers.push_back (shared_ptr (new CipherTwofish ())); + Ciphers.push_back (shared_ptr (new CipherSerpent ())); + + SupportedModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } +} diff --git a/src/Volume/EncryptionAlgorithm.h b/src/Volume/EncryptionAlgorithm.h new file mode 100644 index 00000000..8118de6b --- /dev/null +++ b/src/Volume/EncryptionAlgorithm.h @@ -0,0 +1,93 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_EncryptionAlgorithm +#define TC_HEADER_Encryption_EncryptionAlgorithm + +#include "Platform/Platform.h" +#include "Cipher.h" +#include "EncryptionMode.h" + +namespace TrueCrypt +{ + class EncryptionAlgorithm; + typedef list < shared_ptr > EncryptionAlgorithmList; + + class EncryptionAlgorithm + { + public: + virtual ~EncryptionAlgorithm (); + + virtual void Decrypt (byte *data, uint64 length) const; + virtual void Decrypt (const BufferPtr &data) const; + virtual void DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void Encrypt (byte *data, uint64 length) const; + virtual void Encrypt (const BufferPtr &data) const; + virtual void EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + static EncryptionAlgorithmList GetAvailableAlgorithms (); + virtual const CipherList &GetCiphers () const { return Ciphers; } + virtual shared_ptr GetNew () const = 0; + virtual size_t GetMaxBlockSize () const; + virtual size_t GetMinBlockSize () const; + static size_t GetLargestKeySize (const EncryptionAlgorithmList &algorithms); + virtual size_t GetKeySize () const; + virtual shared_ptr GetMode () const; + virtual wstring GetName () const; + bool IsDeprecated () const { return Deprecated; } + virtual bool IsModeSupported (const EncryptionMode &mode) const; + virtual bool IsModeSupported (const shared_ptr mode) const; + virtual void SetKey (const ConstBufferPtr &key); + virtual void SetMode (shared_ptr mode); + + protected: + EncryptionAlgorithm (); + + void ValidateState () const; + + CipherList Ciphers; + bool Deprecated; + shared_ptr Mode; + EncryptionModeList SupportedModes; + + private: + EncryptionAlgorithm (const EncryptionAlgorithm &); + EncryptionAlgorithm &operator= (const EncryptionAlgorithm &); + }; + +#define TC_ENCRYPTION_ALGORITHM(NAME) \ + class NAME : public EncryptionAlgorithm \ + { \ + public: \ + NAME (); \ + virtual ~NAME () { } \ +\ + virtual shared_ptr GetNew () const { return shared_ptr (new NAME()); } \ +\ + private: \ + NAME (const NAME &); \ + NAME &operator= (const NAME &); \ + } + + TC_ENCRYPTION_ALGORITHM (AES); + TC_ENCRYPTION_ALGORITHM (AESBlowfish); + TC_ENCRYPTION_ALGORITHM (AESBlowfishSerpent); + TC_ENCRYPTION_ALGORITHM (AESTwofish); + TC_ENCRYPTION_ALGORITHM (AESTwofishSerpent); + TC_ENCRYPTION_ALGORITHM (Blowfish); + TC_ENCRYPTION_ALGORITHM (Cast5); + TC_ENCRYPTION_ALGORITHM (Serpent); + TC_ENCRYPTION_ALGORITHM (SerpentAES); + TC_ENCRYPTION_ALGORITHM (TripleDES); + TC_ENCRYPTION_ALGORITHM (Twofish); + TC_ENCRYPTION_ALGORITHM (TwofishSerpent); + TC_ENCRYPTION_ALGORITHM (SerpentTwofishAES); + +#undef TC_ENCRYPTION_ALGORITHM +} + +#endif // TC_HEADER_Encryption_EncryptionAlgorithm diff --git a/src/Volume/EncryptionMode.cpp b/src/Volume/EncryptionMode.cpp new file mode 100644 index 00000000..eb68186c --- /dev/null +++ b/src/Volume/EncryptionMode.cpp @@ -0,0 +1,63 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "EncryptionMode.h" +#include "EncryptionModeCBC.h" +#include "EncryptionModeLRW.h" +#include "EncryptionModeXTS.h" +#include "EncryptionThreadPool.h" + +namespace TrueCrypt +{ + EncryptionMode::EncryptionMode () : KeySet (false), SectorOffset (0) + { + } + + EncryptionMode::~EncryptionMode () + { + } + + void EncryptionMode::DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + EncryptionThreadPool::DoWork (EncryptionThreadPool::WorkType::DecryptDataUnits, this, data, sectorIndex, sectorCount, sectorSize); + } + + void EncryptionMode::EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + EncryptionThreadPool::DoWork (EncryptionThreadPool::WorkType::EncryptDataUnits, this, data, sectorIndex, sectorCount, sectorSize); + } + + EncryptionModeList EncryptionMode::GetAvailableModes () + { + EncryptionModeList l; + + l.push_back (shared_ptr (new EncryptionModeXTS ())); + l.push_back (shared_ptr (new EncryptionModeLRW ())); + l.push_back (shared_ptr (new EncryptionModeCBC ())); + + return l; + } + + void EncryptionMode::ValidateState () const + { + if (!KeySet || Ciphers.size() < 1) + throw NotInitialized (SRC_POS); + } + + void EncryptionMode::ValidateParameters (byte *data, uint64 length) const + { + if ((Ciphers.size() > 0 && (length % Ciphers.front()->GetBlockSize()) != 0)) + throw ParameterIncorrect (SRC_POS); + } + + void EncryptionMode::ValidateParameters (byte *data, uint64 sectorCount, size_t sectorSize) const + { + if (sectorCount == 0 || sectorSize == 0 || (sectorSize % EncryptionDataUnitSize) != 0) + throw ParameterIncorrect (SRC_POS); + } +} diff --git a/src/Volume/EncryptionMode.h b/src/Volume/EncryptionMode.h new file mode 100644 index 00000000..e74fca55 --- /dev/null +++ b/src/Volume/EncryptionMode.h @@ -0,0 +1,62 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_EncryptionMode +#define TC_HEADER_Encryption_EncryptionMode + +#include "Platform/Platform.h" +#include "Common/Crypto.h" +#include "Cipher.h" + +namespace TrueCrypt +{ + class EncryptionMode; + typedef list < shared_ptr > EncryptionModeList; + + class EncryptionMode + { + public: + virtual ~EncryptionMode (); + + virtual void Decrypt (byte *data, uint64 length) const = 0; + virtual void DecryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const = 0; + virtual void Encrypt (byte *data, uint64 length) const = 0; + virtual void EncryptSectors (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const = 0; + static EncryptionModeList GetAvailableModes (); + virtual const SecureBuffer &GetKey () const { throw NotApplicable (SRC_POS); } + virtual size_t GetKeySize () const = 0; + virtual wstring GetName () const = 0; + virtual shared_ptr GetNew () const = 0; + virtual uint64 GetSectorOffset () const { return SectorOffset; } + virtual bool IsKeySet () const { return KeySet; } + virtual void SetKey (const ConstBufferPtr &key) = 0; + virtual void SetCiphers (const CipherList &ciphers) { Ciphers = ciphers; } + virtual void SetSectorOffset (int64 offset) { SectorOffset = offset; } + + protected: + EncryptionMode (); + + virtual void ValidateState () const; + void ValidateParameters (byte *data, uint64 length) const; + virtual void ValidateParameters (byte *data, uint64 sectorCount, size_t sectorSize) const; + + static const size_t EncryptionDataUnitSize = ENCRYPTION_DATA_UNIT_SIZE; + + CipherList Ciphers; + bool KeySet; + uint64 SectorOffset; + + private: + EncryptionMode (const EncryptionMode &); + EncryptionMode &operator= (const EncryptionMode &); + }; +} + +#endif // TC_HEADER_Encryption_EncryptionMode diff --git a/src/Volume/EncryptionModeCBC.cpp b/src/Volume/EncryptionModeCBC.cpp new file mode 100644 index 00000000..f299b888 --- /dev/null +++ b/src/Volume/EncryptionModeCBC.cpp @@ -0,0 +1,335 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Memory.h" +#include "Common/Crc.h" +#include "Common/Endian.h" +#include "EncryptionModeCBC.h" + +namespace TrueCrypt +{ + void EncryptionModeCBC::Decrypt (byte *data, uint64 length) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, length)); + + if (IsOuterCBC (Ciphers)) + { + DecryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset)); + } + else + { + for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin(); + iCipherList != Ciphers.rend(); + ++iCipherList) + { + CipherList cl; + cl.push_back (*iCipherList); + + DecryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset)); + } + } + } + + void EncryptionModeCBC::DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const + { + size_t blockSize = ciphers.front()->GetBlockSize(); + if (blockSize != 8 && blockSize != 16) + throw ParameterIncorrect (SRC_POS); + + uint32 *data32 = (uint32 *) data; + uint32 bufIV[4]; + uint32 ct[4]; + uint64 i; + + bufIV[0] = iv[0]; + bufIV[1] = iv[1]; + if (blockSize == 16) + { + bufIV[2] = iv[2]; + bufIV[3] = iv[3]; + } + + for (i = 0; i < length / blockSize; i++) + { + // Dewhitening + data32[0] ^= whitening[0]; + data32[1] ^= whitening[1]; + if (blockSize == 16) + { + data32[2] ^= whitening[0]; + data32[3] ^= whitening[1]; + } + + // CBC + ct[0] = data32[0]; + ct[1] = data32[1]; + if (blockSize == 16) + { + ct[2] = data32[2]; + ct[3] = data32[3]; + } + + for (CipherList::const_reverse_iterator iCipherList = ciphers.rbegin(); + iCipherList != ciphers.rend(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + + if (c.GetBlockSize () != blockSize) + throw ParameterIncorrect (SRC_POS); + + c.DecryptBlock ((byte *) data32); + } + + // CBC + data32[0] ^= bufIV[0]; + data32[1] ^= bufIV[1]; + bufIV[0] = ct[0]; + bufIV[1] = ct[1]; + if (blockSize == 16) + { + data32[2] ^= bufIV[2]; + data32[3] ^= bufIV[3]; + bufIV[2] = ct[2]; + bufIV[3] = ct[3]; + } + + data32 += blockSize / sizeof(*data32); + } + + Memory::Erase (bufIV, sizeof (bufIV)); + Memory::Erase (ct, sizeof (ct)); + } + + void EncryptionModeCBC::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, sectorCount, sectorSize)); + + uint32 sectorIV[4]; + uint32 sectorWhitening[2]; + + while (sectorCount--) + { + if (IsOuterCBC (Ciphers)) + { + InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening); + DecryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening); + } + else + { + for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin(); + iCipherList != Ciphers.rend(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + CipherList cl; + cl.push_back (*iCipherList); + + InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening); + DecryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening); + } + } + + data += sectorSize; + sectorIndex++; + } + + Memory::Erase (sectorIV, sizeof (sectorIV)); + Memory::Erase (sectorWhitening, sizeof (sectorWhitening)); + } + + void EncryptionModeCBC::Encrypt (byte *data, uint64 length) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, length)); + + if (IsOuterCBC (Ciphers)) + { + EncryptBuffer (data, length, Ciphers, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset)); + } + else + { + for (CipherList::const_iterator iCipherList = Ciphers.begin(); + iCipherList != Ciphers.end(); + ++iCipherList) + { + CipherList cl; + cl.push_back (*iCipherList); + + EncryptBuffer (data, length, cl, (uint32 *) IV.Ptr(), (uint32 *) (IV.Ptr() + WhiteningIVOffset)); + } + } + } + + void EncryptionModeCBC::EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const + { + size_t blockSize = ciphers.front()->GetBlockSize(); + if (blockSize != 8 && blockSize != 16) + throw ParameterIncorrect (SRC_POS); + + uint32 *data32 = (uint32 *) data; + uint32 bufIV[4]; + uint64 i; + + bufIV[0] = iv[0]; + bufIV[1] = iv[1]; + if (blockSize == 16) + { + bufIV[2] = iv[2]; + bufIV[3] = iv[3]; + } + + for (i = 0; i < length / blockSize; i++) + { + data32[0] ^= bufIV[0]; + data32[1] ^= bufIV[1]; + if (blockSize == 16) + { + data32[2] ^= bufIV[2]; + data32[3] ^= bufIV[3]; + } + + for (CipherList::const_iterator iCipherList = ciphers.begin(); + iCipherList != ciphers.end(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + + if (c.GetBlockSize () != blockSize) + throw ParameterIncorrect (SRC_POS); + + c.EncryptBlock ((byte *) data32); + } + + bufIV[0] = data32[0]; + bufIV[1] = data32[1]; + if (blockSize == 16) + { + bufIV[2] = data32[2]; + bufIV[3] = data32[3]; + } + + data32[0] ^= whitening[0]; + data32[1] ^= whitening[1]; + if (blockSize == 16) + { + data32[2] ^= whitening[0]; + data32[3] ^= whitening[1]; + } + + data32 += blockSize / sizeof(*data32); + } + + Memory::Erase (bufIV, sizeof (bufIV)); + } + + void EncryptionModeCBC::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, sectorCount, sectorSize)); + + uint32 sectorIV[4]; + uint32 sectorWhitening[2]; + + while (sectorCount--) + { + if (IsOuterCBC (Ciphers)) + { + InitSectorIVAndWhitening (sectorIndex, Ciphers.front()->GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening); + EncryptBuffer (data, sectorSize, Ciphers, sectorIV, sectorWhitening); + } + else + { + for (CipherList::const_iterator iCipherList = Ciphers.begin(); + iCipherList != Ciphers.end(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + CipherList cl; + cl.push_back (*iCipherList); + + InitSectorIVAndWhitening (sectorIndex, c.GetBlockSize(), (uint64 *) IV.Ptr(), sectorIV, sectorWhitening); + EncryptBuffer (data, sectorSize, cl, sectorIV, sectorWhitening); + } + } + + data += sectorSize; + sectorIndex++; + } + + Memory::Erase (sectorIV, sizeof (sectorIV)); + Memory::Erase (sectorWhitening, sizeof (sectorWhitening)); + } + + void EncryptionModeCBC::InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const + { + if (blockSize != 8 && blockSize != 16) + throw ParameterIncorrect (SRC_POS); + + uint64 iv64[4]; + uint32 *iv32 = (uint32 *) iv64; + + iv64[0] = ivSeed[0] ^ Endian::Little (sectorIndex); + iv64[1] = ivSeed[1] ^ Endian::Little (sectorIndex); + iv64[2] = ivSeed[2] ^ Endian::Little (sectorIndex); + if (blockSize == 16) + { + iv64[3] = ivSeed[3] ^ Endian::Little (sectorIndex); + } + + iv[0] = iv32[0]; + iv[1] = iv32[1]; + + if (blockSize == 8) + { + whitening[0] = Endian::Little ( crc32int ( &iv32[2] ) ^ crc32int ( &iv32[5] ) ); + whitening[1] = Endian::Little ( crc32int ( &iv32[3] ) ^ crc32int ( &iv32[4] ) ); + } + else + { + iv[2] = iv32[2]; + iv[3] = iv32[3]; + + whitening[0] = Endian::Little ( crc32int ( &iv32[4] ) ^ crc32int ( &iv32[7] ) ); + whitening[1] = Endian::Little ( crc32int ( &iv32[5] ) ^ crc32int ( &iv32[6] ) ); + } + } + + bool EncryptionModeCBC::IsOuterCBC (const CipherList &ciphers) const + { + if (ciphers.size() < 2) + return false; + + size_t blockSize = ciphers.front()->GetBlockSize(); + + for (CipherList::const_iterator iCipherList = ciphers.begin(); + iCipherList != ciphers.end(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + if (c.GetBlockSize() != blockSize) + return false; + } + + return true; + } + + void EncryptionModeCBC::SetKey (const ConstBufferPtr &key) + { + if (key.Size() != GetKeySize ()) + throw ParameterIncorrect (SRC_POS); + + if (!KeySet) + IV.Allocate (GetKeySize ()); + + IV.CopyFrom (key); + KeySet = true; + } +} diff --git a/src/Volume/EncryptionModeCBC.h b/src/Volume/EncryptionModeCBC.h new file mode 100644 index 00000000..3e1094aa --- /dev/null +++ b/src/Volume/EncryptionModeCBC.h @@ -0,0 +1,47 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_EncryptionModeCBC +#define TC_HEADER_Encryption_EncryptionModeCBC + +#include "Platform/Platform.h" +#include "EncryptionMode.h" + +namespace TrueCrypt +{ + class EncryptionModeCBC : public EncryptionMode + { + public: + EncryptionModeCBC () { } + virtual ~EncryptionModeCBC () { } + + virtual void Decrypt (byte *data, uint64 length) const; + virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void Encrypt (byte *data, uint64 length) const; + virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual size_t GetKeySize () const { return 32; }; + virtual wstring GetName () const { return L"CBC"; }; + virtual shared_ptr GetNew () const { return shared_ptr (new EncryptionModeCBC); } + virtual void SetKey (const ConstBufferPtr &key); + + protected: + void DecryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const; + void EncryptBuffer (byte *data, uint64 length, const CipherList &ciphers, const uint32 *iv, const uint32 *whitening) const; + void InitSectorIVAndWhitening (uint64 sectorIndex, size_t blockSize, const uint64 *ivSeed, uint32 *iv, uint32 *whitening) const; + bool IsOuterCBC (const CipherList &ciphers) const; + + SecureBuffer IV; + static const int WhiteningIVOffset = 8; + + private: + EncryptionModeCBC (const EncryptionModeCBC &); + EncryptionModeCBC &operator= (const EncryptionModeCBC &); + }; +} + +#endif // TC_HEADER_Encryption_EncryptionModeCBC diff --git a/src/Volume/EncryptionModeLRW.cpp b/src/Volume/EncryptionModeLRW.cpp new file mode 100644 index 00000000..38731d5d --- /dev/null +++ b/src/Volume/EncryptionModeLRW.cpp @@ -0,0 +1,195 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "EncryptionModeLRW.h" +#include "Common/GfMul.h" + +namespace TrueCrypt +{ + void EncryptionModeLRW::Decrypt (byte *data, uint64 length) const + { + if_debug (ValidateState ()); + DecryptBuffer (data, length, 1); + } + + void EncryptionModeLRW::DecryptBuffer (byte *data, uint64 length, uint64 blockIndex) const + { + size_t blockSize = Ciphers.front()->GetBlockSize(); + if (blockSize != 8 && blockSize != 16) + throw ParameterIncorrect (SRC_POS); + + byte i[8]; + *(uint64 *)i = Endian::Big (blockIndex); + + byte t[Cipher::MaxBlockSize]; + + for (unsigned int b = 0; b < length / blockSize; b++) + { + if (blockSize == 8) + { + Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr())); + Xor64 ((uint64 *)data, (uint64 *)t); + } + else + { + Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr())); + Xor128 ((uint64 *)data, (uint64 *)t); + } + + for (CipherList::const_reverse_iterator iCipherList = Ciphers.rbegin(); + iCipherList != Ciphers.rend(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + + if (c.GetBlockSize () != blockSize) + throw ParameterIncorrect (SRC_POS); + + c.DecryptBlock (data); + } + + if (blockSize == 8) + Xor64 ((uint64 *)data, (uint64 *)t); + else + Xor128 ((uint64 *)data, (uint64 *)t); + + data += blockSize; + IncrementBlockIndex (i); + } + + Memory::Erase (t, sizeof (t)); + } + + void EncryptionModeLRW::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, sectorCount, sectorSize)); + + DecryptBuffer (data, + sectorCount * sectorSize, + SectorToBlockIndex (sectorIndex)); + } + + void EncryptionModeLRW::Encrypt (byte *data, uint64 length) const + { + ValidateState (); + EncryptBuffer (data, length, 1); + } + + void EncryptionModeLRW::EncryptBuffer (byte *data, uint64 length, uint64 blockIndex) const + { + size_t blockSize = Ciphers.front()->GetBlockSize(); + if (blockSize != 8 && blockSize != 16) + throw ParameterIncorrect (SRC_POS); + + byte i[8]; + *(uint64 *)i = Endian::Big (blockIndex); + + byte t[Cipher::MaxBlockSize]; + + for (unsigned int b = 0; b < length / blockSize; b++) + { + if (blockSize == 8) + { + Gf64MulTab (i, t, (GfCtx *) (GfContext.Ptr())); + Xor64 ((uint64 *)data, (uint64 *)t); + } + else + { + Gf128MulBy64Tab (i, t, (GfCtx *) (GfContext.Ptr())); + Xor128 ((uint64 *)data, (uint64 *)t); + } + + for (CipherList::const_iterator iCipherList = Ciphers.begin(); + iCipherList != Ciphers.end(); + ++iCipherList) + { + const Cipher &c = **iCipherList; + + if (c.GetBlockSize () != blockSize) + throw ParameterIncorrect (SRC_POS); + + c.EncryptBlock (data); + } + + if (blockSize == 8) + Xor64 ((uint64 *)data, (uint64 *)t); + else + Xor128 ((uint64 *)data, (uint64 *)t); + + data += blockSize; + IncrementBlockIndex (i); + } + + Memory::Erase (t, sizeof (t)); + } + + void EncryptionModeLRW::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + if_debug (ValidateState ()); + if_debug (ValidateParameters (data, sectorCount, sectorSize)); + + EncryptBuffer (data, + sectorCount * sectorSize, + SectorToBlockIndex (sectorIndex)); + } + + void EncryptionModeLRW::IncrementBlockIndex (byte *index) const + { + if (index[7] != 0xff) + index[7]++; + else + *(uint64 *)index = Endian::Big ( Endian::Big (*(uint64 *)index) + 1 ); + } + + uint64 EncryptionModeLRW::SectorToBlockIndex (uint64 sectorIndex) const + { + sectorIndex -= SectorOffset; + + switch (Ciphers.front()->GetBlockSize()) + { + case 8: + return (sectorIndex << 6) | 1; + + case 16: + return (sectorIndex << 5) | 1; + + default: + throw ParameterIncorrect (SRC_POS); + } + } + + void EncryptionModeLRW::SetKey (const ConstBufferPtr &key) + { + if (key.Size() != 16) + throw ParameterIncorrect (SRC_POS); + + if (!KeySet) + GfContext.Allocate (sizeof (GfCtx)); + + if (!Gf64TabInit ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr()))) + throw bad_alloc(); + + if (!Gf128Tab64Init ((unsigned char *) key.Get(), (GfCtx *) (GfContext.Ptr()))) + throw bad_alloc(); + + Key.CopyFrom (key); + KeySet = true; + } + + void EncryptionModeLRW::Xor64 (uint64 *a, const uint64 *b) const + { + *a ^= *b; + } + + void EncryptionModeLRW::Xor128 (uint64 *a, const uint64 *b) const + { + *a++ ^= *b++; + *a ^= *b; + } +} diff --git a/src/Volume/EncryptionModeLRW.h b/src/Volume/EncryptionModeLRW.h new file mode 100644 index 00000000..97a8528d --- /dev/null +++ b/src/Volume/EncryptionModeLRW.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_EncryptionModeLRW +#define TC_HEADER_Encryption_EncryptionModeLRW + +#include "Platform/Platform.h" +#include "EncryptionMode.h" + +namespace TrueCrypt +{ + class EncryptionModeLRW : public EncryptionMode + { + public: + EncryptionModeLRW () { } + virtual ~EncryptionModeLRW () { } + + virtual void Decrypt (byte *data, uint64 length) const; + virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void Encrypt (byte *data, uint64 length) const; + virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual const SecureBuffer &GetKey () const { return Key; } + virtual size_t GetKeySize () const { return 16; }; + virtual wstring GetName () const { return L"LRW"; }; + virtual shared_ptr GetNew () const { return shared_ptr (new EncryptionModeLRW); } + virtual void SetKey (const ConstBufferPtr &key); + + protected: + void DecryptBuffer (byte *plainText, uint64 length, uint64 blockIndex) const; + void EncryptBuffer (byte *plainText, uint64 length, uint64 blockIndex) const; + void IncrementBlockIndex (byte *index) const; + uint64 SectorToBlockIndex (uint64 sectorIndex) const; + void Xor64 (uint64 *a, const uint64 *b) const; + void Xor128 (uint64 *a, const uint64 *b) const; + + SecureBuffer GfContext; + SecureBuffer Key; + + private: + EncryptionModeLRW (const EncryptionModeLRW &); + EncryptionModeLRW &operator= (const EncryptionModeLRW &); + }; +} + +#endif // TC_HEADER_Encryption_EncryptionModeLRW diff --git a/src/Volume/EncryptionModeXTS.cpp b/src/Volume/EncryptionModeXTS.cpp new file mode 100644 index 00000000..8073f3ca --- /dev/null +++ b/src/Volume/EncryptionModeXTS.cpp @@ -0,0 +1,374 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "EncryptionModeXTS.h" +#include "Common/Crypto.h" + +namespace TrueCrypt +{ + void EncryptionModeXTS::Encrypt (byte *data, uint64 length) const + { + EncryptBuffer (data, length, 0); + } + + void EncryptionModeXTS::EncryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const + { + if_debug (ValidateState()); + + CipherList::const_iterator iSecondaryCipher = SecondaryCiphers.begin(); + + for (CipherList::const_iterator iCipher = Ciphers.begin(); iCipher != Ciphers.end(); ++iCipher) + { + EncryptBufferXTS (**iCipher, **iSecondaryCipher, data, length, startDataUnitNo, 0); + ++iSecondaryCipher; + } + + assert (iSecondaryCipher == SecondaryCiphers.end()); + } + + void EncryptionModeXTS::EncryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const + { + byte finalCarry; + byte whiteningValues [ENCRYPTION_DATA_UNIT_SIZE]; + byte whiteningValue [BYTES_PER_XTS_BLOCK]; + byte byteBufUnitNo [BYTES_PER_XTS_BLOCK]; + uint64 *whiteningValuesPtr64 = (uint64 *) whiteningValues; + uint64 *whiteningValuePtr64 = (uint64 *) whiteningValue; + uint64 *bufPtr = (uint64 *) buffer; + uint64 *dataUnitBufPtr; + unsigned int startBlock = startCipherBlockNo, endBlock, block; + uint64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1; + uint64 blockCount, dataUnitNo; + + startDataUnitNo += SectorOffset; + + /* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the + finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block + number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented + as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if + the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is + derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */ + + // Convert the 64-bit data unit number into a little-endian 16-byte array. + // Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes. + dataUnitNo = startDataUnitNo; + *((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo); + *((uint64 *) byteBufUnitNo + 1) = 0; + + if (length % BYTES_PER_XTS_BLOCK) + TC_THROW_FATAL_EXCEPTION; + + blockCount = length / BYTES_PER_XTS_BLOCK; + + // Process all blocks in the buffer + while (blockCount > 0) + { + if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) + endBlock = startBlock + (unsigned int) blockCount; + else + endBlock = BLOCKS_PER_XTS_DATA_UNIT; + + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + whiteningValuePtr64 = (uint64 *) whiteningValue; + + // Encrypt the data unit number using the secondary key (in order to generate the first + // whitening value for this data unit) + *whiteningValuePtr64 = *((uint64 *) byteBufUnitNo); + *(whiteningValuePtr64 + 1) = 0; + secondaryCipher.EncryptBlock (whiteningValue); + + // Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit + // whitening values are stored in memory as a sequence of 64-bit integers in reverse order. + for (block = 0; block < endBlock; block++) + { + if (block >= startBlock) + { + *whiteningValuesPtr64-- = *whiteningValuePtr64++; + *whiteningValuesPtr64-- = *whiteningValuePtr64; + } + else + whiteningValuePtr64++; + + // Derive the next whitening value + +#if BYTE_ORDER == LITTLE_ENDIAN + + // Little-endian platforms + + finalCarry = + (*whiteningValuePtr64 & 0x8000000000000000ULL) ? + 135 : 0; + + *whiteningValuePtr64-- <<= 1; + + if (*whiteningValuePtr64 & 0x8000000000000000ULL) + *(whiteningValuePtr64 + 1) |= 1; + + *whiteningValuePtr64 <<= 1; +#else + + // Big-endian platforms + + finalCarry = + (*whiteningValuePtr64 & 0x80) ? + 135 : 0; + + *whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1); + + whiteningValuePtr64--; + + if (*whiteningValuePtr64 & 0x80) + *(whiteningValuePtr64 + 1) |= 0x0100000000000000ULL; + + *whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1); +#endif + + whiteningValue[0] ^= finalCarry; + } + + dataUnitBufPtr = bufPtr; + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + + // Encrypt all blocks in this data unit + + for (block = startBlock; block < endBlock; block++) + { + // Pre-whitening + *bufPtr++ ^= *whiteningValuesPtr64--; + *bufPtr++ ^= *whiteningValuesPtr64--; + } + + // Actual encryption + cipher.EncryptBlocks ((byte *) dataUnitBufPtr, endBlock - startBlock); + + bufPtr = dataUnitBufPtr; + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + + for (block = startBlock; block < endBlock; block++) + { + // Post-whitening + *bufPtr++ ^= *whiteningValuesPtr64--; + *bufPtr++ ^= *whiteningValuesPtr64--; + } + + blockCount -= endBlock - startBlock; + startBlock = 0; + dataUnitNo++; + *((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo); + } + + FAST_ERASE64 (whiteningValue, sizeof (whiteningValue)); + FAST_ERASE64 (whiteningValues, sizeof (whiteningValues)); + } + + void EncryptionModeXTS::EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + EncryptBuffer (data, sectorCount * sectorSize, sectorIndex * sectorSize / ENCRYPTION_DATA_UNIT_SIZE); + } + + size_t EncryptionModeXTS::GetKeySize () const + { + if (Ciphers.empty()) + throw NotInitialized (SRC_POS); + + size_t keySize = 0; + foreach_ref (const Cipher &cipher, SecondaryCiphers) + { + keySize += cipher.GetKeySize(); + } + + return keySize; + } + + void EncryptionModeXTS::Decrypt (byte *data, uint64 length) const + { + DecryptBuffer (data, length, 0); + } + + void EncryptionModeXTS::DecryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const + { + if_debug (ValidateState()); + + CipherList::const_iterator iSecondaryCipher = SecondaryCiphers.end(); + + for (CipherList::const_reverse_iterator iCipher = Ciphers.rbegin(); iCipher != Ciphers.rend(); ++iCipher) + { + --iSecondaryCipher; + DecryptBufferXTS (**iCipher, **iSecondaryCipher, data, length, startDataUnitNo, 0); + } + + assert (iSecondaryCipher == SecondaryCiphers.begin()); + } + + void EncryptionModeXTS::DecryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const + { + byte finalCarry; + byte whiteningValues [ENCRYPTION_DATA_UNIT_SIZE]; + byte whiteningValue [BYTES_PER_XTS_BLOCK]; + byte byteBufUnitNo [BYTES_PER_XTS_BLOCK]; + uint64 *whiteningValuesPtr64 = (uint64 *) whiteningValues; + uint64 *whiteningValuePtr64 = (uint64 *) whiteningValue; + uint64 *bufPtr = (uint64 *) buffer; + uint64 *dataUnitBufPtr; + unsigned int startBlock = startCipherBlockNo, endBlock, block; + uint64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1; + uint64 blockCount, dataUnitNo; + + startDataUnitNo += SectorOffset; + + // Convert the 64-bit data unit number into a little-endian 16-byte array. + // Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes. + dataUnitNo = startDataUnitNo; + *((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo); + *((uint64 *) byteBufUnitNo + 1) = 0; + + if (length % BYTES_PER_XTS_BLOCK) + TC_THROW_FATAL_EXCEPTION; + + blockCount = length / BYTES_PER_XTS_BLOCK; + + // Process all blocks in the buffer + while (blockCount > 0) + { + if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) + endBlock = startBlock + (unsigned int) blockCount; + else + endBlock = BLOCKS_PER_XTS_DATA_UNIT; + + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + whiteningValuePtr64 = (uint64 *) whiteningValue; + + // Encrypt the data unit number using the secondary key (in order to generate the first + // whitening value for this data unit) + *whiteningValuePtr64 = *((uint64 *) byteBufUnitNo); + *(whiteningValuePtr64 + 1) = 0; + secondaryCipher.EncryptBlock (whiteningValue); + + // Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit + // whitening values are stored in memory as a sequence of 64-bit integers in reverse order. + for (block = 0; block < endBlock; block++) + { + if (block >= startBlock) + { + *whiteningValuesPtr64-- = *whiteningValuePtr64++; + *whiteningValuesPtr64-- = *whiteningValuePtr64; + } + else + whiteningValuePtr64++; + + // Derive the next whitening value + +#if BYTE_ORDER == LITTLE_ENDIAN + + // Little-endian platforms + + finalCarry = + (*whiteningValuePtr64 & 0x8000000000000000ULL) ? + 135 : 0; + + *whiteningValuePtr64-- <<= 1; + + if (*whiteningValuePtr64 & 0x8000000000000000ULL) + *(whiteningValuePtr64 + 1) |= 1; + + *whiteningValuePtr64 <<= 1; + +#else + // Big-endian platforms + + finalCarry = + (*whiteningValuePtr64 & 0x80) ? + 135 : 0; + + *whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1); + + whiteningValuePtr64--; + + if (*whiteningValuePtr64 & 0x80) + *(whiteningValuePtr64 + 1) |= 0x0100000000000000ULL; + + *whiteningValuePtr64 = Endian::Little (Endian::Little (*whiteningValuePtr64) << 1); +#endif + + whiteningValue[0] ^= finalCarry; + } + + dataUnitBufPtr = bufPtr; + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + + // Decrypt blocks in this data unit + + for (block = startBlock; block < endBlock; block++) + { + *bufPtr++ ^= *whiteningValuesPtr64--; + *bufPtr++ ^= *whiteningValuesPtr64--; + } + + cipher.DecryptBlocks ((byte *) dataUnitBufPtr, endBlock - startBlock); + + bufPtr = dataUnitBufPtr; + whiteningValuesPtr64 = finalInt64WhiteningValuesPtr; + + for (block = startBlock; block < endBlock; block++) + { + *bufPtr++ ^= *whiteningValuesPtr64--; + *bufPtr++ ^= *whiteningValuesPtr64--; + } + + blockCount -= endBlock - startBlock; + startBlock = 0; + dataUnitNo++; + + *((uint64 *) byteBufUnitNo) = Endian::Little (dataUnitNo); + } + + FAST_ERASE64 (whiteningValue, sizeof (whiteningValue)); + FAST_ERASE64 (whiteningValues, sizeof (whiteningValues)); + } + + void EncryptionModeXTS::DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const + { + DecryptBuffer (data, sectorCount * sectorSize, sectorIndex * sectorSize / ENCRYPTION_DATA_UNIT_SIZE); + } + + void EncryptionModeXTS::SetCiphers (const CipherList &ciphers) + { + EncryptionMode::SetCiphers (ciphers); + + SecondaryCiphers.clear(); + + foreach_ref (const Cipher &cipher, ciphers) + { + SecondaryCiphers.push_back (cipher.GetNew()); + } + + if (SecondaryKey.Size() > 0) + SetSecondaryCipherKeys(); + } + + void EncryptionModeXTS::SetKey (const ConstBufferPtr &key) + { + SecondaryKey.Allocate (key.Size()); + SecondaryKey.CopyFrom (key); + + if (!SecondaryCiphers.empty()) + SetSecondaryCipherKeys(); + } + + void EncryptionModeXTS::SetSecondaryCipherKeys () + { + size_t keyOffset = 0; + foreach_ref (Cipher &cipher, SecondaryCiphers) + { + cipher.SetKey (SecondaryKey.GetRange (keyOffset, cipher.GetKeySize())); + keyOffset += cipher.GetKeySize(); + } + + KeySet = true; + } +} diff --git a/src/Volume/EncryptionModeXTS.h b/src/Volume/EncryptionModeXTS.h new file mode 100644 index 00000000..927a34cb --- /dev/null +++ b/src/Volume/EncryptionModeXTS.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_EncryptionModeXTS +#define TC_HEADER_Volume_EncryptionModeXTS + +#include "Platform/Platform.h" +#include "EncryptionMode.h" + +namespace TrueCrypt +{ + class EncryptionModeXTS : public EncryptionMode + { + public: + EncryptionModeXTS () { } + virtual ~EncryptionModeXTS () { } + + virtual void Decrypt (byte *data, uint64 length) const; + virtual void DecryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual void Encrypt (byte *data, uint64 length) const; + virtual void EncryptSectorsCurrentThread (byte *data, uint64 sectorIndex, uint64 sectorCount, size_t sectorSize) const; + virtual const SecureBuffer &GetKey () const { return SecondaryKey; } + virtual size_t GetKeySize () const; + virtual wstring GetName () const { return L"XTS"; }; + virtual shared_ptr GetNew () const { return shared_ptr (new EncryptionModeXTS); } + virtual void SetCiphers (const CipherList &ciphers); + virtual void SetKey (const ConstBufferPtr &key); + + protected: + void DecryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const; + void DecryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const; + void EncryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const; + void EncryptBufferXTS (const Cipher &cipher, const Cipher &secondaryCipher, byte *buffer, uint64 length, uint64 startDataUnitNo, unsigned int startCipherBlockNo) const; + void SetSecondaryCipherKeys (); + + SecureBuffer SecondaryKey; + CipherList SecondaryCiphers; + + private: + EncryptionModeXTS (const EncryptionModeXTS &); + EncryptionModeXTS &operator= (const EncryptionModeXTS &); + }; +} + +#endif // TC_HEADER_Volume_EncryptionModeXTS diff --git a/src/Volume/EncryptionTest.cpp b/src/Volume/EncryptionTest.cpp new file mode 100644 index 00000000..cfede524 --- /dev/null +++ b/src/Volume/EncryptionTest.cpp @@ -0,0 +1,890 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Cipher.h" +#include "Common/Crc.h" +#include "Crc32.h" +#include "EncryptionAlgorithm.h" +#include "EncryptionMode.h" +#include "EncryptionModeCBC.h" +#include "EncryptionModeLRW.h" +#include "EncryptionModeXTS.h" +#include "EncryptionTest.h" +#include "Pkcs5Kdf.h" + +namespace TrueCrypt +{ + void EncryptionTest::TestAll () + { + TestAll (false); + TestAll (true); + } + + void EncryptionTest::TestAll (bool enableCpuEncryptionSupport) + { + bool hwSupportEnabled = Cipher::IsHwSupportEnabled(); + finally_do_arg (bool, hwSupportEnabled, { Cipher::EnableHwSupport (finally_arg); }); + + Cipher::EnableHwSupport (enableCpuEncryptionSupport); + + TestCiphers(); + TestXtsAES(); + TestXts(); + TestLegacyModes(); + TestPkcs5(); + } + + void EncryptionTest::TestLegacyModes () + { + byte buf[ENCRYPTION_DATA_UNIT_SIZE * 2]; + byte iv[32]; + unsigned int i; + uint32 crc; + uint64 secNo = 0x0234567890ABCDEFull; + + for (i = 0; i < sizeof (buf); i++) + buf[i] = (byte) i; + + for (i = 0; i < sizeof (iv); i++) + iv[i] = (byte) i; + + EncryptionModeList encModes = EncryptionMode::GetAvailableModes (); + + foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms()) + { + foreach (shared_ptr mode, encModes) + { + if (typeid (*mode) == typeid (EncryptionModeXTS)) + continue; + + if (!mode->IsKeySet()) + { + mode->SetKey (ConstBufferPtr (iv, mode->GetKeySize())); + mode->SetSectorOffset (1); + } + + if (ea.IsModeSupported (mode)) + { + ea.SetMode (mode); + ea.SetKey (ConstBufferPtr (buf, ea.GetKeySize())); + + ea.EncryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + ea.DecryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + ea.EncryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + + crc = ::GetCrc32 (buf, sizeof (buf)); + + if (typeid (*mode) == typeid (EncryptionModeLRW)) + { + if (typeid (ea) == typeid (AES) && crc != 0x5237acf9) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESTwofish) && crc != 0x4ed0fd80) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESTwofishSerpent) && crc != 0xea04b3cf) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Blowfish) && crc != 0xf94d5300) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Cast5) && crc != 0x33971e82) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Serpent) && crc != 0x7fb86805) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (TripleDES) && crc != 0x2b20bb84) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Twofish) && crc != 0xa9de0f0b) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (TwofishSerpent) && crc != 0xca65c5cd) throw TestFailed (SRC_POS); + } + + if (typeid (*mode) == typeid (EncryptionModeCBC)) + { + if (typeid (ea) == typeid (AES) && crc != 0x2274f53d) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESBlowfish) && crc != 0xa7a80c84) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESBlowfishSerpent) && crc != 0xa0584562) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESTwofish) && crc != 0x3c226444) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (AESTwofishSerpent) && crc != 0x5e5e77fd) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Blowfish) && crc != 0x033899a1) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Cast5) && crc != 0x331cecc7) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (Serpent) && crc != 0x42dff3d4) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (TripleDES) && crc != 0xfe497d0c) throw TestFailed (SRC_POS); + if (typeid (ea) == typeid (TwofishSerpent) && crc != 0xa7b659f3) throw TestFailed (SRC_POS); + } + + ea.DecryptSectors (buf, secNo, sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + } + } + } + } + + + struct CipherTestVector + { + byte Key[32]; + byte Plaintext[16]; + byte Ciphertext[16]; + }; + + static const CipherTestVector AESTestVectors[] = + { + { + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + }, + { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }, + { + 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 + } + } + }; + + static const CipherTestVector SerpentTestVectors[] = + { + { + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }, + { + 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8, 0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c + } + } + }; + + static const CipherTestVector TwofishTestVectors[] = + { + { + { + 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F + }, + { + 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 + }, + { + 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA + } + } + }; + + static void TestCipher (Cipher &cipher, const CipherTestVector *testVector, size_t testVectorCount) + { + Buffer buffer (cipher.GetBlockSize()); + for (size_t i = 0; i < testVectorCount; ++i) + { + cipher.SetKey (ConstBufferPtr (testVector[i].Key, sizeof (testVector[i].Key))); + buffer.CopyFrom (ConstBufferPtr (testVector[i].Plaintext, sizeof (testVector[i].Plaintext))); + cipher.EncryptBlock (buffer); + + if (memcmp (buffer, testVector[i].Ciphertext, buffer.Size()) != 0) + throw TestFailed (SRC_POS); + } + } + + void EncryptionTest::TestCiphers () + { + CipherAES aes; + TestCipher (aes, AESTestVectors, array_capacity (AESTestVectors)); + + Buffer testData (1024); + for (size_t i = 0; i < testData.Size(); ++i) + { + testData[i] = (byte) i; + } + + uint32 origCrc = Crc32::ProcessBuffer (testData); + + aes.SetKey (ConstBufferPtr (testData, aes.GetKeySize())); + aes.EncryptBlocks (testData, testData.Size() / aes.GetBlockSize()); + + if (Crc32::ProcessBuffer (testData) != 0xb5cd5631) + throw TestFailed (SRC_POS); + + aes.DecryptBlocks (testData, testData.Size() / aes.GetBlockSize()); + + if (origCrc != Crc32::ProcessBuffer (testData)) + throw TestFailed (SRC_POS); + + CipherSerpent serpent; + TestCipher (serpent, SerpentTestVectors, array_capacity (SerpentTestVectors)); + + CipherTwofish twofish; + TestCipher (twofish, TwofishTestVectors, array_capacity (TwofishTestVectors)); + } + + const EncryptionTest::XtsTestVector EncryptionTest::XtsTestVectors[] = + { + /* XTS-AES-256 */ + { + // IEEE 1619 - Vector 10 + + { 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 }, + { 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff }, + 0, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, + { + 0x1c, 0x3b, 0x3a, 0x10, 0x2f, 0x77, 0x03, 0x86, 0xe4, 0x83, 0x6c, 0x99, 0xe3, 0x70, 0xcf, 0x9b, 0xea, 0x00, 0x80, 0x3f, 0x5e, 0x48, 0x23, 0x57, 0xa4, 0xae, 0x12, 0xd4, 0x14, 0xa3, 0xe6, 0x3b, + 0x5d, 0x31, 0xe2, 0x76, 0xf8, 0xfe, 0x4a, 0x8d, 0x66, 0xb3, 0x17, 0xf9, 0xac, 0x68, 0x3f, 0x44, 0x68, 0x0a, 0x86, 0xac, 0x35, 0xad, 0xfc, 0x33, 0x45, 0xbe, 0xfe, 0xcb, 0x4b, 0xb1, 0x88, 0xfd, + 0x57, 0x76, 0x92, 0x6c, 0x49, 0xa3, 0x09, 0x5e, 0xb1, 0x08, 0xfd, 0x10, 0x98, 0xba, 0xec, 0x70, 0xaa, 0xa6, 0x69, 0x99, 0xa7, 0x2a, 0x82, 0xf2, 0x7d, 0x84, 0x8b, 0x21, 0xd4, 0xa7, 0x41, 0xb0, + 0xc5, 0xcd, 0x4d, 0x5f, 0xff, 0x9d, 0xac, 0x89, 0xae, 0xba, 0x12, 0x29, 0x61, 0xd0, 0x3a, 0x75, 0x71, 0x23, 0xe9, 0x87, 0x0f, 0x8a, 0xcf, 0x10, 0x00, 0x02, 0x08, 0x87, 0x89, 0x14, 0x29, 0xca, + 0x2a, 0x3e, 0x7a, 0x7d, 0x7d, 0xf7, 0xb1, 0x03, 0x55, 0x16, 0x5c, 0x8b, 0x9a, 0x6d, 0x0a, 0x7d, 0xe8, 0xb0, 0x62, 0xc4, 0x50, 0x0d, 0xc4, 0xcd, 0x12, 0x0c, 0x0f, 0x74, 0x18, 0xda, 0xe3, 0xd0, + 0xb5, 0x78, 0x1c, 0x34, 0x80, 0x3f, 0xa7, 0x54, 0x21, 0xc7, 0x90, 0xdf, 0xe1, 0xde, 0x18, 0x34, 0xf2, 0x80, 0xd7, 0x66, 0x7b, 0x32, 0x7f, 0x6c, 0x8c, 0xd7, 0x55, 0x7e, 0x12, 0xac, 0x3a, 0x0f, + 0x93, 0xec, 0x05, 0xc5, 0x2e, 0x04, 0x93, 0xef, 0x31, 0xa1, 0x2d, 0x3d, 0x92, 0x60, 0xf7, 0x9a, 0x28, 0x9d, 0x6a, 0x37, 0x9b, 0xc7, 0x0c, 0x50, 0x84, 0x14, 0x73, 0xd1, 0xa8, 0xcc, 0x81, 0xec, + 0x58, 0x3e, 0x96, 0x45, 0xe0, 0x7b, 0x8d, 0x96, 0x70, 0x65, 0x5b, 0xa5, 0xbb, 0xcf, 0xec, 0xc6, 0xdc, 0x39, 0x66, 0x38, 0x0a, 0xd8, 0xfe, 0xcb, 0x17, 0xb6, 0xba, 0x02, 0x46, 0x9a, 0x02, 0x0a, + 0x84, 0xe1, 0x8e, 0x8f, 0x84, 0x25, 0x20, 0x70, 0xc1, 0x3e, 0x9f, 0x1f, 0x28, 0x9b, 0xe5, 0x4f, 0xbc, 0x48, 0x14, 0x57, 0x77, 0x8f, 0x61, 0x60, 0x15, 0xe1, 0x32, 0x7a, 0x02, 0xb1, 0x40, 0xf1, + 0x50, 0x5e, 0xb3, 0x09, 0x32, 0x6d, 0x68, 0x37, 0x8f, 0x83, 0x74, 0x59, 0x5c, 0x84, 0x9d, 0x84, 0xf4, 0xc3, 0x33, 0xec, 0x44, 0x23, 0x88, 0x51, 0x43, 0xcb, 0x47, 0xbd, 0x71, 0xc5, 0xed, 0xae, + 0x9b, 0xe6, 0x9a, 0x2f, 0xfe, 0xce, 0xb1, 0xbe, 0xc9, 0xde, 0x24, 0x4f, 0xbe, 0x15, 0x99, 0x2b, 0x11, 0xb7, 0x7c, 0x04, 0x0f, 0x12, 0xbd, 0x8f, 0x6a, 0x97, 0x5a, 0x44, 0xa0, 0xf9, 0x0c, 0x29, + 0xa9, 0xab, 0xc3, 0xd4, 0xd8, 0x93, 0x92, 0x72, 0x84, 0xc5, 0x87, 0x54, 0xcc, 0xe2, 0x94, 0x52, 0x9f, 0x86, 0x14, 0xdc, 0xd2, 0xab, 0xa9, 0x91, 0x92, 0x5f, 0xed, 0xc4, 0xae, 0x74, 0xff, 0xac, + 0x6e, 0x33, 0x3b, 0x93, 0xeb, 0x4a, 0xff, 0x04, 0x79, 0xda, 0x9a, 0x41, 0x0e, 0x44, 0x50, 0xe0, 0xdd, 0x7a, 0xe4, 0xc6, 0xe2, 0x91, 0x09, 0x00, 0x57, 0x5d, 0xa4, 0x01, 0xfc, 0x07, 0x05, 0x9f, + 0x64, 0x5e, 0x8b, 0x7e, 0x9b, 0xfd, 0xef, 0x33, 0x94, 0x30, 0x54, 0xff, 0x84, 0x01, 0x14, 0x93, 0xc2, 0x7b, 0x34, 0x29, 0xea, 0xed, 0xb4, 0xed, 0x53, 0x76, 0x44, 0x1a, 0x77, 0xed, 0x43, 0x85, + 0x1a, 0xd7, 0x7f, 0x16, 0xf5, 0x41, 0xdf, 0xd2, 0x69, 0xd5, 0x0d, 0x6a, 0x5f, 0x14, 0xfb, 0x0a, 0xab, 0x1c, 0xbb, 0x4c, 0x15, 0x50, 0xbe, 0x97, 0xf7, 0xab, 0x40, 0x66, 0x19, 0x3c, 0x4c, 0xaa, + 0x77, 0x3d, 0xad, 0x38, 0x01, 0x4b, 0xd2, 0x09, 0x2f, 0xa7, 0x55, 0xc8, 0x24, 0xbb, 0x5e, 0x54, 0xc4, 0xf3, 0x6f, 0xfd, 0xa9, 0xfc, 0xea, 0x70, 0xb9, 0xc6, 0xe6, 0x93, 0xe1, 0x48, 0xc1, 0x51 + } + }, + { + // IEEE 1619 - Vector 11 + + { 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 }, + { 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }, + 0, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, + { + 0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6, 0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50, 0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02, 0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11, + 0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24, 0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4, 0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2, 0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2, + 0x46, 0x9e, 0xe4, 0xa4, 0xfa, 0x79, 0x4e, 0x4b, 0xbc, 0x7f, 0x39, 0xbc, 0x02, 0x6e, 0x3c, 0xb7, 0x2c, 0x33, 0xb0, 0x88, 0x8f, 0x25, 0xb4, 0xac, 0xf5, 0x6a, 0x2a, 0x98, 0x04, 0xf1, 0xce, 0x6d, + 0x3d, 0x6e, 0x1d, 0xc6, 0xca, 0x18, 0x1d, 0x4b, 0x54, 0x61, 0x79, 0xd5, 0x55, 0x44, 0xaa, 0x77, 0x60, 0xc4, 0x0d, 0x06, 0x74, 0x15, 0x39, 0xc7, 0xe3, 0xcd, 0x9d, 0x2f, 0x66, 0x50, 0xb2, 0x01, + 0x3f, 0xd0, 0xee, 0xb8, 0xc2, 0xb8, 0xe3, 0xd8, 0xd2, 0x40, 0xcc, 0xae, 0x2d, 0x4c, 0x98, 0x32, 0x0a, 0x74, 0x42, 0xe1, 0xc8, 0xd7, 0x5a, 0x42, 0xd6, 0xe6, 0xcf, 0xa4, 0xc2, 0xec, 0xa1, 0x79, + 0x8d, 0x15, 0x8c, 0x7a, 0xec, 0xdf, 0x82, 0x49, 0x0f, 0x24, 0xbb, 0x9b, 0x38, 0xe1, 0x08, 0xbc, 0xda, 0x12, 0xc3, 0xfa, 0xf9, 0xa2, 0x11, 0x41, 0xc3, 0x61, 0x3b, 0x58, 0x36, 0x7f, 0x92, 0x2a, + 0xaa, 0x26, 0xcd, 0x22, 0xf2, 0x3d, 0x70, 0x8d, 0xae, 0x69, 0x9a, 0xd7, 0xcb, 0x40, 0xa8, 0xad, 0x0b, 0x6e, 0x27, 0x84, 0x97, 0x3d, 0xcb, 0x60, 0x56, 0x84, 0xc0, 0x8b, 0x8d, 0x69, 0x98, 0xc6, + 0x9a, 0xac, 0x04, 0x99, 0x21, 0x87, 0x1e, 0xbb, 0x65, 0x30, 0x1a, 0x46, 0x19, 0xca, 0x80, 0xec, 0xb4, 0x85, 0xa3, 0x1d, 0x74, 0x42, 0x23, 0xce, 0x8d, 0xdc, 0x23, 0x94, 0x82, 0x8d, 0x6a, 0x80, + 0x47, 0x0c, 0x09, 0x2f, 0x5b, 0xa4, 0x13, 0xc3, 0x37, 0x8f, 0xa6, 0x05, 0x42, 0x55, 0xc6, 0xf9, 0xdf, 0x44, 0x95, 0x86, 0x2b, 0xbb, 0x32, 0x87, 0x68, 0x1f, 0x93, 0x1b, 0x68, 0x7c, 0x88, 0x8a, + 0xbf, 0x84, 0x4d, 0xfc, 0x8f, 0xc2, 0x83, 0x31, 0xe5, 0x79, 0x92, 0x8c, 0xd1, 0x2b, 0xd2, 0x39, 0x0a, 0xe1, 0x23, 0xcf, 0x03, 0x81, 0x8d, 0x14, 0xde, 0xdd, 0xe5, 0xc0, 0xc2, 0x4c, 0x8a, 0xb0, + 0x18, 0xbf, 0xca, 0x75, 0xca, 0x09, 0x6f, 0x2d, 0x53, 0x1f, 0x3d, 0x16, 0x19, 0xe7, 0x85, 0xf1, 0xad, 0xa4, 0x37, 0xca, 0xb9, 0x2e, 0x98, 0x05, 0x58, 0xb3, 0xdc, 0xe1, 0x47, 0x4a, 0xfb, 0x75, + 0xbf, 0xed, 0xbf, 0x8f, 0xf5, 0x4c, 0xb2, 0x61, 0x8e, 0x02, 0x44, 0xc9, 0xac, 0x0d, 0x3c, 0x66, 0xfb, 0x51, 0x59, 0x8c, 0xd2, 0xdb, 0x11, 0xf9, 0xbe, 0x39, 0x79, 0x1a, 0xbe, 0x44, 0x7c, 0x63, + 0x09, 0x4f, 0x7c, 0x45, 0x3b, 0x7f, 0xf8, 0x7c, 0xb5, 0xbb, 0x36, 0xb7, 0xc7, 0x9e, 0xfb, 0x08, 0x72, 0xd1, 0x70, 0x58, 0xb8, 0x3b, 0x15, 0xab, 0x08, 0x66, 0xad, 0x8a, 0x58, 0x65, 0x6c, 0x5a, + 0x7e, 0x20, 0xdb, 0xdf, 0x30, 0x8b, 0x24, 0x61, 0xd9, 0x7c, 0x0e, 0xc0, 0x02, 0x4a, 0x27, 0x15, 0x05, 0x52, 0x49, 0xcf, 0x3b, 0x47, 0x8d, 0xdd, 0x47, 0x40, 0xde, 0x65, 0x4f, 0x75, 0xca, 0x68, + 0x6e, 0x0d, 0x73, 0x45, 0xc6, 0x9e, 0xd5, 0x0c, 0xdc, 0x2a, 0x8b, 0x33, 0x2b, 0x1f, 0x88, 0x24, 0x10, 0x8a, 0xc9, 0x37, 0xeb, 0x05, 0x05, 0x85, 0x60, 0x8e, 0xe7, 0x34, 0x09, 0x7f, 0xc0, 0x90, + 0x54, 0xfb, 0xff, 0x89, 0xee, 0xae, 0xea, 0x79, 0x1f, 0x4a, 0x7a, 0xb1, 0xf9, 0x86, 0x82, 0x94, 0xa4, 0xf9, 0xe2, 0x7b, 0x42, 0xaf, 0x81, 0x00, 0xcb, 0x9d, 0x59, 0xce, 0xf9, 0x64, 0x58, 0x03 + } + }, + { + // IEEE 1619 - Vector 12 + + { 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 }, + { 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff }, + 0, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, + { + 0xe3, 0x87, 0xaa, 0xa5, 0x8b, 0xa4, 0x83, 0xaf, 0xa7, 0xe8, 0xeb, 0x46, 0x97, 0x78, 0x31, 0x7e, 0xcf, 0x4c, 0xf5, 0x73, 0xaa, 0x9d, 0x4e, 0xac, 0x23, 0xf2, 0xcd, 0xf9, 0x14, 0xe4, 0xe2, 0x00, + 0xa8, 0xb4, 0x90, 0xe4, 0x2e, 0xe6, 0x46, 0x80, 0x2d, 0xc6, 0xee, 0x2b, 0x47, 0x1b, 0x27, 0x81, 0x95, 0xd6, 0x09, 0x18, 0xec, 0xec, 0xb4, 0x4b, 0xf7, 0x99, 0x66, 0xf8, 0x3f, 0xab, 0xa0, 0x49, + 0x92, 0x98, 0xeb, 0xc6, 0x99, 0xc0, 0xc8, 0x63, 0x47, 0x15, 0xa3, 0x20, 0xbb, 0x4f, 0x07, 0x5d, 0x62, 0x2e, 0x74, 0xc8, 0xc9, 0x32, 0x00, 0x4f, 0x25, 0xb4, 0x1e, 0x36, 0x10, 0x25, 0xb5, 0xa8, + 0x78, 0x15, 0x39, 0x1f, 0x61, 0x08, 0xfc, 0x4a, 0xfa, 0x6a, 0x05, 0xd9, 0x30, 0x3c, 0x6b, 0xa6, 0x8a, 0x12, 0x8a, 0x55, 0x70, 0x5d, 0x41, 0x59, 0x85, 0x83, 0x2f, 0xde, 0xaa, 0xe6, 0xc8, 0xe1, + 0x91, 0x10, 0xe8, 0x4d, 0x1b, 0x1f, 0x19, 0x9a, 0x26, 0x92, 0x11, 0x9e, 0xdc, 0x96, 0x13, 0x26, 0x58, 0xf0, 0x9d, 0xa7, 0xc6, 0x23, 0xef, 0xce, 0xc7, 0x12, 0x53, 0x7a, 0x3d, 0x94, 0xc0, 0xbf, + 0x5d, 0x7e, 0x35, 0x2e, 0xc9, 0x4a, 0xe5, 0x79, 0x7f, 0xdb, 0x37, 0x7d, 0xc1, 0x55, 0x11, 0x50, 0x72, 0x1a, 0xdf, 0x15, 0xbd, 0x26, 0xa8, 0xef, 0xc2, 0xfc, 0xaa, 0xd5, 0x68, 0x81, 0xfa, 0x9e, + 0x62, 0x46, 0x2c, 0x28, 0xf3, 0x0a, 0xe1, 0xce, 0xac, 0xa9, 0x3c, 0x34, 0x5c, 0xf2, 0x43, 0xb7, 0x3f, 0x54, 0x2e, 0x20, 0x74, 0xa7, 0x05, 0xbd, 0x26, 0x43, 0xbb, 0x9f, 0x7c, 0xc7, 0x9b, 0xb6, + 0xe7, 0x09, 0x1e, 0xa6, 0xe2, 0x32, 0xdf, 0x0f, 0x9a, 0xd0, 0xd6, 0xcf, 0x50, 0x23, 0x27, 0x87, 0x6d, 0x82, 0x20, 0x7a, 0xbf, 0x21, 0x15, 0xcd, 0xac, 0xf6, 0xd5, 0xa4, 0x8f, 0x6c, 0x18, 0x79, + 0xa6, 0x5b, 0x11, 0x5f, 0x0f, 0x8b, 0x3c, 0xb3, 0xc5, 0x9d, 0x15, 0xdd, 0x8c, 0x76, 0x9b, 0xc0, 0x14, 0x79, 0x5a, 0x18, 0x37, 0xf3, 0x90, 0x1b, 0x58, 0x45, 0xeb, 0x49, 0x1a, 0xdf, 0xef, 0xe0, + 0x97, 0xb1, 0xfa, 0x30, 0xa1, 0x2f, 0xc1, 0xf6, 0x5b, 0xa2, 0x29, 0x05, 0x03, 0x15, 0x39, 0x97, 0x1a, 0x10, 0xf2, 0xf3, 0x6c, 0x32, 0x1b, 0xb5, 0x13, 0x31, 0xcd, 0xef, 0xb3, 0x9e, 0x39, 0x64, + 0xc7, 0xef, 0x07, 0x99, 0x94, 0xf5, 0xb6, 0x9b, 0x2e, 0xdd, 0x83, 0xa7, 0x1e, 0xf5, 0x49, 0x97, 0x1e, 0xe9, 0x3f, 0x44, 0xea, 0xc3, 0x93, 0x8f, 0xcd, 0xd6, 0x1d, 0x01, 0xfa, 0x71, 0x79, 0x9d, + 0xa3, 0xa8, 0x09, 0x1c, 0x4c, 0x48, 0xaa, 0x9e, 0xd2, 0x63, 0xff, 0x07, 0x49, 0xdf, 0x95, 0xd4, 0x4f, 0xef, 0x6a, 0x0b, 0xb5, 0x78, 0xec, 0x69, 0x45, 0x6a, 0xa5, 0x40, 0x8a, 0xe3, 0x2c, 0x7a, + 0xf0, 0x8a, 0xd7, 0xba, 0x89, 0x21, 0x28, 0x7e, 0x3b, 0xbe, 0xe3, 0x1b, 0x76, 0x7b, 0xe0, 0x6a, 0x0e, 0x70, 0x5c, 0x86, 0x4a, 0x76, 0x91, 0x37, 0xdf, 0x28, 0x29, 0x22, 0x83, 0xea, 0x81, 0xa2, + 0x48, 0x02, 0x41, 0xb4, 0x4d, 0x99, 0x21, 0xcd, 0xbe, 0xc1, 0xbc, 0x28, 0xdc, 0x1f, 0xda, 0x11, 0x4b, 0xd8, 0xe5, 0x21, 0x7a, 0xc9, 0xd8, 0xeb, 0xaf, 0xa7, 0x20, 0xe9, 0xda, 0x4f, 0x9a, 0xce, + 0x23, 0x1c, 0xc9, 0x49, 0xe5, 0xb9, 0x6f, 0xe7, 0x6f, 0xfc, 0x21, 0x06, 0x3f, 0xdd, 0xc8, 0x3a, 0x6b, 0x86, 0x79, 0xc0, 0x0d, 0x35, 0xe0, 0x95, 0x76, 0xa8, 0x75, 0x30, 0x5b, 0xed, 0x5f, 0x36, + 0xed, 0x24, 0x2c, 0x89, 0x00, 0xdd, 0x1f, 0xa9, 0x65, 0xbc, 0x95, 0x0d, 0xfc, 0xe0, 0x9b, 0x13, 0x22, 0x63, 0xa1, 0xee, 0xf5, 0x2d, 0xd6, 0x88, 0x8c, 0x30, 0x9f, 0x5a, 0x7d, 0x71, 0x28, 0x26 + } + }, + { + // IEEE 1619 - Vector 13 + + { 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 }, + { 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 }, + { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }, + 0, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, + { + 0xbf, 0x53, 0xd2, 0xda, 0xde, 0x78, 0xe8, 0x22, 0xa4, 0xd9, 0x49, 0xa9, 0xbc, 0x67, 0x66, 0xb0, 0x1b, 0x06, 0xa8, 0xef, 0x70, 0xd2, 0x67, 0x48, 0xc6, 0xa7, 0xfc, 0x36, 0xd8, 0x0a, 0xe4, 0xc5, + 0x52, 0x0f, 0x7c, 0x4a, 0xb0, 0xac, 0x85, 0x44, 0x42, 0x4f, 0xa4, 0x05, 0x16, 0x2f, 0xef, 0x5a, 0x6b, 0x7f, 0x22, 0x94, 0x98, 0x06, 0x36, 0x18, 0xd3, 0x9f, 0x00, 0x03, 0xcb, 0x5f, 0xb8, 0xd1, + 0xc8, 0x6b, 0x64, 0x34, 0x97, 0xda, 0x1f, 0xf9, 0x45, 0xc8, 0xd3, 0xbe, 0xde, 0xca, 0x4f, 0x47, 0x97, 0x02, 0xa7, 0xa7, 0x35, 0xf0, 0x43, 0xdd, 0xb1, 0xd6, 0xaa, 0xad, 0xe3, 0xc4, 0xa0, 0xac, + 0x7c, 0xa7, 0xf3, 0xfa, 0x52, 0x79, 0xbe, 0xf5, 0x6f, 0x82, 0xcd, 0x7a, 0x2f, 0x38, 0x67, 0x2e, 0x82, 0x48, 0x14, 0xe1, 0x07, 0x00, 0x30, 0x0a, 0x05, 0x5e, 0x16, 0x30, 0xb8, 0xf1, 0xcb, 0x0e, + 0x91, 0x9f, 0x5e, 0x94, 0x20, 0x10, 0xa4, 0x16, 0xe2, 0xbf, 0x48, 0xcb, 0x46, 0x99, 0x3d, 0x3c, 0xb6, 0xa5, 0x1c, 0x19, 0xba, 0xcf, 0x86, 0x47, 0x85, 0xa0, 0x0b, 0xc2, 0xec, 0xff, 0x15, 0xd3, + 0x50, 0x87, 0x5b, 0x24, 0x6e, 0xd5, 0x3e, 0x68, 0xbe, 0x6f, 0x55, 0xbd, 0x7e, 0x05, 0xcf, 0xc2, 0xb2, 0xed, 0x64, 0x32, 0x19, 0x8a, 0x64, 0x44, 0xb6, 0xd8, 0xc2, 0x47, 0xfa, 0xb9, 0x41, 0xf5, + 0x69, 0x76, 0x8b, 0x5c, 0x42, 0x93, 0x66, 0xf1, 0xd3, 0xf0, 0x0f, 0x03, 0x45, 0xb9, 0x61, 0x23, 0xd5, 0x62, 0x04, 0xc0, 0x1c, 0x63, 0xb2, 0x2c, 0xe7, 0x8b, 0xaf, 0x11, 0x6e, 0x52, 0x5e, 0xd9, + 0x0f, 0xde, 0xa3, 0x9f, 0xa4, 0x69, 0x49, 0x4d, 0x38, 0x66, 0xc3, 0x1e, 0x05, 0xf2, 0x95, 0xff, 0x21, 0xfe, 0xa8, 0xd4, 0xe6, 0xe1, 0x3d, 0x67, 0xe4, 0x7c, 0xe7, 0x22, 0xe9, 0x69, 0x8a, 0x1c, + 0x10, 0x48, 0xd6, 0x8e, 0xbc, 0xde, 0x76, 0xb8, 0x6f, 0xcf, 0x97, 0x6e, 0xab, 0x8a, 0xa9, 0x79, 0x02, 0x68, 0xb7, 0x06, 0x8e, 0x01, 0x7a, 0x8b, 0x9b, 0x74, 0x94, 0x09, 0x51, 0x4f, 0x10, 0x53, + 0x02, 0x7f, 0xd1, 0x6c, 0x37, 0x86, 0xea, 0x1b, 0xac, 0x5f, 0x15, 0xcb, 0x79, 0x71, 0x1e, 0xe2, 0xab, 0xe8, 0x2f, 0x5c, 0xf8, 0xb1, 0x3a, 0xe7, 0x30, 0x30, 0xef, 0x5b, 0x9e, 0x44, 0x57, 0xe7, + 0x5d, 0x13, 0x04, 0xf9, 0x88, 0xd6, 0x2d, 0xd6, 0xfc, 0x4b, 0x94, 0xed, 0x38, 0xba, 0x83, 0x1d, 0xa4, 0xb7, 0x63, 0x49, 0x71, 0xb6, 0xcd, 0x8e, 0xc3, 0x25, 0xd9, 0xc6, 0x1c, 0x00, 0xf1, 0xdf, + 0x73, 0x62, 0x7e, 0xd3, 0x74, 0x5a, 0x5e, 0x84, 0x89, 0xf3, 0xa9, 0x5c, 0x69, 0x63, 0x9c, 0x32, 0xcd, 0x6e, 0x1d, 0x53, 0x7a, 0x85, 0xf7, 0x5c, 0xc8, 0x44, 0x72, 0x6e, 0x8a, 0x72, 0xfc, 0x00, + 0x77, 0xad, 0x22, 0x00, 0x0f, 0x1d, 0x50, 0x78, 0xf6, 0xb8, 0x66, 0x31, 0x8c, 0x66, 0x8f, 0x1a, 0xd0, 0x3d, 0x5a, 0x5f, 0xce, 0xd5, 0x21, 0x9f, 0x2e, 0xab, 0xbd, 0x0a, 0xa5, 0xc0, 0xf4, 0x60, + 0xd1, 0x83, 0xf0, 0x44, 0x04, 0xa0, 0xd6, 0xf4, 0x69, 0x55, 0x8e, 0x81, 0xfa, 0xb2, 0x4a, 0x16, 0x79, 0x05, 0xab, 0x4c, 0x78, 0x78, 0x50, 0x2a, 0xd3, 0xe3, 0x8f, 0xdb, 0xe6, 0x2a, 0x41, 0x55, + 0x6c, 0xec, 0x37, 0x32, 0x57, 0x59, 0x53, 0x3c, 0xe8, 0xf2, 0x5f, 0x36, 0x7c, 0x87, 0xbb, 0x55, 0x78, 0xd6, 0x67, 0xae, 0x93, 0xf9, 0xe2, 0xfd, 0x99, 0xbc, 0xbc, 0x5f, 0x2f, 0xbb, 0xa8, 0x8c, + 0xf6, 0x51, 0x61, 0x39, 0x42, 0x0f, 0xcf, 0xf3, 0xb7, 0x36, 0x1d, 0x86, 0x32, 0x2c, 0x4b, 0xd8, 0x4c, 0x82, 0xf3, 0x35, 0xab, 0xb1, 0x52, 0xc4, 0xa9, 0x34, 0x11, 0x37, 0x3a, 0xaa, 0x82, 0x20 + } + }, + { + // IEEE 1619 - Vector 14 + + { 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27 }, + { 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92 }, + { 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff }, + 0, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }, + { + 0x64, 0x49, 0x7e, 0x5a, 0x83, 0x1e, 0x4a, 0x93, 0x2c, 0x09, 0xbe, 0x3e, 0x53, 0x93, 0x37, 0x6d, 0xaa, 0x59, 0x95, 0x48, 0xb8, 0x16, 0x03, 0x1d, 0x22, 0x4b, 0xbf, 0x50, 0xa8, 0x18, 0xed, 0x23, + 0x50, 0xea, 0xe7, 0xe9, 0x60, 0x87, 0xc8, 0xa0, 0xdb, 0x51, 0xad, 0x29, 0x0b, 0xd0, 0x0c, 0x1a, 0xc1, 0x62, 0x08, 0x57, 0x63, 0x5b, 0xf2, 0x46, 0xc1, 0x76, 0xab, 0x46, 0x3b, 0xe3, 0x0b, 0x80, + 0x8d, 0xa5, 0x48, 0x08, 0x1a, 0xc8, 0x47, 0xb1, 0x58, 0xe1, 0x26, 0x4b, 0xe2, 0x5b, 0xb0, 0x91, 0x0b, 0xbc, 0x92, 0x64, 0x71, 0x08, 0x08, 0x94, 0x15, 0xd4, 0x5f, 0xab, 0x1b, 0x3d, 0x26, 0x04, + 0xe8, 0xa8, 0xef, 0xf1, 0xae, 0x40, 0x20, 0xcf, 0xa3, 0x99, 0x36, 0xb6, 0x68, 0x27, 0xb2, 0x3f, 0x37, 0x1b, 0x92, 0x20, 0x0b, 0xe9, 0x02, 0x51, 0xe6, 0xd7, 0x3c, 0x5f, 0x86, 0xde, 0x5f, 0xd4, + 0xa9, 0x50, 0x78, 0x19, 0x33, 0xd7, 0x9a, 0x28, 0x27, 0x2b, 0x78, 0x2a, 0x2e, 0xc3, 0x13, 0xef, 0xdf, 0xcc, 0x06, 0x28, 0xf4, 0x3d, 0x74, 0x4c, 0x2d, 0xc2, 0xff, 0x3d, 0xcb, 0x66, 0x99, 0x9b, + 0x50, 0xc7, 0xca, 0x89, 0x5b, 0x0c, 0x64, 0x79, 0x1e, 0xea, 0xa5, 0xf2, 0x94, 0x99, 0xfb, 0x1c, 0x02, 0x6f, 0x84, 0xce, 0x5b, 0x5c, 0x72, 0xba, 0x10, 0x83, 0xcd, 0xdb, 0x5c, 0xe4, 0x54, 0x34, + 0x63, 0x16, 0x65, 0xc3, 0x33, 0xb6, 0x0b, 0x11, 0x59, 0x3f, 0xb2, 0x53, 0xc5, 0x17, 0x9a, 0x2c, 0x8d, 0xb8, 0x13, 0x78, 0x2a, 0x00, 0x48, 0x56, 0xa1, 0x65, 0x30, 0x11, 0xe9, 0x3f, 0xb6, 0xd8, + 0x76, 0xc1, 0x83, 0x66, 0xdd, 0x86, 0x83, 0xf5, 0x34, 0x12, 0xc0, 0xc1, 0x80, 0xf9, 0xc8, 0x48, 0x59, 0x2d, 0x59, 0x3f, 0x86, 0x09, 0xca, 0x73, 0x63, 0x17, 0xd3, 0x56, 0xe1, 0x3e, 0x2b, 0xff, + 0x3a, 0x9f, 0x59, 0xcd, 0x9a, 0xeb, 0x19, 0xcd, 0x48, 0x25, 0x93, 0xd8, 0xc4, 0x61, 0x28, 0xbb, 0x32, 0x42, 0x3b, 0x37, 0xa9, 0xad, 0xfb, 0x48, 0x2b, 0x99, 0x45, 0x3f, 0xbe, 0x25, 0xa4, 0x1b, + 0xf6, 0xfe, 0xb4, 0xaa, 0x0b, 0xef, 0x5e, 0xd2, 0x4b, 0xf7, 0x3c, 0x76, 0x29, 0x78, 0x02, 0x54, 0x82, 0xc1, 0x31, 0x15, 0xe4, 0x01, 0x5a, 0xac, 0x99, 0x2e, 0x56, 0x13, 0xa3, 0xb5, 0xc2, 0xf6, + 0x85, 0xb8, 0x47, 0x95, 0xcb, 0x6e, 0x9b, 0x26, 0x56, 0xd8, 0xc8, 0x81, 0x57, 0xe5, 0x2c, 0x42, 0xf9, 0x78, 0xd8, 0x63, 0x4c, 0x43, 0xd0, 0x6f, 0xea, 0x92, 0x8f, 0x28, 0x22, 0xe4, 0x65, 0xaa, + 0x65, 0x76, 0xe9, 0xbf, 0x41, 0x93, 0x84, 0x50, 0x6c, 0xc3, 0xce, 0x3c, 0x54, 0xac, 0x1a, 0x6f, 0x67, 0xdc, 0x66, 0xf3, 0xb3, 0x01, 0x91, 0xe6, 0x98, 0x38, 0x0b, 0xc9, 0x99, 0xb0, 0x5a, 0xbc, + 0xe1, 0x9d, 0xc0, 0xc6, 0xdc, 0xc2, 0xdd, 0x00, 0x1e, 0xc5, 0x35, 0xba, 0x18, 0xde, 0xb2, 0xdf, 0x1a, 0x10, 0x10, 0x23, 0x10, 0x83, 0x18, 0xc7, 0x5d, 0xc9, 0x86, 0x11, 0xa0, 0x9d, 0xc4, 0x8a, + 0x0a, 0xcd, 0xec, 0x67, 0x6f, 0xab, 0xdf, 0x22, 0x2f, 0x07, 0xe0, 0x26, 0xf0, 0x59, 0xb6, 0x72, 0xb5, 0x6e, 0x5c, 0xbc, 0x8e, 0x1d, 0x21, 0xbb, 0xd8, 0x67, 0xdd, 0x92, 0x72, 0x12, 0x05, 0x46, + 0x81, 0xd7, 0x0e, 0xa7, 0x37, 0x13, 0x4c, 0xdf, 0xce, 0x93, 0xb6, 0xf8, 0x2a, 0xe2, 0x24, 0x23, 0x27, 0x4e, 0x58, 0xa0, 0x82, 0x1c, 0xc5, 0x50, 0x2e, 0x2d, 0x0a, 0xb4, 0x58, 0x5e, 0x94, 0xde, + 0x69, 0x75, 0xbe, 0x5e, 0x0b, 0x4e, 0xfc, 0xe5, 0x1c, 0xd3, 0xe7, 0x0c, 0x25, 0xa1, 0xfb, 0xbb, 0xd6, 0x09, 0xd2, 0x73, 0xad, 0x5b, 0x0d, 0x59, 0x63, 0x1c, 0x53, 0x1f, 0x6a, 0x0a, 0x57, 0xb9 + } + } + }; + + void EncryptionTest::TestXtsAES () + { + unsigned __int8 p[ENCRYPTION_DATA_UNIT_SIZE]; + uint64 dataUnitNo; + size_t i; + + for (i = 0; i < array_capacity (XtsTestVectors); i++) + { + AES aes; + shared_ptr xts (new EncryptionModeXTS); + + aes.SetKey (ConstBufferPtr (XtsTestVectors[i].key1, sizeof (XtsTestVectors[i].key1))); + xts->SetKey (ConstBufferPtr (XtsTestVectors[i].key2, sizeof (XtsTestVectors[i].key2))); + aes.SetMode (xts); + + memcpy (p, XtsTestVectors[i].plaintext, sizeof (p)); + + dataUnitNo = Endian::Big (*((uint64 *) XtsTestVectors[i].dataUnitNo)); + + aes.EncryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + + aes.DecryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + if (memcmp (XtsTestVectors[i].ciphertext, p, sizeof (p)) == 0) + throw TestFailed (SRC_POS); + + aes.EncryptSectors (p, dataUnitNo, sizeof (p) / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + + if (memcmp (XtsTestVectors[i].ciphertext, p, sizeof (p)) != 0) + throw TestFailed (SRC_POS); + } + } + + void EncryptionTest::TestXts () + { + unsigned char buf [ENCRYPTION_DATA_UNIT_SIZE * 4]; + unsigned int i; + uint32 crc; + uint64 unitNo; + uint64 nbrUnits; + uint64 writeOffset; + int testCase = 0; + int nTestsPerformed = 0; + + static const byte testKey[] = + { + 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27, + 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 + }; + + /* Encryption/decryption of data units (typically, volume data sectors) */ + + nbrUnits = sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE; + + /* The buffer can accommodate 4 data units and we'll test 4 cases by "scrolling". The data unit 0xFFFFFFFFFF + will "move" from the start of the buffer to its end. For a 512-byte data unit, the byte offset 562949953420800 + corresponds to the data unit 0xFFFFFFFFFF. */ + for (writeOffset = 562949953420800LL; + writeOffset > 562949953420800LL - nbrUnits * ENCRYPTION_DATA_UNIT_SIZE; + writeOffset -= ENCRYPTION_DATA_UNIT_SIZE) + { + unitNo = writeOffset / ENCRYPTION_DATA_UNIT_SIZE; + + // Test all EAs that support this mode of operation + foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms()) + { + shared_ptr mode (new EncryptionModeXTS); + + if (!ea.IsModeSupported (mode)) + continue; + + ea.SetKey (ConstBufferPtr (testKey, ea.GetKeySize())); + + Buffer modeKey (ea.GetKeySize()); + for (size_t mi = 0; mi < modeKey.Size(); mi++) + modeKey[mi] = (byte) mi; + modeKey.CopyFrom (ConstBufferPtr (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2, sizeof (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2))); + + mode->SetKey (modeKey); + ea.SetMode (mode); + + // Each data unit will contain the same plaintext + for (i = 0; i < nbrUnits; i++) + { + memcpy ((unsigned char *) buf + i * ENCRYPTION_DATA_UNIT_SIZE, + XtsTestVectors[array_capacity (XtsTestVectors)-1].plaintext, + ENCRYPTION_DATA_UNIT_SIZE); + } + + ea.EncryptSectors (buf, unitNo, nbrUnits, ENCRYPTION_DATA_UNIT_SIZE); + + crc = GetCrc32 (buf, sizeof (buf)); + + if (typeid (ea) == typeid (AES)) + { + // Verify the ciphertext of the "moving" data unit using the IEEE test vector #14 + if (memcmp (XtsTestVectors[array_capacity (XtsTestVectors)-1].ciphertext, + (unsigned char *) buf + testCase * ENCRYPTION_DATA_UNIT_SIZE, + ENCRYPTION_DATA_UNIT_SIZE) != 0) + { + throw TestFailed (SRC_POS); + } + + // CRC of all data units in the buffer for each test case + switch (testCase) + { + case 0: + if (crc != 0x888f2990) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0xea28ea34) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0xe058f5a2) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0x10473dc9) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (Serpent)) + { + switch (testCase) + { + case 0: + if (crc != 0x7edfecb3) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x357baaaa) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0xc7b9fca5) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xb5263e0c) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (Twofish)) + { + switch (testCase) + { + case 0: + if (crc != 0x91525124) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x2895cc47) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0x6bee346d) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xb1c45759) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (AESTwofish)) + { + switch (testCase) + { + case 0: + if (crc != 0x6cea7fa2) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x69052c4c) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0x88db8de5) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xf16fd8c5) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (AESTwofishSerpent)) + { + switch (testCase) + { + case 0: + if (crc != 0xa2d7d82a) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0xdbf76412) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0xdf0ea03e) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xdadedff7) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (SerpentAES)) + { + switch (testCase) + { + case 0: + if (crc != 0x6dd133b3) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x0e5717d2) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0x39f83cd9) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0x8a79fa2c) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (SerpentTwofishAES)) + { + switch (testCase) + { + case 0: + if (crc != 0xe536daf8) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x3ae89e7f) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0x2cc1301a) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xcac7bdc7) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + else if (typeid (ea) == typeid (TwofishSerpent)) + { + switch (testCase) + { + case 0: + if (crc != 0x2686c859) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 1: + if (crc != 0x8a201780) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 2: + if (crc != 0x8dd13796) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + case 3: + if (crc != 0xe95196cb) + throw TestFailed (SRC_POS); + nTestsPerformed++; + break; + } + } + + if (crc == 0x9f5edd58) + throw TestFailed (SRC_POS); + + ea.DecryptSectors (buf, unitNo, nbrUnits, ENCRYPTION_DATA_UNIT_SIZE); + + if (GetCrc32 (buf, sizeof (buf)) != 0x9f5edd58) + throw TestFailed (SRC_POS); + + nTestsPerformed++; + } + testCase++; + } + + /* Encryption/decryption of a buffer (typically, a volume header) */ + + nbrUnits = sizeof (buf) / ENCRYPTION_DATA_UNIT_SIZE; + + // Test all EAs that support this mode of operation + foreach_ref (EncryptionAlgorithm &ea, EncryptionAlgorithm::GetAvailableAlgorithms()) + { + shared_ptr mode (new EncryptionModeXTS); + + if (!ea.IsModeSupported (mode)) + continue; + + ea.SetKey (ConstBufferPtr (testKey, ea.GetKeySize())); + + Buffer modeKey (ea.GetKeySize()); + for (size_t mi = 0; mi < modeKey.Size(); mi++) + modeKey[mi] = (byte) mi; + modeKey.CopyFrom (ConstBufferPtr (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2, sizeof (XtsTestVectors[array_capacity (XtsTestVectors)-1].key2))); + + mode->SetKey (modeKey); + ea.SetMode (mode); + + // Each data unit will contain the same plaintext + for (i = 0; i < nbrUnits; i++) + { + memcpy ((unsigned char *) buf + i * ENCRYPTION_DATA_UNIT_SIZE, + XtsTestVectors[array_capacity (XtsTestVectors)-1].plaintext, + ENCRYPTION_DATA_UNIT_SIZE); + } + + ea.Encrypt (buf, sizeof (buf)); + + crc = GetCrc32 (buf, sizeof (buf)); + + if (typeid (ea) == typeid (AES)) + { + if (crc != 0x33b91fab) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (Serpent)) + { + if (crc != 0x3494d480) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (Twofish)) + { + if (crc != 0xc4d65b46) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (AESTwofish)) + { + if (crc != 0x14ce7385) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (AESTwofishSerpent)) + { + if (crc != 0x0ec81bf7) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (SerpentAES)) + { + if (crc != 0x42f919ad) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (SerpentTwofishAES)) + { + if (crc != 0x208d5c58) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + else if (typeid (ea) == typeid (TwofishSerpent)) + { + if (crc != 0xbe78cec1) + throw TestFailed (SRC_POS); + nTestsPerformed++; + } + + if (crc == 0x9f5edd58) + throw TestFailed (SRC_POS); + + ea.Decrypt (buf, sizeof (buf)); + + if (GetCrc32 (buf, sizeof (buf)) != 0x9f5edd58) + throw TestFailed (SRC_POS); + + nTestsPerformed++; + } + + if (nTestsPerformed != 80) + throw TestFailed (SRC_POS); + } + + void EncryptionTest::TestPkcs5 () + { + VolumePassword password ("password", 8); + static const byte saltData[] = { 0x12, 0x34, 0x56, 0x78 }; + ConstBufferPtr salt (saltData, sizeof (saltData)); + Buffer derivedKey (4); + + Pkcs5HmacRipemd160 pkcs5HmacRipemd160; + pkcs5HmacRipemd160.DeriveKey (derivedKey, password, salt, 5); + if (memcmp (derivedKey.Ptr(), "\x7a\x3d\x7c\x03", 4) != 0) + throw TestFailed (SRC_POS); + + Pkcs5HmacSha1 pkcs5HmacSha1; + pkcs5HmacSha1.DeriveKey (derivedKey, password, salt, 5); + if (memcmp (derivedKey.Ptr(), "\x5c\x75\xce\xf0", 4) != 0) + throw TestFailed (SRC_POS); + + Pkcs5HmacSha512 pkcs5HmacSha512; + pkcs5HmacSha512.DeriveKey (derivedKey, password, salt, 5); + if (memcmp (derivedKey.Ptr(), "\x13\x64\xae\xf8", 4) != 0) + throw TestFailed (SRC_POS); + + Pkcs5HmacWhirlpool pkcs5HmacWhirlpool; + pkcs5HmacWhirlpool.DeriveKey (derivedKey, password, salt, 5); + if (memcmp (derivedKey.Ptr(), "\x50\x7c\x36\x6f", 4) != 0) + throw TestFailed (SRC_POS); + } +} diff --git a/src/Volume/EncryptionTest.h b/src/Volume/EncryptionTest.h new file mode 100644 index 00000000..40221ae0 --- /dev/null +++ b/src/Volume/EncryptionTest.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_EncryptionTest +#define TC_HEADER_Encryption_EncryptionTest + +#include "Platform/Platform.h" +#include "Common/Crypto.h" + +namespace TrueCrypt +{ + class EncryptionTest + { + public: + static void TestAll (); + static void TestAll (bool enableCpuEncryptionSupport); + + protected: + static void TestCiphers (); + static void TestLegacyModes (); + static void TestPkcs5 (); + static void TestXts (); + static void TestXtsAES (); + + struct XtsTestVector + { + byte key1[32]; + byte key2[32]; + byte dataUnitNo[8]; + unsigned int blockNo; + byte plaintext[ENCRYPTION_DATA_UNIT_SIZE]; + byte ciphertext[ENCRYPTION_DATA_UNIT_SIZE]; + }; + + static const XtsTestVector XtsTestVectors[]; + + private: + EncryptionTest (); + virtual ~EncryptionTest (); + EncryptionTest (const EncryptionTest &); + EncryptionTest &operator= (const EncryptionTest &); + }; +} + +#endif // TC_HEADER_Encryption_EncryptionTest diff --git a/src/Volume/EncryptionThreadPool.cpp b/src/Volume/EncryptionThreadPool.cpp new file mode 100644 index 00000000..dbcc1b35 --- /dev/null +++ b/src/Volume/EncryptionThreadPool.cpp @@ -0,0 +1,325 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifdef TC_UNIX +# include +#endif + +#ifdef TC_MACOSX +# include +# include +#endif + +#include "Platform/SyncEvent.h" +#include "Platform/SystemLog.h" +#include "Common/Crypto.h" +#include "EncryptionThreadPool.h" + +namespace TrueCrypt +{ + void EncryptionThreadPool::DoWork (WorkType::Enum type, const EncryptionMode *encryptionMode, byte *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize) + { + size_t fragmentCount; + size_t unitsPerFragment; + size_t remainder; + + byte *fragmentData; + uint64 fragmentStartUnitNo; + + WorkItem *workItem; + WorkItem *firstFragmentWorkItem; + + if (unitCount == 0) + return; + + if (!ThreadPoolRunning || unitCount == 1) + { + switch (type) + { + case WorkType::DecryptDataUnits: + encryptionMode->DecryptSectorsCurrentThread (data, startUnitNo, unitCount, sectorSize); + break; + + case WorkType::EncryptDataUnits: + encryptionMode->EncryptSectorsCurrentThread (data, startUnitNo, unitCount, sectorSize); + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + + return; + } + + if (unitCount <= ThreadCount) + { + fragmentCount = (size_t) unitCount; + unitsPerFragment = 1; + remainder = 0; + } + else + { + fragmentCount = ThreadCount; + unitsPerFragment = (size_t) unitCount / ThreadCount; + remainder = (size_t) unitCount % ThreadCount; + + if (remainder > 0) + ++unitsPerFragment; + } + + fragmentData = data; + fragmentStartUnitNo = startUnitNo; + + { + ScopeLock lock (EnqueueMutex); + firstFragmentWorkItem = &WorkItemQueue[EnqueuePosition]; + + while (firstFragmentWorkItem->State != WorkItem::State::Free) + { + WorkItemCompletedEvent.Wait(); + } + + firstFragmentWorkItem->OutstandingFragmentCount.Set (fragmentCount); + firstFragmentWorkItem->ItemException.reset(); + + while (fragmentCount-- > 0) + { + workItem = &WorkItemQueue[EnqueuePosition++]; + + if (EnqueuePosition >= QueueSize) + EnqueuePosition = 0; + + while (workItem->State != WorkItem::State::Free) + { + WorkItemCompletedEvent.Wait(); + } + + workItem->Type = type; + workItem->FirstFragment = firstFragmentWorkItem; + + workItem->Encryption.Mode = encryptionMode; + workItem->Encryption.Data = fragmentData; + workItem->Encryption.UnitCount = unitsPerFragment; + workItem->Encryption.StartUnitNo = fragmentStartUnitNo; + workItem->Encryption.SectorSize = sectorSize; + + fragmentData += unitsPerFragment * ENCRYPTION_DATA_UNIT_SIZE; + fragmentStartUnitNo += unitsPerFragment; + + if (remainder > 0 && --remainder == 0) + --unitsPerFragment; + + workItem->State.Set (WorkItem::State::Ready); + WorkItemReadyEvent.Signal(); + } + } + + firstFragmentWorkItem->ItemCompletedEvent.Wait(); + + auto_ptr itemException; + if (firstFragmentWorkItem->ItemException.get()) + itemException = firstFragmentWorkItem->ItemException; + + firstFragmentWorkItem->State.Set (WorkItem::State::Free); + WorkItemCompletedEvent.Signal(); + + if (itemException.get()) + itemException->Throw(); + } + + void EncryptionThreadPool::Start () + { + if (ThreadPoolRunning) + return; + + size_t cpuCount; + +#ifdef TC_WINDOWS + + SYSTEM_INFO sysInfo; + GetSystemInfo (&sysInfo); + cpuCount = sysInfo.dwNumberOfProcessors; + +#elif defined (_SC_NPROCESSORS_ONLN) + + cpuCount = (size_t) sysconf (_SC_NPROCESSORS_ONLN); + if (cpuCount == (size_t) -1) + cpuCount = 1; + +#elif defined (TC_MACOSX) + + int cpuCountSys; + int mib[2] = { CTL_HW, HW_NCPU }; + + size_t len = sizeof (cpuCountSys); + if (sysctl (mib, 2, &cpuCountSys, &len, nullptr, 0) == -1) + cpuCountSys = 1; + + cpuCount = (size_t) cpuCountSys; + +#else +# error Cannot determine CPU count +#endif + + if (cpuCount < 2) + return; + + if (cpuCount > MaxThreadCount) + cpuCount = MaxThreadCount; + + StopPending = false; + DequeuePosition = 0; + EnqueuePosition = 0; + + for (size_t i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i) + { + WorkItemQueue[i].State.Set (WorkItem::State::Free); + } + + try + { + for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount) + { + struct ThreadFunctor : public Functor + { + virtual void operator() () + { + WorkThreadProc(); + } + }; + + make_shared_auto (Thread, thread); + thread->Start (new ThreadFunctor ()); + RunningThreads.push_back (thread); + } + } + catch (...) + { + try + { + ThreadPoolRunning = true; + Stop(); + } catch (...) { } + + throw; + } + + ThreadPoolRunning = true; + } + + void EncryptionThreadPool::Stop () + { + if (!ThreadPoolRunning) + return; + + StopPending = true; + WorkItemReadyEvent.Signal(); + + foreach_ref (const Thread &thread, RunningThreads) + { + thread.Join(); + } + + ThreadCount = 0; + ThreadPoolRunning = false; + } + + void EncryptionThreadPool::WorkThreadProc () + { + try + { + WorkItem *workItem; + + while (!StopPending) + { + { + ScopeLock lock (DequeueMutex); + + workItem = &WorkItemQueue[DequeuePosition++]; + + if (DequeuePosition >= QueueSize) + DequeuePosition = 0; + + while (!StopPending && workItem->State != WorkItem::State::Ready) + { + WorkItemReadyEvent.Wait(); + } + + workItem->State.Set (WorkItem::State::Busy); + } + + if (StopPending) + break; + + try + { + switch (workItem->Type) + { + case WorkType::DecryptDataUnits: + workItem->Encryption.Mode->DecryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize); + break; + + case WorkType::EncryptDataUnits: + workItem->Encryption.Mode->EncryptSectorsCurrentThread (workItem->Encryption.Data, workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.SectorSize); + break; + + default: + throw ParameterIncorrect (SRC_POS); + } + } + catch (Exception &e) + { + workItem->FirstFragment->ItemException.reset (e.CloneNew()); + } + catch (exception &e) + { + workItem->FirstFragment->ItemException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e))); + } + catch (...) + { + workItem->FirstFragment->ItemException.reset (new UnknownException (SRC_POS)); + } + + if (workItem != workItem->FirstFragment) + { + workItem->State.Set (WorkItem::State::Free); + WorkItemCompletedEvent.Signal(); + } + + if (workItem->FirstFragment->OutstandingFragmentCount.Decrement() == 0) + workItem->FirstFragment->ItemCompletedEvent.Signal(); + } + } + catch (exception &e) + { + SystemLog::WriteException (e); + } + catch (...) + { + SystemLog::WriteException (UnknownException (SRC_POS)); + } + } + + volatile bool EncryptionThreadPool::ThreadPoolRunning = false; + volatile bool EncryptionThreadPool::StopPending = false; + + size_t EncryptionThreadPool::ThreadCount; + + EncryptionThreadPool::WorkItem EncryptionThreadPool::WorkItemQueue[QueueSize]; + + volatile size_t EncryptionThreadPool::EnqueuePosition; + volatile size_t EncryptionThreadPool::DequeuePosition; + + Mutex EncryptionThreadPool::EnqueueMutex; + Mutex EncryptionThreadPool::DequeueMutex; + + SyncEvent EncryptionThreadPool::WorkItemReadyEvent; + SyncEvent EncryptionThreadPool::WorkItemCompletedEvent; + + list < shared_ptr > EncryptionThreadPool::RunningThreads; +} diff --git a/src/Volume/EncryptionThreadPool.h b/src/Volume/EncryptionThreadPool.h new file mode 100644 index 00000000..70d87021 --- /dev/null +++ b/src/Volume/EncryptionThreadPool.h @@ -0,0 +1,87 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_EncryptionThreadPool +#define TC_HEADER_Volume_EncryptionThreadPool + +#include "Platform/Platform.h" +#include "EncryptionMode.h" + +namespace TrueCrypt +{ + class EncryptionThreadPool + { + public: + struct WorkType + { + enum Enum + { + EncryptDataUnits, + DecryptDataUnits, + DeriveKey + }; + }; + + struct WorkItem + { + struct State + { + enum Enum + { + Free, + Ready, + Busy + }; + }; + + struct WorkItem *FirstFragment; + auto_ptr ItemException; + SyncEvent ItemCompletedEvent; + SharedVal OutstandingFragmentCount; + SharedVal State; + WorkType::Enum Type; + + union + { + struct + { + const EncryptionMode *Mode; + byte *Data; + uint64 StartUnitNo; + uint64 UnitCount; + size_t SectorSize; + } Encryption; + }; + }; + + static void DoWork (WorkType::Enum type, const EncryptionMode *mode, byte *data, uint64 startUnitNo, uint64 unitCount, size_t sectorSize); + static bool IsRunning () { return ThreadPoolRunning; } + static void Start (); + static void Stop (); + + protected: + static void WorkThreadProc (); + + static const size_t MaxThreadCount = 32; + static const size_t QueueSize = MaxThreadCount * 2; + + static Mutex DequeueMutex; + static volatile size_t DequeuePosition; + static volatile size_t EnqueuePosition; + static Mutex EnqueueMutex; + static list < shared_ptr > RunningThreads; + static volatile bool StopPending; + static size_t ThreadCount; + static volatile bool ThreadPoolRunning; + static SyncEvent WorkItemCompletedEvent; + static WorkItem WorkItemQueue[QueueSize]; + static SyncEvent WorkItemReadyEvent; + }; +} + +#endif // TC_HEADER_Volume_EncryptionThreadPool diff --git a/src/Volume/Hash.cpp b/src/Volume/Hash.cpp new file mode 100644 index 00000000..cca8cc6b --- /dev/null +++ b/src/Volume/Hash.cpp @@ -0,0 +1,138 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Hash.h" + +#include "Crypto/Rmd160.h" +#include "Crypto/Sha1.h" +#include "Crypto/Sha2.h" +#include "Crypto/Whirlpool.h" + +namespace TrueCrypt +{ + HashList Hash::GetAvailableAlgorithms () + { + HashList l; + + l.push_back (shared_ptr (new Ripemd160 ())); + l.push_back (shared_ptr (new Sha512 ())); + l.push_back (shared_ptr (new Whirlpool ())); + l.push_back (shared_ptr (new Sha1 ())); + + return l; + } + + void Hash::ValidateDataParameters (const ConstBufferPtr &data) const + { + if (data.Size() < 1) + throw ParameterIncorrect (SRC_POS); + } + + void Hash::ValidateDigestParameters (const BufferPtr &buffer) const + { + if (buffer.Size() != GetDigestSize ()) + throw ParameterIncorrect (SRC_POS); + } + + // RIPEMD-160 + Ripemd160::Ripemd160 () + { + Context.Allocate (sizeof (RMD160_CTX)); + Init(); + } + + void Ripemd160::GetDigest (const BufferPtr &buffer) + { + if_debug (ValidateDigestParameters (buffer)); + RMD160Final (buffer, (RMD160_CTX *) Context.Ptr()); + } + + void Ripemd160::Init () + { + RMD160Init ((RMD160_CTX *) Context.Ptr()); + } + + void Ripemd160::ProcessData (const ConstBufferPtr &data) + { + if_debug (ValidateDataParameters (data)); + RMD160Update ((RMD160_CTX *) Context.Ptr(), data.Get(), (int) data.Size()); + } + + // SHA-1 + Sha1::Sha1 () + { + Deprecated = true; + Context.Allocate (sizeof (sha1_ctx)); + Init(); + } + + void Sha1::GetDigest (const BufferPtr &buffer) + { + if_debug (ValidateDigestParameters (buffer)); + sha1_end (buffer, (sha1_ctx *) Context.Ptr()); + } + + void Sha1::Init () + { + sha1_begin ((sha1_ctx *) Context.Ptr()); + } + + void Sha1::ProcessData (const ConstBufferPtr &data) + { + if_debug (ValidateDataParameters (data)); + sha1_hash (data.Get(), (int) data.Size(), (sha1_ctx *) Context.Ptr()); + } + + // SHA-512 + Sha512::Sha512 () + { + Context.Allocate (sizeof (sha512_ctx)); + Init(); + } + + void Sha512::GetDigest (const BufferPtr &buffer) + { + if_debug (ValidateDigestParameters (buffer)); + sha512_end (buffer, (sha512_ctx *) Context.Ptr()); + } + + void Sha512::Init () + { + sha512_begin ((sha512_ctx *) Context.Ptr()); + } + + void Sha512::ProcessData (const ConstBufferPtr &data) + { + if_debug (ValidateDataParameters (data)); + sha512_hash (data.Get(), (int) data.Size(), (sha512_ctx *) Context.Ptr()); + } + + // Whirlpool + Whirlpool::Whirlpool () + { + Context.Allocate (sizeof (WHIRLPOOL_CTX)); + Init(); + } + + void Whirlpool::GetDigest (const BufferPtr &buffer) + { + if_debug (ValidateDigestParameters (buffer)); + WHIRLPOOL_finalize ((WHIRLPOOL_CTX *) Context.Ptr(), buffer); + } + + void Whirlpool::Init () + { + WHIRLPOOL_init ((WHIRLPOOL_CTX *) Context.Ptr()); + } + + void Whirlpool::ProcessData (const ConstBufferPtr &data) + { + if_debug (ValidateDataParameters (data)); + WHIRLPOOL_add (data.Get(), (int) data.Size() * 8, (WHIRLPOOL_CTX *) Context.Ptr()); + } +} diff --git a/src/Volume/Hash.h b/src/Volume/Hash.h new file mode 100644 index 00000000..3a24602c --- /dev/null +++ b/src/Volume/Hash.h @@ -0,0 +1,135 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Hash +#define TC_HEADER_Encryption_Hash + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + class Hash; + typedef list < shared_ptr > HashList; + + class Hash + { + public: + Hash () : Deprecated (false) { } + virtual ~Hash () { } + + static HashList GetAvailableAlgorithms (); + virtual void GetDigest (const BufferPtr &buffer) = 0; + virtual size_t GetBlockSize () const = 0; + virtual size_t GetDigestSize () const = 0; + virtual wstring GetName () const = 0; + virtual shared_ptr GetNew () const = 0; + virtual void Init () = 0; + bool IsDeprecated () const { return Deprecated; } + virtual void ProcessData (const ConstBufferPtr &data) = 0; + virtual void ValidateDataParameters (const ConstBufferPtr &data) const; + virtual void ValidateDigestParameters (const BufferPtr &buffer) const; + + protected: + SecureBuffer Context; + bool Deprecated; + + private: + Hash (const Hash &); + Hash &operator= (const Hash &); + }; + + // RIPEMD-160 + class Ripemd160 : public Hash + { + public: + Ripemd160 (); + virtual ~Ripemd160 () { } + + virtual void GetDigest (const BufferPtr &buffer); + virtual size_t GetBlockSize () const { return 64; } + virtual size_t GetDigestSize () const { return 160 / 8; } + virtual wstring GetName () const { return L"RIPEMD-160"; } + virtual shared_ptr GetNew () const { return shared_ptr (new Ripemd160); } + virtual void Init (); + virtual void ProcessData (const ConstBufferPtr &data); + + protected: + + private: + Ripemd160 (const Ripemd160 &); + Ripemd160 &operator= (const Ripemd160 &); + }; + + // SHA-1 + class Sha1 : public Hash + { + public: + Sha1 (); + virtual ~Sha1 () { } + + virtual void GetDigest (const BufferPtr &buffer); + virtual size_t GetBlockSize () const { return 64; } + virtual size_t GetDigestSize () const { return 160 / 8; } + virtual wstring GetName () const { return L"SHA-1"; } + virtual shared_ptr GetNew () const { return shared_ptr (new Sha1); } + virtual void Init (); + virtual void ProcessData (const ConstBufferPtr &data); + + protected: + + private: + Sha1 (const Sha1 &); + Sha1 &operator= (const Sha1 &); + }; + + // SHA-512 + class Sha512 : public Hash + { + public: + Sha512 (); + virtual ~Sha512 () { } + + virtual void GetDigest (const BufferPtr &buffer); + virtual size_t GetBlockSize () const { return 128; } + virtual size_t GetDigestSize () const { return 512 / 8; } + virtual wstring GetName () const { return L"SHA-512"; } + virtual shared_ptr GetNew () const { return shared_ptr (new Sha512); } + virtual void Init (); + virtual void ProcessData (const ConstBufferPtr &data); + + protected: + + private: + Sha512 (const Sha512 &); + Sha512 &operator= (const Sha512 &); + }; + + // Whirlpool + class Whirlpool : public Hash + { + public: + Whirlpool (); + virtual ~Whirlpool () { } + + virtual void GetDigest (const BufferPtr &buffer); + virtual size_t GetBlockSize () const { return 64; } + virtual size_t GetDigestSize () const { return 512 / 8; } + virtual wstring GetName () const { return L"Whirlpool"; } + virtual shared_ptr GetNew () const { return shared_ptr (new Whirlpool); } + virtual void Init (); + virtual void ProcessData (const ConstBufferPtr &data); + + protected: + + private: + Whirlpool (const Whirlpool &); + Whirlpool &operator= (const Whirlpool &); + }; +} + +#endif // TC_HEADER_Encryption_Hash diff --git a/src/Volume/Keyfile.cpp b/src/Volume/Keyfile.cpp new file mode 100644 index 00000000..d132dbb8 --- /dev/null +++ b/src/Volume/Keyfile.cpp @@ -0,0 +1,181 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Platform/Serializer.h" +#include "Common/SecurityToken.h" +#include "Crc32.h" +#include "Keyfile.h" +#include "VolumeException.h" + +namespace TrueCrypt +{ + void Keyfile::Apply (const BufferPtr &pool) const + { + if (Path.IsDirectory()) + throw ParameterIncorrect (SRC_POS); + + File file; + + Crc32 crc32; + size_t poolPos = 0; + uint64 totalLength = 0; + uint64 readLength; + + SecureBuffer keyfileBuf (File::GetOptimalReadSize()); + + if (SecurityToken::IsKeyfilePathValid (Path)) + { + // Apply keyfile generated by a security token + vector keyfileData; + SecurityToken::GetKeyfileData (SecurityTokenKeyfile (wstring (Path)), keyfileData); + + if (keyfileData.size() < MinProcessedLength) + throw InsufficientData (SRC_POS, Path); + + for (size_t i = 0; i < keyfileData.size(); i++) + { + uint32 crc = crc32.Process (keyfileData[i]); + + pool[poolPos++] += (byte) (crc >> 24); + pool[poolPos++] += (byte) (crc >> 16); + pool[poolPos++] += (byte) (crc >> 8); + pool[poolPos++] += (byte) crc; + + if (poolPos >= pool.Size()) + poolPos = 0; + + if (++totalLength >= MaxProcessedLength) + break; + } + + Memory::Erase (&keyfileData.front(), keyfileData.size()); + goto done; + } + + file.Open (Path, File::OpenRead, File::ShareRead); + + while ((readLength = file.Read (keyfileBuf)) > 0) + { + for (size_t i = 0; i < readLength; i++) + { + uint32 crc = crc32.Process (keyfileBuf[i]); + + pool[poolPos++] += (byte) (crc >> 24); + pool[poolPos++] += (byte) (crc >> 16); + pool[poolPos++] += (byte) (crc >> 8); + pool[poolPos++] += (byte) crc; + + if (poolPos >= pool.Size()) + poolPos = 0; + + if (++totalLength >= MaxProcessedLength) + goto done; + } + } +done: + if (totalLength < MinProcessedLength) + throw InsufficientData (SRC_POS, Path); + } + + shared_ptr Keyfile::ApplyListToPassword (shared_ptr keyfiles, shared_ptr password) + { + if (!password) + password.reset (new VolumePassword); + + if (!keyfiles || keyfiles->size() < 1) + return password; + + KeyfileList keyfilesExp; + HiddenFileWasPresentInKeyfilePath = false; + + // Enumerate directories + foreach (shared_ptr keyfile, *keyfiles) + { + if (FilesystemPath (*keyfile).IsDirectory()) + { + size_t keyfileCount = 0; + foreach_ref (const FilePath &path, Directory::GetFilePaths (*keyfile)) + { +#ifdef TC_UNIX + // Skip hidden files + if (wstring (path.ToBaseName()).find (L'.') == 0) + { + HiddenFileWasPresentInKeyfilePath = true; + continue; + } +#endif + keyfilesExp.push_back (make_shared (path)); + ++keyfileCount; + } + + if (keyfileCount == 0) + throw KeyfilePathEmpty (SRC_POS, FilesystemPath (*keyfile)); + } + else + { + keyfilesExp.push_back (keyfile); + } + } + + make_shared_auto (VolumePassword, newPassword); + + if (keyfilesExp.size() < 1) + { + newPassword->Set (*password); + } + else + { + SecureBuffer keyfilePool (VolumePassword::MaxSize); + + // Pad password with zeros if shorter than max length + keyfilePool.Zero(); + keyfilePool.CopyFrom (ConstBufferPtr (password->DataPtr(), password->Size())); + + // Apply all keyfiles + foreach_ref (const Keyfile &k, keyfilesExp) + { + k.Apply (keyfilePool); + } + + newPassword->Set (keyfilePool); + } + + return newPassword; + } + + shared_ptr Keyfile::DeserializeList (shared_ptr stream, const string &name) + { + shared_ptr keyfiles; + Serializer sr (stream); + + if (!sr.DeserializeBool (name + "Null")) + { + keyfiles.reset (new KeyfileList); + foreach (const wstring &k, sr.DeserializeWStringList (name)) + keyfiles->push_back (make_shared (k)); + } + return keyfiles; + } + + void Keyfile::SerializeList (shared_ptr stream, const string &name, shared_ptr keyfiles) + { + Serializer sr (stream); + sr.Serialize (name + "Null", keyfiles == nullptr); + if (keyfiles) + { + list sl; + + foreach_ref (const Keyfile &k, *keyfiles) + sl.push_back (FilesystemPath (k)); + + sr.Serialize (name, sl); + } + } + + bool Keyfile::HiddenFileWasPresentInKeyfilePath = false; +} diff --git a/src/Volume/Keyfile.h b/src/Volume/Keyfile.h new file mode 100644 index 00000000..6d7a1a87 --- /dev/null +++ b/src/Volume/Keyfile.h @@ -0,0 +1,49 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Keyfile +#define TC_HEADER_Encryption_Keyfile + +#include "Platform/Platform.h" +#include "Platform/Stream.h" +#include "VolumePassword.h" + +namespace TrueCrypt +{ + class Keyfile; + typedef list < shared_ptr > KeyfileList; + + class Keyfile + { + public: + Keyfile (const FilesystemPath &path) : Path (path) { } + virtual ~Keyfile () { }; + + operator FilesystemPath () const { return Path; } + static shared_ptr ApplyListToPassword (shared_ptr keyfiles, shared_ptr password); + static shared_ptr DeserializeList (shared_ptr stream, const string &name); + static void SerializeList (shared_ptr stream, const string &name, shared_ptr keyfiles); + static bool WasHiddenFilePresentInKeyfilePath() { bool r = HiddenFileWasPresentInKeyfilePath; HiddenFileWasPresentInKeyfilePath = false; return r; } + + static const size_t MinProcessedLength = 1; + static const size_t MaxProcessedLength = 1024 * 1024; + + protected: + void Apply (const BufferPtr &pool) const; + + static bool HiddenFileWasPresentInKeyfilePath; + + FilesystemPath Path; + + private: + Keyfile (const Keyfile &); + Keyfile &operator= (const Keyfile &); + }; +} + +#endif // TC_HEADER_Encryption_Keyfile diff --git a/src/Volume/Pkcs5Kdf.cpp b/src/Volume/Pkcs5Kdf.cpp new file mode 100644 index 00000000..9f9a4d96 --- /dev/null +++ b/src/Volume/Pkcs5Kdf.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Common/Pkcs5.h" +#include "Pkcs5Kdf.h" +#include "VolumePassword.h" + +namespace TrueCrypt +{ + Pkcs5Kdf::Pkcs5Kdf () + { + } + + Pkcs5Kdf::~Pkcs5Kdf () + { + } + + void Pkcs5Kdf::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const + { + DeriveKey (key, password, salt, GetIterationCount()); + } + + shared_ptr Pkcs5Kdf::GetAlgorithm (const wstring &name) + { + foreach (shared_ptr kdf, GetAvailableAlgorithms()) + { + if (kdf->GetName() == name) + return kdf; + } + throw ParameterIncorrect (SRC_POS); + } + + shared_ptr Pkcs5Kdf::GetAlgorithm (const Hash &hash) + { + foreach (shared_ptr kdf, GetAvailableAlgorithms()) + { + if (typeid (*kdf->GetHash()) == typeid (hash)) + return kdf; + } + + throw ParameterIncorrect (SRC_POS); + } + + Pkcs5KdfList Pkcs5Kdf::GetAvailableAlgorithms () + { + Pkcs5KdfList l; + + l.push_back (shared_ptr (new Pkcs5HmacRipemd160 ())); + l.push_back (shared_ptr (new Pkcs5HmacSha512 ())); + l.push_back (shared_ptr (new Pkcs5HmacWhirlpool ())); + l.push_back (shared_ptr (new Pkcs5HmacSha1 ())); + + return l; + } + + void Pkcs5Kdf::ValidateParameters (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + if (key.Size() < 1 || password.Size() < 1 || salt.Size() < 1 || iterationCount < 1) + throw ParameterIncorrect (SRC_POS); + } + + void Pkcs5HmacRipemd160::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + ValidateParameters (key, password, salt, iterationCount); + derive_key_ripemd160 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + } + + void Pkcs5HmacRipemd160_1000::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + ValidateParameters (key, password, salt, iterationCount); + derive_key_ripemd160 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + } + + void Pkcs5HmacSha1::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + ValidateParameters (key, password, salt, iterationCount); + derive_key_sha1 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + } + + void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + ValidateParameters (key, password, salt, iterationCount); + derive_key_sha512 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + } + + void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const + { + ValidateParameters (key, password, salt, iterationCount); + derive_key_whirlpool ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + } +} diff --git a/src/Volume/Pkcs5Kdf.h b/src/Volume/Pkcs5Kdf.h new file mode 100644 index 00000000..a0b8f28a --- /dev/null +++ b/src/Volume/Pkcs5Kdf.h @@ -0,0 +1,127 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Pkcs5 +#define TC_HEADER_Encryption_Pkcs5 + +#include "Platform/Platform.h" +#include "Hash.h" +#include "VolumePassword.h" + +namespace TrueCrypt +{ + class Pkcs5Kdf; + typedef list < shared_ptr > Pkcs5KdfList; + + class Pkcs5Kdf + { + public: + virtual ~Pkcs5Kdf (); + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt) const; + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const = 0; + static shared_ptr GetAlgorithm (const wstring &name); + static shared_ptr GetAlgorithm (const Hash &hash); + static Pkcs5KdfList GetAvailableAlgorithms (); + virtual shared_ptr GetHash () const = 0; + virtual int GetIterationCount () const = 0; + virtual wstring GetName () const = 0; + virtual bool IsDeprecated () const { return GetHash()->IsDeprecated(); } + + protected: + Pkcs5Kdf (); + + void ValidateParameters (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + + private: + Pkcs5Kdf (const Pkcs5Kdf &); + Pkcs5Kdf &operator= (const Pkcs5Kdf &); + }; + + class Pkcs5HmacRipemd160 : public Pkcs5Kdf + { + public: + Pkcs5HmacRipemd160 () { } + virtual ~Pkcs5HmacRipemd160 () { } + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + virtual shared_ptr GetHash () const { return shared_ptr (new Ripemd160); } + virtual int GetIterationCount () const { return 2000; } + virtual wstring GetName () const { return L"HMAC-RIPEMD-160"; } + + private: + Pkcs5HmacRipemd160 (const Pkcs5HmacRipemd160 &); + Pkcs5HmacRipemd160 &operator= (const Pkcs5HmacRipemd160 &); + }; + + class Pkcs5HmacRipemd160_1000 : public Pkcs5Kdf + { + public: + Pkcs5HmacRipemd160_1000 () { } + virtual ~Pkcs5HmacRipemd160_1000 () { } + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + virtual shared_ptr GetHash () const { return shared_ptr (new Ripemd160); } + virtual int GetIterationCount () const { return 1000; } + virtual wstring GetName () const { return L"HMAC-RIPEMD-160"; } + + private: + Pkcs5HmacRipemd160_1000 (const Pkcs5HmacRipemd160_1000 &); + Pkcs5HmacRipemd160_1000 &operator= (const Pkcs5HmacRipemd160_1000 &); + }; + + class Pkcs5HmacSha1 : public Pkcs5Kdf + { + public: + Pkcs5HmacSha1 () { } + virtual ~Pkcs5HmacSha1 () { } + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + virtual shared_ptr GetHash () const { return shared_ptr (new Sha1); } + virtual int GetIterationCount () const { return 2000; } + virtual wstring GetName () const { return L"HMAC-SHA-1"; } + + private: + Pkcs5HmacSha1 (const Pkcs5HmacSha1 &); + Pkcs5HmacSha1 &operator= (const Pkcs5HmacSha1 &); + }; + + class Pkcs5HmacSha512 : public Pkcs5Kdf + { + public: + Pkcs5HmacSha512 () { } + virtual ~Pkcs5HmacSha512 () { } + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + virtual shared_ptr GetHash () const { return shared_ptr (new Sha512); } + virtual int GetIterationCount () const { return 1000; } + virtual wstring GetName () const { return L"HMAC-SHA-512"; } + + private: + Pkcs5HmacSha512 (const Pkcs5HmacSha512 &); + Pkcs5HmacSha512 &operator= (const Pkcs5HmacSha512 &); + }; + + class Pkcs5HmacWhirlpool : public Pkcs5Kdf + { + public: + Pkcs5HmacWhirlpool () { } + virtual ~Pkcs5HmacWhirlpool () { } + + virtual void DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const; + virtual shared_ptr GetHash () const { return shared_ptr (new Whirlpool); } + virtual int GetIterationCount () const { return 1000; } + virtual wstring GetName () const { return L"HMAC-Whirlpool"; } + + private: + Pkcs5HmacWhirlpool (const Pkcs5HmacWhirlpool &); + Pkcs5HmacWhirlpool &operator= (const Pkcs5HmacWhirlpool &); + }; +} + +#endif // TC_HEADER_Encryption_Pkcs5 diff --git a/src/Volume/Version.h b/src/Volume/Version.h new file mode 100644 index 00000000..62738142 --- /dev/null +++ b/src/Volume/Version.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_Version +#define TC_HEADER_Volume_Version + +#include "Platform/PlatformBase.h" +#include "Common/Tcdefs.h" + +namespace TrueCrypt +{ + class Version + { + public: + static const string String () { return VERSION_STRING; } + static const uint16 Number () { return VERSION_NUM; } + }; +} + +#endif // TC_HEADER_Volume_Version diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp new file mode 100644 index 00000000..0acdbb2e --- /dev/null +++ b/src/Volume/Volume.cpp @@ -0,0 +1,388 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_WINDOWS +#include +#endif +#include "EncryptionModeLRW.h" +#include "EncryptionModeXTS.h" +#include "Volume.h" +#include "VolumeHeader.h" +#include "VolumeLayout.h" +#include "Common/Crypto.h" + +namespace TrueCrypt +{ + Volume::Volume () + : HiddenVolumeProtectionTriggered (false), + SystemEncryption (false), + VolumeDataSize (0), + TopWriteOffset (0), + TotalDataRead (0), + TotalDataWritten (0) + { + } + + Volume::~Volume () + { + } + + void Volume::CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength) + { + uint64 writeHostEndOffset = writeHostOffset + writeLength - 1; + + if ((writeHostOffset < ProtectedRangeStart) ? (writeHostEndOffset >= ProtectedRangeStart) : (writeHostOffset <= ProtectedRangeEnd - 1)) + { + HiddenVolumeProtectionTriggered = true; + throw VolumeProtected (SRC_POS); + } + } + + void Volume::Close () + { + if (VolumeFile.get() == nullptr) + throw NotInitialized (SRC_POS); + + VolumeFile.reset(); + } + + shared_ptr Volume::GetEncryptionAlgorithm () const + { + if_debug (ValidateState ()); + return EA; + } + + shared_ptr Volume::GetEncryptionMode () const + { + if_debug (ValidateState ()); + return EA->GetMode(); + } + + void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + { + make_shared_auto (File, file); + + File::FileOpenFlags flags = (preserveTimestamps ? File::PreserveTimestamps : File::FlagsNone); + + try + { + if (protection == VolumeProtection::ReadOnly) + file->Open (volumePath, File::OpenRead, File::ShareRead, flags); + else + file->Open (volumePath, File::OpenReadWrite, File::ShareNone, flags); + } + catch (SystemException &e) + { + if (e.GetErrorCode() == +#ifdef TC_WINDOWS + ERROR_SHARING_VIOLATION) +#else + EAGAIN) +#endif + { + if (!sharedAccessAllowed) + throw VolumeHostInUse (SRC_POS); + + file->Open (volumePath, protection == VolumeProtection::ReadOnly ? File::OpenRead : File::OpenReadWrite, File::ShareReadWriteIgnoreLock, flags); + } + else + throw; + } + + return Open (file, password, keyfiles, protection, protectionPassword, protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); + } + + void Volume::Open (shared_ptr volumeFile, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, shared_ptr protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + { + if (!volumeFile) + throw ParameterIncorrect (SRC_POS); + + Protection = protection; + VolumeFile = volumeFile; + SystemEncryption = partitionInSystemEncryptionScope; + + try + { + VolumeHostSize = VolumeFile->Length(); + shared_ptr passwordKey = Keyfile::ApplyListToPassword (keyfiles, password); + + bool skipLayoutV1Normal = false; + + bool deviceHosted = GetPath().IsDevice(); + size_t hostDeviceSectorSize = 0; + if (deviceHosted) + hostDeviceSectorSize = volumeFile->GetDeviceSectorSize(); + + // Test volume layouts + foreach (shared_ptr layout, VolumeLayout::GetAvailableLayouts (volumeType)) + { + if (skipLayoutV1Normal && typeid (*layout) == typeid (VolumeLayoutV1Normal)) + { + // Skip VolumeLayoutV1Normal as it shares header location with VolumeLayoutV2Normal + continue; + } + + if (useBackupHeaders && !layout->HasBackupHeader()) + continue; + + if (typeid (*layout) == typeid (VolumeLayoutV1Hidden) + && deviceHosted + && hostDeviceSectorSize != TC_SECTOR_SIZE_LEGACY) + { + continue; + } + + SecureBuffer headerBuffer (layout->GetHeaderSize()); + + if (layout->HasDriveHeader()) + { + if (!partitionInSystemEncryptionScope) + continue; + + if (!GetPath().IsDevice()) + throw PartitionDeviceRequired (SRC_POS); + + File driveDevice; + driveDevice.Open (DevicePath (wstring (GetPath())).ToHostDriveOfPartition()); + + int headerOffset = layout->GetHeaderOffset(); + + if (headerOffset >= 0) + driveDevice.SeekAt (headerOffset); + else + driveDevice.SeekEnd (headerOffset); + + if (driveDevice.Read (headerBuffer) != layout->GetHeaderSize()) + continue; + } + else + { + if (partitionInSystemEncryptionScope) + continue; + + int headerOffset = useBackupHeaders ? layout->GetBackupHeaderOffset() : layout->GetHeaderOffset(); + + if (headerOffset >= 0) + VolumeFile->SeekAt (headerOffset); + else + VolumeFile->SeekEnd (headerOffset); + + if (VolumeFile->Read (headerBuffer) != layout->GetHeaderSize()) + continue; + } + + EncryptionAlgorithmList layoutEncryptionAlgorithms = layout->GetSupportedEncryptionAlgorithms(); + EncryptionModeList layoutEncryptionModes = layout->GetSupportedEncryptionModes(); + + if (typeid (*layout) == typeid (VolumeLayoutV2Normal)) + { + skipLayoutV1Normal = true; + + // Test all algorithms and modes of VolumeLayoutV1Normal as it shares header location with VolumeLayoutV2Normal + layoutEncryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); + layoutEncryptionModes = EncryptionMode::GetAvailableModes(); + } + + shared_ptr header = layout->GetHeader(); + + if (header->Decrypt (headerBuffer, *passwordKey, layout->GetSupportedKeyDerivationFunctions(), layoutEncryptionAlgorithms, layoutEncryptionModes)) + { + // Header decrypted + + if (typeid (*layout) == typeid (VolumeLayoutV2Normal) && header->GetRequiredMinProgramVersion() < 0x600) + { + // VolumeLayoutV1Normal has been opened as VolumeLayoutV2Normal + layout.reset (new VolumeLayoutV1Normal); + header->SetSize (layout->GetHeaderSize()); + layout->SetHeader (header); + } + + Type = layout->GetType(); + SectorSize = header->GetSectorSize(); + + VolumeDataOffset = layout->GetDataOffset (VolumeHostSize); + VolumeDataSize = layout->GetDataSize (VolumeHostSize); + + Header = header; + Layout = layout; + EA = header->GetEncryptionAlgorithm(); + EncryptionMode &mode = *EA->GetMode(); + + if (layout->HasDriveHeader()) + { + if (header->GetEncryptedAreaLength() != header->GetVolumeDataSize()) + throw VolumeEncryptionNotCompleted (SRC_POS); + + uint64 partitionStartOffset = VolumeFile->GetPartitionDeviceStartOffset(); + + if (partitionStartOffset < header->GetEncryptedAreaStart() + || partitionStartOffset >= header->GetEncryptedAreaStart() + header->GetEncryptedAreaLength()) + throw PasswordIncorrect (SRC_POS); + + mode.SetSectorOffset (partitionStartOffset / ENCRYPTION_DATA_UNIT_SIZE); + } + else if (typeid (mode) == typeid (EncryptionModeLRW)) + { + mode.SetSectorOffset (VolumeDataOffset / SectorSize); + } + + // Volume protection + if (Protection == VolumeProtection::HiddenVolumeReadOnly) + { + if (Type == VolumeType::Hidden) + throw PasswordIncorrect (SRC_POS); + else + { + try + { + Volume protectedVolume; + + protectedVolume.Open (VolumeFile, + protectionPassword, protectionKeyfiles, + VolumeProtection::ReadOnly, + shared_ptr (), shared_ptr (), + VolumeType::Hidden, + useBackupHeaders); + + if (protectedVolume.GetType() != VolumeType::Hidden) + ParameterIncorrect (SRC_POS); + + ProtectedRangeStart = protectedVolume.VolumeDataOffset; + ProtectedRangeEnd = protectedVolume.VolumeDataOffset + protectedVolume.VolumeDataSize; + + if (typeid (*protectedVolume.Layout) == typeid (VolumeLayoutV1Hidden)) + ProtectedRangeEnd += protectedVolume.Layout->GetHeaderSize(); + } + catch (PasswordException&) + { + if (protectionKeyfiles && !protectionKeyfiles->empty()) + throw ProtectionPasswordKeyfilesIncorrect (SRC_POS); + throw ProtectionPasswordIncorrect (SRC_POS); + } + } + } + return; + } + } + + if (partitionInSystemEncryptionScope) + throw PasswordOrKeyboardLayoutIncorrect (SRC_POS); + + if (!partitionInSystemEncryptionScope && GetPath().IsDevice()) + { + // Check if the device contains TrueCrypt Boot Loader + try + { + File driveDevice; + driveDevice.Open (DevicePath (wstring (GetPath())).ToHostDriveOfPartition()); + + Buffer mbr (VolumeFile->GetDeviceSectorSize()); + driveDevice.ReadAt (mbr, 0); + + // Search for the string "TrueCrypt" + size_t nameLen = strlen (TC_APP_NAME); + for (size_t i = 0; i < mbr.Size() - nameLen; ++i) + { + if (memcmp (mbr.Ptr() + i, TC_APP_NAME, nameLen) == 0) + throw PasswordOrMountOptionsIncorrect (SRC_POS); + } + } + catch (PasswordOrMountOptionsIncorrect&) { throw; } + catch (...) { } + } + + if (keyfiles && !keyfiles->empty()) + throw PasswordKeyfilesIncorrect (SRC_POS); + throw PasswordIncorrect (SRC_POS); + } + catch (...) + { + Close(); + throw; + } + } + + void Volume::ReadSectors (const BufferPtr &buffer, uint64 byteOffset) + { + if_debug (ValidateState ()); + + uint64 length = buffer.Size(); + uint64 hostOffset = VolumeDataOffset + byteOffset; + + if (length % SectorSize != 0 || byteOffset % SectorSize != 0) + throw ParameterIncorrect (SRC_POS); + + if (VolumeFile->ReadAt (buffer, hostOffset) != length) + throw MissingVolumeData (SRC_POS); + + EA->DecryptSectors (buffer, hostOffset / SectorSize, length / SectorSize, SectorSize); + + TotalDataRead += length; + } + + void Volume::ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr newPkcs5Kdf) + { + if_debug (ValidateState ()); + + if (Protection == VolumeProtection::ReadOnly) + throw VolumeReadOnly (SRC_POS); + + SecureBuffer newHeaderBuffer (Layout->GetHeaderSize()); + + Header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, newPkcs5Kdf); + + int headerOffset = backupHeader ? Layout->GetBackupHeaderOffset() : Layout->GetHeaderOffset(); + + if (headerOffset >= 0) + VolumeFile->SeekAt (headerOffset); + else + VolumeFile->SeekEnd (headerOffset); + + VolumeFile->Write (newHeaderBuffer); + } + + void Volume::ValidateState () const + { + if (VolumeFile.get() == nullptr) + throw NotInitialized (SRC_POS); + } + + void Volume::WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset) + { + if_debug (ValidateState ()); + + uint64 length = buffer.Size(); + uint64 hostOffset = VolumeDataOffset + byteOffset; + + if (length % SectorSize != 0 + || byteOffset % SectorSize != 0 + || byteOffset + length > VolumeDataSize) + throw ParameterIncorrect (SRC_POS); + + if (Protection == VolumeProtection::ReadOnly) + throw VolumeReadOnly (SRC_POS); + + if (HiddenVolumeProtectionTriggered) + throw VolumeProtected (SRC_POS); + + if (Protection == VolumeProtection::HiddenVolumeReadOnly) + CheckProtectedRange (hostOffset, length); + + SecureBuffer encBuf (buffer.Size()); + encBuf.CopyFrom (buffer); + + EA->EncryptSectors (encBuf, hostOffset / SectorSize, length / SectorSize, SectorSize); + VolumeFile->WriteAt (encBuf, hostOffset); + + TotalDataWritten += length; + + uint64 writeEndOffset = byteOffset + buffer.Size(); + if (writeEndOffset > TopWriteOffset) + TopWriteOffset = writeEndOffset; + } +} diff --git a/src/Volume/Volume.h b/src/Volume/Volume.h new file mode 100644 index 00000000..8578bec1 --- /dev/null +++ b/src/Volume/Volume.h @@ -0,0 +1,126 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_Volume +#define TC_HEADER_Volume_Volume + +#include "Platform/Platform.h" +#include "Platform/StringConverter.h" +#include "EncryptionAlgorithm.h" +#include "EncryptionMode.h" +#include "Keyfile.h" +#include "VolumePassword.h" +#include "VolumeException.h" +#include "VolumeLayout.h" + +namespace TrueCrypt +{ + class VolumePath + { + public: + VolumePath () { } + VolumePath (const wstring &path) { Data = path; } + VolumePath (const FilesystemPath &path) { Data = path; } + + bool operator== (const VolumePath &other) const { return Data == other.Data; } + bool operator!= (const VolumePath &other) const { return Data != other.Data; } + operator FilesystemPath () const { return FilesystemPath (Data); } + operator string () const { return StringConverter::ToSingle (Data); } + operator wstring () const { return Data; } + + bool IsDevice () const { return FilesystemPath (Data).IsBlockDevice() || FilesystemPath (Data).IsCharacterDevice(); } + bool IsEmpty () const { return Data.empty(); } + + protected: + wstring Data; + }; + + typedef list VolumePathList; + + struct VolumeHostType + { + enum Enum + { + Unknown, + File, + Device + }; + }; + + struct VolumeProtection + { + enum Enum + { + None, + ReadOnly, + HiddenVolumeReadOnly + }; + }; + + class Volume + { + public: + Volume (); + virtual ~Volume (); + + void Close (); + shared_ptr GetEncryptionAlgorithm () const; + shared_ptr GetEncryptionMode () const; + shared_ptr GetFile () const { return VolumeFile; } + shared_ptr GetHeader () const { return Header; } + uint64 GetHeaderCreationTime () const { return Header->GetHeaderCreationTime(); } + uint64 GetHostSize () const { return VolumeHostSize; } + shared_ptr GetLayout () const { return Layout; } + VolumePath GetPath () const { return VolumeFile->GetPath(); } + VolumeProtection::Enum GetProtectionType () const { return Protection; } + shared_ptr GetPkcs5Kdf () const { return Header->GetPkcs5Kdf(); } + uint32 GetSaltSize () const { return Header->GetSaltSize(); } + size_t GetSectorSize () const { return SectorSize; } + uint64 GetSize () const { return VolumeDataSize; } + uint64 GetTopWriteOffset () const { return TopWriteOffset; } + uint64 GetTotalDataRead () const { return TotalDataRead; } + uint64 GetTotalDataWritten () const { return TotalDataWritten; } + VolumeType::Enum GetType () const { return Type; } + uint64 GetVolumeCreationTime () const { return Header->GetVolumeCreationTime(); } + bool IsHiddenVolumeProtectionTriggered () const { return HiddenVolumeProtectionTriggered; } + bool IsInSystemEncryptionScope () const { return SystemEncryption; } + void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); + void Open (shared_ptr volumeFile, shared_ptr password, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); + void ReadSectors (const BufferPtr &buffer, uint64 byteOffset); + void ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr newPkcs5Kdf); + void WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset); + + protected: + void CheckProtectedRange (uint64 writeHostOffset, uint64 writeLength); + void ValidateState () const; + + shared_ptr EA; + shared_ptr Header; + bool HiddenVolumeProtectionTriggered; + shared_ptr Layout; + uint64 ProtectedRangeStart; + uint64 ProtectedRangeEnd; + VolumeProtection::Enum Protection; + size_t SectorSize; + bool SystemEncryption; + VolumeType::Enum Type; + shared_ptr VolumeFile; + uint64 VolumeHostSize; + uint64 VolumeDataOffset; + uint64 VolumeDataSize; + uint64 TopWriteOffset; + uint64 TotalDataRead; + uint64 TotalDataWritten; + + private: + Volume (const Volume &); + Volume &operator= (const Volume &); + }; +} + +#endif // TC_HEADER_Volume_Volume diff --git a/src/Volume/Volume.make b/src/Volume/Volume.make new file mode 100644 index 00000000..29412a9f --- /dev/null +++ b/src/Volume/Volume.make @@ -0,0 +1,62 @@ +# +# Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. +# +# Governed by the TrueCrypt License 3.0 the full text of which is contained in +# the file License.txt included in TrueCrypt binary and source code distribution +# packages. +# + +OBJS := +OBJS += Cipher.o +OBJS += EncryptionAlgorithm.o +OBJS += EncryptionMode.o +OBJS += EncryptionModeCBC.o +OBJS += EncryptionModeLRW.o +OBJS += EncryptionModeXTS.o +OBJS += EncryptionTest.o +OBJS += EncryptionThreadPool.o +OBJS += Hash.o +OBJS += Keyfile.o +OBJS += Pkcs5Kdf.o +OBJS += Volume.o +OBJS += VolumeException.o +OBJS += VolumeHeader.o +OBJS += VolumeInfo.o +OBJS += VolumeLayout.o +OBJS += VolumePassword.o +OBJS += VolumePasswordCache.o + +ifeq "$(CPU_ARCH)" "x86" + OBJS += ../Crypto/Aes_x86.o + OBJS += ../Crypto/Aes_hw_cpu.o + ifeq "$(PLATFORM)" "MacOSX" + OBJS += ../Crypto/Aescrypt.o + endif +else ifeq "$(CPU_ARCH)" "x64" + OBJS += ../Crypto/Aes_x64.o + OBJS += ../Crypto/Aes_hw_cpu.o +else + OBJS += ../Crypto/Aescrypt.o +endif + +OBJS += ../Crypto/Aeskey.o +OBJS += ../Crypto/Aestab.o +OBJS += ../Crypto/Blowfish.o +OBJS += ../Crypto/Cast.o +OBJS += ../Crypto/Des.o +OBJS += ../Crypto/Rmd160.o +OBJS += ../Crypto/Serpent.o +OBJS += ../Crypto/Sha1.o +OBJS += ../Crypto/Sha2.o +OBJS += ../Crypto/Twofish.o +OBJS += ../Crypto/Whirlpool.o + +OBJS += ../Common/Crc.o +OBJS += ../Common/Endian.o +OBJS += ../Common/GfMul.o +OBJS += ../Common/Pkcs5.o +OBJS += ../Common/SecurityToken.o + +VolumeLibrary: Volume.a + +include $(BUILD_INC)/Makefile.inc diff --git a/src/Volume/VolumeException.cpp b/src/Volume/VolumeException.cpp new file mode 100644 index 00000000..2c143dae --- /dev/null +++ b/src/Volume/VolumeException.cpp @@ -0,0 +1,32 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "VolumeException.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + // Do not inline the constructors to ensure this module is not optimized away + VolumeException::VolumeException () + { + } + + VolumeException::VolumeException (const string &message) : Exception (message) + { + } + + VolumeException::VolumeException (const string &message, const wstring &subject) : Exception (message, subject) + { + } + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (VolumeException); +} diff --git a/src/Volume/VolumeException.h b/src/Volume/VolumeException.h new file mode 100644 index 00000000..2f312b7f --- /dev/null +++ b/src/Volume/VolumeException.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeExceptions +#define TC_HEADER_Volume_VolumeExceptions + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + struct VolumeException : public Exception + { + protected: + VolumeException (); + VolumeException (const string &message); + VolumeException (const string &message, const wstring &subject); + }; + +#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,VolumeException) + +#undef TC_EXCEPTION_SET +#define TC_EXCEPTION_SET \ + TC_EXCEPTION (HigherVersionRequired); \ + TC_EXCEPTION (KeyfilePathEmpty); \ + TC_EXCEPTION (MissingVolumeData); \ + TC_EXCEPTION (MountedVolumeInUse); \ + TC_EXCEPTION (UnsupportedSectorSize); \ + TC_EXCEPTION (VolumeEncryptionNotCompleted); \ + TC_EXCEPTION (VolumeHostInUse); \ + TC_EXCEPTION (VolumeProtected); \ + TC_EXCEPTION (VolumeReadOnly); + + TC_EXCEPTION_SET; + +#undef TC_EXCEPTION +} + +#endif // TC_HEADER_Volume_VolumeExceptions diff --git a/src/Volume/VolumeHeader.cpp b/src/Volume/VolumeHeader.cpp new file mode 100644 index 00000000..f31111cc --- /dev/null +++ b/src/Volume/VolumeHeader.cpp @@ -0,0 +1,340 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Crc32.h" +#include "EncryptionModeXTS.h" +#include "Pkcs5Kdf.h" +#include "Pkcs5Kdf.h" +#include "VolumeHeader.h" +#include "VolumeException.h" +#include "Common/Crypto.h" + +namespace TrueCrypt +{ + VolumeHeader::VolumeHeader (uint32 size) + { + Init(); + HeaderSize = size; + EncryptedHeaderDataSize = size - EncryptedHeaderDataOffset; + } + + VolumeHeader::~VolumeHeader () + { + Init(); + } + + void VolumeHeader::Init () + { + VolumeKeyAreaCrc32 = 0; + VolumeCreationTime = 0; + HeaderCreationTime = 0; + mVolumeType = VolumeType::Unknown; + HiddenVolumeDataSize = 0; + VolumeDataSize = 0; + EncryptedAreaStart = 0; + EncryptedAreaLength = 0; + Flags = 0; + SectorSize = 0; + } + + void VolumeHeader::Create (const BufferPtr &headerBuffer, VolumeHeaderCreationOptions &options) + { + if (options.DataKey.Size() != options.EA->GetKeySize() * 2 || options.Salt.Size() != GetSaltSize()) + throw ParameterIncorrect (SRC_POS); + + headerBuffer.Zero(); + + HeaderVersion = CurrentHeaderVersion; + RequiredMinProgramVersion = CurrentRequiredMinProgramVersion; + + DataAreaKey.Zero(); + DataAreaKey.CopyFrom (options.DataKey); + + VolumeCreationTime = 0; + HiddenVolumeDataSize = (options.Type == VolumeType::Hidden ? options.VolumeDataSize : 0); + VolumeDataSize = options.VolumeDataSize; + + EncryptedAreaStart = options.VolumeDataStart; + EncryptedAreaLength = options.VolumeDataSize; + + SectorSize = options.SectorSize; + + if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE + || SectorSize > TC_MAX_VOLUME_SECTOR_SIZE + || SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) + { + throw ParameterIncorrect (SRC_POS); + } + + EA = options.EA; + shared_ptr mode (new EncryptionModeXTS ()); + EA->SetMode (mode); + + EncryptNew (headerBuffer, options.Salt, options.HeaderKey, options.Kdf); + } + + bool VolumeHeader::Decrypt (const ConstBufferPtr &encryptedData, const VolumePassword &password, const Pkcs5KdfList &keyDerivationFunctions, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes) + { + if (password.Size() < 1) + throw PasswordEmpty (SRC_POS); + + ConstBufferPtr salt (encryptedData.GetRange (SaltOffset, SaltSize)); + SecureBuffer header (EncryptedHeaderDataSize); + SecureBuffer headerKey (GetLargestSerializedKeySize()); + + foreach (shared_ptr pkcs5, keyDerivationFunctions) + { + pkcs5->DeriveKey (headerKey, password, salt); + + foreach (shared_ptr mode, encryptionModes) + { + if (typeid (*mode) != typeid (EncryptionModeXTS)) + mode->SetKey (headerKey.GetRange (0, mode->GetKeySize())); + + foreach (shared_ptr ea, encryptionAlgorithms) + { + if (!ea->IsModeSupported (mode)) + continue; + + if (typeid (*mode) == typeid (EncryptionModeXTS)) + { + ea->SetKey (headerKey.GetRange (0, ea->GetKeySize())); + + mode = mode->GetNew(); + mode->SetKey (headerKey.GetRange (ea->GetKeySize(), ea->GetKeySize())); + } + else + { + ea->SetKey (headerKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize())); + } + + ea->SetMode (mode); + + header.CopyFrom (encryptedData.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize)); + ea->Decrypt (header); + + if (Deserialize (header, ea, mode)) + { + EA = ea; + Pkcs5 = pkcs5; + return true; + } + } + } + } + + return false; + } + + bool VolumeHeader::Deserialize (const ConstBufferPtr &header, shared_ptr &ea, shared_ptr &mode) + { + if (header.Size() != EncryptedHeaderDataSize) + throw ParameterIncorrect (SRC_POS); + + if (header[0] != 'T' || + header[1] != 'R' || + header[2] != 'U' || + header[3] != 'E') + return false; + + size_t offset = 4; + HeaderVersion = DeserializeEntry (header, offset); + + if (HeaderVersion < MinAllowedHeaderVersion) + return false; + + if (HeaderVersion > CurrentHeaderVersion) + throw HigherVersionRequired (SRC_POS); + + if (HeaderVersion >= 4 + && Crc32::ProcessBuffer (header.GetRange (0, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC)) + != DeserializeEntryAt (header, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC)) + { + return false; + } + + RequiredMinProgramVersion = DeserializeEntry (header, offset); + + if (RequiredMinProgramVersion > Version::Number()) + throw HigherVersionRequired (SRC_POS); + + VolumeKeyAreaCrc32 = DeserializeEntry (header, offset); + VolumeCreationTime = DeserializeEntry (header, offset); + HeaderCreationTime = DeserializeEntry (header, offset); + HiddenVolumeDataSize = DeserializeEntry (header, offset); + mVolumeType = (HiddenVolumeDataSize != 0 ? VolumeType::Hidden : VolumeType::Normal); + VolumeDataSize = DeserializeEntry (header, offset); + EncryptedAreaStart = DeserializeEntry (header, offset); + EncryptedAreaLength = DeserializeEntry (header, offset); + Flags = DeserializeEntry (header, offset); + + SectorSize = DeserializeEntry (header, offset); + if (HeaderVersion < 5) + SectorSize = TC_SECTOR_SIZE_LEGACY; + + if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE + || SectorSize > TC_MAX_VOLUME_SECTOR_SIZE + || SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) + { + throw ParameterIncorrect (SRC_POS); + } + +#if !(defined (TC_WINDOWS) || defined (TC_LINUX)) + if (SectorSize != TC_SECTOR_SIZE_LEGACY) + throw UnsupportedSectorSize (SRC_POS); +#endif + + offset = DataAreaKeyOffset; + + if (VolumeKeyAreaCrc32 != Crc32::ProcessBuffer (header.GetRange (offset, DataKeyAreaMaxSize))) + return false; + + DataAreaKey.CopyFrom (header.GetRange (offset, DataKeyAreaMaxSize)); + + ea = ea->GetNew(); + mode = mode->GetNew(); + + if (typeid (*mode) == typeid (EncryptionModeXTS)) + { + ea->SetKey (header.GetRange (offset, ea->GetKeySize())); + mode->SetKey (header.GetRange (offset + ea->GetKeySize(), ea->GetKeySize())); + } + else + { + mode->SetKey (header.GetRange (offset, mode->GetKeySize())); + ea->SetKey (header.GetRange (offset + LegacyEncryptionModeKeyAreaSize, ea->GetKeySize())); + } + + ea->SetMode (mode); + + return true; + } + + template + T VolumeHeader::DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const + { + offset += sizeof (T); + + if (offset > header.Size()) + throw ParameterIncorrect (SRC_POS); + + return Endian::Big (*reinterpret_cast (header.Get() + offset - sizeof (T))); + } + + template + T VolumeHeader::DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const + { + if (offset > header.Size()) + throw ParameterIncorrect (SRC_POS); + + return Endian::Big (*reinterpret_cast (header.Get() + offset)); + } + + void VolumeHeader::EncryptNew (const BufferPtr &newHeaderBuffer, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr newPkcs5Kdf) + { + if (newHeaderBuffer.Size() != HeaderSize || newSalt.Size() != SaltSize) + throw ParameterIncorrect (SRC_POS); + + shared_ptr mode = EA->GetMode()->GetNew(); + shared_ptr ea = EA->GetNew(); + + if (typeid (*mode) == typeid (EncryptionModeXTS)) + { + mode->SetKey (newHeaderKey.GetRange (EA->GetKeySize(), EA->GetKeySize())); + ea->SetKey (newHeaderKey.GetRange (0, ea->GetKeySize())); + } + else + { + mode->SetKey (newHeaderKey.GetRange (0, mode->GetKeySize())); + ea->SetKey (newHeaderKey.GetRange (LegacyEncryptionModeKeyAreaSize, ea->GetKeySize())); + } + + ea->SetMode (mode); + + newHeaderBuffer.CopyFrom (newSalt); + + BufferPtr headerData = newHeaderBuffer.GetRange (EncryptedHeaderDataOffset, EncryptedHeaderDataSize); + Serialize (headerData); + ea->Encrypt (headerData); + + if (newPkcs5Kdf) + Pkcs5 = newPkcs5Kdf; + } + + size_t VolumeHeader::GetLargestSerializedKeySize () + { + size_t largestKey = EncryptionAlgorithm::GetLargestKeySize (EncryptionAlgorithm::GetAvailableAlgorithms()); + + // XTS mode requires the same key size as the encryption algorithm. + // Legacy modes may require larger key than XTS. + if (LegacyEncryptionModeKeyAreaSize + largestKey > largestKey * 2) + return LegacyEncryptionModeKeyAreaSize + largestKey; + + return largestKey * 2; + } + + void VolumeHeader::Serialize (const BufferPtr &header) const + { + if (header.Size() != EncryptedHeaderDataSize) + throw ParameterIncorrect (SRC_POS); + + header.Zero(); + + header[0] = 'T'; + header[1] = 'R'; + header[2] = 'U'; + header[3] = 'E'; + size_t offset = 4; + + header.GetRange (DataAreaKeyOffset, DataAreaKey.Size()).CopyFrom (DataAreaKey); + + uint16 headerVersion = CurrentHeaderVersion; + SerializeEntry (headerVersion, header, offset); + SerializeEntry (RequiredMinProgramVersion, header, offset); + SerializeEntry (Crc32::ProcessBuffer (header.GetRange (DataAreaKeyOffset, DataKeyAreaMaxSize)), header, offset); + + uint64 reserved64 = 0; + SerializeEntry (reserved64, header, offset); + SerializeEntry (reserved64, header, offset); + + SerializeEntry (HiddenVolumeDataSize, header, offset); + SerializeEntry (VolumeDataSize, header, offset); + SerializeEntry (EncryptedAreaStart, header, offset); + SerializeEntry (EncryptedAreaLength, header, offset); + SerializeEntry (Flags, header, offset); + + if (SectorSize < TC_MIN_VOLUME_SECTOR_SIZE + || SectorSize > TC_MAX_VOLUME_SECTOR_SIZE + || SectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) + { + throw ParameterIncorrect (SRC_POS); + } + + SerializeEntry (SectorSize, header, offset); + + offset = TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC; + SerializeEntry (Crc32::ProcessBuffer (header.GetRange (0, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC)), header, offset); + } + + template + void VolumeHeader::SerializeEntry (const T &entry, const BufferPtr &header, size_t &offset) const + { + offset += sizeof (T); + + if (offset > header.Size()) + throw ParameterIncorrect (SRC_POS); + + *reinterpret_cast (header.Get() + offset - sizeof (T)) = Endian::Big (entry); + } + + void VolumeHeader::SetSize (uint32 headerSize) + { + HeaderSize = headerSize; + EncryptedHeaderDataSize = HeaderSize - EncryptedHeaderDataOffset; + } +} diff --git a/src/Volume/VolumeHeader.h b/src/Volume/VolumeHeader.h new file mode 100644 index 00000000..c16fc560 --- /dev/null +++ b/src/Volume/VolumeHeader.h @@ -0,0 +1,126 @@ +/* + Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeHeader +#define TC_HEADER_Volume_VolumeHeader + +#include "Common/Tcdefs.h" +#include "Common/Volumes.h" +#include "Platform/Platform.h" +#include "Volume/EncryptionAlgorithm.h" +#include "Volume/EncryptionMode.h" +#include "Volume/Keyfile.h" +#include "Volume/VolumePassword.h" +#include "Volume/Pkcs5Kdf.h" +#include "Version.h" + + +// For specifications of the volume header see Common/Volumes.c + +namespace TrueCrypt +{ + typedef uint64 VolumeTime; + + struct VolumeType + { + enum Enum + { + Unknown, + Normal, + Hidden + }; + }; + + struct VolumeHeaderCreationOptions + { + ConstBufferPtr DataKey; + shared_ptr EA; + shared_ptr Kdf; + ConstBufferPtr HeaderKey; + ConstBufferPtr Salt; + uint32 SectorSize; + uint64 VolumeDataSize; + uint64 VolumeDataStart; + VolumeType::Enum Type; + }; + + class VolumeHeader + { + public: + VolumeHeader (uint32 HeaderSize); + virtual ~VolumeHeader (); + + void Create (const BufferPtr &headerBuffer, VolumeHeaderCreationOptions &options); + bool Decrypt (const ConstBufferPtr &encryptedData, const VolumePassword &password, const Pkcs5KdfList &keyDerivationFunctions, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes); + void EncryptNew (const BufferPtr &newHeaderBuffer, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr newPkcs5Kdf); + uint64 GetEncryptedAreaStart () const { return EncryptedAreaStart; } + uint64 GetEncryptedAreaLength () const { return EncryptedAreaLength; } + shared_ptr GetEncryptionAlgorithm () const { return EA; } + uint32 GetFlags () const { return Flags; } + VolumeTime GetHeaderCreationTime () const { return HeaderCreationTime; } + uint64 GetHiddenVolumeDataSize () const { return HiddenVolumeDataSize; } + static size_t GetLargestSerializedKeySize (); + shared_ptr GetPkcs5Kdf () const { return Pkcs5; } + uint16 GetRequiredMinProgramVersion () const { return RequiredMinProgramVersion; } + size_t GetSectorSize () const { return SectorSize; } + static uint32 GetSaltSize () { return SaltSize; } + uint64 GetVolumeDataSize () const { return VolumeDataSize; } + VolumeTime GetVolumeCreationTime () const { return VolumeCreationTime; } + void SetSize (uint32 headerSize); + + protected: + bool Deserialize (const ConstBufferPtr &header, shared_ptr &ea, shared_ptr &mode); + template T DeserializeEntry (const ConstBufferPtr &header, size_t &offset) const; + template T DeserializeEntryAt (const ConstBufferPtr &header, const size_t &offset) const; + void Init (); + void Serialize (const BufferPtr &header) const; + template void SerializeEntry (const T &entry, const BufferPtr &header, size_t &offset) const; + + uint32 HeaderSize; + + static const uint16 CurrentHeaderVersion = VOLUME_HEADER_VERSION; + static const uint16 CurrentRequiredMinProgramVersion = TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION; + static const uint16 MinAllowedHeaderVersion = 1; + + static const int SaltOffset = 0; + static const uint32 SaltSize = 64; + + static const int EncryptedHeaderDataOffset = SaltOffset + SaltSize; + uint32 EncryptedHeaderDataSize; + + static const uint32 LegacyEncryptionModeKeyAreaSize = 32; + static const int DataKeyAreaMaxSize = 256; + static const uint32 DataAreaKeyOffset = DataKeyAreaMaxSize - EncryptedHeaderDataOffset; + + shared_ptr EA; + shared_ptr Pkcs5; + + uint16 HeaderVersion; + uint16 RequiredMinProgramVersion; + uint32 VolumeKeyAreaCrc32; + + VolumeTime VolumeCreationTime; + VolumeTime HeaderCreationTime; + + VolumeType::Enum mVolumeType; + uint64 HiddenVolumeDataSize; + uint64 VolumeDataSize; + uint64 EncryptedAreaStart; + uint64 EncryptedAreaLength; + uint32 Flags; + uint32 SectorSize; + + SecureBuffer DataAreaKey; + + private: + VolumeHeader (const VolumeHeader &); + VolumeHeader &operator= (const VolumeHeader &); + }; +} + +#endif // TC_HEADER_Volume_VolumeHeader diff --git a/src/Volume/VolumeInfo.cpp b/src/Volume/VolumeInfo.cpp new file mode 100644 index 00000000..28c7f3f6 --- /dev/null +++ b/src/Volume/VolumeInfo.cpp @@ -0,0 +1,118 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Common/Tcdefs.h" +#include "VolumeInfo.h" +#include "Platform/SerializerFactory.h" + +namespace TrueCrypt +{ + void VolumeInfo::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + + sr.Deserialize ("ProgramVersion", ProgramVersion); + AuxMountPoint = sr.DeserializeWString ("AuxMountPoint"); + sr.Deserialize ("EncryptionAlgorithmBlockSize", EncryptionAlgorithmBlockSize); + sr.Deserialize ("EncryptionAlgorithmKeySize", EncryptionAlgorithmKeySize); + sr.Deserialize ("EncryptionAlgorithmMinBlockSize", EncryptionAlgorithmMinBlockSize); + EncryptionAlgorithmName = sr.DeserializeWString ("EncryptionAlgorithmName"); + EncryptionModeName = sr.DeserializeWString ("EncryptionModeName"); + sr.Deserialize ("HeaderCreationTime", HeaderCreationTime); + sr.Deserialize ("HiddenVolumeProtectionTriggered", HiddenVolumeProtectionTriggered); + LoopDevice = sr.DeserializeWString ("LoopDevice"); + + if (ProgramVersion >= 0x600) + sr.Deserialize ("MinRequiredProgramVersion", MinRequiredProgramVersion); + + MountPoint = sr.DeserializeWString ("MountPoint"); + Path = sr.DeserializeWString ("Path"); + sr.Deserialize ("Pkcs5IterationCount", Pkcs5IterationCount); + Pkcs5PrfName = sr.DeserializeWString ("Pkcs5PrfName"); + Protection = static_cast (sr.DeserializeInt32 ("Protection")); + sr.Deserialize ("SerialInstanceNumber", SerialInstanceNumber); + sr.Deserialize ("Size", Size); + sr.Deserialize ("SlotNumber", SlotNumber); + + if (ProgramVersion >= 0x620) + sr.Deserialize ("SystemEncryption", SystemEncryption); + + if (ProgramVersion >= 0x600) + sr.Deserialize ("TopWriteOffset", TopWriteOffset); + + sr.Deserialize ("TotalDataRead", TotalDataRead); + sr.Deserialize ("TotalDataWritten", TotalDataWritten); + Type = static_cast (sr.DeserializeInt32 ("Type")); + VirtualDevice = sr.DeserializeWString ("VirtualDevice"); + sr.Deserialize ("VolumeCreationTime", VolumeCreationTime); + } + + bool VolumeInfo::FirstVolumeMountedAfterSecond (shared_ptr first, shared_ptr second) + { + return first->SerialInstanceNumber > second->SerialInstanceNumber; + } + + void VolumeInfo::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + + const uint32 version = VERSION_NUM; + sr.Serialize ("ProgramVersion", version); + sr.Serialize ("AuxMountPoint", wstring (AuxMountPoint)); + sr.Serialize ("EncryptionAlgorithmBlockSize", EncryptionAlgorithmBlockSize); + sr.Serialize ("EncryptionAlgorithmKeySize", EncryptionAlgorithmKeySize); + sr.Serialize ("EncryptionAlgorithmMinBlockSize", EncryptionAlgorithmMinBlockSize); + sr.Serialize ("EncryptionAlgorithmName", EncryptionAlgorithmName); + sr.Serialize ("EncryptionModeName", EncryptionModeName); + sr.Serialize ("HeaderCreationTime", HeaderCreationTime); + sr.Serialize ("HiddenVolumeProtectionTriggered", HiddenVolumeProtectionTriggered); + sr.Serialize ("LoopDevice", wstring (LoopDevice)); + sr.Serialize ("MinRequiredProgramVersion", MinRequiredProgramVersion); + sr.Serialize ("MountPoint", wstring (MountPoint)); + sr.Serialize ("Path", wstring (Path)); + sr.Serialize ("Pkcs5IterationCount", Pkcs5IterationCount); + sr.Serialize ("Pkcs5PrfName", Pkcs5PrfName); + sr.Serialize ("Protection", static_cast (Protection)); + sr.Serialize ("SerialInstanceNumber", SerialInstanceNumber); + sr.Serialize ("Size", Size); + sr.Serialize ("SlotNumber", SlotNumber); + sr.Serialize ("SystemEncryption", SystemEncryption); + sr.Serialize ("TopWriteOffset", TopWriteOffset); + sr.Serialize ("TotalDataRead", TotalDataRead); + sr.Serialize ("TotalDataWritten", TotalDataWritten); + sr.Serialize ("Type", static_cast (Type)); + sr.Serialize ("VirtualDevice", wstring (VirtualDevice)); + sr.Serialize ("VolumeCreationTime", VolumeCreationTime); + } + + void VolumeInfo::Set (const Volume &volume) + { + EncryptionAlgorithmBlockSize = static_cast (volume.GetEncryptionAlgorithm()->GetMaxBlockSize()); + EncryptionAlgorithmKeySize = static_cast (volume.GetEncryptionAlgorithm()->GetKeySize()); + EncryptionAlgorithmMinBlockSize = static_cast (volume.GetEncryptionAlgorithm()->GetMinBlockSize()); + EncryptionAlgorithmName = volume.GetEncryptionAlgorithm()->GetName(); + EncryptionModeName = volume.GetEncryptionMode()->GetName(); + HeaderCreationTime = volume.GetHeaderCreationTime(); + VolumeCreationTime = volume.GetVolumeCreationTime(); + HiddenVolumeProtectionTriggered = volume.IsHiddenVolumeProtectionTriggered(); + MinRequiredProgramVersion = volume.GetHeader()->GetRequiredMinProgramVersion(); + Path = volume.GetPath(); + Pkcs5IterationCount = volume.GetPkcs5Kdf()->GetIterationCount(); + Pkcs5PrfName = volume.GetPkcs5Kdf()->GetName(); + Protection = volume.GetProtectionType(); + Size = volume.GetSize(); + SystemEncryption = volume.IsInSystemEncryptionScope(); + Type = volume.GetType(); + TopWriteOffset = volume.GetTopWriteOffset(); + TotalDataRead = volume.GetTotalDataRead(); + TotalDataWritten = volume.GetTotalDataWritten(); + } + + TC_SERIALIZER_FACTORY_ADD_CLASS (VolumeInfo); +} diff --git a/src/Volume/VolumeInfo.h b/src/Volume/VolumeInfo.h new file mode 100644 index 00000000..6e5f5dd4 --- /dev/null +++ b/src/Volume/VolumeInfo.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeInfo +#define TC_HEADER_Volume_VolumeInfo + +#include "Platform/Platform.h" +#include "Platform/Serializable.h" +#include "Volume/Volume.h" +#include "Volume/VolumeSlot.h" + +namespace TrueCrypt +{ + class VolumeInfo; + typedef list < shared_ptr > VolumeInfoList; + + class VolumeInfo : public Serializable + { + public: + VolumeInfo () { } + virtual ~VolumeInfo () { } + + TC_SERIALIZABLE (VolumeInfo); + static bool FirstVolumeMountedAfterSecond (shared_ptr first, shared_ptr second); + void Set (const Volume &volume); + + // Modifying this structure can introduce incompatibility with previous versions + DirectoryPath AuxMountPoint; + uint32 EncryptionAlgorithmBlockSize; + uint32 EncryptionAlgorithmKeySize; + uint32 EncryptionAlgorithmMinBlockSize; + wstring EncryptionAlgorithmName; + wstring EncryptionModeName; + VolumeTime HeaderCreationTime; + bool HiddenVolumeProtectionTriggered; + DevicePath LoopDevice; + uint32 MinRequiredProgramVersion; + DirectoryPath MountPoint; + VolumePath Path; + uint32 Pkcs5IterationCount; + wstring Pkcs5PrfName; + uint32 ProgramVersion; + VolumeProtection::Enum Protection; + uint64 SerialInstanceNumber; + uint64 Size; + VolumeSlotNumber SlotNumber; + bool SystemEncryption; + uint64 TopWriteOffset; + uint64 TotalDataRead; + uint64 TotalDataWritten; + VolumeType::Enum Type; + DevicePath VirtualDevice; + VolumeTime VolumeCreationTime; + + private: + VolumeInfo (const VolumeInfo &); + VolumeInfo &operator= (const VolumeInfo &); + }; +} + +#endif // TC_HEADER_Volume_VolumeInfo diff --git a/src/Volume/VolumeLayout.cpp b/src/Volume/VolumeLayout.cpp new file mode 100644 index 00000000..00696e92 --- /dev/null +++ b/src/Volume/VolumeLayout.cpp @@ -0,0 +1,254 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Volume/EncryptionMode.h" +#include "Volume/EncryptionModeCBC.h" +#include "Volume/EncryptionModeLRW.h" +#include "Volume/EncryptionModeXTS.h" +#include "VolumeLayout.h" +#include "Boot/Windows/BootCommon.h" + +namespace TrueCrypt +{ + VolumeLayout::VolumeLayout () + { + } + + VolumeLayout::~VolumeLayout () + { + } + + VolumeLayoutList VolumeLayout::GetAvailableLayouts (VolumeType::Enum type) + { + VolumeLayoutList layouts; + + layouts.push_back (shared_ptr (new VolumeLayoutV2Normal ())); + layouts.push_back (shared_ptr (new VolumeLayoutV1Normal ())); + layouts.push_back (shared_ptr (new VolumeLayoutV2Hidden ())); + layouts.push_back (shared_ptr (new VolumeLayoutV1Hidden ())); + layouts.push_back (shared_ptr (new VolumeLayoutSystemEncryption ())); + + if (type != VolumeType::Unknown) + { + VolumeLayoutList l; + + foreach (shared_ptr vl, layouts) + { + if (vl->GetType() == type) + l.push_back (vl); + } + + layouts = l; + } + + return layouts; + } + + shared_ptr VolumeLayout::GetHeader () + { + if (Header.get() == nullptr) + Header.reset (new VolumeHeader (GetHeaderSize())); + + return Header; + } + + + VolumeLayoutV1Normal::VolumeLayoutV1Normal () + { + Type = VolumeType::Normal; + HeaderOffset = TC_VOLUME_HEADER_OFFSET; + HeaderSize = TC_VOLUME_HEADER_SIZE_LEGACY; + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Serpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Twofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentTwofishAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TwofishSerpent ())); + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESBlowfish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESBlowfishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Blowfish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Cast5 ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TripleDES ())); + + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + uint64 VolumeLayoutV1Normal::GetDataOffset (uint64 volumeHostSize) const + { + return HeaderSize; + } + + uint64 VolumeLayoutV1Normal::GetDataSize (uint64 volumeHostSize) const + { + return volumeHostSize - GetHeaderSize(); + } + + + VolumeLayoutV1Hidden::VolumeLayoutV1Hidden () + { + Type = VolumeType::Hidden; + HeaderOffset = -TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY; + HeaderSize = TC_VOLUME_HEADER_SIZE_LEGACY; + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Serpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Twofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentTwofishAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TwofishSerpent ())); + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESBlowfish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESBlowfishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Blowfish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Cast5 ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TripleDES ())); + + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeXTS ())); + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeLRW ())); + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeCBC ())); + } + + uint64 VolumeLayoutV1Hidden::GetDataOffset (uint64 volumeHostSize) const + { + return volumeHostSize - GetDataSize (volumeHostSize) + HeaderOffset; + } + + uint64 VolumeLayoutV1Hidden::GetDataSize (uint64 volumeHostSize) const + { + return Header->GetHiddenVolumeDataSize (); + } + + + VolumeLayoutV2Normal::VolumeLayoutV2Normal () + { + Type = VolumeType::Normal; + HeaderOffset = TC_VOLUME_HEADER_OFFSET; + HeaderSize = TC_VOLUME_HEADER_SIZE; + BackupHeaderOffset = -TC_VOLUME_HEADER_GROUP_SIZE; + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Serpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Twofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentTwofishAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TwofishSerpent ())); + + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeXTS ())); + } + + uint64 VolumeLayoutV2Normal::GetDataOffset (uint64 volumeHostSize) const + { + return Header->GetEncryptedAreaStart(); + } + + uint64 VolumeLayoutV2Normal::GetDataSize (uint64 volumeHostSize) const + { + return Header->GetVolumeDataSize(); + } + + uint64 VolumeLayoutV2Normal::GetMaxDataSize (uint64 volumeSize) const + { + if (volumeSize < TC_TOTAL_VOLUME_HEADERS_SIZE) + return 0; + + return volumeSize - TC_TOTAL_VOLUME_HEADERS_SIZE; + } + + + VolumeLayoutV2Hidden::VolumeLayoutV2Hidden () + { + Type = VolumeType::Hidden; + HeaderOffset = TC_HIDDEN_VOLUME_HEADER_OFFSET; + HeaderSize = TC_VOLUME_HEADER_SIZE; + BackupHeaderOffset = -TC_HIDDEN_VOLUME_HEADER_OFFSET; + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Serpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Twofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentTwofishAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TwofishSerpent ())); + + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeXTS ())); + } + + uint64 VolumeLayoutV2Hidden::GetDataOffset (uint64 volumeHostSize) const + { + return Header->GetEncryptedAreaStart(); + } + + uint64 VolumeLayoutV2Hidden::GetDataSize (uint64 volumeHostSize) const + { + return Header->GetVolumeDataSize(); + } + + uint64 VolumeLayoutV2Hidden::GetMaxDataSize (uint64 volumeSize) const + { + // Reserve free space at the end of the host filesystem + uint64 reservedSize; + + if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD) + reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE; + else + reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH; // Ensure size of a hidden volume larger than TC_VOLUME_SMALL_SIZE_THRESHOLD is a multiple of the maximum supported sector size + + if (volumeSize < reservedSize) + return 0; + + return volumeSize - reservedSize; + } + + + VolumeLayoutSystemEncryption::VolumeLayoutSystemEncryption () + { + Type = VolumeType::Normal; + HeaderOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; + HeaderSize = TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE; + + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Serpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new Twofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofish ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new AESTwofishSerpent ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new SerpentTwofishAES ())); + SupportedEncryptionAlgorithms.push_back (shared_ptr (new TwofishSerpent ())); + + SupportedEncryptionModes.push_back (shared_ptr (new EncryptionModeXTS ())); + } + + uint64 VolumeLayoutSystemEncryption::GetDataOffset (uint64 volumeHostSize) const + { + return 0; + } + + uint64 VolumeLayoutSystemEncryption::GetDataSize (uint64 volumeHostSize) const + { + return volumeHostSize; + } + + Pkcs5KdfList VolumeLayoutSystemEncryption::GetSupportedKeyDerivationFunctions () const + { + Pkcs5KdfList l; + + l.push_back (shared_ptr (new Pkcs5HmacRipemd160_1000 ())); + return l; + } +} diff --git a/src/Volume/VolumeLayout.h b/src/Volume/VolumeLayout.h new file mode 100644 index 00000000..d2147425 --- /dev/null +++ b/src/Volume/VolumeLayout.h @@ -0,0 +1,153 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeLayout +#define TC_HEADER_Volume_VolumeLayout + +#include "Platform/Platform.h" +#include "Volume/EncryptionAlgorithm.h" +#include "Volume/EncryptionMode.h" +#include "Volume/Pkcs5Kdf.h" +#include "VolumeHeader.h" + +namespace TrueCrypt +{ + class VolumeLayout; + typedef list < shared_ptr > VolumeLayoutList; + + class VolumeLayout + { + public: + virtual ~VolumeLayout (); + + static VolumeLayoutList GetAvailableLayouts (VolumeType::Enum type = VolumeType::Unknown); + virtual int GetBackupHeaderOffset () const { return BackupHeaderOffset; } // Positive value: offset from the start of host, negative: offset from the end + virtual uint64 GetDataOffset (uint64 volumeHostSize) const = 0; + virtual uint64 GetDataSize (uint64 volumeHostSize) const = 0; + virtual shared_ptr GetHeader (); + virtual int GetHeaderOffset () const { return HeaderOffset; } // Positive value: offset from the start of host, negative: offset from the end + virtual uint32 GetHeaderSize () const { return HeaderSize; } + virtual uint64 GetMaxDataSize (uint64 volumeSize) const = 0; + virtual EncryptionAlgorithmList GetSupportedEncryptionAlgorithms () const { return SupportedEncryptionAlgorithms; } + virtual Pkcs5KdfList GetSupportedKeyDerivationFunctions () const { return Pkcs5Kdf::GetAvailableAlgorithms(); } + virtual EncryptionModeList GetSupportedEncryptionModes () const { return SupportedEncryptionModes; } + virtual VolumeType::Enum GetType () const { return Type; } + virtual bool HasBackupHeader () const = 0; + virtual bool HasDriveHeader () const { return false; } + virtual void SetHeader (shared_ptr header) { Header = header; } + + protected: + VolumeLayout (); + + EncryptionAlgorithmList SupportedEncryptionAlgorithms; + EncryptionModeList SupportedEncryptionModes; + + int BackupHeaderOffset; + int HeaderOffset; + uint32 HeaderSize; + VolumeType::Enum Type; + + shared_ptr Header; + + private: + VolumeLayout (const VolumeLayout &); + VolumeLayout &operator= (const VolumeLayout &); + }; + + + class VolumeLayoutV1Normal : public VolumeLayout + { + public: + VolumeLayoutV1Normal (); + virtual ~VolumeLayoutV1Normal () { } + + virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); } + virtual uint64 GetDataOffset (uint64 volumeHostSize) const; + virtual uint64 GetDataSize (uint64 volumeHostSize) const; + virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); } + virtual bool HasBackupHeader () const { return false; } + + private: + VolumeLayoutV1Normal (const VolumeLayoutV1Normal &); + VolumeLayoutV1Normal &operator= (const VolumeLayoutV1Normal &); + }; + + + class VolumeLayoutV1Hidden : public VolumeLayout + { + public: + VolumeLayoutV1Hidden (); + virtual ~VolumeLayoutV1Hidden () { } + + virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); } + virtual uint64 GetDataOffset (uint64 volumeHostSize) const; + virtual uint64 GetDataSize (uint64 volumeHostSize) const; + virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); } + virtual bool HasBackupHeader () const { return false; } + + private: + VolumeLayoutV1Hidden (const VolumeLayoutV1Hidden &); + VolumeLayoutV1Hidden &operator= (const VolumeLayoutV1Hidden &); + }; + + + class VolumeLayoutV2Normal : public VolumeLayout + { + public: + VolumeLayoutV2Normal (); + virtual ~VolumeLayoutV2Normal () { } + + virtual uint64 GetDataOffset (uint64 volumeHostSize) const; + virtual uint64 GetDataSize (uint64 volumeHostSize) const; + virtual uint64 GetMaxDataSize (uint64 volumeSize) const; + virtual bool HasBackupHeader () const { return true; } + + private: + VolumeLayoutV2Normal (const VolumeLayoutV2Normal &); + VolumeLayoutV2Normal &operator= (const VolumeLayoutV2Normal &); + }; + + + class VolumeLayoutV2Hidden : public VolumeLayout + { + public: + VolumeLayoutV2Hidden (); + virtual ~VolumeLayoutV2Hidden () { } + + virtual uint64 GetDataOffset (uint64 volumeHostSize) const; + virtual uint64 GetDataSize (uint64 volumeHostSize) const; + virtual uint64 GetMaxDataSize (uint64 volumeSize) const; + virtual bool HasBackupHeader () const { return true; } + + private: + VolumeLayoutV2Hidden (const VolumeLayoutV2Hidden &); + VolumeLayoutV2Hidden &operator= (const VolumeLayoutV2Hidden &); + }; + + + class VolumeLayoutSystemEncryption : public VolumeLayout + { + public: + VolumeLayoutSystemEncryption (); + virtual ~VolumeLayoutSystemEncryption () { } + + virtual int GetBackupHeaderOffset () const { throw NotApplicable (SRC_POS); } + virtual uint64 GetDataOffset (uint64 volumeHostSize) const; + virtual uint64 GetDataSize (uint64 volumeHostSize) const; + virtual uint64 GetMaxDataSize (uint64 volumeSize) const { throw NotApplicable (SRC_POS); } + virtual Pkcs5KdfList GetSupportedKeyDerivationFunctions () const; + virtual bool HasBackupHeader () const { return false; } + virtual bool HasDriveHeader () const { return true; } + + private: + VolumeLayoutSystemEncryption (const VolumeLayoutSystemEncryption &); + VolumeLayoutSystemEncryption &operator= (const VolumeLayoutSystemEncryption &); + }; +} + +#endif // TC_HEADER_Volume_VolumeLayout diff --git a/src/Volume/VolumePassword.cpp b/src/Volume/VolumePassword.cpp new file mode 100644 index 00000000..86b17e22 --- /dev/null +++ b/src/Volume/VolumePassword.cpp @@ -0,0 +1,167 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "VolumePassword.h" +#include "Platform/SerializerFactory.h" +#include "Platform/StringConverter.h" + +namespace TrueCrypt +{ + VolumePassword::VolumePassword () : PasswordSize (0), Unportable (false) + { + AllocateBuffer (); + } + + VolumePassword::VolumePassword (const char *password, size_t size) + { + Set ((const byte *) password, size); + } + + VolumePassword::VolumePassword (const byte *password, size_t size) + { + Set (password, size); + } + + VolumePassword::VolumePassword (const wchar_t *password, size_t charCount) + { + Set (password, charCount); + } + + VolumePassword::VolumePassword (const wstring &password) + { + Set (password.c_str(), password.size()); + } + + VolumePassword::~VolumePassword () + { + } + + void VolumePassword::AllocateBuffer () + { + if (!PasswordBuffer.IsAllocated ()) + PasswordBuffer.Allocate (MaxSize); + } + + void VolumePassword::CheckPortability () const + { + if (Unportable || !IsPortable()) + throw UnportablePassword (SRC_POS); + } + + void VolumePassword::Deserialize (shared_ptr stream) + { + Serializer sr (stream); + uint64 passwordSize; + sr.Deserialize ("PasswordSize", passwordSize); + PasswordSize = static_cast (passwordSize); + sr.Deserialize ("PasswordBuffer", BufferPtr (PasswordBuffer)); + + Buffer wipeBuffer (128 * 1024); + sr.Deserialize ("WipeData", wipeBuffer); + } + + bool VolumePassword::IsPortable () const + { + for (size_t i = 0; i < PasswordSize; i++) + { + if (PasswordBuffer[i] >= 0x7f || PasswordBuffer[i] < 0x20) + return false; + } + return true; + } + + void VolumePassword::Serialize (shared_ptr stream) const + { + Serializable::Serialize (stream); + Serializer sr (stream); + sr.Serialize ("PasswordSize", static_cast (PasswordSize)); + sr.Serialize ("PasswordBuffer", ConstBufferPtr (PasswordBuffer)); + + // Wipe password from an eventual pipe buffer + Buffer wipeBuffer (128 * 1024); + wipeBuffer.Zero(); + sr.Serialize ("WipeData", ConstBufferPtr (wipeBuffer)); + } + + void VolumePassword::Set (const byte *password, size_t size) + { + AllocateBuffer (); + + if (size > MaxSize) + throw PasswordTooLong (SRC_POS); + + PasswordBuffer.CopyFrom (ConstBufferPtr (password, size)); + PasswordSize = size; + + Unportable = !IsPortable(); + } + + void VolumePassword::Set (const wchar_t *password, size_t charCount) + { + if (charCount > MaxSize) + throw PasswordTooLong (SRC_POS); + + union Conv + { + byte b[sizeof (wchar_t)]; + wchar_t c; + }; + + Conv conv; + conv.c = L'A'; + + int lsbPos = -1; + for (size_t i = 0; i < sizeof (conv.b); ++i) + { + if (conv.b[i] == L'A') + { + lsbPos = i; + break; + } + } + + if (lsbPos == -1) + throw ParameterIncorrect (SRC_POS); + + bool unportable = false; + byte passwordBuf[MaxSize]; + for (size_t i = 0; i < charCount; ++i) + { + conv.c = password[i]; + passwordBuf[i] = conv.b[lsbPos]; + for (int j = 0; j < (int) sizeof (wchar_t); ++j) + { + if (j != lsbPos && conv.b[j] != 0) + unportable = true; + } + } + + Set (passwordBuf, charCount); + + if (unportable) + Unportable = true; + } + + void VolumePassword::Set (const ConstBufferPtr &password) + { + Set (password, password.Size()); + } + + void VolumePassword::Set (const VolumePassword &password) + { + Set (password.DataPtr(), password.Size()); + } + + TC_SERIALIZER_FACTORY_ADD_CLASS (VolumePassword); + +#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +#undef TC_EXCEPTION_NODECL +#define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (PasswordException); +} diff --git a/src/Volume/VolumePassword.h b/src/Volume/VolumePassword.h new file mode 100644 index 00000000..e43c50ec --- /dev/null +++ b/src/Volume/VolumePassword.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Encryption_Password +#define TC_HEADER_Encryption_Password + +#include "Platform/Platform.h" +#include "Platform/Serializable.h" + +namespace TrueCrypt +{ + class VolumePassword : public Serializable + { + public: + VolumePassword (); + VolumePassword (const byte *password, size_t size); + VolumePassword (const char *password, size_t size); + VolumePassword (const wchar_t *password, size_t charCount); + VolumePassword (const wstring &password); + VolumePassword (const VolumePassword &password) { Set (password); } + virtual ~VolumePassword (); + + bool operator== (const VolumePassword &other) const { return ConstBufferPtr (DataPtr(), Size()).IsDataEqual (ConstBufferPtr (other.DataPtr(), other.Size())); } + bool operator!= (const VolumePassword &other) const { return !(*this == other); } + VolumePassword &operator= (const VolumePassword &password) { Set (password); return *this; } + + operator BufferPtr () const { return BufferPtr (PasswordBuffer); } + + void CheckPortability () const; + byte *DataPtr () const { return PasswordBuffer; } + bool IsEmpty () const { return PasswordSize == 0; } + size_t Size () const { return PasswordSize; } + void Set (const byte *password, size_t size); + void Set (const wchar_t *password, size_t charCount); + void Set (const ConstBufferPtr &password); + void Set (const VolumePassword &password); + + TC_SERIALIZABLE (VolumePassword); + + static const size_t MaxSize = 64; + static const size_t WarningSizeThreshold = 12; + + protected: + void AllocateBuffer (); + bool IsPortable () const; + + SecureBuffer PasswordBuffer; + + size_t PasswordSize; + bool Unportable; + }; + + struct PasswordException : public Exception + { + protected: + PasswordException () { } + PasswordException (const string &message) : Exception (message) { } + PasswordException (const string &message, const wstring &subject) : Exception (message, subject) { } + }; + + TC_EXCEPTION_DECL (PasswordIncorrect, PasswordException); + TC_EXCEPTION_DECL (PasswordKeyfilesIncorrect, PasswordIncorrect); + TC_EXCEPTION_DECL (PasswordOrKeyboardLayoutIncorrect, PasswordException); + TC_EXCEPTION_DECL (PasswordOrMountOptionsIncorrect, PasswordException); + TC_EXCEPTION_DECL (ProtectionPasswordIncorrect, PasswordIncorrect); + TC_EXCEPTION_DECL (ProtectionPasswordKeyfilesIncorrect, PasswordIncorrect); + +#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,PasswordException) + +#undef TC_EXCEPTION_SET +#define TC_EXCEPTION_SET \ + TC_EXCEPTION_NODECL (PasswordIncorrect); \ + TC_EXCEPTION_NODECL (PasswordKeyfilesIncorrect); \ + TC_EXCEPTION_NODECL (PasswordOrKeyboardLayoutIncorrect); \ + TC_EXCEPTION_NODECL (PasswordOrMountOptionsIncorrect); \ + TC_EXCEPTION_NODECL (ProtectionPasswordIncorrect); \ + TC_EXCEPTION_NODECL (ProtectionPasswordKeyfilesIncorrect); \ + TC_EXCEPTION (PasswordEmpty); \ + TC_EXCEPTION (PasswordTooLong); \ + TC_EXCEPTION (UnportablePassword); + + TC_EXCEPTION_SET; + +#undef TC_EXCEPTION +} + +#endif // TC_HEADER_Encryption_Password diff --git a/src/Volume/VolumePasswordCache.cpp b/src/Volume/VolumePasswordCache.cpp new file mode 100644 index 00000000..23472d2d --- /dev/null +++ b/src/Volume/VolumePasswordCache.cpp @@ -0,0 +1,43 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "VolumePasswordCache.h" + +namespace TrueCrypt +{ + CachedPasswordList VolumePasswordCache::GetPasswords () + { + CachedPasswordList passwords; + + foreach_ref (const VolumePassword &password, CachedPasswords) + passwords.push_back (make_shared (VolumePassword (password))); + + return passwords; + } + + void VolumePasswordCache::Store (const VolumePassword &newPassword) + { + CachedPasswordList::iterator iter = CachedPasswords.begin(); + foreach_ref (const VolumePassword &password, CachedPasswords) + { + if (newPassword == password) + { + CachedPasswords.erase (iter); + break; + } + iter++; + } + + CachedPasswords.push_front (make_shared (VolumePassword (newPassword))); + + if (CachedPasswords.size() > Capacity) + CachedPasswords.pop_back(); + } + + CachedPasswordList VolumePasswordCache::CachedPasswords; +} diff --git a/src/Volume/VolumePasswordCache.h b/src/Volume/VolumePasswordCache.h new file mode 100644 index 00000000..6d5118af --- /dev/null +++ b/src/Volume/VolumePasswordCache.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumePasswordCache +#define TC_HEADER_Volume_VolumePasswordCache + +#include "Platform/Platform.h" +#include "VolumePassword.h" + +namespace TrueCrypt +{ + typedef list < shared_ptr < VolumePassword > > CachedPasswordList; + + class VolumePasswordCache + { + public: + static CachedPasswordList GetPasswords (); + static bool IsEmpty () { return CachedPasswords.empty(); } + static void Store (const VolumePassword &newPassword); + static void Clear () { CachedPasswords.clear(); } + static const size_t Capacity = 4; + + protected: + static CachedPasswordList CachedPasswords; + + private: + VolumePasswordCache (); + }; +} + +#endif // TC_HEADER_Volume_VolumePasswordCache diff --git a/src/Volume/VolumeSlot.h b/src/Volume/VolumeSlot.h new file mode 100644 index 00000000..fe368772 --- /dev/null +++ b/src/Volume/VolumeSlot.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Volume_VolumeSlot +#define TC_HEADER_Volume_VolumeSlot + +#include "Platform/Platform.h" + +namespace TrueCrypt +{ + typedef uint32 VolumeSlotNumber; +} + +#endif // TC_HEADER_Volume_VolumeSlot