Backport of the following patch to buster:
https://github.com/neomutt/neomutt/commit/fb013ec666759cb8a9e294347c7b4c1f597639cc

This fixes a problem where the buffers were not completely clear after the
STARTTLS message, this allow data to be handled securely.

--- a/conn/socket.c
+++ b/conn/socket.c
@@ -342,3 +342,23 @@
     }
   }
 }
+
+/**
+ * mutt_socket_empty - Clear out any queued data
+ *
+ * The internal buffer is emptied and any data that has already arrived at this
+ * machine (in kernel buffers) is read and dropped.
+ */
+void mutt_socket_empty(struct Connection *conn)
+{
+  if (!conn)
+    return;
+
+  char buf[1024];
+  int bytes;
+
+  while ((bytes = mutt_socket_poll(conn, 0)) > 0)
+  {
+    mutt_socket_read(conn, buf, MIN(bytes, sizeof(buf)));
+  }
+}
--- a/conn/socket.h
+++ b/conn/socket.h
@@ -51,6 +51,7 @@
 
 int mutt_socket_open(struct Connection *conn);
 int mutt_socket_close(struct Connection *conn);
+void mutt_socket_empty   (struct Connection *conn);
 int mutt_socket_read(struct Connection *conn, char *buf, size_t len);
 int mutt_socket_write(struct Connection *conn, const char *buf, size_t len);
 int mutt_socket_poll(struct Connection *conn, time_t wait_secs);
--- a/imap/command.c
+++ b/imap/command.c
@@ -1106,6 +1106,13 @@
 {
   int rc;
 
+  if (flags & IMAP_CMD_SINGLE)
+  {
+    // Process any existing commands
+    if (idata->nextcmd != idata->lastcmd)
+      imap_exec(idata, NULL, IMAP_CMD_POLL);
+  }
+
   rc = cmd_start(idata, cmdstr, flags);
   if (rc < 0)
   {
@@ -1127,8 +1134,12 @@
   /* Allow interruptions, particularly useful if there are network problems. */
   mutt_sig_allow_interrupt(1);
   do
+  {
     rc = imap_cmd_step(idata);
-  while (rc == IMAP_CMD_CONTINUE);
+    // The queue is empty, so the single command has been processed
+    if ((flags & IMAP_CMD_SINGLE) && (idata->nextcmd == idata->lastcmd))
+      break;
+  } while (rc == IMAP_CMD_CONTINUE);
   mutt_sig_allow_interrupt(0);
 
   if (rc == IMAP_CMD_NO && (flags & IMAP_CMD_FAIL_OK))
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -1041,7 +1041,10 @@
       }
       if (rc == MUTT_YES)
       {
-        rc = imap_exec(idata, "STARTTLS", IMAP_CMD_FAIL_OK);
+        rc = imap_exec(idata, "STARTTLS", IMAP_CMD_SINGLE);
+        // Clear any data after the STARTTLS acknowledgement
+        mutt_socket_empty(idata->conn);
+
         if (rc == -1)
           goto bail;
         if (rc != -2)
--- a/smtp.c
+++ b/smtp.c
@@ -597,6 +597,8 @@
     if (mutt_socket_send(conn, "STARTTLS\r\n") < 0)
       return SMTP_ERR_WRITE;
     rc = smtp_get_resp(conn);
+    // Clear any data after the STARTTLS acknowledgement
+    mutt_socket_empty(conn);
     if (rc != 0)
       return rc;
 
--- a/nntp.c
+++ b/nntp.c
@@ -713,6 +713,8 @@
       {
         return nntp_connect_error(nserv);
       }
+      // Clear any data after the STARTTLS acknowledgement
+      mutt_socket_empty(conn);
       if (mutt_str_strncmp("382", buf, 3) != 0)
       {
         nserv->use_tls = 0;
--- a/pop_lib.c
+++ b/pop_lib.c
@@ -334,6 +334,8 @@
     {
       mutt_str_strfcpy(buf, "STLS\r\n", sizeof(buf));
       rc = pop_query(pop_data, buf, sizeof(buf));
+      // Clear any data after the STLS acknowledgement
+      mutt_socket_empty(pop_data->conn);
       if (rc == -1)
         goto err_conn;
       if (rc != 0)
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -77,6 +77,7 @@
 #define IMAP_CMD_PASS    (1 << 1)
 #define IMAP_CMD_QUEUE   (1 << 2)
 #define IMAP_CMD_POLL    (1 << 3)
+#define IMAP_CMD_SINGLE  (1 << 4)
 
 /* length of "DD-MMM-YYYY HH:MM:SS +ZZzz" (null-terminated) */
 #define IMAP_DATELEN 27
