smtp: align BDAT error recovery with Postfix
Debian Trixie package bundle / packages (push) Successful in 22m21s
Debian Trixie package bundle / packages (push) Successful in 22m21s
This commit is contained in:
+45
-2
@@ -289,6 +289,7 @@ typedef struct
|
||||
BOOL IsEHLO; /* used for RFC 3848 */
|
||||
BOOL HasSPFResult;
|
||||
BOOL NMAPMessageWrite;
|
||||
BOOL BdatDiscard;
|
||||
FILE *BdatMessage;
|
||||
uint64_t BdatLength;
|
||||
BongoSPFResponse SPFResult;
|
||||
@@ -902,6 +903,7 @@ SMTPClearTransaction(ConnectionStruct *client, unsigned long next_state)
|
||||
client->RcptCommandCount = 0;
|
||||
client->MsgFlags = MSG_FLAG_ENCODING_NONE;
|
||||
client->HasSPFResult = FALSE;
|
||||
client->BdatDiscard = FALSE;
|
||||
memset(&client->SPFResult, 0, sizeof(client->SPFResult));
|
||||
if (client->BdatMessage != NULL) {
|
||||
fclose(client->BdatMessage);
|
||||
@@ -919,7 +921,8 @@ SMTPResetTransaction(ConnectionStruct *client, unsigned long next_state)
|
||||
{
|
||||
char reply[BUFSIZE + 1];
|
||||
|
||||
if (client->State >= STATE_FROM && client->State <= STATE_BDAT) {
|
||||
if (client->State >= STATE_FROM && client->State <= STATE_BDAT &&
|
||||
!client->BdatDiscard) {
|
||||
if (NMAPSendCommand(client->nmap.conn, "QABRT\r\n", 7) < 0 ||
|
||||
NMAPReadResponse(client->nmap.conn, reply, sizeof(reply), TRUE) !=
|
||||
1000) return FALSE;
|
||||
@@ -973,7 +976,8 @@ EndClientConnection (ConnectionStruct * Client)
|
||||
* closing it lets the queue discard the incomplete entry. */
|
||||
FreeInternalConnection(Client->nmap);
|
||||
} else if (Client->Flags >= STATE_FROM &&
|
||||
Client->Flags <= STATE_BDAT) {
|
||||
Client->Flags <= STATE_BDAT &&
|
||||
!Client->BdatDiscard) {
|
||||
if (NMAPSendCommand(Client->nmap.conn, "QABRT\r\n", 7) >= 0 &&
|
||||
NMAPReadResponse(Client->nmap.conn, Reply, sizeof(Reply),
|
||||
TRUE) == 1000) {
|
||||
@@ -2189,6 +2193,26 @@ HandleConnection (void *param)
|
||||
ConnFlush(Client->client.conn);
|
||||
return EndClientConnection(Client);
|
||||
}
|
||||
if (Client->BdatDiscard) {
|
||||
if (ConnDiscard64(Client->client.conn, ChunkSize) < 0)
|
||||
return EndClientConnection(Client);
|
||||
if (LastChunk) {
|
||||
SMTPClearTransaction(
|
||||
Client,
|
||||
IsAuthed ? STATE_AUTH : STATE_HELO);
|
||||
}
|
||||
count = snprintf(
|
||||
Answer, sizeof(Answer),
|
||||
"551 5.0.0 Discarded %" PRIu64
|
||||
" bytes after earlier BDAT error\r\n",
|
||||
ChunkSize);
|
||||
if (count < 0 ||
|
||||
(size_t)count >= sizeof(Answer))
|
||||
return EndClientConnection(Client);
|
||||
ConnWrite(Client->client.conn, Answer,
|
||||
(size_t)count);
|
||||
break;
|
||||
}
|
||||
if (!Client->IsEHLO ||
|
||||
(Client->State != STATE_TO &&
|
||||
Client->State != STATE_BDAT)) {
|
||||
@@ -2203,6 +2227,21 @@ HandleConnection (void *param)
|
||||
MSG503BADORDER_LEN);
|
||||
break;
|
||||
}
|
||||
if (ChunkSize == 0U && !LastChunk) {
|
||||
if (!SMTPResetTransaction(
|
||||
Client,
|
||||
IsAuthed ? STATE_AUTH : STATE_HELO))
|
||||
return EndClientConnection(Client);
|
||||
Client->State = STATE_BDAT;
|
||||
Client->BdatDiscard = TRUE;
|
||||
NullSender = FALSE;
|
||||
TooManyNullSenderRecips = FALSE;
|
||||
ConnWrite(
|
||||
Client->client.conn,
|
||||
"551 5.7.1 Null BDAT request\r\n",
|
||||
sizeof("551 5.7.1 Null BDAT request\r\n") - 1U);
|
||||
break;
|
||||
}
|
||||
if (Client->State == STATE_TO) {
|
||||
Client->BdatMessage = tmpfile();
|
||||
if (Client->BdatMessage == NULL) {
|
||||
@@ -2233,6 +2272,10 @@ HandleConnection (void *param)
|
||||
if (!SMTPResetTransaction(
|
||||
Client, IsAuthed ? STATE_AUTH : STATE_HELO))
|
||||
return EndClientConnection(Client);
|
||||
if (!LastChunk) {
|
||||
Client->State = STATE_BDAT;
|
||||
Client->BdatDiscard = TRUE;
|
||||
}
|
||||
NullSender = FALSE;
|
||||
TooManyNullSenderRecips = FALSE;
|
||||
ConnWrite(Client->client.conn, MSG552MSGTOOBIG,
|
||||
|
||||
Reference in New Issue
Block a user