📄 cli.c
字号:
"truecrypt --type normal -c volume.tc && truecrypt --type hidden -c volume.tc\n"
" Create a new volume and then create a hidden volume inside it."
"\n"
"truecrypt --keyfile-add keyfile -C volume.tc\n"
" Change password and add a new keyfile to volume.\n"
"\n"
"truecrypt -k keyfile -C volume.tc\n"
" Change password and remove a keyfile from volume.\n"
"\n"
"truecrypt -k keyfile --keyfile-add keyfile -C volume.tc\n"
" Change password and keep previous keyfile.\n"
"\n"
"Report bugs at <http://www.truecrypt.org/bugs>.\n"
);
}
static BOOL DumpMountList (int devNo)
{
BOOL found = FALSE;
int i;
if (!CheckKernelModuleVersion (FALSE))
return FALSE;
if (!GetMountList ())
return FALSE;
if (devNo == -1 && MountList[0].DeviceNumber == -1)
{
error ("No volumes mounted\n");
return FALSE;
}
for (i = 0; MountList[i].DeviceNumber != -1; i++)
{
MountListEntry *e = &MountList[i];
if (devNo != -1 && e->DeviceNumber != devNo)
continue;
found = TRUE;
if (Verbose == 0)
{
printf (TC_MAP_DEV "%d %s\n",
e->DeviceNumber,
e->VolumePath);
}
else
{
char eaName[128];
EAGetName (eaName, e->EA);
printf (TC_MAP_DEV "%d:\n"
" Volume: %s\n"
" Type: %s\n"
" Size: %lld bytes\n"
" Encryption algorithm: %s\n"
" Mode of operation: %s\n"
" Read-only: %s\n"
" Hidden volume protected: %s\n\n",
e->DeviceNumber,
e->VolumePath,
e->Hidden ? "Hidden" : "Normal",
e->VolumeSize,
eaName,
EAGetModeName (e->EA, e->Mode, TRUE),
(e->Flags & FLAG_READ_ONLY) ? "Yes" : "No",
(e->Flags & FLAG_PROTECTION_ACTIVATED) ? "Yes - damage prevented" : (
(e->Flags & FLAG_HIDDEN_VOLUME_PROTECTION) ? "Yes" : "No" )
);
}
}
if (!found)
{
error (TC_MAP_DEV "%d not mapped\n", devNo);
return FALSE;
}
return TRUE;
}
static BOOL EnumMountPoints (char *device, char *mountPoint)
{
static FILE *m = NULL;
if (device == NULL)
{
fclose (m);
m = NULL;
return TRUE;
}
if (m == NULL)
{
m = fopen ("/proc/mounts", "r");
if (m == NULL)
{
perror ("fopen /proc/mounts");
return FALSE;
}
}
if (fscanf (m, "%" MAX_PATH_STR "s %" MAX_PATH_STR "s %*s %*s %*s %*s",
device, mountPoint) != 2)
{
fclose (m);
m = NULL;
return FALSE;
}
return TRUE;
}
static BOOL DismountFileSystem (char *device)
{
char mountedDevice[MAX_PATH], mountPoint[MAX_PATH];
BOOL result = TRUE;
while (EnumMountPoints (mountedDevice, mountPoint))
{
if (strcmp (mountedDevice, device) == 0)
{
if (!Execute (FALSE, "umount", mountPoint, NULL))
result = FALSE;
else if (Verbose >= 1)
printf ("Dismounted %s\n", mountPoint);
}
}
return result;
}
// devNo: -1 = Dismount all volumes
static BOOL DismountVolume (int devNo)
{
char mapDevice[MAX_PATH];
int nMountedVolumes = 0;
int i;
BOOL found = FALSE;
BOOL status = TRUE;
if (!CheckKernelModuleVersion (FALSE))
return FALSE;
if (!GetMountList ())
return FALSE;
if (devNo == -1 && MountList[0].DeviceNumber == -1)
{
error ("No volumes mounted\n");
return FALSE;
}
// Flush write buffers before dismount if there are
// mounted volumes with hidden volume protection
for (i = 0; MountList[i].DeviceNumber != -1; i++)
{
if (MountList[i].Flags & FLAG_HIDDEN_VOLUME_PROTECTION)
{
sync ();
MountListValid = FALSE;
GetMountList ();
break;
}
}
for (i = 0; MountList[i].DeviceNumber != -1; i++)
{
MountListEntry *e = &MountList[i];
nMountedVolumes++;
if (devNo == -1 || e->DeviceNumber == devNo)
{
BOOL dismounted = FALSE;
found = TRUE;
if (e->Flags & FLAG_PROTECTION_ACTIVATED)
printf ("WARNING: Write to the hidden volume %s has been prevented!\n", e->VolumePath);
sprintf (mapDevice, TC_MAP_DEV "%d", e->DeviceNumber);
if (DismountFileSystem (mapDevice))
{
char name[32];
sprintf (name, "truecrypt%d", e->DeviceNumber);
dismounted = Execute (FALSE, "dmsetup", "remove", name, NULL);
if (dismounted && IsFile (e->VolumePath))
{
if (!DeleteLoopDevice (e->DeviceMinor))
status = FALSE;
RestoreFileTime (e->VolumePath,
UpdateTime ? time (NULL) : (time_t) e->ModTime,
UpdateTime ? time (NULL) : (time_t) e->AcTime);
}
}
if (!dismounted)
{
error ("Cannot dismount %s\n", mapDevice);
status = FALSE;
}
else
{
nMountedVolumes--;
if (Verbose >= 1)
printf ("Unmapped %s\n", mapDevice);
}
if (devNo != -1)
break;
}
}
if (!found)
{
error (TC_MAP_DEV "%d not mapped\n", devNo);
return FALSE;
}
if (nMountedVolumes == 0)
{
// Ignore errors as volumes may be mounted asynchronously
UnloadKernelModule (TRUE);
}
return status;
}
// Convert a string to device number
// text: device number or name or mount point
BOOL ToDeviceNumber (char *text, int *deviceNumber)
{
char mountedDevice[MAX_PATH], mountPoint[MAX_PATH];
int i;
if (sscanf (text, "%d", deviceNumber) == 1)
return TRUE;
if (sscanf (text, TC_MAP_DEV "%d", deviceNumber) == 1)
return TRUE;
while (EnumMountPoints (mountedDevice, mountPoint))
{
if (strcmp (mountPoint, text) == 0
&& sscanf (mountedDevice, TC_MAP_DEV "%d", deviceNumber) == 1)
{
EnumMountPoints (NULL, NULL);
return TRUE;
}
}
if (!GetMountList ())
return FALSE;
for (i = 0; MountList[i].DeviceNumber != -1; i++)
{
MountListEntry *e = &MountList[i];
if (e->DeviceNumber == -1)
break;
if (strcmp (text, e->VolumePath) == 0)
{
*deviceNumber = e->DeviceNumber;
return TRUE;
}
}
error ("%s not mounted\n", text);
return FALSE;
}
int main (int argc, char **argv)
{
char *volumePath = NULL;
char *mountPoint = NULL;
char volumePathBuf[MAX_PATH];
int i, o;
int optIndex = 0;
FILE *f;
struct option longOptions[] = {
{"backup-headers", required_argument, 0, 0},
{"cluster", required_argument, 0, 0},
{"change", optional_argument, 0, 'C'},
{"create", optional_argument, 0, 'c'},
{"device-number", required_argument, 0, 'N'},
{"dismount", optional_argument, 0, 'd'},
{"disable-progress", 0, 0, 0},
{"display-keys", 0, 0, 0},
{"display-password", 0, 0, 0},
{"encryption", required_argument, 0, 0},
{"keyfile", required_argument, 0, 'k'},
{"keyfile-add", required_argument, 0, 0},
{"keyfile-protected", required_argument, 0, 'K'},
{"filesystem", required_argument, 0, 0},
{"keyfile-create", required_argument, 0, 0},
{"list", optional_argument, 0, 'l'},
{"hash", required_argument, 0, 0},
{"help", 0, 0, 'h'},
{"mount-options", required_argument, 0, 'M'},
{"password", required_argument, 0, 'l'},
{"password-tries", required_argument, 0, 0},
{"properties", optional_argument, 0, 0},
{"protect-hidden", 0, 0, 'P'},
{"quick", 0, 0, 0},
{"read-only", 0, 0, 'r'},
{"restore-header", required_argument, 0, 0},
{"size", required_argument, 0, 0},
{"test", 0, 0, 0},
{"type", required_argument, 0, 0},
{"update-time", 0, 0, 0},
{"user-mount", 0, 0, 'u'},
{"verbose", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{0, 0, 0, 0}
};
// Make sure pipes will not use file descriptors <= STDERR_FILENO
f = fdopen (STDIN_FILENO, "r");
if (f == NULL)
open ("/dev/null", 0);
f = fdopen (STDOUT_FILENO, "w");
if (f == NULL)
open ("/dev/null", 0);
f = fdopen (STDERR_FILENO, "w");
if (f == NULL)
open ("/dev/null", 0);
signal (SIGHUP, OnSignal);
signal (SIGINT, OnSignal);
signal (SIGQUIT, OnSignal);
signal (SIGABRT, OnSignal);
signal (SIGPIPE, OnSignal);
signal (SIGTERM, OnSignal);
LockMemory ();
atexit (OnExit);
RealUserId = getuid ();
RealGroupId = getgid ();
if (tcgetattr (0, &TerminalAttributes) == 0)
IsTerminal = TRUE;
while ((o = getopt_long (argc, argv, "c::C::d::hk:K:l::M:N:p:PruvV", longOptions, &optIndex)) != -1)
{
switch (o)
{
case 'c':
{
char *hostPath = NULL;
if (optind < argc)
{
hostPath = argv[optind++];
if (optind < argc)
goto usage;
}
return CreateVolume (hostPath) ? 0 : 1;
}
case 'C':
{
char *hostPath = NULL;
if (optind < argc)
{
hostPath = argv[optind++];
if (optind < argc)
goto usage;
}
return ChangePassword (hostPath) ? 0 : 1;
}
case 'd':
// Dismount
{
int devNo;
if (optind < argc)
{
if (!ToDeviceNumber (argv[optind++], &devNo))
return 1;
if (optind < argc)
goto usage;
}
else
devNo = -1;
if (!CheckAdminPrivileges ())
return 1;
return DismountVolume (devNo) ? 0 : 1;
}
case 'l':
// List
{
int devNo;
if (optind < argc)
{
if (!ToDeviceNumber (argv[optind++], &devNo))
return 1;
if (optind < argc)
goto usage;
}
else
devNo = -1;
if (!CheckAdminPrivileges ())
return 1;
return DumpMountList (devNo) ? 0 : 1;
}
case 'k':
case 'K':
// Keyfile
{
KeyFile *kf = malloc (sizeof (KeyFile));
if (!kf)
{
perror ("malloc");
return 1;
}
strncpy (kf->FileName, optarg, sizeof (kf->FileName));
if (o == 'k')
FirstKeyFile = KeyFileAdd (FirstKeyFile, kf);
else
FirstProtVolKeyFile = KeyFileAdd (FirstProtVolKeyFile, kf);
}
break;
case 'M':
MountOpts = optarg;
break;
case 'N':
if (sscanf (optarg, "%d", &UseDeviceNumber) == 1 && UseDeviceNumber >= 0)
break;
goto usage;
case 'p':
// Password
if (!CmdPasswordValid)
{
strncpy ((char *)CmdPassword.Text, optarg, sizeof (CmdPassword.Text));
CmdPassword.Length = strlen ((char *)CmdPassword.Text);
CmdPasswordValid = TRUE;
}
else if (!CmdPassword2Valid)
{
strncpy ((char *)CmdPassword2.Text, optarg, sizeof (CmdPassword2.Text));
CmdPassword2.Length = strlen ((char *)CmdPassword2.Text);
CmdPassword2Valid = TRUE;
}
break;
case 'P':
// Hidden volume protection
ProtectHidden = TRUE;
break;
case 'r':
ReadOnly = TRUE;
break;
case 'u':
UserMount = TRUE;
break;
case 'v':
// Verbose
Verbose++;
break;
case 'V':
DumpVersion (stdout);
return 0;
case 'h':
// Help
DumpHelp ();
return 0;
case 0:
if (strcmp ("backup-headers", longOptions[optIndex].name) == 0)
{
char *volumePath = NULL;
if (optind < argc)
volumePath = argv[optind++];
if (optind < argc)
goto usage;
if (BackupVolumeHeaders (optarg, volumePath))
{
printf ("Backup of volume headers succeeded.\n");
return 0;
}
return 1;
}
if (strcmp ("cluster", longOptions[optIndex].name) == 0)
{
if (sscanf (optarg, "%d", &ClusterSize) != 1)
goto usage;
break;
}
if (strcmp ("display-keys", longOptions[optIndex].name) == 0)
{
DisplayKeys = TRUE;
break;
}
if (strcmp ("display-password", longOptions[optIndex].name) == 0)
{
DisplayPassword = TRUE;
break;
}
if (strcmp ("disable-progress", longOptions[optIndex].name) == 0)
{
DisplayProgress = FALSE;
break;
}
if (strcmp ("encryption", longOptions[optIndex].name) == 0)
{
EA = EAGetByName (optarg);
if (EA == 0)
goto usage;
break;
}
if (strcmp ("filesystem", longOptions[optIndex].name) == 0)
{
Filesystem = optarg;
break;
}
if (strcmp ("hash", longOptions[optIndex].name) == 0)
{
HashAlgorithm = 0;
for (i = 1; i <= LAST_PRF_ID; i++)
{
if (strcasecmp (optarg, Ha
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -