1 /*-
2 * Copyright 2016 Vsevolod Stakhov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "config.h"
18 #include "libutil/util.h"
19 #include "libutil/hash.h"
20 #include "libserver/logger.h"
21 #include "libserver/cfg_file.h"
22 #include "ssl_util.h"
23 #include "unix-std.h"
24 #include "cryptobox.h"
25 #include "contrib/libottery/ottery.h"
26
27 #include <openssl/ssl.h>
28 #include <openssl/err.h>
29 #include <openssl/rand.h>
30 #include <openssl/conf.h>
31 #include <openssl/evp.h>
32 #include <openssl/engine.h>
33 #include <openssl/x509v3.h>
34
35 enum rspamd_ssl_state {
36 ssl_conn_reset = 0,
37 ssl_conn_init,
38 ssl_conn_connected,
39 ssl_next_read,
40 ssl_next_write,
41 ssl_next_shutdown,
42 };
43
44 enum rspamd_ssl_shutdown {
45 ssl_shut_default = 0,
46 ssl_shut_unclean,
47 };
48
49 struct rspamd_ssl_ctx {
50 SSL_CTX *s;
51 rspamd_lru_hash_t *sessions;
52 };
53
54 struct rspamd_ssl_connection {
55 gint fd;
56 enum rspamd_ssl_state state;
57 enum rspamd_ssl_shutdown shut;
58 gboolean verify_peer;
59 SSL *ssl;
60 struct rspamd_ssl_ctx *ssl_ctx;
61 gchar *hostname;
62 struct rspamd_io_ev *ev;
63 struct rspamd_io_ev *shut_ev;
64 struct ev_loop *event_loop;
65 rspamd_ssl_handler_t handler;
66 rspamd_ssl_error_handler_t err_handler;
67 gpointer handler_data;
68 gchar log_tag[8];
69 };
70
71 #define msg_debug_ssl(...) rspamd_conditional_debug_fast (NULL, NULL, \
72 rspamd_ssl_log_id, "ssl", conn->log_tag, \
73 G_STRFUNC, \
74 __VA_ARGS__)
75
76 static void rspamd_ssl_event_handler (gint fd, short what, gpointer ud);
77
INIT_LOG_MODULE(ssl)78 INIT_LOG_MODULE(ssl)
79
80 static GQuark
81 rspamd_ssl_quark (void)
82 {
83 return g_quark_from_static_string ("rspamd-ssl");
84 }
85
86 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
87 #ifndef X509_get_notBefore
88 #define X509_get_notBefore(x) X509_get0_notBefore(x)
89 #endif
90 #ifndef X509_get_notAfter
91 #define X509_get_notAfter(x) X509_get0_notAfter(x)
92 #endif
93 #ifndef ASN1_STRING_data
94 #define ASN1_STRING_data(x) ASN1_STRING_get0_data(x)
95 #endif
96 #endif
97
98 /* $OpenBSD: tls_verify.c,v 1.14 2015/09/29 10:17:04 deraadt Exp $ */
99 /*
100 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
101 *
102 * Permission to use, copy, modify, and distribute this software for any
103 * purpose with or without fee is hereby granted, provided that the above
104 * copyright notice and this permission notice appear in all copies.
105 *
106 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
107 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
108 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
109 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
110 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
111 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
112 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
113 */
114
115 static gboolean
rspamd_tls_match_name(const char * cert_name,const char * name)116 rspamd_tls_match_name (const char *cert_name, const char *name)
117 {
118 const char *cert_domain, *domain, *next_dot;
119
120 if (g_ascii_strcasecmp (cert_name, name) == 0) {
121 return TRUE;
122 }
123
124 /* Wildcard match? */
125 if (cert_name[0] == '*') {
126 /*
127 * Valid wildcards:
128 * - "*.domain.tld"
129 * - "*.sub.domain.tld"
130 * - etc.
131 * Reject "*.tld".
132 * No attempt to prevent the use of eg. "*.co.uk".
133 */
134 cert_domain = &cert_name[1];
135 /* Disallow "*" */
136 if (cert_domain[0] == '\0') {
137 return FALSE;
138 }
139
140 /* Disallow "*foo" */
141 if (cert_domain[0] != '.') {
142 return FALSE;
143 }
144 /* Disallow "*.." */
145 if (cert_domain[1] == '.') {
146 return FALSE;
147 }
148 next_dot = strchr (&cert_domain[1], '.');
149 /* Disallow "*.bar" */
150 if (next_dot == NULL) {
151 return FALSE;
152 }
153 /* Disallow "*.bar.." */
154 if (next_dot[1] == '.') {
155 return FALSE;
156 }
157
158 domain = strchr (name, '.');
159
160 /* No wildcard match against a name with no host part. */
161 if (name[0] == '.') {
162 return FALSE;
163 }
164 /* No wildcard match against a name with no domain part. */
165 if (domain == NULL || strlen (domain) == 1) {
166 return FALSE;
167 }
168
169 if (g_ascii_strcasecmp (cert_domain, domain) == 0) {
170 return TRUE;
171 }
172 }
173
174 return FALSE;
175 }
176
177 /* See RFC 5280 section 4.2.1.6 for SubjectAltName details. */
178 static gboolean
rspamd_tls_check_subject_altname(X509 * cert,const char * name)179 rspamd_tls_check_subject_altname (X509 *cert, const char *name)
180 {
181 STACK_OF(GENERAL_NAME) *altname_stack = NULL;
182 int addrlen, type;
183 int count, i;
184 union {
185 struct in_addr ip4;
186 struct in6_addr ip6;
187 } addrbuf;
188 gboolean ret = FALSE;
189
190 altname_stack = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);
191
192 if (altname_stack == NULL) {
193 return FALSE;
194 }
195
196 if (inet_pton (AF_INET, name, &addrbuf) == 1) {
197 type = GEN_IPADD;
198 addrlen = 4;
199 }
200 else if (inet_pton (AF_INET6, name, &addrbuf) == 1) {
201 type = GEN_IPADD;
202 addrlen = 16;
203 }
204 else {
205 type = GEN_DNS;
206 addrlen = 0;
207 }
208
209 count = sk_GENERAL_NAME_num (altname_stack);
210
211 for (i = 0; i < count; i++) {
212 GENERAL_NAME *altname;
213
214 altname = sk_GENERAL_NAME_value (altname_stack, i);
215
216 if (altname->type != type) {
217 continue;
218 }
219
220 if (type == GEN_DNS) {
221 const char *data;
222 int format, len;
223
224 format = ASN1_STRING_type (altname->d.dNSName);
225
226 if (format == V_ASN1_IA5STRING) {
227 data = (const char *)ASN1_STRING_data (altname->d.dNSName);
228 len = ASN1_STRING_length (altname->d.dNSName);
229
230 if (len < 0 || len != (gint)strlen (data)) {
231 ret = FALSE;
232 break;
233 }
234
235 /*
236 * Per RFC 5280 section 4.2.1.6:
237 * " " is a legal domain name, but that
238 * dNSName must be rejected.
239 */
240 if (strcmp (data, " ") == 0) {
241 ret = FALSE;
242 break;
243 }
244
245 if (rspamd_tls_match_name (data, name)) {
246 ret = TRUE;
247 break;
248 }
249 }
250 }
251 else if (type == GEN_IPADD) {
252 const char *data;
253 int datalen;
254
255 datalen = ASN1_STRING_length (altname->d.iPAddress);
256 data = (const char *)ASN1_STRING_data (altname->d.iPAddress);
257
258 if (datalen < 0) {
259 ret = FALSE;
260 break;
261 }
262
263 /*
264 * Per RFC 5280 section 4.2.1.6:
265 * IPv4 must use 4 octets and IPv6 must use 16 octets.
266 */
267 if (datalen == addrlen && memcmp (data, &addrbuf, addrlen) == 0) {
268 ret = TRUE;
269 break;
270 }
271 }
272 }
273
274 sk_GENERAL_NAME_pop_free (altname_stack, GENERAL_NAME_free);
275 return ret;
276 }
277
278 static gboolean
rspamd_tls_check_common_name(X509 * cert,const char * name)279 rspamd_tls_check_common_name (X509 *cert, const char *name)
280 {
281 X509_NAME *subject_name;
282 char *common_name = NULL;
283 union {
284 struct in_addr ip4;
285 struct in6_addr ip6;
286 } addrbuf;
287 int common_name_len;
288 gboolean ret = FALSE;
289
290 subject_name = X509_get_subject_name (cert);
291 if (subject_name == NULL) {
292 goto out;
293 }
294
295 common_name_len = X509_NAME_get_text_by_NID (subject_name, NID_commonName, NULL, 0);
296
297 if (common_name_len < 0) {
298 goto out;
299 }
300
301 common_name = g_malloc0 (common_name_len + 1);
302 X509_NAME_get_text_by_NID (subject_name, NID_commonName, common_name,
303 common_name_len + 1);
304
305 /* NUL bytes in CN? */
306 if (common_name_len != (gint)strlen (common_name)) {
307 goto out;
308 }
309
310 if (inet_pton (AF_INET, name, &addrbuf) == 1
311 || inet_pton (AF_INET6, name, &addrbuf) == 1) {
312 /*
313 * We don't want to attempt wildcard matching against IP
314 * addresses, so perform a simple comparison here.
315 */
316 if (strcmp (common_name, name) == 0) {
317 ret = TRUE;
318 }
319 else {
320 ret = FALSE;
321 }
322
323 goto out;
324 }
325
326 if (rspamd_tls_match_name (common_name, name)) {
327 ret = TRUE;
328 }
329
330 out:
331 g_free (common_name);
332
333 return ret;
334 }
335
336 static gboolean
rspamd_tls_check_name(X509 * cert,const char * name)337 rspamd_tls_check_name (X509 *cert, const char *name)
338 {
339 gboolean ret;
340
341 ret = rspamd_tls_check_subject_altname (cert, name);
342 if (ret) {
343 return ret;
344 }
345
346 return rspamd_tls_check_common_name (cert, name);
347 }
348
349 static gboolean
rspamd_ssl_peer_verify(struct rspamd_ssl_connection * c)350 rspamd_ssl_peer_verify (struct rspamd_ssl_connection *c)
351 {
352 X509 *server_cert;
353 glong ver_err;
354 GError *err = NULL;
355
356 ver_err = SSL_get_verify_result (c->ssl);
357
358 if (ver_err != X509_V_OK) {
359 g_set_error (&err, rspamd_ssl_quark (), 400, "certificate validation "
360 "failed: %s", X509_verify_cert_error_string (ver_err));
361 c->err_handler (c->handler_data, err);
362 g_error_free (err);
363
364 return FALSE;
365 }
366
367 /* Get server's certificate */
368 server_cert = SSL_get_peer_certificate (c->ssl);
369 if (server_cert == NULL) {
370 g_set_error (&err, rspamd_ssl_quark (), 401, "peer certificate is absent");
371 c->err_handler (c->handler_data, err);
372 g_error_free (err);
373
374 return FALSE;
375 }
376
377 if (c->hostname) {
378 if (!rspamd_tls_check_name (server_cert, c->hostname)) {
379 X509_free (server_cert);
380 g_set_error (&err, rspamd_ssl_quark (), 403, "peer certificate fails "
381 "hostname verification for %s", c->hostname);
382 c->err_handler (c->handler_data, err);
383 g_error_free (err);
384
385 return FALSE;
386 }
387 }
388
389 X509_free (server_cert);
390
391 return TRUE;
392 }
393
394 static void
rspamd_tls_set_error(gint retcode,const gchar * stage,GError ** err)395 rspamd_tls_set_error (gint retcode, const gchar *stage, GError **err)
396 {
397 GString *reason;
398 gchar buf[120];
399 gint err_code = 0;
400
401 reason = g_string_sized_new (sizeof (buf));
402
403 if (retcode == SSL_ERROR_SYSCALL) {
404 rspamd_printf_gstring (reason, "syscall fail: %s", strerror (errno));
405 err_code = 500;
406 }
407 else {
408 while ((err_code = ERR_get_error()) != 0) {
409 ERR_error_string (err_code, buf);
410 rspamd_printf_gstring (reason, "ssl error: %s,", buf);
411 }
412
413 err_code = 400;
414
415 if (reason->len > 0 && reason->str[reason->len - 1] == ',') {
416 reason->str[reason->len - 1] = '\0';
417 reason->len --;
418 }
419 }
420
421 g_set_error (err, rspamd_ssl_quark (), err_code,
422 "ssl %s error: %s", stage, reason->str);
423 g_string_free (reason, TRUE);
424 }
425
426 static void
rspamd_ssl_connection_dtor(struct rspamd_ssl_connection * conn)427 rspamd_ssl_connection_dtor (struct rspamd_ssl_connection *conn)
428 {
429 msg_debug_ssl ("closing SSL connection %p; %d sessions in the cache",
430 conn->ssl, rspamd_lru_hash_size (conn->ssl_ctx->sessions));
431 SSL_free (conn->ssl);
432
433 if (conn->hostname) {
434 g_free (conn->hostname);
435 }
436
437 if (conn->shut_ev) {
438 rspamd_ev_watcher_stop (conn->event_loop, conn->shut_ev);
439 g_free (conn->shut_ev);
440 }
441
442 close (conn->fd);
443 g_free (conn);
444 }
445
446 static void
rspamd_ssl_shutdown(struct rspamd_ssl_connection * conn)447 rspamd_ssl_shutdown (struct rspamd_ssl_connection *conn)
448 {
449 gint ret = 0, nret, retries;
450 static const gint max_retries = 5;
451
452 /*
453 * Fucking openssl...
454 * From the manual, 0 means: "The shutdown is not yet finished.
455 * Call SSL_shutdown() for a second time,
456 * if a bidirectional shutdown shall be performed.
457 * The output of SSL_get_error(3) may be misleading,
458 * as an erroneous SSL_ERROR_SYSCALL may be flagged
459 * even though no error occurred."
460 *
461 * What is `second`, what if `second` also returns 0?
462 * What a retarded behaviour!
463 */
464 for (retries = 0; retries < max_retries; retries ++) {
465 ret = SSL_shutdown (conn->ssl);
466
467 if (ret != 0) {
468 break;
469 }
470 }
471
472 if (ret == 1) {
473 /* All done */
474 msg_debug_ssl ("ssl shutdown: all done");
475 rspamd_ssl_connection_dtor (conn);
476 }
477 else if (ret < 0) {
478 short what;
479
480 nret = SSL_get_error (conn->ssl, ret);
481 conn->state = ssl_next_shutdown;
482
483 if (nret == SSL_ERROR_WANT_READ) {
484 msg_debug_ssl ("ssl shutdown: need read");
485 what = EV_READ;
486 }
487 else if (nret == SSL_ERROR_WANT_WRITE) {
488 msg_debug_ssl ("ssl shutdown: need write");
489 what = EV_WRITE;
490 }
491 else {
492 /* Cannot do anything else, fatal error */
493 GError *err = NULL;
494
495 rspamd_tls_set_error (nret, "final shutdown", &err);
496 msg_debug_ssl ("ssl shutdown: fatal error: %e; retries=%d; ret=%d",
497 err, retries, ret);
498 g_error_free (err);
499 rspamd_ssl_connection_dtor (conn);
500
501 return;
502 }
503
504 /* As we own fd, we can try to perform shutdown one more time */
505 /* BUGON: but we DO NOT own conn->ev, and it's a big issue */
506 static const ev_tstamp shutdown_time = 5.0;
507
508 if (conn->shut_ev == NULL) {
509 rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
510 conn->shut_ev = g_malloc0 (sizeof (*conn->shut_ev));
511 rspamd_ev_watcher_init (conn->shut_ev, conn->fd, what,
512 rspamd_ssl_event_handler, conn);
513 rspamd_ev_watcher_start (conn->event_loop, conn->shut_ev, shutdown_time);
514 /* XXX: can it be done safely ? */
515 conn->ev = conn->shut_ev;
516 }
517 else {
518 rspamd_ev_watcher_reschedule (conn->event_loop, conn->shut_ev, what);
519 }
520
521 conn->state = ssl_next_shutdown;
522 }
523 else if (ret == 0) {
524 /* What can we do here?? */
525 msg_debug_ssl ("ssl shutdown: openssl failed to initiate shutdown after "
526 "%d attempts!", max_retries);
527 rspamd_ssl_connection_dtor (conn);
528 }
529 }
530
531 static void
rspamd_ssl_event_handler(gint fd,short what,gpointer ud)532 rspamd_ssl_event_handler (gint fd, short what, gpointer ud)
533 {
534 struct rspamd_ssl_connection *conn = ud;
535 gint ret;
536 GError *err = NULL;
537
538 if (what == EV_TIMER) {
539 if (conn->state == ssl_next_shutdown) {
540 /* No way to restore, just terminate */
541 rspamd_ssl_connection_dtor (conn);
542 }
543 else {
544 conn->shut = ssl_shut_unclean;
545 rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
546 g_set_error (&err, rspamd_ssl_quark (), 408,
547 "ssl connection timed out");
548 conn->err_handler (conn->handler_data, err);
549 g_error_free (err);
550 }
551
552 return;
553 }
554
555 msg_debug_ssl ("ssl event; what=%d; c->state=%d", (int)what,
556 (int)conn->state);
557
558 switch (conn->state) {
559 case ssl_conn_init:
560 /* Continue connection */
561 ret = SSL_connect (conn->ssl);
562
563 if (ret == 1) {
564 rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
565 /* Verify certificate */
566 if ((!conn->verify_peer) || rspamd_ssl_peer_verify (conn)) {
567 msg_debug_ssl ("ssl connect: connected");
568 conn->state = ssl_conn_connected;
569 conn->handler (fd, EV_WRITE, conn->handler_data);
570 }
571 else {
572 return;
573 }
574 }
575 else {
576 ret = SSL_get_error (conn->ssl, ret);
577
578 if (ret == SSL_ERROR_WANT_READ) {
579 msg_debug_ssl ("ssl connect: need read");
580 what = EV_READ;
581 }
582 else if (ret == SSL_ERROR_WANT_WRITE) {
583 msg_debug_ssl ("ssl connect: need write");
584 what = EV_WRITE;
585 }
586 else {
587 rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
588 rspamd_tls_set_error (ret, "connect", &err);
589 conn->err_handler (conn->handler_data, err);
590 g_error_free (err);
591 return;
592 }
593
594 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, what);
595
596 }
597 break;
598 case ssl_next_read:
599 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, EV_READ);
600 conn->state = ssl_conn_connected;
601 conn->handler (fd, EV_READ, conn->handler_data);
602 break;
603 case ssl_next_write:
604 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, EV_WRITE);
605 conn->state = ssl_conn_connected;
606 conn->handler (fd, EV_WRITE, conn->handler_data);
607 break;
608 case ssl_conn_connected:
609 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, what);
610 conn->state = ssl_conn_connected;
611 conn->handler (fd, what, conn->handler_data);
612 break;
613 case ssl_next_shutdown:
614 rspamd_ssl_shutdown (conn);
615 break;
616 default:
617 rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
618 g_set_error (&err, rspamd_ssl_quark (), 500,
619 "ssl bad state error: %d", conn->state);
620 conn->err_handler (conn->handler_data, err);
621 g_error_free (err);
622 break;
623 }
624 }
625
626 struct rspamd_ssl_connection *
rspamd_ssl_connection_new(gpointer ssl_ctx,struct ev_loop * ev_base,gboolean verify_peer,const gchar * log_tag)627 rspamd_ssl_connection_new (gpointer ssl_ctx, struct ev_loop *ev_base,
628 gboolean verify_peer, const gchar *log_tag)
629 {
630 struct rspamd_ssl_connection *conn;
631 struct rspamd_ssl_ctx *ctx = (struct rspamd_ssl_ctx *)ssl_ctx;
632
633 g_assert (ssl_ctx != NULL);
634 conn = g_malloc0 (sizeof (*conn));
635 conn->ssl_ctx = ctx;
636 conn->event_loop = ev_base;
637 conn->verify_peer = verify_peer;
638
639 if (log_tag) {
640 rspamd_strlcpy (conn->log_tag, log_tag, sizeof (conn->log_tag));
641 }
642 else {
643 rspamd_random_hex (conn->log_tag, sizeof (log_tag) - 1);
644 conn->log_tag[sizeof (log_tag) - 1] = '\0';
645 }
646
647 return conn;
648 }
649
650
651 gboolean
rspamd_ssl_connect_fd(struct rspamd_ssl_connection * conn,gint fd,const gchar * hostname,struct rspamd_io_ev * ev,ev_tstamp timeout,rspamd_ssl_handler_t handler,rspamd_ssl_error_handler_t err_handler,gpointer handler_data)652 rspamd_ssl_connect_fd (struct rspamd_ssl_connection *conn, gint fd,
653 const gchar *hostname, struct rspamd_io_ev *ev, ev_tstamp timeout,
654 rspamd_ssl_handler_t handler, rspamd_ssl_error_handler_t err_handler,
655 gpointer handler_data)
656 {
657 gint ret;
658 SSL_SESSION *session = NULL;
659
660 g_assert (conn != NULL);
661
662 conn->ssl = SSL_new (conn->ssl_ctx->s);
663
664 if (hostname) {
665 session = rspamd_lru_hash_lookup (conn->ssl_ctx->sessions, hostname,
666 ev_now (conn->event_loop));
667
668 }
669
670 if (session) {
671 SSL_set_session (conn->ssl, session);
672 }
673
674 SSL_set_app_data (conn->ssl, conn);
675 msg_debug_ssl ("new ssl connection %p; session reused=%s",
676 conn->ssl, SSL_session_reused (conn->ssl) ? "true" : "false");
677
678 if (conn->state != ssl_conn_reset) {
679 return FALSE;
680 }
681
682 /* We dup fd to allow graceful closing */
683 gint nfd = dup (fd);
684
685 if (nfd == -1) {
686 return FALSE;
687 }
688
689 conn->fd = nfd;
690 conn->ev = ev;
691 conn->handler = handler;
692 conn->err_handler = err_handler;
693 conn->handler_data = handler_data;
694
695 if (SSL_set_fd (conn->ssl, conn->fd) != 1) {
696 close (conn->fd);
697
698 return FALSE;
699 }
700
701 if (hostname) {
702 conn->hostname = g_strdup (hostname);
703 #ifdef HAVE_SSL_TLSEXT_HOSTNAME
704 SSL_set_tlsext_host_name (conn->ssl, conn->hostname);
705 #endif
706 }
707
708 conn->state = ssl_conn_init;
709
710 ret = SSL_connect (conn->ssl);
711
712 if (ret == 1) {
713 conn->state = ssl_conn_connected;
714
715 msg_debug_ssl ("connected, start write event");
716 rspamd_ev_watcher_stop (conn->event_loop, ev);
717 rspamd_ev_watcher_init (ev, nfd, EV_WRITE, rspamd_ssl_event_handler, conn);
718 rspamd_ev_watcher_start (conn->event_loop, ev, timeout);
719 }
720 else {
721 ret = SSL_get_error (conn->ssl, ret);
722
723 if (ret == SSL_ERROR_WANT_READ) {
724 msg_debug_ssl ("not connected, want read");
725 }
726 else if (ret == SSL_ERROR_WANT_WRITE) {
727 msg_debug_ssl ("not connected, want write");
728 }
729 else {
730 GError *err = NULL;
731
732 conn->shut = ssl_shut_unclean;
733 rspamd_tls_set_error (ret, "initial connect", &err);
734 msg_debug_ssl ("not connected, fatal error %e", err);
735 g_error_free (err);
736
737
738 return FALSE;
739 }
740
741 rspamd_ev_watcher_stop (conn->event_loop, ev);
742 rspamd_ev_watcher_init (ev, nfd, EV_WRITE|EV_READ,
743 rspamd_ssl_event_handler, conn);
744 rspamd_ev_watcher_start (conn->event_loop, ev, timeout);
745 }
746
747 return TRUE;
748 }
749
750 gssize
rspamd_ssl_read(struct rspamd_ssl_connection * conn,gpointer buf,gsize buflen)751 rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
752 gsize buflen)
753 {
754 gint ret;
755 short what;
756 GError *err = NULL;
757
758 g_assert (conn != NULL);
759
760 if (conn->state != ssl_conn_connected && conn->state != ssl_next_read) {
761 errno = EINVAL;
762 g_set_error (&err, rspamd_ssl_quark (), 400,
763 "ssl state error: cannot read data");
764 conn->shut = ssl_shut_unclean;
765 conn->err_handler (conn->handler_data, err);
766 g_error_free (err);
767
768 return -1;
769 }
770
771 ret = SSL_read (conn->ssl, buf, buflen);
772 msg_debug_ssl ("ssl read: %d", ret);
773
774 if (ret > 0) {
775 conn->state = ssl_conn_connected;
776 return ret;
777 }
778 else if (ret == 0) {
779 ret = SSL_get_error (conn->ssl, ret);
780
781 if (ret == SSL_ERROR_ZERO_RETURN || ret == SSL_ERROR_SYSCALL) {
782 conn->state = ssl_conn_reset;
783 return 0;
784 }
785 else {
786 conn->shut = ssl_shut_unclean;
787 rspamd_tls_set_error (ret, "read", &err);
788 conn->err_handler (conn->handler_data, err);
789 g_error_free (err);
790 errno = EINVAL;
791
792 return -1;
793 }
794 }
795 else {
796 ret = SSL_get_error (conn->ssl, ret);
797 conn->state = ssl_next_read;
798 what = 0;
799
800 if (ret == SSL_ERROR_WANT_READ) {
801 msg_debug_ssl ("ssl read: need read");
802 what |= EV_READ;
803 }
804 else if (ret == SSL_ERROR_WANT_WRITE) {
805 msg_debug_ssl ("ssl read: need write");
806 what |= EV_WRITE;
807 }
808 else {
809 conn->shut = ssl_shut_unclean;
810 rspamd_tls_set_error (ret, "read", &err);
811 conn->err_handler (conn->handler_data, err);
812 g_error_free (err);
813 errno = EINVAL;
814
815 return -1;
816 }
817
818 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, what);
819 errno = EAGAIN;
820 }
821
822 return -1;
823 }
824
825 gssize
rspamd_ssl_write(struct rspamd_ssl_connection * conn,gconstpointer buf,gsize buflen)826 rspamd_ssl_write (struct rspamd_ssl_connection *conn, gconstpointer buf,
827 gsize buflen)
828 {
829 gint ret;
830 short what;
831 GError *err = NULL;
832
833 g_assert (conn != NULL);
834
835 if (conn->state != ssl_conn_connected && conn->state != ssl_next_write) {
836 errno = EINVAL;
837 return -1;
838 }
839
840 ret = SSL_write (conn->ssl, buf, buflen);
841 msg_debug_ssl ("ssl write: ret=%d, buflen=%z", ret, buflen);
842
843 if (ret > 0) {
844 conn->state = ssl_conn_connected;
845 return ret;
846 }
847 else if (ret == 0) {
848 ret = SSL_get_error (conn->ssl, ret);
849
850 if (ret == SSL_ERROR_ZERO_RETURN) {
851 rspamd_tls_set_error (ret, "write", &err);
852 conn->err_handler (conn->handler_data, err);
853 g_error_free (err);
854 errno = ECONNRESET;
855 conn->state = ssl_conn_reset;
856
857 return -1;
858 }
859 else {
860 conn->shut = ssl_shut_unclean;
861 rspamd_tls_set_error (ret, "write", &err);
862 conn->err_handler (conn->handler_data, err);
863 g_error_free (err);
864 errno = EINVAL;
865
866 return -1;
867 }
868 }
869 else {
870 ret = SSL_get_error (conn->ssl, ret);
871 conn->state = ssl_next_write;
872
873 if (ret == SSL_ERROR_WANT_READ) {
874 msg_debug_ssl ("ssl write: need read");
875 what = EV_READ;
876 }
877 else if (ret == SSL_ERROR_WANT_WRITE) {
878 msg_debug_ssl ("ssl write: need write");
879 what = EV_WRITE;
880 }
881 else {
882 conn->shut = ssl_shut_unclean;
883 rspamd_tls_set_error (ret, "write", &err);
884 conn->err_handler (conn->handler_data, err);
885 g_error_free (err);
886 errno = EINVAL;
887
888 return -1;
889 }
890
891 rspamd_ev_watcher_reschedule (conn->event_loop, conn->ev, what);
892 errno = EAGAIN;
893 }
894
895 return -1;
896 }
897
898 gssize
rspamd_ssl_writev(struct rspamd_ssl_connection * conn,struct iovec * iov,gsize iovlen)899 rspamd_ssl_writev (struct rspamd_ssl_connection *conn, struct iovec *iov,
900 gsize iovlen)
901 {
902 /*
903 * Static is needed to avoid issue:
904 * https://github.com/openssl/openssl/issues/6865
905 */
906 static guchar ssl_buf[16384];
907 guchar *p;
908 struct iovec *cur;
909 gsize i, remain;
910
911 remain = sizeof (ssl_buf);
912 p = ssl_buf;
913
914 for (i = 0; i < iovlen; i ++) {
915 cur = &iov[i];
916
917 if (cur->iov_len > 0) {
918 if (remain >= cur->iov_len) {
919 memcpy (p, cur->iov_base, cur->iov_len);
920 p += cur->iov_len;
921 remain -= cur->iov_len;
922 }
923 else {
924 memcpy (p, cur->iov_base, remain);
925 p += remain;
926 remain = 0;
927 break;
928 }
929 }
930 }
931
932 return rspamd_ssl_write (conn, ssl_buf, p - ssl_buf);
933 }
934
935 /**
936 * Removes connection data
937 * @param conn
938 */
939 void
rspamd_ssl_connection_free(struct rspamd_ssl_connection * conn)940 rspamd_ssl_connection_free (struct rspamd_ssl_connection *conn)
941 {
942 if (conn) {
943 if (conn->shut == ssl_shut_unclean) {
944 /* Ignore return result and close socket */
945 msg_debug_ssl ("unclean shutdown");
946 SSL_set_quiet_shutdown (conn->ssl, 1);
947 (void)SSL_shutdown (conn->ssl);
948 rspamd_ssl_connection_dtor (conn);
949 }
950 else {
951 msg_debug_ssl ("normal shutdown");
952 rspamd_ssl_shutdown (conn);
953 }
954 }
955 }
956
957 static int
rspamd_ssl_new_client_session(SSL * ssl,SSL_SESSION * sess)958 rspamd_ssl_new_client_session (SSL *ssl, SSL_SESSION *sess)
959 {
960 struct rspamd_ssl_connection *conn;
961
962 conn = SSL_get_app_data (ssl);
963
964 if (conn->hostname) {
965 rspamd_lru_hash_insert (conn->ssl_ctx->sessions,
966 g_strdup (conn->hostname), SSL_get1_session (ssl),
967 ev_now (conn->event_loop), SSL_CTX_get_timeout (conn->ssl_ctx->s));
968 msg_debug_ssl ("saved new session for %s: %p", conn->hostname, conn);
969 }
970
971 return 0;
972 }
973
974 static struct rspamd_ssl_ctx *
rspamd_init_ssl_ctx_common(void)975 rspamd_init_ssl_ctx_common (void)
976 {
977 struct rspamd_ssl_ctx *ret;
978 SSL_CTX *ssl_ctx;
979 gint ssl_options;
980 static const guint client_cache_size = 1024;
981
982 rspamd_openssl_maybe_init ();
983
984 ret = g_malloc0 (sizeof (*ret));
985 ssl_options = SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
986 ssl_ctx = SSL_CTX_new (SSLv23_method ());
987
988 #ifdef SSL_OP_NO_COMPRESSION
989 ssl_options |= SSL_OP_NO_COMPRESSION;
990 #elif OPENSSL_VERSION_NUMBER >= 0x00908000L
991 sk_SSL_COMP_zero (SSL_COMP_get_compression_methods ());
992 #endif
993
994 SSL_CTX_set_options (ssl_ctx, ssl_options);
995
996 #ifdef TLS1_3_VERSION
997 SSL_CTX_set_min_proto_version (ssl_ctx, 0);
998 SSL_CTX_set_max_proto_version (ssl_ctx, TLS1_3_VERSION);
999 #endif
1000
1001 #ifdef SSL_SESS_CACHE_CLIENT
1002 SSL_CTX_set_session_cache_mode (ssl_ctx, SSL_SESS_CACHE_CLIENT
1003 | SSL_SESS_CACHE_NO_INTERNAL_STORE);
1004 #endif
1005
1006 ret->s = ssl_ctx;
1007 ret->sessions = rspamd_lru_hash_new_full (client_cache_size,
1008 g_free, (GDestroyNotify)SSL_SESSION_free, rspamd_str_hash,
1009 rspamd_str_equal);
1010 SSL_CTX_set_app_data (ssl_ctx, ret);
1011 SSL_CTX_sess_set_new_cb (ssl_ctx, rspamd_ssl_new_client_session);
1012
1013 return ret;
1014 }
1015
1016 gpointer
rspamd_init_ssl_ctx(void)1017 rspamd_init_ssl_ctx (void)
1018 {
1019 struct rspamd_ssl_ctx *ssl_ctx = rspamd_init_ssl_ctx_common ();
1020
1021 SSL_CTX_set_verify (ssl_ctx->s, SSL_VERIFY_PEER, NULL);
1022 SSL_CTX_set_verify_depth (ssl_ctx->s, 4);
1023
1024 return ssl_ctx;
1025 }
1026
rspamd_init_ssl_ctx_noverify(void)1027 gpointer rspamd_init_ssl_ctx_noverify (void)
1028 {
1029 struct rspamd_ssl_ctx *ssl_ctx_noverify = rspamd_init_ssl_ctx_common ();
1030
1031 SSL_CTX_set_verify (ssl_ctx_noverify->s, SSL_VERIFY_NONE, NULL);
1032
1033 return ssl_ctx_noverify;
1034 }
1035
1036 void
rspamd_openssl_maybe_init(void)1037 rspamd_openssl_maybe_init (void)
1038 {
1039 static gboolean openssl_initialized = FALSE;
1040
1041 if (!openssl_initialized) {
1042 ERR_load_crypto_strings ();
1043 SSL_load_error_strings ();
1044
1045 OpenSSL_add_all_algorithms ();
1046 OpenSSL_add_all_digests ();
1047 OpenSSL_add_all_ciphers ();
1048
1049 #if OPENSSL_VERSION_NUMBER >= 0x1000104fL && !defined(LIBRESSL_VERSION_NUMBER)
1050 ENGINE_load_builtin_engines ();
1051 #endif
1052 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
1053 SSL_library_init ();
1054 #else
1055 OPENSSL_init_ssl (0, NULL);
1056 #endif
1057
1058 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
1059 OPENSSL_config (NULL);
1060 #endif
1061 if (RAND_status () == 0) {
1062 guchar seed[128];
1063
1064 /* Try to use ottery to seed rand */
1065 ottery_rand_bytes (seed, sizeof (seed));
1066 RAND_seed (seed, sizeof (seed));
1067 rspamd_explicit_memzero (seed, sizeof (seed));
1068 }
1069
1070 openssl_initialized = TRUE;
1071 }
1072 }
1073
1074 void
rspamd_ssl_ctx_config(struct rspamd_config * cfg,gpointer ssl_ctx)1075 rspamd_ssl_ctx_config (struct rspamd_config *cfg, gpointer ssl_ctx)
1076 {
1077 struct rspamd_ssl_ctx *ctx = (struct rspamd_ssl_ctx *)ssl_ctx;
1078 static const char default_secure_ciphers[] = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
1079
1080 if (cfg->ssl_ca_path) {
1081 if (SSL_CTX_load_verify_locations (ctx->s, cfg->ssl_ca_path,
1082 NULL) != 1) {
1083 msg_err_config ("cannot load CA certs from %s: %s",
1084 cfg->ssl_ca_path,
1085 ERR_error_string (ERR_get_error (), NULL));
1086 }
1087 }
1088 else {
1089 msg_debug_config ("ssl_ca_path is not set, using default CA path");
1090 SSL_CTX_set_default_verify_paths (ctx->s);
1091 }
1092
1093 if (cfg->ssl_ciphers) {
1094 if (SSL_CTX_set_cipher_list (ctx->s, cfg->ssl_ciphers) != 1) {
1095 msg_err_config (
1096 "cannot set ciphers set to %s: %s; fallback to %s",
1097 cfg->ssl_ciphers,
1098 ERR_error_string (ERR_get_error (), NULL),
1099 default_secure_ciphers);
1100 /* Default settings */
1101 SSL_CTX_set_cipher_list (ctx->s, default_secure_ciphers);
1102 }
1103 }
1104 }
1105
1106 void
rspamd_ssl_ctx_free(gpointer ssl_ctx)1107 rspamd_ssl_ctx_free (gpointer ssl_ctx)
1108 {
1109 struct rspamd_ssl_ctx *ctx = (struct rspamd_ssl_ctx *)ssl_ctx;
1110
1111 rspamd_lru_hash_destroy (ctx->sessions);
1112 SSL_CTX_free (ctx->s);
1113 g_free (ssl_ctx);
1114 }