diff options
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/bounce.c | 23 | ||||
-rw-r--r-- | usr.sbin/smtpd/lka.c | 6 | ||||
-rw-r--r-- | usr.sbin/smtpd/lka_session.c | 111 | ||||
-rw-r--r-- | usr.sbin/smtpd/mda.c | 40 | ||||
-rw-r--r-- | usr.sbin/smtpd/mfa.c | 16 | ||||
-rw-r--r-- | usr.sbin/smtpd/mfa_session.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/mta.c | 44 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue.c | 24 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_backend.c | 39 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_fsqueue.c | 103 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_fsqueue_ascii.c | 783 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue_shared.c | 83 | ||||
-rw-r--r-- | usr.sbin/smtpd/ramqueue.c | 42 | ||||
-rw-r--r-- | usr.sbin/smtpd/ruleset.c | 10 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 69 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp.c | 24 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp_session.c | 76 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 3 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 77 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/util.c | 40 |
22 files changed, 1235 insertions, 390 deletions
diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c index af6a60dda93..6c729aa6ae8 100644 --- a/usr.sbin/smtpd/bounce.c +++ b/usr.sbin/smtpd/bounce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bounce.c,v 1.33 2011/09/01 19:56:49 eric Exp $ */ +/* $OpenBSD: bounce.c,v 1.34 2011/10/23 09:30:06 gilles Exp $ */ /* * Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org> @@ -54,7 +54,7 @@ bounce_session(int fd, struct envelope *m) FILE *msgfp = NULL; u_int32_t msgid; - msgid = evpid_to_msgid(m->delivery.id); + msgid = evpid_to_msgid(m->id); /* get message content */ if ((msgfd = queue_message_fd_r(Q_QUEUE, msgid)) == -1) @@ -72,11 +72,11 @@ bounce_session(int fd, struct envelope *m) client_ssl_optional(cc->pcb); client_sender(cc->pcb, ""); - client_rcpt(cc->pcb, NULL, "%s@%s", m->delivery.from.user, - m->delivery.from.domain); + client_rcpt(cc->pcb, NULL, "%s@%s", m->sender.user, + m->sender.domain); /* Construct an appropriate reason line. */ - reason = m->delivery.errorline; + reason = m->errorline; if (strlen(reason) > 4 && (*reason == '1' || *reason == '6')) reason += 4; @@ -100,9 +100,9 @@ bounce_session(int fd, struct envelope *m) "Below is a copy of the original message:\n" "\n", env->sc_hostname, - m->delivery.from.user, m->delivery.from.domain, + m->sender.user, m->sender.domain, time_to_text(time(NULL)), - m->delivery.rcpt.user, m->delivery.rcpt.domain, + m->dest.user, m->dest.domain, reason); /* setup event */ @@ -147,13 +147,16 @@ bounce_event(int fd, short event, void *p) } out: - if (*ep == '2') + if (*ep == '2') { + log_debug("#### %s: queue_envelope_delete: %016llx", + __func__, cc->m.id); queue_envelope_delete(Q_QUEUE, &cc->m); + } else { if (*ep == '5' || *ep == '6') - cc->m.delivery.status = DS_PERMFAILURE; + cc->m.status = DS_PERMFAILURE; else - cc->m.delivery.status = DS_TEMPFAILURE; + cc->m.status = DS_TEMPFAILURE; envelope_set_errormsg(&cc->m, "%s", ep); queue_message_update(&cc->m); } diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index 3ba0514430f..086c7395953 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.128 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: lka.c,v 1.129 2011/10/23 09:30:06 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -92,9 +92,9 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) ss->code = 250; ss->envelope.rule = *rule; if (IS_RELAY(*rule)) - ss->envelope.delivery.type = D_MTA; + ss->envelope.type = D_MTA; else - ss->envelope.delivery.type = D_MDA; + ss->envelope.type = D_MDA; } imsg_compose_event(iev, IMSG_LKA_RULEMATCH, 0, 0, -1, ss, sizeof *ss); diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c index df60ebf1dd3..6c0ddcb82a3 100644 --- a/usr.sbin/smtpd/lka_session.c +++ b/usr.sbin/smtpd/lka_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_session.c,v 1.10 2011/10/22 18:03:27 eric Exp $ */ +/* $OpenBSD: lka_session.c,v 1.11 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -81,7 +81,7 @@ lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep) char username[MAX_LOCALPART_SIZE]; /* remote delivery, no need to process further */ - if (ep->delivery.type == D_MTA) { + if (ep->type == D_MTA) { lka_session_deliver(lks, ep); return 1; } @@ -90,10 +90,10 @@ lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep) case C_ALL: case C_NET: case C_DOM: { - if (ep->delivery.agent.mda.to.user[0] == '\0') - user = ep->delivery.rcpt.user; + if (ep->agent.mda.to.user[0] == '\0') + user = ep->dest.user; else - user = ep->delivery.agent.mda.to.user; + user = ep->agent.mda.to.user; lowercase(username, user, sizeof(username)); /* gilles+hackers@ -> gilles@ */ @@ -113,24 +113,24 @@ lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep) if (! ub->getbyname(&u, username)) return 0; - (void)strlcpy(ep->delivery.agent.mda.as_user, u.username, - sizeof (ep->delivery.agent.mda.as_user)); + (void)strlcpy(ep->agent.mda.as_user, u.username, + sizeof (ep->agent.mda.as_user)); - ep->delivery.type = D_MDA; + ep->type = D_MDA; switch (ep->rule.r_action) { case A_MBOX: - ep->delivery.agent.mda.method = A_MBOX; - (void)strlcpy(ep->delivery.agent.mda.to.user, + ep->agent.mda.method = A_MBOX; + (void)strlcpy(ep->agent.mda.to.user, u.username, - sizeof (ep->delivery.agent.mda.to.user)); + sizeof (ep->agent.mda.to.user)); break; case A_MAILDIR: case A_FILENAME: case A_EXT: - ep->delivery.agent.mda.method = ep->rule.r_action; - (void)strlcpy(ep->delivery.agent.mda.to.buffer, + ep->agent.mda.method = ep->rule.r_action; + (void)strlcpy(ep->agent.mda.to.buffer, ep->rule.r_value.buffer, - sizeof (ep->delivery.agent.mda.to.buffer)); + sizeof (ep->agent.mda.to.buffer)); break; default: fatalx("lka_session_envelope_expand: unexpected rule action"); @@ -142,9 +142,9 @@ lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep) } case C_VDOM: { - if (aliases_virtual_exist(ep->rule.r_condition.c_map, &ep->delivery.rcpt)) { + if (aliases_virtual_exist(ep->rule.r_condition.c_map, &ep->dest)) { if (! aliases_virtual_get(ep->rule.r_condition.c_map, - &lks->expandtree, &ep->delivery.rcpt)) + &lks->expandtree, &ep->dest)) return 0; return 1; } @@ -373,8 +373,8 @@ lka_session_deliver(struct lka_session *lks, struct envelope *ep) if (new_ep == NULL) fatal("lka_session_deliver: calloc"); *new_ep = *ep; - if (new_ep->delivery.type == D_MDA) { - d_mda = &new_ep->delivery.agent.mda; + if (new_ep->type == D_MDA) { + d_mda = &new_ep->agent.mda; if (d_mda->method == A_INVALID) fatalx("lka_session_deliver: mda method == A_INVALID"); @@ -391,11 +391,12 @@ lka_session_deliver(struct lka_session *lks, struct envelope *ep) default: break; } - } else if (new_ep->delivery.type == D_MTA) { + } + else if (new_ep->type == D_MTA) { if (ep->rule.r_action == A_RELAYVIA) - new_ep->delivery.agent.mta.relay = ep->rule.r_value.relayhost; + new_ep->agent.mta.relay = ep->rule.r_value.relayhost; if (ep->rule.r_as) - new_ep->delivery.from = *ep->rule.r_as; + new_ep->sender = *ep->rule.r_as; } TAILQ_INSERT_TAIL(&lks->deliverylist, new_ep, entry); } @@ -403,12 +404,12 @@ lka_session_deliver(struct lka_session *lks, struct envelope *ep) int lka_session_resolve_node(struct envelope *ep, struct expandnode *xn) { - struct delivery *dlv; - struct delivery olddlv; +// struct delivery *dlv; +// struct delivery olddlv; + struct envelope oldep; - dlv = &ep->delivery; - memcpy(&olddlv, dlv, sizeof (*dlv)); - bzero(&dlv->agent, sizeof (dlv->agent)); + memcpy(&oldep, ep, sizeof (*ep)); + bzero(&ep->agent, sizeof (ep->agent)); switch (xn->type) { case EXPAND_INVALID: @@ -419,13 +420,13 @@ lka_session_resolve_node(struct envelope *ep, struct expandnode *xn) case EXPAND_ADDRESS: log_debug("lka_resolve_node: node is address: %s@%s", xn->u.mailaddr.user, xn->u.mailaddr.domain); - dlv->rcpt = xn->u.mailaddr; + ep->dest = xn->u.mailaddr; /* evaluation of ruleset assumes local source * since we're expanding on already accepted * source. */ - dlv->flags |= DF_INTERNAL; + ep->flags |= DF_INTERNAL; if (! lka_session_rcpt_action(ep)) return -1; return 0; @@ -433,8 +434,8 @@ lka_session_resolve_node(struct envelope *ep, struct expandnode *xn) case EXPAND_USERNAME: log_debug("lka_resolve_node: node is local username: %s", xn->u.user); - dlv->type = D_MDA; - dlv->agent.mda.to = xn->u; + ep->type = D_MDA; + ep->agent.mda.to = xn->u; /* overwrite the initial condition before we expand the * envelope again. if we came from a C_VDOM, not doing @@ -448,35 +449,35 @@ lka_session_resolve_node(struct envelope *ep, struct expandnode *xn) /* if expansion of a user results in same user ... deliver */ if (strcmp(xn->u.user, xn->as_user) == 0) { - ep->delivery.agent.mda.method = olddlv.agent.mda.method; + ep->agent.mda.method = oldep.agent.mda.method; break; } /* otherwise rewrite delivery user with expansion result */ - (void)strlcpy(dlv->agent.mda.to.user, xn->u.user, - sizeof (dlv->agent.mda.to.user)); - (void)strlcpy(dlv->agent.mda.as_user, xn->u.user, - sizeof (dlv->agent.mda.as_user)); + (void)strlcpy(ep->agent.mda.to.user, xn->u.user, + sizeof (ep->agent.mda.to.user)); + (void)strlcpy(ep->agent.mda.as_user, xn->u.user, + sizeof (ep->agent.mda.as_user)); return 0; case EXPAND_FILENAME: log_debug("lka_resolve_node: node is filename: %s", xn->u.buffer); - dlv->type = D_MDA; - dlv->agent.mda.to = xn->u; - dlv->agent.mda.method = A_FILENAME; - (void)strlcpy(dlv->agent.mda.as_user, xn->as_user, - sizeof (dlv->agent.mda.as_user)); + ep->type = D_MDA; + ep->agent.mda.to = xn->u; + ep->agent.mda.method = A_FILENAME; + (void)strlcpy(ep->agent.mda.as_user, xn->as_user, + sizeof (ep->agent.mda.as_user)); break; case EXPAND_FILTER: log_debug("lka_resolve_node: node is filter: %s", xn->u.buffer); - dlv->type = D_MDA; - dlv->agent.mda.to = xn->u; - dlv->agent.mda.method = A_EXT; - (void)strlcpy(dlv->agent.mda.as_user, xn->as_user, - sizeof (dlv->agent.mda.as_user)); + ep->type = D_MDA; + ep->agent.mda.to = xn->u; + ep->agent.mda.method = A_EXT; + (void)strlcpy(ep->agent.mda.as_user, xn->as_user, + sizeof (ep->agent.mda.as_user)); break; } @@ -491,7 +492,7 @@ lka_session_expand_format(char *buf, size_t len, struct envelope *ep) struct user_backend *ub; struct user u; char lbuffer[MAX_RULEBUFFER_LEN]; - struct delivery *dlv = &ep->delivery; +// struct delivery *dlv = &ep->delivery; bzero(lbuffer, sizeof (lbuffer)); pbuf = lbuffer; @@ -504,7 +505,7 @@ lka_session_expand_format(char *buf, size_t len, struct envelope *ep) bzero(&u, sizeof (u)); ub = user_backend_lookup(USER_GETPWNAM); - if (! ub->getbyname(&u, dlv->agent.mda.as_user)) + if (! ub->getbyname(&u, ep->agent.mda.as_user)) return 0; lret = strlcat(pbuf, u.directory, len); @@ -549,19 +550,19 @@ lka_session_expand_format(char *buf, size_t len, struct envelope *ep) } switch (*tmp) { case 'U': - string = dlv->from.user; + string = ep->sender.user; break; case 'D': - string = dlv->from.domain; + string = ep->sender.domain; break; case 'a': - string = dlv->agent.mda.as_user; + string = ep->agent.mda.as_user; break; case 'u': - string = dlv->rcpt.user; + string = ep->dest.user; break; case 'd': - string = dlv->rcpt.domain; + string = ep->dest.domain; break; default: goto copy; @@ -604,7 +605,7 @@ lka_session_rcpt_action(struct envelope *ep) r = ruleset_match(ep); if (r == NULL) { - ep->delivery.type = D_MTA; + ep->type = D_MTA; return 0; } @@ -614,10 +615,10 @@ lka_session_rcpt_action(struct envelope *ep) case A_MAILDIR: case A_FILENAME: case A_EXT: - ep->delivery.type = D_MDA; + ep->type = D_MDA; break; default: - ep->delivery.type = D_MTA; + ep->type = D_MTA; } return 1; diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c index eaef4e7bd62..a2a783a2566 100644 --- a/usr.sbin/smtpd/mda.c +++ b/usr.sbin/smtpd/mda.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mda.c,v 1.60 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: mda.c,v 1.61 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -53,9 +53,9 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) char output[128], *error, *parent_error; struct deliver deliver; struct mda_session *s; - struct delivery *d; struct delivery_mda *d_mda; struct mailaddr *maddr; + struct envelope *ep; log_imsg(PROC_MDA, iev->proc, imsg); @@ -68,7 +68,7 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) fatal(NULL); msgbuf_init(&s->w); s->msg = *(struct envelope *)imsg->data; - s->msg.delivery.status = DS_TEMPFAILURE; + s->msg.status = DS_TEMPFAILURE; s->id = mda_id++; s->datafp = fdopen(imsg->fd, "r"); if (s->datafp == NULL) @@ -76,8 +76,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) LIST_INSERT_HEAD(&env->mda_sessions, s, entry); /* request parent to fork a helper process */ - d = &s->msg.delivery; - d_mda = &s->msg.delivery.agent.mda; + ep = &s->msg; + d_mda = &s->msg.agent.mda; switch (d_mda->method) { case A_EXT: deliver.mode = A_EXT; @@ -93,8 +93,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) sizeof (deliver.user)); snprintf(deliver.to, sizeof (deliver.to), "%s -f %s@%s %s", PATH_MAILLOCAL, - d->from.user, - d->from.domain, + ep->sender.user, + ep->sender.domain, d_mda->to.user); break; @@ -197,10 +197,10 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) /* update queue entry */ if (error == NULL) - s->msg.delivery.status = DS_ACCEPTED; + s->msg.status = DS_ACCEPTED; else - strlcpy(s->msg.delivery.errorline, error, - sizeof s->msg.delivery.errorline); + strlcpy(s->msg.errorline, error, + sizeof s->msg.errorline); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_MESSAGE_UPDATE, 0, 0, -1, &s->msg, sizeof s->msg); @@ -213,16 +213,16 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) */ if (s->msg.rule.r_action == A_MAILDIR || s->msg.rule.r_action == A_MBOX) - maddr = &s->msg.delivery.rcpt; + maddr = &s->msg.dest; else - maddr = &s->msg.delivery.rcpt_orig; + maddr = &s->msg.rcpt; /* log status */ if (error && asprintf(&error, "Error (%s)", error) < 0) fatal("mda: asprintf"); log_info("%016llx: to=<%s@%s>, delay=%lld, stat=%s", - s->msg.delivery.id, maddr->user, maddr->domain, - (long long int) (time(NULL) - s->msg.delivery.creation), + s->msg.id, maddr->user, maddr->domain, + (long long int) (time(NULL) - s->msg.creation), error ? error : "Sent"); free(error); @@ -339,16 +339,16 @@ mda_store(struct mda_session *s) struct ibuf *buf; int len; - if (s->msg.delivery.from.user[0] && s->msg.delivery.from.domain[0]) + if (s->msg.sender.user[0] && s->msg.sender.domain[0]) /* XXX: remove user provided Return-Path, if any */ len = asprintf(&p, "Return-Path: %s@%s\nDelivered-To: %s@%s\n", - s->msg.delivery.from.user, s->msg.delivery.from.domain, - s->msg.delivery.rcpt_orig.user, - s->msg.delivery.rcpt_orig.domain); + s->msg.sender.user, s->msg.sender.domain, + s->msg.rcpt.user, + s->msg.rcpt.domain); else len = asprintf(&p, "Delivered-To: %s@%s\n", - s->msg.delivery.rcpt_orig.user, - s->msg.delivery.rcpt_orig.domain); + s->msg.rcpt.user, + s->msg.rcpt.domain); if (len == -1) fatal("mda_store: asprintf"); diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c index b2c02918ee9..d1736b72eec 100644 --- a/usr.sbin/smtpd/mfa.c +++ b/usr.sbin/smtpd/mfa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa.c,v 1.63 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: mfa.c,v 1.64 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -245,7 +245,7 @@ mfa_test_mail(struct envelope *e) ss.id = e->session_id; ss.code = 530; - ss.u.maddr = e->delivery.from; + ss.u.maddr = e->sender; if (mfa_strip_source_route(ss.u.maddr.user, sizeof(ss.u.maddr.user))) goto refuse; @@ -275,11 +275,11 @@ mfa_test_rcpt(struct envelope *e) ss.id = e->session_id; ss.code = 530; - ss.u.maddr = e->delivery.rcpt_orig; - ss.ss = e->delivery.ss; + ss.u.maddr = e->rcpt; + ss.ss = e->ss; ss.envelope = *e; - ss.envelope.delivery.rcpt = e->delivery.rcpt_orig; - ss.flags = e->delivery.flags; + ss.envelope.dest = e->rcpt; + ss.flags = e->flags; mfa_strip_source_route(ss.u.maddr.user, sizeof(ss.u.maddr.user)); @@ -303,8 +303,8 @@ mfa_test_rcpt_resume(struct submit_status *ss) { return; } - ss->envelope.delivery.rcpt = ss->u.maddr; - ss->envelope.delivery.expire = ss->envelope.rule.r_qexpire; + ss->envelope.dest = ss->u.maddr; + ss->envelope.expire = ss->envelope.rule.r_qexpire; imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_RCPT, 0, 0, -1, ss, sizeof(*ss)); } diff --git a/usr.sbin/smtpd/mfa_session.c b/usr.sbin/smtpd/mfa_session.c index c7158085a32..4d92262a181 100644 --- a/usr.sbin/smtpd/mfa_session.c +++ b/usr.sbin/smtpd/mfa_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa_session.c,v 1.4 2011/09/01 09:42:15 chl Exp $ */ +/* $OpenBSD: mfa_session.c,v 1.5 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -98,7 +98,7 @@ mfa_session_proceed(struct mfa_session *ms) switch (ms->state) { case S_HELO: fm.type = FILTER_HELO; - if (strlcpy(fm.u.helo.buffer, ms->ss.envelope.delivery.helo, + if (strlcpy(fm.u.helo.buffer, ms->ss.envelope.helo, sizeof(fm.u.helo.buffer)) >= sizeof(fm.u.helo.buffer)) fatalx("mfa_session_proceed: HELO: truncation"); break; diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c index c727307ecd6..26d83c3833e 100644 --- a/usr.sbin/smtpd/mta.c +++ b/usr.sbin/smtpd/mta.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mta.c,v 1.114 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: mta.c,v 1.115 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -136,11 +136,11 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg) if (e == NULL) fatal(NULL); *e = *(struct envelope *)imsg->data; - strlcpy(e->delivery.errorline, "000 init", - sizeof(e->delivery.errorline)); + strlcpy(e->errorline, "000 init", + sizeof(e->errorline)); if (s->host == NULL) { - s->host = strdup(e->delivery.rcpt.domain); + s->host = strdup(e->dest.domain); if (s->host == NULL) fatal("strdup"); } @@ -480,16 +480,16 @@ mta_enter_state(struct mta_session *s, int newstate, void *p) /* set envelope sender */ e = TAILQ_FIRST(&s->recipients); - if (e->delivery.from.user[0] && e->delivery.from.domain[0]) - client_sender(pcb, "%s@%s", e->delivery.from.user, - e->delivery.from.domain); + if (e->sender.user[0] && e->sender.domain[0]) + client_sender(pcb, "%s@%s", e->sender.user, + e->sender.domain); else client_sender(pcb, ""); /* set envelope recipients */ TAILQ_FOREACH(e, &s->recipients, entry) - client_rcpt(pcb, e, "%s@%s", e->delivery.rcpt.user, - e->delivery.rcpt.domain); + client_rcpt(pcb, e, "%s@%s", e->dest.user, + e->dest.domain); s->pcb = pcb; event_set(&s->ev, s->fd, EV_READ|EV_WRITE, mta_event, s); @@ -684,25 +684,25 @@ mta_message_status(struct envelope *e, char *status) * higher status (eg. 5yz is of higher status than 4yz), so check * this before deciding to overwrite existing status with a new one. */ - if (*status != '2' && strncmp(e->delivery.errorline, status, 3) > 0) + if (*status != '2' && strncmp(e->errorline, status, 3) > 0) return; /* change status */ - log_debug("mta: new status for %s@%s: %s", e->delivery.rcpt.user, - e->delivery.rcpt.domain, status); - strlcpy(e->delivery.errorline, status, sizeof(e->delivery.errorline)); + log_debug("mta: new status for %s@%s: %s", e->dest.user, + e->dest.domain, status); + strlcpy(e->errorline, status, sizeof(e->errorline)); } static void mta_message_log(struct mta_session *s, struct envelope *e) { struct mta_relay *relay = TAILQ_FIRST(&s->relays); - char *status = e->delivery.errorline; + char *status = e->errorline; log_info("%016llx: to=<%s@%s>, delay=%lld, relay=%s [%s], stat=%s (%s)", - e->delivery.id, e->delivery.rcpt.user, - e->delivery.rcpt.domain, - (long long int) (time(NULL) - e->delivery.creation), + e->id, e->dest.user, + e->dest.domain, + (long long int) (time(NULL) - e->creation), relay ? relay->fqdn : "(none)", relay ? ss_to_text(&relay->sa) : "", *status == '2' ? "Sent" : @@ -714,16 +714,16 @@ mta_message_log(struct mta_session *s, struct envelope *e) static void mta_message_done(struct mta_session *s, struct envelope *e) { - switch (e->delivery.errorline[0]) { + switch (e->errorline[0]) { case '6': case '5': - e->delivery.status = DS_PERMFAILURE; + e->status = DS_PERMFAILURE; break; case '2': - e->delivery.status = DS_ACCEPTED; + e->status = DS_ACCEPTED; break; default: - e->delivery.status = DS_TEMPFAILURE; + e->status = DS_TEMPFAILURE; break; } imsg_compose_event(env->sc_ievs[PROC_QUEUE], @@ -747,7 +747,7 @@ mta_request_datafd(struct mta_session *s) e = TAILQ_FIRST(&s->recipients); rq_batch.b_id = s->id; - rq_batch.msgid = evpid_to_msgid(e->delivery.id); + rq_batch.msgid = evpid_to_msgid(e->id); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_MESSAGE_FD, 0, 0, -1, &rq_batch, sizeof(rq_batch)); } diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index 12ea1bd0d8a..2d19a2698b6 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.107 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: queue.c,v 1.108 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -61,7 +61,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) ss.id = e->session_id; ss.code = 250; ss.u.msgid = 0; - if (e->delivery.flags & DF_ENQUEUED) + if (e->flags & DF_ENQUEUED) ret = queue_message_create(Q_ENQUEUE, &ss.u.msgid); else ret = queue_message_create(Q_INCOMING, &ss.u.msgid); @@ -72,21 +72,21 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) return; case IMSG_QUEUE_REMOVE_MESSAGE: - if (e->delivery.flags & DF_ENQUEUED) - queue_message_purge(Q_ENQUEUE, evpid_to_msgid(e->delivery.id)); + if (e->flags & DF_ENQUEUED) + queue_message_purge(Q_ENQUEUE, evpid_to_msgid(e->id)); else - queue_message_purge(Q_INCOMING, evpid_to_msgid(e->delivery.id)); + queue_message_purge(Q_INCOMING, evpid_to_msgid(e->id)); return; case IMSG_QUEUE_COMMIT_MESSAGE: ss.id = e->session_id; - if (e->delivery.flags & DF_ENQUEUED) { - if (queue_message_commit(Q_ENQUEUE, evpid_to_msgid(e->delivery.id))) + if (e->flags & DF_ENQUEUED) { + if (queue_message_commit(Q_ENQUEUE, evpid_to_msgid(e->id))) stat_increment(STATS_QUEUE_LOCAL); else ss.code = 421; } else { - if (queue_message_commit(Q_INCOMING, evpid_to_msgid(e->delivery.id))) + if (queue_message_commit(Q_INCOMING, evpid_to_msgid(e->id))) stat_increment(STATS_QUEUE_REMOTE); else ss.code = 421; @@ -101,10 +101,10 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) case IMSG_QUEUE_MESSAGE_FILE: ss.id = e->session_id; - if (e->delivery.flags & DF_ENQUEUED) - fd = queue_message_fd_rw(Q_ENQUEUE, evpid_to_msgid(e->delivery.id)); + if (e->flags & DF_ENQUEUED) + fd = queue_message_fd_rw(Q_ENQUEUE, evpid_to_msgid(e->id)); else - fd = queue_message_fd_rw(Q_INCOMING, evpid_to_msgid(e->delivery.id)); + fd = queue_message_fd_rw(Q_INCOMING, evpid_to_msgid(e->id)); if (fd == -1) ss.code = 421; imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FILE, 0, 0, fd, @@ -125,7 +125,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) ss.id = e->session_id; /* Write to disk */ - if (e->delivery.flags & DF_ENQUEUED) + if (e->flags & DF_ENQUEUED) ret = queue_envelope_create(Q_ENQUEUE, e); else ret = queue_envelope_create(Q_INCOMING, e); diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c index d86033126ff..1095a591fe3 100644 --- a/usr.sbin/smtpd/queue_backend.c +++ b/usr.sbin/smtpd/queue_backend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_backend.c,v 1.11 2011/05/16 21:05:52 gilles Exp $ */ +/* $OpenBSD: queue_backend.c,v 1.12 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -23,6 +23,7 @@ #include <sys/socket.h> #include <sys/stat.h> +#include <ctype.h> #include <event.h> #include <imsg.h> #include <libgen.h> @@ -35,12 +36,13 @@ #include "smtpd.h" #include "log.h" +static int envelope_validate(struct envelope *); + /* fsqueue backend */ int fsqueue_init(void); int fsqueue_message(enum queue_kind, enum queue_op, u_int32_t *); int fsqueue_envelope(enum queue_kind, enum queue_op , struct envelope *); - struct queue_backend queue_backends[] = { { QT_FS, fsqueue_init, @@ -114,8 +116,10 @@ queue_envelope_delete(enum queue_kind qkind, struct envelope *ep) int queue_envelope_load(enum queue_kind qkind, u_int64_t evpid, struct envelope *ep) { - ep->delivery.id = evpid; - return env->sc_queue->envelope(qkind, QOP_LOAD, ep); + ep->id = evpid; + if (env->sc_queue->envelope(qkind, QOP_LOAD, ep)) + return envelope_validate(ep); + return 0; } int @@ -123,3 +127,30 @@ queue_envelope_update(enum queue_kind qkind, struct envelope *ep) { return env->sc_queue->envelope(qkind, QOP_UPDATE, ep); } + +static int +envelope_validate(struct envelope *ep) +{ + if (ep->version != SMTPD_ENVELOPE_VERSION) + return 0; + + if ((ep->id & 0xffffffff) == 0 || + ((ep->id >> 32) & 0xffffffff) == 0) + return 0; + + if (ep->helo[0] == '\0') + return 0; + + if (ep->hostname[0] == '\0') + return 0; + + if (ep->errorline[0] != '\0') { + if (! isdigit(ep->errorline[0]) || + ! isdigit(ep->errorline[1]) || + ! isdigit(ep->errorline[2]) || + ep->errorline[3] != ' ') + return 0; + } + + return 1; +} diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c index e1e5e5f0b2b..f0c7361d7ce 100644 --- a/usr.sbin/smtpd/queue_fsqueue.c +++ b/usr.sbin/smtpd/queue_fsqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_fsqueue.c,v 1.13 2011/08/26 14:39:47 chl Exp $ */ +/* $OpenBSD: queue_fsqueue.c,v 1.14 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -40,7 +40,6 @@ #include "log.h" static char *fsqueue_getpath(enum queue_kind); -/*static*/ u_int16_t fsqueue_hash(u_int32_t); static int fsqueue_envelope_load(enum queue_kind, struct envelope *); static int fsqueue_envelope_update(enum queue_kind, struct envelope *); @@ -57,6 +56,9 @@ int fsqueue_init(void); int fsqueue_message(enum queue_kind, enum queue_op, u_int32_t *); int fsqueue_envelope(enum queue_kind, enum queue_op , struct envelope *); +int fsqueue_load_envelope_ascii(FILE *, struct envelope *); +int fsqueue_dump_envelope_ascii(FILE *, struct envelope *); + static char * fsqueue_getpath(enum queue_kind kind) { @@ -85,12 +87,6 @@ fsqueue_getpath(enum queue_kind kind) return NULL; } -/*static*/ u_int16_t -fsqueue_hash(u_int32_t h) -{ - return (h % DIRHASH_BUCKETS); -} - static int fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep) { @@ -106,8 +102,7 @@ again: rnd = (u_int32_t)arc4random(); if (rnd == 0) goto again; - evpid = ep->delivery.id | rnd; - + evpid = ep->id | rnd; if (! bsnprintf(evpname, sizeof(evpname), "%s/%08x%s/%016llx", fsqueue_getpath(qkind), @@ -127,19 +122,19 @@ again: fp = fdopen(fd, "w"); if (fp == NULL) fatal("fsqueue_envelope_create: fdopen"); - - ep->delivery.creation = time(NULL); - ep->delivery.id = evpid; + + ep->creation = time(NULL); + ep->id = evpid; if (qkind == Q_BOUNCE) { - ep->delivery.lasttry = 0; - ep->delivery.retry = 0; + ep->lasttry = 0; + ep->retry = 0; } - if (fwrite(ep, sizeof (*ep), 1, fp) != 1) { + if (! fsqueue_dump_envelope_ascii(fp, ep)) { if (errno == ENOSPC) goto tempfail; - fatal("fsqueue_envelope_create: write"); + fatal("fsqueue_dump_envelope_ascii: write"); } if (! safe_fclose(fp)) { @@ -156,8 +151,8 @@ tempfail: fclose(fp); else if (fd != -1) close(fd); - ep->delivery.creation = 0; - ep->delivery.id = 0; + ep->creation = 0; + ep->id = 0; return 0; } @@ -168,11 +163,11 @@ fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep) char pathname[MAXPATHLEN]; FILE *fp; - if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx", + if (! bsnprintf(pathname, sizeof(pathname), "%s/%03x/%08x%s/%016llx", fsqueue_getpath(qkind), - fsqueue_hash(evpid_to_msgid(ep->delivery.id)), - evpid_to_msgid(ep->delivery.id), - PATH_ENVELOPES, ep->delivery.id)) + evpid_to_msgid(ep->id) & 0xfff, + evpid_to_msgid(ep->id), + PATH_ENVELOPES, ep->id)) fatalx("fsqueue_envelope_load: snprintf"); fp = fopen(pathname, "r"); @@ -181,8 +176,8 @@ fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep) return 0; fatal("fsqueue_envelope_load: fopen"); } - if (fread(ep, sizeof (*ep), 1, fp) != 1) - fatal("fsqueue_envelope_load: fread"); + if (! fsqueue_load_envelope_ascii(fp, ep)) + fatal("fsqueue_load_envelope_ascii: fread"); fclose(fp); return 1; } @@ -201,11 +196,11 @@ fsqueue_envelope_update(enum queue_kind qkind, struct envelope *ep) if (! bsnprintf(temp, sizeof(temp), "%s/envelope.tmp", PATH_QUEUE)) fatalx("fsqueue_envelope_update"); - if (! bsnprintf(dest, sizeof(dest), "%s/%04x/%08x%s/%016llx", + if (! bsnprintf(dest, sizeof(dest), "%s/%03x/%08x%s/%016llx", fsqueue_getpath(qkind), - fsqueue_hash(evpid_to_msgid(ep->delivery.id)), - evpid_to_msgid(ep->delivery.id), - PATH_ENVELOPES, ep->delivery.id)) + evpid_to_msgid(ep->id) & 0xfff, + evpid_to_msgid(ep->id), + PATH_ENVELOPES, ep->id)) fatal("fsqueue_envelope_update: snprintf"); fp = fopen(temp, "w"); @@ -214,10 +209,10 @@ fsqueue_envelope_update(enum queue_kind qkind, struct envelope *ep) goto tempfail; fatal("fsqueue_envelope_update: open"); } - if (fwrite(ep, sizeof (*ep), 1, fp) != 1) { + if (! fsqueue_dump_envelope_ascii(fp, ep)) { if (errno == ENOSPC) goto tempfail; - fatal("fsqueue_envelope_update: fwrite"); + fatal("fsqueue_dump_envelope_ascii: fwrite"); } if (! safe_fclose(fp)) goto tempfail; @@ -245,27 +240,27 @@ static int fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep) { char pathname[MAXPATHLEN]; - u_int16_t hval; - - hval = fsqueue_hash(evpid_to_msgid(ep->delivery.id)); - if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx", + if (! bsnprintf(pathname, sizeof(pathname), "%s/%03x/%08x%s/%016llx", fsqueue_getpath(qkind), - hval, - evpid_to_msgid(ep->delivery.id), + evpid_to_msgid(ep->id) & 0xfff, + evpid_to_msgid(ep->id), PATH_ENVELOPES, - ep->delivery.id)) + ep->id)) fatal("fsqueue_envelope_delete: snprintf"); - if (unlink(pathname) == -1) + if (unlink(pathname) == -1) { + log_debug("######: %s [errno: %d]", pathname, errno); fatal("fsqueue_envelope_delete: unlink"); + } - if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s", PATH_QUEUE, - hval, evpid_to_msgid(ep->delivery.id), PATH_ENVELOPES)) + if (! bsnprintf(pathname, sizeof(pathname), "%s/%03x/%08x%s", PATH_QUEUE, + evpid_to_msgid(ep->id) & 0xfff, + evpid_to_msgid(ep->id), PATH_ENVELOPES)) fatal("fsqueue_envelope_delete: snprintf"); if (rmdir(pathname) != -1) - fsqueue_message_delete(qkind, evpid_to_msgid(ep->delivery.id)); + fsqueue_message_delete(qkind, evpid_to_msgid(ep->id)); return 1; } @@ -313,9 +308,9 @@ again: } if (qkind == Q_BOUNCE) { - if (! bsnprintf(msgpath, sizeof(msgpath), "%s/%04x/%08x/message", + if (! bsnprintf(msgpath, sizeof(msgpath), "%s/%03x/%08x/message", fsqueue_getpath(Q_QUEUE), - fsqueue_hash(msgid_save), + msgid_save & 0xfff, msgid_save)) return 0; @@ -341,10 +336,10 @@ fsqueue_message_commit(enum queue_kind qkind, u_int32_t msgid) fsqueue_getpath(qkind), msgid)) fatal("fsqueue_message_commit: snprintf"); - if (! bsnprintf(queuedir, sizeof(queuedir), "%s/%04x", - fsqueue_getpath(Q_QUEUE), fsqueue_hash(msgid))) + if (! bsnprintf(queuedir, sizeof(queuedir), "%s/%03x", + fsqueue_getpath(Q_QUEUE), msgid & 0xfff)) fatal("fsqueue_message_commit: snprintf"); - + if (mkdir(queuedir, 0700) == -1) { if (errno == ENOSPC) return 0; @@ -370,7 +365,6 @@ fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid) { int fd; char pathname[MAXPATHLEN]; - u_int16_t hval; if (qkind == Q_ENQUEUE || qkind == Q_INCOMING) { if (! bsnprintf(pathname, sizeof(pathname), "%s/%08x/message", @@ -378,9 +372,8 @@ fsqueue_message_fd_r(enum queue_kind qkind, u_int32_t msgid) fatal("fsqueue_message_fd_r: snprintf"); } else { - hval = fsqueue_hash(msgid); - if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x/message", - fsqueue_getpath(qkind), hval, msgid)) + if (! bsnprintf(pathname, sizeof(pathname), "%s/%03x/%08x/message", + fsqueue_getpath(qkind), msgid & 0xfff, msgid)) fatal("fsqueue_message_fd_r: snprintf"); } @@ -409,11 +402,9 @@ fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid) char rootdir[MAXPATHLEN]; char evpdir[MAXPATHLEN]; char msgpath[MAXPATHLEN]; - u_int16_t hval; - hval = fsqueue_hash(msgid); - if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%04x/%08x", PATH_QUEUE, - hval, msgid)) + if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%03x/%08x", PATH_QUEUE, + msgid & 0xfff, msgid)) fatal("queue_delete_message: snprintf"); if (! bsnprintf(evpdir, sizeof(evpdir), "%s%s", rootdir, @@ -438,7 +429,7 @@ fsqueue_message_delete(enum queue_kind qkind, u_int32_t msgid) if (rmdir(rootdir) == -1) fatal("#2 queue_delete_message: rmdir"); - if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%04x", PATH_QUEUE, hval)) + if (! bsnprintf(rootdir, sizeof(rootdir), "%s/%03x", PATH_QUEUE, msgid & 0xffff)) fatal("queue_delete_message: snprintf"); rmdir(rootdir); diff --git a/usr.sbin/smtpd/queue_fsqueue_ascii.c b/usr.sbin/smtpd/queue_fsqueue_ascii.c new file mode 100644 index 00000000000..1c7c78ddd5e --- /dev/null +++ b/usr.sbin/smtpd/queue_fsqueue_ascii.c @@ -0,0 +1,783 @@ +/* $OpenBSD: queue_fsqueue_ascii.c,v 1.1 2011/10/23 09:30:07 gilles Exp $ */ + +/* + * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/tree.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/stat.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <event.h> +#include <fcntl.h> +#include <imsg.h> +#include <libgen.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "smtpd.h" +#include "log.h" + + +#define KW_VERSION "version" +#define KW_EVPID "evpid" +#define KW_TYPE "type" +#define KW_HELO "helo" +#define KW_HOSTNAME "hostname" +#define KW_ERRORLINE "errorline" +#define KW_SOCKADDR "sockaddr" +#define KW_SENDER "sender" +#define KW_RCPT "rcpt" +#define KW_DEST "dest" +#define KW_CTIME "ctime" +#define KW_EXPIRE "expire" +#define KW_RETRY "retry" +#define KW_LAST_TRY "last-try" +#define KW_FLAGS "flags" +#define KW_STATUS "status" + +#define KW_MDA_METHOD "mda-method" +#define KW_MDA_BUFFER "mda-buffer" +#define KW_MDA_USER "mda-user" + +#define KW_MTA_RELAY_HOST "mta-relay-hostname" +#define KW_MTA_RELAY_PORT "mta-relay-port" +#define KW_MTA_RELAY_FLAGS "mta-relay-flags" +#define KW_MTA_RELAY_CERT "mta-relay-cert" +#define KW_MTA_RELAY_AS "mta-relay-as" + +int fsqueue_load_envelope_ascii(FILE *, struct envelope *); +int fsqueue_dump_envelope_ascii(FILE *, struct envelope *); + +static int +ascii_load_version(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->version = strtonum(buf, 0, 0xffffffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_version(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %d\n", KW_VERSION, SMTPD_ENVELOPE_VERSION); + return 1; +} + + +static int +ascii_load_evpid(struct envelope *ep, char *buf) +{ + char *endptr; + + ep->id = strtoull(buf, &endptr, 16); + if (buf[0] == '\0' || *endptr != '\0') + return 0; + if (errno == ERANGE && ep->id == ULLONG_MAX) + return 0; + return 1; +} + +static int +ascii_dump_evpid(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %016llx\n", KW_EVPID, ep->id); + return 1; +} + + +static int +ascii_load_type(struct envelope *ep, char *buf) +{ + if (strcasecmp(buf, "mda") == 0) + ep->type = D_MDA; + else if (strcasecmp(buf, "mta") == 0) + ep->type = D_MTA; + else if (strcasecmp(buf, "bounce") == 0) + ep->type = D_BOUNCE; + else + return 0; + return 1; +} + +static int +ascii_dump_type(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: ", KW_TYPE); + switch (ep->type) { + case D_MDA: + fprintf(fp, "mda\n"); + break; + case D_MTA: + fprintf(fp, "mta\n"); + break; + case D_BOUNCE: + fprintf(fp, "bounce\n"); + break; + default: + return 0; + } + return 1; +} + + +static int +ascii_load_mda_method(struct envelope *ep, char *buf) +{ + if (strcasecmp(buf, "mbox") == 0) + ep->agent.mda.method = A_MBOX; + else if (strcasecmp(buf, "maildir") == 0) + ep->agent.mda.method = A_MAILDIR; + else if (strcasecmp(buf, "filename") == 0) + ep->agent.mda.method = A_FILENAME; + else if (strcasecmp(buf, "external") == 0) + ep->agent.mda.method = A_EXT; + else + return 0; + return 1; +} + +static int +ascii_dump_mda_method(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: ", KW_MDA_METHOD); + switch (ep->agent.mda.method) { + case A_MAILDIR: + fprintf(fp, "maildir\n"); + break; + case A_MBOX: + fprintf(fp, "mbox\n"); + break; + case A_FILENAME: + fprintf(fp, "filename\n"); + break; + case A_EXT: + fprintf(fp, "external\n"); + break; + default: + return 0; + } + return 1; +} + +static int +ascii_load_mda_buffer(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->agent.mda.to.buffer, buf, + sizeof (ep->agent.mda.to.buffer)) + >= sizeof (ep->agent.mda.to.buffer)) + return 0; + return 1; +} + +static int +ascii_dump_mda_buffer(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s\n", KW_MDA_BUFFER, + ep->agent.mda.to.buffer); + return 1; +} + + +static int +ascii_load_mda_user(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->agent.mda.as_user, buf, + sizeof (ep->agent.mda.as_user)) + >= sizeof (ep->agent.mda.as_user)) + return 0; + return 1; +} + +static int +ascii_dump_mda_user(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s\n", KW_MDA_USER, + ep->agent.mda.as_user); + return 1; +} + + +static int +ascii_load_helo(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->helo, buf, + sizeof (ep->helo)) + >= sizeof (ep->helo)) + return 0; + return 1; +} + +static int +ascii_dump_helo(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s\n", KW_HELO, ep->helo); + return 1; +} + + +static int +ascii_load_hostname(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->hostname, buf, + sizeof (ep->hostname)) + >= sizeof (ep->hostname)) + return 0; + return 1; +} + +static int +ascii_dump_hostname(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s\n", KW_HOSTNAME, ep->hostname); + return 1; +} + +static int +ascii_load_errorline(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->errorline, buf, + sizeof(ep->errorline)) >= + sizeof(ep->errorline)) + return 0; + + return 1; +} + +static int +ascii_dump_errorline(struct envelope *ep, FILE *fp) +{ + if (ep->errorline[0]) + fprintf(fp, "%s: %s\n", KW_ERRORLINE, + ep->errorline); + return 1; +} + + +static int +ascii_load_sockaddr(struct envelope *ep, char *buf) +{ + struct sockaddr_in6 ssin6; + struct sockaddr_in ssin; + + if (strncasecmp("IPv6:", buf, 5) == 0) { + if (inet_pton(AF_INET6, buf + 5, &ssin6.sin6_addr) != 1) + return 0; + ssin6.sin6_family = AF_INET6; + memcpy(&ep->ss, &ssin6, sizeof(ssin6)); + ep->ss.ss_len = sizeof(struct sockaddr_in6); + } + else { + if (inet_pton(AF_INET, buf, &ssin.sin_addr) != 1) + return 0; + ssin.sin_family = AF_INET; + memcpy(&ep->ss, &ssin6, sizeof(ssin)); + ep->ss.ss_len = sizeof(struct sockaddr_in); + } + return 1; +} + +static int +ascii_dump_sockaddr(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s\n", KW_SOCKADDR, ss_to_text(&ep->ss)); + return 1; +} + + +static int +ascii_load_sender(struct envelope *ep, char *buf) +{ + if (! email_to_mailaddr(&ep->sender, buf)) + return 0; + return 1; +} + +static int +ascii_dump_sender(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s@%s\n", KW_SENDER, + ep->sender.user, ep->sender.domain); + return 1; +} + + +static int +ascii_load_rcpt(struct envelope *ep, char *buf) +{ + if (! email_to_mailaddr(&ep->rcpt, buf)) + return 0; + ep->dest = ep->rcpt; + return 1; +} + +static int +ascii_dump_rcpt(struct envelope *ep, FILE *fp) +{ + fprintf(fp, "%s: %s@%s\n", KW_RCPT, + ep->dest.user, ep->dest.domain); + return 1; +} + + +static int +ascii_load_dest(struct envelope *ep, char *buf) +{ + if (! email_to_mailaddr(&ep->dest, buf)) + return 0; + return 1; +} + +static int +ascii_dump_dest(struct envelope *ep, FILE *fp) +{ + if (strcmp(ep->dest.user, ep->dest.user) != 0 || + strcmp(ep->dest.domain, ep->dest.domain) != 0) + fprintf(fp, "%s: %s@%s\n", KW_DEST, + ep->dest.user, + ep->dest.domain); + return 1; +} + + +static int +ascii_load_mta_relay_host(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->agent.mta.relay.hostname, buf, + sizeof(ep->agent.mta.relay.hostname)) + >= sizeof(ep->agent.mta.relay.hostname)) + return 0; + return 1; +} + +static int +ascii_dump_mta_relay_host(struct envelope *ep, FILE *fp) +{ + if (ep->agent.mta.relay.hostname[0]) + fprintf(fp, "%s: %s\n", KW_MTA_RELAY_HOST, + ep->agent.mta.relay.hostname); + return 1; +} + +static int +ascii_load_mta_relay_port(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->agent.mta.relay.port = strtonum(buf, 0, 0xffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_mta_relay_port(struct envelope *ep, FILE *fp) +{ + if (ep->agent.mta.relay.port) + fprintf(fp, "%s: %d\n", KW_MTA_RELAY_PORT, + ep->agent.mta.relay.port); + return 1; +} + +static int +ascii_load_mta_relay_cert(struct envelope *ep, char *buf) +{ + if (strlcpy(ep->agent.mta.relay.cert, buf, + sizeof(ep->agent.mta.relay.cert)) + >= sizeof(ep->agent.mta.relay.cert)) + return 0; + return 1; +} + +static int +ascii_dump_mta_relay_cert(struct envelope *ep, FILE *fp) +{ + if (ep->agent.mta.relay.cert[0]) + fprintf(fp, "%s: %s\n", KW_MTA_RELAY_CERT, + ep->agent.mta.relay.cert); + return 1; +} + +static int +ascii_load_mta_relay_flags(struct envelope *ep, char *buf) +{ + char *flag; + + while ((flag = strsep(&buf, " ,|")) != NULL) { + if (strcasecmp(flag, "force-anyssl") == 0) + ep->agent.mta.relay.flags |= MTA_FORCE_ANYSSL; + else if (strcasecmp(flag, "force-smtps") == 0) + ep->agent.mta.relay.flags |= MTA_FORCE_SMTPS; + else if (strcasecmp(flag, "allow-plain") == 0) + ep->agent.mta.relay.flags |= MTA_ALLOW_PLAIN; + else if (strcasecmp(flag, "use-auth") == 0) + ep->agent.mta.relay.flags |= MTA_USE_AUTH; + else if (strcasecmp(flag, "force-mx") == 0) + ep->agent.mta.relay.flags |= MTA_FORCE_MX; + else + return 0; + } + + return 1; +} + +static int +ascii_dump_mta_relay_flags(struct envelope *ep, FILE *fp) +{ + if (ep->agent.mta.relay.flags) { + fprintf(fp, "%s:", KW_MTA_RELAY_FLAGS); + if (ep->agent.mta.relay.flags & MTA_FORCE_ANYSSL) + fprintf(fp, " force-anyssl"); + if (ep->agent.mta.relay.flags & MTA_FORCE_SMTPS) + fprintf(fp, " force-smtps"); + if (ep->agent.mta.relay.flags & MTA_ALLOW_PLAIN) + fprintf(fp, " allow-plain"); + if (ep->agent.mta.relay.flags & MTA_USE_AUTH) + fprintf(fp, " use-auth"); + if (ep->agent.mta.relay.flags & MTA_FORCE_MX) + fprintf(fp, " force-mx"); + fprintf(fp, "\n"); + } + return 1; +} + +static int +ascii_dump_mta_relay_as(struct envelope *ep, FILE *fp) +{ + if (ep->agent.mta.relay_as.user[0] || + ep->agent.mta.relay_as.domain[0]) + fprintf(fp, "%s: %s@%s\n", KW_MTA_RELAY_AS, + ep->agent.mta.relay_as.user, + ep->agent.mta.relay_as.domain); + return 1; +} + + +static int +ascii_load_ctime(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->creation = strtonum(buf, 0, 0xffffffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_ctime(struct envelope *ep, FILE *fp) +{ + if (ep->creation) + fprintf(fp, "%s: %qd\n", KW_CTIME, + (u_int64_t)ep->creation); + return 1; +} + + +static int +ascii_load_expire(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->expire = strtonum(buf, 0, 0xffffffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_expire(struct envelope *ep, FILE *fp) +{ + if (ep->expire) + fprintf(fp, "%s: %qd\n", KW_EXPIRE, + (u_int64_t)ep->expire); + return 1; +} + +static int +ascii_load_retry(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->retry = strtonum(buf, 0, 0xffffffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_retry(struct envelope *ep, FILE *fp) +{ + if (ep->retry) + fprintf(fp, "%s: %d\n", KW_RETRY, + ep->retry); + return 1; +} + +static int +ascii_load_lasttry(struct envelope *ep, char *buf) +{ + const char *errstr; + + ep->lasttry = strtonum(buf, 0, 0xffffffff, &errstr); + if (errstr) + return 0; + return 1; +} + +static int +ascii_dump_lasttry(struct envelope *ep, FILE *fp) +{ + if (ep->lasttry) + fprintf(fp, "%s: %qd\n", KW_LAST_TRY, + (u_int64_t)ep->lasttry); + return 1; +} + +static int +ascii_dump_flags(struct envelope *ep, FILE *fp) +{ + if (ep->flags) { + fprintf(fp, "%s:", KW_FLAGS); + if (ep->flags & DF_AUTHENTICATED) + fprintf(fp, " authenticated"); + if (ep->flags & DF_ENQUEUED) + fprintf(fp, " enqueued"); + if (ep->flags & DF_BOUNCE) + fprintf(fp, " bounce"); + if (ep->flags & DF_INTERNAL) + fprintf(fp, " internal"); + fprintf(fp, "\n"); + } + return 1; +} + +static int +ascii_load_flags(struct envelope *ep, char *buf) +{ + char *flag; + + while ((flag = strsep(&buf, " ,|")) != NULL) { + if (strcasecmp(flag, "authenticated") == 0) + ep->flags |= DF_AUTHENTICATED; + else if (strcasecmp(flag, "enqueued") == 0) + ep->flags |= DF_ENQUEUED; + else if (strcasecmp(flag, "bounce") == 0) + ep->flags |= DF_BOUNCE; + else if (strcasecmp(flag, "internal") == 0) + ep->flags |= DF_INTERNAL; + else + return 0; + } + return 1; +} + +static int +ascii_dump_status(struct envelope *ep, FILE *fp) +{ + if (ep->status) { + fprintf(fp, "%s ", KW_STATUS); + if (ep->status & DS_PERMFAILURE) + fprintf(fp, " permfail"); + if (ep->status & DS_TEMPFAILURE) + fprintf(fp, " tempfail"); + if (ep->status & DS_REJECTED) + fprintf(fp, " rejected"); + if (ep->status & DS_ACCEPTED) + fprintf(fp, " accepted"); + fprintf(fp, "\n"); + } + return 1; +} + +static int +ascii_dump_agent(struct envelope *ep, FILE *fp) +{ + if (! ascii_dump_type(ep, fp)) + return 0; + + switch (ep->type) { + case D_MDA: + if (! ascii_dump_mda_method(ep, fp) || + ! ascii_dump_mda_buffer(ep, fp) || + ! ascii_dump_mda_user(ep, fp)) + return 0; + break; + + case D_MTA: + if (! ascii_dump_mta_relay_host(ep, fp) || + ! ascii_dump_mta_relay_port(ep, fp) || + ! ascii_dump_mta_relay_cert(ep, fp) || + ! ascii_dump_mta_relay_flags(ep, fp) || + ! ascii_dump_mta_relay_as(ep, fp)) + return 0; + break; + + case D_BOUNCE: + /* nothing ! */ + break; + + default: + return 0; + } + + return 1; +} + +int +fsqueue_load_envelope_ascii(FILE *fp, struct envelope *ep) +{ + char *buf, *lbuf; + size_t len; + struct ascii_load_handler { + char *kw; + int (*hdl)(struct envelope *, char *); + } ascii_load_handlers[] = { + { KW_VERSION, ascii_load_version }, + { KW_EVPID, ascii_load_evpid }, + + { KW_HOSTNAME, ascii_load_hostname }, + { KW_SOCKADDR, ascii_load_sockaddr }, + + { KW_HELO, ascii_load_helo }, + { KW_SENDER, ascii_load_sender }, + { KW_RCPT, ascii_load_rcpt }, + + { KW_TYPE, ascii_load_type }, + { KW_DEST, ascii_load_dest }, + + { KW_CTIME, ascii_load_ctime }, + { KW_EXPIRE, ascii_load_expire }, + { KW_RETRY, ascii_load_retry }, + { KW_LAST_TRY, ascii_load_lasttry }, + + { KW_FLAGS, ascii_load_flags }, + + { KW_ERRORLINE, ascii_load_errorline }, + + { KW_MDA_METHOD, ascii_load_mda_method }, + { KW_MDA_BUFFER, ascii_load_mda_buffer }, + { KW_MDA_USER, ascii_load_mda_user }, + + { KW_MTA_RELAY_HOST, ascii_load_mta_relay_host }, + { KW_MTA_RELAY_PORT, ascii_load_mta_relay_port }, + { KW_MTA_RELAY_FLAGS, ascii_load_mta_relay_flags }, + { KW_MTA_RELAY_CERT, ascii_load_mta_relay_cert }, + }; + int i; + int n; + int ret; + + n = sizeof(ascii_load_handlers) / sizeof(struct ascii_load_handler); + + bzero(ep, sizeof (*ep)); + lbuf = NULL; + while ((buf = fgetln(fp, &len))) { + if (buf[len - 1] == '\n') + buf[len - 1] = '\0'; + else { + if ((lbuf = malloc(len + 1)) == NULL) + err(1, NULL); + memcpy(lbuf, buf, len); + lbuf[len] = '\0'; + buf = lbuf; + } + + for (i = 0; i < n; ++i) { + len = strlen(ascii_load_handlers[i].kw); + if (! strncasecmp(ascii_load_handlers[i].kw, buf, len)) { + /* skip kw and tailing whitespaces */ + buf += len; + while (*buf && isspace(*buf)) + buf++; + + /* we *want* ':' */ + if (*buf != ':') + continue; + buf++; + + /* skip whitespaces after separator */ + while (*buf && isspace(*buf)) + buf++; + + ret = ascii_load_handlers[i].hdl(ep, buf); + if (ret == 0) { + log_debug("### CHOKED ON: %s", buf); + goto err; + } + break; + } + } + + /* unknown keyword */ + if (i == n) { + log_debug("### CHOKED ON: %s", buf); + goto err; + } + } + free(lbuf); + + return 1; + +err: + free(lbuf); + return 0; +} + +int +fsqueue_dump_envelope_ascii(FILE *fp, struct envelope *ep) +{ + if (! ascii_dump_version(ep, fp) || + ! ascii_dump_evpid(ep, fp) || + ! ascii_dump_agent(ep, fp) || + ! ascii_dump_helo(ep, fp) || + ! ascii_dump_hostname(ep, fp) || + ! ascii_dump_errorline(ep, fp) || + ! ascii_dump_sockaddr(ep, fp) || + ! ascii_dump_sender(ep, fp) || + ! ascii_dump_rcpt(ep, fp) || + ! ascii_dump_dest(ep, fp) || + ! ascii_dump_ctime(ep, fp) || + ! ascii_dump_lasttry(ep, fp) || + ! ascii_dump_expire(ep, fp) || + ! ascii_dump_retry(ep, fp) || + ! ascii_dump_flags(ep, fp) || + ! ascii_dump_status(ep, fp)) + goto err; + + if (fflush(fp) != 0) + goto err; + + return 1; + +err: + return 0; +} diff --git a/usr.sbin/smtpd/queue_shared.c b/usr.sbin/smtpd/queue_shared.c index 726a63f6359..9b7a4b8e2ce 100644 --- a/usr.sbin/smtpd/queue_shared.c +++ b/usr.sbin/smtpd/queue_shared.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_shared.c,v 1.51 2011/08/29 21:43:09 chl Exp $ */ +/* $OpenBSD: queue_shared.c,v 1.52 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -43,6 +43,8 @@ #define QWALK_RECURSE 0x2 #define QWALK_RETURN 0x3 +int fsqueue_load_envelope_ascii(FILE *, struct envelope *); + struct qwalk { char path[MAXPATHLEN]; DIR *dirs[3]; @@ -65,20 +67,20 @@ bounce_record_message(struct envelope *e, struct envelope *bounce) bzero(bounce, sizeof(*bounce)); - if (e->delivery.type == D_BOUNCE) { + if (e->type == D_BOUNCE) { log_debug("mailer daemons loop detected !"); return 0; } *bounce = *e; - bounce->delivery.type = D_BOUNCE; - bounce->delivery.status &= ~DS_PERMFAILURE; + bounce->type = D_BOUNCE; + bounce->status &= ~DS_PERMFAILURE; - msgid = evpid_to_msgid(e->delivery.id); + msgid = evpid_to_msgid(e->id); if (! queue_message_create(Q_BOUNCE, &msgid)) return 0; - bounce->delivery.id = msgid_to_evpid(msgid); + bounce->id = msgid_to_evpid(msgid); if (! queue_envelope_create(Q_BOUNCE, bounce)) return 0; @@ -89,14 +91,13 @@ void queue_message_update(struct envelope *e) { e->batch_id = 0; - e->delivery.flags &= ~DF_PROCESSING; - e->delivery.status &= ~(DS_ACCEPTED|DS_REJECTED); - e->delivery.retry++; + e->status &= ~(DS_ACCEPTED|DS_REJECTED); + e->retry++; - if (e->delivery.status & DS_PERMFAILURE) { - if (e->delivery.type != D_BOUNCE && - e->delivery.from.user[0] != '\0') { + if (e->status & DS_PERMFAILURE) { + if (e->type != D_BOUNCE && + e->sender.user[0] != '\0') { struct envelope bounce; bounce_record_message(e, &bounce); @@ -105,8 +106,8 @@ queue_message_update(struct envelope *e) return; } - if (e->delivery.status & DS_TEMPFAILURE) { - e->delivery.status &= ~DS_TEMPFAILURE; + if (e->status & DS_TEMPFAILURE) { + e->status &= ~DS_TEMPFAILURE; queue_envelope_update(Q_QUEUE, e); return; } @@ -230,13 +231,13 @@ walk_queue(struct qwalk *q, char *fname) log_warnx("walk_queue: invalid bucket: %s", fname); return (QWALK_AGAIN); } - if (! bsnprintf(q->path, sizeof(q->path), "%s/%04x", PATH_QUEUE, - q->bucket)) + if (! bsnprintf(q->path, sizeof(q->path), "%s/%03x", PATH_QUEUE, + q->bucket & 0xfff)) fatalx("walk_queue: snprintf"); return (QWALK_RECURSE); case 1: - if (! bsnprintf(q->path, sizeof(q->path), "%s/%04x/%s%s", - PATH_QUEUE, q->bucket, fname, PATH_ENVELOPES)) + if (! bsnprintf(q->path, sizeof(q->path), "%s/%03x/%s%s", + PATH_QUEUE, q->bucket & 0xfff, fname, PATH_ENVELOPES)) fatalx("walk_queue: snprintf"); return (QWALK_RECURSE); case 2: @@ -270,7 +271,7 @@ show_queue(char *queuepath, int flags) } errno = 0; - if (fread(&message, sizeof(message), 1, fp) != 1) + if (! fsqueue_load_envelope_ascii(fp, &message)) err(1, "%s", path); fclose(fp); @@ -287,36 +288,32 @@ display_envelope(struct envelope *e, int flags) status[0] = '\0'; - getflag(&e->delivery.status, DS_TEMPFAILURE, "TEMPFAIL", + getflag(&e->status, DS_TEMPFAILURE, "TEMPFAIL", status, sizeof(status)); - if (e->delivery.status) - errx(1, "%016llx: unexpected status 0x%04x", e->delivery.id, - e->delivery.status); + if (e->status) + errx(1, "%016llx: unexpected status 0x%04x", e->id, + e->status); - getflag(&e->delivery.flags, DF_BOUNCE, "BOUNCE", - status, sizeof(status)); - getflag(&e->delivery.flags, DF_AUTHENTICATED, "AUTH", - status, sizeof(status)); - getflag(&e->delivery.flags, DF_PROCESSING, "PROCESSING", + getflag(&e->flags, DF_BOUNCE, "BOUNCE", status, sizeof(status)); - getflag(&e->delivery.flags, DF_SCHEDULED, "SCHEDULED", + getflag(&e->flags, DF_AUTHENTICATED, "AUTH", status, sizeof(status)); - getflag(&e->delivery.flags, DF_ENQUEUED, "ENQUEUED", + getflag(&e->flags, DF_ENQUEUED, "ENQUEUED", status, sizeof(status)); - getflag(&e->delivery.flags, DF_FORCESCHEDULE, "SCHEDULED_MANUAL", + getflag(&e->flags, DF_INTERNAL, "INTERNAL", status, sizeof(status)); - if (e->delivery.flags) - errx(1, "%016llx: unexpected flags 0x%04x", e->delivery.id, - e->delivery.flags); + if (e->flags) + errx(1, "%016llx: unexpected flags 0x%04x", e->id, + e->flags); if (status[0]) status[strlen(status) - 1] = '\0'; else strlcpy(status, "-", sizeof(status)); - switch (e->delivery.type) { + switch (e->type) { case D_MDA: printf("MDA"); break; @@ -331,16 +328,16 @@ display_envelope(struct envelope *e, int flags) } printf("|%016llx|%s|%s@%s|%s@%s|%lld|%lld|%u", - e->delivery.id, + e->id, status, - e->delivery.from.user, e->delivery.from.domain, - e->delivery.rcpt.user, e->delivery.rcpt.domain, - (long long int) e->delivery.lasttry, - (long long int) e->delivery.expire, - e->delivery.retry); + e->sender.user, e->sender.domain, + e->dest.user, e->dest.domain, + (long long int) e->lasttry, + (long long int) e->expire, + e->retry); - if (e->delivery.errorline[0] != '\0') - printf("|%s", e->delivery.errorline); + if (e->errorline[0] != '\0') + printf("|%s", e->errorline); printf("\n"); } diff --git a/usr.sbin/smtpd/ramqueue.c b/usr.sbin/smtpd/ramqueue.c index 2762df5ff36..aba38b5560f 100644 --- a/usr.sbin/smtpd/ramqueue.c +++ b/usr.sbin/smtpd/ramqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ramqueue.c,v 1.19 2011/09/18 21:37:53 gilles Exp $ */ +/* $OpenBSD: ramqueue.c,v 1.20 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -181,7 +181,7 @@ ramqueue_insert(struct ramqueue *rqueue, struct envelope *envelope, time_t curtm struct ramqueue_envelope *evp; struct ramqueue_message *rq_msg, msgkey; - msgkey.msgid = evpid_to_msgid(envelope->delivery.id); + msgkey.msgid = evpid_to_msgid(envelope->id); rq_msg = RB_FIND(msgtree, &rqueue->msgtree, &msgkey); if (rq_msg == NULL) { rq_msg = calloc(1, sizeof (*rq_msg)); @@ -196,9 +196,9 @@ ramqueue_insert(struct ramqueue *rqueue, struct envelope *envelope, time_t curtm rq_evp = calloc(1, sizeof (*rq_evp)); if (rq_evp == NULL) fatal("calloc"); - rq_evp->evpid = envelope->delivery.id; + rq_evp->evpid = envelope->id; rq_evp->sched = ramqueue_next_schedule(envelope, curtm); - rq_evp->rq_host = ramqueue_get_host(rqueue, envelope->delivery.rcpt.domain); + rq_evp->rq_host = ramqueue_get_host(rqueue, envelope->dest.domain); rq_evp->rq_batch = ramqueue_get_batch(rqueue, rq_evp->rq_host, envelope); RB_INSERT(evptree, &rq_msg->evptree, rq_evp); rq_evp->rq_msg = rq_msg; @@ -224,12 +224,14 @@ ramqueue_expire(struct envelope *envelope, time_t curtm) { struct envelope bounce; - if (curtm - envelope->delivery.creation >= envelope->delivery.expire) { + if (curtm - envelope->creation >= envelope->expire) { envelope_set_errormsg(envelope, "message expired after sitting in queue for %d days", - envelope->delivery.expire / 60 / 60 / 24); + envelope->expire / 60 / 60 / 24); bounce_record_message(envelope, &bounce); ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL)); + log_debug("#### %s: queue_envelope_delete: %016llx", + __func__, envelope->id); queue_envelope_delete(Q_QUEUE, envelope); return 1; } @@ -241,31 +243,31 @@ ramqueue_next_schedule(struct envelope *envelope, time_t curtm) { time_t delay; - if (envelope->delivery.lasttry == 0) + if (envelope->lasttry == 0) return curtm; delay = SMTPD_QUEUE_MAXINTERVAL; - if (envelope->delivery.type == D_MDA || - envelope->delivery.type == D_BOUNCE) { - if (envelope->delivery.retry < 5) + if (envelope->type == D_MDA || + envelope->type == D_BOUNCE) { + if (envelope->retry < 5) return curtm; - if (envelope->delivery.retry < 15) - delay = (envelope->delivery.retry * 60) + arc4random_uniform(60); + if (envelope->retry < 15) + delay = (envelope->retry * 60) + arc4random_uniform(60); } - if (envelope->delivery.type == D_MTA) { - if (envelope->delivery.retry < 3) + if (envelope->type == D_MTA) { + if (envelope->retry < 3) delay = SMTPD_QUEUE_INTERVAL; - else if (envelope->delivery.retry <= 7) { - delay = SMTPD_QUEUE_INTERVAL * (1 << (envelope->delivery.retry - 3)); + else if (envelope->retry <= 7) { + delay = SMTPD_QUEUE_INTERVAL * (1 << (envelope->retry - 3)); if (delay > SMTPD_QUEUE_MAXINTERVAL) delay = SMTPD_QUEUE_MAXINTERVAL; } } - if (curtm >= envelope->delivery.lasttry + delay) + if (curtm >= envelope->lasttry + delay) return curtm; return curtm + delay; @@ -306,7 +308,7 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host, struct ramqueue_batch *rq_batch; TAILQ_FOREACH(rq_batch, &host->batch_queue, batch_entry) { - if (rq_batch->msgid == (u_int32_t)(envelope->delivery.id >> 32)) + if (rq_batch->msgid == evpid_to_msgid(envelope->id)) return rq_batch; } @@ -315,8 +317,8 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host, fatal("calloc"); rq_batch->b_id = generate_uid(); rq_batch->rule = envelope->rule; - rq_batch->type = envelope->delivery.type; - rq_batch->msgid = envelope->delivery.id >> 32; + rq_batch->type = envelope->type; + rq_batch->msgid = evpid_to_msgid(envelope->id); TAILQ_INIT(&rq_batch->envelope_queue); TAILQ_INSERT_TAIL(&host->batch_queue, rq_batch, batch_entry); diff --git a/usr.sbin/smtpd/ruleset.c b/usr.sbin/smtpd/ruleset.c index b8a214085e6..c5a9b68cff0 100644 --- a/usr.sbin/smtpd/ruleset.c +++ b/usr.sbin/smtpd/ruleset.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ruleset.c,v 1.19 2011/05/21 18:39:03 gilles Exp $ */ +/* $OpenBSD: ruleset.c,v 1.20 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org> @@ -47,10 +47,10 @@ ruleset_match(struct envelope *evp) struct rule *r; struct map *map; struct mapel *me; - struct mailaddr *maddr = &evp->delivery.rcpt; - struct sockaddr_storage *ss = &evp->delivery.ss; + struct mailaddr *maddr = &evp->dest; + struct sockaddr_storage *ss = &evp->ss; - if (evp->delivery.flags & DF_INTERNAL) + if (evp->flags & DF_INTERNAL) ss = NULL; TAILQ_FOREACH(r, env->sc_rules, r_entry) { @@ -59,7 +59,7 @@ ruleset_match(struct envelope *evp) continue; if (ss != NULL && - (!(evp->delivery.flags & DF_AUTHENTICATED) && + (!(evp->flags & DF_AUTHENTICATED) && ! ruleset_check_source(r->r_sources, ss))) continue; diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 33f9b7f6af9..6c7d5c70717 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.119 2011/10/09 18:39:53 eric Exp $ */ +/* $OpenBSD: runner.c,v 1.120 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -60,7 +60,6 @@ static int runner_force_message_to_ramqueue(struct ramqueue *, u_int32_t); /*temporary*/ -u_int16_t fsqueue_hash(u_int32_t); u_int64_t filename_to_evpid(char *); u_int32_t filename_to_msgid(char *); @@ -75,20 +74,22 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg) switch (imsg->hdr.type) { case IMSG_QUEUE_COMMIT_MESSAGE: e = imsg->data; - runner_force_message_to_ramqueue(&env->sc_rqueue, e->delivery.id>>32); + runner_force_message_to_ramqueue(&env->sc_rqueue, + evpid_to_msgid(e->id)); runner_reset_events(); return; case IMSG_QUEUE_MESSAGE_UPDATE: e = imsg->data; - e->delivery.retry++; + e->retry++; stat_decrement(STATS_RUNNER); /* temporary failure, message remains in queue, * gets reinserted in ramqueue */ - if (e->delivery.status & DS_TEMPFAILURE) { - e->delivery.status &= ~DS_TEMPFAILURE; + if (e->status & DS_TEMPFAILURE) { + log_debug("TEMPFAIL: %016llx", e->id); + e->status &= ~DS_TEMPFAILURE; queue_envelope_update(Q_QUEUE, e); ramqueue_insert(&env->sc_rqueue, e, time(NULL)); runner_reset_events(); @@ -98,11 +99,12 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg) /* permanent failure, eventually generate a * bounce (and insert bounce in ramqueue). */ - if (e->delivery.status & DS_PERMFAILURE) { + if (e->status & DS_PERMFAILURE) { struct envelope bounce; - - if (e->delivery.type != D_BOUNCE && - e->delivery.from.user[0] != '\0') { + log_debug("PERMFAIL: %016llx", e->id); + if (e->type != D_BOUNCE && + e->sender.user[0] != '\0') { + log_debug("PERMFAIL #2: %016llx", e->id); bounce_record_message(e, &bounce); ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL)); runner_reset_events(); @@ -112,6 +114,8 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg) /* successful delivery or permanent failure, * remove envelope from queue. */ + log_debug("#### %s: queue_envelope_delete: %016llx", + __func__, e->id); queue_envelope_delete(Q_QUEUE, e); return; @@ -130,7 +134,7 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg) case IMSG_SMTP_ENQUEUE: e = imsg->data; if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) { - e->delivery.status = 0; + e->status = 0; queue_envelope_update(Q_QUEUE, e); ramqueue_insert(&env->sc_rqueue, e, time(NULL)); runner_reset_events(); @@ -371,21 +375,21 @@ runner_process_envelope(struct ramqueue_envelope *rq_evp, time_t curtm) if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &envelope)) return 0; - if (envelope.delivery.type & D_MDA) { + if (envelope.type & D_MDA) { if (env->sc_opts & SMTPD_MDA_PAUSED) return 0; if (mda_av == 0) return 0; } - if (envelope.delivery.type & D_MTA) { + if (envelope.type & D_MTA) { if (env->sc_opts & SMTPD_MTA_PAUSED) return 0; if (mta_av == 0) return 0; } - if (envelope.delivery.type & D_BOUNCE) { + if (envelope.type & D_BOUNCE) { if (env->sc_opts & (SMTPD_MDA_PAUSED|SMTPD_MTA_PAUSED)) return 0; if (bnc_av == 0) @@ -399,6 +403,8 @@ runner_process_envelope(struct ramqueue_envelope *rq_evp, time_t curtm) bounce_record_message(&envelope, &bounce); ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL)); runner_setup_events(); + log_debug("#### %s: queue_envelope_delete: %016llx", + __func__, envelope.id); queue_envelope_delete(Q_QUEUE, &envelope); return 0; } @@ -428,7 +434,7 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm) if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &evp)) return; - evp.delivery.lasttry = curtm; + evp.lasttry = curtm; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_SMTP_ENQUEUE, PROC_SMTP, 0, -1, &evp, sizeof evp); @@ -444,8 +450,9 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm) rq_evp = ramqueue_batch_first_envelope(rq_batch); if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &evp)) return; - evp.delivery.lasttry = curtm; - fd = queue_message_fd_r(Q_QUEUE, rq_evp->evpid>>32); + evp.lasttry = curtm; + fd = queue_message_fd_r(Q_QUEUE, + evpid_to_msgid(rq_evp->evpid)); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_MDA_SESS_NEW, PROC_MDA, 0, fd, &evp, sizeof evp); @@ -464,7 +471,7 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm) if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &evp)) return; - evp.delivery.lasttry = curtm; + evp.lasttry = curtm; evp.batch_id = rq_batch->b_id; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_BATCH_APPEND, PROC_MTA, 0, -1, &evp, @@ -503,8 +510,8 @@ runner_force_message_to_ramqueue(struct ramqueue *rqueue, u_int32_t msgid) struct envelope envelope; time_t curtm; - if (! bsnprintf(path, MAXPATHLEN, "%s/%04x/%08x/envelopes", - PATH_QUEUE, fsqueue_hash(msgid), msgid)) + if (! bsnprintf(path, MAXPATHLEN, "%s/%03x/%08x/envelopes", + PATH_QUEUE, msgid & 0xfff, msgid)) return 0; dirp = opendir(path); @@ -624,7 +631,8 @@ runner_check_loop(struct envelope *ep) int ret = 0; int rcvcount = 0; - fd = queue_message_fd_r(Q_QUEUE, ep->delivery.id>>32); + fd = queue_message_fd_r(Q_QUEUE, + evpid_to_msgid(ep->id)); if ((fp = fdopen(fd, "r")) == NULL) fatal("fdopen"); @@ -653,18 +661,18 @@ runner_check_loop(struct envelope *ep) } else if (strncasecmp("Delivered-To: ", buf, 14) == 0) { - struct mailaddr rcpt; + struct mailaddr dest; bzero(&maddr, sizeof (struct mailaddr)); if (! email_to_mailaddr(&maddr, buf + 14)) continue; + + dest = ep->dest; + if (ep->type == D_BOUNCE) + dest = ep->sender; - rcpt = ep->delivery.rcpt; - if (ep->delivery.type == D_BOUNCE) - rcpt = ep->delivery.from; - - if (strcasecmp(maddr.user, rcpt.user) == 0 && - strcasecmp(maddr.domain, rcpt.domain) == 0) { + if (strcasecmp(maddr.user, dest.user) == 0 && + strcasecmp(maddr.domain, dest.domain) == 0) { ret = 1; break; } @@ -713,8 +721,11 @@ runner_remove_envelope(struct ramqueue *rq, struct ramqueue_envelope *rq_evp) { struct envelope evp; - if (queue_envelope_load(Q_QUEUE, rq_evp->evpid, &evp)) + if (queue_envelope_load(Q_QUEUE, rq_evp->evpid, &evp)) { + log_debug("#### %s: queue_envelope_delete: %016llx", + __func__, evp.id); queue_envelope_delete(Q_QUEUE, &evp); + } ramqueue_remove_envelope(rq, rq_evp); } diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index 8ea6d9465ec..b3d9e9a21e5 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.92 2011/10/09 18:39:54 eric Exp $ */ +/* $OpenBSD: smtp.c,v 1.93 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -73,8 +73,8 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) strlcpy(s->s_hostname, dns->error ? "<unknown>" : dns->host, sizeof s->s_hostname); - strlcpy(s->s_msg.delivery.hostname, s->s_hostname, - sizeof s->s_msg.delivery.hostname); + strlcpy(s->s_msg.hostname, s->s_hostname, + sizeof s->s_msg.hostname); session_init(s->s_l, s); return; } @@ -103,7 +103,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) s = session_lookup(ss->id); if (s == NULL) return; - s->s_msg.delivery.id = (u_int64_t)ss->u.msgid << 32; + s->s_msg.id = ((u_int64_t)ss->u.msgid) << 32; session_pickup(s, ss); return; @@ -130,7 +130,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) fatalx("smtp: session is gone"); if (s->s_flags & F_WRITEONLY) /* session is write-only, must not destroy it. */ - s->s_msg.delivery.status |= DS_TEMPFAILURE; + s->s_msg.status |= DS_TEMPFAILURE; else fatalx("smtp: corrupt session"); return; @@ -167,7 +167,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) */ SPLAY_FOREACH(s, sessiontree, &env->sc_sessions) { s->s_l = NULL; - s->s_msg.delivery.status |= DS_TEMPFAILURE; + s->s_msg.status |= DS_TEMPFAILURE; } if (env->sc_listeners) smtp_disable_events(); @@ -247,10 +247,10 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) return; if (auth->success) { s->s_flags |= F_AUTHENTICATED; - s->s_msg.delivery.flags |= DF_AUTHENTICATED; + s->s_msg.flags |= DF_AUTHENTICATED; } else { s->s_flags &= ~F_AUTHENTICATED; - s->s_msg.delivery.flags &= ~DF_AUTHENTICATED; + s->s_msg.flags &= ~DF_AUTHENTICATED; } session_pickup(s, NULL); return; @@ -478,18 +478,18 @@ smtp_enqueue(uid_t *euid) s->s_fd = fd[0]; s->s_ss = sa; - s->s_msg.delivery.flags |= DF_ENQUEUED; + s->s_msg.flags |= DF_ENQUEUED; if (euid) bsnprintf(s->s_hostname, sizeof(s->s_hostname), "%d@localhost", *euid); else { strlcpy(s->s_hostname, "localhost", sizeof(s->s_hostname)); - s->s_msg.delivery.flags |= DF_BOUNCE; + s->s_msg.flags |= DF_BOUNCE; } - strlcpy(s->s_msg.delivery.hostname, s->s_hostname, - sizeof(s->s_msg.delivery.hostname)); + strlcpy(s->s_msg.hostname, s->s_hostname, + sizeof(s->s_msg.hostname)); session_init(l, s); diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 3c75142b8e2..a4386a11b3a 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.149 2011/10/03 19:20:51 gilles Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.150 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -323,8 +323,8 @@ session_rfc5321_helo_handler(struct session *s, char *args) return 1; } - if (strlcpy(s->s_msg.delivery.helo, args, sizeof(s->s_msg.delivery.helo)) - >= sizeof(s->s_msg.delivery.helo)) { + if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo)) + >= sizeof(s->s_msg.helo)) { session_respond(s, "501 Invalid domain name"); return 1; } @@ -346,8 +346,8 @@ session_rfc5321_ehlo_handler(struct session *s, char *args) return 1; } - if (strlcpy(s->s_msg.delivery.helo, args, sizeof(s->s_msg.delivery.helo)) - >= sizeof(s->s_msg.delivery.helo)) { + if (strlcpy(s->s_msg.helo, args, sizeof(s->s_msg.helo)) + >= sizeof(s->s_msg.helo)) { session_respond(s, "501 Invalid domain name"); return 1; } @@ -393,7 +393,7 @@ session_rfc5321_mail_handler(struct session *s, char *args) return 1; } - if (! session_set_mailaddr(&s->s_msg.delivery.from, args)) { + if (! session_set_mailaddr(&s->s_msg.sender, args)) { /* No need to even transmit to MFA, path is invalid */ session_respond(s, "553 5.1.7 Sender address syntax error"); return 1; @@ -401,8 +401,8 @@ session_rfc5321_mail_handler(struct session *s, char *args) s->rcptcount = 0; s->s_state = S_MAIL_MFA; - s->s_msg.delivery.id = 0; - s->s_msg.delivery.ss = s->s_ss; + s->s_msg.id = 0; + s->s_msg.ss = s->s_ss; log_debug("session_rfc5321_mail_handler: sending notification to mfa"); @@ -424,7 +424,7 @@ session_rfc5321_rcpt_handler(struct session *s, char *args) return 1; } - if (! session_set_mailaddr(&s->s_msg.delivery.rcpt_orig, args)) { + if (! session_set_mailaddr(&s->s_msg.rcpt, args)) { /* No need to even transmit to MFA, path is invalid */ session_respond(s, "553 5.1.3 Recipient address syntax error"); return 1; @@ -582,7 +582,7 @@ session_pickup(struct session *s, struct submit_status *ss) fatal("session_pickup: desynchronized"); if ((ss != NULL && ss->code == 421) || - (s->s_msg.delivery.status & DS_TEMPFAILURE)) { + (s->s_msg.status & DS_TEMPFAILURE)) { session_respond(s, "421 Service temporarily unavailable"); env->stats->smtp.tempfail++; s->s_flags |= F_QUIT; @@ -622,7 +622,7 @@ session_pickup(struct session *s, struct submit_status *ss) session_respond(s, "250%c%s Hello %s [%s], pleased to meet you", (s->s_flags & F_EHLO) ? '-' : ' ', - env->sc_hostname, s->s_msg.delivery.helo, ss_to_text(&s->s_ss)); + env->sc_hostname, s->s_msg.helo, ss_to_text(&s->s_ss)); if (s->s_flags & F_EHLO) { /* unconditionnal extensions go first */ @@ -651,7 +651,7 @@ session_pickup(struct session *s, struct submit_status *ss) } s->s_state = S_MAIL_QUEUE; - s->s_msg.delivery.from = ss->u.maddr; + s->s_msg.sender = ss->u.maddr; session_imsg(s, PROC_QUEUE, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1, &s->s_msg, sizeof(s->s_msg)); @@ -675,14 +675,14 @@ session_pickup(struct session *s, struct submit_status *ss) else s->s_state = S_RCPT; session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", ss->code, - s->s_msg.delivery.rcpt_orig.user, - s->s_msg.delivery.rcpt_orig.domain); + s->s_msg.rcpt.user, + s->s_msg.rcpt.domain); return; } s->s_state = S_RCPT; s->rcptcount++; - s->s_msg.delivery.rcpt = ss->u.maddr; + s->s_msg.dest = ss->u.maddr; session_respond(s, "%d 2.0.0 Recipient ok", ss->code); break; @@ -693,10 +693,10 @@ session_pickup(struct session *s, struct submit_status *ss) " itself"); fprintf(s->datafp, "Received: from %s (%s [%s])\n", - s->s_msg.delivery.helo, s->s_hostname, ss_to_text(&s->s_ss)); + s->s_msg.helo, s->s_hostname, ss_to_text(&s->s_ss)); fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %08x", env->sc_hostname, s->s_flags & F_EHLO ? "E" : "", - (u_int32_t)(s->s_msg.delivery.id >> 32)); + evpid_to_msgid(s->s_msg.id)); if (s->s_flags & F_SECURE) { fprintf(s->datafp, "\n\t(version=%s cipher=%s bits=%d)", @@ -706,8 +706,8 @@ session_pickup(struct session *s, struct submit_status *ss) } if (s->rcptcount == 1) fprintf(s->datafp, "\n\tfor <%s@%s>; ", - s->s_msg.delivery.rcpt_orig.user, - s->s_msg.delivery.rcpt_orig.domain); + s->s_msg.rcpt.user, + s->s_msg.rcpt.domain); else fprintf(s->datafp, ";\n\t"); @@ -716,19 +716,19 @@ session_pickup(struct session *s, struct submit_status *ss) case S_DATACONTENT: if (ss->code != 250) - s->s_msg.delivery.status |= DS_PERMFAILURE; + s->s_msg.status |= DS_PERMFAILURE; session_read_data(s, ss->u.dataline); break; case S_DONE: session_respond(s, "250 2.0.0 %08x Message accepted for delivery", - (u_int32_t)(s->s_msg.delivery.id >> 32)); + evpid_to_msgid(s->s_msg.id)); log_info("%08x: from=<%s%s%s>, size=%ld, nrcpts=%zd, proto=%s, " "relay=%s [%s]", - (u_int32_t)(s->s_msg.delivery.id >> 32), - s->s_msg.delivery.from.user, - s->s_msg.delivery.from.user[0] == '\0' ? "" : "@", - s->s_msg.delivery.from.domain, + evpid_to_msgid(s->s_msg.id), + s->s_msg.sender.user, + s->s_msg.sender.user[0] == '\0' ? "" : "@", + s->s_msg.sender.domain, s->s_datalen, s->rcptcount, s->s_flags & F_EHLO ? "ESMTP" : "SMTP", @@ -736,7 +736,7 @@ session_pickup(struct session *s, struct submit_status *ss) ss_to_text(&s->s_ss)); s->s_state = S_HELO; - s->s_msg.delivery.id = 0; + s->s_msg.id = 0; bzero(&s->s_nresp, sizeof(s->s_nresp)); break; @@ -791,14 +791,14 @@ session_read(struct bufferevent *bev, void *p) switch (s->s_state) { case S_AUTH_INIT: - if (s->s_msg.delivery.status & DS_TEMPFAILURE) + if (s->s_msg.status & DS_TEMPFAILURE) goto tempfail; session_rfc4954_auth_plain(s, line); break; case S_AUTH_USERNAME: case S_AUTH_PASSWORD: - if (s->s_msg.delivery.status & DS_TEMPFAILURE) + if (s->s_msg.status & DS_TEMPFAILURE) goto tempfail; session_rfc4954_auth_login(s, line); break; @@ -807,7 +807,7 @@ session_read(struct bufferevent *bev, void *p) case S_HELO: case S_MAIL: case S_RCPT: - if (s->s_msg.delivery.status & DS_TEMPFAILURE) + if (s->s_msg.status & DS_TEMPFAILURE) goto tempfail; session_command(s, line); break; @@ -864,13 +864,13 @@ session_read_data(struct session *s, char *line) if (strcmp(line, ".") == 0) { s->s_datalen = ftell(s->datafp); if (! safe_fclose(s->datafp)) - s->s_msg.delivery.status |= DS_TEMPFAILURE; + s->s_msg.status |= DS_TEMPFAILURE; s->datafp = NULL; - if (s->s_msg.delivery.status & DS_PERMFAILURE) { + if (s->s_msg.status & DS_PERMFAILURE) { session_respond(s, "554 5.0.0 Transaction failed"); s->s_state = S_HELO; - } else if (s->s_msg.delivery.status & DS_TEMPFAILURE) { + } else if (s->s_msg.status & DS_TEMPFAILURE) { session_respond(s, "421 4.0.0 Temporary failure"); s->s_flags |= F_QUIT; env->stats->smtp.tempfail++; @@ -883,7 +883,7 @@ session_read_data(struct session *s, char *line) } /* Don't waste resources on message if it's going to bin anyway. */ - if (s->s_msg.delivery.status & (DS_PERMFAILURE|DS_TEMPFAILURE)) + if (s->s_msg.status & (DS_PERMFAILURE|DS_TEMPFAILURE)) goto end; /* "If the first character is a period and there are other characters @@ -900,12 +900,12 @@ session_read_data(struct session *s, char *line) datalen = ftell(s->datafp); if (SIZE_MAX - datalen < len + 1 || datalen + len + 1 > env->sc_maxsize) { - s->s_msg.delivery.status |= DS_PERMFAILURE; + s->s_msg.status |= DS_PERMFAILURE; goto end; } if (fprintf(s->datafp, "%s\n", line) != (int)len + 1) { - s->s_msg.delivery.status |= DS_TEMPFAILURE; + s->s_msg.status |= DS_TEMPFAILURE; goto end; } @@ -1016,7 +1016,7 @@ session_destroy(struct session *s) if (s->datafp != NULL) fclose(s->datafp); - if (s->s_msg.delivery.id != 0 && s->s_state != S_DONE) + if (s->s_msg.id != 0 && s->s_state != S_DONE) imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_REMOVE_MESSAGE, 0, 0, -1, &s->s_msg, sizeof(s->s_msg)); @@ -1135,8 +1135,8 @@ session_respond(struct session *s, char *fmt, ...) case '5': case '4': log_info("%08x: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)", - (u_int32_t)(s->s_msg.delivery.id >> 32), - s->s_msg.delivery.from.user, s->s_msg.delivery.from.domain, + evpid_to_msgid(s->s_msg.id), + s->s_msg.sender.user, s->s_msg.sender.domain, s->s_hostname, ss_to_text(&s->s_ss), (int)EVBUFFER_LENGTH(EVBUFFER_OUTPUT(s->s_bev)) - n - 2, EVBUFFER_DATA(EVBUFFER_OUTPUT(s->s_bev))); diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index a417dfa6a47..3c97118d018 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.67 2011/09/01 19:56:49 eric Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.68 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -285,7 +285,6 @@ show_sizes(void) printf("struct ramqueue_envelope: %zu\n", sizeof (struct ramqueue_envelope)); printf("struct envelope: %zu\n", sizeof (struct envelope)); - printf("struct delivery: %zu\n", sizeof (struct delivery)); } static void diff --git a/usr.sbin/smtpd/smtpctl/Makefile b/usr.sbin/smtpd/smtpctl/Makefile index 9b3f4576c24..948b2d32578 100644 --- a/usr.sbin/smtpd/smtpctl/Makefile +++ b/usr.sbin/smtpd/smtpctl/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.18 2011/09/01 19:56:49 eric Exp $ +# $OpenBSD: Makefile,v 1.19 2011/10/23 09:30:07 gilles Exp $ .PATH: ${.CURDIR}/.. @@ -17,7 +17,7 @@ CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual CFLAGS+= -Wsign-compare -Wbounded CFLAGS+= -DCLIENT_NO_SSL -SRCS= smtpctl.c parser.c log.c enqueue.c queue_shared.c util.c client.c queue_backend.c queue_fsqueue.c stats.c +SRCS= smtpctl.c parser.c log.c enqueue.c queue_shared.c util.c client.c queue_backend.c queue_fsqueue.c queue_fsqueue_ascii.c stats.c LDADD+= -lutil -levent DPADD+= ${LIBUTIL} ${LIBEVENT} .include <bsd.prog.mk> diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index af037c663fc..0824231361a 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.242 2011/10/22 00:16:34 eric Exp $ */ +/* $OpenBSD: smtpd.h,v 1.243 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -355,21 +355,14 @@ enum delivery_status { DS_PERMFAILURE = 0x2, DS_TEMPFAILURE = 0x4, DS_REJECTED = 0x8, - DS_ACCEPTED = 0x10, - DS_RETRY = 0x20, - DS_EDNS = 0x40, - DS_ECONNECT = 0x80 + DS_ACCEPTED = 0x10 }; enum delivery_flags { - DF_RESOLVED = 0x1, - DF_SCHEDULED = 0x2, - DF_PROCESSING = 0x4, - DF_AUTHENTICATED = 0x8, - DF_ENQUEUED = 0x10, - DF_FORCESCHEDULE = 0x20, - DF_BOUNCE = 0x40, - DF_INTERNAL = 0x80 /* internal expansion forward */ + DF_AUTHENTICATED = 0x1, + DF_ENQUEUED = 0x2, + DF_BOUNCE = 0x4, + DF_INTERNAL = 0x8 /* internal expansion forward */ }; union delivery_data { @@ -389,32 +382,6 @@ struct delivery_mta { struct mailaddr relay_as; }; -struct delivery { - u_int64_t id; - enum delivery_type type; - - char helo[MAXHOSTNAMELEN]; - char hostname[MAXHOSTNAMELEN]; - char errorline[MAX_LINE_SIZE + 1]; - struct sockaddr_storage ss; - - struct mailaddr from; - struct mailaddr rcpt; - struct mailaddr rcpt_orig; - - union delivery_method { - struct delivery_mda mda; - struct delivery_mta mta; - } agent; - - time_t creation; - time_t lasttry; - time_t expire; - u_int8_t retry; - enum delivery_flags flags; - enum delivery_status status; -}; - enum expand_type { EXPAND_INVALID, EXPAND_USERNAME, @@ -440,7 +407,7 @@ struct expandnode { RB_HEAD(expandtree, expandnode); - +#define SMTPD_ENVELOPE_VERSION 1 struct envelope { TAILQ_ENTRY(envelope) entry; @@ -450,7 +417,33 @@ struct envelope { u_int64_t session_id; u_int64_t batch_id; - struct delivery delivery; +// struct delivery delivery; + + u_int32_t version; + u_int64_t id; + enum delivery_type type; + + char helo[MAXHOSTNAMELEN]; + char hostname[MAXHOSTNAMELEN]; + char errorline[MAX_LINE_SIZE + 1]; + struct sockaddr_storage ss; + + struct mailaddr sender; + struct mailaddr rcpt; + struct mailaddr dest; + + union delivery_method { + struct delivery_mda mda; + struct delivery_mta mta; + } agent; + + time_t creation; + time_t lasttry; + time_t expire; + u_int8_t retry; + enum delivery_flags flags; + enum delivery_status status; + }; TAILQ_HEAD(deliverylist, envelope); @@ -1224,6 +1217,8 @@ void sa_set_port(struct sockaddr *, int); u_int64_t generate_uid(void); void fdlimit(double); int availdesc(void); +u_int32_t msgid_generate(void); +u_int64_t evpid_generate(u_int32_t); u_int32_t evpid_to_msgid(u_int64_t); u_int64_t msgid_to_evpid(u_int32_t); u_int32_t filename_to_msgid(char *); diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile index 45ef959c8f2..0e9c42f4a7f 100644 --- a/usr.sbin/smtpd/smtpd/Makefile +++ b/usr.sbin/smtpd/smtpd/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.30 2011/09/01 19:56:49 eric Exp $ +# $OpenBSD: Makefile,v 1.31 2011/10/23 09:30:07 gilles Exp $ PROG= smtpd SRCS= aliases.c auth_backend.c bounce.c client.c \ @@ -10,7 +10,7 @@ SRCS= aliases.c auth_backend.c bounce.c client.c \ smtp_session.c smtpd.c ssl.c ssl_privsep.c util.c asr.c \ print.c pack.c dname.c res_random.c sockaddr.c \ ramqueue.c queue_backend.c queue_fsqueue.c \ - user_backend.c stats.c + queue_fsqueue_ascii.c user_backend.c stats.c MAN= smtpd.8 smtpd.conf.5 BINDIR= /usr/sbin diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c index afa5eef128f..128a6275211 100644 --- a/usr.sbin/smtpd/util.c +++ b/usr.sbin/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.47 2011/05/17 18:54:32 gilles Exp $ */ +/* $OpenBSD: util.c,v 1.48 2011/10/23 09:30:07 gilles Exp $ */ /* * Copyright (c) 2000,2001 Markus Friedl. All rights reserved. @@ -352,9 +352,9 @@ envelope_set_errormsg(struct envelope *e, char *fmt, ...) va_start(ap, fmt); - ret = vsnprintf(e->delivery.errorline, MAX_LINE_SIZE, fmt, ap); + ret = vsnprintf(e->errorline, MAX_LINE_SIZE, fmt, ap); if (ret >= MAX_LINE_SIZE) - strlcpy(e->delivery.errorline + (MAX_LINE_SIZE - 4), "...", 4); + strlcpy(e->errorline + (MAX_LINE_SIZE - 4), "...", 4); /* this should not happen */ if (ret == -1) @@ -366,7 +366,7 @@ envelope_set_errormsg(struct envelope *e, char *fmt, ...) char * envelope_get_errormsg(struct envelope *e) { - return e->delivery.errorline; + return e->errorline; } void @@ -547,6 +547,38 @@ filename_to_evpid(char *filename) } u_int32_t +msgid_generate(void) +{ + u_int32_t ret; + + do { + ret = arc4random(); + } while (ret == 0); + + log_debug("msgid_generate: %08x", ret); + + return ret; +} + +u_int64_t +evpid_generate(u_int32_t msgid) +{ + u_int64_t ret; + + ret = msgid; + log_debug("evpid_generate: %016llx", ret); + ret <<= 32; + log_debug("evpid_generate: %016llx", ret); + do { + ret |= arc4random(); + } while ((ret & 0xffffffff) == 0); + + log_debug("evpid_generate: %016llx", ret); + + return ret; +} + +u_int32_t evpid_to_msgid(u_int64_t evpid) { return (evpid >> 32); |