aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--smtpd/mta_session.c55
-rw-r--r--smtpd/smtp_session.c12
-rw-r--r--smtpd/smtpd.conf.56
3 files changed, 58 insertions, 15 deletions
diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c
index 4a631daf..f337539c 100644
--- a/smtpd/mta_session.c
+++ b/smtpd/mta_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta_session.c,v 1.33 2013/02/15 22:43:21 eric Exp $ */
+/* $OpenBSD: mta_session.c,v 1.34 2013/02/21 16:25:21 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -85,8 +85,8 @@ enum mta_state {
#define MTA_VERIFIED 0x0200
#define MTA_FREE 0x0400
-
#define MTA_LMTP 0x0800
+#define MTA_WAIT 0x1000
#define MTA_EXT_STARTTLS 0x01
#define MTA_EXT_AUTH 0x02
@@ -136,6 +136,7 @@ static const char * mta_strstate(int);
static int mta_check_loop(FILE *);
static void mta_start_tls(struct mta_session *);
static int mta_verify_certificate(struct mta_session *);
+static struct mta_session *mta_tree_pop(struct tree *, uint64_t);
static struct tree wait_helo;
static struct tree wait_ptr;
@@ -213,6 +214,7 @@ mta_session(struct mta_relay *relay, struct mta_route *route)
} else if (waitq_wait(&route->dst->ptrname, mta_on_ptr, s)) {
dns_query_ptr(s->id, s->route->dst->sa);
tree_xset(&wait_ptr, s->id, s);
+ s->flags |= MTA_WAIT;
}
}
@@ -238,7 +240,12 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
if (imsg->fd == -1)
fatalx("mta: cannot obtain msgfd");
- s = tree_xpop(&wait_fd, reqid);
+ s = mta_tree_pop(&wait_fd, reqid);
+ if (s == NULL) {
+ close(imsg->fd);
+ return;
+ }
+
s->datafp = fdopen(imsg->fd, "r");
if (s->datafp == NULL)
fatal("mta: fdopen");
@@ -265,7 +272,10 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
else
m_get_string(&m, &name);
m_end(&m);
- s = tree_xpop(&wait_ptr, reqid);
+ s = mta_tree_pop(&wait_ptr, reqid);
+ if (s == NULL)
+ return;
+
h = s->route->dst;
h->lastptrquery = time(NULL);
if (name)
@@ -275,7 +285,9 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_LKA_SSL_INIT:
resp_ca_cert = imsg->data;
- s = tree_xpop(&wait_ssl_init, resp_ca_cert->reqid);
+ s = mta_tree_pop(&wait_ssl_init, resp_ca_cert->reqid);
+ if (s == NULL)
+ return;
if (resp_ca_cert->status == CA_FAIL) {
log_info("smtp-out: Disconnecting session %016" PRIx64
@@ -308,7 +320,9 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
case IMSG_LKA_SSL_VERIFY:
resp_ca_vrfy = imsg->data;
- s = tree_xpop(&wait_ssl_verify, resp_ca_vrfy->reqid);
+ s = mta_tree_pop(&wait_ssl_verify, resp_ca_vrfy->reqid);
+ if (s == NULL)
+ return;
if (resp_ca_vrfy->status == CA_OK)
s->flags |= MTA_VERIFIED;
@@ -326,7 +340,9 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
m_get_string(&m, &name);
m_end(&m);
- s = tree_xpop(&wait_helo, reqid);
+ s = mta_tree_pop(&wait_helo, reqid);
+ if (s == NULL)
+ return;
if (status == LKA_OK) {
s->helo = xstrdup(name, "mta_session_imsg");
@@ -344,6 +360,22 @@ mta_session_imsg(struct mproc *p, struct imsg *imsg)
}
}
+static struct mta_session *
+mta_tree_pop(struct tree *wait, uint64_t reqid)
+{
+ struct mta_session *s;
+
+ s = tree_xpop(wait, reqid);
+ if (s->flags & MTA_FREE) {
+ log_debug("debug: mta: %p: zombie session", s);
+ mta_free(s);
+ return (NULL);
+ }
+ s->flags &= ~MTA_WAIT;
+
+ return (s);
+}
+
static void
mta_free(struct mta_session *s)
{
@@ -401,6 +433,7 @@ mta_connect(struct mta_session *s)
m_add_sockaddr(p_lka, s->route->src->sa);
m_close(p_lka);
tree_xset(&wait_helo, s->id, s);
+ s->flags |= MTA_WAIT;
return;
}
if (s->relay->heloname)
@@ -583,6 +616,7 @@ mta_enter_state(struct mta_session *s, int newstate)
m_close(p_queue);
tree_xset(&wait_fd, s->id, s);
+ s->flags |= MTA_WAIT;
break;
case MTA_MAIL:
@@ -923,7 +957,10 @@ mta_io(struct io *io, int evt)
if (iobuf_len(&s->iobuf)) {
log_debug("debug: mta: remaining data in input buffer");
mta_error(s, "Remote host sent too much data");
- mta_free(s);
+ if (s->flags & MTA_WAIT)
+ s->flags |= MTA_FREE;
+ else
+ mta_free(s);
}
break;
@@ -1158,6 +1195,7 @@ mta_start_tls(struct mta_session *s)
m_compose(p_lka, IMSG_LKA_SSL_INIT, 0, 0, -1,
&req_ca_cert, sizeof(req_ca_cert));
tree_xset(&wait_ssl_init, s->id, s);
+ s->flags |= MTA_WAIT;
return;
}
ssl = ssl_mta_init(NULL, 0, NULL, 0);
@@ -1189,6 +1227,7 @@ mta_verify_certificate(struct mta_session *s)
*/
tree_xset(&wait_ssl_verify, s->id, s);
+ s->flags |= MTA_WAIT;
/* Send the client certificate */
bzero(&req_ca_vrfy, sizeof req_ca_vrfy);
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 0ac7ee92..ab8105cc 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.180 2013/02/16 16:20:07 gilles Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.181 2013/02/21 14:22:52 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -79,6 +79,7 @@ enum session_flags {
SF_BOUNCE = 0x0010,
SF_KICK = 0x0020,
SF_VERIFIED = 0x0040,
+ SF_MFACONNSENT = 0x0080,
};
enum message_flags {
@@ -1300,6 +1301,7 @@ smtp_connected(struct smtp_session *s)
m_add_sockaddr(p_mfa, (struct sockaddr *)&s->ss);
m_add_string(p_mfa, s->hostname);
m_close(p_mfa);
+ s->flags |= SF_MFACONNSENT;
smtp_wait_mfa(s, IMSG_MFA_REQ_CONNECT);
}
@@ -1446,9 +1448,11 @@ smtp_free(struct smtp_session *s, const char * reason)
m_close(p_queue);
}
- m_create(p_mfa, IMSG_MFA_EVENT_DISCONNECT, 0, 0, -1, 16);
- m_add_id(p_mfa, s->id);
- m_close(p_mfa);
+ if (s->flags & SF_MFACONNSENT) {
+ m_create(p_mfa, IMSG_MFA_EVENT_DISCONNECT, 0, 0, -1, 16);
+ m_add_id(p_mfa, s->id);
+ m_close(p_mfa);
+ }
if (s->flags & SF_SECURE && s->listener->flags & F_SMTPS)
stat_decrement("smtp.smtps", 1);
diff --git a/smtpd/smtpd.conf.5 b/smtpd/smtpd.conf.5
index e24a2660..dcbc3473 100644
--- a/smtpd/smtpd.conf.5
+++ b/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.91 2013/02/17 12:28:30 gilles Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.92 2013/02/17 17:45:01 jmc Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -567,7 +567,7 @@ the name itself is arbitrarily chosen.
.Pp
The table must contain at least one value and may declare many values as a
list of comma separated strings.
-.It Ic table Ar name Brq Ar key = value Op , Ar ...
+.It Ic table Ar name Brq Ar key Ns = Ns Ar value Op , Ar ...
Tables containing static key-value mappings may be declared
using an inlined notation.
.Pp
@@ -577,7 +577,7 @@ the name itself is arbitrarily chosen.
.Pp
The table must contain at least one key-value mapping and may declare
many mappings as a list of comma separated
-.Ar key = value
+.Ar key Ns = Ns Ar value
descriptions.
.El
.Sh FILES