diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-01-27 22:48:30 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2009-01-27 22:48:30 +0000 |
commit | 07ef6c3ed7a914b835f530fffc9c76a585c8dadc (patch) | |
tree | a767cc662c479ce645cacf87f3d6cc5074755e41 /usr.sbin/smtpd/mfa.c | |
parent | 1e71a92a6d728ac28d7ff50d7b911d046b2eb37a (diff) |
first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.
Diffstat (limited to 'usr.sbin/smtpd/mfa.c')
-rw-r--r-- | usr.sbin/smtpd/mfa.c | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c index f03cbe7084b..4aec3aad6a1 100644 --- a/usr.sbin/smtpd/mfa.c +++ b/usr.sbin/smtpd/mfa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfa.c,v 1.9 2009/01/04 17:45:58 gilles Exp $ */ +/* $OpenBSD: mfa.c,v 1.10 2009/01/27 22:48:29 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -40,6 +40,7 @@ void mfa_sig_handler(int, short, void *); void mfa_dispatch_parent(int, short, void *); void mfa_dispatch_smtp(int, short, void *); void mfa_dispatch_lka(int, short, void *); +void mfa_dispatch_control(int, short, void *); void mfa_setup_events(struct smtpd *); void mfa_disable_events(struct smtpd *); void mfa_timeout(int, short, void *); @@ -242,8 +243,16 @@ mfa_dispatch_lka(int sig, short event, void *p) struct submit_status *ss; ss = imsg.data; - imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_MFA_RCPT, - 0, 0, -1, ss, sizeof(*ss)); + if (ss->msg.flags & F_MESSAGE_ENQUEUED) { + log_debug("FOOO"); + imsg_compose(env->sc_ibufs[PROC_CONTROL], IMSG_MFA_RCPT, + 0, 0, -1, ss, sizeof(*ss)); + } + else { + log_debug("BAAR"); + imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_MFA_RCPT, + 0, 0, -1, ss, sizeof(*ss)); + } break; } default: @@ -257,6 +266,78 @@ mfa_dispatch_lka(int sig, short event, void *p) } void +mfa_dispatch_control(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + ibuf = env->sc_ibufs[PROC_CONTROL]; + switch (event) { + case EV_READ: + if ((n = imsg_read(ibuf)) == -1) + fatal("imsg_read_error"); + if (n == 0) { + /* this pipe is dead, so remove the event handler */ + event_del(&ibuf->ev); + event_loopexit(NULL); + return; + } + break; + case EV_WRITE: + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + return; + default: + fatalx("unknown event"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatal("mfa_dispatch_smtp: imsg_read error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_MFA_RCPT: { + struct message_recipient *mr; + struct submit_status ss; + + mr = imsg.data; + log_debug("mfa_dispatch_control: testing forward path"); + ss.id = mr->id; + ss.code = 530; + ss.u.path = mr->path; + ss.ss = mr->ss; + ss.msg = mr->msg; + + ss.flags = mr->flags; + + if (! mfa_check_rcpt(env, &ss.u.path, &ss.ss)) { + imsg_compose(ibuf, IMSG_MFA_RCPT, 0, + 0, -1, &ss, sizeof(ss)); + } + else { + ss.code = 250; + imsg_compose(env->sc_ibufs[PROC_LKA], IMSG_LKA_RCPT, 0, + 0, -1, &ss, sizeof(ss)); + } + + break; + } + default: + log_debug("mfa_dispatch_smtp: unexpected imsg %d", + imsg.hdr.type); + break; + } + imsg_free(&imsg); + } + imsg_event_add(ibuf); +} + +void mfa_shutdown(void) { log_info("mail filter exiting"); @@ -304,6 +385,7 @@ mfa(struct smtpd *env) { PROC_PARENT, mfa_dispatch_parent }, { PROC_SMTP, mfa_dispatch_smtp }, { PROC_LKA, mfa_dispatch_lka }, + { PROC_CONTROL, mfa_dispatch_control}, }; switch (pid = fork()) { @@ -347,7 +429,7 @@ mfa(struct smtpd *env) signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); - config_peers(env, peers, 3); + config_peers(env, peers, 4); mfa_setup_events(env); event_dispatch(); @@ -382,7 +464,6 @@ mfa_check_rcpt(struct smtpd *env, struct path *path, struct sockaddr_storage *ss if (! mfa_check_source(r->r_sources, ss)) continue; - log_debug("client authorized"); TAILQ_FOREACH(cond, &r->r_conditions, c_entry) { if (cond->c_type == C_ALL) { path->rule = *r; @@ -396,6 +477,8 @@ mfa_check_rcpt(struct smtpd *env, struct path *path, struct sockaddr_storage *ss map = cond->c_match; TAILQ_FOREACH(me, &map->m_contents, me_entry) { + log_debug("matching: %s to %s", + path->domain, me->me_key.med_string); if (hostname_match(path->domain, me->me_key.med_string)) { path->rule = *r; return 1; @@ -429,8 +512,8 @@ mfa_check_source(struct map *map, struct sockaddr_storage *ss) if (mfa_match_mask(ss, &me->me_key.med_addr)) return 1; - } + return 0; } |