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;
}