From 09951bea7fe30cd91d8a4dee95278218f0aa199e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 29 Sep 2014 12:57:07 -0400 Subject: [PATCH 1/4] Don't use the getaddrinfo sandbox cache from tor-resolve Fixes bug 13295; bugfix on 0.2.5.3-alpha. The alternative here is to call crypto_global_init() from tor-resolve, but let's avoid linking openssl into tor-resolve for as long as we can. --- changes/13295 | 5 +++++ src/common/sandbox.c | 21 +++++++++++++++++++++ src/common/sandbox.h | 2 ++ src/tools/tor-resolve.c | 2 ++ 4 files changed, 30 insertions(+) create mode 100644 changes/13295 diff --git a/changes/13295 b/changes/13295 new file mode 100644 index 000000000..433432595 --- /dev/null +++ b/changes/13295 @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Disable sandbox name resolver cache when running tor-resolve: + tor-resolve doesn't use the sandbox code, and turning it on was + breaking attempts to do tor-resolve on a non-default server on + Linux. Fixes bug 13295; bugfix on 0.2.5.3-alpha. diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 05b91be7b..dbbaa59d7 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -1385,6 +1385,18 @@ HT_GENERATE(getaddrinfo_cache, cached_getaddrinfo_item_t, node, cached_getaddrinfo_items_eq, 0.6, tor_malloc_, tor_realloc_, tor_free_); +/** If true, don't try to cache getaddrinfo results. */ +static int sandbox_getaddrinfo_cache_disabled = 0; + +/** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in + * tor-resolve, when we have no intention of initializing crypto or of + * installing the sandbox.*/ +void +sandbox_disable_getaddrinfo_cache(void) +{ + sandbox_getaddrinfo_cache_disabled = 1; +} + int sandbox_getaddrinfo(const char *name, const char *servname, const struct addrinfo *hints, @@ -1393,6 +1405,10 @@ sandbox_getaddrinfo(const char *name, const char *servname, int err; struct cached_getaddrinfo_item_t search, *item; + if (sandbox_getaddrinfo_cache_disabled) { + return getaddrinfo(name, NULL, hints, res); + } + if (servname != NULL) { log_warn(LD_BUG, "called with non-NULL servname"); return EAI_NONAME; @@ -1834,5 +1850,10 @@ sandbox_is_active(void) { return 0; } + +void +sandbox_disable_getaddrinfo_cache(void) +{ +} #endif diff --git a/src/common/sandbox.h b/src/common/sandbox.h index 20d5d5080..35d87772f 100644 --- a/src/common/sandbox.h +++ b/src/common/sandbox.h @@ -208,5 +208,7 @@ int sandbox_init(sandbox_cfg_t* cfg); /** Return true iff the sandbox is turned on. */ int sandbox_is_active(void); +void sandbox_disable_getaddrinfo_cache(void); + #endif /* SANDBOX_H_ */ diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c index 306f6c66a..480c7e52c 100644 --- a/src/tools/tor-resolve.c +++ b/src/tools/tor-resolve.c @@ -8,6 +8,7 @@ #include "../common/util.h" #include "address.h" #include "../common/torlog.h" +#include "sandbox.h" #include #include @@ -344,6 +345,7 @@ main(int argc, char **argv) log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); init_logging(); + sandbox_disable_getaddrinfo_cache(); arg = &argv[1]; n_args = argc-1; From d1fa0163e571913b8e4972c5c8a2d46798f46156 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 3 Oct 2014 12:15:09 -0400 Subject: [PATCH 2/4] Run correctly on OpenBSD systems without SSL_METHOD.get_cipher_by_char MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, make sure we will compile correctly on systems where they finally rip it out. Fixes issue #13325. Caused by this openbsd commit: ​http://marc.info/?l=openbsd-cvs&m=140768179627976&w=2 Reported by Fredzupy. --- changes/bug13325 | 4 ++++ configure.ac | 4 ++++ src/common/tortls.c | 48 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 changes/bug13325 diff --git a/changes/bug13325 b/changes/bug13325 new file mode 100644 index 000000000..b1da4d0bd --- /dev/null +++ b/changes/bug13325 @@ -0,0 +1,4 @@ + o Compilation fixes: + - Build and run correctly on systems like OpenBSD-current that + have patched OpenSSL to remove get_cipher_by_char and/or its + implementations. Fixes issue 13325. diff --git a/configure.ac b/configure.ac index 345601332..35484748c 100644 --- a/configure.ac +++ b/configure.ac @@ -524,6 +524,10 @@ else fi AC_SUBST(TOR_OPENSSL_LIBS) +AC_CHECK_MEMBERS([struct ssl_method_st.get_cipher_by_char], , , +[#include +]) + dnl ------------------------------------------------------ dnl Where do you live, zlib? And how do we call you? diff --git a/src/common/tortls.c b/src/common/tortls.c index c13b12fd4..9d45eb00f 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1478,6 +1478,43 @@ static uint16_t v2_cipher_list[] = { /** Have we removed the unrecognized ciphers from v2_cipher_list yet? */ static int v2_cipher_list_pruned = 0; +/** Return 0 if m does not support the cipher with ID cipher; + * return 1 if it does support it, or if we have no way to tell. */ +static int +find_cipher_by_id(const SSL_METHOD *m, uint16_t cipher) +{ + const SSL_CIPHER *c; +#ifdef HAVE_STRUCT_SSL_METHOD_ST_GET_CIPHER_BY_CHAR + if (m && m->get_cipher_by_char) { + unsigned char cipherid[3]; + set_uint16(cipherid, htons(cipher)); + cipherid[2] = 0; /* If ssl23_get_cipher_by_char finds no cipher starting + * with a two-byte 'cipherid', it may look for a v2 + * cipher with the appropriate 3 bytes. */ + c = m->get_cipher_by_char(cipherid); + if (c) + tor_assert((c->id & 0xffff) == cipher); + return c != NULL; + } else +#endif + if (m && m->get_cipher && m->num_ciphers) { + /* It would seem that some of the "let's-clean-up-openssl" forks have + * removed the get_cipher_by_char function. Okay, so now you get a + * quadratic search. + */ + int i; + for (i = 0; i < m->num_ciphers(); ++i) { + c = m->get_cipher(i); + if (c && (c->id & 0xffff) == cipher) { + return 1; + } + } + return 0; + } else { + return 1; /* No way to search */ + } +} + /** Remove from v2_cipher_list every cipher that we don't support, so that * comparing v2_cipher_list to a client's cipher list will give a sensible * result. */ @@ -1489,16 +1526,7 @@ prune_v2_cipher_list(void) inp = outp = v2_cipher_list; while (*inp) { - unsigned char cipherid[3]; - const SSL_CIPHER *cipher; - /* Is there no better way to do this? */ - set_uint16(cipherid, htons(*inp)); - cipherid[2] = 0; /* If ssl23_get_cipher_by_char finds no cipher starting - * with a two-byte 'cipherid', it may look for a v2 - * cipher with the appropriate 3 bytes. */ - cipher = m->get_cipher_by_char(cipherid); - if (cipher) { - tor_assert((cipher->id & 0xffff) == *inp); + if (find_cipher_by_id(m, *inp)) { *outp++ = *inp++; } else { inp++; From af73d3e4d83ba7f404068008ad617e02b8a0a77b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Oct 2014 11:50:05 -0400 Subject: [PATCH 3/4] Disable SSLv3 unconditionally. Closes ticket 13426. The POODLE attack doesn't affect Tor, but there's no reason to tempt fate: SSLv3 isn't going to get any better. --- changes/disable_sslv3 | 4 ++++ src/common/tortls.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changes/disable_sslv3 diff --git a/changes/disable_sslv3 b/changes/disable_sslv3 new file mode 100644 index 000000000..bb4c2df7a --- /dev/null +++ b/changes/disable_sslv3 @@ -0,0 +1,4 @@ + o Major security fixes: + - Disable support for SSLv3. All versions of OpenSSL in use with + Tor today support TLS 1.0 or later, so we can safely turn off + support for this old (and insecure) protocol. Fixes bug 13426. diff --git a/src/common/tortls.c b/src/common/tortls.c index 60aac6492..11fe220e2 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1176,10 +1176,11 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, goto error; #endif - /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */ + /* Tell OpenSSL to use TLS 1.0 or later but not SSL2 or SSL3. */ if (!(result->ctx = SSL_CTX_new(SSLv23_method()))) goto error; SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2); + SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv3); /* Disable TLS1.1 and TLS1.2 if they exist. We need to do this to * workaround a bug present in all OpenSSL 1.0.1 versions (as of 1 @@ -1204,6 +1205,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, SSL_CTX_set_options(result->ctx, SSL_OP_NO_TICKET); #endif + /* XXX This block is now obsolete. */ if ( #ifdef DISABLE_SSL3_HANDSHAKE 1 || From ab4b29625db720817f9af502199ebf1ee3ac5af7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 16 Oct 2014 13:04:11 -0400 Subject: [PATCH 4/4] Downgrade 'unexpected sendme cell from client' to PROTOCOL_WARN Closes 8093. --- changes/bug8093 | 3 +++ src/or/relay.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changes/bug8093 diff --git a/changes/bug8093 b/changes/bug8093 new file mode 100644 index 000000000..f0fbc618c --- /dev/null +++ b/changes/bug8093 @@ -0,0 +1,3 @@ + o Downgraded warnings: + - Downgrade the severity of the 'unexpected sendme cell from client' from + 'warn' to 'protocol warning'. Closes ticket 8093. diff --git a/src/or/relay.c b/src/or/relay.c index 4d71157db..9407df055 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1718,7 +1718,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, if (circ->package_window + CIRCWINDOW_INCREMENT > CIRCWINDOW_START_MAX) { static struct ratelim_t client_warn_ratelim = RATELIM_INIT(600); - log_fn_ratelim(&client_warn_ratelim, LOG_WARN, LD_PROTOCOL, + log_fn_ratelim(&client_warn_ratelim,LOG_PROTOCOL_WARN, LD_PROTOCOL, "Unexpected sendme cell from client. " "Closing circ (window %d).", circ->package_window);