mirror of
https://github.com/moparisthebest/curl
synced 2024-08-13 17:03:50 -04:00
smtp: Fixed sending of double CRLF caused by first in EOB
If the mail sent during the transfer contains a terminating <CRLF> then we should not send the first <CRLF> of the EOB as specified in RFC-5321. Additionally don't send the <CRLF> if there is "no mail data" as the DATA command already includes it.
This commit is contained in:
parent
087f9bb20a
commit
99b4045183
41
lib/smtp.c
41
lib/smtp.c
@ -1455,6 +1455,9 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct SMTP *smtp = data->state.proto.smtp;
|
struct SMTP *smtp = data->state.proto.smtp;
|
||||||
|
struct pingpong *pp = &conn->proto.smtpc.pp;
|
||||||
|
const char *eob;
|
||||||
|
size_t len;
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
|
|
||||||
(void)premature;
|
(void)premature;
|
||||||
@ -1471,25 +1474,27 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
|||||||
result = status; /* use the already set error code */
|
result = status; /* use the already set error code */
|
||||||
}
|
}
|
||||||
else if(!data->set.connect_only) {
|
else if(!data->set.connect_only) {
|
||||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
/* Calculate the EOB taking into account any terminating CRLF from the
|
||||||
struct pingpong *pp = &smtpc->pp;
|
previous line of the email or the CRLF of the DATA command when there
|
||||||
|
is "no mail data". RFC-5321, sect. 4.1.1.4. */
|
||||||
|
eob = SMTP_EOB;
|
||||||
|
len = SMTP_EOB_LEN;
|
||||||
|
if(smtp->trailing_crlf || !conn->data->set.infilesize) {
|
||||||
|
eob += 2;
|
||||||
|
len -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send the end of block data */
|
/* Send the end of block data */
|
||||||
result = Curl_write(conn,
|
result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
|
||||||
conn->writesockfd, /* socket to send to */
|
|
||||||
SMTP_EOB, /* buffer pointer */
|
|
||||||
SMTP_EOB_LEN, /* buffer size */
|
|
||||||
&bytes_written); /* actually sent away */
|
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if(bytes_written != SMTP_EOB_LEN) {
|
if(bytes_written != len) {
|
||||||
/* The whole chunk was not sent so keep it around and adjust the
|
/* The whole chunk was not sent so keep it around and adjust the
|
||||||
pingpong structure accordingly */
|
pingpong structure accordingly */
|
||||||
pp->sendthis = strdup(SMTP_EOB);
|
pp->sendthis = strdup(eob);
|
||||||
pp->sendsize = SMTP_EOB_LEN;
|
pp->sendsize = len;
|
||||||
pp->sendleft = SMTP_EOB_LEN - bytes_written;
|
pp->sendleft = len - bytes_written;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Successfully sent so adjust the response timeout relative to now */
|
/* Successfully sent so adjust the response timeout relative to now */
|
||||||
@ -1812,8 +1817,15 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
|||||||
/* This loop can be improved by some kind of Boyer-Moore style of
|
/* This loop can be improved by some kind of Boyer-Moore style of
|
||||||
approach but that is saved for later... */
|
approach but that is saved for later... */
|
||||||
for(i = 0, si = 0; i < nread; i++) {
|
for(i = 0, si = 0; i < nread; i++) {
|
||||||
if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i])
|
if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) {
|
||||||
smtp->eob++;
|
smtp->eob++;
|
||||||
|
|
||||||
|
/* Is the EOB potentially the terminating CRLF? */
|
||||||
|
if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob)
|
||||||
|
smtp->trailing_crlf = TRUE;
|
||||||
|
else
|
||||||
|
smtp->trailing_crlf = FALSE;
|
||||||
|
}
|
||||||
else if(smtp->eob) {
|
else if(smtp->eob) {
|
||||||
/* A previous substring matched so output that first */
|
/* A previous substring matched so output that first */
|
||||||
memcpy(&data->state.scratch[si], SMTP_EOB, smtp->eob);
|
memcpy(&data->state.scratch[si], SMTP_EOB, smtp->eob);
|
||||||
@ -1824,6 +1836,9 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
|||||||
smtp->eob = 1;
|
smtp->eob = 1;
|
||||||
else
|
else
|
||||||
smtp->eob = 0;
|
smtp->eob = 0;
|
||||||
|
|
||||||
|
/* Reset the trailing CRLF flag as there was more data */
|
||||||
|
smtp->trailing_crlf = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have a match for CRLF. as per RFC-2821, sect. 4.5.2 */
|
/* Do we have a match for CRLF. as per RFC-2821, sect. 4.5.2 */
|
||||||
|
@ -62,6 +62,7 @@ struct SMTP {
|
|||||||
struct curl_slist *rcpt; /* Recipient list */
|
struct curl_slist *rcpt; /* Recipient list */
|
||||||
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
||||||
have been received so far */
|
have been received so far */
|
||||||
|
bool trailing_crlf; /* Specifies if the tailing CRLF is present */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* smtp_conn is used for struct connection-oriented data in the connectdata
|
/* smtp_conn is used for struct connection-oriented data in the connectdata
|
||||||
|
@ -58,7 +58,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
<proxy>
|
<proxy>
|
||||||
|
@ -49,7 +49,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
<file name="log/test1406.c" mode="text">
|
<file name="log/test1406.c" mode="text">
|
||||||
|
@ -46,7 +46,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -57,7 +57,6 @@ To: another
|
|||||||
..
|
..
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -52,7 +52,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -49,7 +49,6 @@ QUIT
|
|||||||
</protocol>
|
</protocol>
|
||||||
<upload>
|
<upload>
|
||||||
mail body
|
mail body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -50,7 +50,6 @@ QUIT
|
|||||||
</protocol>
|
</protocol>
|
||||||
<upload>
|
<upload>
|
||||||
mail body
|
mail body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -52,7 +52,6 @@ QUIT
|
|||||||
</protocol>
|
</protocol>
|
||||||
<upload>
|
<upload>
|
||||||
mail body
|
mail body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -45,7 +45,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -47,7 +47,6 @@ QUIT
|
|||||||
</protocol>
|
</protocol>
|
||||||
<upload>
|
<upload>
|
||||||
mail body
|
mail body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -48,7 +48,6 @@ QUIT
|
|||||||
</protocol>
|
</protocol>
|
||||||
<upload>
|
<upload>
|
||||||
mail body
|
mail body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
@ -50,7 +50,6 @@ From: different
|
|||||||
To: another
|
To: another
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
||||||
.
|
.
|
||||||
</upload>
|
</upload>
|
||||||
</verify>
|
</verify>
|
||||||
|
Loading…
Reference in New Issue
Block a user