summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/bounce.c23
-rw-r--r--usr.sbin/smtpd/lka.c6
-rw-r--r--usr.sbin/smtpd/lka_session.c111
-rw-r--r--usr.sbin/smtpd/mda.c40
-rw-r--r--usr.sbin/smtpd/mfa.c16
-rw-r--r--usr.sbin/smtpd/mfa_session.c4
-rw-r--r--usr.sbin/smtpd/mta.c44
-rw-r--r--usr.sbin/smtpd/queue.c24
-rw-r--r--usr.sbin/smtpd/queue_backend.c39
-rw-r--r--usr.sbin/smtpd/queue_fsqueue.c103
-rw-r--r--usr.sbin/smtpd/queue_fsqueue_ascii.c783
-rw-r--r--usr.sbin/smtpd/queue_shared.c83
-rw-r--r--usr.sbin/smtpd/ramqueue.c42
-rw-r--r--usr.sbin/smtpd/ruleset.c10
-rw-r--r--usr.sbin/smtpd/runner.c69
-rw-r--r--usr.sbin/smtpd/smtp.c24
-rw-r--r--usr.sbin/smtpd/smtp_session.c76
-rw-r--r--usr.sbin/smtpd/smtpctl.c3
-rw-r--r--usr.sbin/smtpd/smtpctl/Makefile4
-rw-r--r--usr.sbin/smtpd/smtpd.h77
-rw-r--r--usr.sbin/smtpd/smtpd/Makefile4
-rw-r--r--usr.sbin/smtpd/util.c40
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);