mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-08-29 12:17:16 +00:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e653c926 | ||
|
|
751a454e6c | ||
|
|
9b19baf73e | ||
|
|
5ebd79745d | ||
|
|
1763e8a2ba | ||
|
|
49f679ca53 | ||
|
|
edc9f36322 | ||
|
|
34370b9933 | ||
|
|
7ffce028d0 | ||
|
|
97011f179c | ||
|
|
235f0b85ea |
@@ -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) $@
|
||||||
@@ -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.idrix.VeraCrypt</string>
|
||||||
|
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>VeraCrypt</string>
|
||||||
|
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>VeraCrypt.icns</string>
|
||||||
|
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>VeraCrypt</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>VeraCrypt _VERSION_</string>
|
||||||
|
|
||||||
|
<key>LSRequiresCarbon</key>
|
||||||
|
<true/>
|
||||||
|
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -7404,7 +7404,7 @@ char *LoadFile (const char *fileName, DWORD *size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*size = GetFileSize (h, NULL);
|
*size = GetFileSize (h, NULL);
|
||||||
buf = (char *) malloc (*size + 1);
|
buf = (char *) calloc (*size + 1, 1);
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
{
|
{
|
||||||
@@ -7412,8 +7412,6 @@ char *LoadFile (const char *fileName, DWORD *size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory (buf, *size + 1);
|
|
||||||
|
|
||||||
if (!ReadFile (h, buf, *size, size, NULL))
|
if (!ReadFile (h, buf, *size, size, NULL))
|
||||||
{
|
{
|
||||||
free (buf);
|
free (buf);
|
||||||
@@ -7444,18 +7442,15 @@ char *LoadFileBlock (char *fileName, __int64 fileOffset, size_t count)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = (char *) malloc (count);
|
buf = (char *) calloc (count, 1);
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
{
|
{
|
||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory (buf, count);
|
|
||||||
|
|
||||||
if (buf != NULL)
|
ReadFile (h, buf, count, &bytesRead, NULL);
|
||||||
ReadFile (h, buf, count, &bytesRead, NULL);
|
|
||||||
|
|
||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
|
|
||||||
|
|||||||
+19
-6
@@ -393,7 +393,7 @@ void derive_u_ripemd160 (BOOL bNotTest, char *pwd, int pwd_len, char *salt, int
|
|||||||
char init[128];
|
char init[128];
|
||||||
char counter[4];
|
char counter[4];
|
||||||
int c, i, l;
|
int c, i, l;
|
||||||
int EnhanceSecurityLoops = (bNotTest)? 10 : 1;
|
int EnhanceSecurityLoops = (bNotTest)? 20 : 1;
|
||||||
|
|
||||||
/* iteration 1 */
|
/* iteration 1 */
|
||||||
memset (counter, 0, 4);
|
memset (counter, 0, 4);
|
||||||
@@ -417,6 +417,21 @@ void derive_u_ripemd160 (BOOL bNotTest, char *pwd, int pwd_len, char *salt, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add extra 10 loops to ensure backward compatibilty with the previous count (327661 for boot, 655331 for normal) */
|
||||||
|
if (iterations == 32767)
|
||||||
|
{
|
||||||
|
/* case of normal partition : add 10 iterations to have a total of 655331 = (32767 - 1)*20 + 1 + 10 */
|
||||||
|
for (c = 0; c < 10; c++)
|
||||||
|
{
|
||||||
|
hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
|
||||||
|
for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
|
||||||
|
{
|
||||||
|
u[i] ^= k[i];
|
||||||
|
j[i] = k[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Prevent possible leaks. */
|
/* Prevent possible leaks. */
|
||||||
burn (j, sizeof(j));
|
burn (j, sizeof(j));
|
||||||
burn (k, sizeof(k));
|
burn (k, sizeof(k));
|
||||||
@@ -624,13 +639,11 @@ int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
|
|||||||
{
|
{
|
||||||
switch (pkcs5_prf_id)
|
switch (pkcs5_prf_id)
|
||||||
{
|
{
|
||||||
#ifdef TC_WINDOWS_BOOT
|
|
||||||
case RIPEMD160:
|
|
||||||
return 32767; /* we multiply this number by 10 inside derive_u_ripemd160 */
|
|
||||||
|
|
||||||
#else
|
|
||||||
case RIPEMD160:
|
case RIPEMD160:
|
||||||
return bBoot? 32767 : 65534; /* we multiply this number by 10 inside derive_u_ripemd160 */
|
return bBoot? 16384 : 32767; /* we multiply this number by 10 inside derive_u_ripemd160 */
|
||||||
|
|
||||||
|
#ifndef TC_WINDOWS_BOOT
|
||||||
|
|
||||||
case SHA512:
|
case SHA512:
|
||||||
return 500000;
|
return 500000;
|
||||||
|
|||||||
@@ -104,12 +104,13 @@ char *ReadRegistryString (char *subKey, char *name, char *defaultValue, char *st
|
|||||||
char value[MAX_PATH*4];
|
char value[MAX_PATH*4];
|
||||||
DWORD size = sizeof (value);
|
DWORD size = sizeof (value);
|
||||||
|
|
||||||
|
str[maxLen-1] = 0;
|
||||||
strncpy (str, defaultValue, maxLen-1);
|
strncpy (str, defaultValue, maxLen-1);
|
||||||
|
|
||||||
ZeroMemory (value, sizeof value);
|
ZeroMemory (value, sizeof value);
|
||||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
||||||
0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
||||||
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS)
|
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) value, &size) == ERROR_SUCCESS)
|
||||||
strncpy (str, value, maxLen-1);
|
strncpy (str, value, maxLen-1);
|
||||||
|
|
||||||
RegCloseKey (hkey);
|
RegCloseKey (hkey);
|
||||||
|
|||||||
+5
-5
@@ -15,15 +15,15 @@
|
|||||||
#define TC_APP_NAME "VeraCrypt"
|
#define TC_APP_NAME "VeraCrypt"
|
||||||
|
|
||||||
// Version displayed to user
|
// Version displayed to user
|
||||||
#define VERSION_STRING "1.0b"
|
#define VERSION_STRING "1.0d"
|
||||||
|
|
||||||
// Version number to compare against driver
|
// Version number to compare against driver
|
||||||
#define VERSION_NUM 0x010b
|
#define VERSION_NUM 0x010d
|
||||||
|
|
||||||
// Release date
|
// Release date
|
||||||
#define TC_STR_RELEASE_DATE "June 26, 2013"
|
#define TC_STR_RELEASE_DATE "June 3, 2014"
|
||||||
#define TC_RELEASE_DATE_YEAR 2013
|
#define TC_RELEASE_DATE_YEAR 2014
|
||||||
#define TC_RELEASE_DATE_MONTH 6
|
#define TC_RELEASE_DATE_MONTH 06
|
||||||
|
|
||||||
#define BYTES_PER_KB 1024LL
|
#define BYTES_PER_KB 1024LL
|
||||||
#define BYTES_PER_MB 1048576LL
|
#define BYTES_PER_MB 1048576LL
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
// Unencrypted:
|
// Unencrypted:
|
||||||
// 0 64 Salt
|
// 0 64 Salt
|
||||||
// Encrypted:
|
// Encrypted:
|
||||||
// 64 4 ASCII string 'TRUE'
|
// 64 4 ASCII string 'VERA'
|
||||||
// 68 2 Header version
|
// 68 2 Header version
|
||||||
// 70 2 Required program version
|
// 70 2 Required program version
|
||||||
// 72 4 CRC-32 checksum of the (decrypted) bytes 256-511
|
// 72 4 CRC-32 checksum of the (decrypted) bytes 256-511
|
||||||
@@ -596,7 +596,7 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, PCRYPTO_INFO
|
|||||||
|
|
||||||
// PKCS5 PRF
|
// PKCS5 PRF
|
||||||
derive_key_ripemd160 (TRUE, password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
|
derive_key_ripemd160 (TRUE, password->Text, (int) password->Length, header + HEADER_SALT_OFFSET,
|
||||||
PKCS5_SALT_SIZE, 32767, dk, sizeof (dk));
|
PKCS5_SALT_SIZE, bBoot ? 16384 : 32767, dk, sizeof (dk));
|
||||||
|
|
||||||
// Mode of operation
|
// Mode of operation
|
||||||
cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
|
cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID;
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ extern "C" {
|
|||||||
|
|
||||||
// Version number written to volume header during format;
|
// Version number written to volume header during format;
|
||||||
// specifies the minimum program version required to mount the volume
|
// specifies the minimum program version required to mount the volume
|
||||||
#define TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION 0x0100
|
#define TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION 0x010b
|
||||||
|
|
||||||
// Version number written (encrypted) to the key data area of an encrypted system partition/drive;
|
// Version number written (encrypted) to the key data area of an encrypted system partition/drive;
|
||||||
// specifies the minimum program version required to decrypt the system partition/drive
|
// specifies the minimum program version required to decrypt the system partition/drive
|
||||||
#define TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION 0x0100
|
#define TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION 0x010b
|
||||||
|
|
||||||
// Current volume format version (created by TrueCrypt 6.0+)
|
// Current volume format version (created by TrueCrypt 6.0+)
|
||||||
#define TC_VOLUME_FORMAT_VERSION 2
|
#define TC_VOLUME_FORMAT_VERSION 2
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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 = "veracrypt";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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/veracrypt";
|
||||||
|
|
||||||
|
if (FilesystemPath ("/mnt").IsDirectory())
|
||||||
|
return "/mnt/veracrypt";
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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/veracrypt") != 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 << "veracrypt" << 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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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/veracrypt"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MountAuxVolumeImage (const DirectoryPath &auxMountPoint, const MountOptions &options) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CoreMacOSX (const CoreMacOSX &);
|
||||||
|
CoreMacOSX &operator= (const CoreMacOSX &);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TC_HEADER_Core_CoreMacOSX
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
+1
-1
@@ -140,7 +140,7 @@ void RMD160Final(unsigned char *digest, RMD160_CTX *ctx)
|
|||||||
if (digest) {
|
if (digest) {
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
|
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
|
||||||
memset (ctx, 0, sizeof(*ctx));
|
burn (ctx, sizeof(*ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,0
|
FILEVERSION 1,0,4,0
|
||||||
PRODUCTVERSION 1,0,2,0
|
PRODUCTVERSION 1,0,4,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -45,11 +45,11 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "IDRIX"
|
VALUE "CompanyName", "IDRIX"
|
||||||
VALUE "FileDescription", "VeraCrypt Driver"
|
VALUE "FileDescription", "VeraCrypt Driver"
|
||||||
VALUE "FileVersion", "1.11"
|
VALUE "FileVersion", "1.13"
|
||||||
VALUE "LegalTrademarks", "VeraCrypt"
|
VALUE "LegalTrademarks", "VeraCrypt"
|
||||||
VALUE "OriginalFilename", "veracrypt.sys"
|
VALUE "OriginalFilename", "veracrypt.sys"
|
||||||
VALUE "ProductName", "VeraCrypt"
|
VALUE "ProductName", "VeraCrypt"
|
||||||
VALUE "ProductVersion", "1.0b"
|
VALUE "ProductVersion", "1.0d"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 "veracrypt"; }
|
||||||
|
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
|
||||||
@@ -3049,7 +3049,7 @@ BOOL IsVolumeClassFilterRegistered ()
|
|||||||
{
|
{
|
||||||
if (data->Type == REG_MULTI_SZ && data->DataLength >= 9 * sizeof (wchar_t))
|
if (data->Type == REG_MULTI_SZ && data->DataLength >= 9 * sizeof (wchar_t))
|
||||||
{
|
{
|
||||||
// Search for the string "truecrypt"
|
// Search for the string "veracrypt"
|
||||||
ULONG i;
|
ULONG i;
|
||||||
for (i = 0; i <= data->DataLength - 9 * sizeof (wchar_t); ++i)
|
for (i = 0; i <= data->DataLength - 9 * sizeof (wchar_t); ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,0
|
FILEVERSION 1,0,4,0
|
||||||
PRODUCTVERSION 1,0,2,0
|
PRODUCTVERSION 1,0,4,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -46,11 +46,11 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "IDRIX"
|
VALUE "CompanyName", "IDRIX"
|
||||||
VALUE "FileDescription", "VeraCrypt Format"
|
VALUE "FileDescription", "VeraCrypt Format"
|
||||||
VALUE "FileVersion", "1.0b"
|
VALUE "FileVersion", "1.0d"
|
||||||
VALUE "LegalTrademarks", "VeraCrypt"
|
VALUE "LegalTrademarks", "VeraCrypt"
|
||||||
VALUE "OriginalFilename", "VeraCrypt Format.exe"
|
VALUE "OriginalFilename", "VeraCrypt Format.exe"
|
||||||
VALUE "ProductName", "VeraCrypt"
|
VALUE "ProductName", "VeraCrypt"
|
||||||
VALUE "ProductVersion", "1.0b"
|
VALUE "ProductVersion", "1.0d"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@@ -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/VeraCrypt");
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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"VeraCrypt"; }
|
||||||
|
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
|
||||||
@@ -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", _("VeraCrypt 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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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 VeraCrypt must be terminated. If this is caused by a bug in VeraCrypt, 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 VeraCrypt executable\n- Error category\n- Error address\n";
|
||||||
|
#if wxUSE_STACKWALKER == 1
|
||||||
|
msg += L"- VeraCrypt 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"VeraCrypt::") != string::npos)
|
||||||
|
exName = exName.Mid (11);
|
||||||
|
|
||||||
|
wxString exPos = StringConverter::ToWide (e.what());
|
||||||
|
if (exPos.find (L"VeraCrypt::") != 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 VeraCrypt must be terminated. If this is caused by a bug in VeraCrypt, 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 VeraCrypt executable\n- Error description\n- Error location\n";
|
||||||
|
#if wxUSE_STACKWALKER == 1
|
||||||
|
msg += L"- VeraCrypt 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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.idrix.fr");
|
||||||
|
|
||||||
|
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 2014 IDRIX. 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"An IDRIX Release");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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 (_("VeraCrypt 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user