summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2011-12-11 17:02:11 +0000
committerEric Faurot <eric@cvs.openbsd.org>2011-12-11 17:02:11 +0000
commit94afd7f54d95bd107bd8068480d4531b070dd1b3 (patch)
tree332d2ceb278e7268170ac4d6c53bde4c7cd74423 /usr.sbin
parentbfb9c87d7b3f5b12387b38452c8141fb8058f21f (diff)
Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed - skip mta_pickup() when handling the incoming fd ok gilles@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/mta.c83
-rw-r--r--usr.sbin/smtpd/smtpd.h6
2 files changed, 38 insertions, 51 deletions
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 2af2c62e50b..c362a2fdcc0 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.119 2011/11/14 19:23:41 chl Exp $ */
+/* $OpenBSD: mta.c,v 1.120 2011/12/11 17:02:10 eric Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -65,7 +65,8 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
struct envelope *e;
struct secret *secret;
struct dns *dns;
- struct ssl *ssl;
+ struct ssl key, *ssl;
+ char *cert;
log_imsg(PROC_MTA, iev->proc, imsg);
@@ -79,28 +80,16 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
fatal(NULL);
s->id = rq_batch->b_id;
s->state = MTA_INIT;
- s->batch = rq_batch;
/* establish host name */
if (rq_batch->relay.hostname[0]) {
s->host = strdup(rq_batch->relay.hostname);
s->flags |= MTA_FORCE_MX;
}
- else
- s->host = NULL;
/* establish port */
s->port = ntohs(rq_batch->relay.port); /* XXX */
- /* have cert? */
- s->cert = strdup(rq_batch->relay.cert);
- if (s->cert == NULL)
- fatal(NULL);
- else if (s->cert[0] == '\0') {
- free(s->cert);
- s->cert = NULL;
- }
-
/* use auth? */
if ((rq_batch->relay.flags & F_SSL) &&
(rq_batch->relay.flags & F_AUTH)) {
@@ -115,23 +104,31 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
case F_SSL:
s->flags |= MTA_FORCE_ANYSSL;
break;
-
case F_SMTPS:
s->flags |= MTA_FORCE_SMTPS;
-
+ break;
case F_STARTTLS:
- /* client_* API by default requires STARTTLS */
+ /* STARTTLS is tried by default */
break;
-
default:
s->flags |= MTA_ALLOW_PLAIN;
}
+ /* have cert? */
+ cert = rq_batch->relay.cert;
+ if (cert[0] != '\0') {
+ s->flags |= MTA_USE_CERT;
+ strlcpy(key.ssl_name, cert, sizeof(key.ssl_name));
+ s->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key);
+ }
+
TAILQ_INIT(&s->recipients);
TAILQ_INIT(&s->relays);
SPLAY_INSERT(mtatree, &env->mta_sessions, s);
- return;
+ log_debug("mta: %p: new session for batch %llu", s, s->id);
+
+ return;
case IMSG_BATCH_APPEND:
e = imsg->data;
@@ -148,17 +145,30 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
if (s->host == NULL)
fatal("strdup");
}
- TAILQ_INSERT_TAIL(&s->recipients, e, entry);
+ log_debug("mta: %p: adding <%s@%s> from envelope %016" PRIx64,
+ s, e->dest.user, e->dest.domain, e->id);
+ TAILQ_INSERT_TAIL(&s->recipients, e, entry);
return;
case IMSG_BATCH_CLOSE:
rq_batch = imsg->data;
- mta_pickup(mta_lookup(rq_batch->b_id), NULL);
+ s = mta_lookup(rq_batch->b_id);
+ if (s->flags & MTA_USE_CERT && s->ssl == NULL) {
+ mta_status(s, "190 certificate not found");
+ mta_enter_state(s, MTA_DONE, NULL);
+ } else
+ mta_pickup(s, NULL);
return;
case IMSG_QUEUE_MESSAGE_FD:
rq_batch = imsg->data;
- mta_pickup(mta_lookup(rq_batch->b_id), &imsg->fd);
+ if (imsg->fd == -1)
+ fatalx("mta: cannot obtain msgfd");
+ s = mta_lookup(rq_batch->b_id);
+ s->datafp = fdopen(imsg->fd, "r");
+ if (s->datafp == NULL)
+ fatal("mta: fdopen");
+ mta_enter_state(s, MTA_CONNECT, NULL);
return;
}
}
@@ -451,22 +461,10 @@ mta_enter_state(struct mta_session *s, int newstate, void *p)
pcb = client_init(s->fd, s->datafp, env->sc_hostname, 1);
- /* lookup SSL certificate */
- if (s->cert) {
- struct ssl key, *res;
-
- strlcpy(key.ssl_name, s->cert, sizeof(key.ssl_name));
- res = SPLAY_FIND(ssltree, env->sc_ssl, &key);
- if (res == NULL) {
- client_close(pcb);
- s->pcb = NULL;
- mta_status(s, "190 certificate not found");
- mta_enter_state(s, MTA_DONE, NULL);
- break;
- }
+ if (s->ssl) {
client_certificate(pcb,
- res->ssl_cert, res->ssl_cert_len,
- res->ssl_key, res->ssl_key_len);
+ s->ssl->ssl_cert, s->ssl->ssl_cert_len,
+ s->ssl->ssl_key, s->ssl->ssl_key_len);
}
/* choose SMTPS vs. STARTTLS */
@@ -525,7 +523,6 @@ mta_enter_state(struct mta_session *s, int newstate, void *p)
free(s->authmap);
free(s->secret);
free(s->host);
- free(s->cert);
free(s);
break;
@@ -575,16 +572,6 @@ mta_pickup(struct mta_session *s, void *p)
mta_enter_state(s, MTA_DATA, NULL);
break;
- case MTA_DATA:
- /* QUEUE replied to body fd request. */
- if (*(int *)p == -1)
- fatalx("mta cannot obtain msgfd");
- s->datafp = fdopen(*(int *)p, "r");
- if (s->datafp == NULL)
- fatal("fdopen");
- mta_enter_state(s, MTA_CONNECT, NULL);
- break;
-
case MTA_CONNECT:
/* Remote accepted/rejected connection. */
error = session_socket_error(s->fd);
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 27b46480288..6ffafc74186 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.256 2011/12/08 17:00:28 todd Exp $ */
+/* $OpenBSD: smtpd.h,v 1.257 2011/12/11 17:02:10 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -831,6 +831,7 @@ enum mta_state {
#define MTA_ALLOW_PLAIN 0x04
#define MTA_USE_AUTH 0x08
#define MTA_FORCE_MX 0x10
+#define MTA_USE_CERT 0x20
struct mta_relay {
TAILQ_ENTRY(mta_relay) entry;
@@ -853,9 +854,8 @@ struct mta_session {
int fd;
FILE *datafp;
struct event ev;
- char *cert;
void *pcb;
- struct ramqueue_batch *batch;
+ struct ssl *ssl;
};