diff options
-rw-r--r-- | smtpd/mta_session.c | 55 | ||||
-rw-r--r-- | smtpd/smtp_session.c | 12 | ||||
-rw-r--r-- | smtpd/smtpd.conf.5 | 6 |
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 |