From 3c97ab3c24ba4a133377c7ec6ec89cc6903ffb2e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 17 Sep 2019 09:09:36 -0400 Subject: Treat an unexpected constant-sized VERSIONS cell as a PROTOCOL_WARN. We previously used tor_fragile_assert() to declare that this case could not happen: VERSIONS cells are always supposed to be variable-sized, right? This is incorrect, though. On a v1 link protocol connection, all cells are fixed-sized. There aren't supposed to be any VERSIONS cells with this version of the protocol, but apparently, somebody was messing up. (The v1 link protocol is obsolete, so probably the implementer responsible didn't mean to be using it.) Fixes bug 31107. Bugfix on 0.2.4.4-alpha, when we introduced a tor_fragile_assert() for this case. --- changes/bug31107 | 4 ++++ src/or/channeltls.c | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 changes/bug31107 diff --git a/changes/bug31107 b/changes/bug31107 new file mode 100644 index 0000000000..9652927c30 --- /dev/null +++ b/changes/bug31107 @@ -0,0 +1,4 @@ + o Minor bugfixes (logging, protocol violations): + - Do not log a nonfatal assertion failure when receiving a VERSIONS + cell on a connection using the obsolete v1 link protocol. Log a + protocol_warn instead. Fixes bug 31107; bugfix on 0.2.4.4-alpha. diff --git a/src/or/channeltls.c b/src/or/channeltls.c index d44f719138..6f4e413dc6 100644 --- a/src/or/channeltls.c +++ b/src/or/channeltls.c @@ -1098,7 +1098,15 @@ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn) /* do nothing */ break; case CELL_VERSIONS: - tor_fragile_assert(); + /* A VERSIONS cell should always be a variable-length cell, and + * so should never reach this function (which handles constant-sized + * cells). But if the connection is using the (obsolete) v1 link + * protocol, all cells will be treated as constant-sized, and so + * it's possible we'll reach this code. + */ + log_fn(LOG_PROTOCOL_WARN, LD_CHANNEL, + "Received unexpected VERSIONS cell on a channel using link " + "protocol %d; ignoring.", conn->link_proto); break; case CELL_NETINFO: ++stats_n_netinfo_cells_processed; -- cgit v1.2.3-54-g00ecf From 1e9488f2fd829d48eb5ef6c2170e0f7163061136 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 18 Sep 2019 11:11:05 -0400 Subject: Extract expressions in construct_ntor_key_map() No behavioral change here: this is just refactoring. --- src/feature/relay/router.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index dad2c6a50f..88a30cef08 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -278,19 +278,16 @@ construct_ntor_key_map(void) { di_digest256_map_t *m = NULL; - if (!tor_mem_is_zero((const char*) - curve25519_onion_key.pubkey.public_key, - CURVE25519_PUBKEY_LEN)) { - dimap_add_entry(&m, - curve25519_onion_key.pubkey.public_key, + const uint8_t *cur_pk = curve25519_onion_key.pubkey.public_key; + const uint8_t *last_pk = last_curve25519_onion_key.pubkey.public_key; + + if (!tor_mem_is_zero((const char *)cur_pk, CURVE25519_PUBKEY_LEN)) { + dimap_add_entry(&m, cur_pk, tor_memdup(&curve25519_onion_key, sizeof(curve25519_keypair_t))); } - if (!tor_mem_is_zero((const char*) - last_curve25519_onion_key.pubkey.public_key, - CURVE25519_PUBKEY_LEN)) { - dimap_add_entry(&m, - last_curve25519_onion_key.pubkey.public_key, + if (!tor_mem_is_zero((const char*)last_pk, CURVE25519_PUBKEY_LEN)) { + dimap_add_entry(&m, last_pk, tor_memdup(&last_curve25519_onion_key, sizeof(curve25519_keypair_t))); } -- cgit v1.2.3-54-g00ecf From 2da4d64a64a803f4b0a6d56e517b4288bef6c4f8 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 18 Sep 2019 11:14:45 -0400 Subject: Avoid a crash if our "current" and "old" ntor onion keys are equal Our dimap code asserts if you try to add the same key twice; this can't happen if everything is running smoothly, but it's possible if you try to start a relay where secret_onion_key_ntor is the same as secret_onion_key_ntor.old. Fixes bug 30916; bugfix on 0.2.4.8-alpha when ntor keys were introduced. --- changes/bug30916 | 4 ++++ src/feature/relay/router.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changes/bug30916 diff --git a/changes/bug30916 b/changes/bug30916 new file mode 100644 index 0000000000..b006bfc75d --- /dev/null +++ b/changes/bug30916 @@ -0,0 +1,4 @@ + o Minor bugfixes (relay): + - Avoid crashing when starting with a corrupt keys directory where + the old ntor key and the new ntor key are identical. Fixes bug 30916; + bugfix on 0.2.4.8-alpha. diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 88a30cef08..1dbaf2ed66 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -286,7 +286,8 @@ construct_ntor_key_map(void) tor_memdup(&curve25519_onion_key, sizeof(curve25519_keypair_t))); } - if (!tor_mem_is_zero((const char*)last_pk, CURVE25519_PUBKEY_LEN)) { + if (!tor_mem_is_zero((const char*)last_pk, CURVE25519_PUBKEY_LEN) && + tor_memneq(cur_pk, last_pk, CURVE25519_PUBKEY_LEN)) { dimap_add_entry(&m, last_pk, tor_memdup(&last_curve25519_onion_key, sizeof(curve25519_keypair_t))); -- cgit v1.2.3-54-g00ecf From f0e4120996d3a96252200ea5302dcde3af6e0bc0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 18 Sep 2019 15:38:33 -0400 Subject: Add a rate-limit to our warning about the disabled .exit notation This warning would previously be given every time we tried to open a connection to a foo.exit address, which could potentially be used to flood the logs. Now, we don't allow this warning to appear more than once every 15 minutes. Fixes bug 31466; bugfix on 0.2.2.1-alpha, when .exit was first deprecated. --- changes/ticket31466 | 5 +++++ src/or/connection_edge.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 changes/ticket31466 diff --git a/changes/ticket31466 b/changes/ticket31466 new file mode 100644 index 0000000000..e535b4502e --- /dev/null +++ b/changes/ticket31466 @@ -0,0 +1,5 @@ + o Minor bugfixes (logging): + - Rate-limit our the logging message about the obsolete .exit notation. + Previously, there was no limit on this warning, which could potentially + be triggered many times by a hostile website. Fixes bug 31466; + bugfix on 0.2.2.1-alpha. diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 7a97c632d1..5638d9a1be 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1186,9 +1186,11 @@ connection_ap_handshake_rewrite(entry_connection_t *conn, * disallowed when they're coming straight from the client, but you're * allowed to have them in MapAddress commands and so forth. */ if (!strcmpend(socks->address, ".exit") && !options->AllowDotExit) { - log_warn(LD_APP, "The \".exit\" notation is disabled in Tor due to " - "security risks. Set AllowDotExit in your torrc to enable " - "it (at your own risk)."); + static ratelim_t exit_warning_limit = RATELIM_INIT(60*15); + log_fn_ratelim(&exit_warning_limit, LOG_WARN, LD_APP, + "The \".exit\" notation is disabled in Tor due to " + "security risks. Set AllowDotExit in your torrc to enable " + "it (at your own risk)."); control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s", escaped(socks->address)); out->end_reason = END_STREAM_REASON_TORPROTOCOL; -- cgit v1.2.3-54-g00ecf From 15490816da0f8b651d67acef9c7f4e5bf9652ce2 Mon Sep 17 00:00:00 2001 From: Daniel Pinto Date: Sun, 22 Sep 2019 22:30:48 +0100 Subject: Fix bug when %including folder with comment only files. #31408 When processing a %included folder, a bug caused the pointer to the last element of the options list to be set to NULL when processing a file with only comments or whitepace. This could cause options from other files on the same folder to be discarded depending on the lines after the affected %include. --- changes/bug31408 | 4 +++ src/lib/fs/conffile.c | 10 +++++--- src/test/test_config.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 changes/bug31408 diff --git a/changes/bug31408 b/changes/bug31408 new file mode 100644 index 0000000000..7a6744cee4 --- /dev/null +++ b/changes/bug31408 @@ -0,0 +1,4 @@ + o Major bugfixes (torrc): + - Fix configuration files in a %included folder containing a + configuration file with only comments or whitespace being + ignored. Fixes bug 31408; bugfix on 0.4.0.5. diff --git a/src/lib/fs/conffile.c b/src/lib/fs/conffile.c index 7bb2f23931..0d5d56b335 100644 --- a/src/lib/fs/conffile.c +++ b/src/lib/fs/conffile.c @@ -153,16 +153,18 @@ config_process_include(const char *path, int recursion_level, int extended, int rv = -1; SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) { config_line_t *included_config = NULL; + config_line_t *included_config_last = NULL; if (config_get_included_config(config_file, recursion_level, extended, - &included_config, list_last, + &included_config, &included_config_last, opened_lst) < 0) { goto done; } *next = included_config; - if (*list_last) - next = &(*list_last)->next; - + if (included_config_last) { + next = &included_config_last->next; + *list_last = included_config_last; + } } SMARTLIST_FOREACH_END(config_file); *list = ret_list; rv = 0; diff --git a/src/test/test_config.c b/src/test/test_config.c index 0de6b12919..8f011ce1f1 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -5286,6 +5286,73 @@ test_config_include_folder_order(void *data) tor_free(dir); } +static void +test_config_include_blank_file_last(void *data) +{ + (void)data; + + config_line_t *result = NULL; + char *torrcd = NULL; + char *path = NULL; + char *dir = tor_strdup(get_fname("test_include_blank_file_last")); + tt_ptr_op(dir, OP_NE, NULL); + +#ifdef _WIN32 + tt_int_op(mkdir(dir), OP_EQ, 0); +#else + tt_int_op(mkdir(dir, 0700), OP_EQ, 0); +#endif + + tor_asprintf(&torrcd, "%s"PATH_SEPARATOR"%s", dir, "torrc.d"); + +#ifdef _WIN32 + tt_int_op(mkdir(torrcd), OP_EQ, 0); +#else + tt_int_op(mkdir(torrcd, 0700), OP_EQ, 0); +#endif + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "aa_1st"); + tt_int_op(write_str_to_file(path, "Test 1\n", 0), OP_EQ, 0); + tor_free(path); + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "bb_2nd"); + tt_int_op(write_str_to_file(path, "Test 2\n", 0), OP_EQ, 0); + tor_free(path); + + tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", torrcd, "cc_comment"); + tt_int_op(write_str_to_file(path, "# comment only\n", 0), OP_EQ, 0); + tor_free(path); + + char torrc_contents[1000]; + tor_snprintf(torrc_contents, sizeof(torrc_contents), + "%%include %s\n" + "Test 3\n", + torrcd); + + int include_used; + tt_int_op(config_get_lines_include(torrc_contents, &result, 0, &include_used, + NULL), OP_EQ, 0); + tt_ptr_op(result, OP_NE, NULL); + tt_int_op(include_used, OP_EQ, 1); + + int len = 0; + config_line_t *next; + for (next = result; next != NULL; next = next->next) { + char expected[10]; + tor_snprintf(expected, sizeof(expected), "%d", len + 1); + tt_str_op(next->key, OP_EQ, "Test"); + tt_str_op(next->value, OP_EQ, expected); + len++; + } + tt_int_op(len, OP_EQ, 3); + + done: + config_free_lines(result); + tor_free(torrcd); + tor_free(path); + tor_free(dir); +} + static void test_config_include_path_syntax(void *data) { @@ -5848,6 +5915,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(include_recursion_before_after, 0), CONFIG_TEST(include_recursion_after_only, 0), CONFIG_TEST(include_folder_order, 0), + CONFIG_TEST(include_blank_file_last, 0), CONFIG_TEST(include_path_syntax, 0), CONFIG_TEST(include_not_processed, 0), CONFIG_TEST(include_has_include, 0), -- cgit v1.2.3-54-g00ecf From 0614f839054a52e6e1a79a366fcc70da0691df66 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 23 Sep 2019 11:11:50 +1000 Subject: changes: use correct bugfix release, and reword changes file for 31408 --- changes/bug31408 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/changes/bug31408 b/changes/bug31408 index 7a6744cee4..3e4ffa927d 100644 --- a/changes/bug31408 +++ b/changes/bug31408 @@ -1,4 +1,5 @@ o Major bugfixes (torrc): - - Fix configuration files in a %included folder containing a - configuration file with only comments or whitespace being - ignored. Fixes bug 31408; bugfix on 0.4.0.5. + - Stop ignoring torrc options after an %include directive, when the + included directory ends with a file that does not contain any config + options. (But does contain comments or whitespace.) + Fixes bug 31408; bugfix on 0.3.1.1-alpha. -- cgit v1.2.3-54-g00ecf From cf2b00d3f50f3421c3c22777113e25d5f7812e67 Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 6 Aug 2019 01:33:14 +1000 Subject: test/rebind: Make control formatting and log parsing more robust * actually sleep when tor has not logged anything * log at debug level when waiting for tor to log something * backslash-replace bad UTF-8 characters in logs * format control messages as ASCII: tor does not accept UTF-8 control commands Fixes bug 31837; bugfix on 0.3.5.1-alpha. --- changes/bug31837 | 5 +++++ src/test/test_rebind.py | 16 +++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 changes/bug31837 diff --git a/changes/bug31837 b/changes/bug31837 new file mode 100644 index 0000000000..0f976edfe0 --- /dev/null +++ b/changes/bug31837 @@ -0,0 +1,5 @@ + o Minor bugfixes (testing): + - When testing port rebinding, don't busy-wait for tor to log. Instead, + actually sleep for a short time before polling again. Also improve the + formatting of control commands and log messages. + Fixes bug 31837; bugfix on 0.3.5.1-alpha. diff --git a/src/test/test_rebind.py b/src/test/test_rebind.py index 45ad1c5469..30a587858f 100644 --- a/src/test/test_rebind.py +++ b/src/test/test_rebind.py @@ -31,15 +31,17 @@ def wait_for_log(s): cutoff = time.time() + LOG_TIMEOUT while time.time() < cutoff: l = tor_process.stdout.readline() - l = l.decode('utf8') + l = l.decode('utf8', 'backslashreplace') if s in l: logging.info('Tor logged: "{}"'.format(l.strip())) return - logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) # readline() returns a blank string when there is no output # avoid busy-waiting - if len(s) == 0: + if len(l) == 0: + logging.debug('Tor has not logged anything, waiting for "{}"'.format(s)) time.sleep(LOG_WAIT) + else: + logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) fail('Could not find "{}" in logs after {} seconds'.format(s, LOG_TIMEOUT)) def pick_random_port(): @@ -119,18 +121,18 @@ if control_socket.connect_ex(('127.0.0.1', control_port)): tor_process.terminate() fail('Cannot connect to ControlPort') -control_socket.sendall('AUTHENTICATE \r\n'.encode('utf8')) -control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('AUTHENTICATE \r\n'.encode('ascii')) +control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SIGNAL HALT\r\n'.encode('utf8')) +control_socket.sendall('SIGNAL HALT\r\n'.encode('ascii')) wait_for_log('exiting cleanly') logging.info('OK') -- cgit v1.2.3-54-g00ecf