Exemple #1
0
bool agent_load_key(unsigned char key[KDF_HASH_LEN])
{
	_cleanup_free_ char *iterationbuf = NULL;
	_cleanup_free_ char *verify = NULL;
	_cleanup_free_ char *username = NULL;
	_cleanup_free_ char *password = NULL;
	int iterations;

	iterationbuf = config_read_string("iterations");
	username = config_read_string("username");
	if (!iterationbuf || !username || !config_exists("verify"))
		return false;
	iterations = strtoul(iterationbuf, NULL, 10);
	if (iterations <= 0)
		return false;

	for (;;) {
		free(password);
		password = password_prompt("Master Password", password ? "Incorrect master password; please try again." : NULL, "Please enter the LastPass master password for <%s>.", username);
		if (!password)
			return false;
		kdf_decryption_key(username, password, iterations, key);

		/* no longer need password contents, zero it */
		secure_clear_str(password);

		verify = config_read_encrypted_string("verify", key);
		if (verify && !strcmp(verify, AGENT_VERIFICATION_STRING))
			break;
	}

	return true;
}
Exemple #2
0
struct session *sesssion_load(unsigned const char key[KDF_HASH_LEN])
{
	struct session *session = session_new();
	session->uid = config_read_encrypted_string("session_uid", key);
	session->sessionid = config_read_encrypted_string("session_sessionid", key);
	session->token = config_read_encrypted_string("session_token", key);
	session->private_key.len = config_read_encrypted_buffer("session_privatekey", &session->private_key.key, key);
	mlock(session->private_key.key, session->private_key.len);

	if (session_is_valid(session))
		return session;
	else {
		session_free(session);
		return NULL;
	}
}
Exemple #3
0
bool agent_get_decryption_key(unsigned char key[KDF_HASH_LEN])
{
	char *disable_str;

	if (config_exists("plaintext_key")) {
		_cleanup_free_ char *key_buffer = NULL;
		if (config_read_buffer("plaintext_key", &key_buffer) == KDF_HASH_LEN) {
			_cleanup_free_ char *verify = config_read_encrypted_string("verify", (unsigned char *)key_buffer);
			if (!verify || strcmp(verify, AGENT_VERIFICATION_STRING))
				goto badkey;
			memcpy(key, key_buffer, KDF_HASH_LEN);
			secure_clear(key_buffer, KDF_HASH_LEN);
			mlock(key, KDF_HASH_LEN);
			return true;
		}
		badkey: config_unlink("plaintext_key");
	}
	if (!agent_ask(key)) {
		if (!agent_load_key(key))
			return false;
		disable_str = getenv("LPASS_AGENT_DISABLE");
		if (!disable_str || strcmp(disable_str, "1")) {
			agent_start(key);
		}
	}
	mlock(key, KDF_HASH_LEN);
	return true;
}
Exemple #4
0
static char *upload_queue_next_entry(unsigned const char key[KDF_HASH_LEN], char **name, char **lock)
{
	unsigned long long smallest = ULLONG_MAX, current;
	_cleanup_free_ char *smallest_name = NULL;
	_cleanup_free_ char *base_path = config_path("upload-queue");
	_cleanup_free_ char *pidstr = NULL;
	pid_t pid;
	char *result, *p;
	DIR *dir = opendir(base_path);
	struct dirent *entry;

	if (!dir)
		return NULL;
	while ((entry = readdir(dir))) {
		if (entry->d_type != DT_REG)
			continue;
		for (p = entry->d_name; *p; ++p) {
			if (!isdigit(*p))
				break;
		}
		if (*p)
			continue;
		current = strtoull(entry->d_name, NULL, 10);
		if (!current)
			continue;
		if (current < smallest) {
			smallest = current;
			free(smallest_name);
			smallest_name = xstrdup(entry->d_name);
		}
	}
	closedir(dir);
	if (smallest == ULLONG_MAX)
		return NULL;

	xasprintf(name, "upload-queue/%s", smallest_name);
	xasprintf(lock, "%s.lock", *name);
	while (config_exists(*lock)) {
		free(pidstr);
		pidstr = config_read_encrypted_string(*lock, key);
		if (!pidstr) {
			config_unlink(*lock);
			break;
		}
		pid = strtoul(pidstr, NULL, 10);
		if (!pid) {
			config_unlink(*lock);
			break;
		}
		if (process_is_same_executable(pid))
			sleep(1);
		else {
			config_unlink(*lock);
			break;
		}
	}
	free(pidstr);
	pidstr = xultostr(getpid());
	config_write_encrypted_string(*lock, pidstr, key);
	result = config_read_encrypted_string(*name, key);
	if (!result) {
		/* could not decrypt: drop this file */
		upload_queue_drop(*name);
		config_unlink(*lock);
		return NULL;
	}
	return result;
}