mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-30 15:03:31 +01:00
Add TrueCrypt 7.1a MacOSX/Linux specific source files.
This commit is contained in:
parent
97011f179c
commit
7ffce028d0
58
src/Build/Include/Makefile.inc
Normal file
58
src/Build/Include/Makefile.inc
Normal 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) $@
|
44
src/Build/Resources/MacOSX/Info.plist.xml
Normal file
44
src/Build/Resources/MacOSX/Info.plist.xml
Normal 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
20
src/Core/Core.h
Normal 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
27
src/Core/Core.make
Normal 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
279
src/Core/CoreBase.cpp
Normal 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
99
src/Core/CoreBase.h
Normal 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
|
29
src/Core/CoreException.cpp
Normal file
29
src/Core/CoreException.cpp
Normal 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
52
src/Core/CoreException.h
Normal 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
384
src/Core/FatFormatter.cpp
Normal 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
29
src/Core/FatFormatter.h
Normal 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 §or) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Format (WriteSectorCallback &writeSector, uint64 deviceSize, uint32 clusterSize, uint32 sectorSize);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TC_HEADER_Core_FatFormatter
|
47
src/Core/HostDevice.cpp
Normal file
47
src/Core/HostDevice.cpp
Normal 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
45
src/Core/HostDevice.h
Normal 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
129
src/Core/MountOptions.cpp
Normal 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
70
src/Core/MountOptions.h
Normal 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
|
213
src/Core/RandomNumberGenerator.cpp
Normal file
213
src/Core/RandomNumberGenerator.cpp
Normal 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;
|
||||||
|
}
|
55
src/Core/RandomNumberGenerator.h
Normal file
55
src/Core/RandomNumberGenerator.h
Normal 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
|
544
src/Core/Unix/CoreService.cpp
Normal file
544
src/Core/Unix/CoreService.cpp
Normal 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;
|
||||||
|
}
|
63
src/Core/Unix/CoreService.h
Normal file
63
src/Core/Unix/CoreService.h
Normal 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
|
152
src/Core/Unix/CoreServiceProxy.h
Normal file
152
src/Core/Unix/CoreServiceProxy.h
Normal 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
|
269
src/Core/Unix/CoreServiceRequest.cpp
Normal file
269
src/Core/Unix/CoreServiceRequest.cpp
Normal 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);
|
||||||
|
}
|
136
src/Core/Unix/CoreServiceRequest.h
Normal file
136
src/Core/Unix/CoreServiceRequest.h
Normal 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
|
119
src/Core/Unix/CoreServiceResponse.cpp
Normal file
119
src/Core/Unix/CoreServiceResponse.cpp
Normal 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);
|
||||||
|
}
|
84
src/Core/Unix/CoreServiceResponse.h
Normal file
84
src/Core/Unix/CoreServiceResponse.h
Normal 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
618
src/Core/Unix/CoreUnix.cpp
Normal 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
69
src/Core/Unix/CoreUnix.h
Normal 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
|
202
src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
Normal file
202
src/Core/Unix/FreeBSD/CoreFreeBSD.cpp
Normal 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
|
||||||
|
}
|
37
src/Core/Unix/FreeBSD/CoreFreeBSD.h
Normal file
37
src/Core/Unix/FreeBSD/CoreFreeBSD.h
Normal 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
|
12
src/Core/Unix/FreeBSD/System.h
Normal file
12
src/Core/Unix/FreeBSD/System.h
Normal 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
|
477
src/Core/Unix/Linux/CoreLinux.cpp
Normal file
477
src/Core/Unix/Linux/CoreLinux.cpp
Normal 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);
|
||||||
|
}
|
39
src/Core/Unix/Linux/CoreLinux.h
Normal file
39
src/Core/Unix/Linux/CoreLinux.h
Normal 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
|
12
src/Core/Unix/Linux/System.h
Normal file
12
src/Core/Unix/Linux/System.h
Normal 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
|
215
src/Core/Unix/MacOSX/CoreMacOSX.cpp
Normal file
215
src/Core/Unix/MacOSX/CoreMacOSX.cpp
Normal 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);
|
||||||
|
}
|
36
src/Core/Unix/MacOSX/CoreMacOSX.h
Normal file
36
src/Core/Unix/MacOSX/CoreMacOSX.h
Normal 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
|
12
src/Core/Unix/MacOSX/System.h
Normal file
12
src/Core/Unix/MacOSX/System.h
Normal 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
|
27
src/Core/Unix/MountedFilesystem.h
Normal file
27
src/Core/Unix/MountedFilesystem.h
Normal 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
|
174
src/Core/Unix/Solaris/CoreSolaris.cpp
Normal file
174
src/Core/Unix/Solaris/CoreSolaris.cpp
Normal 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);
|
||||||
|
}
|
37
src/Core/Unix/Solaris/CoreSolaris.h
Normal file
37
src/Core/Unix/Solaris/CoreSolaris.h
Normal 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
|
12
src/Core/Unix/Solaris/System.h
Normal file
12
src/Core/Unix/Solaris/System.h
Normal 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
12
src/Core/Unix/System.h
Normal 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
345
src/Core/VolumeCreator.cpp
Normal 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 §or)
|
||||||
|
{
|
||||||
|
OutputBuffer.GetRange (OutputBufferWritePos, sector.Size()).CopyFrom (sector);
|
||||||
|
OutputBufferWritePos += sector.Size();
|
||||||
|
|
||||||
|
if (OutputBufferWritePos >= OutputBuffer.Size())
|
||||||
|
FlushOutputBuffer();
|
||||||
|
|
||||||
|
return !Creator->AbortRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlushOutputBuffer ()
|
||||||
|
{
|
||||||
|
if (OutputBufferWritePos > 0)
|
||||||
|
{
|
||||||
|
Creator->Options->EA->EncryptSectors (OutputBuffer.GetRange (0, OutputBufferWritePos),
|
||||||
|
Creator->WriteOffset / ENCRYPTION_DATA_UNIT_SIZE, OutputBufferWritePos / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||||
|
|
||||||
|
Creator->VolumeFile->Write (OutputBuffer.GetRange (0, OutputBufferWritePos));
|
||||||
|
|
||||||
|
Creator->WriteOffset += OutputBufferWritePos;
|
||||||
|
Creator->SizeDone.Set (Creator->WriteOffset - Creator->DataStart);
|
||||||
|
|
||||||
|
OutputBufferWritePos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeCreator *Creator;
|
||||||
|
SecureBuffer OutputBuffer;
|
||||||
|
size_t OutputBufferWritePos;
|
||||||
|
};
|
||||||
|
|
||||||
|
WriteSectorCallback sectorWriter (this);
|
||||||
|
FatFormatter::Format (sectorWriter, filesystemSize, Options->FilesystemClusterSize, Options->SectorSize);
|
||||||
|
sectorWriter.FlushOutputBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Options->Quick)
|
||||||
|
{
|
||||||
|
// Empty sectors are encrypted with different key to randomize plaintext
|
||||||
|
Core->RandomizeEncryptionAlgorithmKey (Options->EA);
|
||||||
|
|
||||||
|
SecureBuffer outputBuffer (File::GetOptimalWriteSize());
|
||||||
|
uint64 dataFragmentLength = outputBuffer.Size();
|
||||||
|
|
||||||
|
while (!AbortRequested && WriteOffset < endOffset)
|
||||||
|
{
|
||||||
|
if (WriteOffset + dataFragmentLength > endOffset)
|
||||||
|
dataFragmentLength = endOffset - WriteOffset;
|
||||||
|
|
||||||
|
outputBuffer.Zero();
|
||||||
|
Options->EA->EncryptSectors (outputBuffer, WriteOffset / ENCRYPTION_DATA_UNIT_SIZE, dataFragmentLength / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE);
|
||||||
|
VolumeFile->Write (outputBuffer, (size_t) dataFragmentLength);
|
||||||
|
|
||||||
|
WriteOffset += dataFragmentLength;
|
||||||
|
SizeDone.Set (WriteOffset - DataStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AbortRequested)
|
||||||
|
{
|
||||||
|
SizeDone.Set (Options->Size);
|
||||||
|
|
||||||
|
// Backup header
|
||||||
|
SecureBuffer backupHeader (Layout->GetHeaderSize());
|
||||||
|
|
||||||
|
SecureBuffer backupHeaderSalt (VolumeHeader::GetSaltSize());
|
||||||
|
RandomNumberGenerator::GetData (backupHeaderSalt);
|
||||||
|
|
||||||
|
Options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, backupHeaderSalt);
|
||||||
|
|
||||||
|
Layout->GetHeader()->EncryptNew (backupHeader, backupHeaderSalt, HeaderKey, Options->VolumeHeaderKdf);
|
||||||
|
|
||||||
|
if (Options->Quick || Options->Type == VolumeType::Hidden)
|
||||||
|
VolumeFile->SeekEnd (Layout->GetBackupHeaderOffset());
|
||||||
|
|
||||||
|
VolumeFile->Write (backupHeader);
|
||||||
|
|
||||||
|
if (Options->Type == VolumeType::Normal)
|
||||||
|
{
|
||||||
|
// Write random data to space reserved for hidden volume backup header
|
||||||
|
Core->RandomizeEncryptionAlgorithmKey (Options->EA);
|
||||||
|
Options->EA->Encrypt (backupHeader);
|
||||||
|
|
||||||
|
VolumeFile->Write (backupHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeFile->Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception &e)
|
||||||
|
{
|
||||||
|
ThreadException.reset (e.CloneNew());
|
||||||
|
}
|
||||||
|
catch (exception &e)
|
||||||
|
{
|
||||||
|
ThreadException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
ThreadException.reset (new UnknownException (SRC_POS));
|
||||||
|
}
|
||||||
|
|
||||||
|
VolumeFile.reset();
|
||||||
|
mProgressInfo.CreationInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VolumeCreator::CreateVolume (shared_ptr <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
119
src/Core/VolumeCreator.h
Normal 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
|
16
src/Driver/Fuse/Driver.make
Normal file
16
src/Driver/Fuse/Driver.make
Normal 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
|
592
src/Driver/Fuse/FuseService.cpp
Normal file
592
src/Driver/Fuse/FuseService.cpp
Normal 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;
|
||||||
|
}
|
73
src/Driver/Fuse/FuseService.h
Normal file
73
src/Driver/Fuse/FuseService.h
Normal 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
98
src/Main/Application.cpp
Normal 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
40
src/Main/Application.h
Normal 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
|
583
src/Main/CommandLineInterface.cpp
Normal file
583
src/Main/CommandLineInterface.cpp
Normal 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;
|
||||||
|
}
|
94
src/Main/CommandLineInterface.h
Normal file
94
src/Main/CommandLineInterface.h
Normal 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
|
274
src/Main/FatalErrorHandler.cpp
Normal file
274
src/Main/FatalErrorHandler.cpp
Normal 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
|
||||||
|
}
|
||||||
|
}
|
33
src/Main/FatalErrorHandler.h
Normal file
33
src/Main/FatalErrorHandler.h
Normal 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
|
94
src/Main/FavoriteVolume.cpp
Normal file
94
src/Main/FavoriteVolume.cpp
Normal 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
53
src/Main/FavoriteVolume.h
Normal 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
|
66
src/Main/Forms/AboutDialog.cpp
Normal file
66
src/Main/Forms/AboutDialog.cpp
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
25
src/Main/Forms/AboutDialog.h
Normal file
25
src/Main/Forms/AboutDialog.h
Normal 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
|
157
src/Main/Forms/BenchmarkDialog.cpp
Normal file
157
src/Main/Forms/BenchmarkDialog.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
src/Main/Forms/BenchmarkDialog.h
Normal file
43
src/Main/Forms/BenchmarkDialog.h
Normal 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
|
195
src/Main/Forms/ChangePasswordDialog.cpp
Normal file
195
src/Main/Forms/ChangePasswordDialog.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
48
src/Main/Forms/ChangePasswordDialog.h
Normal file
48
src/Main/Forms/ChangePasswordDialog.h
Normal 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
|
120
src/Main/Forms/DeviceSelectionDialog.cpp
Normal file
120
src/Main/Forms/DeviceSelectionDialog.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
46
src/Main/Forms/DeviceSelectionDialog.h
Normal file
46
src/Main/Forms/DeviceSelectionDialog.h
Normal 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
|
137
src/Main/Forms/EncryptionOptionsWizardPage.cpp
Normal file
137
src/Main/Forms/EncryptionOptionsWizardPage.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
41
src/Main/Forms/EncryptionOptionsWizardPage.h
Normal file
41
src/Main/Forms/EncryptionOptionsWizardPage.h
Normal 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
|
227
src/Main/Forms/EncryptionTestDialog.cpp
Normal file
227
src/Main/Forms/EncryptionTestDialog.cpp
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
40
src/Main/Forms/EncryptionTestDialog.h
Normal file
40
src/Main/Forms/EncryptionTestDialog.h
Normal 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
|
118
src/Main/Forms/FavoriteVolumesDialog.cpp
Normal file
118
src/Main/Forms/FavoriteVolumesDialog.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
45
src/Main/Forms/FavoriteVolumesDialog.h
Normal file
45
src/Main/Forms/FavoriteVolumesDialog.h
Normal 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
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
1023
src/Main/Forms/Forms.h
Normal file
File diff suppressed because it is too large
Load Diff
33
src/Main/Forms/InfoWizardPage.cpp
Normal file
33
src/Main/Forms/InfoWizardPage.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
32
src/Main/Forms/InfoWizardPage.h
Normal file
32
src/Main/Forms/InfoWizardPage.h
Normal 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
|
118
src/Main/Forms/KeyfileGeneratorDialog.cpp
Normal file
118
src/Main/Forms/KeyfileGeneratorDialog.cpp
Normal 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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/Main/Forms/KeyfileGeneratorDialog.h
Normal file
34
src/Main/Forms/KeyfileGeneratorDialog.h
Normal 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
|
44
src/Main/Forms/KeyfilesDialog.cpp
Normal file
44
src/Main/Forms/KeyfilesDialog.cpp
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
33
src/Main/Forms/KeyfilesDialog.h
Normal file
33
src/Main/Forms/KeyfilesDialog.h
Normal 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
|
160
src/Main/Forms/KeyfilesPanel.cpp
Normal file
160
src/Main/Forms/KeyfilesPanel.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
37
src/Main/Forms/KeyfilesPanel.h
Normal file
37
src/Main/Forms/KeyfilesPanel.h
Normal 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
|
28
src/Main/Forms/LegalNoticesDialog.cpp
Normal file
28
src/Main/Forms/LegalNoticesDialog.cpp
Normal 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()));
|
||||||
|
}
|
||||||
|
}
|
23
src/Main/Forms/LegalNoticesDialog.h
Normal file
23
src/Main/Forms/LegalNoticesDialog.h
Normal 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
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
173
src/Main/Forms/MainFrame.h
Normal 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
|
174
src/Main/Forms/MountOptionsDialog.cpp
Normal file
174
src/Main/Forms/MountOptionsDialog.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
42
src/Main/Forms/MountOptionsDialog.h
Normal file
42
src/Main/Forms/MountOptionsDialog.h
Normal 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
|
45
src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp
Normal file
45
src/Main/Forms/NewSecurityTokenKeyfileDialog.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
30
src/Main/Forms/NewSecurityTokenKeyfileDialog.h
Normal file
30
src/Main/Forms/NewSecurityTokenKeyfileDialog.h
Normal 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
|
488
src/Main/Forms/PreferencesDialog.cpp
Normal file
488
src/Main/Forms/PreferencesDialog.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
60
src/Main/Forms/PreferencesDialog.h
Normal file
60
src/Main/Forms/PreferencesDialog.h
Normal 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
|
80
src/Main/Forms/ProgressWizardPage.cpp
Normal file
80
src/Main/Forms/ProgressWizardPage.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
42
src/Main/Forms/ProgressWizardPage.h
Normal file
42
src/Main/Forms/ProgressWizardPage.h
Normal 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
|
93
src/Main/Forms/RandomPoolEnrichmentDialog.cpp
Normal file
93
src/Main/Forms/RandomPoolEnrichmentDialog.cpp
Normal 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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/Main/Forms/RandomPoolEnrichmentDialog.h
Normal file
33
src/Main/Forms/RandomPoolEnrichmentDialog.h
Normal 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
|
197
src/Main/Forms/SecurityTokenKeyfilesDialog.cpp
Normal file
197
src/Main/Forms/SecurityTokenKeyfilesDialog.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
47
src/Main/Forms/SecurityTokenKeyfilesDialog.h
Normal file
47
src/Main/Forms/SecurityTokenKeyfilesDialog.h
Normal 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
|
32
src/Main/Forms/SelectDirectoryWizardPage.cpp
Normal file
32
src/Main/Forms/SelectDirectoryWizardPage.cpp
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
33
src/Main/Forms/SelectDirectoryWizardPage.h
Normal file
33
src/Main/Forms/SelectDirectoryWizardPage.h
Normal 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
|
116
src/Main/Forms/SingleChoiceWizardPage.h
Normal file
116
src/Main/Forms/SingleChoiceWizardPage.h
Normal 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
17436
src/Main/Forms/TrueCrypt.fbp
Normal file
File diff suppressed because it is too large
Load Diff
183
src/Main/Forms/VolumeCreationProgressWizardPage.cpp
Normal file
183
src/Main/Forms/VolumeCreationProgressWizardPage.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
53
src/Main/Forms/VolumeCreationProgressWizardPage.h
Normal file
53
src/Main/Forms/VolumeCreationProgressWizardPage.h
Normal 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
|
984
src/Main/Forms/VolumeCreationWizard.cpp
Normal file
984
src/Main/Forms/VolumeCreationWizard.cpp
Normal 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;
|
||||||
|
}
|
85
src/Main/Forms/VolumeCreationWizard.h
Normal file
85
src/Main/Forms/VolumeCreationWizard.h
Normal 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
Loading…
Reference in New Issue
Block a user