aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Faurot <eric@faurot.net>2013-10-10 12:13:57 +0200
committerEric Faurot <eric@faurot.net>2013-10-10 12:13:57 +0200
commit350bcde7481388736632dd56337226af4d6fd5d7 (patch)
treedbd506ce73d4bf8049e10e9cbef06168a9d9cfd4
parentmissing stat counter update (diff)
downloadOpenSMTPD-opensmtpd-201310101757.tar.xz
OpenSMTPD-opensmtpd-201310101757.zip
Allow to specify a hostname on relay rule:opensmtpd-201310101757
accept ... relay hostname "foobar" Tweak the on-disk envelope format a bit, but make update seamless for existing envelopes.
-rw-r--r--smtpd/envelope.c24
-rw-r--r--smtpd/mta.c19
-rw-r--r--smtpd/mta_session.c2
-rw-r--r--smtpd/parse.y5
-rw-r--r--smtpd/smtpd.conf.530
-rw-r--r--smtpd/smtpd.h5
6 files changed, 76 insertions, 9 deletions
diff --git a/smtpd/envelope.c b/smtpd/envelope.c
index 5ee1e080..f5f40ebd 100644
--- a/smtpd/envelope.c
+++ b/smtpd/envelope.c
@@ -115,7 +115,9 @@ envelope_load_buffer(struct envelope *ep, const char *ibuf, size_t buflen)
EVP_MTA_RELAY_SOURCE,
EVP_MTA_RELAY_CERT,
EVP_MTA_RELAY_AUTH,
- EVP_MTA_RELAY_HELO,
+ EVP_MTA_RELAY_HELONAME,
+ EVP_MTA_RELAY_HELOTABLE,
+ EVP_MTA_RELAY_HELOTABLEOLD,
EVP_MTA_RELAY_FLAGS,
EVP_MTA_RELAY,
EVP_BOUNCE_TYPE,
@@ -217,7 +219,8 @@ envelope_dump_buffer(const struct envelope *ep, char *dest, size_t len)
EVP_MTA_RELAY_SOURCE,
EVP_MTA_RELAY_CERT,
EVP_MTA_RELAY_AUTH,
- EVP_MTA_RELAY_HELO,
+ EVP_MTA_RELAY_HELONAME,
+ EVP_MTA_RELAY_HELOTABLE,
EVP_MTA_RELAY_FLAGS,
EVP_MTA_RELAY,
};
@@ -346,7 +349,11 @@ envelope_ascii_field_name(enum envelope_field field)
return "mta-relay-flags";
case EVP_MTA_RELAY_SOURCE:
return "mta-relay-source";
- case EVP_MTA_RELAY_HELO:
+ case EVP_MTA_RELAY_HELONAME:
+ return "mta-relay-heloname";
+ case EVP_MTA_RELAY_HELOTABLE:
+ return "mta-relay-helotable";
+ case EVP_MTA_RELAY_HELOTABLEOLD:
return "mta-relay-helo";
case EVP_BOUNCE_TYPE:
return "bounce-type";
@@ -409,7 +416,11 @@ envelope_ascii_load(enum envelope_field field, struct envelope *ep, char *buf)
case EVP_MTA_RELAY_AUTH:
return ascii_load_string(ep->agent.mta.relay.authtable, buf,
sizeof ep->agent.mta.relay.authtable);
- case EVP_MTA_RELAY_HELO:
+ case EVP_MTA_RELAY_HELONAME:
+ return ascii_load_string(ep->agent.mta.relay.heloname, buf,
+ sizeof ep->agent.mta.relay.heloname);
+ case EVP_MTA_RELAY_HELOTABLEOLD:
+ case EVP_MTA_RELAY_HELOTABLE:
return ascii_load_string(ep->agent.mta.relay.helotable, buf,
sizeof ep->agent.mta.relay.helotable);
case EVP_MTA_RELAY_FLAGS:
@@ -491,7 +502,10 @@ envelope_ascii_dump(enum envelope_field field, const struct envelope *ep,
case EVP_MTA_RELAY_AUTH:
return ascii_dump_string(ep->agent.mta.relay.authtable,
buf, len);
- case EVP_MTA_RELAY_HELO:
+ case EVP_MTA_RELAY_HELONAME:
+ return ascii_dump_string(ep->agent.mta.relay.heloname,
+ buf, len);
+ case EVP_MTA_RELAY_HELOTABLE:
return ascii_dump_string(ep->agent.mta.relay.helotable,
buf, len);
case EVP_MTA_RELAY_FLAGS:
diff --git a/smtpd/mta.c b/smtpd/mta.c
index 59592695..03ab187c 100644
--- a/smtpd/mta.c
+++ b/smtpd/mta.c
@@ -1572,6 +1572,9 @@ mta_relay(struct envelope *e)
key.helotable = e->agent.mta.relay.helotable;
if (!key.helotable[0])
key.helotable = NULL;
+ key.heloname = e->agent.mta.relay.heloname;
+ if (!key.heloname[0])
+ key.heloname = NULL;
if ((r = SPLAY_FIND(mta_relay_tree, &relays, &key)) == NULL) {
r = xcalloc(1, sizeof *r, "mta_relay");
@@ -1594,6 +1597,9 @@ mta_relay(struct envelope *e)
if (key.helotable)
r->helotable = xstrdup(key.helotable,
"mta: helotable");
+ if (key.heloname)
+ r->heloname = xstrdup(key.heloname,
+ "mta: heloname");
SPLAY_INSERT(mta_relay_tree, &relays, r);
stat_increment("mta.relay", 1);
} else {
@@ -1635,6 +1641,7 @@ mta_relay_unref(struct mta_relay *relay)
free(relay->backupname);
free(relay->cert);
free(relay->helotable);
+ free(relay->heloname);
free(relay->secret);
free(relay->sourcetable);
@@ -1707,6 +1714,12 @@ mta_relay_to_text(struct mta_relay *relay)
strlcat(buf, relay->helotable, sizeof buf);
}
+ if (relay->heloname) {
+ strlcat(buf, sep, sizeof buf);
+ strlcat(buf, "heloname=", sizeof buf);
+ strlcat(buf, relay->heloname, sizeof buf);
+ }
+
strlcat(buf, "]", sizeof buf);
return (buf);
@@ -1844,6 +1857,12 @@ mta_relay_cmp(const struct mta_relay *a, const struct mta_relay *b)
return (1);
if (a->helotable && ((r = strcmp(a->helotable, b->helotable))))
return (r);
+ if (a->heloname == NULL && b->heloname)
+ return (-1);
+ if (a->heloname && b->heloname == NULL)
+ return (1);
+ if (a->heloname && ((r = strcmp(a->heloname, b->heloname))))
+ return (r);
if (a->cert == NULL && b->cert)
return (-1);
diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c
index fe7e4fda..5dd60428 100644
--- a/smtpd/mta_session.c
+++ b/smtpd/mta_session.c
@@ -509,7 +509,7 @@ mta_connect(struct mta_session *s)
s->flags |= MTA_WAIT;
return;
}
- if (s->relay->heloname)
+ else if (s->relay->heloname)
s->helo = xstrdup(s->relay->heloname, "mta_connect");
else
s->helo = xstrdup(env->sc_hostname, "mta_connect");
diff --git a/smtpd/parse.y b/smtpd/parse.y
index 1c7f3340..662cf6c4 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -387,6 +387,11 @@ opt_relay_common: AS STRING {
strlcpy(rule->r_value.relayhost.sourcetable, t->t_name,
sizeof rule->r_value.relayhost.sourcetable);
}
+ | HOSTNAME STRING {
+ strlcat(rule->r_value.relayhost.heloname, $2,
+ sizeof rule->r_value.relayhost.heloname);
+ free($2);
+ }
| HOSTNAMES tables {
struct table *t = $2;
if (! table_check_use(t, T_DYNAMIC|T_HASH, K_ADDRNAME)) {
diff --git a/smtpd/smtpd.conf.5 b/smtpd/smtpd.conf.5
index 3d699df4..ad98bd4f 100644
--- a/smtpd/smtpd.conf.5
+++ b/smtpd/smtpd.conf.5
@@ -309,6 +309,7 @@ This parameter may use conversion specifiers that are expanded before use
.Op Ic as Ar address
.Op Ic source Ar source
.Bk -words
+.Op Ic hostname Ar name
.Op Ic hostnames Ar names
.Ek
.Op Ic pki Ar pkiname
@@ -355,14 +356,26 @@ By default, when connecting to a remote server,
.Xr smtpd 8
advertises its default server name.
A
+.Ic hostname
+parameter may be specified to advertise the alternate hostname
+.Ar name .
+If the
+.Ic source
+parameter is used, the
.Ic hostnames
-parameter may be specified to advertise an alternate hostname.
+parameter may be specified to advertise a hostname based on
+the source address.
Table
.Ar names
contains a mapping of IP addresses to hostnames and
.Xr smtpd 8
will automatically select the name that matches its source address
when connected to the remote server.
+The
+.Ic hostname
+and
+.Ic hostnames
+parameters are mutually exclusive.
.Pp
When relaying, STARTTLS is always attempted if available on remote host
and OpenSMTPD will try to present a certificate matching the outgoing
@@ -395,6 +408,7 @@ as they will prevent proper relaying on the Internet.
.Op Ic auth Aq Ar auth
.Op Ic as Ar address
.Op Ic source Ar source
+.Op Ic hostname Ar name
.Op Ic hostnames Ar names
.Op Ic pki Ar pkiname
.Xc
@@ -471,14 +485,26 @@ By default, when connecting to a remote server,
.Xr smtpd 8
advertises its default server name.
A
+.Ic hostname
+parameter may be specified to advertise the alternate hostname
+.Ar name .
+If the
+.Ic source
+parameter is used, the
.Ic hostnames
-parameter may be specified to advertise an alternate hostname.
+parameter may be specified to advertise a hostname based on
+the source address.
Table
.Ar names
contains a mapping of IP addresses to hostnames and
.Xr smtpd 8
will automatically select the name that matches its source address
when connected to the remote server.
+The
+.Ic hostname
+and
+.Ic hostnames
+parameters are mutually exclusive.
.El
.Pp
Additional per-rule adjustments available:
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index 2b6dabcd..f8f3a2f8 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -109,6 +109,7 @@ struct relayhost {
char authtable[SMTPD_MAXPATHLEN];
char authlabel[SMTPD_MAXPATHLEN];
char sourcetable[SMTPD_MAXPATHLEN];
+ char heloname[SMTPD_MAXHOSTNAMELEN];
char helotable[SMTPD_MAXPATHLEN];
};
@@ -492,7 +493,9 @@ enum envelope_field {
EVP_MTA_RELAY_AUTH,
EVP_MTA_RELAY_CERT,
EVP_MTA_RELAY_SOURCE,
- EVP_MTA_RELAY_HELO,
+ EVP_MTA_RELAY_HELONAME,
+ EVP_MTA_RELAY_HELOTABLE,
+ EVP_MTA_RELAY_HELOTABLEOLD,
EVP_MTA_RELAY_FLAGS,
EVP_BOUNCE_TYPE,
EVP_BOUNCE_DELAY,