1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/bufferevent_openssl.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1454 @@ 1.4 +/* 1.5 + * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 3. The name of the author may not be used to endorse or promote products 1.16 + * derived from this software without specific prior written permission. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.28 + */ 1.29 + 1.30 +#include <sys/types.h> 1.31 + 1.32 +#include "event2/event-config.h" 1.33 + 1.34 +#ifdef _EVENT_HAVE_SYS_TIME_H 1.35 +#include <sys/time.h> 1.36 +#endif 1.37 + 1.38 +#include <errno.h> 1.39 +#include <stdio.h> 1.40 +#include <stdlib.h> 1.41 +#include <string.h> 1.42 +#ifdef _EVENT_HAVE_STDARG_H 1.43 +#include <stdarg.h> 1.44 +#endif 1.45 +#ifdef _EVENT_HAVE_UNISTD_H 1.46 +#include <unistd.h> 1.47 +#endif 1.48 + 1.49 +#ifdef WIN32 1.50 +#include <winsock2.h> 1.51 +#endif 1.52 + 1.53 +#include "event2/bufferevent.h" 1.54 +#include "event2/bufferevent_struct.h" 1.55 +#include "event2/bufferevent_ssl.h" 1.56 +#include "event2/buffer.h" 1.57 +#include "event2/event.h" 1.58 + 1.59 +#include "mm-internal.h" 1.60 +#include "bufferevent-internal.h" 1.61 +#include "log-internal.h" 1.62 + 1.63 +#include <openssl/bio.h> 1.64 +#include <openssl/ssl.h> 1.65 +#include <openssl/err.h> 1.66 + 1.67 +/* 1.68 + * Define an OpenSSL bio that targets a bufferevent. 1.69 + */ 1.70 + 1.71 +/* -------------------- 1.72 + A BIO is an OpenSSL abstraction that handles reading and writing data. The 1.73 + library will happily speak SSL over anything that implements a BIO 1.74 + interface. 1.75 + 1.76 + Here we define a BIO implementation that directs its output to a 1.77 + bufferevent. We'll want to use this only when none of OpenSSL's built-in 1.78 + IO mechanisms work for us. 1.79 + -------------------- */ 1.80 + 1.81 +/* every BIO type needs its own integer type value. */ 1.82 +#define BIO_TYPE_LIBEVENT 57 1.83 +/* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on 1.84 + * this. */ 1.85 + 1.86 +#if 0 1.87 +static void 1.88 +print_err(int val) 1.89 +{ 1.90 + int err; 1.91 + printf("Error was %d\n", val); 1.92 + 1.93 + while ((err = ERR_get_error())) { 1.94 + const char *msg = (const char*)ERR_reason_error_string(err); 1.95 + const char *lib = (const char*)ERR_lib_error_string(err); 1.96 + const char *func = (const char*)ERR_func_error_string(err); 1.97 + 1.98 + printf("%s in %s %s\n", msg, lib, func); 1.99 + } 1.100 +} 1.101 +#else 1.102 +#define print_err(v) ((void)0) 1.103 +#endif 1.104 + 1.105 +/* Called to initialize a new BIO */ 1.106 +static int 1.107 +bio_bufferevent_new(BIO *b) 1.108 +{ 1.109 + b->init = 0; 1.110 + b->num = -1; 1.111 + b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/ 1.112 + b->flags = 0; 1.113 + return 1; 1.114 +} 1.115 + 1.116 +/* Called to uninitialize the BIO. */ 1.117 +static int 1.118 +bio_bufferevent_free(BIO *b) 1.119 +{ 1.120 + if (!b) 1.121 + return 0; 1.122 + if (b->shutdown) { 1.123 + if (b->init && b->ptr) 1.124 + bufferevent_free(b->ptr); 1.125 + b->init = 0; 1.126 + b->flags = 0; 1.127 + b->ptr = NULL; 1.128 + } 1.129 + return 1; 1.130 +} 1.131 + 1.132 +/* Called to extract data from the BIO. */ 1.133 +static int 1.134 +bio_bufferevent_read(BIO *b, char *out, int outlen) 1.135 +{ 1.136 + int r = 0; 1.137 + struct evbuffer *input; 1.138 + 1.139 + BIO_clear_retry_flags(b); 1.140 + 1.141 + if (!out) 1.142 + return 0; 1.143 + if (!b->ptr) 1.144 + return -1; 1.145 + 1.146 + input = bufferevent_get_input(b->ptr); 1.147 + if (evbuffer_get_length(input) == 0) { 1.148 + /* If there's no data to read, say so. */ 1.149 + BIO_set_retry_read(b); 1.150 + return -1; 1.151 + } else { 1.152 + r = evbuffer_remove(input, out, outlen); 1.153 + } 1.154 + 1.155 + return r; 1.156 +} 1.157 + 1.158 +/* Called to write data info the BIO */ 1.159 +static int 1.160 +bio_bufferevent_write(BIO *b, const char *in, int inlen) 1.161 +{ 1.162 + struct bufferevent *bufev = b->ptr; 1.163 + struct evbuffer *output; 1.164 + size_t outlen; 1.165 + 1.166 + BIO_clear_retry_flags(b); 1.167 + 1.168 + if (!b->ptr) 1.169 + return -1; 1.170 + 1.171 + output = bufferevent_get_output(bufev); 1.172 + outlen = evbuffer_get_length(output); 1.173 + 1.174 + /* Copy only as much data onto the output buffer as can fit under the 1.175 + * high-water mark. */ 1.176 + if (bufev->wm_write.high && bufev->wm_write.high <= (outlen+inlen)) { 1.177 + if (bufev->wm_write.high <= outlen) { 1.178 + /* If no data can fit, we'll need to retry later. */ 1.179 + BIO_set_retry_write(b); 1.180 + return -1; 1.181 + } 1.182 + inlen = bufev->wm_write.high - outlen; 1.183 + } 1.184 + 1.185 + EVUTIL_ASSERT(inlen > 0); 1.186 + evbuffer_add(output, in, inlen); 1.187 + return inlen; 1.188 +} 1.189 + 1.190 +/* Called to handle various requests */ 1.191 +static long 1.192 +bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr) 1.193 +{ 1.194 + struct bufferevent *bufev = b->ptr; 1.195 + long ret = 1; 1.196 + 1.197 + switch (cmd) { 1.198 + case BIO_CTRL_GET_CLOSE: 1.199 + ret = b->shutdown; 1.200 + break; 1.201 + case BIO_CTRL_SET_CLOSE: 1.202 + b->shutdown = (int)num; 1.203 + break; 1.204 + case BIO_CTRL_PENDING: 1.205 + ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0; 1.206 + break; 1.207 + case BIO_CTRL_WPENDING: 1.208 + ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0; 1.209 + break; 1.210 + /* XXXX These two are given a special-case treatment because 1.211 + * of cargo-cultism. I should come up with a better reason. */ 1.212 + case BIO_CTRL_DUP: 1.213 + case BIO_CTRL_FLUSH: 1.214 + ret = 1; 1.215 + break; 1.216 + default: 1.217 + ret = 0; 1.218 + break; 1.219 + } 1.220 + return ret; 1.221 +} 1.222 + 1.223 +/* Called to write a string to the BIO */ 1.224 +static int 1.225 +bio_bufferevent_puts(BIO *b, const char *s) 1.226 +{ 1.227 + return bio_bufferevent_write(b, s, strlen(s)); 1.228 +} 1.229 + 1.230 +/* Method table for the bufferevent BIO */ 1.231 +static BIO_METHOD methods_bufferevent = { 1.232 + BIO_TYPE_LIBEVENT, "bufferevent", 1.233 + bio_bufferevent_write, 1.234 + bio_bufferevent_read, 1.235 + bio_bufferevent_puts, 1.236 + NULL /* bio_bufferevent_gets */, 1.237 + bio_bufferevent_ctrl, 1.238 + bio_bufferevent_new, 1.239 + bio_bufferevent_free, 1.240 + NULL /* callback_ctrl */, 1.241 +}; 1.242 + 1.243 +/* Return the method table for the bufferevents BIO */ 1.244 +static BIO_METHOD * 1.245 +BIO_s_bufferevent(void) 1.246 +{ 1.247 + return &methods_bufferevent; 1.248 +} 1.249 + 1.250 +/* Create a new BIO to wrap communication around a bufferevent. If close_flag 1.251 + * is true, the bufferevent will be freed when the BIO is closed. */ 1.252 +static BIO * 1.253 +BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag) 1.254 +{ 1.255 + BIO *result; 1.256 + if (!bufferevent) 1.257 + return NULL; 1.258 + if (!(result = BIO_new(BIO_s_bufferevent()))) 1.259 + return NULL; 1.260 + result->init = 1; 1.261 + result->ptr = bufferevent; 1.262 + result->shutdown = close_flag ? 1 : 0; 1.263 + return result; 1.264 +} 1.265 + 1.266 +/* -------------------- 1.267 + Now, here's the OpenSSL-based implementation of bufferevent. 1.268 + 1.269 + The implementation comes in two flavors: one that connects its SSL object 1.270 + to an underlying bufferevent using a BIO_bufferevent, and one that has the 1.271 + SSL object connect to a socket directly. The latter should generally be 1.272 + faster, except on Windows, where your best bet is using a 1.273 + bufferevent_async. 1.274 + 1.275 + (OpenSSL supports many other BIO types, too. But we can't use any unless 1.276 + we have a good way to get notified when they become readable/writable.) 1.277 + -------------------- */ 1.278 + 1.279 +struct bio_data_counts { 1.280 + unsigned long n_written; 1.281 + unsigned long n_read; 1.282 +}; 1.283 + 1.284 +struct bufferevent_openssl { 1.285 + /* Shared fields with common bufferevent implementation code. 1.286 + If we were set up with an underlying bufferevent, we use the 1.287 + events here as timers only. If we have an SSL, then we use 1.288 + the events as socket events. 1.289 + */ 1.290 + struct bufferevent_private bev; 1.291 + /* An underlying bufferevent that we're directing our output to. 1.292 + If it's NULL, then we're connected to an fd, not an evbuffer. */ 1.293 + struct bufferevent *underlying; 1.294 + /* The SSL object doing our encryption. */ 1.295 + SSL *ssl; 1.296 + 1.297 + /* A callback that's invoked when data arrives on our outbuf so we 1.298 + know to write data to the SSL. */ 1.299 + struct evbuffer_cb_entry *outbuf_cb; 1.300 + 1.301 + /* A count of how much data the bios have read/written total. Used 1.302 + for rate-limiting. */ 1.303 + struct bio_data_counts counts; 1.304 + 1.305 + /* If this value is greater than 0, then the last SSL_write blocked, 1.306 + * and we need to try it again with this many bytes. */ 1.307 + ev_ssize_t last_write; 1.308 + 1.309 +#define NUM_ERRORS 3 1.310 + ev_uint32_t errors[NUM_ERRORS]; 1.311 + 1.312 + /* When we next get available space, we should say "read" instead of 1.313 + "write". This can happen if there's a renegotiation during a read 1.314 + operation. */ 1.315 + unsigned read_blocked_on_write : 1; 1.316 + /* When we next get data, we should say "write" instead of "read". */ 1.317 + unsigned write_blocked_on_read : 1; 1.318 + /* XXX */ 1.319 + unsigned allow_dirty_shutdown : 1; 1.320 + /* XXXX */ 1.321 + unsigned fd_is_set : 1; 1.322 + /* XXX */ 1.323 + unsigned n_errors : 2; 1.324 + 1.325 + /* Are we currently connecting, accepting, or doing IO? */ 1.326 + unsigned state : 2; 1.327 +}; 1.328 + 1.329 +static int be_openssl_enable(struct bufferevent *, short); 1.330 +static int be_openssl_disable(struct bufferevent *, short); 1.331 +static void be_openssl_destruct(struct bufferevent *); 1.332 +static int be_openssl_adj_timeouts(struct bufferevent *); 1.333 +static int be_openssl_flush(struct bufferevent *bufev, 1.334 + short iotype, enum bufferevent_flush_mode mode); 1.335 +static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *); 1.336 + 1.337 +const struct bufferevent_ops bufferevent_ops_openssl = { 1.338 + "ssl", 1.339 + evutil_offsetof(struct bufferevent_openssl, bev.bev), 1.340 + be_openssl_enable, 1.341 + be_openssl_disable, 1.342 + be_openssl_destruct, 1.343 + be_openssl_adj_timeouts, 1.344 + be_openssl_flush, 1.345 + be_openssl_ctrl, 1.346 +}; 1.347 + 1.348 +/* Given a bufferevent, return a pointer to the bufferevent_openssl that 1.349 + * contains it, if any. */ 1.350 +static inline struct bufferevent_openssl * 1.351 +upcast(struct bufferevent *bev) 1.352 +{ 1.353 + struct bufferevent_openssl *bev_o; 1.354 + if (bev->be_ops != &bufferevent_ops_openssl) 1.355 + return NULL; 1.356 + bev_o = (void*)( ((char*)bev) - 1.357 + evutil_offsetof(struct bufferevent_openssl, bev.bev)); 1.358 + EVUTIL_ASSERT(bev_o->bev.bev.be_ops == &bufferevent_ops_openssl); 1.359 + return bev_o; 1.360 +} 1.361 + 1.362 +static inline void 1.363 +put_error(struct bufferevent_openssl *bev_ssl, unsigned long err) 1.364 +{ 1.365 + if (bev_ssl->n_errors == NUM_ERRORS) 1.366 + return; 1.367 + /* The error type according to openssl is "unsigned long", but 1.368 + openssl never uses more than 32 bits of it. It _can't_ use more 1.369 + than 32 bits of it, since it needs to report errors on systems 1.370 + where long is only 32 bits. 1.371 + */ 1.372 + bev_ssl->errors[bev_ssl->n_errors++] = (ev_uint32_t) err; 1.373 +} 1.374 + 1.375 +/* Have the base communications channel (either the underlying bufferevent or 1.376 + * ev_read and ev_write) start reading. Take the read-blocked-on-write flag 1.377 + * into account. */ 1.378 +static int 1.379 +start_reading(struct bufferevent_openssl *bev_ssl) 1.380 +{ 1.381 + if (bev_ssl->underlying) { 1.382 + bufferevent_unsuspend_read(bev_ssl->underlying, 1.383 + BEV_SUSPEND_FILT_READ); 1.384 + return 0; 1.385 + } else { 1.386 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.387 + int r; 1.388 + r = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read); 1.389 + if (r == 0 && bev_ssl->read_blocked_on_write) 1.390 + r = _bufferevent_add_event(&bev->ev_write, 1.391 + &bev->timeout_write); 1.392 + return r; 1.393 + } 1.394 +} 1.395 + 1.396 +/* Have the base communications channel (either the underlying bufferevent or 1.397 + * ev_read and ev_write) start writing. Take the write-blocked-on-read flag 1.398 + * into account. */ 1.399 +static int 1.400 +start_writing(struct bufferevent_openssl *bev_ssl) 1.401 +{ 1.402 + int r = 0; 1.403 + if (bev_ssl->underlying) { 1.404 + ; 1.405 + } else { 1.406 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.407 + r = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write); 1.408 + if (!r && bev_ssl->write_blocked_on_read) 1.409 + r = _bufferevent_add_event(&bev->ev_read, 1.410 + &bev->timeout_read); 1.411 + } 1.412 + return r; 1.413 +} 1.414 + 1.415 +static void 1.416 +stop_reading(struct bufferevent_openssl *bev_ssl) 1.417 +{ 1.418 + if (bev_ssl->write_blocked_on_read) 1.419 + return; 1.420 + if (bev_ssl->underlying) { 1.421 + bufferevent_suspend_read(bev_ssl->underlying, 1.422 + BEV_SUSPEND_FILT_READ); 1.423 + } else { 1.424 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.425 + event_del(&bev->ev_read); 1.426 + } 1.427 +} 1.428 + 1.429 +static void 1.430 +stop_writing(struct bufferevent_openssl *bev_ssl) 1.431 +{ 1.432 + if (bev_ssl->read_blocked_on_write) 1.433 + return; 1.434 + if (bev_ssl->underlying) { 1.435 + ; 1.436 + } else { 1.437 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.438 + event_del(&bev->ev_write); 1.439 + } 1.440 +} 1.441 + 1.442 +static int 1.443 +set_rbow(struct bufferevent_openssl *bev_ssl) 1.444 +{ 1.445 + if (!bev_ssl->underlying) 1.446 + stop_reading(bev_ssl); 1.447 + bev_ssl->read_blocked_on_write = 1; 1.448 + return start_writing(bev_ssl); 1.449 +} 1.450 + 1.451 +static int 1.452 +set_wbor(struct bufferevent_openssl *bev_ssl) 1.453 +{ 1.454 + if (!bev_ssl->underlying) 1.455 + stop_writing(bev_ssl); 1.456 + bev_ssl->write_blocked_on_read = 1; 1.457 + return start_reading(bev_ssl); 1.458 +} 1.459 + 1.460 +static int 1.461 +clear_rbow(struct bufferevent_openssl *bev_ssl) 1.462 +{ 1.463 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.464 + int r = 0; 1.465 + bev_ssl->read_blocked_on_write = 0; 1.466 + if (!(bev->enabled & EV_WRITE)) 1.467 + stop_writing(bev_ssl); 1.468 + if (bev->enabled & EV_READ) 1.469 + r = start_reading(bev_ssl); 1.470 + return r; 1.471 +} 1.472 + 1.473 + 1.474 +static int 1.475 +clear_wbor(struct bufferevent_openssl *bev_ssl) 1.476 +{ 1.477 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.478 + int r = 0; 1.479 + bev_ssl->write_blocked_on_read = 0; 1.480 + if (!(bev->enabled & EV_READ)) 1.481 + stop_reading(bev_ssl); 1.482 + if (bev->enabled & EV_WRITE) 1.483 + r = start_writing(bev_ssl); 1.484 + return r; 1.485 +} 1.486 + 1.487 +static void 1.488 +conn_closed(struct bufferevent_openssl *bev_ssl, int errcode, int ret) 1.489 +{ 1.490 + int event = BEV_EVENT_ERROR; 1.491 + int dirty_shutdown = 0; 1.492 + unsigned long err; 1.493 + 1.494 + switch (errcode) { 1.495 + case SSL_ERROR_ZERO_RETURN: 1.496 + /* Possibly a clean shutdown. */ 1.497 + if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN) 1.498 + event = BEV_EVENT_EOF; 1.499 + else 1.500 + dirty_shutdown = 1; 1.501 + break; 1.502 + case SSL_ERROR_SYSCALL: 1.503 + /* IO error; possibly a dirty shutdown. */ 1.504 + if (ret == 0 && ERR_peek_error() == 0) 1.505 + dirty_shutdown = 1; 1.506 + break; 1.507 + case SSL_ERROR_SSL: 1.508 + /* Protocol error. */ 1.509 + break; 1.510 + case SSL_ERROR_WANT_X509_LOOKUP: 1.511 + /* XXXX handle this. */ 1.512 + break; 1.513 + case SSL_ERROR_NONE: 1.514 + case SSL_ERROR_WANT_READ: 1.515 + case SSL_ERROR_WANT_WRITE: 1.516 + case SSL_ERROR_WANT_CONNECT: 1.517 + case SSL_ERROR_WANT_ACCEPT: 1.518 + default: 1.519 + /* should be impossible; treat as normal error. */ 1.520 + event_warnx("BUG: Unexpected OpenSSL error code %d", errcode); 1.521 + break; 1.522 + } 1.523 + 1.524 + while ((err = ERR_get_error())) { 1.525 + put_error(bev_ssl, err); 1.526 + } 1.527 + 1.528 + if (dirty_shutdown && bev_ssl->allow_dirty_shutdown) 1.529 + event = BEV_EVENT_EOF; 1.530 + 1.531 + stop_reading(bev_ssl); 1.532 + stop_writing(bev_ssl); 1.533 + 1.534 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, event); 1.535 +} 1.536 + 1.537 +static void 1.538 +init_bio_counts(struct bufferevent_openssl *bev_ssl) 1.539 +{ 1.540 + bev_ssl->counts.n_written = 1.541 + BIO_number_written(SSL_get_wbio(bev_ssl->ssl)); 1.542 + bev_ssl->counts.n_read = 1.543 + BIO_number_read(SSL_get_rbio(bev_ssl->ssl)); 1.544 +} 1.545 + 1.546 +static inline void 1.547 +decrement_buckets(struct bufferevent_openssl *bev_ssl) 1.548 +{ 1.549 + unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl)); 1.550 + unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl)); 1.551 + /* These next two subtractions can wrap around. That's okay. */ 1.552 + unsigned long w = num_w - bev_ssl->counts.n_written; 1.553 + unsigned long r = num_r - bev_ssl->counts.n_read; 1.554 + if (w) 1.555 + _bufferevent_decrement_write_buckets(&bev_ssl->bev, w); 1.556 + if (r) 1.557 + _bufferevent_decrement_read_buckets(&bev_ssl->bev, r); 1.558 + bev_ssl->counts.n_written = num_w; 1.559 + bev_ssl->counts.n_read = num_r; 1.560 +} 1.561 + 1.562 +#define OP_MADE_PROGRESS 1 1.563 +#define OP_BLOCKED 2 1.564 +#define OP_ERR 4 1.565 + 1.566 +/* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if 1.567 + we're now blocked); and OP_ERR (if an error occurred). */ 1.568 +static int 1.569 +do_read(struct bufferevent_openssl *bev_ssl, int n_to_read) { 1.570 + /* Requires lock */ 1.571 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.572 + struct evbuffer *input = bev->input; 1.573 + int r, n, i, n_used = 0, atmost; 1.574 + struct evbuffer_iovec space[2]; 1.575 + int result = 0; 1.576 + 1.577 + if (bev_ssl->bev.read_suspended) 1.578 + return 0; 1.579 + 1.580 + atmost = _bufferevent_get_read_max(&bev_ssl->bev); 1.581 + if (n_to_read > atmost) 1.582 + n_to_read = atmost; 1.583 + 1.584 + n = evbuffer_reserve_space(input, n_to_read, space, 2); 1.585 + if (n < 0) 1.586 + return OP_ERR; 1.587 + 1.588 + for (i=0; i<n; ++i) { 1.589 + if (bev_ssl->bev.read_suspended) 1.590 + break; 1.591 + r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len); 1.592 + if (r>0) { 1.593 + result |= OP_MADE_PROGRESS; 1.594 + if (bev_ssl->read_blocked_on_write) 1.595 + if (clear_rbow(bev_ssl) < 0) 1.596 + return OP_ERR | result; 1.597 + ++n_used; 1.598 + space[i].iov_len = r; 1.599 + decrement_buckets(bev_ssl); 1.600 + } else { 1.601 + int err = SSL_get_error(bev_ssl->ssl, r); 1.602 + print_err(err); 1.603 + switch (err) { 1.604 + case SSL_ERROR_WANT_READ: 1.605 + /* Can't read until underlying has more data. */ 1.606 + if (bev_ssl->read_blocked_on_write) 1.607 + if (clear_rbow(bev_ssl) < 0) 1.608 + return OP_ERR | result; 1.609 + break; 1.610 + case SSL_ERROR_WANT_WRITE: 1.611 + /* This read operation requires a write, and the 1.612 + * underlying is full */ 1.613 + if (!bev_ssl->read_blocked_on_write) 1.614 + if (set_rbow(bev_ssl) < 0) 1.615 + return OP_ERR | result; 1.616 + break; 1.617 + default: 1.618 + conn_closed(bev_ssl, err, r); 1.619 + break; 1.620 + } 1.621 + result |= OP_BLOCKED; 1.622 + break; /* out of the loop */ 1.623 + } 1.624 + } 1.625 + 1.626 + if (n_used) { 1.627 + evbuffer_commit_space(input, space, n_used); 1.628 + if (bev_ssl->underlying) 1.629 + BEV_RESET_GENERIC_READ_TIMEOUT(bev); 1.630 + } 1.631 + 1.632 + return result; 1.633 +} 1.634 + 1.635 +/* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if 1.636 + we're now blocked); and OP_ERR (if an error occurred). */ 1.637 +static int 1.638 +do_write(struct bufferevent_openssl *bev_ssl, int atmost) 1.639 +{ 1.640 + int i, r, n, n_written = 0; 1.641 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.642 + struct evbuffer *output = bev->output; 1.643 + struct evbuffer_iovec space[8]; 1.644 + int result = 0; 1.645 + 1.646 + if (bev_ssl->last_write > 0) 1.647 + atmost = bev_ssl->last_write; 1.648 + else 1.649 + atmost = _bufferevent_get_write_max(&bev_ssl->bev); 1.650 + 1.651 + n = evbuffer_peek(output, atmost, NULL, space, 8); 1.652 + if (n < 0) 1.653 + return OP_ERR | result; 1.654 + 1.655 + if (n > 8) 1.656 + n = 8; 1.657 + for (i=0; i < n; ++i) { 1.658 + if (bev_ssl->bev.write_suspended) 1.659 + break; 1.660 + 1.661 + /* SSL_write will (reasonably) return 0 if we tell it to 1.662 + send 0 data. Skip this case so we don't interpret the 1.663 + result as an error */ 1.664 + if (space[i].iov_len == 0) 1.665 + continue; 1.666 + 1.667 + r = SSL_write(bev_ssl->ssl, space[i].iov_base, 1.668 + space[i].iov_len); 1.669 + if (r > 0) { 1.670 + result |= OP_MADE_PROGRESS; 1.671 + if (bev_ssl->write_blocked_on_read) 1.672 + if (clear_wbor(bev_ssl) < 0) 1.673 + return OP_ERR | result; 1.674 + n_written += r; 1.675 + bev_ssl->last_write = -1; 1.676 + decrement_buckets(bev_ssl); 1.677 + } else { 1.678 + int err = SSL_get_error(bev_ssl->ssl, r); 1.679 + print_err(err); 1.680 + switch (err) { 1.681 + case SSL_ERROR_WANT_WRITE: 1.682 + /* Can't read until underlying has more data. */ 1.683 + if (bev_ssl->write_blocked_on_read) 1.684 + if (clear_wbor(bev_ssl) < 0) 1.685 + return OP_ERR | result; 1.686 + bev_ssl->last_write = space[i].iov_len; 1.687 + break; 1.688 + case SSL_ERROR_WANT_READ: 1.689 + /* This read operation requires a write, and the 1.690 + * underlying is full */ 1.691 + if (!bev_ssl->write_blocked_on_read) 1.692 + if (set_wbor(bev_ssl) < 0) 1.693 + return OP_ERR | result; 1.694 + bev_ssl->last_write = space[i].iov_len; 1.695 + break; 1.696 + default: 1.697 + conn_closed(bev_ssl, err, r); 1.698 + bev_ssl->last_write = -1; 1.699 + break; 1.700 + } 1.701 + result |= OP_BLOCKED; 1.702 + break; 1.703 + } 1.704 + } 1.705 + if (n_written) { 1.706 + evbuffer_drain(output, n_written); 1.707 + if (bev_ssl->underlying) 1.708 + BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); 1.709 + 1.710 + if (evbuffer_get_length(output) <= bev->wm_write.low) 1.711 + _bufferevent_run_writecb(bev); 1.712 + } 1.713 + return result; 1.714 +} 1.715 + 1.716 +#define WRITE_FRAME 15000 1.717 + 1.718 +#define READ_DEFAULT 4096 1.719 + 1.720 +/* Try to figure out how many bytes to read; return 0 if we shouldn't be 1.721 + * reading. */ 1.722 +static int 1.723 +bytes_to_read(struct bufferevent_openssl *bev) 1.724 +{ 1.725 + struct evbuffer *input = bev->bev.bev.input; 1.726 + struct event_watermark *wm = &bev->bev.bev.wm_read; 1.727 + int result = READ_DEFAULT; 1.728 + ev_ssize_t limit; 1.729 + /* XXX 99% of this is generic code that nearly all bufferevents will 1.730 + * want. */ 1.731 + 1.732 + if (bev->write_blocked_on_read) { 1.733 + return 0; 1.734 + } 1.735 + 1.736 + if (! (bev->bev.bev.enabled & EV_READ)) { 1.737 + return 0; 1.738 + } 1.739 + 1.740 + if (bev->bev.read_suspended) { 1.741 + return 0; 1.742 + } 1.743 + 1.744 + if (wm->high) { 1.745 + if (evbuffer_get_length(input) >= wm->high) { 1.746 + return 0; 1.747 + } 1.748 + 1.749 + result = wm->high - evbuffer_get_length(input); 1.750 + } else { 1.751 + result = READ_DEFAULT; 1.752 + } 1.753 + 1.754 + /* Respect the rate limit */ 1.755 + limit = _bufferevent_get_read_max(&bev->bev); 1.756 + if (result > limit) { 1.757 + result = limit; 1.758 + } 1.759 + 1.760 + return result; 1.761 +} 1.762 + 1.763 + 1.764 +/* Things look readable. If write is blocked on read, write till it isn't. 1.765 + * Read from the underlying buffer until we block or we hit our high-water 1.766 + * mark. 1.767 + */ 1.768 +static void 1.769 +consider_reading(struct bufferevent_openssl *bev_ssl) 1.770 +{ 1.771 + int r; 1.772 + int n_to_read; 1.773 + int all_result_flags = 0; 1.774 + 1.775 + while (bev_ssl->write_blocked_on_read) { 1.776 + r = do_write(bev_ssl, WRITE_FRAME); 1.777 + if (r & (OP_BLOCKED|OP_ERR)) 1.778 + break; 1.779 + } 1.780 + if (bev_ssl->write_blocked_on_read) 1.781 + return; 1.782 + 1.783 + n_to_read = bytes_to_read(bev_ssl); 1.784 + 1.785 + while (n_to_read) { 1.786 + r = do_read(bev_ssl, n_to_read); 1.787 + all_result_flags |= r; 1.788 + 1.789 + if (r & (OP_BLOCKED|OP_ERR)) 1.790 + break; 1.791 + 1.792 + if (bev_ssl->bev.read_suspended) 1.793 + break; 1.794 + 1.795 + /* Read all pending data. This won't hit the network 1.796 + * again, and will (most importantly) put us in a state 1.797 + * where we don't need to read anything else until the 1.798 + * socket is readable again. It'll potentially make us 1.799 + * overrun our read high-watermark (somewhat 1.800 + * regrettable). The damage to the rate-limit has 1.801 + * already been done, since OpenSSL went and read a 1.802 + * whole SSL record anyway. */ 1.803 + n_to_read = SSL_pending(bev_ssl->ssl); 1.804 + 1.805 + /* XXX This if statement is actually a bad bug, added to avoid 1.806 + * XXX a worse bug. 1.807 + * 1.808 + * The bad bug: It can potentially cause resource unfairness 1.809 + * by reading too much data from the underlying bufferevent; 1.810 + * it can potentially cause read looping if the underlying 1.811 + * bufferevent is a bufferevent_pair and deferred callbacks 1.812 + * aren't used. 1.813 + * 1.814 + * The worse bug: If we didn't do this, then we would 1.815 + * potentially not read any more from bev_ssl->underlying 1.816 + * until more data arrived there, which could lead to us 1.817 + * waiting forever. 1.818 + */ 1.819 + if (!n_to_read && bev_ssl->underlying) 1.820 + n_to_read = bytes_to_read(bev_ssl); 1.821 + } 1.822 + 1.823 + if (all_result_flags & OP_MADE_PROGRESS) { 1.824 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.825 + struct evbuffer *input = bev->input; 1.826 + 1.827 + if (evbuffer_get_length(input) >= bev->wm_read.low) { 1.828 + _bufferevent_run_readcb(bev); 1.829 + } 1.830 + } 1.831 + 1.832 + if (!bev_ssl->underlying) { 1.833 + /* Should be redundant, but let's avoid busy-looping */ 1.834 + if (bev_ssl->bev.read_suspended || 1.835 + !(bev_ssl->bev.bev.enabled & EV_READ)) { 1.836 + event_del(&bev_ssl->bev.bev.ev_read); 1.837 + } 1.838 + } 1.839 +} 1.840 + 1.841 +static void 1.842 +consider_writing(struct bufferevent_openssl *bev_ssl) 1.843 +{ 1.844 + int r; 1.845 + struct evbuffer *output = bev_ssl->bev.bev.output; 1.846 + struct evbuffer *target = NULL; 1.847 + struct event_watermark *wm = NULL; 1.848 + 1.849 + while (bev_ssl->read_blocked_on_write) { 1.850 + r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */ 1.851 + if (r & OP_MADE_PROGRESS) { 1.852 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.853 + struct evbuffer *input = bev->input; 1.854 + 1.855 + if (evbuffer_get_length(input) >= bev->wm_read.low) { 1.856 + _bufferevent_run_readcb(bev); 1.857 + } 1.858 + } 1.859 + if (r & (OP_ERR|OP_BLOCKED)) 1.860 + break; 1.861 + } 1.862 + if (bev_ssl->read_blocked_on_write) 1.863 + return; 1.864 + if (bev_ssl->underlying) { 1.865 + target = bev_ssl->underlying->output; 1.866 + wm = &bev_ssl->underlying->wm_write; 1.867 + } 1.868 + while ((bev_ssl->bev.bev.enabled & EV_WRITE) && 1.869 + (! bev_ssl->bev.write_suspended) && 1.870 + evbuffer_get_length(output) && 1.871 + (!target || (! wm->high || evbuffer_get_length(target) < wm->high))) { 1.872 + int n_to_write; 1.873 + if (wm && wm->high) 1.874 + n_to_write = wm->high - evbuffer_get_length(target); 1.875 + else 1.876 + n_to_write = WRITE_FRAME; 1.877 + r = do_write(bev_ssl, n_to_write); 1.878 + if (r & (OP_BLOCKED|OP_ERR)) 1.879 + break; 1.880 + } 1.881 + 1.882 + if (!bev_ssl->underlying) { 1.883 + if (evbuffer_get_length(output) == 0) { 1.884 + event_del(&bev_ssl->bev.bev.ev_write); 1.885 + } else if (bev_ssl->bev.write_suspended || 1.886 + !(bev_ssl->bev.bev.enabled & EV_WRITE)) { 1.887 + /* Should be redundant, but let's avoid busy-looping */ 1.888 + event_del(&bev_ssl->bev.bev.ev_write); 1.889 + } 1.890 + } 1.891 +} 1.892 + 1.893 +static void 1.894 +be_openssl_readcb(struct bufferevent *bev_base, void *ctx) 1.895 +{ 1.896 + struct bufferevent_openssl *bev_ssl = ctx; 1.897 + consider_reading(bev_ssl); 1.898 +} 1.899 + 1.900 +static void 1.901 +be_openssl_writecb(struct bufferevent *bev_base, void *ctx) 1.902 +{ 1.903 + struct bufferevent_openssl *bev_ssl = ctx; 1.904 + consider_writing(bev_ssl); 1.905 +} 1.906 + 1.907 +static void 1.908 +be_openssl_eventcb(struct bufferevent *bev_base, short what, void *ctx) 1.909 +{ 1.910 + struct bufferevent_openssl *bev_ssl = ctx; 1.911 + int event = 0; 1.912 + 1.913 + if (what & BEV_EVENT_EOF) { 1.914 + if (bev_ssl->allow_dirty_shutdown) 1.915 + event = BEV_EVENT_EOF; 1.916 + else 1.917 + event = BEV_EVENT_ERROR; 1.918 + } else if (what & BEV_EVENT_TIMEOUT) { 1.919 + /* We sure didn't set this. Propagate it to the user. */ 1.920 + event = what; 1.921 + } else if (what & BEV_EVENT_ERROR) { 1.922 + /* An error occurred on the connection. Propagate it to the user. */ 1.923 + event = what; 1.924 + } else if (what & BEV_EVENT_CONNECTED) { 1.925 + /* Ignore it. We're saying SSL_connect() already, which will 1.926 + eat it. */ 1.927 + } 1.928 + if (event) 1.929 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, event); 1.930 +} 1.931 + 1.932 +static void 1.933 +be_openssl_readeventcb(evutil_socket_t fd, short what, void *ptr) 1.934 +{ 1.935 + struct bufferevent_openssl *bev_ssl = ptr; 1.936 + _bufferevent_incref_and_lock(&bev_ssl->bev.bev); 1.937 + if (what == EV_TIMEOUT) { 1.938 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, 1.939 + BEV_EVENT_TIMEOUT|BEV_EVENT_READING); 1.940 + } else { 1.941 + consider_reading(bev_ssl); 1.942 + } 1.943 + _bufferevent_decref_and_unlock(&bev_ssl->bev.bev); 1.944 +} 1.945 + 1.946 +static void 1.947 +be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr) 1.948 +{ 1.949 + struct bufferevent_openssl *bev_ssl = ptr; 1.950 + _bufferevent_incref_and_lock(&bev_ssl->bev.bev); 1.951 + if (what == EV_TIMEOUT) { 1.952 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, 1.953 + BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING); 1.954 + } else { 1.955 + consider_writing(bev_ssl); 1.956 + } 1.957 + _bufferevent_decref_and_unlock(&bev_ssl->bev.bev); 1.958 +} 1.959 + 1.960 +static int 1.961 +set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) 1.962 +{ 1.963 + if (bev_ssl->underlying) { 1.964 + bufferevent_setcb(bev_ssl->underlying, 1.965 + be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb, 1.966 + bev_ssl); 1.967 + return 0; 1.968 + } else { 1.969 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.970 + int rpending=0, wpending=0, r1=0, r2=0; 1.971 + if (fd < 0 && bev_ssl->fd_is_set) 1.972 + fd = event_get_fd(&bev->ev_read); 1.973 + if (bev_ssl->fd_is_set) { 1.974 + rpending = event_pending(&bev->ev_read, EV_READ, NULL); 1.975 + wpending = event_pending(&bev->ev_write, EV_WRITE, NULL); 1.976 + event_del(&bev->ev_read); 1.977 + event_del(&bev->ev_write); 1.978 + } 1.979 + event_assign(&bev->ev_read, bev->ev_base, fd, 1.980 + EV_READ|EV_PERSIST, be_openssl_readeventcb, bev_ssl); 1.981 + event_assign(&bev->ev_write, bev->ev_base, fd, 1.982 + EV_WRITE|EV_PERSIST, be_openssl_writeeventcb, bev_ssl); 1.983 + if (rpending) 1.984 + r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read); 1.985 + if (wpending) 1.986 + r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write); 1.987 + if (fd >= 0) { 1.988 + bev_ssl->fd_is_set = 1; 1.989 + } 1.990 + return (r1<0 || r2<0) ? -1 : 0; 1.991 + } 1.992 +} 1.993 + 1.994 +static int 1.995 +do_handshake(struct bufferevent_openssl *bev_ssl) 1.996 +{ 1.997 + int r; 1.998 + 1.999 + switch (bev_ssl->state) { 1.1000 + default: 1.1001 + case BUFFEREVENT_SSL_OPEN: 1.1002 + EVUTIL_ASSERT(0); 1.1003 + return -1; 1.1004 + case BUFFEREVENT_SSL_CONNECTING: 1.1005 + case BUFFEREVENT_SSL_ACCEPTING: 1.1006 + r = SSL_do_handshake(bev_ssl->ssl); 1.1007 + break; 1.1008 + } 1.1009 + decrement_buckets(bev_ssl); 1.1010 + 1.1011 + if (r==1) { 1.1012 + /* We're done! */ 1.1013 + bev_ssl->state = BUFFEREVENT_SSL_OPEN; 1.1014 + set_open_callbacks(bev_ssl, -1); /* XXXX handle failure */ 1.1015 + /* Call do_read and do_write as needed */ 1.1016 + bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled); 1.1017 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, 1.1018 + BEV_EVENT_CONNECTED); 1.1019 + return 1; 1.1020 + } else { 1.1021 + int err = SSL_get_error(bev_ssl->ssl, r); 1.1022 + print_err(err); 1.1023 + switch (err) { 1.1024 + case SSL_ERROR_WANT_WRITE: 1.1025 + if (!bev_ssl->underlying) { 1.1026 + stop_reading(bev_ssl); 1.1027 + return start_writing(bev_ssl); 1.1028 + } 1.1029 + return 0; 1.1030 + case SSL_ERROR_WANT_READ: 1.1031 + if (!bev_ssl->underlying) { 1.1032 + stop_writing(bev_ssl); 1.1033 + return start_reading(bev_ssl); 1.1034 + } 1.1035 + return 0; 1.1036 + default: 1.1037 + conn_closed(bev_ssl, err, r); 1.1038 + return -1; 1.1039 + } 1.1040 + } 1.1041 +} 1.1042 + 1.1043 +static void 1.1044 +be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx) 1.1045 +{ 1.1046 + struct bufferevent_openssl *bev_ssl = ctx; 1.1047 + do_handshake(bev_ssl);/* XXX handle failure */ 1.1048 +} 1.1049 + 1.1050 +static void 1.1051 +be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr) 1.1052 +{ 1.1053 + struct bufferevent_openssl *bev_ssl = ptr; 1.1054 + 1.1055 + _bufferevent_incref_and_lock(&bev_ssl->bev.bev); 1.1056 + if (what & EV_TIMEOUT) { 1.1057 + _bufferevent_run_eventcb(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT); 1.1058 + } else 1.1059 + do_handshake(bev_ssl);/* XXX handle failure */ 1.1060 + _bufferevent_decref_and_unlock(&bev_ssl->bev.bev); 1.1061 +} 1.1062 + 1.1063 +static int 1.1064 +set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) 1.1065 +{ 1.1066 + if (bev_ssl->underlying) { 1.1067 + bufferevent_setcb(bev_ssl->underlying, 1.1068 + be_openssl_handshakecb, be_openssl_handshakecb, 1.1069 + be_openssl_eventcb, 1.1070 + bev_ssl); 1.1071 + return do_handshake(bev_ssl); 1.1072 + } else { 1.1073 + struct bufferevent *bev = &bev_ssl->bev.bev; 1.1074 + int r1=0, r2=0; 1.1075 + if (fd < 0 && bev_ssl->fd_is_set) 1.1076 + fd = event_get_fd(&bev->ev_read); 1.1077 + if (bev_ssl->fd_is_set) { 1.1078 + event_del(&bev->ev_read); 1.1079 + event_del(&bev->ev_write); 1.1080 + } 1.1081 + event_assign(&bev->ev_read, bev->ev_base, fd, 1.1082 + EV_READ|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl); 1.1083 + event_assign(&bev->ev_write, bev->ev_base, fd, 1.1084 + EV_WRITE|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl); 1.1085 + if (fd >= 0) { 1.1086 + r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read); 1.1087 + r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write); 1.1088 + bev_ssl->fd_is_set = 1; 1.1089 + } 1.1090 + return (r1<0 || r2<0) ? -1 : 0; 1.1091 + } 1.1092 +} 1.1093 + 1.1094 +int 1.1095 +bufferevent_ssl_renegotiate(struct bufferevent *bev) 1.1096 +{ 1.1097 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1098 + if (!bev_ssl) 1.1099 + return -1; 1.1100 + if (SSL_renegotiate(bev_ssl->ssl) < 0) 1.1101 + return -1; 1.1102 + bev_ssl->state = BUFFEREVENT_SSL_CONNECTING; 1.1103 + if (set_handshake_callbacks(bev_ssl, -1) < 0) 1.1104 + return -1; 1.1105 + if (!bev_ssl->underlying) 1.1106 + return do_handshake(bev_ssl); 1.1107 + return 0; 1.1108 +} 1.1109 + 1.1110 +static void 1.1111 +be_openssl_outbuf_cb(struct evbuffer *buf, 1.1112 + const struct evbuffer_cb_info *cbinfo, void *arg) 1.1113 +{ 1.1114 + struct bufferevent_openssl *bev_ssl = arg; 1.1115 + int r = 0; 1.1116 + /* XXX need to hold a reference here. */ 1.1117 + 1.1118 + if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) { 1.1119 + if (cbinfo->orig_size == 0) 1.1120 + r = _bufferevent_add_event(&bev_ssl->bev.bev.ev_write, 1.1121 + &bev_ssl->bev.bev.timeout_write); 1.1122 + consider_writing(bev_ssl); 1.1123 + } 1.1124 + /* XXX Handle r < 0 */ 1.1125 + (void)r; 1.1126 +} 1.1127 + 1.1128 + 1.1129 +static int 1.1130 +be_openssl_enable(struct bufferevent *bev, short events) 1.1131 +{ 1.1132 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1133 + int r1 = 0, r2 = 0; 1.1134 + 1.1135 + if (bev_ssl->state != BUFFEREVENT_SSL_OPEN) 1.1136 + return 0; 1.1137 + 1.1138 + if (events & EV_READ) 1.1139 + r1 = start_reading(bev_ssl); 1.1140 + if (events & EV_WRITE) 1.1141 + r2 = start_writing(bev_ssl); 1.1142 + 1.1143 + if (bev_ssl->underlying) { 1.1144 + if (events & EV_READ) 1.1145 + BEV_RESET_GENERIC_READ_TIMEOUT(bev); 1.1146 + if (events & EV_WRITE) 1.1147 + BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); 1.1148 + 1.1149 + if (events & EV_READ) 1.1150 + consider_reading(bev_ssl); 1.1151 + if (events & EV_WRITE) 1.1152 + consider_writing(bev_ssl); 1.1153 + } 1.1154 + return (r1 < 0 || r2 < 0) ? -1 : 0; 1.1155 +} 1.1156 + 1.1157 +static int 1.1158 +be_openssl_disable(struct bufferevent *bev, short events) 1.1159 +{ 1.1160 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1161 + if (bev_ssl->state != BUFFEREVENT_SSL_OPEN) 1.1162 + return 0; 1.1163 + 1.1164 + if (events & EV_READ) 1.1165 + stop_reading(bev_ssl); 1.1166 + if (events & EV_WRITE) 1.1167 + stop_writing(bev_ssl); 1.1168 + 1.1169 + if (bev_ssl->underlying) { 1.1170 + if (events & EV_READ) 1.1171 + BEV_DEL_GENERIC_READ_TIMEOUT(bev); 1.1172 + if (events & EV_WRITE) 1.1173 + BEV_DEL_GENERIC_WRITE_TIMEOUT(bev); 1.1174 + } 1.1175 + return 0; 1.1176 +} 1.1177 + 1.1178 +static void 1.1179 +be_openssl_destruct(struct bufferevent *bev) 1.1180 +{ 1.1181 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1182 + 1.1183 + if (bev_ssl->underlying) { 1.1184 + _bufferevent_del_generic_timeout_cbs(bev); 1.1185 + } else { 1.1186 + event_del(&bev->ev_read); 1.1187 + event_del(&bev->ev_write); 1.1188 + } 1.1189 + 1.1190 + if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) { 1.1191 + if (bev_ssl->underlying) { 1.1192 + if (BEV_UPCAST(bev_ssl->underlying)->refcnt < 2) { 1.1193 + event_warnx("BEV_OPT_CLOSE_ON_FREE set on an " 1.1194 + "bufferevent with too few references"); 1.1195 + } else { 1.1196 + bufferevent_free(bev_ssl->underlying); 1.1197 + bev_ssl->underlying = NULL; 1.1198 + } 1.1199 + } else { 1.1200 + evutil_socket_t fd = -1; 1.1201 + BIO *bio = SSL_get_wbio(bev_ssl->ssl); 1.1202 + if (bio) 1.1203 + fd = BIO_get_fd(bio, NULL); 1.1204 + if (fd >= 0) 1.1205 + evutil_closesocket(fd); 1.1206 + } 1.1207 + SSL_free(bev_ssl->ssl); 1.1208 + } else { 1.1209 + if (bev_ssl->underlying) { 1.1210 + if (bev_ssl->underlying->errorcb == be_openssl_eventcb) 1.1211 + bufferevent_setcb(bev_ssl->underlying, 1.1212 + NULL,NULL,NULL,NULL); 1.1213 + bufferevent_unsuspend_read(bev_ssl->underlying, 1.1214 + BEV_SUSPEND_FILT_READ); 1.1215 + } 1.1216 + } 1.1217 +} 1.1218 + 1.1219 +static int 1.1220 +be_openssl_adj_timeouts(struct bufferevent *bev) 1.1221 +{ 1.1222 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1223 + 1.1224 + if (bev_ssl->underlying) 1.1225 + return _bufferevent_generic_adj_timeouts(bev); 1.1226 + else { 1.1227 + int r1=0, r2=0; 1.1228 + if (event_pending(&bev->ev_read, EV_READ, NULL)) 1.1229 + r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read); 1.1230 + if (event_pending(&bev->ev_write, EV_WRITE, NULL)) 1.1231 + r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write); 1.1232 + return (r1<0 || r2<0) ? -1 : 0; 1.1233 + } 1.1234 +} 1.1235 + 1.1236 +static int 1.1237 +be_openssl_flush(struct bufferevent *bufev, 1.1238 + short iotype, enum bufferevent_flush_mode mode) 1.1239 +{ 1.1240 + /* XXXX Implement this. */ 1.1241 + return 0; 1.1242 +} 1.1243 + 1.1244 +static int 1.1245 +be_openssl_ctrl(struct bufferevent *bev, 1.1246 + enum bufferevent_ctrl_op op, union bufferevent_ctrl_data *data) 1.1247 +{ 1.1248 + struct bufferevent_openssl *bev_ssl = upcast(bev); 1.1249 + switch (op) { 1.1250 + case BEV_CTRL_SET_FD: 1.1251 + if (bev_ssl->underlying) 1.1252 + return -1; 1.1253 + { 1.1254 + BIO *bio; 1.1255 + bio = BIO_new_socket(data->fd, 0); 1.1256 + SSL_set_bio(bev_ssl->ssl, bio, bio); 1.1257 + bev_ssl->fd_is_set = 1; 1.1258 + } 1.1259 + if (bev_ssl->state == BUFFEREVENT_SSL_OPEN) 1.1260 + return set_open_callbacks(bev_ssl, data->fd); 1.1261 + else { 1.1262 + return set_handshake_callbacks(bev_ssl, data->fd); 1.1263 + } 1.1264 + case BEV_CTRL_GET_FD: 1.1265 + if (bev_ssl->underlying) 1.1266 + return -1; 1.1267 + if (!bev_ssl->fd_is_set) 1.1268 + return -1; 1.1269 + data->fd = event_get_fd(&bev->ev_read); 1.1270 + return 0; 1.1271 + case BEV_CTRL_GET_UNDERLYING: 1.1272 + if (!bev_ssl->underlying) 1.1273 + return -1; 1.1274 + data->ptr = bev_ssl->underlying; 1.1275 + return 0; 1.1276 + case BEV_CTRL_CANCEL_ALL: 1.1277 + default: 1.1278 + return -1; 1.1279 + } 1.1280 +} 1.1281 + 1.1282 +SSL * 1.1283 +bufferevent_openssl_get_ssl(struct bufferevent *bufev) 1.1284 +{ 1.1285 + struct bufferevent_openssl *bev_ssl = upcast(bufev); 1.1286 + if (!bev_ssl) 1.1287 + return NULL; 1.1288 + return bev_ssl->ssl; 1.1289 +} 1.1290 + 1.1291 +static struct bufferevent * 1.1292 +bufferevent_openssl_new_impl(struct event_base *base, 1.1293 + struct bufferevent *underlying, 1.1294 + evutil_socket_t fd, 1.1295 + SSL *ssl, 1.1296 + enum bufferevent_ssl_state state, 1.1297 + int options) 1.1298 +{ 1.1299 + struct bufferevent_openssl *bev_ssl = NULL; 1.1300 + struct bufferevent_private *bev_p = NULL; 1.1301 + int tmp_options = options & ~BEV_OPT_THREADSAFE; 1.1302 + 1.1303 + if (underlying != NULL && fd >= 0) 1.1304 + return NULL; /* Only one can be set. */ 1.1305 + 1.1306 + if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl)))) 1.1307 + goto err; 1.1308 + 1.1309 + bev_p = &bev_ssl->bev; 1.1310 + 1.1311 + if (bufferevent_init_common(bev_p, base, 1.1312 + &bufferevent_ops_openssl, tmp_options) < 0) 1.1313 + goto err; 1.1314 + 1.1315 + /* Don't explode if we decide to realloc a chunk we're writing from in 1.1316 + * the output buffer. */ 1.1317 + SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 1.1318 + 1.1319 + bev_ssl->underlying = underlying; 1.1320 + bev_ssl->ssl = ssl; 1.1321 + 1.1322 + bev_ssl->outbuf_cb = evbuffer_add_cb(bev_p->bev.output, 1.1323 + be_openssl_outbuf_cb, bev_ssl); 1.1324 + 1.1325 + if (options & BEV_OPT_THREADSAFE) 1.1326 + bufferevent_enable_locking(&bev_ssl->bev.bev, NULL); 1.1327 + 1.1328 + if (underlying) { 1.1329 + _bufferevent_init_generic_timeout_cbs(&bev_ssl->bev.bev); 1.1330 + bufferevent_incref(underlying); 1.1331 + } 1.1332 + 1.1333 + bev_ssl->state = state; 1.1334 + bev_ssl->last_write = -1; 1.1335 + 1.1336 + init_bio_counts(bev_ssl); 1.1337 + 1.1338 + switch (state) { 1.1339 + case BUFFEREVENT_SSL_ACCEPTING: 1.1340 + SSL_set_accept_state(bev_ssl->ssl); 1.1341 + if (set_handshake_callbacks(bev_ssl, fd) < 0) 1.1342 + goto err; 1.1343 + break; 1.1344 + case BUFFEREVENT_SSL_CONNECTING: 1.1345 + SSL_set_connect_state(bev_ssl->ssl); 1.1346 + if (set_handshake_callbacks(bev_ssl, fd) < 0) 1.1347 + goto err; 1.1348 + break; 1.1349 + case BUFFEREVENT_SSL_OPEN: 1.1350 + if (set_open_callbacks(bev_ssl, fd) < 0) 1.1351 + goto err; 1.1352 + break; 1.1353 + default: 1.1354 + goto err; 1.1355 + } 1.1356 + 1.1357 + if (underlying) { 1.1358 + bufferevent_setwatermark(underlying, EV_READ, 0, 0); 1.1359 + bufferevent_enable(underlying, EV_READ|EV_WRITE); 1.1360 + if (state == BUFFEREVENT_SSL_OPEN) 1.1361 + bufferevent_suspend_read(underlying, 1.1362 + BEV_SUSPEND_FILT_READ); 1.1363 + } else { 1.1364 + bev_ssl->bev.bev.enabled = EV_READ|EV_WRITE; 1.1365 + if (bev_ssl->fd_is_set) { 1.1366 + if (state != BUFFEREVENT_SSL_OPEN) 1.1367 + if (event_add(&bev_ssl->bev.bev.ev_read, NULL) < 0) 1.1368 + goto err; 1.1369 + if (event_add(&bev_ssl->bev.bev.ev_write, NULL) < 0) 1.1370 + goto err; 1.1371 + } 1.1372 + } 1.1373 + 1.1374 + return &bev_ssl->bev.bev; 1.1375 +err: 1.1376 + if (bev_ssl) 1.1377 + bufferevent_free(&bev_ssl->bev.bev); 1.1378 + return NULL; 1.1379 +} 1.1380 + 1.1381 +struct bufferevent * 1.1382 +bufferevent_openssl_filter_new(struct event_base *base, 1.1383 + struct bufferevent *underlying, 1.1384 + SSL *ssl, 1.1385 + enum bufferevent_ssl_state state, 1.1386 + int options) 1.1387 +{ 1.1388 + /* We don't tell the BIO to close the bufferevent; we do it ourselves 1.1389 + * on be_openssl_destruct */ 1.1390 + int close_flag = 0; /* options & BEV_OPT_CLOSE_ON_FREE; */ 1.1391 + BIO *bio; 1.1392 + if (!underlying) 1.1393 + return NULL; 1.1394 + if (!(bio = BIO_new_bufferevent(underlying, close_flag))) 1.1395 + return NULL; 1.1396 + 1.1397 + SSL_set_bio(ssl, bio, bio); 1.1398 + 1.1399 + return bufferevent_openssl_new_impl( 1.1400 + base, underlying, -1, ssl, state, options); 1.1401 +} 1.1402 + 1.1403 +struct bufferevent * 1.1404 +bufferevent_openssl_socket_new(struct event_base *base, 1.1405 + evutil_socket_t fd, 1.1406 + SSL *ssl, 1.1407 + enum bufferevent_ssl_state state, 1.1408 + int options) 1.1409 +{ 1.1410 + /* Does the SSL already have an fd? */ 1.1411 + BIO *bio = SSL_get_wbio(ssl); 1.1412 + long have_fd = -1; 1.1413 + 1.1414 + if (bio) 1.1415 + have_fd = BIO_get_fd(bio, NULL); 1.1416 + 1.1417 + if (have_fd >= 0) { 1.1418 + /* The SSL is already configured with an fd. */ 1.1419 + if (fd < 0) { 1.1420 + /* We should learn the fd from the SSL. */ 1.1421 + fd = (evutil_socket_t) have_fd; 1.1422 + } else if (have_fd == (long)fd) { 1.1423 + /* We already know the fd from the SSL; do nothing */ 1.1424 + } else { 1.1425 + /* We specified an fd different from that of the SSL. 1.1426 + This is probably an error on our part. Fail. */ 1.1427 + return NULL; 1.1428 + } 1.1429 + (void) BIO_set_close(bio, 0); 1.1430 + } else { 1.1431 + /* The SSL isn't configured with a BIO with an fd. */ 1.1432 + if (fd >= 0) { 1.1433 + /* ... and we have an fd we want to use. */ 1.1434 + bio = BIO_new_socket(fd, 0); 1.1435 + SSL_set_bio(ssl, bio, bio); 1.1436 + } else { 1.1437 + /* Leave the fd unset. */ 1.1438 + } 1.1439 + } 1.1440 + 1.1441 + return bufferevent_openssl_new_impl( 1.1442 + base, NULL, fd, ssl, state, options); 1.1443 +} 1.1444 + 1.1445 +unsigned long 1.1446 +bufferevent_get_openssl_error(struct bufferevent *bev) 1.1447 +{ 1.1448 + unsigned long err = 0; 1.1449 + struct bufferevent_openssl *bev_ssl; 1.1450 + BEV_LOCK(bev); 1.1451 + bev_ssl = upcast(bev); 1.1452 + if (bev_ssl && bev_ssl->n_errors) { 1.1453 + err = bev_ssl->errors[--bev_ssl->n_errors]; 1.1454 + } 1.1455 + BEV_UNLOCK(bev); 1.1456 + return err; 1.1457 +}