Skip to content

Commit fb013ec

Browse files
flatcapgahr
andcommitted
tls: clear data after a starttls acknowledgement
After a starttls acknowledgement message, clear the buffers of any incoming data / commands. This will ensure that all future data is handled securely. Co-authored-by: Pietro Cerutti <gahr@gahr.ch>
1 parent 523664a commit fb013ec

File tree

8 files changed

+42
-1
lines changed

8 files changed

+42
-1
lines changed

Diff for: conn/socket.c

+20
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,23 @@ struct Connection *mutt_socket_new(enum ConnectionType type)
301301

302302
return conn;
303303
}
304+
305+
/**
306+
* mutt_socket_empty - Clear out any queued data
307+
*
308+
* The internal buffer is emptied and any data that has already arrived at this
309+
* machine (in kernel buffers) is read and dropped.
310+
*/
311+
void mutt_socket_empty(struct Connection *conn)
312+
{
313+
if (!conn)
314+
return;
315+
316+
char buf[1024];
317+
int bytes;
318+
319+
while ((bytes = mutt_socket_poll(conn, 0)) > 0)
320+
{
321+
mutt_socket_read(conn, buf, MIN(bytes, sizeof(buf)));
322+
}
323+
}

Diff for: conn/socket.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum ConnectionType
3939
};
4040

4141
int mutt_socket_close (struct Connection *conn);
42+
void mutt_socket_empty (struct Connection *conn);
4243
struct Connection *mutt_socket_new (enum ConnectionType type);
4344
int mutt_socket_open (struct Connection *conn);
4445
int mutt_socket_poll (struct Connection *conn, time_t wait_secs);

Diff for: imap/command.c

+10
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,13 @@ int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags fl
12501250
{
12511251
int rc;
12521252

1253+
if (flags & IMAP_CMD_SINGLE)
1254+
{
1255+
// Process any existing commands
1256+
if (adata->nextcmd != adata->lastcmd)
1257+
imap_exec(adata, NULL, IMAP_CMD_POLL);
1258+
}
1259+
12531260
rc = cmd_start(adata, cmdstr, flags);
12541261
if (rc < 0)
12551262
{
@@ -1273,6 +1280,9 @@ int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags fl
12731280
do
12741281
{
12751282
rc = imap_cmd_step(adata);
1283+
// The queue is empty, so the single command has been processed
1284+
if ((flags & IMAP_CMD_SINGLE) && (adata->nextcmd == adata->lastcmd))
1285+
break;
12761286
} while (rc == IMAP_RES_CONTINUE);
12771287
mutt_sig_allow_interrupt(false);
12781288

Diff for: imap/imap.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,10 @@ int imap_open_connection(struct ImapAccountData *adata)
739739
}
740740
if (ans == MUTT_YES)
741741
{
742-
enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_NO_FLAGS);
742+
enum ImapExecResult rc = imap_exec(adata, "STARTTLS", IMAP_CMD_SINGLE);
743+
// Clear any data after the STARTTLS acknowledgement
744+
mutt_socket_empty(adata->conn);
745+
743746
if (rc == IMAP_EXEC_FATAL)
744747
goto bail;
745748
if (rc != IMAP_EXEC_ERROR)

Diff for: imap/private.h

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typedef uint8_t ImapCmdFlags; ///< Flags for imap_exec(), e.g. #IMAP_CM
7373
#define IMAP_CMD_PASS (1 << 0) ///< Command contains a password. Suppress logging
7474
#define IMAP_CMD_QUEUE (1 << 1) ///< Queue a command, do not execute
7575
#define IMAP_CMD_POLL (1 << 2) ///< Poll the tcp connection before running the imap command
76+
#define IMAP_CMD_SINGLE (1 << 3) ///< Run a single command
7677

7778
/**
7879
* enum ImapExecResult - imap_exec return code

Diff for: nntp/nntp.c

+2
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,8 @@ int nntp_open_connection(struct NntpAccountData *adata)
18991899
{
19001900
return nntp_connect_error(adata);
19011901
}
1902+
// Clear any data after the STARTTLS acknowledgement
1903+
mutt_socket_empty(conn);
19021904
if (!mutt_str_startswith(buf, "382", CASE_MATCH))
19031905
{
19041906
adata->use_tls = 0;

Diff for: pop/pop_lib.c

+2
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ int pop_open_connection(struct PopAccountData *adata)
358358
{
359359
mutt_str_strfcpy(buf, "STLS\r\n", sizeof(buf));
360360
rc = pop_query(adata, buf, sizeof(buf));
361+
// Clear any data after the STLS acknowledgement
362+
mutt_socket_empty(adata->conn);
361363
if (rc == -1)
362364
goto err_conn;
363365
if (rc != 0)

Diff for: smtp.c

+2
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,8 @@ static int smtp_open(struct Connection *conn, bool esmtp)
719719
if (mutt_socket_send(conn, "STARTTLS\r\n") < 0)
720720
return SMTP_ERR_WRITE;
721721
rc = smtp_get_resp(conn);
722+
// Clear any data after the STARTTLS acknowledgement
723+
mutt_socket_empty(conn);
722724
if (rc != 0)
723725
return rc;
724726

0 commit comments

Comments
 (0)