Merge branch 'maint-0.3.5' into maint-0.4.0

This commit is contained in:
teor 2019-08-12 13:10:05 +10:00
commit 20943d00f1
No known key found for this signature in database
GPG Key ID: 10FEAA0E7075672A
15 changed files with 83 additions and 23 deletions

3
changes/bug22619 Normal file
View File

@ -0,0 +1,3 @@
o Minor bugfixes (circuit isolation):
- Fix a logic error that prevented the SessionGroup sub-option from
being accepted. Fixes bug 22619; bugfix on 0.2.7.2-alpha.

5
changes/bug29034 Normal file
View File

@ -0,0 +1,5 @@
o Major bugfixes (Onion service reachability):
- Properly clean up the introduction point map when circuits change purpose
from onion service circuits to pathbias, measurement, or other circuit types.
This should fix some service-side instances of introduction point failure.
Fixes bug 29034; bugfix on 0.3.2.1-alpha.

4
changes/bug29670 Normal file
View File

@ -0,0 +1,4 @@
o Minor bugfixes (configuration, proxies):
- Fix a bug that prevented us from supporting SOCKS5 proxies that want
authentication along with configued (but unused!)
ClientTransportPlugins. Fixes bug 29670; bugfix on 0.2.6.1-alpha.

11
changes/bug29875 Normal file
View File

@ -0,0 +1,11 @@
o Major bugfixes (bridges):
- Do not count previously configured working bridges towards our total of
working bridges. Previously, when Tor's list of bridges changed, it
would think that the old bridges were still usable, and delay fetching
router descriptors for the new ones. Fixes part of bug 29875; bugfix
on 0.3.0.1-alpha.
- Consider our directory information to have changed when our list of
bridges changes. Previously, Tor would not re-compute the status of its
directory information when bridges changed, and therefore would not
realize that it was no longer able to build circuits. Fixes part of bug
29875.

4
changes/bug30148 Normal file
View File

@ -0,0 +1,4 @@
o Minor bugfixes (memory leak):
- Avoid a minor memory leak that could occur on relays when
creating a keys directory failed. Fixes bug 30148; bugfix on
0.3.3.1-alpha.

3
changes/bug30190 Normal file
View File

@ -0,0 +1,3 @@
o Minor bugfixes (lib):
do not log a warning for OpenSSL versions that should be compatible
Fixes bug 30190; bugfix on 0.2.4.2-alpha

4
changes/ticket29617 Normal file
View File

@ -0,0 +1,4 @@
o Minor bugfixes (out-of-memory handler):
- When purging the DNS cache because of an out-of-memory condition,
try purging just the older entries at first. Previously, we would
purge the whole thing. Fixes bug 29617; bugfix on 0.3.5.1-alpha.

View File

@ -2382,7 +2382,8 @@ options_act(const or_options_t *old_options)
if (!bool_eq(directory_fetches_dir_info_early(options), if (!bool_eq(directory_fetches_dir_info_early(options),
directory_fetches_dir_info_early(old_options)) || directory_fetches_dir_info_early(old_options)) ||
!bool_eq(directory_fetches_dir_info_later(options), !bool_eq(directory_fetches_dir_info_later(options),
directory_fetches_dir_info_later(old_options))) { directory_fetches_dir_info_later(old_options)) ||
!config_lines_eq(old_options->Bridges, options->Bridges)) {
/* Make sure update_router_have_minimum_dir_info() gets called. */ /* Make sure update_router_have_minimum_dir_info() gets called. */
router_dir_info_changed(); router_dir_info_changed();
/* We might need to download a new consensus status later or sooner than /* We might need to download a new consensus status later or sooner than
@ -7071,7 +7072,7 @@ parse_port_config(smartlist_t *out,
if (!strcasecmpstart(elt, "SessionGroup=")) { if (!strcasecmpstart(elt, "SessionGroup=")) {
int group = (int)tor_parse_long(elt+strlen("SessionGroup="), int group = (int)tor_parse_long(elt+strlen("SessionGroup="),
10, 0, INT_MAX, &ok, NULL); 10, 0, INT_MAX, &ok, NULL);
if (!ok || !allow_no_stream_options) { if (!ok || allow_no_stream_options) {
log_warn(LD_CONFIG, "Invalid %sPort option '%s'", log_warn(LD_CONFIG, "Invalid %sPort option '%s'",
portname, escaped(elt)); portname, escaped(elt));
goto err; goto err;

View File

@ -182,7 +182,7 @@ static const char *connection_proxy_state_to_string(int state);
static int connection_read_https_proxy_response(connection_t *conn); static int connection_read_https_proxy_response(connection_t *conn);
static void connection_send_socks5_connect(connection_t *conn); static void connection_send_socks5_connect(connection_t *conn);
static const char *proxy_type_to_string(int proxy_type); static const char *proxy_type_to_string(int proxy_type);
static int get_proxy_type(void); static int conn_get_proxy_type(const connection_t *conn);
const tor_addr_t *conn_get_outbound_address(sa_family_t family, const tor_addr_t *conn_get_outbound_address(sa_family_t family,
const or_options_t *options, unsigned int conn_type); const or_options_t *options, unsigned int conn_type);
static void reenable_blocked_connection_init(const or_options_t *options); static void reenable_blocked_connection_init(const or_options_t *options);
@ -2282,18 +2282,27 @@ connection_proxy_state_to_string(int state)
return states[state]; return states[state];
} }
/** Returns the global proxy type used by tor. Use this function for /** Returns the proxy type used by tor for a single connection, for
* logging or high-level purposes, don't use it to fill the * logging or high-level purposes. Don't use it to fill the
* <b>proxy_type</b> field of or_connection_t; use the actual proxy * <b>proxy_type</b> field of or_connection_t; use the actual proxy
* protocol instead.*/ * protocol instead.*/
static int static int
get_proxy_type(void) conn_get_proxy_type(const connection_t *conn)
{ {
const or_options_t *options = get_options(); const or_options_t *options = get_options();
if (options->ClientTransportPlugin) if (options->ClientTransportPlugin) {
/* If we have plugins configured *and* this addr/port is a known bridge
* with a transport, then we should be PROXY_PLUGGABLE. */
const transport_t *transport = NULL;
int r;
r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
if (r == 0 && transport)
return PROXY_PLUGGABLE; return PROXY_PLUGGABLE;
else if (options->HTTPSProxy) }
/* In all other cases, we're using a global proxy. */
if (options->HTTPSProxy)
return PROXY_CONNECT; return PROXY_CONNECT;
else if (options->Socks4Proxy) else if (options->Socks4Proxy)
return PROXY_SOCKS4; return PROXY_SOCKS4;
@ -2380,7 +2389,7 @@ connection_proxy_connect(connection_t *conn, int type)
arguments to transmit. If we do, compress all arguments to arguments to transmit. If we do, compress all arguments to
a single string in 'socks_args_string': */ a single string in 'socks_args_string': */
if (get_proxy_type() == PROXY_PLUGGABLE) { if (conn_get_proxy_type(conn) == PROXY_PLUGGABLE) {
socks_args_string = socks_args_string =
pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port); pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port);
if (socks_args_string) if (socks_args_string)
@ -2440,7 +2449,7 @@ connection_proxy_connect(connection_t *conn, int type)
Socks5ProxyUsername or if we want to pass arguments to our Socks5ProxyUsername or if we want to pass arguments to our
pluggable transport proxy: */ pluggable transport proxy: */
if ((options->Socks5ProxyUsername) || if ((options->Socks5ProxyUsername) ||
(get_proxy_type() == PROXY_PLUGGABLE && (conn_get_proxy_type(conn) == PROXY_PLUGGABLE &&
(get_socks_args_by_bridge_addrport(&conn->addr, conn->port)))) { (get_socks_args_by_bridge_addrport(&conn->addr, conn->port)))) {
/* number of auth methods */ /* number of auth methods */
buf[1] = 2; buf[1] = 2;
@ -2633,16 +2642,16 @@ connection_read_proxy_handshake(connection_t *conn)
const char *user, *pass; const char *user, *pass;
char *socks_args_string = NULL; char *socks_args_string = NULL;
if (get_proxy_type() == PROXY_PLUGGABLE) { if (conn_get_proxy_type(conn) == PROXY_PLUGGABLE) {
socks_args_string = socks_args_string =
pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port); pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port);
if (!socks_args_string) { if (!socks_args_string) {
log_warn(LD_NET, "Could not create SOCKS args string."); log_warn(LD_NET, "Could not create SOCKS args string for PT.");
ret = -1; ret = -1;
break; break;
} }
log_debug(LD_NET, "SOCKS5 arguments: %s", socks_args_string); log_debug(LD_NET, "PT SOCKS5 arguments: %s", socks_args_string);
tor_assert(strlen(socks_args_string) > 0); tor_assert(strlen(socks_args_string) > 0);
tor_assert(strlen(socks_args_string) <= MAX_SOCKS5_AUTH_SIZE_TOTAL); tor_assert(strlen(socks_args_string) <= MAX_SOCKS5_AUTH_SIZE_TOTAL);

View File

@ -3078,6 +3078,12 @@ circuit_change_purpose(circuit_t *circ, uint8_t new_purpose)
circ->purpose, circ->purpose,
circuit_purpose_to_string(new_purpose), circuit_purpose_to_string(new_purpose),
new_purpose); new_purpose);
/* Take specific actions if we are repurposing a hidden service circuit. */
if (circuit_purpose_is_hidden_service(circ->purpose) &&
!circuit_purpose_is_hidden_service(new_purpose)) {
hs_circ_cleanup(circ);
}
} }
old_purpose = circ->purpose; old_purpose = circ->purpose;

View File

@ -3300,6 +3300,9 @@ num_bridges_usable,(int use_maybe_reachable))
} }
SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) { SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) {
/* Not a bridge, or not one we are configured to be able to use. */
if (! guard->is_filtered_guard)
continue;
/* Definitely not usable */ /* Definitely not usable */
if (guard->is_reachable == GUARD_REACHABLE_NO) if (guard->is_reachable == GUARD_REACHABLE_NO)
continue; continue;

View File

@ -2187,7 +2187,8 @@ dns_cache_handle_oom(time_t now, size_t min_remove_bytes)
current_size -= bytes_removed; current_size -= bytes_removed;
total_bytes_removed += bytes_removed; total_bytes_removed += bytes_removed;
time_inc += 3600; /* Increase time_inc by 1 hour. */ /* Increase time_inc by a reasonable fraction. */
time_inc += (MAX_DNS_TTL_AT_EXIT / 4);
} while (total_bytes_removed < min_remove_bytes); } while (total_bytes_removed < min_remove_bytes);
return total_bytes_removed; return total_bytes_removed;

View File

@ -188,7 +188,7 @@ load_ed_keys(const or_options_t *options, time_t now)
/* Check/Create the key directory */ /* Check/Create the key directory */
if (create_keys_directory(options) < 0) if (create_keys_directory(options) < 0)
return -1; goto err;
char *fname; char *fname;
if (options->master_key_fname) { if (options->master_key_fname) {

View File

@ -213,6 +213,14 @@ crypto_openssl_early_init(void)
!strcmp(version_str, OPENSSL_VERSION_TEXT)) { !strcmp(version_str, OPENSSL_VERSION_TEXT)) {
log_info(LD_CRYPTO, "OpenSSL version matches version from headers " log_info(LD_CRYPTO, "OpenSSL version matches version from headers "
"(%lx: %s).", version_num, version_str); "(%lx: %s).", version_num, version_str);
} else if ((version_num & 0xffff0000) ==
(OPENSSL_VERSION_NUMBER & 0xffff0000)) {
log_notice(LD_CRYPTO,
"We compiled with OpenSSL %lx: %s and we "
"are running with OpenSSL %lx: %s. "
"These two versions should be binary compatible.",
(unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
version_num, version_str);
} else { } else {
log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the " log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the "
"version we're running with. If you get weird crashes, that " "version we're running with. If you get weird crashes, that "

View File

@ -4569,16 +4569,14 @@ test_config_parse_port_config__ports__ports_given(void *data)
"127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
// TODO: this seems wrong. Shouldn't it be the other way around? // Test failure for a SessionGroup argument with valid value but with no
// Potential bug. // stream options allowed
// Test failure for a SessionGroup argument with valid value but with stream
// options allowed
config_free_lines(config_port_invalid); config_port_invalid = NULL; config_free_lines(config_port_invalid); config_port_invalid = NULL;
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
smartlist_clear(slout); smartlist_clear(slout);
config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123"); config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123");
ret = parse_port_config(slout, config_port_invalid, "DNS", 0, ret = parse_port_config(slout, config_port_invalid, "DNS", 0,
"127.0.0.44", 0, 0); "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
// Test failure for more than one SessionGroup argument // Test failure for more than one SessionGroup argument
@ -4588,7 +4586,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123 " config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123 "
"SessionGroup=321"); "SessionGroup=321");
ret = parse_port_config(slout, config_port_invalid, "DNS", 0, ret = parse_port_config(slout, config_port_invalid, "DNS", 0,
"127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); "127.0.0.44", 0, 0);
tt_int_op(ret, OP_EQ, -1); tt_int_op(ret, OP_EQ, -1);
// Test success with a sessiongroup options // Test success with a sessiongroup options
@ -4597,7 +4595,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
smartlist_clear(slout); smartlist_clear(slout);
config_port_valid = mock_config_line("DNSPort", "42 SessionGroup=1111122"); config_port_valid = mock_config_line("DNSPort", "42 SessionGroup=1111122");
ret = parse_port_config(slout, config_port_valid, "DNS", 0, ret = parse_port_config(slout, config_port_valid, "DNS", 0,
"127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); "127.0.0.44", 0, 0);
tt_int_op(ret, OP_EQ, 0); tt_int_op(ret, OP_EQ, 0);
tt_int_op(smartlist_len(slout), OP_EQ, 1); tt_int_op(smartlist_len(slout), OP_EQ, 1);
port_cfg = (port_cfg_t *)smartlist_get(slout, 0); port_cfg = (port_cfg_t *)smartlist_get(slout, 0);