Пример #1
0
void stats_connection_connect(struct stats_connection *conn,
			      struct mail_user *user)
{
	struct stats_user *suser = STATS_USER_CONTEXT(user);
	string_t *str = t_str_new(128);

	str_append(str, "CONNECT\t");
	/* required fields */
	str_append(str, guid_128_to_string(suser->session_guid));
	str_append_c(str, '\t');
	str_append_tabescaped(str, user->username);
	str_append_c(str, '\t');
	str_append_tabescaped(str, user->service);
	str_printfa(str, "\t%s", my_pid);

	/* optional fields */
	if (user->local_ip != NULL) {
		str_append(str, "\tlip=");
		str_append(str, net_ip2addr(user->local_ip));
	}
	if (user->remote_ip != NULL) {
		str_append(str, "\trip=");
		str_append(str, net_ip2addr(user->remote_ip));
	}
	str_append_c(str, '\n');
	stats_connection_send(conn, str);
}
Пример #2
0
static void
login_proxy_cmd_list_reply(struct ipc_cmd *cmd, string_t *str,
			   struct login_proxy *proxy)
{
	unsigned int i, alt_count = array_count(&global_alt_usernames);

	str_truncate(str, 0);
	str_append_tabescaped(str, proxy->client->virtual_user);
	str_append_c(str, '\t');
	i = 0;
	if (proxy->client->alt_usernames != NULL) {
		for (; proxy->client->alt_usernames[i] != NULL; i++) {
			str_append_tabescaped(str, proxy->client->alt_usernames[i]);
			str_append_c(str, '\t');
		}
		i_assert(i <= alt_count);
	}
	for (; i < alt_count; i++)
		str_append_c(str, '\t');

	str_printfa(str, "%s\t%s\t%s\t%u", login_binary->protocol,
		    net_ip2addr(&proxy->client->ip),
		    net_ip2addr(&proxy->ip), proxy->port);
	ipc_cmd_send(cmd, str_c(str));
}
Пример #3
0
void fd_debug_verify_leaks(int first_fd, int last_fd)
{
	struct ip_addr addr, raddr;
	in_port_t port, rport;
	struct stat st;
	int old_errno;

	for (; first_fd <= last_fd; first_fd++) {
		if (fcntl(first_fd, F_GETFD, 0) == -1 && errno == EBADF)
			continue;

		old_errno = errno;

		if (net_getsockname(first_fd, &addr, &port) == 0) {
			if (addr.family == AF_UNIX) {
				struct sockaddr_un sa;

				socklen_t socklen = sizeof(sa);

				if (getsockname(first_fd, (void *)&sa,
						&socklen) < 0)
					sa.sun_path[0] = '\0';

				i_panic("Leaked UNIX socket fd %d: %s",
					first_fd, sa.sun_path);
			}

			if (net_getpeername(first_fd, &raddr, &rport) < 0) {
				memset(&raddr, 0, sizeof(raddr));
				rport = 0;
			}
			i_panic("Leaked socket fd %d: %s:%u -> %s:%u",
				first_fd, net_ip2addr(&addr), port,
				net_ip2addr(&raddr), rport);
		}

		if (fstat(first_fd, &st) == 0) {
#ifdef __APPLE__
			/* OSX workaround: gettimeofday() calls shm_open()
			   internally and the fd won't get closed on exec.
			   We'll just skip all ino/dev=0 files and hope they
			   weren't anything else. */
			if (st.st_ino == 0 && st.st_dev == 0)
				continue;
#endif
#ifdef HAVE_SYS_SYSMACROS_H
			i_panic("Leaked file fd %d: dev %s.%s inode %s",
				first_fd, dec2str(major(st.st_dev)),
				dec2str(minor(st.st_dev)), dec2str(st.st_ino));
#else
			i_panic("Leaked file fd %d: dev %s inode %s",
				first_fd, dec2str(st.st_dev),
				dec2str(st.st_ino));
#endif
		}

		i_panic("Leaked unknown fd %d (errno = %s)",
			first_fd, strerror(old_errno));
	}
}
Пример #4
0
static int handle_ssl_error(struct ssl_proxy *proxy, int error)
{
	if (!gnutls_error_is_fatal(error)) {
		if (!verbose_ssl)
			return 0;

		if (error == GNUTLS_E_WARNING_ALERT_RECEIVED) {
			i_warning("Received SSL warning alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Non-fatal SSL error: %s: %s",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		}
		return 0;
	}

	if (verbose_ssl) {
		/* fatal error occurred */
		if (error == GNUTLS_E_FATAL_ALERT_RECEIVED) {
			i_warning("Received SSL fatal alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Error reading from SSL client: %s [%s]",
				  gnutls_strerror(error),
				  net_ip2addr(&proxy->ip));
		}
	}

        gnutls_alert_send_appropriate(proxy->session, error);
	ssl_proxy_destroy(proxy);
	return -1;
}
Пример #5
0
static void
proxy_log_connect_error(struct login_proxy *proxy)
{
	string_t *str = t_str_new(128);
	struct ip_addr local_ip;
	in_port_t local_port;

	str_printfa(str, "proxy(%s): ", proxy->client->virtual_user);
	if (!proxy->connected) {
		str_printfa(str, "connect(%s, %u) failed: %m",
			    proxy->host, proxy->port);
	} else {
		str_printfa(str, "Login for %s:%u timed out in state=%u",
			    proxy->host, proxy->port,
			    proxy->client->proxy_state);
	}
	str_printfa(str, " (after %u secs",
		    (unsigned int)(ioloop_time - proxy->created.tv_sec));
	if (proxy->reconnect_count > 0)
		str_printfa(str, ", %u reconnects", proxy->reconnect_count);

	if (proxy->server_fd != -1 &&
	    net_getsockname(proxy->server_fd, &local_ip, &local_port) == 0) {
		str_printfa(str, ", local=%s:%u",
			    net_ip2addr(&local_ip), local_port);
	} else if (proxy->source_ip.family != 0) {
		str_printfa(str, ", local=%s",
			    net_ip2addr(&proxy->source_ip));
	}

	str_append_c(str, ')');
	i_error("%s", str_c(str));
}
Пример #6
0
static const struct var_expand_table *
get_var_expand_table(struct client *client)
{
	struct var_expand_table *tab;

	tab = t_malloc(sizeof(login_var_expand_empty_tab));
	memcpy(tab, login_var_expand_empty_tab,
	       sizeof(login_var_expand_empty_tab));

	if (client->virtual_user != NULL)
		get_var_expand_users(tab, client->virtual_user);
	tab[3].value = login_binary->protocol;
	tab[4].value = getenv("HOME");
	tab[5].value = net_ip2addr(&client->local_ip);
	tab[6].value = net_ip2addr(&client->ip);
	tab[7].value = my_pid;
	tab[8].value = client->auth_mech_name == NULL ? NULL :
		str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
	tab[9].value = dec2str(client->local_port);
	tab[10].value = dec2str(client->remote_port);
	if (!client->tls) {
		tab[11].value = client->secured ? "secured" : NULL;
		tab[12].value = "";
	} else {
		const char *ssl_state =
			ssl_proxy_is_handshaked(client->ssl_proxy) ?
			"TLS" : "TLS handshaking";
		const char *ssl_error =
			ssl_proxy_get_last_error(client->ssl_proxy);

		tab[11].value = ssl_error == NULL ? ssl_state :
			t_strdup_printf("%s: %s", ssl_state, ssl_error);
		tab[12].value =
			ssl_proxy_get_security_string(client->ssl_proxy);
	}
	tab[13].value = client->mail_pid == 0 ? "" :
		dec2str(client->mail_pid);
	tab[14].value = client_get_session_id(client);
	tab[15].value = net_ip2addr(&client->real_local_ip);
	tab[16].value = net_ip2addr(&client->real_remote_ip);
	tab[17].value = dec2str(client->real_local_port);
	tab[18].value = dec2str(client->real_remote_port);
	if (client->virtual_user_orig != NULL)
		get_var_expand_users(tab+19, client->virtual_user_orig);
	else {
		tab[19].value = tab[0].value;
		tab[20].value = tab[1].value;
		tab[21].value = tab[2].value;
	}
	if (client->virtual_auth_user != NULL)
		get_var_expand_users(tab+22, client->virtual_auth_user);
	else {
		tab[22].value = tab[19].value;
		tab[23].value = tab[20].value;
		tab[24].value = tab[21].value;
	}
	tab[25].value = client->listener_name;
	return tab;
}
Пример #7
0
static void imap_hibernate_write_cmd(struct client *client, string_t *cmd,
				     const buffer_t *state, int fd_notify)
{
	struct stat peer_st;

	str_append_tabescaped(cmd, client->user->username);
	str_append_c(cmd, '\t');
	str_append_tabescaped(cmd, client->user->set->mail_log_prefix);
	str_printfa(cmd, "\tidle_notify_interval=%u",
		    client->set->imap_idle_notify_interval);
	if (fstat(client->fd_in, &peer_st) == 0) {
		str_printfa(cmd, "\tpeer_dev_major=%lu\tpeer_dev_minor=%lu\tpeer_ino=%llu",
			    (unsigned long)major(peer_st.st_dev),
			    (unsigned long)minor(peer_st.st_dev),
			    (unsigned long long)peer_st.st_ino);
	}

	if (client->session_id != NULL) {
		str_append(cmd, "\tsession=");
		str_append_tabescaped(cmd, client->session_id);
	}
	if (client->user->local_ip != NULL)
		str_printfa(cmd, "\tlip=%s", net_ip2addr(client->user->local_ip));
	if (client->user->remote_ip != NULL)
		str_printfa(cmd, "\trip=%s", net_ip2addr(client->user->remote_ip));
	if (client->userdb_fields != NULL) {
		string_t *userdb_fields = t_str_new(256);
		unsigned int i;

		for (i = 0; client->userdb_fields[i] != NULL; i++) {
			if (i > 0)
				str_append_c(userdb_fields, '\t');
			str_append_tabescaped(userdb_fields, client->userdb_fields[i]);
		}
		str_append(cmd, "\tuserdb_fields=");
		str_append_tabescaped(cmd, str_c(userdb_fields));
	}
	if (client->user->uid != (uid_t)-1)
		str_printfa(cmd, "\tuid=%s", dec2str(client->user->uid));
	if (client->user->gid != (gid_t)-1)
		str_printfa(cmd, "\tgid=%s", dec2str(client->user->gid));
	str_append(cmd, "\tstats=");
	str_append_tabescaped(cmd, client_stats(client));
	if (client->command_queue != NULL &&
	    strcasecmp(client->command_queue->name, "IDLE") == 0)
		str_append(cmd, "\tidle-cmd");
	if (fd_notify != -1)
		str_append(cmd, "\tnotify_fd");
	str_append(cmd, "\tstate=");
	base64_encode(state->data, state->used, cmd);
	str_append_c(cmd, '\n');
}
Пример #8
0
static const struct var_expand_table *
get_var_expand_table(struct master_service *service,
		     struct mail_storage_service_user *user,
		     const struct mail_storage_service_input *input,
		     const struct mail_storage_service_privileges *priv)
{
	static struct var_expand_table static_tab[] = {
		{ 'u', NULL, "user" },
		{ 'n', NULL, "username" },
		{ 'd', NULL, "domain" },
		{ 's', NULL, "service" },
		{ 'l', NULL, "lip" },
		{ 'r', NULL, "rip" },
		{ 'p', NULL, "pid" },
		{ 'i', NULL, "uid" },
		{ '\0', NULL, "gid" },
		{ '\0', NULL, "session" },
		{ '\0', NULL, "auth_user" },
		{ '\0', NULL, "auth_username" },
		{ '\0', NULL, "auth_domain" },
		{ '\0', NULL, NULL }
	};
	struct var_expand_table *tab;

	tab = t_malloc(sizeof(static_tab));
	memcpy(tab, static_tab, sizeof(static_tab));

	tab[0].value = input->username;
	tab[1].value = t_strcut(input->username, '@');
	tab[2].value = strchr(input->username, '@');
	if (tab[2].value != NULL) tab[2].value++;
	tab[3].value = service->name;
	tab[4].value = net_ip2addr(&input->local_ip);
	tab[5].value = net_ip2addr(&input->remote_ip);
	tab[6].value = my_pid;
	tab[7].value = priv == NULL ? NULL :
		dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
	tab[8].value = priv == NULL ? NULL :
		dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
	tab[9].value = input->session_id;
	if (user == NULL || user->auth_user == NULL) {
		tab[10].value = tab[0].value;
		tab[11].value = tab[1].value;
		tab[12].value = tab[2].value;
	} else {
		tab[10].value = user->auth_user;
		tab[11].value = t_strcut(user->auth_user, '@');
		tab[12].value = strchr(user->auth_user, '@');
	}
	return tab;
}
Пример #9
0
static void
login_host_callback(const struct ip_addr *ip, const char *errormsg,
		    void *context)
{
	struct login_host_request *request = context;
	struct director *dir = request->conn->dir;
	const char *line, *line_params;
	unsigned int secs;

	if (ip != NULL) {
		secs = dir->set->director_user_expire / 2;
		line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u",
				       request->line, net_ip2addr(ip), secs);
	} else {
		if (strncmp(request->line, "OK\t", 3) == 0)
			line_params = request->line + 3;
		else if (strncmp(request->line, "PASS\t", 5) == 0)
			line_params = request->line + 5;
		else
			i_panic("BUG: Unexpected line: %s", request->line);

		i_error("director: User %s host lookup failed: %s",
			request->username, errormsg);
		line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'),
				   "\ttemp", NULL);
	}
	login_connection_send_line(request->conn, line);

	login_connection_unref(&request->conn);
	i_free(request->username);
	i_free(request->line);
	i_free(request);
}
Пример #10
0
static void pop3c_client_connect_ip(struct pop3c_client *client)
{
	struct stat st;

	client->fd = net_connect_ip(&client->ip, client->set.port, NULL);
	if (client->fd == -1) {
		pop3c_client_disconnect(client);
		return;
	}

	client->input = client->raw_input =
		i_stream_create_fd(client->fd, POP3C_MAX_INBUF_SIZE, FALSE);
	client->output = client->raw_output =
		o_stream_create_fd(client->fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(client->output, TRUE);

	if (*client->set.rawlog_dir != '\0' &&
	    client->set.ssl_mode != POP3C_CLIENT_SSL_MODE_IMMEDIATE &&
	    stat(client->set.rawlog_dir, &st) == 0) {
		iostream_rawlog_create(client->set.rawlog_dir,
				       &client->input, &client->output);
	}
	client->io = io_add(client->fd, IO_WRITE,
			    pop3c_client_connected, client);
	client->to = timeout_add(POP3C_CONNECT_TIMEOUT_MSECS,
				 pop3c_client_timeout, client);
	if (client->set.debug) {
		i_debug("pop3c(%s): Connecting to %s:%u", client->set.host,
			net_ip2addr(&client->ip), client->set.port);
	}
}
Пример #11
0
void pop3_refresh_proctitle(void)
{
	struct client *client;
	string_t *title = t_str_new(128);

	if (!verbose_proctitle)
		return;

	str_append_c(title, '[');
	switch (pop3_client_count) {
	case 0:
		str_append(title, "idling");
		break;
	case 1:
		client = pop3_clients;
		str_append(title, client->user->username);
		if (client->user->remote_ip != NULL) {
			str_append_c(title, ' ');
			str_append(title, net_ip2addr(client->user->remote_ip));
		}
		break;
	default:
		str_printfa(title, "%u connections", pop3_client_count);
		break;
	}
	str_append_c(title, ']');
	process_title_set(str_c(title));
}
Пример #12
0
static bool lmtp_client_send_xclient(struct lmtp_client *client)
{
	string_t *str;
	unsigned int empty_len;

	if (client->xclient_args == NULL) {
		/* not supported */
		return FALSE;
	}
	if (client->xclient_sent)
		return FALSE;

	str = t_str_new(64);
	str_append(str, "XCLIENT");
	empty_len = str_len(str);
	if (client->set.source_ip.family != 0 &&
	    str_array_icase_find(client->xclient_args, "ADDR"))
		str_printfa(str, " ADDR=%s", net_ip2addr(&client->set.source_ip));
	if (client->set.source_port != 0 &&
	    str_array_icase_find(client->xclient_args, "PORT"))
		str_printfa(str, " PORT=%u", client->set.source_port);
	if (client->set.proxy_ttl != 0 &&
	    str_array_icase_find(client->xclient_args, "TTL"))
		str_printfa(str, " TTL=%u", client->set.proxy_ttl);
	if (client->set.proxy_timeout_secs != 0 &&
	    str_array_icase_find(client->xclient_args, "TIMEOUT"))
		str_printfa(str, " TIMEOUT=%u", client->set.proxy_timeout_secs);

	if (str_len(str) == empty_len)
		return FALSE;

	str_append(str, "\r\n");
	o_stream_nsend(client->output, str_data(str), str_len(str));
	return TRUE;
}
Пример #13
0
static void
master_service_haproxy_timeout(struct master_service_haproxy_conn *hpconn)
{
	i_error("haproxy: Client timed out (rip=%s)",
		net_ip2addr(&hpconn->conn.remote_ip));
	master_service_haproxy_conn_failure(hpconn);
}
Пример #14
0
static void proxy_write_id(struct imap_client *client, string_t *str)
{
	i_assert(client->common.proxy_ttl > 1);

	str_printfa(str, "I ID ("
		    "\"x-session-id\" \"%s\" "
		    "\"x-originating-ip\" \"%s\" "
		    "\"x-originating-port\" \"%u\" "
		    "\"x-connected-ip\" \"%s\" "
		    "\"x-connected-port\" \"%u\" "
		    "\"x-proxy-ttl\" \"%u\")\r\n",
		    client_get_session_id(&client->common),
		    net_ip2addr(&client->common.ip),
		    client->common.remote_port,
		    net_ip2addr(&client->common.local_ip),
		    client->common.local_port,
		    client->common.proxy_ttl - 1);
}
Пример #15
0
static void
login_host_callback(const struct ip_addr *ip, const char *hostname,
		    const char *errormsg, void *context)
{
	struct login_host_request *request = context;
	struct director *dir = request->conn->dir;
	const char *line, *line_params;
	unsigned int secs;

	if (ip == NULL) {
		if (strncmp(request->line, "OK\t", 3) == 0)
			line_params = request->line + 3;
		else if (strncmp(request->line, "PASS\t", 5) == 0)
			line_params = request->line + 5;
		else
			i_panic("BUG: Unexpected line: %s", request->line);

		i_error("director: User %s host lookup failed: %s",
			request->username, errormsg);
		line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'),
				   "\ttemp", NULL);
	} else if (request->director_proxy_maybe &&
		   login_host_request_is_self(request, ip)) {
		line = request->line;
	} else {
		string_t *str = t_str_new(64);

		secs = dir->set->director_user_expire / 2;
		str_printfa(str, "%s\tproxy_refresh=%u\t", request->line, secs);
		if (hostname == NULL || hostname[0] == '\0')
			str_printfa(str, "host=%s", net_ip2addr(ip));
		else {
			str_printfa(str, "host=%s\thostip=%s",
				    hostname, net_ip2addr(ip));
		}
		line = str_c(str);
	}
	login_connection_send_line(request->conn, line);

	login_connection_unref(&request->conn);
	i_free(request->username);
	i_free(request->line);
	i_free(request);
}
Пример #16
0
static void
vpopmail_verify_plain(struct auth_request *request, const char *password,
		      verify_plain_callback_t *callback)
{
	enum passdb_result result;
	const char *scheme, *tmp_pass;
	char *crypted_pass;
	bool cleartext = FALSE;
	int ret;

	crypted_pass = vpopmail_password_lookup(request, &cleartext, &result);
	if (crypted_pass == NULL) {
		callback(result, request);
		return;
	}
	tmp_pass = crypted_pass;

	if (cleartext)
		scheme = "CLEARTEXT";
	else {
		scheme = password_get_scheme(&tmp_pass);
		if (scheme == NULL)
			scheme = request->passdb->passdb->default_pass_scheme;
	}

	ret = auth_request_password_verify(request, password, tmp_pass,
					   scheme, AUTH_SUBSYS_DB);
	safe_memset(crypted_pass, 0, strlen(crypted_pass));

	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

#ifdef POP_AUTH_OPEN_RELAY
	if (strcasecmp(request->service, "POP3") == 0 ||
	    strcasecmp(request->service, "IMAP") == 0) {
		const char *host = net_ip2addr(&request->remote_ip);
		/* vpopmail 5.4 does not understand IPv6 */
		if (host[0] != '\0' && IPADDR_IS_V4(&request->remote_ip)) {
			/* use putenv() directly rather than env_put() which
			   would leak memory every time we got here. use a
			   static buffer for putenv() as SUSv2 requirements
			   would otherwise corrupt our environment later. */
			static char ip_env[256];

			i_snprintf(ip_env, sizeof(ip_env),
				   "TCPREMOTEIP=%s", host);
			putenv(ip_env);
			open_smtp_relay();
		}
	}
#endif

	callback(PASSDB_RESULT_OK, request);
}
Пример #17
0
static const char *client_remote_id(struct client *client)
{
	const char *addr = NULL;

	if (client->user->conn.remote_ip != NULL)
		addr = net_ip2addr(client->user->conn.remote_ip);
	if (addr == NULL)
		addr = "local";
	return addr;
}
Пример #18
0
void checkpassword_setup_env(struct auth_request *request)
{
	/* Besides passing the standard username and password in a
	   pipe, also pass some other possibly interesting information
	   via environment. Use UCSPI names for local/remote IPs. */
	env_put("PROTO=TCP"); /* UCSPI */
	env_put(t_strconcat("SERVICE=", request->service, NULL));
	if (request->local_ip.family != 0) {
		env_put(t_strconcat("TCPLOCALIP=",
				    net_ip2addr(&request->local_ip), NULL));
		/* FIXME: for backwards compatibility only,
		   remove some day */
		env_put(t_strconcat("LOCAL_IP=",
				    net_ip2addr(&request->local_ip), NULL));
	}
	if (request->remote_ip.family != 0) {
		env_put(t_strconcat("TCPREMOTEIP=",
				    net_ip2addr(&request->remote_ip), NULL));
		/* FIXME: for backwards compatibility only,
		   remove some day */
		env_put(t_strconcat("REMOTE_IP=",
				    net_ip2addr(&request->remote_ip), NULL));
	}
	if (request->local_port != 0) {
		env_put(t_strdup_printf("TCPLOCALPORT=%u",
					request->local_port));
	}
	if (request->remote_port != 0) {
		env_put(t_strdup_printf("TCPREMOTEPORT=%u",
					request->remote_port));
	}
	if (request->master_user != NULL) {
		env_put(t_strconcat("MASTER_USER=",
				    request->master_user, NULL));
	}
	if (request->extra_fields != NULL) {
		const char *fields =
			auth_stream_reply_export(request->extra_fields);

		/* extra fields could come from master db */
		env_put_extra_fields(fields);
	}
}
Пример #19
0
login_proxy_free_full(struct login_proxy **_proxy, const char *reason,
		      bool delayed)
{
	struct login_proxy *proxy = *_proxy;
	struct client *client = proxy->client;
	const char *ipstr;
	unsigned int delay_ms = 0;

	*_proxy = NULL;

	if (proxy->destroying)
		return;
	proxy->destroying = TRUE;

	/* we'll disconnect server side in any case. */
	login_proxy_disconnect(proxy);

	if (proxy->client_fd != -1) {
		/* detached proxy */
		DLLIST_REMOVE(&login_proxies, proxy);

		if (delayed)
			delay_ms = login_proxy_delay_disconnect(proxy);

		ipstr = net_ip2addr(&proxy->client->ip);
		client_log(proxy->client, t_strdup_printf(
			"proxy(%s): disconnecting %s%s%s",
			proxy->client->virtual_user,
			ipstr != NULL ? ipstr : "",
			reason == NULL ? "" : t_strdup_printf(" (%s)", reason),
			delay_ms == 0 ? "" : t_strdup_printf(" - disconnecting client in %ums", delay_ms)));

		if (proxy->client_io != NULL)
			io_remove(&proxy->client_io);
	} else {
		i_assert(proxy->client_io == NULL);
		i_assert(proxy->client_input == NULL);
		i_assert(proxy->client_output == NULL);
		i_assert(proxy->client_fd == -1);

		DLLIST_REMOVE(&login_proxies_pending, proxy);

		if (proxy->callback != NULL)
			proxy->callback(proxy->client);
	}
	if (delay_ms == 0)
		login_proxy_free_final(proxy);
	else {
		proxy->client_io = io_add_istream(proxy->client_input,
			proxy_client_disconnected_input, proxy);
	}

	client->login_proxy = NULL;
	client_unref(&client);
}
Пример #20
0
static int client_export_iter_session(struct client *client)
{
	struct client_export_cmd *cmd = client->cmd_export;
	struct mail_session *session = client->mail_session_iter;

	i_assert(cmd->level == MAIL_EXPORT_LEVEL_SESSION);
	mail_session_unref(&client->mail_session_iter);

	if (!cmd->header_sent) {
		o_stream_nsend_str(client->output,
			"session\tuser\tip\tservice\tpid\tconnected"
			"\tlast_update\tnum_cmds"
			MAIL_STATS_HEADER);
		cmd->header_sent = TRUE;
	}

	for (; session != NULL; session = session->stable_next) {
		if (client_is_busy(client))
			break;
		if (!mail_export_filter_match_session(&cmd->filter, session))
			continue;

		str_truncate(cmd->str, 0);
		T_BEGIN {
			str_append(cmd->str, guid_128_to_string(session->guid));
			str_append_c(cmd->str, '\t');
			str_append_tabescaped(cmd->str, session->user->name);
			str_append_c(cmd->str, '\t');
			if (session->ip != NULL) {
				str_append(cmd->str,
					   net_ip2addr(&session->ip->ip));
			}
			str_append_c(cmd->str, '\t');
			str_append_tabescaped(cmd->str, session->service);
		} T_END;
		str_printfa(cmd->str, "\t%ld", (long)session->pid);
		str_printfa(cmd->str, "\t%d", !session->disconnected);
		client_export_timeval(cmd->str, &session->last_update);
		str_printfa(cmd->str, "\t%u", session->num_cmds);
		client_export_mail_stats(cmd->str, &session->stats);
		str_append_c(cmd->str, '\n');
		o_stream_nsend(client->output, str_data(cmd->str),
			       str_len(cmd->str));
	}

	if (session != NULL) {
		client->mail_session_iter = session;
		mail_session_ref(session);
		return 0;
	}
	return 1;
}
Пример #21
0
struct client_connection *
client_connection_create(int fd, int listen_fd, bool ssl)
{
	struct client_connection *conn;
	const char *ip;
	pool_t pool;

	pool = pool_alloconly_create("doveadm client", 1024*16);
	conn = p_new(pool, struct client_connection, 1);
	conn->pool = pool;
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, client_connection_input, conn);
	conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(conn->output, TRUE);

	(void)net_getsockname(fd, &conn->local_ip, &conn->local_port);
	(void)net_getpeername(fd, &conn->remote_ip, &conn->remote_port);

	i_stream_set_name(conn->input, net_ip2addr(&conn->remote_ip));
	o_stream_set_name(conn->output, net_ip2addr(&conn->remote_ip));

	ip = net_ip2addr(&conn->remote_ip);
	if (ip[0] != '\0')
		i_set_failure_prefix("doveadm(%s): ", ip);

	if (client_connection_read_settings(conn) < 0) {
		client_connection_destroy(&conn);
		return NULL;
	}
	if (ssl) {
		if (client_connection_init_ssl(conn) < 0) {
			client_connection_destroy(&conn);
			return NULL;
		}
	}
	client_connection_send_auth_handshake(conn, listen_fd);
	return conn;
}
Пример #22
0
static void
config_build_request(struct master_service *service, string_t *str,
		     const struct master_service_settings_input *input)
{
	str_append(str, "REQ");
	if (input->module != NULL) {
		str_printfa(str, "\tmodule=%s", input->module);
		if (service->want_ssl_settings)
			str_append(str, "\tmodule=ssl");
	}
	if (input->service != NULL)
		str_printfa(str, "\tservice=%s", input->service);
	if (input->username != NULL)
		str_printfa(str, "\tuser=%s", input->username);
	if (input->local_ip.family != 0)
		str_printfa(str, "\tlip=%s", net_ip2addr(&input->local_ip));
	if (input->remote_ip.family != 0)
		str_printfa(str, "\trip=%s", net_ip2addr(&input->remote_ip));
	if (input->local_name != NULL)
		str_printfa(str, "\tlname=%s", input->local_name);
	str_append_c(str, '\n');
}
Пример #23
0
static void proxy_write_id(struct imap_client *client, string_t *str)
{
	i_assert(client->common.proxy_ttl > 1);

	str_append(str, "I ID (");
	if (client->common.client_id != NULL &&
	    str_len(client->common.client_id) > 0) {
		str_append_str(str, client->common.client_id);
		str_append_c(str, ' ');
	}
	str_printfa(str, "\"x-session-id\" \"%s\" "
		    "\"x-originating-ip\" \"%s\" "
		    "\"x-originating-port\" \"%u\" "
		    "\"x-connected-ip\" \"%s\" "
		    "\"x-connected-port\" \"%u\" "
		    "\"x-proxy-ttl\" \"%u\"",
		    client_get_session_id(&client->common),
		    net_ip2addr(&client->common.ip),
		    client->common.remote_port,
		    net_ip2addr(&client->common.local_ip),
		    client->common.local_port,
		    client->common.proxy_ttl - 1);

	/* append any forward_ variables to request */
	for(const char *const *ptr = client->common.auth_passdb_args; *ptr != NULL; ptr++) {
		if (strncasecmp(*ptr, "forward_", 8) == 0) {
			const char *key = t_strconcat("x-forward-",
						      t_strcut((*ptr)+8, '='),
						      NULL);
			const char *val = i_strchr_to_next(*ptr, '=');
			str_append_c(str, ' ');
			imap_append_string(str, key);
			str_append_c(str, ' ');
			imap_append_nstring(str, val);
		}
	}

	str_append(str, ")\r\n");
}
Пример #24
0
void uri_append_host_ip(string_t *out, const struct ip_addr *host_ip)
{
	const char *addr = net_ip2addr(host_ip);

	if (host_ip->family == AF_INET) {
		str_append(out, addr);
		return;
	}

	i_assert(host_ip->family == AF_INET6);
	str_append_c(out, '[');
	str_append(out, addr);
	str_append_c(out, ']');
}
Пример #25
0
static void memcached_conn_connected(struct connection *_conn, bool success)
{
	struct memcached_connection *conn =
		(struct memcached_connection *)_conn;

	if (!success) {
		i_error("memcached: connect(%s, %u) failed: %m",
			net_ip2addr(&conn->dict->ip), conn->dict->port);
	} else {
		conn->dict->connected = TRUE;
	}
	if (conn->dict->ioloop != NULL)
		io_loop_stop(conn->dict->ioloop);
}
Пример #26
0
static void login_access_callback(bool success, void *context)
{
	struct login_access_lookup *lookup = context;

	if (!success) {
		i_info("access(%s): Client refused (rip=%s)",
		       *lookup->next_socket,
		       net_ip2addr(&lookup->conn.remote_ip));
		login_access_lookup_free(lookup);
	} else {
		lookup->next_socket++;
		login_access_lookup_next(lookup);
	}
}
Пример #27
0
struct http_client_request *
http_client_request_connect_ip(struct http_client *client,
		    const struct ip_addr *ip, in_port_t port,
		    http_client_request_callback_t *callback,
				void *context)
{
	struct http_client_request *req;
	const char *hostname = net_ip2addr(ip);

	req = http_client_request_connect
		(client, hostname, port, callback, context);
	req->origin_url.host_ip = *ip;
	req->origin_url.have_host_ip = TRUE;
	return req;
}
Пример #28
0
static void client_input_error(struct login_access_lookup *lookup)
{
	char c;
	int ret;

	ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
	if (ret <= 0) {
		i_info("access(%s): Client disconnected during lookup (rip=%s)",
		       *lookup->next_socket,
		       net_ip2addr(&lookup->conn.remote_ip));
		login_access_lookup_free(lookup);
	} else {
		/* actual input. stop listening until lookup is done. */
		io_remove(&lookup->io);
	}
}
Пример #29
0
void connection_init_client_ip(struct connection_list *list,
			       struct connection *conn,
			       const struct ip_addr *ip, unsigned int port)
{
	i_assert(list->set.client);

	conn->fd_in = conn->fd_out = -1;
	conn->list = list;
	conn->name = i_strdup_printf("%s:%u", net_ip2addr(ip), port);

	conn->ip = *ip;
	conn->port = port;

	DLLIST_PREPEND(&list->connections, conn);
	list->connections_count++;
}
Пример #30
0
static void
penalty_print_line(struct penalty_context *ctx,
		   const struct penalty_line *line)
{
	const struct tm *tm;
	char buf[10];

	if (ctx->net_bits > 0) {
		if (!net_is_in_network(&line->ip, &ctx->net_ip, ctx->net_bits))
			return;
	}

	tm = localtime(&line->last_update);
	strftime(buf, sizeof(buf), "%H:%M:%S", tm);

	printf("%-16s %7u %s %s\n", net_ip2addr(&line->ip), line->penalty,
	       unixdate2str(line->last_penalty), buf);
}