From 0b18c6060fc9eb2220e8c4374ee4ca7f2687c45b Mon Sep 17 00:00:00 2001 From: Janos SUTO Date: Sat, 3 Jul 2021 13:08:33 +0200 Subject: [PATCH] Fixed handling dot stuffing in the DATA stage of the smtp chat Signed-off-by: Janos SUTO --- src/smtp.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/smtp.c b/src/smtp.c index 08873226..a7b6d4e4 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -85,12 +85,21 @@ void process_data(struct smtp_session *session, char *buf, int buflen){ int written=0, n_writes=0; while(written < buflen) { - int len = write(session->fd, buf+written, buflen-written); + // In the DATA phase skip the 1st character if it's a dot (.) + // and there are more characters before the trailing CR-LF + // + // See https://www.ietf.org/rfc/rfc5321.html#section-4.5.2 for more. + + int dotstuff = 0; + if(*buf == '.' && buflen > 1 && *(buf+1) != '\r' && *(buf+1) != '\n') dotstuff = 1; + + int len = write(session->fd, buf+dotstuff+written, buflen-dotstuff-written); + n_writes++; if(len > 0){ - if(len != buflen) syslog(LOG_PRIORITY, "WARN: partial write: %d/%d bytes (round: %d)", len, buflen, n_writes); - written += len; + if(len != buflen-dotstuff) syslog(LOG_PRIORITY, "WARN: partial write: %d/%d bytes (round: %d)", len, buflen-dotstuff, n_writes); + written += len + dotstuff; session->tot_len += len; } else syslog(LOG_PRIORITY, "ERROR (line: %d) process_data(): written %d bytes", __LINE__, len);