From: Stephan Bosch Date: Mon, 12 Apr 2021 19:18:05 +0000 (+0200) Subject: lib-smtp: fuzz-smtp-server - Implement all callbacks required for full transaction. X-Git-Tag: 2.3.15~89 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d76fa500be66c0c073015cf9be6dc8f0c7ac001;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: fuzz-smtp-server - Implement all callbacks required for full transaction. Before required RCPT and DATA callbacks were omitted, causing assertion failures when the fuzzer reached the RCPT stage. --- diff --git a/src/lib-smtp/fuzz-smtp-server.c b/src/lib-smtp/fuzz-smtp-server.c index baad599822..4b5d21d372 100644 --- a/src/lib-smtp/fuzz-smtp-server.c +++ b/src/lib-smtp/fuzz-smtp-server.c @@ -2,9 +2,62 @@ #include "lib.h" #include "fuzzer.h" +#include "istream.h" #include "ioloop.h" #include "smtp-server.h" +static struct { + struct istream *data_input; +} state = { + .data_input = NULL, +}; + +static int +server_cmd_rcpt(void *conn_ctx ATTR_UNUSED, + struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct smtp_server_recipient *rcpt ATTR_UNUSED) +{ + return 1; +} + +static int +server_cmd_data_continue(void *conn_ctx ATTR_UNUSED, + struct smtp_server_cmd_ctx *cmd, + struct smtp_server_transaction *trans ATTR_UNUSED) +{ + struct istream *data_input = state.data_input; + const unsigned char *data; + size_t size; + ssize_t ret; + + while ((ret = i_stream_read(data_input)) > 0 || ret == -2) { + data = i_stream_get_data(data_input, &size); + i_stream_skip(data_input, size); + if (!smtp_server_cmd_data_check_size(cmd)) + return -1; + } + + if (ret == 0) + return 0; + if (ret < 0 && data_input->stream_errno != 0) { + /* Client probably disconnected */ + return -1; + } + + smtp_server_reply_all(cmd, 250, "2.0.0", "Accepted"); + return 1; +} + +static int +server_cmd_data_begin(void *conn_ctx ATTR_UNUSED, + struct smtp_server_cmd_ctx *cmd ATTR_UNUSED, + struct smtp_server_transaction *trans ATTR_UNUSED, + struct istream *data_input) +{ + state.data_input = data_input; + return 0; +} + static void server_connection_free(void *context) { struct fuzzer_context *ctx = context; @@ -26,12 +79,15 @@ FUZZ_BEGIN_FD .auth_optional = TRUE, }; struct smtp_server_callbacks server_callbacks = { + .conn_cmd_rcpt = server_cmd_rcpt, + .conn_cmd_data_begin = server_cmd_data_begin, + .conn_cmd_data_continue = server_cmd_data_continue, .conn_free = server_connection_free, }; struct smtp_server *smtp_server = NULL; struct timeout *to; - to = timeout_add_short(0, test_server_continue, &fuzz_ctx); + to = timeout_add_short(10, test_server_continue, &fuzz_ctx); smtp_server = smtp_server_init(&smtp_server_set); conn = smtp_server_connection_create(smtp_server, fuzz_ctx.fd, fuzz_ctx.fd, NULL, 0,