⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cli.c

📁 truecrypt-4.2a-source-cod 文件虚拟磁盘源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	fprintf (w, " %s %llu %llu %llu %llu %llu %d %s\n",
		hostDevice,
		startSector,
		readOnlyStartSector,
		readOnlySectors,
		(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;
	}

	sprintf (mapDevice, TC_MAP_DEV "%d", devNo);

	if (Verbose >= 1)
		printf ("Mapped %s as %s\n", volumePath, mapDevice);

	// Mount
	if (mountPoint)
	{
		char fstype[64], opts[128];

		strcpy (fstype, "-t");
		if (Filesystem)
			strncat (fstype, Filesystem, sizeof (fstype) - 3);
		else
			strcat (fstype, "auto");

		strcpy (opts, ReadOnly ? "-oro" : "-orw");
		if (MountOpts)
		{
			strcat (opts, ",");
			strncat (opts, MountOpts, sizeof (opts) - 6);
		}

		if (UserMount)
		{
			// Set default uid and gid
			char s[64];
			sprintf (s, ",uid=%d,gid=%d", RealUserId, RealGroupId);
			strcat (opts, s);
		}

		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"
					"- Install TrueCrypt as set-euid root.\n"
					"- Add read permission to mouse device for all users (chmod o+r " 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 * 4];
			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 ();
	DropEffectiveUserId ();

	// Volume type
	switch (VolumeType)
	{
	case VOLUME_TYPE_NORMAL:
		hiddenVolume = FALSE;
		break;

	case VOLUME_TYPE_HIDDEN:
		hiddenVolume = TRUE;
		Quick = TRUE;
		break;

	default:
		puts ("Volume type:\n 1) Normal\n 2) Hidden");
		hiddenVolume = AskSelection (1, 1, 2) == 2;
		break;
	}

	// 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;
	}
	else
	{
		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;
ea:
		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);

		if (CipherGetBlockSize (EAGetFirstCipher (EA)) == 8
			&& VolumeSize > WARN_VOL_SIZE_BLOCK64)
		{
			char s[3];

			AskString ("WARNING: You have selected a 64-bit block cipher. Due to security reasons,\n"
				"for this volume size, it is strongly recommended to select a 128-bit block cipher\n"
				"(for example, AES, Serpent, or Twofish) instead.\n\n"
				"Continue? [y/N]", s, sizeof (s));
			puts ("");

			if (strcmp (s, "y") && strcmp (s, "Y"))
				goto ea;
		}
	}

	// Password
	if (!CmdPasswordValid)
	{
		while (1)
		{
			AskPassword ("Enter password for new volume '%s': ", hostPath, &password);
			if (!DisplayPassword)
			{
				Password pv;
				AskPassword ("Re-enter password%s", ": ", &pv);
				if (password.Length != pv.Length || memcmp (password.Text, pv.Text, pv.Length))
				{
					puts ("Passwords do not match.\n");
					continue;
				}
			}
			break;
		}
		puts ("");
	}
	else
		pw = &CmdPassword;

	if (!NoKeyFiles && !FirstKeyFile)
	{
		AskKeyFiles ("Enter keyfile path", &FirstKeyFile);
		puts ("");
	}
	
	if (!FirstKeyFile && pw->Length == 0)
	{
		error ("Password cannot be empty when no keyfiles are specified\n");
		goto err;
	}

	if (FirstKeyFile && !KeyFilesApply (pw, FirstKeyFile, !UpdateTime))
	{
		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;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -