A message with a single successful recipient but with a failed rcpt to: command afterward generates an incorrect Received: header.
The following produces the bug: thief$ nc localhost 25 220 thief.private ESMTP OpenSMTPD ehlo thief.private^M 250-thief.private Hello thief.private [127.0.0.1], pleased to meet you 250-8BITMIME 250-ENHANCEDSTATUSCODES 250-SIZE 36700160 250-DSN 250 HELP mail from:<me>^M 250 2.0.0 Ok rcpt to:<me>^M 250 2.1.5 Destination address valid: Recipient ok rcpt to:<nonexistant>^M 550 Invalid recipient: <nonexistant@thief.private> data^M 354 Enter mail, end with "." on a line by itself From:<me>^M ^M test^M .^M 250 2.0.0 8f9363cc Message accepted for delivery quit^M 221 2.0.0 Bye thief$ This gives the following message (I have the mask-src option set here): Date: Sat, 8 Oct 2022 12:08:48 -0600 (MDT) From: me@thief.private Return-Path: <me@thief.private> Delivered-To: me@thief.private Received: by thief.private (OpenSMTPD) with ESMTP id 8f9363cc for <nonexistant@thief.private>; Sat, 8 Oct 2022 12:08:48 -0600 (MDT) Message-ID: <ba820306321af158@thief.private> test The following patch fixes the problem: Index: smtp_session.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v retrieving revision 1.432 diff -u -p -r1.432 smtp_session.c --- smtp_session.c 1 Jul 2021 07:42:16 -0000 1.432 +++ smtp_session.c 8 Oct 2022 18:04:51 -0000 @@ -2732,6 +2732,7 @@ static void smtp_message_begin(struct smtp_tx *tx) { struct smtp_session *s; + struct smtp_rcpt *srfp; int (*m_printf)(struct smtp_tx *, const char *, ...); m_printf = smtp_message_printf; @@ -2780,10 +2781,13 @@ smtp_message_begin(struct smtp_tx *tx) } } + /* If we get failed "RCPT TO" commands that modify tx->evp, then + * make sure we use the real recipient for the "for" clause */ if (tx->rcptcount == 1) { + srfp = TAILQ_FIRST(&tx->rcpts); m_printf(tx, "\n\tfor <%s@%s>", - tx->evp.rcpt.user, - tx->evp.rcpt.domain); + srfp->maddr.user, + srfp->maddr.domain); } m_printf(tx, ";\n\t%s\n", time_to_text(time(&tx->time))); I use OpenSMTPD on OpenBSD for my personal mail, and it's great. Happy to contribute in any way I can. Thank you for all you do.