From 0a80c58a3f722c3fd7044edc8cc269e838bbc2da Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 23 Jun 2016 11:56:19 +0000 Subject: [PATCH] move transaction-specific states from struct smtp_session to struct smtp_tx ok gilles@ --- usr.sbin/smtpd/smtp_session.c | 341 +++++++++++++++++++--------------- 1 file changed, 191 insertions(+), 150 deletions(-) diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 05425f4189f..f8795607916 100644 --- a/usr.sbin/smtpd/smtp_session.c +++ b/usr.sbin/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 @@ -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 -- 2.20.1