📄 cli.c
字号:
/*
Copyright (c) TrueCrypt Foundation. All rights reserved.
Covered by the TrueCrypt License 2.3 the full text of which is contained
in the file License.txt included in TrueCrypt binary and source code
distribution packages.
*/
#define _LARGEFILE_SOURCE 1
#define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include "Tcdefs.h"
#include "Crc.h"
#include "Dm-target.h"
#include "Keyfiles.h"
#include "Fat.h"
#include "Format.h"
#include "Password.h"
#include "Progress.h"
#include "Random.h"
#include "Volumes.h"
#include "Tests.h"
#include "Cli.h"
static MountListEntry MountList[TC_MAX_VOLUMES];
static BOOL MountListValid = FALSE;
static FILE *MiceDevice = NULL;
static int MiceDeviceErrNo;
static BOOL DisplayKeys = FALSE;
static BOOL DisplayPassword = FALSE;
static BOOL DisplayProgress = TRUE;
static BOOL UserMount = FALSE;
static BOOL UserMountAvailable = TRUE;
static char *Filesystem = NULL;
static char *MountOpts = NULL;
static int PasswordEntryTries = 3;
static Password CmdPassword;
static Password CmdPassword2;
static BOOL CmdPasswordValid = FALSE;
static BOOL CmdPassword2Valid = FALSE;
static int UseDeviceNumber = -1;
static BOOL ProtectHidden = FALSE;
static BOOL ReadOnly = FALSE;
static BOOL UpdateTime = FALSE;
static BOOL Interactive = FALSE;
static BOOL Overwrite = FALSE;
static int Verbose = 0;
static BOOL IsTerminal = FALSE;
static struct termios TerminalAttributes;
static Password password;
static KeyFile *FirstKeyFile;
static KeyFile *FirstProtVolKeyFile;
static KeyFile *FirstNewKeyFile;
static BOOL NoKeyFiles = FALSE;
static BOOL NoNewKeyFiles = FALSE;
static unsigned long long VolumeSize;
static unsigned int ClusterSize = 0;
static int EA;
static int EAMode;
static int HashAlgorithm;
static char *Filesystem;
static int VolumeType = -1;
static BOOL Quick;
static char *RandomSource = NULL;
static uid_t RealUserId;
static gid_t RealGroupId;
static int LastExitStatus;
static void SecurityCleanup ()
{
burn (&password, sizeof (password));
burn (&CmdPassword, sizeof (CmdPassword));
burn (&CmdPassword2, sizeof (CmdPassword2));
}
static void OnSignal (int signal)
{
SecurityCleanup ();
if (IsTerminal)
{
tcsetattr (0, TCSANOW, &TerminalAttributes);
puts ("");
}
_exit (1);
}
static void OnExit ()
{
SecurityCleanup ();
}
static BOOL CheckAdminPrivileges (int argc, char **argv)
{
char *env;
if (getuid () != 0)
{
char *args[128];
int i;
args[0] = "sudo";
args[1] = "-p";
args[2] = "Enter %u's or root's system password: ";
for (i = 0; i < argc && i < 127; i++)
args[i + 3] = argv[i];
args[i + 3] = NULL;
execvp ("sudo", args);
perror ("Executing sudo failed");
error ("Administrator (root) privileges required\n");
return FALSE;
}
setenv ("PATH", "/usr/sbin:/sbin:/usr/bin:/bin", 1);
return TRUE;
}
static BOOL LockMemory ()
{
// Lock process memory
if (mlockall (MCL_FUTURE) != 0)
{
perror ("Cannot prevent paging of memory to disk: mlockall");
return FALSE;
}
return TRUE;
}
static BOOL WaitChild (BOOL quiet, char *execName)
{
int status;
if (wait (&status) == -1)
{
perror ("wait");
return FALSE;
}
LastExitStatus = WEXITSTATUS (status);
if (!WIFEXITED (status)
|| (WIFEXITED (status) && WEXITSTATUS (status)))
{
if (!quiet && Verbose >= 3)
error ("Error: %s returned %d\n", execName, WEXITSTATUS (status));
return FALSE;
}
return TRUE;
}
static BOOL Execute (BOOL quiet, char *execName, ...)
{
int pid;
va_list vl;
va_start (vl, execName);
LastExitStatus = -1;
pid = fork ();
if (pid == -1)
{
perror ("fork");
goto err;
}
else if (pid == 0)
{
char *args[32];
int i = 1;
SecurityCleanup ();
if (Verbose >= 3)
printf ("Executing %s", execName);
args[0] = execName;
while (i < 32 && (args[i] = (va_arg (vl, char *))))
{
if (Verbose >= 3)
printf (" %s", args[i]);
i++;
}
if (Verbose >= 3)
puts ("");
if (quiet)
{
// >/dev/null is safer than >&-
int i = open ("/dev/null", 0);
if (i == -1)
{
perror ("open /dev/null");
_exit (1);
}
dup2 (i, STDOUT_FILENO);
dup2 (i, STDERR_FILENO);
}
execvp (execName, args);
fprintf (stderr, "Executing %s", execName);
perror (" failed");
_exit (1);
}
if (!WaitChild (quiet, execName))
goto err;
va_end (vl);
return TRUE;
err:
va_end (vl);
return FALSE;
}
static BOOL IsFile (char *path)
{
struct stat st;
if (stat (path, &st) != 0)
return FALSE;
return S_ISREG (st.st_mode);
}
static BOOL IsBlockDevice (char *path)
{
struct stat st;
if (stat (path, &st) != 0)
return FALSE;
return S_ISBLK (st.st_mode);
}
static BOOL RestoreFileTime (char *path, time_t modTime, time_t acTime)
{
struct utimbuf t;
t.actime = acTime;
t.modtime = modTime;
return utime (path, &t) != 0;
}
static BOOL LoadKernelModule ()
{
char s[2048];
FILE *m;
m = fopen ("/proc/modules", "r");
if (m == NULL)
{
perror ("fopen /proc/modules");
return FALSE;
}
while (fgets (s, sizeof (s), m))
{
if (strstr (s, "truecrypt ") == s)
{
fclose (m);
return TRUE;
}
}
fclose (m);
if (!Execute (TRUE, "modprobe", "truecrypt", NULL))
{
struct utsname u;
char module[128];
int r1, r2, r3;
char *p;
if (!Execute (TRUE, "modprobe", "dm-mod", NULL))
Execute (TRUE, "modprobe", "dm", NULL);
if (uname (&u) == 0 && sscanf (u.release, "%d.%d.%d", &r1, &r2, &r3) == 3)
{
snprintf (module, sizeof (module), "%s/truecrypt.ko", TC_SHARE_KERNEL);
if (IsFile (module) && Execute (TRUE, "insmod", module, NULL))
return TRUE;
snprintf (module, sizeof (module), "%s/truecrypt-%d.%d.%d.ko", TC_SHARE_KERNEL, r1, r2, r3);
if (IsFile (module) && Execute (FALSE, "insmod", module, NULL))
return TRUE;
}
Execute (FALSE, "modprobe", "truecrypt", NULL);
error ("Failed to load TrueCrypt kernel module\n");
return FALSE;
}
return TRUE;
}
static BOOL UnloadKernelModule (BOOL quiet)
{
// rmmod is used instead of modprobe to prevent unload of dependencies
return Execute (quiet, "rmmod", "truecrypt", NULL);
}
static BOOL CheckKernelModuleVersion (BOOL wait, BOOL quiet)
{
FILE *p;
int pfd[2];
int pid, res;
int i, dummy;
char s[2048];
int ver1 = 0, ver2 = 0, ver3 = 0;
int tries = 10;
do
{
pipe (pfd);
pid = fork ();
if (pid == -1)
{
perror ("fork");
return FALSE;
}
else if (pid == 0)
{
SecurityCleanup ();
dup2 (pfd[1], STDOUT_FILENO);
close (pfd[0]);
close (STDERR_FILENO);
execlp ("dmsetup", "dmsetup", "targets", NULL);
perror ("execlp dmsetup");
_exit (1);
}
close (pfd[1]);
p = fdopen (pfd[0], "r");
if (p == NULL)
{
perror ("fdopen");
return FALSE;
}
while (fgets (s, sizeof (s), p))
{
char name[32];
if (sscanf (s, "%31s v%d.%d.%d", &name, &ver1, &ver2, &ver3) == 4
&& strcmp (name, "truecrypt") == 0)
{
fclose (p);
WaitChild (FALSE, "dmsetup");
if (ver1 == TC_VERSION_NUM1 && ver2 == TC_VERSION_NUM2 && ver3 == TC_VERSION_NUM3)
return TRUE;
error ("Incorrect version of kernel module loaded - version %s required\n", VERSION_STRING);
UnloadKernelModule (TRUE);
return FALSE;
}
}
fclose (p);
WaitChild (FALSE, "dmsetup");
// Target registration may take some time
if (wait)
usleep (100 * 1000);
else
break;
} while (tries--);
if (!quiet)
error ("Kernel module not loaded\n");
return FALSE;
}
static void OpenMiceDevice ()
{
if (!MiceDevice)
{
FILE *m;
char s[2048];
m = fopen ("/proc/bus/input/devices", "r");
if (m != NULL)
{
BOOL found = FALSE;
while (fgets (s, sizeof (s), m))
{
if (strstr (s, "mouse") || strstr (s, "Mouse") || strstr (s, "MOUSE"))
{
found = TRUE;
break;
}
}
fclose (m);
if (!found)
return;
}
MiceDevice = fopen (TC_MICE_DEVICE, "rb");
MiceDeviceErrNo = errno;
}
}
static BOOL GetMountList (BOOL force)
{
FILE *p;
int pfd[2];
int pid, res;
int i, dummy;
if (!force && MountListValid)
return TRUE;
MountList[0].DeviceNumber = -1;
pipe (pfd);
pid = fork ();
if (pid == -1)
{
perror ("fork");
goto err;
}
else if (pid == 0)
{
SecurityCleanup ();
dup2 (pfd[1], STDOUT_FILENO);
close (pfd[0]);
close (STDERR_FILENO);
execlp ("dmsetup", "dmsetup", "table", NULL);
perror ("execlp dmsetup");
_exit (1);
}
close (pfd[1]);
p = fdopen (pfd[0], "r");
if (p == NULL)
{
perror ("fdopen");
goto err;
}
for (i = 0; i < TC_MAX_VOLUMES; i++)
{
int n = 0;
char s[2048];
MountListEntry *e = &MountList[i];
if (!fgets (s, sizeof (s), p))
break;
if (sscanf (s, "truecrypt%d: 0 %llu truecrypt %d %d 0 0 %d:%d %llu %llu %llu %llu %llu %llu %d %n",
&e->DeviceNumber,
&e->VolumeSize,
&e->EA,
&e->Mode,
&e->DeviceMajor,
&e->DeviceMinor,
&e->Hidden,
&e->ReadOnlyStart,
&e->ReadOnlyEnd,
&e->UserId,
&e->ModTime,
&e->AcTime,
&e->Flags,
&n) >= 12 && n > 0)
{
int l;
snprintf (e->VolumePath, sizeof (e->VolumePath), "%s", s + n);
l = strlen (s + n);
if (l > 0)
e->VolumePath[l - 1] = 0;
e->Hidden = e->Hidden == 1 ? FALSE : TRUE;
e->VolumeSize *= SECTOR_SIZE;
}
else
i--;
}
MountList[i].DeviceNumber = -1;
fclose (p);
if (!WaitChild (TRUE, "dmsetup"))
goto err;
MountListValid = TRUE;
return TRUE;
err:
MountList[0].DeviceNumber = -1;
return FALSE;
}
static BOOL IsVolumeMounted (char *volumePath)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -