]> granicus.if.org Git - libevent/blob - bufferevent_openssl.c
Fix memleak in regress tests
[libevent] / bufferevent_openssl.c
1 /*
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
27 #include <string.h>
28
29 #include <openssl/ssl.h>
30 #include <openssl/err.h>
31 #include "openssl-compat.h"
32
33 #include "event2/bufferevent.h"
34 #include "event2/bufferevent_struct.h"
35 #include "event2/buffer.h"
36
37 #include "ssl-compat.h"
38
39 /*
40  * Define an OpenSSL bio that targets a bufferevent.
41  */
42
43 /* --------------------
44    A BIO is an OpenSSL abstraction that handles reading and writing data.  The
45    library will happily speak SSL over anything that implements a BIO
46    interface.
47
48    Here we define a BIO implementation that directs its output to a
49    bufferevent.  We'll want to use this only when none of OpenSSL's built-in
50    IO mechanisms work for us.
51    -------------------- */
52
53 /* every BIO type needs its own integer type value. */
54 #define BIO_TYPE_LIBEVENT 57
55 /* ???? Arguably, we should set BIO_TYPE_FILTER or BIO_TYPE_SOURCE_SINK on
56  * this. */
57
58 #if 0
59 static void
60 print_err(int val)
61 {
62         int err;
63         printf("Error was %d\n", val);
64
65         while ((err = ERR_get_error())) {
66                 const char *msg = (const char*)ERR_reason_error_string(err);
67                 const char *lib = (const char*)ERR_lib_error_string(err);
68                 const char *func = (const char*)ERR_func_error_string(err);
69
70                 printf("%s in %s %s\n", msg, lib, func);
71         }
72 }
73 #else
74 static void
75 print_err(int val)
76 {
77 }
78 #endif
79
80 /* Called to initialize a new BIO */
81 static int
82 bio_bufferevent_new(BIO *b)
83 {
84         BIO_set_init(b, 0);
85         BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
86         return 1;
87 }
88
89 /* Called to uninitialize the BIO. */
90 static int
91 bio_bufferevent_free(BIO *b)
92 {
93         if (!b)
94                 return 0;
95         if (BIO_get_shutdown(b)) {
96                 if (BIO_get_init(b) && BIO_get_data(b))
97                         bufferevent_free(BIO_get_data(b));
98                 BIO_free(b);
99         }
100         return 1;
101 }
102
103 /* Called to extract data from the BIO. */
104 static int
105 bio_bufferevent_read(BIO *b, char *out, int outlen)
106 {
107         int r = 0;
108         struct evbuffer *input;
109
110         BIO_clear_retry_flags(b);
111
112         if (!out)
113                 return 0;
114         if (!BIO_get_data(b))
115                 return -1;
116
117         input = bufferevent_get_input(BIO_get_data(b));
118         if (evbuffer_get_length(input) == 0) {
119                 /* If there's no data to read, say so. */
120                 BIO_set_retry_read(b);
121                 return -1;
122         } else {
123                 r = evbuffer_remove(input, out, outlen);
124         }
125
126         return r;
127 }
128
129 /* Called to write data into the BIO */
130 static int
131 bio_bufferevent_write(BIO *b, const char *in, int inlen)
132 {
133         struct bufferevent *bufev = BIO_get_data(b);
134         struct evbuffer *output;
135         size_t outlen;
136
137         BIO_clear_retry_flags(b);
138
139         if (!BIO_get_data(b))
140                 return -1;
141
142         output = bufferevent_get_output(bufev);
143         outlen = evbuffer_get_length(output);
144
145         /* Copy only as much data onto the output buffer as can fit under the
146          * high-water mark. */
147         if (bufev->wm_write.high && bufev->wm_write.high <= (outlen + inlen)) {
148                 if (bufev->wm_write.high <= outlen) {
149                         /* If no data can fit, we'll need to retry later. */
150                         BIO_set_retry_write(b);
151                         return -1;
152                 }
153                 inlen = bufev->wm_write.high - outlen;
154         }
155
156         EVUTIL_ASSERT(inlen > 0);
157         evbuffer_add(output, in, inlen);
158         return inlen;
159 }
160
161 /* Called to handle various requests */
162 static long
163 bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
164 {
165         struct bufferevent *bufev = BIO_get_data(b);
166         long ret = 1;
167
168         switch (cmd) {
169         case BIO_CTRL_GET_CLOSE:
170                 ret = BIO_get_shutdown(b);
171                 break;
172         case BIO_CTRL_SET_CLOSE:
173                 BIO_set_shutdown(b, (int)num);
174                 break;
175         case BIO_CTRL_PENDING:
176                 ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
177                 break;
178         case BIO_CTRL_WPENDING:
179                 ret = evbuffer_get_length(bufferevent_get_output(bufev)) != 0;
180                 break;
181         /* XXXX These two are given a special-case treatment because
182          * of cargo-cultism.  I should come up with a better reason. */
183         case BIO_CTRL_DUP:
184         case BIO_CTRL_FLUSH:
185                 ret = 1;
186                 break;
187         default:
188                 ret = 0;
189                 break;
190         }
191         return ret;
192 }
193
194 /* Called to write a string to the BIO */
195 static int
196 bio_bufferevent_puts(BIO *b, const char *s)
197 {
198         return bio_bufferevent_write(b, s, strlen(s));
199 }
200
201 /* Method table for the bufferevent BIO */
202 static BIO_METHOD *methods_bufferevent;
203
204 /* Return the method table for the bufferevents BIO */
205 static BIO_METHOD *
206 BIO_s_bufferevent(void)
207 {
208         if (methods_bufferevent == NULL) {
209                 methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
210                 if (methods_bufferevent == NULL)
211                         return NULL;
212                 BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
213                 BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
214                 BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
215                 BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
216                 BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
217                 BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
218         }
219         return methods_bufferevent;
220 }
221
222 /* Create a new BIO to wrap communication around a bufferevent.  If close_flag
223  * is true, the bufferevent will be freed when the BIO is closed. */
224 static BIO *
225 BIO_new_bufferevent(struct bufferevent *bufferevent)
226 {
227         BIO *result;
228         if (!bufferevent)
229                 return NULL;
230         if (!(result = BIO_new(BIO_s_bufferevent())))
231                 return NULL;
232         BIO_set_init(result, 1);
233         BIO_set_data(result, bufferevent);
234         /* We don't tell the BIO to close the bufferevent; we do it ourselves on
235          * be_openssl_destruct() */
236         BIO_set_shutdown(result, 0);
237         return result;
238 }
239
240 static void
241 conn_closed(struct bufferevent_ssl *bev_ssl, int when, int errcode, int ret)
242 {
243         int event = BEV_EVENT_ERROR;
244         int dirty_shutdown = 0;
245         unsigned long err;
246
247         switch (errcode) {
248         case SSL_ERROR_ZERO_RETURN:
249                 /* Possibly a clean shutdown. */
250                 if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
251                         event = BEV_EVENT_EOF;
252                 else
253                         dirty_shutdown = 1;
254                 break;
255         case SSL_ERROR_SYSCALL:
256                 /* IO error; possibly a dirty shutdown. */
257                 if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
258                         dirty_shutdown = 1;
259                 bufferevent_ssl_put_error(bev_ssl, errcode);
260                 break;
261         case SSL_ERROR_SSL:
262                 /* Protocol error; possibly a dirty shutdown. */
263                 if (ret == 0 && SSL_is_init_finished(bev_ssl->ssl) == 0)
264                         dirty_shutdown = 1;
265                 bufferevent_ssl_put_error(bev_ssl, errcode);
266                 break;
267         case SSL_ERROR_WANT_X509_LOOKUP:
268                 /* XXXX handle this. */
269                 bufferevent_ssl_put_error(bev_ssl, errcode);
270                 break;
271         case SSL_ERROR_NONE:
272         case SSL_ERROR_WANT_READ:
273         case SSL_ERROR_WANT_WRITE:
274         case SSL_ERROR_WANT_CONNECT:
275         case SSL_ERROR_WANT_ACCEPT:
276         default:
277                 /* should be impossible; treat as normal error. */
278                 event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
279                 break;
280         }
281
282         while ((err = ERR_get_error())) {
283                 bufferevent_ssl_put_error(bev_ssl, err);
284         }
285
286         if (dirty_shutdown && bev_ssl->flags & BUFFEREVENT_SSL_DIRTY_SHUTDOWN)
287                 event = BEV_EVENT_EOF;
288
289         bufferevent_ssl_stop_reading(bev_ssl);
290         bufferevent_ssl_stop_writing(bev_ssl);
291
292         /* when is BEV_EVENT_{READING|WRITING} */
293         event = when | event;
294         bufferevent_run_eventcb_(&bev_ssl->bev.bev, event, 0);
295 }
296
297 static void
298 init_bio_counts(struct bufferevent_ssl *bev_ssl)
299 {
300         BIO *rbio, *wbio;
301
302         wbio = SSL_get_wbio(bev_ssl->ssl);
303         bev_ssl->counts.n_written = wbio ? BIO_number_written(wbio) : 0;
304         rbio = SSL_get_rbio(bev_ssl->ssl);
305         bev_ssl->counts.n_read = rbio ? BIO_number_read(rbio) : 0;
306 }
307
308 static inline void
309 decrement_buckets(struct bufferevent_ssl *bev_ssl)
310 {
311         unsigned long num_w = BIO_number_written(SSL_get_wbio(bev_ssl->ssl));
312         unsigned long num_r = BIO_number_read(SSL_get_rbio(bev_ssl->ssl));
313         /* These next two subtractions can wrap around. That's okay. */
314         unsigned long w = num_w - bev_ssl->counts.n_written;
315         unsigned long r = num_r - bev_ssl->counts.n_read;
316         if (w)
317                 bufferevent_decrement_write_buckets_(&bev_ssl->bev, w);
318         if (r)
319                 bufferevent_decrement_read_buckets_(&bev_ssl->bev, r);
320         bev_ssl->counts.n_written = num_w;
321         bev_ssl->counts.n_read = num_r;
322 }
323
324 static void *
325 SSL_init(void *ssl)
326 {
327         /* Don't explode if we decide to realloc a chunk we're writing from in
328          * the output buffer. */
329         SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
330
331         return ssl;
332 }
333
334 static void
335 SSL_context_free(void *ssl, int flags)
336 {
337         if (flags & BEV_OPT_CLOSE_ON_FREE)
338                 SSL_free(ssl);
339 }
340
341 static int
342 SSL_is_ok(int err)
343 {
344         return err == 1;
345 }
346
347 static int
348 SSL_is_want_read(int err)
349 {
350         return err == SSL_ERROR_WANT_READ;
351 }
352
353 static int
354 SSL_is_want_write(int err)
355 {
356         return err == SSL_ERROR_WANT_WRITE;
357 }
358
359 static int
360 openssl_read(void *ssl, unsigned char *buf, size_t len)
361 {
362         return SSL_read(ssl, buf, len);
363 }
364
365 static int
366 openssl_write(void *ssl, const unsigned char *buf, size_t len)
367 {
368         return SSL_write(ssl, buf, len);
369 }
370
371 static evutil_socket_t
372 be_openssl_get_fd(struct bufferevent_ssl *bev_ssl)
373 {
374         evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
375         BIO *bio = SSL_get_wbio(bev_ssl->ssl);
376         if (bio)
377                 fd = BIO_get_fd(bio, NULL);
378         return fd;
379 }
380
381 static int
382 be_openssl_bio_set_fd(struct bufferevent_ssl *bev_ssl, evutil_socket_t fd)
383 {
384         if (!bev_ssl->underlying) {
385                 BIO *bio;
386                 bio = BIO_new_socket((int)fd, 0);
387                 SSL_set_bio(bev_ssl->ssl, bio, bio);
388         } else {
389                 BIO *bio;
390                 if (!(bio = BIO_new_bufferevent(bev_ssl->underlying)))
391                         return -1;
392                 SSL_set_bio(bev_ssl->ssl, bio, bio);
393         }
394         return 0;
395 }
396
397 static size_t SSL_pending_wrap(void *ssl)
398 {
399         return SSL_pending(ssl);
400 }
401
402 static struct le_ssl_ops le_openssl_ops = {
403         SSL_init,
404         SSL_context_free,
405         (void (*)(void *))SSL_free,
406         (int (*)(void *))SSL_renegotiate,
407         openssl_write,
408         openssl_read,
409         SSL_pending_wrap,
410         (int (*)(void *))SSL_do_handshake,
411         (int (*)(void *, int))SSL_get_error,
412         ERR_clear_error,
413         (int (*)(void *))SSL_clear,
414         (void (*)(void *))SSL_set_connect_state,
415         (void (*)(void *))SSL_set_accept_state,
416         SSL_is_ok,
417         SSL_is_want_read,
418         SSL_is_want_write,
419         (int (*)(void *))be_openssl_get_fd,
420         be_openssl_bio_set_fd,
421         init_bio_counts,
422         decrement_buckets,
423         conn_closed,
424         print_err,
425 };
426
427 struct bufferevent *
428 bufferevent_openssl_filter_new(struct event_base *base,
429     struct bufferevent *underlying,
430     SSL *ssl,
431     enum bufferevent_ssl_state state,
432     int options)
433 {
434         BIO *bio;
435         struct bufferevent *bev;
436
437         if (!underlying)
438                 goto err;
439         if (!(bio = BIO_new_bufferevent(underlying)))
440                 goto err;
441
442         SSL_set_bio(ssl, bio, bio);
443
444         bev = bufferevent_ssl_new_impl(
445                 base, underlying, -1, ssl, state, options, &le_openssl_ops);
446         return bev;
447
448 err:
449         if (options & BEV_OPT_CLOSE_ON_FREE)
450                 SSL_free(ssl);
451         return NULL;
452 }
453
454 struct bufferevent *
455 bufferevent_openssl_socket_new(struct event_base *base,
456     evutil_socket_t fd,
457     SSL *ssl,
458     enum bufferevent_ssl_state state,
459     int options)
460 {
461         /* Does the SSL already have an fd? */
462         BIO *bio = SSL_get_wbio(ssl);
463         long have_fd = -1;
464
465         if (bio)
466                 have_fd = BIO_get_fd(bio, NULL);
467
468         if (have_fd >= 0) {
469                 /* The SSL is already configured with an fd. */
470                 if (fd < 0) {
471                         /* We should learn the fd from the SSL. */
472                         fd = (evutil_socket_t) have_fd;
473                 } else if (have_fd == (long)fd) {
474                         /* We already know the fd from the SSL; do nothing */
475                 } else {
476                         /* We specified an fd different from that of the SSL.
477                            This is probably an error on our part.  Fail. */
478                         goto err;
479                 }
480                 (void)BIO_set_close(bio, 0);
481         } else {
482                 /* The SSL isn't configured with a BIO with an fd. */
483                 if (fd >= 0) {
484                         /* ... and we have an fd we want to use. */
485                         bio = BIO_new_socket((int)fd, 0);
486                         SSL_set_bio(ssl, bio, bio);
487                 } else {
488                         /* Leave the fd unset. */
489                 }
490         }
491
492         return bufferevent_ssl_new_impl(
493                 base, NULL, fd, ssl, state, options, &le_openssl_ops);
494
495 err:
496         if (options & BEV_OPT_CLOSE_ON_FREE)
497                 SSL_free(ssl);
498         return NULL;
499 }
500
501 int
502 bufferevent_ssl_renegotiate(struct bufferevent *bev)
503 {
504         return bufferevent_ssl_renegotiate_impl(bev);
505 }
506
507 SSL *
508 bufferevent_openssl_get_ssl(struct bufferevent *bufev)
509 {
510         struct bufferevent_ssl *bev_ssl = bufferevent_ssl_upcast(bufev);
511         if (!bev_ssl)
512                 return NULL;
513         return bev_ssl->ssl;
514 }
515
516 int
517 bufferevent_openssl_get_allow_dirty_shutdown(struct bufferevent *bev)
518 {
519         return bufferevent_ssl_get_allow_dirty_shutdown(bev);
520 }
521
522 void
523 bufferevent_openssl_set_allow_dirty_shutdown(
524         struct bufferevent *bev, int allow_dirty_shutdown)
525 {
526         bufferevent_ssl_set_allow_dirty_shutdown(bev, allow_dirty_shutdown);
527 }
528
529 unsigned long
530 bufferevent_get_openssl_error(struct bufferevent *bufev)
531 {
532         struct bufferevent_ssl *bev_ssl = bufferevent_ssl_upcast(bufev);
533         if (!bev_ssl)
534                 return 0;
535         return bufferevent_get_ssl_error(bufev);
536 }