]> granicus.if.org Git - curl/commitdiff
smtp: Fixed non-escaping of dot character at beginning of line
authorSteve Holme <steve_holme@hotmail.com>
Thu, 17 May 2012 10:31:06 +0000 (11:31 +0100)
committerSteve Holme <steve_holme@hotmail.com>
Thu, 17 May 2012 10:31:06 +0000 (11:31 +0100)
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
lib/smtp.h

index 42cff6e4171d2211e21700557de15e450427207d..aa4f6bd396b15bfcba7ed94aa997759559906d73 100644 (file)
@@ -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];
index 502f65cbe6a575a45e6baa84e715a1bce703ac09..55f169e027c3456f43cf7bea608efb58c57593b3 100644 (file)
@@ -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"