aboutsummaryrefslogtreecommitdiffstats
path: root/smtpd
diff options
context:
space:
mode:
authorgilles <gilles@poolp.org>2016-06-23 17:44:05 +0200
committergilles <gilles@poolp.org>2016-06-23 17:44:05 +0200
commit0f8afea264118cd46b3d7c4b5be240ce5d76c253 (patch)
tree89308c32a6c582f6c1f945f419036f00b539eea3 /smtpd
parentsync with OpenBSD: (diff)
downloadOpenSMTPD-0f8afea264118cd46b3d7c4b5be240ce5d76c253.tar.xz
OpenSMTPD-0f8afea264118cd46b3d7c4b5be240ce5d76c253.zip
split session and transaction in smtp_session, by eric@
Diffstat (limited to 'smtpd')
-rw-r--r--smtpd/CVS/Entries150
-rw-r--r--smtpd/smtp_session.c341
2 files changed, 266 insertions, 225 deletions
diff --git a/smtpd/CVS/Entries b/smtpd/CVS/Entries
index 77b913c9..e3c1bc8c 100644
--- a/smtpd/CVS/Entries
+++ b/smtpd/CVS/Entries
@@ -2,89 +2,89 @@ D/smtpctl////
D/smtpd////
/Makefile/1.15/Mon Mar 7 16:27:28 2016//
/aliases.5/1.12/Mon Mar 7 16:27:28 2016//
-/aliases.c/1.70/Tue Jun 21 07:41:24 2016//
-/bounce.c/1.72/Tue Jun 21 07:41:24 2016//
-/ca.c/1.22/Tue Jun 21 07:41:24 2016//
-/compress_backend.c/1.9/Tue Jun 21 07:41:24 2016//
-/compress_gzip.c/1.10/Tue Jun 21 07:41:24 2016//
-/config.c/1.35/Tue Jun 21 07:41:24 2016//
-/control.c/1.113/Tue Jun 21 07:41:24 2016//
-/crypto.c/1.5/Tue Jun 21 07:41:24 2016//
-/delivery.c/1.6/Tue Jun 21 07:41:24 2016//
-/delivery_filename.c/1.14/Tue Jun 21 07:41:24 2016//
-/delivery_lmtp.c/1.17/Tue Jun 21 07:41:24 2016//
-/delivery_maildir.c/1.17/Tue Jun 21 07:41:24 2016//
-/delivery_mbox.c/1.12/Tue Jun 21 07:41:24 2016//
-/delivery_mda.c/1.9/Tue Jun 21 07:41:24 2016//
-/dict.c/1.5/Tue Jun 21 07:41:24 2016//
-/dns.c/1.83/Tue Jun 21 07:41:24 2016//
-/enqueue.c/1.112/Tue Jun 21 07:41:24 2016//
-/envelope.c/1.36/Tue Jun 21 07:41:24 2016//
-/esc.c/1.4/Tue Jun 21 07:41:24 2016//
-/expand.c/1.29/Tue Jun 21 07:41:24 2016//
-/filter.c/1.18/Tue Jun 21 07:41:24 2016//
/forward.5/1.9/Mon Mar 7 16:27:28 2016//
-/forward.c/1.39/Tue Jun 21 07:41:24 2016//
-/iobuf.c/1.9/Tue Jun 21 07:41:24 2016//
/iobuf.h/1.4/Mon Mar 7 16:27:28 2016//
-/ioev.c/1.26/Tue Jun 21 07:41:24 2016//
/ioev.h/1.6/Wed May 18 07:36:31 2016//
-/limit.c/1.5/Tue Jun 21 07:41:27 2016//
-/lka.c/1.193/Tue Jun 21 07:41:24 2016//
-/lka_session.c/1.79/Tue Jun 21 07:41:24 2016//
-/log.c/1.17/Tue Jun 21 07:41:24 2016//
-/log.h/1.5/Tue Jun 21 07:41:24 2016//
-/mailaddr.c/1.2/Tue Jun 21 07:41:24 2016//
/makemap.8/1.29/Mon Mar 7 16:27:28 2016//
-/makemap.c/1.65/Tue Jun 21 07:41:24 2016//
-/mda.c/1.119/Tue Jun 21 07:41:24 2016//
-/mproc.c/1.20/Tue Jun 21 07:41:24 2016//
-/mta.c/1.201/Tue Jun 21 07:41:24 2016//
-/mta_session.c/1.83/Tue Jun 21 07:41:24 2016//
/newaliases.8/1.11/Mon Mar 7 16:27:28 2016//
-/parse.y/1.185/Wed Jun 22 05:50:11 2016//
-/parser.c/1.40/Tue Jun 21 07:41:24 2016//
/parser.h/1.29/Mon Mar 7 16:27:28 2016//
-/pony.c/1.13/Tue Jun 21 07:41:24 2016//
-/queue.c/1.178/Tue Jun 21 07:41:24 2016//
-/queue_backend.c/1.62/Tue Jun 21 07:41:24 2016//
-/queue_fs.c/1.14/Tue Jun 21 07:41:24 2016//
-/queue_null.c/1.6/Tue Jun 21 07:41:24 2016//
-/queue_proc.c/1.6/Tue Jun 21 07:41:24 2016//
-/queue_ram.c/1.7/Tue Jun 21 07:41:24 2016//
-/rfc2822.c/1.7/Tue Jun 21 07:41:24 2016//
/rfc2822.h/1.4/Mon Mar 7 16:27:28 2016//
-/ruleset.c/1.32/Tue Jun 21 07:41:24 2016//
-/runq.c/1.2/Tue Jun 21 07:41:24 2016//
-/scheduler.c/1.52/Tue Jun 21 07:41:24 2016//
-/scheduler_backend.c/1.15/Tue Jun 21 07:41:24 2016//
-/scheduler_null.c/1.9/Tue Jun 21 07:41:24 2016//
-/scheduler_proc.c/1.8/Tue Jun 21 07:41:24 2016//
-/scheduler_ramqueue.c/1.42/Tue Jun 21 07:41:24 2016//
/sendmail.8/1.4/Mon Mar 7 16:27:28 2016//
-/smtp.c/1.155/Tue Jun 21 07:41:24 2016//
-/smtp_session.c/1.276/Wed Jun 22 05:50:11 2016//
-/smtpctl.8/1.57/Tue Jun 21 07:41:27 2016//
-/smtpctl.c/1.149/Tue Jun 21 07:41:24 2016//
/smtpd-api.h/1.29/Mon Mar 7 16:27:28 2016//
-/smtpd-defines.h/1.6/Tue Jun 21 07:41:24 2016//
/smtpd.8/1.30/Wed May 18 07:36:31 2016//
-/smtpd.c/1.279/Wed Jun 22 05:50:11 2016//
-/smtpd.conf.5/1.161/Tue Jun 21 07:41:24 2016//
-/smtpd.h/1.515/Tue Jun 21 07:41:24 2016//
-/ssl.c/1.86/Tue Jun 21 07:41:24 2016//
-/ssl.h/1.20/Tue Jun 21 07:41:24 2016//
-/ssl_smtpd.c/1.13/Tue Jun 21 07:41:24 2016//
-/stat_backend.c/1.10/Tue Jun 21 07:41:24 2016//
-/stat_ramstat.c/1.10/Tue Jun 21 07:41:24 2016//
/table.5/1.5/Mon Mar 7 16:27:28 2016//
-/table.c/1.23/Tue Jun 21 07:41:24 2016//
-/table_api.c/1.8/Tue Jun 21 07:41:24 2016//
-/table_db.c/1.9/Tue Jun 21 07:41:24 2016//
-/table_getpwnam.c/1.4/Tue Jun 21 07:41:24 2016//
-/table_proc.c/1.6/Tue Jun 21 07:41:24 2016//
-/table_static.c/1.15/Tue Jun 21 07:41:24 2016//
-/to.c/1.28/Tue Jun 21 07:41:24 2016//
-/tree.c/1.5/Tue Jun 21 07:41:24 2016//
-/util.c/1.127/Tue Jun 21 07:41:24 2016//
-/waitq.c/1.5/Tue Jun 21 07:41:24 2016//
+/aliases.c/1.70/Wed Jun 22 06:15:50 2016//
+/bounce.c/1.72/Wed Jun 22 06:15:50 2016//
+/ca.c/1.22/Wed Jun 22 06:15:50 2016//
+/compress_backend.c/1.9/Wed Jun 22 06:15:50 2016//
+/compress_gzip.c/1.10/Wed Jun 22 06:15:50 2016//
+/config.c/1.35/Wed Jun 22 06:15:50 2016//
+/control.c/1.113/Wed Jun 22 06:15:50 2016//
+/crypto.c/1.5/Wed Jun 22 06:15:50 2016//
+/delivery.c/1.6/Wed Jun 22 06:15:50 2016//
+/delivery_filename.c/1.14/Wed Jun 22 06:15:50 2016//
+/delivery_lmtp.c/1.17/Wed Jun 22 06:15:50 2016//
+/delivery_maildir.c/1.17/Wed Jun 22 06:15:50 2016//
+/delivery_mbox.c/1.12/Wed Jun 22 06:15:50 2016//
+/delivery_mda.c/1.9/Wed Jun 22 06:15:50 2016//
+/dict.c/1.5/Wed Jun 22 06:15:50 2016//
+/dns.c/1.83/Wed Jun 22 06:15:50 2016//
+/enqueue.c/1.112/Wed Jun 22 06:15:50 2016//
+/envelope.c/1.36/Wed Jun 22 06:15:50 2016//
+/esc.c/1.4/Wed Jun 22 06:15:50 2016//
+/expand.c/1.29/Wed Jun 22 06:15:50 2016//
+/filter.c/1.18/Wed Jun 22 06:15:50 2016//
+/forward.c/1.39/Wed Jun 22 06:15:50 2016//
+/iobuf.c/1.9/Wed Jun 22 06:15:50 2016//
+/ioev.c/1.26/Wed Jun 22 06:15:50 2016//
+/limit.c/1.5/Wed Jun 22 06:15:50 2016//
+/lka.c/1.193/Wed Jun 22 06:15:50 2016//
+/lka_session.c/1.79/Wed Jun 22 06:15:50 2016//
+/log.c/1.17/Wed Jun 22 06:15:50 2016//
+/log.h/1.5/Wed Jun 22 06:15:50 2016//
+/mailaddr.c/1.2/Wed Jun 22 06:15:50 2016//
+/makemap.c/1.65/Wed Jun 22 06:15:50 2016//
+/mda.c/1.119/Wed Jun 22 06:15:50 2016//
+/mproc.c/1.20/Wed Jun 22 06:15:50 2016//
+/mta.c/1.201/Wed Jun 22 06:15:50 2016//
+/mta_session.c/1.83/Wed Jun 22 06:15:50 2016//
+/parse.y/1.185/Wed Jun 22 06:15:50 2016//
+/parser.c/1.40/Wed Jun 22 06:15:50 2016//
+/pony.c/1.13/Wed Jun 22 06:15:50 2016//
+/queue.c/1.178/Wed Jun 22 06:15:50 2016//
+/queue_backend.c/1.62/Wed Jun 22 06:15:50 2016//
+/queue_fs.c/1.14/Wed Jun 22 06:15:50 2016//
+/queue_null.c/1.6/Wed Jun 22 06:15:50 2016//
+/queue_proc.c/1.6/Wed Jun 22 06:15:50 2016//
+/queue_ram.c/1.7/Wed Jun 22 06:15:50 2016//
+/rfc2822.c/1.7/Wed Jun 22 06:15:50 2016//
+/ruleset.c/1.32/Wed Jun 22 06:15:50 2016//
+/runq.c/1.2/Wed Jun 22 06:15:50 2016//
+/scheduler.c/1.52/Wed Jun 22 06:15:50 2016//
+/scheduler_backend.c/1.15/Wed Jun 22 06:15:50 2016//
+/scheduler_null.c/1.9/Wed Jun 22 06:15:50 2016//
+/scheduler_proc.c/1.8/Wed Jun 22 06:15:50 2016//
+/scheduler_ramqueue.c/1.42/Wed Jun 22 06:15:50 2016//
+/smtp.c/1.155/Wed Jun 22 06:15:50 2016//
+/smtp_session.c/1.277/Thu Jun 23 15:43:56 2016//
+/smtpctl.8/1.57/Wed Jun 22 05:52:29 2016//
+/smtpctl.c/1.149/Wed Jun 22 06:15:50 2016//
+/smtpd-defines.h/1.6/Wed Jun 22 06:15:50 2016//
+/smtpd.c/1.279/Wed Jun 22 06:15:50 2016//
+/smtpd.conf.5/1.161/Wed Jun 22 06:15:50 2016//
+/smtpd.h/1.515/Wed Jun 22 06:15:50 2016//
+/ssl.c/1.86/Wed Jun 22 06:15:50 2016//
+/ssl.h/1.20/Wed Jun 22 06:15:50 2016//
+/ssl_smtpd.c/1.13/Wed Jun 22 06:15:50 2016//
+/stat_backend.c/1.10/Wed Jun 22 06:15:50 2016//
+/stat_ramstat.c/1.10/Wed Jun 22 06:15:50 2016//
+/table.c/1.23/Wed Jun 22 06:15:50 2016//
+/table_api.c/1.8/Wed Jun 22 06:15:50 2016//
+/table_db.c/1.9/Wed Jun 22 06:15:50 2016//
+/table_getpwnam.c/1.4/Wed Jun 22 06:15:50 2016//
+/table_proc.c/1.6/Wed Jun 22 06:15:50 2016//
+/table_static.c/1.15/Wed Jun 22 06:15:50 2016//
+/to.c/1.28/Wed Jun 22 06:15:50 2016//
+/tree.c/1.5/Wed Jun 22 06:15:50 2016//
+/util.c/1.127/Wed Jun 22 06:15:50 2016//
+/waitq.c/1.5/Wed Jun 22 06:15:50 2016//
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index 05425f41..f8795607 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.276 2016/06/17 18:56:51 otto Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.277 2016/06/23 11:56:19 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -110,6 +110,28 @@ struct smtp_rcpt {
size_t destcount;
};
+struct smtp_tx {
+ struct smtp_session *session;
+
+ struct envelope evp;
+ size_t rcptcount;
+ size_t destcount;
+ TAILQ_HEAD(, smtp_rcpt) rcpts;
+
+ size_t odatalen;
+ struct iobuf obuf;
+ struct io oev;
+ int hdrdone;
+ int rcvcount;
+ int dataeom;
+
+ int msgflags;
+ int msgcode;
+
+ int skiphdr;
+ struct rfc2822_parser rfc2822_parser;
+};
+
struct smtp_session {
uint64_t id;
struct iobuf iobuf;
@@ -128,28 +150,13 @@ struct smtp_session {
char cmd[LINE_MAX];
char username[SMTPD_MAXMAILADDRSIZE];
- struct envelope evp;
-
size_t mailcount;
- int msgflags;
- int msgcode;
- size_t rcptcount;
- size_t destcount;
- TAILQ_HEAD(, smtp_rcpt) rcpts;
-
size_t datain;
- size_t odatalen;
- struct iobuf obuf;
- struct io oev;
- int hdrdone;
- int rcvcount;
- int dataeom;
- int skiphdr;
struct event pause;
- struct rfc2822_parser rfc2822_parser;
+ struct smtp_tx *tx;
};
#define ADVERTISE_TLS(s) \
@@ -187,6 +194,9 @@ static uint8_t dsn_notify_str_to_uint8(const char *);
static void smtp_auth_failure_pause(struct smtp_session *);
static void smtp_auth_failure_resume(int, short, void *);
+static int smtp_tx(struct smtp_session *);
+static void smtp_tx_free(struct smtp_tx *);
+
static void smtp_queue_create_message(struct smtp_session *);
static void smtp_queue_open_message(struct smtp_session *);
static void smtp_queue_commit(struct smtp_session *);
@@ -537,7 +547,7 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
if (l->buffer[i] == ',' && !escape && !quote && !comment) {
if (!skip && j + strlen(s->listener->hostname) + 1 < sizeof buffer) {
header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
- header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->evp.sender),
+ header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender),
sizeof buffer);
}
if (smtp_message_printf(s, "%s,", buffer) == -1)
@@ -583,7 +593,7 @@ header_masquerade_callback(const struct rfc2822_header *hdr, void *arg)
if (buffer[0]) {
if (j + strlen(s->listener->hostname) + 1 < sizeof buffer) {
header_append_domain_buffer(buffer, s->listener->hostname, sizeof buffer);
- header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->evp.sender),
+ header_address_rewrite_buffer(buffer, mailaddr_to_text(&s->tx->evp.sender),
sizeof buffer);
}
smtp_message_printf(s, "%s", buffer);
@@ -637,11 +647,18 @@ smtp_session(struct listener *listener, int sock,
if ((s = calloc(1, sizeof(*s))) == NULL)
return (-1);
+
+ if (smtp_tx(s) == 0) {
+ free(s);
+ return -1;
+ }
+
if (iobuf_init(&s->iobuf, LINE_MAX, LINE_MAX) == -1) {
+ smtp_tx_free(s->tx);
free(s);
return (-1);
}
- TAILQ_INIT(&s->rcpts);
+ TAILQ_INIT(&s->tx->rcpts);
s->id = generate_uid();
s->listener = listener;
@@ -649,7 +666,7 @@ smtp_session(struct listener *listener, int sock,
io_init(&s->io, sock, s, smtp_io, &s->iobuf);
io_set_timeout(&s->io, SMTPD_SESSION_TIMEOUT * 1000);
io_set_write(&s->io);
- io_init(&s->oev, -1, s, NULL, NULL); /* initialise 'sock', but not to 0 */
+ io_init(&s->tx->oev, -1, s, NULL, NULL); /* initialise 'sock', but not to 0 */
s->state = STATE_NEW;
s->phase = PHASE_INIT;
@@ -661,24 +678,24 @@ smtp_session(struct listener *listener, int sock,
listener->hostname, ntohs(listener->port), listener->tag);
/* Setup parser and callbacks before smtp_connected() can be called */
- rfc2822_parser_init(&s->rfc2822_parser);
- rfc2822_header_default_callback(&s->rfc2822_parser,
+ rfc2822_parser_init(&s->tx->rfc2822_parser);
+ rfc2822_header_default_callback(&s->tx->rfc2822_parser,
header_default_callback, s);
- rfc2822_header_callback(&s->rfc2822_parser, "bcc",
+ rfc2822_header_callback(&s->tx->rfc2822_parser, "bcc",
header_bcc_callback, s);
- rfc2822_header_callback(&s->rfc2822_parser, "from",
+ rfc2822_header_callback(&s->tx->rfc2822_parser, "from",
header_domain_append_callback, s);
- rfc2822_header_callback(&s->rfc2822_parser, "to",
+ rfc2822_header_callback(&s->tx->rfc2822_parser, "to",
header_domain_append_callback, s);
- rfc2822_header_callback(&s->rfc2822_parser, "cc",
+ rfc2822_header_callback(&s->tx->rfc2822_parser, "cc",
header_domain_append_callback, s);
- rfc2822_body_callback(&s->rfc2822_parser,
+ rfc2822_body_callback(&s->tx->rfc2822_parser,
dataline_callback, s);
if (hostname || listener->local || listener->port == 587) {
- rfc2822_missing_header_callback(&s->rfc2822_parser, "date",
+ rfc2822_missing_header_callback(&s->tx->rfc2822_parser, "date",
header_missing_callback, s);
- rfc2822_missing_header_callback(&s->rfc2822_parser, "message-id",
+ rfc2822_missing_header_callback(&s->tx->rfc2822_parser, "message-id",
header_missing_callback, s);
}
@@ -748,7 +765,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
/* sender check passed, override From callback if masquerading */
if (s->listener->flags & F_MASQUERADE)
- rfc2822_header_callback(&s->rfc2822_parser, "from",
+ rfc2822_header_callback(&s->tx->rfc2822_parser, "from",
header_masquerade_callback, s);
break;
@@ -803,8 +820,8 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
s = tree_xpop(&wait_queue_msg, reqid);
if (success) {
m_get_msgid(&m, &msgid);
- s->evp.id = msgid_to_evpid(msgid);
- s->rcptcount = 0;
+ s->tx->evp.id = msgid_to_evpid(msgid);
+ s->tx->rcptcount = 0;
s->phase = PHASE_TRANSACTION;
smtp_reply(s, "250 %s: Ok",
esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
@@ -847,10 +864,10 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
s = tree_xget(&wait_lka_rcpt, reqid);
if (success) {
m_get_evpid(&m, &evpid);
- s->destcount++;
+ s->tx->destcount++;
}
else
- s->msgflags |= MF_QUEUE_ENVELOPE_FAIL;
+ s->tx->msgflags |= MF_QUEUE_ENVELOPE_FAIL;
m_end(&m);
return;
@@ -862,7 +879,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
if (!success)
fatalx("commit evp failed: not supposed to happen");
s = tree_xpop(&wait_lka_rcpt, reqid);
- if (s->msgflags & MF_QUEUE_ENVELOPE_FAIL) {
+ if (s->tx->msgflags & MF_QUEUE_ENVELOPE_FAIL) {
/*
* If an envelope failed, we can't cancel the last
* RCPT only so we must cancel the whole transaction
@@ -874,12 +891,12 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
}
else {
rcpt = xcalloc(1, sizeof(*rcpt), "smtp_rcpt");
- rcpt->destcount = s->destcount;
- rcpt->maddr = s->evp.rcpt;
- TAILQ_INSERT_TAIL(&s->rcpts, rcpt, entry);
+ rcpt->destcount = s->tx->destcount;
+ rcpt->maddr = s->tx->evp.rcpt;
+ TAILQ_INSERT_TAIL(&s->tx->rcpts, rcpt, entry);
- s->destcount = 0;
- s->rcptcount++;
+ s->tx->destcount = 0;
+ s->tx->rcptcount++;
smtp_reply(s, "250 %s %s: Recipient ok",
esc_code(ESC_STATUS_OK, ESC_DESTINATION_ADDRESS_VALID),
esc_description(ESC_DESTINATION_ADDRESS_VALID));
@@ -905,20 +922,20 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
smtp_filter_commit(s);
smtp_reply(s, "250 %s: %08x Message accepted for delivery",
esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS),
- evpid_to_msgid(s->evp.id));
+ evpid_to_msgid(s->tx->evp.id));
- TAILQ_FOREACH(rcpt, &s->rcpts, entry) {
+ TAILQ_FOREACH(rcpt, &s->tx->rcpts, entry) {
log_info("%016"PRIx64" smtp event=message msgid=%08x "
"from=<%s%s%s> to=<%s%s%s> size=%zu ndest=%zu proto=%s",
s->id,
- evpid_to_msgid(s->evp.id),
- s->evp.sender.user,
- s->evp.sender.user[0] == '\0' ? "" : "@",
- s->evp.sender.domain,
+ evpid_to_msgid(s->tx->evp.id),
+ s->tx->evp.sender.user,
+ s->tx->evp.sender.user[0] == '\0' ? "" : "@",
+ s->tx->evp.sender.domain,
rcpt->maddr.user,
rcpt->maddr.user[0] == '\0' ? "" : "@",
rcpt->maddr.domain,
- s->odatalen,
+ s->tx->odatalen,
rcpt->destcount,
s->flags & SF_EHLO ? "ESMTP" : "SMTP");
}
@@ -1076,7 +1093,7 @@ smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
smtp_reply(s, "250%c%s Hello %s [%s], pleased to meet you",
(s->flags & SF_EHLO) ? '-' : ' ',
s->smtpname,
- s->evp.helo,
+ s->tx->evp.helo,
ss_to_text(&s->ss));
if (s->flags & SF_EHLO) {
@@ -1111,7 +1128,7 @@ smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
m_add_id(p_lka, s->id);
m_add_string(p_lka, s->listener->sendertable);
m_add_string(p_lka, s->username);
- m_add_mailaddr(p_lka, &s->evp.sender);
+ m_add_mailaddr(p_lka, &s->tx->evp.sender);
m_close(p_lka);
tree_xset(&wait_lka_mail, s->id, s);
}
@@ -1130,7 +1147,7 @@ smtp_filter_response(uint64_t id, int query, int status, uint32_t code,
m_create(p_lka, IMSG_SMTP_EXPAND_RCPT, 0, 0, -1);
m_add_id(p_lka, s->id);
- m_add_envelope(p_lka, &s->evp);
+ m_add_envelope(p_lka, &s->tx->evp);
m_close(p_lka);
tree_xset(&wait_lka_rcpt, s->id, s);
return;
@@ -1185,28 +1202,28 @@ smtp_filter_fd(uint64_t id, int fd)
return;
}
- iobuf_init(&s->obuf, 0, 0);
+ iobuf_init(&s->tx->obuf, 0, 0);
io_set_nonblocking(fd);
- io_init(&s->oev, fd, s, smtp_data_io, &s->obuf);
+ io_init(&s->tx->oev, fd, s, smtp_data_io, &s->tx->obuf);
- iobuf_fqueue(&s->obuf, "Received: ");
+ iobuf_fqueue(&s->tx->obuf, "Received: ");
if (!(s->listener->flags & F_MASK_SOURCE)) {
- iobuf_fqueue(&s->obuf, "from %s (%s [%s])",
- s->evp.helo,
+ iobuf_fqueue(&s->tx->obuf, "from %s (%s [%s])",
+ s->tx->evp.helo,
s->hostname,
ss_to_text(&s->ss));
}
- iobuf_fqueue(&s->obuf, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
+ iobuf_fqueue(&s->tx->obuf, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
s->smtpname,
SMTPD_NAME,
s->flags & SF_EHLO ? "E" : "",
s->flags & SF_SECURE ? "S" : "",
s->flags & SF_AUTHENTICATED ? "A" : "",
- evpid_to_msgid(s->evp.id));
+ evpid_to_msgid(s->tx->evp.id));
if (s->flags & SF_SECURE) {
x = SSL_get_peer_certificate(s->io.ssl);
- iobuf_fqueue(&s->obuf,
+ iobuf_fqueue(&s->tx->obuf,
" (%s:%s:%d:%s)",
SSL_get_version(s->io.ssl),
SSL_get_cipher_name(s->io.ssl),
@@ -1216,27 +1233,27 @@ smtp_filter_fd(uint64_t id, int fd)
X509_free(x);
if (s->listener->flags & F_RECEIVEDAUTH) {
- iobuf_fqueue(&s->obuf, " auth=%s", s->username[0] ? "yes" : "no");
+ iobuf_fqueue(&s->tx->obuf, " auth=%s", s->username[0] ? "yes" : "no");
if (s->username[0])
- iobuf_fqueue(&s->obuf, " user=%s", s->username);
+ iobuf_fqueue(&s->tx->obuf, " user=%s", s->username);
}
}
- if (s->rcptcount == 1) {
- iobuf_fqueue(&s->obuf, "\n\tfor <%s@%s>",
- s->evp.rcpt.user,
- s->evp.rcpt.domain);
+ if (s->tx->rcptcount == 1) {
+ iobuf_fqueue(&s->tx->obuf, "\n\tfor <%s@%s>",
+ s->tx->evp.rcpt.user,
+ s->tx->evp.rcpt.domain);
}
- iobuf_fqueue(&s->obuf, ";\n\t%s\n", time_to_text(time(NULL)));
+ iobuf_fqueue(&s->tx->obuf, ";\n\t%s\n", time_to_text(time(NULL)));
/*
* XXX This is not exactly fair, since this is not really
* user data.
*/
- s->odatalen = iobuf_queued(&s->obuf);
+ s->tx->odatalen = iobuf_queued(&s->tx->obuf);
- io_set_write(&s->oev);
+ io_set_write(&s->tx->oev);
smtp_enter_state(s, STATE_BODY);
smtp_reply(s, "354 Enter mail, end with \".\""
@@ -1343,13 +1360,13 @@ smtp_io(struct io *io, int evt)
if (s->state == STATE_BODY) {
log_trace(TRACE_SMTP, "<<< [EOM]");
- rfc2822_parser_flush(&s->rfc2822_parser);
+ rfc2822_parser_flush(&s->tx->rfc2822_parser);
iobuf_normalize(&s->iobuf);
io_set_write(io);
- s->dataeom = 1;
- if (iobuf_queued(&s->obuf) == 0)
+ s->tx->dataeom = 1;
+ if (iobuf_queued(&s->tx->obuf) == 0)
smtp_data_io_done(s);
return;
}
@@ -1415,6 +1432,29 @@ smtp_io(struct io *io, int evt)
}
}
+static int
+smtp_tx(struct smtp_session *s)
+{
+ struct smtp_tx *tx;
+
+ tx = calloc(1, sizeof(*tx));
+ if (tx == NULL)
+ return 0;
+
+ s->tx = tx;
+ tx->session = s;
+
+ return 1;
+}
+
+static void
+smtp_tx_free(struct smtp_tx *tx)
+{
+ tx->session->tx = NULL;
+
+ free(tx);
+}
+
static void
smtp_data_io(struct io *io, int evt)
{
@@ -1428,9 +1468,9 @@ smtp_data_io(struct io *io, int evt)
case IO_DISCONNECTED:
case IO_ERROR:
log_debug("debug: smtp: %p: io error on mfa", s);
- io_clear(&s->oev);
- iobuf_clear(&s->obuf);
- s->msgflags |= MF_ERROR_IO;
+ io_clear(&s->tx->oev);
+ iobuf_clear(&s->tx->obuf);
+ s->tx->msgflags |= MF_ERROR_IO;
if (s->io.flags & IO_PAUSE_IN) {
log_debug("debug: smtp: %p: resuming session after mfa error", s);
io_resume(&s->io, IO_PAUSE_IN);
@@ -1438,7 +1478,7 @@ smtp_data_io(struct io *io, int evt)
break;
case IO_LOWAT:
- if (s->dataeom && iobuf_queued(&s->obuf) == 0) {
+ if (s->tx->dataeom && iobuf_queued(&s->tx->obuf) == 0) {
smtp_data_io_done(s);
} else if (s->io.flags & IO_PAUSE_IN) {
log_debug("debug: smtp: %p: filter congestion over: resuming session", s);
@@ -1454,32 +1494,32 @@ smtp_data_io(struct io *io, int evt)
static void
smtp_data_io_done(struct smtp_session *s)
{
- log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->odatalen);
- io_clear(&s->oev);
- iobuf_clear(&s->obuf);
+ log_debug("debug: smtp: %p: data io done (%zu bytes)", s, s->tx->odatalen);
+ io_clear(&s->tx->oev);
+ iobuf_clear(&s->tx->obuf);
- if (s->msgflags & MF_ERROR) {
+ if (s->tx->msgflags & MF_ERROR) {
tree_pop(&wait_filter_data, s->id);
smtp_filter_rollback(s);
smtp_queue_rollback(s);
- if (s->msgflags & MF_ERROR_SIZE)
+ if (s->tx->msgflags & MF_ERROR_SIZE)
smtp_reply(s, "554 Message too big");
- else if (s->msgflags & MF_ERROR_LOOP)
+ else if (s->tx->msgflags & MF_ERROR_LOOP)
smtp_reply(s, "500 %s %s: Loop detected",
esc_code(ESC_STATUS_PERMFAIL, ESC_ROUTING_LOOP_DETECTED),
esc_description(ESC_ROUTING_LOOP_DETECTED));
- else if (s->msgflags & MF_ERROR_RESOURCES)
+ else if (s->tx->msgflags & MF_ERROR_RESOURCES)
smtp_reply(s, "421 %s: Temporary Error",
esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
- else if (s->msgflags & MF_ERROR_MALFORMED)
+ else if (s->tx->msgflags & MF_ERROR_MALFORMED)
smtp_reply(s, "550 %s %s: Message is not RFC 2822 compliant",
esc_code(ESC_STATUS_PERMFAIL,
ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED),
esc_description(ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED));
- else if (s->msgflags)
+ else if (s->tx->msgflags)
smtp_reply(s, "421 Internal server error");
smtp_message_reset(s, 0);
smtp_enter_state(s, STATE_HELO);
@@ -1690,7 +1730,7 @@ smtp_command(struct smtp_session *s, char *line)
smtp_message_reset(s, 1);
- if (smtp_mailaddr(&s->evp.sender, args, 1, &args,
+ if (smtp_mailaddr(&s->tx->evp.sender, args, 1, &args,
s->smtpname) == 0) {
smtp_reply(s, "553 %s: Sender address syntax error",
esc_code(ESC_STATUS_PERMFAIL, ESC_OTHER_ADDRESS_STATUS));
@@ -1712,14 +1752,14 @@ smtp_command(struct smtp_session *s, char *line)
break;
}
- if (s->rcptcount >= env->sc_session_max_rcpt) {
+ if (s->tx->rcptcount >= env->sc_session_max_rcpt) {
smtp_reply(s, "451 %s %s: Too many recipients",
esc_code(ESC_STATUS_TEMPFAIL, ESC_TOO_MANY_RECIPIENTS),
esc_description(ESC_TOO_MANY_RECIPIENTS));
break;
}
- if (smtp_mailaddr(&s->evp.rcpt, args, 0, &args,
+ if (smtp_mailaddr(&s->tx->evp.rcpt, args, 0, &args,
s->smtpname) == 0) {
smtp_reply(s,
"501 %s: Recipient address syntax error",
@@ -1742,7 +1782,7 @@ smtp_command(struct smtp_session *s, char *line)
smtp_filter_rset(s);
- if (s->evp.id)
+ if (s->tx->evp.id)
smtp_queue_rollback(s);
s->phase = PHASE_SETUP;
@@ -1758,14 +1798,14 @@ smtp_command(struct smtp_session *s, char *line)
esc_description(ESC_INVALID_COMMAND));
break;
}
- if (s->rcptcount == 0) {
+ if (s->tx->rcptcount == 0) {
smtp_reply(s, "503 %s %s: No recipient specified",
esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
esc_description(ESC_INVALID_COMMAND_ARGUMENTS));
break;
}
- rfc2822_parser_reset(&s->rfc2822_parser);
+ rfc2822_parser_reset(&s->tx->rfc2822_parser);
smtp_filter_data(s);
break;
@@ -1947,10 +1987,10 @@ smtp_parse_rcpt_args(struct smtp_session *s, char *args)
if ((flag = dsn_notify_str_to_uint8(p)) == 0)
continue;
- s->evp.dsn_notify |= flag;
+ s->tx->evp.dsn_notify |= flag;
}
- if (s->evp.dsn_notify & DSN_NEVER &&
- s->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE |
+ if (s->tx->evp.dsn_notify & DSN_NEVER &&
+ s->tx->evp.dsn_notify & (DSN_SUCCESS | DSN_FAILURE |
DSN_DELAY)) {
smtp_reply(s,
"553 NOTIFY option NEVER cannot be \
@@ -1959,7 +1999,7 @@ smtp_parse_rcpt_args(struct smtp_session *s, char *args)
}
} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ORCPT=", 6) == 0) {
b += 6;
- if (!text_to_mailaddr(&s->evp.dsn_orcpt, b)) {
+ if (!text_to_mailaddr(&s->tx->evp.dsn_orcpt, b)) {
smtp_reply(s, "553 ORCPT address syntax error");
return (-1);
}
@@ -1993,13 +2033,13 @@ smtp_parse_mail_args(struct smtp_session *s, char *args)
else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "RET=", 4) == 0) {
b += 4;
if (strcasecmp(b, "HDRS") == 0)
- s->evp.dsn_ret = DSN_RETHDRS;
+ s->tx->evp.dsn_ret = DSN_RETHDRS;
else if (strcasecmp(b, "FULL") == 0)
- s->evp.dsn_ret = DSN_RETFULL;
+ s->tx->evp.dsn_ret = DSN_RETFULL;
} else if (ADVERTISE_EXT_DSN(s) && strncasecmp(b, "ENVID=", 6) == 0) {
b += 6;
- if (strlcpy(s->evp.dsn_envid, b, sizeof(s->evp.dsn_envid))
- >= sizeof(s->evp.dsn_envid)) {
+ if (strlcpy(s->tx->evp.dsn_envid, b, sizeof(s->tx->evp.dsn_envid))
+ >= sizeof(s->tx->evp.dsn_envid)) {
smtp_reply(s, "503 %s %s: option too large, truncated: %s",
esc_code(ESC_STATUS_PERMFAIL, ESC_INVALID_COMMAND_ARGUMENTS),
esc_description(ESC_INVALID_COMMAND_ARGUMENTS), b);
@@ -2083,20 +2123,20 @@ smtp_enter_state(struct smtp_session *s, int newstate)
static void
smtp_message_end(struct smtp_session *s)
{
- log_debug("debug: %p: end of message, msgflags=0x%04x", s, s->msgflags);
+ log_debug("debug: %p: end of message, msgflags=0x%04x", s, s->tx->msgflags);
tree_xpop(&wait_filter_data, s->id);
s->phase = PHASE_SETUP;
- if (s->msgflags & MF_ERROR) {
+ if (s->tx->msgflags & MF_ERROR) {
smtp_queue_rollback(s);
- if (s->msgflags & MF_ERROR_SIZE)
+ if (s->tx->msgflags & MF_ERROR_SIZE)
smtp_reply(s, "554 %s %s: Transaction failed, message too big",
esc_code(ESC_STATUS_PERMFAIL, ESC_MESSAGE_TOO_BIG_FOR_SYSTEM),
esc_description(ESC_MESSAGE_TOO_BIG_FOR_SYSTEM));
else
- smtp_reply(s, "%d Message rejected", s->msgcode);
+ smtp_reply(s, "%d Message rejected", s->tx->msgcode);
smtp_message_reset(s, 0);
smtp_enter_state(s, STATE_HELO);
return;
@@ -2110,32 +2150,32 @@ smtp_message_reset(struct smtp_session *s, int prepare)
{
struct smtp_rcpt *rcpt;
- while ((rcpt = TAILQ_FIRST(&s->rcpts))) {
- TAILQ_REMOVE(&s->rcpts, rcpt, entry);
+ while ((rcpt = TAILQ_FIRST(&s->tx->rcpts))) {
+ TAILQ_REMOVE(&s->tx->rcpts, rcpt, entry);
free(rcpt);
}
- memset(&s->evp, 0, sizeof s->evp);
- s->msgflags = 0;
- s->destcount = 0;
- s->rcptcount = 0;
+ memset(&s->tx->evp, 0, sizeof s->tx->evp);
+ s->tx->msgflags = 0;
+ s->tx->destcount = 0;
+ s->tx->rcptcount = 0;
s->datain = 0;
- s->odatalen = 0;
- s->dataeom = 0;
- s->rcvcount = 0;
- s->hdrdone = 0;
+ s->tx->odatalen = 0;
+ s->tx->dataeom = 0;
+ s->tx->rcvcount = 0;
+ s->tx->hdrdone = 0;
if (prepare) {
- s->evp.ss = s->ss;
- (void)strlcpy(s->evp.tag, s->listener->tag, sizeof(s->evp.tag));
- (void)strlcpy(s->evp.smtpname, s->smtpname, sizeof(s->evp.smtpname));
- (void)strlcpy(s->evp.hostname, s->hostname, sizeof s->evp.hostname);
- (void)strlcpy(s->evp.helo, s->helo, sizeof s->evp.helo);
+ s->tx->evp.ss = s->ss;
+ (void)strlcpy(s->tx->evp.tag, s->listener->tag, sizeof(s->tx->evp.tag));
+ (void)strlcpy(s->tx->evp.smtpname, s->smtpname, sizeof(s->tx->evp.smtpname));
+ (void)strlcpy(s->tx->evp.hostname, s->hostname, sizeof s->tx->evp.hostname);
+ (void)strlcpy(s->tx->evp.helo, s->helo, sizeof s->tx->evp.helo);
if (s->flags & SF_BOUNCE)
- s->evp.flags |= EF_BOUNCE;
+ s->tx->evp.flags |= EF_BOUNCE;
if (s->flags & SF_AUTHENTICATED)
- s->evp.flags |= EF_AUTHENTICATED;
+ s->tx->evp.flags |= EF_AUTHENTICATED;
}
}
@@ -2145,19 +2185,19 @@ smtp_message_printf(struct smtp_session *s, const char *fmt, ...)
va_list ap;
int len;
- if (s->msgflags & MF_ERROR)
+ if (s->tx->msgflags & MF_ERROR)
return -1;
va_start(ap, fmt);
- len = iobuf_vfqueue(&s->obuf, fmt, ap);
+ len = iobuf_vfqueue(&s->tx->obuf, fmt, ap);
va_end(ap);
if (len < 0) {
log_warn("smtp-in: session %016"PRIx64": vfprintf", s->id);
- s->msgflags |= MF_ERROR_IO;
+ s->tx->msgflags |= MF_ERROR_IO;
}
else
- s->odatalen += len;
+ s->tx->odatalen += len;
return len;
}
@@ -2220,10 +2260,10 @@ smtp_free(struct smtp_session *s, const char * reason)
tree_pop(&wait_filter_data, s->id);
- if (s->evp.id) {
+ if (s->tx->evp.id) {
smtp_queue_rollback(s);
- io_clear(&s->oev);
- iobuf_clear(&s->obuf);
+ io_clear(&s->tx->oev);
+ iobuf_clear(&s->tx->obuf);
}
if (s->flags & SF_FILTERCONN)
@@ -2234,15 +2274,16 @@ smtp_free(struct smtp_session *s, const char * reason)
if (s->flags & SF_SECURE && s->listener->flags & F_STARTTLS)
stat_decrement("smtp.tls", 1);
- while ((rcpt = TAILQ_FIRST(&s->rcpts))) {
- TAILQ_REMOVE(&s->rcpts, rcpt, entry);
+ while ((rcpt = TAILQ_FIRST(&s->tx->rcpts))) {
+ TAILQ_REMOVE(&s->tx->rcpts, rcpt, entry);
free(rcpt);
}
- rfc2822_parser_release(&s->rfc2822_parser);
+ rfc2822_parser_release(&s->tx->rfc2822_parser);
io_clear(&s->io);
iobuf_clear(&s->iobuf);
+ smtp_tx_free(s->tx);
free(s);
smtp_collect();
@@ -2459,7 +2500,7 @@ smtp_queue_open_message(struct smtp_session *s)
{
m_create(p_queue, IMSG_SMTP_MESSAGE_OPEN, 0, 0, -1);
m_add_id(p_queue, s->id);
- m_add_msgid(p_queue, evpid_to_msgid(s->evp.id));
+ m_add_msgid(p_queue, evpid_to_msgid(s->tx->evp.id));
m_close(p_queue);
tree_xset(&wait_queue_fd, s->id, s);
}
@@ -2469,7 +2510,7 @@ smtp_queue_commit(struct smtp_session *s)
{
m_create(p_queue, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
m_add_id(p_queue, s->id);
- m_add_msgid(p_queue, evpid_to_msgid(s->evp.id));
+ m_add_msgid(p_queue, evpid_to_msgid(s->tx->evp.id));
m_close(p_queue);
tree_xset(&wait_queue_commit, s->id, s);
}
@@ -2478,7 +2519,7 @@ static void
smtp_queue_rollback(struct smtp_session *s)
{
m_create(p_queue, IMSG_SMTP_MESSAGE_ROLLBACK, 0, 0, -1);
- m_add_msgid(p_queue, evpid_to_msgid(s->evp.id));
+ m_add_msgid(p_queue, evpid_to_msgid(s->tx->evp.id));
m_close(p_queue);
}
@@ -2522,7 +2563,7 @@ static void
smtp_filter_eom(struct smtp_session *s)
{
tree_xset(&wait_filter, s->id, s);
- filter_eom(s->id, QUERY_EOM, s->odatalen);
+ filter_eom(s->id, QUERY_EOM, s->tx->odatalen);
}
static void
@@ -2536,14 +2577,14 @@ static void
smtp_filter_mail(struct smtp_session *s)
{
tree_xset(&wait_filter, s->id, s);
- filter_mailaddr(s->id, QUERY_MAIL, &s->evp.sender);
+ filter_mailaddr(s->id, QUERY_MAIL, &s->tx->evp.sender);
}
static void
smtp_filter_rcpt(struct smtp_session *s)
{
tree_xset(&wait_filter, s->id, s);
- filter_mailaddr(s->id, QUERY_RCPT, &s->evp.rcpt);
+ filter_mailaddr(s->id, QUERY_RCPT, &s->tx->evp.rcpt);
}
static void
@@ -2561,7 +2602,7 @@ smtp_filter_dataline(struct smtp_session *s, const char *line)
log_trace(TRACE_SMTP, "<<< [MSG] %s", line);
/* ignore data line if an error flag is set */
- if (s->msgflags & MF_ERROR)
+ if (s->tx->msgflags & MF_ERROR)
return;
/* escape lines starting with a '.' */
@@ -2571,52 +2612,52 @@ smtp_filter_dataline(struct smtp_session *s, const char *line)
/* account for newline */
s->datain += strlen(line) + 1;
if (s->datain > env->sc_maxsize) {
- s->msgflags |= MF_ERROR_SIZE;
+ s->tx->msgflags |= MF_ERROR_SIZE;
return;
}
- if (!s->hdrdone) {
+ if (!s->tx->hdrdone) {
/* folded header that must be skipped */
- if (isspace((unsigned char)line[0]) && s->skiphdr)
+ if (isspace((unsigned char)line[0]) && s->tx->skiphdr)
return;
- s->skiphdr = 0;
+ s->tx->skiphdr = 0;
/* BCC should be stripped from headers */
if (strncasecmp("bcc:", line, 4) == 0) {
- s->skiphdr = 1;
+ s->tx->skiphdr = 1;
return;
}
/* check for loop */
if (strncasecmp("Received: ", line, 10) == 0)
- s->rcvcount++;
- if (s->rcvcount == MAX_HOPS_COUNT) {
- s->msgflags |= MF_ERROR_LOOP;
+ s->tx->rcvcount++;
+ if (s->tx->rcvcount == MAX_HOPS_COUNT) {
+ s->tx->msgflags |= MF_ERROR_LOOP;
log_warnx("warn: loop detected");
return;
}
if (line[0] == '\0')
- s->hdrdone = 1;
+ s->tx->hdrdone = 1;
}
- ret = rfc2822_parser_feed(&s->rfc2822_parser, line);
+ ret = rfc2822_parser_feed(&s->tx->rfc2822_parser, line);
if (ret == -1) {
- s->msgflags |= MF_ERROR_RESOURCES;
+ s->tx->msgflags |= MF_ERROR_RESOURCES;
return;
}
if (ret == 0) {
- s->msgflags |= MF_ERROR_MALFORMED;
+ s->tx->msgflags |= MF_ERROR_MALFORMED;
return;
}
- if (iobuf_queued(&s->obuf) > DATA_HIWAT && !(s->io.flags & IO_PAUSE_IN)) {
+ if (iobuf_queued(&s->tx->obuf) > DATA_HIWAT && !(s->io.flags & IO_PAUSE_IN)) {
log_debug("debug: smtp: %p: filter congestion over: pausing session", s);
io_pause(&s->io, IO_PAUSE_IN);
}
- io_reload(&s->oev);
+ io_reload(&s->tx->oev);
}
#define CASE(x) case x : return #x