diff options
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r-- | usr.sbin/smtpd/mta.c | 36 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 5 | ||||
-rw-r--r-- | usr.sbin/smtpd/ssl.c | 9 |
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); |