コード例 #1
0
int auth_server_connection_connect(struct auth_server_connection *conn)
{
	const char *handshake;
	int fd;

	i_assert(conn->fd == -1);

	conn->last_connect = ioloop_time;
	if (conn->to != NULL)
		timeout_remove(&conn->to);

	/* max. 1 second wait here. */
	fd = net_connect_unix_with_retries(conn->client->auth_socket_path,
					   1000);
	if (fd == -1) {
		if (errno == EACCES) {
			i_error("auth: %s",
				eacces_error_get("connect",
					conn->client->auth_socket_path));
		} else {
			i_error("auth: connect(%s) failed: %m",
				conn->client->auth_socket_path);
		}
		return -1;
	}
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, auth_server_connection_input, conn);
	conn->input = i_stream_create_fd(fd, AUTH_SERVER_CONN_MAX_LINE_LENGTH,
					 FALSE);
	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);

	handshake = t_strdup_printf("VERSION\t%u\t%u\nCPID\t%u\n",
				    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
                                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
				    conn->client->client_pid);
	if (o_stream_send_str(conn->output, handshake) < 0) {
		i_warning("Error sending handshake to auth server: %m");
		auth_server_connection_disconnect(conn);
		return -1;
	}

	conn->to = timeout_add(AUTH_HANDSHAKE_TIMEOUT,
			       auth_client_handshake_timeout, conn);
	return 0;
}
コード例 #2
0
ファイル: lmtp-client.c プロジェクト: jkerihuel/dovecot
static int lmtp_client_connect(struct lmtp_client *client)
{
	client->fd = net_connect_ip(&client->ip, client->port, NULL);
	if (client->fd == -1) {
		i_error("lmtp client: connect(%s, %u) failed: %m",
			client->host, client->port);
		return -1;
	}
	client->input =
		i_stream_create_fd(client->fd, LMTP_MAX_LINE_LEN, FALSE);
	client->output = o_stream_create_fd(client->fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(client->output, TRUE);
	o_stream_set_flush_callback(client->output, lmtp_client_output, client);
	/* we're already sending data in ostream, so can't use IO_WRITE here */
	client->io = io_add(client->fd, IO_READ,
			    lmtp_client_wait_connect, client);
	return 0;
}
コード例 #3
0
ファイル: lmtp-client.c プロジェクト: bechtoldt/dovecot-core
static void lmtp_client_wait_connect(struct lmtp_client *client)
{
	int err;

	err = net_geterror(client->fd);
	if (err != 0) {
		i_error("lmtp client: connect(%s, %u) failed: %s",
			client->host, client->port, strerror(err));
		lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE
				 " (connect)");
		return;
	}
	if (client->to != NULL)
		timeout_remove(&client->to);
	io_remove(&client->io);
	client->io = io_add(client->fd, IO_READ, lmtp_client_input, client);
	lmtp_client_input(client);
}
コード例 #4
0
ファイル: login-proxy.c プロジェクト: bjacke/core
static int proxy_client_output(struct login_proxy *proxy)
{
	proxy->last_io = ioloop_time;
	if (o_stream_flush(proxy->client_output) < 0) {
		login_proxy_free_ostream(&proxy, proxy->client_output, FALSE);
		return 1;
	}

	if (proxy->server_io == NULL &&
	    o_stream_get_buffer_used_size(proxy->client_output) <
	    OUTBUF_THRESHOLD) {
		/* there's again space in client's output buffer, so we can
		   read more from proxy. */
		proxy->server_io =
			io_add(proxy->server_fd, IO_READ, server_input, proxy);
	}
	return 1;
}
コード例 #5
0
static void replicator_connection_connect(struct replicator_connection *conn)
{
	unsigned int n;
	int fd = -1;

	if (conn->fd != -1)
		return;

	if (conn->port == 0) {
		fd = net_connect_unix(conn->path);
		if (fd == -1)
			i_error("net_connect_unix(%s) failed: %m", conn->path);
	} else {
		for (n = 0; n < conn->ips_count; n++) {
			unsigned int idx = conn->ip_idx;

			conn->ip_idx = (conn->ip_idx + 1) % conn->ips_count;
			fd = net_connect_ip(&conn->ips[idx], conn->port, NULL);
			if (fd != -1)
				break;
			i_error("connect(%s, %u) failed: %m",
				net_ip2addr(&conn->ips[idx]), conn->port);
		}
	}

	if (fd == -1) {
		if (conn->to == NULL) {
			conn->to = timeout_add(REPLICATOR_RECONNECT_MSECS,
					       replicator_connection_connect,
					       conn);
		}
		return;
	}

	if (conn->to != NULL)
		timeout_remove(&conn->to);
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, replicator_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);
	o_stream_nsend_str(conn->output, REPLICATOR_HANDSHAKE);
	o_stream_set_flush_callback(conn->output, replicator_output, conn);
}
コード例 #6
0
void auth_client_connection_create(struct auth *auth, int fd,
				   bool login_requests, bool token_auth)
{
	static unsigned int connect_uid_counter = 0;
	struct auth_client_connection *conn;
	const char *mechanisms;
	string_t *str;

	conn = i_new(struct auth_client_connection, 1);
	conn->auth = auth;
	conn->refcount = 1;
	conn->connect_uid = ++connect_uid_counter;
	conn->login_requests = login_requests;
	conn->token_auth = token_auth;
	random_fill(conn->cookie, sizeof(conn->cookie));

	conn->fd = fd;
	conn->input = i_stream_create_fd(fd, AUTH_CLIENT_MAX_LINE_LENGTH);
	conn->output = o_stream_create_fd(fd, (size_t)-1);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_set_flush_callback(conn->output, auth_client_output, conn);
	conn->io = io_add(fd, IO_READ, auth_client_input, conn);

	DLLIST_PREPEND(&auth_client_connections, conn);

	if (token_auth) {
		mechanisms = t_strconcat("MECH\t",
			mech_dovecot_token.mech_name, "\n", NULL);
	} else {
		mechanisms = str_c(auth->reg->handshake);
	}

	str = t_str_new(128);
	str_printfa(str, "VERSION\t%u\t%u\n%sSPID\t%s\nCUID\t%u\nCOOKIE\t",
                    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
		    mechanisms, my_pid, conn->connect_uid);
	binary_to_hex_append(str, conn->cookie, sizeof(conn->cookie));
	str_append(str, "\nDONE\n");

	if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0)
		auth_client_disconnected(&conn);
}
コード例 #7
0
ファイル: auth-worker-client.c プロジェクト: aosm/dovecot
static void list_iter_deinit(struct auth_worker_list_context *ctx)
{
	struct auth_worker_client *client = ctx->client;
	string_t *str;

	i_assert(client->io == NULL);

	str = t_str_new(32);
	if (ctx->userdb->iface->iterate_deinit(ctx->iter) < 0)
		str_printfa(str, "%u\tFAIL\n", ctx->id);
	else
		str_printfa(str, "%u\tOK\n", ctx->id);
	auth_worker_send_reply(client, str);

	client->io = io_add(client->fd, IO_READ, auth_worker_input, client);
	o_stream_set_flush_callback(client->output, auth_worker_output, client);
	auth_worker_client_unref(&client);
	i_free(ctx);
}
コード例 #8
0
ファイル: auth-worker-client.c プロジェクト: aosm/dovecot
struct auth_worker_client *
auth_worker_client_create(struct auth *auth, int fd)
{
        struct auth_worker_client *client;

	client = i_new(struct auth_worker_client, 1);
	client->refcount = 1;

	client->auth = auth;
	client->fd = fd;
	client->input = i_stream_create_fd(fd, AUTH_WORKER_MAX_LINE_LENGTH,
					   FALSE);
	client->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
	o_stream_set_flush_callback(client->output, auth_worker_output, client);
	client->io = io_add(fd, IO_READ, auth_worker_input, client);

	auth_worker_client = client;
	return client;
}
コード例 #9
0
ファイル: io_socket.c プロジェクト: bronson/rzh
int io_socket_accept(io_atom *io, io_proc proc, int flags, io_atom *listener, socket_addr *remote)
{
    struct sockaddr_in pin;
    socklen_t plen;
	int err;

    plen = sizeof(pin);
    while((io->fd = accept(listener->fd, (struct sockaddr*)&pin, &plen)) < 0) {
        if(errno == EINTR) {
            // This call was interrupted by a signal.  Try again and
            // see if we receive a connection.
            continue;
        }
        if(errno == EAGAIN || errno == EWOULDBLOCK) {
            // No pending connections are present (socket is nonblocking).
            return -1;
        }

        // Probably there is a network error pending for this
        // connection (already!).  Should probably just ignore it...?
        return -1;
    }

    // Excellent.  We managed to connect to the remote socket.
    if(set_nonblock(io->fd) < 0) {
        close(io->fd);
        return -1;
    }

	io->proc = proc;
    err = io_add(io, flags);
    if(err < 0) {
        close(io->fd);
        return -1;
    }

    if(remote) {
        remote->addr = pin.sin_addr;
        remote->port = (int)ntohs(pin.sin_port);
    }

    return io->fd;
}
コード例 #10
0
static void
proxy_client_worker_msg_get_done(struct proxy_client_dsync_worker *worker)
{
    struct istream *input = worker->msg_get_data.input;

    i_assert(worker->io == NULL);

    if (input->eof)
        proxy_client_worker_msg_get_finish(worker);
    else {
        /* saving read the message only partially. we'll need to read
           the input until EOF or we'll start treating the input as
           commands. */
        worker->io = io_add(worker->fd_in, IO_READ,
                            proxy_client_worker_read_to_eof, worker);
        worker->msg_get_data.input =
            i_stream_create_dot(worker->input, FALSE);
    }
}
コード例 #11
0
int pop3c_client_cmd_stream(struct pop3c_client *client, const char *cmd,
			    struct istream **input_r, const char **error_r)
{
	struct istream *inputs[2];

	*input_r = NULL;

	/* read the +OK / -ERR */
	if (pop3c_client_cmd_line(client, cmd, error_r) < 0)
		return -1;
	/* read the stream */
	inputs[0] = i_stream_create_dot(client->input, TRUE);
	inputs[1] = NULL;
	client->dot_input =
		i_stream_create_seekable(inputs, POP3C_MAX_INBUF_SIZE,
					 seekable_fd_callback, client);
	i_stream_unref(&inputs[0]);

	i_assert(client->io == NULL);
	client->io = io_add(client->fd, IO_READ,
			    pop3c_client_dot_input, client);
	/* read any pending data from the stream */
	pop3c_client_dot_input(client);
	if (!client->dot_input->eof)
		pop3c_client_run(client);

	if (client->input == NULL) {
		i_assert(client->io == NULL);
		i_stream_destroy(&client->dot_input);
		*error_r = "Disconnected";
		return -1;
	}
	io_remove(&client->io);
	i_stream_seek(client->dot_input, 0);
	/* if this stream is used by some filter stream, make the filter
	   stream blocking */
	client->dot_input->blocking = TRUE;

	*input_r = client->dot_input;
	client->dot_input = NULL;
	return 0;
}
コード例 #12
0
static void print_connection_released(void)
{
	struct doveadm_server *server = printing_conn->server;
	struct server_connection *const *conns;
	unsigned int i, count;

	printing_conn = NULL;

	conns = array_get(&server->connections, &count);
	for (i = 0; i < count; i++) {
		if (conns[i]->io != NULL)
			continue;

		conns[i]->io = io_add(conns[i]->fd, IO_READ,
				      server_connection_input, conns[i]);
		server_connection_input(conns[i]);
		if (printing_conn != NULL)
			break;
	}
}
コード例 #13
0
static int
master_login_auth_connect(struct master_login_auth *auth)
{
	int fd;

	i_assert(auth->fd == -1);

	fd = net_connect_unix_with_retries(auth->auth_socket_path, 1000);
	if (fd == -1) {
		i_error("net_connect_unix(%s) failed: %m",
			auth->auth_socket_path);
		return -1;
	}
	auth->fd = fd;
	auth->input = i_stream_create_fd(fd, AUTH_MAX_INBUF_SIZE, FALSE);
	auth->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(auth->output, TRUE);
	auth->io = io_add(fd, IO_READ, master_login_auth_input, auth);
	return 0;
}
コード例 #14
0
ファイル: notify-connection.c プロジェクト: Raffprta/core
struct notify_connection *
notify_connection_create(int fd, struct replicator_queue *queue)
{
	struct notify_connection *conn;

	i_assert(fd >= 0);

	conn = i_new(struct notify_connection, 1);
	conn->refcount = 1;
	conn->queue = queue;
	conn->fd = fd;
	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);
	conn->io = io_add(fd, IO_READ, notify_connection_input, conn);
	conn->queue = queue;

	DLLIST_PREPEND(&connections, conn);
	return conn;
}
コード例 #15
0
struct login_connection *
login_connection_init(struct director *dir, int fd,
		      struct auth_connection *auth, bool userdb)
{
	struct login_connection *conn;

	conn = i_new(struct login_connection, 1);
	conn->refcount = 1;
	conn->fd = fd;
	conn->auth = auth;
	conn->dir = dir;
	conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(conn->output, TRUE);
	conn->io = io_add(conn->fd, IO_READ, login_connection_input, conn);
	conn->userdb = userdb;

	auth_connection_set_callback(conn->auth, auth_input_line, conn);
	DLLIST_PREPEND(&login_connections, conn);
	return conn;
}
コード例 #16
0
static void
user_callback(enum userdb_result result, struct auth_request *auth_request)
{
	struct auth_postfix_connection *conn = auth_request->context;
	string_t *str;
	const char *value;

	if (auth_request->userdb_lookup_tempfailed)
		result = USERDB_RESULT_INTERNAL_FAILURE;

	str = t_str_new(128);
	switch (result) {
	case USERDB_RESULT_INTERNAL_FAILURE:
		if (auth_request->userdb_lookup_tempfailed)
			value = auth_fields_find(auth_request->userdb_reply, "reason");
		else
			value = NULL;
		str_printfa(str, "400 %s",
			    value != NULL ? value: "Internal failure");
		break;
	case USERDB_RESULT_USER_UNKNOWN:
		str_append(str, "500 User not found");
		break;
	case USERDB_RESULT_OK:
		str_append(str, "200 1");
		break;
	}

	if (conn->auth->set->debug)
		i_debug("postfix out: %s", str_c(str));

	str_append_c(str, '\n');
	o_stream_nsend(conn->output, str_data(str), str_len(str));

	i_assert(conn->io == NULL);
	if (!conn->destroyed)
		conn->io = io_add(conn->fd, IO_READ, postfix_input, conn);

	auth_request_unref(&auth_request);
	auth_postfix_connection_unref(&conn);
}
コード例 #17
0
ファイル: pop3c-client.c プロジェクト: Distrotech/dovecot
static void pop3c_client_connected(struct pop3c_client *client)
{
	int err;

	err = net_geterror(client->fd);
	if (err != 0) {
		i_error("pop3c(%s): connect(%s, %u) failed: %s",
			client->set.host, net_ip2addr(&client->ip),
			client->set.port, strerror(err));
		pop3c_client_disconnect(client);
		return;
	}
	io_remove(&client->io);
	client->io = io_add(client->fd, IO_READ,
			    pop3c_client_prelogin_input, client);

	if (client->set.ssl_mode == POP3C_CLIENT_SSL_MODE_IMMEDIATE) {
		if (pop3c_client_ssl_init(client) < 0)
			pop3c_client_disconnect(client);
	}
}
コード例 #18
0
ファイル: client-connection.c プロジェクト: bsmr-dovecot/core
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;
}
コード例 #19
0
ファイル: login-proxy.c プロジェクト: bjacke/core
static int login_proxy_connect(struct login_proxy *proxy)
{
	struct login_proxy_record *rec = proxy->state_rec;

	if (rec->last_success.tv_sec == 0) {
		/* first connect to this IP. don't start immediately failing
		   the check below. */
		rec->last_success.tv_sec = ioloop_timeval.tv_sec - 1;
	}
	if (timeval_cmp(&rec->last_failure, &rec->last_success) > 0 &&
	    rec->last_failure.tv_sec - rec->last_success.tv_sec > PROXY_IMMEDIATE_FAILURE_SECS &&
	    rec->num_waiting_connections != 0) {
		/* the server is down. fail immediately */
		i_error("proxy(%s): Host %s:%u is down",
			proxy->client->virtual_user, proxy->host, proxy->port);
		login_proxy_free(&proxy);
		return -1;
	}

	proxy->server_fd = net_connect_ip(&proxy->ip, proxy->port,
					  proxy->source_ip.family == 0 ? NULL :
					  &proxy->source_ip);
	if (proxy->server_fd == -1) {
		proxy_log_connect_error(proxy);
		login_proxy_free(&proxy);
		return -1;
	}
	proxy->server_io = io_add(proxy->server_fd, IO_WRITE,
				  proxy_wait_connect, proxy);
	if (proxy->connect_timeout_msecs != 0) {
		proxy->to = timeout_add(proxy->connect_timeout_msecs,
					proxy_connect_timeout, proxy);
	}

	proxy->num_waiting_connections_updated = FALSE;
	proxy->state_rec = rec;
	proxy->state_rec->num_waiting_connections++;
	return 0;
}
コード例 #20
0
ファイル: fts-indexer.c プロジェクト: LTD-Beget/dovecot
static int fts_indexer_more_int(struct fts_indexer_context *ctx)
{
	struct ioloop *ioloop;
	struct io *io;
	struct timeout *to;
	int ret;

	if ((ret = fts_indexer_input(ctx)) != 0)
		return ret;

	/* wait for a while for the reply. FIXME: once search API supports
	   asynchronous waits, get rid of this wait and use the mail IO loop */
	ioloop = io_loop_create();
	io = io_add(ctx->fd, IO_READ, io_loop_stop, ioloop);
	to = timeout_add_short(INDEXER_WAIT_MSECS, io_loop_stop, ioloop);
	io_loop_run(ioloop);
	io_remove(&io);
	timeout_remove(&to);
	io_loop_destroy(&ioloop);

	return fts_indexer_input(ctx);
}
コード例 #21
0
ファイル: io_socket.c プロジェクト: bronson/rzh
int io_socket_connect(io_atom *io, io_proc proc, socket_addr remote, int flags)
{
	int err;

	io->fd = io_socket_connect_fd(remote);
	if(io->fd < 0) {
		return -1;
	}

	io->proc = proc;
    err = io_add(io, flags);
    if(err < 0) {
		goto bail;
    }

    return io->fd;

bail:
	close(io->fd);
	io->fd = -1;
	return -1;
}
コード例 #22
0
static
int ldap_connection_connect(struct ldap_connection *conn)
{
	const char *error;
	int fd;
	Sockbuf *sb;
	bool finished;

	if (conn->conn == NULL) {
		/* try to reconnect after disconnection */
		if (ldap_connection_setup(conn, &error) < 0)
			i_error("%s", error);
	}

	pool_t pool = pool_alloconly_create(MEMPOOL_GROWING "ldap bind", 128);
	struct ldap_op_queue_entry *req = p_new(pool, struct ldap_op_queue_entry, 1);
	req->pool = pool;

	req->internal_response_cb = ldap_connection_connect_parse;
	req->timeout_secs = conn->set.timeout_secs;

	if (ldap_connect_next_message(conn, req, &finished) != LDAP_SUCCESS ||
	    conn->conn == NULL) {
		pool_unref(&pool);
		return -1;
	}
	conn->pending++;
	aqueue_append(conn->request_queue, &req);
	/* start timeout */
	if (req->timeout_secs > 0)
		req->to_abort = timeout_add(req->timeout_secs * 1000, ldap_connection_abort_request, req);

	ldap_get_option(conn->conn, LDAP_OPT_SOCKBUF, &sb);
	ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &fd);
	conn->io = io_add(fd, IO_READ, ldap_connection_read_more, conn);
	if (conn->set.max_idle_time_secs > 0)
		conn->to_disconnect = timeout_add(conn->set.max_idle_time_secs * 1000, ldap_connection_kill, conn);
	return 0;
}
コード例 #23
0
ファイル: io_socket.c プロジェクト: bronson/rzh
int io_socket_listen(io_atom *io, io_proc proc, socket_addr local)
{
    struct sockaddr_in sin;

    if((io->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		return -1;
    }

    if(set_nonblock(io->fd) < 0) {
        close(io->fd);
		return -1;
    }

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr = local.addr;
    sin.sin_port = htons(local.port);

    if(bind(io->fd, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        close(io->fd);
		return -1;
    }

    // NOTE: if we're dropping connection requests under load, we
    // may need to tune the second parameter to listen.
    if (listen(io->fd, STD_LISTEN_SIZE) == -1) {
        close(io->fd);
		return -1;
    }

    io->proc = proc;
    if(io_add(io, IO_READ) < 0) {
        close(io->fd);
		return -1;
    }

	return io->fd;
}
コード例 #24
0
ファイル: ssl-proxy-gnutls.c プロジェクト: aosm/dovecot
static void ssl_output(struct ssl_proxy *proxy)
{
	int sent;

	sent = net_transmit(proxy->fd_plain,
			    proxy->outbuf_plain + proxy->outbuf_pos_plain,
			    proxy->send_left_plain);
	if (sent < 0) {
		/* disconnected */
		ssl_proxy_destroy(proxy);
		return;
	}

	proxy->send_left_plain -= sent;
	proxy->outbuf_pos_plain += sent;

	if (proxy->send_left_plain > 0)
		return;

	/* everything is sent, start reading again */
	io_remove(proxy->io_ssl);
	proxy->io_ssl = io_add(proxy->fd_ssl, IO_READ, ssl_input, proxy);
}
コード例 #25
0
ファイル: server-connection.c プロジェクト: rowhit/core-1
int server_connection_create(struct doveadm_server *server,
			     struct server_connection **conn_r)
{
#define DOVEADM_SERVER_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n"
	struct server_connection *conn;
	pool_t pool;

	pool = pool_alloconly_create("doveadm server connection", 1024*16);
	conn = p_new(pool, struct server_connection, 1);
	conn->pool = pool;
	conn->server = server;
	conn->fd = doveadm_connect_with_default_port(server->name,
						     doveadm_settings->doveadm_port);
	net_set_nonblock(conn->fd, TRUE);
	conn->io = io_add(conn->fd, IO_READ, server_connection_input, conn);
	conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE);
	conn->output = o_stream_create_fd(conn->fd, (size_t)-1);
	o_stream_set_flush_callback(conn->output, server_connection_output, conn);

	i_stream_set_name(conn->input, server->name);
	o_stream_set_name(conn->output, server->name);

	array_append(&conn->server->connections, &conn, 1);

	if (server_connection_read_settings(conn) < 0 ||
	    server_connection_init_ssl(conn) < 0) {
		server_connection_destroy(&conn);
		return -1;
	}

	o_stream_set_no_error_handling(conn->output, TRUE);
	conn->state = SERVER_REPLY_STATE_DONE;
	o_stream_nsend_str(conn->output, DOVEADM_SERVER_HANDSHAKE);

	*conn_r = conn;
	return 0;
}
コード例 #26
0
ファイル: access-lookup.c プロジェクト: Raffprta/core
struct access_lookup *
access_lookup(const char *path, int client_fd, const char *daemon_name,
	      access_lookup_callback_t *callback, void *context)
{
	struct access_lookup *lookup;
	const char *cmd;
	ssize_t ret;
	int fd;

	fd = net_connect_unix(path);
	if (fd == -1) {
		i_error("connect(%s) failed: %m", path);
		return NULL;
	}

	cmd = t_strconcat(daemon_name, "\n", NULL);
	ret = fd_send(fd, client_fd, cmd, strlen(cmd));
	if (ret != (ssize_t)strlen(cmd)) {
		if (ret < 0)
			i_error("fd_send(%s) failed: %m", path);
		else
			i_error("fd_send(%s) didn't write enough bytes", path);
		i_close_fd(&fd);
		return NULL;
	}

	lookup = i_new(struct access_lookup, 1);
	lookup->refcount = 1;
	lookup->fd = fd;
	lookup->path = i_strdup(path);
	lookup->io = io_add(fd, IO_READ, access_lookup_input, lookup);
	lookup->to = timeout_add(ACCESS_LOOKUP_TIMEOUT_MSECS,
				 access_lookup_timeout, lookup);
	lookup->callback = callback;
	lookup->context = context;
	return lookup;
}
コード例 #27
0
ファイル: imap-urlauth-worker.c プロジェクト: bdraco/dovecot
static struct client *client_create(int fd)
{
	struct client *client;

	/* always use nonblocking I/O */
	net_set_nonblock(fd, TRUE);

	client = i_new(struct client, 1);
	i_array_init(&client->access_apps, 16);
	client->fd_in = -1;
	client->fd_out = -1;
	client->fd_ctrl = fd;
	client->access_anonymous = TRUE; /* default until overridden */

	client->ctrl_io = io_add(fd, IO_READ, client_ctrl_input, client);
	client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS,
				      client_idle_timeout, client);

	imap_urlauth_worker_client_count++;
	DLLIST_PREPEND(&imap_urlauth_worker_clients, client);

	imap_urlauth_worker_refresh_proctitle();
	return client;
}
コード例 #28
0
ファイル: ssl-proxy-gnutls.c プロジェクト: aosm/dovecot
static void plain_input(struct ssl_proxy *proxy)
{
	char buf[1024];
	ssize_t rcvd, sent;

	rcvd = net_receive(proxy->fd_plain, buf, sizeof(buf));
	if (rcvd < 0) {
		/* disconnected */
		gnutls_bye(proxy->session, 1);
		ssl_proxy_destroy(proxy);
		return;
	}

	sent = proxy_send_ssl(proxy, buf, (size_t)rcvd);
	if (sent < 0 || sent == rcvd)
		return;

	/* everything wasn't sent - don't read anything until we've
	   sent it all */
	proxy->send_left_ssl = rcvd - sent;

	io_remove(proxy->io_plain);
	proxy->io_plain = io_add(proxy->fd_ssl, IO_WRITE, plain_output, proxy);
}
コード例 #29
0
ファイル: pop3c-client.c プロジェクト: Distrotech/dovecot
static int
pop3c_client_read_line(struct pop3c_client *client,
		       const char **line_r, const char **error_r)
{
	i_assert(client->io == NULL);
	i_assert(client->input_line == NULL);

	client->io = io_add(client->fd, IO_READ,
			    pop3c_client_input_reply, client);
	pop3c_client_input_reply(client);
	if (client->input_line == NULL && client->input != NULL)
		pop3c_client_run(client);

	if (client->input_line == NULL) {
		i_assert(client->io == NULL);
		*error_r = "Disconnected";
		return -1;
	}

	io_remove(&client->io);
	*line_r = t_strdup(client->input_line);
	client->input_line = NULL;
	return 0;
}
コード例 #30
0
static void
sasl_callback(struct client *client, enum sasl_server_reply sasl_reply,
	      const char *data, const char *const *args)
{
	struct client_auth_reply reply;

	i_assert(!client->destroyed ||
		 sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED ||
		 sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED);

	switch (sasl_reply) {
	case SASL_SERVER_REPLY_SUCCESS:
		if (client->to_auth_waiting != NULL)
			timeout_remove(&client->to_auth_waiting);
		if (args != NULL) {
			client_auth_parse_args(client, args, &reply);
			if (client_auth_handle_reply(client, &reply, TRUE))
				break;
		}
		client_auth_result(client, CLIENT_AUTH_RESULT_SUCCESS,
				   NULL, NULL);
		client_destroy_success(client, "Login");
		break;
	case SASL_SERVER_REPLY_AUTH_FAILED:
	case SASL_SERVER_REPLY_AUTH_ABORTED:
		if (client->to_auth_waiting != NULL)
			timeout_remove(&client->to_auth_waiting);
		if (args != NULL) {
			client_auth_parse_args(client, args, &reply);
			reply.nologin = TRUE;
			if (client_auth_handle_reply(client, &reply, FALSE))
				break;
		}

		if (sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
			client_auth_result(client, CLIENT_AUTH_RESULT_ABORTED,
				NULL, "Authentication aborted by client.");
		} else if (data == NULL) {
			client_auth_result(client,
				CLIENT_AUTH_RESULT_AUTHFAILED, NULL,
				AUTH_FAILED_MSG);
		} else {
			client_auth_result(client,
				CLIENT_AUTH_RESULT_AUTHFAILED_REASON, NULL,
				data);
		}

		if (!client->destroyed)
			client_auth_failed(client);
		break;
	case SASL_SERVER_REPLY_MASTER_FAILED:
		if (data != NULL) {
			/* authentication itself succeeded, we just hit some
			   internal failure. */
			client_auth_result(client, CLIENT_AUTH_RESULT_TEMPFAIL,
					   NULL, data);
		}

		/* the fd may still be hanging somewhere in kernel or another
		   process. make sure the client gets disconnected. */
		if (shutdown(client->fd, SHUT_RDWR) < 0 && errno != ENOTCONN)
			i_error("shutdown() failed: %m");

		if (data == NULL)
			client_destroy_internal_failure(client);
		else
			client_destroy_success(client, data);
		break;
	case SASL_SERVER_REPLY_CONTINUE:
		i_assert(client->v.auth_send_challenge != NULL);
		client->v.auth_send_challenge(client, data);

		if (client->to_auth_waiting != NULL)
			timeout_remove(&client->to_auth_waiting);

		if (client->auth_response != NULL)
			str_truncate(client->auth_response, 0);

		i_assert(client->io == NULL);
		client->auth_waiting = TRUE;
		client->io = io_add(client->fd, IO_READ,
				    client_auth_input, client);
		client_auth_input(client);
		return;
	}

	client_unref(&client);
}