xref: /openbsd-src/usr.sbin/smtpd/ssl.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: ssl.c,v 1.11 2009/03/15 19:32:11 gilles Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
5  * Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/queue.h>
22 #include <sys/tree.h>
23 #include <sys/param.h>
24 #include <sys/socket.h>
25 #include <sys/stat.h>
26 #include <sys/time.h>
27 
28 #include <ctype.h>
29 #include <event.h>
30 #include <fcntl.h>
31 #include <pwd.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #include <openssl/ssl.h>
38 #include <openssl/engine.h>
39 #include <openssl/err.h>
40 
41 #include "smtpd.h"
42 
43 #define SSL_CIPHERS	"HIGH:!ADH"
44 
45 void	 ssl_error(const char *);
46 char	*ssl_load_file(const char *, off_t *);
47 SSL_CTX	*ssl_ctx_create(void);
48 void	 ssl_session_accept(int, short, void *);
49 void	 ssl_read(int, short, void *);
50 void	 ssl_write(int, short, void *);
51 int	 ssl_bufferevent_add(struct event *, int);
52 void	 ssl_connect(int, short, void *);
53 void	 ssl_client_init(struct session *);
54 
55 extern void	bufferevent_read_pressure_cb(struct evbuffer *, size_t,
56 		    size_t, void *);
57 
58 extern struct s_session	s_smtp;
59 
60 void
61 ssl_connect(int fd, short event, void *p)
62 {
63 	struct session	*s = p;
64 	int		 ret;
65 	int		 retry_flag;
66 	int		 ssl_err;
67 
68 	if (event == EV_TIMEOUT) {
69 		log_debug("ssl_session_accept: session timed out");
70 		session_destroy(s);
71 		return;
72 	}
73 
74 	ret = SSL_connect(s->s_ssl);
75 	if (ret <= 0) {
76 		ssl_err = SSL_get_error(s->s_ssl, ret);
77 
78 		switch (ssl_err) {
79 		case SSL_ERROR_WANT_READ:
80 			retry_flag = EV_READ;
81 			goto retry;
82 		case SSL_ERROR_WANT_WRITE:
83 			retry_flag = EV_WRITE;
84 			goto retry;
85 		case SSL_ERROR_ZERO_RETURN:
86 		case SSL_ERROR_SYSCALL:
87 			if (ret == 0) {
88 				log_debug("session destroy in MTA #1");
89 				session_destroy(s);
90 				return;
91 			}
92 			/* FALLTHROUGH */
93 		default:
94 			ssl_error("ssl_session_connect");
95 			session_destroy(s);
96 			return;
97 		}
98 	}
99 
100 	event_set(&s->s_bev->ev_read, s->s_fd, EV_READ, ssl_read, s->s_bev);
101 	event_set(&s->s_bev->ev_write, s->s_fd, EV_WRITE, ssl_write, s->s_bev);
102 
103 	log_info("ssl_connect: connected to remote ssl server");
104 	bufferevent_enable(s->s_bev, EV_READ|EV_WRITE);
105 	s->s_flags |= F_SECURE;
106 
107 	if (s->s_flags & F_PEERHASTLS) {
108 		session_respond(s, "EHLO %s", s->s_env->sc_hostname);
109 	}
110 
111 	return;
112 retry:
113 	event_add(&s->s_ev, &s->s_tv);
114 }
115 
116 void
117 ssl_read(int fd, short event, void *p)
118 {
119 	struct bufferevent	*bufev = p;
120 	struct session		*s = bufev->cbarg;
121 	int			 ret;
122 	int			 ssl_err;
123 	short			 what;
124 	size_t			 len;
125 	char			 rbuf[READ_BUF_SIZE];
126 	int			 howmuch = READ_BUF_SIZE;
127 
128 	what = EVBUFFER_READ;
129 	ret = ssl_err = 0;
130 
131 	if (event == EV_TIMEOUT) {
132 		what |= EVBUFFER_TIMEOUT;
133 		goto err;
134 	}
135 
136 	if (bufev->wm_read.high != 0)
137 		howmuch = MIN(sizeof(rbuf), bufev->wm_read.high);
138 
139 	ret = SSL_read(s->s_ssl, rbuf, howmuch);
140 	if (ret <= 0) {
141 		ssl_err = SSL_get_error(s->s_ssl, ret);
142 
143 		switch (ssl_err) {
144 		case SSL_ERROR_WANT_READ:
145 			goto retry;
146 		case SSL_ERROR_WANT_WRITE:
147 			goto retry;
148 		default:
149 			if (ret == 0)
150 				what |= EVBUFFER_EOF;
151 			else {
152 				ssl_error("ssl_read");
153 				what |= EVBUFFER_ERROR;
154 			}
155 			goto err;
156 		}
157 	}
158 
159 	if (evbuffer_add(bufev->input, rbuf, ret) == -1) {
160 		what |= EVBUFFER_ERROR;
161 		goto err;
162 	}
163 
164 	ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
165 
166 	len = EVBUFFER_LENGTH(bufev->input);
167 	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
168 		return;
169 	if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
170 		struct evbuffer *buf = bufev->input;
171 		event_del(&bufev->ev_read);
172 		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
173 		return;
174 	}
175 
176 	if (bufev->readcb != NULL)
177 		(*bufev->readcb)(bufev, bufev->cbarg);
178 	return;
179 
180 retry:
181 	ssl_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
182 	return;
183 
184 err:
185 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
186 }
187 
188 
189 void
190 ssl_write(int fd, short event, void *p)
191 {
192 	struct bufferevent	*bufev = p;
193 	struct session		*s = bufev->cbarg;
194 	int			 ret;
195 	int			 ssl_err;
196 	short			 what;
197 
198 	ret = 0;
199 	what = EVBUFFER_WRITE;
200 
201 	if (event == EV_TIMEOUT) {
202 		what |= EV_TIMEOUT;
203 		goto err;
204 	}
205 
206 	if (EVBUFFER_LENGTH(bufev->output)) {
207 		if (s->s_buf == NULL) {
208 			s->s_buflen = EVBUFFER_LENGTH(bufev->output);
209 			if ((s->s_buf = malloc(s->s_buflen)) == NULL) {
210 				what |= EVBUFFER_ERROR;
211 				goto err;
212 			}
213 			memcpy(s->s_buf, EVBUFFER_DATA(bufev->output),
214 			    s->s_buflen);
215 		}
216 
217 		ret = SSL_write(s->s_ssl, s->s_buf, s->s_buflen);
218 		if (ret <= 0) {
219 			ssl_err = SSL_get_error(s->s_ssl, ret);
220 
221 			switch (ssl_err) {
222 			case SSL_ERROR_WANT_READ:
223 				goto retry;
224 			case SSL_ERROR_WANT_WRITE:
225 				goto retry;
226 			default:
227 				if (ret == 0)
228 					what |= EVBUFFER_EOF;
229 				else {
230 					ssl_error("ssl_write");
231 					what |= EVBUFFER_ERROR;
232 				}
233 				goto err;
234 			}
235 		}
236 		evbuffer_drain(bufev->output, ret);
237 	}
238 	if (s->s_buf != NULL) {
239 		free(s->s_buf);
240 		s->s_buf = NULL;
241 		s->s_buflen = 0;
242 	}
243 	if (EVBUFFER_LENGTH(bufev->output) != 0)
244 		ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
245 
246 	if (bufev->writecb != NULL &&
247 	    EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
248 		(*bufev->writecb)(bufev, bufev->cbarg);
249 	return;
250 
251 retry:
252 	if (s->s_buflen != 0)
253 		ssl_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
254 	return;
255 
256 err:
257 	if (s->s_buf != NULL) {
258 		free(s->s_buf);
259 		s->s_buf = NULL;
260 		s->s_buflen = 0;
261 	}
262 	(*bufev->errorcb)(bufev, what, bufev->cbarg);
263 }
264 
265 int
266 ssl_bufferevent_add(struct event *ev, int timeout)
267 {
268 	struct timeval	 tv;
269 	struct timeval	*ptv = NULL;
270 
271 	if (timeout) {
272 		timerclear(&tv);
273 		tv.tv_sec = timeout;
274 		ptv = &tv;
275 	}
276 
277 	return (event_add(ev, ptv));
278 }
279 
280 int
281 ssl_cmp(struct ssl *s1, struct ssl *s2)
282 {
283 	return (strcmp(s1->ssl_name, s2->ssl_name));
284 }
285 
286 SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp);
287 
288 char *
289 ssl_load_file(const char *name, off_t *len)
290 {
291 	struct stat	 st;
292 	off_t		 size;
293 	char		*buf = NULL;
294 	int		 fd;
295 
296 	if ((fd = open(name, O_RDONLY)) == -1)
297 		return (NULL);
298 	if (fstat(fd, &st) != 0)
299 		goto fail;
300 	size = st.st_size;
301 	if ((buf = calloc(1, size + 1)) == NULL)
302 		goto fail;
303 	if (read(fd, buf, size) != size)
304 		goto fail;
305 	close(fd);
306 
307 	*len = size + 1;
308 	return (buf);
309 
310 fail:
311 	if (buf != NULL)
312 		free(buf);
313 	close(fd);
314 	return (NULL);
315 }
316 
317 SSL_CTX *
318 ssl_ctx_create(void)
319 {
320 	SSL_CTX	*ctx;
321 
322 	ctx = SSL_CTX_new(SSLv23_method());
323 	if (ctx == NULL) {
324 		ssl_error("ssl_ctx_create");
325 		fatal("ssl_ctx_create: could not create SSL context");
326 	}
327 
328 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
329 	SSL_CTX_set_timeout(ctx, SMTPD_SESSION_TIMEOUT);
330 	SSL_CTX_set_options(ctx, SSL_OP_ALL);
331 	SSL_CTX_set_options(ctx,
332 	    SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
333 
334 	if (!SSL_CTX_set_cipher_list(ctx, SSL_CIPHERS)) {
335 		ssl_error("ssl_ctx_create");
336 		fatal("ssl_ctx_create: could not set cipher list");
337 	}
338 	return (ctx);
339 }
340 
341 int
342 ssl_load_certfile(struct smtpd *env, const char *name)
343 {
344 	struct ssl	*s;
345 	struct ssl	 key;
346 	char		 certfile[PATH_MAX];
347 
348 	if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name))
349 	    >= sizeof(key.ssl_name)) {
350 		log_warn("ssl_load_certfile: certificate name truncated");
351 		return -1;
352 	}
353 
354 	s = SPLAY_FIND(ssltree, &env->sc_ssl, &key);
355 	if (s != NULL)
356 		return 0;
357 
358 	if ((s = calloc(1, sizeof(*s))) == NULL)
359 		fatal(NULL);
360 
361 	(void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name));
362 
363 	if (! bsnprintf(certfile, sizeof(certfile),
364 		"/etc/mail/certs/%s.crt", name)) {
365 		free(s);
366 		return (-1);
367 	}
368 
369 	if ((s->ssl_cert = ssl_load_file(certfile, &s->ssl_cert_len)) == NULL) {
370 		free(s);
371 		return (-1);
372 	}
373 
374 	if (! bsnprintf(certfile, sizeof(certfile),
375 		"/etc/mail/certs/%s.key", name)) {
376 		free(s->ssl_cert);
377 		free(s);
378 		return -1;
379 	}
380 
381 	if ((s->ssl_key = ssl_load_file(certfile, &s->ssl_key_len)) == NULL) {
382 		free(s->ssl_cert);
383 		free(s);
384 		return (-1);
385 	}
386 
387 	if (s->ssl_cert == NULL || s->ssl_key == NULL)
388 		fatal("invalid certificates");
389 
390 	SPLAY_INSERT(ssltree, &env->sc_ssl, s);
391 
392 	return (0);
393 }
394 
395 void
396 ssl_init(void)
397 {
398 	SSL_library_init();
399 	SSL_load_error_strings();
400 
401 	OpenSSL_add_all_algorithms();
402 
403 	/* Init hardware crypto engines. */
404 	ENGINE_load_builtin_engines();
405 	ENGINE_register_all_complete();
406 }
407 
408 void
409 ssl_setup(struct smtpd *env, struct listener *l)
410 {
411 	struct ssl	key;
412 
413 	if (!(l->flags & F_SSL))
414 		return;
415 
416 	if (strlcpy(key.ssl_name, l->ssl_cert_name, sizeof(key.ssl_name))
417 	    >= sizeof(key.ssl_name))
418 		fatal("ssl_setup: certificate name truncated");
419 
420 	if ((l->ssl = SPLAY_FIND(ssltree, &env->sc_ssl, &key)) == NULL)
421 		fatal("ssl_setup: certificate tree corrupted");
422 
423 	l->ssl_ctx = ssl_ctx_create();
424 
425 	if (!ssl_ctx_use_certificate_chain(l->ssl_ctx,
426 	    l->ssl->ssl_cert, l->ssl->ssl_cert_len))
427 		goto err;
428 	if (!ssl_ctx_use_private_key(l->ssl_ctx,
429 	    l->ssl->ssl_key, l->ssl->ssl_key_len))
430 		goto err;
431 
432 	if (!SSL_CTX_check_private_key(l->ssl_ctx))
433 		goto err;
434 	if (!SSL_CTX_set_session_id_context(l->ssl_ctx,
435 		(const unsigned char *)l->ssl_cert_name, strlen(l->ssl_cert_name) + 1))
436 		goto err;
437 
438 	log_debug("ssl_setup: ssl setup finished for listener: %p", l);
439 	return;
440 
441 err:
442 	if (l->ssl_ctx != NULL)
443 		SSL_CTX_free(l->ssl_ctx);
444 	ssl_error("ssl_setup");
445 	fatal("ssl_setup: cannot set SSL up");
446 	return;
447 }
448 
449 void
450 ssl_error(const char *where)
451 {
452 	unsigned long	code;
453 	char		errbuf[128];
454 	extern int	debug;
455 
456 	if (!debug)
457 		return;
458 	for (; (code = ERR_get_error()) != 0 ;) {
459 		ERR_error_string_n(code, errbuf, sizeof(errbuf));
460 		log_debug("SSL library error: %s: %s", where, errbuf);
461 	}
462 }
463 
464 void
465 ssl_session_accept(int fd, short event, void *p)
466 {
467 	struct session	*s = p;
468 	int		 ret;
469 	int		 retry_flag;
470 	int		 ssl_err;
471 
472 	if (event == EV_TIMEOUT) {
473 		log_debug("ssl_session_accept: session timed out");
474 		session_destroy(s);
475 		return;
476 	}
477 
478 	retry_flag = ssl_err = 0;
479 
480 	log_debug("ssl_session_accept: accepting client");
481 	ret = SSL_accept(s->s_ssl);
482 	if (ret <= 0) {
483 		ssl_err = SSL_get_error(s->s_ssl, ret);
484 
485 		switch (ssl_err) {
486 		case SSL_ERROR_WANT_READ:
487 			retry_flag = EV_READ;
488 			goto retry;
489 		case SSL_ERROR_WANT_WRITE:
490 			retry_flag = EV_WRITE;
491 			goto retry;
492 		case SSL_ERROR_ZERO_RETURN:
493 		case SSL_ERROR_SYSCALL:
494 			if (ret == 0) {
495 				session_destroy(s);
496 				return;
497 			}
498 			/* FALLTHROUGH */
499 		default:
500 			ssl_error("ssl_session_accept");
501 			session_destroy(s);
502 			return;
503 		}
504 	}
505 
506 	event_set(&s->s_bev->ev_read, s->s_fd, EV_READ, ssl_read, s->s_bev);
507 	event_set(&s->s_bev->ev_write, s->s_fd, EV_WRITE, ssl_write, s->s_bev);
508 
509 	log_info("ssl_session_accept: accepted ssl client");
510 	s->s_flags |= F_SECURE;
511 
512 	if (s->s_l->flags & F_SSMTP) {
513 		s_smtp.ssmtp++;
514 		s_smtp.ssmtp_active++;
515 	}
516 	if (s->s_l->flags & F_STARTTLS) {
517 		s_smtp.starttls++;
518 		s_smtp.starttls_active++;
519 	}
520 
521 	session_pickup(s, NULL);
522 	return;
523 retry:
524 	event_add(&s->s_ev, &s->s_tv);
525 }
526 
527 void
528 ssl_session_init(struct session *s)
529 {
530 	struct listener	*l;
531 	SSL             *ssl;
532 
533 	l = s->s_l;
534 
535 	if (!(l->flags & F_SSL))
536 		return;
537 
538 	log_debug("ssl_session_init: switching to SSL");
539 	ssl = SSL_new(l->ssl_ctx);
540 	if (ssl == NULL)
541 		goto err;
542 
543 	if (!SSL_set_ssl_method(ssl, SSLv23_server_method()))
544 		goto err;
545 	if (!SSL_set_fd(ssl, s->s_fd))
546 		goto err;
547 	SSL_set_accept_state(ssl);
548 
549 	s->s_ssl = ssl;
550 
551 	s->s_tv.tv_sec = SMTPD_SESSION_TIMEOUT;
552 	s->s_tv.tv_usec = 0;
553 	event_set(&s->s_ev, s->s_fd, EV_READ|EV_TIMEOUT, ssl_session_accept, s);
554 	event_add(&s->s_ev, &s->s_tv);
555 	return;
556 
557  err:
558 	if (ssl != NULL)
559 		SSL_free(ssl);
560 	ssl_error("ssl_session_init");
561 }
562 
563 void
564 ssl_client_init(struct session *s)
565 {
566 	SSL_CTX		*ctx;
567 
568 	log_debug("ssl_client_init: preparing SSL");
569 	ctx = ssl_ctx_create();
570 
571 	s->s_ssl = SSL_new(ctx);
572 	if (s->s_ssl == NULL)
573 		goto err;
574 
575 	if (!SSL_set_ssl_method(s->s_ssl, SSLv23_client_method()))
576 		goto err;
577 	if (!SSL_set_fd(s->s_ssl, s->s_fd))
578 		goto err;
579 	SSL_set_connect_state(s->s_ssl);
580 
581 	s->s_tv.tv_sec = SMTPD_SESSION_TIMEOUT;
582 	s->s_tv.tv_usec = 0;
583 
584 	event_set(&s->s_ev, s->s_fd, EV_WRITE|EV_TIMEOUT, ssl_connect, s);
585 	event_add(&s->s_ev, &s->s_tv);
586 	return;
587 
588  err:
589 	if (s->s_ssl != NULL)
590 		SSL_free(s->s_ssl);
591 	ssl_error("ssl_client_init");
592 }
593 
594 void
595 ssl_session_destroy(struct session *s)
596 {
597 	SSL_free(s->s_ssl);
598 
599 	if (s->s_l == NULL) {
600 		/* called from mta */
601 		return;
602 	}
603 
604 	if (s->s_l->flags & F_SSMTP) {
605 		if (s->s_flags & F_SECURE)
606 			s_smtp.ssmtp_active--;
607 	}
608 	if (s->s_l->flags & F_STARTTLS) {
609 		if (s->s_flags & F_SECURE)
610 			s_smtp.starttls_active--;
611 	}
612 }
613