📄 cli.c
字号:
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; } 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -