blob: b51b834bca7f815993ce4e5ba1c7596b67ce9f44 [file] [log] [blame]
Christopher Wileye8679812015-07-01 13:36:18 -07001/*
2 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
Narayan Kamathfc74cb42017-09-13 12:53:52 +010027// Get rid of OSX 10.7 and greater deprecation warnings.
28#if defined(__APPLE__) && defined(__clang__)
29#pragma clang diagnostic ignored "-Wdeprecated-declarations"
30#endif
Elliott Hughes2a572d12017-08-07 14:18:18 -070031
Josh Gao83a0c9c2017-08-10 12:30:25 -070032#include "event2/event-config.h"
Narayan Kamathfc74cb42017-09-13 12:53:52 +010033#include "evconfig-private.h"
Josh Gao83a0c9c2017-08-10 12:30:25 -070034
Narayan Kamathfc74cb42017-09-13 12:53:52 +010035#include <sys/types.h>
36
37#ifdef EVENT__HAVE_SYS_TIME_H
Christopher Wileye8679812015-07-01 13:36:18 -070038#include <sys/time.h>
39#endif
40
41#include <errno.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010045#ifdef EVENT__HAVE_STDARG_H
Christopher Wileye8679812015-07-01 13:36:18 -070046#include <stdarg.h>
47#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010048#ifdef EVENT__HAVE_UNISTD_H
Christopher Wileye8679812015-07-01 13:36:18 -070049#include <unistd.h>
50#endif
51
Narayan Kamathfc74cb42017-09-13 12:53:52 +010052#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -070053#include <winsock2.h>
54#endif
55
56#include "event2/bufferevent.h"
57#include "event2/bufferevent_struct.h"
58#include "event2/bufferevent_ssl.h"
59#include "event2/buffer.h"
60#include "event2/event.h"
61
62#include "mm-internal.h"
63#include "bufferevent-internal.h"
64#include "log-internal.h"
65
Christopher Wileye8679812015-07-01 13:36:18 -070066#include <openssl/ssl.h>
67#include <openssl/err.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010068#include "openssl-compat.h"
Christopher Wileye8679812015-07-01 13:36:18 -070069
70/*
71 * Define an OpenSSL bio that targets a bufferevent.
72 */
73
74/* --------------------
75 A BIO is an OpenSSL abstraction that handles reading and writing data. The
76 library will happily speak SSL over anything that implements a BIO
77 interface.
78
79 Here we define a BIO implementation that directs its output to a
80 bufferevent. We'll want to use this only when none of OpenSSL's built-in
81 IO mechanisms work for us.
82 -------------------- */
83
84/* every BIO type needs its own integer type value. */
85#define BIO_TYPE_LIBEVENT 57
86/* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
87 * this. */
88
89#if 0
90static void
91print_err(int val)
92{
93 int err;
94 printf("Error was %d\n", val);
95
96 while ((err = ERR_get_error())) {
97 const char *msg = (const char*)ERR_reason_error_string(err);
98 const char *lib = (const char*)ERR_lib_error_string(err);
99 const char *func = (const char*)ERR_func_error_string(err);
100
101 printf("%s in %s %s\n", msg, lib, func);
102 }
103}
104#else
105#define print_err(v) ((void)0)
106#endif
107
108/* Called to initialize a new BIO */
109static int
110bio_bufferevent_new(BIO *b)
111{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100112 BIO_set_init(b, 0);
113 BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
Christopher Wileye8679812015-07-01 13:36:18 -0700114 return 1;
115}
116
117/* Called to uninitialize the BIO. */
118static int
119bio_bufferevent_free(BIO *b)
120{
121 if (!b)
122 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100123 if (BIO_get_shutdown(b)) {
124 if (BIO_get_init(b) && BIO_get_data(b))
125 bufferevent_free(BIO_get_data(b));
126 BIO_free(b);
Christopher Wileye8679812015-07-01 13:36:18 -0700127 }
128 return 1;
129}
130
131/* Called to extract data from the BIO. */
132static int
133bio_bufferevent_read(BIO *b, char *out, int outlen)
134{
135 int r = 0;
136 struct evbuffer *input;
137
138 BIO_clear_retry_flags(b);
139
140 if (!out)
141 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100142 if (!BIO_get_data(b))
Christopher Wileye8679812015-07-01 13:36:18 -0700143 return -1;
144
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100145 input = bufferevent_get_input(BIO_get_data(b));
Christopher Wileye8679812015-07-01 13:36:18 -0700146 if (evbuffer_get_length(input) == 0) {
147 /* If there's no data to read, say so. */
148 BIO_set_retry_read(b);
149 return -1;
150 } else {
151 r = evbuffer_remove(input, out, outlen);
152 }
153
154 return r;
155}
156
Haibo Huangb2279672019-05-31 16:12:39 -0700157/* Called to write data into the BIO */
Christopher Wileye8679812015-07-01 13:36:18 -0700158static int
159bio_bufferevent_write(BIO *b, const char *in, int inlen)
160{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100161 struct bufferevent *bufev = BIO_get_data(b);
Christopher Wileye8679812015-07-01 13:36:18 -0700162 struct evbuffer *output;
163 size_t outlen;
164
165 BIO_clear_retry_flags(b);
166
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100167 if (!BIO_get_data(b))
Christopher Wileye8679812015-07-01 13:36:18 -0700168 return -1;
169
170 output = bufferevent_get_output(bufev);
171 outlen = evbuffer_get_length(output);
172
173 /* Copy only as much data onto the output buffer as can fit under the
174 * high-water mark. */
175 if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) {
176 if (bufev->wm_write.high <= outlen) {
177 /* If no data can fit, we'll need to retry later. */
178 BIO_set_retry_write(b);
179 return -1;
180 }
181 inlen = bufev->wm_write.high - outlen;
182 }
183
184 EVUTIL_ASSERT(inlen > 0);
185 evbuffer_add(output, in, inlen);
186 return inlen;
187}
188
189/* Called to handle various requests */
190static long
191bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
192{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100193 struct bufferevent *bufev = BIO_get_data(b);
Christopher Wileye8679812015-07-01 13:36:18 -0700194 long ret = 1;
195
196 switch (cmd) {
197 case BIO_CTRL_GET_CLOSE:
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100198 ret = BIO_get_shutdown(b);
Christopher Wileye8679812015-07-01 13:36:18 -0700199 break;
200 case BIO_CTRL_SET_CLOSE:
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100201 BIO_set_shutdown(b, (int)num);
Christopher Wileye8679812015-07-01 13:36:18 -0700202 break;
203 case BIO_CTRL_PENDING:
204 ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
205 break;
206 case BIO_CTRL_WPENDING:
207 ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0;
208 break;
209 /* XXXX These two are given a special-case treatment because
210 * of cargo-cultism. I should come up with a better reason. */
211 case BIO_CTRL_DUP:
212 case BIO_CTRL_FLUSH:
213 ret = 1;
214 break;
215 default:
216 ret = 0;
217 break;
218 }
219 return ret;
220}
221
222/* Called to write a string to the BIO */
223static int
224bio_bufferevent_puts(BIO *b, const char *s)
225{
226 return bio_bufferevent_write(b, s, strlen(s));
227}
228
229/* Method table for the bufferevent BIO */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100230static BIO_METHOD *methods_bufferevent;
Christopher Wileye8679812015-07-01 13:36:18 -0700231
232/* Return the method table for the bufferevents BIO */
233static BIO_METHOD *
234BIO_s_bufferevent(void)
235{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100236 if (methods_bufferevent == NULL) {
237 methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
238 if (methods_bufferevent == NULL)
239 return NULL;
240 BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
241 BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
242 BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
243 BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
244 BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
245 BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
246 }
247 return methods_bufferevent;
Christopher Wileye8679812015-07-01 13:36:18 -0700248}
249
250/* Create a new BIO to wrap communication around a bufferevent. If close_flag
251 * is true, the bufferevent will be freed when the BIO is closed. */
252static BIO *
Haibo Huangb2279672019-05-31 16:12:39 -0700253BIO_new_bufferevent(struct bufferevent *bufferevent)
Christopher Wileye8679812015-07-01 13:36:18 -0700254{
255 BIO *result;
256 if (!bufferevent)
257 return NULL;
258 if (!(result = BIO_new(BIO_s_bufferevent())))
259 return NULL;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100260 BIO_set_init(result, 1);
261 BIO_set_data(result, bufferevent);
Haibo Huangb2279672019-05-31 16:12:39 -0700262 /* We don't tell the BIO to close the bufferevent; we do it ourselves on
263 * be_openssl_destruct() */
264 BIO_set_shutdown(result, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700265 return result;
266}
267
268/* --------------------
269 Now, here's the OpenSSL-based implementation of bufferevent.
270
271 The implementation comes in two flavors: one that connects its SSL object
272 to an underlying bufferevent using a BIO_bufferevent, and one that has the
273 SSL object connect to a socket directly. The latter should generally be
274 faster, except on Windows, where your best bet is using a
275 bufferevent_async.
276
277 (OpenSSL supports many other BIO types, too. But we can't use any unless
278 we have a good way to get notified when they become readable/writable.)
279 -------------------- */
280
281struct bio_data_counts {
282 unsigned long n_written;
283 unsigned long n_read;
284};
285
286struct bufferevent_openssl {
287 /* Shared fields with common bufferevent implementation code.
288 If we were set up with an underlying bufferevent, we use the
289 events here as timers only. If we have an SSL, then we use
290 the events as socket events.
291 */
292 struct bufferevent_private bev;
293 /* An underlying bufferevent that we're directing our output to.
294 If it's NULL, then we're connected to an fd, not an evbuffer. */
295 struct bufferevent *underlying;
296 /* The SSL object doing our encryption. */
297 SSL *ssl;
298
299 /* A callback that's invoked when data arrives on our outbuf so we
300 know to write data to the SSL. */
301 struct evbuffer_cb_entry *outbuf_cb;
302
303 /* A count of how much data the bios have read/written total. Used
304 for rate-limiting. */
305 struct bio_data_counts counts;
306
307 /* If this value is greater than 0, then the last SSL_write blocked,
308 * and we need to try it again with this many bytes. */
309 ev_ssize_t last_write;
310
311#define NUM_ERRORS 3
312 ev_uint32_t errors[NUM_ERRORS];
313
314 /* When we next get available space, we should say "read" instead of
315 "write". This can happen if there's a renegotiation during a read
316 operation. */
317 unsigned read_blocked_on_write : 1;
318 /* When we next get data, we should say "write" instead of "read". */
319 unsigned write_blocked_on_read : 1;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100320 /* Treat TCP close before SSL close on SSL >= v3 as clean EOF. */
Christopher Wileye8679812015-07-01 13:36:18 -0700321 unsigned allow_dirty_shutdown : 1;
Christopher Wileye8679812015-07-01 13:36:18 -0700322 /* XXX */
323 unsigned n_errors : 2;
324
325 /* Are we currently connecting, accepting, or doing IO? */
326 unsigned state : 2;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100327 /* If we reset fd, we sould reset state too */
328 unsigned old_state : 2;
Christopher Wileye8679812015-07-01 13:36:18 -0700329};
330
331static int be_openssl_enable(struct bufferevent *, short);
332static int be_openssl_disable(struct bufferevent *, short);
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100333static void be_openssl_unlink(struct bufferevent *);
Christopher Wileye8679812015-07-01 13:36:18 -0700334static void be_openssl_destruct(struct bufferevent *);
335static int be_openssl_adj_timeouts(struct bufferevent *);
336static int be_openssl_flush(struct bufferevent *bufev,
337 short iotype, enum bufferevent_flush_mode mode);
338static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
339
340const struct bufferevent_ops bufferevent_ops_openssl = {
341 "ssl",
342 evutil_offsetof(struct bufferevent_openssl, bev.bev),
343 be_openssl_enable,
344 be_openssl_disable,
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100345 be_openssl_unlink,
Christopher Wileye8679812015-07-01 13:36:18 -0700346 be_openssl_destruct,
347 be_openssl_adj_timeouts,
348 be_openssl_flush,
349 be_openssl_ctrl,
350};
351
352/* Given a bufferevent, return a pointer to the bufferevent_openssl that
353 * contains it, if any. */
354static inline struct bufferevent_openssl *
355upcast(struct bufferevent *bev)
356{
357 struct bufferevent_openssl *bev_o;
Haibo Huangb2279672019-05-31 16:12:39 -0700358 if (!BEV_IS_OPENSSL(bev))
Christopher Wileye8679812015-07-01 13:36:18 -0700359 return NULL;
360 bev_o = (void*)( ((char*)bev) -
361 evutil_offsetof(struct bufferevent_openssl, bev.bev));
Haibo Huangb2279672019-05-31 16:12:39 -0700362 EVUTIL_ASSERT(BEV_IS_OPENSSL(&bev_o->bev.bev));
Christopher Wileye8679812015-07-01 13:36:18 -0700363 return bev_o;
364}
365
366static inline void
367put_error(struct bufferevent_openssl *bev_ssl, unsigned long err)
368{
369 if (bev_ssl->n_errors == NUM_ERRORS)
370 return;
371 /* The error type according to openssl is "unsigned long", but
372 openssl never uses more than 32 bits of it. It _can't_ use more
373 than 32 bits of it, since it needs to report errors on systems
374 where long is only 32 bits.
375 */
376 bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err;
377}
378
379/* Have the base communications channel (either the underlying bufferevent or
380 * ev_read and ev_write) start reading. Take the read-blocked-on-write flag
381 * into account. */
382static int
383start_reading(struct bufferevent_openssl *bev_ssl)
384{
385 if (bev_ssl->underlying) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100386 bufferevent_unsuspend_read_(bev_ssl->underlying,
Christopher Wileye8679812015-07-01 13:36:18 -0700387 BEV_SUSPEND_FILT_READ);
388 return 0;
389 } else {
390 struct bufferevent *bev = &bev_ssl->bev.bev;
391 int r;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100392 r = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
Christopher Wileye8679812015-07-01 13:36:18 -0700393 if (r == 0 && bev_ssl->read_blocked_on_write)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100394 r = bufferevent_add_event_(&bev->ev_write,
Christopher Wileye8679812015-07-01 13:36:18 -0700395 &bev->timeout_write);
396 return r;
397 }
398}
399
400/* Have the base communications channel (either the underlying bufferevent or
401 * ev_read and ev_write) start writing. Take the write-blocked-on-read flag
402 * into account. */
403static int
404start_writing(struct bufferevent_openssl *bev_ssl)
405{
406 int r = 0;
407 if (bev_ssl->underlying) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100408 if (bev_ssl->write_blocked_on_read) {
409 bufferevent_unsuspend_read_(bev_ssl->underlying,
410 BEV_SUSPEND_FILT_READ);
411 }
Christopher Wileye8679812015-07-01 13:36:18 -0700412 } else {
413 struct bufferevent *bev = &bev_ssl->bev.bev;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100414 r = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
Christopher Wileye8679812015-07-01 13:36:18 -0700415 if (!r && bev_ssl->write_blocked_on_read)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100416 r = bufferevent_add_event_(&bev->ev_read,
Christopher Wileye8679812015-07-01 13:36:18 -0700417 &bev->timeout_read);
418 }
419 return r;
420}
421
422static void
423stop_reading(struct bufferevent_openssl *bev_ssl)
424{
425 if (bev_ssl->write_blocked_on_read)
426 return;
427 if (bev_ssl->underlying) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100428 bufferevent_suspend_read_(bev_ssl->underlying,
Christopher Wileye8679812015-07-01 13:36:18 -0700429 BEV_SUSPEND_FILT_READ);
430 } else {
431 struct bufferevent *bev = &bev_ssl->bev.bev;
432 event_del(&bev->ev_read);
433 }
434}
435
436static void
437stop_writing(struct bufferevent_openssl *bev_ssl)
438{
439 if (bev_ssl->read_blocked_on_write)
440 return;
441 if (bev_ssl->underlying) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100442 bufferevent_unsuspend_read_(bev_ssl->underlying,
443 BEV_SUSPEND_FILT_READ);
Christopher Wileye8679812015-07-01 13:36:18 -0700444 } else {
445 struct bufferevent *bev = &bev_ssl->bev.bev;
446 event_del(&bev->ev_write);
447 }
448}
449
450static int
451set_rbow(struct bufferevent_openssl *bev_ssl)
452{
453 if (!bev_ssl->underlying)
454 stop_reading(bev_ssl);
455 bev_ssl->read_blocked_on_write = 1;
456 return start_writing(bev_ssl);
457}
458
459static int
460set_wbor(struct bufferevent_openssl *bev_ssl)
461{
462 if (!bev_ssl->underlying)
463 stop_writing(bev_ssl);
464 bev_ssl->write_blocked_on_read = 1;
465 return start_reading(bev_ssl);
466}
467
468static int
469clear_rbow(struct bufferevent_openssl *bev_ssl)
470{
471 struct bufferevent *bev = &bev_ssl->bev.bev;
472 int r = 0;
473 bev_ssl->read_blocked_on_write = 0;
474 if (!(bev->enabled & EV_WRITE))
475 stop_writing(bev_ssl);
476 if (bev->enabled & EV_READ)
477 r = start_reading(bev_ssl);
478 return r;
479}
480
481
482static int
483clear_wbor(struct bufferevent_openssl *bev_ssl)
484{
485 struct bufferevent *bev = &bev_ssl->bev.bev;
486 int r = 0;
487 bev_ssl->write_blocked_on_read = 0;
488 if (!(bev->enabled & EV_READ))
489 stop_reading(bev_ssl);
490 if (bev->enabled & EV_WRITE)
491 r = start_writing(bev_ssl);
492 return r;
493}
494
495static void
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100496conn_closed(struct bufferevent_openssl *bev_ssl, int when, int errcode, int ret)
Christopher Wileye8679812015-07-01 13:36:18 -0700497{
498 int event = BEV_EVENT_ERROR;
499 int dirty_shutdown = 0;
500 unsigned long err;
501
502 switch (errcode) {
503 case SSL_ERROR_ZERO_RETURN:
504 /* Possibly a clean shutdown. */
505 if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
506 event = BEV_EVENT_EOF;
507 else
508 dirty_shutdown = 1;
509 break;
510 case SSL_ERROR_SYSCALL:
511 /* IO error; possibly a dirty shutdown. */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100512 if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
Christopher Wileye8679812015-07-01 13:36:18 -0700513 dirty_shutdown = 1;
Haibo Huangb2279672019-05-31 16:12:39 -0700514 put_error(bev_ssl, errcode);
Christopher Wileye8679812015-07-01 13:36:18 -0700515 break;
516 case SSL_ERROR_SSL:
517 /* Protocol error. */
Haibo Huangb2279672019-05-31 16:12:39 -0700518 put_error(bev_ssl, errcode);
Christopher Wileye8679812015-07-01 13:36:18 -0700519 break;
520 case SSL_ERROR_WANT_X509_LOOKUP:
521 /* XXXX handle this. */
Haibo Huangb2279672019-05-31 16:12:39 -0700522 put_error(bev_ssl, errcode);
Christopher Wileye8679812015-07-01 13:36:18 -0700523 break;
524 case SSL_ERROR_NONE:
525 case SSL_ERROR_WANT_READ:
526 case SSL_ERROR_WANT_WRITE:
527 case SSL_ERROR_WANT_CONNECT:
528 case SSL_ERROR_WANT_ACCEPT:
529 default:
530 /* should be impossible; treat as normal error. */
531 event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
532 break;
533 }
534
535 while ((err = ERR_get_error())) {
536 put_error(bev_ssl, err);
537 }
538
539 if (dirty_shutdown && bev_ssl->allow_dirty_shutdown)
540 event = BEV_EVENT_EOF;
541
542 stop_reading(bev_ssl);
543 stop_writing(bev_ssl);
544
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100545 /* when is BEV_EVENT_{READING|WRITING} */
546 event = when | event;
547 bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700548}
549
550static void
551init_bio_counts(struct bufferevent_openssl *bev_ssl)
552{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100553 BIO *rbio, *wbio;
554
555 wbio = SSL_get_wbio(bev_ssl->ssl);
556 bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
557 rbio = SSL_get_rbio(bev_ssl->ssl);
558 bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
Christopher Wileye8679812015-07-01 13:36:18 -0700559}
560
561static inline void
562decrement_buckets(struct bufferevent_openssl *bev_ssl)
563{
564 unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
565 unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
566 /* These next two subtractions can wrap around. That's okay. */
567 unsigned long w = num_w - bev_ssl->counts.n_written;
568 unsigned long r = num_r - bev_ssl->counts.n_read;
569 if (w)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100570 bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
Christopher Wileye8679812015-07-01 13:36:18 -0700571 if (r)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100572 bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
Christopher Wileye8679812015-07-01 13:36:18 -0700573 bev_ssl->counts.n_written = num_w;
574 bev_ssl->counts.n_read = num_r;
575}
576
577#define OP_MADE_PROGRESS 1
578#define OP_BLOCKED 2
579#define OP_ERR 4
580
581/* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if
582 we're now blocked); and OP_ERR (if an error occurred). */
583static int
584do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) {
585 /* Requires lock */
586 struct bufferevent *bev = &bev_ssl->bev.bev;
587 struct evbuffer *input = bev->input;
588 int r, n, i, n_used = 0, atmost;
589 struct evbuffer_iovec space[2];
590 int result = 0;
591
592 if (bev_ssl->bev.read_suspended)
593 return 0;
594
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100595 atmost = bufferevent_get_read_max_(&bev_ssl->bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700596 if (n_to_read > atmost)
597 n_to_read = atmost;
598
599 n = evbuffer_reserve_space(input, n_to_read, space, 2);
600 if (n < 0)
601 return OP_ERR;
602
603 for (i=0; i<n; ++i) {
604 if (bev_ssl->bev.read_suspended)
605 break;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100606 ERR_clear_error();
Christopher Wileye8679812015-07-01 13:36:18 -0700607 r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
608 if (r>0) {
609 result |= OP_MADE_PROGRESS;
610 if (bev_ssl->read_blocked_on_write)
611 if (clear_rbow(bev_ssl) < 0)
612 return OP_ERR | result;
613 ++n_used;
614 space[i].iov_len = r;
615 decrement_buckets(bev_ssl);
616 } else {
617 int err = SSL_get_error(bev_ssl->ssl, r);
618 print_err(err);
619 switch (err) {
620 case SSL_ERROR_WANT_READ:
621 /* Can't read until underlying has more data. */
622 if (bev_ssl->read_blocked_on_write)
623 if (clear_rbow(bev_ssl) < 0)
624 return OP_ERR | result;
625 break;
626 case SSL_ERROR_WANT_WRITE:
627 /* This read operation requires a write, and the
628 * underlying is full */
629 if (!bev_ssl->read_blocked_on_write)
630 if (set_rbow(bev_ssl) < 0)
631 return OP_ERR | result;
632 break;
633 default:
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100634 conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
Christopher Wileye8679812015-07-01 13:36:18 -0700635 break;
636 }
637 result |= OP_BLOCKED;
638 break; /* out of the loop */
639 }
640 }
641
642 if (n_used) {
643 evbuffer_commit_space(input, space, n_used);
644 if (bev_ssl->underlying)
645 BEV_RESET_GENERIC_READ_TIMEOUT(bev);
646 }
647
648 return result;
649}
650
651/* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if
652 we're now blocked); and OP_ERR (if an error occurred). */
653static int
654do_write(struct bufferevent_openssl *bev_ssl, int atmost)
655{
656 int i, r, n, n_written = 0;
657 struct bufferevent *bev = &bev_ssl->bev.bev;
658 struct evbuffer *output = bev->output;
659 struct evbuffer_iovec space[8];
660 int result = 0;
661
662 if (bev_ssl->last_write > 0)
663 atmost = bev_ssl->last_write;
664 else
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100665 atmost = bufferevent_get_write_max_(&bev_ssl->bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700666
667 n = evbuffer_peek(output, atmost, NULL, space, 8);
668 if (n < 0)
669 return OP_ERR | result;
670
671 if (n > 8)
672 n = 8;
673 for (i=0; i < n; ++i) {
674 if (bev_ssl->bev.write_suspended)
675 break;
676
677 /* SSL_write will (reasonably) return 0 if we tell it to
678 send 0 data. Skip this case so we don't interpret the
679 result as an error */
680 if (space[i].iov_len == 0)
681 continue;
682
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100683 ERR_clear_error();
Christopher Wileye8679812015-07-01 13:36:18 -0700684 r = SSL_write(bev_ssl->ssl, space[i].iov_base,
685 space[i].iov_len);
686 if (r > 0) {
687 result |= OP_MADE_PROGRESS;
688 if (bev_ssl->write_blocked_on_read)
689 if (clear_wbor(bev_ssl) < 0)
690 return OP_ERR | result;
691 n_written += r;
692 bev_ssl->last_write = -1;
693 decrement_buckets(bev_ssl);
694 } else {
695 int err = SSL_get_error(bev_ssl->ssl, r);
696 print_err(err);
697 switch (err) {
698 case SSL_ERROR_WANT_WRITE:
699 /* Can't read until underlying has more data. */
700 if (bev_ssl->write_blocked_on_read)
701 if (clear_wbor(bev_ssl) < 0)
702 return OP_ERR | result;
703 bev_ssl->last_write = space[i].iov_len;
704 break;
705 case SSL_ERROR_WANT_READ:
706 /* This read operation requires a write, and the
707 * underlying is full */
708 if (!bev_ssl->write_blocked_on_read)
709 if (set_wbor(bev_ssl) < 0)
710 return OP_ERR | result;
711 bev_ssl->last_write = space[i].iov_len;
712 break;
713 default:
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100714 conn_closed(bev_ssl, BEV_EVENT_WRITING, err, r);
Christopher Wileye8679812015-07-01 13:36:18 -0700715 bev_ssl->last_write = -1;
716 break;
717 }
718 result |= OP_BLOCKED;
719 break;
720 }
721 }
722 if (n_written) {
723 evbuffer_drain(output, n_written);
724 if (bev_ssl->underlying)
725 BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
726
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100727 bufferevent_trigger_nolock_(bev, EV_WRITE, BEV_OPT_DEFER_CALLBACKS);
Christopher Wileye8679812015-07-01 13:36:18 -0700728 }
729 return result;
730}
731
732#define WRITE_FRAME 15000
733
734#define READ_DEFAULT 4096
735
736/* Try to figure out how many bytes to read; return 0 if we shouldn't be
737 * reading. */
738static int
739bytes_to_read(struct bufferevent_openssl *bev)
740{
741 struct evbuffer *input = bev->bev.bev.input;
742 struct event_watermark *wm = &bev->bev.bev.wm_read;
743 int result = READ_DEFAULT;
744 ev_ssize_t limit;
745 /* XXX 99% of this is generic code that nearly all bufferevents will
746 * want. */
747
748 if (bev->write_blocked_on_read) {
749 return 0;
750 }
751
752 if (! (bev->bev.bev.enabled & EV_READ)) {
753 return 0;
754 }
755
756 if (bev->bev.read_suspended) {
757 return 0;
758 }
759
760 if (wm->high) {
761 if (evbuffer_get_length(input) >= wm->high) {
762 return 0;
763 }
764
765 result = wm->high - evbuffer_get_length(input);
766 } else {
767 result = READ_DEFAULT;
768 }
769
770 /* Respect the rate limit */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100771 limit = bufferevent_get_read_max_(&bev->bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700772 if (result > limit) {
773 result = limit;
774 }
775
776 return result;
777}
778
779
780/* Things look readable. If write is blocked on read, write till it isn't.
781 * Read from the underlying buffer until we block or we hit our high-water
782 * mark.
783 */
784static void
785consider_reading(struct bufferevent_openssl *bev_ssl)
786{
787 int r;
788 int n_to_read;
789 int all_result_flags = 0;
790
791 while (bev_ssl->write_blocked_on_read) {
792 r = do_write(bev_ssl, WRITE_FRAME);
793 if (r & (OP_BLOCKED|OP_ERR))
794 break;
795 }
796 if (bev_ssl->write_blocked_on_read)
797 return;
798
799 n_to_read = bytes_to_read(bev_ssl);
800
801 while (n_to_read) {
802 r = do_read(bev_ssl, n_to_read);
803 all_result_flags |= r;
804
805 if (r & (OP_BLOCKED|OP_ERR))
806 break;
807
808 if (bev_ssl->bev.read_suspended)
809 break;
Haibo Huangb2279672019-05-31 16:12:39 -0700810
Christopher Wileye8679812015-07-01 13:36:18 -0700811 /* Read all pending data. This won't hit the network
812 * again, and will (most importantly) put us in a state
813 * where we don't need to read anything else until the
814 * socket is readable again. It'll potentially make us
815 * overrun our read high-watermark (somewhat
816 * regrettable). The damage to the rate-limit has
817 * already been done, since OpenSSL went and read a
818 * whole SSL record anyway. */
819 n_to_read = SSL_pending(bev_ssl->ssl);
820
821 /* XXX This if statement is actually a bad bug, added to avoid
822 * XXX a worse bug.
823 *
824 * The bad bug: It can potentially cause resource unfairness
825 * by reading too much data from the underlying bufferevent;
826 * it can potentially cause read looping if the underlying
827 * bufferevent is a bufferevent_pair and deferred callbacks
828 * aren't used.
829 *
830 * The worse bug: If we didn't do this, then we would
831 * potentially not read any more from bev_ssl->underlying
832 * until more data arrived there, which could lead to us
833 * waiting forever.
834 */
835 if (!n_to_read && bev_ssl->underlying)
836 n_to_read = bytes_to_read(bev_ssl);
837 }
838
839 if (all_result_flags & OP_MADE_PROGRESS) {
840 struct bufferevent *bev = &bev_ssl->bev.bev;
Christopher Wileye8679812015-07-01 13:36:18 -0700841
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100842 bufferevent_trigger_nolock_(bev, EV_READ, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700843 }
844
845 if (!bev_ssl->underlying) {
846 /* Should be redundant, but let's avoid busy-looping */
847 if (bev_ssl->bev.read_suspended ||
848 !(bev_ssl->bev.bev.enabled & EV_READ)) {
849 event_del(&bev_ssl->bev.bev.ev_read);
850 }
851 }
852}
853
854static void
855consider_writing(struct bufferevent_openssl *bev_ssl)
856{
857 int r;
858 struct evbuffer *output = bev_ssl->bev.bev.output;
859 struct evbuffer *target = NULL;
860 struct event_watermark *wm = NULL;
861
862 while (bev_ssl->read_blocked_on_write) {
863 r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
864 if (r & OP_MADE_PROGRESS) {
865 struct bufferevent *bev = &bev_ssl->bev.bev;
Christopher Wileye8679812015-07-01 13:36:18 -0700866
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100867 bufferevent_trigger_nolock_(bev, EV_READ, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700868 }
869 if (r & (OP_ERR|OP_BLOCKED))
870 break;
871 }
872 if (bev_ssl->read_blocked_on_write)
873 return;
874 if (bev_ssl->underlying) {
875 target = bev_ssl->underlying->output;
876 wm = &bev_ssl->underlying->wm_write;
877 }
878 while ((bev_ssl->bev.bev.enabled & EV_WRITE) &&
879 (! bev_ssl->bev.write_suspended) &&
880 evbuffer_get_length(output) &&
881 (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) {
882 int n_to_write;
883 if (wm && wm->high)
884 n_to_write = wm->high - evbuffer_get_length(target);
885 else
886 n_to_write = WRITE_FRAME;
887 r = do_write(bev_ssl, n_to_write);
888 if (r & (OP_BLOCKED|OP_ERR))
889 break;
890 }
891
892 if (!bev_ssl->underlying) {
893 if (evbuffer_get_length(output) == 0) {
894 event_del(&bev_ssl->bev.bev.ev_write);
895 } else if (bev_ssl->bev.write_suspended ||
896 !(bev_ssl->bev.bev.enabled & EV_WRITE)) {
897 /* Should be redundant, but let's avoid busy-looping */
898 event_del(&bev_ssl->bev.bev.ev_write);
899 }
900 }
901}
902
903static void
904be_openssl_readcb(struct bufferevent *bev_base, void *ctx)
905{
906 struct bufferevent_openssl *bev_ssl = ctx;
907 consider_reading(bev_ssl);
908}
909
910static void
911be_openssl_writecb(struct bufferevent *bev_base, void *ctx)
912{
913 struct bufferevent_openssl *bev_ssl = ctx;
914 consider_writing(bev_ssl);
915}
916
917static void
918be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx)
919{
920 struct bufferevent_openssl *bev_ssl = ctx;
921 int event = 0;
922
923 if (what & BEV_EVENT_EOF) {
924 if (bev_ssl->allow_dirty_shutdown)
925 event = BEV_EVENT_EOF;
926 else
927 event = BEV_EVENT_ERROR;
928 } else if (what & BEV_EVENT_TIMEOUT) {
929 /* We sure didn't set this. Propagate it to the user. */
930 event = what;
931 } else if (what & BEV_EVENT_ERROR) {
932 /* An error occurred on the connection. Propagate it to the user. */
933 event = what;
934 } else if (what & BEV_EVENT_CONNECTED) {
935 /* Ignore it. We're saying SSL_connect() already, which will
936 eat it. */
937 }
938 if (event)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100939 bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700940}
941
942static void
943be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr)
944{
945 struct bufferevent_openssl *bev_ssl = ptr;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100946 bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700947 if (what == EV_TIMEOUT) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100948 bufferevent_run_eventcb_(&bev_ssl->bev.bev,
949 BEV_EVENT_TIMEOUT|BEV_EVENT_READING, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700950 } else {
951 consider_reading(bev_ssl);
952 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100953 bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700954}
955
956static void
957be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
958{
959 struct bufferevent_openssl *bev_ssl = ptr;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100960 bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
Christopher Wileye8679812015-07-01 13:36:18 -0700961 if (what == EV_TIMEOUT) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100962 bufferevent_run_eventcb_(&bev_ssl->bev.bev,
963 BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700964 } else {
965 consider_writing(bev_ssl);
966 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100967 bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
968}
969
Haibo Huangb2279672019-05-31 16:12:39 -0700970static evutil_socket_t
971be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100972{
973 if (!bev_ssl->underlying) {
974 struct bufferevent *bev = &bev_ssl->bev.bev;
975 if (event_initialized(&bev->ev_read) && fd < 0) {
976 fd = event_get_fd(&bev->ev_read);
977 }
978 }
979 return fd;
Christopher Wileye8679812015-07-01 13:36:18 -0700980}
981
982static int
983set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
984{
985 if (bev_ssl->underlying) {
986 bufferevent_setcb(bev_ssl->underlying,
987 be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb,
988 bev_ssl);
989 return 0;
990 } else {
991 struct bufferevent *bev = &bev_ssl->bev.bev;
992 int rpending=0, wpending=0, r1=0, r2=0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100993
994 if (event_initialized(&bev->ev_read)) {
Christopher Wileye8679812015-07-01 13:36:18 -0700995 rpending = event_pending(&bev->ev_read, EV_READ, NULL);
996 wpending = event_pending(&bev->ev_write, EV_WRITE, NULL);
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100997
Christopher Wileye8679812015-07-01 13:36:18 -0700998 event_del(&bev->ev_read);
999 event_del(&bev->ev_write);
1000 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001001
Christopher Wileye8679812015-07-01 13:36:18 -07001002 event_assign(&bev->ev_read, bev->ev_base, fd,
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001003 EV_READ|EV_PERSIST|EV_FINALIZE,
1004 be_openssl_readeventcb, bev_ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001005 event_assign(&bev->ev_write, bev->ev_base, fd,
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001006 EV_WRITE|EV_PERSIST|EV_FINALIZE,
1007 be_openssl_writeeventcb, bev_ssl);
1008
Christopher Wileye8679812015-07-01 13:36:18 -07001009 if (rpending)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001010 r1 = bufferevent_add_event_(&bev->ev_read, &bev->timeout_read);
Christopher Wileye8679812015-07-01 13:36:18 -07001011 if (wpending)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001012 r2 = bufferevent_add_event_(&bev->ev_write, &bev->timeout_write);
1013
Christopher Wileye8679812015-07-01 13:36:18 -07001014 return (r1<0 || r2<0) ? -1 : 0;
1015 }
1016}
1017
1018static int
1019do_handshake(struct bufferevent_openssl *bev_ssl)
1020{
1021 int r;
1022
1023 switch (bev_ssl->state) {
1024 default:
1025 case BUFFEREVENT_SSL_OPEN:
1026 EVUTIL_ASSERT(0);
1027 return -1;
1028 case BUFFEREVENT_SSL_CONNECTING:
1029 case BUFFEREVENT_SSL_ACCEPTING:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001030 ERR_clear_error();
Christopher Wileye8679812015-07-01 13:36:18 -07001031 r = SSL_do_handshake(bev_ssl->ssl);
1032 break;
1033 }
1034 decrement_buckets(bev_ssl);
1035
1036 if (r==1) {
Haibo Huangb2279672019-05-31 16:12:39 -07001037 evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read);
Christopher Wileye8679812015-07-01 13:36:18 -07001038 /* We're done! */
1039 bev_ssl->state = BUFFEREVENT_SSL_OPEN;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001040 set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */
Christopher Wileye8679812015-07-01 13:36:18 -07001041 /* Call do_read and do_write as needed */
1042 bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001043 bufferevent_run_eventcb_(&bev_ssl->bev.bev,
1044 BEV_EVENT_CONNECTED, 0);
Christopher Wileye8679812015-07-01 13:36:18 -07001045 return 1;
1046 } else {
1047 int err = SSL_get_error(bev_ssl->ssl, r);
1048 print_err(err);
1049 switch (err) {
1050 case SSL_ERROR_WANT_WRITE:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001051 stop_reading(bev_ssl);
1052 return start_writing(bev_ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001053 case SSL_ERROR_WANT_READ:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001054 stop_writing(bev_ssl);
1055 return start_reading(bev_ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001056 default:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001057 conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
Christopher Wileye8679812015-07-01 13:36:18 -07001058 return -1;
1059 }
1060 }
1061}
1062
1063static void
1064be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx)
1065{
1066 struct bufferevent_openssl *bev_ssl = ctx;
1067 do_handshake(bev_ssl);/* XXX handle failure */
1068}
1069
1070static void
1071be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
1072{
1073 struct bufferevent_openssl *bev_ssl = ptr;
1074
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001075 bufferevent_incref_and_lock_(&bev_ssl->bev.bev);
Christopher Wileye8679812015-07-01 13:36:18 -07001076 if (what & EV_TIMEOUT) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001077 bufferevent_run_eventcb_(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT, 0);
Christopher Wileye8679812015-07-01 13:36:18 -07001078 } else
1079 do_handshake(bev_ssl);/* XXX handle failure */
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001080 bufferevent_decref_and_unlock_(&bev_ssl->bev.bev);
Christopher Wileye8679812015-07-01 13:36:18 -07001081}
1082
1083static int
1084set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
1085{
1086 if (bev_ssl->underlying) {
1087 bufferevent_setcb(bev_ssl->underlying,
1088 be_openssl_handshakecb, be_openssl_handshakecb,
1089 be_openssl_eventcb,
1090 bev_ssl);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001091
1092 if (fd < 0)
1093 return 0;
1094
1095 if (bufferevent_setfd(bev_ssl->underlying, fd))
1096 return 1;
1097
Christopher Wileye8679812015-07-01 13:36:18 -07001098 return do_handshake(bev_ssl);
1099 } else {
1100 struct bufferevent *bev = &bev_ssl->bev.bev;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001101
1102 if (event_initialized(&bev->ev_read)) {
Christopher Wileye8679812015-07-01 13:36:18 -07001103 event_del(&bev->ev_read);
1104 event_del(&bev->ev_write);
1105 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001106
Christopher Wileye8679812015-07-01 13:36:18 -07001107 event_assign(&bev->ev_read, bev->ev_base, fd,
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001108 EV_READ|EV_PERSIST|EV_FINALIZE,
1109 be_openssl_handshakeeventcb, bev_ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001110 event_assign(&bev->ev_write, bev->ev_base, fd,
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001111 EV_WRITE|EV_PERSIST|EV_FINALIZE,
1112 be_openssl_handshakeeventcb, bev_ssl);
1113 if (fd >= 0)
1114 bufferevent_enable(bev, bev->enabled);
1115 return 0;
Christopher Wileye8679812015-07-01 13:36:18 -07001116 }
1117}
1118
1119int
1120bufferevent_ssl_renegotiate(struct bufferevent *bev)
1121{
1122 struct bufferevent_openssl *bev_ssl = upcast(bev);
1123 if (!bev_ssl)
1124 return -1;
1125 if (SSL_renegotiate(bev_ssl->ssl) < 0)
1126 return -1;
1127 bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001128 if (set_handshake_callbacks(bev_ssl, be_openssl_auto_fd(bev_ssl, -1)) < 0)
Christopher Wileye8679812015-07-01 13:36:18 -07001129 return -1;
1130 if (!bev_ssl->underlying)
1131 return do_handshake(bev_ssl);
1132 return 0;
1133}
1134
1135static void
1136be_openssl_outbuf_cb(struct evbuffer *buf,
1137 const struct evbuffer_cb_info *cbinfo, void *arg)
1138{
1139 struct bufferevent_openssl *bev_ssl = arg;
1140 int r = 0;
1141 /* XXX need to hold a reference here. */
1142
1143 if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
1144 if (cbinfo->orig_size == 0)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001145 r = bufferevent_add_event_(&bev_ssl->bev.bev.ev_write,
Christopher Wileye8679812015-07-01 13:36:18 -07001146 &bev_ssl->bev.bev.timeout_write);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001147
1148 if (bev_ssl->underlying)
1149 consider_writing(bev_ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001150 }
1151 /* XXX Handle r < 0 */
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001152 (void)r;
Christopher Wileye8679812015-07-01 13:36:18 -07001153}
1154
1155
1156static int
1157be_openssl_enable(struct bufferevent *bev, short events)
1158{
1159 struct bufferevent_openssl *bev_ssl = upcast(bev);
1160 int r1 = 0, r2 = 0;
1161
Christopher Wileye8679812015-07-01 13:36:18 -07001162 if (events & EV_READ)
1163 r1 = start_reading(bev_ssl);
1164 if (events & EV_WRITE)
1165 r2 = start_writing(bev_ssl);
1166
1167 if (bev_ssl->underlying) {
1168 if (events & EV_READ)
1169 BEV_RESET_GENERIC_READ_TIMEOUT(bev);
1170 if (events & EV_WRITE)
1171 BEV_RESET_GENERIC_WRITE_TIMEOUT(bev);
1172
1173 if (events & EV_READ)
1174 consider_reading(bev_ssl);
1175 if (events & EV_WRITE)
1176 consider_writing(bev_ssl);
1177 }
1178 return (r1 < 0 || r2 < 0) ? -1 : 0;
1179}
1180
1181static int
1182be_openssl_disable(struct bufferevent *bev, short events)
1183{
1184 struct bufferevent_openssl *bev_ssl = upcast(bev);
Christopher Wileye8679812015-07-01 13:36:18 -07001185
1186 if (events & EV_READ)
1187 stop_reading(bev_ssl);
1188 if (events & EV_WRITE)
1189 stop_writing(bev_ssl);
1190
1191 if (bev_ssl->underlying) {
1192 if (events & EV_READ)
1193 BEV_DEL_GENERIC_READ_TIMEOUT(bev);
1194 if (events & EV_WRITE)
1195 BEV_DEL_GENERIC_WRITE_TIMEOUT(bev);
1196 }
1197 return 0;
1198}
1199
1200static void
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001201be_openssl_unlink(struct bufferevent *bev)
Christopher Wileye8679812015-07-01 13:36:18 -07001202{
1203 struct bufferevent_openssl *bev_ssl = upcast(bev);
1204
Christopher Wileye8679812015-07-01 13:36:18 -07001205 if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
1206 if (bev_ssl->underlying) {
1207 if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) {
1208 event_warnx("BEV_OPT_CLOSE_ON_FREE set on an "
1209 "bufferevent with too few references");
1210 } else {
1211 bufferevent_free(bev_ssl->underlying);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001212 /* We still have a reference to it, via our
1213 * BIO. So we don't drop this. */
1214 // bev_ssl->underlying = NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001215 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001216 }
1217 } else {
1218 if (bev_ssl->underlying) {
1219 if (bev_ssl->underlying->errorcb == be_openssl_eventcb)
1220 bufferevent_setcb(bev_ssl->underlying,
1221 NULL,NULL,NULL,NULL);
1222 bufferevent_unsuspend_read_(bev_ssl->underlying,
1223 BEV_SUSPEND_FILT_READ);
1224 }
1225 }
1226}
1227
1228static void
1229be_openssl_destruct(struct bufferevent *bev)
1230{
1231 struct bufferevent_openssl *bev_ssl = upcast(bev);
1232
1233 if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) {
1234 if (! bev_ssl->underlying) {
Haibo Huangb2279672019-05-31 16:12:39 -07001235 evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
Christopher Wileye8679812015-07-01 13:36:18 -07001236 BIO *bio = SSL_get_wbio(bev_ssl->ssl);
1237 if (bio)
1238 fd = BIO_get_fd(bio, NULL);
1239 if (fd >= 0)
1240 evutil_closesocket(fd);
1241 }
1242 SSL_free(bev_ssl->ssl);
Christopher Wileye8679812015-07-01 13:36:18 -07001243 }
1244}
1245
1246static int
1247be_openssl_adj_timeouts(struct bufferevent *bev)
1248{
1249 struct bufferevent_openssl *bev_ssl = upcast(bev);
1250
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001251 if (bev_ssl->underlying) {
1252 return bufferevent_generic_adj_timeouts_(bev);
1253 } else {
1254 return bufferevent_generic_adj_existing_timeouts_(bev);
Christopher Wileye8679812015-07-01 13:36:18 -07001255 }
1256}
1257
1258static int
1259be_openssl_flush(struct bufferevent *bufev,
1260 short iotype, enum bufferevent_flush_mode mode)
1261{
1262 /* XXXX Implement this. */
1263 return 0;
1264}
1265
1266static int
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001267be_openssl_set_fd(struct bufferevent_openssl *bev_ssl,
Haibo Huangb2279672019-05-31 16:12:39 -07001268 enum bufferevent_ssl_state state, evutil_socket_t fd)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001269{
1270 bev_ssl->state = state;
1271
1272 switch (state) {
1273 case BUFFEREVENT_SSL_ACCEPTING:
Haibo Huangb2279672019-05-31 16:12:39 -07001274 if (!SSL_clear(bev_ssl->ssl))
1275 return -1;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001276 SSL_set_accept_state(bev_ssl->ssl);
1277 if (set_handshake_callbacks(bev_ssl, fd) < 0)
1278 return -1;
1279 break;
1280 case BUFFEREVENT_SSL_CONNECTING:
Haibo Huangb2279672019-05-31 16:12:39 -07001281 if (!SSL_clear(bev_ssl->ssl))
1282 return -1;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001283 SSL_set_connect_state(bev_ssl->ssl);
1284 if (set_handshake_callbacks(bev_ssl, fd) < 0)
1285 return -1;
1286 break;
1287 case BUFFEREVENT_SSL_OPEN:
1288 if (set_open_callbacks(bev_ssl, fd) < 0)
1289 return -1;
1290 break;
1291 default:
1292 return -1;
1293 }
1294
1295 return 0;
1296}
1297
1298static int
Christopher Wileye8679812015-07-01 13:36:18 -07001299be_openssl_ctrl(struct bufferevent *bev,
1300 enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data)
1301{
1302 struct bufferevent_openssl *bev_ssl = upcast(bev);
1303 switch (op) {
1304 case BEV_CTRL_SET_FD:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001305 if (!bev_ssl->underlying) {
Christopher Wileye8679812015-07-01 13:36:18 -07001306 BIO *bio;
Haibo Huangb2279672019-05-31 16:12:39 -07001307 bio = BIO_new_socket((int)data->fd, 0);
Christopher Wileye8679812015-07-01 13:36:18 -07001308 SSL_set_bio(bev_ssl->ssl, bio, bio);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001309 } else {
1310 BIO *bio;
Haibo Huangb2279672019-05-31 16:12:39 -07001311 if (!(bio = BIO_new_bufferevent(bev_ssl->underlying)))
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001312 return -1;
1313 SSL_set_bio(bev_ssl->ssl, bio, bio);
Christopher Wileye8679812015-07-01 13:36:18 -07001314 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001315
1316 return be_openssl_set_fd(bev_ssl, bev_ssl->old_state, data->fd);
Christopher Wileye8679812015-07-01 13:36:18 -07001317 case BEV_CTRL_GET_FD:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001318 if (bev_ssl->underlying) {
1319 data->fd = event_get_fd(&bev_ssl->underlying->ev_read);
1320 } else {
1321 data->fd = event_get_fd(&bev->ev_read);
1322 }
Christopher Wileye8679812015-07-01 13:36:18 -07001323 return 0;
1324 case BEV_CTRL_GET_UNDERLYING:
Christopher Wileye8679812015-07-01 13:36:18 -07001325 data->ptr = bev_ssl->underlying;
1326 return 0;
1327 case BEV_CTRL_CANCEL_ALL:
1328 default:
1329 return -1;
1330 }
1331}
1332
1333SSL *
1334bufferevent_openssl_get_ssl(struct bufferevent *bufev)
1335{
1336 struct bufferevent_openssl *bev_ssl = upcast(bufev);
1337 if (!bev_ssl)
1338 return NULL;
1339 return bev_ssl->ssl;
1340}
1341
1342static struct bufferevent *
1343bufferevent_openssl_new_impl(struct event_base *base,
1344 struct bufferevent *underlying,
1345 evutil_socket_t fd,
1346 SSL *ssl,
1347 enum bufferevent_ssl_state state,
1348 int options)
1349{
1350 struct bufferevent_openssl *bev_ssl = NULL;
1351 struct bufferevent_private *bev_p = NULL;
1352 int tmp_options = options & ~BEV_OPT_THREADSAFE;
1353
Haibo Huangb2279672019-05-31 16:12:39 -07001354 /* Only one can be set. */
Christopher Wileye8679812015-07-01 13:36:18 -07001355 if (underlying != NULL && fd >= 0)
Haibo Huangb2279672019-05-31 16:12:39 -07001356 goto err;
Christopher Wileye8679812015-07-01 13:36:18 -07001357
1358 if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl))))
1359 goto err;
1360
1361 bev_p = &bev_ssl->bev;
1362
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001363 if (bufferevent_init_common_(bev_p, base,
Christopher Wileye8679812015-07-01 13:36:18 -07001364 &bufferevent_ops_openssl, tmp_options) < 0)
1365 goto err;
1366
1367 /* Don't explode if we decide to realloc a chunk we're writing from in
1368 * the output buffer. */
1369 SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1370
1371 bev_ssl->underlying = underlying;
1372 bev_ssl->ssl = ssl;
1373
1374 bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output,
1375 be_openssl_outbuf_cb, bev_ssl);
1376
1377 if (options & BEV_OPT_THREADSAFE)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001378 bufferevent_enable_locking_(&bev_ssl->bev.bev, NULL);
Christopher Wileye8679812015-07-01 13:36:18 -07001379
1380 if (underlying) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001381 bufferevent_init_generic_timeout_cbs_(&bev_ssl->bev.bev);
1382 bufferevent_incref_(underlying);
Christopher Wileye8679812015-07-01 13:36:18 -07001383 }
1384
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001385 bev_ssl->old_state = state;
Christopher Wileye8679812015-07-01 13:36:18 -07001386 bev_ssl->last_write = -1;
1387
1388 init_bio_counts(bev_ssl);
1389
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001390 fd = be_openssl_auto_fd(bev_ssl, fd);
1391 if (be_openssl_set_fd(bev_ssl, state, fd))
Christopher Wileye8679812015-07-01 13:36:18 -07001392 goto err;
Christopher Wileye8679812015-07-01 13:36:18 -07001393
1394 if (underlying) {
1395 bufferevent_setwatermark(underlying, EV_READ, 0, 0);
1396 bufferevent_enable(underlying, EV_READ|EV_WRITE);
1397 if (state == BUFFEREVENT_SSL_OPEN)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001398 bufferevent_suspend_read_(underlying,
Christopher Wileye8679812015-07-01 13:36:18 -07001399 BEV_SUSPEND_FILT_READ);
Christopher Wileye8679812015-07-01 13:36:18 -07001400 }
1401
1402 return &bev_ssl->bev.bev;
1403err:
Haibo Huangb2279672019-05-31 16:12:39 -07001404 if (options & BEV_OPT_CLOSE_ON_FREE)
1405 SSL_free(ssl);
1406 if (bev_ssl) {
1407 bev_ssl->ssl = NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001408 bufferevent_free(&bev_ssl->bev.bev);
Haibo Huangb2279672019-05-31 16:12:39 -07001409 }
Christopher Wileye8679812015-07-01 13:36:18 -07001410 return NULL;
1411}
1412
1413struct bufferevent *
1414bufferevent_openssl_filter_new(struct event_base *base,
1415 struct bufferevent *underlying,
1416 SSL *ssl,
1417 enum bufferevent_ssl_state state,
1418 int options)
1419{
Christopher Wileye8679812015-07-01 13:36:18 -07001420 BIO *bio;
Haibo Huangb2279672019-05-31 16:12:39 -07001421 struct bufferevent *bev;
1422
Christopher Wileye8679812015-07-01 13:36:18 -07001423 if (!underlying)
Haibo Huangb2279672019-05-31 16:12:39 -07001424 goto err;
1425 if (!(bio = BIO_new_bufferevent(underlying)))
1426 goto err;
Christopher Wileye8679812015-07-01 13:36:18 -07001427
1428 SSL_set_bio(ssl, bio, bio);
1429
Haibo Huangb2279672019-05-31 16:12:39 -07001430 bev = bufferevent_openssl_new_impl(
Christopher Wileye8679812015-07-01 13:36:18 -07001431 base, underlying, -1, ssl, state, options);
Haibo Huangb2279672019-05-31 16:12:39 -07001432 return bev;
1433
1434err:
1435 if (options & BEV_OPT_CLOSE_ON_FREE)
1436 SSL_free(ssl);
1437 return NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001438}
1439
1440struct bufferevent *
1441bufferevent_openssl_socket_new(struct event_base *base,
1442 evutil_socket_t fd,
1443 SSL *ssl,
1444 enum bufferevent_ssl_state state,
1445 int options)
1446{
1447 /* Does the SSL already have an fd? */
1448 BIO *bio = SSL_get_wbio(ssl);
1449 long have_fd = -1;
1450
1451 if (bio)
1452 have_fd = BIO_get_fd(bio, NULL);
1453
1454 if (have_fd >= 0) {
1455 /* The SSL is already configured with an fd. */
1456 if (fd < 0) {
1457 /* We should learn the fd from the SSL. */
1458 fd = (evutil_socket_t) have_fd;
1459 } else if (have_fd == (long)fd) {
1460 /* We already know the fd from the SSL; do nothing */
1461 } else {
1462 /* We specified an fd different from that of the SSL.
1463 This is probably an error on our part. Fail. */
Haibo Huangb2279672019-05-31 16:12:39 -07001464 goto err;
Christopher Wileye8679812015-07-01 13:36:18 -07001465 }
Haibo Huangb2279672019-05-31 16:12:39 -07001466 BIO_set_close(bio, 0);
Christopher Wileye8679812015-07-01 13:36:18 -07001467 } else {
1468 /* The SSL isn't configured with a BIO with an fd. */
1469 if (fd >= 0) {
1470 /* ... and we have an fd we want to use. */
Haibo Huangb2279672019-05-31 16:12:39 -07001471 bio = BIO_new_socket((int)fd, 0);
Christopher Wileye8679812015-07-01 13:36:18 -07001472 SSL_set_bio(ssl, bio, bio);
1473 } else {
1474 /* Leave the fd unset. */
1475 }
1476 }
1477
1478 return bufferevent_openssl_new_impl(
1479 base, NULL, fd, ssl, state, options);
Haibo Huangb2279672019-05-31 16:12:39 -07001480
1481err:
1482 if (options & BEV_OPT_CLOSE_ON_FREE)
1483 SSL_free(ssl);
1484 return NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001485}
1486
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001487int
1488bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
1489{
1490 int allow_dirty_shutdown = -1;
1491 struct bufferevent_openssl *bev_ssl;
1492 BEV_LOCK(bev);
1493 bev_ssl = upcast(bev);
1494 if (bev_ssl)
1495 allow_dirty_shutdown = bev_ssl->allow_dirty_shutdown;
1496 BEV_UNLOCK(bev);
1497 return allow_dirty_shutdown;
1498}
1499
1500void
1501bufferevent_openssl_set_allow_dirty_shutdown(struct bufferevent *bev,
1502 int allow_dirty_shutdown)
1503{
1504 struct bufferevent_openssl *bev_ssl;
1505 BEV_LOCK(bev);
1506 bev_ssl = upcast(bev);
1507 if (bev_ssl)
1508 bev_ssl->allow_dirty_shutdown = !!allow_dirty_shutdown;
1509 BEV_UNLOCK(bev);
1510}
1511
Christopher Wileye8679812015-07-01 13:36:18 -07001512unsigned long
1513bufferevent_get_openssl_error(struct bufferevent *bev)
1514{
1515 unsigned long err = 0;
1516 struct bufferevent_openssl *bev_ssl;
1517 BEV_LOCK(bev);
1518 bev_ssl = upcast(bev);
1519 if (bev_ssl && bev_ssl->n_errors) {
1520 err = bev_ssl->errors[--bev_ssl->n_errors];
1521 }
1522 BEV_UNLOCK(bev);
1523 return err;
1524}