Hi, Experimental support for filters has been removed some time ago from the config parser. Now we want to get rid of the remaining code. It's not that trivial, so we proceed in several steps.
The first (and trickiest) one is to bypass the filter code for incoming smtp sessions, so that filter.c can be unhooked. This is what the following diff does: - drop filter configuration, - drop filter events, - simulate a positive reply for all filter queries, - write message content directly to the file. There should be no functionnal change. Eric. Index: pony.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/pony.c,v retrieving revision 1.17 diff -u -p -r1.17 pony.c --- pony.c 9 Jan 2017 09:53:23 -0000 1.17 +++ pony.c 3 Aug 2017 09:57:22 -0000 @@ -60,7 +60,7 @@ pony_imsg(struct mproc *p, struct imsg * case IMSG_CONF_START: return; case IMSG_CONF_END: - filter_configure(); + smtp_configure(); return; case IMSG_CTL_VERBOSE: m_msg(&m, imsg); @@ -148,7 +148,6 @@ pony(void) mda_postfork(); mta_postfork(); smtp_postfork(); - filter_postfork(); /* do not purge listeners and pki, they are purged * in smtp_configure() Index: smtp_session.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v retrieving revision 1.304 diff -u -p -r1.304 smtp_session.c --- smtp_session.c 19 Jun 2017 08:35:56 -0000 1.304 +++ smtp_session.c 4 Aug 2017 10:32:41 -0000 @@ -69,9 +69,6 @@ enum session_flags { SF_BOUNCE = 0x0010, SF_VERIFIED = 0x0020, SF_BADINPUT = 0x0080, - SF_FILTERCONN = 0x0100, - SF_FILTERDATA = 0x0200, - SF_FILTERTX = 0x0400, }; enum message_flags { @@ -116,7 +113,7 @@ struct smtp_tx { size_t datain; size_t odatalen; - struct io *oev; + FILE *ofile; int hdrdone; int rcvcount; int dataeom; @@ -167,7 +164,6 @@ static void smtp_connected(struct smtp_s static void smtp_send_banner(struct smtp_session *); static void smtp_tls_verified(struct smtp_session *); static void smtp_io(struct io *, int, void *); -static void smtp_data_io(struct io *, int, void *); static void smtp_data_io_done(struct smtp_session *); static void smtp_enter_state(struct smtp_session *, int); static void smtp_reply(struct smtp_session *, char *, ...); @@ -194,11 +190,6 @@ static void smtp_queue_commit(struct smt 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_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 *); @@ -728,12 +719,10 @@ smtp_session_imsg(struct mproc *p, struc break; case LKA_PERMFAIL: - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); smtp_reply(s, "%d %s", 530, "Sender rejected"); break; case LKA_TEMPFAIL: - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); smtp_reply(s, "421 %s: Temporary Error", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); @@ -785,7 +774,6 @@ smtp_session_imsg(struct mproc *p, struc smtp_reply(s, "250 %s: Ok", esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); } else { - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); smtp_reply(s, "421 %s: Temporary Error", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); @@ -813,7 +801,7 @@ smtp_session_imsg(struct mproc *p, struc log_debug("smtp: %p: fd %d from queue", s, imsg->fd); tree_xset(&wait_filter, s->id, s); - filter_build_fd_chain(s->id, imsg->fd); + smtp_filter_fd(s->id, imsg->fd); return; case IMSG_QUEUE_ENVELOPE_SUBMIT: @@ -869,7 +857,6 @@ smtp_session_imsg(struct mproc *p, struc m_end(&m); s = tree_xpop(&wait_queue_commit, reqid); if (!success) { - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); smtp_reply(s, "421 %s: Temporary failure", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); @@ -877,7 +864,6 @@ smtp_session_imsg(struct mproc *p, struc return; } - smtp_filter_tx_commit(s); smtp_reply(s, "250 %s: %08x Message accepted for delivery", esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS), s->tx->msgid); @@ -1093,7 +1079,6 @@ smtp_filter_response(uint64_t id, int qu case QUERY_MAIL: if (status != FILTER_OK) { - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); code = code ? code : 530; line = line ? line : "Sender rejected"; @@ -1143,7 +1128,6 @@ smtp_filter_response(uint64_t id, int qu case QUERY_EOM: if (status != FILTER_OK) { tree_pop(&wait_filter_data, s->id); - smtp_filter_tx_rollback(s); smtp_queue_rollback(s); smtp_tx_free(s->tx); code = code ? code : 530; @@ -1170,26 +1154,25 @@ smtp_filter_fd(uint64_t id, int fd) log_debug("smtp: %p: fd %d from filter", s, fd); - if (fd == -1) { + if (fd == -1 || (s->tx->ofile = fdopen(fd, "w")) == NULL) { + if (fd != -1) + close(fd); smtp_reply(s, "421 %s: Temporary Error", esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS)); smtp_enter_state(s, STATE_QUIT); return; } - io_set_nonblocking(fd); - s->tx->oev = io_new(); - io_set_callback(s->tx->oev, smtp_data_io, s); - io_set_fd(s->tx->oev, fd); + s->tx->odatalen = 0; - io_print(s->tx->oev, "Received: "); + smtp_message_printf(s, "Received: "); if (!(s->listener->flags & F_MASK_SOURCE)) { - io_printf(s->tx->oev, "from %s (%s [%s])", + smtp_message_printf(s, "from %s (%s [%s])", s->helo, s->hostname, ss_to_text(&s->ss)); } - io_printf(s->tx->oev, "\n\tby %s (%s) with %sSMTP%s%s id %08x", + smtp_message_printf(s, "\n\tby %s (%s) with %sSMTP%s%s id %08x", s->smtpname, SMTPD_NAME, s->flags & SF_EHLO ? "E" : "", @@ -1199,7 +1182,7 @@ smtp_filter_fd(uint64_t id, int fd) if (s->flags & SF_SECURE) { x = SSL_get_peer_certificate(io_ssl(s->io)); - io_printf(s->tx->oev, " (%s:%s:%d:%s)", + smtp_message_printf(s, " (%s:%s:%d:%s)", SSL_get_version(io_ssl(s->io)), SSL_get_cipher_name(io_ssl(s->io)), SSL_get_cipher_bits(io_ssl(s->io), NULL), @@ -1207,23 +1190,20 @@ smtp_filter_fd(uint64_t id, int fd) X509_free(x); if (s->listener->flags & F_RECEIVEDAUTH) { - io_printf(s->tx->oev, " auth=%s", s->username[0] ? "yes" : "no"); + smtp_message_printf(s, " auth=%s", + s->username[0] ? "yes" : "no"); if (s->username[0]) - io_printf(s->tx->oev, " user=%s", s->username); + smtp_message_printf(s, " user=%s", s->username); } } if (s->tx->rcptcount == 1) { - io_printf(s->tx->oev, "\n\tfor <%s@%s>", + smtp_message_printf(s, "\n\tfor <%s@%s>", s->tx->evp.rcpt.user, s->tx->evp.rcpt.domain); } - io_printf(s->tx->oev, ";\n\t%s\n", time_to_text(time(NULL))); - - s->tx->odatalen = io_queued(s->tx->oev); - - io_set_write(s->tx->oev); + smtp_message_printf(s, ";\n\t%s\n", time_to_text(time(NULL))); smtp_enter_state(s, STATE_BODY); smtp_reply(s, "354 Enter mail, end with \".\"" @@ -1311,8 +1291,7 @@ smtp_io(struct io *io, int evt, void *ar io_set_write(io); s->tx->dataeom = 1; - if (io_queued(s->tx->oev) == 0) - smtp_data_io_done(s); + smtp_data_io_done(s); return; } @@ -1443,8 +1422,8 @@ smtp_tx_free(struct smtp_tx *tx) free(rcpt); } - if (tx->oev) - io_free(tx->oev); + if (tx->ofile) + fclose(tx->ofile); tx->session->tx = NULL; @@ -1452,56 +1431,14 @@ smtp_tx_free(struct smtp_tx *tx) } static void -smtp_data_io(struct io *io, int evt, void *arg) -{ - struct smtp_session *s = arg; - - log_trace(TRACE_IO, "smtp: %p (data): %s %s", s, io_strevent(evt), - io_strio(io)); - - switch (evt) { - case IO_TIMEOUT: - case IO_DISCONNECTED: - case IO_ERROR: - log_debug("debug: smtp: %p: io error on mfa", s); - io_free(s->tx->oev); - s->tx->oev = NULL; - s->tx->msgflags |= MF_ERROR_IO; - if (io_paused(s->io, IO_IN)) { - log_debug("debug: smtp: %p: resuming session after mfa error", s); - io_resume(s->io, IO_IN); - } - break; - - case IO_LOWAT: - if (io_paused(s->io, IO_IN)) { - log_debug("debug: smtp: %p: filter congestion over: resuming session", s); - io_resume(s->io, IO_IN); - } - if (s->tx->dataeom && io_queued(s->tx->oev) == 0) - smtp_data_io_done(s); - break; - - default: - fatalx("smtp_data_io()"); - } -} - -static void smtp_data_io_done(struct smtp_session *s) { log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->tx->odatalen); - if (s->tx->oev) { - io_free(s->tx->oev); - s->tx->oev = NULL; - } - if (s->tx->msgflags & MF_ERROR) { tree_pop(&wait_filter_data, s->id); - smtp_filter_tx_rollback(s); smtp_queue_rollback(s); if (s->tx->msgflags & MF_ERROR_SIZE) @@ -1600,7 +1537,7 @@ smtp_command(struct smtp_session *s, cha break; } (void)strlcpy(s->helo, args, sizeof(s->helo)); - s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED | SF_FILTERCONN; + s->flags &= SF_SECURE | SF_AUTHENTICATED | SF_VERIFIED; if (cmd == CMD_EHLO) { s->flags |= SF_EHLO; s->flags |= SF_8BITMIME; @@ -1743,7 +1680,6 @@ smtp_command(struct smtp_session *s, cha break; } - smtp_filter_tx_begin(s); smtp_filter_mail(s); break; /* @@ -1786,13 +1722,11 @@ smtp_command(struct smtp_session *s, cha } if (s->tx) { - smtp_filter_tx_rollback(s); if (s->tx->msgid) smtp_queue_rollback(s); smtp_tx_free(s->tx); } - smtp_filter_rset(s); smtp_reply(s, "250 %s: Reset state", esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS)); break; @@ -2103,7 +2037,6 @@ smtp_connected(struct smtp_session *s) return; } - s->flags |= SF_FILTERCONN; smtp_filter_connect(s, (struct sockaddr *)&ss); } @@ -2131,7 +2064,6 @@ smtp_message_end(struct smtp_session *s) tree_xpop(&wait_filter_data, s->id); 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", @@ -2144,6 +2076,9 @@ smtp_message_end(struct smtp_session *s) return; } + fclose(s->tx->ofile); + s->tx->ofile = NULL; + smtp_queue_commit(s); } @@ -2157,7 +2092,7 @@ smtp_message_printf(struct smtp_session return -1; va_start(ap, fmt); - len = io_vprintf(s->tx->oev, fmt, ap); + len = vfprintf(s->tx->ofile, fmt, ap); va_end(ap); if (len < 0) { @@ -2236,13 +2171,9 @@ smtp_free(struct smtp_session *s, const if (s->tx) { if (s->tx->msgid) smtp_queue_rollback(s); - smtp_filter_tx_rollback(s); smtp_tx_free(s->tx); } - if (s->flags & SF_FILTERCONN) - smtp_filter_disconnect(s); - if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS) stat_decrement("smtp.smtps", 1); if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS) @@ -2488,83 +2419,45 @@ smtp_queue_rollback(struct smtp_session } static void -smtp_filter_rset(struct smtp_session *s) -{ - filter_event(s->id, EVENT_RESET); -} - -static void -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) -{ - s->flags &= ~SF_FILTERTX; - filter_event(s->id, EVENT_TX_COMMIT); -} - -static void -smtp_filter_tx_rollback(struct smtp_session *s) -{ - s->flags &= ~SF_FILTERTX; - filter_event(s->id, EVENT_TX_ROLLBACK); -} - -static void -smtp_filter_disconnect(struct smtp_session *s) -{ - filter_event(s->id, EVENT_DISCONNECT); -} - -static void smtp_filter_connect(struct smtp_session *s, struct sockaddr *sa) { - char *filter; - tree_xset(&wait_filter, s->id, s); - - filter = s->listener->filter[0] ? s->listener->filter : NULL; - - filter_connect(s->id, sa, (struct sockaddr *)&s->ss, s->hostname, filter); + smtp_filter_response(s->id, QUERY_CONNECT, FILTER_OK, 0, NULL); } static void smtp_filter_eom(struct smtp_session *s) { tree_xset(&wait_filter, s->id, s); - filter_eom(s->id, QUERY_EOM, s->tx->odatalen); + smtp_filter_response(s->id, QUERY_EOM, FILTER_OK, 0, NULL); } static void smtp_filter_helo(struct smtp_session *s) { tree_xset(&wait_filter, s->id, s); - filter_line(s->id, QUERY_HELO, s->helo); + smtp_filter_response(s->id, QUERY_HELO, FILTER_OK, 0, NULL); } static void smtp_filter_mail(struct smtp_session *s) { tree_xset(&wait_filter, s->id, s); - filter_mailaddr(s->id, QUERY_MAIL, &s->tx->evp.sender); + smtp_filter_response(s->id, QUERY_MAIL, FILTER_OK, 0, NULL); } static void smtp_filter_rcpt(struct smtp_session *s) { tree_xset(&wait_filter, s->id, s); - filter_mailaddr(s->id, QUERY_RCPT, &s->tx->evp.rcpt); + smtp_filter_response(s->id, QUERY_RCPT, FILTER_OK, 0, NULL); } static void smtp_filter_data(struct smtp_session *s) { tree_xset(&wait_filter, s->id, s); - filter_line(s->id, QUERY_DATA, NULL); + smtp_filter_response(s->id, QUERY_DATA, FILTER_OK, 0, NULL); } static void @@ -2624,11 +2517,6 @@ smtp_filter_dataline(struct smtp_session if (ret == 0) { s->tx->msgflags |= MF_ERROR_MALFORMED; return; - } - - if (io_queued(s->tx->oev) > DATA_HIWAT && !io_paused(s->io, IO_IN)) { - log_debug("debug: smtp: %p: filter congestion: pausing session", s); - io_pause(s->io, IO_IN); } } Index: smtpd.h =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v retrieving revision 1.533 diff -u -p -r1.533 smtpd.h --- smtpd.h 27 Jul 2017 18:48:30 -0000 1.533 +++ smtpd.h 4 Aug 2017 09:53:16 -0000 @@ -1200,18 +1200,6 @@ int expand_to_text(struct expand *, char RB_PROTOTYPE(expandtree, expandnode, nodes, expand_cmp); -/* filter.c */ -void filter_postfork(void); -void filter_configure(void); -void filter_connect(uint64_t, const struct sockaddr *, - const struct sockaddr *, const char *, const char *); -void filter_mailaddr(uint64_t, int, const struct mailaddr *); -void filter_line(uint64_t, int, const char *); -void filter_eom(uint64_t, int, size_t); -void filter_event(uint64_t, int); -void filter_build_fd_chain(uint64_t, int); - - /* forward.c */ int forwards_get(int, struct expand *); Index: smtpd/Makefile =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtpd/Makefile,v retrieving revision 1.87 diff -u -p -r1.87 Makefile --- smtpd/Makefile 26 May 2017 21:30:00 -0000 1.87 +++ smtpd/Makefile 3 Aug 2017 09:55:57 -0000 @@ -17,7 +17,6 @@ SRCS+= dns.c SRCS+= envelope.c SRCS+= esc.c SRCS+= expand.c -SRCS+= filter.c SRCS+= forward.c SRCS+= iobuf.c SRCS+= ioev.c