diff options
Diffstat (limited to 'src')
49 files changed, 354 insertions, 171 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index 0b1b758d96..cbca7d3899 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -6839,7 +6839,7 @@ check_bridge_distribution_setting(const char *bd) }; unsigned i; for (i = 0; i < ARRAY_LENGTH(RECOGNIZED); ++i) { - if (!strcmp(bd, RECOGNIZED[i])) + if (!strcasecmp(bd, RECOGNIZED[i])) return 0; } diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c index 729e7a4478..efa0c19fa6 100644 --- a/src/app/config/confparse.c +++ b/src/app/config/confparse.c @@ -179,7 +179,7 @@ config_assign_value(const config_format_t *fmt, void *options, *(int *)lvalue = CFG_AUTO_PORT; break; } - /* fall through */ + FALLTHROUGH; case CONFIG_TYPE_INT: case CONFIG_TYPE_UINT: i = (int)tor_parse_long(c->value, 10, @@ -577,7 +577,7 @@ config_get_assigned_option(const config_format_t *fmt, const void *options, escape_val = 0; break; } - /* fall through */ + FALLTHROUGH; case CONFIG_TYPE_CSV_INTERVAL: case CONFIG_TYPE_INTERVAL: case CONFIG_TYPE_MSEC_INTERVAL: @@ -588,7 +588,7 @@ config_get_assigned_option(const config_format_t *fmt, const void *options, tor_asprintf(&result->value, "%d", *(int*)value); escape_val = 0; /* Can't need escape. */ break; - case CONFIG_TYPE_UINT64: /* Fall through */ + case CONFIG_TYPE_UINT64: FALLTHROUGH; case CONFIG_TYPE_MEMUNIT: tor_asprintf(&result->value, "%"PRIu64, (*(uint64_t*)value)); @@ -605,7 +605,7 @@ config_get_assigned_option(const config_format_t *fmt, const void *options, escape_val = 0; break; } - /* fall through */ + FALLTHROUGH; case CONFIG_TYPE_BOOL: result->value = tor_strdup(*(int*)value ? "1" : "0"); escape_val = 0; /* Can't need escape. */ diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 4b3c3bf6af..f0aa37e8da 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -774,6 +774,10 @@ tor_shutdown_event_loop_and_exit(int exitcode) main_loop_should_exit = 1; main_loop_exit_value = exitcode; + if (! tor_libevent_is_initialized()) { + return; /* No event loop to shut down. */ + } + /* Die with an assertion failure in ten seconds, if for some reason we don't * exit normally. */ /* XXXX We should consider this code if it's never used. */ diff --git a/src/core/or/channel.c b/src/core/or/channel.c index fd7bf62789..3886906875 100644 --- a/src/core/or/channel.c +++ b/src/core/or/channel.c @@ -1871,7 +1871,7 @@ channel_do_open_actions(channel_t *chan) tor_free(transport_name); /* Notify the DoS subsystem of a new client. */ if (tlschan && tlschan->conn) { - dos_new_client_conn(tlschan->conn); + dos_new_client_conn(tlschan->conn, transport_name); } } /* Otherwise the underlying transport can't tell us this, so skip it */ diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 4db283d20e..f874e39946 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -1238,7 +1238,7 @@ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn) /* But that should be happening any longer've disabled bufferevents. */ tor_assert_nonfatal_unreached_once(); - /* fall through */ + FALLTHROUGH; case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING: if (!(command_allowed_before_handshake(var_cell->command))) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index 21369fb538..f3a5791d6c 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -2106,7 +2106,7 @@ choose_good_exit_server(origin_circuit_t *circ, /* For these three, we want to pick the exit like a middle hop, * since it should be random. */ tor_assert_nonfatal(is_internal); - /* Falls through */ + FALLTHROUGH; case CIRCUIT_PURPOSE_C_GENERAL: if (is_internal) /* pick it like a middle hop */ return router_choose_random_node(NULL, options->ExcludeNodes, flags); diff --git a/src/core/or/circuitlist.c b/src/core/or/circuitlist.c index 145004c71d..be5ac3b7f6 100644 --- a/src/core/or/circuitlist.c +++ b/src/core/or/circuitlist.c @@ -787,7 +787,7 @@ circuit_purpose_to_controller_hs_state_string(uint8_t purpose) "Unrecognized circuit purpose: %d", (int)purpose); tor_fragile_assert(); - /* fall through */ + FALLTHROUGH; case CIRCUIT_PURPOSE_OR: case CIRCUIT_PURPOSE_C_GENERAL: @@ -2738,7 +2738,7 @@ assert_cpath_layer_ok(const crypt_path_t *cp) { case CPATH_STATE_OPEN: relay_crypto_assert_ok(&cp->crypto); - /* fall through */ + FALLTHROUGH; case CPATH_STATE_CLOSED: /*XXXX Assert that there's no handshake_state either. */ tor_assert(!cp->rend_dh_handshake_state); diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 000a7c36da..7273be3510 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -780,7 +780,7 @@ circuit_expire_building(void) TO_ORIGIN_CIRCUIT(victim)->build_state->pending_final_cpath == NULL) break; - /* fallthrough! */ + FALLTHROUGH; case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT: case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED: /* If we have reached this line, we want to spare the circ for now. */ diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 90991107dc..67a772be08 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -324,7 +324,7 @@ connection_edge_process_inbuf(edge_connection_t *conn, int package_partial) } /* Fall through if the connection is on a circuit without optimistic * data support. */ - /* Falls through. */ + FALLTHROUGH; case EXIT_CONN_STATE_CONNECTING: case AP_CONN_STATE_RENDDESC_WAIT: case AP_CONN_STATE_CIRCUIT_WAIT: diff --git a/src/core/or/dos.c b/src/core/or/dos.c index 5f9bbf90ab..d06eaa6d05 100644 --- a/src/core/or/dos.c +++ b/src/core/or/dos.c @@ -671,7 +671,7 @@ dos_log_heartbeat(void) /* Called when a new client connection has been established on the given * address. */ void -dos_new_client_conn(or_connection_t *or_conn) +dos_new_client_conn(or_connection_t *or_conn, const char *transport_name) { clientmap_entry_t *entry; @@ -692,7 +692,7 @@ dos_new_client_conn(or_connection_t *or_conn) } /* We are only interested in client connection from the geoip cache. */ - entry = geoip_lookup_client(&or_conn->real_addr, NULL, + entry = geoip_lookup_client(&or_conn->real_addr, transport_name, GEOIP_CLIENT_CONNECT); if (BUG(entry == NULL)) { /* Should never happen because we note down the address in the geoip diff --git a/src/core/or/dos.h b/src/core/or/dos.h index 95448d0530..058b7afce6 100644 --- a/src/core/or/dos.h +++ b/src/core/or/dos.h @@ -53,7 +53,8 @@ int dos_enabled(void); void dos_log_heartbeat(void); void dos_geoip_entry_about_to_free(const struct clientmap_entry_t *geoip_ent); -void dos_new_client_conn(or_connection_t *or_conn); +void dos_new_client_conn(or_connection_t *or_conn, + const char *transport_name); void dos_close_client_conn(const or_connection_t *or_conn); int dos_should_refuse_single_hop_client(void); diff --git a/src/core/or/onion.c b/src/core/or/onion.c index aa77465b96..aeddedd807 100644 --- a/src/core/or/onion.c +++ b/src/core/or/onion.c @@ -509,7 +509,7 @@ create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in, p += 16; space -= 16; } - /* Fall through */ + FALLTHROUGH; case CELL_CREATE_FAST: tor_assert(cell_in->handshake_len <= space); memcpy(p, cell_in->onionskin, cell_in->handshake_len); diff --git a/src/core/or/reasons.c b/src/core/or/reasons.c index a7952279ba..e21bfa670a 100644 --- a/src/core/or/reasons.c +++ b/src/core/or/reasons.c @@ -489,7 +489,7 @@ end_reason_to_http_connect_response_line(int endreason) return "HTTP/1.0 502 Bad Gateway (tor protocol violation)\r\n\r\n"; case END_STREAM_REASON_ENTRYPOLICY: return "HTTP/1.0 403 Forbidden (entry policy violation)\r\n\r\n"; - case END_STREAM_REASON_NOTDIRECTORY: /* Fall Through */ + case END_STREAM_REASON_NOTDIRECTORY: FALLTHROUGH; default: tor_assert_nonfatal_unreached(); return "HTTP/1.0 500 Internal Server Error (weird end reason)\r\n\r\n"; diff --git a/src/core/or/relay.c b/src/core/or/relay.c index dc88a6f649..f5fc1cfbb3 100644 --- a/src/core/or/relay.c +++ b/src/core/or/relay.c @@ -866,7 +866,7 @@ connection_ap_process_end_not_open( break; /* break means it'll close, below */ /* Else fall through: expire this circuit, clear the * chosen_exit_name field, and try again. */ - /* Falls through. */ + FALLTHROUGH; case END_STREAM_REASON_RESOLVEFAILED: case END_STREAM_REASON_TIMEOUT: case END_STREAM_REASON_MISC: diff --git a/src/core/or/scheduler.c b/src/core/or/scheduler.c index f85201b7d5..9f1a27d501 100644 --- a/src/core/or/scheduler.c +++ b/src/core/or/scheduler.c @@ -192,7 +192,7 @@ get_scheduler_type_string(scheduler_types_t type) case SCHEDULER_KIST_LITE: return "KISTLite"; case SCHEDULER_NONE: - /* fallthrough */ + FALLTHROUGH; default: tor_assert_unreached(); return "(N/A)"; @@ -288,7 +288,7 @@ select_scheduler(void) scheduler_kist_set_lite_mode(); goto end; case SCHEDULER_NONE: - /* fallthrough */ + FALLTHROUGH; default: /* Our option validation should have caught this. */ tor_assert_unreached(); diff --git a/src/core/proto/proto_socks.c b/src/core/proto/proto_socks.c index 8b78ed44c2..c7bf13b9f4 100644 --- a/src/core/proto/proto_socks.c +++ b/src/core/proto/proto_socks.c @@ -856,7 +856,7 @@ fetch_from_buf_socks(buf_t *buf, socks_request_t *req, case SOCKS_RESULT_TRUNCATED: if (datalen == n_pullup) return 0; - /* FALLTHRU */ + FALLTHROUGH; case SOCKS_RESULT_MORE_EXPECTED: res = 0; break; @@ -962,7 +962,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req, strlcpy((char*)req->reply, SOCKS_PROXY_IS_NOT_AN_HTTP_PROXY_MSG, MAX_SOCKS_REPLY_LEN); req->replylen = strlen((char*)req->reply)+1; - /* fall through */ + FALLTHROUGH; default: /* version is not socks4 or socks5 */ log_warn(LD_APP, "Socks version %d not recognized. (This port is not an " @@ -1067,7 +1067,10 @@ parse_socks_client(const uint8_t *data, size_t datalen, log_info(LD_NET, "SOCKS 5 client: need authentication."); *drain_out = -1; return 2; - /* fall through */ + default: + /* This wasn't supposed to be exhaustive; there are other + * authentication methods too. */ + ; } *reason = tor_strdup("server doesn't support any of our available " diff --git a/src/ext/csiphash.c b/src/ext/csiphash.c index a6a9846db4..a65b6fcbe6 100644 --- a/src/ext/csiphash.c +++ b/src/ext/csiphash.c @@ -88,13 +88,13 @@ uint64_t siphash24(const void *src, unsigned long src_sz, const struct sipkey *k } switch (src_sz - blocks) { - case 7: last7 |= (uint64_t)m[i + 6] << 48; /* Falls through. */ - case 6: last7 |= (uint64_t)m[i + 5] << 40; /* Falls through. */ - case 5: last7 |= (uint64_t)m[i + 4] << 32; /* Falls through. */ - case 4: last7 |= (uint64_t)m[i + 3] << 24; /* Falls through. */ - case 3: last7 |= (uint64_t)m[i + 2] << 16; /* Falls through. */ - case 2: last7 |= (uint64_t)m[i + 1] << 8; /* Falls through. */ - case 1: last7 |= (uint64_t)m[i + 0] ; /* Falls through. */ + case 7: last7 |= (uint64_t)m[i + 6] << 48; FALLTHROUGH; + case 6: last7 |= (uint64_t)m[i + 5] << 40; FALLTHROUGH; + case 5: last7 |= (uint64_t)m[i + 4] << 32; FALLTHROUGH; + case 4: last7 |= (uint64_t)m[i + 3] << 24; FALLTHROUGH; + case 3: last7 |= (uint64_t)m[i + 2] << 16; FALLTHROUGH; + case 2: last7 |= (uint64_t)m[i + 1] << 8; FALLTHROUGH; + case 1: last7 |= (uint64_t)m[i + 0] ; FALLTHROUGH; case 0: default:; } diff --git a/src/ext/ed25519/donna/ed25519_tor.c b/src/ext/ed25519/donna/ed25519_tor.c index 7f5ab398d8..a5bb6f4e21 100644 --- a/src/ext/ed25519/donna/ed25519_tor.c +++ b/src/ext/ed25519/donna/ed25519_tor.c @@ -35,6 +35,9 @@ #define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX) #include "orconfig.h" + +#include "lib/cc/compat_compiler.h" + #include "ed25519-donna.h" #include "ed25519_donna_tor.h" #include "ed25519-randombytes.h" @@ -366,4 +369,3 @@ ed25519_donna_scalarmult_with_group_order(unsigned char *out, } #include "test-internals.c" - diff --git a/src/ext/ed25519/donna/modm-donna-32bit.h b/src/ext/ed25519/donna/modm-donna-32bit.h index 0ef9e58fa1..5934d9ca9d 100644 --- a/src/ext/ed25519/donna/modm-donna-32bit.h +++ b/src/ext/ed25519/donna/modm-donna-32bit.h @@ -385,14 +385,14 @@ sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm size_t i = 0; bignum256modm_element_t carry = 0; switch (limbsize) { - case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ - case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */ + case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; + case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH; case 0: default: out[i] = (a[i] - b[i]) - carry; } @@ -403,14 +403,14 @@ sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm static int lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { switch (limbsize) { - case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* Falls through. */ - case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* Falls through. */ - case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* Falls through. */ - case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* Falls through. */ - case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* Falls through. */ - case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* Falls through. */ - case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* Falls through. */ - case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* Falls through. */ + case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; FALLTHROUGH; + case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; FALLTHROUGH; + case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; FALLTHROUGH; + case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; FALLTHROUGH; + case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; FALLTHROUGH; + case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; FALLTHROUGH; + case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; FALLTHROUGH; + case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; FALLTHROUGH; case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; } return 0; @@ -420,14 +420,14 @@ lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) static int lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { switch (limbsize) { - case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* Falls through. */ - case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* Falls through. */ - case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* Falls through. */ - case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* Falls through. */ - case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* Falls through. */ - case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* Falls through. */ - case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* Falls through. */ - case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* Falls through. */ + case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; FALLTHROUGH; + case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; FALLTHROUGH; + case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; FALLTHROUGH; + case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; FALLTHROUGH; + case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; FALLTHROUGH; + case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; FALLTHROUGH; + case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; FALLTHROUGH; + case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; FALLTHROUGH; case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; } return 1; diff --git a/src/ext/ed25519/donna/modm-donna-64bit.h b/src/ext/ed25519/donna/modm-donna-64bit.h index 06c98e3039..aa361afdbc 100644 --- a/src/ext/ed25519/donna/modm-donna-64bit.h +++ b/src/ext/ed25519/donna/modm-donna-64bit.h @@ -294,10 +294,10 @@ sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm size_t i = 0; bignum256modm_element_t carry = 0; switch (limbsize) { - case 4: out[i] = (a[i] - b[i]) ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */ - case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */ - case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */ - case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */ + case 4: out[i] = (a[i] - b[i]) ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH; + case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH; + case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH; + case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH; case 0: default: out[i] = (a[i] - b[i]) - carry; } @@ -310,10 +310,10 @@ lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) size_t i = 0; bignum256modm_element_t t, carry = 0; switch (limbsize) { - case 4: t = (a[i] - b[i]) ; carry = (t >> 63); i++; /* Falls through. */ - case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ - case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ - case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ + case 4: t = (a[i] - b[i]) ; carry = (t >> 63); i++; FALLTHROUGH; + case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; + case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; + case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; case 0: t = (a[i] - b[i]) - carry; carry = (t >> 63); } return (int)carry; @@ -325,10 +325,10 @@ lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) size_t i = 0; bignum256modm_element_t t, carry = 0; switch (limbsize) { - case 4: t = (b[i] - a[i]) ; carry = (t >> 63); i++; /* Falls through. */ - case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ - case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ - case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */ + case 4: t = (b[i] - a[i]) ; carry = (t >> 63); i++; FALLTHROUGH; + case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; + case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; + case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH; case 0: t = (b[i] - a[i]) - carry; carry = (t >> 63); } return (int)!carry; diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index 1bfb62538e..7c2159ce84 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -2263,7 +2263,7 @@ entry_guards_note_guard_success(guard_selection_t *gs, break; default: tor_assert_nonfatal_unreached(); - /* Fall through. */ + FALLTHROUGH; case GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD: if (guard->is_primary) { /* XXXX #20832 -- I don't actually like this logic. It seems to make diff --git a/src/feature/control/control.c b/src/feature/control/control.c index cc7ecff2ff..26ac12d307 100644 --- a/src/feature/control/control.c +++ b/src/feature/control/control.c @@ -4934,7 +4934,7 @@ handle_control_add_onion(control_connection_t *conn, case RSAE_BADAUTH: connection_printf_to_buf(conn, "512 Invalid client authorization\r\n"); break; - case RSAE_INTERNAL: /* FALLSTHROUGH */ + case RSAE_INTERNAL: FALLTHROUGH; default: connection_printf_to_buf(conn, "551 Failed to add Onion Service\r\n"); } diff --git a/src/feature/dirauth/keypin.c b/src/feature/dirauth/keypin.c index 667feb2c03..06cb9ba1ff 100644 --- a/src/feature/dirauth/keypin.c +++ b/src/feature/dirauth/keypin.c @@ -267,7 +267,7 @@ keypin_add_or_replace_entry_in_map(keypin_ent_t *ent) } tor_free(ent2); r = -1; - /* Fall through */ + /* Note lack of return here: we fall through to the next line. */ } keypin_add_entry_to_map(ent); diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 0fd1a47017..6725fc3369 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -1369,7 +1369,7 @@ directory_initiate_request,(directory_request_t *request)) case 1: /* start flushing conn */ conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING; - /* fall through */ + FALLTHROUGH; case 0: /* queue the command on the outbuf */ directory_send_command(conn, 1, request); diff --git a/src/feature/dirparse/parsecommon.c b/src/feature/dirparse/parsecommon.c index 632f5adff0..1664a77bbe 100644 --- a/src/feature/dirparse/parsecommon.c +++ b/src/feature/dirparse/parsecommon.c @@ -222,7 +222,7 @@ token_check_object(memarea_t *area, const char *kwd, kwd, crypto_pk_num_bits(tok->key)); RET_ERR(ebuf); } - /* fall through */ + FALLTHROUGH; case NEED_KEY: /* There must be some kind of key. */ if (!tok->key) { tor_snprintf(ebuf, sizeof(ebuf), "Missing public key for %s", kwd); @@ -384,12 +384,19 @@ get_next_token(memarea_t *area, RET_ERR("Couldn't parse object: missing footer or object much too big."); if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */ + if (o_syn != NEED_KEY && o_syn != NEED_KEY_1024 && o_syn != OBJ_OK) { + RET_ERR("Unexpected public key."); + } tok->key = crypto_pk_new(); if (crypto_pk_read_public_key_from_string(tok->key, obstart, eol-obstart)) RET_ERR("Couldn't parse public key."); } else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */ + if (o_syn != NEED_SKEY_1024 && o_syn != OBJ_OK) { + RET_ERR("Unexpected private key."); + } tok->key = crypto_pk_new(); - if (crypto_pk_read_private_key_from_string(tok->key, obstart, eol-obstart)) + if (crypto_pk_read_private_key1024_from_string(tok->key, + obstart, eol-obstart)) RET_ERR("Couldn't parse private key."); } else { /* If it's something else, try to base64-decode it */ int r; diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index fd2d266453..c65f857419 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -596,9 +596,14 @@ send_introduce1(origin_circuit_t *intro_circ, /* We need to find which intro point in the descriptor we are connected to * on intro_circ. */ ip = find_desc_intro_point_by_ident(intro_circ->hs_ident, desc); - if (BUG(ip == NULL)) { - /* If we can find a descriptor from this introduction circuit ident, we - * must have a valid intro point object. Permanent error. */ + if (ip == NULL) { + /* The following is possible if the descriptor was changed while we had + * this introduction circuit open and waiting for the rendezvous circuit to + * be ready. Which results in this situation where we can't find the + * corresponding intro point within the descriptor of the service. */ + log_info(LD_REND, "Unable to find introduction point for service %s " + "while trying to send an INTRODUCE1 cell.", + safe_str_client(onion_address)); goto perm_err; } @@ -1275,7 +1280,7 @@ hs_client_decode_descriptor(const char *desc_str, uint8_t subcredential[DIGEST256_LEN]; ed25519_public_key_t blinded_pubkey; hs_client_service_authorization_t *client_auth = NULL; - curve25519_secret_key_t *client_auht_sk = NULL; + curve25519_secret_key_t *client_auth_sk = NULL; tor_assert(desc_str); tor_assert(service_identity_pk); @@ -1284,7 +1289,7 @@ hs_client_decode_descriptor(const char *desc_str, /* Check if we have a client authorization for this service in the map. */ client_auth = find_client_auth(service_identity_pk); if (client_auth) { - client_auht_sk = &client_auth->enc_seckey; + client_auth_sk = &client_auth->enc_seckey; } /* Create subcredential for this HS so that we can decrypt */ @@ -1297,7 +1302,7 @@ hs_client_decode_descriptor(const char *desc_str, /* Parse descriptor */ ret = hs_desc_decode_descriptor(desc_str, subcredential, - client_auht_sk, desc); + client_auth_sk, desc); memwipe(subcredential, 0, sizeof(subcredential)); if (ret < 0) { goto err; diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 7e150599fc..6d32cae86c 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -3578,6 +3578,12 @@ hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports, goto err; } + if (ed25519_validate_pubkey(&service->keys.identity_pk) < 0) { + log_warn(LD_CONFIG, "Bad ed25519 private key was provided"); + ret = RSAE_BADPRIVKEY; + goto err; + } + /* Make sure we have at least one port. */ if (smartlist_len(service->config.ports) == 0) { log_warn(LD_CONFIG, "At least one VIRTPORT/TARGET must be specified " diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c index cc9f4cf490..e20a39482f 100644 --- a/src/feature/relay/dns.c +++ b/src/feature/relay/dns.c @@ -546,9 +546,9 @@ send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type, break; } else { answer_type = RESOLVED_TYPE_ERROR; - /* fall through. */ + /* We let this fall through and treat it as an error. */ } - /* Falls through. */ + FALLTHROUGH; case RESOLVED_TYPE_ERROR_TRANSIENT: case RESOLVED_TYPE_ERROR: { diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 1dbaf2ed66..e91550a78c 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -2635,15 +2635,20 @@ router_dump_router_to_string(routerinfo_t *router, } if (options->BridgeRelay) { - const char *bd; + char *bd = NULL; + if (options->BridgeDistribution && strlen(options->BridgeDistribution)) { - bd = options->BridgeDistribution; + bd = tor_strdup(options->BridgeDistribution); } else { - bd = "any"; + bd = tor_strdup("any"); } - if (strchr(bd, '\n') || strchr(bd, '\r')) - bd = escaped(bd); + + // Make sure our value is lowercased in the descriptor instead of just + // forwarding what the user wrote in their torrc directly. + tor_strlower(bd); + smartlist_add_asprintf(chunks, "bridge-distribution-request %s\n", bd); + tor_free(bd); } if (router->onion_curve25519_pkey) { diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index 4ca783c7c3..cde954da95 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -819,7 +819,7 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro, log_warn(LD_BUG, "Unknown failure type %u. Removing intro point.", failure_type); tor_fragile_assert(); - /* fall through */ + FALLTHROUGH; case INTRO_POINT_FAILURE_GENERIC: rend_cache_intro_failure_note(failure_type, (uint8_t *)failed_intro->identity_digest, diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h index 3a0f307186..fbe6a38f1f 100644 --- a/src/lib/cc/compat_compiler.h +++ b/src/lib/cc/compat_compiler.h @@ -50,6 +50,12 @@ #define CHECK_SCANF(formatIdx, firstArg) #endif /* defined(__GNUC__) */ +#if defined(HAVE_ATTR_FALLTHROUGH) +#define FALLTHROUGH __attribute__((fallthrough)) +#else +#define FALLTHROUGH +#endif + /* What GCC do we have? */ #ifdef __GNUC__ #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) diff --git a/src/lib/crypt_ops/crypto_digest.c b/src/lib/crypt_ops/crypto_digest.c index 26f06c6c79..de81b87b7e 100644 --- a/src/lib/crypt_ops/crypto_digest.c +++ b/src/lib/crypt_ops/crypto_digest.c @@ -50,8 +50,8 @@ digest_alg_to_nss_oid(digest_algorithm_t alg) case DIGEST_SHA1: return SEC_OID_SHA1; case DIGEST_SHA256: return SEC_OID_SHA256; case DIGEST_SHA512: return SEC_OID_SHA512; - case DIGEST_SHA3_256: /* Fall through */ - case DIGEST_SHA3_512: /* Fall through */ + case DIGEST_SHA3_256: FALLTHROUGH; + case DIGEST_SHA3_512: FALLTHROUGH; default: return SEC_OID_UNKNOWN; } @@ -98,12 +98,12 @@ static bool library_supports_digest(digest_algorithm_t alg) { switch (alg) { - case DIGEST_SHA1: /* Fall through */ - case DIGEST_SHA256: /* Fall through */ - case DIGEST_SHA512: /* Fall through */ + case DIGEST_SHA1: FALLTHROUGH; + case DIGEST_SHA256: FALLTHROUGH; + case DIGEST_SHA512: return true; - case DIGEST_SHA3_256: /* Fall through */ - case DIGEST_SHA3_512: /* Fall through */ + case DIGEST_SHA3_256: FALLTHROUGH; + case DIGEST_SHA3_512: FALLTHROUGH; default: return false; } @@ -313,8 +313,8 @@ crypto_digest_alloc_bytes(digest_algorithm_t alg) STRUCT_FIELD_SIZE(crypto_digest_t, f)) switch (alg) { #ifdef ENABLE_NSS - case DIGEST_SHA1: /* Fall through */ - case DIGEST_SHA256: /* Fall through */ + case DIGEST_SHA1: FALLTHROUGH; + case DIGEST_SHA256: FALLTHROUGH; case DIGEST_SHA512: return END_OF_FIELD(d.ctx); #else @@ -349,8 +349,8 @@ crypto_digest_new_internal(digest_algorithm_t algorithm) switch (algorithm) { #ifdef ENABLE_NSS - case DIGEST_SHA1: /* fall through */ - case DIGEST_SHA256: /* fall through */ + case DIGEST_SHA1: FALLTHROUGH; + case DIGEST_SHA256: FALLTHROUGH; case DIGEST_SHA512: r->d.ctx = PK11_CreateDigestContext(digest_alg_to_nss_oid(algorithm)); if (BUG(!r->d.ctx)) { @@ -451,8 +451,8 @@ crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, */ switch (digest->algorithm) { #ifdef ENABLE_NSS - case DIGEST_SHA1: /* fall through */ - case DIGEST_SHA256: /* fall through */ + case DIGEST_SHA1: FALLTHROUGH; + case DIGEST_SHA256: FALLTHROUGH; case DIGEST_SHA512: tor_assert(len <= UINT_MAX); SECStatus s = PK11_DigestOp(digest->d.ctx, @@ -471,7 +471,7 @@ crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, SHA512_Update(&digest->d.sha512, (void*)data, len); break; #endif - case DIGEST_SHA3_256: /* FALLSTHROUGH */ + case DIGEST_SHA3_256: FALLTHROUGH; case DIGEST_SHA3_512: keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len); break; @@ -540,7 +540,7 @@ crypto_digest_get_digest(crypto_digest_t *digest, SHA512_Final(r, &tmpenv.d.sha512); break; //LCOV_EXCL_START - case DIGEST_SHA3_256: /* FALLSTHROUGH */ + case DIGEST_SHA3_256: FALLTHROUGH; case DIGEST_SHA3_512: default: log_warn(LD_BUG, "Handling unexpected algorithm %d", digest->algorithm); diff --git a/src/lib/crypt_ops/crypto_ed25519.c b/src/lib/crypt_ops/crypto_ed25519.c index 400f963898..0a442bb739 100644 --- a/src/lib/crypt_ops/crypto_ed25519.c +++ b/src/lib/crypt_ops/crypto_ed25519.c @@ -795,7 +795,7 @@ ed25519_point_is_identity_element(const uint8_t *point) int ed25519_validate_pubkey(const ed25519_public_key_t *pubkey) { - uint8_t result[32] = {9}; + uint8_t result[32] = {0}; /* First check that we were not given the identity element */ if (ed25519_point_is_identity_element(pubkey->pubkey)) { diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c index c9189b0dfc..8fd8a8aa7b 100644 --- a/src/lib/crypt_ops/crypto_rsa.c +++ b/src/lib/crypt_ops/crypto_rsa.c @@ -490,7 +490,7 @@ crypto_pk_write_private_key_to_string(crypto_pk_t *env, static int crypto_pk_read_from_string_generic(crypto_pk_t *env, const char *src, size_t len, int severity, - bool private_key) + bool private_key, int max_bits) { if (len == (size_t)-1) // "-1" indicates "use the length of the string." len = strlen(src); @@ -510,7 +510,7 @@ crypto_pk_read_from_string_generic(crypto_pk_t *env, const char *src, } crypto_pk_t *pk = private_key - ? crypto_pk_asn1_decode_private((const char*)buf, n) + ? crypto_pk_asn1_decode_private((const char*)buf, n, max_bits) : crypto_pk_asn1_decode((const char*)buf, n); if (! pk) { log_fn(severity, LD_CRYPTO, @@ -539,7 +539,8 @@ int crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src, size_t len) { - return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, false); + return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, false, + -1); } /** Read a PEM-encoded private key from the <b>len</b>-byte string <b>src</b> @@ -550,7 +551,21 @@ int crypto_pk_read_private_key_from_string(crypto_pk_t *env, const char *src, ssize_t len) { - return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true); + return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true, + -1); +} + +/** + * As crypto_pk_read_private_key_from_string(), but reject any key + * with a modulus longer than 1024 bits before doing any expensive + * validation on it. + */ +int +crypto_pk_read_private_key1024_from_string(crypto_pk_t *env, + const char *src, ssize_t len) +{ + return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true, + 1024); } /** If a file is longer than this, we won't try to decode its private key */ @@ -578,7 +593,7 @@ crypto_pk_read_private_key_from_filename(crypto_pk_t *env, } int rv = crypto_pk_read_from_string_generic(env, buf, (ssize_t)st.st_size, - LOG_WARN, true); + LOG_WARN, true, -1); if (rv < 0) { log_warn(LD_CRYPTO, "Unable to decode private key from file %s", escaped(keyfile)); @@ -662,7 +677,7 @@ crypto_pk_base64_decode_private(const char *str, size_t len) goto out; } - pk = crypto_pk_asn1_decode_private(der, der_len); + pk = crypto_pk_asn1_decode_private(der, der_len, -1); out: memwipe(der, 0, len+1); diff --git a/src/lib/crypt_ops/crypto_rsa.h b/src/lib/crypt_ops/crypto_rsa.h index c1ea767f85..6d9cc8d30e 100644 --- a/src/lib/crypt_ops/crypto_rsa.h +++ b/src/lib/crypt_ops/crypto_rsa.h @@ -61,6 +61,8 @@ int crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src, size_t len); int crypto_pk_read_private_key_from_string(crypto_pk_t *env, const char *s, ssize_t len); +int crypto_pk_read_private_key1024_from_string(crypto_pk_t *env, + const char *src, ssize_t len); int crypto_pk_write_private_key_to_filename(crypto_pk_t *env, const char *fname); @@ -95,7 +97,8 @@ int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len); crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len); int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len); -crypto_pk_t *crypto_pk_asn1_decode_private(const char *str, size_t len); +crypto_pk_t *crypto_pk_asn1_decode_private(const char *str, size_t len, + int max_bits); int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space); int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out); void crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in); diff --git a/src/lib/crypt_ops/crypto_rsa_nss.c b/src/lib/crypt_ops/crypto_rsa_nss.c index ad2ad38b66..7abf6716f0 100644 --- a/src/lib/crypt_ops/crypto_rsa_nss.c +++ b/src/lib/crypt_ops/crypto_rsa_nss.c @@ -679,9 +679,12 @@ crypto_pk_asn1_encode_private(const crypto_pk_t *pk, /** Given a buffer containing the DER representation of the * private key <b>str</b>, decode and return the result on success, or NULL * on failure. + * + * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits + * without performing any expensive validation on it. */ crypto_pk_t * -crypto_pk_asn1_decode_private(const char *str, size_t len) +crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits) { tor_assert(str); tor_assert(len < INT_MAX); @@ -731,6 +734,15 @@ crypto_pk_asn1_decode_private(const char *str, size_t len) output = NULL; } + if (output) { + const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey); + if (max_bits >= 0 && bits > max_bits) { + log_info(LD_CRYPTO, "Private key longer than expected."); + crypto_pk_free(output); + output = NULL; + } + } + if (slot) PK11_FreeSlot(slot); diff --git a/src/lib/crypt_ops/crypto_rsa_openssl.c b/src/lib/crypt_ops/crypto_rsa_openssl.c index fbdc76ccd6..17eae24cc2 100644 --- a/src/lib/crypt_ops/crypto_rsa_openssl.c +++ b/src/lib/crypt_ops/crypto_rsa_openssl.c @@ -33,6 +33,7 @@ ENABLE_GCC_WARNING(redundant-decls) #include "lib/encoding/binascii.h" #include <string.h> +#include <stdbool.h> /** Declaration for crypto_pk_t structure. */ struct crypto_pk_t @@ -564,11 +565,71 @@ crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, return len; } +/** Check whether any component of a private key is too large in a way that + * seems likely to make verification too expensive. Return true if it's too + * long, and false otherwise. */ +static bool +rsa_private_key_too_long(RSA *rsa, int max_bits) +{ + const BIGNUM *n, *e, *p, *q, *d, *dmp1, *dmq1, *iqmp; +#ifdef OPENSSL_1_1_API + +#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1) + n = RSA_get0_n(rsa); + e = RSA_get0_e(rsa); + p = RSA_get0_p(rsa); + q = RSA_get0_q(rsa); + d = RSA_get0_d(rsa); + dmp1 = RSA_get0_dmp1(rsa); + dmq1 = RSA_get0_dmq1(rsa); + iqmp = RSA_get0_iqmp(rsa); +#else + /* The accessors above did not exist in openssl 1.1.0. */ + p = q = dmp1 = dmq1 = iqmp = NULL; + RSA_get0_key(rsa, &n, &e, &d); +#endif + + if (RSA_bits(rsa) > max_bits) + return true; +#else + n = rsa->n; + e = rsa->e; + p = rsa->p; + q = rsa->q; + d = rsa->d; + dmp1 = rsa->dmp1; + dmq1 = rsa->dmq1; + iqmp = rsa->iqmp; +#endif + + if (n && BN_num_bits(n) > max_bits) + return true; + if (e && BN_num_bits(e) > max_bits) + return true; + if (p && BN_num_bits(p) > max_bits) + return true; + if (q && BN_num_bits(q) > max_bits) + return true; + if (d && BN_num_bits(d) > max_bits) + return true; + if (dmp1 && BN_num_bits(dmp1) > max_bits) + return true; + if (dmq1 && BN_num_bits(dmq1) > max_bits) + return true; + if (iqmp && BN_num_bits(iqmp) > max_bits) + return true; + + return false; +} + /** Decode an ASN.1-encoded private key from <b>str</b>; return the result on * success and NULL on failure. + * + * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits + * without performing any expensive validation on it. */ crypto_pk_t * -crypto_pk_asn1_decode_private(const char *str, size_t len) +crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits) { RSA *rsa; unsigned char *buf; @@ -578,7 +639,12 @@ crypto_pk_asn1_decode_private(const char *str, size_t len) rsa = d2i_RSAPrivateKey(NULL, &cp, len); tor_free(buf); if (!rsa) { - crypto_openssl_log_errors(LOG_WARN,"decoding public key"); + crypto_openssl_log_errors(LOG_WARN,"decoding private key"); + return NULL; + } + if (max_bits >= 0 && rsa_private_key_too_long(rsa, max_bits)) { + log_info(LD_CRYPTO, "Private key longer than expected."); + RSA_free(rsa); return NULL; } crypto_pk_t *result = crypto_new_pk_from_openssl_rsa_(rsa); diff --git a/src/lib/evloop/compat_libevent.c b/src/lib/evloop/compat_libevent.c index 91eacb9938..939d77f857 100644 --- a/src/lib/evloop/compat_libevent.c +++ b/src/lib/evloop/compat_libevent.c @@ -181,6 +181,16 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg) event_get_version(), tor_libevent_get_method()); } +/** + * Return true iff the libevent module has been successfully initialized, + * and not subsequently shut down. + **/ +bool +tor_libevent_is_initialized(void) +{ + return the_event_base != NULL; +} + /** Return the current Libevent event base that we're set up to use. */ MOCK_IMPL(struct event_base *, tor_libevent_get_base, (void)) diff --git a/src/lib/evloop/compat_libevent.h b/src/lib/evloop/compat_libevent.h index afe887a013..92724c369c 100644 --- a/src/lib/evloop/compat_libevent.h +++ b/src/lib/evloop/compat_libevent.h @@ -13,6 +13,8 @@ #include "lib/testsupport/testsupport.h" #include "lib/malloc/malloc.h" +#include <stdbool.h> + void configure_libevent_logging(void); void suppress_libevent_log_msg(const char *msg); @@ -68,6 +70,7 @@ typedef struct tor_libevent_cfg { } tor_libevent_cfg; void tor_libevent_initialize(tor_libevent_cfg *cfg); +bool tor_libevent_is_initialized(void); MOCK_DECL(struct event_base *, tor_libevent_get_base, (void)); const char *tor_libevent_get_method(void); void tor_check_libevent_header_compatibility(void); diff --git a/src/lib/net/address.c b/src/lib/net/address.c index a2d234b742..076ca3eb34 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -926,6 +926,7 @@ tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src) break; case AF_INET6: memcpy(dest->addr.in6_addr.s6_addr, src->addr.in6_addr.s6_addr, 16); + break; case AF_UNSPEC: break; // LCOV_EXCL_START diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index e2356a1720..8f577b0660 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -491,24 +491,6 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) } } - rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), - SCMP_CMP_MASKED(1, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW, - O_RDONLY)); - if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp " - "error %d", rc); - return rc; - } - - rc = seccomp_rule_add_1(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(openat), - SCMP_CMP_MASKED(2, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_NOFOLLOW, - O_RDONLY)); - if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add openat syscall, received " - "libseccomp error %d", rc); - return rc; - } - return 0; } @@ -562,23 +544,6 @@ sb_chown(scmp_filter_ctx ctx, sandbox_cfg_t *filter) return 0; } -static int -sb__sysctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) -{ - int rc; - (void) filter; - (void) ctx; - - rc = seccomp_rule_add_0(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(_sysctl)); - if (rc != 0) { - log_err(LD_BUG,"(Sandbox) failed to add _sysctl syscall, " - "received libseccomp error %d", rc); - return rc; - } - - return 0; -} - /** * Function responsible for setting up the rename syscall for * the seccomp filter sandbox. @@ -1141,7 +1106,6 @@ static sandbox_filter_func_t filter_func[] = { sb_chmod, sb_open, sb_openat, - sb__sysctl, sb_rename, #ifdef __NR_fcntl64 sb_fcntl64, @@ -1518,14 +1482,14 @@ install_syscall_filter(sandbox_cfg_t* cfg) int rc = 0; scmp_filter_ctx ctx; - ctx = seccomp_init(SCMP_ACT_TRAP); + ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM)); if (ctx == NULL) { log_err(LD_BUG,"(Sandbox) failed to initialise libseccomp context"); rc = -1; goto end; } - // protectign sandbox parameter strings + // protecting sandbox parameter strings if ((rc = prot_strings(ctx, cfg))) { goto end; } diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c index e92cb9163f..b570216df0 100644 --- a/src/lib/tls/buffers_tls.c +++ b/src/lib/tls/buffers_tls.c @@ -146,10 +146,10 @@ buf_flush_to_tls(buf_t *buf, tor_tls_t *tls, size_t flushlen, size_t flushed = 0; ssize_t sz; tor_assert(buf_flushlen); - if (BUG(*buf_flushlen > buf->datalen)) { + IF_BUG_ONCE(*buf_flushlen > buf->datalen) { *buf_flushlen = buf->datalen; } - if (BUG(flushlen > *buf_flushlen)) { + IF_BUG_ONCE(flushlen > *buf_flushlen) { flushlen = *buf_flushlen; } sz = (ssize_t) flushlen; diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs index 2661d811c4..06fdf56c69 100644 --- a/src/rust/protover/protover.rs +++ b/src/rust/protover/protover.rs @@ -26,7 +26,7 @@ const FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS: &'static str = "0.2.9.3-alpha"; /// before concluding that someone is trying to DoS us /// /// C_RUST_COUPLED: protover.c `MAX_PROTOCOLS_TO_EXPAND` -const MAX_PROTOCOLS_TO_EXPAND: usize = (1 << 16); +const MAX_PROTOCOLS_TO_EXPAND: usize = 1 << 16; /// The maximum size an `UnknownProtocol`'s name may be. pub(crate) const MAX_PROTOCOL_NAME_LENGTH: usize = 100; diff --git a/src/test/test_config.c b/src/test/test_config.c index 8f011ce1f1..855725411a 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -5620,11 +5620,27 @@ test_config_check_bridge_distribution_setting_not_a_bridge(void *arg) static void test_config_check_bridge_distribution_setting_valid(void *arg) { - int ret = check_bridge_distribution_setting("https"); - (void)arg; - tt_int_op(ret, OP_EQ, 0); + // Check all the possible values we support right now. + tt_int_op(check_bridge_distribution_setting("none"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("any"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("https"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("email"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("moat"), OP_EQ, 0); + + // Check all the possible values we support right now with weird casing. + tt_int_op(check_bridge_distribution_setting("NoNe"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("anY"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("hTTps"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("emAIl"), OP_EQ, 0); + tt_int_op(check_bridge_distribution_setting("moAt"), OP_EQ, 0); + + // Invalid values. + tt_int_op(check_bridge_distribution_setting("x\rx"), OP_EQ, -1); + tt_int_op(check_bridge_distribution_setting("x\nx"), OP_EQ, -1); + tt_int_op(check_bridge_distribution_setting("\t\t\t"), OP_EQ, -1); + done: return; } diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index fa79f4cc47..5af0cce130 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1492,6 +1492,44 @@ test_crypto_pk_pem_encrypted(void *arg) } static void +test_crypto_pk_bad_size(void *arg) +{ + (void)arg; + crypto_pk_t *pk1 = pk_generate(0); + crypto_pk_t *pk2 = NULL; + char buf[2048]; + int n = crypto_pk_asn1_encode_private(pk1, buf, sizeof(buf)); + tt_int_op(n, OP_GT, 0); + + /* Set the max bit count smaller: we should refuse to decode the key.*/ + pk2 = crypto_pk_asn1_decode_private(buf, n, 1020); + tt_assert(! pk2); + + /* Set the max bit count one bit smaller: we should refuse to decode the + key.*/ + pk2 = crypto_pk_asn1_decode_private(buf, n, 1023); + tt_assert(! pk2); + + /* Correct size: should work. */ + pk2 = crypto_pk_asn1_decode_private(buf, n, 1024); + tt_assert(pk2); + crypto_pk_free(pk2); + + /* One bit larger: should work. */ + pk2 = crypto_pk_asn1_decode_private(buf, n, 1025); + tt_assert(pk2); + crypto_pk_free(pk2); + + /* Set the max bit count larger: it should decode fine. */ + pk2 = crypto_pk_asn1_decode_private(buf, n, 2048); + tt_assert(pk2); + + done: + crypto_pk_free(pk1); + crypto_pk_free(pk2); +} + +static void test_crypto_pk_invalid_private_key(void *arg) { (void)arg; @@ -3163,6 +3201,7 @@ struct testcase_t crypto_tests[] = { { "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL }, { "pk_base64", test_crypto_pk_base64, TT_FORK, NULL, NULL }, { "pk_pem_encrypted", test_crypto_pk_pem_encrypted, TT_FORK, NULL, NULL }, + { "pk_bad_size", test_crypto_pk_bad_size, 0, NULL, NULL }, { "pk_invalid_private_key", test_crypto_pk_invalid_private_key, 0, NULL, NULL }, CRYPTO_LEGACY(digests), diff --git a/src/test/test_dos.c b/src/test/test_dos.c index 4756c5014e..01d7cd006e 100644 --- a/src/test/test_dos.c +++ b/src/test/test_dos.c @@ -79,7 +79,7 @@ test_dos_conn_creation(void *arg) { /* Register many conns from this client but not enough to get it blocked */ unsigned int i; for (i = 0; i < max_concurrent_conns; i++) { - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); } } @@ -88,7 +88,7 @@ test_dos_conn_creation(void *arg) dos_conn_addr_get_defense_type(addr)); /* Register another conn and check that new conns are not allowed anymore */ - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ, dos_conn_addr_get_defense_type(addr)); @@ -98,7 +98,7 @@ test_dos_conn_creation(void *arg) dos_conn_addr_get_defense_type(addr)); /* Register another conn and see that defense measures get reactivated */ - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ, dos_conn_addr_get_defense_type(addr)); @@ -153,7 +153,7 @@ test_dos_circuit_creation(void *arg) * circuit counting subsystem */ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now); for (i = 0; i < min_conc_conns_for_cc ; i++) { - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); } /* Register new circuits for this client and conn, but not enough to get @@ -217,7 +217,7 @@ test_dos_bucket_refill(void *arg) /* Register this client */ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now); - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); /* Fetch this client from the geoip cache and get its DoS structs */ clientmap_entry_t *entry = geoip_lookup_client(addr, NULL, @@ -460,11 +460,11 @@ test_known_relay(void *arg) geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0); /* Suppose we have 5 connections in rapid succession, the counter should * always be 0 because we should ignore this. */ - dos_new_client_conn(&or_conn); - dos_new_client_conn(&or_conn); - dos_new_client_conn(&or_conn); - dos_new_client_conn(&or_conn); - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); + dos_new_client_conn(&or_conn, NULL); + dos_new_client_conn(&or_conn, NULL); + dos_new_client_conn(&or_conn, NULL); + dos_new_client_conn(&or_conn, NULL); entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT); tt_assert(entry); /* We should have a count of 0. */ @@ -474,8 +474,8 @@ test_known_relay(void *arg) * connection and see if we do get it. */ tor_addr_parse(&or_conn.real_addr, "42.42.42.43"); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0); - dos_new_client_conn(&or_conn); - dos_new_client_conn(&or_conn); + dos_new_client_conn(&or_conn, NULL); + dos_new_client_conn(&or_conn, NULL); entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT); tt_assert(entry); /* We should have a count of 2. */ diff --git a/src/test/test_socks.c b/src/test/test_socks.c index 783f4726ee..3686e1036b 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -778,7 +778,7 @@ test_socks_truncated(void *ptr) for (i = 0; i < ARRAY_LENGTH(commands); ++i) { for (j = 0; j < commands[i].len; ++j) { switch (commands[i].setup) { - default: /* Falls through */ + default: FALLTHROUGH; case NONE: /* This test calls for no setup on the socks state. */ break; diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 62d40a42fa..2c9c4538b9 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -348,6 +348,21 @@ main(int c, const char **v) atexit(remove_directory); + /* Look for TOR_SKIP_TESTCASES: a space-separated list of tests to skip. */ + const char *skip_tests = getenv("TOR_SKIP_TESTCASES"); + if (skip_tests) { + smartlist_t *skip = smartlist_new(); + smartlist_split_string(skip, skip_tests, NULL, + SPLIT_IGNORE_BLANK, -1); + int n = 0; + SMARTLIST_FOREACH_BEGIN(skip, char *, cp) { + n += tinytest_skip(testgroups, cp); + tor_free(cp); + } SMARTLIST_FOREACH_END(cp); + printf("Skipping %d testcases.\n", n); + smartlist_free(skip); + } + int have_failed = (tinytest_main(c, v, testgroups) != 0); free_pregenerated_keys(); diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h index baad733d0f..2b21abe888 100644 --- a/src/win32/orconfig.h +++ b/src/win32/orconfig.h @@ -218,7 +218,7 @@ #define USING_TWOS_COMPLEMENT /* Version number of package */ -#define VERSION "0.3.5.9-dev" +#define VERSION "0.3.5.10-dev" |