Exemplo n.º 1
0
static void list_iter_callback(const char *user, void *context)
{
	struct auth_worker_list_context *ctx = context;
	string_t *str;

	if (user == NULL) {
		if (ctx->sending)
			ctx->done = TRUE;
		else
			list_iter_deinit(ctx);
		return;
	}

	T_BEGIN {
		str = t_str_new(128);
		str_printfa(str, "%u\t*\t%s\n", ctx->id, user);
		o_stream_send(ctx->client->output, str_data(str), str_len(str));
	} T_END;

	if (ctx->sending) {
		/* avoid recursively looping to this same function */
		ctx->sent = TRUE;
		return;
	}

	do {
		ctx->sending = TRUE;
		ctx->sent = FALSE;
		ctx->userdb->iface->iterate_next(ctx->iter);
	} while (ctx->sent &&
		 o_stream_get_buffer_used_size(ctx->client->output) == 0);
	ctx->sending = FALSE;
	if (ctx->done)
		list_iter_deinit(ctx);
}
Exemplo n.º 2
0
static void program_client_program_input(struct program_client *pclient)
{
	struct istream *input = pclient->program_input;
	struct ostream *output = pclient->output;
	const unsigned char *data;
	size_t size;
	int ret = 0;

	if ( input != NULL ) {
		while ( (ret=i_stream_read_data(input, &data, &size, 0)) > 0 ) {
			if ( output != NULL ) {
				ssize_t sent;

				if ( (sent=o_stream_send(output, data, size)) < 0 ) {
					program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
					return;
				}
				size = (size_t)sent;
			}

			i_stream_skip(input, size);
		}

		if ( ret < 0 ) {
			if ( i_stream_is_eof(input) ) {
				if ( !program_client_input_pending(pclient) )
					program_client_disconnect(pclient, FALSE);
				return;
			}
			program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
		}
	}
}
static bool
replicator_send_buf(struct replicator_connection *conn, buffer_t *buf)
{
	const unsigned char *data = buf->data;
	unsigned int len = IO_BLOCK_SIZE;

	/* try to send about IO_BLOCK_SIZE amount of data,
	   but only full lines */
	if (len > buf->used)
		len = buf->used;
	for (;; len++) {
		i_assert(len < buf->used); /* there is always LF */
		if (data[len] == '\n') {
			len++;
			break;
		}
	}

	if (o_stream_send(conn->output, data, len) < 0) {
		replicator_connection_disconnect(conn);
		return FALSE;
	}
	buffer_delete(buf, 0, len);
	return TRUE;
}
Exemplo n.º 4
0
static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail,
			     struct imap_fetch_body_data *body)
{
	string_t *str;
	uoff_t size;

	if (mail == NULL) {
		imap_msgpart_free(&body->msgpart);
		return 1;
	}

	if (imap_msgpart_size(mail, body->msgpart, &size) < 0)
		return -1;

	str = t_str_new(128);
	if (ctx->state.cur_first)
		ctx->state.cur_first = FALSE;
	else
		str_append_c(str, ' ');
	str_printfa(str, "%s %"PRIuUOFF_T, get_body_name(body), size);

	if (o_stream_send(ctx->client->output, str_data(str), str_len(str)) < 0)
		return -1;
	return 1;
}
Exemplo n.º 5
0
static void test_ostream_dot_one(const struct dot_test *test)
{
	struct istream *test_input;
	struct ostream *output, *test_output;
	buffer_t *output_data;
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	test_input = test_istream_create(test->input);
	output_data = buffer_create_dynamic(pool_datastack_create(), 1024);
	test_output = o_stream_create_buffer(output_data);

	output = o_stream_create_dot(test_output, FALSE);

	while ((ret = i_stream_read(test_input)) > 0 || ret == -2) {
		data = i_stream_get_data(test_input, &size);
		ret = o_stream_send(output, data, size);
		test_assert(ret >= 0);
		if (ret <= 0)
			break;
		i_stream_skip(test_input, ret);
	}

	test_assert(test_input->eof);

	test_assert(o_stream_flush(output) > 0);
	o_stream_unref(&output);
	o_stream_unref(&test_output);

	test_assert(strcmp(str_c(output_data), test->output) == 0);

	i_stream_unref(&test_input);
}
Exemplo n.º 6
0
static int program_client_program_output(struct program_client *pclient)
{
	struct istream *input = pclient->input;
	struct ostream *output = pclient->program_output;
	const unsigned char *data;
	size_t size;
	int ret = 0;

	if ((ret = o_stream_flush(output)) <= 0) {
		if (ret < 0)
			program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
		return ret;
	}

	if ( input != NULL && output != NULL ) {
		do {
			while ( (data=i_stream_get_data(input, &size)) != NULL ) {
				ssize_t sent;
	
				if ( (sent=o_stream_send(output, data, size)) < 0 ) {
					program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
					return -1;
				}
	
				if ( sent == 0 )
					return 0;
				i_stream_skip(input, sent);
			}
		} while ( (ret=i_stream_read(input)) > 0 );

		if ( ret == 0 )
			return 1;

		if ( ret < 0 ) {
			if ( !input->eof ) {
				program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
				return -1;
			} else if ( !i_stream_have_bytes_left(input) ) {
				i_stream_unref(&pclient->input);
				input = NULL;

				if ( (ret = o_stream_flush(output)) <= 0 ) {
					if ( ret < 0 )
						program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
					return ret;
				}
			} 
		}
	}

	if ( input == NULL ) {
		if ( !program_client_input_pending(pclient) ) {
			program_client_disconnect(pclient, FALSE);
		} else if (program_client_close_output(pclient) < 0) {
			program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
		}
	}
	return 1;
}
Exemplo n.º 7
0
static void test_iostream_temp_create_sized_disk(void)
{
	struct ostream *output;

	test_begin("iostream_temp_create_sized() disk");
	output = iostream_temp_create_sized(".", 0, "test", 4);
	test_assert(o_stream_send(output, "123", 3) == 3);
	test_assert(output->offset == 3);
	test_assert(o_stream_send(output, "4", 1) == 1);
	test_assert(output->offset == 4);
	test_assert(o_stream_get_fd(output) == -1);
	test_assert(o_stream_send(output, "5", 1) == 1);
	test_assert(output->offset == 5);
	test_assert(o_stream_get_fd(output) != -1);
	o_stream_destroy(&output);
	test_end();
}
Exemplo n.º 8
0
static void
config_request_output(const char *key, const char *value,
		      enum config_key_type type ATTR_UNUSED, void *context)
{
	struct ostream *output = context;
	const char *p;

	o_stream_send_str(output, key);
	o_stream_send_str(output, "=");
	while ((p = strchr(value, '\n')) != NULL) {
		o_stream_send(output, value, p-value);
		o_stream_send(output, SETTING_STREAM_LF_CHAR, 1);
		value = p+1;
	}
	o_stream_send_str(output, value);
	o_stream_send_str(output, "\n");
}
Exemplo n.º 9
0
static int mbox_append_lf(struct mbox_save_context *ctx)
{
	if (o_stream_send(ctx->output, "\n", 1) < 0) {
		write_error(ctx);
		return -1;
	}

	return 0;
}
Exemplo n.º 10
0
static void
http_transfer_chunked_ostream_close(struct iostream_private *stream,
				    bool close_parent)
{
	struct http_transfer_chunked_ostream *tcstream =
		(struct http_transfer_chunked_ostream *)stream;

	(void)o_stream_send(tcstream->ostream.parent, "0\r\n\r\n", 5);
	(void)o_stream_flush(&tcstream->ostream.ostream);
	if (close_parent)
		o_stream_close(tcstream->ostream.parent);
}
Exemplo n.º 11
0
static void test_iostream_temp_create_sized_memory(void)
{
	struct ostream *output;

	test_begin("iostream_temp_create_sized() memory");
	output = iostream_temp_create_sized(".intentional-nonexistent-error/", 0, "test", 4);
	test_assert(o_stream_send(output, "123", 3) == 3);
	test_assert(output->offset == 3);
	test_assert(o_stream_send(output, "4", 1) == 1);
	test_assert(output->offset == 4);
	test_assert(o_stream_get_fd(output) == -1);

	/* now we'll try to switch to writing to a file, but it'll fail */
	test_expect_error_string("safe_mkstemp");
	test_assert(o_stream_send(output, "5", 1) == 1);
	test_expect_no_more_errors();

	test_assert(o_stream_get_fd(output) == -1);
	o_stream_destroy(&output);
	test_end();
}
Exemplo n.º 12
0
static int o_stream_zlib_lsb_uint32(struct ostream *output, uint32_t num)
{
	unsigned char buf[sizeof(uint32_t)];
	unsigned int i;

	for (i = 0; i < sizeof(buf); i++) {
		buf[i] = num & 0xff;
		num >>= 8;
	}
	if (o_stream_send(output, buf, sizeof(buf)) != sizeof(buf))
		return -1;
	return 0;
}
Exemplo n.º 13
0
static int o_stream_zlib_send_gz_header(struct zlib_ostream *zstream)
{
	ssize_t ret;

	ret = o_stream_send(zstream->output, zstream->gz_header,
			    sizeof(zstream->gz_header));
	if ((size_t)ret != sizeof(zstream->gz_header)) {
		zstream_copy_error(zstream);
		return -1;
	}
	zstream->header_sent = TRUE;
	return 0;
}
Exemplo n.º 14
0
static bool openssl_iostream_bio_output(struct ssl_iostream *ssl_io)
{
	size_t bytes, max_bytes;
	ssize_t sent;
	unsigned char buffer[IO_BLOCK_SIZE];
	bool bytes_sent = FALSE;
	int ret;

	o_stream_cork(ssl_io->plain_output);
	while ((bytes = BIO_ctrl_pending(ssl_io->bio_ext)) > 0) {
		/* bytes contains how many SSL encrypted bytes we should be
		   sending out */
		max_bytes = o_stream_get_buffer_avail_size(ssl_io->plain_output);
		if (bytes > max_bytes) {
			if (max_bytes == 0) {
				/* wait until output buffer clears */
				o_stream_set_flush_pending(ssl_io->plain_output,
							   TRUE);
				break;
			}
			bytes = max_bytes;
		}
		if (bytes > sizeof(buffer))
			bytes = sizeof(buffer);

		/* BIO_read() is guaranteed to return all the bytes that
		   BIO_ctrl_pending() returned */
		ret = BIO_read(ssl_io->bio_ext, buffer, bytes);
		i_assert(ret == (int)bytes);

		/* we limited number of read bytes to plain_output's
		   available size. this send() is guaranteed to either
		   fully succeed or completely fail due to some error. */
		sent = o_stream_send(ssl_io->plain_output, buffer, bytes);
		if (sent < 0) {
			i_assert(ssl_io->plain_output->closed ||
				 ssl_io->plain_output->stream_errno != 0);
			i_free(ssl_io->plain_stream_errstr);
			ssl_io->plain_stream_errstr =
				i_strdup(o_stream_get_error(ssl_io->plain_output));
			ssl_io->plain_stream_errno =
				ssl_io->plain_output->stream_errno;
			ssl_io->closed = TRUE;
			break;
		}
		i_assert(sent == (ssize_t)bytes);
		bytes_sent = TRUE;
	}
	o_stream_uncork(ssl_io->plain_output);
	return bytes_sent;
}
Exemplo n.º 15
0
static int client_input_status_overview(struct doveadm_connection *client)
{
	struct replicator_queue *queue =
		replicator_brain_get_queue(client->brain);
	struct replicator_queue_iter *iter;
	struct replicator_user *user;
	enum replication_priority priority;
	unsigned int pending_counts[REPLICATION_PRIORITY_SYNC+1];
	unsigned int user_count, next_secs, pending_failed_count;
	unsigned int pending_full_resync_count, waiting_failed_count;
	string_t *str = t_str_new(256);

	memset(pending_counts, 0, sizeof(pending_counts));
	pending_failed_count = 0; waiting_failed_count = 0;
	pending_full_resync_count = 0;

	user_count = 0;
	iter = replicator_queue_iter_init(queue);
	while ((user = replicator_queue_iter_next(iter)) != NULL) {
		if (user->priority != REPLICATION_PRIORITY_NONE)
			pending_counts[user->priority]++;
		else if (replicator_queue_want_sync_now(queue, user, &next_secs)) {
			if (user->last_sync_failed)
				pending_failed_count++;
			else
				pending_full_resync_count++;
		} else {
			if (user->last_sync_failed)
				waiting_failed_count++;
		}
		user_count++;
	}
	replicator_queue_iter_deinit(&iter);

	for (priority = REPLICATION_PRIORITY_SYNC; priority > 0; priority--) {
		str_printfa(str, "Queued '%s' requests\t%u\n",
			    replicator_priority_to_str(priority),
			    pending_counts[priority]);
	}
	str_printfa(str, "Queued 'failed' requests\t%u\n",
		    pending_failed_count);
	str_printfa(str, "Queued 'full resync' requests\t%u\n",
		    pending_full_resync_count);
	str_printfa(str, "Waiting 'failed' requests\t%u\n",
		    waiting_failed_count);
	str_printfa(str, "Total number of known users\t%u\n", user_count);
	str_append_c(str, '\n');
	o_stream_send(client->conn.output, str_data(str), str_len(str));
	return 0;
}
Exemplo n.º 16
0
static void client_handle(int fd)
{
	struct ostream *output;

	output = o_stream_create_fd(fd, (size_t)-1, TRUE);
	o_stream_send(output, ssl_params->data, ssl_params->used);

	if (o_stream_get_buffer_used_size(output) == 0)
		client_deinit(output);
	else {
		o_stream_set_flush_callback(output, client_output_flush,
					    output);
	}
}
Exemplo n.º 17
0
static int o_stream_mail_filter_flush(struct ostream_private *stream)
{
	struct mail_filter_ostream *mstream =
		(struct mail_filter_ostream *)stream;
	const unsigned char *data;
	size_t size;
	ssize_t ret;

	if (mstream->ext_out == NULL) {
		/* connect failed */
		return -1;
	}
	if (mstream->flushed)
		return 0;

	if (shutdown(mstream->fd, SHUT_WR) < 0)
		i_error("ext-filter: shutdown() failed: %m");

	while ((ret = i_stream_read_data(mstream->ext_in, &data, &size, 0)) > 0) {
		ret = o_stream_send(stream->parent, data, size);
		if (ret != (ssize_t)size) {
			i_assert(ret < 0);
			o_stream_copy_error_from_parent(stream);
			return -1;
		}
		i_stream_skip(mstream->ext_in, size);
	}
	i_assert(ret == -1);

	if (!i_stream_have_bytes_left(mstream->ext_in) &&
	    mstream->ext_in->v_offset == 0) {
		/* EOF without any input -> assume the script is repoting
		   failure. pretty ugly way, but currently there's no error
		   reporting channel. */
		stream->ostream.stream_errno = EIO;
		return -1;
	}
	if (mstream->ext_in->stream_errno != 0) {
		stream->ostream.stream_errno = mstream->ext_in->stream_errno;
		return -1;
	}

	ret = o_stream_flush(stream->parent);
	if (ret < 0)
		o_stream_copy_error_from_parent(stream);
	else
		mstream->flushed = TRUE;
	return ret;
}
Exemplo n.º 18
0
static void test_iostream_temp_create_write_error(void)
{
	struct ostream *output;

	test_begin("iostream_temp_create_sized() write error");
	output = iostream_temp_create_sized(".", 0, "test", 1);

	test_assert(o_stream_send(output, "123", 3) == 3);
	test_assert(o_stream_get_fd(output) != -1);
	test_assert(output->offset == 3);
	test_assert(o_stream_temp_move_to_memory(output) == 0);
	test_assert(o_stream_get_fd(output) == -1);
	test_assert(o_stream_send(output, "45", 2) == 2);
	test_assert(output->offset == 5);

	const unsigned char *data;
	size_t size;
	struct istream *input = iostream_temp_finish(&output, 128);
	test_assert(i_stream_read_bytes(input, &data, &size, 5) == 1 &&
		    memcmp(data, "12345", 5) == 0);
	i_stream_destroy(&input);

	test_end();
}
Exemplo n.º 19
0
static int o_stream_zlib_send_flush(struct zlib_ostream *zstream)
{
	z_stream *zs = &zstream->zs;
	unsigned int len;
	bool done = FALSE;
	int ret;

	i_assert(zs->avail_in == 0);

	if (zstream->flushed)
		return 0;
	if (!zstream->header_sent)
		o_stream_zlib_send_gz_header(zstream);

	do {
		len = sizeof(zstream->outbuf) - zs->avail_out;
		if (len != 0) {
			zs->next_out = zstream->outbuf;
			zs->avail_out = sizeof(zstream->outbuf);

			ret = o_stream_send(zstream->output,
					    zstream->outbuf, len);
			if (ret != (int)len) {
				zstream_copy_error(zstream);
				return -1;
			}
			if (done)
				break;
		}

		switch (deflate(zs, zstream->gz ? Z_FINISH : Z_SYNC_FLUSH)) {
		case Z_OK:
		case Z_BUF_ERROR:
			break;
		case Z_STREAM_END:
			done = TRUE;
			break;
		default:
			i_unreached();
		}
	} while (zs->avail_out != sizeof(zstream->outbuf));

	if (o_stream_zlib_send_gz_trailer(zstream) < 0)
		return -1;
	zstream->flushed = TRUE;
	return 0;
}
Exemplo n.º 20
0
void http_server_request_abort(struct http_server_request **_req,
	const char *reason)
{
	struct http_server_request *req = *_req;
	struct http_server_connection *conn = req->conn;

	if (req->state >= HTTP_SERVER_REQUEST_STATE_FINISHED)
		return;

	http_server_request_debug(req, "Abort");

	req->conn = NULL;
	if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
		if (conn != NULL) {
			http_server_connection_remove_request(conn, req);

			if (!conn->closed) {
				/* send best-effort response if appropriate */
				if (!conn->output_locked &&
					req->state >= HTTP_SERVER_REQUEST_STATE_PROCESSING &&
					req->state < HTTP_SERVER_REQUEST_STATE_SENT_RESPONSE) {
					static const char *response =
						"HTTP/1.1 500 Internal Server Error\r\n"
						"Content-Length: 0\r\n"
						"\r\n";

					(void)o_stream_send(conn->conn.output,
						response, strlen(response));
				}

				/* close the connection */
				http_server_connection_close(&conn, reason);
			}
		}

		req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
	}
	
	if (req->response != NULL &&
		!req->response->payload_blocking) {
		http_server_response_free(req->response);
		req->response = NULL;
	}

	http_server_request_destroy(_req);
}
Exemplo n.º 21
0
static void proxy_send_login(struct pop3_client *client, struct ostream *output)
{
	string_t *str;

	str = t_str_new(128);
	if (client->common.proxy_master_user == NULL) {
		/* send USER command */
		str_append(str, "USER ");
		str_append(str, client->common.proxy_user);
		str_append(str, "\r\n");
	} else {
		/* master user login - use AUTH PLAIN. */
		str_append(str, "AUTH PLAIN\r\n");
	}
	(void)o_stream_send(output, str_data(str), str_len(str));
	client->common.proxy_state = POP3_PROXY_LOGIN1;
}
Exemplo n.º 22
0
static void test_ostream_file_random(void)
{
	struct ostream *output;
	string_t *path = t_str_new(128);
	char buf[MAX_BUFSIZE*4], buf2[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE];
	unsigned int i, offset, size;
	ssize_t ret;
	int fd;

	memset(buf, 0, sizeof(buf));
	fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
	if (fd == -1)
		i_fatal("safe_mkstemp(%s) failed: %m", str_c(path));
	if (unlink(str_c(path)) < 0)
		i_fatal("unlink(%s) failed: %m", str_c(path));
	output = o_stream_create_fd(fd, MAX_BUFSIZE, FALSE);
	o_stream_cork(output);

	size = (rand() % MAX_BUFSIZE) + 1;
	random_fill_weak(randbuf, size);
	memcpy(buf, randbuf, size);
	test_assert(o_stream_send(output, buf, size) > 0);

	for (i = 0; i < 10; i++) {
		offset = rand() % (MAX_BUFSIZE*3);
		size = (rand() % MAX_BUFSIZE) + 1;
		random_fill_weak(randbuf, size);
		memcpy(buf + offset, randbuf, size);
		test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0);
		if (rand() % 10 == 0)
			test_assert(o_stream_flush(output) > 0);
	}

	test_assert(o_stream_flush(output) > 0);
	o_stream_uncork(output);
	ret = pread(fd, buf2, sizeof(buf2), 0);
	if (ret < 0)
		i_fatal("pread() failed: %m");
	else {
		i_assert(ret > 0);
		test_assert(memcmp(buf, buf2, ret) == 0);
	}
	o_stream_unref(&output);
	i_close_fd(&fd);
}
Exemplo n.º 23
0
static int
client_handle_request(struct client *client, struct http_request *request)
{
    string_t *str = t_str_new(128);

    if (strcmp(request->method, "GET") != 0) {
        o_stream_send_str(client->conn.output, "HTTP/1.1 501 Not Implemented\r\nAllow: GET\r\n\r\n");
        return 0;
    }
    str_append(str, "HTTP/1.1 200 OK\r\n");
    str_printfa(str, "Date: %s\r\n", http_date_create(ioloop_time));
    str_printfa(str, "Content-Length: %d\r\n", (int)strlen(request->target_raw));
    str_append(str, "Content-Type: text/plain\r\n");
    str_append(str, "\r\n");
    str_append(str, request->target_raw);
    o_stream_send(client->conn.output, str_data(str), str_len(str));
    return 0;
}
Exemplo n.º 24
0
static int mbox_write_content_length(struct mbox_save_context *ctx)
{
	uoff_t end_offset;
	const char *str;
	size_t len;

	i_assert(ctx->eoh_offset != (uoff_t)-1);

	if (ctx->mbox->mbox_writeonly) {
		/* we can't seek, don't set Content-Length */
		return 0;
	}

	end_offset = ctx->output->offset;

	/* write Content-Length headers */
	str = t_strdup_printf("\nContent-Length: %s",
			      dec2str(end_offset - ctx->eoh_offset));
	len = strlen(str);

	/* flush manually here so that we don't confuse seek() errors with
	   buffer flushing errors */
	if (o_stream_flush(ctx->output) < 0) {
		write_error(ctx);
		return -1;
	}
	if (o_stream_seek(ctx->output, ctx->extra_hdr_offset +
			  ctx->space_end_idx - len) < 0) {
		mbox_set_syscall_error(ctx->mbox, "lseek()");
		return -1;
	}

	if (o_stream_send(ctx->output, str, len) < 0 ||
	    o_stream_flush(ctx->output) < 0) {
		write_error(ctx);
		return -1;
	}

	if (o_stream_seek(ctx->output, end_offset) < 0) {
		mbox_set_syscall_error(ctx->mbox, "lseek()");
		return -1;
	}
	return 0;
}
Exemplo n.º 25
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);
}
Exemplo n.º 26
0
static
int o_stream_encrypt_send(struct encrypt_ostream *stream,
			  const unsigned char *data, size_t size)
{
	ssize_t ec;

	ec = o_stream_send(stream->ostream.parent, data, size);
	if (ec == (ssize_t)size)
		return 0;
	else if (ec < 0) {
		o_stream_copy_error_from_parent(&stream->ostream);
		return -1;
	} else {
		io_stream_set_error(&stream->ostream.iostream,
			"ostream-encrypt: Unexpectedly short write to parent stream");
		stream->ostream.ostream.stream_errno = EINVAL;
		return -1;
	}
}
Exemplo n.º 27
0
static int
o_stream_zlib_send_chunk(struct zlib_ostream *zstream,
			 const void *data, size_t size)
{
	z_stream *zs = &zstream->zs;
	ssize_t ret;
	int flush;

	flush = zstream->ostream.corked || zstream->gz ?
		Z_NO_FLUSH : Z_SYNC_FLUSH;

	if (!zstream->header_sent)
		o_stream_zlib_send_gz_header(zstream);

	zs->next_in = (void *)data;
	zs->avail_in = size;
	while (zs->avail_in > 0) {
		if (zs->avail_out == 0) {
			zs->next_out = zstream->outbuf;
			zs->avail_out = sizeof(zstream->outbuf);

			ret = o_stream_send(zstream->output, zstream->outbuf,
					    sizeof(zstream->outbuf));
			if (ret != (ssize_t)sizeof(zstream->outbuf)) {
				zstream_copy_error(zstream);
				return -1;
			}
		}

		switch (deflate(zs, flush)) {
		case Z_OK:
		case Z_BUF_ERROR:
			break;
		default:
			i_unreached();
		}
	}
	zstream->crc = crc32_data_more(zstream->crc, data, size);
	zstream->bytes32 += size;
	zstream->flushed = FALSE;
	return 0;
}
Exemplo n.º 28
0
static int fetch_stream_send_direct(struct imap_fetch_context *ctx)
{
	off_t ret;

	o_stream_set_max_buffer_size(ctx->client->output, 0);
	ret = o_stream_send_istream(ctx->client->output, ctx->cur_input);
	o_stream_set_max_buffer_size(ctx->client->output, (size_t)-1);

	if (ret < 0)
		return -1;

	ctx->cur_offset += ret;

	if (ctx->cur_append_eoh && ctx->cur_offset + 2 == ctx->cur_size) {
		/* Netscape missing EOH workaround. */
		if (o_stream_send(ctx->client->output, "\r\n", 2) < 0)
			return -1;
		ctx->cur_offset += 2;
		ctx->cur_append_eoh = FALSE;
	}

	if (ctx->cur_offset != ctx->cur_size) {
		/* unfinished */
		if (!i_stream_have_bytes_left(ctx->cur_input)) {
			/* Input stream gave less data than expected */
			i_error("FETCH %s for mailbox %s UID %u "
				"got too little data (copying): "
				"%"PRIuUOFF_T" vs %"PRIuUOFF_T,
				ctx->cur_name, mailbox_get_vname(ctx->mail->box),
				ctx->mail->uid, ctx->cur_offset, ctx->cur_size);
			mail_set_cache_corrupted(ctx->mail,
						 ctx->cur_size_field);
			client_disconnect(ctx->client, "FETCH failed");
			return -1;
		}

		o_stream_set_flush_pending(ctx->client->output, TRUE);
		return 0;
	}
	return 1;
}
Exemplo n.º 29
0
static ssize_t
o_stream_escaped_send_outbuf(struct escaped_ostream *estream)
{
	ssize_t ret;

	if (estream->flushed)
		return 1; /* nothing to send */
	ret = o_stream_send(estream->ostream.parent, str_data(estream->buf), str_len(estream->buf));
	if (ret < 0) {
		o_stream_copy_error_from_parent(&estream->ostream);
		return -1;
	}
	if ((size_t)ret != str_len(estream->buf)) {
		/* move data */
		str_delete(estream->buf, 0, ret);
		return 0;
	}
	str_truncate(estream->buf, 0);
	estream->flushed = TRUE;
	return 1;
}
Exemplo n.º 30
0
static int filter_connect(struct mail_filter_istream *mstream,
			  const char *socket_path, const char *args)
{
	const char **argv;
	string_t *str;
	int fd;

	argv = t_strsplit(args, " ");

	if ((fd = net_connect_unix_with_retries(socket_path, 1000)) < 0) {
		if (errno == EACCES) {
			i_error("ext-filter: %s",
				eacces_error_get("net_connect_unix",
						 socket_path));
		} else {
			i_error("ext-filter: net_connect_unix(%s) failed: %m",
				socket_path);
		}
		return -1;
	}
	if (mstream->istream.istream.blocking)
		net_set_nonblock(fd, FALSE);

	mstream->fd = fd;
	mstream->ext_in =
		i_stream_create_fd(fd, mstream->istream.max_buffer_size, FALSE);
	mstream->ext_out = o_stream_create_fd(fd, 0, FALSE);

	str = t_str_new(256);
	str_append(str, "VERSION\tscript\t3\t0\nnoreply\n");
	for (; *argv != NULL; argv++) {
		str_append(str, *argv);
		str_append_c(str, '\n');
	}
	str_append_c(str, '\n');

	o_stream_send(mstream->ext_out, str_data(str), str_len(str));
	return 0;
}