From 5bfc3fefb85490547c9e8bb071fa1d8b9953dd6f Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 9 Feb 2018 09:29:03 +0000 Subject: [PATCH] isolate calls to the rfc2822 parser and handling of "." in smtp_dataline() ok gilles@ --- usr.sbin/smtpd/smtp_session.c | 52 ++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 5e7a91eb775..61ed2cac853 100644 --- a/usr.sbin/smtpd/smtp_session.c +++ b/usr.sbin/smtpd/smtp_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp_session.c,v 1.315 2017/11/18 08:23:14 eric Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.316 2018/02/09 09:29:03 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -186,7 +186,7 @@ static void smtp_queue_open_message(struct smtp_session *); static void smtp_queue_commit(struct smtp_session *); static void smtp_queue_rollback(struct smtp_session *); -static void smtp_dataline(struct smtp_session *, const char *); +static int smtp_dataline(struct smtp_session *, const char *); static struct { int code; const char *cmd; } commands[] = { { CMD_HELO, "HELO" }, @@ -974,6 +974,7 @@ smtp_io(struct io *io, int evt, void *arg) struct smtp_session *s = arg; char *line; size_t len; + int eom; log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), io_strio(io)); @@ -1021,9 +1022,11 @@ smtp_io(struct io *io, int evt, void *arg) return; /* Message body */ - if (s->state == STATE_BODY && strcmp(line, ".")) { - smtp_dataline(s, line); - goto nextline; + eom = 0; + if (s->state == STATE_BODY) { + eom = smtp_dataline(s, line); + if (eom == 0) + goto nextline; } /* Pipelining not supported */ @@ -1037,15 +1040,9 @@ smtp_io(struct io *io, int evt, void *arg) return; } - /* End of body */ - if (s->state == STATE_BODY) { - log_trace(TRACE_SMTP, "<<< [EOM]"); - - rfc2822_parser_flush(&s->tx->rfc2822_parser); - - io_set_write(io); - + if (eom) { smtp_message_end(s); + io_set_write(io); return; } @@ -2208,16 +2205,23 @@ smtp_queue_rollback(struct smtp_session *s) m_close(p_queue); } -static void +static int smtp_dataline(struct smtp_session *s, const char *line) { int ret; log_trace(TRACE_SMTP, "<<< [MSG] %s", line); + if (!strcmp(line, ".")) { + log_trace(TRACE_SMTP, "<<< [EOM]"); + if (!s->tx->error) + rfc2822_parser_flush(&s->tx->rfc2822_parser); + return 1; + } + /* ignore data line if an error is set */ if (s->tx->error) - return; + return 0; /* escape lines starting with a '.' */ if (line[0] == '.') @@ -2227,20 +2231,20 @@ smtp_dataline(struct smtp_session *s, const char *line) s->tx->datain += strlen(line) + 1; if (s->tx->datain > env->sc_maxsize) { s->tx->error = TX_ERROR_SIZE; - return; + return 0; } if (!s->tx->hdrdone) { /* folded header that must be skipped */ if (isspace((unsigned char)line[0]) && s->tx->skiphdr) - return; + return 0; s->tx->skiphdr = 0; /* BCC should be stripped from headers */ if (strncasecmp("bcc:", line, 4) == 0) { s->tx->skiphdr = 1; - return; + return 0; } /* check for loop */ @@ -2249,7 +2253,7 @@ smtp_dataline(struct smtp_session *s, const char *line) if (s->tx->rcvcount == MAX_HOPS_COUNT) { s->tx->error = TX_ERROR_LOOP; log_warnx("warn: loop detected"); - return; + return 0; } if (line[0] == '\0') @@ -2257,15 +2261,13 @@ smtp_dataline(struct smtp_session *s, const char *line) } ret = rfc2822_parser_feed(&s->tx->rfc2822_parser, line); - if (ret == -1) { + if (ret == -1) s->tx->error = TX_ERROR_RESOURCES; - return; - } - if (ret == 0) { + if (ret == 0) s->tx->error = TX_ERROR_MALFORMED; - return; - } + + return 0; } #define CASE(x) case x : return #x -- 2.20.1