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

📄 cli.c

📁 一个关于磁盘加密保护的驱动开发以及示例源码.对于学习这方面的人可以有点参考和学习作用.
💻 C
📖 第 1 页 / 共 5 页
字号:
{
	int i;
	if (!GetMountList (FALSE))
		return FALSE;

	for (i = 0; MountList[i].DeviceNumber != -1; i++)
		if (strcmp (volumePath, MountList[i].VolumePath) == 0)
			return TRUE;

	return FALSE;
}


static int GetFreeMapDevice ()
{
	FILE *p;
	char cmd[128];
	int n;

	if (!GetMountList (FALSE))
		return -1;

	for (n = 0; n < TC_MAX_MINOR; n++)
	{
		int j = 0;
		while (MountList[j].DeviceNumber != -1)
		{
			if (MountList[j].DeviceNumber == n)
				break;
			j++;
		}

		if (MountList[j].DeviceNumber == -1)
			return n;
	}

	return -1;
}


static BOOL DeleteLoopDevice (int loopDeviceNo)
{
	char dev[64];
	BOOL r;
	int i;

	snprintf (dev, sizeof (dev), TC_LOOP_DEV "%d", loopDeviceNo);
	if (!IsBlockDevice (dev))
		snprintf (dev, sizeof (dev), TC_LOOP_DEV "/%d", loopDeviceNo);

	for (i = 0; i < 10; i++)
	{
		r = Execute (TRUE, "losetup", "-d", dev, NULL);
		if (r)
			break;

		usleep (200 * 1000);
	}

	if (r && Verbose > 1)
		printf ("Detached %s\n", dev);

	if (!r)
		error ("Failed to detach %s\n", dev);

	return r;
}


static int AskSelection (int defaultChoice, int min, int max)
{
	int c;
	char s[10];

	while (1)
	{
		printf ("Select [%d]: ", defaultChoice);

		if (fgets (s, sizeof (s), stdin) && sscanf (s, "%d", &c) == 1)
		{
			if (c < min || c > max)
				continue;

			puts ("");
			return c;
		}

		if (s[0] != 0 && s[0] != '\n')
			continue;

		puts ("");
		return defaultChoice;
	}
}


static BOOL AskYesNo (char *prompt, BOOL defaultNo)
{
	char s[4];

	do
	{
		printf ("%s [%c/%c]: ", prompt, defaultNo ? 'y' : 'Y', defaultNo ? 'N' : 'n');
		fgets (s, sizeof(s), stdin);

		if (s[0] == 'y' || s[0] == 'Y')
			return TRUE;

		if (s[0] == 'n' || s[0] == 'N')
			return FALSE;

	} while (s[0] != '\n');

	return !defaultNo;
}


static char *AskString (char *prompt, char *buf, int maxSize)
{
	printf ("%s: ", prompt);

	if (fgets (buf, maxSize, stdin))
	{
		char *lf = strchr (buf, '\n');
		if (lf)
			lf[0] = 0;

		return buf;
	}

	return NULL;
}


static BOOL ValidatePassword (Password *password, BOOL requireAscii)
{
	int i;

	if (password->Length > MAX_PASSWORD)
	{
		error ("Maximum password length is %d characters\n", MAX_PASSWORD);
		return FALSE;
	}

	for (i = 0; i < password->Length; i++)
	{
		if (password->Text[i] >= 0x7f || password->Text[i] < 0x20)
		{
			error ("Password must be composed only of US-ASCII printable characters to maintain portability.\n");
			
			if (requireAscii)
				return FALSE;
			else
				break;
		}
	}

	return TRUE;
}


static void AskPassword (char *prompt, char *volumePath, Password *password, BOOL requireAscii)
{
	struct termios noEcho;
	char pw[2048];

	if (tcgetattr (0, &TerminalAttributes) == 0)
	{
		noEcho = TerminalAttributes;

		if (!DisplayPassword)
		{
			noEcho.c_lflag &= ~ECHO;
			if (tcsetattr (0, TCSANOW, &noEcho) != 0)
				error ("Failed to turn terminal echo off\n");
		}
	}

	while (TRUE)
	{
		char *newl;
		
		if (IsTerminal)
			printf (prompt, volumePath);

		if (!fgets (pw, sizeof (pw), stdin))
		{
			password->Length = 0;
			break;
		}

		newl = strchr (pw, '\n');
		if (newl) newl[0] = 0;

		snprintf ((char *)password->Text, sizeof (password->Text), "%s", pw);
		password->Length = strlen ((char *)password->Text);

		if (ValidatePassword (password, requireAscii))
			break;
	}

	burn(pw, sizeof (pw));

	if (IsTerminal && !DisplayPassword)
	{
		tcsetattr (0, TCSANOW, &TerminalAttributes);
		puts ("");
	}
}


static char *AskVolumePath (char *volumePath, char *prompt)
{
	static char path[TC_MAX_PATH];

	// Volume path
	while (!volumePath || !volumePath[0])
	{
		volumePath = AskString (prompt, path, sizeof (path));
	}

	return volumePath;
}


static BOOL AskKeyFiles (char *prompt, KeyFile **firstKeyFile)
{
	char path[TC_MAX_PATH];
	char lprompt[128];

	snprintf (lprompt, sizeof(lprompt), "%s [none]", prompt); 
	while (AskString (lprompt, path, sizeof (path)) && path[0] != 0)
	{
		KeyFile *kf = malloc (sizeof (KeyFile));
		if (!kf)
		{
			perror ("malloc");
			return FALSE;
		}
		snprintf (kf->FileName, sizeof (kf->FileName), "%s", path);
		*firstKeyFile = KeyFileAdd (*firstKeyFile, kf);

		snprintf (lprompt, sizeof(lprompt), "%s [finish]", prompt); 
	}

	return TRUE;
}


static BOOL OpenVolume (char *volumePath, char *prompt, char *promptArg, BOOL secondaryPassword, PCRYPTO_INFO *cryptoInfo, unsigned long long *startSector, unsigned long long *totalSectors, time_t *modTime, time_t *acTime)
{
	char header[SECTOR_SIZE];
	FILE *f = NULL;
	struct stat volumeStat;
	int tries = PasswordEntryTries;
	char msg[128];
	BOOL ret = FALSE;
	int r;

	memset (&volumeStat, 0, sizeof (volumeStat));
	if ((!UpdateTime || ReadOnly)
		&& IsFile (volumePath) && stat (volumePath, &volumeStat) != 0)
	{
		perror ("Cannot open volume");
		volumeStat.st_ctime = 0;
		goto err;
	}

	f = fopen (volumePath, "rb");
	if (!f)
	{
		perror ("Cannot open volume");
		goto err;
	}

	do
	{
		Password *pw = &password;

		if (!secondaryPassword && !CmdPasswordValid || (secondaryPassword && !CmdPassword2Valid))
			AskPassword (prompt, promptArg, &password, FALSE);
		else
			pw = secondaryPassword ? &CmdPassword2 : &CmdPassword;

		if ((!secondaryPassword
				&& FirstKeyFile
				&& !KeyFilesApply (pw, FirstKeyFile))
			|| (secondaryPassword 
				&& FirstProtVolKeyFile
				&& !KeyFilesApply (pw, FirstProtVolKeyFile)))
		{
			error ("Error while processing keyfiles\n");
			goto err;
		}

		// Normal header
		fseek (f, 0, SEEK_SET);
		if (fread (header, 1, SECTOR_SIZE, f) != SECTOR_SIZE)
		{
			perror ("Cannot read volume header");
			goto err;
		}

		if (fseek (f, 0, SEEK_END) == -1)
		{
			perror ("Cannot determine volume size");
			goto err;
		}

		r = VolumeReadHeader (header, pw, cryptoInfo);

		if (r == 0)
		{
			*totalSectors = ftello (f) / SECTOR_SIZE - 1;
			*startSector = 1;
			ret = TRUE;
			break;
		}

		if (r == ERR_PASSWORD_WRONG)
		{
			// Hidden header
			if (fseek (f, -HIDDEN_VOL_HEADER_OFFSET, SEEK_END) == -1
				|| fread (header, 1, SECTOR_SIZE, f) != SECTOR_SIZE)
			{
				perror ("Cannot read hidden volume header");
				if (IsFile (volumePath))
					error ("Please check the filesystem supports files larger than 2GB.\n");
				goto err;
			}

			r = VolumeReadHeader (header, pw, cryptoInfo);

			if (r == 0)
			{
				*startSector = (ftello (f) 
					+ SECTOR_SIZE * 2 
					- (*cryptoInfo)->hiddenVolumeSize 
					- HIDDEN_VOL_HEADER_OFFSET) / SECTOR_SIZE;

				*totalSectors = (*cryptoInfo)->hiddenVolumeSize / SECTOR_SIZE;
				ret = TRUE;
				break;
			}
			
			if (r == ERR_PASSWORD_WRONG)
			{
				char s[128];

				snprintf (s, sizeof (s), "Incorrect password %sor not a TrueCrypt volume."
					, (FirstKeyFile || FirstProtVolKeyFile) ? "and/or keyfile(s) " : "");

				if (IsTerminal)
				{
					puts (s);
					continue;
				}
				else
				{
					error ("%s\n", s);
					goto err;
				}
			}
		}

		// Report errors
		switch (r)
		{
		case ERR_NEW_VERSION_REQUIRED:
			snprintf (msg, sizeof (msg), "A newer version of TrueCrypt is required to open this volume."); 
			break;

		default:
			snprintf (msg, sizeof (msg), "Volume cannot be opened: Error %d", r);
			break;
		}

		if (IsTerminal)
			printf ("%s\n", msg);
		else
			error ("%s\n", msg);

		goto err;

	} while (IsTerminal
		&& --tries > 0
		&& ((!secondaryPassword && !CmdPasswordValid)
			|| (secondaryPassword && !CmdPassword2Valid)));

	fclose (f);

	if (!UpdateTime)
		RestoreFileTime (volumePath, volumeStat.st_mtime, volumeStat.st_atime);

	*modTime = volumeStat.st_mtime;
	*acTime = volumeStat.st_atime;

	return ret;

err:
	*cryptoInfo = NULL;

	if (f)
		fclose (f);

	if (volumeStat.st_ctime != 0 && !UpdateTime)
		RestoreFileTime (volumePath, volumeStat.st_mtime, volumeStat.st_atime);

	*totalSectors = 0;
	return FALSE;
}


static char *EscapeSpaces (char *string)
{
	static char escapedString[TC_MAX_PATH * 2];
	char *e = escapedString;
	char c;

	if (strlen (string) > TC_MAX_PATH)
		return NULL;

	while ((c = *string++))
	{
		if (c == ' ')
			*e++ = '\\';

		*e++ = c;
	}

	return escapedString;
}


static BOOL IsMountPointAvailable (char *mountPoint)
{
	char md[TC_MAX_PATH], mp[TC_MAX_PATH];

	while (EnumMountPoints (md, mp))
	{
		if (strcmp (mountPoint, mp) == 0)
		{
			EnumMountPoints (NULL, NULL);
			return FALSE;
		}
	}
	return TRUE;
}


static BOOL MountVolume (char *volumePath, char *mountPoint)
{
	char hostDevice[TC_MAX_PATH];
	char mapDevice[TC_MAX_PATH];
	int loopDevNo = -1;
	PCRYPTO_INFO ci = NULL;
	unsigned long long startSector, totalSectors;
	unsigned long long readOnlyStartSector = 0, readOnlySectors = 0;
	int pfd[2];
	int pid, res, devNo;
	time_t modTime, acTime;
	FILE *f, *w;
	int flags;
	int i;
	int tries = PasswordEntryTries;

#if DEBUG
	if (!AutoTestAlgorithms ())
	{
		error ("Self-tests of algorithms FAILED!\n");
		return FALSE;
	}
#endif

	if (IsVolumeMounted (volumePath))
	{
		error ("Volume already mapped\n");
		return FALSE;
	}

	if (UseDeviceNumber != -1)
	{
		for (i = 0; MountList[i].DeviceNumber != -1; i++)
		{
			if (MountList[i].DeviceNumber == UseDeviceNumber)
			{
				error (TC_MAP_DEV "%d already in use\n", UseDeviceNumber);
				return FALSE;
			}
		}
	}

	if (mountPoint && !IsMountPointAvailable (mountPoint))
	{
		error ("Mount directory %s is already in use\n", mountPoint);
		return FALSE;
	}

	if (!OpenVolume (volumePath, "Enter password for '%s': ", volumePath, FALSE,
		&ci, &startSector, &totalSectors, &modTime, &acTime))
		goto err;

	if (totalSectors == 0)
	{
		error ("Illegal volume size (0 bytes).\n");
		goto err;
	}

	// Hidden volume protection
	if (ProtectHidden)
	{
		PCRYPTO_INFO ciH = NULL;
		unsigned long long startSectorH, totalSectorsH;

		if (OpenVolume (volumePath, "Enter hidden volume password: ", "", TRUE,
			&ciH, &startSectorH, &totalSectorsH, &modTime, &acTime))
		{
			readOnlyStartSector = startSectorH;
			readOnlySectors = startSectorH + totalSectorsH;
		}
		
		if (ciH)
			crypto_close (ciH);

		if (readOnlySectors == 0)
			goto err;
	}

	// Headers decrypted

	// Loopback
	if (IsFile (volumePath))
	{
		int i;

		for (i = 0; i < TC_MAX_MINOR; i++)
		{
			snprintf (hostDevice, sizeof (hostDevice), TC_LOOP_DEV "%d", i);

			if (!IsBlockDevice (hostDevice))
			{
				snprintf (hostDevice, sizeof (hostDevice), TC_LOOP_DEV "/%d", i);
				if (!IsBlockDevice (hostDevice))
					continue;
			}

			if (Execute (TRUE, "losetup", hostDevice, volumePath, NULL))
				break;
		}

		if (i >= TC_MAX_MINOR)

⌨️ 快捷键说明

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