Exemple #1
0
void Drive::Umount(HWND)
{
	// check mounted
	CheckMounted();
//	if (GetDriveType(mnt) == DRIVE_NO_ROOT_DIR)
//		mounted = false;
	if (!mounted)
		throw truntime_error(_T("Cannot unmount a not mounted drive"));

	// unmount
	fuse_unmount(wchar_to_utf8_cstr(mnt).c_str(), NULL);

	if (subProcess) {
		// attach console to allow sending ctrl-c
		AttachConsole(subProcess->pid);

		// disable ctrl-c to not exit this process
		SetConsoleCtrlHandler(HandlerRoutine, TRUE);

		if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, subProcess->pid)
		    && !GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, subProcess->pid))
			TerminateProcess(subProcess->hProcess, 0);

		// force exit
		if (WaitForSingleObject(subProcess->hProcess, 2000) == WAIT_TIMEOUT)
			TerminateProcess(subProcess->hProcess, 0);
			
		// close the console
		FreeConsole();
		SetConsoleCtrlHandler(HandlerRoutine, FALSE);
	}
	CheckMounted();
}
Exemple #2
0
void Drive::Mount(HWND hwnd)
{
	// check drive empty or require a new drive
	while (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) {
		char drive = SelectFreeDrive(hwnd);
		if (!drive)
			return;
		_stprintf(mnt, _T("%c:\\"), drive);
		Save();
	}

	// check directory existence
	if (!isDirectory(wchar_to_utf8_cstr(dir.c_str()).c_str())) {
		if (YesNo(hwnd, _T("Directory does not exists. Remove from list?")))
			Drives::Delete(shared_from_this());
		return;
	}

	// TODO check configuration still exists ?? ... no can cause recursion problem

	// search if executable is present
	TCHAR executable[MAX_PATH];
	if (!SearchPath(NULL, _T("encfs.exe"), NULL, LENGTH(executable), executable, NULL))
		throw truntime_error(_T("Unable to find encfs.exe file"));

	// ask a password to mount
	TCHAR pass[128+2];
	if (!GetPassword(hwnd, pass, LENGTH(pass)-2))
		return;
	_tcscat(pass, _T("\r\n"));

	// mount using a sort of popen
	TCHAR cmd[2048];
	_sntprintf(cmd, LENGTH(cmd), _T("\"%s\" -S \"%s\" %c:"), executable, dir.c_str(), mnt[0]);
	boost::shared_ptr<SubProcessInformations> proc(new SubProcessInformations);
	proc->creationFlags = CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW;
	if (!CreateSubProcess(cmd, proc.get())) {
		DWORD err = GetLastError();
		memset(pass, 0, sizeof(pass));
		_sntprintf(cmd, LENGTH(cmd), _T("Error: %s (%u)"), proc->errorPart, (unsigned) err);
		throw truntime_error(cmd);
	}
	subProcess = proc;

	// send the password
	std::string pwd = wchar_to_utf8_cstr(pass);
	DWORD written;
	WriteFile(proc->hIn, pwd.c_str(), pwd.length(), &written, NULL);
	CloseHandle(proc->hIn);	// close input so sub process does not any more
	proc->hIn = NULL;
	memset(pass, 0, sizeof(pass));
	memset((char*) pwd.c_str(), 0, pwd.length());

	mounted = false;

	// wait for mount, read error and give feedback
	for (unsigned n = 0; n < 5*10; ++n) {
		// drive appeared
		if (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) {
			if (Drives::autoShow)
				Show(hwnd);
			break;
		}

		// process terminated
		DWORD readed;
		char output[2048];
		switch (WaitForSingleObject(subProcess->hProcess, 200)) {
		case WAIT_OBJECT_0:
		case WAIT_ABANDONED:
			if (ReadFile(proc->hOut, output, sizeof(output)-1, &readed, NULL)) {
				output[readed] = 0;
				utf8_to_wchar_buf(output, cmd, LENGTH(cmd));
			} else {
				_stprintf(cmd, _T("Unknown error mounting drive %c:"), mnt[0]);
			}
			subProcess.reset();
			throw truntime_error(cmd);
		}
	}
	if (subProcess)
		mounted = true;
	Save(); // save for resume
}
Exemple #3
0
static void createConfig(const std::string& rootDir, bool paranoid, const char* password)
{
	bool reverseEncryption = false;
	ConfigMode configMode = paranoid ? Config_Paranoia : Config_Standard;
    
	int keySize = 0;
	int blockSize = 0;
	Cipher::CipherAlgorithm alg;
	rel::Interface nameIOIface;
	int blockMACBytes = 0;
	int blockMACRandBytes = 0;
	bool uniqueIV = false;
	bool chainedIV = false;
	bool externalIV = false;
	bool allowHoles = true;
	long desiredKDFDuration = NormalKDFDuration;
    
	if (reverseEncryption)
	{
		uniqueIV = false;
		chainedIV = false;
		externalIV = false;
		blockMACBytes = 0;
		blockMACRandBytes = 0;
	}

	if(configMode == Config_Paranoia)
	{
		// look for AES with 256 bit key..
		// Use block filename encryption mode.
		// Enable per-block HMAC headers at substantial performance penalty..
		// Enable per-file initialization vector headers.
		// Enable filename initialization vector chaning
		keySize = 256;
		blockSize = DefaultBlockSize;
		alg = findCipherAlgorithm("AES", keySize);
		nameIOIface = BlockNameIO::CurrentInterface();
		blockMACBytes = 8;
		blockMACRandBytes = 0; // using uniqueIV, so this isn't necessary
		uniqueIV = true;
		chainedIV = true;
		externalIV = true;
		desiredKDFDuration = ParanoiaKDFDuration;
	} else {
		// xgroup(setup)
		// AES w/ 192 bit key, block name encoding, per-file initialization
		// vectors are all standard.
		keySize = 192;
		blockSize = DefaultBlockSize;
		alg = findCipherAlgorithm("AES", keySize);
		blockMACBytes = 0;
		externalIV = false;
		nameIOIface = BlockNameIO::CurrentInterface();

		if (!reverseEncryption)
		{
			uniqueIV = true;
			chainedIV = true;
		}
	}

	boost::shared_ptr<Cipher> cipher = Cipher::New( alg.name, keySize );
	if(!cipher)
	{
		TCHAR buf[256];
		_sntprintf(buf, LENGTH(buf), _T("Unable to instanciate cipher %s, key size %i, block size %i"),
			alg.name.c_str(), keySize, blockSize);
		throw truntime_error(buf);
	}
    
	boost::shared_ptr<EncFSConfig> config( new EncFSConfig );

	config->cfgType = Config_V6;
	config->cipherIface = cipher->Interface();
	config->keySize = keySize;
	config->blockSize = blockSize;
	config->nameIface = nameIOIface;
	config->creator = "EncFS " VERSION;
	config->subVersion = V6SubVersion;
	config->blockMACBytes = blockMACBytes;
	config->blockMACRandBytes = blockMACRandBytes;
	config->uniqueIV = uniqueIV;
	config->chainedNameIV = chainedIV;
	config->externalIVChaining = externalIV;
	config->allowHoles = allowHoles;

	config->salt.clear();
	config->kdfIterations = 0; // filled in by keying function
	config->desiredKDFDuration = desiredKDFDuration;

	int encodedKeySize = cipher->encodedKeySize();
	unsigned char *encodedKey = new unsigned char[ encodedKeySize ];

	CipherKey volumeKey = cipher->newRandomKey();

	// get user key and use it to encode volume key
	CipherKey userKey;
	userKey = config->makeKey(password, strlen(password));

	cipher->writeKey( volumeKey, encodedKey, userKey );
	userKey.reset();

	config->assignKeyData(encodedKey, encodedKeySize);
	delete[] encodedKey;

	if(!volumeKey)
		throw truntime_error(_T("Failure generating new volume key! ")
		                         _T("Please report this error."));

	if (!saveConfig( Config_V6, rootDir, config ))
		throw truntime_error(_T("Error saving configuration file"));
}