Hi

[2024-04-15 10:11] Lévai, Dániel <l...@ecentrum.hu>
> I've been using this Samsung C480FW printer/scanner forever with OpenSMTPD 
> and suddenly (no upgrades to OpenSMTPD or changes in the 
> configuration) it started to complain (it's trying to send scanned documents 
> via e-mail):

Has something on the scanner changed? Like a firmwareupdate or changed
settings. Something must have changed, when it has worked and now it
doesn't work anymore.

>
> [...]
>
> When I issue an SMTP test on the printer admin page, this is what happens in 
> smtpd:
> # smtpd -d -Tall
> [...]
> smtp: 0xa146908b000: >>> 354 Enter mail, end with "." on a line by itself
> smtp: 0xa146908b000: STATE_HELO -> STATE_BODY
> smtp: 0xa146908b000: IO_LOWAT <io:0xa14d67bfd00 fd=17 to=300000 fl=W 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=0 ob=0>
> smtp: 0xa146908b000: IO_DATAIN <io:0xa14d67bfd00 fd=17 to=300000 fl=R 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=360 ob=0>
> <<< [MSG] From:"Device Administrator"<l...@ecentrum.hu>
> <<< [MSG] To: "Device Administrator"<l...@ecentrum.hu>
> <<< [MSG] Subject:=?utf-8?B?VGVzdCBNZXNzYWdl?=
> <<< [MSG] MIME-Version: 1.0
> <<< [MSG] Content-Type: MULTIPART/MIXED; 
> BOUNDARY="----=_NextPart_2948fd8e_345963ff_126832f6.29a9d5e8"
> <<< [MSG] Content-features:
> <<< [MSG]       (& (dpi=100) (dpi-xyratio=[100/200]))
> <<< [MSG]
> <<< [MSG] ------=_NextPart_2948fd8e_345963ff_126832f6.29a9d5e8
> smtp: 0xa146908b000: IO_DATAIN <io:0xa14d67bfd00 fd=17 to=300000 fl=R 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=46 ob=0>
> <<< [MSG] Content-Type: TEXT/PLAIN; charset=US-ASCII
> <<< [MSG]
> smtp: 0xa146908b000: IO_DATAIN <io:0xa14d67bfd00 fd=17 to=300000 fl=R 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=17 ob=0>
> smtp: 0xa146908b000: IO_DATAIN <io:0xa14d67bfd00 fd=17 to=300000 fl=R 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=75 ob=0>
> <<< [MSG] Test mail sending
> <<< [MSG] ------=_NextPart_2948fd8e_345963ff_126832f6.29a9d5e8--
> smtp: 0xa146908b000: IO_DATAIN <io:0xa14d67bfd00 fd=17 to=300000 fl=R 
> tls=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384 ib=3 ob=0>
> <<< [MSG] .
> <<< [EOM]
> smtp: 0xa146908b000: >>> 550 5.7.1 Delivery not authorized, message refused: 
> Message is not RFC 2822 compliant
> 1d1e5bc4223e33ab smtp failed-command command="DATA" result="550 5.7.1 
> Delivery not authorized, message refused: Message is not RFC 2822 compliant"

Thanks for the full debug log. I would say this is the intresting part.

> It's somewhere after DATA smtpd doesn't like what it's seeing.

Actually I don't see why this message is not accepted. Only think I can
imagen is that the Content-features field is not properly folded. So that
the character used to indent is not WSP (space or horizontal tab). But
this is only a guess.

The attached patch adds a few more tracing information for the parser. Can
you apply this patch and try again?

> Can I somehow relax some checks in smtpd.conf to allow - a possible broken - 
> SMTP implementation to work reliably?

No, the parser is quite basic and only checks for the bare minimum to be
considderd a mail. A Message failing this parser probaly causing problems
in other programms handling the mail.

Philipp
diff --git a/usr.sbin/smtpd/rfc5322.c b/usr.sbin/smtpd/rfc5322.c
index e009ba77..00a3271d 100644
--- a/usr.sbin/smtpd/rfc5322.c
+++ b/usr.sbin/smtpd/rfc5322.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "smtpd.h"
 #include "rfc5322.h"
 
 struct buf {
@@ -136,8 +137,10 @@ _rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
 			parser->next = 1;
 			if (parser->unfold) {
 				if (buf_cat(&parser->val, "\n") == -1 ||
-				    buf_cat(&parser->val, line) == -1)
+				    buf_cat(&parser->val, line) == -1) {
+					log_trace(TRACE_SMTP, "rfc5322 parser: buf_cat failed");
 					return -1;
+				}
 			}
 			res->value = line;
 			return RFC5322_HEADER_CONT;
@@ -155,8 +158,10 @@ _rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
 		if (line && line[0] != ' ' && line[0] != '\t' &&
 		    (pos = strchr(line, ':'))) {
 			len = pos - line;
-			if (buf_grow(&parser->hdr, len + 1) == -1)
+			if (buf_grow(&parser->hdr, len + 1) == -1) {
+				log_trace(TRACE_SMTP, "rfc5322 parser: buf_grow failed");
 				return -1;
+			}
 			(void)memcpy(parser->hdr.buf, line, len);
 			parser->hdr.buf[len] = '\0';
 			parser->hdr.buflen = len + 1;
@@ -181,6 +186,7 @@ _rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
 			return RFC5322_BODY_START;
 		}
 
+		log_trace(TRACE_SMTP, "rfc5322 parser: invalide BODY seperator");
 		errno = EINVAL;
 		return -1;
 
@@ -195,10 +201,12 @@ _rfc5322_next(struct rfc5322_parser *parser, struct rfc5322_result *res)
 		return RFC5322_BODY;
 
 	case RFC5322_END_OF_MESSAGE:
+		log_trace(TRACE_SMTP, "rfc5322 parser: line after EOM (bug)");
 		errno = ENOMSG;
 		return -1;
 
 	default:
+		log_trace(TRACE_SMTP, "rfc5322 parser: unknown state %i", parser->state);
 		errno = EINVAL;
 		return -1;
 	}
diff --git a/usr.sbin/smtpd/rfc5322.h b/usr.sbin/smtpd/rfc5322.h
index 0979bd4c..e0f79009 100644
--- a/usr.sbin/smtpd/rfc5322.h
+++ b/usr.sbin/smtpd/rfc5322.h
@@ -31,6 +31,31 @@ struct rfc5322_result {
 #define	RFC5322_BODY		6
 #define	RFC5322_END_OF_MESSAGE	7
 
+static const char *
+rfc5322_state_string(int s)
+{
+	switch (s) {
+	case RFC5322_ERR:
+		return "RFC5322_ERR";
+	case RFC5322_NONE:
+		return "RFC5322_NONE";
+	case RFC5322_HEADER_START:
+		return "RFC5322_HEADER_START";
+	case RFC5322_HEADER_CONT:
+		return "RFC5322_HEADER_CONT";
+	case RFC5322_END_OF_HEADERS:
+		return "RFC5322_HEADER_END_OF_HEADERS";
+	case RFC5322_BODY_START:
+		return "RFC5322_BODY_START";
+	case RFC5322_BODY:
+		return "RFC5322_BODY";
+	case RFC5322_END_OF_MESSAGE:
+		return "RFC5322_END_OF_MESSAGE";
+	default:
+		return "<unknown>";
+	}
+}
+
 struct rfc5322_parser;
 
 struct rfc5322_parser *rfc5322_parser_new(void);
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index 269e03ed..81feb9ae 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -2579,6 +2579,7 @@ smtp_tx_dataline(struct smtp_tx *tx, const char *line)
 
 	for(;;) {
 		r = rfc5322_next(tx->parser, &res);
+		log_trace(TRACE_SMTP, "rfc5322 state: %s", rfc5322_state_string(r));
 		switch (r) {
 		case -1:
 			if (errno == ENOMEM)

Reply via email to