bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void test_files_read_dir(const char *path)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* open the directory */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* read entries */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* Close the directory */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* initialize file array */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* obtain all filenames */
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic struct istream *
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch file = i_stream_create_fd_autoclose(&fd, 40960);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch * Test server
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschclient_transaction_read_more(struct client_transaction *ctrans)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_debug("test server: read more payload for [%s]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* read payload */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch while ((ret=i_stream_read_more(payload, &pdata, &psize)) > 0) {
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "got data for [%s] (size=%d)",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* compare with file on disk */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch (ctrans->file, &fdata, &fsize)) > 0 && pleft > 0) {
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "received data does not match file [%s] "
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch if (ret < 0 && ctrans->file->stream_errno != 0) {
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "failed to read file: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "need more data for [%s]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* we will be called again for this request */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "failed to read transaction payload: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch } if (i_stream_have_bytes_left(ctrans->file)) {
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch if (i_stream_read_more(ctrans->file, &fdata, &fsize) <= 0)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "payload ended prematurely "
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "(at least %"PRIuSIZE_T" bytes left)", fsize);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "finished transaction for [%s]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* dereference payload stream; finishes the request */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* finished */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_server_reply_all(ctrans->data_cmd, 250, "2.0.0", "OK");
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschclient_transaction_handle_payload(struct client_transaction *ctrans,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch struct smtp_server_transaction *trans = ctrans->trans;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_debug("test server: got transaction for: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_fatal("test server: failed to open: %s", path);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch ctrans->file = i_stream_create_base64_encoder(fstream, 80, TRUE),
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch/* transaction */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch ctrans = p_new(pool, struct client_transaction, 1);
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschclient_transaction_deinit(struct client_transaction **_ctrans)
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_server_conn_trans_free(void *context ATTR_UNUSED,
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_server_conn_cmd_rcpt(void *conn_ctx ATTR_UNUSED,
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_server_conn_cmd_data_begin(void *conn_ctx,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch struct client *client = (struct client *)conn_ctx;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_debug("test server: DATA (file path = %s)", fpath);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch ctrans = client_transaction_init(client, cmd, trans);
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_server_conn_cmd_data_continue(void *conn_ctx ATTR_UNUSED,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch/* client connection */
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic const struct smtp_server_callbacks server_callbacks =
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch .conn_cmd_data_begin = test_server_conn_cmd_data_begin,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch .conn_cmd_data_continue = test_server_conn_cmd_data_continue,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch .conn_trans_free = test_server_conn_trans_free,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch .conn_destroy = test_server_connection_destroy
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch client->smtp_conn = smtp_server_connection_create(smtp_server,
40a926a1aeae93b3d4944b56eacb013d3059b549Stephan Bosch fd, fd, NULL, 0, FALSE, NULL, &server_callbacks, client);
40a926a1aeae93b3d4944b56eacb013d3059b549Stephan Bosch smtp_server_connection_start(client->smtp_conn);
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void client_deinit(struct client **_client)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_server_connection_terminate(&client->smtp_conn, NULL, "deinit");
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void client_accept(void *context ATTR_UNUSED)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* accept new client */
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_server_init(const struct smtp_server_settings *server_set)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* open server socket */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* close server socket */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* deinitialize */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch * Test client
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic struct test_client_transaction *client_requests;
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic unsigned int client_files_first, client_files_last;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch tctrans = i_new(struct test_client_transaction, 1);
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_client_transaction_destroy(struct test_client_transaction *tctrans)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_client_transaction_destroy(&tctrans->trans);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch client_to = timeout_add_short(0, test_client_continue, NULL);
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_client_transaction_finish(struct test_client_transaction *tctrans)
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_client_transaction_rcpt(const struct smtp_reply *reply,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "SMTP RCPT for %s failed: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_client_transaction_rcpt_data(const struct smtp_reply *reply ATTR_UNUSED,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "SMTP DATA for %s failed: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschtest_client_transaction_data(const struct smtp_reply *reply,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "got response for DATA [%u]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "path for [%u]: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "SMTP transaction for %s failed: %s",
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void test_client_continue(void *dummy ATTR_UNUSED)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_assert(client_files_first <= client_files_last);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch for (; client_files_first < client_files_last &&
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch paths[client_files_first] == NULL; client_files_first++);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "received until [%u/%u]", client_files_first-1, count);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "next blocking: %s [%d]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch (client_files_last - client_files_first) < test_max_pending;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "skipping %s [%u]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch client_to = timeout_add_short(0, test_client_continue, NULL);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "retrieving %s [%u]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch tctrans->conn = smtp_client_connection_create(smtp_client,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch client_protocol, net_ip2addr(&bind_ip), bind_port,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch tctrans->trans = smtp_client_transaction_create(tctrans->conn,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch &mail_params, test_client_transaction_finish, tctrans);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_client_transaction_add_rcpt(tctrans->trans,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch t_strdup_printf("rcpt%u", r), "example.com"), NULL,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch payload = i_stream_create_base64_encoder(fstream, 80, TRUE);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch i_stream_create_base64_encoder(fstream, 80, FALSE);
836ed7eb3d79eb41b28d80d4f59099e54b7cb20aJosef 'Jeff' Sipek uoff_t raw_size = (uoff_t)-1, b64_size = (uoff_t)-1;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch (void)i_stream_get_size(fstream, TRUE, &raw_size);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch (void)i_stream_get_size(payload, TRUE, &b64_size);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch "sending %"PRIuUOFF_T"/%"PRIuUOFF_T" bytes payload %s [%u]",
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_client_transaction_send(tctrans->trans, payload,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch const struct smtp_client_settings *client_set)
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* create client */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* start querying server */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch fd_listen = net_listen(&bind_ip, &bind_port, 128);
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch const struct smtp_client_settings *client_set,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch const struct smtp_server_settings *server_set,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch void (*client_init)(enum smtp_protocol protocol,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch const struct smtp_client_settings *client_set))
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* child: server */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* parent: client */
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void test_run_scenarios(enum smtp_protocol protocol,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch void (*client_init)(enum smtp_protocol protocol,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch const struct smtp_client_settings *client_set))
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* server settings */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_server_set.max_client_idle_time_msecs = 10*000;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* client settings */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_server_set.capabilities |= SMTP_CAPABILITY_PIPELINING;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch smtp_server_set.capabilities |= SMTP_CAPABILITY_PIPELINING;
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch SMTP_CAPABILITY_DSN | SMTP_CAPABILITY_CHUNKING,
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch SMTP_CAPABILITY_DSN | SMTP_CAPABILITY_CHUNKING,
8620dc793885749c37000f11dd83b902b6844e20Stephan Boschstatic void (*const test_functions[])(void) = {
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* make sure we don't leave any pesky children alive */
8620dc793885749c37000f11dd83b902b6844e20Stephan Bosch /* listen on localhost */