From 7ba07c80a16cd4ce711b5ac62d3632ae4145e9a9 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Thu, 17 May 2012 11:31:06 +0100 Subject: smtp: Fixed non-escaping of dot character at beginning of line A dot character at the beginning of a line would not be escaped to a double dot as required by RFC-2821, instead it would be deleted by the mail server. Please see section 4.5.2 of the RFC for more information. Note: This fix also simplifies the detection of repeated CRLF.CRLF combinations, such as CRLF.CRLF.CRLF, a little rather than having to advance the eob counter to 2. --- lib/smtp.c | 28 ++++++++++++---------------- lib/smtp.h | 1 + 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/smtp.c b/lib/smtp.c index 42cff6e41..aa4f6bd39 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1929,17 +1929,19 @@ static CURLcode smtp_setup_connection(struct connectdata *conn) CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) { - /* When sending SMTP payload, we must detect CRLF.CRLF sequences in - * the data and make sure it is sent as CRLF..CRLF instead, as - * otherwise it will wrongly be detected as end of data by the server. - */ + /* When sending a SMTP payload we must detect CRLF. sequences making sure + they are sent as CRLF.. instead, as a . on the beginning of a line will + be deleted by the server when not part of an EOB terminator and a + genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of + data by the server. + */ ssize_t i; ssize_t si; struct smtp_conn *smtpc = &conn->proto.smtpc; struct SessionHandle *data = conn->data; /* Do we need to allocate the scatch buffer? */ - if(!data->state.scratch) { + if(!data->state.scratch) { data->state.scratch = malloc(2 * BUFSIZE); if(!data->state.scratch) { @@ -1965,18 +1967,12 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) smtpc->eob = 0; } - if(SMTP_EOB_LEN == smtpc->eob) { - /* It matched, copy the replacement data to the target buffer - instead. Note that the replacement does not contain the - trailing CRLF but we instead continue to match on that one - to deal with repeated sequences. Like CRLF.CRLF.CRLF etc - */ - memcpy(&data->state.scratch[si], SMTP_EOB_REPL, - SMTP_EOB_REPL_LEN); + /* Do we have a match for CRLF. as per RFC-2821, sect. 4.5.2 */ + if(SMTP_EOB_FIND_LEN == smtpc->eob) { + /* Copy the replacement data to the target buffer */ + memcpy(&data->state.scratch[si], SMTP_EOB_REPL, SMTP_EOB_REPL_LEN); si += SMTP_EOB_REPL_LEN; - - /* Start over at two bytes */ - smtpc->eob = 2; + smtpc->eob = 0; } else if(!smtpc->eob) data->state.scratch[si++] = data->req.upload_fromhere[i]; diff --git a/lib/smtp.h b/lib/smtp.h index 502f65cbe..55f169e02 100644 --- a/lib/smtp.h +++ b/lib/smtp.h @@ -82,6 +82,7 @@ extern const struct Curl_handler Curl_handler_smtps; /* this is the 5-bytes End-Of-Body marker for SMTP */ #define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a" #define SMTP_EOB_LEN 5 +#define SMTP_EOB_FIND_LEN 3 /* if found in data, replace it with this string instead */ #define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e" -- cgit v1.2.3