bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "lib.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "lib-signals.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "str.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "hostpid.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "ioloop.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "istream.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "istream-dot.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "istream-chain.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "istream-failure-at.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "ostream.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "time-util.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "connection.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "test-common.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "smtp-client.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "smtp-client-connection.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include "smtp-client-transaction.h"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include <sys/types.h>
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include <sys/wait.h>
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include <signal.h>
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch#include <unistd.h>
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Types
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschenum server_connection_state {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SERVER_CONNECTION_STATE_EHLO = 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SERVER_CONNECTION_STATE_MAIL_FROM,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SERVER_CONNECTION_STATE_RCPT_TO,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SERVER_CONNECTION_STATE_DATA,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SERVER_CONNECTION_STATE_FINISH
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct server_connection {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct connection conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch enum server_connection_state state;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch char *file_path;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *dot_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pool_t pool;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtypedef void (*test_server_init_t)(unsigned int index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtypedef bool (*test_client_init_t)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (const struct smtp_client_settings *client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtypedef void (*test_dns_init_t)(void);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * State
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* common */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct ip_addr bind_ip;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic in_port_t *bind_ports = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct ioloop *ioloop;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool debug = FALSE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* dns */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic pid_t dns_pid = (pid_t)-1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct io *io_listen;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int fd_listen = -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic pid_t *server_pids = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic unsigned int server_pids_count = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct connection_list *server_conn_list;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic unsigned int server_index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void (*test_server_input)(struct server_connection *conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int (*test_server_input_line)(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int (*test_server_input_data)(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const unsigned char *data, size_t size);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int (*test_server_init)(struct server_connection *conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void (*test_server_deinit)(struct server_connection *conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct smtp_client *smtp_client = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Forward declarations
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_run(unsigned int index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_deinit(struct server_connection **_conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_defaults(struct smtp_client_settings *smtp_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_client_deinit(void);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test*/
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_run_client_server(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_init_t client_test,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_init_t server_test,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int server_tests_count,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_init_t dns_test)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ATTR_NULL(3);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Unconfigured SSL
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_server_unconfigured_ssl_input(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* nothing */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_server_unconfigured_ssl(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(100);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input = test_server_unconfigured_ssl_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _unconfigured_ssl {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unconfigured_ssl_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unconfigured_ssl *ctx = (struct _unconfigured_ssl *)context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unconfigured_ssl(const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unconfigured_ssl *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _unconfigured_ssl, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "127.0.0.1", bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "127.0.0.1", bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_unconfigured_ssl(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("unconfigured ssl");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_unconfigured_ssl, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Unconfigured SSL abort
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_server_unconfigured_ssl_abort_input(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* nothing */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_server_unconfigured_ssl_abort(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(100);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input = test_server_unconfigured_ssl_abort_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _unconfigured_ssl_abort {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unconfigured_ssl_abort_reply1(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unconfigured_ssl_abort *ctx ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_out_quiet("inappropriate callback", FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unconfigured_ssl_abort_reply2(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unconfigured_ssl_abort *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unconfigured_ssl_abort(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unconfigured_ssl_abort *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _unconfigured_ssl_abort, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "127.0.0.1", bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl_abort_reply1, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_abort(&scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "127.0.0.1", bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl_abort_reply2, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_unconfigured_ssl_abort(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("unconfigured ssl abort");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unconfigured_ssl_abort,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_unconfigured_ssl_abort, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Host lookup failed
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _host_lookup_failed {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_host_lookup_failed_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _host_lookup_failed *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_HOST_LOOKUP_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_host_lookup_failed(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _host_lookup_failed *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _host_lookup_failed, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "host.in-addr.arpa", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_host_lookup_failed_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "host.in-addr.arpa", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_host_lookup_failed_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_host_lookup_failed(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("host lookup failed");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_host_lookup_failed,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch NULL, 0, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Connection refused
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_server_connection_refused(unsigned int index ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_close_fd(&fd_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _connection_refused {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_refused_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_refused *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_refused(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_refused *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _connection_refused, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_refused_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_refused_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_connection_refused(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("connection refused");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_refused,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_connection_refused, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Connection lost prematurely
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_connection_lost_prematurely_input(struct server_connection *conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch line = i_stream_read_next_line(conn->conn.input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (line == NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->conn.input->eof ||
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->conn.input->stream_errno != 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_connection_lost_prematurely_init(struct server_connection *conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "220 testserver ESMTP Testfix (Frop/GNU)\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_connection_lost_prematurely(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_init = test_connection_lost_prematurely_init;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input = test_connection_lost_prematurely_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _connection_lost_prematurely {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_prematurely_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_prematurely *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_prematurely(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_prematurely *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _connection_lost_prematurely, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_prematurely_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_prematurely_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_connection_lost_prematurely(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("connection lost prematurely");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_prematurely,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_connection_lost_prematurely, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Connection timed out
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_connection_timed_out(unsigned int index ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(10);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _connection_timed_out {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_timed_out_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_timed_out *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECT_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_timed_out(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_timed_out *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _connection_timed_out, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_timed_out_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_timed_out_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_connection_timed_out(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.connect_timeout_msecs = 1000;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("connection timed out");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_timed_out,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_connection_timed_out, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Broken payload
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_broken_payload_input_line(struct server_connection *conn ATTR_UNUSED,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_broken_payload(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_broken_payload_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_broken_payload_chunking_input_line(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn, const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-testserver\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-PIPELINING\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-CHUNKING\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-ENHANCEDSTATUSCODES\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 DSN\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_broken_payload_chunking(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_broken_payload_chunking_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload_rcpt_to_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload_rcpt_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_BROKEN_PAYLOAD);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_BROKEN_PAYLOAD);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload_finished(void *context ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *strans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch input = i_stream_create_error_str(EIO, "Moehahahaha!!");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_set_name(input, "PURE EVIL");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch strans = smtp_client_transaction_create(sconn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_finished, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_unref(&sconn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_add_rcpt(strans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("rcpt", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_rcpt_to_cb,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_rcpt_data_cb, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_send(strans, input,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_data_cb, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_broken_payload_later(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch static const char *message =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "From: lucifer@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "To: lostsoul@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Subject: Moehahaha!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Moehahahahahahahahahahahahahahahahahahahahahaha!!\r\n";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *strans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *input, *msg_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch msg_input = i_stream_create_from_data(message, strlen(message));
a4985564b81d51caaddd38376792432428fd449bStephan Bosch input = i_stream_create_failure_at(msg_input, 666,
a4985564b81d51caaddd38376792432428fd449bStephan Bosch EIO, "Moehahahaha!!");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&msg_input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_set_name(input, "PURE EVIL");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch strans = smtp_client_transaction_create(sconn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_finished, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_unref(&sconn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_add_rcpt(strans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("rcpt", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_rcpt_to_cb,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_rcpt_data_cb, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_send
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (strans, input, test_client_broken_payload_data_cb, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_broken_payload(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.connect_timeout_msecs = 1000;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("broken payload");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_broken_payload, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("broken payload (later)");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_later,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_broken_payload, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("broken payload (later, chunking)");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_broken_payload_later,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_broken_payload_chunking, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Connection lost
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_connection_lost_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (conn->state) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_EHLO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_MAIL_FROM;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_MAIL_FROM:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_RCPT_TO;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_RCPT_TO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 2) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_DATA;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_DATA:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 3) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_FINISH;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_FINISH:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_connection_lost_input_data(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const unsigned char *data ATTR_UNUSED, size_t size ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_connection_lost(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_connection_lost_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_data = test_connection_lost_input_data;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _connection_lost {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _connection_lost_peer {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost *context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_rcpt_to_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT TO REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 3:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_rcpt_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT DATA REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 3:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("DATA REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_finished(struct _connection_lost_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost *ctx = pctx->context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("FINISHED[%u]", pctx->index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost_submit(struct _connection_lost *ctx,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch static const char *message =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "From: stephan@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "To: timo@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Subject: Frop!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Frop!\r\n";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost_peer *pctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *strans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx = i_new(struct _connection_lost_peer, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->context = ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index = index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch input = i_stream_create_from_data(message, strlen(message));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_set_name(input, "message");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch strans = smtp_client_transaction_create(sconn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_finished, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_unref(&sconn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_add_rcpt(strans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("rcpt", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_rcpt_to_cb,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_rcpt_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_send
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (strans, input, test_client_connection_lost_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_connection_lost(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _connection_lost *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int i;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _connection_lost, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 5;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < ctx->count; i++)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost_submit(ctx, i);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_connection_lost(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("connection lost");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_connection_lost,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_connection_lost, 5, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Unexpected reply
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_unexpected_reply_init(struct server_connection *conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 5) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "220 testserver ESMTP Testfix (Debian/GNU)\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "421 testserver Server shutting down for maintenance\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(4);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_unexpected_reply_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (conn->state) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_EHLO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 4) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-testserver\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-PIPELINING\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-ENHANCEDSTATUSCODES\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 DSN\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "421 testserver Server shutting down for maintenance\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(4);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_MAIL_FROM:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 3) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 2.1.0 Ok\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "421 testserver Server shutting down for maintenance\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(4);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_RCPT_TO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 2) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 2.1.5 Ok\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "421 testserver Server shutting down for maintenance\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(4);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_DATA:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "354 End data with <CR><LF>.<CR><LF>\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "421 testserver Server shutting down for maintenance\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(4);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_FINISH:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_unexpected_reply(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_init = test_unexpected_reply_init;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_unexpected_reply_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _unexpected_reply {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _unexpected_reply_peer {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply *context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *trans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct timeout *to;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bool login_callback:1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bool mail_from_callback:1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bool rcpt_to_callback:1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bool rcpt_data_callback:1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bool data_callback:1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_login_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (struct _unexpected_reply_peer *)context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->login_callback = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("LOGIN REPLY[%u]: %s", pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0: case 1: case 2: case 3: case 4:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 421);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_mail_from_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("MAIL FROM REPLY[%u]: %s", pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->mail_from_callback = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0: case 1: case 2: case 3:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 4: case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 421);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_rcpt_to_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT TO REPLY[%u]: %s", pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->rcpt_to_callback = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0: case 1: case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 3: case 4: case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 421);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_rcpt_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT DATA REPLY[%u]: %s", pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->rcpt_data_callback = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1: case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 421);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 3: case 4: case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_unreached();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("DATA REPLY[%u]: %s", pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->data_callback = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(smtp_reply_is_success(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1: case 2: case 3: case 4: case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 421);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_finished(struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply *ctx = pctx->context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("FINISHED[%u]", pctx->index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0: case 1: case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->mail_from_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->rcpt_to_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->rcpt_data_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->data_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 3: case 4: case 5:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->mail_from_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->rcpt_to_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(!pctx->rcpt_data_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(pctx->data_callback);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->trans = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch timeout_remove(&pctx->to);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_submit2(struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *strans = pctx->trans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch static const char *message =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "From: stephan@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "To: timo@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Subject: Frop!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Frop!\r\n";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch timeout_remove(&pctx->to);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch input = i_stream_create_from_data(message, strlen(message));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_set_name(input, "message");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_send
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (strans, input, test_client_unexpected_reply_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_submit1(struct _unexpected_reply_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch timeout_remove(&pctx->to);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_add_rcpt(pctx->trans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("rcpt", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_rcpt_to_cb,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_rcpt_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->to = timeout_add_short(500,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_submit2, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply_submit(struct _unexpected_reply *ctx,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply_peer *pctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx = i_new(struct _unexpected_reply_peer, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->context = ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index = index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->conn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->trans = smtp_client_transaction_create(pctx->conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_finished, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(pctx->conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_login_cb, (void *)pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_start(pctx->trans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_mail_from_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_unref(&pctx->conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->to = timeout_add_short(500,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_submit1, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_unexpected_reply(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _unexpected_reply *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int i;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _unexpected_reply, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 6;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < ctx->count; i++)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply_submit(ctx, i);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_unexpected_reply(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("unexpected reply");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_unexpected_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_unexpected_reply, 6, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Partial reply
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_partial_reply_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "500 Command not");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_partial_reply(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_partial_reply_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _partial_reply {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_partial_reply_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _partial_reply *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_CONNECTION_LOST);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_partial_reply(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _partial_reply *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _partial_reply, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_partial_reply_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_partial_reply_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_partial_reply(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("partial reply");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_partial_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_partial_reply, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Bad reply
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_bad_reply_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "666 Really bad reply\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_bad_reply(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_bad_reply_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _bad_reply {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_bad_reply_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_reply *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_bad_reply(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_reply *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _bad_reply, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_reply_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_reply_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_bad_reply(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("bad reply");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_bad_reply, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Bad greeting
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_bad_greeting_init(struct server_connection *conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (server_index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "666 Mouhahahaha!!\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "446 Not right now, sorry.\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "233 Gimme all your mail, NOW!!\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_bad_greeting(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_init = test_bad_greeting_init;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _bad_greeting {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _bad_greeting_peer {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_greeting *context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_bad_greeting_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_greeting_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 446);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 2:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_BAD_REPLY);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--pctx->context->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(pctx->context);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_bad_greeting_submit(struct _bad_greeting *ctx,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_greeting_peer *pctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx = i_new(struct _bad_greeting_peer, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->context = ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index = index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_greeting_reply, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_bad_greeting(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _bad_greeting *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _bad_greeting, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 3;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_greeting_submit(ctx, 0);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_greeting_submit(ctx, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_greeting_submit(ctx, 2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_bad_greeting(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("bad greeting");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_bad_greeting,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_bad_greeting, 3, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Command timeout
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_command_timed_out_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(10);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_command_timed_out(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_command_timed_out_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _command_timed_out {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_command_timed_out_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _command_timed_out *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_TIMED_OUT);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_command_timed_out(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _command_timed_out *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _command_timed_out, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_timed_out_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_command_timed_out(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.command_timeout_msecs = 1000;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("command timed out");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_timed_out,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_command_timed_out, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Command aborted early
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_command_aborted_early_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_nsend_str(conn->conn.output, "200 OK\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_command_aborted_early(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_command_aborted_early_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _command_aborted_early {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *cmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct timeout *to;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_command_aborted_early_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _command_aborted_early *ctx ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* abort does not trigger callback */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_command_aborted_early_timeout(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _command_aborted_early *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch timeout_remove(&ctx->to);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (ctx->cmd != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("ABORT");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* abort early */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_abort(&ctx->cmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* wait a little for server to actually respond to an
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch already aborted request */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->to = timeout_add_short(1000,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_aborted_early_timeout, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch } else {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("FINISHED");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* all done */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_command_aborted_early(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _command_aborted_early *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _command_aborted_early, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->cmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_aborted_early_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(ctx->cmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(ctx->cmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->to = timeout_add_short(500,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_aborted_early_timeout, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_command_aborted_early(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("command aborted early");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_command_aborted_early,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_command_aborted_early, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Client deinit early
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_deinit_early_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_EHLO)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_nsend_str(conn->conn.output, "200 OK\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_client_deinit_early(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_client_deinit_early_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _client_deinit_early {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *cmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct timeout *to;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_client_deinit_early_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _client_deinit_early *ctx ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* abort does not trigger callback */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_client_deinit_early_timeout(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _client_deinit_early *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch timeout_remove(&ctx->to);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* deinit early */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_deinit(&smtp_client);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* all done */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_client_deinit_early(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _client_deinit_early *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _client_deinit_early, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->cmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_client_deinit_early_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(ctx->cmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(ctx->cmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->to = timeout_add_short(500,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_client_deinit_early_timeout, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_client_deinit_early(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("client deinit early");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_client_deinit_early,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_client_deinit_early, 1, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * DNS service failure
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _dns_service_failure {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_service_failure_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_service_failure *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_HOST_LOOKUP_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_service_failure(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_service_failure *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _dns_service_failure, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "host.in-addr.arpa", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_service_failure_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "host.in-addr.arpa", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_service_failure_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_dns_service_failure(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.dns_client_socket_path = "./frop";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("dns service failure");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_service_failure,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch NULL, 0, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * DNS timeout
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* dns */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_dns_timeout_input(struct server_connection *conn ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* hang */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(100);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_dns_dns_timeout(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input = test_dns_timeout_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(0);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _dns_timeout {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_timeout_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_timeout *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_HOST_LOOKUP_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_timeout(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_timeout *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _dns_timeout, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "example.com", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_timeout_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "example.com", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_timeout_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_dns_timeout(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.connect_timeout_msecs = 2000;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.dns_client_socket_path = "./dns-test";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("dns timeout");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_timeout, NULL, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_dns_timeout);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * DNS lookup failure
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* dns */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_dns_lookup_failure_input(struct server_connection *conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_nsend_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch t_strdup_printf("%d\n", EAI_FAIL));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_dns_dns_lookup_failure(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input = test_dns_lookup_failure_input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(0);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _dns_lookup_failure {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_lookup_failure_reply(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_lookup_failure *ctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("REPLY: %s", smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == SMTP_CLIENT_COMMAND_ERROR_HOST_LOOKUP_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_dns_lookup_failure(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *sconn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_command *scmd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _dns_lookup_failure *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(2);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _dns_lookup_failure, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "example.com", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_lookup_failure_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sconn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, "example.com", 465,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_IMMEDIATE, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(sconn, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch scmd = smtp_client_command_new(sconn, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_lookup_failure_reply, ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_write(scmd, "FROP");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_command_submit(scmd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_dns_lookup_failure(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_set.dns_client_socket_path = "./dns-test";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("dns lookup failure");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_dns_lookup_failure, NULL, 0,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_dns_lookup_failure);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Authentication failed
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_authentication_failed_input_line(struct server_connection *conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (conn->state) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_EHLO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-testserver\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-PIPELINING\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-ENHANCEDSTATUSCODES\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-AUTH PLAIN\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 DSN\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_MAIL_FROM;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_MAIL_FROM:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_index == 1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "535 5.7.8 "
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Authentication credentials invalid\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(10);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch default:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_authentication_failed(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input_line = test_authentication_failed_input_line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_run(index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _authentication_failed {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstruct _authentication_failed_peer {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed *context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_connection *conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_transaction *trans;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_login_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch void *context)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (struct _authentication_failed_peer *)context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("LOGIN REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 535);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_mail_from_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("MAIL FROM REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 535);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_rcpt_to_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT TO REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 535);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_rcpt_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("RCPT DATA REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(FALSE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_data_cb(const struct smtp_reply *reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("DATA REPLY[%u]: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index, smtp_reply_log(reply));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (pctx->index) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 0:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status ==
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_COMMAND_ERROR_AUTH_FAILED);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 1:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_assert(reply->status == 535);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_finished(struct _authentication_failed_peer *pctx)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed *ctx = pctx->context;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("FINISHED[%u]", pctx->index);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (--ctx->count == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(ctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_stop(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->trans = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed_submit(struct _authentication_failed *ctx,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed_peer *pctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch static const char *message =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "From: stephan@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "To: timo@example.com\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Subject: Frop!\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Frop!\r\n";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct istream *input;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx = i_new(struct _authentication_failed_peer, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->context = ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->index = index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_zero(&smtp_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_set.username = "peter.wolfsen";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_set.password = "crybaby";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->conn = smtp_client_connection_create(smtp_client,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index],
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_CLIENT_SSL_MODE_NONE, &smtp_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pctx->trans = smtp_client_transaction_create(pctx->conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_finished, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_connect(pctx->conn,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_login_cb, (void *)pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_start(pctx->trans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_mail_from_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_connection_unref(&pctx->conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_add_rcpt(pctx->trans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch SMTP_ADDRESS_LITERAL("rcpt", "example.com"), NULL,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_rcpt_to_cb,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_rcpt_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch input = i_stream_create_from_data(message, strlen(message));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_set_name(input, "message");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_transaction_send(pctx->trans,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch input, test_client_authentication_failed_data_cb, pctx);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic bool
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_authentication_failed(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct _authentication_failed *ctx;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int i;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx = i_new(struct _authentication_failed, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ctx->count = 2;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = smtp_client_init(client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < ctx->count; i++)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed_submit(ctx, i);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* test */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_authentication_failed(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct smtp_client_settings smtp_client_set;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_defaults(&smtp_client_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_begin("authentication failed");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_expect_errors(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run_client_server(&smtp_client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_authentication_failed,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_authentication_failed, 2, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_end();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * All tests
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void (*const test_functions[])(void) = {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_unconfigured_ssl,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_unconfigured_ssl_abort,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_host_lookup_failed,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_connection_refused,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_connection_lost_prematurely,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_connection_timed_out,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_broken_payload,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_connection_lost,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_unexpected_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_partial_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_bad_reply,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_bad_greeting,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_command_timed_out,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_command_aborted_early,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_deinit_early,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_service_failure,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_timeout,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_lookup_failure,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_authentication_failed,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch NULL
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Test client
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_client_defaults(struct smtp_client_settings *smtp_set)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* client settings */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_zero(smtp_set);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_set->my_hostname = "frop.example.com";
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_set->debug = debug;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_client_deinit(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (smtp_client != NULL)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client_deinit(&smtp_client);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch smtp_client = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Test server
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* client connection */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_input(struct connection *_conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn = (struct server_connection *)_conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const char *line;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_input(conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (;;) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->state == SERVER_CONNECTION_STATE_FINISH) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const unsigned char *data;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch size_t size;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int ret;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->dot_input == NULL)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->dot_input = i_stream_create_dot(conn->conn.input, TRUE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch while ((ret=i_stream_read_more(conn->dot_input,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch &data, &size)) > 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input_data != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input_data(conn, data, size) < 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_skip(conn->dot_input, size);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (ret == 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->dot_input->stream_errno != 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_error("Failed to read message payload: %s",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_get_error(conn->dot_input));
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 2.0.0 Ok: queued as 73BDE342129\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_MAIL_FROM;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch continue;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch line = i_stream_read_next_line(conn->conn.input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (line == NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (conn->conn.input->eof ||
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->conn.input->stream_errno != 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input_line != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input_line(conn, line) != 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (conn->state) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_EHLO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-testserver\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-PIPELINING\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250-ENHANCEDSTATUSCODES\r\n"
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 DSN\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_MAIL_FROM;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_MAIL_FROM:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (strncmp(line, "AUTH ", 5) == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "235 2.7.0 "
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "Authentication successful\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch continue;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 2.1.0 Ok\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_RCPT_TO;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch continue;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_RCPT_TO:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "250 2.1.5 Ok\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_DATA;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch continue;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_DATA:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "354 End data with <CR><LF>.<CR><LF>\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->state = SERVER_CONNECTION_STATE_FINISH;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch continue;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case SERVER_CONNECTION_STATE_FINISH:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_unreached();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_init(int fd)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pool_t pool;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch net_set_nonblock(fd, TRUE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pool = pool_alloconly_create("server connection", 256);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn = p_new(pool, struct server_connection, 1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch conn->pool = pool;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch connection_init_server
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (server_conn_list, &conn->conn, "server connection", fd, fd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_init != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_init(conn) != 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_input == NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch o_stream_send_str(conn->conn.output,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch "220 testserver ESMTP Testfix (Debian/GNU)\r\n");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_deinit(struct server_connection **_conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn = *_conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch *_conn = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (test_server_deinit != NULL)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_deinit(conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_stream_unref(&conn->dot_input);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch connection_deinit(&conn->conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch pool_unref(&conn->pool);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_destroy(struct connection *_conn)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch struct server_connection *conn =
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (struct server_connection *)_conn;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_deinit(&conn);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschserver_connection_accept(void *context ATTR_UNUSED)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int fd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* accept new client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch fd = net_accept(fd_listen, NULL, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (fd == -1)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (fd == -2) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("test server: accept() failed: %m");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_connection_init(fd);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/* */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic struct connection_settings server_connection_set = {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch .input_max_size = (size_t)-1,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch .output_max_size = (size_t)-1,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch .client = FALSE
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic const struct connection_vfuncs server_connection_vfuncs = {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch .destroy = server_connection_destroy,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch .input = server_connection_input
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch};
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_server_run(unsigned int index)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_index = index;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* open server socket */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_listen = io_add(fd_listen,
677b75f90d81eafe742896d6570a2f63ce501d05Josef 'Jeff' Sipek IO_READ, server_connection_accept, NULL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_conn_list = connection_list_init
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (&server_connection_set, &server_connection_vfuncs);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_run(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* close server socket */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_remove(&io_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch connection_list_deinit(&server_conn_list);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Tests
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic int test_open_server_fd(in_port_t *bind_port)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int fd = net_listen(&bind_ip, bind_port, 128);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("server listening on %u", *bind_port);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (fd == -1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("listen(%s:%u) failed: %m",
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch net_ip2addr(&bind_ip), *bind_port);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch return fd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_servers_kill_all(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int i;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_pids_count > 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < server_pids_count; i++) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_pids[i] != (pid_t)-1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)kill(server_pids[i], SIGKILL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)waitpid(server_pids[i], NULL, 0);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids[i] = -1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids_count = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (dns_pid != (pid_t)-1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)kill(dns_pid, SIGKILL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)waitpid(dns_pid, NULL, 0);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch dns_pid = (pid_t)-1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_run_client_server(
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch const struct smtp_client_settings *client_set,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_init_t client_test,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_server_init_t server_test,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int server_tests_count,
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_dns_init_t dns_test)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch unsigned int i;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids = NULL;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids_count = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_tests_count > 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int fds[server_tests_count];
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bind_ports = i_new(in_port_t, server_tests_count);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids = i_new(pid_t, server_tests_count);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < server_tests_count; i++)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids[i] = (pid_t)-1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids_count = server_tests_count;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < server_tests_count; i++)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch fds[i] = test_open_server_fd(&bind_ports[i]);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch for (i = 0; i < server_tests_count; i++) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch fd_listen = fds[i];
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if ((server_pids[i] = fork()) == (pid_t)-1)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("fork() failed: %m");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (server_pids[i] == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch lib_signals_ignore(SIGPIPE, TRUE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids[i] = (pid_t)-1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_pids_count = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch hostpid_init();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("server[%d]: PID=%s", i+1, my_pid);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* child: server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ioloop = io_loop_create();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch server_test(i);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_destroy(&ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_close_fd(&fd_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(bind_ports);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(server_pids);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* wait for it to be killed; this way, valgrind will not
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch object to this process going away inelegantly. */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(60);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch exit(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_close_fd(&fd_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("client: PID=%s", my_pid);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (dns_test != NULL) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int fd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_unlink_if_exists("./dns-test");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch fd = net_listen_unix("./dns-test", 128);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (fd == -1) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("listen(./dns-test) failed: %m");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch fd_listen = fd;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if ((dns_pid = fork()) == (pid_t)-1)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("fork() failed: %m");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (dns_pid == 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch lib_signals_ignore(SIGPIPE, TRUE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch dns_pid = (pid_t)-1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch hostpid_init();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (debug)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_debug("dns server: PID=%s", my_pid);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* child: server */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ioloop = io_loop_create();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch dns_test();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_destroy(&ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_close_fd(&fd_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* wait for it to be killed; this way, valgrind will not
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch object to this process going away inelegantly. */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch sleep(60);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch exit(1);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_close_fd(&fd_listen);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* parent: client */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch usleep(100000); /* wait a little for server setup */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch lib_signals_ignore(SIGPIPE, TRUE);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch ioloop = io_loop_create();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (client_test(client_set))
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_run(ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_client_deinit();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch io_loop_destroy(&ioloop);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_servers_kill_all();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(server_pids);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_free(bind_ports);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_unlink_if_exists("./dns-test");
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch/*
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch * Main
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschvolatile sig_atomic_t terminating = 0;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschtest_signal_handler(int signo)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch if (terminating != 0)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch raise(signo);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch terminating = 1;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* make sure we don't leave any pesky children alive */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_servers_kill_all();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(signo, SIG_DFL);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch raise(signo);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschstatic void test_atexit(void)
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_servers_kill_all();
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Boschint main(int argc, char *argv[])
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch{
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch int c;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch atexit(test_atexit);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGCHLD, SIG_IGN);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGTERM, test_signal_handler);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGQUIT, test_signal_handler);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGINT, test_signal_handler);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGSEGV, test_signal_handler);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch (void)signal(SIGABRT, test_signal_handler);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch while ((c = getopt(argc, argv, "D")) > 0) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch switch (c) {
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch case 'D':
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch debug = TRUE;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch break;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch default:
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_fatal("Usage: %s [-D]", argv[0]);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch }
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch /* listen on localhost */
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch i_zero(&bind_ip);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bind_ip.family = AF_INET;
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch bind_ip.u.ip4.s_addr = htonl(INADDR_LOOPBACK);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch test_run(test_functions);
9051b704ca26ef833544cf006134f25cddde2525Stephan Bosch}