Correctly fallback to PLAIN if opportunistics TLS fails during TLS handshake.
authoreric <eric@openbsd.org>
Wed, 24 Dec 2014 13:51:31 +0000 (13:51 +0000)
committereric <eric@openbsd.org>
Wed, 24 Dec 2014 13:51:31 +0000 (13:51 +0000)
fix by Stefan Sieg

ok gilles

usr.sbin/smtpd/ioev.c
usr.sbin/smtpd/ioev.h
usr.sbin/smtpd/mta_session.c

index 802cd70..ebfb613 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ioev.c,v 1.19 2014/07/08 07:59:31 sobrado Exp $       */
+/*     $OpenBSD: ioev.c,v 1.20 2014/12/24 13:51:31 eric Exp $  */
 /*      
  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
  *
@@ -770,7 +770,7 @@ io_dispatch_connect_ssl(int fd, short event, void *humppa)
        default:
                io->error = io_ssl_error();
                ssl_error("io_dispatch_connect_ssl:SSL_connect");
-               io_callback(io, IO_ERROR);
+               io_callback(io, IO_TLSERROR);
                break;
        }
 
index cc0e42c..dfcc784 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ioev.h,v 1.4 2014/07/08 07:59:31 sobrado Exp $        */
+/*     $OpenBSD: ioev.h,v 1.5 2014/12/24 13:51:31 eric Exp $   */
 /*
  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
  *
@@ -21,6 +21,7 @@ enum {
        IO_CONNECTED = 0,       /* connection successful        */
        IO_TLSREADY,            /* TLS started successfully     */
        IO_TLSVERIFIED,         /* XXX - needs more work        */
+       IO_TLSERROR,            /* XXX - needs more work        */
        IO_DATAIN,              /* new data in input buffer     */
        IO_LOWAT,               /* output queue running low     */
        IO_DISCONNECTED,        /* error?                       */
index e6e42a0..ce87934 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mta_session.c,v 1.68 2014/07/04 15:24:46 eric Exp $   */
+/*     $OpenBSD: mta_session.c,v 1.69 2014/12/24 13:51:31 eric Exp $   */
 
 /*
  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -1307,6 +1307,22 @@ mta_io(struct io *io, int evt)
                mta_free(s);
                break;
 
+       case IO_TLSERROR:
+               log_debug("debug: mta: %p: TLS IO error: %s", s, io->error);
+               if (!(s->flags & (MTA_FORCE_TLS|MTA_FORCE_ANYSSL))) {
+                       /* error in non-strict SSL negotiation, downgrade to plain */
+                       log_info("smtp-out: TLS Error on session %016"PRIx64
+                           ": TLS failed, "
+                           "downgrading to plain", s->id);
+                       s->flags &= ~MTA_TLS;
+                       s->flags |= MTA_DOWNGRADE_PLAIN;
+                       mta_connect(s);
+                       break;
+               }
+               mta_error(s, "IO Error: %s", io->error);
+               mta_free(s);
+               break;
+
        case IO_DISCONNECTED:
                log_debug("debug: mta: %p: disconnected in state %s",
                    s, mta_strstate(s->state));