Esempio n. 1
0
bool upload_queue_is_running(void)
{
	_cleanup_free_ char *pidstr = NULL;
	pid_t pid;

	pidstr = config_read_string("uploader.pid");
	if (!pidstr)
		return false;
	pid = strtoul(pidstr, NULL, 10);
	if (!pid)
		return false;
	return process_is_same_executable(pid);
}
Esempio n. 2
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;
}
Esempio n. 3
0
static void agent_run(unsigned const char key[KDF_HASH_LEN])
{
	_cleanup_free_ char *path;
	char *agent_timeout_str;
	unsigned int agent_timeout;
	struct sockaddr_un sa, listensa;
	struct ucred cred;
	int fd, listenfd;
	socklen_t len;

	signal(SIGHUP, agent_cleanup);
	signal(SIGINT, agent_cleanup);
	signal(SIGQUIT, agent_cleanup);
	signal(SIGTERM, agent_cleanup);
	signal(SIGALRM, agent_cleanup);
	agent_timeout_str = getenv("LPASS_AGENT_TIMEOUT");
	agent_timeout = 60 * 60; /* One hour by default. */
	if (agent_timeout_str && strlen(agent_timeout_str))
		agent_timeout = strtoul(agent_timeout_str, NULL, 10);
	if (agent_timeout)
		alarm(agent_timeout);

	path = agent_socket_path();
	if (strlen(path) >= sizeof(sa.sun_path))
		die("Path too large for agent control socket.");

	fd = socket(AF_UNIX, SOCK_STREAM, 0);

	memset(&sa, 0, sizeof(sa));
	sa.sun_family = AF_UNIX;
	strlcpy(sa.sun_path, path, sizeof(sa.sun_path));

	unlink(path);

	if (bind(fd, (struct sockaddr *)&sa, SUN_LEN(&sa)) < 0 || listen(fd, 16) < 0) {
		listenfd = errno;
		close(fd);
		unlink(path);
		errno = listenfd;
		die_errno("bind|listen");
	}

	for (len = sizeof(listensa); (listenfd = accept(fd, (struct sockaddr *)&listensa, &len)) > 0; len = sizeof(listensa)) {
		if (agent_socket_get_cred(listenfd, &cred) < 0) {
			close(listenfd);
			continue;
		}
		if (cred.uid != getuid() || cred.gid != getgid() || !process_is_same_executable(cred.pid)) {
			close(listenfd);
			continue;
		}

#if SOCKET_SEND_PID == 1
		pid_t pid = getpid();
		IGNORE_RESULT(write(listenfd, &pid, sizeof(pid)));
#endif
		IGNORE_RESULT(write(listenfd, key, KDF_HASH_LEN));
		close(listenfd);
	}

	listenfd = errno;
	close(fd);
	unlink(path);
	errno = listenfd;
	die_errno("accept");
}