Skip to content

Commit

Permalink
smtp: Fixed non-escaping of dot character at beginning of line
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
captain-caveman2k committed May 17, 2012
1 parent fec096f commit 7ba07c8
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 16 deletions.
28 changes: 12 additions & 16 deletions lib/smtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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];
Expand Down
1 change: 1 addition & 0 deletions lib/smtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 7ba07c8

Please sign in to comment.