On Fri, Aug 04, 2017 at 01:13:06PM +0200, Eric Faurot wrote:
> 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.
>
this should be tested by many people right away to spot subtle regressions
ok gilles@
> 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
>
--
Gilles Chehade
https://www.poolp.org @poolpOrg