📄 cli.c
字号:
}
puts ("");
}
else
{
if (!ValidatePassword (&CmdPassword, TRUE))
goto err;
pw = &CmdPassword;
}
if (!NoKeyFiles && !FirstKeyFile)
{
AskKeyFiles ("Enter keyfile path", &FirstKeyFile);
puts ("");
}
if (!FirstKeyFile && pw->Length == 0)
{
error ("Password cannot be empty when no keyfile is specified\n");
goto err;
}
if (FirstKeyFile && !KeyFilesApply (pw, FirstKeyFile))
{
error ("Error while processing keyfiles\n");
goto err;
}
if (!RandFillPool ())
goto err;
// Create volume header
r = VolumeWriteHeader (header,
EA,
EAMode,
pw,
HashAlgorithm,
0,
0,
&ci,
hiddenVolume ? VolumeSize : 0,
FALSE);
if (r == ERR_CIPHER_INIT_WEAK_KEY)
{
error ("A weak or a potentially weak key has been generated. Please try again.\n");
goto err;
}
if (r != 0)
{
error ("Volume header creation failed.\n");
goto err;
}
totalSectors = VolumeSize / SECTOR_SIZE;
ci->hiddenVolumeOffset = hostSize - VolumeSize - HIDDEN_VOL_HEADER_OFFSET;
startSector = !hiddenVolume ? 1 : (ci->hiddenVolumeOffset / SECTOR_SIZE);
if (DisplayKeys)
{
printf ("Master Key: ");
HexDump (ci->master_key, EAGetKeySize (ci->ea));
printf ("\nSecondary Key: ");
HexDump (ci->iv, sizeof (ci->iv));
puts ("\n");
}
// Write header
if (hiddenVolume)
{
if (fseek (f, -HIDDEN_VOL_HEADER_OFFSET, SEEK_END) == -1)
{
perror ("Cannot seek to hidden volume header location");
goto err;
}
}
else
{
if (fseek (f, 0, SEEK_SET) == -1)
{
perror ("Cannot seek to volume header location");
goto err;
}
}
if (fwrite (header, 1, HEADER_SIZE, f) != HEADER_SIZE)
{
perror ("Cannot write volume header");
goto err;
}
InitProgressBar (totalSectors - 1);
StartSector = startSector;
if (Quick && !hiddenVolume && IsFile (hostPath))
Quick = FALSE;
if (strcasecmp ("FAT", Filesystem) == 0)
{
if (hiddenVolume)
{
if (fseeko (f, startSector * SECTOR_SIZE, SEEK_SET) == -1)
{
perror ("Cannot seek to hidden volume data area");
goto err;
}
}
ft.num_sectors = (unsigned int) totalSectors - 1;
ft.cluster_size = ClusterSize;
memcpy (ft.volume_name, "NO NAME ", 11);
GetFatParams (&ft);
r = FormatFat (startSector, &ft, f, ci, Quick);
}
else if (!hiddenVolume)
{
r = FormatNoFs (startSector, totalSectors - 1, f, ci, Quick);
}
if (r == ERR_OS_ERROR)
{
perror ("Volume creation failed");
goto err;
}
LastUpdateTime = 0;
UpdateProgressBar (TotalSectors + StartSector);
if (DisplayProgress && IsTerminal)
puts ("\nVolume created.");
ret = TRUE;
err:
if (ci)
crypto_close (ci);
if (f)
fclose (f);
if (!ret && deleteOnError && IsFile (hostPath))
remove (hostPath);
Randfree ();
return ret;
}
static BOOL ChangePassword (char *volumePath)
{
char header[HEADER_SIZE];
char path[TC_MAX_PATH];
Password *pw = &password;
PCRYPTO_INFO ci = NULL, ci2 = NULL;
unsigned long long startSector, totalSectors;
time_t modTime = 0, acTime;
int wipePass, ret = FALSE;
int fd = -1, r;
FILE *f;
// Volume path
volumePath = AskVolumePath (volumePath, "Enter volume path");
if (!NoKeyFiles && !FirstKeyFile)
AskKeyFiles ("Enter current keyfile path", &FirstKeyFile);
// Open volume
if (!OpenVolume (volumePath, "Enter current password for '%s': ", volumePath, FALSE,
&ci, &startSector, &totalSectors, &modTime, &acTime))
return FALSE;
puts ("");
// New password and/or keyfile(s)
if (!NoNewKeyFiles && !FirstNewKeyFile)
AskKeyFiles ("Enter new keyfile path", &FirstNewKeyFile);
if (!CmdPassword2Valid)
{
while (1)
{
AskPassword ("Enter new password for '%s': ", volumePath, &password, TRUE);
if (!DisplayPassword)
{
Password pv;
AskPassword ("Re-enter new password%s", ": ", &pv, TRUE);
if (password.Length != pv.Length || memcmp (password.Text, pv.Text, pv.Length))
{
puts ("Passwords do not match.\n");
continue;
}
}
break;
}
puts ("");
}
else
{
if (!ValidatePassword (&CmdPassword2, TRUE))
goto err;
pw = &CmdPassword2;
}
if (!FirstNewKeyFile && pw->Length == 0)
{
error ("Password cannot be empty when no keyfile is specified\n");
goto err;
}
if (FirstNewKeyFile && !KeyFilesApply (pw, FirstNewKeyFile))
{
error ("Error while processing new keyfiles\n");
goto err;
}
fd = open (volumePath, O_RDWR | O_SYNC);
if (fd == -1)
{
perror ("Cannot open file or device");
goto err;
}
OpenMiceDevice ();
if (!RandFillPool ())
goto err;
f = fdopen (fd, "r+b");
// Write a new volume header
for (wipePass = 0; wipePass < DISK_WIPE_PASSES; wipePass++)
{
BOOL wipeMode = wipePass < DISK_WIPE_PASSES - 1;
if (Verbose)
{
printf ("\rWriting header (pass %d)%s", wipePass, wipeMode ? "" : "\n");
fflush (stdout);
}
r = VolumeWriteHeader (header,
ci->ea,
ci->mode,
pw,
HashAlgorithm == 0 ? ci->pkcs5 : HashAlgorithm,
(char *)ci->master_key,
ci->volume_creation_time,
&ci2,
ci->hiddenVolumeSize,
wipeMode);
if (r == ERR_CIPHER_INIT_WEAK_KEY)
{
error ("A weak or a potentially weak key has been generated. Please try again.\n");
goto err;
}
if (r != 0)
{
error ("Volume header creation failed.\n");
goto err;
}
crypto_close (ci2);
ci2 = NULL;
if (ci->hiddenVolumeSize)
{
if (fseek (f, -HIDDEN_VOL_HEADER_OFFSET, SEEK_END) == -1)
{
perror ("Cannot seek to hidden volume header location");
goto err;
}
}
else
{
if (fseek (f, 0, SEEK_SET) == -1)
{
perror ("Cannot seek to volume header location");
goto err;
}
}
if (fwrite (header, 1, HEADER_SIZE, f) != HEADER_SIZE)
{
perror ("Cannot write volume header");
goto err;
}
fflush (f);
fdatasync (fd);
}
if (Verbose)
puts ("");
printf ("Password %schanged.\n", FirstKeyFile && FirstNewKeyFile ? "and/or keyfile(s) " : "");
if (!FirstKeyFile && FirstNewKeyFile)
puts ("Keyfiles added.");
if (FirstKeyFile && !FirstNewKeyFile)
puts ("Keyfiles removed.");
ret = TRUE;
err:
if (ci)
crypto_close (ci);
if (fd != -1)
close (fd);
if (!UpdateTime && modTime != 0)
RestoreFileTime (volumePath, modTime, acTime);
Randfree ();
return ret;
}
static BOOL BackupVolumeHeaders (char *backupFile, char *volumePath)
{
char path[TC_MAX_PATH];
char header[HEADER_SIZE * 2];
FILE *f = NULL, *fb = NULL;
struct stat volumeStat;
int ret = FALSE;
// Volume path
volumePath = AskVolumePath (volumePath, "Enter volume path");
if (strcmp (backupFile, volumePath) == 0)
{
error ("Volume path identical to backup file\n");
goto err;
}
volumeStat.st_mtime = 0;
if (IsFile (volumePath) && stat (volumePath, &volumeStat) != 0)
{
perror ("Cannot read volume's modification and access time");
volumeStat.st_mtime = 0;
goto err;
}
// Volume
f = fopen (volumePath, "rb");
if (!f)
{
perror ("Cannot open volume");
goto err;
}
if (fread (header, 1, HEADER_SIZE, f) != HEADER_SIZE)
{
perror ("Cannot read volume header");
goto err;
}
if (fseek (f, -HIDDEN_VOL_HEADER_OFFSET, SEEK_END) == -1)
{
perror ("Cannot seek to hidden volume header location");
goto err;
}
if (fread (header + HEADER_SIZE, 1, HEADER_SIZE, f) != HEADER_SIZE)
{
perror ("Cannot read hidden volume header");
goto err;
}
// Backup file
fb = fopen (backupFile, "wb");
if (!fb)
{
perror ("Cannot open backup file");
goto err;
}
if (fwrite (header, 1, HEADER_SIZE * 2, fb) != HEADER_SIZE * 2)
{
perror ("Cannot write backup file");
goto err;
}
ret = TRUE;
err:
if (f)
fclose (f);
if (f)
fclose (fb);
if (!UpdateTime && volumeStat.st_mtime != 0)
RestoreFileTime (volumePath, volumeStat.st_mtime, volumeStat.st_atime);
return ret;
}
static BOOL RestoreVolumeHeader (char *backupFile, char *volumePath)
{
char path[TC_MAX_PATH];
char header[HEADER_SIZE];
FILE *f = NULL, *fb = NULL;
struct stat volumeStat;
int ret = FALSE;
BOOL hiddenVolume;
// Backup file
fb = fopen (backupFile, "rb");
if (!fb)
{
perror ("Cannot open backup file");
goto err;
}
// Volume path
volumePath = AskVolumePath (volumePath, "Enter volume path");
if (strcmp (backupFile, volumePath) == 0)
{
error ("Volume path identical to backup file\n");
goto err;
}
// Volume type
switch (VolumeType)
{
case VOLUME_TYPE_NORMAL:
hiddenVolume = FALSE;
break;
case VOLUME_TYPE_HIDDEN:
hiddenVolume = TRUE;
Quick = TRUE;
break;
default:
puts ("Restore header of:\n 1) Normal/Outer Volume\n 2) Hidden Volume");
hiddenVolume = AskSelection (1, 1, 2) == 2;
break;
}
volumeStat.st_mtime = 0;
if (IsFile (volumePath) && stat (volumePath, &volumeStat) != 0)
{
perror ("Cannot read volume's modification and access time");
volumeStat.st_mtime = 0;
goto err;
}
f = fopen (volumePath, "r+b");
if (!f)
{
perror ("Cannot open volume");
goto err;
}
if (hiddenVolume)
{
if (fseek (fb, HEADER_SIZE, SEEK_SET) == -1)
{
perror ("Cannot seek to hidden volume header location in backup file");
goto err;
}
if (fseek (f, -HIDDEN_VOL_HEADER_OFFSET, SEEK_END) == -1)
{
perror ("Cannot seek to hidden volume header location");
goto err;
}
}
if (fread (header, 1, HEADER_SIZE, fb) != HEADER_SIZE)
{
perror ("Cannot read backup file");
goto err;
}
if (fwrite (header, 1, HEADER_SIZE, f) != HEADER_SIZE)
{
perror ("Cannot write volume header");
goto err;
}
ret = TRUE;
err:
if (f)
fclose (f);
if (f)
fclose (fb);
if (!UpdateTime && volumeStat.st_mtime != 0)
RestoreFileTime (volumePath, volumeStat.st_mtime, volumeStat.st_atime);
return ret;
}
static BOOL CreateKeyfile (char *path)
{
uint8_t keyFile[MAX_PASSWORD];
FILE *f = NULL;
int ret = FALSE;
OpenMiceDevice ();
if (!Overwrite
&& IsFile (path)
&& (!IsTerminal || !AskYesNo ("Keyfile already exists - overwrite?", TRUE)))
{
if (!IsTerminal)
error ("Keyfile already exists.\n");
return FALSE;
}
f = fopen (path, "wb");
if (!f)
{
perror ("Cannot open file");
goto err;
}
if (!RandFillPool ())
goto err;
if (!RandgetBytes (keyFile, sizeof (keyFile), FALSE))
goto err;
if (fwrite (keyFile, 1, sizeof (keyFile), f) != sizeof (keyFile))
{
perror ("Cannot write file");
goto err;
}
puts ("Keyfile created.");
ret = TRUE;
err:
if (f)
fclose (f);
Randfree ();
return ret;
}
static time_t WindowsFileTime2UnixTime (uint64_t wTime)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -