With the recent changes in the smarthost syntax, and the removal of
the "secure" keyword, it's now possible to clarify the mta code by
changing the TLS option from a set flags to exclusive values.
This is far less confusing.

More cleanup to come in mta_session.c after that.

Eric.

Index: mta.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mta.c,v
retrieving revision 1.222
diff -u -p -r1.222 mta.c
--- mta.c       22 Aug 2018 10:11:43 -0000      1.222
+++ mta.c       5 Sep 2018 12:42:19 -0000
@@ -635,6 +635,7 @@ mta_handle_envelope(struct envelope *evp
        }
 
        memset(&relayh, 0, sizeof(relayh));
+       relayh.tls = RELAY_TLS_OPPORTUNISTIC;
        if (smarthost && !text_to_relayhost(&relayh, smarthost)) {
                log_warnx("warn: Failed to parse smarthost %s", smarthost);
                m_create(p_queue, IMSG_MTA_DELIVERY_TEMPFAIL, 0, 0, -1);
@@ -1730,10 +1731,9 @@ mta_relay(struct envelope *e, struct rel
                key.flags |= RELAY_MX;
        } else {
                key.domain = mta_domain(e->dest.domain, 0);
-               if (!(relayh->flags & RELAY_STARTTLS))
-                       key.flags |= RELAY_TLS_OPTIONAL;
        }
 
+       key.tls = relayh->tls;
        key.flags |= relayh->flags;
        key.port = relayh->port;
        key.authlabel = relayh->authlabel;
@@ -1748,6 +1748,7 @@ mta_relay(struct envelope *e, struct rel
                r = xcalloc(1, sizeof *r);
                TAILQ_INIT(&r->tasks);
                r->id = generate_uid();
+               r->tls = key.tls;
                r->flags = key.flags;
                r->domain = key.domain;
                r->backupname = key.backupname ?
@@ -1834,14 +1835,25 @@ mta_relay_to_text(struct mta_relay *rela
                (void)strlcat(buf, tmp, sizeof buf);
        }
 
-       if (relay->flags & RELAY_STARTTLS) {
-               (void)strlcat(buf, sep, sizeof buf);
-               (void)strlcat(buf, "starttls", sizeof buf);
-       }
-
-       if (relay->flags & RELAY_SMTPS) {
-               (void)strlcat(buf, sep, sizeof buf);
+       (void)strlcat(buf, sep, sizeof buf);
+       switch(relay->tls) {
+       case RELAY_TLS_OPPORTUNISTIC:
+               (void)strlcat(buf, "smtp", sizeof buf);
+               break;
+       case RELAY_TLS_STARTTLS:
+               (void)strlcat(buf, "smtp+tls", sizeof buf);
+               break;
+       case RELAY_TLS_SMTPS:
                (void)strlcat(buf, "smtps", sizeof buf);
+               break;
+       case RELAY_TLS_NO:
+               if (relay->flags & RELAY_LMTP)
+                       (void)strlcat(buf, "lmtp", sizeof buf);
+               else
+                       (void)strlcat(buf, "smtp+notls", sizeof buf);
+               break;
+       default:
+               (void)strlcat(buf, "???", sizeof buf);
        }
 
        if (relay->flags & RELAY_AUTH) {
@@ -1993,6 +2005,11 @@ mta_relay_cmp(const struct mta_relay *a,
        if (a->domain < b->domain)
                return (-1);
        if (a->domain > b->domain)
+               return (1);
+
+       if (a->tls < b->tls)
+               return (-1);
+       if (a->tls > b->tls)
                return (1);
 
        if (a->flags < b->flags)
Index: mta_session.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mta_session.c,v
retrieving revision 1.109
diff -u -p -r1.109 mta_session.c
--- mta_session.c       5 Sep 2018 10:15:41 -0000       1.109
+++ mta_session.c       5 Sep 2018 12:42:19 -0000
@@ -199,24 +199,23 @@ mta_session(struct mta_relay *relay, str
 
        if (relay->flags & RELAY_LMTP)
                s->flags |= MTA_LMTP;
-       switch (relay->flags & (RELAY_SSL|RELAY_TLS_OPTIONAL)) {
-               case RELAY_SSL:
-                       s->flags |= MTA_FORCE_ANYSSL;
-                       s->flags |= MTA_WANT_SECURE;
-                       break;
-               case RELAY_SMTPS:
+       switch (relay->tls) {
+               case RELAY_TLS_SMTPS:
                        s->flags |= MTA_FORCE_SMTPS;
                        s->flags |= MTA_WANT_SECURE;
                        break;
-               case RELAY_STARTTLS:
+               case RELAY_TLS_STARTTLS:
                        s->flags |= MTA_FORCE_TLS;
                        s->flags |= MTA_WANT_SECURE;
                        break;
-               case RELAY_TLS_OPTIONAL:
+               case RELAY_TLS_OPPORTUNISTIC:
                        /* do not force anything, try tls then smtp */
                        break;
-               default:
+               case RELAY_TLS_NO:
                        s->flags |= MTA_FORCE_PLAIN;
+                       break;
+               default:
+                       fatalx("bad value for relay->tls: %d", relay->tls);
        }
 
        if (relay->flags & RELAY_BACKUP)
Index: smtpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v
retrieving revision 1.558
diff -u -p -r1.558 smtpd.h
--- smtpd.h     4 Sep 2018 13:04:42 -0000       1.558
+++ smtpd.h     5 Sep 2018 12:42:19 -0000
@@ -84,11 +84,11 @@
 #define        F_RECEIVEDAUTH          0x800
 #define        F_MASQUERADE            0x1000
 
+#define RELAY_TLS_OPPORTUNISTIC        0
+#define RELAY_TLS_STARTTLS     1
+#define RELAY_TLS_SMTPS                2
+#define RELAY_TLS_NO           3
 
-#define RELAY_STARTTLS         0x01
-#define RELAY_SMTPS            0x02
-#define        RELAY_TLS_OPTIONAL      0x04
-#define RELAY_SSL              (RELAY_STARTTLS | RELAY_SMTPS)
 #define RELAY_AUTH             0x08
 #define RELAY_BACKUP           0x10
 #define RELAY_MX               0x20
@@ -115,6 +115,7 @@ struct netaddr {
 
 struct relayhost {
        uint16_t flags;
+       int tls;
        char hostname[HOST_NAME_MAX+1];
        uint16_t port;
        char authlabel[PATH_MAX];
@@ -732,6 +733,7 @@ struct mta_relay {
        struct dispatcher       *dispatcher;
        struct mta_domain       *domain;
        struct mta_limits       *limits;
+       int                      tls;
        int                      flags;
        char                    *backupname;
        int                      backuppref;
Index: to.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/to.c,v
retrieving revision 1.32
diff -u -p -r1.32 to.c
--- to.c        3 Sep 2018 11:30:14 -0000       1.32
+++ to.c        5 Sep 2018 12:42:19 -0000
@@ -304,17 +304,18 @@ text_to_relayhost(struct relayhost *rela
 {
        static const struct schema {
                const char      *name;
-               uint16_t         flags;
+               int              tls;
+               uint16_t         flags;
        } schemas [] = {
                /*
                 * new schemas should be *appended* otherwise the default
                 * schema index needs to be updated later in this function.
                 */
-               { "smtp://",            RELAY_TLS_OPTIONAL              },
-               { "smtp+tls://",        RELAY_STARTTLS                  },
-               { "smtp+notls://",      0                               },
-               { "lmtp://",            RELAY_LMTP                      },
-               { "smtps://",           RELAY_SMTPS                     }
+               { "smtp://",            RELAY_TLS_OPPORTUNISTIC, 0              
},
+               { "smtp+tls://",        RELAY_TLS_STARTTLS,      0              
},
+               { "smtp+notls://",      RELAY_TLS_NO,            0              
},
+               { "lmtp://",            RELAY_TLS_NO,            RELAY_LMTP     
},
+               { "smtps://",           RELAY_TLS_SMTPS,         0              
}
        };
        const char     *errstr = NULL;
        char           *p, *q;
@@ -344,6 +345,7 @@ text_to_relayhost(struct relayhost *rela
        else
                p = buffer + strlen(schemas[i].name);
 
+       relay->tls = schemas[i].tls;
        relay->flags = schemas[i].flags;
 
        /* need to specify an explicit port for LMTP */
@@ -395,7 +397,8 @@ text_to_relayhost(struct relayhost *rela
                return 0;
        if (relay->authlabel[0]) {
                /* disallow auth on non-tls scheme. */
-               if (!(relay->flags & (RELAY_STARTTLS | RELAY_SMTPS)))
+               if (relay->tls != RELAY_TLS_STARTTLS &&
+                   relay->tls != RELAY_TLS_SMTPS)
                        return 0;
                relay->flags |= RELAY_AUTH;
        }

Reply via email to