summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/mta.c36
-rw-r--r--usr.sbin/smtpd/smtpd.h5
-rw-r--r--usr.sbin/smtpd/ssl.c9
3 files changed, 45 insertions, 5 deletions
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 5a13c33b37e..3bda0eb63a3 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.22 2009/01/29 13:00:12 gilles Exp $ */
+/* $OpenBSD: mta.c,v 1.23 2009/01/29 14:25:55 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -546,10 +546,13 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
batchp->status |= S_BATCH_PERMFAILURE;
strlcpy(batchp->errorline, line, MAX_LINE_SIZE);
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
}
if (line[3] == '-') {
+ if (strcasecmp(&line[4], "STARTTLS") == 0)
+ sessionp->s_flags |= F_PEERHASTLS;
return 1;
}
@@ -557,11 +560,38 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
case 250:
if (sessionp->s_state == S_DONE) {
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
+ return 0;
+ }
+
+ if (sessionp->s_state == S_GREETED &&
+ (sessionp->s_flags & F_PEERHASTLS) &&
+ !(sessionp->s_flags & F_SECURE)) {
+ session_respond(sessionp, "STARTTLS");
+ sessionp->s_state = S_TLS;
+ return 0;
+ }
+
+ if (sessionp->s_state == S_GREETED &&
+ !(sessionp->s_flags & F_PEERHASTLS) &&
+ sessionp->mxarray[sessionp->mx_off].flags & F_STARTTLS) {
+ /* PERM - we want TLS but it is not advertised */
+ batchp->status |= S_BATCH_PERMFAILURE;
+ mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
}
+
break;
case 220:
+ if (sessionp->s_state == S_TLS) {
+ ssl_client_init(sessionp);
+ bufferevent_disable(bev, EV_READ|EV_WRITE);
+ sessionp->s_state = S_GREETED;
+ return 0;
+ }
+
session_respond(sessionp, "EHLO %s", env->sc_hostname);
sessionp->s_state = S_GREETED;
return 1;
@@ -572,6 +602,7 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
batchp->status |= S_BATCH_TEMPFAILURE;
strlcpy(batchp->errorline, line, MAX_LINE_SIZE);
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
/* The following codes are state dependant and will cause
@@ -593,6 +624,7 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
case 221:
if (sessionp->s_state == S_DONE) {
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
}
@@ -607,6 +639,7 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
batchp->status |= S_BATCH_PERMFAILURE;
strlcpy(batchp->errorline, line, MAX_LINE_SIZE);
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
}
@@ -683,6 +716,7 @@ mta_reply_handler(struct bufferevent *bev, void *arg)
if (messagep == NULL) {
batchp->status |= S_BATCH_PERMFAILURE;
mta_batch_update_queue(batchp);
+ session_destroy(sessionp);
return 0;
}
}
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index ae124674101..c3a588594f5 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.58 2009/01/29 13:00:12 gilles Exp $ */
+/* $OpenBSD: smtpd.h,v 1.59 2009/01/29 14:25:55 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -568,7 +568,8 @@ enum session_flags {
F_QUIT = 0x2,
F_8BITMIME = 0x4,
F_SECURE = 0x8,
- F_AUTHENTICATED = 0x10
+ F_AUTHENTICATED = 0x10,
+ F_PEERHASTLS = 0x20
};
struct session {
diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c
index 49f7d1238c7..377bf726e1a 100644
--- a/usr.sbin/smtpd/ssl.c
+++ b/usr.sbin/smtpd/ssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.c,v 1.6 2009/01/29 13:00:12 gilles Exp $ */
+/* $OpenBSD: ssl.c,v 1.7 2009/01/29 14:25:55 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -99,8 +99,13 @@ ssl_connect(int fd, short event, void *p)
event_set(&s->s_bev->ev_write, s->s_fd, EV_WRITE, ssl_write, s->s_bev);
log_info("ssl_connect: connected to remote ssl server");
- bufferevent_enable(s->s_bev, EV_READ);
+ bufferevent_enable(s->s_bev, EV_READ|EV_WRITE);
s->s_flags |= F_SECURE;
+
+ if (s->s_flags & F_PEERHASTLS) {
+ session_respond(s, "EHLO %s", s->s_env->sc_hostname);
+ }
+
return;
retry:
event_add(&s->s_ev, &s->s_tv);