Add TrueCrypt 7.1a MacOSX/Linux specific source files.

This commit is contained in:
Mounir IDRASSI 2014-05-31 18:44:53 +02:00
parent 97011f179c
commit 7ffce028d0
203 changed files with 51616 additions and 0 deletions

View File

@ -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 $(<F)
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.cpp
@echo Compiling $(<F)
$(CXX) $(CXXFLAGS) -c $< -o $@
%.o: %.asm
@echo Assembling $(<F)
$(AS) $(ASFLAGS) -o $@ $<
# Precompiled headers
%.h.gch: %.h
@echo Precompiling $(<F)
$(CXX) $(CXXFLAGS) -g0 -c $< || (rm -f $(<F).gch && exit 1)
# Embedded files
OD_BIN := od -v -t u1 -A n
TR_SED_BIN := tr '\n' ' ' | tr -s ' ' ',' | sed -e 's/^,//g' -e 's/,$$/n/' | tr 'n' '\n'
%.xml.h: %.xml
@echo Converting $(<F)
$(OD_BIN) $< | $(TR_SED_BIN) >$@
%.txt.h: %.txt
@echo Converting $(<F)
$(OD_BIN) $< | $(TR_SED_BIN) >$@
%.bmp.h: %.bmp
@echo Converting $(<F)
$(OD_BIN) $< | $(TR_SED_BIN) >$@
# Dependencies
-include $(OBJS:.o=.d)
$(NAME).a: $(OBJS)
@echo Updating library $@
$(AR) $(AFLAGS) -rcu $@ $(OBJS)
$(RANLIB) $@

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleIdentifier</key>
<string>org.TrueCryptFoundation.TrueCrypt</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>TrueCrypt</string>
<key>CFBundleIconFile</key>
<string>TrueCrypt.icns</string>
<key>CFBundleName</key>
<string>TrueCrypt</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>TRUE</string>
<key>CFBundleVersion</key>
<string>0</string>
<key>CFBundleShortVersionString</key>
<string>_VERSION_</string>
<key>CFBundleLongVersionString</key>
<string>TrueCrypt _VERSION_</string>
<key>LSRequiresCarbon</key>
<true/>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
</plist>

20
src/Core/Core.h Normal file
View File

@ -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 <CoreBase> Core;
extern auto_ptr <CoreBase> CoreDirect;
}
#endif // TC_HEADER_Core_Core

27
src/Core/Core.make Normal file
View File

@ -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

279
src/Core/CoreBase.cpp Normal file
View File

@ -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 <set>
#include "CoreBase.h"
#include "RandomNumberGenerator.h"
#include "Volume/Volume.h"
namespace TrueCrypt
{
CoreBase::CoreBase ()
: DeviceChangeInProgress (false)
{
}
CoreBase::~CoreBase ()
{
}
void CoreBase::ChangePassword (shared_ptr <Volume> openVolume, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> 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 <VolumePassword> 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> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf) const
{
shared_ptr <Volume> 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 <VolumeSlotNumber> 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 <Volume> 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 <VolumeInfo> CoreBase::GetMountedVolume (const VolumePath &volumePath) const
{
VolumeInfoList volumes = GetMountedVolumes (volumePath);
if (volumes.empty())
return shared_ptr <VolumeInfo> ();
else
return volumes.front();
}
shared_ptr <VolumeInfo> CoreBase::GetMountedVolume (VolumeSlotNumber slot) const
{
foreach (shared_ptr <VolumeInfo> volume, GetMountedVolumes())
{
if (volume->SlotNumber == slot)
return volume;
}
return shared_ptr <VolumeInfo> ();
}
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 <Volume> CoreBase::OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection, shared_ptr <VolumePassword> protectionPassword, shared_ptr <KeyfileList> 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> 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 <VolumeHeader> header, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles) const
{
shared_ptr <Pkcs5Kdf> pkcs5Kdf = header->GetPkcs5Kdf();
RandomNumberGenerator::SetHash (pkcs5Kdf->GetHash());
SecureBuffer newSalt (header->GetSaltSize());
SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize());
shared_ptr <VolumePassword> passwordKey (Keyfile::ApplyListToPassword (keyfiles, password));
RandomNumberGenerator::GetData (newSalt);
pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, newSalt);
header->EncryptNew (newHeaderBuffer, newSalt, newHeaderKey, pkcs5Kdf);
}
}

99
src/Core/CoreBase.h Normal file
View File

@ -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 <Volume> openVolume, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> ()) const;
virtual void ChangePassword (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> newKeyfiles, shared_ptr <Pkcs5Kdf> newPkcs5Kdf = shared_ptr <Pkcs5Kdf> ()) const;
virtual void CheckFilesystem (shared_ptr <VolumeInfo> 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 <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> 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 <Volume> outerVolume) const;
virtual int GetOSMajorVersion () const = 0;
virtual int GetOSMinorVersion () const = 0;
virtual shared_ptr <VolumeInfo> GetMountedVolume (const VolumePath &volumePath) const;
virtual shared_ptr <VolumeInfo> 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 <VolumeInfo> MountVolume (MountOptions &options) = 0;
virtual shared_ptr <Volume> OpenVolume (shared_ptr <VolumePath> volumePath, bool preserveTimestamps, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr <VolumePassword> protectionPassword = shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> protectionKeyfiles = shared_ptr <KeyfileList> (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const;
virtual void RandomizeEncryptionAlgorithmKey (shared_ptr <EncryptionAlgorithm> encryptionAlgorithm) const;
virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr <VolumeHeader> header, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles) const;
virtual void SetAdminPasswordCallback (shared_ptr <GetStringFunctor> 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 <VolumeInfo> volume) : mVolume (volume) { }
shared_ptr <VolumeInfo> mVolume;
};
}
#endif // TC_HEADER_Core_CoreBase

View File

@ -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> stream)
{
ExecutedProcessFailed::Deserialize (stream);
}
void ElevationFailed::Serialize (shared_ptr <Stream> 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);
}

52
src/Core/CoreException.h Normal file
View File

@ -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

384
src/Core/FatFormatter.cpp Normal file
View File

@ -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;
}
}
}

29
src/Core/FatFormatter.h Normal file
View File

@ -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 &sector) = 0;
};
static void Format (WriteSectorCallback &writeSector, uint64 deviceSize, uint32 clusterSize, uint32 sectorSize);
};
}
#endif // TC_HEADER_Core_FatFormatter

47
src/Core/HostDevice.cpp Normal file
View File

@ -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> 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 <HostDevice> (stream));
}
void HostDevice::Serialize (shared_ptr <Stream> 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);
}

45
src/Core/HostDevice.h Normal file
View File

@ -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 <HostDevice> > 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

129
src/Core/MountOptions.cpp Normal file
View File

@ -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 <TYPE> (*other.NAME) : shared_ptr <TYPE> ()
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> 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 <VolumePassword> (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 <VolumeProtection::Enum> (sr.DeserializeInt32 ("Protection"));
if (!sr.DeserializeBool ("ProtectionPasswordNull"))
ProtectionPassword = Serializable::DeserializeNew <VolumePassword> (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> 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 <uint32> (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);
}

70
src/Core/MountOptions.h Normal file
View File

@ -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 <KeyfileList> Keyfiles;
shared_ptr <DirectoryPath> MountPoint;
bool NoFilesystem;
bool NoHardwareCrypto;
bool NoKernelCrypto;
shared_ptr <VolumePassword> Password;
bool PartitionInSystemEncryptionScope;
shared_ptr <VolumePath> Path;
bool PreserveTimestamps;
VolumeProtection::Enum Protection;
shared_ptr <VolumePassword> ProtectionPassword;
shared_ptr <KeyfileList> ProtectionKeyfiles;
bool Removable;
bool SharedAccessAllowed;
VolumeSlotNumber SlotNumber;
bool UseBackupHeaders;
protected:
void CopyFrom (const MountOptions &other);
};
}
#endif // TC_HEADER_Core_MountOptions

View File

@ -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 <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#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 <Hash> 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> 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 <Hash> 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 <Hash> RandomNumberGenerator::PoolHash;
size_t RandomNumberGenerator::ReadOffset;
bool RandomNumberGenerator::Running = false;
size_t RandomNumberGenerator::WriteOffset;
}

View File

@ -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 <Hash> 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> 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 <Hash> PoolHash;
static size_t ReadOffset;
static bool Running;
static size_t WriteOffset;
};
}
#endif // TC_HEADER_Core_RandomNumberGenerator

View File

@ -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 <fcntl.h>
#include <sys/wait.h>
#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 <class T>
auto_ptr <T> CoreService::GetResponse ()
{
auto_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream));
Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
if (deserializedException)
deserializedException->Throw();
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
throw ParameterIncorrect (SRC_POS);
return auto_ptr <T> (dynamic_cast <T *> (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 <Stream> inputStream (new FileStream (inputFD != -1 ? inputFD : InputPipe->GetReadFD()));
shared_ptr <Stream> outputStream (new FileStream (outputFD != -1 ? outputFD : OutputPipe->GetWriteFD()));
while (true)
{
shared_ptr <CoreServiceRequest> request = Serializable::DeserializeNew <CoreServiceRequest> (inputStream);
try
{
// ExitRequest
if (dynamic_cast <ExitRequest*> (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 <Serializable>()->Serialize (outputStream);
continue;
}
// CheckFilesystemRequest
CheckFilesystemRequest *checkRequest = dynamic_cast <CheckFilesystemRequest*> (request.get());
if (checkRequest)
{
Core->CheckFilesystem (checkRequest->MountedVolumeInfo, checkRequest->Repair);
CheckFilesystemResponse().Serialize (outputStream);
continue;
}
// DismountFilesystemRequest
DismountFilesystemRequest *dismountFsRequest = dynamic_cast <DismountFilesystemRequest*> (request.get());
if (dismountFsRequest)
{
Core->DismountFilesystem (dismountFsRequest->MountPoint, dismountFsRequest->Force);
DismountFilesystemResponse().Serialize (outputStream);
continue;
}
// DismountVolumeRequest
DismountVolumeRequest *dismountRequest = dynamic_cast <DismountVolumeRequest*> (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 <GetDeviceSectorSizeRequest*> (request.get());
if (getDeviceSectorSizeRequest)
{
GetDeviceSectorSizeResponse response;
response.Size = Core->GetDeviceSectorSize (getDeviceSectorSizeRequest->Path);
response.Serialize (outputStream);
continue;
}
// GetDeviceSizeRequest
GetDeviceSizeRequest *getDeviceSizeRequest = dynamic_cast <GetDeviceSizeRequest*> (request.get());
if (getDeviceSizeRequest)
{
GetDeviceSizeResponse response;
response.Size = Core->GetDeviceSize (getDeviceSizeRequest->Path);
response.Serialize (outputStream);
continue;
}
// GetHostDevicesRequest
GetHostDevicesRequest *getHostDevicesRequest = dynamic_cast <GetHostDevicesRequest*> (request.get());
if (getHostDevicesRequest)
{
GetHostDevicesResponse response;
response.HostDevices = Core->GetHostDevices (getHostDevicesRequest->PathListOnly);
response.Serialize (outputStream);
continue;
}
// MountVolumeRequest
MountVolumeRequest *mountRequest = dynamic_cast <MountVolumeRequest*> (request.get());
if (mountRequest)
{
MountVolumeResponse (
Core->MountVolume (*mountRequest->Options)
).Serialize (outputStream);
continue;
}
// SetFileOwnerRequest
SetFileOwnerRequest *setFileOwnerRequest = dynamic_cast <SetFileOwnerRequest*> (request.get());
if (setFileOwnerRequest)
{
CoreUnix *coreUnix = dynamic_cast <CoreUnix *> (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 <VolumeInfo> mountedVolume, bool repair)
{
CheckFilesystemRequest request (mountedVolume, repair);
SendRequest <CheckFilesystemResponse> (request);
}
void CoreService::RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force)
{
DismountFilesystemRequest request (mountPoint, force);
SendRequest <DismountFilesystemResponse> (request);
}
shared_ptr <VolumeInfo> CoreService::RequestDismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
DismountVolumeRequest request (mountedVolume, ignoreOpenFiles, syncVolumeInfo);
return SendRequest <DismountVolumeResponse> (request)->DismountedVolumeInfo;
}
uint32 CoreService::RequestGetDeviceSectorSize (const DevicePath &devicePath)
{
GetDeviceSectorSizeRequest request (devicePath);
return SendRequest <GetDeviceSectorSizeResponse> (request)->Size;
}
uint64 CoreService::RequestGetDeviceSize (const DevicePath &devicePath)
{
GetDeviceSizeRequest request (devicePath);
return SendRequest <GetDeviceSizeResponse> (request)->Size;
}
HostDeviceList CoreService::RequestGetHostDevices (bool pathListOnly)
{
GetHostDevicesRequest request (pathListOnly);
return SendRequest <GetHostDevicesResponse> (request)->HostDevices;
}
shared_ptr <VolumeInfo> CoreService::RequestMountVolume (MountOptions &options)
{
MountVolumeRequest request (&options);
return SendRequest <MountVolumeResponse> (request)->MountedVolumeInfo;
}
void CoreService::RequestSetFileOwner (const FilesystemPath &path, const UserId &owner)
{
SetFileOwnerRequest request (path, owner);
SendRequest <SetFileOwnerResponse> (request);
}
template <class T>
auto_ptr <T> 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 <T> response (GetResponse <T>());
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 <T>();
}
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 <Stream> (new FileStream (InputPipe->GetWriteFD()));
ServiceOutputStream = shared_ptr <Stream> (new FileStream (OutputPipe->GetReadFD()));
}
void CoreService::StartElevated (const CoreServiceRequest &request)
{
auto_ptr <Pipe> inPipe (new Pipe());
auto_ptr <Pipe> 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 <Stream> outputStream (new FileStream (errPipe.GetWriteFD()));
e.Serialize (outputStream);
}
catch (...) { }
}
_exit (1);
}
vector <char> adminPassword (request.AdminPassword.size() + 1);
int timeout = 6000;
if (request.FastElevation)
{
string dummyPassword = "dummy\n";
adminPassword = vector <char> (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 <char> 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 <Serializable> deserializedObject;
Exception *deserializedException = nullptr;
try
{
shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((byte *) &errOutput[0], errOutput.size())));
deserializedObject.reset (Serializable::DeserializeNew (stream));
deserializedException = dynamic_cast <Exception*> (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 <Stream> (new FileStream (inPipe->GetWriteFD()));
ServiceOutputStream = shared_ptr <Stream> (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 <GetStringFunctor> CoreService::AdminPasswordCallback;
auto_ptr <Pipe> CoreService::AdminInputPipe;
auto_ptr <Pipe> CoreService::AdminOutputPipe;
auto_ptr <Pipe> CoreService::InputPipe;
auto_ptr <Pipe> CoreService::OutputPipe;
shared_ptr <Stream> CoreService::ServiceInputStream;
shared_ptr <Stream> CoreService::ServiceOutputStream;
bool CoreService::ElevatedPrivileges = false;
bool CoreService::ElevatedServiceAvailable = false;
}

View File

@ -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 <VolumeInfo> mountedVolume, bool repair);
static void RequestDismountFilesystem (const DirectoryPath &mountPoint, bool force);
static shared_ptr <VolumeInfo> RequestDismountVolume (shared_ptr <VolumeInfo> 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 <VolumeInfo> RequestMountVolume (MountOptions &options);
static void RequestSetFileOwner (const FilesystemPath &path, const UserId &owner);
static void SetAdminPasswordCallback (shared_ptr <GetStringFunctor> functor) { AdminPasswordCallback = functor; }
static void Start ();
static void Stop ();
protected:
template <class T> static auto_ptr <T> GetResponse ();
template <class T> static auto_ptr <T> SendRequest (CoreServiceRequest &request);
static void StartElevated (const CoreServiceRequest &request);
static shared_ptr <GetStringFunctor> AdminPasswordCallback;
static auto_ptr <Pipe> AdminInputPipe;
static auto_ptr <Pipe> AdminOutputPipe;
static auto_ptr <Pipe> InputPipe;
static auto_ptr <Pipe> OutputPipe;
static shared_ptr <Stream> ServiceInputStream;
static shared_ptr <Stream> 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

View File

@ -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 T>
class CoreServiceProxy : public T
{
public:
CoreServiceProxy () { }
virtual ~CoreServiceProxy () { }
virtual void CheckFilesystem (shared_ptr <VolumeInfo> mountedVolume, bool repair) const
{
CoreService::RequestCheckFilesystem (mountedVolume, repair);
}
virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const
{
CoreService::RequestDismountFilesystem (mountPoint, force);
}
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles = false, bool syncVolumeInfo = false)
{
shared_ptr <VolumeInfo> 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 <VolumeInfo> MountVolume (MountOptions &options)
{
shared_ptr <VolumeInfo> 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 <VolumePassword> password, VolumePasswordCache::GetPasswords())
{
try
{
options.Password = password;
mountedVolume = CoreService::RequestMountVolume (options);
break;
}
catch (PasswordIncorrect &e)
{
passwordException = e;
}
}
if (!mountedVolume)
passwordException.Throw();
}
else
{
MountOptions newOptions = options;
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 <GetStringFunctor> 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

View File

@ -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 <errno.h>
#include "CoreServiceRequest.h"
#include "Platform/SerializerFactory.h"
namespace TrueCrypt
{
void CoreServiceRequest::Deserialize (shared_ptr <Stream> 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> 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> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
sr.Deserialize ("Repair", Repair);
}
bool CheckFilesystemRequest::RequiresElevation () const
{
#ifdef TC_MACOSX
return false;
#endif
return !Core->HasAdminPrivileges();
}
void CheckFilesystemRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
MountedVolumeInfo->Serialize (stream);
sr.Serialize ("Repair", Repair);
}
// DismountFilesystemRequest
void DismountFilesystemRequest::Deserialize (shared_ptr <Stream> 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> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Force", Force);
sr.Serialize ("MountPoint", wstring (MountPoint));
}
// DismountVolumeRequest
void DismountVolumeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("IgnoreOpenFiles", IgnoreOpenFiles);
sr.Deserialize ("SyncVolumeInfo", SyncVolumeInfo);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (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> 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> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
Path = sr.DeserializeWString ("Path");
}
bool GetDeviceSectorSizeRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetDeviceSectorSizeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Path", wstring (Path));
}
// GetDeviceSizeRequest
void GetDeviceSizeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
Path = sr.DeserializeWString ("Path");
}
bool GetDeviceSizeRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetDeviceSizeRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Path", wstring (Path));
}
// GetHostDevicesRequest
void GetHostDevicesRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
sr.Deserialize ("PathListOnly", PathListOnly);
}
bool GetHostDevicesRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void GetHostDevicesRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("PathListOnly", PathListOnly);
}
// ExitRequest
void ExitRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
}
void ExitRequest::Serialize (shared_ptr <Stream> stream) const
{
CoreServiceRequest::Serialize (stream);
}
// MountVolumeRequest
void MountVolumeRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
DeserializedOptions = Serializable::DeserializeNew <MountOptions> (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> stream) const
{
CoreServiceRequest::Serialize (stream);
Serializer sr (stream);
Options->Serialize (stream);
}
// SetFileOwnerRequest
void SetFileOwnerRequest::Deserialize (shared_ptr <Stream> stream)
{
CoreServiceRequest::Deserialize (stream);
Serializer sr (stream);
uint64 owner;
sr.Deserialize ("Owner", owner);
Owner.SystemId = static_cast <uid_t> (owner);
Path = sr.DeserializeWString ("Path");
}
bool SetFileOwnerRequest::RequiresElevation () const
{
return !Core->HasAdminPrivileges();
}
void SetFileOwnerRequest::Serialize (shared_ptr <Stream> 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);
}

View File

@ -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> volumeInfo, bool repair)
: MountedVolumeInfo (volumeInfo), Repair (repair) { }
TC_SERIALIZABLE (CheckFilesystemRequest);
virtual bool RequiresElevation () const;
shared_ptr <VolumeInfo> 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> volumeInfo, bool ignoreOpenFiles, bool syncVolumeInfo)
: IgnoreOpenFiles (ignoreOpenFiles), MountedVolumeInfo (volumeInfo), SyncVolumeInfo (syncVolumeInfo) { }
TC_SERIALIZABLE (DismountVolumeRequest);
virtual bool RequiresElevation () const;
bool IgnoreOpenFiles;
shared_ptr <VolumeInfo> 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 <MountOptions> 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

View File

@ -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> stream)
{
}
void CheckFilesystemResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
// DismountFilesystemResponse
void DismountFilesystemResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void DismountFilesystemResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
}
// DismountVolumeResponse
void DismountVolumeResponse::Deserialize (shared_ptr <Stream> stream)
{
DismountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
}
void DismountVolumeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
DismountedVolumeInfo->Serialize (stream);
}
// GetDeviceSectorSizeResponse
void GetDeviceSectorSizeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
sr.Deserialize ("Size", Size);
}
void GetDeviceSectorSizeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Size", Size);
}
// GetDeviceSizeResponse
void GetDeviceSizeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
sr.Deserialize ("Size", Size);
}
void GetDeviceSizeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
sr.Serialize ("Size", Size);
}
// GetHostDevicesResponse
void GetHostDevicesResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializable::DeserializeList (stream, HostDevices);
}
void GetHostDevicesResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializable::SerializeList (stream, HostDevices);
}
// MountVolumeResponse
void MountVolumeResponse::Deserialize (shared_ptr <Stream> stream)
{
Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
}
void MountVolumeResponse::Serialize (shared_ptr <Stream> stream) const
{
Serializable::Serialize (stream);
Serializer sr (stream);
MountedVolumeInfo->Serialize (stream);
}
// SetFileOwnerResponse
void SetFileOwnerResponse::Deserialize (shared_ptr <Stream> stream)
{
}
void SetFileOwnerResponse::Serialize (shared_ptr <Stream> 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);
}

View File

@ -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 <VolumeInfo> 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> volumeInfo) : MountedVolumeInfo (volumeInfo) { }
TC_SERIALIZABLE (MountVolumeResponse);
shared_ptr <VolumeInfo> MountedVolumeInfo;
};
struct SetFileOwnerResponse : CoreServiceResponse
{
SetFileOwnerResponse () { }
TC_SERIALIZABLE (SetFileOwnerResponse);
};
}
#endif // TC_HEADER_Core_Unix_CoreServiceResponse

618
src/Core/Unix/CoreUnix.cpp Normal file
View File

@ -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 <errno.h>
#include <iostream>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#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 <VolumeInfo> mountedVolume, bool repair) const
{
if (!mountedVolume->MountPoint.IsEmpty())
DismountFilesystem (mountedVolume->MountPoint, false);
list <string> 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 <string> args;
#ifdef TC_MACOSX
if (force)
args.push_back ("-f");
#endif
args.push_back ("--");
args.push_back (mountPoint);
Process::Execute ("umount", args);
}
shared_ptr <VolumeInfo> CoreUnix::DismountVolume (shared_ptr <VolumeInfo> 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 <string> 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 <VolumeInfo> mountedVol;
try
{
shared_ptr <File> controlFile (new File);
controlFile->Open (string (mf.MountPoint) + FuseService::GetControlPath());
shared_ptr <Stream> controlFileStream (new FileStream (controlFile));
mountedVol = Serializable::DeserializeNew <VolumeInfo> (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 <gid_t> (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 <uid_t> (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 <string> 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 <VolumeInfo> CoreUnix::MountVolume (MountOptions &options)
{
CoalesceSlotNumberAndMountPoint (options);
if (IsVolumeMounted (*options.Path))
throw VolumeAlreadyMounted (SRC_POS);
Cipher::EnableHwSupport (!options.NoHardwareCrypto);
shared_ptr <Volume> 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 <VolumeInfo> 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();
}
}

69
src/Core/Unix/CoreUnix.h Normal file
View File

@ -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 <VolumeInfo> mountedVolume, bool repair = false) const;
virtual void DismountFilesystem (const DirectoryPath &mountPoint, bool force) const;
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> 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 <VolumeInfo> 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 <VolumeInfo> 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> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const { throw NotApplicable (SRC_POS); }
private:
CoreUnix (const CoreUnix &);
CoreUnix &operator= (const CoreUnix &);
};
}
#endif // TC_HEADER_Core_CoreUnix

View File

@ -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 <fstream>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include "CoreFreeBSD.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreFreeBSD::CoreFreeBSD ()
{
}
CoreFreeBSD::~CoreFreeBSD ()
{
}
DevicePath CoreFreeBSD::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const
{
list <string> 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 <string> 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 <CoreBase> Core (new CoreServiceProxy <CoreFreeBSD>);
auto_ptr <CoreBase> CoreDirect (new CoreFreeBSD);
#endif
}

View File

@ -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

View File

@ -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

View File

@ -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 <fstream>
#include <iomanip>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/wait.h>
#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 <string> 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 <string> args;
list <string>::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 <string> 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 <VolumeInfo> 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 <string> 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 <string> 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> 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 <string> 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 <CoreBase> Core (new CoreServiceProxy <CoreLinux>);
auto_ptr <CoreBase> CoreDirect (new CoreLinux);
}

View File

@ -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 <VolumeInfo> 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> volume, MountOptions &options, const DirectoryPath &auxMountPoint) const;
private:
CoreLinux (const CoreLinux &);
CoreLinux &operator= (const CoreLinux &);
};
}
#endif // TC_HEADER_Core_CoreLinux

View File

@ -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

View File

@ -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 <fstream>
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "CoreMacOSX.h"
#include "Driver/Fuse/FuseService.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreMacOSX::CoreMacOSX ()
{
}
CoreMacOSX::~CoreMacOSX ()
{
}
shared_ptr <VolumeInfo> CoreMacOSX::DismountVolume (shared_ptr <VolumeInfo> mountedVolume, bool ignoreOpenFiles, bool syncVolumeInfo)
{
if (!mountedVolume->VirtualDevice.IsEmpty() && mountedVolume->VirtualDevice.IsBlockDevice())
{
list <string> 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 <string> 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 <VolumeInfo> mountedVolume, bool repair) const
{
list <string> 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 <string> 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 <string> 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 ("<key>dev-entry</key>");
if (p == string::npos)
throw ParameterIncorrect (SRC_POS);
p = xml.find ("<string>", p);
if (p == string::npos)
throw ParameterIncorrect (SRC_POS);
p += 8;
size_t e = xml.find ("</string>", 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 <string> args;
args.push_back ("detach");
args.push_back (volImage);
args.push_back ("-force");
Process::Execute ("hdiutil", args);
}
catch (ExecutedProcessFailed&) { }
throw;
}
}
auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreMacOSX>);
auto_ptr <CoreBase> CoreDirect (new CoreMacOSX);
}

View File

@ -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 <VolumeInfo> mountedVolume, bool repair = false) const;
virtual shared_ptr <VolumeInfo> DismountVolume (shared_ptr <VolumeInfo> 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

View File

@ -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

View File

@ -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 <MountedFilesystem> > MountedFilesystemList;
}
#endif // TC_HEADER_Core_Unix_MountedFilesystem

View File

@ -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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include "CoreSolaris.h"
#include "Core/Unix/CoreServiceProxy.h"
namespace TrueCrypt
{
CoreSolaris::CoreSolaris ()
{
}
CoreSolaris::~CoreSolaris ()
{
}
DevicePath CoreSolaris::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const
{
list <string> args;
args.push_back ("-a");
args.push_back (filePath);
return StringConverter::Trim (Process::Execute ("lofiadm", args));
}
void CoreSolaris::DetachLoopDevice (const DevicePath &devicePath) const
{
list <string> 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 <CoreBase> Core (new CoreServiceProxy <CoreSolaris>);
auto_ptr <CoreBase> CoreDirect (new CoreSolaris);
}

View File

@ -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

View File

@ -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

12
src/Core/Unix/System.h Normal file
View File

@ -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

345
src/Core/VolumeCreator.cpp Normal file
View File

@ -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 <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#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 &sector)
{
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 <VolumeCreationOptions> 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 <VolumeHeader> 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 <EncryptionMode> 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;
}
}

119
src/Core/VolumeCreator.h Normal file
View File

@ -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 <VolumePassword> Password;
shared_ptr <KeyfileList> Keyfiles;
shared_ptr <Pkcs5Kdf> VolumeHeaderKdf;
shared_ptr <EncryptionAlgorithm> 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 <VolumeCreationOptions> options);
KeyInfo GetKeyInfo () const;
ProgressInfo GetProgressInfo ();
protected:
void CreationThread ();
volatile bool AbortRequested;
volatile bool CreationInProgress;
uint64 DataStart;
uint64 HostSize;
shared_ptr <VolumeCreationOptions> Options;
shared_ptr <Exception> ThreadException;
uint64 VolumeSize;
shared_ptr <VolumeLayout> Layout;
shared_ptr <File> VolumeFile;
SharedVal <uint64> SizeDone;
uint64 WriteOffset;
ProgressInfo mProgressInfo;
SecureBuffer HeaderKey;
shared_ptr <VolumePassword> PasswordKey;
SecureBuffer MasterKey;
private:
VolumeCreator (const VolumeCreator &);
VolumeCreator &operator= (const VolumeCreator &);
};
}
#endif // TC_HEADER_Volume_VolumeCreator

View File

@ -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

View File

@ -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 <errno.h>
#include <fcntl.h>
#include <fuse.h>
#include <iostream>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/wait.h>
#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 <Buffer> 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 <int> (e.GetErrorCode());
}
catch (std::exception &e)
{
SystemLog::WriteException (e);
return -EINTR;
}
catch (...)
{
SystemLog::WriteException (UnknownException (SRC_POS));
return -EINTR;
}
}
shared_ptr <Buffer> FuseService::GetVolumeInfo ()
{
shared_ptr <Stream> stream (new MemoryStream);
{
ScopeLock lock (OpenVolumeInfoMutex);
OpenVolumeInfo.Set (*MountedVolume);
OpenVolumeInfo.SlotNumber = SlotNumber;
OpenVolumeInfo.Serialize (stream);
}
ConstBufferPtr infoBuf = dynamic_cast <MemoryStream&> (*stream);
shared_ptr <Buffer> 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 <Volume> openVolume, VolumeSlotNumber slotNumber, const string &fuseMountPoint)
{
list <string> 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> 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> stream (new MemoryStream);
Serializer sr (stream);
sr.Serialize ("VirtualDevice", string (virtualDevice));
sr.Serialize ("LoopDevice", string (loopDevice));
fuseServiceControl.Write (dynamic_cast <MemoryStream&> (*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 <VolumeInfo> 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 <uid_t> (StringConverter::ToUInt64 (s));
if (getenv ("SUDO_GID"))
{
s = getenv ("SUDO_GID");
FuseService::GroupId = static_cast <gid_t> (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 <Volume> FuseService::MountedVolume;
VolumeSlotNumber FuseService::SlotNumber;
uid_t FuseService::UserId;
gid_t FuseService::GroupId;
auto_ptr <Pipe> FuseService::SignalHandlerPipe;
}

View File

@ -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 <Volume> openVolume, VolumeSlotNumber slotNumber)
: MountedVolume (openVolume), SlotNumber (slotNumber)
{
}
virtual void operator() (int argc, char *argv[]);
protected:
shared_ptr <Volume> 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 <Buffer> GetVolumeInfo ();
static uint64 GetVolumeSize ();
static uint64 GetVolumeSectorSize () { return MountedVolume->GetSectorSize(); }
static void Mount (shared_ptr <Volume> 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 <Volume> MountedVolume;
static VolumeSlotNumber SlotNumber;
static uid_t UserId;
static gid_t GroupId;
static auto_ptr <Pipe> SignalHandlerPipe;
};
}
#endif // TC_HEADER_Driver_Fuse_FuseService

98
src/Main/Application.cpp Normal file
View File

@ -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 <wx/stdpaths.h>
#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;
}

40
src/Main/Application.h Normal file
View File

@ -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

View File

@ -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 <wx/cmdline.h>
#include <wx/tokenzr.h>
#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 <EncryptionAlgorithm> 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, 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 <VolumeInfo> 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 <KeyfileList> 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 <Keyfile> (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 <VolumeInfo> 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 <CommandLineInterface> CmdLine;
}

View File

@ -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 <EncryptionAlgorithm> ArgEncryptionAlgorithm;
shared_ptr <FilePath> ArgFilePath;
VolumeCreationOptions::FilesystemType::Enum ArgFilesystem;
bool ArgForce;
shared_ptr <Hash> ArgHash;
shared_ptr <KeyfileList> ArgKeyfiles;
MountOptions ArgMountOptions;
shared_ptr <DirectoryPath> ArgMountPoint;
shared_ptr <KeyfileList> ArgNewKeyfiles;
shared_ptr <VolumePassword> ArgNewPassword;
bool ArgNoHiddenVolumeProtection;
shared_ptr <VolumePassword> ArgPassword;
bool ArgQuick;
FilesystemPath ArgRandomSourcePath;
uint64 ArgSize;
shared_ptr <VolumePath> ArgVolumePath;
VolumeInfoList ArgVolumes;
VolumeType::Enum ArgVolumeType;
bool StartBackgroundTask;
UserPreferences Preferences;
protected:
void CheckCommandSingle () const;
shared_ptr <KeyfileList> ToKeyfileList (const wxString &arg) const;
VolumeInfoList GetMountedVolumes (const wxString &filter) const;
private:
CommandLineInterface (const CommandLineInterface &);
CommandLineInterface &operator= (const CommandLineInterface &);
};
extern auto_ptr <CommandLineInterface> CmdLine;
}
#endif // TC_HEADER_Main_CommandInterface

View File

@ -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 <wx/stackwalk.h>
#include "Main.h"
#include "Application.h"
#include "UserInterface.h"
#include "GraphicUserInterface.h"
#include "Volume/Crc32.h"
#ifdef TC_UNIX
#include <signal.h>
#endif
#ifdef TC_MACOSX
# ifdef __ppc__
# include <ppc/ucontext.h>
# else
# include <i386/ucontext.h>
# endif
#elif defined (TC_BSD)
# include <ucontext.h>
#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
}
}

View File

@ -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

View File

@ -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 <FavoriteVolume> (
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;
}
}

53
src/Main/FavoriteVolume.h Normal file
View File

@ -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 <FavoriteVolume> > 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

View File

@ -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");
}
}

View File

@ -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

View File

@ -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 <size_t> 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 <int> 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 <BenchmarkResult> results;
wxBusyCursor busy;
Buffer buffer ((size_t) Gui->GetSelectedData <size_t> (BufferSizeChoice));
EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms();
foreach (shared_ptr <EncryptionAlgorithm> ea, encryptionAlgorithms)
{
if (!ea->IsDeprecated())
{
BenchmarkResult result;
result.AlgorithmName = ea->GetName();
Buffer key (ea->GetKeySize());
ea->SetKey (key);
shared_ptr <EncryptionMode> 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 <BenchmarkResult>::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 <wstring> 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);
}
}
}

View File

@ -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

View File

@ -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> volumePath, Mode::Enum mode, shared_ptr <VolumePassword> password, shared_ptr <KeyfileList> keyfiles, shared_ptr <VolumePassword> newPassword, shared_ptr <KeyfileList> 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 <ChangePasswordDialog> (this, &ChangePasswordDialog::OnPasswordPanelUpdate));
CurrentPasswordPanelSizer->Add (CurrentPasswordPanel, 1, wxALL | wxEXPAND);
NewPasswordPanel = new VolumePasswordPanel (this, newPassword, newKeyfiles, false, enableNewPassword, enableNewKeyfiles, enableNewPassword, enablePkcs5Prf);
NewPasswordPanel->UpdateEvent.Connect (EventConnector <ChangePasswordDialog> (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 <VolumePassword> 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 <KeyfileList> 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 <Hash>());
{
#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);
}
}

View File

@ -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> volumePath, Mode::Enum mode = Mode::ChangePasswordAndKeyfiles, shared_ptr <VolumePassword> password = shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> keyfiles = shared_ptr <KeyfileList> (), shared_ptr <VolumePassword> newPassword = shared_ptr <VolumePassword> (), shared_ptr <KeyfileList> newKeyfiles = shared_ptr <KeyfileList> ());
virtual ~ChangePasswordDialog ();
protected:
void OnOKButtonClick (wxCommandEvent& event);
void OnPasswordPanelUpdate ();
void OnPasswordPanelUpdate (EventArgs &args) { OnPasswordPanelUpdate(); }
Mode::Enum DialogMode;
VolumePasswordPanel *CurrentPasswordPanel;
VolumePasswordPanel *NewPasswordPanel;
shared_ptr <VolumePath> Path;
};
}
#endif // TC_HEADER_Main_Forms_ChangePasswordDialog

View File

@ -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 <int> 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 <wstring> 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();
}
}

View File

@ -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

View File

@ -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 <EncryptionAlgorithm> ea, EncryptionAlgorithms)
{
if (!ea->IsDeprecated())
EncryptionAlgorithmChoice->Append (ea->GetName(), ea.get());
}
EncryptionAlgorithmChoice->Select (0);
Hashes = Hash::GetAvailableAlgorithms();
foreach (shared_ptr <Hash> hash, Hashes)
{
if (!hash->IsDeprecated())
HashChoice->Append (hash->GetName(), hash.get());
}
HashChoice->Select (0);
OnEncryptionAlgorithmSelected();
}
shared_ptr <EncryptionAlgorithm> EncryptionOptionsWizardPage::GetEncryptionAlgorithm () const
{
return Gui->GetSelectedData <EncryptionAlgorithm> (EncryptionAlgorithmChoice)->GetNew();
}
shared_ptr <Hash> EncryptionOptionsWizardPage::GetHash () const
{
return Gui->GetSelectedData <Hash> (HashChoice)->GetNew();
}
void EncryptionOptionsWizardPage::OnBenchmarkButtonClick (wxCommandEvent& event)
{
BenchmarkDialog dialog (this);
dialog.ShowModal();
}
void EncryptionOptionsWizardPage::OnEncryptionAlgorithmSelected ()
{
FreezeScope freeze (this);
shared_ptr <EncryptionAlgorithm> 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 <EncryptionAlgorithm> algorithm)
{
if (algorithm)
{
EncryptionAlgorithmChoice->SetStringSelection (algorithm->GetName());
OnEncryptionAlgorithmSelected ();
}
}
void EncryptionOptionsWizardPage::SetHash (shared_ptr <Hash> hash)
{
if (hash)
HashChoice->SetStringSelection (hash->GetName());
}
}

View File

@ -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 <EncryptionAlgorithm> GetEncryptionAlgorithm () const;
shared_ptr <Hash> GetHash () const;
bool IsValid () { return true; }
void SetPageText (const wxString &text) { }
void SetEncryptionAlgorithm (shared_ptr <EncryptionAlgorithm> algorithm);
void SetHash (shared_ptr <Hash> 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

View File

@ -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 <EncryptionAlgorithm> 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 <EncryptionAlgorithm> 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 <EncryptionMode> 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 <EncryptionAlgorithm> EncryptionTestDialog::GetSelectedEncryptionAlgorithm () const
{
return Gui->GetSelectedData <EncryptionAlgorithm> (EncryptionAlgorithmChoice)->GetNew();
}
void EncryptionTestDialog::GetTextCtrlData (wxTextCtrl *textCtrl, Buffer &buffer) const
{
vector <byte> 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 <EncryptionAlgorithm> 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");
}
}

View File

@ -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 <EncryptionAlgorithm> 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

View File

@ -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 <int> 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 <wstring> fields (FavoritesListCtrl->GetColumnCount());
size_t itemCount = 0;
foreach (shared_ptr <FavoriteVolume> 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 <FavoriteVolume> (
*reinterpret_cast <FavoriteVolume *> (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);
}
}

View File

@ -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

3062
src/Main/Forms/Forms.cpp Normal file

File diff suppressed because it is too large Load Diff

1023
src/Main/Forms/Forms.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 <Functor> 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);
}
}

View File

@ -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 <Functor> actionFunctor = shared_ptr <Functor> ());
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 <Functor> ActionFunctor;
};
}
#endif // TC_HEADER_Main_Forms_InfoWizardPage

View File

@ -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> hash, Hashes)
{
if (!hash->IsDeprecated())
HashChoice->Append (hash->GetName(), hash.get());
}
HashChoice->Select (0);
RandomNumberGenerator::SetHash (Gui->GetSelectedData <Hash> (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 <Hash> (HashChoice)->GetNew());
}
void KeyfileGeneratorDialog::OnMouseMotion (wxMouseEvent& event)
{
event.Skip();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&event), sizeof (event)));
long coord = event.GetX();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&coord), sizeof (coord)));
coord = event.GetY();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&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';
}
}
}

View File

@ -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

View File

@ -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 <KeyfileList> 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");
}
}

View File

@ -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 <KeyfileList> keyfiles);
shared_ptr <KeyfileList> GetKeyfiles () const { return mKeyfilesPanel->GetKeyfiles(); }
protected:
void OnCreateKeyfileButttonClick (wxCommandEvent& event);
void OnKeyfilesHyperlinkClick (wxHyperlinkEvent& event);
shared_ptr <KeyfileList> Keyfiles;
KeyfilesPanel *mKeyfilesPanel;
};
}
#endif // TC_HEADER_Main_Forms_KeyfilesDialog

View File

@ -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 <KeyfileList> 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 <wstring> 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 <Keyfile> (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> keyfile)
{
vector <wstring> fields;
fields.push_back (FilesystemPath (*keyfile));
Gui->AppendToListCtrl (KeyfilesListCtrl, fields);
UpdateButtons();
}
shared_ptr <KeyfileList> KeyfilesPanel::GetKeyfiles () const
{
make_shared_auto (KeyfileList, keyfiles);
for (long i = 0; i < KeyfilesListCtrl->GetItemCount(); i++)
keyfiles->push_back (make_shared <Keyfile> (wstring (KeyfilesListCtrl->GetItemText (i))));
return keyfiles;
}
void KeyfilesPanel::OnAddDirectoryButtonClick (wxCommandEvent& event)
{
DirectoryPath dir = Gui->SelectDirectory (this, LangString["SELECT_KEYFILE_PATH"]);
if (!dir.IsEmpty())
{
vector <wstring> 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 <wstring> 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 <wstring> fields;
fields.push_back (path);
Gui->AppendToListCtrl (KeyfilesListCtrl, fields);
}
UpdateButtons();
}
}
catch (exception &e)
{
Gui->ShowError (e);
}
}
void KeyfilesPanel::OnListSizeChanged (wxSizeEvent& event)
{
list <int> 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);
}
}

View File

@ -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 <KeyfileList> keyfiles);
void AddKeyfile (shared_ptr <Keyfile> keyfile);
shared_ptr <KeyfileList> 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

View File

@ -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()));
}
}

View File

@ -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

1585
src/Main/Forms/MainFrame.cpp Normal file

File diff suppressed because it is too large Load Diff

173
src/Main/Forms/MainFrame.h Normal file
View File

@ -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 <VolumeInfo> volume = shared_ptr <VolumeInfo> ());
const UserPreferences &GetPreferences () const { return Gui->GetPreferences(); }
shared_ptr <VolumeInfo> GetSelectedVolume () const;
shared_ptr <VolumePath> GetSelectedVolumePath () const { return make_shared <VolumePath> (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 <VolumeInfo> 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 <OpenVolumeSystemRequestEventArgs &> (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 <int, FavoriteVolume> FavoriteVolumesMenuMap;
bool ListItemRightClickEventPending;
VolumeInfoList MountedVolumes;
auto_ptr <wxTaskBarIcon> mTaskBarIcon;
auto_ptr <wxTimer> mTimer;
long SelectedItemIndex;
VolumeSlotNumber SelectedSlotNumber;
int ShowRequestFifo;
map <wstring, VolumeActivityMapEntry> VolumeActivityMap;
};
}
#endif // TC_HEADER_Main_Forms_MainFrame

View File

@ -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 <DirectoryPath> (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();
}
}

View File

@ -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

View File

@ -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 <SecurityTokenInfo> 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();
}
}

View File

@ -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 <CK_SLOT_ID> (SecurityTokenChoice->GetClientData (SecurityTokenChoice->GetSelection())); }
protected:
void OnKeyfileNameChanged (wxCommandEvent& event);
};
}
#endif // TC_HEADER_Main_Forms_NewSecurityTokenKeyfileDialog

View File

@ -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 <wx/dynlib.h>
#ifdef TC_WINDOWS
#include <wx/msw/registry.h>
#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 <KeyfileList> (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 <int> 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 <wstring> fields (HotkeyListCtrl->GetColumnCount());
UnregisteredHotkeys = Preferences.Hotkeys;
Hotkey::UnregisterList (Gui->GetMainFrame(), UnregisteredHotkeys);
foreach (shared_ptr <Hotkey> 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 <wxTimer *> (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 <Hotkey *> (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 <wstring> 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 <Hotkey *> (HotkeyListCtrl->GetItemData (item));
hotkey->VirtualKeyCode = 0;
hotkey->VirtualKeyModifiers = 0;
vector <wstring> 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 <wstring, wstring> > 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 <Hotkey *> (HotkeyListCtrl->GetItemData (item))->VirtualKeyCode != 0)
remove = true;
}
RemoveHotkeyButton->Enable (remove);
}
}

View File

@ -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 <wxTimer> mTimer;
UserPreferences Preferences;
bool RestoreValidatorBell;
HotkeyList UnregisteredHotkeys;
};
}
#endif // TC_HEADER_Main_Forms_PreferencesDialog

View File

@ -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 <wxTimer *> (new Timer (this)));
mTimer->Start (30);
}
void ProgressWizardPage::OnAbortButtonClick (wxCommandEvent& event)
{
AbortEvent.Raise();
}
void ProgressWizardPage::OnTimer ()
{
uint64 value = ProgressValue.Get();
int gaugeValue = static_cast <int> (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);
}
}

View File

@ -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 <uint64> ProgressValue;
protected:
void OnAbortButtonClick (wxCommandEvent& event);
void OnTimer ();
auto_ptr <wxTimer> mTimer;
int PreviousGaugeValue;
uint64 ProgressBarRange;
int RealProgressBarRange;
};
}
#endif // TC_HEADER_Main_Forms_ProgressWizardPage

View File

@ -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> 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 <Hash> (HashChoice)->GetNew());
}
void RandomPoolEnrichmentDialog::OnMouseMotion (wxMouseEvent& event)
{
event.Skip();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&event), sizeof (event)));
long coord = event.GetX();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&coord), sizeof (coord)));
coord = event.GetY();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&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';
}
}
}

View File

@ -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

View File

@ -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 <int> 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 <wstring> 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 <SecurityTokenKeyfile *> (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 <SecurityTokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData (item));
FilePathList files = Gui->SelectFiles (this, wxEmptyString, true);
if (!files.empty())
{
wxBusyCursor busy;
vector <byte> 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 <byte> 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 <SecurityTokenKeyfile *> (SecurityTokenKeyfileListCtrl->GetItemData (item));
SelectedSecurityTokenKeyfilePaths.push_back (*key);
}
EndModal (wxID_OK);
}
}

View File

@ -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 <SecurityTokenKeyfilePath> 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 <SecurityTokenKeyfile> SecurityTokenKeyfileList;
list <SecurityTokenKeyfilePath> SelectedSecurityTokenKeyfilePaths;
};
}
#endif // TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog

View File

@ -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));
}
}

View File

@ -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

View File

@ -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 ChoiceType>
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 <ChoiceType, wxRadioButton*> 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 <wxStaticText*> ChoiceInfoTexts;
map <ChoiceType, wxRadioButton*> RadioButtonMap;
};
}
#endif // TC_HEADER_Main_Forms_SingleChoiceWizardPage

17436
src/Main/Forms/TrueCrypt.fbp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 <wxTimer *> (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 <int> (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);
}
}

View File

@ -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 <wxTimer> RandomPoolTimer;
int RealProgressBarRange;
wxLongLong StartTime;
bool VolumeCreatorRunning;
};
}
#endif // TC_HEADER_Main_Forms_VolumeCreationProgressWizardPage

View File

@ -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 <unistd.h>
#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 <wxTimer *> (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 <VolumeHostType::Enum> *page = new SingleChoiceWizardPage <VolumeHostType::Enum> (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 <VolumeType::Enum> *page = new SingleChoiceWizardPage <VolumeType::Enum> (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 <bool> *page = new SingleChoiceWizardPage <bool> (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 <bool> *page = new SingleChoiceWizardPage <bool> (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 <VolumeCreationWizard> (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 <VolumePath> (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 <Functor> (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 <byte *> (&event), sizeof (event)));
long coord = event.GetX();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&coord), sizeof (coord)));
coord = event.GetY();
RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&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 <VolumeCreationProgressWizardPage *> (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 <byte *> (&time), sizeof (time)));
}
}
void VolumeCreationWizard::OnVolumeCreatorFinished ()
{
VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (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 <VolumePath> (SelectedVolumePath);
mountOptions.NoFilesystem = true;
mountOptions.Protection = VolumeProtection::None;
mountOptions.Password = Password;
mountOptions.Keyfiles = Keyfiles;
shared_ptr <VolumeInfo> volume = Core->MountVolume (mountOptions);
finally_do_arg (shared_ptr <VolumeInfo>, 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 <string> 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 <VolumeHostType::Enum> *page = dynamic_cast <SingleChoiceWizardPage <VolumeHostType::Enum> *> (GetCurrentPage());
try
{
SelectedVolumeHostType = page->GetSelection();
}
catch (NoItemSelected &)
{
return GetCurrentStep();
}
return Step::VolumeType;
}
case Step::VolumeType:
{
SingleChoiceWizardPage <VolumeType::Enum> *page = dynamic_cast <SingleChoiceWizardPage <VolumeType::Enum> *> (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 <VolumeLocationWizardPage *> (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 <EncryptionOptionsWizardPage *> (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 <VolumeSizeWizardPage *> (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 <VolumePasswordWizardPage *> (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 <bool> *page = dynamic_cast <SingleChoiceWizardPage <bool> *> (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 <VolumeFormatOptionsWizardPage *> (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 <bool> *page = dynamic_cast <SingleChoiceWizardPage <bool> *> (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 <VolumeCreationProgressWizardPage *> (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 <wxTimer *> (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 <Volume> outerVolume = Core->OpenVolume (make_shared <VolumePath> (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 <VolumeCreationProgressWizardPage *> (GetCurrentPage());
if (page)
{
page->EnableAbort (IsWorkInProgress());
}
}
bool VolumeCreationWizard::DeviceWarningConfirmed;
}

View File

@ -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 <VolumeCreator> Creator;
bool CrossPlatformSupport;
static bool DeviceWarningConfirmed;
bool DisplayKeyInfo;
auto_ptr <wxTimer> ProgressTimer;
auto_ptr <wxTimer> RandomPoolUpdateTimer;
shared_ptr <KeyfileList> Keyfiles;
bool LargeFilesSupport;
uint64 MaxHiddenVolumeSize;
shared_ptr <VolumeInfo> MountedOuterVolume;
bool OuterVolume;
bool QuickFormatEnabled;
shared_ptr <EncryptionAlgorithm> SelectedEncryptionAlgorithm;
uint32 SelectedFilesystemClusterSize;
VolumeCreationOptions::FilesystemType::Enum SelectedFilesystemType;
VolumePath SelectedVolumePath;
VolumeHostType::Enum SelectedVolumeHostType;
VolumeType::Enum SelectedVolumeType;
shared_ptr <VolumePassword> Password;
uint32 SectorSize;
shared_ptr <Hash> SelectedHash;
uint64 VolumeSize;
private:
void UpdateControls ();
};
}
#endif // TC_HEADER_Main_Forms_VolumeCreationWizard

Some files were not shown because too many files have changed in this diff Show More