http://bugzilla.cyrusimap.org/show_bug.cgi?id=3423 http://bugzilla.cyrusimap.org/show_bug.cgi?id=3424 http://git.cyrusimap.org/cyrus-imapd/patch/?id=523a91a5e86c8b9a27a138f04a3e3f2d8786f162 From 523a91a5e86c8b9a27a138f04a3e3f2d8786f162 Mon Sep 17 00:00:00 2001 From: Ken Murchison <murch@andrew.cmu.edu> Date: Fri, 25 Mar 2011 15:50:18 +0000 Subject: Fixed bug #3423 - STARTTLS plaintext command injection vulnerability diff -Naurp cyrus-imapd-2.3.15/imap/imapd.c cyrus-imapd-2.3.15.oden/imap/imapd.c --- cyrus-imapd-2.3.15/imap/imapd.c 2011-05-24 08:03:28.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/imapd.c 2011-05-24 08:03:41.000000000 +0000 @@ -1689,6 +1689,9 @@ void cmdloop() if (c == '\r') c = prot_getc(imapd_in); if (c != '\n') goto extraargs; + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(imapd_in); + /* if we've already done SASL fail */ if (imapd_userid != NULL) { prot_printf(imapd_out, diff -Naurp cyrus-imapd-2.3.15/imap/lmtpengine.c cyrus-imapd-2.3.15.oden/imap/lmtpengine.c --- cyrus-imapd-2.3.15/imap/lmtpengine.c 2009-04-23 01:30:32.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/lmtpengine.c 2011-05-24 08:03:41.000000000 +0000 @@ -1562,6 +1562,9 @@ void lmtpmode(struct lmtp_func *func, sasl_ssf_t ssf; char *auth_id; + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(pin); + /* SASL and openssl have different ideas about whether ssf is signed */ layerp = (int *) &ssf; diff -Naurp cyrus-imapd-2.3.15/imap/mupdate.c cyrus-imapd-2.3.15.oden/imap/mupdate.c --- cyrus-imapd-2.3.15/imap/mupdate.c 2009-04-30 18:20:58.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/mupdate.c 2011-05-24 08:03:41.000000000 +0000 @@ -927,6 +927,9 @@ mupdate_docmd_result_t docmd(struct conn if (!strcmp(c->cmd.s, "Starttls")) { CHECKNEWLINE(c, ch); + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(c->pin); + if (!tls_enabled()) { /* we don't support starttls */ goto badcmd; diff -Naurp cyrus-imapd-2.3.15/imap/nntpd.c cyrus-imapd-2.3.15.oden/imap/nntpd.c --- cyrus-imapd-2.3.15/imap/nntpd.c 2009-05-05 01:23:02.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/nntpd.c 2011-05-24 08:03:41.000000000 +0000 @@ -1406,6 +1406,9 @@ static void cmdloop(void) if (c == '\r') c = prot_getc(nntp_in); if (c != '\n') goto extraargs; + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(nntp_in); + cmd_starttls(0); } else if (!strcmp(cmd.s, "Stat")) { diff -Naurp cyrus-imapd-2.3.15/imap/pop3d.c cyrus-imapd-2.3.15.oden/imap/pop3d.c --- cyrus-imapd-2.3.15/imap/pop3d.c 2011-05-24 08:03:28.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/pop3d.c 2011-05-24 08:08:11.000000000 +0000 @@ -872,6 +872,8 @@ static void cmdloop(void) prot_printf(popd_out, "-ERR STLS doesn't take any arguments\r\n"); } else { + /* XXX discard any input pipelined after STLS */ + prot_flush(popd_in); cmd_starttls(0); } } diff -Naurp cyrus-imapd-2.3.15/imap/sync_server.c cyrus-imapd-2.3.15.oden/imap/sync_server.c --- cyrus-imapd-2.3.15/imap/sync_server.c 2009-08-28 13:48:46.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/imap/sync_server.c 2011-05-24 08:03:41.000000000 +0000 @@ -889,6 +889,9 @@ static void cmdloop(void) if (c == '\r') c = prot_getc(sync_in); if (c != '\n') goto extraargs; + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(sync_in); + /* if we've already done SASL fail */ if (sync_userid != NULL) { prot_printf(sync_out, diff -Naurp cyrus-imapd-2.3.15/lib/prot.c cyrus-imapd-2.3.15.oden/lib/prot.c --- cyrus-imapd-2.3.15/lib/prot.c 2011-05-24 08:03:28.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/lib/prot.c 2011-05-24 08:03:42.000000000 +0000 @@ -728,10 +728,29 @@ int prot_fill(struct protstream *s) } /* + * If 's' is an input stream, discard any pending/buffered data. Otherwise, * Write out any buffered data in the stream 's' */ int prot_flush(struct protstream *s) { + if (!s->write) { + int c, save_dontblock = s->dontblock; + + /* Set stream to nonblocking mode */ + if (!save_dontblock) nonblock(s->fd, (s->dontblock = 1)); + + /* Ingest any pending input */ + while ((c = prot_fill(s)) != EOF); + + /* Reset stream to previous blocking mode */ + if (!save_dontblock) nonblock(s->fd, (s->dontblock = 0)); + + /* Discard any buffered input */ + s->cnt = 0; + + return 0; + } + return prot_flush_internal(s, 1); } diff -Naurp cyrus-imapd-2.3.15/timsieved/parser.c cyrus-imapd-2.3.15.oden/timsieved/parser.c --- cyrus-imapd-2.3.15/timsieved/parser.c 2011-05-24 08:03:28.000000000 +0000 +++ cyrus-imapd-2.3.15.oden/timsieved/parser.c 2011-05-24 08:03:42.000000000 +0000 @@ -443,6 +443,9 @@ int parser(struct protstream *sieved_out goto error; } + /* XXX discard any input pipelined after STARTTLS */ + prot_flush(sieved_in); + if(referral_host) goto do_referral;