summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/ssl.c
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2009-01-29 13:00:13 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2009-01-29 13:00:13 +0000
commitf2d99bc67c64b127af29db19d8973f978dd85ee2 (patch)
treea89ddc86d4bf6a304b562557bcf11dc661061e79 /usr.sbin/smtpd/ssl.c
parentba96c5d19beb899512c74a252bc27ba22155b7bc (diff)
bring initial support for SSL in the mta part of smtpd, allowing for:
accept for domain "openbsd.org" relay via ssmtp "mx1.example.org" to ensure that deliveries for whatever@openbsd.org goes through an SSL session to mx1.example.org
Diffstat (limited to 'usr.sbin/smtpd/ssl.c')
-rw-r--r--usr.sbin/smtpd/ssl.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/usr.sbin/smtpd/ssl.c b/usr.sbin/smtpd/ssl.c
index 8b508c14c19..49f7d1238c7 100644
--- a/usr.sbin/smtpd/ssl.c
+++ b/usr.sbin/smtpd/ssl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.c,v 1.5 2009/01/01 16:15:47 jacekm Exp $ */
+/* $OpenBSD: ssl.c,v 1.6 2009/01/29 13:00:12 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -49,11 +49,64 @@ void ssl_session_accept(int, short, void *);
void ssl_read(int, short, void *);
void ssl_write(int, short, void *);
int ssl_bufferevent_add(struct event *, int);
+void ssl_connect(int, short, void *);
+void ssl_client_init(struct session *);
extern void bufferevent_read_pressure_cb(struct evbuffer *, size_t,
size_t, void *);
void
+ssl_connect(int fd, short event, void *p)
+{
+ struct session *s = p;
+ int ret;
+ int retry_flag;
+ int ssl_err;
+
+ if (event == EV_TIMEOUT) {
+ log_debug("ssl_session_accept: session timed out");
+ session_destroy(s);
+ return;
+ }
+
+ ret = SSL_connect(s->s_ssl);
+ if (ret <= 0) {
+ ssl_err = SSL_get_error(s->s_ssl, ret);
+
+ switch (ssl_err) {
+ case SSL_ERROR_WANT_READ:
+ retry_flag = EV_READ;
+ goto retry;
+ case SSL_ERROR_WANT_WRITE:
+ retry_flag = EV_WRITE;
+ goto retry;
+ case SSL_ERROR_ZERO_RETURN:
+ case SSL_ERROR_SYSCALL:
+ if (ret == 0) {
+ log_debug("session destroy in MTA #1");
+ session_destroy(s);
+ return;
+ }
+ /* FALLTHROUGH */
+ default:
+ ssl_error("ssl_session_connect");
+ session_destroy(s);
+ return;
+ }
+ }
+
+ event_set(&s->s_bev->ev_read, s->s_fd, EV_READ, ssl_read, s->s_bev);
+ 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);
+ s->s_flags |= F_SECURE;
+ return;
+retry:
+ event_add(&s->s_ev, &s->s_tv);
+}
+
+void
ssl_read(int fd, short event, void *p)
{
struct bufferevent *bufev = p;
@@ -491,6 +544,37 @@ ssl_session_init(struct session *s)
}
void
+ssl_client_init(struct session *s)
+{
+ SSL_CTX *ctx;
+
+ log_debug("ssl_client_init: preparing SSL");
+ ctx = ssl_ctx_create();
+
+ s->s_ssl = SSL_new(ctx);
+ if (s->s_ssl == NULL)
+ goto err;
+
+ if (!SSL_set_ssl_method(s->s_ssl, SSLv23_client_method()))
+ goto err;
+ if (!SSL_set_fd(s->s_ssl, s->s_fd))
+ goto err;
+ SSL_set_connect_state(s->s_ssl);
+
+ s->s_tv.tv_sec = SMTPD_SESSION_TIMEOUT;
+ s->s_tv.tv_usec = 0;
+
+ event_set(&s->s_ev, s->s_fd, EV_WRITE|EV_TIMEOUT, ssl_connect, s);
+ event_add(&s->s_ev, &s->s_tv);
+ return;
+
+ err:
+ if (s->s_ssl != NULL)
+ SSL_free(s->s_ssl);
+ ssl_error("ssl_client_init");
+}
+
+void
ssl_session_destroy(struct session *s)
{
SSL_free(s->s_ssl);