📄 cli.c
字号:
{
error ("Failed to assign loopback device for file-hosted volume\n");
goto err;
}
loopDevNo = i;
if (Verbose > 1)
printf ("Attached %s to %s\n", volumePath, hostDevice);
}
else
snprintf (hostDevice, sizeof (hostDevice), "%s", volumePath);
// Load kernel module
if (!LoadKernelModule ())
goto err;
if (!CheckKernelModuleVersion (TRUE, FALSE))
goto err;
// dmsetup
devNo = UseDeviceNumber == -1 ? GetFreeMapDevice () : UseDeviceNumber;
if (devNo == -1)
{
error ("Maximum number of volumes mounted\n");
goto err;
}
snprintf (mapDevice, sizeof (mapDevice), "truecrypt%d", devNo);
pipe (pfd);
pid = fork ();
if (pid == -1)
{
perror ("fork");
goto err;
}
else if (pid == 0)
{
SecurityCleanup ();
close (pfd[1]);
dup2 (pfd[0], STDIN_FILENO);
execlp ("dmsetup", "dmsetup", "create", mapDevice, NULL);
perror ("execlp dmsetup");
_exit (1);
}
close (pfd[0]);
w = fdopen (pfd[1], "a");
if (w == NULL)
{
perror ("fdopen");
goto err;
}
fprintf (w, "0 %llu truecrypt %d %d ", totalSectors, ci->ea, ci->mode);
for (i = DISK_IV_SIZE; i < EAGetKeySize (ci->ea) + DISK_IV_SIZE; i++)
fprintf (w, "%02x", ci->master_key[i]);
fprintf (w, " ");
for (i = 0; i < (int)sizeof (ci->iv); i++)
fprintf (w, "%02x", ci->iv[i]);
flags = 0;
if (ReadOnly)
flags |= TC_READ_ONLY;
else if (ProtectHidden)
flags |= TC_HIDDEN_VOLUME_PROTECTION;
fprintf (w, " %s %llu %llu %llu %llu %llu %llu %d %s\n",
hostDevice,
startSector,
readOnlyStartSector,
readOnlySectors,
(unsigned long long) RealUserId,
(unsigned long long) modTime,
(unsigned long long) acTime,
flags,
EscapeSpaces (volumePath));
fclose (w);
if (!WaitChild (FALSE, "dmsetup"))
{
Execute (TRUE, "dmsetup", "remove", mapDevice, NULL);
goto err;
}
snprintf (mapDevice, sizeof (mapDevice), TC_MAP_DEV "%d", devNo);
if (Verbose >= 1)
printf ("Mapped %s as %s\n", volumePath, mapDevice);
// Mount
if (mountPoint)
{
char fstype[64] = "-tauto";
char opts[1024];
char uopts[64] = "";
if (Filesystem)
snprintf (fstype, sizeof (fstype), "-t%s", Filesystem);
if (UserMount)
{
// Set default uid and gid
if (UserMountAvailable)
{
snprintf (uopts, sizeof (uopts), ",uid=%d,gid=%d,umask=077", RealUserId, RealGroupId);
}
else
{
error ("--user-mount can be specified only after sudo(8) command has been used.\n");
Execute (TRUE, "dmsetup", "remove", mapDevice, NULL);
goto err;
}
}
snprintf (opts, sizeof (opts), "%s%s%s%s",
ReadOnly ? "-oro" : "-orw",
MountOpts ? "," : "",
MountOpts ? MountOpts : "",
uopts);
if (!Execute (FALSE, "mount", fstype, opts, mapDevice, mountPoint, NULL))
{
int devNo;
error ("Mount failed\n");
if (GetMountList (TRUE) && ToDeviceNumber (mapDevice, &devNo))
DismountVolume (devNo);
loopDevNo = -1;
goto err;
}
if (Verbose >= 1)
printf ("Mounted %s at %s\n", mapDevice, mountPoint);
}
crypto_close (ci);
return TRUE;
err:
if (ci)
crypto_close (ci);
if (loopDevNo != -1)
DeleteLoopDevice (loopDevNo);
UnloadKernelModule (TRUE);
return FALSE;
}
static void HexDump (unsigned __int8 *data, unsigned int length)
{
while (length--)
printf ("%02x", (unsigned int) *data++);
}
static uint64_t GetTimeUsec ()
{
struct timeval tv;
gettimeofday (&tv, NULL);
return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
static double GetTime ()
{
struct timeval tv;
gettimeofday (&tv, NULL);
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
}
static BOOL RandFillPool ()
{
int i;
if (Randinit () != 0)
{
error ("Error while initializing the TrueCrypt random number generator.\n");
return FALSE;
}
FastPoll ();
if (IsTerminal && !RandomSource)
{
puts ("TrueCrypt will now collect random data.");
if (MiceDevice != NULL)
{
if (AskYesNo ("\nIs your mouse connected directly to computer where TrueCrypt is running?", FALSE))
{
// Mouse
puts ("\nPlease move the mouse randomly until the required amount of data is captured...");
for (i = 0; i <= TC_REQUIRED_MOUSE_EVENTS; i++)
{
unsigned char buf[sizeof (uint64_t)];
printf ("\rMouse data captured: %d%% ", i * 100 / TC_REQUIRED_MOUSE_EVENTS);
fflush (stdout);
if (fread (buf, 1, 1, MiceDevice) != 1)
{
perror ("Cannot read from " TC_MICE_DEVICE);
goto keyboard;
}
RandaddBuf (buf, 1);
*(uint64_t *)buf += GetTimeUsec ();
/* The role of CRC-32 is merely to perform diffusion. Note that the output
of CRC-32 is subsequently processed using a cryptographically secure hash
algorithm. */
RandAddInt (crc32 (buf, sizeof (buf)));
}
if (i >= TC_REQUIRED_MOUSE_EVENTS)
{
puts ("\n");
return TRUE;
}
}
}
else if (MiceDeviceErrNo == EACCES)
{
if (IsTerminal)
{
puts ("\nTo enable mouse movements to be used as a source of random data,\n"
"please do one of the following:\n"
"- Run TrueCrypt under administrator (root) account.\n"
"- Add read permission for your user to device " TC_MICE_DEVICE ".");
}
}
keyboard:
// Keyboard
printf ("\nPlease type at least %d randomly chosen characters and then press Enter:\n", TC_REQUIRED_KEYSTROKES);
i = 0;
while (1)
{
char buf[TC_REQUIRED_KEYSTROKES * 8];
int l;
if (!fgets (buf, sizeof (buf), stdin))
return FALSE;
l = strlen (buf) - 1;
if (l > 0)
{
RandaddBuf (buf, l);
i += l;
}
if (i >= TC_REQUIRED_KEYSTROKES)
break;
printf ("\nCharacters remaining: %d\n", TC_REQUIRED_KEYSTROKES - i);
fflush (stdout);
}
puts ("");
}
else if (RandomSource)
{
// File
char buf[RNG_POOL_SIZE];
FILE *f = NULL;
int r;
if (strcmp (RandomSource, "-") != 0)
{
f = fopen (RandomSource, "rb");
if (!f)
{
perror ("Cannot open source of random data");
return FALSE;
}
}
if ((r = fread (buf, 1, sizeof (buf), f ? f : stdin)) < 1)
{
error ("Cannot read from source of random data");
if (f)
fclose (f);
return FALSE;
}
if (f)
fclose (f);
RandaddBuf (buf, r);
}
else
{
error ("Source of random data required (use --random-source).\n");
return FALSE;
}
return TRUE;
}
static unsigned __int64 TotalSectors, StartSector;
static double StartTime;
static double LastUpdateTime;
void InitProgressBar (__int64 totalSectors)
{
LastUpdateTime = 0;
StartTime = GetTime ();
TotalSectors = (unsigned __int64) totalSectors;
}
BOOL UpdateProgressBar (__int64 sector)
{
unsigned __int64 s = (unsigned __int64) sector - StartSector;
double t = GetTime ();
double elapsed = t - StartTime;
unsigned __int64 bytesDone = (s + 1) * SECTOR_SIZE;
unsigned __int64 bytesPerSec = bytesDone / (1 + elapsed);
int timeRemain = (int)((TotalSectors - s) / ((s + 1)/(elapsed + 1) + 1));
if (DisplayProgress && IsTerminal && t - LastUpdateTime > 0.2)
{
printf ("\rDone: %.2f MB Speed: %.2f MB/s Left: %d:%02d:%02d "
, (double)bytesDone / 1024 / 1024
, (double)bytesPerSec / 1024 / 1024
, timeRemain / 3600
, (timeRemain % 3600) / 60
, (timeRemain % 3600) % 60);
fflush (stdout);
LastUpdateTime = t;
}
}
static BOOL ParseSize (char *string, unsigned long long *size)
{
if (sscanf (string, "%llu", size) == 1)
{
if (strchr (string, 'k') || strchr (string, 'K'))
*size *= 1024;
else if (strchr (string, 'M'))
*size *= 1024 * 1024;
else if (strchr (string, 'G'))
*size *= 1024 * 1024 * 1024;
*size &= ~0x1FF;
return TRUE;
}
return FALSE;
}
static BOOL CreateVolume (char *hostPath)
{
PCRYPTO_INFO ci = NULL;
char header[HEADER_SIZE];
char path[TC_MAX_PATH];
char str[128];
FILE *f;
fatparams ft;
Password *pw = &password;
unsigned long long startSector, totalSectors, hostSize;
BOOL hiddenVolume;
BOOL deleteOnError = FALSE;
BOOL ret = FALSE;
int i, r = 0;
OpenMiceDevice ();
// Volume type
switch (VolumeType)
{
case VOLUME_TYPE_NORMAL:
hiddenVolume = FALSE;
break;
case VOLUME_TYPE_HIDDEN:
hiddenVolume = TRUE;
break;
default:
puts ("Volume type:\n 1) Normal\n 2) Hidden");
hiddenVolume = AskSelection (1, 1, 2) == 2;
break;
}
if (hiddenVolume)
Quick = TRUE;
// Host file or device
hostPath = AskVolumePath (hostPath, hiddenVolume ? "Enter volume path" : "Enter file or device path for new volume");
if (hiddenVolume)
{
if (!IsFile (hostPath) && !IsBlockDevice (hostPath))
{
error ("File or device %s does not exist. Hidden volume cannot be created.\n", hostPath);
return FALSE;
}
f = fopen (hostPath, "r+b");
}
else
{
if (!Overwrite
&& IsFile (hostPath)
&& (!IsTerminal || !AskYesNo ("Volume already exists - overwrite?", TRUE)))
{
if (!IsTerminal)
error ("Volume already exists.\n");
return FALSE;
}
if (!Overwrite
&& IsBlockDevice (hostPath)
&& (!IsTerminal || !AskYesNo ("WARNING: Data on device will be lost. Continue?", TRUE)))
{
return FALSE;
}
f = fopen (hostPath, "wb");
deleteOnError = TRUE;
}
if (!f)
{
perror ("Cannot open file or device");
return FALSE;
}
EAMode = LRW;
// Filesystem
if (!Filesystem)
{
puts ("Filesystem:\n 1) FAT\n 2) None");
Filesystem = AskSelection (1, 1, 2) == 1 ? "FAT" : "None";
}
// Host file/device size
if (fseek (f, 0, SEEK_END) == -1 || (hostSize = ftello (f)) == (unsigned __int64)-1)
{
perror ("Cannot determine host file/device size");
goto err;
}
// Volume size
if (IsBlockDevice (hostPath) && !hiddenVolume)
{
if (VolumeSize != 0)
{
error ("Volume size cannot be changed for device-hosted volumes.\n");
goto err;
}
VolumeSize = hostSize;
}
else if (VolumeSize == 0)
{
while (!AskString ("Enter volume size (bytes - size/sizeK/sizeM/sizeG)", str, sizeof (str))
|| !ParseSize (str, &VolumeSize)
|| VolumeSize == 0);
puts ("");
}
if (hiddenVolume && VolumeSize > hostSize - MIN_VOLUME_SIZE )
{
error ("Outer volume too small for the size specified.\n");
goto err;
}
if (strcasecmp ("FAT", Filesystem) == 0)
{
if (VolumeSize < MIN_VOLUME_SIZE || VolumeSize > MAX_FAT_VOLUME_SIZE)
{
error ("Specified volume size cannot be used with FAT filesystem.\n");
goto err;
}
}
// Hash algorithm
if (HashAlgorithm == 0)
{
puts ("Hash algorithm:");
for (i = 1; i <= LAST_PRF_ID; i++)
printf ("%2d) %s\n", i, HashGetName (i));
HashAlgorithm = AskSelection (1, 1, LAST_PRF_ID);
}
// Encryption algorithm
if (EA == 0)
{
int max = 0;
puts ("Encryption algorithm:");
for (i = EAGetFirst (); i != 0; i = EAGetNext (i))
{
if (EAGetFirstMode (i) == LRW)
{
printf ("%2d) %s\n", i, EAGetName (str, i));
max = i;
}
}
EA = AskSelection (1, EAGetFirst (), max);
}
// Password
if (!CmdPasswordValid)
{
while (1)
{
AskPassword ("Enter password for new volume '%s': ", hostPath, &password, TRUE);
if (!DisplayPassword)
{
Password pv;
AskPassword ("Re-enter password%s", ": ", &pv, TRUE);
if (password.Length != pv.Length || memcmp (password.Text, pv.Text, pv.Length))
{
puts ("Passwords do not match.\n");
continue;
}
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -