コード例 #1
0
ファイル: strescape.c プロジェクト: bdraco/core
const char *t_str_tabunescape(const char *str)
{
	if (strchr(str, '\001') == NULL)
		return str;
	else
		return str_tabunescape(t_strdup_noconst(str));
}
コード例 #2
0
static void stream_data(string_t *str, const unsigned char *data, size_t size)
{
	const char *text;

	str_truncate(str, 0);
	str_append_n(str, data, size);
	text = str_tabunescape(str_c_modifiable(str));
	doveadm_print_stream(text, strlen(text));
}
コード例 #3
0
static void server_flush_field(struct server_connection *conn, string_t *str,
			       const unsigned char *data, size_t size)
{
	if (conn->streaming) {
		conn->streaming = FALSE;
		if (size > 0)
			stream_data(str, data, size);
		doveadm_print_stream("", 0);
	} else {
		const char *text;

		str_truncate(str, 0);
		str_append_n(str, data, size);
		text = str_tabunescape(str_c_modifiable(str));
		doveadm_print(text);
	}
}
コード例 #4
0
ファイル: client-connection.c プロジェクト: bdraco/dovecot
static bool client_handle_command(struct client_connection *conn, char **args)
{
	struct mail_storage_service_input input;
	struct doveadm_mail_cmd_context *ctx;
	const char *flags, *cmd_name;
	unsigned int argc;

	memset(&input, 0, sizeof(input));
	input.service = "doveadm";

	for (argc = 0; args[argc] != NULL; argc++)
		args[argc] = str_tabunescape(args[argc]);

	if (argc < 3) {
		i_error("doveadm client: No command given");
		return FALSE;
	}
	flags = args[0];
	input.username = args[1];
	cmd_name = args[2];
	/* leave the command name as args[0] so getopt() works */
	args += 2;
	argc -= 2;

	doveadm_debug = FALSE;
	doveadm_verbose = FALSE;

	for (; *flags != '\0'; flags++) {
		switch (*flags) {
		case 'D':
			doveadm_debug = TRUE;
			doveadm_verbose = TRUE;
			break;
		case 'v':
			doveadm_verbose = TRUE;
			break;
		default:
			i_error("doveadm client: Unknown flag: %c", *flags);
			return FALSE;
		}
	}

	if (!client_is_allowed_command(conn->set, cmd_name)) {
		i_error("doveadm client isn't allowed to use command: %s",
			cmd_name);
		return FALSE;
	}

	/* make sure client_connection_input() isn't called by the ioloop that
	   is going to be run by doveadm_mail_cmd_server_run() */
	io_remove(&conn->io);

	o_stream_cork(conn->output);
	ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args);
	if (ctx == NULL)
		o_stream_nsend(conn->output, "\n-\n", 3);
	else
		doveadm_mail_cmd_server_run(conn, ctx, &input);
	o_stream_uncork(conn->output);

	/* flush the output and disconnect */
	net_set_nonblock(conn->fd, FALSE);
	(void)o_stream_flush(conn->output);
	net_set_nonblock(conn->fd, TRUE);

	conn->io = io_add(conn->fd, IO_READ, client_connection_input, conn);
	return TRUE;
}
コード例 #5
0
ファイル: script-login.c プロジェクト: Raffprta/core
static void client_connected(struct master_service_connection *conn)
{
	enum mail_storage_service_flags flags =
		MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS;
	string_t *instr, *keys;
	const char **args, *key, *value, *error, *version_line, *data_line;
	struct mail_storage_service_ctx *service_ctx;
	struct mail_storage_service_input input;
	struct mail_storage_service_user *user;
	char buf[1024];
	unsigned int i, socket_count;
	int fd = -1;
	ssize_t ret;

	alarm(SCRIPT_LOGIN_READ_TIMEOUT_SECS);

	net_set_nonblock(conn->fd, FALSE);
	instr = t_str_new(1024);
	ret = fd_read(conn->fd, buf, sizeof(buf), &fd);
	while (ret > 0) {
		str_append_n(instr, buf, ret);
		if (buf[ret-1] == '\n' &&
		    strchr(str_c(instr), '\n')[1] != '\0') {
			str_truncate(instr, str_len(instr)-1);
			break;
		}

		ret = read(conn->fd, buf, sizeof(buf));
	}

	version_line = str_c(instr);
	data_line = strchr(version_line, '\n');
	if (data_line != NULL)
		version_line = t_strdup_until(version_line, data_line++);
	else
		version_line = NULL;

	if (ret > 0 || version_line != NULL) {
		if (version_line == NULL ||
		    !version_string_verify(version_line, "script-login",
				SCRIPT_LOGIN_PROTOCOL_VERSION_MAJOR)) {
			i_fatal("Client not compatible with this binary "
				"(connecting to wrong socket?)");
		}
	}

	if (ret <= 0) {
		if (ret < 0)
			i_fatal("read() failed: %m");
		else
			i_fatal("read() failed: disconnected");
	}
	if (fd == -1)
		i_fatal("client fd not received");

	alarm(0);

	/* put everything to environment */
	env_clean();
	keys = t_str_new(256);
	args = t_strsplit_tab(data_line);

	if (str_array_length(args) < 3)
		i_fatal("Missing input fields");

	i = 0;
	memset(&input, 0, sizeof(input));
	input.module = "mail"; /* need to get mail_uid, mail_gid */
	input.service = "script-login";
	(void)net_addr2ip(args[i++], &input.local_ip);
	(void)net_addr2ip(args[i++], &input.remote_ip);
	input.username = args[i++];
	input.userdb_fields = args + i;

	env_put(t_strconcat("LOCAL_IP=", net_ip2addr(&input.local_ip), NULL));
	env_put(t_strconcat("IP=", net_ip2addr(&input.remote_ip), NULL));
	env_put(t_strconcat("USER="******"%s ", key);
		}
	}
	env_put(t_strconcat(ENV_USERDB_KEYS"=", str_c(keys), NULL));

	master_service_init_log(master_service,
		t_strdup_printf("script-login(%s): ", input.username));

	if (drop_to_userdb_privileges) {
		service_ctx = mail_storage_service_init(master_service, NULL, flags);
		if (mail_storage_service_lookup(service_ctx, &input, &user, &error) <= 0)
			i_fatal("%s", error);
		mail_storage_service_restrict_setenv(service_ctx, user);
		/* we can't exec anything in a chroot */
		env_remove("RESTRICT_CHROOT");
		restrict_access_by_env(getenv("HOME"), TRUE);
	}

	if (dup2(fd, STDIN_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (dup2(fd, STDOUT_FILENO) < 0)
		i_fatal("dup2() failed: %m");
	if (close(fd) < 0)
		i_fatal("close() failed: %m");
	if (conn->fd != SCRIPT_COMM_FD) {
		if (dup2(conn->fd, SCRIPT_COMM_FD) < 0)
			i_fatal("dup2() failed: %m");
		if (close(conn->fd) < 0)
			i_fatal("close() failed: %m");
	}

	/* close all listener sockets */
	socket_count = master_service_get_socket_count(master_service);
	for (i = 0; i < socket_count; i++) {
		if (close(MASTER_LISTEN_FD_FIRST + i) < 0)
			i_error("close(listener) failed: %m");
	}
	if (close(MASTER_STATUS_FD) < 0)
		i_error("close(status) failed: %m");

	execvp_const(exec_args[0], exec_args);
}
コード例 #6
0
ファイル: client-connection.c プロジェクト: bsmr-dovecot/core
static bool client_handle_command(struct client_connection *conn, char **args)
{
	struct mail_storage_service_input input;
	const char *flags, *cmd_name;
	unsigned int argc;

	memset(&input, 0, sizeof(input));
	input.service = "doveadm";
	input.local_ip = conn->local_ip;
	input.remote_ip = conn->remote_ip;
	input.local_port = conn->local_port;
	input.remote_port = conn->remote_port;

	for (argc = 0; args[argc] != NULL; argc++)
		args[argc] = str_tabunescape(args[argc]);

	if (argc < 3) {
		i_error("doveadm client: No command given");
		return FALSE;
	}
	flags = args[0];
	input.username = args[1];
	cmd_name = args[2];
	/* leave the command name as args[0] so getopt() works */
	args += 2;
	argc -= 2;

	doveadm_debug = FALSE;
	doveadm_verbose = FALSE;

	for (; *flags != '\0'; flags++) {
		switch (*flags) {
		case 'D':
			doveadm_debug = TRUE;
			doveadm_verbose = TRUE;
			break;
		case 'v':
			doveadm_verbose = TRUE;
			break;
		default:
			i_error("doveadm client: Unknown flag: %c", *flags);
			return FALSE;
		}
	}

	if (!client_is_allowed_command(conn->set, cmd_name)) {
		i_error("doveadm client isn't allowed to use command: %s",
			cmd_name);
		return FALSE;
	}

	o_stream_cork(conn->output);
	if (doveadm_cmd_handle(conn, cmd_name, &input, argc, args) < 0)
		o_stream_nsend(conn->output, "\n-\n", 3);
	o_stream_uncork(conn->output);

	/* flush the output and disconnect */
	net_set_nonblock(conn->fd, FALSE);
	(void)o_stream_flush(conn->output);
	net_set_nonblock(conn->fd, TRUE);
	return TRUE;
}
コード例 #7
0
ファイル: test-strescape.c プロジェクト: via/dovecot-clouddb
void test_strescape(void)
{
	static struct strinput unesc[] = {
		{ "foo", "foo" },
		{ "\\\\\\\\\\\"\\\"\\\'\\\'", "\\\\\"\"\'\'" },
		{ "\\a\\n\\r\\", "anr" }
	};
	static struct strinput tabesc[] = {
		{ "foo", "foo" },
		{ "\001", "\0011" },
		{ "\t", "\001t" },
		{ "\r", "\001r" },
		{ "\n", "\001n" },
		{ "\001\001\t\t\r\r\n\n", "\0011\0011\001t\001t\001r\001r\001n\001n" }
	};
	unsigned char buf[1 << CHAR_BIT];
	const char *escaped, *tabstr;
	string_t *str;
	unsigned int i;

	test_begin("str_escape");
	for (i = 1; i < sizeof(buf); i++)
		buf[i-1] = i;
	buf[i-1] = '\0';

	escaped = str_escape((char *)buf);
	test_assert(strlen(escaped) == (1 << CHAR_BIT) - 1 + 3);
	test_assert(escaped['\"'-1] == '\\'); /* 34 */
	test_assert(escaped['\"'] == '\"');
	test_assert(escaped['\''+1-1] == '\\'); /* 39 */
	test_assert(escaped['\''+1] == '\'');
	test_assert(escaped['\\'+2-1] == '\\'); /* 92 */
	test_assert(escaped['\\'+2] == '\\');
	test_assert(strcmp(str_escape("\\\\\"\"\'\'"),
			   "\\\\\\\\\\\"\\\"\\\'\\\'") == 0);
	test_end();

	str = t_str_new(256);
	test_begin("str_unescape");
	for (i = 0; i < N_ELEMENTS(unesc); i++) {
		test_assert(strcmp(str_unescape(t_strdup_noconst(unesc[i].input)),
				   unesc[i].output) == 0);
		str_truncate(str, 0);
		str_append_unescaped(str, unesc[i].input, strlen(unesc[i].input));
		test_assert(strcmp(str_c(str), unesc[i].output) == 0);
	}
	test_end();

	test_begin("str_tabescape");
	for (i = 0; i < N_ELEMENTS(tabesc); i++) {
		test_assert(strcmp(str_tabunescape(t_strdup_noconst(tabesc[i].output)),
				   tabesc[i].input) == 0);
		test_assert(strcmp(str_tabescape(tabesc[i].input),
				   tabesc[i].output) == 0);
		str_truncate(str, 0);
		str_append_tabunescaped(str, tabesc[i].output, strlen(tabesc[i].output));
		test_assert(strcmp(str_c(str), tabesc[i].input) == 0);
	}
	str_truncate(str, 0);
	tabstr = "\0012\001l\001";
	str_append_tabunescaped(str, tabstr, strlen(tabstr));
	test_assert(strcmp(str_c(str), "2l") == 0);
	test_assert(strcmp(str_c(str), str_tabunescape(t_strdup_noconst(tabstr))) == 0);
	test_end();
}