diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2014-04-30 12:49:55 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2014-04-30 12:49:55 +0000 |
commit | 687a0a1ab616708f75fd41113e116a000ad83c48 (patch) | |
tree | 3bc95a8e31fec9523fd46d08a2eb159efb777eed | |
parent | acb856ab1f74e675df9681b53bec30b4755890c2 (diff) |
when doing opportunistic TLS, do not only downgrade during negotiation, but
also downgrade if a TLS error happens during the session.
ok eric@ who helped me with this
-rw-r--r-- | usr.sbin/smtpd/mta_session.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/usr.sbin/smtpd/mta_session.c b/usr.sbin/smtpd/mta_session.c index e3b43b7f50e..44f57fb4a20 100644 --- a/usr.sbin/smtpd/mta_session.c +++ b/usr.sbin/smtpd/mta_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta_session.c,v 1.63 2014/04/29 19:13:13 reyk Exp $ */ +/* $OpenBSD: mta_session.c,v 1.64 2014/04/30 12:49:54 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -626,6 +626,8 @@ mta_enter_state(struct mta_session *s, int newstate) break; case MTA_STARTTLS: + if (s->flags & MTA_DOWNGRADE_PLAIN) + mta_enter_state(s, MTA_AUTH); if (s->flags & MTA_TLS) /* already started */ mta_enter_state(s, MTA_AUTH); else if ((s->ext & MTA_EXT_STARTTLS) == 0) { @@ -737,7 +739,17 @@ mta_enter_state(struct mta_session *s, int newstate) break; } - s->task = mta_route_next_task(s->relay, s->route); + /* + * When downgrading from opportunistic TLS, clear flag and + * possibly reuse the same task (forbidden in other cases). + */ + if (s->flags & MTA_DOWNGRADE_PLAIN) + s->flags &= ~MTA_DOWNGRADE_PLAIN; + else if (s->task) + fatalx("task should be NULL at this point"); + + if (s->task == NULL) + s->task = mta_route_next_task(s->relay, s->route); if (s->task == NULL) { log_debug("debug: mta: %p: no task for relay %s", s, mta_relay_to_text(s->relay)); @@ -1275,16 +1287,25 @@ mta_io(struct io *io, int evt) case IO_ERROR: log_debug("debug: mta: %p: IO error: %s", s, io->error); - mta_error(s, "IO Error: %s", io->error); - if (!s->ready) + if (!s->ready) { + mta_error(s, "IO Error: %s", io->error); mta_connect(s); + break; + } else if (!(s->flags & (MTA_FORCE_TLS|MTA_FORCE_ANYSSL))) { /* error in non-strict SSL negotiation, downgrade to plain */ + if (s->flags & MTA_TLS) { + log_info("smtp-out: Error on session %016"PRIx64 + ": opportunistic TLS failed, " + "downgrading to plain", s->id); + s->flags &= ~MTA_TLS; s->flags |= MTA_DOWNGRADE_PLAIN; mta_connect(s); + break; + } } - else - mta_free(s); + mta_error(s, "IO Error: %s", io->error); + mta_free(s); break; case IO_DISCONNECTED: |