diff options
author | eolianoe | 2017-07-25 12:12:09 +0200 |
---|---|---|
committer | eolianoe | 2017-07-25 12:12:09 +0200 |
commit | 337451a175f491c00b0875f94fac62b6e1a574b3 (patch) | |
tree | 9430a4a441647a97b261e4b2c551986b7bc7be7a | |
download | aur-337451a175f491c00b0875f94fac62b6e1a574b3.tar.gz |
Initial commit
-rw-r--r-- | .SRCINFO | 29 | ||||
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | 0001-evdns-fix-searching-empty-hostnames.patch | 65 | ||||
-rw-r--r-- | 0002-test-dns-regression-for-empty-hostname.patch | 55 | ||||
-rw-r--r-- | 0003-evdns-name_parse-fix-remote-stack-overread.patch | 115 | ||||
-rw-r--r-- | 0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch | 88 | ||||
-rw-r--r-- | PKGBUILD | 59 | ||||
-rw-r--r-- | openssl_1.1.patch | 190 |
8 files changed, 606 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..ece1a06a3f0b --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,29 @@ +# Generated by mksrcinfo v8 +# Tue Jul 25 10:11:57 UTC 2017 +pkgbase = libevent-compat + pkgdesc = An event notification library + pkgver = 2.0.22 + pkgrel = 1 + url = http://libevent.org/ + arch = i686 + arch = x86_64 + license = BSD + depends = openssl + optdepends = python2: to use event_rpcgen.py + source = https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz + source = https://github.com/libevent/libevent/releases/download/release-2.0.22-stable/libevent-2.0.22-stable.tar.gz.asc + source = openssl_1.1.patch + source = 0001-evdns-fix-searching-empty-hostnames.patch + source = 0002-test-dns-regression-for-empty-hostname.patch + source = 0003-evdns-name_parse-fix-remote-stack-overread.patch + source = 0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch + sha256sums = 71c2c49f0adadacfdbe6332a372c38cf9c8b7895bb73dabeaa53cdcc1d4e1fa3 + sha256sums = SKIP + sha256sums = 1c0e3a47e5739ce6f05cfdaeaf1bb33eb7c6c89003538f680586e50cbd2abb48 + sha256sums = 66ca7cd16a2260537e1f7d7d22ace9c50bcc54f5f47af41361f1771de6b37526 + sha256sums = b76aaa4730fe377f49077a428645e6e5335a5fe5600fece1e0dd4503749e25d5 + sha256sums = e2bbd44121f4f5c70ba891e4dc9f150254babae0c647bb47792571a6e88c0614 + sha256sums = c02932ec76925d9c470a7b955add045f59dbef3dcc85b46020bda61151b22533 + +pkgname = libevent-compat + diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..091c0fce482e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.gz +*.xz +visit-install* +/pkg +/src diff --git a/0001-evdns-fix-searching-empty-hostnames.patch b/0001-evdns-fix-searching-empty-hostnames.patch new file mode 100644 index 000000000000..33b81108e890 --- /dev/null +++ b/0001-evdns-fix-searching-empty-hostnames.patch @@ -0,0 +1,65 @@ +From ec65c42052d95d2c23d1d837136d1cf1d9ecef9e Mon Sep 17 00:00:00 2001 +From: Azat Khuzhin <a3at.mail@gmail.com> +Date: Fri, 25 Mar 2016 00:33:47 +0300 +Subject: [PATCH] evdns: fix searching empty hostnames + +From #332: + Here follows a bug report by **Guido Vranken** via the _Tor bug bounty program_. Please credit Guido accordingly. + + ## Bug report + + The DNS code of Libevent contains this rather obvious OOB read: + + ```c + static char * + search_make_new(const struct search_state *const state, int n, const char *const base_name) { + const size_t base_len = strlen(base_name); + const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1; + ``` + + If the length of ```base_name``` is 0, then line 3125 reads 1 byte before the buffer. This will trigger a crash on ASAN-protected builds. + + To reproduce: + + Build libevent with ASAN: + ``` + $ CFLAGS='-fomit-frame-pointer -fsanitize=address' ./configure && make -j4 + ``` + Put the attached ```resolv.conf``` and ```poc.c``` in the source directory and then do: + + ``` + $ gcc -fsanitize=address -fomit-frame-pointer poc.c .libs/libevent.a + $ ./a.out + ================================================================= + ==22201== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60060000efdf at pc 0x4429da bp 0x7ffe1ed47300 sp 0x7ffe1ed472f8 + READ of size 1 at 0x60060000efdf thread T0 + ``` + +P.S. we can add a check earlier, but since this is very uncommon, I didn't add it. + +Fixes: #332 +--- + evdns.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/evdns.c b/evdns.c +index 905ff6b..e9dbc35 100644 +--- a/evdns.c ++++ b/evdns.c +@@ -3175,9 +3175,12 @@ search_set_from_hostname(struct evdns_base *base) { + static char * + search_make_new(const struct search_state *const state, int n, const char *const base_name) { + const size_t base_len = strlen(base_name); +- const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1; ++ char need_to_append_dot; + struct search_domain *dom; + ++ if (!base_len) return NULL; ++ need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1; ++ + for (dom = state->head; dom; dom = dom->next) { + if (!n--) { + /* this is the postfix we want */ +-- +2.1.4 + diff --git a/0002-test-dns-regression-for-empty-hostname.patch b/0002-test-dns-regression-for-empty-hostname.patch new file mode 100644 index 000000000000..bf90a4f64385 --- /dev/null +++ b/0002-test-dns-regression-for-empty-hostname.patch @@ -0,0 +1,55 @@ +From 683cf19b56dad3bc7b5915e2765b3e3c325c2dfe Mon Sep 17 00:00:00 2001 +From: Azat Khuzhin <a3at.mail@gmail.com> +Date: Fri, 25 Mar 2016 00:21:06 +0300 +Subject: [PATCH] test/dns: regression for empty hostname + +Refs: #332 + +Conflicts: + test/regress_dns.c +--- + test/regress_dns.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/test/regress_dns.c b/test/regress_dns.c +index 4d90d67..1817fb3 100644 +--- a/test/regress_dns.c ++++ b/test/regress_dns.c +@@ -562,6 +562,26 @@ end: + + regress_clean_dnsserver(); + } ++static void ++dns_search_empty_test(void *arg) ++{ ++ struct basic_test_data *data = arg; ++ struct event_base *base = data->base; ++ struct evdns_base *dns = NULL; ++ ++ dns = evdns_base_new(base, 0); ++ ++ evdns_base_search_add(dns, "whatever.example.com"); ++ ++ n_replies_left = 1; ++ exit_base = base; ++ ++ tt_ptr_op(evdns_base_resolve_ipv4(dns, "", 0, generic_dns_callback, NULL), ==, NULL); ++ ++end: ++ if (dns) ++ evdns_base_free(dns, 0); ++} + + static int request_count = 0; + static struct evdns_request *current_req = NULL; +@@ -1831,6 +1851,7 @@ struct testcase_t dns_testcases[] = { + DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS), + DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS), + { "resolve_reverse", dns_resolve_reverse, TT_FORK, NULL, NULL }, ++ { "search_empty", dns_search_empty_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + { "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + { "search_cancel", dns_search_cancel_test, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, +-- +2.1.4 + diff --git a/0003-evdns-name_parse-fix-remote-stack-overread.patch b/0003-evdns-name_parse-fix-remote-stack-overread.patch new file mode 100644 index 000000000000..5a4a61598f78 --- /dev/null +++ b/0003-evdns-name_parse-fix-remote-stack-overread.patch @@ -0,0 +1,115 @@ +From 96f64a022014a208105ead6c8a7066018449d86d Mon Sep 17 00:00:00 2001 +From: Azat Khuzhin <a3at.mail@gmail.com> +Date: Mon, 1 Feb 2016 17:32:09 +0300 +Subject: [PATCH] evdns: name_parse(): fix remote stack overread + +@asn-the-goblin-slayer: + "the name_parse() function in libevent's DNS code is vulnerable to a buffer overread. + + 971 if (cp != name_out) { + 972 if (cp + 1 >= end) return -1; + 973 *cp++ = '.'; + 974 } + 975 if (cp + label_len >= end) return -1; + 976 memcpy(cp, packet + j, label_len); + 977 cp += label_len; + 978 j += label_len; + No check is made against length before the memcpy occurs. + + This was found through the Tor bug bounty program and the discovery should be credited to 'Guido Vranken'." + +Reproducer for gdb (https://gist.github.com/azat/e4fcf540e9b89ab86d02): + set $PROT_NONE=0x0 + set $PROT_READ=0x1 + set $PROT_WRITE=0x2 + set $MAP_ANONYMOUS=0x20 + set $MAP_SHARED=0x01 + set $MAP_FIXED=0x10 + set $MAP_32BIT=0x40 + + start + + set $length=202 + # overread + set $length=2 + # allocate with mmap to have a seg fault on page boundary + set $l=(1<<20)*2 + p mmap(0, $l, $PROT_READ|$PROT_WRITE, $MAP_ANONYMOUS|$MAP_SHARED|$MAP_32BIT, -1, 0) + set $packet=(char *)$1+$l-$length + # hack the packet + set $packet[0]=63 + set $packet[1]='/' + + p malloc(sizeof(int)) + set $idx=(int *)$2 + set $idx[0]=0 + set $name_out_len=202 + + p malloc($name_out_len) + set $name_out=$3 + + # have WRITE only mapping to fail on read + set $end=$1+$l + p (void *)mmap($end, 1<<12, $PROT_NONE, $MAP_ANONYMOUS|$MAP_SHARED|$MAP_FIXED|$MAP_32BIT, -1, 0) + set $m=$4 + + p name_parse($packet, $length, $idx, $name_out, $name_out_len) + x/2s (char *)$name_out + +Before this patch: +$ gdb -ex 'source gdb' dns-example +$1 = 1073741824 +$2 = (void *) 0x633010 +$3 = (void *) 0x633030 +$4 = (void *) 0x40200000 + +Program received signal SIGSEGV, Segmentation fault. +__memcpy_sse2_unaligned () at memcpy-sse2-unaligned.S:33 + +After this patch: +$ gdb -ex 'source gdb' dns-example +$1 = 1073741824 +$2 = (void *) 0x633010 +$3 = (void *) 0x633030 +$4 = (void *) 0x40200000 +$5 = -1 +0x633030: "/" +0x633032: "" +(gdb) p $m +$6 = (void *) 0x40200000 +(gdb) p $1 +$7 = 1073741824 +(gdb) p/x $1 +$8 = 0x40000000 +(gdb) quit + +P.S. plus drop one condition duplicate. + +Fixes: #317 +--- + evdns.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/evdns.c b/evdns.c +index 0955a28..c411233 100644 +--- a/evdns.c ++++ b/evdns.c +@@ -976,7 +976,6 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) { + + for (;;) { + u8 label_len; +- if (j >= length) return -1; + GET8(label_len); + if (!label_len) break; + if (label_len & 0xc0) { +@@ -997,6 +996,7 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) { + *cp++ = '.'; + } + if (cp + label_len >= end) return -1; ++ if (j + label_len > length) return -1; + memcpy(cp, packet + j, label_len); + cp += label_len; + j += label_len; +-- +2.1.4 + diff --git a/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch b/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch new file mode 100644 index 000000000000..19dc592e9370 --- /dev/null +++ b/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch @@ -0,0 +1,88 @@ +From 329acc18a0768c21ba22522f01a5c7f46cacc4d5 Mon Sep 17 00:00:00 2001 +From: Azat Khuzhin <a3at.mail@gmail.com> +Date: Sun, 31 Jan 2016 00:57:16 +0300 +Subject: [PATCH] evutil_parse_sockaddr_port(): fix buffer overflow + +@asn-the-goblin-slayer: + "Length between '[' and ']' is cast to signed 32 bit integer on line 1815. Is + the length is more than 2<<31 (INT_MAX), len will hold a negative value. + Consequently, it will pass the check at line 1816. Segfault happens at line + 1819. + + Generate a resolv.conf with generate-resolv.conf, then compile and run + poc.c. See entry-functions.txt for functions in tor that might be + vulnerable. + + Please credit 'Guido Vranken' for this discovery through the Tor bug bounty + program." + +Reproducer for gdb (https://gist.github.com/azat/be2b0d5e9417ba0dfe2c): + start + p (1ULL<<31)+1ULL + # $1 = 2147483649 + p malloc(sizeof(struct sockaddr)) + # $2 = (void *) 0x646010 + p malloc(sizeof(int)) + # $3 = (void *) 0x646030 + p malloc($1) + # $4 = (void *) 0x7fff76a2a010 + p memset($4, 1, $1) + # $5 = 1990369296 + p (char *)$4 + # $6 = 0x7fff76a2a010 '\001' <repeats 200 times>... + set $6[0]='[' + set $6[$1]=']' + p evutil_parse_sockaddr_port($4, $2, $3) + # $7 = -1 + +Before: + $ gdb bin/http-connect < gdb + (gdb) $1 = 2147483649 + (gdb) (gdb) $2 = (void *) 0x646010 + (gdb) (gdb) $3 = (void *) 0x646030 + (gdb) (gdb) $4 = (void *) 0x7fff76a2a010 + (gdb) (gdb) $5 = 1990369296 + (gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>... + (gdb) (gdb) (gdb) (gdb) + Program received signal SIGSEGV, Segmentation fault. + __memcpy_sse2_unaligned () at memcpy-sse2-unaligned.S:36 + +After: + $ gdb bin/http-connect < gdb + (gdb) $1 = 2147483649 + (gdb) (gdb) $2 = (void *) 0x646010 + (gdb) (gdb) $3 = (void *) 0x646030 + (gdb) (gdb) $4 = (void *) 0x7fff76a2a010 + (gdb) (gdb) $5 = 1990369296 + (gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>... + (gdb) (gdb) (gdb) (gdb) $7 = -1 + (gdb) (gdb) quit + +Fixes: #318 +--- + evutil.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/evutil.c b/evutil.c +index 79d825d..495bfcc 100644 +--- a/evutil.c ++++ b/evutil.c +@@ -2058,12 +2058,12 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int * + + cp = strchr(ip_as_string, ':'); + if (*ip_as_string == '[') { +- int len; ++ size_t len; + if (!(cp = strchr(ip_as_string, ']'))) { + return -1; + } +- len = (int) ( cp-(ip_as_string + 1) ); +- if (len > (int)sizeof(buf)-1) { ++ len = ( cp-(ip_as_string + 1) ); ++ if (len > sizeof(buf)-1) { + return -1; + } + memcpy(buf, ip_as_string+1, len); +-- +2.1.4 + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..f4c41abd5fd3 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,59 @@ +# $Id$ +# Maintainer: Tom Gundersen <teg@jklm.no> +# Contributor: Judd <jvinet@zeroflux.org> + +_pkgname=libevent +pkgname=libevent-compat +pkgver=2.0.22 +pkgrel=1 +pkgdesc="An event notification library" +arch=('i686' 'x86_64') +url="http://libevent.org/" +license=('BSD') +depends=('openssl') +optdepends=('python2: to use event_rpcgen.py') +source=(https://github.com/libevent/libevent/releases/download/release-$pkgver-stable/$_pkgname-$pkgver-stable.tar.gz{,.asc} + openssl_1.1.patch + 0001-evdns-fix-searching-empty-hostnames.patch + 0002-test-dns-regression-for-empty-hostname.patch + 0003-evdns-name_parse-fix-remote-stack-overread.patch + 0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch) +sha256sums=('71c2c49f0adadacfdbe6332a372c38cf9c8b7895bb73dabeaa53cdcc1d4e1fa3' + 'SKIP' + '1c0e3a47e5739ce6f05cfdaeaf1bb33eb7c6c89003538f680586e50cbd2abb48' + '66ca7cd16a2260537e1f7d7d22ace9c50bcc54f5f47af41361f1771de6b37526' + 'b76aaa4730fe377f49077a428645e6e5335a5fe5600fece1e0dd4503749e25d5' + 'e2bbd44121f4f5c70ba891e4dc9f150254babae0c647bb47792571a6e88c0614' + 'c02932ec76925d9c470a7b955add045f59dbef3dcc85b46020bda61151b22533') +validpgpkeys=('B35BF85BF19489D04E28C33C21194EBB165733EA') + +prepare() { + cd ${_pkgname}-${pkgver}-stable + patch -Np1 -i ../0001-evdns-fix-searching-empty-hostnames.patch + patch -Np1 -i ../0002-test-dns-regression-for-empty-hostname.patch + patch -Np1 -i ../0003-evdns-name_parse-fix-remote-stack-overread.patch + patch -Np1 -i ../0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch + patch -Np1 -i ../openssl_1.1.patch +} + +build() { + cd ${_pkgname}-${pkgver}-stable + ./autogen.sh + ./configure --prefix=/usr --sysconfdir=/etc --disable-libevent-regress + make +} + +check() { + cd ${_pkgname}-${pkgver}-stable + make -j1 check +} + +package() { + cd ${_pkgname}-${pkgver}-stable + make DESTDIR="${pkgdir}" install + install -Dm 644 LICENSE "${pkgdir}"/usr/share/licenses/${pkgname}/LICENSE + rm -rf -- "${pkgdir}/usr/include" + rm -rf -- "${pkgdir}/usr/bin" + rm -rf -- "${pkgdir}/usr/lib/"*.so + rm -rf -- "${pkgdir}/usr/lib/pkgconfig" +} diff --git a/openssl_1.1.patch b/openssl_1.1.patch new file mode 100644 index 000000000000..aeab3e28757a --- /dev/null +++ b/openssl_1.1.patch @@ -0,0 +1,190 @@ +From 7fb978bf21e21a1de36777b45ea984bb1d5c52dd Mon Sep 17 00:00:00 2001 +From: Kurt Roeckx <kurt@roeckx.be> +Date: Mon, 19 Sep 2016 22:05:15 +0200 +Subject: [PATCH] Make it build using OpenSSL 1.1.0 + +--- + bufferevent_openssl.c | 62 +++++++++++++++++------------------- + openssl-compat.h | 33 +++++++++++++++++++ + 5 files changed, 102 insertions(+), 63 deletions(-) + create mode 100644 openssl-compat.h + +diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c +index 017bfce..b8a0fe0 100644 +--- a/bufferevent_openssl.c ++++ b/bufferevent_openssl.c +@@ -66,6 +66,7 @@ + #include <openssl/bio.h> + #include <openssl/ssl.h> + #include <openssl/err.h> ++#include "openssl-compat.h" + + /* + * Define an OpenSSL bio that targets a bufferevent. +@@ -109,10 +110,8 @@ print_err(int val) + static int + bio_bufferevent_new(BIO *b) + { +- b->init = 0; +- b->num = -1; +- b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/ +- b->flags = 0; ++ BIO_set_init(b, 0); ++ BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/ + return 1; + } + +@@ -122,12 +121,10 @@ bio_bufferevent_free(BIO *b) + { + if (!b) + return 0; +- if (b->shutdown) { +- if (b->init && b->ptr) +- bufferevent_free(b->ptr); +- b->init = 0; +- b->flags = 0; +- b->ptr = NULL; ++ if (BIO_get_shutdown(b)) { ++ if (BIO_get_init(b) && BIO_get_data(b)) ++ bufferevent_free(BIO_get_data(b)); ++ BIO_free(b); + } + return 1; + } +@@ -143,10 +140,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen) + + if (!out) + return 0; +- if (!b->ptr) ++ if (!BIO_get_data(b)) + return -1; + +- input = bufferevent_get_input(b->ptr); ++ input = bufferevent_get_input(BIO_get_data(b)); + if (evbuffer_get_length(input) == 0) { + /* If there's no data to read, say so. */ + BIO_set_retry_read(b); +@@ -162,13 +159,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen) + static int + bio_bufferevent_write(BIO *b, const char *in, int inlen) + { +- struct bufferevent *bufev = b->ptr; ++ struct bufferevent *bufev = BIO_get_data(b); + struct evbuffer *output; + size_t outlen; + + BIO_clear_retry_flags(b); + +- if (!b->ptr) ++ if (!BIO_get_data(b)) + return -1; + + output = bufferevent_get_output(bufev); +@@ -194,15 +191,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen) + static long + bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr) + { +- struct bufferevent *bufev = b->ptr; ++ struct bufferevent *bufev = BIO_get_data(b); + long ret = 1; + + switch (cmd) { + case BIO_CTRL_GET_CLOSE: +- ret = b->shutdown; ++ ret = BIO_get_shutdown(b); + break; + case BIO_CTRL_SET_CLOSE: +- b->shutdown = (int)num; ++ BIO_set_shutdown(b, (int)num); + break; + case BIO_CTRL_PENDING: + ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0; +@@ -231,23 +228,24 @@ bio_bufferevent_puts(BIO *b, const char *s) + } + + /* Method table for the bufferevent BIO */ +-static BIO_METHOD methods_bufferevent = { +- BIO_TYPE_LIBEVENT, "bufferevent", +- bio_bufferevent_write, +- bio_bufferevent_read, +- bio_bufferevent_puts, +- NULL /* bio_bufferevent_gets */, +- bio_bufferevent_ctrl, +- bio_bufferevent_new, +- bio_bufferevent_free, +- NULL /* callback_ctrl */, +-}; ++static BIO_METHOD *methods_bufferevent; + + /* Return the method table for the bufferevents BIO */ + static BIO_METHOD * + BIO_s_bufferevent(void) + { +- return &methods_bufferevent; ++ if (methods_bufferevent == NULL) { ++ methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent"); ++ if (methods_bufferevent == NULL) ++ return NULL; ++ BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write); ++ BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read); ++ BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts); ++ BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl); ++ BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new); ++ BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free); ++ } ++ return methods_bufferevent; + } + + /* Create a new BIO to wrap communication around a bufferevent. If close_flag +@@ -260,9 +258,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag) + return NULL; + if (!(result = BIO_new(BIO_s_bufferevent()))) + return NULL; +- result->init = 1; +- result->ptr = bufferevent; +- result->shutdown = close_flag ? 1 : 0; ++ BIO_set_init(result, 1); ++ BIO_set_data(result, bufferevent); ++ BIO_set_shutdown(result, close_flag ? 1 : 0); + return result; + } + +diff --git a/openssl-compat.h b/openssl-compat.h +new file mode 100644 +index 0000000..e47bac6 +--- /dev/null ++++ b/openssl-compat.h +@@ -0,0 +1,33 @@ ++#ifndef OPENSSL_COMPAT_H ++#define OPENSSL_COMPAT_H ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++static BIO_METHOD *BIO_meth_new(int type, const char *name) ++{ ++ BIO_METHOD *biom = calloc(1, sizeof(BIO_METHOD)); ++ ++ if (biom != NULL) { ++ biom->type = type; ++ biom->name = name; ++ } ++ return biom; ++} ++ ++#define BIO_meth_set_write(b, f) b->bwrite = f ++#define BIO_meth_set_read(b, f) b->bread = f ++#define BIO_meth_set_puts(b, f) b->bputs = f ++#define BIO_meth_set_ctrl(b, f) b->ctrl = f ++#define BIO_meth_set_create(b, f) b->create = f ++#define BIO_meth_set_destroy(b, f) b->destroy = f ++ ++#define BIO_set_init(b, val) b->init = val ++#define BIO_set_data(b, val) b->ptr = val ++#define BIO_set_shutdown(b, val) b->shutdown = val ++#define BIO_get_init(b) b->init ++#define BIO_get_data(b) b->ptr ++#define BIO_get_shutdown(b) b->shutdown ++ ++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ ++ ++#endif /* OPENSSL_COMPAT_H */ |