From dcdb4581626eda840b14185a03d6d4ac0ded4952 Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 29 Jun 2016 06:46:06 +0000 Subject: [PATCH] Explicitely enclose SMTP transactions between BEGIN and COMMIT/ROLLBACK filter events. Bump filter API version. ok gilles@ jung@ --- usr.sbin/smtpd/filter.c | 7 ++--- usr.sbin/smtpd/smtp_session.c | 49 +++++++++++++++++++++++++---------- usr.sbin/smtpd/smtpd-api.h | 9 ++++--- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/usr.sbin/smtpd/filter.c b/usr.sbin/smtpd/filter.c index bc880ee4cf1..69aeccc3a6e 100644 --- a/usr.sbin/smtpd/filter.c +++ b/usr.sbin/smtpd/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.18 2016/05/16 19:25:05 gilles Exp $ */ +/* $OpenBSD: filter.c,v 1.19 2016/06/29 06:46:06 eric Exp $ */ /* * Copyright (c) 2011 Gilles Chehade @@ -847,8 +847,9 @@ event_to_str(int event) CASE(EVENT_CONNECT); CASE(EVENT_RESET); CASE(EVENT_DISCONNECT); - CASE(EVENT_COMMIT); - CASE(EVENT_ROLLBACK); + CASE(EVENT_TX_BEGIN); + CASE(EVENT_TX_COMMIT); + CASE(EVENT_TX_ROLLBACK); default: return "EVENT_???"; } diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index f8795607916..191cb1089c7 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.277 2016/06/23 11:56:19 eric Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.278 2016/06/29 06:46:06 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -77,6 +77,7 @@ enum session_flags { SF_BADINPUT = 0x0080, SF_FILTERCONN = 0x0100, SF_FILTERDATA = 0x0200, + SF_FILTERTX = 0x0400, }; enum message_flags { @@ -205,8 +206,9 @@ static void smtp_queue_rollback(struct smtp_session *); static void smtp_filter_connect(struct smtp_session *, struct sockaddr *); static void smtp_filter_rset(struct smtp_session *); static void smtp_filter_disconnect(struct smtp_session *); -static void smtp_filter_commit(struct smtp_session *); -static void smtp_filter_rollback(struct smtp_session *); +static void smtp_filter_tx_begin(struct smtp_session *); +static void smtp_filter_tx_commit(struct smtp_session *); +static void smtp_filter_tx_rollback(struct smtp_session *); static void smtp_filter_eom(struct smtp_session *); static void smtp_filter_helo(struct smtp_session *); static void smtp_filter_mail(struct smtp_session *); @@ -770,10 +772,12 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg) break; case LKA_PERMFAIL: + smtp_filter_tx_rollback(s); smtp_reply(s, "%d %s", 530, "Sender rejected"); io_reload(&s->io); break; case LKA_TEMPFAIL: + smtp_filter_tx_rollback(s); smtp_reply(s, "421 %s: Temporary Error", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); io_reload(&s->io); @@ -826,6 +830,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg) smtp_reply(s, "250 %s: Ok", esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); } else { + smtp_filter_tx_rollback(s); smtp_reply(s, "421 %s: Temporary Error", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); smtp_enter_state(s, STATE_QUIT); @@ -911,7 +916,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg) m_end(&m); s = tree_xpop(&wait_queue_commit, reqid); if (!success) { - smtp_filter_rollback(s); + smtp_filter_tx_rollback(s); smtp_reply(s, "421 %s: Temporary failure", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); smtp_enter_state(s, STATE_QUIT); @@ -919,7 +924,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg) return; } - smtp_filter_commit(s); + smtp_filter_tx_commit(s); smtp_reply(s, "250 %s: %08x Message accepted for delivery", esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS), evpid_to_msgid(s->tx->evp.id)); @@ -1114,7 +1119,7 @@ smtp_filter_response(uint64_t id, int query, int status, uint32_t code, case QUERY_MAIL: if (status != FILTER_OK) { - smtp_filter_rollback(s); + smtp_filter_tx_rollback(s); code = code ? code : 530; line = line ? line : "Sender rejected"; smtp_reply(s, "%d %s", code, line); @@ -1166,7 +1171,7 @@ smtp_filter_response(uint64_t id, int query, int status, uint32_t code, case QUERY_EOM: if (status != FILTER_OK) { tree_pop(&wait_filter_data, s->id); - smtp_filter_rollback(s); + smtp_filter_tx_rollback(s); smtp_queue_rollback(s); code = code ? code : 530; line = line ? line : "Message rejected"; @@ -1502,7 +1507,7 @@ smtp_data_io_done(struct smtp_session *s) tree_pop(&wait_filter_data, s->id); - smtp_filter_rollback(s); + smtp_filter_tx_rollback(s); smtp_queue_rollback(s); if (s->tx->msgflags & MF_ERROR_SIZE) @@ -1739,6 +1744,7 @@ smtp_command(struct smtp_session *s, char *line) if (args && smtp_parse_mail_args(s, args) == -1) break; + smtp_filter_tx_begin(s); smtp_filter_mail(s); break; /* @@ -1780,11 +1786,13 @@ smtp_command(struct smtp_session *s, char *line) break; } - smtp_filter_rset(s); - + if (s->flags & SF_FILTERTX) + smtp_filter_tx_rollback(s); if (s->tx->evp.id) smtp_queue_rollback(s); + smtp_filter_rset(s); + s->phase = PHASE_SETUP; smtp_message_reset(s, 0); smtp_reply(s, "250 %s: Reset state", @@ -2130,6 +2138,7 @@ smtp_message_end(struct smtp_session *s) s->phase = PHASE_SETUP; if (s->tx->msgflags & MF_ERROR) { + smtp_filter_tx_rollback(s); smtp_queue_rollback(s); if (s->tx->msgflags & MF_ERROR_SIZE) smtp_reply(s, "554 %s %s: Transaction failed, message too big", @@ -2266,6 +2275,9 @@ smtp_free(struct smtp_session *s, const char * reason) iobuf_clear(&s->tx->obuf); } + if (s->flags & SF_FILTERTX) + smtp_filter_tx_rollback(s); + if (s->flags & SF_FILTERCONN) smtp_filter_disconnect(s); @@ -2530,15 +2542,24 @@ smtp_filter_rset(struct smtp_session *s) } static void -smtp_filter_commit(struct smtp_session *s) +smtp_filter_tx_begin(struct smtp_session *s) +{ + s->flags |= SF_FILTERTX; + filter_event(s->id, EVENT_TX_BEGIN); +} + +static void +smtp_filter_tx_commit(struct smtp_session *s) { - filter_event(s->id, EVENT_COMMIT); + s->flags &= ~SF_FILTERTX; + filter_event(s->id, EVENT_TX_COMMIT); } static void -smtp_filter_rollback(struct smtp_session *s) +smtp_filter_tx_rollback(struct smtp_session *s) { - filter_event(s->id, EVENT_ROLLBACK); + s->flags &= ~SF_FILTERTX; + filter_event(s->id, EVENT_TX_ROLLBACK); } static void diff --git a/usr.sbin/smtpd/smtpd-api.h b/usr.sbin/smtpd/smtpd-api.h index ecac08494fa..9a7b3308293 100644 --- a/usr.sbin/smtpd/smtpd-api.h +++ b/usr.sbin/smtpd/smtpd-api.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd-api.h,v 1.29 2016/02/09 22:18:17 gilles Exp $ */ +/* $OpenBSD: smtpd-api.h,v 1.30 2016/06/29 06:46:06 eric Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -20,7 +20,7 @@ #ifndef _SMTPD_API_H_ #define _SMTPD_API_H_ -#define FILTER_API_VERSION 50 +#define FILTER_API_VERSION 51 struct mailaddr { char user[SMTPD_MAXLOCALPARTSIZE]; @@ -59,8 +59,9 @@ enum filter_event_type { EVENT_CONNECT, EVENT_RESET, EVENT_DISCONNECT, - EVENT_COMMIT, - EVENT_ROLLBACK, + EVENT_TX_BEGIN, + EVENT_TX_COMMIT, + EVENT_TX_ROLLBACK, }; /* XXX - server side requires mfa_session.c update on filter_hook changes */ -- 2.20.1