struct login_connection * login_connection_init(struct director *dir, int fd, struct auth_connection *auth, enum login_connection_type type) { struct login_connection *conn; conn = i_new(struct login_connection, 1); conn->refcount = 1; conn->fd = fd; conn->dir = dir; conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); if (type != LOGIN_CONNECTION_TYPE_AUTHREPLY) { i_assert(auth != NULL); conn->auth = auth; conn->io = io_add(conn->fd, IO_READ, login_connection_input, conn); auth_connection_set_callback(conn->auth, auth_input_line, conn); } else { i_assert(auth == NULL); conn->input = i_stream_create_fd(conn->fd, IO_BLOCK_SIZE, FALSE); conn->io = io_add(conn->fd, IO_READ, login_connection_authreply_input, conn); o_stream_nsend_str(conn->output, t_strdup_printf( "VERSION\tdirector-authreply-server\t%d\t%d\n", AUTHREPLY_PROTOCOL_MAJOR_VERSION, AUTHREPLY_PROTOCOL_MINOR_VERSION)); } conn->type = type; DLLIST_PREPEND(&login_connections, conn); return conn; }
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); } }
void connection_init_from_streams(struct connection_list *list, struct connection *conn, const char *name, struct istream *input, struct ostream *output) { i_assert(name != NULL); conn->list = list; conn->name = i_strdup(name); conn->fd_in = i_stream_get_fd(input); conn->fd_out = o_stream_get_fd(output); i_assert(conn->fd_in >= 0); i_assert(conn->fd_out >= 0); i_assert(conn->io == NULL); i_assert(conn->input == NULL); i_assert(conn->output == NULL); i_assert(conn->to == NULL); conn->input = input; i_stream_ref(conn->input); i_stream_set_name(conn->input, conn->name); conn->output = output; o_stream_ref(conn->output); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_set_name(conn->output, conn->name); conn->io = io_add_istream(conn->input, *list->v.input, conn); DLLIST_PREPEND(&list->connections, conn); list->connections_count++; if (list->v.client_connected != NULL) list->v.client_connected(conn, TRUE); }
struct client_connection * client_connection_create(int fd, int listen_fd, bool ssl) { struct client_connection *conn; unsigned int port; 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, &port); (void)net_getpeername(fd, &conn->remote_ip, &port); 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; }
static int lmtp_client_connect(struct lmtp_client *client) { i_assert(client->fd == -1); client->times.connect_started = ioloop_timeval; 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); client->output = o_stream_create_fd(client->fd, (size_t)-1); 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); if (client->set.timeout_secs > 0) { client->to = timeout_add(client->set.timeout_secs*1000, lmtp_client_connect_timeout, client); } return 0; }
static void connection_init_streams(struct connection *conn) { const struct connection_settings *set = &conn->list->set; i_assert(conn->io == NULL); i_assert(conn->input == NULL); i_assert(conn->output == NULL); i_assert(conn->to == NULL); conn->version_received = set->major_version == 0; if (set->input_max_size != 0) { conn->input = i_stream_create_fd(conn->fd_in, set->input_max_size, FALSE); i_stream_set_name(conn->input, conn->name); } if (set->output_max_size != 0) { conn->output = o_stream_create_fd(conn->fd_out, set->output_max_size, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_set_name(conn->output, conn->name); } conn->io = io_add(conn->fd_in, IO_READ, *conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { conn->to = timeout_add(set->input_idle_timeout_secs*1000, connection_idle_timeout, conn); } if (set->major_version != 0 && !set->dont_send_version) { o_stream_nsend_str(conn->output, t_strdup_printf( "VERSION\t%s\t%u\t%u\n", set->service_name_out, set->major_version, set->minor_version)); } }
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, FALSE); conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); 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; }
static void proxy_plain_connected(struct login_proxy *proxy) { proxy->server_input = i_stream_create_fd(proxy->server_fd, MAX_PROXY_INPUT_SIZE); proxy->server_output = o_stream_create_fd(proxy->server_fd, (size_t)-1); o_stream_set_no_error_handling(proxy->server_output, TRUE); proxy->server_io = io_add(proxy->server_fd, IO_READ, proxy_prelogin_input, proxy); }
static struct dns_client *dns_client_create(int fd) { struct dns_client *client; client = i_new(struct dns_client, 1); client->fd = fd; client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE, FALSE); o_stream_set_no_error_handling(client->output, TRUE); client->io = io_add(fd, IO_READ, dns_client_input, client); return client; }
struct config_connection *config_connection_create(int fd) { struct config_connection *conn; conn = i_new(struct config_connection, 1); 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, config_connection_input, conn); DLLIST_PREPEND(&config_connections, conn); return conn; }
struct ostream *o_stream_create_null(void) { struct ostream_private *stream; struct ostream *output; stream = i_new(struct ostream_private, 1); stream->ostream.blocking = TRUE; stream->sendv = o_stream_null_sendv; output = o_stream_create(stream, NULL, -1); o_stream_set_no_error_handling(output, TRUE); o_stream_set_name(output, "(/dev/null)"); return output; }
static void client_open_streams(struct client *client) { client->input = i_stream_create_fd(client->fd, LOGIN_MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(client->fd, LOGIN_MAX_OUTBUF_SIZE, FALSE); o_stream_set_no_error_handling(client->output, TRUE); if (login_rawlog_dir != NULL) { if (iostream_rawlog_create(login_rawlog_dir, &client->input, &client->output) < 0) login_rawlog_dir = NULL; } }
void notify_connection_create(int fd, bool fifo) { struct notify_connection *conn; conn = i_new(struct notify_connection, 1); conn->refcount = 1; conn->fd = fd; conn->io = io_add(fd, IO_READ, notify_input, conn); conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); if (!fifo) { conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); } DLLIST_PREPEND(&conns, conn); }
int worker_connection_connect(struct worker_connection *conn) { i_assert(conn->fd == -1); conn->fd = net_connect_unix(conn->socket_path); if (conn->fd == -1) { i_error("connect(%s) failed: %m", conn->socket_path); return -1; } conn->io = io_add(conn->fd, IO_READ, worker_connection_input, conn); conn->input = i_stream_create_fd(conn->fd, (size_t)-1); conn->output = o_stream_create_fd(conn->fd, (size_t)-1); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_nsend_str(conn->output, INDEXER_MASTER_HANDSHAKE); return 0; }
struct auth_postfix_connection * auth_postfix_connection_create(struct auth *auth, int fd) { struct auth_postfix_connection *conn; conn = i_new(struct auth_postfix_connection, 1); conn->refcount = 1; conn->fd = fd; conn->auth = auth; 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, postfix_input, conn); DLLIST_PREPEND(&auth_postfix_connections, conn); return conn; }
struct client *client_create(int fd) { struct client *client; client = i_new(struct client, 1); client->fd = fd; client->io = io_add(fd, IO_READ, client_input, client); client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); client->output = o_stream_create_fd(fd, (size_t)-1, FALSE); o_stream_set_no_error_handling(client->output, TRUE); o_stream_set_flush_callback(client->output, client_output, client); client->cmd_pool = pool_alloconly_create("cmd pool", 1024); DLLIST_PREPEND(&clients, client); return client; }
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); }
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); }
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; }
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; }
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; }
static void cmd_zlibconnect(int argc ATTR_UNUSED, char *argv[]) { struct client client; struct ip_addr *ips; unsigned int ips_count; in_port_t port = 143; int fd, ret; if (argv[1] == NULL || (argv[2] != NULL && net_str2port(argv[2], &port) < 0)) help(&doveadm_cmd_zlibconnect); ret = net_gethostbyname(argv[1], &ips, &ips_count); if (ret != 0) { i_fatal("Host %s lookup failed: %s", argv[1], net_gethosterror(ret)); } if ((fd = net_connect_ip(&ips[0], port, NULL)) == -1) i_fatal("connect(%s, %u) failed: %m", argv[1], port); i_info("Connected to %s port %u. Ctrl-D starts compression", net_ip2addr(&ips[0]), port); memset(&client, 0, sizeof(client)); client.fd = fd; client.input = i_stream_create_fd(fd, (size_t)-1); client.output = o_stream_create_fd(fd, 0); o_stream_set_no_error_handling(client.output, TRUE); client.io_client = io_add(STDIN_FILENO, IO_READ, client_input, &client); client.io_server = io_add(fd, IO_READ, server_input, &client); master_service_run(master_service, NULL); io_remove(&client.io_client); io_remove(&client.io_server); i_stream_unref(&client.input); o_stream_unref(&client.output); if (close(fd) < 0) i_fatal("close() failed: %m"); }
static int openssl_iostream_create(struct ssl_iostream_context *ctx, const char *source, const struct ssl_iostream_settings *set, struct istream **input, struct ostream **output, struct ssl_iostream **iostream_r) { struct ssl_iostream *ssl_io; SSL *ssl; BIO *bio_int, *bio_ext; int ret; ssl = SSL_new(ctx->ssl_ctx); if (ssl == NULL) { i_error("SSL_new() failed: %s", openssl_iostream_error()); return -1; } /* BIO pairs use default buffer sizes (17 kB in OpenSSL 0.9.8e). Each of the BIOs have one "write buffer". BIO_write() copies data to them, while BIO_read() reads from the other BIO's write buffer into the given buffer. The bio_int is used by OpenSSL and bio_ext is used by this library. */ if (BIO_new_bio_pair(&bio_int, 0, &bio_ext, 0) != 1) { i_error("BIO_new_bio_pair() failed: %s", openssl_iostream_error()); SSL_free(ssl); return -1; } ssl_io = i_new(struct ssl_iostream, 1); ssl_io->refcount = 1; ssl_io->ctx = ctx; ssl_io->ssl = ssl; ssl_io->bio_ext = bio_ext; ssl_io->plain_input = *input; ssl_io->plain_output = *output; ssl_io->source = i_strdup(source); /* bio_int will be freed by SSL_free() */ SSL_set_bio(ssl_io->ssl, bio_int, bio_int); SSL_set_ex_data(ssl_io->ssl, dovecot_ssl_extdata_index, ssl_io); T_BEGIN { ret = openssl_iostream_set(ssl_io, set); } T_END; if (ret < 0) { openssl_iostream_free(ssl_io); return -1; } o_stream_uncork(ssl_io->plain_output); *input = openssl_i_stream_create_ssl(ssl_io); *output = openssl_o_stream_create_ssl(ssl_io); i_stream_set_name(*input, t_strconcat("SSL ", i_stream_get_name(ssl_io->plain_input), NULL)); o_stream_set_name(*output, t_strconcat("SSL ", o_stream_get_name(ssl_io->plain_output), NULL)); if (ssl_io->plain_output->real_stream->error_handling_disabled) o_stream_set_no_error_handling(*output, TRUE); ssl_io->ssl_output = *output; *iostream_r = ssl_io; return 0; }
struct client *client_create(int fd_in, int fd_out, const char *session_id, struct mail_user *user, struct mail_storage_service_user *service_user, const struct imap_settings *set) { const struct mail_storage_settings *mail_set; struct client *client; const char *ident; pool_t pool; bool explicit_capability = FALSE; /* always use nonblocking I/O */ net_set_nonblock(fd_in, TRUE); net_set_nonblock(fd_out, TRUE); pool = pool_alloconly_create("imap client", 2048); client = p_new(pool, struct client, 1); client->pool = pool; client->v = imap_client_vfuncs; client->set = set; client->service_user = service_user; client->session_id = p_strdup(pool, session_id); client->fd_in = fd_in; client->fd_out = fd_out; client->input = i_stream_create_fd(fd_in, set->imap_max_line_length, FALSE); client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE); o_stream_set_no_error_handling(client->output, TRUE); i_stream_set_name(client->input, "<imap client>"); o_stream_set_name(client->output, "<imap client>"); o_stream_set_flush_callback(client->output, client_output, client); p_array_init(&client->module_contexts, client->pool, 5); client->io = io_add_istream(client->input, client_input, client); client->last_input = ioloop_time; client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS, client_idle_timeout, client); client->command_pool = pool_alloconly_create(MEMPOOL_GROWING"client command", 1024*2); client->user = user; client->notify_count_changes = TRUE; client->notify_flag_changes = TRUE; mail_namespaces_set_storage_callbacks(user->namespaces, &mail_storage_callbacks, client); client->capability_string = str_new(client->pool, sizeof(CAPABILITY_STRING)+64); if (*set->imap_capability == '\0') str_append(client->capability_string, CAPABILITY_STRING); else if (*set->imap_capability != '+') { explicit_capability = TRUE; str_append(client->capability_string, set->imap_capability); } else { str_append(client->capability_string, CAPABILITY_STRING); str_append_c(client->capability_string, ' '); str_append(client->capability_string, set->imap_capability + 1); } if (user->fuzzy_search && !explicit_capability) { /* Enable FUZZY capability only when it actually has a chance of working */ str_append(client->capability_string, " SEARCH=FUZZY"); } mail_set = mail_user_set_get_storage_set(user); if (mail_set->mailbox_list_index && !explicit_capability) { /* NOTIFY is enabled only when mailbox list indexes are enabled, although even that doesn't necessarily guarantee it always */ str_append(client->capability_string, " NOTIFY"); } if (*set->imap_urlauth_host != '\0' && *mail_set->mail_attribute_dict != '\0') { /* Enable URLAUTH capability only when dict is configured correctly */ client_init_urlauth(client); if (!explicit_capability) str_append(client->capability_string, " URLAUTH URLAUTH=BINARY"); } if (set->imap_metadata && *mail_set->mail_attribute_dict != '\0') { client->imap_metadata_enabled = TRUE; if (!explicit_capability) str_append(client->capability_string, " METADATA"); } if (!explicit_capability && user_has_special_use_mailboxes(user)) { /* Advertise SPECIAL-USE only if there are actually some SPECIAL-USE flags in mailbox configuration. */ str_append(client->capability_string, " SPECIAL-USE"); } ident = mail_user_get_anvil_userip_ident(client->user); if (ident != NULL) { master_service_anvil_send(master_service, t_strconcat( "CONNECT\t", my_pid, "\timap/", ident, "\n", NULL)); client->anvil_sent = TRUE; } imap_client_count++; DLLIST_PREPEND(&imap_clients, client); if (hook_client_created != NULL) hook_client_created(&client); imap_refresh_proctitle(); return client; }