diff options
249 files changed, 4695 insertions, 2606 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d2d0d55dd4..402c7646c0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,33 +13,3 @@ build: - make check || (e=$?; cat test-suite.log; exit $e) - make install -update: - only: - - schedules - script: - - "apt-get install -y --fix-missing git openssh-client" - - # Run ssh-agent (inside the build environment) - - eval $(ssh-agent -s) - - # Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store - - ssh-add <(echo "$DEPLOY_KEY") - - # For Docker builds disable host key checking. Be aware that by adding that - # you are susceptible to man-in-the-middle attacks. - # WARNING: Use this only with the Docker executor, if you use it with shell - # you will overwrite your user's SSH config. - - mkdir -p ~/.ssh - - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' - # In order to properly check the server's host key, assuming you created the - # SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines - # instead. - - mkdir -p ~/.ssh - - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts' - - echo "merging from torgit" - - git config --global user.email "labadmin@oniongit.eu" - - git config --global user.name "gitadmin" - - "mkdir tor" - - "cd tor" - - git clone --bare https://git.torproject.org/tor.git - - git push --mirror git@oniongit.eu:network/tor.git diff --git a/.travis.yml b/.travis.yml index ccd2107fd2..16d2e432df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,8 @@ env: ## Turn off tor's sandbox in chutney, until we fix sandbox errors that are ## triggered by Ubuntu Xenial and Bionic. See #32722. - CHUTNEY_TOR_SANDBOX="0" + ## The default target for chutney jobs + - CHUTNEY_MAKE="test-network-all" matrix: ## This matrix entry is required, but it doesn't actually create any jobs - @@ -41,34 +43,48 @@ env: matrix: ## include creates builds with gcc, linux, unless we override those defaults include: - ## We run basic tests on macOS + ## We run chutney on macOS, because macOS Travis has IPv6 + ## But we only run the IPv6 chutney tests, to speed up the job + - env: CHUTNEY_MAKE="test-network-ipv6" CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes" + os: osx + + ## We also run basic tests on macOS - compiler: clang os: osx ## Turn off some newer features, turn on clang's -Wtypedef-redefinition env: C_DIALECT_OPTIONS="-std=gnu99" - ## We check NSS - ## Use -std=gnu99 to turn off some newer features, and maybe turn on some - ## extra gcc warnings? - - env: NSS_OPTIONS="--enable-nss" C_DIALECT_OPTIONS="-std=gnu99" + ## We run chutney on Linux, because it's faster than chutney on macOS ## Chutney is a fast job, clang is slower on Linux, so we do Chutney clang - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes" compiler: clang - ## We check asciidoc with distcheck, to make sure we remove doc products - ## We use Linux clang, because there are no other Linux clang jobs - - env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes" - compiler: clang - ## We include a single coverage build with the best options for coverage - - env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS="" TOR_TEST_RNG_SEED="636f766572616765" - ## We run rust on Linux, because it's faster than rust on macOS - ## We check rust offline - - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true + ## We check asciidoc with distcheck, to make sure we remove doc products - env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes" + ## We check disable module relay - env: MODULES_OPTIONS="--disable-module-relay" ## We check disable module dirauth - env: MODULES_OPTIONS="--disable-module-dirauth" + + ## We run rust on Linux, because it's faster than rust on macOS + ## We check rust offline + - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true + + ## We check NSS + ## Use -std=gnu99 to turn off some newer features, and maybe turn on some + ## extra gcc warnings? + - env: NSS_OPTIONS="--enable-nss" C_DIALECT_OPTIONS="-std=gnu99" + + ## We include a single coverage build with the best options for coverage + - env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS="" TOR_TEST_RNG_SEED="636f766572616765" + + ## We clone our stem repo and run `make test-stem` + - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes" + + ## We run `make doxygen` without `make check`. + - env: SKIP_MAKE_CHECK="yes" DOXYGEN="yes" + ## macOS builds are very slow, and we have a limited number of ## concurrent macOS jobs. We're not actively developing Rust, so it is ## the lowest priority. @@ -76,11 +92,6 @@ matrix: #- env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" # compiler: clang # os: osx - ## We run chutney on macOS, because macOS Travis has IPv6 - - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes" - os: osx - ## We clone our stem repo and run `make test-stem` - - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes" ## Allow the build to report success (with non-required sub-builds ## continuing to run) if all required sub-builds have succeeded. @@ -92,13 +103,17 @@ matrix: ## macOS rust and chutney are very slow, so we let the build finish before ## they are done. We'd like to fast finish, but still eventually show ## any failures in the build status. But Travis doesn't have that ability. - - env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" - compiler: clang - os: osx - - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes" - os: osx - ## test-stem sometimes hangs on Travis - - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes" + + ## Since this job is disabled, there's not much point having an exception + ## for it + #- env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" + # compiler: clang + # os: osx + + ## Since we're actively developing IPv6, we want to require the IPv6 + ## chutney tests + #- env: CHUTNEY_MAKE="test-network-ipv6" CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes" + # os: osx ## (Linux only) Use a recent Linux image (Ubuntu Bionic) dist: bionic @@ -129,6 +144,7 @@ addons: - docbook-xsl - docbook-xml - xmlto + - doxygen ## Utilities ## preventing or diagnosing hangs - timelimit @@ -229,10 +245,11 @@ script: ## We run `make check` because that's what https://jenkins.torproject.org does. - if [[ "$SKIP_MAKE_CHECK" == "" ]]; then make check; fi - if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$CONFIGURE_FLAGS"; fi - - if [[ "$CHUTNEY" != "" ]]; then make test-network-all; fi + - if [[ "$CHUTNEY" != "" ]]; then make "$CHUTNEY_MAKE"; fi ## Diagnostic for bug 29437: kill stem if it hangs for 9.5 minutes ## Travis will kill the job after 10 minutes with no output - if [[ "$TEST_STEM" != "" ]]; then make src/app/tor; timelimit -p -t 540 -s USR1 -T 30 -S ABRT python3 "$STEM_SOURCE_DIR"/run_tests.py --tor src/app/tor --integ --test control.controller --test control.base_controller --test process --log TRACE --log-file stem.log; fi + - if [[ "$DOXYGEN" != "" ]]; then make doxygen; fi ## If this build was one that produced coverage, upload it. - if [[ "$COVERAGE_OPTIONS" != "" ]]; then coveralls -b . --exclude src/test --exclude src/trunnel --gcov-options '\-p' || echo "Coverage failed"; fi @@ -245,7 +262,7 @@ after_failure: ## `make distcheck` puts it somewhere different. - if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog || echo "make failed"; fi - if [[ "$DISTCHECK" != "" ]]; then make show-distdir-core || echo "make failed"; fi - - if [[ "$CHUTNEY" != "" ]]; then ls test_network_log || echo "ls failed"; cat test_network_log/* || echo "cat failed"; fi + - if [[ "$CHUTNEY" != "" ]]; then "$CHUTNEY_PATH/tools/diagnostics.sh" || echo "diagnostics failed"; ls test_network_log || echo "ls failed"; cat test_network_log/* || echo "cat failed"; fi - if [[ "$TEST_STEM" != "" ]]; then tail -1000 "$STEM_SOURCE_DIR"/test/data/tor_log || echo "tail failed"; fi - if [[ "$TEST_STEM" != "" ]]; then grep -v "SocketClosed" stem.log | tail -1000 || echo "grep | tail failed"; fi @@ -1,3 +1,656 @@ +Changes in version 0.4.3.2-alpha - 2020-02-10 + This is the second stable alpha release in the Tor 0.4.3.x series. It + fixes several bugs present in the previous alpha release. Anybody + running the previous alpha should upgrade, and look for bugs in this + one instead. + + o Major bugfixes (onion service client, authorization): + - On a NEWNYM signal, purge entries from the ephemeral client + authorization cache. The permanent ones are kept. Fixes bug 33139; + bugfix on 0.4.3.1-alpha. + + o Minor features (best practices tracker): + - Practracker now supports a --regen-overbroad option to regenerate + the exceptions file, but only to revise exceptions to be _less_ + tolerant of best-practices violations. Closes ticket 32372. + + o Minor features (continuous integration): + - Run Doxygen Makefile target on Travis, so we can learn about + regressions in our internal documentation. Closes ticket 32455. + - Stop allowing failures on the Travis CI stem tests job. It looks + like all the stem hangs we were seeing before are now fixed. + Closes ticket 33075. + + o Minor bugfixes (build system): + - Revise configure options that were either missing or incorrect in + the configure summary. Fixes bug 32230; bugfix on 0.4.3.1-alpha. + + o Minor bugfixes (controller protocol): + - Fix a memory leak introduced by refactoring of control reply + formatting code. Fixes bug 33039; bugfix on 0.4.3.1-alpha. + - Fix a memory leak in GETINFO responses. Fixes bug 33103; bugfix + on 0.4.3.1-alpha. + - When receiving "ACTIVE" or "DORMANT" signals on the control port, + report them as SIGNAL events. Previously we would log a bug + warning. Fixes bug 33104; bugfix on 0.4.0.1-alpha. + + o Minor bugfixes (logging): + - If we encounter a bug when flushing a buffer to a TLS connection, + only log the bug once per invocation of the Tor process. + Previously we would log with every occurrence, which could cause + us to run out of disk space. Fixes bug 33093; bugfix + on 0.3.2.2-alpha. + - When logging a bug, do not say "Future instances of this warning + will be silenced" unless we are actually going to silence them. + Previously we would say this whenever a BUG() check failed in the + code. Fixes bug 33095; bugfix on 0.4.1.1-alpha. + + o Minor bugfixes (onion service v2): + - Move a series of v2 onion service warnings to protocol-warning + level because they can all be triggered remotely by a malformed + request. Fixes bug 32706; bugfix on 0.1.1.14-alpha. + + o Minor bugfixes (onion service v3, client authorization): + - When removing client authorization credentials using the control + port, also remove the associated descriptor, so the onion service + can no longer be contacted. Fixes bug 33148; bugfix + on 0.4.3.1-alpha. + + o Minor bugfixes (pluggable transports): + - When receiving a message on standard error from a pluggable + transport, log it at info level, rather than as a warning. Fixes + bug 33005; bugfix on 0.4.0.1-alpha. + + o Minor bugfixes (rust, build): + - Fix a syntax warning given by newer versions of Rust that was + creating problems for our continuous integration. Fixes bug 33212; + bugfix on 0.3.5.1-alpha. + + o Minor bugfixes (TLS bug handling): + - When encountering a bug in buf_read_from_tls(), return a "MISC" + error code rather than "WANTWRITE". This change might help avoid + some CPU-wasting loops if the bug is ever triggered. Bug reported + by opara. Fixes bug 32673; bugfix on 0.3.0.4-alpha. + + o Code simplification and refactoring (mainloop): + - Simplify the ip_address_changed() function by removing redundant + checks. Closes ticket 33091. + + o Documentation (manpage): + - Split "Circuit Timeout" options and "Node Selection" options into + their own sections of the tor manpage. Closes tickets 32928 and + 32929. Work by Swati Thacker as part of Google Season of Docs. + + +Changes in version 0.4.2.6 - 2020-01-30 + This is the second stable release in the 0.4.2.x series. It backports + several bugfixes from 0.4.3.1-alpha, including some that had affected + the Linux seccomp2 sandbox or Windows services. If you're running with + one of those configurations, you'll probably want to upgrade; + otherwise, you should be fine with 0.4.2.5. + + o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha): + - Correct how we use libseccomp. Particularly, stop assuming that + rules are applied in a particular order or that more rules are + processed after the first match. Neither is the case! In + libseccomp <2.4.0 this led to some rules having no effect. + libseccomp 2.4.0 changed how rules are generated, leading to a + different ordering, which in turn led to a fatal crash during + startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by + Peter Gerber. + - Fix crash when reloading logging configuration while the + experimental sandbox is enabled. Fixes bug 32841; bugfix on + 0.4.1.7. Patch by Peter Gerber. + + o Minor bugfixes (correctness checks, backport from 0.4.3.1-alpha): + - Use GCC/Clang's printf-checking feature to make sure that + tor_assertf() arguments are correctly typed. Fixes bug 32765; + bugfix on 0.4.1.1-alpha. + + o Minor bugfixes (logging, crash, backport from 0.4.3.1-alpha): + - Avoid a possible crash when trying to log a (fatal) assertion + failure about mismatched magic numbers in configuration objects. + Fixes bug 32771; bugfix on 0.4.2.1-alpha. + + o Minor bugfixes (testing, backport from 0.4.3.1-alpha): + - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the + test_practracker.sh script. Doing so caused a test failure. Fixes + bug 32705; bugfix on 0.4.2.1-alpha. + - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr when + skipping practracker checks. Fixes bug 32705; bugfix + on 0.4.2.1-alpha. + + o Minor bugfixes (windows service, backport from 0.4.3.1-alpha): + - Initialize the publish/subscribe system when running as a windows + service. Fixes bug 32778; bugfix on 0.4.1.1-alpha. + + o Testing (backport from 0.4.3.1-alpha): + - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on + Ubuntu Bionic. Turning off the Sandbox is a work-around, until we + fix the sandbox errors in 32722. Closes ticket 32240. + - Re-enable the Travis CI macOS Chutney build, but don't let it + prevent the Travis job from finishing. (The Travis macOS jobs are + slow, so we don't want to have it delay the whole CI process.) + Closes ticket 32629. + + o Testing (continuous integration, backport from 0.4.3.1-alpha): + - Use zstd in our Travis Linux builds. Closes ticket 32242. + + +Changes in version 0.4.1.8 - 2020-01-30 + This release backports several bugfixes from later release series, + including some that had affected the Linux seccomp2 sandbox or Windows + services. If you're running with one of those configurations, you'll + probably want to upgrade; otherwise, you should be fine with your + current version of 0.4.1.x. + + o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha): + - Correct how we use libseccomp. Particularly, stop assuming that + rules are applied in a particular order or that more rules are + processed after the first match. Neither is the case! In + libseccomp <2.4.0 this led to some rules having no effect. + libseccomp 2.4.0 changed how rules are generated, leading to a + different ordering, which in turn led to a fatal crash during + startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by + Peter Gerber. + - Fix crash when reloading logging configuration while the + experimental sandbox is enabled. Fixes bug 32841; bugfix on + 0.4.1.7. Patch by Peter Gerber. + + o Minor bugfixes (crash, backport form 0.4.2.4-rc): + - When running Tor with an option like --verify-config or + --dump-config that does not start the event loop, avoid crashing + if we try to exit early because of an error. Fixes bug 32407; + bugfix on 0.3.3.1-alpha. + + o Minor bugfixes (windows service, backport from 0.4.3.1-alpha): + - Initialize the publish/subscribe system when running as a windows + service. Fixes bug 32778; bugfix on 0.4.1.1-alpha. + + o Testing (backport from 0.4.3.1-alpha): + - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on + Ubuntu Bionic. Turning off the Sandbox is a work-around, until we + fix the sandbox errors in 32722. Closes ticket 32240. + - Re-enable the Travis CI macOS Chutney build, but don't let it + prevent the Travis job from finishing. (The Travis macOS jobs are + slow, so we don't want to have it delay the whole CI process.) + Closes ticket 32629. + + o Testing (continuous integration, backport from 0.4.3.1-alpha): + - Use zstd in our Travis Linux builds. Closes ticket 32242. + + +Changes in version 0.4.3.1-alpha - 2020-01-22 + This is the first alpha release in the 0.4.3.x series. It includes + improved support for application integration of onion services, support + for building in a client-only mode, and newly improved internal + documentation (online at https://src-ref.docs.torproject.org/tor/). It + also has numerous other small bugfixes and features, as well as + improvements to our code's internal organization that should help us + write better code in the future. + + o New system requirements: + - When building Tor, you now need to have Python 3 in order to run + the integration tests. (Python 2 is officially unsupported + upstream, as of 1 Jan 2020.) Closes ticket 32608. + + o Major features (build system): + - The relay code can now be disabled using the --disable-module-relay + configure option. When this option is set, we also disable the + dirauth module. Closes ticket 32123. + - When Tor is compiled --disable-module-relay, we also omit the code + used to act as a directory cache. Closes ticket 32487. + + o Major features (directory authority, ed25519): + - Add support for banning a relay's ed25519 keys in the approved- + routers file. This will help us migrate away from RSA keys in the + future. Previously, only RSA keys could be banned in approved- + routers. Resolves ticket 22029. Patch by Neel Chauhan. + + o Major features (onion service, controller): + - New control port commands to manage client-side onion service + authorization credentials. The ONION_CLIENT_AUTH_ADD command adds + a credential, ONION_CLIENT_AUTH_REMOVE deletes a credential, and + ONION_CLIENT_AUTH_VIEW lists the credentials. Closes ticket 30381. + + o Major features (onion service, SOCKS5): + - Introduce a new SocksPort flag, ExtendedErrors, to support more + detailed error codes in information for applications that support + them. Closes ticket 30382; implements proposal 304. + + o Major features (proxy): + - In addition to its current supported proxy types (HTTP CONNECT, + SOCKS4, and SOCKS5), Tor can now make its OR connections through a + HAProxy server. A new torrc option was added to specify the + address/port of the server: TCPProxy <protocol> <host>:<port>. + Currently the only supported protocol for the option is haproxy. + Closes ticket 31518. Patch done by Suphanat Chunhapanya (haxxpop). + + o Major bugfixes (linux seccomp sandbox): + - Correct how we use libseccomp. Particularly, stop assuming that + rules are applied in a particular order or that more rules are + processed after the first match. Neither is the case! In + libseccomp <2.4.0 this led to some rules having no effect. + libseccomp 2.4.0 changed how rules are generated, leading to a + different ordering, which in turn led to a fatal crash during + startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by + Peter Gerber. + - Fix crash when reloading logging configuration while the + experimental sandbox is enabled. Fixes bug 32841; bugfix on + 0.4.1.7. Patch by Peter Gerber. + + o Major bugfixes (networking): + - Correctly handle IPv6 addresses in SOCKS5 RESOLVE_PTR requests, + and accept strings as well as binary addresses. Fixes bug 32315; + bugfix on 0.3.5.1-alpha. + + o Major bugfixes (onion service): + - Report HS circuit failure back into the HS subsystem so we take + appropriate action with regards to the client introduction point + failure cache. This improves reachability of onion services, since + now clients notice failing introduction circuits properly. Fixes + bug 32020; bugfix on 0.3.2.1-alpha. + + o Minor feature (configure, build system): + - Output a list of enabled/disabled features at the end of the + configure process in a pleasing way. Closes ticket 31373. + + o Minor feature (heartbeat, onion service): + - Add the DoS INTRODUCE2 defenses counter to the heartbeat DoS + message. Closes ticket 31371. + + o Minor features (configuration validation): + - Configuration validation can now be done by per-module callbacks, + rather than a global validation function. This will let us reduce + the size of config.c and some of its more cumbersome functions. + Closes ticket 31241. + + o Minor features (configuration): + - If a configured hardware crypto accelerator in AccelName is + prefixed with "!", Tor now exits when it cannot be found. Closes + ticket 32406. + - We now use flag-driven logic to warn about obsolete configuration + fields, so that we can include their names. In 0.4.2, we used a + special type, which prevented us from generating good warnings. + Implements ticket 32404. + + o Minor features (controller): + - Add stream isolation data to STREAM event. Closes ticket 19859. + - Implement a new GETINFO command to fetch microdescriptor + consensus. Closes ticket 31684. + + o Minor features (debugging, directory system): + - Don't crash when we find a non-guard with a guard-fraction value + set. Instead, log a bug warning, in an attempt to figure out how + this happened. Diagnostic for ticket 32868. + + o Minor features (defense in depth): + - Add additional checks around tor_vasprintf() usage, in case the + function returns an error. Patch by Tobias Stoeckmann. Fixes + ticket 31147. + + o Minor features (developer tooling): + - Remove the 0.2.9.x series branches from git scripts (git-merge- + forward.sh, git-pull-all.sh, git-push-all.sh, git-setup-dirs.sh). + Closes ticket 32772. + + o Minor features (developer tools): + - Add a check_cocci_parse.sh script that checks that new code is + parseable by Coccinelle. Add an exceptions file for unparseable + files, and run the script from travis CI. Closes ticket 31919. + - Call the check_cocci_parse.sh script from a 'check-cocci' Makefile + target. Closes ticket 31919. + - Add a rename_c_identifiers.py tool to rename a bunch of C + identifiers at once, and generate a well-formed commit message + describing the change. This should help with refactoring. Closes + ticket 32237. + - Add some scripts in "scripts/coccinelle" to invoke the Coccinelle + semantic patching tool with the correct flags. These flags are + fairly easy to forget, and these scripts should help us use + Coccinelle more effectively in the future. Closes ticket 31705. + + o Minor features (Doxygen): + - Update Doxygen configuration file to a more recent template (from + 1.8.15). Closes ticket 32110. + - "make doxygen" now works with out-of-tree builds. Closes + ticket 32113. + - Make sure that doxygen outputs documentation for all of our C + files. Previously, some were missing @file declarations, causing + them to be ignored. Closes ticket 32307. + - Our "make doxygen" target now respects --enable-fatal-warnings by + default, and does not warn about items that are missing + documentation. To warn about missing documentation, run configure + with the "--enable-missing-doc-warnings" flag: doing so suspends + fatal warnings for doxygen. Closes ticket 32385. + + o Minor features (git scripts): + - Add TOR_EXTRA_CLONE_ARGS to git-setup-dirs.sh for git clone + customisation. Closes ticket 32347. + - Add git-setup-dirs.sh, which sets up an upstream git repository + and worktrees for tor maintainers. Closes ticket 29603. + - Add TOR_EXTRA_REMOTE_* to git-setup-dirs.sh for a custom extra + remote. Closes ticket 32347. + - Call the check_cocci_parse.sh script from the git commit and push + hooks. Closes ticket 31919. + - Make git-push-all.sh skip unchanged branches when pushing to + upstream. The script already skipped unchanged test branches. + Closes ticket 32216. + - Make git-setup-dirs.sh create a master symlink in the worktree + directory. Closes ticket 32347. + - Skip unmodified source files when doing some existing git hook + checks. Related to ticket 31919. + + o Minor features (IPv6, client): + - Make Tor clients tell dual-stack exits that they prefer IPv6 + connections. This change is equivalent to setting the PreferIPv6 + flag on SOCKSPorts (and most other listener ports). Tor Browser + has been setting this flag for some time, and we want to remove a + client distinguisher at exits. Closes ticket 32637. + + o Minor features (portability, android): + - When building for Android, disable some tests that depend on $HOME + and/or pwdb, which Android doesn't have. Closes ticket 32825. + Patch from Hans-Christoph Steiner. + + o Minor features (relay modularity): + - Split the relay and server pluggable transport config code into + separate files in the relay module. Disable this code when the + relay module is disabled. Closes part of ticket 32213. + - When the relay module is disabled, reject attempts to set the + ORPort, DirPort, DirCache, BridgeRelay, ExtORPort, or + ServerTransport* options, rather than ignoring the values of these + options. Closes part of ticket 32213. + + o Minor features (relay): + - When the relay module is disabled, change the default config so + that DirCache is 0, and ClientOnly is 1. Closes ticket 32410. + + o Minor features (release tools): + - Port our ChangeLog formatting and sorting tools to Python 3. + Closes ticket 32704. + + o Minor features (testing): + - Detect some common failure cases for test_parseconf.sh in + src/test/conf_failures. Closes ticket 32451. + - Allow test_parseconf.sh to test expected log outputs for successful + configs, as well as failed configs. Closes ticket 32451. + - The test_parseconf.sh script now supports result variants for any + combination of the optional libraries lzma, nss, and zstd. Closes + ticket 32397. + + o Minor features (tests, Android): + - When running the unit tests on Android, create temporary files in + a subdirectory of /data/local/tmp. Closes ticket 32172. Based on a + patch from Hans-Christoph Steiner. + + o Minor bugfixes (bridges): + - Lowercase the configured value of BridgeDistribution before adding + it to the descriptor. Fixes bug 32753; bugfix on 0.3.2.3-alpha. + + o Minor bugfixes (build system): + - Fix "make autostyle" for out-of-tree builds. Fixes bug 32370; + bugfix on 0.4.1.2-alpha. + + o Minor bugfixes (configuration handling): + - Make control_event_conf_changed() take in a config_line_t instead + of a smartlist of alternating key/value entries. Fixes bug 31531; + bugfix on 0.2.3.3-alpha. Patch by Neel Chauhan. + + o Minor bugfixes (configuration): + - Check for multiplication overflow when parsing memory units inside + configuration. Fixes bug 30920; bugfix on 0.0.9rc1. + - When dumping the configuration, stop adding a trailing space after + the option name when there is no option value. This issue only + affects options that accept an empty value or list. (Most options + reject empty values, or delete the entire line from the dumped + options.) Fixes bug 32352; bugfix on 0.0.9pre6. + - Avoid changing the user's value of HardwareAccel as stored by + SAVECONF, when AccelName is set but HardwareAccel is not. Fixes + bug 32382; bugfix on 0.2.2.1-alpha. + - When creating a KeyDirectory with the same location as the + DataDirectory (not recommended), respect the DataDirectory's + group-readable setting if one has not been set for the + KeyDirectory. Fixes bug 27992; bugfix on 0.3.3.1-alpha. + + o Minor bugfixes (controller): + - In routerstatus_has_changed(), check all the fields that are + output over the control port. Fixes bug 20218; bugfix + on 0.1.1.11-alpha + + o Minor bugfixes (correctness checks): + - Use GCC/Clang's printf-checking feature to make sure that + tor_assertf() arguments are correctly typed. Fixes bug 32765; + bugfix on 0.4.1.1-alpha. + + o Minor bugfixes (developer tools): + - Allow paths starting with ./ in scripts/add_c_file.py. Fixes bug + 31336; bugfix on 0.4.1.2-alpha. + + o Minor bugfixes (dirauth module): + - Split the dirauth config code into a separate file in the dirauth + module. Disable this code when the dirauth module is disabled. + Closes ticket 32213. + - When the dirauth module is disabled, reject attempts to set the + AuthoritativeDir option, rather than ignoring the value of the + option. Fixes bug 32213; bugfix on 0.3.4.1-alpha. + + o Minor bugfixes (embedded Tor): + - When starting Tor any time after the first time in a process, + register the thread in which it is running as the main thread. + Previously, we only did this on Windows, which could lead to bugs + like 23081 on non-Windows platforms. Fixes bug 32884; bugfix + on 0.3.3.1-alpha. + + o Minor bugfixes (git scripts): + - Avoid sleeping before the last push in git-push-all.sh. Closes + ticket 32216. + - Forward all unrecognised arguments in git-push-all.sh to git push. + Closes ticket 32216. + + o Minor bugfixes (hidden service v3): + - Do not rely on a "circuit established" flag for intro circuits but + instead always query the HS circuit map. This is to avoid sync + issue with that flag and the map. Fixes bug 32094; bugfix + on 0.3.2.1-alpha. + + o Minor bugfixes (logging, crash): + - Avoid a possible crash when trying to log a (fatal) assertion + failure about mismatched magic numbers in configuration objects. + Fixes bug 32771; bugfix on 0.4.2.1-alpha. + + o Minor bugfixes (onion service v2): + - When sending the INTRO cell for a v2 Onion Service, look at the + failure cache alongside timeout values to check if the intro point + is marked as failed. Previously, we only looked at the relay + timeout values. Fixes bug 25568; bugfix on 0.2.7.3-rc. Patch by + Neel Chauhan. + + o Minor bugfixes (onion services v3, client): + - Properly handle the client rendezvous circuit timeout. Previously + Tor would sometimes timeout a rendezvous circuit awaiting the + introduction ACK, and find itself unable to re-establish all + circuits because the rendezvous circuit timed out too early. Fixes + bug 32021; bugfix on 0.3.2.1-alpha. + + o Minor bugfixes (onion services): + - In cancel_descriptor_fetches(), use + connection_list_by_type_purpose() instead of + connection_list_by_type_state(). Fixes bug 32639; bugfix on + 0.3.2.1-alpha. Patch by Neel Chauhan. + + o Minor bugfixes (scripts): + - Fix update_versions.py for out-of-tree builds. Fixes bug 32371; + bugfix on 0.4.0.1-alpha. + + o Minor bugfixes (test): + - Use the same code to find the tor binary in all of our test + scripts. This change makes sure we are always using the coverage + binary when coverage is enabled. Fixes bug 32368; bugfix + on 0.2.7.3-rc. + + o Minor bugfixes (testing): + - Stop ignoring "tor --dump-config" errors in test_parseconf.sh. + Fixes bug 32468; bugfix on 0.4.2.1-alpha. + - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the + test_practracker.sh script. Doing so caused a test failure. Fixes + bug 32705; bugfix on 0.4.2.1-alpha. + - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr when + skipping practracker checks. Fixes bug 32705; bugfix + on 0.4.2.1-alpha. + + o Minor bugfixes (tests): + - Our option-validation tests no longer depend on specially + configured non-default, non-passing sets of options. Previously, + the tests had been written to assume that options would _not_ be + set to their defaults, which led to needless complexity and + verbosity. Fixes bug 32175; bugfix on 0.2.8.1-alpha. + + o Minor bugfixes (windows service): + - Initialize the publish/subscribe system when running as a windows + service. Fixes bug 32778; bugfix on 0.4.1.1-alpha. + + o Deprecated features: + - Deprecate the ClientAutoIPv6ORPort option. This option was not + true "Happy Eyeballs", and often failed on connections that + weren't reliably dual-stack. Closes ticket 32942. Patch by + Neel Chauhan. + + o Documentation: + - Provide a quickstart guide for a Circuit Padding Framework, and + documentation for researchers to implement and study circuit + padding machines. Closes ticket 28804. + - Add documentation in 'HelpfulTools.md' to describe how to build a + tag file. Closes ticket 32779. + - Create a high-level description of the long-term software + architecture goals. Closes ticket 32206. + - Describe the --dump-config command in the manual page. Closes + ticket 32467. + - Unite coding advice from this_not_that.md in torguts repo into our + coding standards document. Resolves ticket 31853. + + o Removed features: + - Our Doxygen configuration no longer generates LaTeX output. The + reference manual produced by doing this was over 4000 pages long, + and generally unusable. Closes ticket 32099. + - The option "TestingEstimatedDescriptorPropagationTime" is now + marked as obsolete. It has had no effect since 0.3.0.7, when + clients stopped rejecting consensuses "from the future". Closes + ticket 32807. + - We no longer support consensus methods before method 28; these + methods were only used by authorities running versions of Tor that + are now at end-of-life. In effect, this means that clients, + relays, and authorities now assume that authorities will be + running version 0.3.5.x or later. Closes ticket 32695. + + o Testing: + - Add more test cases for tor's UTF-8 validation function. Also, + check the arguments passed to the function for consistency. Closes + ticket 32845. + - Improve test coverage for relay and dirauth config code, focusing + on option validation and normalization. Closes ticket 32213. + - Improve the consistency of test_parseconf.sh output, and run all + the tests, even if one fails. Closes ticket 32213. + - Re-enable the Travis CI macOS Chutney build, but don't let it + prevent the Travis job from finishing. (The Travis macOS jobs are + slow, so we don't want to have it delay the whole CI process.) + Closes ticket 32629. + - Run the practracker unit tests in the pre-commit git hook. Closes + ticket 32609. + - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on + Ubuntu Bionic. Turning off the Sandbox is a work-around, until we + fix the sandbox errors in 32722. Closes ticket 32240. + + o Code simplification and refactoring (channel): + - Channel layer had a variable length cell handler that was not used + and thus removed. Closes ticket 32892. + + o Code simplification and refactoring (configuration): + - Immutability is now implemented as a flag on individual + configuration options rather than as part of the option-transition + checking code. Closes ticket 32344. + - Instead of keeping a list of configuration options to check for + relative paths, check all the options whose type is "FILENAME". + Solves part of ticket 32339. + - Our default log (which ordinarily sends NOTICE-level messages to + standard output) is now handled in a more logical manner. + Previously, we replaced the configured log options if they were + empty. Now, we interpret an empty set of log options as meaning + "use the default log". Closes ticket 31999. + - Remove some unused arguments from the options_validate() function, + to simplify our code and tests. Closes ticket 32187. + - Simplify the options_validate() code so that it looks at the + default options directly, rather than taking default options as an + argument. This change lets us simplify its interface. Closes + ticket 32185. + - Use our new configuration architecture to move most authority- + related options to the directory authority module. Closes + ticket 32806. + - When parsing the command line, handle options that determine our + "quiet level" and our mode of operation (e.g., --dump-config and + so on) all in one table. Closes ticket 32003. + + o Code simplification and refactoring (controller): + - Create a new abstraction for formatting control protocol reply + lines based on key-value pairs. Refactor some existing control + protocol code to take advantage of this. Closes ticket 30984. + - Create a helper function that can fetch network status or + microdesc consensuses. Closes ticket 31684. + + o Code simplification and refactoring (dirauth modularization): + - Remove the last remaining HAVE_MODULE_DIRAUTH inside a function. + Closes ticket 32163. + - Replace some confusing identifiers in process_descs.c. Closes + ticket 29826. + - Simplify some relay and dirauth config code. Closes ticket 32213. + + o Code simplification and refactoring (misc): + - Make all the structs we declare follow the same naming convention + of ending with "_t". Closes ticket 32415. + - Move and rename some configuration-related code for clarity. + Closes ticket 32304. + - Our include.am files are now broken up by subdirectory. + Previously, src/core/include.am covered all of the subdirectories + in "core", "feature", and "app". Closes ticket 32137. + - Remove underused NS*() macros from test code: they make our tests + more confusing, especially for code-formatting tools. Closes + ticket 32887. + + o Code simplification and refactoring (relay modularization): + - Disable relay_periodic when the relay module is disabled. Closes + ticket 32244. + - Disable relay_sys when the relay module is disabled. Closes + ticket 32245. + + o Code simplification and refactoring (tool support): + - Add numerous missing dependencies to our include files, so that + they can be included in different reasonable orders and still + compile. Addresses part of ticket 32764. + - Fix some parts of our code that were difficult for Coccinelle to + parse. Related to ticket 31705. + - Fix some small issues in our code that prevented automatic + formatting tools from working. Addresses part of ticket 32764. + + o Documentation (manpage): + - Alphabetize the Client Options section of the tor manpage. Closes + ticket 32846. + - Alphabetize the General Options section of the tor manpage. Closes + ticket 32708. + - In the tor(1) manpage, reword and improve formatting of the + COMMAND-LINE OPTIONS and DESCRIPTION sections. Closes ticket + 32277. Based on work by Swati Thacker as part of Google Season + of Docs. + - In the tor(1) manpage, reword and improve formatting of the FILES, + SEE ALSO, and BUGS sections. Closes ticket 32176. Based on work by + Swati Thacker as part of Google Season of Docs. + + o Testing (circuit, EWMA): + - Add unit tests for circuitmux and EWMA subsystems. Closes + ticket 32196. + + o Testing (continuous integration): + - Use zstd in our Travis Linux builds. Closes ticket 32242. + + Changes in version 0.4.2.5 - 2019-12-09 This is the first stable release in the 0.4.2.x series. This series improves reliability and stability, and includes several stability and diff --git a/Makefile.am b/Makefile.am index 811694f0b6..b9bae2395c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -196,6 +196,8 @@ EXTRA_DIST+= \ scripts/maint/practracker/testdata/ex1-expected.txt \ scripts/maint/practracker/testdata/ex1.txt \ scripts/maint/practracker/testdata/ex1-overbroad-expected.txt \ + scripts/maint/practracker/testdata/ex1-regen-expected.txt \ + scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt \ scripts/maint/practracker/testdata/ex.txt \ scripts/maint/practracker/testdata/header.h \ scripts/maint/practracker/testdata/not_c_file \ @@ -273,60 +275,186 @@ check-local: \ shellcheck \ check-cocci +# test-network requires a copy of Chutney in $CHUTNEY_PATH. +# Chutney can be cloned from https://git.torproject.org/chutney.git . +.PHONY: need-chutney-path need-chutney-path: @if test ! -d "$$CHUTNEY_PATH"; then \ echo '$$CHUTNEY_PATH was not set.'; \ - if test -d $(top_srcdir)/../chutney -a -x $(top_srcdir)/../chutney/chutney; then \ - echo "Assuming test-network.sh will find" $(top_srcdir)/../chutney; \ + if test -d "$(top_srcdir)/../chutney" && \ + test -x "$(top_srcdir)/../chutney/chutney"; then \ + echo "Assuming test-network.sh will find" \ + "$(top_srcdir)/../chutney"; \ else \ echo; \ - echo "To run these tests, git clone https://git.torproject.org/chutney.git ; export CHUTNEY_PATH=\`pwd\`/chutney"; \ + echo "To run these tests," \ + "git clone" \ + "https://git.torproject.org/chutney.git ;" \ + "export CHUTNEY_PATH=\`pwd\`/chutney"; \ exit 1; \ fi \ fi -# Note that test-network requires a copy of Chutney in $CHUTNEY_PATH. -# Chutney can be cloned from https://git.torproject.org/chutney.git . -test-network: need-chutney-path $(TESTING_TOR_BINARY) src/tools/tor-gencert - $(top_srcdir)/src/test/test-network.sh $(TEST_NETWORK_FLAGS) +# Run some basic tests using automake's test-driver +.PHONY: test-network +# Hide directory path logs from submakes using $(MAKE) -s +test-network: + @$(MAKE) -s test-network-mkdir + @$(MAKE) -s test-network-clean + @$(MAKE) -s test-network-run \ + ipv4_flavors="$(TEST_CHUTNEY_FLAVOR_QUICK)" \ + ipv6_flavors="$(TEST_CHUTNEY_FLAVOR_QUICK_IPV6)" + @$(MAKE) -s test-network-results # Run all available tests using automake's test-driver +.PHONY: test-network-all +# Hide directory path logs from submakes using $(MAKE) -s +test-network-all: + @$(MAKE) -s test-network-mkdir + @$(MAKE) -s test-network-clean + @$(MAKE) -s test-network-run \ + ipv4_flavors="$(TEST_CHUTNEY_FLAVORS)" \ + mixed_flavors="$(TEST_CHUTNEY_FLAVORS_MIXED)" \ + ipv6_flavors="$(TEST_CHUTNEY_FLAVORS_IPV6)" \ + ipv6_mixed_flavors="$(TEST_CHUTNEY_FLAVORS_IPV6_MIXED)" + @$(MAKE) -s test-network-results + +# Run IPv4 and mixed tests using automake's test-driver +.PHONY: test-network-ipv4 +# Hide directory path logs from submakes using $(MAKE) -s +test-network-ipv4: + @$(MAKE) -s test-network-mkdir + @$(MAKE) -s test-network-clean + @$(MAKE) -s test-network-run \ + ipv4_flavors="$(TEST_CHUTNEY_FLAVORS)" \ + mixed_flavors="$(TEST_CHUTNEY_FLAVORS_MIXED)" + @$(MAKE) -s test-network-results + +# Run IPv6 tests using automake's test-driver +.PHONY: test-network-ipv6 +# Hide directory path logs from submakes using $(MAKE) -s +test-network-ipv6: + @$(MAKE) -s test-network-mkdir + @$(MAKE) -s test-network-clean + @$(MAKE) -s test-network-run \ + ipv6_flavors="$(TEST_CHUTNEY_FLAVORS_IPV6)" \ + ipv6_mixed_flavors="$(TEST_CHUTNEY_FLAVORS_IPV6_MIXED)" + @$(MAKE) -s test-network-results + +# Make the test network log directory, if it does not exist +.PHONY: test-network-mkdir +test-network-mkdir: + @mkdir -p "$(TEST_NETWORK_ALL_LOG_DIR)" + +# Clean the test network log directory +.PHONY: test-network-clean +# We need to remove all matching files, so we can't quote the glob part of the +# rm arguments +test-network-clean: + rm -f "$(TEST_NETWORK_ALL_LOG_DIR)"/*.log \ + "$(TEST_NETWORK_ALL_LOG_DIR)"/*.trs + +# Run tests using automake's test-driver +# When checking if a set of test can be run, log the type of test, and the +# list of tests that will be run (or skipped). +# +# Run the IPv4 tests in $(ipv4_flavors), unconditionally +# - tor relays and directory authorities require IPv4. +# Run the IPv6 tests in $(ipv6_flavors), if IPv6 is available # - only run IPv6 tests if we can ping6 or ping -6 ::1 (localhost) # we try the syntax for BSD ping6, Linux ping6, and Linux ping -6, # because they're incompatible # - some IPv6 tests may fail without an IPv6 DNS server # (see #16971 and #17011) +# Run the mixed tests in $(mixed_flavors), if a tor-stable binary is available # - only run mixed tests if we have a tor-stable binary -# - show tor warnings on the console after each network run -# (otherwise, warnings go to the logs, and people don't see them unless -# there is a network failure) -test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert - mkdir -p $(TEST_NETWORK_ALL_LOG_DIR) - rm -f $(TEST_NETWORK_ALL_LOG_DIR)/*.log $(TEST_NETWORK_ALL_LOG_DIR)/*.trs - @flavors="$(TEST_CHUTNEY_FLAVORS)"; \ - if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1 || ping -6 -c 1 -W 1 ::1 >/dev/null 2>&1; then \ - echo "ping6 ::1 or ping ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \ - flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \ - else \ - echo "ping6 ::1 and ping ::1 failed, skipping IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \ - skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \ +# Run the IPv6 mixed tests in $(ipv6_mixed_flavors), if IPv6 and mixed are run +# - see above for details about IPv6 and mixed +.PHONY: test-network-run +# We need the word splitting in the "for" lines, so we can't quote +# $(skip_flavors) or $(flavors) +test-network-run: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert + @flavors=""; \ + skip_flavors=""; \ + if test -n "$(ipv4_flavors)"; then \ + echo "Running IPv4 flavors: $(ipv4_flavors)."; \ + flavors="$$flavors $(ipv4_flavors)"; \ fi; \ - if command -v tor-stable >/dev/null 2>&1; then \ - echo "tor-stable found, running mixed flavors: $(TEST_CHUTNEY_FLAVORS_MIXED)."; \ - flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_MIXED)"; \ - else \ - echo "tor-stable not found, skipping mixed flavors: $(TEST_CHUTNEY_FLAVORS_MIXED)."; \ - skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_MIXED)"; \ + test_network_ipv6=false; \ + if test -n "$(ipv6_flavors)" || \ + test -n "$(ipv6_mixed_flavors)"; then \ + if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || \ + ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1 || \ + ping -6 -c 1 -W 1 ::1 >/dev/null 2>&1; then \ + test_network_ipv6=true; \ + fi; \ + fi; \ + if test -n "$(ipv6_flavors)"; then \ + if test "$$test_network_ipv6" = "true"; then \ + echo "ping6 ::1 or ping ::1 succeeded, running IPv6" \ + "flavors: $(ipv6_flavors)."; \ + flavors="$$flavors $(ipv6_flavors)"; \ + else \ + echo "ping6 ::1 and ping ::1 failed, skipping IPv6" \ + "flavors: $(ipv6_flavors)."; \ + skip_flavors="$$skip_flavors $(ipv6_flavors)"; \ + fi; \ + fi; \ + test_network_mixed=false; \ + if test -n "$(mixed_flavors)" || \ + test -n "$(ipv6_mixed_flavors)"; then \ + if command -v tor-stable >/dev/null 2>&1; then \ + test_network_mixed=true; \ + fi; \ + fi; \ + if test -n "$(mixed_flavors)"; then \ + if test "$$test_network_mixed" = "true"; then \ + echo "tor-stable found, running mixed flavors:" \ + "$(mixed_flavors)."; \ + flavors="$$flavors $(mixed_flavors)"; \ + else \ + echo "tor-stable not found, skipping mixed flavors:" \ + "$(mixed_flavors)."; \ + skip_flavors="$$skip_flavors $(mixed_flavors)"; \ + fi; \ + fi; \ + if test -n "$(ipv6_mixed_flavors)"; then \ + if test "$$test_network_ipv6" = "true" && \ + test "$$test_network_mixed" = "true"; then \ + echo "Running IPv6 mixed flavors:" \ + "$(ipv6_mixed_flavors)."; \ + flavors="$$flavors $(ipv6_mixed_flavors)"; \ + else \ + echo "Skipping IPv6 mixed flavors:" \ + "$(ipv6_mixed_flavors)."; \ + skip_flavors="$$skip_flavors $(ipv6_mixed_flavors)"; \ + fi; \ fi; \ for f in $$skip_flavors; do \ echo "SKIP: $$f"; \ done; \ for f in $$flavors; do \ - $(SHELL) $(top_srcdir)/test-driver --test-name $$f --log-file $(TEST_NETWORK_ALL_LOG_DIR)/$$f.log --trs-file $(TEST_NETWORK_ALL_LOG_DIR)/$$f.trs $(TEST_NETWORK_ALL_DRIVER_FLAGS) $(top_srcdir)/src/test/test-network.sh --flavor $$f $(TEST_NETWORK_FLAGS); \ - $(top_srcdir)/src/test/test-network.sh $(TEST_NETWORK_SHOW_WARNINGS_FOR_LAST_RUN_FLAGS); \ - done; \ - echo "Log and result files are available in $(TEST_NETWORK_ALL_LOG_DIR)."; \ - ! grep -q FAIL $(TEST_NETWORK_ALL_LOG_DIR)/*.trs + $(SHELL) "$(top_srcdir)/test-driver" --test-name "$$f" \ + --log-file "$(TEST_NETWORK_ALL_LOG_DIR)/$$f.log" \ + --trs-file "$(TEST_NETWORK_ALL_LOG_DIR)/$$f.trs" \ + $(TEST_NETWORK_ALL_DRIVER_FLAGS) \ + "$(top_srcdir)/src/test/test-network.sh" \ + --flavor "$$f" $(TEST_NETWORK_FLAGS); \ + "$(top_srcdir)/src/test/test-network.sh" \ + $(TEST_NETWORK_SHOW_WARNINGS_FOR_LAST_RUN_FLAGS); \ + done + +# Print the results from automake's test-driver +# - show tor warnings on the console after each network run +# (otherwise, warnings go to the logs, and people don't see them unless +# there is a network failure) +.PHONY: test-network-results +# We need to grep all matching files, so we can't quote the glob part of the +# grep arguments +test-network-results: + @echo \ + "Log and result files are available in $(TEST_NETWORK_ALL_LOG_DIR)." + @! grep -q FAIL "$(TEST_NETWORK_ALL_LOG_DIR)"/*.trs need-stem-path: @if test ! -d "$$STEM_SOURCE_DIR"; then \ diff --git a/ReleaseNotes b/ReleaseNotes index 97e16a6d8b..7d981e2c42 100644 --- a/ReleaseNotes +++ b/ReleaseNotes @@ -2,6 +2,104 @@ This document summarizes new features and bugfixes in each stable release of Tor. If you want to see more detailed descriptions of the changes in each development snapshot, see the ChangeLog file. +Changes in version 0.4.2.6 - 2020-01-30 + This is the second stable release in the 0.4.2.x series. It backports + several bugfixes from 0.4.3.1-alpha, including some that had affected + the Linux seccomp2 sandbox or Windows services. If you're running with + one of those configurations, you'll probably want to upgrade; + otherwise, you should be fine with 0.4.2.5. + + o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha): + - Correct how we use libseccomp. Particularly, stop assuming that + rules are applied in a particular order or that more rules are + processed after the first match. Neither is the case! In + libseccomp <2.4.0 this led to some rules having no effect. + libseccomp 2.4.0 changed how rules are generated, leading to a + different ordering, which in turn led to a fatal crash during + startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by + Peter Gerber. + - Fix crash when reloading logging configuration while the + experimental sandbox is enabled. Fixes bug 32841; bugfix on + 0.4.1.7. Patch by Peter Gerber. + + o Minor bugfixes (correctness checks, backport from 0.4.3.1-alpha): + - Use GCC/Clang's printf-checking feature to make sure that + tor_assertf() arguments are correctly typed. Fixes bug 32765; + bugfix on 0.4.1.1-alpha. + + o Minor bugfixes (logging, crash, backport from 0.4.3.1-alpha): + - Avoid a possible crash when trying to log a (fatal) assertion + failure about mismatched magic numbers in configuration objects. + Fixes bug 32771; bugfix on 0.4.2.1-alpha. + + o Minor bugfixes (testing, backport from 0.4.3.1-alpha): + - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the + test_practracker.sh script. Doing so caused a test failure. Fixes + bug 32705; bugfix on 0.4.2.1-alpha. + - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr when + skipping practracker checks. Fixes bug 32705; bugfix + on 0.4.2.1-alpha. + + o Minor bugfixes (windows service, backport from 0.4.3.1-alpha): + - Initialize the publish/subscribe system when running as a windows + service. Fixes bug 32778; bugfix on 0.4.1.1-alpha. + + o Testing (backport from 0.4.3.1-alpha): + - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on + Ubuntu Bionic. Turning off the Sandbox is a work-around, until we + fix the sandbox errors in 32722. Closes ticket 32240. + - Re-enable the Travis CI macOS Chutney build, but don't let it + prevent the Travis job from finishing. (The Travis macOS jobs are + slow, so we don't want to have it delay the whole CI process.) + Closes ticket 32629. + + o Testing (continuous integration, backport from 0.4.3.1-alpha): + - Use zstd in our Travis Linux builds. Closes ticket 32242. + + +Changes in version 0.4.1.8 - 2020-01-30 + This release backports several bugfixes from later release series, + including some that had affected the Linux seccomp2 sandbox or Windows + services. If you're running with one of those configurations, you'll + probably want to upgrade; otherwise, you should be fine with your + current version of 0.4.1.x. + + o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha): + - Correct how we use libseccomp. Particularly, stop assuming that + rules are applied in a particular order or that more rules are + processed after the first match. Neither is the case! In + libseccomp <2.4.0 this led to some rules having no effect. + libseccomp 2.4.0 changed how rules are generated, leading to a + different ordering, which in turn led to a fatal crash during + startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by + Peter Gerber. + - Fix crash when reloading logging configuration while the + experimental sandbox is enabled. Fixes bug 32841; bugfix on + 0.4.1.7. Patch by Peter Gerber. + + o Minor bugfixes (crash, backport form 0.4.2.4-rc): + - When running Tor with an option like --verify-config or + --dump-config that does not start the event loop, avoid crashing + if we try to exit early because of an error. Fixes bug 32407; + bugfix on 0.3.3.1-alpha. + + o Minor bugfixes (windows service, backport from 0.4.3.1-alpha): + - Initialize the publish/subscribe system when running as a windows + service. Fixes bug 32778; bugfix on 0.4.1.1-alpha. + + o Testing (backport from 0.4.3.1-alpha): + - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on + Ubuntu Bionic. Turning off the Sandbox is a work-around, until we + fix the sandbox errors in 32722. Closes ticket 32240. + - Re-enable the Travis CI macOS Chutney build, but don't let it + prevent the Travis job from finishing. (The Travis macOS jobs are + slow, so we don't want to have it delay the whole CI process.) + Closes ticket 32629. + + o Testing (continuous integration, backport from 0.4.3.1-alpha): + - Use zstd in our Travis Linux builds. Closes ticket 32242. + + Changes in version 0.4.2.5 - 2019-12-09 This is the first stable release in the 0.4.2.x series. This series improves reliability and stability, and includes several stability and diff --git a/changes/31147 b/changes/31147 deleted file mode 100644 index d6f5cbdf43..0000000000 --- a/changes/31147 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (defense in depth): - - Add additional sanity checks around tor_vasprintf() usage in case the - function returns an error. Patch by Tobias Stoeckmann. Fixes ticket 31147. diff --git a/changes/bug19859 b/changes/bug19859 deleted file mode 100644 index 36908854df..0000000000 --- a/changes/bug19859 +++ /dev/null @@ -1,2 +0,0 @@ - o Minor features (controller): - - Add stream isolation data to STREAM event. Closes ticket 19859. diff --git a/changes/bug22029 b/changes/bug22029 deleted file mode 100644 index 6bfb7012f6..0000000000 --- a/changes/bug22029 +++ /dev/null @@ -1,5 +0,0 @@ - o Major features (directory authority, ed25519): - Add support for banning a relay's ed25519 keys in the approved-routers - file. This will allow us to migrate away from RSA keys in the future. - Previously, only RSA keys could be banned in approved-routers. Resolves - ticket 22029. Patch by Neel Chauhan. diff --git a/changes/bug25568 b/changes/bug25568 deleted file mode 100644 index eeb7235cae..0000000000 --- a/changes/bug25568 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor bugfixes (onion service v2): - - When sending the INTRO cell for a v2 Onion Service, look at the failure - cache alongside timeout values to check if the intro point is marked - as failed. Previously, we only looked at if the relay timeout values. - Fixes bug 25568; bugfix on 0.2.7.3-rc. Patch by Neel Chauhan. diff --git a/changes/bug29819 b/changes/bug29819 deleted file mode 100644 index d37ac83d66..0000000000 --- a/changes/bug29819 +++ /dev/null @@ -1,8 +0,0 @@ - o Minor bugfixes (linux seccomp sandbox): - - Correct how we use libseccomp. Particularly, stop assuming that - rules are applied in a particular order or that more rules are - processed after the first match. Neither is the case! In libseccomp - <2.4.0 this lead to some rules having no effect. Libseccomp 2.4.0 - changed how rules are generated leading to a different ordering - which in turn lead to a fatal crash during startup. Fixes bug - 29819; bugfix on 0.2.5.1-alpha. Patch by Peter Gerber. diff --git a/changes/bug30381 b/changes/bug30381 deleted file mode 100644 index 2430b45af0..0000000000 --- a/changes/bug30381 +++ /dev/null @@ -1,9 +0,0 @@ - o Major features (controller): - - New ONION_CLIENT_AUTH_ADD control port command to add client-side onion - service client authorization credentials. Closes part of ticket 30381. - - New ONION_CLIENT_AUTH_REMOVE control port command to remove client-side - onion service client authorization credentials. Closes part of ticket - 30381. - - New ONION_CLIENT_AUTH_VIEW control port command to view stored - client-side onion service client authorization credentials. Closes part - of ticket 30381.
\ No newline at end of file diff --git a/changes/bug31531 b/changes/bug31531 deleted file mode 100644 index c549c79ecb..0000000000 --- a/changes/bug31531 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (configuration handling): - - Make control_event_conf_changed() take in a config_line_t instead of - a smartlist(k, v, k, v, ...) where keys are followed by values. Fixes - bug 31531; bugfix on 0.2.3.3-alpha. Patch by Neel Chauhan. diff --git a/changes/bug32175 b/changes/bug32175 deleted file mode 100644 index ac78dcf340..0000000000 --- a/changes/bug32175 +++ /dev/null @@ -1,6 +0,0 @@ - o Minor bugfixes (tests): - - Our option-validation tests no longer depend on specially configured - non-default, non-passing set of options. Previously, the tests had - been written to assume that options would _not_ be set to their - defaults, which led to needless complexity and verbosity. - Fixes bug 32175; bugfix on 0.2.8.1-alpha. diff --git a/changes/bug32213 b/changes/bug32213 deleted file mode 100644 index 9083f4286c..0000000000 --- a/changes/bug32213 +++ /dev/null @@ -1,20 +0,0 @@ - o Minor bugfixes (dirauth module): - - When the dirauth module is disabled, reject attempts to set the - AuthoritativeDir option, rather than ignoring the value of the - option. Fixes bug 32213; bugfix on 0.3.4.1-alpha. - - Split the dirauth config code into a separate file in the dirauth - module. Disable this code when the dirauth module is disabled. - Closes ticket 32213. - o Minor features (relay module): - - When the relay module is disabled, reject attempts to set the - ORPort, DirPort, DirCache, BridgeRelay, ExtORPort, or - ServerTransport* options, rather than ignoring the values of these - options. Closes ticket 32213. - - Split the relay and server pluggable transport config code into - separate files in the relay module. Disable this code when the relay - module is disabled. Closes ticket 32213. - o Code simplification and refactoring: - - Simplify some relay and dirauth config code. Closes ticket 32213. - o Testing: - - Improve test coverage for relay and dirauth config code, focusing on - option validation and normalization. Closes ticket 32213. diff --git a/changes/bug32315 b/changes/bug32315 deleted file mode 100644 index 2d8e5decf2..0000000000 --- a/changes/bug32315 +++ /dev/null @@ -1,4 +0,0 @@ - o Major bugfixes (networking): - - Correctly handle IPv6 addresses in SOCKS5 RESOLVE_PTR requests, - and accept strings as well as binary addresses. Fixes bug 32315; - bugfix on 0.3.5.1-alpha. diff --git a/changes/bug32352 b/changes/bug32352 deleted file mode 100644 index ca93e4efdf..0000000000 --- a/changes/bug32352 +++ /dev/null @@ -1,6 +0,0 @@ - o Minor bugfixes (config): - - When dumping the config, stop adding a trailing space after the option - name, when there is no option value. This issue only affects options - that accept an empty value or list. (Most options reject empty values, - or delete the entire line from the dumped options.) - Fixes bug 32352; bugfix on 0.0.9pre6. diff --git a/changes/bug32368 b/changes/bug32368 deleted file mode 100644 index 378f74fa54..0000000000 --- a/changes/bug32368 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (test): - - Use the same code to find the tor binary in all of our test scripts. - This change makes sure we are always using the coverage binary, when - coverage is enabled. Fixes bug 32368; bugfix on 0.2.7.3-rc. diff --git a/changes/bug32370 b/changes/bug32370 deleted file mode 100644 index 9e450d9612..0000000000 --- a/changes/bug32370 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (build): - - Fix "make autostyle" for out-of-tree builds. - Fixes bug 32370; bugfix on 0.4.1.2-alpha. diff --git a/changes/bug32371 b/changes/bug32371 deleted file mode 100644 index 1fed15c2d7..0000000000 --- a/changes/bug32371 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (scripts): - - Fix update_versions.py for out-of-tree builds. - Fixes bug 32371; bugfix on 0.4.0.1-alpha. diff --git a/changes/bug32468 b/changes/bug32468 deleted file mode 100644 index fa0d877096..0000000000 --- a/changes/bug32468 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (testing): - - Stop ignoring "tor --dump-config" errors in test_parseconf.sh. - Fixes bug 32468; bugfix on 0.4.2.1-alpha. diff --git a/changes/bug32639 b/changes/bug32639 deleted file mode 100644 index 1237ba074f..0000000000 --- a/changes/bug32639 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (onion services): - - In cancel_descriptor_fetches(), use connection_list_by_type_purpose() - instead of connection_list_by_type_state(). Fixes bug 32639; bugfix on - 0.3.2.1-alpha. Patch by Neel Chauhan. diff --git a/changes/bug32753 b/changes/bug32753 deleted file mode 100644 index 6f59c7729d..0000000000 --- a/changes/bug32753 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (bridges): - - Lowercase the value of BridgeDistribution from torrc before adding it to - the descriptor. Fixes bug 32753; bugfix on 0.3.2.3-alpha. diff --git a/changes/bug32771 b/changes/bug32771 deleted file mode 100644 index 606bcf4be4..0000000000 --- a/changes/bug32771 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (logging, crash): - - Avoid a possible crash when trying to log a (fatal) assertion failure - about mismatched magic numbers in configuration objects. Fixes bug 32771; - bugfix on 0.4.2.1-alpha. diff --git a/changes/bug32778 b/changes/bug32778 deleted file mode 100644 index ccb6104692..0000000000 --- a/changes/bug32778 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (windows service): - - Initialize publish/subscribe system when running as a windows service. - Fixes bug 32778; bugfix on 0.4.1.1-alpha. diff --git a/changes/bug32825 b/changes/bug32825 deleted file mode 100644 index c51f2f8574..0000000000 --- a/changes/bug32825 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (portability, android): - - When building for Android, disable some tests that depend on - $HOME and/or pwdb, which Android doesn't have. Closes ticket 32825. - Patch from Hans-Christoph Steiner. diff --git a/changes/bug32841 b/changes/bug32841 deleted file mode 100644 index 48568f6a61..0000000000 --- a/changes/bug32841 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (linux seccomp sandbox): - - Fix crash when reloading logging configuration while the - experimental sandbox is enabled. Fixes bug 32841; bugfix - on 0.4.1.7. Patch by Peter Gerber. diff --git a/changes/bug32884 b/changes/bug32884 deleted file mode 100644 index 9ab1d24464..0000000000 --- a/changes/bug32884 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor bugfixes (embedded Tor): - - When starting Tor any time after the first time in a process, register - the thread in which it is running as the main thread. Previously, we - only did this on Windows, which could lead to bugs like 23081 on - non-Windows platforms. Fixes bug 32884; bugfix on 0.3.3.1-alpha. diff --git a/changes/bug32942 b/changes/bug32942 deleted file mode 100644 index 0a4ef9b092..0000000000 --- a/changes/bug32942 +++ /dev/null @@ -1,4 +0,0 @@ - o Deprecated features: - - Deprecate the ClientAutoIPv6ORPort option. This option was not true - Happy Eyeballs, and often failed on connections that weren't reliably - dual-stack. Closes ticket 32942. Patch by Neel Chauhan. diff --git a/changes/bug33284 b/changes/bug33284 new file mode 100644 index 0000000000..e6aed4d2d4 --- /dev/null +++ b/changes/bug33284 @@ -0,0 +1,4 @@ + o Minor bugfixes (git scripts): + - Stop executing the checked-out pre-commit hook from the pre-push hook. + Instead, execute the copy in the user's git dir. Fixes bug 33284; bugfix + on 0.4.1.1-alpha. diff --git a/changes/bug33285 b/changes/bug33285 new file mode 100644 index 0000000000..a4d06a7eb8 --- /dev/null +++ b/changes/bug33285 @@ -0,0 +1,3 @@ + o Minor bugfixes (protocol versions): + - Sort tor's supported protocol version lists, as recommended by the + tor directory specification. Fixes bug 33285; bugfix on 0.4.0.1-alpha. diff --git a/changes/bug33374 b/changes/bug33374 new file mode 100644 index 0000000000..d1141faf78 --- /dev/null +++ b/changes/bug33374 @@ -0,0 +1,5 @@ + o Minor bugfixes (coding best practices checks): + - Allow the "practracker" coding best practices checking script to read + unicode files, when using Python 2. We made the script use unicode + literals in 0.4.3.1-alpha, but didn't change the codec for opening files. + Fixes bug 33374; bugfix on 0.4.3.1-alpha. diff --git a/changes/bug4631 b/changes/bug4631 new file mode 100644 index 0000000000..be3dd2b43e --- /dev/null +++ b/changes/bug4631 @@ -0,0 +1,6 @@ + o Minor bugfixes (directory authorities): + - Directory authorities reject votes that arrive too late. In particular, + once an authority has started fetching missing votes, it no longer + accepts new votes posted by other authorities. This change helps prevent + a consensus split, where only some authorities have the late vote. + Fixes bug 4631; bugfix on 0.2.0.5-alpha. diff --git a/changes/doc31853 b/changes/doc31853 deleted file mode 100644 index 9118a4f8b1..0000000000 --- a/changes/doc31853 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation: - - Unite coding advice from this_not_that.md in torguts repo into our - coding standards document. Resolves ticket 31853. diff --git a/changes/feature32487 b/changes/feature32487 deleted file mode 100644 index 520ad8db41..0000000000 --- a/changes/feature32487 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (disabling relay support): - - When Tor is compiled --disable-module-relay, we also omit the - code used to act as a directory cache. Closes ticket 32487. diff --git a/changes/geoip-2019-12-03 b/changes/geoip-2019-12-03 deleted file mode 100644 index ea62b6ee89..0000000000 --- a/changes/geoip-2019-12-03 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (geoip): - - Update geoip and geoip6 to the December 3 2019 Maxmind GeoLite2 - Country database. Closes ticket 32685. - diff --git a/changes/log_32868 b/changes/log_32868 deleted file mode 100644 index 34476078b2..0000000000 --- a/changes/log_32868 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (debugging, directory system): - - Don't crash when we find a non-guard with a guard-fraction value set. - Instead, log a bug warning, in an attempt to figure out how this - happened. Diagnostic for ticket 32868. diff --git a/changes/ticket20218 b/changes/ticket20218 deleted file mode 100644 index d5fb2b2cfd..0000000000 --- a/changes/ticket20218 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (controller): - - In routerstatus_has_changed(), check all the fields that are output over the control port. - Fixes bug 20218; bugfix on 0.1.1.11-alpha diff --git a/changes/ticket27992 b/changes/ticket27992 deleted file mode 100644 index 9329a78915..0000000000 --- a/changes/ticket27992 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor bugfixes (configuration): - - When creating a KeyDirectory with the same location as the - DataDirectory (not recommended), respect the DataDirectory's - group-readable setting if one has not been set for the KeyDirectory. - Fixes bug 27992; bugfix on 0.3.3.1-alpha. diff --git a/changes/ticket28208 b/changes/ticket28208 new file mode 100644 index 0000000000..8818aad1d5 --- /dev/null +++ b/changes/ticket28208 @@ -0,0 +1,4 @@ + o Testing: + - Use the "bridges+hs-v23" chutney network flavor in "make test-network". + This test requires a recent version of chutney (mid-February 2020). + Closes ticket 28208. diff --git a/changes/ticket28804 b/changes/ticket28804 deleted file mode 100644 index 9c4eb47766..0000000000 --- a/changes/ticket28804 +++ /dev/null @@ -1,5 +0,0 @@ - o Major features (documentation): - - Provide a Circuit Padding Framework quickstart guide and developer - documentation for researchers to implement and study Circuit Padding - machines. Closes ticket 28804. - diff --git a/changes/ticket28992 b/changes/ticket28992 new file mode 100644 index 0000000000..3e45d73e45 --- /dev/null +++ b/changes/ticket28992 @@ -0,0 +1,3 @@ + o Minor bugfixes (onion service v3, client): + - Remove a BUG() that is causing a stacktrace for a situation that very + rarely happens but still can. Fixes bug 28992; bugfix on 0.3.2.1-alpha. diff --git a/changes/ticket29603 b/changes/ticket29603 deleted file mode 100644 index f820352cbb..0000000000 --- a/changes/ticket29603 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (git scripts): - - Add git-setup-dirs.sh, which sets up an upstream git repository and - worktrees for tor maintainers. Closes ticket 29603. diff --git a/changes/ticket29826 b/changes/ticket29826 deleted file mode 100644 index 480247e77c..0000000000 --- a/changes/ticket29826 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Replace some confusing identifiers in process_descs.c. - Closes ticket 29826. diff --git a/changes/ticket30382 b/changes/ticket30382 deleted file mode 100644 index bb8308a9fb..0000000000 --- a/changes/ticket30382 +++ /dev/null @@ -1,5 +0,0 @@ - o Major feature (onion service, SOCKS5): - - Introduce a new SocksPort flag named: ExtendedErrors. Detailed in - proposal 304, a number of onion service error codes are now sent back, - if this flag is set, with the SOCKS5 protocol using new custom error - values. Closes ticket 30382; diff --git a/changes/ticket30920 b/changes/ticket30920 deleted file mode 100644 index d2fd8c9dab..0000000000 --- a/changes/ticket30920 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfix (configuration): - - Check for multiplication overflow when parsing memory units inside - configuration. Fixes bug 30920; bugfix on 0.0.9rc1~46. diff --git a/changes/ticket30984 b/changes/ticket30984 deleted file mode 100644 index de7d055415..0000000000 --- a/changes/ticket30984 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Create a new abstraction for formatting control protocol reply - lines based on key-value pairs. Refactor some existing control - protocol code to take advantage of this. Closes ticket 30984. diff --git a/changes/ticket31241 b/changes/ticket31241 deleted file mode 100644 index 64852ca4be..0000000000 --- a/changes/ticket31241 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor features (configuration validation): - - Configuration validation can now be done by per-module callbacks, - rather than a global validation function. This will let us reduce the - size of config.c and some of its more cumbersome functions. Closes - ticket 31241. diff --git a/changes/ticket31336 b/changes/ticket31336 deleted file mode 100644 index c5a013699f..0000000000 --- a/changes/ticket31336 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor bugfixes (developer tools): - - Allow paths starting with ./ in scripts/add_c_file.py. Fixes bug - 31336; bugfix on 0.4.1.2-alpha. diff --git a/changes/ticket31371 b/changes/ticket31371 deleted file mode 100644 index 25457da81e..0000000000 --- a/changes/ticket31371 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor feature (heartbeat, onion service): - - Add the DoS INTRODUCE2 defenses counter to the heartbeat DoS message. - Closes ticket 31371. diff --git a/changes/ticket31373 b/changes/ticket31373 deleted file mode 100644 index 1f2dea3cd4..0000000000 --- a/changes/ticket31373 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor feature (configure, build system): - - Output enabled/disabled features at the end of the configure process in a - pleasing way. Closes ticket 31373. diff --git a/changes/ticket31518 b/changes/ticket31518 deleted file mode 100644 index 8deac56b98..0000000000 --- a/changes/ticket31518 +++ /dev/null @@ -1,6 +0,0 @@ - o Major features (proxy): - - In addition to HTTP CONNECT, SOCKS4, and SOCKS5, Tor can make all OR - connections through the HAProxy server. A new torrc option was added to - specify the address/port of the server: TCPProxy <protocol> - <host>:<port>. Currently the only supported protocol in the option is - haproxy. Close ticket 31518. Patch done by Suphanat Chunhapanya (haxxpop). diff --git a/changes/ticket31576 b/changes/ticket31576 new file mode 100644 index 0000000000..ab984cf3d4 --- /dev/null +++ b/changes/ticket31576 @@ -0,0 +1,3 @@ + o Removed features: + - Stop shipping contrib/dist/rc.subr file, as it is not being used on + FreeBSD anymore. Closes issue 31576. diff --git a/changes/ticket31684 b/changes/ticket31684 deleted file mode 100644 index 6631c87940..0000000000 --- a/changes/ticket31684 +++ /dev/null @@ -1,6 +0,0 @@ - o Minor features (controller): - - Implement a new GETINFO command to fetch microdescriptor consensus. - Closes ticket 31684. - o Code simplification and refactoring (controller): - - Create a helper function that can fetch network status or microdesc - consensuses. Closes ticket 31684. diff --git a/changes/ticket31705 b/changes/ticket31705 deleted file mode 100644 index 5ac736d4f5..0000000000 --- a/changes/ticket31705 +++ /dev/null @@ -1,9 +0,0 @@ - o Minor features (developer tools): - - Add some scripts in "scripts/coccinelle" to invoke the Coccinelle - semantic patching tool with the correct flags. These flags are fairly - easy to forget, and these scripts should help us use Coccinelle more - effectively in the future. Closes ticket 31705. - - o Code simplification and refactoring: - - Fix some parts of our code that were difficult for Coccinelle to parse. - Related to ticket 31705. diff --git a/changes/ticket31919 b/changes/ticket31919 deleted file mode 100644 index 5344db956b..0000000000 --- a/changes/ticket31919 +++ /dev/null @@ -1,13 +0,0 @@ - o Minor features (developer tools): - - Add a check_cocci_parse.sh script that checks that new code - is parseable by Coccinelle. Add an exceptions file for unparseable - files. Closes ticket 31919. - - Call the check_cocci_parse.sh script from a 'check-cocci' Makefile - target. Closes ticket 31919. - o Minor features (git scripts): - - Call the check_cocci_parse.sh script from the git commit and push hooks. - Closes ticket 31919. - - Skip unmodified source files when doing some existing git hook checks. - Related to ticket 31919. - o Minor features (continuous integration): - - Call the check_cocci_parse.sh script from Travis CI. Closes ticket 31919. diff --git a/changes/ticket31999 b/changes/ticket31999 deleted file mode 100644 index 31f230ee20..0000000000 --- a/changes/ticket31999 +++ /dev/null @@ -1,6 +0,0 @@ - o Code simplification and refactoring: - - Our default log (which ordinarily sends NOTICE-level message to - standard output) is now handled in a more logical manner. Previously, - we replaced the configured log options if they were empty. - Now, we interpret an empty set of log options as meaning "use the - default log". Closes ticket 31999. diff --git a/changes/ticket32003 b/changes/ticket32003 deleted file mode 100644 index b8809f288e..0000000000 --- a/changes/ticket32003 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - When parsing the command line, handle options that determine our "quiet - level" and our mode of operation (e.g., --dump-config and so on) - all in one table. Closes ticket 32003. diff --git a/changes/ticket32020 b/changes/ticket32020 deleted file mode 100644 index 1cad61af89..0000000000 --- a/changes/ticket32020 +++ /dev/null @@ -1,6 +0,0 @@ - o Major bugfixes (onion service): - - Report back HS circuit failure back into the HS subsytem so we take - appropriate action with regards to the client introduction point failure - cache. This improves reachability of onion services, since now clients - notice failing introduction circuits properly. Fixes bug 32020; bugfix on - 0.3.2.1-alpha; diff --git a/changes/ticket32021 b/changes/ticket32021 deleted file mode 100644 index 24a6d9d981..0000000000 --- a/changes/ticket32021 +++ /dev/null @@ -1,7 +0,0 @@ - o Minor bugfixes (onion services v3, client): - - Properly handle the client rendezvous circuit timeout. This results in - better reachability because tor doesn't timeout a rendezvous circuit - awaiting the introduction ACK and thus preventing tor to re-establish all - circuits because the rendezvous circuit timed out too early. Fixes bug - 32021; bugfix on 0.3.2.1-alpha. - diff --git a/changes/ticket32094 b/changes/ticket32094 deleted file mode 100644 index f6d0aba164..0000000000 --- a/changes/ticket32094 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (hidden service v3): - - Do not rely on a "circuit established" flag for intro circuit but instead - always query the HS circuit map. This is to avoid sync issue with that - flag and the map. Fixes bug 32094; bugfix on 0.3.2.1-alpha. diff --git a/changes/ticket32099 b/changes/ticket32099 deleted file mode 100644 index 7a111df6ba..0000000000 --- a/changes/ticket32099 +++ /dev/null @@ -1,4 +0,0 @@ - o Removed features: - - Our Doxygen configuration no longer generates LaTeX output. The - reference manual produced by doing this was over 4000 pages long, - and generally unusable. Closes ticket 32099. diff --git a/changes/ticket32110 b/changes/ticket32110 deleted file mode 100644 index 75d20a74bf..0000000000 --- a/changes/ticket32110 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (Doxygen): - - - Update Doxygen configuration file to a more recent template (from - 1.8.15). Closes ticket 32110. diff --git a/changes/ticket32113 b/changes/ticket32113 deleted file mode 100644 index ef7978f1b9..0000000000 --- a/changes/ticket32113 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (doxygen): - - "make doxygen" now works with out-of-tree builds. Closes ticket - 32113. diff --git a/changes/ticket32123 b/changes/ticket32123 deleted file mode 100644 index 8200f5fca6..0000000000 --- a/changes/ticket32123 +++ /dev/null @@ -1,5 +0,0 @@ - o Major features (build system): - - Create an optional relay module, which can be disabled using the - --disable-module-relay configure option. When it is set, also disable - the dirauth module. Add a minimal implemention, which disables the - relay and dircache modes in tor. Closes ticket 32123. diff --git a/changes/ticket32137 b/changes/ticket32137 deleted file mode 100644 index 3b00ddcf24..0000000000 --- a/changes/ticket32137 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Our include.am files are now broken up by subdirectory. Previously, - src/core/include.am covered all of the subdirectories in "core", - "feature", and "app". Closes ticket 32137. diff --git a/changes/ticket32163 b/changes/ticket32163 deleted file mode 100644 index 06ea838f07..0000000000 --- a/changes/ticket32163 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Remove the last remaining HAVE_MODULE_DIRAUTH inside a function. - Closes ticket 32163. diff --git a/changes/ticket32172 b/changes/ticket32172 deleted file mode 100644 index a661617999..0000000000 --- a/changes/ticket32172 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (tests, Android): - - When running the unit tests on Android, create temporary files - in a subdirectory of /data/local/tmp. Closes ticket - 32172. Based on a patch from Hans-Christoph Steiner. diff --git a/changes/ticket32176 b/changes/ticket32176 deleted file mode 100644 index ad44d3280d..0000000000 --- a/changes/ticket32176 +++ /dev/null @@ -1,4 +0,0 @@ - o Documentation (manpage): - - In the tor(1) manpage, reword and improve formatting of the - FILES, SEE ALSO, and BUGS sections. Closes ticket 32176. Based - on work by Swati Thacker as part of Google Season of Docs. diff --git a/changes/ticket32185 b/changes/ticket32185 deleted file mode 100644 index 86f5dc5af1..0000000000 --- a/changes/ticket32185 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Simplify the options_validate() code so that it looks at the default - options directly, rather than taking default options as an argument. - This change lets us simplify its interface. Closes ticket 32185. diff --git a/changes/ticket32187 b/changes/ticket32187 deleted file mode 100644 index b5b4e16bfc..0000000000 --- a/changes/ticket32187 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Remove some unused arguments from the options_validate() function, - to simplify our code and tests. Closes ticket 32187. diff --git a/changes/ticket32196 b/changes/ticket32196 deleted file mode 100644 index d642478fe4..0000000000 --- a/changes/ticket32196 +++ /dev/null @@ -1,2 +0,0 @@ - o Testing (circuit, EWMA): - - Add unit tests for circuitmux and EWMA subsystems. Closes ticket 32196. diff --git a/changes/ticket32206 b/changes/ticket32206 deleted file mode 100644 index 7ced81853e..0000000000 --- a/changes/ticket32206 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation: - - Create a high-level description of the long-term software - architecture goals. Closes ticket 32206. diff --git a/changes/ticket32213_parseconf b/changes/ticket32213_parseconf deleted file mode 100644 index a334bec5c6..0000000000 --- a/changes/ticket32213_parseconf +++ /dev/null @@ -1,3 +0,0 @@ - o Testing: - - Improve the consistency of test_parseconf.sh output, and run all the - tests, even if one fails. Closes ticket 32213. diff --git a/changes/ticket32216 b/changes/ticket32216 deleted file mode 100644 index 86712d700d..0000000000 --- a/changes/ticket32216 +++ /dev/null @@ -1,9 +0,0 @@ - o Minor features (git scripts): - - Make git-push-all.sh skip unchanged branches when pushing to upstream. - The script already skipped unchanged test branches. - Closes ticket 32216. - o Minor bugfixes (git scripts): - - Avoid sleeping before the last push in git-push-all.sh. - Closes ticket 32216. - - Forward all unrecognised arguments in git-push-all.sh to git push. - Closes ticket 32216. diff --git a/changes/ticket32237 b/changes/ticket32237 deleted file mode 100644 index dfa0b78405..0000000000 --- a/changes/ticket32237 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor features (developer tools): - - Add a rename_c_identifiers.py tool to rename a bunch of C - identifiers at once, and generate a well-formed commit message - describing the change. This should help with refactoring. Closes - ticket 32237. diff --git a/changes/ticket32240 b/changes/ticket32240 deleted file mode 100644 index 35cc3df27e..0000000000 --- a/changes/ticket32240 +++ /dev/null @@ -1,4 +0,0 @@ - o Testing: - - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on Ubuntu - Bionic. Turning off the Sandbox is a work-around, until we fix the - sandbox errors in 32722. Closes ticket 32240. diff --git a/changes/ticket32242 b/changes/ticket32242 deleted file mode 100644 index d63d5a586e..0000000000 --- a/changes/ticket32242 +++ /dev/null @@ -1,2 +0,0 @@ - o Testing (continuous integration): - - Use zstd in our Travis Linux builds. Closes ticket 32242. diff --git a/changes/ticket32244 b/changes/ticket32244 deleted file mode 100644 index b3690b7d8c..0000000000 --- a/changes/ticket32244 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Disable relay_periodic when the relay module is disabled. - Closes ticket 32244. diff --git a/changes/ticket32245 b/changes/ticket32245 deleted file mode 100644 index fc79e748b1..0000000000 --- a/changes/ticket32245 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Disable relay_sys when the relay module is disabled. - Closes ticket 32245. diff --git a/changes/ticket32277 b/changes/ticket32277 deleted file mode 100644 index 1ef0c4ab56..0000000000 --- a/changes/ticket32277 +++ /dev/null @@ -1,5 +0,0 @@ - o Documentation (manpage): - - In the tor(1) manpage, reword and improve formatting of the - COMMAND-LINE OPTIONS and DESCRIPTION sections. Closes ticket - 32277. Based on work by Swati Thacker as part of Google Season - of Docs. diff --git a/changes/ticket32304 b/changes/ticket32304 deleted file mode 100644 index 5dde7b6d84..0000000000 --- a/changes/ticket32304 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Move and rename some configuration-related code for clarity. - Closes ticket 32304. diff --git a/changes/ticket32307 b/changes/ticket32307 deleted file mode 100644 index 1e68430991..0000000000 --- a/changes/ticket32307 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (documentation): - - Make sure that doxygen outputs documentation for all of our C files. - Previously, some were missing @file declarations, causing them to be - ignored. Closes ticket 32307. diff --git a/changes/ticket32339_relative b/changes/ticket32339_relative deleted file mode 100644 index 83af9f031b..0000000000 --- a/changes/ticket32339_relative +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Instead of keeping a list of configuration options to check for - relative paths, check all the options whose type is "FILENAME". - Solves part of ticket 32339. diff --git a/changes/ticket32344 b/changes/ticket32344 deleted file mode 100644 index 9dfb326976..0000000000 --- a/changes/ticket32344 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Immutability is now implemented as a flag on individual configuration - options rather than as part of the option-transition checking - code. Closes ticket 32344. diff --git a/changes/ticket32347 b/changes/ticket32347 deleted file mode 100644 index 076efe8b42..0000000000 --- a/changes/ticket32347 +++ /dev/null @@ -1,7 +0,0 @@ - o Minor features (git scripts): - - Make git-setup-dirs.sh create a master symlink in the worktree directory. - Closes ticket 32347. - - Add TOR_EXTRA_CLONE_ARGS to git-setup-dirs.sh for git clone - customisation. Closes ticket 32347. - - Add TOR_EXTRA_REMOTE_* to git-setup-dirs.sh for a custom extra remote. - Closes ticket 32347. diff --git a/changes/ticket32382 b/changes/ticket32382 deleted file mode 100644 index 85cf07b2ef..0000000000 --- a/changes/ticket32382 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (configuration): - - Avoid changing the user's value of HardwareAccel as stored by SAVECONF, - when AccelName is set but HardwareAccel is not. - Fixes bug 32382; bugfix on 0.2.2.1-alpha. diff --git a/changes/ticket32385 b/changes/ticket32385 deleted file mode 100644 index 2ff76be267..0000000000 --- a/changes/ticket32385 +++ /dev/null @@ -1,6 +0,0 @@ - o Minor features (doxygen): - - Our "make doxygen" target now respects --enable-fatal-warnings by - default, and does not warn about items that are missing documentation. - To warn about missing documentation, run configure with the - "--enable-missing-doc-warnings" flag: doing so suspends fatal warnings - for doxygen. Closes ticket 32385. diff --git a/changes/ticket32397 b/changes/ticket32397 deleted file mode 100644 index 4e77ea135d..0000000000 --- a/changes/ticket32397 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (testing): - - test_parseconf.sh now supports result variants for any combination - of the optional libraries lzma, nss, and zstd. - Closes ticket 32397. diff --git a/changes/ticket32404 b/changes/ticket32404 deleted file mode 100644 index 1bffbc652b..0000000000 --- a/changes/ticket32404 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor features (configuration): - - We use a flag-driven logic to warn about obsolete configuration fields, - so that we can include their names. In 0.4.2, we used - a special type, which prevented us from generating good warnings. - Implements ticket 32404. diff --git a/changes/ticket32406 b/changes/ticket32406 deleted file mode 100644 index c0c60207c0..0000000000 --- a/changes/ticket32406 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (configuration): - - If the configured hardware crypto accelerator in AccelName - is prefixed with "!", Tor now exits when it cannot be found. - Closes ticket 32406. diff --git a/changes/ticket32410 b/changes/ticket32410 deleted file mode 100644 index 3b516d7a8c..0000000000 --- a/changes/ticket32410 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (relay): - - When the relay module is disabled, change the default config so that - DirCache is 0, and ClientOnly is 1. Closes ticket 32410. diff --git a/changes/ticket32415 b/changes/ticket32415 deleted file mode 100644 index 5d732978ae..0000000000 --- a/changes/ticket32415 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Make all the structs we declare follow the same naming convention - of ending with "_t". Closes ticket 32415. diff --git a/changes/ticket32451 b/changes/ticket32451 deleted file mode 100644 index dcca851e57..0000000000 --- a/changes/ticket32451 +++ /dev/null @@ -1,5 +0,0 @@ - o Minor features (testing): - - Allow test_parseconf.sh to test expected log outputs for successful - configs, as well as failed configs. Closes ticket 32451. - - Add common failure cases for test_parseconf.sh in - src/test/conf_failures. Closes ticket 32451. diff --git a/changes/ticket32467 b/changes/ticket32467 deleted file mode 100644 index 8cbb23812a..0000000000 --- a/changes/ticket32467 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation: - - Describe the --dump-config command in the manual page. Closes ticket - 32467. diff --git a/changes/ticket32608 b/changes/ticket32608 deleted file mode 100644 index 2915e62caa..0000000000 --- a/changes/ticket32608 +++ /dev/null @@ -1,4 +0,0 @@ - o New system requirements: - - When building Tor, you now need to have Python 3 in order to - run the integration tests. (Python 2 is officially unsupported - upstream, as of 1 Jan 2020.) Closes ticket 32608. diff --git a/changes/ticket32609 b/changes/ticket32609 deleted file mode 100644 index d37b3d66b8..0000000000 --- a/changes/ticket32609 +++ /dev/null @@ -1,3 +0,0 @@ - o Testing: - - Run the practracker unit tests in the pre-commit git hook. - Closes ticket 32609. diff --git a/changes/ticket32629 b/changes/ticket32629 deleted file mode 100644 index 740746c572..0000000000 --- a/changes/ticket32629 +++ /dev/null @@ -1,4 +0,0 @@ - o Testing: - - Re-enable the Travis CI macOS Chutney build, but allow the job to finish - before it finishes, because the Travis macOS jobs are slow. - Closes ticket 32629. diff --git a/changes/ticket32637 b/changes/ticket32637 deleted file mode 100644 index 253f445c89..0000000000 --- a/changes/ticket32637 +++ /dev/null @@ -1,6 +0,0 @@ - o Minor features (IPv6, client): - - Make Tor clients tell dual-stack exits that they prefer IPv6 - connections. This change is equivalent to setting the PreferIPv6 flag - on SOCKSPorts (and most other listener ports). Tor Browser has been - setting this flag for some time, and we want to remove a client - distinguisher at exits. Closes ticket 32637. diff --git a/changes/ticket32695 b/changes/ticket32695 deleted file mode 100644 index 2df53144eb..0000000000 --- a/changes/ticket32695 +++ /dev/null @@ -1,6 +0,0 @@ - o Removed features: - - We no longer support consensus methods before method 28; these - methods were only used by authorities running versions of Tor that - are now at end-of-life. In effect, this means that clients and - relays, and authorities now assume that authorities will be - running version 0.3.5.x or later. Closes ticket 32695. diff --git a/changes/ticket32704 b/changes/ticket32704 deleted file mode 100644 index 4cc001975e..0000000000 --- a/changes/ticket32704 +++ /dev/null @@ -1,3 +0,0 @@ - o Minor features (release tools): - - Port our changelog formatting and sorting tools to Python 3. - Closes ticket 32704. diff --git a/changes/ticket32705_disable b/changes/ticket32705_disable deleted file mode 100644 index 6d5b0779ab..0000000000 --- a/changes/ticket32705_disable +++ /dev/null @@ -1,7 +0,0 @@ - o Minor bugfixes (testing): - - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the - test_practracker.sh script. Doing so caused a test failure. - Fixes bug 32705; bugfix on 0.4.2.1-alpha. - - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr - when skipping practracker checks. - Fixes bug 32705; bugfix on 0.4.2.1-alpha. diff --git a/changes/ticket32708 b/changes/ticket32708 deleted file mode 100644 index 06bf4cf22b..0000000000 --- a/changes/ticket32708 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation (manpage): - - Alphabetize the General Options section of the tor - manpage. Closes ticket 32708. diff --git a/changes/ticket32764 b/changes/ticket32764 deleted file mode 100644 index 7795339f37..0000000000 --- a/changes/ticket32764 +++ /dev/null @@ -1,9 +0,0 @@ - o Code simplification and refactoring: - - - Add numerous missing dependencies to our include files, so that - they can be included in different reasonable orders and still - compile. Addresses part of ticket 32764. - - - Fix some small issues in our code that prevented automatic - formatting tools from working. - Addresses part of ticket 32764. diff --git a/changes/ticket32765 b/changes/ticket32765 deleted file mode 100644 index a9663a5df3..0000000000 --- a/changes/ticket32765 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor bugfixes (correctness checks): - - Use GCC/Clang's printf-checking feature to make sure that - tor_assertf() arguments are correctly typed. Fixes bug 32765; - bugfix on 0.4.1.1-alpha. diff --git a/changes/ticket32772 b/changes/ticket32772 deleted file mode 100644 index 217ae48438..0000000000 --- a/changes/ticket32772 +++ /dev/null @@ -1,4 +0,0 @@ - o Minor features (developer tooling): - - Remove 0.2.9 series branches from git scripts (git-merge-forward.sh, - git-pull-all.sh, git-push-all.sh, git-setup-dirs.sh). Closes ticket - 32772. diff --git a/changes/ticket32779 b/changes/ticket32779 deleted file mode 100644 index 1b7ccaa7ed..0000000000 --- a/changes/ticket32779 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation: - - Add documentation in 'HelpfulTools.md' to describe how to build a tag - file. Closes ticket 32779. diff --git a/changes/ticket32792 b/changes/ticket32792 new file mode 100644 index 0000000000..553cf0ca81 --- /dev/null +++ b/changes/ticket32792 @@ -0,0 +1,3 @@ + o Testing: + - When a Travis chutney job fails, use chutney's new "diagnostics.sh" tool + to produce detailed diagnostic output. Closes ticket 32792. diff --git a/changes/ticket32806 b/changes/ticket32806 deleted file mode 100644 index 357e281d36..0000000000 --- a/changes/ticket32806 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring: - - Use our new configuration architecture to move most authority-related - options to the directory authority module. Closes ticket 32806. diff --git a/changes/ticket32807 b/changes/ticket32807 deleted file mode 100644 index 07f8716e1f..0000000000 --- a/changes/ticket32807 +++ /dev/null @@ -1,4 +0,0 @@ - o Removed features: - - The option "TestingEstimatedDescriptorPropagationTime" is now marked as - obsolete. It has had no effect since 0.3.0.7, when clients stopped - rejecting consensuses "from the future". Closes ticket 32807. diff --git a/changes/ticket32845 b/changes/ticket32845 deleted file mode 100644 index 23bdd355ff..0000000000 --- a/changes/ticket32845 +++ /dev/null @@ -1,4 +0,0 @@ - o Testing: - - Add more test cases for tor's UTF-8 validation function. Also, check the - arguments passed to the function for consistency. - Closes ticket 32845. diff --git a/changes/ticket32846 b/changes/ticket32846 deleted file mode 100644 index 5022c61451..0000000000 --- a/changes/ticket32846 +++ /dev/null @@ -1,3 +0,0 @@ - o Documentation (manpage): - - Alphabetize the Client Options section of the tor manpage. - Closes ticket 32846. diff --git a/changes/ticket32887 b/changes/ticket32887 deleted file mode 100644 index a7406bcce3..0000000000 --- a/changes/ticket32887 +++ /dev/null @@ -1,4 +0,0 @@ - o Code simplification and refactoring: - - Remove underused NS*() macros from test code: they make our - tests more confusing, especially for code-formatting tools. - Closes ticket 32887. diff --git a/changes/ticket32892 b/changes/ticket32892 deleted file mode 100644 index f6360d2883..0000000000 --- a/changes/ticket32892 +++ /dev/null @@ -1,3 +0,0 @@ - o Code simplification and refactoring (channel): - - Channel layer had a variable length cell handler that was not used and - thus removed. Closes ticket 32892. diff --git a/changes/ticket33029 b/changes/ticket33029 new file mode 100644 index 0000000000..c32ee4ad84 --- /dev/null +++ b/changes/ticket33029 @@ -0,0 +1,5 @@ + o Major bugfixes (directory authority): + - Directory authorities will now send a 503 (not enough bandwidth) code to + clients when under bandwidth pressure. Known relays and other authorities + will always be answered regardless of the bandwidth situation. Fixes bug + 33029; bugfix on 0.1.2.5-alpha. diff --git a/changes/ticket33188 b/changes/ticket33188 new file mode 100644 index 0000000000..7bec15b99b --- /dev/null +++ b/changes/ticket33188 @@ -0,0 +1,5 @@ + o Documentation (manpage): + - Alphabetize the Server and Directory server sections of the tor + manpage. Also split Statistics options into their own section + of the manpage. Closes ticket 33188. Work by Swati Thacker as + part of Google Season of Docs. diff --git a/changes/ticket33192 b/changes/ticket33192 new file mode 100644 index 0000000000..97f976226b --- /dev/null +++ b/changes/ticket33192 @@ -0,0 +1,5 @@ + o Minor feature (python): + - Stop assuming that /usr/bin/python exists. Instead of using a + hardcoded path in scripts that still use Python 2, use /usr/bin/env, + similarly to the scripts that use Python 3. Fixes bug 33192; bugfix + on 0.4.2.
\ No newline at end of file diff --git a/changes/ticket33194 b/changes/ticket33194 new file mode 100644 index 0000000000..b87e55348e --- /dev/null +++ b/changes/ticket33194 @@ -0,0 +1,4 @@ + o Testing: + - Remove a redundant distcheck job. Closes ticket 33194. + - Sort the Travis jobs in order of speed. Putting the slowest jobs first + takes full advantage of Travis job concurrency. Closes ticket 33194. diff --git a/changes/ticket33195 b/changes/ticket33195 new file mode 100644 index 0000000000..11abd4816e --- /dev/null +++ b/changes/ticket33195 @@ -0,0 +1,4 @@ + o Testing: + - Stop allowing the Chutney IPv6 Travis job to fail. This job was + previously configured to fast_finish (which requires allow_failure), to + speed up the build. Closes ticket 33195. diff --git a/changes/ticket33213 b/changes/ticket33213 new file mode 100644 index 0000000000..f1da591bd1 --- /dev/null +++ b/changes/ticket33213 @@ -0,0 +1,3 @@ + o Minor bugfixes (continuous integration): + - Remove the buggy and unused mirroring job. Fixes bug 33213; + bugfix on 0.3.2.2-alpha. diff --git a/changes/ticket33275 b/changes/ticket33275 new file mode 100644 index 0000000000..bff3a7a3ad --- /dev/null +++ b/changes/ticket33275 @@ -0,0 +1,5 @@ + o Documentation (manpage): + - Alphabetize the Denial of Service Mitigation Options, Directory + Authority Server Options, Hidden Service Options, and Testing + Network Options sections of the tor(1) manpage. Closes ticket + 33275. Work by Swati Thacker as part of Google Season of Docs. diff --git a/changes/ticket33280 b/changes/ticket33280 new file mode 100644 index 0000000000..b90c3086ea --- /dev/null +++ b/changes/ticket33280 @@ -0,0 +1,4 @@ + o Testing: + - Add test-network-ipv4 and test-network-ipv6 jobs to the Makefile. + These jobs run the IPv4-only and dual-stack chutney flavours from + test-network-all. Closes ticket 33280. diff --git a/changes/ticket33290 b/changes/ticket33290 new file mode 100644 index 0000000000..882764020e --- /dev/null +++ b/changes/ticket33290 @@ -0,0 +1,4 @@ + o Minor features (diagnostic): + - Improve assertions and add some memory-poisoning code to try to track + down possible causes of a rare crash (32564) in the EWMA code. + Closes ticket 33290. diff --git a/changes/ticket33300 b/changes/ticket33300 new file mode 100644 index 0000000000..9b0bdce372 --- /dev/null +++ b/changes/ticket33300 @@ -0,0 +1,3 @@ + o Testing: + - Add a basic IPv6 test to "make test-network". This test only runs when + the local machine has an IPv6 stack. Closes ticket 33300. diff --git a/changes/ticket33303 b/changes/ticket33303 new file mode 100644 index 0000000000..b7ac7b5067 --- /dev/null +++ b/changes/ticket33303 @@ -0,0 +1,4 @@ + o Testing: + - Run the test-network-ipv6 Makefile target in the Travis CI IPv6 chutney + job. This job runs on macOS, so it's a bit slow. + Closes ticket 33303. diff --git a/changes/ticket33334 b/changes/ticket33334 new file mode 100644 index 0000000000..ada3cb284c --- /dev/null +++ b/changes/ticket33334 @@ -0,0 +1,5 @@ + o Testing: + - Test v3 onion services to tor's mixed IPv4 chutney network. And add a + mixed IPv6 chutney network. These networks are used in the + test-network-all, test-network-ipv4, and test-network-ipv6 make targets. + Closes ticket 33334. diff --git a/changes/ticket33339 b/changes/ticket33339 new file mode 100644 index 0000000000..75ccb3546f --- /dev/null +++ b/changes/ticket33339 @@ -0,0 +1,3 @@ + o Minor feature (developer tools): + - Add a script to help check the alphabetical ordering of option + names in a manpage. Closes ticket 33339. diff --git a/changes/ticket33349 b/changes/ticket33349 new file mode 100644 index 0000000000..0458a72c8d --- /dev/null +++ b/changes/ticket33349 @@ -0,0 +1,4 @@ + o Code simplification and refactoring: + - Updated comments in 'scheduler.c' to reflect old code changes, + and simplified the scheduler channel state change code. Closes + ticket 33349. diff --git a/changes/ticket33366 b/changes/ticket33366 new file mode 100644 index 0000000000..1310c493c2 --- /dev/null +++ b/changes/ticket33366 @@ -0,0 +1,3 @@ + o Minor features (compilation size): + - Most Server-side DNS code is now disabled when building without + support for relay mode. Closes ticket 33366. diff --git a/changes/ticket33368 b/changes/ticket33368 new file mode 100644 index 0000000000..ecc6f66f4e --- /dev/null +++ b/changes/ticket33368 @@ -0,0 +1,3 @@ + o Minor features (client-only compilation): + - Disable more code related to the ext_orport protocol when compiling + without support for relay mode. Closes ticket 33368. diff --git a/changes/ticket33370 b/changes/ticket33370 new file mode 100644 index 0000000000..41e03357f0 --- /dev/null +++ b/changes/ticket33370 @@ -0,0 +1,3 @@ + o Minor features (client-only compilation): + - Disable more of our self-testing code when support for relay mode is + disabled. Closes ticket 33370. diff --git a/configure.ac b/configure.ac index 4571768d8e..aa511a3911 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2019, The Tor Project, Inc. dnl See LICENSE for licensing information AC_PREREQ([2.63]) -AC_INIT([tor],[0.4.3.0-alpha-dev]) +AC_INIT([tor],[0.4.4.0-alpha-dev]) AC_CONFIG_SRCDIR([src/app/main/tor_main.c]) AC_CONFIG_MACRO_DIR([m4]) @@ -16,7 +16,7 @@ configure_flags="$*" # version number changes. Tor uses it to make sure that it # only shuts down for missing "required protocols" when those protocols # are listed as required by a consensus after this date. -AC_DEFINE(APPROX_RELEASE_DATE, ["2019-10-11"], # for 0.4.3.0-alpha-dev +AC_DEFINE(APPROX_RELEASE_DATE, ["2020-02-11"], # for 0.4.4.0-alpha-dev [Approximate date when this software was released. (Updated when the version changes.)]) # "foreign" means we don't follow GNU package layout standards @@ -2591,21 +2591,18 @@ PPRINT_PROP_STRING([Compiler], [$CC]) PPRINT_PROP_STRING([Host OS], [$host_os]) AS_ECHO -test "x$enable_gcc_warnings" = "xyes" && value=1 || value=0 -PPRINT_PROP_BOOL([Verbose Warnings (--enable-gcc-warnings)], $value) - test "x$enable_fatal_warnings" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Warnings are fatal (--enable-fatal-warnings)], $value) test "x$enable_rust" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Rust support (--enable-rust)], $value) +test "x$enable_cargo_online_mode" = "xyes" && value=1 || value=0 +PPRINT_PROP_BOOL([Cargo Online Fetch (--enable-cargo-online-mode)], $value) + test "x$enable_android" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Android support (--enable-android)], $value) -test "x$enable_systemd" = "xyes" && value=1 || value=0 -PPRINT_PROP_BOOL([Systemd support (--enable-systemd)], $value) - AS_ECHO PPRINT_SUBTITLE([Static Build]) @@ -2642,6 +2639,15 @@ PPRINT_PROP_BOOL([libseccomp (--disable-seccomp)], $value) test "x$enable_libscrypt" != "xno" && value=1 || value=0 PPRINT_PROP_BOOL([libscrypt (--disable-libscrypt)], $value) +test "x$enable_systemd" = "xyes" && value=1 || value=0 +PPRINT_PROP_BOOL([Systemd support (--enable-systemd)], $value) + +test "x$enable_lzma" = "xyes" && value=1 || value=0 +PPRINT_PROP_BOOL([liblzma (--enable-lzma)], $value) + +test "x$enable_zstd" = "xyes" && value=1 || value=0 +PPRINT_PROP_BOOL([libzstd (--enable-zstd)], $value) + AS_ECHO PPRINT_SUBTITLE([Hardening]) @@ -2651,21 +2657,25 @@ PPRINT_PROP_BOOL([Compiler Hardening (--disable-gcc-hardening)], $value) test "x$enable_linker_hardening" != "xno" && value=1 || value=0 PPRINT_PROP_BOOL([Linker Hardening (--disable-linker-hardening)], $value) -test "x$enable_fragile_hardening" = "xyes" && value=1 || value=0 +test "x$fragile_hardening" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Fragile Hardening (--enable-fragile-hardening, dev only)], $value) AS_ECHO PPRINT_SUBTITLE([Modules]) -test "x$enable_module_dirauth" != "xno" && value=1 || value=0 -PPRINT_PROP_BOOL([Directory Authority (--disable-module-dirauth)], $value) - -test "x$enable_module_relay" != "xno" && value=1 || value=0 -PPRINT_PROP_BOOL([Relay (--disable-module-relay)], $value) +m4_foreach_w([mname], MODULES, + [ + test "xenable_module_mname" != "xno" && value=1 || value=0 + PPRINT_PROP_BOOL([mname (--disable-module-mname)], $value) + ] +) AS_ECHO PPRINT_SUBTITLE([Documentation]) +test "x$enable_asciidoc" != "xno" && value=1 || value=0 +PPRINT_PROP_BOOL([AsciiDoc (--disable-asciidoc)], $value) + test "x$enable_manpage" != "xno" && value=1 || value=0 PPRINT_PROP_BOOL([Man Pages (--disable-manpage)], $value) @@ -2679,7 +2689,7 @@ test "x$enable_unittests" != "xno" && value=1 || value=0 PPRINT_PROP_BOOL([Unit tests (--disable-unittests)], $value) test "x$enable_asserts_in_tests" = "xno" && value=1 || value=0 -PPRINT_PROP_BOOL([assert()s disabled (--disable-asserts-in-tests, dev only)], $value) +PPRINT_PROP_BOOL([assert()s enabled (--enable-asserts-in-tests, dev only)], $value) test "x$enable_coverage" = "xyes" && value=1 || value=0 PPRINT_PROP_BOOL([Code Coverage (--enable-coverage)], $value) diff --git a/contrib/README b/contrib/README index 735fcf4c9f..a56065f97d 100644 --- a/contrib/README +++ b/contrib/README @@ -29,7 +29,7 @@ should probably use src/tools/tor-resolve instead. dist/ -- Scripts and files for use when packaging Tor ----------------------------------------------------- -torctl, rc.subr, and tor.sh are init scripts for use with SysV-style init +torctl and tor.sh are init scripts for use with SysV-style init tools. Everybody likes to write init scripts differently, it seems. tor.service is a sample service file for use with systemd. diff --git a/contrib/client-tools/tor-resolve.py b/contrib/client-tools/tor-resolve.py index 593efc97d4..85e7d2d8b4 100755 --- a/contrib/client-tools/tor-resolve.py +++ b/contrib/client-tools/tor-resolve.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Future imports for Python 2.7, mandatory in 3.0 from __future__ import division @@ -87,7 +87,7 @@ def parseHostAndPort(h): try: port = int(h[i+1:]) except ValueError: - print "Bad hostname %r"%h + print("Bad hostname %r"%h) sys.exit(1) elif h: try: @@ -123,15 +123,15 @@ def resolve(hostname, sockshost, socksport, socksver=4, reverse=0): return None answer += more result = parse(answer) - print "Got answer",result + print("Got answer",result) m = s.recv(1) if m: - print "Got extra data too: %r"%m + print("Got extra data too: %r"%m) return result if __name__ == '__main__': if len(sys.argv) not in (2,3,4): - print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]" + print("Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]") sys.exit(0) socksver = 4 reverse = 0 @@ -146,7 +146,7 @@ if __name__ == '__main__': break if len(sys.argv) >= 4: - print "Syntax: resolve.py [-x] [-4|-5] hostname [sockshost:socksport]" + print("Syntax: resolve.py [-x] [-4|-5] hostname [sockshost:socksport]") sys.exit(0) if len(sys.argv) == 3: sh,sp = parseHostAndPort(sys.argv[2]) diff --git a/contrib/dist/rc.subr b/contrib/dist/rc.subr deleted file mode 100644 index d757e89528..0000000000 --- a/contrib/dist/rc.subr +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# $FreeBSD: ports/security/tor-devel/files/tor.in,v 1.1 2006/02/17 22:21:25 mnag Exp $ -# -# (rc.subr written by Peter Thoenen for Net/FreeBSD) -# -# REQUIRE: NETWORKING SERVERS USR -# BEFORE: LOGIN -# -# Add the following lines to /etc/rc.conf to enable tor -# -# tor_enable (bool): Set to "NO" by default -# Set it to "YES" to enable tor -# tor_conf (str): Points to your tor conf file -# Default: /usr/local/etc/tor/torrc -# tor_user (str): Tor Daemon user. Default _tor -# - -. /etc/rc.subr - -name="tor" -rcvar=${name}_enable - -load_rc_config ${name} - -: ${tor_enable="NO"} -: ${tor_conf="/usr/local/etc/tor/torrc"} -: ${tor_user="_tor"} -: ${tor_pidfile="/var/run/tor/tor.pid"} -: ${tor_logfile="/var/log/tor"} -: ${tor_datadir="/var/run/tor"} - -required_files=${tor_conf} -required_dirs=${tor_datadir} -command="/usr/local/bin/${name}" -command_args="-f ${tor_conf} --pidfile ${tor_pidfile} --runasdaemon 1 --datadirectory ${tor_datadir} --user ${tor_user}" -extra_commands="log" -log_cmd="${name}_log" - -tor_log() { - cat ${tor_logfile} -} - -run_rc_command "$1" diff --git a/contrib/include.am b/contrib/include.am index 784f5427b8..60783dc439 100644 --- a/contrib/include.am +++ b/contrib/include.am @@ -2,7 +2,6 @@ EXTRA_DIST+= \ contrib/README \ contrib/client-tools/torify \ - contrib/dist/rc.subr \ contrib/dist/tor.service.in \ contrib/operator-tools/tor-exit-notice.html \ contrib/or-tools/exitlist \ diff --git a/contrib/win32build/tor-mingw.nsi.in b/contrib/win32build/tor-mingw.nsi.in index 990f4933fe..fb13a2eb36 100644 --- a/contrib/win32build/tor-mingw.nsi.in +++ b/contrib/win32build/tor-mingw.nsi.in @@ -8,7 +8,7 @@ !include "LogicLib.nsh" !include "FileFunc.nsh" !insertmacro GetParameters -!define VERSION "0.4.3.0-alpha-dev" +!define VERSION "0.4.4.0-alpha-dev" !define INSTALLER "tor-${VERSION}-win32.exe" !define WEBSITE "https://www.torproject.org/" !define LICENSE "LICENSE" diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md index 866b321287..ae892c34a2 100644 --- a/doc/HACKING/HelpfulTools.md +++ b/doc/HACKING/HelpfulTools.md @@ -251,16 +251,16 @@ Now you can run Tor with profiling enabled, and use the pprof utility to look at performance! See the gperftools manual for more info, but basically: 2. Run `env CPUPROFILE=/tmp/profile src/app/tor -f <path/torrc>`. The profile file - is not written to until Tor finishes execuction. + is not written to until Tor finishes execution. -3. Run `pprof src/app/tor /tm/profile` to start the REPL. +3. Run `pprof src/app/tor /tmp/profile` to start the REPL. Generating and analyzing a callgraph ------------------------------------ 0. Build Tor on linux or mac, ideally with -O0 or -fno-inline. -1. Clone 'https://gitweb.torproject.org/user/nickm/calltool.git/' . +1. Clone 'https://git.torproject.org/user/nickm/calltool.git/' . Follow the README in that repository. Note that currently the callgraph generator can't detect calls that pass @@ -396,7 +396,7 @@ source code. Here's how to use it: 6. See the Doxygen manual for more information; this summary just scratches the surface. -Style and best-pratices checking +Style and best-practices checking -------------------------------- We use scripts to check for various problems in the formatting and style diff --git a/doc/HACKING/ReleasingTor.md b/doc/HACKING/ReleasingTor.md index f40e2af573..0f453ca2aa 100644 --- a/doc/HACKING/ReleasingTor.md +++ b/doc/HACKING/ReleasingTor.md @@ -197,7 +197,7 @@ new Tor release: 3. Email the packagers (cc'ing tor-team) that a new tarball is up. The current list of packagers is: - - {weasel,gk,mikeperry} at torproject dot org + - {weasel,sysrqb,mikeperry} at torproject dot org - {blueness} at gentoo dot org - {paul} at invizbox dot io - {vincent} at invizbox dot com diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 4aa09e7f3e..52beb3221c 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -794,6 +794,11 @@ forward slash (/) in the configuration file and on the command line. fetches by the relay (from authority or other relays), because that is considered "client" activity. (Default: 0) +[[RephistTrackTime]] **RephistTrackTime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: + Tells an authority, or other node tracking node reliability and history, + that fine-grained information about nodes can be discarded when it hasn't + changed for a given amount of time. (Default: 24 hours) + [[RunAsDaemon]] **RunAsDaemon** **0**|**1**:: If 1, Tor forks and daemonizes to the background. This option has no effect on Windows; instead you should use the --service command-line option. @@ -998,18 +1003,6 @@ The following options are useful only for clients (that is, if the documentation of the pluggable transport for details of what arguments it supports. -// Out of order because it logically belongs before the CircuitBuildTimeout option -[[LearnCircuitBuildTimeout]] **LearnCircuitBuildTimeout** **0**|**1**:: - If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1) - -[[CircuitBuildTimeout]] **CircuitBuildTimeout** __NUM__:: - - Try for at most NUM seconds when building circuits. If the circuit isn't - open in that time, give up on it. If LearnCircuitBuildTimeout is 1, this - value serves as the initial value to use before a timeout is learned. If - LearnCircuitBuildTimeout is 0, this value is the only value used. - (Default: 60 seconds) - [[CircuitPadding]] **CircuitPadding** **0**|**1**:: If set to 0, Tor will not pad client circuits with additional cover traffic. Only clients may set this option. This option should be offered @@ -1025,22 +1018,6 @@ The following options are useful only for clients (that is, if via the UI to mobile users for use where bandwidth may be expensive. (Default: 0) -[[CircuitsAvailableTimeout]] **CircuitsAvailableTimeout** __NUM__:: - Tor will attempt to keep at least one open, unused circuit available for - this amount of time. This option governs how long idle circuits are kept - open, as well as the amount of time Tor will keep a circuit open to each - of the recently used ports. This way when the Tor client is entirely - idle, it can expire all of its circuits, and then expire its TLS - connections. Note that the actual timeout value is uniformly randomized - from the specified value to twice that amount. (Default: 30 minutes; - Max: 24 hours) - -[[CircuitStreamTimeout]] **CircuitStreamTimeout** __NUM__:: - If non-zero, this option overrides our internal timeout schedule for how - many seconds until we detach a stream from a circuit and try a new circuit. - If your network is particularly slow, you might want to set this to a - number like 60. (Default: 0) - [[ClientAutoIPv6ORPort]] **ClientAutoIPv6ORPort** **0**|**1**:: If this option is set to 1, Tor clients randomly prefer a node's IPv4 or IPv6 ORPort. The random preference is set every time a node is loaded @@ -1166,43 +1143,6 @@ The following options are useful only for clients (that is, if addresses/ports. See SocksPort for an explanation of isolation flags. (Default: 0) -[[DormantCanceledByStartup]] **DormantCanceledByStartup** **0**|**1**:: - By default, Tor starts in active mode if it was active the last time - it was shut down, and in dormant mode if it was dormant. But if - this option is true, Tor treats every startup event as user - activity, and Tor will never start in Dormant mode, even if it has - been unused for a long time on previous runs. (Default: 0) - + - Note: Packagers and application developers should change the value of - this option only with great caution: it has the potential to - create spurious traffic on the network. This option should only - be used if Tor is started by an affirmative user activity (like - clicking on an applcation or running a command), and not if Tor - is launched for some other reason (for example, by a startup - process, or by an application that launches itself on every login.) - -[[DormantClientTimeout]] **DormantClientTimeout** __N__ **minutes**|**hours**|**days**|**weeks**:: - If Tor spends this much time without any client activity, - enter a dormant state where automatic circuits are not built, and - directory information is not fetched. - Does not affect servers or onion services. Must be at least 10 minutes. - (Default: 24 hours) - -[[DormantOnFirstStartup]] **DormantOnFirstStartup** **0**|**1**:: - If true, then the first time Tor starts up with a fresh DataDirectory, - it starts in dormant mode, and takes no actions until the user has made - a request. (This mode is recommended if installing a Tor client for a - user who might not actually use it.) If false, Tor bootstraps the first - time it is started, whether it sees a user request or not. - + - After the first time Tor starts, it begins in dormant mode if it was - dormant before, and not otherwise. (Default: 0) - -[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams** **0**|**1**:: - If true, then any open client stream (even one not reading or writing) - counts as client activity for the purpose of DormantClientTimeout. - If false, then only network activity counts. (Default: 1) - [[DownloadExtraInfo]] **DownloadExtraInfo** **0**|**1**:: If true, Tor downloads and caches "extra-info" documents. These documents contain information about servers other than the information in their @@ -1214,76 +1154,6 @@ The following options are useful only for clients (that is, if the same circuit. Currently, two addresses are "too close" if they lie in the same /16 range. (Default: 1) -[[EntryNodes]] **EntryNodes** __node__,__node__,__...__:: - A list of identity fingerprints and country codes of nodes - to use for the first hop in your normal circuits. - Normal circuits include all - circuits except for direct connections to directory servers. The Bridge - option overrides this option; if you have configured bridges and - UseBridges is 1, the Bridges are used as your entry nodes. + - + - The ExcludeNodes option overrides this option: any node listed in both - EntryNodes and ExcludeNodes is treated as excluded. See - the **ExcludeNodes** option for more information on how to specify nodes. - -[[ExcludeNodes]] **ExcludeNodes** __node__,__node__,__...__:: - A list of identity fingerprints, country codes, and address - patterns of nodes to avoid when building a circuit. Country codes are - 2-letter ISO3166 codes, and must - be wrapped in braces; fingerprints may be preceded by a dollar sign. - (Example: - ExcludeNodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + - + - By default, this option is treated as a preference that Tor is allowed - to override in order to keep working. - For example, if you try to connect to a hidden service, - but you have excluded all of the hidden service's introduction points, - Tor will connect to one of them anyway. If you do not want this - behavior, set the StrictNodes option (documented below). + - + - Note also that if you are a relay, this (and the other node selection - options below) only affects your own circuits that Tor builds for you. - Clients can still build circuits through you to any node. Controllers - can tell Tor to build circuits through any node. + - + - Country codes are case-insensitive. The code "\{??}" refers to nodes whose - country can't be identified. No country code, including \{??}, works if - no GeoIPFile can be loaded. See also the GeoIPExcludeUnknown option below. - -// Out of order because it logically belongs after the ExcludeNodes option -[[ExcludeExitNodes]] **ExcludeExitNodes** __node__,__node__,__...__:: - A list of identity fingerprints, country codes, and address - patterns of nodes to never use when picking an exit node---that is, a - node that delivers traffic for you *outside* the Tor network. Note that any - node listed in ExcludeNodes is automatically considered to be part of this - list too. See - the **ExcludeNodes** option for more information on how to specify - nodes. See also the caveats on the "ExitNodes" option below. - -[[ExitNodes]] **ExitNodes** __node__,__node__,__...__:: - A list of identity fingerprints, country codes, and address - patterns of nodes to use as exit node---that is, a - node that delivers traffic for you *outside* the Tor network. See - the **ExcludeNodes** option for more information on how to specify nodes. + - + - Note that if you list too few nodes here, or if you exclude too many exit - nodes with ExcludeExitNodes, you can degrade functionality. For example, - if none of the exits you list allows traffic on port 80 or 443, you won't - be able to browse the web. + - + - Note also that not every circuit is used to deliver traffic *outside* of - the Tor network. It is normal to see non-exit circuits (such as those - used to connect to hidden services, those that do directory fetches, - those used for relay reachability self-tests, and so on) that end - at a non-exit node. To - keep a node from being used entirely, see ExcludeNodes and StrictNodes. + - + - The ExcludeNodes option overrides this option: any node listed in both - ExitNodes and ExcludeNodes is treated as excluded. + - + - The .exit address notation, if enabled via MapAddress, overrides - this option. - [[FascistFirewall]] **FascistFirewall** **0**|**1**:: If 1, Tor will only create outgoing connections to ORs running on ports that your firewall allows (defaults to 80 and 443; see **FirewallPorts**). @@ -1297,14 +1167,6 @@ The following options are useful only for clients (that is, if **FascistFirewall** is set. This option is deprecated; use ReachableAddresses instead. (Default: 80, 443) -[[GeoIPExcludeUnknown]] **GeoIPExcludeUnknown** **0**|**1**|**auto**:: - If this option is set to 'auto', then whenever any country code is set in - ExcludeNodes or ExcludeExitNodes, all nodes with unknown country (\{??} and - possibly \{A1}) are treated as excluded as well. If this option is set to - '1', then all unknown countries are treated as excluded in ExcludeNodes - and ExcludeExitNodes. This option has no effect when a GeoIP file isn't - configured or can't be found. (Default: auto) - [[HidServAuth]] **HidServAuth** __onion-address__ __auth-cookie__ [__service-name__]:: Client authorization for a v2 hidden service. Valid onion addresses contain 16 characters in a-z2-7 plus ".onion", and valid auth cookies contain 22 @@ -1315,116 +1177,6 @@ The following options are useful only for clients (that is, if services can be configured to require authorization using the **HiddenServiceAuthorizeClient** option. -[[HSLayer2Nodes]] **HSLayer2Nodes** __node__,__node__,__...__:: - A list of identity fingerprints, nicknames, country codes, and - address patterns of nodes that are allowed to be used as the - second hop in all client or service-side Onion Service circuits. - This option mitigates attacks where the adversary runs middle nodes - and induces your client or service to create many circuits, in order - to discover your primary guard node. - (Default: Any node in the network may be used in the second hop.) - + - (Example: - HSLayer2Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + - + - When this is set, the resulting hidden service paths will - look like: - + - C - G - L2 - M - Rend + - C - G - L2 - M - HSDir + - C - G - L2 - M - Intro + - S - G - L2 - M - Rend + - S - G - L2 - M - HSDir + - S - G - L2 - M - Intro + - + - where C is this client, S is the service, G is the Guard node, - L2 is a node from this option, and M is a random middle node. - Rend, HSDir, and Intro point selection is not affected by this - option. - + - This option may be combined with HSLayer3Nodes to create - paths of the form: - + - C - G - L2 - L3 - Rend + - C - G - L2 - L3 - M - HSDir + - C - G - L2 - L3 - M - Intro + - S - G - L2 - L3 - M - Rend + - S - G - L2 - L3 - HSDir + - S - G - L2 - L3 - Intro + - + - ExcludeNodes have higher priority than HSLayer2Nodes, - which means that nodes specified in ExcludeNodes will not be - picked. - + - When either this option or HSLayer3Nodes are set, the /16 subnet - and node family restrictions are removed for hidden service - circuits. Additionally, we allow the guard node to be present - as the Rend, HSDir, and IP node, and as the hop before it. This - is done to prevent the adversary from inferring information - about our guard, layer2, and layer3 node choices at later points - in the path. - + - This option is meant to be managed by a Tor controller such as - https://github.com/mikeperry-tor/vanguards that selects and - updates this set of nodes for you. Hence it does not do load - balancing if fewer than 20 nodes are selected, and if no nodes in - HSLayer2Nodes are currently available for use, Tor will not work. - Please use extreme care if you are setting this option manually. - -[[HSLayer3Nodes]] **HSLayer3Nodes** __node__,__node__,__...__:: - A list of identity fingerprints, nicknames, country codes, and - address patterns of nodes that are allowed to be used as the - third hop in all client and service-side Onion Service circuits. - This option mitigates attacks where the adversary runs middle nodes - and induces your client or service to create many circuits, in order - to discover your primary or Layer2 guard nodes. - (Default: Any node in the network may be used in the third hop.) - + - (Example: - HSLayer3Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + - + - When this is set by itself, the resulting hidden service paths - will look like: + - C - G - M - L3 - Rend + - C - G - M - L3 - M - HSDir + - C - G - M - L3 - M - Intro + - S - G - M - L3 - M - Rend + - S - G - M - L3 - HSDir + - S - G - M - L3 - Intro + - where C is this client, S is the service, G is the Guard node, - L2 is a node from this option, and M is a random middle node. - Rend, HSDir, and Intro point selection is not affected by this - option. - + - While it is possible to use this option by itself, it should be - combined with HSLayer2Nodes to create paths of the form: - + - C - G - L2 - L3 - Rend + - C - G - L2 - L3 - M - HSDir + - C - G - L2 - L3 - M - Intro + - S - G - L2 - L3 - M - Rend + - S - G - L2 - L3 - HSDir + - S - G - L2 - L3 - Intro + - + - ExcludeNodes have higher priority than HSLayer3Nodes, - which means that nodes specified in ExcludeNodes will not be - picked. - + - When either this option or HSLayer2Nodes are set, the /16 subnet - and node family restrictions are removed for hidden service - circuits. Additionally, we allow the guard node to be present - as the Rend, HSDir, and IP node, and as the hop before it. This - is done to prevent the adversary from inferring information - about our guard, layer2, and layer3 node choices at later points - in the path. - + - This option is meant to be managed by a Tor controller such as - https://github.com/mikeperry-tor/vanguards that selects and - updates this set of nodes for you. Hence it does not do load - balancing if fewer than 20 nodes are selected, and if no nodes in - HSLayer3Nodes are currently available for use, Tor will not work. - Please use extreme care if you are setting this option manually. - [[HTTPTunnelPort]] **HTTPTunnelPort** ['address'**:**]{empty}__port__|**auto** [_isolation flags_]:: Open this port to listen for proxy connections using the "HTTP CONNECT" protocol instead of SOCKS. Set this to @@ -1510,26 +1262,6 @@ The following options are useful only for clients (that is, if client streams. A circuit is pending if we have begun constructing it, but it has not yet been completely constructed. (Default: 32) -[[MiddleNodes]] **MiddleNodes** __node__,__node__,__...__:: - A list of identity fingerprints and country codes of nodes - to use for "middle" hops in your normal circuits. - Normal circuits include all circuits except for direct connections - to directory servers. Middle hops are all hops other than exit and entry. + -+ - This is an **experimental** feature that is meant to be used by researchers - and developers to test new features in the Tor network safely. Using it - without care will strongly influence your anonymity. This feature might get - removed in the future. -+ - The HSLayer2Node and HSLayer3Node options override this option for onion - service circuits, if they are set. The vanguards addon will read this - option, and if set, it will set HSLayer2Nodes and HSLayer3Nodes to nodes - from this set. -+ - The ExcludeNodes option overrides this option: any node listed in both - MiddleNodes and ExcludeNodes is treated as excluded. See - the **ExcludeNodes** option for more information on how to specify nodes. - [[NATDPort]] **NATDPort** ['address'**:**]{empty}__port__|**auto** [_isolation flags_]:: Open this port to listen for connections from old versions of ipfw (as included in old versions of FreeBSD, etc) using the NATD protocol. @@ -1546,16 +1278,6 @@ The following options are useful only for clients (that is, if Every NUM seconds consider whether to build a new circuit. (Default: 30 seconds) -[[NodeFamily]] **NodeFamily** __node__,__node__,__...__:: - The Tor servers, defined by their identity fingerprints, - constitute a "family" of similar or co-administered servers, so never use - any two of them in the same circuit. Defining a NodeFamily is only needed - when a server doesn't list the family itself (with MyFamily). This option - can be used multiple times; each instance defines a separate family. In - addition to nodes, you can also list IP address and ranges and country - codes in {curly braces}. See the **ExcludeNodes** option for more - information on how to specify nodes. - [[OptimisticData]] **OptimisticData** **0**|**1**|**auto**:: When this option is set, and Tor is using an exit node that supports the feature, it will try optimistically to send data to the exit node @@ -1871,24 +1593,6 @@ The following options are useful only for clients (that is, if line is used, and all earlier flags are ignored. No error is issued for conflicting flags. -[[SocksTimeout]] **SocksTimeout** __NUM__:: - Let a socks connection wait NUM seconds handshaking, and NUM seconds - unattached waiting for an appropriate circuit, before we fail it. (Default: - 2 minutes) - -[[StrictNodes]] **StrictNodes** **0**|**1**:: - If StrictNodes is set to 1, Tor will treat solely the ExcludeNodes option - as a requirement to follow for all the circuits you generate, even if - doing so will break functionality for you (StrictNodes does not apply to - ExcludeExitNodes, ExitNodes, MiddleNodes, or MapAddress). If StrictNodes - is set to 0, Tor will still try to avoid nodes in the ExcludeNodes list, - but it will err on the side of avoiding unexpected errors. - Specifically, StrictNodes 0 tells Tor that it is okay to use an excluded - node when it is *necessary* to perform relay reachability self-tests, - connect to a hidden service, provide a hidden service to a client, - fulfill a .exit request, upload directory information, or download - directory information. (Default: 0) - [[TokenBucketRefillInterval]] **TokenBucketRefillInterval** __NUM__ [**msec**|**second**]:: Set the refill delay interval of Tor's token bucket to NUM milliseconds. NUM must be between 1 and 1000, inclusive. When Tor is out of bandwidth, @@ -2033,12 +1737,386 @@ The following options are useful only for clients (that is, if used IP. For local use, no change to the default VirtualAddrNetwork setting is needed. +== CIRCUIT TIMEOUT OPTIONS + +// These options are in alphabetical order, with exceptions as noted. +// Please keep them that way! + +The following options are useful for configuring timeouts related +to building Tor circuits and using them: + +[[CircuitsAvailableTimeout]] **CircuitsAvailableTimeout** __NUM__:: + Tor will attempt to keep at least one open, unused circuit available for + this amount of time. This option governs how long idle circuits are kept + open, as well as the amount of time Tor will keep a circuit open to each + of the recently used ports. This way when the Tor client is entirely + idle, it can expire all of its circuits, and then expire its TLS + connections. Note that the actual timeout value is uniformly randomized + from the specified value to twice that amount. (Default: 30 minutes; + Max: 24 hours) + +// Out of order because it logically belongs before the CircuitBuildTimeout option +[[LearnCircuitBuildTimeout]] **LearnCircuitBuildTimeout** **0**|**1**:: + If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1) + +[[CircuitBuildTimeout]] **CircuitBuildTimeout** __NUM__:: + Try for at most NUM seconds when building circuits. If the circuit isn't + open in that time, give up on it. If LearnCircuitBuildTimeout is 1, this + value serves as the initial value to use before a timeout is learned. If + LearnCircuitBuildTimeout is 0, this value is the only value used. + (Default: 60 seconds) + +[[CircuitStreamTimeout]] **CircuitStreamTimeout** __NUM__:: + If non-zero, this option overrides our internal timeout schedule for how + many seconds until we detach a stream from a circuit and try a new circuit. + If your network is particularly slow, you might want to set this to a + number like 60. (Default: 0) + +[[SocksTimeout]] **SocksTimeout** __NUM__:: + Let a socks connection wait NUM seconds handshaking, and NUM seconds + unattached waiting for an appropriate circuit, before we fail it. (Default: + 2 minutes) + +== DORMANT MODE OPTIONS + +// These options are in alphabetical order, with exceptions as noted. +// Please keep them that way! + +Tor can enter dormant mode to conserve power and network bandwidth. +The following options control when Tor enters and leaves dormant mode: + +[[DormantCanceledByStartup]] **DormantCanceledByStartup** **0**|**1**:: + By default, Tor starts in active mode if it was active the last time + it was shut down, and in dormant mode if it was dormant. But if + this option is true, Tor treats every startup event as user + activity, and Tor will never start in Dormant mode, even if it has + been unused for a long time on previous runs. (Default: 0) + + + Note: Packagers and application developers should change the value of + this option only with great caution: it has the potential to + create spurious traffic on the network. This option should only + be used if Tor is started by an affirmative user activity (like + clicking on an applcation or running a command), and not if Tor + is launched for some other reason (for example, by a startup + process, or by an application that launches itself on every login.) + +[[DormantClientTimeout]] **DormantClientTimeout** __N__ **minutes**|**hours**|**days**|**weeks**:: + If Tor spends this much time without any client activity, + enter a dormant state where automatic circuits are not built, and + directory information is not fetched. + Does not affect servers or onion services. Must be at least 10 minutes. + (Default: 24 hours) + +[[DormantOnFirstStartup]] **DormantOnFirstStartup** **0**|**1**:: + If true, then the first time Tor starts up with a fresh DataDirectory, + it starts in dormant mode, and takes no actions until the user has made + a request. (This mode is recommended if installing a Tor client for a + user who might not actually use it.) If false, Tor bootstraps the first + time it is started, whether it sees a user request or not. + + + After the first time Tor starts, it begins in dormant mode if it was + dormant before, and not otherwise. (Default: 0) + +[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams** **0**|**1**:: + If true, then any open client stream (even one not reading or writing) + counts as client activity for the purpose of DormantClientTimeout. + If false, then only network activity counts. (Default: 1) + +== NODE SELECTION OPTIONS + +// These options are in alphabetical order, with exceptions as noted. +// Please keep them that way! + +The following options restrict the nodes that a tor client +(or onion service) can use while building a circuit. +These options can weaken your anonymity by making your client behavior +different from other Tor clients: + +[[EntryNodes]] **EntryNodes** __node__,__node__,__...__:: + A list of identity fingerprints and country codes of nodes + to use for the first hop in your normal circuits. + Normal circuits include all + circuits except for direct connections to directory servers. The Bridge + option overrides this option; if you have configured bridges and + UseBridges is 1, the Bridges are used as your entry nodes. + + + + The ExcludeNodes option overrides this option: any node listed in both + EntryNodes and ExcludeNodes is treated as excluded. See + the **ExcludeNodes** option for more information on how to specify nodes. + +[[ExcludeNodes]] **ExcludeNodes** __node__,__node__,__...__:: + A list of identity fingerprints, country codes, and address + patterns of nodes to avoid when building a circuit. Country codes are + 2-letter ISO3166 codes, and must + be wrapped in braces; fingerprints may be preceded by a dollar sign. + (Example: + ExcludeNodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + + + + By default, this option is treated as a preference that Tor is allowed + to override in order to keep working. + For example, if you try to connect to a hidden service, + but you have excluded all of the hidden service's introduction points, + Tor will connect to one of them anyway. If you do not want this + behavior, set the StrictNodes option (documented below). + + + + Note also that if you are a relay, this (and the other node selection + options below) only affects your own circuits that Tor builds for you. + Clients can still build circuits through you to any node. Controllers + can tell Tor to build circuits through any node. + + + + Country codes are case-insensitive. The code "\{??}" refers to nodes whose + country can't be identified. No country code, including \{??}, works if + no GeoIPFile can be loaded. See also the GeoIPExcludeUnknown option below. + +// Out of order because it logically belongs after the ExcludeNodes option +[[ExcludeExitNodes]] **ExcludeExitNodes** __node__,__node__,__...__:: + A list of identity fingerprints, country codes, and address + patterns of nodes to never use when picking an exit node---that is, a + node that delivers traffic for you *outside* the Tor network. Note that any + node listed in ExcludeNodes is automatically considered to be part of this + list too. See + the **ExcludeNodes** option for more information on how to specify + nodes. See also the caveats on the "ExitNodes" option below. + +[[ExitNodes]] **ExitNodes** __node__,__node__,__...__:: + A list of identity fingerprints, country codes, and address + patterns of nodes to use as exit node---that is, a + node that delivers traffic for you *outside* the Tor network. See + the **ExcludeNodes** option for more information on how to specify nodes. + + + + Note that if you list too few nodes here, or if you exclude too many exit + nodes with ExcludeExitNodes, you can degrade functionality. For example, + if none of the exits you list allows traffic on port 80 or 443, you won't + be able to browse the web. + + + + Note also that not every circuit is used to deliver traffic *outside* of + the Tor network. It is normal to see non-exit circuits (such as those + used to connect to hidden services, those that do directory fetches, + those used for relay reachability self-tests, and so on) that end + at a non-exit node. To + keep a node from being used entirely, see ExcludeNodes and StrictNodes. + + + + The ExcludeNodes option overrides this option: any node listed in both + ExitNodes and ExcludeNodes is treated as excluded. + + + + The .exit address notation, if enabled via MapAddress, overrides + this option. + +[[GeoIPExcludeUnknown]] **GeoIPExcludeUnknown** **0**|**1**|**auto**:: + If this option is set to 'auto', then whenever any country code is set in + ExcludeNodes or ExcludeExitNodes, all nodes with unknown country (\{??} and + possibly \{A1}) are treated as excluded as well. If this option is set to + '1', then all unknown countries are treated as excluded in ExcludeNodes + and ExcludeExitNodes. This option has no effect when a GeoIP file isn't + configured or can't be found. (Default: auto) + +[[HSLayer2Nodes]] **HSLayer2Nodes** __node__,__node__,__...__:: + A list of identity fingerprints, nicknames, country codes, and + address patterns of nodes that are allowed to be used as the + second hop in all client or service-side Onion Service circuits. + This option mitigates attacks where the adversary runs middle nodes + and induces your client or service to create many circuits, in order + to discover your primary guard node. + (Default: Any node in the network may be used in the second hop.) + + + (Example: + HSLayer2Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + + + + When this is set, the resulting hidden service paths will + look like: + + + C - G - L2 - M - Rend + + C - G - L2 - M - HSDir + + C - G - L2 - M - Intro + + S - G - L2 - M - Rend + + S - G - L2 - M - HSDir + + S - G - L2 - M - Intro + + + + where C is this client, S is the service, G is the Guard node, + L2 is a node from this option, and M is a random middle node. + Rend, HSDir, and Intro point selection is not affected by this + option. + + + This option may be combined with HSLayer3Nodes to create + paths of the form: + + + C - G - L2 - L3 - Rend + + C - G - L2 - L3 - M - HSDir + + C - G - L2 - L3 - M - Intro + + S - G - L2 - L3 - M - Rend + + S - G - L2 - L3 - HSDir + + S - G - L2 - L3 - Intro + + + + ExcludeNodes have higher priority than HSLayer2Nodes, + which means that nodes specified in ExcludeNodes will not be + picked. + + + When either this option or HSLayer3Nodes are set, the /16 subnet + and node family restrictions are removed for hidden service + circuits. Additionally, we allow the guard node to be present + as the Rend, HSDir, and IP node, and as the hop before it. This + is done to prevent the adversary from inferring information + about our guard, layer2, and layer3 node choices at later points + in the path. + + + This option is meant to be managed by a Tor controller such as + https://github.com/mikeperry-tor/vanguards that selects and + updates this set of nodes for you. Hence it does not do load + balancing if fewer than 20 nodes are selected, and if no nodes in + HSLayer2Nodes are currently available for use, Tor will not work. + Please use extreme care if you are setting this option manually. + +[[HSLayer3Nodes]] **HSLayer3Nodes** __node__,__node__,__...__:: + A list of identity fingerprints, nicknames, country codes, and + address patterns of nodes that are allowed to be used as the + third hop in all client and service-side Onion Service circuits. + This option mitigates attacks where the adversary runs middle nodes + and induces your client or service to create many circuits, in order + to discover your primary or Layer2 guard nodes. + (Default: Any node in the network may be used in the third hop.) + + + (Example: + HSLayer3Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) + + + + When this is set by itself, the resulting hidden service paths + will look like: + + C - G - M - L3 - Rend + + C - G - M - L3 - M - HSDir + + C - G - M - L3 - M - Intro + + S - G - M - L3 - M - Rend + + S - G - M - L3 - HSDir + + S - G - M - L3 - Intro + + where C is this client, S is the service, G is the Guard node, + L2 is a node from this option, and M is a random middle node. + Rend, HSDir, and Intro point selection is not affected by this + option. + + + While it is possible to use this option by itself, it should be + combined with HSLayer2Nodes to create paths of the form: + + + C - G - L2 - L3 - Rend + + C - G - L2 - L3 - M - HSDir + + C - G - L2 - L3 - M - Intro + + S - G - L2 - L3 - M - Rend + + S - G - L2 - L3 - HSDir + + S - G - L2 - L3 - Intro + + + + ExcludeNodes have higher priority than HSLayer3Nodes, + which means that nodes specified in ExcludeNodes will not be + picked. + + + When either this option or HSLayer2Nodes are set, the /16 subnet + and node family restrictions are removed for hidden service + circuits. Additionally, we allow the guard node to be present + as the Rend, HSDir, and IP node, and as the hop before it. This + is done to prevent the adversary from inferring information + about our guard, layer2, and layer3 node choices at later points + in the path. + + + This option is meant to be managed by a Tor controller such as + https://github.com/mikeperry-tor/vanguards that selects and + updates this set of nodes for you. Hence it does not do load + balancing if fewer than 20 nodes are selected, and if no nodes in + HSLayer3Nodes are currently available for use, Tor will not work. + Please use extreme care if you are setting this option manually. + +[[MiddleNodes]] **MiddleNodes** __node__,__node__,__...__:: + A list of identity fingerprints and country codes of nodes + to use for "middle" hops in your normal circuits. + Normal circuits include all circuits except for direct connections + to directory servers. Middle hops are all hops other than exit and entry. + ++ + This is an **experimental** feature that is meant to be used by researchers + and developers to test new features in the Tor network safely. Using it + without care will strongly influence your anonymity. This feature might get + removed in the future. ++ + The HSLayer2Node and HSLayer3Node options override this option for onion + service circuits, if they are set. The vanguards addon will read this + option, and if set, it will set HSLayer2Nodes and HSLayer3Nodes to nodes + from this set. ++ + The ExcludeNodes option overrides this option: any node listed in both + MiddleNodes and ExcludeNodes is treated as excluded. See + the **ExcludeNodes** option for more information on how to specify nodes. + +[[NodeFamily]] **NodeFamily** __node__,__node__,__...__:: + The Tor servers, defined by their identity fingerprints, + constitute a "family" of similar or co-administered servers, so never use + any two of them in the same circuit. Defining a NodeFamily is only needed + when a server doesn't list the family itself (with MyFamily). This option + can be used multiple times; each instance defines a separate family. In + addition to nodes, you can also list IP address and ranges and country + codes in {curly braces}. See the **ExcludeNodes** option for more + information on how to specify nodes. + +[[StrictNodes]] **StrictNodes** **0**|**1**:: + If StrictNodes is set to 1, Tor will treat solely the ExcludeNodes option + as a requirement to follow for all the circuits you generate, even if + doing so will break functionality for you (StrictNodes does not apply to + ExcludeExitNodes, ExitNodes, MiddleNodes, or MapAddress). If StrictNodes + is set to 0, Tor will still try to avoid nodes in the ExcludeNodes list, + but it will err on the side of avoiding unexpected errors. + Specifically, StrictNodes 0 tells Tor that it is okay to use an excluded + node when it is *necessary* to perform relay reachability self-tests, + connect to a hidden service, provide a hidden service to a client, + fulfill a .exit request, upload directory information, or download + directory information. (Default: 0) == SERVER OPTIONS +// These options are in alphabetical order, with exceptions as noted. +// Please keep them that way! + The following options are useful only for servers (that is, if ORPort is non-zero): +[[AccountingMax]] **AccountingMax** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: + Limits the max number of bytes sent and received within a set time period + using a given calculation rule (see: AccountingStart, AccountingRule). + Useful if you need to stay under a specific bandwidth. By default, the + number used for calculation is the max of either the bytes sent or + received. For example, with AccountingMax set to 1 TByte, a server + could send 900 GBytes and receive 800 GBytes and continue running. + It will only hibernate once one of the two reaches 1 TByte. This can + be changed to use the sum of the both bytes received and sent by setting + the AccountingRule option to "sum" (total bandwidth in/out). When the + number of bytes remaining gets low, Tor will stop accepting new connections + and circuits. When the number of bytes is exhausted, Tor will hibernate + until some time in the next accounting period. To prevent all servers + from waking at the same time, Tor will also wait until a random point + in each period before waking up. If you have bandwidth cost issues, + enabling hibernation is preferable to setting a low bandwidth, since + it provides users with a collection of fast servers that are up some + of the time, which is more useful than a set of slow servers that are + always "available". + + + + Note that (as also described in the Bandwidth section) Tor uses + powers of two, not powers of ten: 1 GByte is 1024*1024*1024, not + one billion. Be careful: some internet service providers might count + GBytes differently. + +[[AccountingRule]] **AccountingRule** **sum**|**max**|**in**|**out**:: + How we determine when our AccountingMax has been reached (when we + should hibernate) during a time interval. Set to "max" to calculate + using the higher of either the sent or received bytes (this is the + default functionality). Set to "sum" to calculate using the sent + plus received bytes. Set to "in" to calculate using only the + received bytes. Set to "out" to calculate using only the sent bytes. + (Default: max) + +[[AccountingStart]] **AccountingStart** **day**|**week**|**month** [__day__] __HH:MM__:: + Specify how long accounting periods last. If **month** is given, + each accounting period runs from the time __HH:MM__ on the __dayth__ day of one + month to the same day and time of the next. The relay will go at full speed, + use all the quota you specify, then hibernate for the rest of the period. (The + day must be between 1 and 28.) If **week** is given, each accounting period + runs from the time __HH:MM__ of the __dayth__ day of one week to the same day + and time of the next week, with Monday as day 1 and Sunday as day 7. If **day** + is given, each accounting period runs from the time __HH:MM__ each day to the + same time on the next day. All times are local, and given in 24-hour time. + (Default: "month 1 0:00") + [[Address]] **Address** __address__:: The IPv4 address of this server, or a fully qualified domain name of this server that resolves to an IPv4 address. You can leave this @@ -2064,6 +2142,15 @@ is non-zero): Note: make sure that no MyFamily lines are present in your torrc when relay is configured in bridge mode. +//Out of order because it logically belongs after BridgeRelay. +[[BridgeRecordUsageByCountry]] **BridgeRecordUsageByCountry** **0**|**1**:: + When this option is enabled and BridgeRelay is also enabled, and we have + GeoIP data, Tor keeps a per-country count of how many client + addresses have contacted it so that it can help the bridge authority guess + which countries have blocked access to it. If ExtraInfoStatistics is + enabled, it will be published as part of extra-info document. (Default: 1) + +//Out of order because it logically belongs after BridgeRelay. [[BridgeDistribution]] **BridgeDistribution** __string__:: If set along with BridgeRelay, Tor will include a new line in its bridge descriptor which indicates to the BridgeDB service how it @@ -2084,21 +2171,11 @@ is non-zero): relay or bridge. (Really, everybody running a relay or bridge should set it.) - -[[ExitRelay]] **ExitRelay** **0**|**1**|**auto**:: - Tells Tor whether to run as an exit relay. If Tor is running as a - non-bridge server, and ExitRelay is set to 1, then Tor allows traffic to - exit according to the ExitPolicy option, the ReducedExitPolicy option, - or the default ExitPolicy (if no other exit policy option is specified). + - + - If ExitRelay is set to 0, no traffic is allowed to exit, and the - ExitPolicy, ReducedExitPolicy, and IPv6Exit options are ignored. + - + - If ExitRelay is set to "auto", then Tor checks the ExitPolicy, - ReducedExitPolicy, and IPv6Exit options. If at least one of these options - is set, Tor behaves as if ExitRelay were set to 1. If none of these exit - policy options are set, Tor behaves as if ExitRelay were set to 0. - (Default: auto) +[[DisableOOSCheck]] **DisableOOSCheck** **0**|**1**:: + This option disables the code that closes connections when Tor notices + that it is running low on sockets. Right now, it is on by default, + since the existing out-of-sockets mechanism tends to kill OR connections + more than it should. (Default: 1) [[ExitPolicy]] **ExitPolicy** __policy__,__policy__,__...__:: Set an exit policy for this server. Each policy is of the form @@ -2181,12 +2258,6 @@ is non-zero): Since the default exit policy uses accept/reject *, it applies to both IPv4 and IPv6 addresses. -[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**:: - Reject all private (local) networks, along with the relay's advertised - public IPv4 and IPv6 addresses, at the beginning of your exit policy. - See above entry on ExitPolicy. - (Default: 1) - [[ExitPolicyRejectLocalInterfaces]] **ExitPolicyRejectLocalInterfaces** **0**|**1**:: Reject all IPv4 and IPv6 addresses that the relay knows about, at the beginning of your exit policy. This includes any OutboundBindAddress, the @@ -2199,104 +2270,81 @@ is non-zero): to disclose. (Default: 0) -[[ReducedExitPolicy]] **ReducedExitPolicy** **0**|**1**:: - If set, use a reduced exit policy rather than the default one. + +[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**:: + Reject all private (local) networks, along with the relay's advertised + public IPv4 and IPv6 addresses, at the beginning of your exit policy. + See above entry on ExitPolicy. + (Default: 1) + +[[ExitRelay]] **ExitRelay** **0**|**1**|**auto**:: + Tells Tor whether to run as an exit relay. If Tor is running as a + non-bridge server, and ExitRelay is set to 1, then Tor allows traffic to + exit according to the ExitPolicy option, the ReducedExitPolicy option, + or the default ExitPolicy (if no other exit policy option is specified). + + - The reduced exit policy is an alternative to the default exit policy. It - allows as many Internet services as possible while still blocking the - majority of TCP ports. Currently, the policy allows approximately 65 ports. - This reduces the odds that your node will be used for peer-to-peer - applications. + + If ExitRelay is set to 0, no traffic is allowed to exit, and the + ExitPolicy, ReducedExitPolicy, and IPv6Exit options are ignored. + + - The reduced exit policy is: - - accept *:20-21 - accept *:22 - accept *:23 - accept *:43 - accept *:53 - accept *:79 - accept *:80-81 - accept *:88 - accept *:110 - accept *:143 - accept *:194 - accept *:220 - accept *:389 - accept *:443 - accept *:464 - accept *:465 - accept *:531 - accept *:543-544 - accept *:554 - accept *:563 - accept *:587 - accept *:636 - accept *:706 - accept *:749 - accept *:873 - accept *:902-904 - accept *:981 - accept *:989-990 - accept *:991 - accept *:992 - accept *:993 - accept *:994 - accept *:995 - accept *:1194 - accept *:1220 - accept *:1293 - accept *:1500 - accept *:1533 - accept *:1677 - accept *:1723 - accept *:1755 - accept *:1863 - accept *:2082 - accept *:2083 - accept *:2086-2087 - accept *:2095-2096 - accept *:2102-2104 - accept *:3128 - accept *:3389 - accept *:3690 - accept *:4321 - accept *:4643 - accept *:5050 - accept *:5190 - accept *:5222-5223 - accept *:5228 - accept *:5900 - accept *:6660-6669 - accept *:6679 - accept *:6697 - accept *:8000 - accept *:8008 - accept *:8074 - accept *:8080 - accept *:8082 - accept *:8087-8088 - accept *:8232-8233 - accept *:8332-8333 - accept *:8443 - accept *:8888 - accept *:9418 - accept *:9999 - accept *:10000 - accept *:11371 - accept *:19294 - accept *:19638 - accept *:50002 - accept *:64738 - reject *:* + If ExitRelay is set to "auto", then Tor checks the ExitPolicy, + ReducedExitPolicy, and IPv6Exit options. If at least one of these options + is set, Tor behaves as if ExitRelay were set to 1. If none of these exit + policy options are set, Tor behaves as if ExitRelay were set to 0. + (Default: auto) +[[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**:: + When this option is enabled, Tor will connect to relays on localhost, + RFC1918 addresses, and so on. In particular, Tor will make direct OR + connections, and Tor routers allow EXTEND requests, to these private + addresses. (Tor will always allow connections to bridges, proxies, and + pluggable transports configured on private addresses.) Enabling this + option can create security issues; you should probably leave it off. (Default: 0) +[[GeoIPFile]] **GeoIPFile** __filename__:: + A filename containing IPv4 GeoIP data, for use with by-country statistics. + +[[GeoIPv6File]] **GeoIPv6File** __filename__:: + A filename containing IPv6 GeoIP data, for use with by-country statistics. + +[[HeartbeatPeriod]] **HeartbeatPeriod** __N__ **minutes**|**hours**|**days**|**weeks**:: + Log a heartbeat message every **HeartbeatPeriod** seconds. This is + a log level __notice__ message, designed to let you know your Tor + server is still alive and doing useful things. Settings this + to 0 will disable the heartbeat. Otherwise, it must be at least 30 + minutes. (Default: 6 hours) + [[IPv6Exit]] **IPv6Exit** **0**|**1**:: If set, and we are an exit node, allow clients to use us for IPv6 traffic. When this option is set and ExitRelay is auto, we act as if ExitRelay is 1. (Default: 0) +[[KeyDirectory]] **KeyDirectory** __DIR__:: + Store secret keys in DIR. Can not be changed while tor is + running. + (Default: the "keys" subdirectory of DataDirectory.) + +[[KeyDirectoryGroupReadable]] **KeyDirectoryGroupReadable** **0**|**1**|**auto**:: + If this option is set to 0, don't allow the filesystem group to read the + KeyDirectory. If the option is set to 1, make the KeyDirectory readable + by the default GID. If the option is "auto", then we use the + setting for DataDirectoryGroupReadable when the KeyDirectory is the + same as the DataDirectory, and 0 otherwise. (Default: auto) + +[[MainloopStats]] **MainloopStats** **0**|**1**:: + Log main loop statistics every **HeartbeatPeriod** seconds. This is a log + level __notice__ message designed to help developers instrumenting Tor's + main event loop. (Default: 0) + +[[MaxMemInQueues]] **MaxMemInQueues** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**:: + This option configures a threshold above which Tor will assume that it + needs to stop queueing or buffering data because it's about to run out of + memory. If it hits this threshold, it will begin killing circuits until + it has recovered at least 10% of this memory. Do not set this option too + low, or your relay may be unreliable under load. This option only + affects some queues, so the actual process size will be larger than + this. If this option is set to 0, Tor will try to pick a reasonable + default based on your system's physical memory. (Default: 0) + [[MaxOnionQueueDelay]] **MaxOnionQueueDelay** __NUM__ [**msec**|**second**]:: If we have more onionskins queued for processing than we can process in this amount of time, reject new ones. (Default: 1750 msec) @@ -2334,6 +2382,12 @@ is non-zero): parallelizable operations. If this is set to 0, Tor will try to detect how many CPUs you have, defaulting to 1 if it can't tell. (Default: 0) +[[OfflineMasterKey]] **OfflineMasterKey** **0**|**1**:: + If non-zero, the Tor relay will never generate or load its master secret + key. Instead, you'll have to use "tor --keygen" to manage the permanent + ed25519 master identity key, as well as the corresponding temporary + signing keys and certificates. (Default: 0) + [[ORPort]] **ORPort** ['address'**:**]{empty}__PORT__|**auto** [_flags_]:: Advertise this port to listen for connections from Tor clients and servers. This option is required to be a Tor server. @@ -2378,74 +2432,98 @@ is non-zero): "publish as if you're a relay", and "bridge", meaning "publish as if you're a bridge". -[[ShutdownWaitLength]] **ShutdownWaitLength** __NUM__:: - When we get a SIGINT and we're a server, we begin shutting down: - we close listeners and start refusing new circuits. After **NUM** - seconds, we exit. If we get a second SIGINT, we exit immediately. - (Default: 30 seconds) - -[[SSLKeyLifetime]] **SSLKeyLifetime** __N__ **minutes**|**hours**|**days**|**weeks**:: - When creating a link certificate for our outermost SSL handshake, - set its lifetime to this amount of time. If set to 0, Tor will choose - some reasonable random defaults. (Default: 0) - -[[HeartbeatPeriod]] **HeartbeatPeriod** __N__ **minutes**|**hours**|**days**|**weeks**:: - Log a heartbeat message every **HeartbeatPeriod** seconds. This is - a log level __notice__ message, designed to let you know your Tor - server is still alive and doing useful things. Settings this - to 0 will disable the heartbeat. Otherwise, it must be at least 30 - minutes. (Default: 6 hours) - -[[MainloopStats]] **MainloopStats** **0**|**1**:: - Log main loop statistics every **HeartbeatPeriod** seconds. This is a log - level __notice__ message designed to help developers instrumenting Tor's - main event loop. (Default: 0) - -[[AccountingMax]] **AccountingMax** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: - Limits the max number of bytes sent and received within a set time period - using a given calculation rule (see: AccountingStart, AccountingRule). - Useful if you need to stay under a specific bandwidth. By default, the - number used for calculation is the max of either the bytes sent or - received. For example, with AccountingMax set to 1 TByte, a server - could send 900 GBytes and receive 800 GBytes and continue running. - It will only hibernate once one of the two reaches 1 TByte. This can - be changed to use the sum of the both bytes received and sent by setting - the AccountingRule option to "sum" (total bandwidth in/out). When the - number of bytes remaining gets low, Tor will stop accepting new connections - and circuits. When the number of bytes is exhausted, Tor will hibernate - until some time in the next accounting period. To prevent all servers - from waking at the same time, Tor will also wait until a random point - in each period before waking up. If you have bandwidth cost issues, - enabling hibernation is preferable to setting a low bandwidth, since - it provides users with a collection of fast servers that are up some - of the time, which is more useful than a set of slow servers that are - always "available". + +[[ReducedExitPolicy]] **ReducedExitPolicy** **0**|**1**:: + If set, use a reduced exit policy rather than the default one. + + - Note that (as also described in the Bandwidth section) Tor uses - powers of two, not powers of ten: 1 GByte is 1024*1024*1024, not - one billion. Be careful: some internet service providers might count - GBytes differently. + The reduced exit policy is an alternative to the default exit policy. It + allows as many Internet services as possible while still blocking the + majority of TCP ports. Currently, the policy allows approximately 65 ports. + This reduces the odds that your node will be used for peer-to-peer + applications. + + + + The reduced exit policy is: -[[AccountingRule]] **AccountingRule** **sum**|**max**|**in**|**out**:: - How we determine when our AccountingMax has been reached (when we - should hibernate) during a time interval. Set to "max" to calculate - using the higher of either the sent or received bytes (this is the - default functionality). Set to "sum" to calculate using the sent - plus received bytes. Set to "in" to calculate using only the - received bytes. Set to "out" to calculate using only the sent bytes. - (Default: max) + accept *:20-21 + accept *:22 + accept *:23 + accept *:43 + accept *:53 + accept *:79 + accept *:80-81 + accept *:88 + accept *:110 + accept *:143 + accept *:194 + accept *:220 + accept *:389 + accept *:443 + accept *:464 + accept *:465 + accept *:531 + accept *:543-544 + accept *:554 + accept *:563 + accept *:587 + accept *:636 + accept *:706 + accept *:749 + accept *:873 + accept *:902-904 + accept *:981 + accept *:989-990 + accept *:991 + accept *:992 + accept *:993 + accept *:994 + accept *:995 + accept *:1194 + accept *:1220 + accept *:1293 + accept *:1500 + accept *:1533 + accept *:1677 + accept *:1723 + accept *:1755 + accept *:1863 + accept *:2082 + accept *:2083 + accept *:2086-2087 + accept *:2095-2096 + accept *:2102-2104 + accept *:3128 + accept *:3389 + accept *:3690 + accept *:4321 + accept *:4643 + accept *:5050 + accept *:5190 + accept *:5222-5223 + accept *:5228 + accept *:5900 + accept *:6660-6669 + accept *:6679 + accept *:6697 + accept *:8000 + accept *:8008 + accept *:8074 + accept *:8080 + accept *:8082 + accept *:8087-8088 + accept *:8232-8233 + accept *:8332-8333 + accept *:8443 + accept *:8888 + accept *:9418 + accept *:9999 + accept *:10000 + accept *:11371 + accept *:19294 + accept *:19638 + accept *:50002 + accept *:64738 + reject *:* -[[AccountingStart]] **AccountingStart** **day**|**week**|**month** [__day__] __HH:MM__:: - Specify how long accounting periods last. If **month** is given, - each accounting period runs from the time __HH:MM__ on the __dayth__ day of one - month to the same day and time of the next. The relay will go at full speed, - use all the quota you specify, then hibernate for the rest of the period. (The - day must be between 1 and 28.) If **week** is given, each accounting period - runs from the time __HH:MM__ of the __dayth__ day of one week to the same day - and time of the next week, with Monday as day 1 and Sunday as day 7. If **day** - is given, each accounting period runs from the time __HH:MM__ each day to the - same time on the next day. All times are local, and given in 24-hour time. - (Default: "month 1 0:00") + (Default: 0) [[RefuseUnknownExits]] **RefuseUnknownExits** **0**|**1**|**auto**:: Prevent nodes that don't appear in the consensus from exiting using this @@ -2454,6 +2532,34 @@ is non-zero): whatever the authorities suggest in the consensus (and block if the consensus is quiet on the issue). (Default: auto) +[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**:: + If this option is false, Tor exits immediately if there are problems + parsing the system DNS configuration or connecting to nameservers. + Otherwise, Tor continues to periodically retry the system nameservers until + it eventually succeeds. (Default: 1) + +[[ServerDNSAllowNonRFC953Hostnames]] **ServerDNSAllowNonRFC953Hostnames** **0**|**1**:: + When this option is disabled, Tor does not try to resolve hostnames + containing illegal characters (like @ and :) rather than sending them to an + exit node to be resolved. This helps trap accidental attempts to resolve + URLs and so on. This option only affects name lookups that your server does + on behalf of clients. (Default: 0) + +[[ServerDNSDetectHijacking]] **ServerDNSDetectHijacking** **0**|**1**:: + When this option is set to 1, we will test periodically to determine + whether our local nameservers have been configured to hijack failing DNS + requests (usually to an advertising site). If they are, we will attempt to + correct this. This option only affects name lookups that your server does + on behalf of clients. (Default: 1) + +[[ServerDNSRandomizeCase]] **ServerDNSRandomizeCase** **0**|**1**:: + When this option is set, Tor sets the case of each character randomly in + outgoing DNS requests, and makes sure that the case matches in DNS replies. + This so-called "0x20 hack" helps resist some types of DNS poisoning attack. + For more information, see "Increased DNS Forgery Resistance through + 0x20-Bit Encoding". This option only affects name lookups that your server + does on behalf of clients. (Default: 1) + [[ServerDNSResolvConfFile]] **ServerDNSResolvConfFile** __filename__:: Overrides the default DNS configuration with the configuration in __filename__. The file format is the same as the standard Unix @@ -2462,12 +2568,6 @@ is non-zero): (Defaults to use the system DNS configuration or a localhost DNS service in case no nameservers are found in a given configuration.) -[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**:: - If this option is false, Tor exits immediately if there are problems - parsing the system DNS configuration or connecting to nameservers. - Otherwise, Tor continues to periodically retry the system nameservers until - it eventually succeeds. (Default: 1) - [[ServerDNSSearchDomains]] **ServerDNSSearchDomains** **0**|**1**:: If set to 1, then we will search for addresses in the local search domain. For example, if this system is configured to believe it is in @@ -2475,13 +2575,6 @@ is non-zero): connected to "www.example.com". This option only affects name lookups that your server does on behalf of clients. (Default: 0) -[[ServerDNSDetectHijacking]] **ServerDNSDetectHijacking** **0**|**1**:: - When this option is set to 1, we will test periodically to determine - whether our local nameservers have been configured to hijack failing DNS - requests (usually to an advertising site). If they are, we will attempt to - correct this. This option only affects name lookups that your server does - on behalf of clients. (Default: 1) - [[ServerDNSTestAddresses]] **ServerDNSTestAddresses** __hostname__,__hostname__,__...__:: When we're detecting DNS hijacking, make sure that these __valid__ addresses aren't getting redirected. If they are, then our DNS is completely useless, @@ -2489,33 +2582,32 @@ is non-zero): name lookups that your server does on behalf of clients. (Default: "www.google.com, www.mit.edu, www.yahoo.com, www.slashdot.org") -[[ServerDNSAllowNonRFC953Hostnames]] **ServerDNSAllowNonRFC953Hostnames** **0**|**1**:: - When this option is disabled, Tor does not try to resolve hostnames - containing illegal characters (like @ and :) rather than sending them to an - exit node to be resolved. This helps trap accidental attempts to resolve - URLs and so on. This option only affects name lookups that your server does - on behalf of clients. (Default: 0) +[[ShutdownWaitLength]] **ShutdownWaitLength** __NUM__:: + When we get a SIGINT and we're a server, we begin shutting down: + we close listeners and start refusing new circuits. After **NUM** + seconds, we exit. If we get a second SIGINT, we exit immediately. + (Default: 30 seconds) -[[BridgeRecordUsageByCountry]] **BridgeRecordUsageByCountry** **0**|**1**:: - When this option is enabled and BridgeRelay is also enabled, and we have - GeoIP data, Tor keeps a per-country count of how many client - addresses have contacted it so that it can help the bridge authority guess - which countries have blocked access to it. If ExtraInfoStatistics is - enabled, it will be published as part of extra-info document. (Default: 1) +[[SigningKeyLifetime]] **SigningKeyLifetime** __N__ **days**|**weeks**|**months**:: + For how long should each Ed25519 signing key be valid? Tor uses a + permanent master identity key that can be kept offline, and periodically + generates new "signing" keys that it uses online. This option + configures their lifetime. + (Default: 30 days) -[[ServerDNSRandomizeCase]] **ServerDNSRandomizeCase** **0**|**1**:: - When this option is set, Tor sets the case of each character randomly in - outgoing DNS requests, and makes sure that the case matches in DNS replies. - This so-called "0x20 hack" helps resist some types of DNS poisoning attack. - For more information, see "Increased DNS Forgery Resistance through - 0x20-Bit Encoding". This option only affects name lookups that your server - does on behalf of clients. (Default: 1) +[[SSLKeyLifetime]] **SSLKeyLifetime** __N__ **minutes**|**hours**|**days**|**weeks**:: + When creating a link certificate for our outermost SSL handshake, + set its lifetime to this amount of time. If set to 0, Tor will choose + some reasonable random defaults. (Default: 0) -[[GeoIPFile]] **GeoIPFile** __filename__:: - A filename containing IPv4 GeoIP data, for use with by-country statistics. +== STATISTICS OPTIONS -[[GeoIPv6File]] **GeoIPv6File** __filename__:: - A filename containing IPv6 GeoIP data, for use with by-country statistics. +// These options are in alphabetical order, with exceptions as noted. +// Please keep them that way! + +Relays publish most statistics in a document called the +extra-info document. The following options affect the different +types of statistics that Tor relays collect and publish: [[CellStatistics]] **CellStatistics** **0**|**1**:: Relays only. @@ -2527,14 +2619,14 @@ is non-zero): If ExtraInfoStatistics is enabled, it will published as part of extra-info document. (Default: 0) -[[PaddingStatistics]] **PaddingStatistics** **0**|**1**:: - Relays and bridges only. - When this option is enabled, Tor collects statistics for padding cells - sent and received by this relay, in addition to total cell counts. - These statistics are rounded, and omitted if traffic is low. This - information is important for load balancing decisions related to padding. - If ExtraInfoStatistics is enabled, it will be published - as a part of extra-info document. (Default: 1) +[[ConnDirectionStatistics]] **ConnDirectionStatistics** **0**|**1**:: + Relays only. + When this option is enabled, Tor writes statistics on the amounts of + traffic it passes between itself and other relays to disk every 24 + hours. Enables relay operators to monitor how much their relay is + being used as middle node in the circuit. If ExtraInfoStatistics is + enabled, it will be published as part of extra-info document. + (Default: 0) [[DirReqStatistics]] **DirReqStatistics** **0**|**1**:: Relays and bridges only. @@ -2563,23 +2655,6 @@ is non-zero): is enabled, it will be published as part of extra-info document. (Default: 0) -[[ConnDirectionStatistics]] **ConnDirectionStatistics** **0**|**1**:: - Relays only. - When this option is enabled, Tor writes statistics on the amounts of - traffic it passes between itself and other relays to disk every 24 - hours. Enables relay operators to monitor how much their relay is - being used as middle node in the circuit. If ExtraInfoStatistics is - enabled, it will be published as part of extra-info document. - (Default: 0) - -[[HiddenServiceStatistics]] **HiddenServiceStatistics** **0**|**1**:: - Relays only. - When this option is enabled, a Tor relay writes obfuscated - statistics on its role as hidden-service directory, introduction - point, or rendezvous point to disk every 24 hours. If - ExtraInfoStatistics is also enabled, these statistics are further - published to the directory authorities. (Default: 1) - [[ExtraInfoStatistics]] **ExtraInfoStatistics** **0**|**1**:: When this option is enabled, Tor includes previously gathered statistics in its extra-info documents that it uploads to the directory authorities. @@ -2589,61 +2664,22 @@ is non-zero): because they are required by BridgeDB. (Default: 1) -[[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**:: - When this option is enabled, Tor will connect to relays on localhost, - RFC1918 addresses, and so on. In particular, Tor will make direct OR - connections, and Tor routers allow EXTEND requests, to these private - addresses. (Tor will always allow connections to bridges, proxies, and - pluggable transports configured on private addresses.) Enabling this - option can create security issues; you should probably leave it off. - (Default: 0) - -[[MaxMemInQueues]] **MaxMemInQueues** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**:: - This option configures a threshold above which Tor will assume that it - needs to stop queueing or buffering data because it's about to run out of - memory. If it hits this threshold, it will begin killing circuits until - it has recovered at least 10% of this memory. Do not set this option too - low, or your relay may be unreliable under load. This option only - affects some queues, so the actual process size will be larger than - this. If this option is set to 0, Tor will try to pick a reasonable - default based on your system's physical memory. (Default: 0) - -[[DisableOOSCheck]] **DisableOOSCheck** **0**|**1**:: - This option disables the code that closes connections when Tor notices - that it is running low on sockets. Right now, it is on by default, - since the existing out-of-sockets mechanism tends to kill OR connections - more than it should. (Default: 1) - -[[SigningKeyLifetime]] **SigningKeyLifetime** __N__ **days**|**weeks**|**months**:: - For how long should each Ed25519 signing key be valid? Tor uses a - permanent master identity key that can be kept offline, and periodically - generates new "signing" keys that it uses online. This option - configures their lifetime. - (Default: 30 days) - -[[OfflineMasterKey]] **OfflineMasterKey** **0**|**1**:: - If non-zero, the Tor relay will never generate or load its master secret - key. Instead, you'll have to use "tor --keygen" to manage the permanent - ed25519 master identity key, as well as the corresponding temporary - signing keys and certificates. (Default: 0) - -[[KeyDirectory]] **KeyDirectory** __DIR__:: - Store secret keys in DIR. Can not be changed while tor is - running. - (Default: the "keys" subdirectory of DataDirectory.) - -[[KeyDirectoryGroupReadable]] **KeyDirectoryGroupReadable** **0**|**1**|**auto**:: - If this option is set to 0, don't allow the filesystem group to read the - KeyDirectory. If the option is set to 1, make the KeyDirectory readable - by the default GID. If the option is "auto", then we use the - setting for DataDirectoryGroupReadable when the KeyDirectory is the - same as the DataDirectory, and 0 otherwise. (Default: auto) - -[[RephistTrackTime]] **RephistTrackTime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: - Tells an authority, or other node tracking node reliability and history, - that fine-grained information about nodes can be discarded when it hasn't - changed for a given amount of time. (Default: 24 hours) +[[HiddenServiceStatistics]] **HiddenServiceStatistics** **0**|**1**:: + Relays only. + When this option is enabled, a Tor relay writes obfuscated + statistics on its role as hidden-service directory, introduction + point, or rendezvous point to disk every 24 hours. If + ExtraInfoStatistics is also enabled, these statistics are further + published to the directory authorities. (Default: 1) +[[PaddingStatistics]] **PaddingStatistics** **0**|**1**:: + Relays and bridges only. + When this option is enabled, Tor collects statistics for padding cells + sent and received by this relay, in addition to total cell counts. + These statistics are rounded, and omitted if traffic is low. This + information is important for load balancing decisions related to padding. + If ExtraInfoStatistics is enabled, it will be published + as a part of extra-info document. (Default: 1) == DIRECTORY SERVER OPTIONS @@ -2651,11 +2687,19 @@ The following options are useful only for directory servers. (Relays with enough bandwidth automatically become directory servers; see DirCache for details.) -[[DirPortFrontPage]] **DirPortFrontPage** __FILENAME__:: - When this option is set, it takes an HTML file and publishes it as "/" on - the DirPort. Now relay operators can provide a disclaimer without needing - to set up a separate webserver. There's a sample disclaimer in - contrib/operator-tools/tor-exit-notice.html. +[[DirCache]] **DirCache** **0**|**1**:: + When this option is set, Tor caches all current directory documents except + extra info documents, and accepts client requests for them. If + **DownloadExtraInfo** is set, cached extra info documents are also cached. + Setting **DirPort** is not required for **DirCache**, because clients + connect via the ORPort by default. Setting either DirPort or BridgeRelay + and setting DirCache to 0 is not supported. (Default: 1) + +[[DirPolicy]] **DirPolicy** __policy__,__policy__,__...__:: + Set an entrance policy for this server, to limit who can connect to the + directory ports. The policies have the same form as exit policies above, + except that port specifiers are ignored. Any address not matched by + some entry in the policy is accepted. [[DirPort]] **DirPort** ['address'**:**]{empty}__PORT__|**auto** [_flags_]:: If this option is nonzero, advertise the directory service on this port. @@ -2665,19 +2709,11 @@ details.) + The same flags are supported here as are supported by ORPort. -[[DirPolicy]] **DirPolicy** __policy__,__policy__,__...__:: - Set an entrance policy for this server, to limit who can connect to the - directory ports. The policies have the same form as exit policies above, - except that port specifiers are ignored. Any address not matched by - some entry in the policy is accepted. - -[[DirCache]] **DirCache** **0**|**1**:: - When this option is set, Tor caches all current directory documents except - extra info documents, and accepts client requests for them. If - **DownloadExtraInfo** is set, cached extra info documents are also cached. - Setting **DirPort** is not required for **DirCache**, because clients - connect via the ORPort by default. Setting either DirPort or BridgeRelay - and setting DirCache to 0 is not supported. (Default: 1) +[[DirPortFrontPage]] **DirPortFrontPage** __FILENAME__:: + When this option is set, it takes an HTML file and publishes it as "/" on + the DirPort. Now relay operators can provide a disclaimer without needing + to set up a separate webserver. There's a sample disclaimer in + contrib/operator-tools/tor-exit-notice.html. [[MaxConsensusAgeForDiffs]] **MaxConsensusAgeForDiffs** __N__ **minutes**|**hours**|**days**|**weeks**:: When this option is nonzero, Tor caches will not try to generate @@ -2728,6 +2764,7 @@ your log at NOTICE level which looks like: The following options are useful only for a public relay. They control the Denial of Service mitigation subsystem described above. +//Out of order because it logically belongs before the other DoSCircuitCreation options. [[DoSCircuitCreationEnabled]] **DoSCircuitCreationEnabled** **0**|**1**|**auto**:: Enable circuit creation DoS mitigation. If set to 1 (enabled), tor will @@ -2738,22 +2775,6 @@ Denial of Service mitigation subsystem described above. use the consensus parameter. If not defined in the consensus, the value is 0. (Default: auto) -[[DoSCircuitCreationMinConnections]] **DoSCircuitCreationMinConnections** __NUM__:: - - Minimum threshold of concurrent connections before a client address can be - flagged as executing a circuit creation DoS. In other words, once a client - address reaches the circuit rate and has a minimum of NUM concurrent - connections, a detection is positive. "0" means use the consensus - parameter. If not defined in the consensus, the value is 3. - (Default: 0) - -[[DoSCircuitCreationRate]] **DoSCircuitCreationRate** __NUM__:: - - The allowed circuit creation rate per second applied per client IP - address. If this option is 0, it obeys a consensus parameter. If not - defined in the consensus, the value is 3. - (Default: 0) - [[DoSCircuitCreationBurst]] **DoSCircuitCreationBurst** __NUM__:: The allowed circuit creation burst per client IP address. If the circuit @@ -2762,6 +2783,14 @@ Denial of Service mitigation subsystem described above. consensus, the value is 90. (Default: 0) +[[DoSCircuitCreationDefenseTimePeriod]] **DoSCircuitCreationDefenseTimePeriod** __N__ **seconds**|**minutes**|**hours**:: + + The base time period in seconds that the DoS defense is activated for. The + actual value is selected randomly for each activation from N+1 to 3/2 * N. + "0" means use the consensus parameter. If not defined in the consensus, + the value is 3600 seconds (1 hour). + (Default: 0) + [[DoSCircuitCreationDefenseType]] **DoSCircuitCreationDefenseType** __NUM__:: This is the type of defense applied to a detected client address. The @@ -2774,14 +2803,23 @@ Denial of Service mitigation subsystem described above. "0" means use the consensus parameter. If not defined in the consensus, the value is 2. (Default: 0) -[[DoSCircuitCreationDefenseTimePeriod]] **DoSCircuitCreationDefenseTimePeriod** __N__ **seconds**|**minutes**|**hours**:: +[[DoSCircuitCreationMinConnections]] **DoSCircuitCreationMinConnections** __NUM__:: - The base time period in seconds that the DoS defense is activated for. The - actual value is selected randomly for each activation from N+1 to 3/2 * N. - "0" means use the consensus parameter. If not defined in the consensus, - the value is 3600 seconds (1 hour). + Minimum threshold of concurrent connections before a client address can be + flagged as executing a circuit creation DoS. In other words, once a client + address reaches the circuit rate and has a minimum of NUM concurrent + connections, a detection is positive. "0" means use the consensus + parameter. If not defined in the consensus, the value is 3. + (Default: 0) + +[[DoSCircuitCreationRate]] **DoSCircuitCreationRate** __NUM__:: + + The allowed circuit creation rate per second applied per client IP + address. If this option is 0, it obeys a consensus parameter. If not + defined in the consensus, the value is 3. (Default: 0) +//out of order because it logically belongs before the other DoSConnection options. [[DoSConnectionEnabled]] **DoSConnectionEnabled** **0**|**1**|**auto**:: Enable the connection DoS mitigation. If set to 1 (enabled), for client @@ -2790,14 +2828,6 @@ Denial of Service mitigation subsystem described above. consensus parameter. If not defined in the consensus, the value is 0. (Default: auto) -[[DoSConnectionMaxConcurrentCount]] **DoSConnectionMaxConcurrentCount** __NUM__:: - - The maximum threshold of concurrent connection from a client IP address. - Above this limit, a defense selected by DoSConnectionDefenseType is - applied. "0" means use the consensus parameter. If not defined in the - consensus, the value is 100. - (Default: 0) - [[DoSConnectionDefenseType]] **DoSConnectionDefenseType** __NUM__:: This is the type of defense applied to a detected client address for the @@ -2810,6 +2840,14 @@ Denial of Service mitigation subsystem described above. "0" means use the consensus parameter. If not defined in the consensus, the value is 2. (Default: 0) +[[DoSConnectionMaxConcurrentCount]] **DoSConnectionMaxConcurrentCount** __NUM__:: + + The maximum threshold of concurrent connection from a client IP address. + Above this limit, a defense selected by DoSConnectionDefenseType is + applied. "0" means use the consensus parameter. If not defined in the + consensus, the value is 100. + (Default: 0) + [[DoSRefuseSingleHopClientRendezvous]] **DoSRefuseSingleHopClientRendezvous** **0**|**1**|**auto**:: Refuse establishment of rendezvous points for single hop clients. In other @@ -2826,6 +2864,7 @@ control how Tor behaves as a directory authority. You should not need to adjust any of them if you're running a regular relay or exit server on the public Tor network. +// Out of order because it logically belongs first in this section [[AuthoritativeDirectory]] **AuthoritativeDirectory** **0**|**1**:: When this option is set to 1, Tor operates as an authoritative directory server. Instead of caching the directory, it generates its own list of @@ -2833,59 +2872,18 @@ on the public Tor network. already have you listed as a trusted directory, you probably do not want to set this option. -[[V3AuthoritativeDirectory]] **V3AuthoritativeDirectory** **0**|**1**:: - When this option is set in addition to **AuthoritativeDirectory**, Tor - generates version 3 network statuses and serves descriptors, etc as - described in dir-spec.txt file of https://spec.torproject.org/[torspec] - (for Tor clients and servers running at least 0.2.0.x). - -[[VersioningAuthoritativeDirectory]] **VersioningAuthoritativeDirectory** **0**|**1**:: - When this option is set to 1, Tor adds information on which versions of - Tor are still believed safe for use to the published directory. Each - version 1 authority is automatically a versioning authority; version 2 - authorities provide this service optionally. See **RecommendedVersions**, - **RecommendedClientVersions**, and **RecommendedServerVersions**. - -[[RecommendedVersions]] **RecommendedVersions** __STRING__:: - STRING is a comma-separated list of Tor versions currently believed to be - safe. The list is included in each directory, and nodes which pull down the - directory learn whether they need to upgrade. This option can appear - multiple times: the values from multiple lines are spliced together. When - this is set then **VersioningAuthoritativeDirectory** should be set too. - -[[RecommendedClientVersions]] **RecommendedClientVersions** __STRING__:: - STRING is a comma-separated list of Tor versions currently believed to be - safe for clients to use. This information is included in version 2 - directories. If this is not set then the value of **RecommendedVersions** - is used. When this is set then **VersioningAuthoritativeDirectory** should - be set too. - +//Out of order because it belongs with the AuthoritativeDirectory option. [[BridgeAuthoritativeDir]] **BridgeAuthoritativeDir** **0**|**1**:: When this option is set in addition to **AuthoritativeDirectory**, Tor accepts and serves server descriptors, but it caches and serves the main networkstatus documents rather than generating its own. (Default: 0) -[[MinUptimeHidServDirectoryV2]] **MinUptimeHidServDirectoryV2** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: - Minimum uptime of a v2 hidden service directory to be accepted as such by - authoritative directories. (Default: 25 hours) - -[[RecommendedServerVersions]] **RecommendedServerVersions** __STRING__:: - STRING is a comma-separated list of Tor versions currently believed to be - safe for servers to use. This information is included in version 2 - directories. If this is not set then the value of **RecommendedVersions** - is used. When this is set then **VersioningAuthoritativeDirectory** should - be set too. - -[[ConsensusParams]] **ConsensusParams** __STRING__:: - STRING is a space-separated list of key=value pairs that Tor will include - in the "params" line of its networkstatus vote. - -[[DirAllowPrivateAddresses]] **DirAllowPrivateAddresses** **0**|**1**:: - If set to 1, Tor will accept server descriptors with arbitrary "Address" - elements. Otherwise, if the address is not an IP address or is a private IP - address, it will reject the server descriptor. Additionally, Tor - will allow exit policies for private networks to fulfill Exit flag - requirements. (Default: 0) +//Out of order because it belongs with the AuthoritativeDirectory option. +[[V3AuthoritativeDirectory]] **V3AuthoritativeDirectory** **0**|**1**:: + When this option is set in addition to **AuthoritativeDirectory**, Tor + generates version 3 network statuses and serves descriptors, etc as + described in dir-spec.txt file of https://spec.torproject.org/[torspec] + (for Tor clients and servers running at least 0.2.0.x). [[AuthDirBadExit]] **AuthDirBadExit** __AddressPattern...__:: Authoritative directories only. A set of address patterns for servers that @@ -2896,26 +2894,46 @@ on the public Tor network. is the same as for exit policies, except that you don't need to say "accept" or "reject", and ports are not needed.) -[[AuthDirInvalid]] **AuthDirInvalid** __AddressPattern...__:: - Authoritative directories only. A set of address patterns for servers that - will never be listed as "valid" in any network status document that this - authority publishes. +[[AuthDirFastGuarantee]] **AuthDirFastGuarantee** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: + Authoritative directories only. If non-zero, always vote the + Fast flag for any relay advertising this amount of capacity or + more. (Default: 100 KBytes) -[[AuthDirReject]] **AuthDirReject** __AddressPattern__...:: - Authoritative directories only. A set of address patterns for servers that - will never be listed at all in any network status document that this - authority publishes, or accepted as an OR address in any descriptor - submitted for publication by this authority. +[[AuthDirGuardBWGuarantee]] **AuthDirGuardBWGuarantee** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: + Authoritative directories only. If non-zero, this advertised capacity + or more is always sufficient to satisfy the bandwidth requirement + for the Guard flag. (Default: 2 MBytes) -[[AuthDirBadExitCCs]] **AuthDirBadExitCCs** __CC__,... + +[[AuthDirHasIPv6Connectivity]] **AuthDirHasIPv6Connectivity** **0**|**1**:: + Authoritative directories only. When set to 0, OR ports with an + IPv6 address are not included in the authority's votes. When set to 1, + IPv6 OR ports are tested for reachability like IPv4 OR ports. If the + reachability test succeeds, the authority votes for the IPv6 ORPort, and + votes Running for the relay. If the reachability test fails, the authority + does not vote for the IPv6 ORPort, and does not vote Running (Default: 0) + ++ + The content of the consensus depends on the number of voting authorities + that set AuthDirHasIPv6Connectivity: -[[AuthDirInvalidCCs]] **AuthDirInvalidCCs** __CC__,... + + If no authorities set AuthDirHasIPv6Connectivity 1, there will be no + IPv6 ORPorts in the consensus. -[[AuthDirRejectCCs]] **AuthDirRejectCCs** __CC__,...:: - Authoritative directories only. These options contain a comma-separated - list of country codes such that any server in one of those country codes - will be marked as a bad exit/invalid for use, or rejected - entirely. + If a minority of authorities set AuthDirHasIPv6Connectivity 1, + unreachable IPv6 ORPorts will be removed from the consensus. But the + majority of IPv4-only authorities will still vote the relay as Running. + Reachable IPv6 ORPort lines will be included in the consensus + + If a majority of voting authorities set AuthDirHasIPv6Connectivity 1, + relays with unreachable IPv6 ORPorts will not be listed as Running. + Reachable IPv6 ORPort lines will be included in the consensus + (To ensure that any valid majority will vote relays with unreachable + IPv6 ORPorts not Running, 75% of authorities must set + AuthDirHasIPv6Connectivity 1.) + +[[AuthDirInvalid]] **AuthDirInvalid** __AddressPattern...__:: + Authoritative directories only. A set of address patterns for servers that + will never be listed as "valid" in any network status document that this + authority publishes. [[AuthDirListBadExits]] **AuthDirListBadExits** **0**|**1**:: Authoritative directories only. If set to 1, this directory has some @@ -2928,16 +2946,6 @@ on the public Tor network. list as acceptable on a single IP address. Set this to "0" for "no limit". (Default: 2) -[[AuthDirFastGuarantee]] **AuthDirFastGuarantee** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: - Authoritative directories only. If non-zero, always vote the - Fast flag for any relay advertising this amount of capacity or - more. (Default: 100 KBytes) - -[[AuthDirGuardBWGuarantee]] **AuthDirGuardBWGuarantee** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: - Authoritative directories only. If non-zero, this advertised capacity - or more is always sufficient to satisfy the bandwidth requirement - for the Guard flag. (Default: 2 MBytes) - [[AuthDirPinKeys]] **AuthDirPinKeys** **0**|**1**:: Authoritative directories only. If non-zero, do not allow any relay to publish a descriptor if any other relay has reserved its <Ed25519,RSA> @@ -2945,6 +2953,31 @@ on the public Tor network. in a journal if it is new, or if it differs from the most recently accepted pinning for one of the keys it contains. (Default: 1) +[[AuthDirReject]] **AuthDirReject** __AddressPattern__...:: + Authoritative directories only. A set of address patterns for servers that + will never be listed at all in any network status document that this + authority publishes, or accepted as an OR address in any descriptor + submitted for publication by this authority. + +//Out of order because it logically belongs with the other CCs options. +[[AuthDirBadExitCCs]] **AuthDirBadExitCCs** __CC__,... + + +//Out of order because it logically belongs with the other CCs options. +[[AuthDirInvalidCCs]] **AuthDirInvalidCCs** __CC__,... + + + +[[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**:: + If set, the directory authority will start rejecting directory requests + from non relay connections by sending a 503 error code if it is under + bandwidth pressure (reaching the configured limit if any). Relays will + always tried to be answered even if this is on. (Default: 1) + +[[AuthDirRejectCCs]] **AuthDirRejectCCs** __CC__,...:: + Authoritative directories only. These options contain a comma-separated + list of country codes such that any server in one of those country codes + will be marked as a bad exit/invalid for use, or rejected + entirely. + [[AuthDirSharedRandomness]] **AuthDirSharedRandomness** **0**|**1**:: Authoritative directories only. Switch for the shared random protocol. If zero, the authority won't participate in the protocol. If non-zero @@ -2966,17 +2999,52 @@ on the public Tor network. and their target user audience can periodically fetch the list of available community bridges to stay up-to-date. (Default: not set) -[[V3AuthVotingInterval]] **V3AuthVotingInterval** __N__ **minutes**|**hours**:: - V3 authoritative directories only. Configures the server's preferred voting - interval. Note that voting will __actually__ happen at an interval chosen - by consensus from all the authorities' preferred intervals. This time - SHOULD divide evenly into a day. (Default: 1 hour) +[[ConsensusParams]] **ConsensusParams** __STRING__:: + STRING is a space-separated list of key=value pairs that Tor will include + in the "params" line of its networkstatus vote. -[[V3AuthVoteDelay]] **V3AuthVoteDelay** __N__ **minutes**|**hours**:: - V3 authoritative directories only. Configures the server's preferred delay - between publishing its vote and assuming it has all the votes from all the - other authorities. Note that the actual time used is not the server's - preferred time, but the consensus of all preferences. (Default: 5 minutes) +[[DirAllowPrivateAddresses]] **DirAllowPrivateAddresses** **0**|**1**:: + If set to 1, Tor will accept server descriptors with arbitrary "Address" + elements. Otherwise, if the address is not an IP address or is a private IP + address, it will reject the server descriptor. Additionally, Tor + will allow exit policies for private networks to fulfill Exit flag + requirements. (Default: 0) + +[[GuardfractionFile]] **GuardfractionFile** __FILENAME__:: + V3 authoritative directories only. Configures the location of the + guardfraction file which contains information about how long relays + have been guards. (Default: unset) + +[[MinMeasuredBWsForAuthToIgnoreAdvertised]] **MinMeasuredBWsForAuthToIgnoreAdvertised** __N__:: + A total value, in abstract bandwidth units, describing how much + measured total bandwidth an authority should have observed on the network + before it will treat advertised bandwidths as wholly + unreliable. (Default: 500) + +[[MinUptimeHidServDirectoryV2]] **MinUptimeHidServDirectoryV2** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: + Minimum uptime of a v2 hidden service directory to be accepted as such by + authoritative directories. (Default: 25 hours) + +[[RecommendedClientVersions]] **RecommendedClientVersions** __STRING__:: + STRING is a comma-separated list of Tor versions currently believed to be + safe for clients to use. This information is included in version 2 + directories. If this is not set then the value of **RecommendedVersions** + is used. When this is set then **VersioningAuthoritativeDirectory** should + be set too. + +[[RecommendedServerVersions]] **RecommendedServerVersions** __STRING__:: + STRING is a comma-separated list of Tor versions currently believed to be + safe for servers to use. This information is included in version 2 + directories. If this is not set then the value of **RecommendedVersions** + is used. When this is set then **VersioningAuthoritativeDirectory** should + be set too. + +[[RecommendedVersions]] **RecommendedVersions** __STRING__:: + STRING is a comma-separated list of Tor versions currently believed to be + safe. The list is included in each directory, and nodes which pull down the + directory learn whether they need to upgrade. This option can appear + multiple times: the values from multiple lines are spliced together. When + this is set then **VersioningAuthoritativeDirectory** should be set too. [[V3AuthDistDelay]] **V3AuthDistDelay** __N__ **minutes**|**hours**:: V3 authoritative directories only. Configures the server's preferred delay @@ -2993,55 +3061,38 @@ on the public Tor network. server's preferred number, but the consensus of all preferences. Must be at least 2. (Default: 3) -[[V3BandwidthsFile]] **V3BandwidthsFile** __FILENAME__:: - V3 authoritative directories only. Configures the location of the - bandwidth-authority generated file storing information on relays' measured - bandwidth capacities. To avoid inconsistent reads, bandwidth data should - be written to temporary file, then renamed to the configured filename. - (Default: unset) - -[[GuardfractionFile]] **GuardfractionFile** __FILENAME__:: - V3 authoritative directories only. Configures the location of the - guardfraction file which contains information about how long relays - have been guards. (Default: unset) - [[V3AuthUseLegacyKey]] **V3AuthUseLegacyKey** **0**|**1**:: If set, the directory authority will sign consensuses not only with its own signing key, but also with a "legacy" key and certificate with a different identity. This feature is used to migrate directory authority keys in the event of a compromise. (Default: 0) -[[AuthDirHasIPv6Connectivity]] **AuthDirHasIPv6Connectivity** **0**|**1**:: - Authoritative directories only. When set to 0, OR ports with an - IPv6 address are not included in the authority's votes. When set to 1, - IPv6 OR ports are tested for reachability like IPv4 OR ports. If the - reachability test succeeds, the authority votes for the IPv6 ORPort, and - votes Running for the relay. If the reachability test fails, the authority - does not vote for the IPv6 ORPort, and does not vote Running (Default: 0) + -+ - The content of the consensus depends on the number of voting authorities - that set AuthDirHasIPv6Connectivity: - - If no authorities set AuthDirHasIPv6Connectivity 1, there will be no - IPv6 ORPorts in the consensus. +[[V3AuthVoteDelay]] **V3AuthVoteDelay** __N__ **minutes**|**hours**:: + V3 authoritative directories only. Configures the server's preferred delay + between publishing its vote and assuming it has all the votes from all the + other authorities. Note that the actual time used is not the server's + preferred time, but the consensus of all preferences. (Default: 5 + minutes) - If a minority of authorities set AuthDirHasIPv6Connectivity 1, - unreachable IPv6 ORPorts will be removed from the consensus. But the - majority of IPv4-only authorities will still vote the relay as Running. - Reachable IPv6 ORPort lines will be included in the consensus +[[V3AuthVotingInterval]] **V3AuthVotingInterval** __N__ **minutes**|**hours**:: + V3 authoritative directories only. Configures the server's preferred voting + interval. Note that voting will __actually__ happen at an interval chosen + by consensus from all the authorities' preferred intervals. This time + SHOULD divide evenly into a day. (Default: 1 hour) - If a majority of voting authorities set AuthDirHasIPv6Connectivity 1, - relays with unreachable IPv6 ORPorts will not be listed as Running. - Reachable IPv6 ORPort lines will be included in the consensus - (To ensure that any valid majority will vote relays with unreachable - IPv6 ORPorts not Running, 75% of authorities must set - AuthDirHasIPv6Connectivity 1.) +[[V3BandwidthsFile]] **V3BandwidthsFile** __FILENAME__:: + V3 authoritative directories only. Configures the location of the + bandwidth-authority generated file storing information on relays' measured + bandwidth capacities. To avoid inconsistent reads, bandwidth data should + be written to temporary file, then renamed to the configured filename. + (Default: unset) -[[MinMeasuredBWsForAuthToIgnoreAdvertised]] **MinMeasuredBWsForAuthToIgnoreAdvertised** __N__:: - A total value, in abstract bandwidth units, describing how much - measured total bandwidth an authority should have observed on the network - before it will treat advertised bandwidths as wholly - unreliable. (Default: 500) +[[VersioningAuthoritativeDirectory]] **VersioningAuthoritativeDirectory** **0**|**1**:: + When this option is set to 1, Tor adds information on which versions of + Tor are still believed safe for use to the published directory. Each + version 1 authority is automatically a versioning authority; version 2 + authorities provide this service optionally. See **RecommendedVersions**, + **RecommendedClientVersions**, and **RecommendedServerVersions**. == HIDDEN SERVICE OPTIONS @@ -3053,33 +3104,11 @@ The next section describes the per service options that can only be set **PER SERVICE OPTIONS:** -[[HiddenServiceDir]] **HiddenServiceDir** __DIRECTORY__:: - Store data files for a hidden service in DIRECTORY. Every hidden service - must have a separate directory. You may use this option multiple times to - specify multiple services. If DIRECTORY does not exist, Tor will create it. - Please note that you cannot add new Onion Service to already running Tor - instance if **Sandbox** is enabled. - (Note: in current versions of Tor, if DIRECTORY is a relative path, - it will be relative to the current - working directory of Tor instance, not to its DataDirectory. Do not - rely on this behavior; it is not guaranteed to remain the same in future - versions.) - -[[HiddenServicePort]] **HiddenServicePort** __VIRTPORT__ [__TARGET__]:: - Configure a virtual port VIRTPORT for a hidden service. You may use this - option multiple times; each time applies to the service using the most - recent HiddenServiceDir. By default, this option maps the virtual port to - the same port on 127.0.0.1 over TCP. You may override the target port, - address, or both by specifying a target of addr, port, addr:port, or - **unix:**__path__. (You can specify an IPv6 target as [addr]:port. Unix - paths may be quoted, and may use standard C escapes.) - You may also have multiple lines with the same VIRTPORT: when a user - connects to that VIRTPORT, one of the TARGETs from those lines will be - chosen at random. Note that address-port pairs have to be comma-separated. - -[[HiddenServiceVersion]] **HiddenServiceVersion** **2**|**3**:: - A list of rendezvous service descriptor versions to publish for the hidden - service. Currently, versions 2 and 3 are supported. (Default: 3) +[[HiddenServiceAllowUnknownPorts]] **HiddenServiceAllowUnknownPorts** **0**|**1**:: + If set to 1, then connections to unrecognized ports do not cause the + current hidden service to close rendezvous circuits. (Setting this to 0 is + not an authorization mechanism; it is instead meant to be a mild + inconvenience to port-scanners.) (Default: 0) [[HiddenServiceAuthorizeClient]] **HiddenServiceAuthorizeClient** __auth-type__ __client-name__,__client-name__,__...__:: If configured, the v2 hidden service is accessible for authorized clients @@ -3095,11 +3124,47 @@ The next section describes the per service options that can only be set services; v3 services configure client authentication in a subdirectory of HiddenServiceDir instead (see the **Client Authorization** section). -[[HiddenServiceAllowUnknownPorts]] **HiddenServiceAllowUnknownPorts** **0**|**1**:: - If set to 1, then connections to unrecognized ports do not cause the - current hidden service to close rendezvous circuits. (Setting this to 0 is - not an authorization mechanism; it is instead meant to be a mild - inconvenience to port-scanners.) (Default: 0) +[[HiddenServiceDir]] **HiddenServiceDir** __DIRECTORY__:: + Store data files for a hidden service in DIRECTORY. Every hidden service + must have a separate directory. You may use this option multiple times to + specify multiple services. If DIRECTORY does not exist, Tor will create it. + Please note that you cannot add new Onion Service to already running Tor + instance if **Sandbox** is enabled. + (Note: in current versions of Tor, if DIRECTORY is a relative path, + it will be relative to the current + working directory of Tor instance, not to its DataDirectory. Do not + rely on this behavior; it is not guaranteed to remain the same in future + versions.) + +[[HiddenServiceDirGroupReadable]] **HiddenServiceDirGroupReadable** **0**|**1**:: + If this option is set to 1, allow the filesystem group to read the + hidden service directory and hostname file. If the option is set to 0, + only owner is able to read the hidden service directory. (Default: 0) + Has no effect on Windows. + +[[HiddenServiceEnableIntroDoSDefense]] **HiddenServiceEnableIntroDoSDefense** **0**|**1**:: + Enable DoS defense at the intropoint level. When this is enabled, the + rate and burst parameter (see below) will be sent to the intro point which + will then use them to apply rate limiting for introduction request to this + service. + + + The introduction point honors the consensus parameters except if this is + specifically set by the service operator using this option. The service + never looks at the consensus parameters in order to enable or disable this + defense. (Default: 0) + +//Out of order because it logically belongs after HiddenServiceEnableIntroDoSDefense. +[[HiddenServiceEnableIntroDoSBurstPerSec]] **HiddenServiceEnableIntroDoSBurstPerSec** __NUM__:: + The allowed client introduction burst per second at the introduction + point. If this option is 0, it is considered infinite and thus if + **HiddenServiceEnableIntroDoSDefense** is set, it then effectively + disables the defenses. (Default: 200) + +[[HiddenServiceEnableIntroDoSRatePerSec]] **HiddenServiceEnableIntroDoSRatePerSec** __NUM__:: + The allowed client introduction rate per second at the introduction + point. If this option is 0, it is considered infinite and thus if + **HiddenServiceEnableIntroDoSDefense** is set, it then effectively + disables the defenses. (Default: 25) [[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** __protocol__:: The onion service will use the given protocol to expose the global circuit @@ -3151,6 +3216,26 @@ The next section describes the per service options that can only be set offending rendezvous circuit to be torn down, as opposed to stream creation requests that exceed the limit being silently ignored. (Default: 0) +[[HiddenServiceNumIntroductionPoints]] **HiddenServiceNumIntroductionPoints** __NUM__:: + Number of introduction points the hidden service will have. You can't + have more than 10 for v2 service and 20 for v3. (Default: 3) + +[[HiddenServicePort]] **HiddenServicePort** __VIRTPORT__ [__TARGET__]:: + Configure a virtual port VIRTPORT for a hidden service. You may use this + option multiple times; each time applies to the service using the most + recent HiddenServiceDir. By default, this option maps the virtual port to + the same port on 127.0.0.1 over TCP. You may override the target port, + address, or both by specifying a target of addr, port, addr:port, or + **unix:**__path__. (You can specify an IPv6 target as [addr]:port. Unix + paths may be quoted, and may use standard C escapes.) + You may also have multiple lines with the same VIRTPORT: when a user + connects to that VIRTPORT, one of the TARGETs from those lines will be + chosen at random. Note that address-port pairs have to be comma-separated. + +[[HiddenServiceVersion]] **HiddenServiceVersion** **2**|**3**:: + A list of rendezvous service descriptor versions to publish for the hidden + service. Currently, versions 2 and 3 are supported. (Default: 3) + [[RendPostPeriod]] **RendPostPeriod** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**:: Every time the specified period elapses, Tor uploads any rendezvous service descriptors to the directory servers. This information is also @@ -3158,48 +3243,10 @@ The next section describes the per service options that can only be set maximum is 3.5 days. This option is only for v2 services. (Default: 1 hour) -[[HiddenServiceDirGroupReadable]] **HiddenServiceDirGroupReadable** **0**|**1**:: - If this option is set to 1, allow the filesystem group to read the - hidden service directory and hostname file. If the option is set to 0, - only owner is able to read the hidden service directory. (Default: 0) - Has no effect on Windows. - -[[HiddenServiceNumIntroductionPoints]] **HiddenServiceNumIntroductionPoints** __NUM__:: - Number of introduction points the hidden service will have. You can't - have more than 10 for v2 service and 20 for v3. (Default: 3) - -[[HiddenServiceEnableIntroDoSDefense]] **HiddenServiceEnableIntroDoSDefense** **0**|**1**:: - Enable DoS defense at the intropoint level. When this is enabled, the - rate and burst parameter (see below) will be sent to the intro point which - will then use them to apply rate limiting for introduction request to this - service. - + - The introduction point honors the consensus parameters except if this is - specifically set by the service operator using this option. The service - never looks at the consensus parameters in order to enable or disable this - defense. (Default: 0) - -[[HiddenServiceEnableIntroDoSRatePerSec]] **HiddenServiceEnableIntroDoSRatePerSec** __NUM__:: - The allowed client introduction rate per second at the introduction - point. If this option is 0, it is considered infinite and thus if - **HiddenServiceEnableIntroDoSDefense** is set, it then effectively - disables the defenses. (Default: 25) - -[[HiddenServiceEnableIntroDoSBurstPerSec]] **HiddenServiceEnableIntroDoSBurstPerSec** __NUM__:: - The allowed client introduction burst per second at the introduction - point. If this option is 0, it is considered infinite and thus if - **HiddenServiceEnableIntroDoSDefense** is set, it then effectively - disables the defenses. (Default: 200) **PER INSTANCE OPTIONS:** -[[PublishHidServDescriptors]] **PublishHidServDescriptors** **0**|**1**:: - If set to 0, Tor will run any hidden services you configure, but it won't - advertise them to the rendezvous directory. This option is only useful if - you're using a Tor controller that handles hidserv publishing for you. - (Default: 1) - [[HiddenServiceSingleHopMode]] **HiddenServiceSingleHopMode** **0**|**1**:: **Experimental - Non Anonymous** Hidden Services on a tor instance in HiddenServiceSingleHopMode make one-hop (direct) circuits between the onion @@ -3226,6 +3273,7 @@ The next section describes the per service options that can only be set **HiddenServiceSingleHopMode**. Can not be changed while tor is running. (Default: 0) +//Out of order because it belongs after HiddenServiceSingleHopMode. [[HiddenServiceNonAnonymousMode]] **HiddenServiceNonAnonymousMode** **0**|**1**:: Makes hidden services non-anonymous on this tor instance. Allows the non-anonymous HiddenServiceSingleHopMode. Enables direct connections in the @@ -3234,6 +3282,13 @@ The next section describes the per service options that can only be set including setting SOCKSPort to "0". Can not be changed while tor is running. (Default: 0) +[[PublishHidServDescriptors]] **PublishHidServDescriptors** **0**|**1**:: + If set to 0, Tor will run any hidden services you configure, but it won't + advertise them to the rendezvous directory. This option is only useful if + you're using a Tor controller that handles hidserv publishing for you. + (Default: 1) + + == Client Authorization (Version 3 only) @@ -3279,6 +3334,7 @@ For more information, please see https://2019.www.torproject.org/docs/tor-onion- The following options are used for running a testing Tor network. +//Out of order because it logically belongs first in this section. [[TestingTorNetwork]] **TestingTorNetwork** **0**|**1**:: If set to 1, Tor adjusts default values of the configuration options below, so that it is easier to set up a testing Tor network. May only be set if @@ -3319,59 +3375,35 @@ The following options are used for running a testing Tor network. TestingEnableConnBwEvent 1 TestingEnableCellStatsEvent 1 -[[TestingV3AuthInitialVotingInterval]] **TestingV3AuthInitialVotingInterval** __N__ **minutes**|**hours**:: - Like V3AuthVotingInterval, but for initial voting interval before the first - consensus has been created. Changing this requires that - **TestingTorNetwork** is set. (Default: 30 minutes) - -[[TestingV3AuthInitialVoteDelay]] **TestingV3AuthInitialVoteDelay** __N__ **minutes**|**hours**:: - Like V3AuthVoteDelay, but for initial voting interval before - the first consensus has been created. Changing this requires that - **TestingTorNetwork** is set. (Default: 5 minutes) - -[[TestingV3AuthInitialDistDelay]] **TestingV3AuthInitialDistDelay** __N__ **minutes**|**hours**:: - Like V3AuthDistDelay, but for initial voting interval before - the first consensus has been created. Changing this requires that - **TestingTorNetwork** is set. (Default: 5 minutes) - -[[TestingV3AuthVotingStartOffset]] **TestingV3AuthVotingStartOffset** __N__ **seconds**|**minutes**|**hours**:: - Directory authorities offset voting start time by this much. - Changing this requires that **TestingTorNetwork** is set. (Default: 0) - [[TestingAuthDirTimeToLearnReachability]] **TestingAuthDirTimeToLearnReachability** __N__ **minutes**|**hours**:: After starting as an authority, do not make claims about whether routers are Running until this much time has passed. Changing this requires that **TestingTorNetwork** is set. (Default: 30 minutes) -[[TestingMinFastFlagThreshold]] **TestingMinFastFlagThreshold** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: - Minimum value for the Fast flag. Overrides the ordinary minimum taken - from the consensus when TestingTorNetwork is set. (Default: 0.) - -[[TestingServerDownloadInitialDelay]] **TestingServerDownloadInitialDelay** __N__:: - Initial delay in seconds for when servers should download things in general. Changing this - requires that **TestingTorNetwork** is set. (Default: 0) - -[[TestingClientDownloadInitialDelay]] **TestingClientDownloadInitialDelay** __N__:: - Initial delay in seconds for when clients should download things in general. Changing this - requires that **TestingTorNetwork** is set. (Default: 0) +[[TestingAuthKeyLifetime]] **TestingAuthKeyLifetime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**|**months**:: + Overrides the default lifetime for a signing Ed25519 TLS Link authentication + key. + (Default: 2 days) -[[TestingServerConsensusDownloadInitialDelay]] **TestingServerConsensusDownloadInitialDelay** __N__:: - Initial delay in seconds for when servers should download consensuses. Changing this - requires that **TestingTorNetwork** is set. (Default: 0) +[[TestingAuthKeySlop]] **TestingAuthKeySlop** __N__ **seconds**|**minutes**|**hours** + -[[TestingClientConsensusDownloadInitialDelay]] **TestingClientConsensusDownloadInitialDelay** __N__:: - Initial delay in seconds for when clients should download consensuses. Changing this - requires that **TestingTorNetwork** is set. (Default: 0) +[[TestingBridgeBootstrapDownloadInitialDelay]] **TestingBridgeBootstrapDownloadInitialDelay** __N__:: + Initial delay in seconds for when clients should download each bridge descriptor when they + have just started, or when they can not contact any of their bridges. + Changing this requires that **TestingTorNetwork** is set. (Default: 0) [[TestingBridgeDownloadInitialDelay]] **TestingBridgeDownloadInitialDelay** __N__:: Initial delay in seconds for when clients should download each bridge descriptor when they know that one or more of their configured bridges are running. Changing this requires that **TestingTorNetwork** is set. (Default: 10800) -[[TestingBridgeBootstrapDownloadInitialDelay]] **TestingBridgeBootstrapDownloadInitialDelay** __N__:: - Initial delay in seconds for when clients should download each bridge descriptor when they - have just started, or when they can not contact any of their bridges. - Changing this requires that **TestingTorNetwork** is set. (Default: 0) +[[TestingClientConsensusDownloadInitialDelay]] **TestingClientConsensusDownloadInitialDelay** __N__:: + Initial delay in seconds for when clients should download consensuses. Changing this + requires that **TestingTorNetwork** is set. (Default: 0) + +[[TestingClientDownloadInitialDelay]] **TestingClientDownloadInitialDelay** __N__:: + Initial delay in seconds for when clients should download things in general. Changing this + requires that **TestingTorNetwork** is set. (Default: 0) [[TestingClientMaxIntervalWithoutRequest]] **TestingClientMaxIntervalWithoutRequest** __N__ **seconds**|**minutes**:: When directory clients have only a few descriptors to request, they batch @@ -3379,11 +3411,6 @@ The following options are used for running a testing Tor network. Changing this requires that **TestingTorNetwork** is set. (Default: 10 minutes) -[[TestingDirConnectionMaxStall]] **TestingDirConnectionMaxStall** __N__ **seconds**|**minutes**:: - Let a directory connection stall this long before expiring it. - Changing this requires that **TestingTorNetwork** is set. (Default: - 5 minutes) - [[TestingDirAuthVoteExit]] **TestingDirAuthVoteExit** __node__,__node__,__...__:: A list of identity fingerprints, country codes, and address patterns of nodes to vote Exit for regardless of their @@ -3434,40 +3461,70 @@ The following options are used for running a testing Tor network. In order for this option to have any effect, **TestingTorNetwork** has to be set. -[[TestingEnableConnBwEvent]] **TestingEnableConnBwEvent** **0**|**1**:: - If this option is set, then Tor controllers may register for CONN_BW - events. Changing this requires that **TestingTorNetwork** is set. - (Default: 0) +[[TestingDirConnectionMaxStall]] **TestingDirConnectionMaxStall** __N__ **seconds**|**minutes**:: + Let a directory connection stall this long before expiring it. + Changing this requires that **TestingTorNetwork** is set. (Default: + 5 minutes) [[TestingEnableCellStatsEvent]] **TestingEnableCellStatsEvent** **0**|**1**:: If this option is set, then Tor controllers may register for CELL_STATS events. Changing this requires that **TestingTorNetwork** is set. (Default: 0) -[[TestingMinExitFlagThreshold]] **TestingMinExitFlagThreshold** __N__ **KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: - Sets a lower-bound for assigning an exit flag when running as an - authority on a testing network. Overrides the usual default lower bound - of 4 KBytes. (Default: 0) +[[TestingEnableConnBwEvent]] **TestingEnableConnBwEvent** **0**|**1**:: + If this option is set, then Tor controllers may register for CONN_BW + events. Changing this requires that **TestingTorNetwork** is set. + (Default: 0) [[TestingLinkCertLifetime]] **TestingLinkCertLifetime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**|**months**:: Overrides the default lifetime for the certificates used to authenticate our X509 link cert with our ed25519 signing key. (Default: 2 days) -[[TestingAuthKeyLifetime]] **TestingAuthKeyLifetime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**|**months**:: - Overrides the default lifetime for a signing Ed25519 TLS Link authentication - key. - (Default: 2 days) - [[TestingLinkKeySlop]] **TestingLinkKeySlop** __N__ **seconds**|**minutes**|**hours** + -[[TestingAuthKeySlop]] **TestingAuthKeySlop** __N__ **seconds**|**minutes**|**hours** + +[[TestingMinExitFlagThreshold]] **TestingMinExitFlagThreshold** __N__ **KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: + Sets a lower-bound for assigning an exit flag when running as an + authority on a testing network. Overrides the usual default lower bound + of 4 KBytes. (Default: 0) + +[[TestingMinFastFlagThreshold]] **TestingMinFastFlagThreshold** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**:: + Minimum value for the Fast flag. Overrides the ordinary minimum taken + from the consensus when TestingTorNetwork is set. (Default: 0.) + +[[TestingServerConsensusDownloadInitialDelay]] **TestingServerConsensusDownloadInitialDelay** __N__:: + Initial delay in seconds for when servers should download consensuses. Changing this + requires that **TestingTorNetwork** is set. (Default: 0) + +[[TestingServerDownloadInitialDelay]] **TestingServerDownloadInitialDelay** __N__:: + Initial delay in seconds for when servers should download things in general. Changing this + requires that **TestingTorNetwork** is set. (Default: 0) [[TestingSigningKeySlop]] **TestingSigningKeySlop** __N__ **seconds**|**minutes**|**hours**:: How early before the official expiration of a an Ed25519 signing key do we replace it and issue a new key? (Default: 3 hours for link and auth; 1 day for signing.) +[[TestingV3AuthInitialDistDelay]] **TestingV3AuthInitialDistDelay** __N__ **minutes**|**hours**:: + Like V3AuthDistDelay, but for initial voting interval before + the first consensus has been created. Changing this requires that + **TestingTorNetwork** is set. (Default: 5 minutes) + +[[TestingV3AuthInitialVoteDelay]] **TestingV3AuthInitialVoteDelay** __N__ **minutes**|**hours**:: + Like V3AuthVoteDelay, but for initial voting interval before + the first consensus has been created. Changing this requires that + **TestingTorNetwork** is set. (Default: 5 minutes) + +[[TestingV3AuthInitialVotingInterval]] **TestingV3AuthInitialVotingInterval** __N__ **minutes**|**hours**:: + Like V3AuthVotingInterval, but for initial voting interval before the first + consensus has been created. Changing this requires that + **TestingTorNetwork** is set. (Default: 30 minutes) + +[[TestingV3AuthVotingStartOffset]] **TestingV3AuthVotingStartOffset** __N__ **seconds**|**minutes**|**hours**:: + Directory authorities offset voting start time by this much. + Changing this requires that **TestingTorNetwork** is set. (Default: 0) + + == NON-PERSISTENT OPTIONS These options are not saved to the torrc file by the "SAVECONF" controller @@ -3665,7 +3722,7 @@ __DataDirectory__/**`approved-routers`**:: __DataDirectory__ for an example fingerprint line. If the status is **!reject** then descriptors from the given identity (fingerprint/pubkey) are rejected by this server. If it is **!invalid** then descriptors are - accepted but marked in the directory as not valid, that is, not + accepted but marked in the directory as not valid, that is, not recommended. __DataDirectory__/**`v3-status-votes`**:: diff --git a/scripts/codegen/fuzzing_include_am.py b/scripts/codegen/fuzzing_include_am.py index aa3ba49a73..ae50563074 100755 --- a/scripts/codegen/fuzzing_include_am.py +++ b/scripts/codegen/fuzzing_include_am.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Future imports for Python 2.7, mandatory in 3.0 from __future__ import division diff --git a/scripts/codegen/gen_server_ciphers.py b/scripts/codegen/gen_server_ciphers.py index dd295b7f7d..8c88e54a13 100755 --- a/scripts/codegen/gen_server_ciphers.py +++ b/scripts/codegen/gen_server_ciphers.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright 2014-2019, The Tor Project, Inc # See LICENSE for licensing information @@ -101,7 +101,7 @@ def parse_cipher(ciph): fwsec, = m.groups() return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a") - print "/* Couldn't parse %s ! */"%ciph + print("/* Couldn't parse %s ! */"%ciph) return None @@ -125,12 +125,12 @@ for c in ALL_CIPHERS: colon = ' ":"' if c.name in MANDATORY: - print "%s/* Required */"%indent - print '%s%s%s'%(indent,c.name,colon) + print("%s/* Required */"%indent) + print('%s%s%s'%(indent,c.name,colon)) else: - print "#ifdef %s"%c.name - print '%s%s%s'%(indent,c.name,colon) - print "#endif" + print("#ifdef %s"%c.name) + print('%s%s%s'%(indent,c.name,colon)) + print("#endif") -print '%s;'%indent +print('%s;'%indent) diff --git a/scripts/codegen/get_mozilla_ciphers.py b/scripts/codegen/get_mozilla_ciphers.py index d149c71c27..ff01dd8719 100755 --- a/scripts/codegen/get_mozilla_ciphers.py +++ b/scripts/codegen/get_mozilla_ciphers.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # coding=utf-8 # Copyright 2011-2019, The Tor Project, Inc # original version by Arturo Filastò @@ -20,7 +20,7 @@ import re import sys if len(sys.argv) != 3: - print >>sys.stderr, "Syntax: get_mozilla_ciphers.py <firefox-source-dir> <openssl-source-dir>" + print("Syntax: get_mozilla_ciphers.py <firefox-source-dir> <openssl-source-dir>", file=sys.stderr) sys.exit(1) ff_root = sys.argv[1] @@ -176,13 +176,13 @@ for fl in oSSLinclude: fp.close() # Now generate the output. -print """\ +print("""\ /* This is an include file used to define the list of ciphers clients should * advertise. Before including it, you should define the CIPHER and XCIPHER * macros. * * This file was automatically generated by get_mozilla_ciphers.py. - */""" + */""") # Go in order by the order in CipherPrefs for firefox_macro in firefox_ciphers: @@ -215,4 +215,4 @@ for firefox_macro in firefox_ciphers: #else XCIPHER(%(hex)s, %(macro)s) #endif""" % format - print res + print(res) diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py index 7d8177f469..48d1d31a02 100644 --- a/scripts/codegen/makedesc.py +++ b/scripts/codegen/makedesc.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright 2014-2019, The Tor Project, Inc. # See LICENSE for license information @@ -24,12 +24,16 @@ import os import re import struct import time -import UserDict import slow_ed25519 import slownacl_curve25519 import ed25519_exts_ref +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + # Pull in the openssl stuff we need. crypt = ctypes.CDLL(ctypes.util.find_library('crypto')) @@ -252,8 +256,8 @@ class OnDemandKeys(object): def signdesc(body, args_out=None): - rsa, ident_pem, id_digest = make_key() - _, onion_pem, _ = make_key() + rsa, ident_pem, id_digest = make_rsa_key() + _, onion_pem, _ = make_rsa_key() need_ed = '{ED25519-CERT}' in body or '{ED25519-SIGNATURE}' in body if need_ed: @@ -303,10 +307,10 @@ def signdesc(body, args_out=None): return body.rstrip() def print_c_string(ident, body): - print "static const char %s[] =" % ident + print("static const char %s[] =" % ident) for line in body.split("\n"): - print ' "%s\\n"' %(line) - print " ;" + print(' "%s\\n"' %(line)) + print(" ;") def emit_ri(name, body): info = OnDemandKeys() @@ -320,8 +324,8 @@ def emit_ei(name, body): body = info.sign_desc(body) print_c_string("EX_EI_%s"%name.upper(), body) - print 'const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format( - d=info, NAME=name.upper()) + print('const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format( + d=info, NAME=name.upper())) print_c_string("EX_EI_%s_KEY"%name.upper(), info.RSA_IDENTITY) def analyze(s): diff --git a/scripts/git/git-merge-forward.sh b/scripts/git/git-merge-forward.sh index bbc5047cb7..247c605436 100755 --- a/scripts/git/git-merge-forward.sh +++ b/scripts/git/git-merge-forward.sh @@ -94,19 +94,19 @@ TOR_WKT_NAME=${TOR_WKT_NAME:-"tor-wkt"} MAINT_035_TB=( "maint-0.3.5" "" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" \ "_035" "") # Used in maint/release merge and test branch modes -MAINT_040=( "maint-0.4.0" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" \ - "_040" "_035") -MAINT_041=( "maint-0.4.1" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" \ - "_041" "_040") +MAINT_041=( "maint-0.4.1" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" \ + "_041" "_035") MAINT_042=( "maint-0.4.2" "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.2" \ "_042" "_041") -MAINT_MASTER=( "master" "maint-0.4.2" "$GIT_PATH/$TOR_MASTER_NAME" \ - "_master" "_042") +MAINT_043=( "maint-0.4.3" "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.3" \ + "_043" "_042") +MAINT_MASTER=( "master" "maint-0.4.3" "$GIT_PATH/$TOR_MASTER_NAME" \ + "_master" "_043") RELEASE_035=( "release-0.3.5" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) -RELEASE_040=( "release-0.4.0" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.0" ) RELEASE_041=( "release-0.4.1" "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.1" ) RELEASE_042=( "release-0.4.2" "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.2" ) +RELEASE_043=( "release-0.4.3" "maint-0.4.3" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.3" ) # The master branch path has to be the main repository thus contains the # origin that will be used to fetch the updates. All the worktrees are created @@ -116,14 +116,14 @@ ORIGIN_PATH="$GIT_PATH/$TOR_MASTER_NAME" # SC2034 -- shellcheck thinks that these are unused. We know better. ACTUALLY_THESE_ARE_USED=<<EOF ${MAINT_035_TB[0]} -${MAINT_040[0]} ${MAINT_041[0]} ${MAINT_042[0]} +${MAINT_043[0]} ${MAINT_MASTER[0]} ${RELEASE_035[0]} -${RELEASE_040[0]} ${RELEASE_041[0]} ${RELEASE_042[0]} +${RELEASE_043[0]} EOF ####################### @@ -181,15 +181,15 @@ if [ -z "$TEST_BRANCH_PREFIX" ]; then # maint branch RELEASE_035[@] - MAINT_040[@] - RELEASE_040[@] - MAINT_041[@] RELEASE_041[@] MAINT_042[@] RELEASE_042[@] + MAINT_043[@] + RELEASE_043[@] + MAINT_MASTER[@] ) @@ -203,12 +203,12 @@ else # We want a test branch based on the earliest maint branch MAINT_035_TB[@] - MAINT_040[@] - MAINT_041[@] MAINT_042[@] + MAINT_043[@] + MAINT_MASTER[@] ) diff --git a/scripts/git/git-pull-all.sh b/scripts/git/git-pull-all.sh index c8d115da01..eb3e1c8881 100755 --- a/scripts/git/git-pull-all.sh +++ b/scripts/git/git-pull-all.sh @@ -59,15 +59,15 @@ TOR_WKT_NAME=${TOR_WKT_NAME:-"tor-wkt"} # First set of arrays are the maint-* branch and then the release-* branch. # New arrays need to be in the WORKTREE= array else they aren't considered. MAINT_035=( "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" ) -MAINT_040=( "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" ) MAINT_041=( "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" ) MAINT_042=( "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.2" ) +MAINT_043=( "maint-0.4.3" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.3" ) MAINT_MASTER=( "master" "$GIT_PATH/$TOR_MASTER_NAME" ) RELEASE_035=( "release-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) -RELEASE_040=( "release-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.0" ) RELEASE_041=( "release-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.1" ) RELEASE_042=( "release-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.2" ) +RELEASE_043=( "release-0.4.3" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.3" ) # The master branch path has to be the main repository thus contains the # origin that will be used to fetch the updates. All the worktrees are created @@ -77,14 +77,14 @@ ORIGIN_PATH="$GIT_PATH/$TOR_MASTER_NAME" # SC2034 -- shellcheck thinks that these are unused. We know better. ACTUALLY_THESE_ARE_USED=<<EOF ${MAINT_035[0]} -${MAINT_040[0]} ${MAINT_041[0]} ${MAINT_042[0]} +${MAINT_043[0]} ${MAINT_MASTER[0]} ${RELEASE_035[0]} -${RELEASE_040[0]} ${RELEASE_041[0]} ${RELEASE_042[0]} +${RELEASE_043[0]} EOF ########################### @@ -96,15 +96,15 @@ WORKTREE=( MAINT_035[@] RELEASE_035[@] - MAINT_040[@] - RELEASE_040[@] - MAINT_041[@] RELEASE_041[@] MAINT_042[@] RELEASE_042[@] + MAINT_043[@] + RELEASE_043[@] + MAINT_MASTER[@] ) COUNT=${#WORKTREE[@]} diff --git a/scripts/git/git-push-all.sh b/scripts/git/git-push-all.sh index 0abddc8023..cb7bb5269b 100755 --- a/scripts/git/git-push-all.sh +++ b/scripts/git/git-push-all.sh @@ -172,18 +172,18 @@ DEFAULT_UPSTREAM_BRANCHES= if [ "$DEFAULT_UPSTREAM_REMOTE" != "$UPSTREAM_REMOTE" ]; then DEFAULT_UPSTREAM_BRANCHES=$(echo \ "$DEFAULT_UPSTREAM_REMOTE"/master \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.3 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.2 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ - "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ ) fi UPSTREAM_BRANCHES=$(echo \ "$UPSTREAM_REMOTE"/master \ + "$UPSTREAM_REMOTE"/{release,maint}-0.4.3 \ "$UPSTREAM_REMOTE"/{release,maint}-0.4.2 \ "$UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ - "$UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ "$UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ ) @@ -193,9 +193,9 @@ UPSTREAM_BRANCHES=$(echo \ PUSH_BRANCHES=$(echo \ master \ + {release,maint}-0.4.3 \ {release,maint}-0.4.2 \ {release,maint}-0.4.1 \ - {release,maint}-0.4.0 \ {release,maint}-0.3.5 \ ) @@ -206,9 +206,9 @@ if [ -z "$TEST_BRANCH_PREFIX" ]; then # List of branches to push. Ordering is not important. PUSH_BRANCHES=$(echo \ master \ + {release,maint}-0.4.3 \ {release,maint}-0.4.2 \ {release,maint}-0.4.1 \ - {release,maint}-0.4.0 \ {release,maint}-0.3.5 \ ) else @@ -218,9 +218,9 @@ else # List of branches to push. Ordering is not important. PUSH_BRANCHES=" \ ${TEST_BRANCH_PREFIX}_master \ + ${TEST_BRANCH_PREFIX}_043 \ ${TEST_BRANCH_PREFIX}_042 \ ${TEST_BRANCH_PREFIX}_041 \ - ${TEST_BRANCH_PREFIX}_040 \ ${TEST_BRANCH_PREFIX}_035 \ " fi diff --git a/scripts/git/git-setup-dirs.sh b/scripts/git/git-setup-dirs.sh index 20a148204a..2d16cc1d66 100755 --- a/scripts/git/git-setup-dirs.sh +++ b/scripts/git/git-setup-dirs.sh @@ -97,15 +97,15 @@ GITHUB_PUSH=${TOR_GITHUB_PUSH:-"No_Pushing_To_GitHub"} # First set of arrays are the maint-* branch and then the release-* branch. # New arrays need to be in the WORKTREE= array else they aren't considered. MAINT_035=( "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" ) -MAINT_040=( "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" ) MAINT_041=( "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" ) MAINT_042=( "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.2" ) +MAINT_043=( "maint-0.4.3" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.3" ) MAINT_MASTER=( "master" "$GIT_PATH/$TOR_MASTER_NAME" ) RELEASE_035=( "release-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) -RELEASE_040=( "release-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.0" ) RELEASE_041=( "release-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.1" ) RELEASE_042=( "release-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.2" ) +RELEASE_043=( "release-0.4.3" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.3" ) # The master branch path has to be the main repository thus contains the # origin that will be used to fetch the updates. All the worktrees are created @@ -115,14 +115,14 @@ ORIGIN_PATH="$GIT_PATH/$TOR_MASTER_NAME" # SC2034 -- shellcheck thinks that these are unused. We know better. ACTUALLY_THESE_ARE_USED=<<EOF ${MAINT_035[0]} -${MAINT_040[0]} ${MAINT_041[0]} ${MAINT_042[0]} +${MAINT_043[0]} ${MAINT_MASTER[0]} ${RELEASE_035[0]} -${RELEASE_040[0]} ${RELEASE_041[0]} ${RELEASE_042[0]} +${RELEASE_043[0]} EOF ####################### @@ -165,15 +165,15 @@ WORKTREE=( MAINT_035[@] RELEASE_035[@] - MAINT_040[@] - RELEASE_040[@] - MAINT_041[@] RELEASE_041[@] MAINT_042[@] RELEASE_042[@] + MAINT_043[@] + RELEASE_043[@] + MAINT_MASTER[@] ) diff --git a/scripts/git/pre-commit.git-hook b/scripts/git/pre-commit.git-hook index d5a75f2794..f630a242bd 100755 --- a/scripts/git/pre-commit.git-hook +++ b/scripts/git/pre-commit.git-hook @@ -17,13 +17,14 @@ if [ $# -eq 0 ]; then # When called in pre-commit, check the files modified in this commit CHECK_FILTER="git diff --cached --name-only --diff-filter=ACMR" # Use the appropriate owned tor source list to filter the changed files - if [ -d src/lib ]; then - # This is the layout in 0.3.5 - # Keep these lists consistent: - # - OWNED_TOR_C_FILES in Makefile.am - # - CHECK_FILES in pre-commit.git-hook and pre-push.git-hook - # - try_parse in check_cocci_parse.sh - CHECK_FILES="$($CHECK_FILTER \ + + # This is the layout in 0.3.5 and later. + + # Keep these lists consistent: + # - OWNED_TOR_C_FILES in Makefile.am + # - CHECK_FILES in pre-commit.git-hook and pre-push.git-hook + # - try_parse in check_cocci_parse.sh + CHECK_FILES="$($CHECK_FILTER \ src/lib/*/*.[ch] \ src/core/*/*.[ch] \ src/feature/*/*.[ch] \ @@ -31,17 +32,7 @@ if [ $# -eq 0 ]; then src/test/*.[ch] \ src/test/*/*.[ch] \ src/tools/*.[ch] \ - )" - elif [ -d src/common ]; then - # This was the layout before 0.3.5 - CHECK_FILES="$($CHECK_FILTER \ - src/common/*/*.[ch] \ - src/or/*/*.[ch] \ - src/test/*.[ch] \ - src/test/*/*.[ch] \ - src/tools/*.[ch] - )" - fi + )" else # When called in pre-push, concatenate the argument array # Fails on special characters in file names diff --git a/scripts/git/pre-push.git-hook b/scripts/git/pre-push.git-hook index 8b5efb0a9d..efa45b9860 100755 --- a/scripts/git/pre-push.git-hook +++ b/scripts/git/pre-push.git-hook @@ -26,7 +26,11 @@ z40=0000000000000000000000000000000000000000 upstream_name=${TOR_UPSTREAM_REMOTE_NAME:-"upstream"} +# The working directory workdir=$(git rev-parse --show-toplevel) +# The .git directory +# If $workdir is a worktree, then $gitdir is not $workdir/.git +gitdir=$(git rev-parse --git-dir) cd "$workdir" || exit 1 @@ -58,18 +62,18 @@ do fi # Call the pre-commit hook for the common checks, if it is executable - if [ -x scripts/git/pre-commit.git-hook ]; then + pre_commit=${gitdir}/hooks/pre-commit + if [ -x "$pre_commit" ]; then # Only check the files newly modified in this branch CHECK_FILTER="git diff --name-only --diff-filter=ACMR $range" # Use the appropriate owned tor source list to filter the changed # files - if [ -d src/lib ]; then - # This is the layout in 0.3.5 - # Keep these lists consistent: - # - OWNED_TOR_C_FILES in Makefile.am - # - CHECK_FILES in pre-commit.git-hook and pre-push.git-hook - # - try_parse in check_cocci_parse.sh - CHECK_FILES="$($CHECK_FILTER \ + # This is the layout in 0.3.5 + # Keep these lists consistent: + # - OWNED_TOR_C_FILES in Makefile.am + # - CHECK_FILES in pre-commit.git-hook and pre-push.git-hook + # - try_parse in check_cocci_parse.sh + CHECK_FILES="$($CHECK_FILTER \ src/lib/*/*.[ch] \ src/core/*/*.[ch] \ src/feature/*/*.[ch] \ @@ -77,22 +81,12 @@ do src/test/*.[ch] \ src/test/*/*.[ch] \ src/tools/*.[ch] \ - )" - elif [ -d src/common ]; then - # This was the layout before 0.3.5 - CHECK_FILES="$($CHECK_FILTER \ - src/common/*/*.[ch] \ - src/or/*/*.[ch] \ - src/test/*.[ch] \ - src/test/*/*.[ch] \ - src/tools/*.[ch] \ - )" - fi + )" # We want word splitting here, because file names are space # separated # shellcheck disable=SC2086 - if ! scripts/git/pre-commit.git-hook $CHECK_FILES ; then + if ! "$pre_commit" $CHECK_FILES ; then exit 1 fi fi diff --git a/scripts/maint/annotate_ifdef_directives.py b/scripts/maint/annotate_ifdef_directives.py index cd70b55c8c..9ca090d595 100755 --- a/scripts/maint/annotate_ifdef_directives.py +++ b/scripts/maint/annotate_ifdef_directives.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (c) 2017-2019, The Tor Project, Inc. # See LICENSE for licensing information diff --git a/scripts/maint/checkIncludes.py b/scripts/maint/checkIncludes.py index 2ca46347f0..ae0ccb9e12 100755 --- a/scripts/maint/checkIncludes.py +++ b/scripts/maint/checkIncludes.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright 2018 The Tor Project, Inc. See LICENSE file for licensing info. # This file is no longer here; see practracker/includes.py for this diff --git a/scripts/maint/checkManpageAlpha.py b/scripts/maint/checkManpageAlpha.py new file mode 100755 index 0000000000..70421c2fd1 --- /dev/null +++ b/scripts/maint/checkManpageAlpha.py @@ -0,0 +1,72 @@ +#!/usr/bin/python + +import difflib +import re +import sys + +# Assume we only use the "== Section Name" section title syntax +sectionheader_re = re.compile(r'^==+\s(.*)\s*$') + +# Assume we only use the "[[ItemName]]" anchor syntax +anchor_re = re.compile(r'^\[\[([^]]+)\]\]') + +class Reader(object): + def __init__(self): + self.d = {} + # Initial state is to gather section headers + self.getline = self._getsec + self.section = None + + def _getsec(self, line): + """Read a section header + + Prepare to gather anchors from subsequent lines. Don't change + state if the line isn't a section header. + """ + m = sectionheader_re.match(line) + if not m: + return + self.anchors = anchors = [] + self.d[m.group(1)] = anchors + self.getline = self._getanchor + + def _getanchor(self, line): + """Read an anchor for an item definition + + Append the anchor names to the list of items in the current + section. + """ + m = anchor_re.match(line) + if not m: + return self._getsec(line) + self.anchors.append(m.group(1)) + + def diffsort(self, key): + """Unified diff of unsorted and sorted item lists + """ + # Append newlines because difflib works better with them + a = [s + '\n' for s in self.d[key]] + b = sorted(a, key=str.lower) + return difflib.unified_diff(a, b, fromfile=key+' unsorted', + tofile=key+' sorted') + +def main(): + """Diff unsorted and sorted lists of option names in a manpage + + Use the file named by the first argument, or standard input if + there is none. + """ + try: + fname = sys.argv[1] + f = open(fname, 'r') + except IndexError: + f = sys.stdin + + reader = Reader() + for line in f: + reader.getline(line) + for key in sorted(reader.d.keys(), key=str.lower): + sys.stdout.writelines(reader.diffsort(key)) + +if __name__ == '__main__': + main() diff --git a/scripts/maint/format_changelog.py b/scripts/maint/format_changelog.py index 5f04a44ef6..7cf55a0d96 100755 --- a/scripts/maint/format_changelog.py +++ b/scripts/maint/format_changelog.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (c) 2014-2019, The Tor Project, Inc. # See LICENSE for licensing information # @@ -291,7 +291,7 @@ class ChangeLog(object): self.curgraf.append(line) else: - assert "This" is "unreachable" + assert "This" is "unreachable" # noqa: F632 def lint_head(self, line, head): m = re.match(r'^ *o ([^\(]+)((?:\([^\)]+\))?):', head) diff --git a/scripts/maint/lintChanges.py b/scripts/maint/lintChanges.py index 88a865a572..cf7b09fcc3 100755 --- a/scripts/maint/lintChanges.py +++ b/scripts/maint/lintChanges.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Future imports for Python 2.7, mandatory in 3.0 from __future__ import division @@ -25,7 +25,12 @@ KNOWN_GROUPS = set([ "Code simplification and refactoring", "Removed features", "Deprecated features", - "Directory authority changes"]) + "Directory authority changes", + + # These aren't preferred, but sortChanges knows how to clean them up. + "Code simplifications and refactoring", + "Code simplification and refactorings", + "Code simplifications and refactorings"]) NEEDS_SUBCATEGORIES = set([ "Minor bugfix", diff --git a/scripts/maint/locatemissingdoxygen.py b/scripts/maint/locatemissingdoxygen.py index 9e58bd3477..a2844346d6 100755 --- a/scripts/maint/locatemissingdoxygen.py +++ b/scripts/maint/locatemissingdoxygen.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ This script parses the stderr output of doxygen and looks for undocumented @@ -34,10 +34,10 @@ def buildWarnings(): def count(fn): if os.path.abspath(fn) not in warnings: - print "0\t%s"%fn + print("0\t%s"%fn) else: n = len(warnings[os.path.abspath(fn)]) - print "%d\t%s"%(n,fn) + print("%d\t%s"%(n,fn)) def getIndentation(line): s = line.lstrip() @@ -67,7 +67,7 @@ def annotate(filename): if __name__ == '__main__': if len(sys.argv) == 1: - print "Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log" + print("Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log") sys.exit(1) buildWarnings() if sys.argv[1] == '-A': diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index 09c496c6dd..b4ef1e51aa 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -35,7 +35,6 @@ problem file-size /src/app/config/config.c 7400 problem include-count /src/app/config/config.c 80 -problem function-size /src/app/config/config.c:options_act_reversible() 298 problem function-size /src/app/config/config.c:options_act() 381 problem function-size /src/app/config/config.c:resolve_my_address() 190 problem function-size /src/app/config/config.c:options_validate_cb() 780 @@ -48,8 +47,8 @@ problem function-size /src/app/config/config.c:parse_dir_authority_line() 150 problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101 problem function-size /src/app/config/config.c:port_parse_config() 450 problem function-size /src/app/config/config.c:parse_ports() 132 -problem file-size /src/app/config/or_options_st.h 1115 -problem include-count /src/app/main/main.c 69 +problem file-size /src/app/config/or_options_st.h 1053 +problem include-count /src/app/main/main.c 68 problem function-size /src/app/main/main.c:dumpstats() 102 problem function-size /src/app/main/main.c:tor_init() 101 problem function-size /src/app/main/main.c:sandbox_init_filter() 291 @@ -63,17 +62,16 @@ problem dependency-violation /src/core/crypto/onion_tap.c 3 problem dependency-violation /src/core/crypto/relay_crypto.c 9 problem file-size /src/core/mainloop/connection.c 5577 problem include-count /src/core/mainloop/connection.c 62 -problem function-size /src/core/mainloop/connection.c:connection_free_minimal() 185 +problem function-size /src/core/mainloop/connection.c:connection_free_minimal() 181 problem function-size /src/core/mainloop/connection.c:connection_listener_new() 324 problem function-size /src/core/mainloop/connection.c:connection_handle_listener_read() 161 -problem function-size /src/core/mainloop/connection.c:connection_proxy_connect() 148 problem function-size /src/core/mainloop/connection.c:connection_read_proxy_handshake() 153 problem function-size /src/core/mainloop/connection.c:retry_listener_ports() 112 problem function-size /src/core/mainloop/connection.c:connection_handle_read_impl() 111 problem function-size /src/core/mainloop/connection.c:connection_buf_read_from_socket() 180 problem function-size /src/core/mainloop/connection.c:connection_handle_write_impl() 241 problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143 -problem dependency-violation /src/core/mainloop/connection.c 44 +problem dependency-violation /src/core/mainloop/connection.c 47 problem dependency-violation /src/core/mainloop/cpuworker.c 12 problem include-count /src/core/mainloop/mainloop.c 64 problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 108 @@ -85,9 +83,9 @@ problem dependency-violation /src/core/mainloop/netstatus.c 4 problem dependency-violation /src/core/mainloop/periodic.c 2 problem dependency-violation /src/core/or/address_set.c 1 problem dependency-violation /src/core/or/cell_queue_st.h 1 -problem file-size /src/core/or/channel.c 3487 +problem file-size /src/core/or/channel.c 3464 problem dependency-violation /src/core/or/channel.c 9 -problem file-size /src/core/or/channel.h 781 +problem file-size /src/core/or/channel.h 775 problem dependency-violation /src/core/or/channel.h 1 problem dependency-violation /src/core/or/channelpadding.c 6 problem function-size /src/core/or/channeltls.c:channel_tls_handle_var_cell() 160 @@ -105,7 +103,6 @@ problem include-count /src/core/or/circuitlist.c 55 problem function-size /src/core/or/circuitlist.c:HT_PROTOTYPE() 109 problem function-size /src/core/or/circuitlist.c:circuit_free_() 146 problem function-size /src/core/or/circuitlist.c:circuit_find_to_cannibalize() 101 -problem function-size /src/core/or/circuitlist.c:circuit_about_to_free() 120 problem function-size /src/core/or/circuitlist.c:circuits_handle_oom() 117 problem dependency-violation /src/core/or/circuitlist.c 19 problem dependency-violation /src/core/or/circuitlist.h 1 @@ -123,7 +120,7 @@ problem function-size /src/core/or/circuitstats.c:circuit_build_times_parse_stat problem dependency-violation /src/core/or/circuitstats.c 11 problem file-size /src/core/or/circuituse.c 3162 problem function-size /src/core/or/circuituse.c:circuit_is_acceptable() 128 -problem function-size /src/core/or/circuituse.c:circuit_expire_building() 394 +problem function-size /src/core/or/circuituse.c:circuit_expire_building() 389 problem function-size /src/core/or/circuituse.c:circuit_log_ancient_one_hop_circuits() 126 problem function-size /src/core/or/circuituse.c:circuit_build_failed() 149 problem function-size /src/core/or/circuituse.c:circuit_launch_by_extend_info() 108 @@ -146,23 +143,22 @@ problem function-size /src/core/or/connection_edge.c:connection_exit_connect() 1 problem dependency-violation /src/core/or/connection_edge.c 27 problem dependency-violation /src/core/or/connection_edge.h 1 problem file-size /src/core/or/connection_or.c 3122 -problem include-count /src/core/or/connection_or.c 51 problem function-size /src/core/or/connection_or.c:connection_or_group_set_badness_() 105 problem function-size /src/core/or/connection_or.c:connection_or_client_learned_peer_id() 142 -problem function-size /src/core/or/connection_or.c:connection_or_compute_authenticate_cell_body() 231 problem dependency-violation /src/core/or/connection_or.c 20 problem dependency-violation /src/core/or/dos.c 6 problem dependency-violation /src/core/or/onion.c 2 problem file-size /src/core/or/or.h 1107 -problem include-count /src/core/or/or.h 49 +problem include-count /src/core/or/or.h 48 problem dependency-violation /src/core/or/or.h 1 problem dependency-violation /src/core/or/or_periodic.c 1 -problem file-size /src/core/or/policies.c 3249 +problem file-size /src/core/or/policies.c 3195 problem function-size /src/core/or/policies.c:policy_summarize() 107 problem dependency-violation /src/core/or/policies.c 14 problem function-size /src/core/or/protover.c:protover_all_supported() 117 problem dependency-violation /src/core/or/reasons.c 2 problem file-size /src/core/or/relay.c 3264 +problem dependency-violation /src/core/or/relay_handshake.c 5 problem function-size /src/core/or/relay.c:circuit_receive_relay_cell() 127 problem function-size /src/core/or/relay.c:relay_send_command_from_edge_() 109 problem function-size /src/core/or/relay.c:connection_ap_process_end_not_open() 192 @@ -207,15 +203,15 @@ problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_misc problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_dir() 297 problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_events() 234 problem function-size /src/feature/dirauth/bwauth.c:dirserv_read_measured_bandwidths() 121 -problem file-size /src/feature/dirauth/dirvote.c 4700 +problem file-size /src/feature/dirauth/dirvote.c 4687 problem include-count /src/feature/dirauth/dirvote.c 53 -problem function-size /src/feature/dirauth/dirvote.c:format_networkstatus_vote() 231 +problem function-size /src/feature/dirauth/dirvote.c:format_networkstatus_vote() 230 problem function-size /src/feature/dirauth/dirvote.c:networkstatus_compute_bw_weights_v10() 233 -problem function-size /src/feature/dirauth/dirvote.c:networkstatus_compute_consensus() 956 +problem function-size /src/feature/dirauth/dirvote.c:networkstatus_compute_consensus() 952 problem function-size /src/feature/dirauth/dirvote.c:networkstatus_add_detached_signatures() 119 problem function-size /src/feature/dirauth/dirvote.c:dirvote_add_vote() 162 problem function-size /src/feature/dirauth/dirvote.c:dirvote_compute_consensuses() 164 -problem function-size /src/feature/dirauth/dirvote.c:dirserv_generate_networkstatus_vote_obj() 283 +problem function-size /src/feature/dirauth/dirvote.c:dirserv_generate_networkstatus_vote_obj() 281 problem function-size /src/feature/dirauth/dsigs_parse.c:networkstatus_parse_detached_signatures() 196 problem function-size /src/feature/dirauth/guardfraction.c:dirserv_read_guardfraction_file_from_str() 109 problem function-size /src/feature/dirauth/process_descs.c:dirserv_add_descriptor() 125 @@ -226,7 +222,7 @@ problem function-size /src/feature/dircache/consdiffmgr.c:consdiffmgr_rescan_fla problem function-size /src/feature/dircache/consdiffmgr.c:consensus_diff_worker_threadfn() 132 problem function-size /src/feature/dircache/dircache.c:handle_get_current_consensus() 165 problem function-size /src/feature/dircache/dircache.c:directory_handle_command_post() 124 -problem file-size /src/feature/dirclient/dirclient.c 3165 +problem file-size /src/feature/dirclient/dirclient.c 3156 problem include-count /src/feature/dirclient/dirclient.c 51 problem function-size /src/feature/dirclient/dirclient.c:directory_get_from_dirserver() 126 problem function-size /src/feature/dirclient/dirclient.c:directory_initiate_request() 201 @@ -248,7 +244,6 @@ problem function-size /src/feature/hibernate/hibernate.c:accounting_parse_option problem function-size /src/feature/hs/hs_cell.c:hs_cell_build_establish_intro() 115 problem function-size /src/feature/hs/hs_cell.c:hs_cell_parse_introduce2() 152 problem function-size /src/feature/hs/hs_client.c:send_introduce1() 103 -problem function-size /src/feature/hs/hs_client.c:hs_config_client_authorization() 107 problem function-size /src/feature/hs/hs_common.c:hs_get_responsible_hsdirs() 102 problem function-size /src/feature/hs/hs_config.c:config_service_v3() 128 problem function-size /src/feature/hs/hs_config.c:config_generic_service() 138 @@ -257,11 +252,11 @@ problem function-size /src/feature/hs/hs_descriptor.c:decrypt_desc_layer() 111 problem function-size /src/feature/hs/hs_descriptor.c:decode_introduction_point() 122 problem function-size /src/feature/hs/hs_descriptor.c:desc_decode_superencrypted_v3() 107 problem function-size /src/feature/hs/hs_descriptor.c:desc_decode_encrypted_v3() 109 -problem file-size /src/feature/hs/hs_service.c 4172 +problem file-size /src/feature/hs/hs_service.c 4131 problem function-size /src/feature/keymgt/loadkey.c:ed_key_init_from_file() 326 problem function-size /src/feature/nodelist/authcert.c:trusted_dirs_load_certs_from_string() 123 problem function-size /src/feature/nodelist/authcert.c:authority_certs_fetch_missing() 295 -problem function-size /src/feature/nodelist/fmt_routerstatus.c:routerstatus_format_entry() 162 +problem function-size /src/feature/nodelist/fmt_routerstatus.c:routerstatus_format_entry() 158 problem function-size /src/feature/nodelist/microdesc.c:microdesc_cache_rebuild() 134 problem include-count /src/feature/nodelist/networkstatus.c 63 problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_check_consensus_signature() 175 @@ -279,6 +274,7 @@ problem function-size /src/feature/nodelist/routerlist.c:update_extrainfo_downlo problem function-size /src/feature/relay/dns.c:dns_resolve_impl() 131 problem function-size /src/feature/relay/dns.c:configure_nameservers() 161 problem function-size /src/feature/relay/dns.c:evdns_callback() 108 +problem function-size /src/feature/relay/relay_handshake.c:connection_or_compute_authenticate_cell_body() 231 problem file-size /src/feature/relay/router.c 3520 problem include-count /src/feature/relay/router.c 57 problem function-size /src/feature/relay/router.c:init_keys() 252 diff --git a/scripts/maint/practracker/includes.py b/scripts/maint/practracker/includes.py index fe0f32e253..e9b02c35b0 100755 --- a/scripts/maint/practracker/includes.py +++ b/scripts/maint/practracker/includes.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright 2018 The Tor Project, Inc. See LICENSE file for licensing info. """This script looks through all the directories for files matching *.c or diff --git a/scripts/maint/practracker/metrics.py b/scripts/maint/practracker/metrics.py index ae88b84f31..300a4501a9 100644 --- a/scripts/maint/practracker/metrics.py +++ b/scripts/maint/practracker/metrics.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Implementation of various source code metrics. # These are currently ad-hoc string operations and regexps. diff --git a/scripts/maint/practracker/practracker.py b/scripts/maint/practracker/practracker.py index e806aef3b4..76ffd64cfb 100755 --- a/scripts/maint/practracker/practracker.py +++ b/scripts/maint/practracker/practracker.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ Best-practices tracker for Tor source code. @@ -24,12 +24,13 @@ from __future__ import division from __future__ import print_function from __future__ import unicode_literals -import os, sys +import codecs, os, sys import metrics import util import problem import includes +import shutil # The filename of the exceptions file (it should be placed in the practracker directory) EXCEPTIONS_FNAME = "./exceptions.txt" @@ -62,12 +63,8 @@ TOR_TOPDIR = None ####################################################### -if sys.version_info[0] <= 2: - def open_file(fname): - return open(fname, 'r') -else: - def open_file(fname): - return open(fname, 'r', encoding='utf-8') +def open_file(fname): + return codecs.open(fname, 'r', encoding='utf-8') def consider_file_size(fname, f): """Consider the size of 'f' and yield an FileSizeItem for it. @@ -185,6 +182,9 @@ def main(argv): help="Regenerate the exceptions file") parser.add_argument("--list-overbroad", action="store_true", help="List over-broad exceptions") + parser.add_argument("--regen-overbroad", action="store_true", + help="Regenerate the exceptions file, " + "removing over-broad exceptions.") parser.add_argument("--exceptions", help="Override the location for the exceptions file") parser.add_argument("--strict", action="store_true", @@ -227,8 +227,9 @@ def main(argv): filt.addThreshold(problem.DependencyViolationItem("*.c", int(args.max_dependency_violations))) filt.addThreshold(problem.DependencyViolationItem("*.h", int(args.max_dependency_violations))) - if args.list_overbroad and args.regen: - print("Cannot use --regen with --list-overbroad", + if args.list_overbroad + args.regen + args.regen_overbroad > 1: + print("Cannot use more than one of --regen, --list-overbroad, and " + "--regen-overbroad.", file=sys.stderr) sys.exit(1) @@ -247,13 +248,15 @@ def main(argv): ProblemVault = problem.ProblemVault(exceptions_file) problem_file = sys.stdout - if args.list_overbroad: - # If we're listing overbroad exceptions, don't list problems. + if args.list_overbroad or args.regen_overbroad: + # If we're looking for overbroad exceptions, don't list problems + # immediately to the problem file. problem_file = util.NullFile() # 2.1) Adjust the exceptions so that we warn only about small problems, # and produce errors on big ones. - if not (args.regen or args.list_overbroad or args.strict): + if not (args.regen or args.list_overbroad or args.regen_overbroad or + args.strict): ProblemVault.set_tolerances(TOLERANCE_FNS) # 3) Go through all the files and report problems if they are not exceptions @@ -269,7 +272,17 @@ def main(argv): if args.regen: tmpfile.close() - os.rename(tmpname, exceptions_file) + shutil.move(tmpname, exceptions_file) + sys.exit(0) + + if args.regen_overbroad: + tmpname = exceptions_file + ".tmp" + tmpfile = open(tmpname, "w") + tmpfile.write(HEADER) + for item in ProblemVault.list_exceptions_without_overbroad(): + print(item, file=tmpfile) + tmpfile.close() + shutil.move(tmpname, exceptions_file) sys.exit(0) # If new issues were found, try to give out some advice to the developer on how to resolve it. @@ -296,6 +309,7 @@ variable. else: print(ex, "->", p.metric_value) + sys.exit(found_new_issues) if __name__ == '__main__': diff --git a/scripts/maint/practracker/practracker_tests.py b/scripts/maint/practracker/practracker_tests.py index 8d0418880c..e03c9e05ae 100755 --- a/scripts/maint/practracker/practracker_tests.py +++ b/scripts/maint/practracker/practracker_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """Some simple tests for practracker metrics""" diff --git a/scripts/maint/practracker/problem.py b/scripts/maint/practracker/problem.py index bee5eeb903..a3255dcc80 100644 --- a/scripts/maint/practracker/problem.py +++ b/scripts/maint/practracker/problem.py @@ -29,6 +29,8 @@ class ProblemVault(object): def __init__(self, exception_fname=None): # Exception dictionary: { problem.key() : Problem object } self.exceptions = {} + # Exception list: list of Problem objects, in the order added. + self.exception_list = [] # Exception dictionary: maps key to the problem it was used to # suppress. self.used_exception_for = {} @@ -63,6 +65,7 @@ class ProblemVault(object): sys.exit(1) self.exceptions[problem.key()] = problem + self.exception_list.append(problem) #print "Registering exception: %s" % problem def register_problem(self, problem): @@ -98,6 +101,24 @@ class ProblemVault(object): if p is None or e.is_worse_than(p): yield (e, p) + def list_exceptions_without_overbroad(self): + """Return an iterator of new problems, such that overbroad + exceptions are replaced with minimally broad versions, or removed. + """ + for e in self.exception_list: + p = self.used_exception_for.get(e.key()) + if p is None: + # This exception wasn't needed at all. + continue + if e.is_worse_than(p): + # The exception is worse than the problem we found. + # Yield the problem as the new exception value. + yield p + else: + # The problem is as bad as the exception, or worse. + # Yield the exception. + yield e + def set_tolerances(self, fns): """Adjust the tolerances for the exceptions in this vault. Takes a map of problem type to a function that adjusts the permitted diff --git a/scripts/maint/practracker/test_practracker.sh b/scripts/maint/practracker/test_practracker.sh index afc267a000..e29b9106de 100755 --- a/scripts/maint/practracker/test_practracker.sh +++ b/scripts/maint/practracker/test_practracker.sh @@ -82,3 +82,15 @@ run_practracker --exceptions "${DATA}/ex1.txt" --list-overbroad \ compare "${TMPDIR}/ex1-overbroad-received.txt" \ "${DATA}/ex1-overbroad-expected.txt" + +echo "ex1.regen:" + +cp "${DATA}/ex1.txt" "${TMPDIR}/ex1-copy.txt" +run_practracker --exceptions "${TMPDIR}/ex1-copy.txt" --regen >/dev/null 2>&1 +compare "${TMPDIR}/ex1-copy.txt" "${DATA}/ex1-regen-expected.txt" + +echo "ex1.regen_overbroad:" + +cp "${DATA}/ex1.txt" "${TMPDIR}/ex1-copy.txt" +run_practracker --exceptions "${TMPDIR}/ex1-copy.txt" --regen-overbroad >/dev/null 2>&1 +compare "${TMPDIR}/ex1-copy.txt" "${DATA}/ex1-regen-overbroad-expected.txt" diff --git a/scripts/maint/practracker/testdata/ex1-regen-expected.txt b/scripts/maint/practracker/testdata/ex1-regen-expected.txt new file mode 100644 index 0000000000..bdf3681edf --- /dev/null +++ b/scripts/maint/practracker/testdata/ex1-regen-expected.txt @@ -0,0 +1,46 @@ +# Welcome to the exceptions file for Tor's best-practices tracker! +# +# Each line of this file represents a single violation of Tor's best +# practices -- typically, a violation that we had before practracker.py +# first existed. +# +# There are three kinds of problems that we recognize right now: +# function-size -- a function of more than 100 lines. +# file-size -- a .c file of more than 3000 lines, or a .h +# file with more than 500 lines. +# include-count -- a .c file with more than 50 #includes, +# or a .h file with more than 15 #includes. +# dependency-violation -- a file includes a header that it should +# not, according to an advisory .may_include file. +# +# Each line below represents a single exception that practracker should +# _ignore_. Each line has four parts: +# 1. The word "problem". +# 2. The kind of problem. +# 3. The location of the problem: either a filename, or a +# filename:functionname pair. +# 4. The magnitude of the problem to ignore. +# +# So for example, consider this line: +# problem file-size /src/core/or/connection_or.c 3200 +# +# It tells practracker to allow the mentioned file to be up to 3200 lines +# long, even though ordinarily it would warn about any file with more than +# 3000 lines. +# +# You can either edit this file by hand, or regenerate it completely by +# running `make practracker-regen`. +# +# Remember: It is better to fix the problem than to add a new exception! + +problem file-size a.c 41 +problem include-count a.c 6 +problem function-size a.c:i_am_a_function() 9 +problem function-size a.c:another_function() 12 +problem dependency-violation a.c 4 +problem file-size b.c 15 +problem function-size b.c:foo() 4 +problem function-size b.c:bar() 5 +problem file-size header.h 8 +problem include-count header.h 4 +problem dependency-violation header.h 3 diff --git a/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt b/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt new file mode 100644 index 0000000000..4521029b10 --- /dev/null +++ b/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt @@ -0,0 +1,45 @@ +# Welcome to the exceptions file for Tor's best-practices tracker! +# +# Each line of this file represents a single violation of Tor's best +# practices -- typically, a violation that we had before practracker.py +# first existed. +# +# There are three kinds of problems that we recognize right now: +# function-size -- a function of more than 100 lines. +# file-size -- a .c file of more than 3000 lines, or a .h +# file with more than 500 lines. +# include-count -- a .c file with more than 50 #includes, +# or a .h file with more than 15 #includes. +# dependency-violation -- a file includes a header that it should +# not, according to an advisory .may_include file. +# +# Each line below represents a single exception that practracker should +# _ignore_. Each line has four parts: +# 1. The word "problem". +# 2. The kind of problem. +# 3. The location of the problem: either a filename, or a +# filename:functionname pair. +# 4. The magnitude of the problem to ignore. +# +# So for example, consider this line: +# problem file-size /src/core/or/connection_or.c 3200 +# +# It tells practracker to allow the mentioned file to be up to 3200 lines +# long, even though ordinarily it would warn about any file with more than +# 3000 lines. +# +# You can either edit this file by hand, or regenerate it completely by +# running `make practracker-regen`. +# +# Remember: It is better to fix the problem than to add a new exception! + +problem file-size a.c 41 +problem include-count a.c 6 +problem function-size a.c:i_am_a_function() 8 +problem function-size a.c:another_function() 11 +problem file-size b.c 15 +problem function-size b.c:bar() 5 +problem dependency-violation a.c 4 +problem dependency-violation header.h 3 +problem file-size header.h 8 +problem include-count header.h 4 diff --git a/scripts/maint/rectify_include_paths.py b/scripts/maint/rectify_include_paths.py index 111cf816ce..c6c5026711 100755 --- a/scripts/maint/rectify_include_paths.py +++ b/scripts/maint/rectify_include_paths.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Future imports for Python 2.7, mandatory in 3.0 from __future__ import division diff --git a/scripts/maint/redox.py b/scripts/maint/redox.py index 171c6d9699..12b02c8a44 100755 --- a/scripts/maint/redox.py +++ b/scripts/maint/redox.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright (c) 2008-2019, The Tor Project, Inc. # See LICENSE for licensing information. @@ -37,6 +37,11 @@ from __future__ import unicode_literals import re import sys +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + # Which files should we ignore warning from? Mostly, these are external # files that we've snarfed in from somebody else, whose C we do no intend # to document for them. @@ -78,7 +83,7 @@ def parsething(thing): else: m = THING_RE.match(thing) if not m: - print thing, "???? Format didn't match." + print(thing, "???? Format didn't match.") return None, None else: name, tp, parent = m.groups() @@ -155,7 +160,7 @@ def checkf(fn, errs): """ for skip in SKIP_FILES: if fn.endswith(skip): - print "Skipping",fn + print("Skipping",fn) return comments = [] @@ -174,8 +179,8 @@ def checkf(fn, errs): ln = findline(lines, line, name) if ln == None: - print "Couldn't find the definition of %s allegedly on %s of %s"%( - name, line, fn) + print("Couldn't find the definition of %s allegedly on %s of %s"%( + name, line, fn)) else: if hasdocdoc(lines, line, kind): # print "Has a DOCDOC" @@ -220,12 +225,12 @@ def applyComments(fn, entries): outf.write(line) outf.close() - print "Added %s DOCDOCs to %s" %(N, fn) + print("Added %s DOCDOCs to %s" %(N, fn)) e = read() for fn, errs in e.iteritems(): - print `(fn, errs)` + print(repr((fn, errs))) comments = checkf(fn, errs) if comments: applyComments(fn, comments) diff --git a/scripts/maint/sortChanges.py b/scripts/maint/sortChanges.py index 2e049b1e53..5f6324e387 100755 --- a/scripts/maint/sortChanges.py +++ b/scripts/maint/sortChanges.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (c) 2014-2019, The Tor Project, Inc. # See LICENSE for licensing information diff --git a/src/app/main/shutdown.c b/src/app/main/shutdown.c index 27d92609eb..aac15246b9 100644 --- a/src/app/main/shutdown.c +++ b/src/app/main/shutdown.c @@ -75,7 +75,8 @@ tor_cleanup(void) /* Remove Extended ORPort cookie authentication file */ { char *cookie_fname = get_ext_or_auth_cookie_file_name(); - tor_remove_file(cookie_fname); + if (cookie_fname) + tor_remove_file(cookie_fname); tor_free(cookie_fname); } if (accounting_is_enabled(options)) diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 223428a8f6..4965c2a1f4 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -91,6 +91,7 @@ #include "feature/control/control.h" #include "feature/control/control_events.h" #include "feature/dirauth/authmode.h" +#include "feature/dirauth/dirauth_config.h" #include "feature/dircache/dirserv.h" #include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" @@ -3137,7 +3138,7 @@ connection_mark_all_noncontrol_connections(void) * uses pluggable transports, since we should then limit it even if it * comes from an internal IP address. */ static int -connection_is_rate_limited(connection_t *conn) +connection_is_rate_limited(const connection_t *conn) { const or_options_t *options = get_options(); if (conn->linked) @@ -3272,14 +3273,14 @@ connection_bucket_write_limit(connection_t *conn, time_t now) global_bucket_val, conn_bucket); } -/** Return 1 if the global write buckets are low enough that we +/** Return true iff the global write buckets are low enough that we * shouldn't send <b>attempt</b> bytes of low-priority directory stuff - * out to <b>conn</b>. Else return 0. - - * Priority was 1 for v1 requests (directories and running-routers), - * and 2 for v2 requests and later (statuses and descriptors). + * out to <b>conn</b>. + * + * If we are a directory authority, always answer dir requests thus true is + * always returned. * - * There are a lot of parameters we could use here: + * Note: There are a lot of parameters we could use here: * - global_relayed_write_bucket. Low is bad. * - global_write_bucket. Low is bad. * - bandwidthrate. Low is bad. @@ -3291,39 +3292,40 @@ connection_bucket_write_limit(connection_t *conn, time_t now) * mean is "total directory bytes added to outbufs recently", but * that's harder to quantify and harder to keep track of. */ -int -global_write_bucket_low(connection_t *conn, size_t attempt, int priority) +bool +connection_dir_is_global_write_low(const connection_t *conn, size_t attempt) { size_t smaller_bucket = MIN(token_bucket_rw_get_write(&global_bucket), token_bucket_rw_get_write(&global_relayed_bucket)); - if (authdir_mode(get_options()) && priority>1) - return 0; /* there's always room to answer v2 if we're an auth dir */ + + /* Special case for authorities (directory only). */ + if (authdir_mode_v3(get_options())) { + /* Are we configured to possibly reject requests under load? */ + if (!dirauth_should_reject_requests_under_load()) { + /* Answer request no matter what. */ + return false; + } + /* Always answer requests from a known relay which includes the other + * authorities. The following looks up the addresses for relays that we + * have their descriptor _and_ any configured trusted directories. */ + if (nodelist_probably_contains_address(&conn->addr)) { + return false; + } + } if (!connection_is_rate_limited(conn)) - return 0; /* local conns don't get limited */ + return false; /* local conns don't get limited */ if (smaller_bucket < attempt) - return 1; /* not enough space no matter the priority */ + return true; /* not enough space. */ { const time_t diff = approx_time() - write_buckets_last_empty_at; if (diff <= 1) - return 1; /* we're already hitting our limits, no more please */ + return true; /* we're already hitting our limits, no more please */ } - - if (priority == 1) { /* old-style v1 query */ - /* Could we handle *two* of these requests within the next two seconds? */ - const or_options_t *options = get_options(); - size_t can_write = (size_t) (smaller_bucket - + 2*(options->RelayBandwidthRate ? options->RelayBandwidthRate : - options->BandwidthRate)); - if (can_write < 2*attempt) - return 1; - } else { /* v2 query */ - /* no further constraints yet */ - } - return 0; + return false; } /** When did we last tell the accounting subsystem about transmitted @@ -3345,8 +3347,17 @@ record_num_bytes_transferred_impl(connection_t *conn, rep_hist_note_dir_bytes_written(num_written, now); } + /* Linked connections and internal IPs aren't counted for statistics or + * accounting: + * - counting linked connections would double-count BEGINDIR bytes, because + * they are sent as Dir bytes on the linked connection, and OR bytes on + * the OR connection; + * - relays and clients don't connect to internal IPs, unless specifically + * configured to do so. If they are configured that way, we don't count + * internal bytes. + */ if (!connection_is_rate_limited(conn)) - return; /* local IPs are free */ + return; if (conn->type == CONN_TYPE_OR) rep_hist_note_or_conn_bytes(conn->global_identifier, num_read, @@ -4970,10 +4981,10 @@ connection_finished_flushing(connection_t *conn) } } -/** Called when our attempt to connect() to another server has just - * succeeded. +/** Called when our attempt to connect() to a server has just succeeded. * - * This function just passes conn to the connection-specific + * This function checks if the interface address has changed (clients only), + * and then passes conn to the connection-specific * connection_*_finished_connecting() function. */ static int diff --git a/src/core/mainloop/connection.h b/src/core/mainloop/connection.h index 0ab601d86f..bcd3d590a5 100644 --- a/src/core/mainloop/connection.h +++ b/src/core/mainloop/connection.h @@ -219,8 +219,8 @@ void connection_mark_all_noncontrol_listeners(void); void connection_mark_all_noncontrol_connections(void); ssize_t connection_bucket_write_limit(struct connection_t *conn, time_t now); -int global_write_bucket_low(struct connection_t *conn, - size_t attempt, int priority); +bool connection_dir_is_global_write_low(const struct connection_t *conn, + size_t attempt); void connection_bucket_init(void); void connection_bucket_adjust(const struct or_options_t *options); void connection_bucket_refill_all(time_t now, diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 7781b29fb1..e4e17f6b76 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -966,7 +966,6 @@ conn_close_if_marked(int i) return 0; /* nothing to see here, move along */ now = time(NULL); assert_connection_ok(conn, now); - /* assert_all_pending_dns_resolves_ok(); */ log_debug(LD_NET,"Cleaning up connection (fd "TOR_SOCKET_T_FORMAT").", conn->s); @@ -2273,18 +2272,23 @@ systemd_watchdog_callback(periodic_timer_t *timer, void *arg) #define UPTIME_CUTOFF_FOR_NEW_BANDWIDTH_TEST (6*60*60) -/** Called when our IP address seems to have changed. <b>at_interface</b> - * should be true if we detected a change in our interface, and false if we - * detected a change in our published address. */ +/** Called when our IP address seems to have changed. <b>on_client_conn</b> + * should be true if: + * - we detected a change in our interface address, using an outbound + * connection, and therefore + * - our client TLS keys need to be rotated. + * Otherwise, it should be false, and: + * - we detected a change in our published address + * (using some other method), and therefore + * - the published addresses in our descriptor need to change. + */ void -ip_address_changed(int at_interface) +ip_address_changed(int on_client_conn) { const or_options_t *options = get_options(); int server = server_mode(options); - int exit_reject_interfaces = (server && options->ExitRelay - && options->ExitPolicyRejectLocalInterfaces); - if (at_interface) { + if (on_client_conn) { if (! server) { /* Okay, change our keys. */ if (init_keys_client() < 0) @@ -2296,15 +2300,14 @@ ip_address_changed(int at_interface) reset_bandwidth_test(); reset_uptime(); router_reset_reachability(); + /* All relays include their IP addresses as their ORPort addresses in + * their descriptor. + * Exit relays also incorporate interface addresses in their exit + * policies, when ExitPolicyRejectLocalInterfaces is set. */ + mark_my_descriptor_dirty("IP address changed"); } } - /* Exit relays incorporate interface addresses in their exit policies when - * ExitPolicyRejectLocalInterfaces is set */ - if (exit_reject_interfaces || (server && !at_interface)) { - mark_my_descriptor_dirty("IP address changed"); - } - dns_servers_relaunch_checks(); } diff --git a/src/core/mainloop/mainloop.h b/src/core/mainloop/mainloop.h index f9a48a8e04..1ddfec2162 100644 --- a/src/core/mainloop/mainloop.h +++ b/src/core/mainloop/mainloop.h @@ -56,7 +56,7 @@ MOCK_DECL(int, connection_count_moribund, (void)); void directory_all_unreachable(time_t now); void directory_info_has_arrived(time_t now, int from_cache, int suppress_logs); -void ip_address_changed(int at_interface); +void ip_address_changed(int on_client_conn); void dns_servers_relaunch_checks(void); void reset_all_main_loop_timers(void); void reschedule_directory_downloads(void); diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 7974da4832..2a35237d30 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -47,6 +47,7 @@ #include "app/config/config.h" #include "core/mainloop/connection.h" #include "core/or/connection_or.h" +#include "feature/relay/relay_handshake.h" #include "feature/control/control.h" #include "feature/client/entrynodes.h" #include "trunnel/link_handshake.h" diff --git a/src/core/or/circuitmux.c b/src/core/or/circuitmux.c index 0e932f032d..da95e93657 100644 --- a/src/core/or/circuitmux.c +++ b/src/core/or/circuitmux.c @@ -79,6 +79,8 @@ #include "core/or/or_circuit_st.h" +#include "lib/crypt_ops/crypto_util.h" + /* * Private typedefs for circuitmux.c */ @@ -921,7 +923,10 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ)) /* Now remove it from the map */ HT_REMOVE(chanid_circid_muxinfo_map, cmux->chanid_circid_map, hashent); - /* Free the hash entry */ + /* Wipe and free the hash entry */ + // This isn't sensitive, but we want to be sure to know if we're accessing + // this accidentally. + memwipe(hashent, 0xef, sizeof(*hashent)); tor_free(hashent); } } @@ -1282,4 +1287,3 @@ circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2)) return 0; } } - diff --git a/src/core/or/circuitmux_ewma.c b/src/core/or/circuitmux_ewma.c index 996d87f96d..b50f33528f 100644 --- a/src/core/or/circuitmux_ewma.c +++ b/src/core/or/circuitmux_ewma.c @@ -38,6 +38,7 @@ #include "core/or/circuitmux.h" #include "core/or/circuitmux_ewma.h" #include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "feature/nodelist/networkstatus.h" #include "app/config/or_options_st.h" @@ -186,6 +187,7 @@ ewma_free_cmux_data(circuitmux_t *cmux, pol = TO_EWMA_POL_DATA(pol_data); smartlist_free(pol->active_circuit_pqueue); + memwipe(pol, 0xda, sizeof(ewma_policy_data_t)); tor_free(pol); } @@ -252,7 +254,7 @@ ewma_free_circ_data(circuitmux_t *cmux, if (!pol_circ_data) return; cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data); - + memwipe(cdata, 0xdc, sizeof(ewma_policy_circ_data_t)); tor_free(cdata); } diff --git a/src/core/or/circuitmux_ewma.h b/src/core/or/circuitmux_ewma.h index fc7e7ebf7f..e41cf9e0f0 100644 --- a/src/core/or/circuitmux_ewma.h +++ b/src/core/or/circuitmux_ewma.h @@ -106,7 +106,9 @@ TO_EWMA_POL_DATA(circuitmux_policy_data_t *pol) { if (!pol) return NULL; else { - tor_assert(pol->magic == EWMA_POL_DATA_MAGIC); + tor_assertf(pol->magic == EWMA_POL_DATA_MAGIC, + "Mismatch: %"PRIu32" != %"PRIu32, + pol->magic, EWMA_POL_DATA_MAGIC); return DOWNCAST(ewma_policy_data_t, pol); } } @@ -121,7 +123,9 @@ TO_EWMA_POL_CIRC_DATA(circuitmux_policy_circ_data_t *pol) { if (!pol) return NULL; else { - tor_assert(pol->magic == EWMA_POL_CIRC_DATA_MAGIC); + tor_assertf(pol->magic == EWMA_POL_CIRC_DATA_MAGIC, + "Mismatch: %"PRIu32" != %"PRIu32, + pol->magic, EWMA_POL_CIRC_DATA_MAGIC); return DOWNCAST(ewma_policy_circ_data_t, pol); } } @@ -132,4 +136,3 @@ STATIC void cell_ewma_initialize_ticks(void); #endif /* defined(CIRCUITMUX_EWMA_PRIVATE) */ #endif /* !defined(TOR_CIRCUITMUX_EWMA_H) */ - diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index aeb9ec6460..23c6e230cb 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -432,6 +432,21 @@ warn_if_hs_unreachable(const edge_connection_t *conn, uint8_t reason) } } +/** Given a TTL (in seconds) from a DNS response or from a relay, determine + * what TTL clients and relays should actually use for caching it. */ +uint32_t +clip_dns_ttl(uint32_t ttl) +{ + /* This logic is a defense against "DefectTor" DNS-based traffic + * confirmation attacks, as in https://nymity.ch/tor-dns/tor-dns.pdf . + * We only give two values: a "low" value and a "high" value. + */ + if (ttl < MIN_DNS_TTL) + return MIN_DNS_TTL; + else + return MAX_DNS_TTL; +} + /** Send a relay end cell from stream <b>conn</b> down conn's circuit, and * remember that we've done so. If this is not a client connection, set the * relay end cell's reason for closing as <b>reason</b>. @@ -480,7 +495,7 @@ connection_edge_end(edge_connection_t *conn, uint8_t reason) memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16); addrlen = 16; } - set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl))); + set_uint32(payload+1+addrlen, htonl(clip_dns_ttl(conn->address_ttl))); payload_len += 4+addrlen; } @@ -845,7 +860,7 @@ connected_cell_format_payload(uint8_t *payload_out, return -1; } - set_uint32(payload_out + connected_payload_len, htonl(dns_clip_ttl(ttl))); + set_uint32(payload_out + connected_payload_len, htonl(clip_dns_ttl(ttl))); connected_payload_len += 4; tor_assert(connected_payload_len <= MAX_CONNECTED_CELL_PAYLOAD_LEN); diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h index 11cb252935..8c06af5664 100644 --- a/src/core/or/connection_edge.h +++ b/src/core/or/connection_edge.h @@ -182,6 +182,21 @@ void connection_ap_warn_and_unmark_if_pending_circ( entry_connection_t *entry_conn, const char *where); +/** Lowest value for DNS ttl that a server should give or a client should + * believe. */ +#define MIN_DNS_TTL (5*60) +/** Highest value for DNS ttl that a server should give or a client should + * believe. */ +#define MAX_DNS_TTL (60*60) +/** How long do we keep DNS cache entries before purging them (regardless of + * their TTL)? */ +#define MAX_DNS_ENTRY_AGE (3*60*60) +/** How long do we cache/tell clients to cache DNS records when no TTL is + * known? */ +#define DEFAULT_DNS_TTL (30*60) + +uint32_t clip_dns_ttl(uint32_t ttl); + int connection_half_edge_is_valid_data(const smartlist_t *half_conns, streamid_t stream_id); int connection_half_edge_is_valid_sendme(const smartlist_t *half_conns, diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c index 76bfbf0b30..6dd646637b 100644 --- a/src/core/or/connection_or.c +++ b/src/core/or/connection_or.c @@ -39,14 +39,13 @@ #include "app/config/config.h" #include "core/mainloop/connection.h" #include "core/or/connection_or.h" +#include "feature/relay/relay_handshake.h" #include "feature/control/control_events.h" -#include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/dirauth/reachability.h" #include "feature/client/entrynodes.h" #include "lib/geoip/geoip.h" #include "core/mainloop/mainloop.h" -#include "trunnel/link_handshake.h" #include "trunnel/netinfo.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" @@ -78,7 +77,6 @@ #include "lib/crypt_ops/crypto_format.h" #include "lib/tls/tortls.h" -#include "lib/tls/x509.h" #include "core/or/orconn_event.h" @@ -109,10 +107,6 @@ TO_OR_CONN(connection_t *c) return DOWNCAST(or_connection_t, c); } -/** Global map between Extended ORPort identifiers and OR - * connections. */ -static digestmap_t *orconn_ext_or_id_map = NULL; - /** Clear clear conn->identity_digest and update other data * structures as appropriate.*/ void @@ -198,71 +192,6 @@ connection_or_set_identity_digest(or_connection_t *conn, channel_set_identity_digest(chan, rsa_digest, ed_id); } -/** Remove the Extended ORPort identifier of <b>conn</b> from the - * global identifier list. Also, clear the identifier from the - * connection itself. */ -void -connection_or_remove_from_ext_or_id_map(or_connection_t *conn) -{ - or_connection_t *tmp; - if (!orconn_ext_or_id_map) - return; - if (!conn->ext_or_conn_id) - return; - - tmp = digestmap_remove(orconn_ext_or_id_map, conn->ext_or_conn_id); - if (!tor_digest_is_zero(conn->ext_or_conn_id)) - tor_assert(tmp == conn); - - memset(conn->ext_or_conn_id, 0, EXT_OR_CONN_ID_LEN); -} - -/** Return the connection whose ext_or_id is <b>id</b>. Return NULL if no such - * connection is found. */ -or_connection_t * -connection_or_get_by_ext_or_id(const char *id) -{ - if (!orconn_ext_or_id_map) - return NULL; - return digestmap_get(orconn_ext_or_id_map, id); -} - -/** Deallocate the global Extended ORPort identifier list */ -void -connection_or_clear_ext_or_id_map(void) -{ - digestmap_free(orconn_ext_or_id_map, NULL); - orconn_ext_or_id_map = NULL; -} - -/** Creates an Extended ORPort identifier for <b>conn</b> and deposits - * it into the global list of identifiers. */ -void -connection_or_set_ext_or_identifier(or_connection_t *conn) -{ - char random_id[EXT_OR_CONN_ID_LEN]; - or_connection_t *tmp; - - if (!orconn_ext_or_id_map) - orconn_ext_or_id_map = digestmap_new(); - - /* Remove any previous identifiers: */ - if (conn->ext_or_conn_id && !tor_digest_is_zero(conn->ext_or_conn_id)) - connection_or_remove_from_ext_or_id_map(conn); - - do { - crypto_rand(random_id, sizeof(random_id)); - } while (digestmap_get(orconn_ext_or_id_map, random_id)); - - if (!conn->ext_or_conn_id) - conn->ext_or_conn_id = tor_malloc_zero(EXT_OR_CONN_ID_LEN); - - memcpy(conn->ext_or_conn_id, random_id, EXT_OR_CONN_ID_LEN); - - tmp = digestmap_set(orconn_ext_or_id_map, random_id, conn); - tor_assert(!tmp); -} - /**************************************************************/ /** Map from a string describing what a non-open OR connection was doing when @@ -2596,533 +2525,3 @@ connection_or_send_netinfo,(or_connection_t *conn)) return r; } - -/** Helper used to add an encoded certs to a cert cell */ -static void -add_certs_cell_cert_helper(certs_cell_t *certs_cell, - uint8_t cert_type, - const uint8_t *cert_encoded, - size_t cert_len) -{ - tor_assert(cert_len <= UINT16_MAX); - certs_cell_cert_t *ccc = certs_cell_cert_new(); - ccc->cert_type = cert_type; - ccc->cert_len = cert_len; - certs_cell_cert_setlen_body(ccc, cert_len); - memcpy(certs_cell_cert_getarray_body(ccc), cert_encoded, cert_len); - - certs_cell_add_certs(certs_cell, ccc); -} - -/** Add an encoded X509 cert (stored as <b>cert_len</b> bytes at - * <b>cert_encoded</b>) to the trunnel certs_cell_t object that we are - * building in <b>certs_cell</b>. Set its type field to <b>cert_type</b>. - * (If <b>cert</b> is NULL, take no action.) */ -static void -add_x509_cert(certs_cell_t *certs_cell, - uint8_t cert_type, - const tor_x509_cert_t *cert) -{ - if (NULL == cert) - return; - - const uint8_t *cert_encoded = NULL; - size_t cert_len; - tor_x509_cert_get_der(cert, &cert_encoded, &cert_len); - - add_certs_cell_cert_helper(certs_cell, cert_type, cert_encoded, cert_len); -} - -/** Add an Ed25519 cert from <b>cert</b> to the trunnel certs_cell_t object - * that we are building in <b>certs_cell</b>. Set its type field to - * <b>cert_type</b>. (If <b>cert</b> is NULL, take no action.) */ -static void -add_ed25519_cert(certs_cell_t *certs_cell, - uint8_t cert_type, - const tor_cert_t *cert) -{ - if (NULL == cert) - return; - - add_certs_cell_cert_helper(certs_cell, cert_type, - cert->encoded, cert->encoded_len); -} - -#ifdef TOR_UNIT_TESTS -int certs_cell_ed25519_disabled_for_testing = 0; -#else -#define certs_cell_ed25519_disabled_for_testing 0 -#endif - -/** Send a CERTS cell on the connection <b>conn</b>. Return 0 on success, -1 - * on failure. */ -int -connection_or_send_certs_cell(or_connection_t *conn) -{ - const tor_x509_cert_t *global_link_cert = NULL, *id_cert = NULL; - tor_x509_cert_t *own_link_cert = NULL; - var_cell_t *cell; - - certs_cell_t *certs_cell = NULL; - - tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3); - - if (! conn->handshake_state) - return -1; - - const int conn_in_server_mode = ! conn->handshake_state->started_here; - - /* Get the encoded values of the X509 certificates */ - if (tor_tls_get_my_certs(conn_in_server_mode, - &global_link_cert, &id_cert) < 0) - return -1; - - if (conn_in_server_mode) { - own_link_cert = tor_tls_get_own_cert(conn->tls); - } - tor_assert(id_cert); - - certs_cell = certs_cell_new(); - - /* Start adding certs. First the link cert or auth1024 cert. */ - if (conn_in_server_mode) { - tor_assert_nonfatal(own_link_cert); - add_x509_cert(certs_cell, - OR_CERT_TYPE_TLS_LINK, own_link_cert); - } else { - tor_assert(global_link_cert); - add_x509_cert(certs_cell, - OR_CERT_TYPE_AUTH_1024, global_link_cert); - } - - /* Next the RSA->RSA ID cert */ - add_x509_cert(certs_cell, - OR_CERT_TYPE_ID_1024, id_cert); - - /* Next the Ed25519 certs */ - add_ed25519_cert(certs_cell, - CERTTYPE_ED_ID_SIGN, - get_master_signing_key_cert()); - if (conn_in_server_mode) { - tor_assert_nonfatal(conn->handshake_state->own_link_cert || - certs_cell_ed25519_disabled_for_testing); - add_ed25519_cert(certs_cell, - CERTTYPE_ED_SIGN_LINK, - conn->handshake_state->own_link_cert); - } else { - add_ed25519_cert(certs_cell, - CERTTYPE_ED_SIGN_AUTH, - get_current_auth_key_cert()); - } - - /* And finally the crosscert. */ - { - const uint8_t *crosscert=NULL; - size_t crosscert_len; - get_master_rsa_crosscert(&crosscert, &crosscert_len); - if (crosscert) { - add_certs_cell_cert_helper(certs_cell, - CERTTYPE_RSA1024_ID_EDID, - crosscert, crosscert_len); - } - } - - /* We've added all the certs; make the cell. */ - certs_cell->n_certs = certs_cell_getlen_certs(certs_cell); - - ssize_t alloc_len = certs_cell_encoded_len(certs_cell); - tor_assert(alloc_len >= 0 && alloc_len <= UINT16_MAX); - cell = var_cell_new(alloc_len); - cell->command = CELL_CERTS; - ssize_t enc_len = certs_cell_encode(cell->payload, alloc_len, certs_cell); - tor_assert(enc_len > 0 && enc_len <= alloc_len); - cell->payload_len = enc_len; - - connection_or_write_var_cell_to_buf(cell, conn); - var_cell_free(cell); - certs_cell_free(certs_cell); - tor_x509_cert_free(own_link_cert); - - return 0; -} - -#ifdef TOR_UNIT_TESTS -int testing__connection_or_pretend_TLSSECRET_is_supported = 0; -#else -#define testing__connection_or_pretend_TLSSECRET_is_supported 0 -#endif - -/** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that - * we can send and receive. */ -int -authchallenge_type_is_supported(uint16_t challenge_type) -{ - switch (challenge_type) { - case AUTHTYPE_RSA_SHA256_TLSSECRET: -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS - return 1; -#else - return testing__connection_or_pretend_TLSSECRET_is_supported; -#endif - case AUTHTYPE_ED25519_SHA256_RFC5705: - return 1; - case AUTHTYPE_RSA_SHA256_RFC5705: - default: - return 0; - } -} - -/** Return true iff <b>challenge_type_a</b> is one that we would rather - * use than <b>challenge_type_b</b>. */ -int -authchallenge_type_is_better(uint16_t challenge_type_a, - uint16_t challenge_type_b) -{ - /* Any supported type is better than an unsupported one; - * all unsupported types are equally bad. */ - if (!authchallenge_type_is_supported(challenge_type_a)) - return 0; - if (!authchallenge_type_is_supported(challenge_type_b)) - return 1; - /* It happens that types are superior in numerically ascending order. - * If that ever changes, this must change too. */ - return (challenge_type_a > challenge_type_b); -} - -/** Send an AUTH_CHALLENGE cell on the connection <b>conn</b>. Return 0 - * on success, -1 on failure. */ -int -connection_or_send_auth_challenge_cell(or_connection_t *conn) -{ - var_cell_t *cell = NULL; - int r = -1; - tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3); - - if (! conn->handshake_state) - return -1; - - auth_challenge_cell_t *ac = auth_challenge_cell_new(); - - tor_assert(sizeof(ac->challenge) == 32); - crypto_rand((char*)ac->challenge, sizeof(ac->challenge)); - - if (authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET)) - auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET); - /* Disabled, because everything that supports this method also supports - * the much-superior ED25519_SHA256_RFC5705 */ - /* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_RFC5705); */ - if (authchallenge_type_is_supported(AUTHTYPE_ED25519_SHA256_RFC5705)) - auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705); - auth_challenge_cell_set_n_methods(ac, - auth_challenge_cell_getlen_methods(ac)); - - cell = var_cell_new(auth_challenge_cell_encoded_len(ac)); - ssize_t len = auth_challenge_cell_encode(cell->payload, cell->payload_len, - ac); - if (len != cell->payload_len) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Encoded auth challenge cell length not as expected"); - goto done; - /* LCOV_EXCL_STOP */ - } - cell->command = CELL_AUTH_CHALLENGE; - - connection_or_write_var_cell_to_buf(cell, conn); - r = 0; - - done: - var_cell_free(cell); - auth_challenge_cell_free(ac); - - return r; -} - -/** Compute the main body of an AUTHENTICATE cell that a client can use - * to authenticate itself on a v3 handshake for <b>conn</b>. Return it - * in a var_cell_t. - * - * If <b>server</b> is true, only calculate the first - * V3_AUTH_FIXED_PART_LEN bytes -- the part of the authenticator that's - * determined by the rest of the handshake, and which match the provided value - * exactly. - * - * If <b>server</b> is false and <b>signing_key</b> is NULL, calculate the - * first V3_AUTH_BODY_LEN bytes of the authenticator (that is, everything - * that should be signed), but don't actually sign it. - * - * If <b>server</b> is false and <b>signing_key</b> is provided, calculate the - * entire authenticator, signed with <b>signing_key</b>. - * - * Return the length of the cell body on success, and -1 on failure. - */ -var_cell_t * -connection_or_compute_authenticate_cell_body(or_connection_t *conn, - const int authtype, - crypto_pk_t *signing_key, - const ed25519_keypair_t *ed_signing_key, - int server) -{ - auth1_t *auth = NULL; - auth_ctx_t *ctx = auth_ctx_new(); - var_cell_t *result = NULL; - int old_tlssecrets_algorithm = 0; - const char *authtype_str = NULL; - - int is_ed = 0; - - /* assert state is reasonable XXXX */ - switch (authtype) { - case AUTHTYPE_RSA_SHA256_TLSSECRET: - authtype_str = "AUTH0001"; - old_tlssecrets_algorithm = 1; - break; - case AUTHTYPE_RSA_SHA256_RFC5705: - authtype_str = "AUTH0002"; - break; - case AUTHTYPE_ED25519_SHA256_RFC5705: - authtype_str = "AUTH0003"; - is_ed = 1; - break; - default: - tor_assert(0); - break; - } - - auth = auth1_new(); - ctx->is_ed = is_ed; - - /* Type: 8 bytes. */ - memcpy(auth1_getarray_type(auth), authtype_str, 8); - - { - const tor_x509_cert_t *id_cert=NULL; - const common_digests_t *my_digests, *their_digests; - const uint8_t *my_id, *their_id, *client_id, *server_id; - if (tor_tls_get_my_certs(server, NULL, &id_cert)) - goto err; - my_digests = tor_x509_cert_get_id_digests(id_cert); - their_digests = - tor_x509_cert_get_id_digests(conn->handshake_state->certs->id_cert); - tor_assert(my_digests); - tor_assert(their_digests); - my_id = (uint8_t*)my_digests->d[DIGEST_SHA256]; - their_id = (uint8_t*)their_digests->d[DIGEST_SHA256]; - - client_id = server ? their_id : my_id; - server_id = server ? my_id : their_id; - - /* Client ID digest: 32 octets. */ - memcpy(auth->cid, client_id, 32); - - /* Server ID digest: 32 octets. */ - memcpy(auth->sid, server_id, 32); - } - - if (is_ed) { - const ed25519_public_key_t *my_ed_id, *their_ed_id; - if (!conn->handshake_state->certs->ed_id_sign) { - log_warn(LD_OR, "Ed authenticate without Ed ID cert from peer."); - goto err; - } - my_ed_id = get_master_identity_key(); - their_ed_id = &conn->handshake_state->certs->ed_id_sign->signing_key; - - const uint8_t *cid_ed = (server ? their_ed_id : my_ed_id)->pubkey; - const uint8_t *sid_ed = (server ? my_ed_id : their_ed_id)->pubkey; - - memcpy(auth->u1_cid_ed, cid_ed, ED25519_PUBKEY_LEN); - memcpy(auth->u1_sid_ed, sid_ed, ED25519_PUBKEY_LEN); - } - - { - crypto_digest_t *server_d, *client_d; - if (server) { - server_d = conn->handshake_state->digest_sent; - client_d = conn->handshake_state->digest_received; - } else { - client_d = conn->handshake_state->digest_sent; - server_d = conn->handshake_state->digest_received; - } - - /* Server log digest : 32 octets */ - crypto_digest_get_digest(server_d, (char*)auth->slog, 32); - - /* Client log digest : 32 octets */ - crypto_digest_get_digest(client_d, (char*)auth->clog, 32); - } - - { - /* Digest of cert used on TLS link : 32 octets. */ - tor_x509_cert_t *cert = NULL; - if (server) { - cert = tor_tls_get_own_cert(conn->tls); - } else { - cert = tor_tls_get_peer_cert(conn->tls); - } - if (!cert) { - log_warn(LD_OR, "Unable to find cert when making %s data.", - authtype_str); - goto err; - } - - memcpy(auth->scert, - tor_x509_cert_get_cert_digests(cert)->d[DIGEST_SHA256], 32); - - tor_x509_cert_free(cert); - } - - /* HMAC of clientrandom and serverrandom using master key : 32 octets */ - if (old_tlssecrets_algorithm) { - if (tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets) < 0) { - log_fn(LOG_PROTOCOL_WARN, LD_OR, "Somebody asked us for an older TLS " - "authentication method (AUTHTYPE_RSA_SHA256_TLSSECRET) " - "which we don't support."); - } - } else { - char label[128]; - tor_snprintf(label, sizeof(label), - "EXPORTER FOR TOR TLS CLIENT BINDING %s", authtype_str); - int r = tor_tls_export_key_material(conn->tls, auth->tlssecrets, - auth->cid, sizeof(auth->cid), - label); - if (r < 0) { - if (r != -2) - log_warn(LD_BUG, "TLS key export failed for unknown reason."); - // If r == -2, this was openssl bug 7712. - goto err; - } - } - - /* 8 octets were reserved for the current time, but we're trying to get out - * of the habit of sending time around willynilly. Fortunately, nothing - * checks it. That's followed by 16 bytes of nonce. */ - crypto_rand((char*)auth->rand, 24); - - ssize_t maxlen = auth1_encoded_len(auth, ctx); - if (ed_signing_key && is_ed) { - maxlen += ED25519_SIG_LEN; - } else if (signing_key && !is_ed) { - maxlen += crypto_pk_keysize(signing_key); - } - - const int AUTH_CELL_HEADER_LEN = 4; /* 2 bytes of type, 2 bytes of length */ - result = var_cell_new(AUTH_CELL_HEADER_LEN + maxlen); - uint8_t *const out = result->payload + AUTH_CELL_HEADER_LEN; - const size_t outlen = maxlen; - ssize_t len; - - result->command = CELL_AUTHENTICATE; - set_uint16(result->payload, htons(authtype)); - - if ((len = auth1_encode(out, outlen, auth, ctx)) < 0) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Unable to encode signed part of AUTH1 data."); - goto err; - /* LCOV_EXCL_STOP */ - } - - if (server) { - auth1_t *tmp = NULL; - ssize_t len2 = auth1_parse(&tmp, out, len, ctx); - if (!tmp) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Unable to parse signed part of AUTH1 data that " - "we just encoded"); - goto err; - /* LCOV_EXCL_STOP */ - } - result->payload_len = (tmp->end_of_signed - result->payload); - - auth1_free(tmp); - if (len2 != len) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Mismatched length when re-parsing AUTH1 data."); - goto err; - /* LCOV_EXCL_STOP */ - } - goto done; - } - - if (ed_signing_key && is_ed) { - ed25519_signature_t sig; - if (ed25519_sign(&sig, out, len, ed_signing_key) < 0) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Unable to sign ed25519 authentication data"); - goto err; - /* LCOV_EXCL_STOP */ - } - auth1_setlen_sig(auth, ED25519_SIG_LEN); - memcpy(auth1_getarray_sig(auth), sig.sig, ED25519_SIG_LEN); - - } else if (signing_key && !is_ed) { - auth1_setlen_sig(auth, crypto_pk_keysize(signing_key)); - - char d[32]; - crypto_digest256(d, (char*)out, len, DIGEST_SHA256); - int siglen = crypto_pk_private_sign(signing_key, - (char*)auth1_getarray_sig(auth), - auth1_getlen_sig(auth), - d, 32); - if (siglen < 0) { - log_warn(LD_OR, "Unable to sign AUTH1 data."); - goto err; - } - - auth1_setlen_sig(auth, siglen); - } - - len = auth1_encode(out, outlen, auth, ctx); - if (len < 0) { - /* LCOV_EXCL_START */ - log_warn(LD_BUG, "Unable to encode signed AUTH1 data."); - goto err; - /* LCOV_EXCL_STOP */ - } - tor_assert(len + AUTH_CELL_HEADER_LEN <= result->payload_len); - result->payload_len = len + AUTH_CELL_HEADER_LEN; - set_uint16(result->payload+2, htons(len)); - - goto done; - - err: - var_cell_free(result); - result = NULL; - done: - auth1_free(auth); - auth_ctx_free(ctx); - return result; -} - -/** Send an AUTHENTICATE cell on the connection <b>conn</b>. Return 0 on - * success, -1 on failure */ -MOCK_IMPL(int, -connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype)) -{ - var_cell_t *cell; - crypto_pk_t *pk = tor_tls_get_my_client_auth_key(); - /* XXXX make sure we're actually supposed to send this! */ - - if (!pk) { - log_warn(LD_BUG, "Can't compute authenticate cell: no client auth key"); - return -1; - } - if (! authchallenge_type_is_supported(authtype)) { - log_warn(LD_BUG, "Tried to send authenticate cell with unknown " - "authentication type %d", authtype); - return -1; - } - - cell = connection_or_compute_authenticate_cell_body(conn, - authtype, - pk, - get_current_auth_keypair(), - 0 /* not server */); - if (! cell) { - log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unable to compute authenticate cell!"); - return -1; - } - connection_or_write_var_cell_to_buf(cell, conn); - var_cell_free(cell); - - return 0; -} diff --git a/src/core/or/connection_or.h b/src/core/or/connection_or.h index 90b21ad77b..02bc87a864 100644 --- a/src/core/or/connection_or.h +++ b/src/core/or/connection_or.h @@ -97,19 +97,6 @@ MOCK_DECL(void,connection_or_write_var_cell_to_buf,(const var_cell_t *cell, or_connection_t *conn)); int connection_or_send_versions(or_connection_t *conn, int v3_plus); MOCK_DECL(int,connection_or_send_netinfo,(or_connection_t *conn)); -int connection_or_send_certs_cell(or_connection_t *conn); -int connection_or_send_auth_challenge_cell(or_connection_t *conn); -int authchallenge_type_is_supported(uint16_t challenge_type); -int authchallenge_type_is_better(uint16_t challenge_type_a, - uint16_t challenge_type_b); -var_cell_t *connection_or_compute_authenticate_cell_body( - or_connection_t *conn, - const int authtype, - crypto_pk_t *signing_key, - const struct ed25519_keypair_t *ed_signing_key, - int server); -MOCK_DECL(int,connection_or_send_authenticate_cell, - (or_connection_t *conn, int type)); int is_or_protocol_version_known(uint16_t version); @@ -144,7 +131,6 @@ MOCK_DECL(STATIC void,connection_or_change_state, #endif /* defined(CONNECTION_OR_PRIVATE) */ #ifdef TOR_UNIT_TESTS -extern int certs_cell_ed25519_disabled_for_testing; extern int testing__connection_or_pretend_TLSSECRET_is_supported; #endif diff --git a/src/core/or/protover.c b/src/core/or/protover.c index 2a0a06f951..c3f443631b 100644 --- a/src/core/or/protover.c +++ b/src/core/or/protover.c @@ -40,8 +40,8 @@ static const struct { protocol_type_t protover_type; const char *name; /* If you add a new protocol here, you probably also want to add - * parsing for it in routerstatus_parse_entry_from_string() so that - * it is set in routerstatus_t */ + * parsing for it in summarize_protover_flags(), so that it has a + * summary flag in routerstatus_t */ } PROTOCOL_NAMES[] = { { PRT_LINK, "Link" }, { PRT_LINKAUTH, "LinkAuth" }, @@ -391,6 +391,7 @@ protover_get_supported_protocols(void) "Cons=1-2 " "Desc=1-2 " "DirCache=1-2 " + "FlowCtrl=1 " "HSDir=1-2 " "HSIntro=3-5 " "HSRend=1-2 " @@ -401,9 +402,8 @@ protover_get_supported_protocols(void) "LinkAuth=3 " #endif "Microdesc=1-2 " - "Relay=1-2 " "Padding=2 " - "FlowCtrl=1"; + "Relay=1-2"; } /** The protocols from protover_get_supported_protocols(), as parsed into a diff --git a/src/core/or/scheduler.c b/src/core/or/scheduler.c index cd9aa54642..6633ccfe1f 100644 --- a/src/core/or/scheduler.c +++ b/src/core/or/scheduler.c @@ -502,7 +502,12 @@ scheduler_free_all(void) the_scheduler = NULL; } -/** Mark a channel as no longer ready to accept writes. */ +/** Mark a channel as no longer ready to accept writes. + * + * Possible state changes: + * - SCHED_CHAN_PENDING -> SCHED_CHAN_WAITING_TO_WRITE + * - SCHED_CHAN_WAITING_FOR_CELLS -> SCHED_CHAN_IDLE + */ MOCK_IMPL(void, scheduler_channel_doesnt_want_writes,(channel_t *chan)) { @@ -513,31 +518,32 @@ scheduler_channel_doesnt_want_writes,(channel_t *chan)) return; } - /* If it's already in pending, we can put it in waiting_to_write */ if (chan->scheduler_state == SCHED_CHAN_PENDING) { /* - * It's in channels_pending, so it shouldn't be in any of - * the other lists. It can't write any more, so it goes to - * channels_waiting_to_write. + * It has cells but no longer can write, so it becomes + * SCHED_CHAN_WAITING_TO_WRITE. It's in channels_pending, so we + * should remove it from the list. */ smartlist_pqueue_remove(channels_pending, scheduler_compare_channels, offsetof(channel_t, sched_heap_idx), chan); scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_TO_WRITE); - } else { + } else if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) { /* - * It's not in pending, so it can't become waiting_to_write; it's - * either not in any of the lists (nothing to do) or it's already in - * waiting_for_cells (remove it, can't write any more). + * It does not have cells and no longer can write, so it becomes + * SCHED_CHAN_IDLE. */ - if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) { - scheduler_set_channel_state(chan, SCHED_CHAN_IDLE); - } + scheduler_set_channel_state(chan, SCHED_CHAN_IDLE); } } -/** Mark a channel as having waiting cells. */ +/** Mark a channel as having waiting cells. + * + * Possible state changes: + * - SCHED_CHAN_WAITING_FOR_CELLS -> SCHED_CHAN_PENDING + * - SCHED_CHAN_IDLE -> SCHED_CHAN_WAITING_TO_WRITE + */ MOCK_IMPL(void, scheduler_channel_has_waiting_cells,(channel_t *chan)) { @@ -548,12 +554,11 @@ scheduler_channel_has_waiting_cells,(channel_t *chan)) return; } - /* First, check if it's also writeable */ if (chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS) { /* - * It's in channels_waiting_for_cells, so it shouldn't be in any of - * the other lists. It has waiting cells now, so it goes to - * channels_pending. + * It is able to write and now has cells, so it becomes + * SCHED_CHAN_PENDING. It must be added to the channels_pending + * list. */ scheduler_set_channel_state(chan, SCHED_CHAN_PENDING); if (!SCHED_BUG(chan->sched_heap_idx != -1, chan)) { @@ -565,16 +570,12 @@ scheduler_channel_has_waiting_cells,(channel_t *chan)) /* If we made a channel pending, we potentially have scheduling work to * do. */ the_scheduler->schedule(); - } else { + } else if (chan->scheduler_state == SCHED_CHAN_IDLE) { /* - * It's not in waiting_for_cells, so it can't become pending; it's - * either not in any of the lists (we add it to waiting_to_write) - * or it's already in waiting_to_write or pending (we do nothing) + * It is not able to write but now has cells, so it becomes + * SCHED_CHAN_WAITING_TO_WRITE. */ - if (!(chan->scheduler_state == SCHED_CHAN_WAITING_TO_WRITE || - chan->scheduler_state == SCHED_CHAN_PENDING)) { - scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_TO_WRITE); - } + scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_TO_WRITE); } } @@ -662,8 +663,12 @@ scheduler_release_channel,(channel_t *chan)) scheduler_set_channel_state(chan, SCHED_CHAN_IDLE); } -/** Mark a channel as ready to accept writes */ - +/** Mark a channel as ready to accept writes. + * Possible state changes: + * + * - SCHED_CHAN_WAITING_TO_WRITE -> SCHED_CHAN_PENDING + * - SCHED_CHAN_IDLE -> SCHED_CHAN_WAITING_FOR_CELLS + */ void scheduler_channel_wants_writes(channel_t *chan) { @@ -674,10 +679,11 @@ scheduler_channel_wants_writes(channel_t *chan) return; } - /* If it's already in waiting_to_write, we can put it in pending */ if (chan->scheduler_state == SCHED_CHAN_WAITING_TO_WRITE) { /* - * It can write now, so it goes to channels_pending. + * It has cells and can now write, so it becomes + * SCHED_CHAN_PENDING. It must be added to the channels_pending + * list. */ scheduler_set_channel_state(chan, SCHED_CHAN_PENDING); if (!SCHED_BUG(chan->sched_heap_idx != -1, chan)) { @@ -688,15 +694,12 @@ scheduler_channel_wants_writes(channel_t *chan) } /* We just made a channel pending, we have scheduling work to do. */ the_scheduler->schedule(); - } else { + } else if (chan->scheduler_state == SCHED_CHAN_IDLE) { /* - * It's not in SCHED_CHAN_WAITING_TO_WRITE, so it can't become pending; - * it's either idle and goes to WAITING_FOR_CELLS, or it's a no-op. + * It does not have cells but can now write, so it becomes + * SCHED_CHAN_WAITING_FOR_CELLS. */ - if (!(chan->scheduler_state == SCHED_CHAN_WAITING_FOR_CELLS || - chan->scheduler_state == SCHED_CHAN_PENDING)) { - scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_FOR_CELLS); - } + scheduler_set_channel_state(chan, SCHED_CHAN_WAITING_FOR_CELLS); } } diff --git a/src/core/or/scheduler_kist.c b/src/core/or/scheduler_kist.c index e56942be09..b6f5846456 100644 --- a/src/core/or/scheduler_kist.c +++ b/src/core/or/scheduler_kist.c @@ -463,6 +463,13 @@ MOCK_IMPL(void, channel_write_to_kernel, (channel_t *chan)) log_debug(LD_SCHED, "Writing %lu bytes to kernel for chan %" PRIu64, (unsigned long)channel_outbuf_length(chan), chan->global_identifier); + /* Note that 'connection_handle_write()' may change the scheduler state of + * the channel during the scheduling loop with + * 'connection_or_flushed_some()' -> 'scheduler_channel_wants_writes()'. + * This side-effect will only occur if the channel is currently in the + * 'SCHED_CHAN_WAITING_TO_WRITE' or 'SCHED_CHAN_IDLE' states, which KIST + * rarely uses, so it should be fine unless KIST begins using these states + * in the future. */ connection_handle_write(TO_CONN(BASE_CHAN_TO_TLS(chan)->conn), 0); } diff --git a/src/core/proto/proto_ext_or.h b/src/core/proto/proto_ext_or.h index daac3e3eb7..3408599fb7 100644 --- a/src/core/proto/proto_ext_or.h +++ b/src/core/proto/proto_ext_or.h @@ -24,4 +24,11 @@ struct ext_or_cmd_t { int fetch_ext_or_command_from_buf(struct buf_t *buf, struct ext_or_cmd_t **out); +ext_or_cmd_t *ext_or_cmd_new(uint16_t len); + +#define ext_or_cmd_free(cmd) \ + FREE_AND_NULL(ext_or_cmd_t, ext_or_cmd_free_, (cmd)) + +void ext_or_cmd_free_(ext_or_cmd_t *cmd); + #endif /* !defined(TOR_PROTO_EXT_OR_H) */ diff --git a/src/ext/ed25519/ref10/base.py b/src/ext/ed25519/ref10/base.py index 8bfaab0568..3d477c5c39 100644 --- a/src/ext/ed25519/ref10/base.py +++ b/src/ext/ed25519/ref10/base.py @@ -56,15 +56,15 @@ def radix255(x): Bi = B for i in range(32): - print "{" + print("{") Bij = Bi for j in range(8): - print " {" - print " {",radix255(Bij[1]+Bij[0]),"}," - print " {",radix255(Bij[1]-Bij[0]),"}," - print " {",radix255(2*d*Bij[0]*Bij[1]),"}," + print(" {") + print(" {",radix255(Bij[1]+Bij[0]),"},") + print(" {",radix255(Bij[1]-Bij[0]),"},") + print(" {",radix255(2*d*Bij[0]*Bij[1]),"},") Bij = edwards(Bij,Bi) - print " }," - print "}," + print(" },") + print("},") for k in range(8): Bi = edwards(Bi,Bi) diff --git a/src/ext/ed25519/ref10/base2.py b/src/ext/ed25519/ref10/base2.py index 5923e43a7b..3f8e3d25d2 100644 --- a/src/ext/ed25519/ref10/base2.py +++ b/src/ext/ed25519/ref10/base2.py @@ -57,9 +57,9 @@ def radix255(x): Bi = B for i in range(8): - print " {" - print " {",radix255(Bi[1]+Bi[0]),"}," - print " {",radix255(Bi[1]-Bi[0]),"}," - print " {",radix255(2*d*Bi[0]*Bi[1]),"}," - print " }," + print(" {") + print(" {",radix255(Bi[1]+Bi[0]),"},") + print(" {",radix255(Bi[1]-Bi[0]),"},") + print(" {",radix255(2*d*Bi[0]*Bi[1]),"},") + print(" },") Bi = edwards(B,edwards(B,Bi)) diff --git a/src/ext/ed25519/ref10/d.py b/src/ext/ed25519/ref10/d.py index 3fbb175077..5b875de666 100644 --- a/src/ext/ed25519/ref10/d.py +++ b/src/ext/ed25519/ref10/d.py @@ -30,4 +30,4 @@ def radix255(x): return result d = -121665 * inv(121666) -print radix255(d) +print(radix255(d)) diff --git a/src/ext/ed25519/ref10/d2.py b/src/ext/ed25519/ref10/d2.py index 3e533730b7..f59a1bc62a 100644 --- a/src/ext/ed25519/ref10/d2.py +++ b/src/ext/ed25519/ref10/d2.py @@ -30,4 +30,4 @@ def radix255(x): return result d = -121665 * inv(121666) -print radix255(d*2) +print(radix255(d*2)) diff --git a/src/ext/ed25519/ref10/sqrtm1.py b/src/ext/ed25519/ref10/sqrtm1.py index a276d4e673..df9f26ee1d 100644 --- a/src/ext/ed25519/ref10/sqrtm1.py +++ b/src/ext/ed25519/ref10/sqrtm1.py @@ -30,4 +30,4 @@ def radix255(x): return result I = expmod(2,(q-1)/4,q) -print radix255(I) +print(radix255(I)) diff --git a/src/feature/client/addressmap.c b/src/feature/client/addressmap.c index 1a6958d38c..cc97166f36 100644 --- a/src/feature/client/addressmap.c +++ b/src/feature/client/addressmap.c @@ -23,7 +23,6 @@ #include "app/config/config.h" #include "core/or/connection_edge.h" #include "feature/control/control_events.h" -#include "feature/relay/dns.h" #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerset.h" @@ -689,7 +688,7 @@ client_dns_set_addressmap_impl(entry_connection_t *for_conn, if (ttl<0) ttl = DEFAULT_DNS_TTL; else - ttl = dns_clip_ttl(ttl); + ttl = clip_dns_ttl(ttl); if (exitname) { /* XXXX fails to ever get attempts to get an exit address of diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c index 68691ef512..55069bb60a 100644 --- a/src/feature/client/transports.c +++ b/src/feature/client/transports.c @@ -1420,8 +1420,10 @@ create_managed_proxy_environment(const managed_proxy_t *mp) smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT=%s", ext_or_addrport_tmp); } - smartlist_add_asprintf(envs, "TOR_PT_AUTH_COOKIE_FILE=%s", - cookie_file_loc); + if (cookie_file_loc) { + smartlist_add_asprintf(envs, "TOR_PT_AUTH_COOKIE_FILE=%s", + cookie_file_loc); + } tor_free(ext_or_addrport_tmp); tor_free(cookie_file_loc); @@ -1858,7 +1860,9 @@ managed_proxy_stderr_callback(process_t *process, if (BUG(mp == NULL)) return; - log_warn(LD_PT, "Managed proxy at '%s' reported: %s", mp->argv[0], line); + log_info(LD_PT, + "Managed proxy at '%s' reported via standard error: %s", + mp->argv[0], line); } /** Callback function that is called when our PT process terminates. The diff --git a/src/feature/control/control.c b/src/feature/control/control.c index b4f27cb820..ee1026359d 100644 --- a/src/feature/control/control.c +++ b/src/feature/control/control.c @@ -158,6 +158,10 @@ control_ports_write_to_file(void) } const struct signal_name_t signal_table[] = { + /* NOTE: this table is used for handling SIGNAL commands and generating + * SIGNAL events. Order is significant: if there are two entries for the + * same numeric signal, the first one is the canonical name generated + * for the events. */ { SIGHUP, "RELOAD" }, { SIGHUP, "HUP" }, { SIGINT, "SHUTDOWN" }, diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index 5fceb404e3..c2d23243e5 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -323,10 +323,8 @@ handle_control_getconf(control_connection_t *conn, send_control_done(conn); } - SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp)); - smartlist_free(answers); - smartlist_free(unrecognized); - + control_reply_free(answers); + control_reply_free(unrecognized); return 0; } diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c index b0a1a3f242..916ccea875 100644 --- a/src/feature/control/control_events.c +++ b/src/feature/control/control_events.c @@ -1559,29 +1559,17 @@ control_event_signal(uintptr_t signal_num) if (!control_event_is_interesting(EVENT_GOT_SIGNAL)) return 0; - switch (signal_num) { - case SIGHUP: - signal_string = "RELOAD"; + for (unsigned i = 0; signal_table[i].signal_name != NULL; ++i) { + if ((int)signal_num == signal_table[i].sig) { + signal_string = signal_table[i].signal_name; break; - case SIGUSR1: - signal_string = "DUMP"; - break; - case SIGUSR2: - signal_string = "DEBUG"; - break; - case SIGNEWNYM: - signal_string = "NEWNYM"; - break; - case SIGCLEARDNSCACHE: - signal_string = "CLEARDNSCACHE"; - break; - case SIGHEARTBEAT: - signal_string = "HEARTBEAT"; - break; - default: - log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal", - (unsigned long)signal_num); - return -1; + } + } + + if (signal_string == NULL) { + log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal", + (unsigned long)signal_num); + return -1; } send_control_event(EVENT_GOT_SIGNAL, "650 SIGNAL %s\r\n", diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c index 6f30878d23..5dcc4b170d 100644 --- a/src/feature/control/control_getinfo.c +++ b/src/feature/control/control_getinfo.c @@ -1735,6 +1735,7 @@ handle_control_getinfo(control_connection_t *conn, } } else { control_reply_add_one_kv(answers, 250, KV_RAW, q, ans); + tor_free(ans); } } SMARTLIST_FOREACH_END(q); diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c index 3aeeab3b31..ca16dc8424 100644 --- a/src/feature/dirauth/dirauth_config.c +++ b/src/feature/dirauth/dirauth_config.c @@ -27,6 +27,7 @@ #include "feature/dirauth/authmode.h" #include "feature/dirauth/bwauth.h" #include "feature/dirauth/dirauth_periodic.h" +#include "feature/dirauth/dirauth_sys.h" #include "feature/dirauth/dirvote.h" #include "feature/dirauth/guardfraction.h" #include "feature/dirauth/dirauth_options_st.h" @@ -45,6 +46,14 @@ #define YES_IF_CHANGED_INT(opt) \ if (!CFG_EQ_INT(old_options, new_options, opt)) return 1; +/** Return true iff we are configured to reject request under load for non + * relay connections. */ +bool +dirauth_should_reject_requests_under_load(void) +{ + return !!dirauth_get_options()->AuthDirRejectRequestsUnderLoad; +} + /** * Legacy validation/normalization function for the dirauth mode options in * options. Uses old_options as the previous options. diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h index 2ebafd917e..1ec599717c 100644 --- a/src/feature/dirauth/dirauth_config.h +++ b/src/feature/dirauth/dirauth_config.h @@ -35,6 +35,8 @@ int options_act_dirauth_mtbf(const struct or_options_t *old_options); int options_act_dirauth_stats(const struct or_options_t *old_options, bool *print_notice_out); +bool dirauth_should_reject_requests_under_load(void); + extern const struct config_format_t dirauth_options_fmt; #else /* !defined(HAVE_MODULE_DIRAUTH) */ @@ -78,6 +80,8 @@ options_validate_dirauth_mode(const struct or_options_t *old_options, #define options_act_dirauth_stats(old_options, print_notice_out) \ (((void)(old_options)),((void)(print_notice_out)),0) +#define dirauth_should_reject_requests_under_load() (false) + #endif /* defined(HAVE_MODULE_DIRAUTH) */ #endif /* !defined(TOR_FEATURE_DIRAUTH_DIRAUTH_CONFIG_H) */ diff --git a/src/feature/dirauth/dirauth_options.inc b/src/feature/dirauth/dirauth_options.inc index 5939010fe7..21f4996c39 100644 --- a/src/feature/dirauth/dirauth_options.inc +++ b/src/feature/dirauth/dirauth_options.inc @@ -95,4 +95,11 @@ CONF_VAR(TestingMinFastFlagThreshold, MEMUNIT, 0, "0") * versions? */ CONF_VAR(VersioningAuthoritativeDirectory, BOOL, 0, "0") +/** Boolean: Under bandwidth pressure, if set to 1, the authority will always + * answer directory requests from relays but will start sending 503 error code + * for the other connections. If set to 0, all connections are considered the + * same and the authority will try to answer them all regardless of bandwidth + * pressure or not. */ +CONF_VAR(AuthDirRejectRequestsUnderLoad, BOOL, 0, "1") + END_CONF_STRUCT(dirauth_options_t) diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index 9490867e82..90e82a4ee8 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -2963,7 +2963,7 @@ dirvote_perform_vote(void) if (!contents) return -1; - pending_vote = dirvote_add_vote(contents, &msg, &status); + pending_vote = dirvote_add_vote(contents, 0, &msg, &status); tor_free(contents); if (!pending_vote) { log_warn(LD_DIR, "Couldn't store my own vote! (I told myself, '%s'.)", @@ -3119,13 +3119,45 @@ list_v3_auth_ids(void) return keys; } +/* Check the voter information <b>vi</b>, and assert that at least one + * signature is good. Asserts on failure. */ +static void +assert_any_sig_good(const networkstatus_voter_info_t *vi) +{ + int any_sig_good = 0; + SMARTLIST_FOREACH(vi->sigs, document_signature_t *, sig, + if (sig->good_signature) + any_sig_good = 1); + tor_assert(any_sig_good); +} + +/* Add <b>cert</b> to our list of known authority certificates. */ +static void +add_new_cert_if_needed(const struct authority_cert_t *cert) +{ + tor_assert(cert); + if (!authority_cert_get_by_digests(cert->cache_info.identity_digest, + cert->signing_key_digest)) { + /* Hey, it's a new cert! */ + trusted_dirs_load_certs_from_string( + cert->cache_info.signed_descriptor_body, + TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 /*flush*/, + NULL); + if (!authority_cert_get_by_digests(cert->cache_info.identity_digest, + cert->signing_key_digest)) { + log_warn(LD_BUG, "We added a cert, but still couldn't find it."); + } + } +} + /** Called when we have received a networkstatus vote in <b>vote_body</b>. * Parse and validate it, and on success store it as a pending vote (which we * then return). Return NULL on failure. Sets *<b>msg_out</b> and * *<b>status_out</b> to an HTTP response and status code. (V3 authority * only) */ pending_vote_t * -dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) +dirvote_add_vote(const char *vote_body, time_t time_posted, + const char **msg_out, int *status_out) { networkstatus_t *vote; networkstatus_voter_info_t *vi; @@ -3156,13 +3188,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) } tor_assert(smartlist_len(vote->voters) == 1); vi = get_voter(vote); - { - int any_sig_good = 0; - SMARTLIST_FOREACH(vi->sigs, document_signature_t *, sig, - if (sig->good_signature) - any_sig_good = 1); - tor_assert(any_sig_good); - } + assert_any_sig_good(vi); ds = trusteddirserver_get_by_v3_auth_digest(vi->identity_digest); if (!ds) { char *keys = list_v3_auth_ids(); @@ -3175,19 +3201,7 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) *msg_out = "Vote not from a recognized v3 authority"; goto err; } - tor_assert(vote->cert); - if (!authority_cert_get_by_digests(vote->cert->cache_info.identity_digest, - vote->cert->signing_key_digest)) { - /* Hey, it's a new cert! */ - trusted_dirs_load_certs_from_string( - vote->cert->cache_info.signed_descriptor_body, - TRUSTED_DIRS_CERTS_SRC_FROM_VOTE, 1 /*flush*/, - NULL); - if (!authority_cert_get_by_digests(vote->cert->cache_info.identity_digest, - vote->cert->signing_key_digest)) { - log_warn(LD_BUG, "We added a cert, but still couldn't find it."); - } - } + add_new_cert_if_needed(vote->cert); /* Is it for the right period? */ if (vote->valid_after != voting_schedule.interval_starts) { @@ -3200,6 +3214,23 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) goto err; } + /* Check if we received it, as a post, after the cutoff when we + * start asking other dir auths for it. If we do, the best plan + * is to discard it, because using it greatly increases the chances + * of a split vote for this round (some dir auths got it in time, + * some didn't). */ + if (time_posted && time_posted > voting_schedule.fetch_missing_votes) { + char tbuf1[ISO_TIME_LEN+1], tbuf2[ISO_TIME_LEN+1]; + format_iso_time(tbuf1, time_posted); + format_iso_time(tbuf2, voting_schedule.fetch_missing_votes); + log_warn(LD_DIR, "Rejecting posted vote from %s received at %s; " + "our cutoff for received votes is %s. Check your clock, " + "CPU load, and network load. Also check the authority that " + "posted the vote.", vi->address, tbuf1, tbuf2); + *msg_out = "Posted vote received too late, would be dangerous to count it"; + goto err; + } + /* Fetch any new router descriptors we just learned about */ update_consensus_router_descriptor_downloads(time(NULL), 1, vote); @@ -4619,17 +4650,14 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, /* These are hardwired, to avoid disaster. */ v3_out->recommended_relay_protocols = - tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " - "Link=4 Microdesc=1-2 Relay=2"); + tor_strdup(DIRVOTE_RECCOMEND_RELAY_PROTO); v3_out->recommended_client_protocols = - tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " - "Link=4 Microdesc=1-2 Relay=2"); - v3_out->required_client_protocols = - tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " - "Link=4 Microdesc=1-2 Relay=2"); + tor_strdup(DIRVOTE_RECCOMEND_CLIENT_PROTO); + v3_out->required_relay_protocols = - tor_strdup("Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " - "Link=3-4 Microdesc=1 Relay=1-2"); + tor_strdup(DIRVOTE_REQUIRE_RELAY_PROTO); + v3_out->required_client_protocols = + tor_strdup(DIRVOTE_REQUIRE_CLIENT_PROTO); /* We are not allowed to vote to require anything we don't have. */ tor_assert(protover_all_supported(v3_out->required_relay_protocols, NULL)); diff --git a/src/feature/dirauth/dirvote.h b/src/feature/dirauth/dirvote.h index f695e93abf..f2dbee20e5 100644 --- a/src/feature/dirauth/dirvote.h +++ b/src/feature/dirauth/dirvote.h @@ -94,6 +94,7 @@ void dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items, /* Storing signatures and votes functions */ struct pending_vote_t * dirvote_add_vote(const char *vote_body, + time_t time_posted, const char **msg_out, int *status_out); int dirvote_add_signatures(const char *detached_signatures_body, @@ -142,9 +143,13 @@ dirvote_dirreq_get_status_vote(const char *url, smartlist_t *items, } static inline struct pending_vote_t * -dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out) +dirvote_add_vote(const char *vote_body, + time_t time_posted, + const char **msg_out, + int *status_out) { (void) vote_body; + (void) time_posted; /* If the dirauth module is disabled, this should NEVER be called else we * failed to safeguard the dirauth module. */ tor_assert_nonfatal_unreached(); @@ -230,6 +235,36 @@ char *networkstatus_get_detached_signatures(smartlist_t *consensuses); STATIC microdesc_t *dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method); +/** The recommended relay protocols for this authority's votes. + * Recommending a new protocol causes old tor versions to log a warning. + */ +#define DIRVOTE_RECCOMEND_RELAY_PROTO \ + "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " \ + "Link=4 Microdesc=1-2 Relay=2" +/** The recommended client protocols for this authority's votes. + * Recommending a new protocol causes old tor versions to log a warning. + */ +#define DIRVOTE_RECCOMEND_CLIENT_PROTO \ + "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " \ + "Link=4 Microdesc=1-2 Relay=2" + +/** The required relay protocols for this authority's votes. + * WARNING: Requiring a new protocol causes old tor versions to shut down. + * Requiring the wrong protocols can break the tor network. + * See Proposal 303: When and how to remove support for protocol versions. + */ +#define DIRVOTE_REQUIRE_RELAY_PROTO \ + "Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " \ + "Link=3-4 Microdesc=1 Relay=1-2" +/** The required relay protocols for this authority's votes. + * WARNING: Requiring a new protocol causes old tor versions to shut down. + * Requiring the wrong protocols can break the tor network. + * See Proposal 303: When and how to remove support for protocol versions. + */ +#define DIRVOTE_REQUIRE_CLIENT_PROTO \ + "Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 " \ + "Link=4 Microdesc=1-2 Relay=2" + #endif /* defined(DIRVOTE_PRIVATE) */ #endif /* !defined(TOR_DIRVOTE_H) */ diff --git a/src/feature/dirauth/process_descs.h b/src/feature/dirauth/process_descs.h index 55b828ba64..9c13692778 100644 --- a/src/feature/dirauth/process_descs.h +++ b/src/feature/dirauth/process_descs.h @@ -15,7 +15,7 @@ // for was_router_added_t. #include "feature/nodelist/routerlist.h" -#include "src/lib/crypt_ops/crypto_ed25519.h" +#include "lib/crypt_ops/crypto_ed25519.h" struct authdir_config_t; @@ -47,7 +47,7 @@ typedef struct authdir_config_t { #define RTR_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */ /* 32 Historically used to indicade Unnamed */ -#endif /* defined(TOR_UNIT_TESTS) */ +#endif /* defined(PROCESS_DESCS_PRIVATE) || defined(TOR_UNIT_TESTS) */ #ifdef TOR_UNIT_TESTS @@ -55,7 +55,7 @@ void authdir_init_fingerprint_list(void); authdir_config_t *authdir_return_fingerprint_list(void); -#endif /* defined(PROCESS_DESCS_PRIVATE) || defined(TOR_UNIT_TESTS) */ +#endif /* defined(TOR_UNIT_TESTS) */ void dirserv_free_fingerprint_list(void); diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index ef7054001e..4f7f209207 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -957,7 +957,7 @@ handle_get_current_consensus(dir_connection_t *conn, goto done; } - if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) { + if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) { log_debug(LD_DIRSERV, "Client asked for network status lists, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); @@ -1066,7 +1066,7 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args) } }); - if (global_write_bucket_low(TO_CONN(conn), estimated_len, 2)) { + if (connection_dir_is_global_write_low(TO_CONN(conn), estimated_len)) { write_short_http_response(conn, 503, "Directory busy, try again later"); goto vote_done; } @@ -1125,7 +1125,7 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args) write_short_http_response(conn, 404, "Not found"); goto done; } - if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) { + if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) { log_info(LD_DIRSERV, "Client asked for server descriptors, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); @@ -1223,7 +1223,7 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args) msg = "Not found"; write_short_http_response(conn, 404, msg); } else { - if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) { + if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) { log_info(LD_DIRSERV, "Client asked for server descriptors, but we've been " "writing too many bytes lately. Sending 503 Dir busy."); @@ -1319,9 +1319,8 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args) SMARTLIST_FOREACH(certs, authority_cert_t *, c, len += c->cache_info.signed_descriptor_len); - if (global_write_bucket_low(TO_CONN(conn), - compress_method != NO_METHOD ? len/2 : len, - 2)) { + if (connection_dir_is_global_write_low(TO_CONN(conn), + compress_method != NO_METHOD ? len/2 : len)) { write_short_http_response(conn, 503, "Directory busy, try again later"); goto keys_done; } @@ -1696,7 +1695,7 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, !strcmp(url,"/tor/post/vote")) { /* v3 networkstatus vote */ const char *msg = "OK"; int status; - if (dirvote_add_vote(body, &msg, &status)) { + if (dirvote_add_vote(body, approx_time(), &msg, &status)) { write_short_http_response(conn, status, "Vote stored"); } else { tor_assert(msg); diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index 3a168c2035..73a64b1b7e 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -93,7 +93,7 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus, const common_digests_t *digests, const uint8_t *sha3_as_signed, time_t published); -#else +#else /* !defined(HAVE_MODULE_DIRCACHE) */ #define have_module_dircache() (0) #define directory_caches_unknown_auth_certs(opt) \ ((void)(opt), 0) @@ -112,7 +112,7 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus, (void)(e); \ (void)(f); \ } STMT_END -#endif +#endif /* defined(HAVE_MODULE_DIRCACHE) */ void dirserv_clear_old_networkstatuses(time_t cutoff); int dirserv_get_routerdesc_spool(smartlist_t *spools_out, const char *key, diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 1b6eed12f0..a216e5e27a 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -2364,7 +2364,7 @@ handle_response_fetch_status_vote(dir_connection_t *conn, conn->base_.port, conn->requested_resource); return -1; } - dirvote_add_vote(body, &msg, &st); + dirvote_add_vote(body, 0, &msg, &st); if (st > 299) { log_warn(LD_DIR, "Error adding retrieved vote: %s", msg); } else { diff --git a/src/feature/dircommon/dir_connection_st.h b/src/feature/dircommon/dir_connection_st.h index 2c68e61845..12230e6741 100644 --- a/src/feature/dircommon/dir_connection_st.h +++ b/src/feature/dircommon/dir_connection_st.h @@ -28,7 +28,9 @@ struct dir_connection_t { * fingerprints. **/ char *requested_resource; - unsigned int dirconn_direct:1; /**< Is this dirconn direct, or via Tor? */ + /** Is this dirconn direct, or via a multi-hop Tor circuit? + * Direct connections can use the DirPort, or BEGINDIR over the ORPort. */ + unsigned int dirconn_direct:1; /** If we're fetching descriptors, what router purpose shall we assign * to them? */ diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index a7b41b835f..9cf408ca3e 100644 --- a/src/feature/hs/hs_cache.c +++ b/src/feature/hs/hs_cache.c @@ -847,6 +847,42 @@ hs_cache_store_as_client(const char *desc_str, return ret; } +/** Remove and free a client cache descriptor entry for the given onion + * service ed25519 public key. If the descriptor is decoded, the intro + * circuits are closed if any. + * + * This does nothing if no descriptor exists for the given key. */ +void +hs_cache_remove_as_client(const ed25519_public_key_t *key) +{ + hs_cache_client_descriptor_t *cached_desc = NULL; + + tor_assert(key); + + cached_desc = lookup_v3_desc_as_client(key->pubkey); + if (!cached_desc) { + return; + } + /* If we have a decrypted/decoded descriptor, attempt to close its + * introduction circuit(s). We shouldn't have circuit(s) without a + * descriptor else it will lead to a failure. */ + if (cached_desc->desc) { + hs_client_close_intro_circuits_from_desc(cached_desc->desc); + } + /* Remove and free. */ + remove_v3_desc_as_client(cached_desc); + cache_client_desc_free(cached_desc); + + /* Logging. */ + { + char key_b64[BASE64_DIGEST256_LEN + 1]; + digest256_to_base64(key_b64, (const char *) key); + log_info(LD_REND, "Onion service v3 descriptor '%s' removed " + "from client cache", + safe_str_client(key_b64)); + } +} + /** Clean all client caches using the current time now. */ void hs_cache_clean_as_client(time_t now) diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h index ebe1621e88..bb3c77f224 100644 --- a/src/feature/hs/hs_cache.h +++ b/src/feature/hs/hs_cache.h @@ -85,6 +85,7 @@ const char * hs_cache_lookup_encoded_as_client(const struct ed25519_public_key_t *key); hs_desc_decode_status_t hs_cache_store_as_client(const char *desc_str, const struct ed25519_public_key_t *identity_pk); +void hs_cache_remove_as_client(const struct ed25519_public_key_t *key); void hs_cache_clean_as_client(time_t now); void hs_cache_purge_as_client(void); diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index 58a143650b..d5c1c5ca9a 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -633,9 +633,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; } @@ -1249,6 +1254,26 @@ can_client_refetch_desc(const ed25519_public_key_t *identity_pk, return 0; } +/** Purge the client authorization cache of all ephemeral entries that is the + * entries that are not flagged with CLIENT_AUTH_FLAG_IS_PERMANENT. + * + * This is called from the hs_client_purge_state() used by a SIGNEWNYM. */ +STATIC void +purge_ephemeral_client_auth(void) +{ + DIGEST256MAP_FOREACH_MODIFY(client_auths, key, + hs_client_service_authorization_t *, auth) { + /* Cleanup every entry that are _NOT_ permanent that is ephemeral. */ + if (!(auth->flags & CLIENT_AUTH_FLAG_IS_PERMANENT)) { + MAP_DEL_CURRENT(key); + client_service_authorization_free(auth); + } + } DIGESTMAP_FOREACH_END; + + log_info(LD_REND, "Client onion service ephemeral authorization " + "cache has been purged."); +} + /** Return the client auth in the map using the service identity public key. * Return NULL if it does not exist in the map. */ static hs_client_service_authorization_t * @@ -1715,6 +1740,9 @@ hs_client_remove_auth_credentials(const char *hsaddress) find_and_remove_client_auth_creds_file(cred); } + /* Remove associated descriptor if any. */ + hs_cache_remove_as_client(&service_identity_pk); + client_service_authorization_free(cred); return REMOVAL_SUCCESS; } @@ -2433,6 +2461,8 @@ hs_client_purge_state(void) hs_cache_purge_as_client(); /* Purge the last hidden service request cache. */ hs_purge_last_hid_serv_requests(); + /* Purge ephemeral client authorization. */ + purge_ephemeral_client_auth(); log_info(LD_REND, "Hidden service client state has been purged."); } diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h index 56b24a4119..3660bfa96c 100644 --- a/src/feature/hs/hs_client.h +++ b/src/feature/hs/hs_client.h @@ -162,6 +162,8 @@ MOCK_DECL(STATIC hs_client_fetch_status_t, STATIC void retry_all_socks_conn_waiting_for_desc(void); +STATIC void purge_ephemeral_client_auth(void); + #ifdef TOR_UNIT_TESTS STATIC void set_hs_client_auths_map(digest256map_t *map); diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index 06f4f5482b..ad3af0a143 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -49,6 +49,37 @@ static smartlist_t *trusted_dir_servers = NULL; * and all fallback directory servers. */ static smartlist_t *fallback_dir_servers = NULL; +/** Helper: From a given trusted directory entry, add the v4 or/and v6 address + * to the nodelist address set. */ +static void +add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir) +{ + tor_assert(dir); + tor_assert(dir->is_authority); + + /* Add IPv4 and then IPv6 if applicable. */ + nodelist_add_addr4_to_address_set(dir->addr); + if (!tor_addr_is_null(&dir->ipv6_addr)) { + nodelist_add_addr6_to_address_set(&dir->ipv6_addr); + } +} + +/** Go over the trusted directory server list and add their address(es) to the + * nodelist address set. This is called everytime a new consensus is set. */ +MOCK_IMPL(void, +dirlist_add_trusted_dir_addresses, (void)) +{ + if (!trusted_dir_servers) { + return; + } + + SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, const dir_server_t *, ent) { + if (ent->is_authority) { + add_trusted_dir_to_nodelist_addr_set(ent); + } + } SMARTLIST_FOREACH_END(ent); +} + /** Return the number of directory authorities whose type matches some bit set * in <b>type</b> */ int diff --git a/src/feature/nodelist/dirlist.h b/src/feature/nodelist/dirlist.h index 6bfc2e1b01..9201e76a9c 100644 --- a/src/feature/nodelist/dirlist.h +++ b/src/feature/nodelist/dirlist.h @@ -44,4 +44,6 @@ void dir_server_add(dir_server_t *ent); void clear_dir_servers(void); void dirlist_free_all(void); +MOCK_DECL(void, dirlist_add_trusted_dir_addresses, (void)); + #endif /* !defined(TOR_DIRLIST_H) */ diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index 0d2ff96a6e..cc4b8e1c34 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -102,7 +102,7 @@ #include "feature/nodelist/routerlist_st.h" #include "feature/dirauth/vote_microdesc_hash_st.h" #include "feature/nodelist/vote_routerstatus_st.h" -#include "routerstatus_st.h" +#include "feature/nodelist/routerstatus_st.h" #ifdef HAVE_UNISTD_H #include <unistd.h> diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 1d0b1a0d4b..9bee16fcaf 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -455,22 +455,43 @@ node_add_to_address_set(const node_t *node) if (node->rs) { if (node->rs->addr) - address_set_add_ipv4h(the_nodelist->node_addrs, node->rs->addr); + nodelist_add_addr4_to_address_set(node->rs->addr); if (!tor_addr_is_null(&node->rs->ipv6_addr)) - address_set_add(the_nodelist->node_addrs, &node->rs->ipv6_addr); + nodelist_add_addr6_to_address_set(&node->rs->ipv6_addr); } if (node->ri) { if (node->ri->addr) - address_set_add_ipv4h(the_nodelist->node_addrs, node->ri->addr); + nodelist_add_addr4_to_address_set(node->ri->addr); if (!tor_addr_is_null(&node->ri->ipv6_addr)) - address_set_add(the_nodelist->node_addrs, &node->ri->ipv6_addr); + nodelist_add_addr6_to_address_set(&node->ri->ipv6_addr); } if (node->md) { if (!tor_addr_is_null(&node->md->ipv6_addr)) - address_set_add(the_nodelist->node_addrs, &node->md->ipv6_addr); + nodelist_add_addr6_to_address_set(&node->md->ipv6_addr); } } +/** Add the given v4 address into the nodelist address set. */ +void +nodelist_add_addr4_to_address_set(const uint32_t addr) +{ + if (!the_nodelist || !the_nodelist->node_addrs || addr == 0) { + return; + } + address_set_add_ipv4h(the_nodelist->node_addrs, addr); +} + +/** Add the given v6 address into the nodelist address set. */ +void +nodelist_add_addr6_to_address_set(const tor_addr_t *addr) +{ + if (BUG(!addr) || tor_addr_is_null(addr) || tor_addr_is_v4(addr) || + !the_nodelist || !the_nodelist->node_addrs) { + return; + } + address_set_add(the_nodelist->node_addrs, addr); +} + /** Return true if <b>addr</b> is the address of some node in the nodelist. * If not, probably return false. */ int @@ -612,9 +633,12 @@ nodelist_set_consensus(networkstatus_t *ns) SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node, node->rs = NULL); - /* Conservatively estimate that every node will have 2 addresses. */ - const int estimated_addresses = smartlist_len(ns->routerstatus_list) * - get_estimated_address_per_node(); + /* Conservatively estimate that every node will have 2 addresses (v4 and + * v6). Then we add the number of configured trusted authorities we have. */ + int estimated_addresses = smartlist_len(ns->routerstatus_list) * + get_estimated_address_per_node(); + estimated_addresses += (get_n_authorities(V3_DIRINFO & BRIDGE_DIRINFO) * + get_estimated_address_per_node()); address_set_free(the_nodelist->node_addrs); the_nodelist->node_addrs = address_set_new(estimated_addresses); @@ -665,6 +689,9 @@ nodelist_set_consensus(networkstatus_t *ns) SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) { node_add_to_address_set(node); } SMARTLIST_FOREACH_END(node); + /* Then, add all trusted configured directories. Some might not be in the + * consensus so make sure we know them. */ + dirlist_add_trusted_dir_addresses(); if (! authdir) { SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) { diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h index 40aed0067f..6e854ec879 100644 --- a/src/feature/nodelist/nodelist.h +++ b/src/feature/nodelist/nodelist.h @@ -35,6 +35,8 @@ node_t *nodelist_add_microdesc(microdesc_t *md); void nodelist_set_consensus(networkstatus_t *ns); void nodelist_ensure_freshness(networkstatus_t *ns); int nodelist_probably_contains_address(const tor_addr_t *addr); +void nodelist_add_addr4_to_address_set(const uint32_t addr); +void nodelist_add_addr6_to_address_set(const tor_addr_t *addr); void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md); void nodelist_remove_routerinfo(routerinfo_t *ri); diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c index da0cbb1df4..99f48ab2c2 100644 --- a/src/feature/relay/dns.c +++ b/src/feature/relay/dns.c @@ -268,22 +268,6 @@ has_dns_init_failed(void) return nameserver_config_failed; } -/** Helper: Given a TTL from a DNS response, determine what TTL to give the - * OP that asked us to resolve it, and how long to cache that record - * ourselves. */ -uint32_t -dns_clip_ttl(uint32_t ttl) -{ - /* This logic is a defense against "DefectTor" DNS-based traffic - * confirmation attacks, as in https://nymity.ch/tor-dns/tor-dns.pdf . - * We only give two values: a "low" value and a "high" value. - */ - if (ttl < MIN_DNS_TTL_AT_EXIT) - return MIN_DNS_TTL_AT_EXIT; - else - return MAX_DNS_TTL_AT_EXIT; -} - /** Helper: free storage held by an entry in the DNS cache. */ static void free_cached_resolve_(cached_resolve_t *r) @@ -521,7 +505,7 @@ send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type, uint32_t ttl; buf[0] = answer_type; - ttl = dns_clip_ttl(conn->address_ttl); + ttl = clip_dns_ttl(conn->address_ttl); switch (answer_type) { @@ -593,7 +577,7 @@ send_resolved_hostname_cell,(edge_connection_t *conn, size_t namelen = strlen(hostname); tor_assert(namelen < 256); - ttl = dns_clip_ttl(conn->address_ttl); + ttl = clip_dns_ttl(conn->address_ttl); buf[0] = RESOLVED_TYPE_HOSTNAME; buf[1] = (uint8_t)namelen; @@ -987,25 +971,6 @@ assert_connection_edge_not_dns_pending(edge_connection_t *conn) #endif /* 1 */ } -/** Log an error and abort if any connection waiting for a DNS resolve is - * corrupted. */ -void -assert_all_pending_dns_resolves_ok(void) -{ - pending_connection_t *pend; - cached_resolve_t **resolve; - - HT_FOREACH(resolve, cache_map, &cache_root) { - for (pend = (*resolve)->pending_connections; - pend; - pend = pend->next) { - assert_connection_ok(TO_CONN(pend->conn), 0); - tor_assert(!SOCKET_OK(pend->conn->base_.s)); - tor_assert(!connection_in_array(TO_CONN(pend->conn))); - } - } -} - /** Remove <b>conn</b> from the list of connections waiting for conn-\>address. */ void @@ -1063,7 +1028,7 @@ connection_dns_remove(edge_connection_t *conn) * the resolve for <b>address</b> itself, and remove any cached results for * <b>address</b> from the cache. */ -MOCK_IMPL(void, +MOCK_IMPL(STATIC void, dns_cancel_pending_resolve,(const char *address)) { pending_connection_t *pend; @@ -1338,7 +1303,7 @@ make_pending_resolve_cached(cached_resolve_t *resolve) resolve->ttl_hostname < ttl) ttl = resolve->ttl_hostname; - set_expiry(new_resolve, time(NULL) + dns_clip_ttl(ttl)); + set_expiry(new_resolve, time(NULL) + clip_dns_ttl(ttl)); } assert_cache_ok(); @@ -2188,7 +2153,7 @@ dns_cache_handle_oom(time_t now, size_t min_remove_bytes) total_bytes_removed += bytes_removed; /* Increase time_inc by a reasonable fraction. */ - time_inc += (MAX_DNS_TTL_AT_EXIT / 4); + time_inc += (MAX_DNS_TTL / 4); } while (total_bytes_removed < min_remove_bytes); return total_bytes_removed; diff --git a/src/feature/relay/dns.h b/src/feature/relay/dns.h index 2b1da8d126..120b75bf8d 100644 --- a/src/feature/relay/dns.h +++ b/src/feature/relay/dns.h @@ -12,29 +12,14 @@ #ifndef TOR_DNS_H #define TOR_DNS_H -/** Lowest value for DNS ttl that a server will give. */ -#define MIN_DNS_TTL_AT_EXIT (5*60) -/** Highest value for DNS ttl that a server will give. */ -#define MAX_DNS_TTL_AT_EXIT (60*60) - -/** How long do we keep DNS cache entries before purging them (regardless of - * their TTL)? */ -#define MAX_DNS_ENTRY_AGE (3*60*60) -/** How long do we cache/tell clients to cache DNS records when no TTL is - * known? */ -#define DEFAULT_DNS_TTL (30*60) +#ifdef HAVE_MODULE_RELAY int dns_init(void); int has_dns_init_failed(void); -void dns_free_all(void); -uint32_t dns_clip_ttl(uint32_t ttl); int dns_reset(void); void connection_dns_remove(edge_connection_t *conn); void assert_connection_edge_not_dns_pending(edge_connection_t *conn); -void assert_all_pending_dns_resolves_ok(void); -MOCK_DECL(void,dns_cancel_pending_resolve,(const char *question)); int dns_resolve(edge_connection_t *exitconn); -void dns_launch_correctness_checks(void); int dns_seems_to_be_broken(void); int dns_seems_to_be_broken_for_ipv6(void); void dns_reset_correctness_checks(void); @@ -42,6 +27,48 @@ size_t dns_cache_total_allocation(void); void dump_dns_mem_usage(int severity); size_t dns_cache_handle_oom(time_t now, size_t min_remove_bytes); +/* These functions are only used within the feature/relay module, and don't + * need stubs. */ +void dns_free_all(void); +void dns_launch_correctness_checks(void); + +#else /* !defined(HAVE_MODULE_RELAY) */ + +#define dns_init() (0) +#define dns_seems_to_be_broken() (0) +#define has_dns_init_failed() (0) +#define dns_cache_total_allocation() (0) + +#define dns_reset_correctness_checks() STMT_NIL + +#define assert_connection_edge_not_dns_pending(conn) \ + ((void)(conn)) +#define dump_dns_mem_usage(severity)\ + ((void)(severity)) +#define dns_cache_handle_oom(now, bytes) \ + ((void)(now), (void)(bytes), 0) + +#define connection_dns_remove(conn) \ + STMT_BEGIN \ + (void)(conn); \ + tor_assert_nonfatal_unreached(); \ + STMT_END + +static inline int +dns_reset(void) +{ + return 0; +} +static inline int +dns_resolve(edge_connection_t *exitconn) +{ + (void)exitconn; + tor_assert_nonfatal_unreached(); + return -1; +} + +#endif /* defined(HAVE_MODULE_RELAY) */ + #ifdef DNS_PRIVATE #include "feature/relay/dns_structs.h" @@ -50,6 +77,7 @@ size_t number_of_configured_nameservers(void); tor_addr_t *configured_nameserver_address(const size_t idx); #endif +MOCK_DECL(STATIC void,dns_cancel_pending_resolve,(const char *question)); MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve,or_circuit_t *oncirc, char **hostname_out, int *made_connection_pending_out, cached_resolve_t **resolve_out)); @@ -74,4 +102,3 @@ launch_resolve,(cached_resolve_t *resolve)); #endif /* defined(DNS_PRIVATE) */ #endif /* !defined(TOR_DNS_H) */ - diff --git a/src/feature/relay/ext_orport.c b/src/feature/relay/ext_orport.c index ce4e043dd7..5568dacf1a 100644 --- a/src/feature/relay/ext_orport.c +++ b/src/feature/relay/ext_orport.c @@ -652,6 +652,77 @@ connection_ext_or_start_auth(or_connection_t *or_conn) return 0; } +/** Global map between Extended ORPort identifiers and OR + * connections. */ +static digestmap_t *orconn_ext_or_id_map = NULL; + +/** Remove the Extended ORPort identifier of <b>conn</b> from the + * global identifier list. Also, clear the identifier from the + * connection itself. */ +void +connection_or_remove_from_ext_or_id_map(or_connection_t *conn) +{ + or_connection_t *tmp; + if (!orconn_ext_or_id_map) + return; + if (!conn->ext_or_conn_id) + return; + + tmp = digestmap_remove(orconn_ext_or_id_map, conn->ext_or_conn_id); + if (!tor_digest_is_zero(conn->ext_or_conn_id)) + tor_assert(tmp == conn); + + memset(conn->ext_or_conn_id, 0, EXT_OR_CONN_ID_LEN); +} + +#ifdef TOR_UNIT_TESTS +/** Return the connection whose ext_or_id is <b>id</b>. Return NULL if no such + * connection is found. */ +or_connection_t * +connection_or_get_by_ext_or_id(const char *id) +{ + if (!orconn_ext_or_id_map) + return NULL; + return digestmap_get(orconn_ext_or_id_map, id); +} +#endif /* defined(TOR_UNIT_TESTS) */ + +/** Deallocate the global Extended ORPort identifier list */ +void +connection_or_clear_ext_or_id_map(void) +{ + digestmap_free(orconn_ext_or_id_map, NULL); + orconn_ext_or_id_map = NULL; +} + +/** Creates an Extended ORPort identifier for <b>conn</b> and deposits + * it into the global list of identifiers. */ +void +connection_or_set_ext_or_identifier(or_connection_t *conn) +{ + char random_id[EXT_OR_CONN_ID_LEN]; + or_connection_t *tmp; + + if (!orconn_ext_or_id_map) + orconn_ext_or_id_map = digestmap_new(); + + /* Remove any previous identifiers: */ + if (conn->ext_or_conn_id && !tor_digest_is_zero(conn->ext_or_conn_id)) + connection_or_remove_from_ext_or_id_map(conn); + + do { + crypto_rand(random_id, sizeof(random_id)); + } while (digestmap_get(orconn_ext_or_id_map, random_id)); + + if (!conn->ext_or_conn_id) + conn->ext_or_conn_id = tor_malloc_zero(EXT_OR_CONN_ID_LEN); + + memcpy(conn->ext_or_conn_id, random_id, EXT_OR_CONN_ID_LEN); + + tmp = digestmap_set(orconn_ext_or_id_map, random_id, conn); + tor_assert(!tmp); +} + /** Free any leftover allocated memory of the ext_orport.c subsystem. */ void ext_orport_free_all(void) diff --git a/src/feature/relay/ext_orport.h b/src/feature/relay/ext_orport.h index dbe89fce18..416c358397 100644 --- a/src/feature/relay/ext_orport.h +++ b/src/feature/relay/ext_orport.h @@ -31,26 +31,56 @@ #define EXT_OR_CONN_STATE_FLUSHING 5 #define EXT_OR_CONN_STATE_MAX_ 5 -int connection_ext_or_start_auth(or_connection_t *or_conn); - -ext_or_cmd_t *ext_or_cmd_new(uint16_t len); +#ifdef HAVE_MODULE_RELAY -#define ext_or_cmd_free(cmd) \ - FREE_AND_NULL(ext_or_cmd_t, ext_or_cmd_free_, (cmd)) +int connection_ext_or_start_auth(or_connection_t *or_conn); -void ext_or_cmd_free_(ext_or_cmd_t *cmd); void connection_or_set_ext_or_identifier(or_connection_t *conn); void connection_or_remove_from_ext_or_id_map(or_connection_t *conn); void connection_or_clear_ext_or_id_map(void); -or_connection_t *connection_or_get_by_ext_or_id(const char *id); - int connection_ext_or_finished_flushing(or_connection_t *conn); int connection_ext_or_process_inbuf(or_connection_t *or_conn); +char *get_ext_or_auth_cookie_file_name(void); +/* (No stub needed for these: they are only called within feature/relay.) */ int init_ext_or_cookie_authentication(int is_enabled); -char *get_ext_or_auth_cookie_file_name(void); void ext_orport_free_all(void); +#else /* !defined(HAVE_MODULE_RELAY) */ + +static inline int +connection_ext_or_start_auth(or_connection_t *conn) +{ + (void)conn; + tor_assert_nonfatal_unreached(); + return -1; +} +static inline int +connection_ext_or_finished_flushing(or_connection_t *conn) +{ + (void)conn; + tor_assert_nonfatal_unreached(); + return -1; +} +static inline int +connection_ext_or_process_inbuf(or_connection_t *conn) +{ + (void)conn; + tor_assert_nonfatal_unreached(); + return -1; +} +#define connection_or_set_ext_or_identifier(conn) \ + ((void)(conn)) +#define connection_or_remove_from_ext_or_id_map(conn) \ + ((void)(conn)) +#define connection_or_clear_ext_or_id_map() \ + STMT_NIL + +#define get_ext_or_auth_cookie_file_name() \ + (NULL) + +#endif /* defined(HAVE_MODULE_RELAY) */ + #ifdef EXT_ORPORT_PRIVATE STATIC int connection_write_ext_or_command(connection_t *conn, uint16_t command, @@ -60,9 +90,11 @@ STATIC int handle_client_auth_nonce(const char *client_nonce, size_t client_nonce_len, char **client_hash_out, char **reply_out, size_t *reply_len_out); + #ifdef TOR_UNIT_TESTS extern uint8_t *ext_or_auth_cookie; extern int ext_or_auth_cookie_is_set; +or_connection_t *connection_or_get_by_ext_or_id(const char *id); #endif #endif /* defined(EXT_ORPORT_PRIVATE) */ diff --git a/src/feature/relay/include.am b/src/feature/relay/include.am index a4c025ae12..813ddb8fb1 100644 --- a/src/feature/relay/include.am +++ b/src/feature/relay/include.am @@ -1,21 +1,22 @@ # Legacy shared relay code: migrate to the relay module over time LIBTOR_APP_A_SOURCES += \ - src/feature/relay/dns.c \ - src/feature/relay/ext_orport.c \ src/feature/relay/onion_queue.c \ - src/feature/relay/router.c \ - src/feature/relay/routerkeys.c \ - src/feature/relay/selftest.c + src/feature/relay/router.c # The Relay module. # ADD_C_FILE: INSERT SOURCES HERE. MODULE_RELAY_SOURCES = \ + src/feature/relay/dns.c \ + src/feature/relay/ext_orport.c \ src/feature/relay/routermode.c \ src/feature/relay/relay_config.c \ + src/feature/relay/relay_handshake.c \ src/feature/relay/relay_periodic.c \ src/feature/relay/relay_sys.c \ + src/feature/relay/routerkeys.c \ + src/feature/relay/selftest.c \ src/feature/relay/transport_config.c # ADD_C_FILE: INSERT HEADERS HERE. @@ -25,6 +26,7 @@ noinst_HEADERS += \ src/feature/relay/ext_orport.h \ src/feature/relay/onion_queue.h \ src/feature/relay/relay_config.h \ + src/feature/relay/relay_handshake.h \ src/feature/relay/relay_periodic.h \ src/feature/relay/relay_sys.h \ src/feature/relay/router.h \ diff --git a/src/feature/relay/relay_handshake.c b/src/feature/relay/relay_handshake.c new file mode 100644 index 0000000000..030dc94956 --- /dev/null +++ b/src/feature/relay/relay_handshake.c @@ -0,0 +1,565 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_handshake.c + * @brief Functions to implement the relay-only parts of our + * connection handshake. + * + * Some parts of our TLS link handshake are only done by relays (including + * bridges). Specifically, only relays need to send CERTS cells; only + * relays need to send or receive AUTHCHALLENGE cells, and only relays need to + * send or receive AUTHENTICATE cells. + **/ + +#include "orconfig.h" +#include "core/or/or.h" +#include "feature/relay/relay_handshake.h" + +#include "app/config/config.h" +#include "core/or/connection_or.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "trunnel/link_handshake.h" +#include "feature/relay/routerkeys.h" +#include "feature/nodelist/torcert.h" + +#include "core/or/or_connection_st.h" +#include "core/or/or_handshake_certs_st.h" +#include "core/or/or_handshake_state_st.h" +#include "core/or/var_cell_st.h" + +#include "lib/tls/tortls.h" +#include "lib/tls/x509.h" + +/** Helper used to add an encoded certs to a cert cell */ +static void +add_certs_cell_cert_helper(certs_cell_t *certs_cell, + uint8_t cert_type, + const uint8_t *cert_encoded, + size_t cert_len) +{ + tor_assert(cert_len <= UINT16_MAX); + certs_cell_cert_t *ccc = certs_cell_cert_new(); + ccc->cert_type = cert_type; + ccc->cert_len = cert_len; + certs_cell_cert_setlen_body(ccc, cert_len); + memcpy(certs_cell_cert_getarray_body(ccc), cert_encoded, cert_len); + + certs_cell_add_certs(certs_cell, ccc); +} + +/** Add an encoded X509 cert (stored as <b>cert_len</b> bytes at + * <b>cert_encoded</b>) to the trunnel certs_cell_t object that we are + * building in <b>certs_cell</b>. Set its type field to <b>cert_type</b>. + * (If <b>cert</b> is NULL, take no action.) */ +static void +add_x509_cert(certs_cell_t *certs_cell, + uint8_t cert_type, + const tor_x509_cert_t *cert) +{ + if (NULL == cert) + return; + + const uint8_t *cert_encoded = NULL; + size_t cert_len; + tor_x509_cert_get_der(cert, &cert_encoded, &cert_len); + + add_certs_cell_cert_helper(certs_cell, cert_type, cert_encoded, cert_len); +} + +/** Add an Ed25519 cert from <b>cert</b> to the trunnel certs_cell_t object + * that we are building in <b>certs_cell</b>. Set its type field to + * <b>cert_type</b>. (If <b>cert</b> is NULL, take no action.) */ +static void +add_ed25519_cert(certs_cell_t *certs_cell, + uint8_t cert_type, + const tor_cert_t *cert) +{ + if (NULL == cert) + return; + + add_certs_cell_cert_helper(certs_cell, cert_type, + cert->encoded, cert->encoded_len); +} + +#ifdef TOR_UNIT_TESTS +int certs_cell_ed25519_disabled_for_testing = 0; +#else +#define certs_cell_ed25519_disabled_for_testing 0 +#endif + +/** Send a CERTS cell on the connection <b>conn</b>. Return 0 on success, -1 + * on failure. */ +int +connection_or_send_certs_cell(or_connection_t *conn) +{ + const tor_x509_cert_t *global_link_cert = NULL, *id_cert = NULL; + tor_x509_cert_t *own_link_cert = NULL; + var_cell_t *cell; + + certs_cell_t *certs_cell = NULL; + + tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3); + + if (! conn->handshake_state) + return -1; + + const int conn_in_server_mode = ! conn->handshake_state->started_here; + + /* Get the encoded values of the X509 certificates */ + if (tor_tls_get_my_certs(conn_in_server_mode, + &global_link_cert, &id_cert) < 0) + return -1; + + if (conn_in_server_mode) { + own_link_cert = tor_tls_get_own_cert(conn->tls); + } + tor_assert(id_cert); + + certs_cell = certs_cell_new(); + + /* Start adding certs. First the link cert or auth1024 cert. */ + if (conn_in_server_mode) { + tor_assert_nonfatal(own_link_cert); + add_x509_cert(certs_cell, + OR_CERT_TYPE_TLS_LINK, own_link_cert); + } else { + tor_assert(global_link_cert); + add_x509_cert(certs_cell, + OR_CERT_TYPE_AUTH_1024, global_link_cert); + } + + /* Next the RSA->RSA ID cert */ + add_x509_cert(certs_cell, + OR_CERT_TYPE_ID_1024, id_cert); + + /* Next the Ed25519 certs */ + add_ed25519_cert(certs_cell, + CERTTYPE_ED_ID_SIGN, + get_master_signing_key_cert()); + if (conn_in_server_mode) { + tor_assert_nonfatal(conn->handshake_state->own_link_cert || + certs_cell_ed25519_disabled_for_testing); + add_ed25519_cert(certs_cell, + CERTTYPE_ED_SIGN_LINK, + conn->handshake_state->own_link_cert); + } else { + add_ed25519_cert(certs_cell, + CERTTYPE_ED_SIGN_AUTH, + get_current_auth_key_cert()); + } + + /* And finally the crosscert. */ + { + const uint8_t *crosscert=NULL; + size_t crosscert_len; + get_master_rsa_crosscert(&crosscert, &crosscert_len); + if (crosscert) { + add_certs_cell_cert_helper(certs_cell, + CERTTYPE_RSA1024_ID_EDID, + crosscert, crosscert_len); + } + } + + /* We've added all the certs; make the cell. */ + certs_cell->n_certs = certs_cell_getlen_certs(certs_cell); + + ssize_t alloc_len = certs_cell_encoded_len(certs_cell); + tor_assert(alloc_len >= 0 && alloc_len <= UINT16_MAX); + cell = var_cell_new(alloc_len); + cell->command = CELL_CERTS; + ssize_t enc_len = certs_cell_encode(cell->payload, alloc_len, certs_cell); + tor_assert(enc_len > 0 && enc_len <= alloc_len); + cell->payload_len = enc_len; + + connection_or_write_var_cell_to_buf(cell, conn); + var_cell_free(cell); + certs_cell_free(certs_cell); + tor_x509_cert_free(own_link_cert); + + return 0; +} + +#ifdef TOR_UNIT_TESTS +int testing__connection_or_pretend_TLSSECRET_is_supported = 0; +#else +#define testing__connection_or_pretend_TLSSECRET_is_supported 0 +#endif + +/** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that + * we can send and receive. */ +int +authchallenge_type_is_supported(uint16_t challenge_type) +{ + switch (challenge_type) { + case AUTHTYPE_RSA_SHA256_TLSSECRET: +#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS + return 1; +#else + return testing__connection_or_pretend_TLSSECRET_is_supported; +#endif + case AUTHTYPE_ED25519_SHA256_RFC5705: + return 1; + case AUTHTYPE_RSA_SHA256_RFC5705: + default: + return 0; + } +} + +/** Return true iff <b>challenge_type_a</b> is one that we would rather + * use than <b>challenge_type_b</b>. */ +int +authchallenge_type_is_better(uint16_t challenge_type_a, + uint16_t challenge_type_b) +{ + /* Any supported type is better than an unsupported one; + * all unsupported types are equally bad. */ + if (!authchallenge_type_is_supported(challenge_type_a)) + return 0; + if (!authchallenge_type_is_supported(challenge_type_b)) + return 1; + /* It happens that types are superior in numerically ascending order. + * If that ever changes, this must change too. */ + return (challenge_type_a > challenge_type_b); +} + +/** Send an AUTH_CHALLENGE cell on the connection <b>conn</b>. Return 0 + * on success, -1 on failure. */ +int +connection_or_send_auth_challenge_cell(or_connection_t *conn) +{ + var_cell_t *cell = NULL; + int r = -1; + tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3); + + if (! conn->handshake_state) + return -1; + + auth_challenge_cell_t *ac = auth_challenge_cell_new(); + + tor_assert(sizeof(ac->challenge) == 32); + crypto_rand((char*)ac->challenge, sizeof(ac->challenge)); + + if (authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET)) + auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET); + /* Disabled, because everything that supports this method also supports + * the much-superior ED25519_SHA256_RFC5705 */ + /* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_RFC5705); */ + if (authchallenge_type_is_supported(AUTHTYPE_ED25519_SHA256_RFC5705)) + auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705); + auth_challenge_cell_set_n_methods(ac, + auth_challenge_cell_getlen_methods(ac)); + + cell = var_cell_new(auth_challenge_cell_encoded_len(ac)); + ssize_t len = auth_challenge_cell_encode(cell->payload, cell->payload_len, + ac); + if (len != cell->payload_len) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Encoded auth challenge cell length not as expected"); + goto done; + /* LCOV_EXCL_STOP */ + } + cell->command = CELL_AUTH_CHALLENGE; + + connection_or_write_var_cell_to_buf(cell, conn); + r = 0; + + done: + var_cell_free(cell); + auth_challenge_cell_free(ac); + + return r; +} + +/** Compute the main body of an AUTHENTICATE cell that a client can use + * to authenticate itself on a v3 handshake for <b>conn</b>. Return it + * in a var_cell_t. + * + * If <b>server</b> is true, only calculate the first + * V3_AUTH_FIXED_PART_LEN bytes -- the part of the authenticator that's + * determined by the rest of the handshake, and which match the provided value + * exactly. + * + * If <b>server</b> is false and <b>signing_key</b> is NULL, calculate the + * first V3_AUTH_BODY_LEN bytes of the authenticator (that is, everything + * that should be signed), but don't actually sign it. + * + * If <b>server</b> is false and <b>signing_key</b> is provided, calculate the + * entire authenticator, signed with <b>signing_key</b>. + * + * Return the length of the cell body on success, and -1 on failure. + */ +var_cell_t * +connection_or_compute_authenticate_cell_body(or_connection_t *conn, + const int authtype, + crypto_pk_t *signing_key, + const ed25519_keypair_t *ed_signing_key, + int server) +{ + auth1_t *auth = NULL; + auth_ctx_t *ctx = auth_ctx_new(); + var_cell_t *result = NULL; + int old_tlssecrets_algorithm = 0; + const char *authtype_str = NULL; + + int is_ed = 0; + + /* assert state is reasonable XXXX */ + switch (authtype) { + case AUTHTYPE_RSA_SHA256_TLSSECRET: + authtype_str = "AUTH0001"; + old_tlssecrets_algorithm = 1; + break; + case AUTHTYPE_RSA_SHA256_RFC5705: + authtype_str = "AUTH0002"; + break; + case AUTHTYPE_ED25519_SHA256_RFC5705: + authtype_str = "AUTH0003"; + is_ed = 1; + break; + default: + tor_assert(0); + break; + } + + auth = auth1_new(); + ctx->is_ed = is_ed; + + /* Type: 8 bytes. */ + memcpy(auth1_getarray_type(auth), authtype_str, 8); + + { + const tor_x509_cert_t *id_cert=NULL; + const common_digests_t *my_digests, *their_digests; + const uint8_t *my_id, *their_id, *client_id, *server_id; + if (tor_tls_get_my_certs(server, NULL, &id_cert)) + goto err; + my_digests = tor_x509_cert_get_id_digests(id_cert); + their_digests = + tor_x509_cert_get_id_digests(conn->handshake_state->certs->id_cert); + tor_assert(my_digests); + tor_assert(their_digests); + my_id = (uint8_t*)my_digests->d[DIGEST_SHA256]; + their_id = (uint8_t*)their_digests->d[DIGEST_SHA256]; + + client_id = server ? their_id : my_id; + server_id = server ? my_id : their_id; + + /* Client ID digest: 32 octets. */ + memcpy(auth->cid, client_id, 32); + + /* Server ID digest: 32 octets. */ + memcpy(auth->sid, server_id, 32); + } + + if (is_ed) { + const ed25519_public_key_t *my_ed_id, *their_ed_id; + if (!conn->handshake_state->certs->ed_id_sign) { + log_warn(LD_OR, "Ed authenticate without Ed ID cert from peer."); + goto err; + } + my_ed_id = get_master_identity_key(); + their_ed_id = &conn->handshake_state->certs->ed_id_sign->signing_key; + + const uint8_t *cid_ed = (server ? their_ed_id : my_ed_id)->pubkey; + const uint8_t *sid_ed = (server ? my_ed_id : their_ed_id)->pubkey; + + memcpy(auth->u1_cid_ed, cid_ed, ED25519_PUBKEY_LEN); + memcpy(auth->u1_sid_ed, sid_ed, ED25519_PUBKEY_LEN); + } + + { + crypto_digest_t *server_d, *client_d; + if (server) { + server_d = conn->handshake_state->digest_sent; + client_d = conn->handshake_state->digest_received; + } else { + client_d = conn->handshake_state->digest_sent; + server_d = conn->handshake_state->digest_received; + } + + /* Server log digest : 32 octets */ + crypto_digest_get_digest(server_d, (char*)auth->slog, 32); + + /* Client log digest : 32 octets */ + crypto_digest_get_digest(client_d, (char*)auth->clog, 32); + } + + { + /* Digest of cert used on TLS link : 32 octets. */ + tor_x509_cert_t *cert = NULL; + if (server) { + cert = tor_tls_get_own_cert(conn->tls); + } else { + cert = tor_tls_get_peer_cert(conn->tls); + } + if (!cert) { + log_warn(LD_OR, "Unable to find cert when making %s data.", + authtype_str); + goto err; + } + + memcpy(auth->scert, + tor_x509_cert_get_cert_digests(cert)->d[DIGEST_SHA256], 32); + + tor_x509_cert_free(cert); + } + + /* HMAC of clientrandom and serverrandom using master key : 32 octets */ + if (old_tlssecrets_algorithm) { + if (tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets) < 0) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Somebody asked us for an older TLS " + "authentication method (AUTHTYPE_RSA_SHA256_TLSSECRET) " + "which we don't support."); + } + } else { + char label[128]; + tor_snprintf(label, sizeof(label), + "EXPORTER FOR TOR TLS CLIENT BINDING %s", authtype_str); + int r = tor_tls_export_key_material(conn->tls, auth->tlssecrets, + auth->cid, sizeof(auth->cid), + label); + if (r < 0) { + if (r != -2) + log_warn(LD_BUG, "TLS key export failed for unknown reason."); + // If r == -2, this was openssl bug 7712. + goto err; + } + } + + /* 8 octets were reserved for the current time, but we're trying to get out + * of the habit of sending time around willynilly. Fortunately, nothing + * checks it. That's followed by 16 bytes of nonce. */ + crypto_rand((char*)auth->rand, 24); + + ssize_t maxlen = auth1_encoded_len(auth, ctx); + if (ed_signing_key && is_ed) { + maxlen += ED25519_SIG_LEN; + } else if (signing_key && !is_ed) { + maxlen += crypto_pk_keysize(signing_key); + } + + const int AUTH_CELL_HEADER_LEN = 4; /* 2 bytes of type, 2 bytes of length */ + result = var_cell_new(AUTH_CELL_HEADER_LEN + maxlen); + uint8_t *const out = result->payload + AUTH_CELL_HEADER_LEN; + const size_t outlen = maxlen; + ssize_t len; + + result->command = CELL_AUTHENTICATE; + set_uint16(result->payload, htons(authtype)); + + if ((len = auth1_encode(out, outlen, auth, ctx)) < 0) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Unable to encode signed part of AUTH1 data."); + goto err; + /* LCOV_EXCL_STOP */ + } + + if (server) { + auth1_t *tmp = NULL; + ssize_t len2 = auth1_parse(&tmp, out, len, ctx); + if (!tmp) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Unable to parse signed part of AUTH1 data that " + "we just encoded"); + goto err; + /* LCOV_EXCL_STOP */ + } + result->payload_len = (tmp->end_of_signed - result->payload); + + auth1_free(tmp); + if (len2 != len) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Mismatched length when re-parsing AUTH1 data."); + goto err; + /* LCOV_EXCL_STOP */ + } + goto done; + } + + if (ed_signing_key && is_ed) { + ed25519_signature_t sig; + if (ed25519_sign(&sig, out, len, ed_signing_key) < 0) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Unable to sign ed25519 authentication data"); + goto err; + /* LCOV_EXCL_STOP */ + } + auth1_setlen_sig(auth, ED25519_SIG_LEN); + memcpy(auth1_getarray_sig(auth), sig.sig, ED25519_SIG_LEN); + + } else if (signing_key && !is_ed) { + auth1_setlen_sig(auth, crypto_pk_keysize(signing_key)); + + char d[32]; + crypto_digest256(d, (char*)out, len, DIGEST_SHA256); + int siglen = crypto_pk_private_sign(signing_key, + (char*)auth1_getarray_sig(auth), + auth1_getlen_sig(auth), + d, 32); + if (siglen < 0) { + log_warn(LD_OR, "Unable to sign AUTH1 data."); + goto err; + } + + auth1_setlen_sig(auth, siglen); + } + + len = auth1_encode(out, outlen, auth, ctx); + if (len < 0) { + /* LCOV_EXCL_START */ + log_warn(LD_BUG, "Unable to encode signed AUTH1 data."); + goto err; + /* LCOV_EXCL_STOP */ + } + tor_assert(len + AUTH_CELL_HEADER_LEN <= result->payload_len); + result->payload_len = len + AUTH_CELL_HEADER_LEN; + set_uint16(result->payload+2, htons(len)); + + goto done; + + err: + var_cell_free(result); + result = NULL; + done: + auth1_free(auth); + auth_ctx_free(ctx); + return result; +} + +/** Send an AUTHENTICATE cell on the connection <b>conn</b>. Return 0 on + * success, -1 on failure */ +MOCK_IMPL(int, +connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype)) +{ + var_cell_t *cell; + crypto_pk_t *pk = tor_tls_get_my_client_auth_key(); + /* XXXX make sure we're actually supposed to send this! */ + + if (!pk) { + log_warn(LD_BUG, "Can't compute authenticate cell: no client auth key"); + return -1; + } + if (! authchallenge_type_is_supported(authtype)) { + log_warn(LD_BUG, "Tried to send authenticate cell with unknown " + "authentication type %d", authtype); + return -1; + } + + cell = connection_or_compute_authenticate_cell_body(conn, + authtype, + pk, + get_current_auth_keypair(), + 0 /* not server */); + if (! cell) { + log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unable to compute authenticate cell!"); + return -1; + } + connection_or_write_var_cell_to_buf(cell, conn); + var_cell_free(cell); + + return 0; +} diff --git a/src/feature/relay/relay_handshake.h b/src/feature/relay/relay_handshake.h new file mode 100644 index 0000000000..99a658cbcc --- /dev/null +++ b/src/feature/relay/relay_handshake.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_handshake.h + * @brief Header for feature/relay/relay_handshake.c + **/ + +#ifndef TOR_CORE_OR_RELAY_HANDSHAKE_H +#define TOR_CORE_OR_RELAY_HANDSHAKE_H + +#ifdef HAVE_MODULE_RELAY +struct ed25519_keypair_t; + +int connection_or_send_certs_cell(or_connection_t *conn); +int connection_or_send_auth_challenge_cell(or_connection_t *conn); + +var_cell_t *connection_or_compute_authenticate_cell_body( + or_connection_t *conn, + const int authtype, + crypto_pk_t *signing_key, + const struct ed25519_keypair_t *ed_signing_key, + int server); + +int authchallenge_type_is_supported(uint16_t challenge_type); +int authchallenge_type_is_better(uint16_t challenge_type_a, + uint16_t challenge_type_b); + +MOCK_DECL(int,connection_or_send_authenticate_cell, + (or_connection_t *conn, int type)); + +#ifdef TOR_UNIT_TESTS +extern int certs_cell_ed25519_disabled_for_testing; +#endif +#else /* !defined(HAVE_MODULE_RELAY) */ + +static inline int +connection_or_send_certs_cell(or_connection_t *conn) +{ + (void)conn; + tor_assert_nonfatal_unreached(); + return -1; +} +static inline int +connection_or_send_auth_challenge_cell(or_connection_t *conn) +{ + (void)conn; + tor_assert_nonfatal_unreached(); + return -1; +} + +static inline var_cell_t * +connection_or_compute_authenticate_cell_body( + or_connection_t *conn, + const int authtype, + crypto_pk_t *signing_key, + const struct ed25519_keypair_t *ed_signing_key, + int server) +{ + (void)conn; + (void)authtype; + (void)signing_key; + (void)ed_signing_key; + (void)server; + tor_assert_nonfatal_unreached(); + return NULL; +} + +#define authchallenge_type_is_supported(t) (0) +#define authchallenge_type_is_better(a, b) (0) + +static inline int +connection_or_send_authenticate_cell(or_connection_t *conn, int type) +{ + (void)conn; + (void)type; + tor_assert_nonfatal_unreached(); + return -1; +} + +#ifdef TOR_UNIT_TESTS +extern int certs_cell_ed25519_disabled_for_testing; +#endif + +#endif /* defined(HAVE_MODULE_RELAY) */ + +#endif /* !defined(TOR_CORE_OR_RELAY_HANDSHAKE_H) */ diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index 782609d8ab..2e07df2e88 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -117,7 +117,6 @@ const char *routerinfo_err_to_string(int err); int routerinfo_err_is_transient(int err); void router_reset_warnings(void); -void router_reset_reachability(void); void router_free_all(void); #ifdef ROUTER_PRIVATE diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h index c2475f195f..2b5f03a2a3 100644 --- a/src/feature/relay/routerkeys.h +++ b/src/feature/relay/routerkeys.h @@ -11,6 +11,8 @@ #include "lib/crypt_ops/crypto_ed25519.h" +#ifdef HAVE_MODULE_RELAY + const ed25519_public_key_t *get_master_identity_key(void); MOCK_DECL(const ed25519_keypair_t *, get_master_signing_keypair,(void)); MOCK_DECL(const struct tor_cert_st *, get_master_signing_key_cert,(void)); @@ -24,6 +26,7 @@ void get_master_rsa_crosscert(const uint8_t **cert_out, int router_ed25519_id_is_me(const ed25519_public_key_t *id); +/* These are only used by router.c */ struct tor_cert_st *make_ntor_onion_key_crosscert( const curve25519_keypair_t *onion_key, const ed25519_public_key_t *master_id_key, @@ -42,6 +45,85 @@ int generate_ed_link_cert(const or_options_t *options, time_t now, int force); void routerkeys_free_all(void); +#else /* !defined(HAVE_MODULE_RELAY) */ + +#define router_ed25519_id_is_me(id) \ + ((void)(id), 0) + +static inline void * +relay_key_is_unavailable_(void) +{ + tor_assert_nonfatal_unreached(); + return NULL; +} +#define relay_key_is_unavailable(type) \ + ((type)(relay_key_is_unavailable_())) + +// Many of these can be removed once relay_handshake.c is relay-only. +#define get_current_auth_keypair() \ + relay_key_is_unavailable(const ed25519_keypair_t *) +#define get_master_signing_keypair() \ + relay_key_is_unavailable(const ed25519_keypair_t *) +#define get_current_link_cert_cert() \ + relay_key_is_unavailable(const struct tor_cert_st *) +#define get_current_auth_key_cert() \ + relay_key_is_unavailable(const struct tor_cert_st *) +#define get_master_signing_key_cert() \ + relay_key_is_unavailable(const struct tor_cert_st *) +#define get_master_rsa_crosscert(cert_out, size_out) \ + STMT_BEGIN \ + tor_assert_nonfatal_unreached(); \ + *(cert_out) = NULL; \ + *(size_out) = 0; \ + STMT_END +#define get_master_identity_key() \ + relay_key_is_unavailable(const ed25519_public_key_t *) + +#define generate_ed_link_cert(options, now, force) \ + ((void)(options), (void)(now), (void)(force), 0) +#define should_make_new_ed_keys(options, now) \ + ((void)(options), (void)(now), 0) + +// These can get removed once router.c becomes relay-only. +static inline struct tor_cert_st * +make_ntor_onion_key_crosscert(const curve25519_keypair_t *onion_key, + const ed25519_public_key_t *master_id_key, + time_t now, time_t lifetime, + int *sign_out) +{ + (void)onion_key; + (void)master_id_key; + (void)now; + (void)lifetime; + (void)sign_out; + tor_assert_nonfatal_unreached(); + return NULL; +} +static inline uint8_t * +make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, + const ed25519_public_key_t *master_id_key, + const crypto_pk_t *rsa_id_key, + int *len_out) +{ + (void)onion_key; + (void)master_id_key; + (void)rsa_id_key; + (void)len_out; + tor_assert_nonfatal_unreached(); + return NULL; +} + +/* This calls is used outside of relay mode, but only to implement + * CMD_KEY_EXPIRATION */ +#define log_cert_expiration() \ + (puts("Not available: Tor has been compiled without relay support"), 0) +/* This calls is used outside of relay mode, but only to implement + * CMD_KEYGEN. */ +#define load_ed_keys(x,y) \ + (puts("Not available: Tor has been compiled without relay support"), 0) + +#endif /* defined(HAVE_MODULE_RELAY) */ + #ifdef TOR_UNIT_TESTS const ed25519_keypair_t *get_master_identity_keypair(void); void init_mock_ed_keys(const crypto_pk_t *rsa_identity_key); diff --git a/src/feature/relay/selftest.h b/src/feature/relay/selftest.h index 94f305f203..f3dd698bb7 100644 --- a/src/feature/relay/selftest.h +++ b/src/feature/relay/selftest.h @@ -12,6 +12,7 @@ #ifndef TOR_SELFTEST_H #define TOR_SELFTEST_H +#ifdef HAVE_MODULE_RELAY struct or_options_t; int check_whether_orport_reachable(const struct or_options_t *options); int check_whether_dirport_reachable(const struct or_options_t *options); @@ -20,5 +21,37 @@ void router_do_reachability_checks(int test_or, int test_dir); void router_orport_found_reachable(void); void router_dirport_found_reachable(void); void router_perform_bandwidth_test(int num_circs, time_t now); +void router_reset_reachability(void); + +#else /* !defined(HAVE_MODULE_RELAY) */ + +#define check_whether_orport_reachable(opts) \ + ((void)(opts), 0) +#define check_whether_dirport_reachable(opts) \ + ((void)(opts), 0) + +#define router_orport_found_reachable() \ + STMT_NIL +#define router_dirport_found_reachable() \ + STMT_NIL +#define router_reset_reachability() \ + STMT_NIL + +static inline void +router_do_reachability_checks(int test_or, int test_dir) +{ + (void)test_or; + (void)test_dir; + tor_assert_nonfatal_unreached(); +} +static inline void +router_perform_bandwidth_test(int num_circs, time_t now) +{ + (void)num_circs; + (void)now; + tor_assert_nonfatal_unreached(); +} + +#endif /* defined(HAVE_MODULE_RELAY) */ #endif /* !defined(TOR_SELFTEST_H) */ diff --git a/src/feature/rend/rendmid.c b/src/feature/rend/rendmid.c index 752375b6d3..a473f0c7e1 100644 --- a/src/feature/rend/rendmid.c +++ b/src/feature/rend/rendmid.c @@ -59,7 +59,7 @@ rend_mid_establish_intro_legacy(or_circuit_t *circ, const uint8_t *request, pk = crypto_pk_asn1_decode((char*)(request+2), asn1len); if (!pk) { reason = END_CIRC_REASON_TORPROTOCOL; - log_warn(LD_PROTOCOL, "Couldn't decode public key."); + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Couldn't decode public key."); goto err; } @@ -81,7 +81,7 @@ rend_mid_establish_intro_legacy(or_circuit_t *circ, const uint8_t *request, (char*)request, 2+asn1len+DIGEST_LEN, (char*)(request+2+DIGEST_LEN+asn1len), request_len-(2+DIGEST_LEN+asn1len))<0) { - log_warn(LD_PROTOCOL, + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Incorrect signature on ESTABLISH_INTRO cell; rejecting."); reason = END_CIRC_REASON_TORPROTOCOL; goto err; @@ -162,9 +162,9 @@ rend_mid_introduce_legacy(or_circuit_t *circ, const uint8_t *request, if (request_len < (DIGEST_LEN+(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+ DH1024_KEY_LEN+CIPHER_KEY_LEN+ PKCS1_OAEP_PADDING_OVERHEAD)) { - log_warn(LD_PROTOCOL, "Impossibly short INTRODUCE1 cell on circuit %u; " - "responding with nack.", - (unsigned)circ->p_circ_id); + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Impossibly short INTRODUCE1 cell on circuit %u; " + "responding with nack.", (unsigned)circ->p_circ_id); goto err; } @@ -258,7 +258,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request, } if (circ->base_.n_chan) { - log_warn(LD_PROTOCOL, + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Tried to establish rendezvous on non-edge circuit"); goto err; } @@ -270,8 +270,8 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request, } if (hs_circuitmap_get_rend_circ_relay_side(request)) { - log_warn(LD_PROTOCOL, - "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS."); + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS."); goto err; } @@ -313,9 +313,9 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request, int reason = END_CIRC_REASON_INTERNAL; if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) { - log_info(LD_REND, - "Tried to complete rendezvous on non-OR or non-edge circuit %u.", - (unsigned)circ->p_circ_id); + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Tried to complete rendezvous on non-OR or non-edge circuit %u.", + (unsigned)circ->p_circ_id); reason = END_CIRC_REASON_TORPROTOCOL; goto err; } diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c index b2817ee760..d229c755b4 100644 --- a/src/feature/stats/rephist.c +++ b/src/feature/stats/rephist.c @@ -1122,7 +1122,7 @@ static bw_array_t *dir_read_array = NULL; directory protocol. */ static bw_array_t *dir_write_array = NULL; -/** Set up [dir-]read_array and [dir-]write_array, freeing them if they +/** Set up [dir_]read_array and [dir_]write_array, freeing them if they * already exist. */ static void bw_arrays_init(void) diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h index 907622f942..1bb8c54a0c 100644 --- a/src/lib/cc/compat_compiler.h +++ b/src/lib/cc/compat_compiler.h @@ -238,6 +238,6 @@ #define POSSIBLE(expr) ((expr) || getenv("STATIC_ANALYZER_DEADCODE_DUMMY_")) #else #define POSSIBLE(expr) (expr) -#endif +#endif /* defined(__COVERITY__) || defined(__clang_analyzer__) */ #endif /* !defined(TOR_COMPAT_COMPILER_H) */ diff --git a/src/lib/log/util_bug.h b/src/lib/log/util_bug.h index f1831fd25b..ae3d125a08 100644 --- a/src/lib/log/util_bug.h +++ b/src/lib/log/util_bug.h @@ -198,7 +198,7 @@ STMT_END #define BUG(cond) \ (ASSERT_PREDICT_UNLIKELY_(cond) ? \ - (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",1,NULL),1) \ + (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \ : 0) #endif /* defined(ALL_BUGS_ARE_FATAL) || ... */ diff --git a/src/lib/net/.may_include b/src/lib/net/.may_include index e4368f799b..6e9af9737a 100644 --- a/src/lib/net/.may_include +++ b/src/lib/net/.may_include @@ -14,4 +14,5 @@ lib/net/*.h lib/string/*.h lib/subsys/*.h lib/testsupport/*.h -lib/malloc/*.h
\ No newline at end of file +lib/malloc/*.h +lib/smartlist_core/*.h diff --git a/src/lib/net/address.h b/src/lib/net/address.h index f04f319449..815fb02283 100644 --- a/src/lib/net/address.h +++ b/src/lib/net/address.h @@ -62,6 +62,7 @@ typedef uint8_t maskbits_t; struct in_addr; + /** Holds an IPv4 or IPv6 address. (Uses less memory than struct * sockaddr_storage.) */ typedef struct tor_addr_t @@ -133,6 +134,7 @@ tor_addr_to_in6_assert(const tor_addr_t *a) * Requires that <b>x</b> is actually an IPv6 address. */ #define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6_assert(x)) + /** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t. * * Requires that <b>x</b> is actually an IPv6 address. @@ -146,6 +148,7 @@ tor_addr_to_ipv4n(const tor_addr_t *a) { return a->family == AF_INET ? a->addr.in_addr.s_addr : 0; } + /** Return an IPv4 address in host order for <b>a</b>, or 0 if * <b>a</b> is not an IPv4 address. */ static inline uint32_t @@ -153,10 +156,11 @@ tor_addr_to_ipv4h(const tor_addr_t *a) { return ntohl(tor_addr_to_ipv4n(a)); } + /** Given an IPv6 address, return its mapped IPv4 address in host order, or * 0 if <b>a</b> is not an IPv6 address. * - * (Does not check whether the address is really a mapped address */ + * (Does not check whether the address is really a mapped address.) */ static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a) { @@ -165,14 +169,13 @@ tor_addr_to_mapped_ipv4h(const tor_addr_t *a) // Work around an incorrect NULL pointer dereference warning in // "clang --analyze" due to limited analysis depth addr32 = tor_addr_to_in6_addr32(a); - // To improve performance, wrap this assertion in: - // #if !defined(__clang_analyzer__) || PARANOIA tor_assert(addr32); return ntohl(addr32[3]); } else { return 0; } } + /** Return the address family of <b>a</b>. Possible values are: * AF_INET6, AF_INET, AF_UNSPEC. */ static inline sa_family_t @@ -180,6 +183,7 @@ tor_addr_family(const tor_addr_t *a) { return a->family; } + /** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not * an IPv4 address. */ static inline const struct in_addr * @@ -187,6 +191,7 @@ tor_addr_to_in(const tor_addr_t *a) { return a->family == AF_INET ? &a->addr.in_addr : NULL; } + /** Return true iff <b>a</b> is an IPv4 address equal to the host-ordered * address in <b>u</b>. */ static inline int @@ -209,19 +214,23 @@ char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC; /** Wrapper function of fmt_addr_impl(). It does not decorate IPv6 * addresses. */ #define fmt_addr(a) fmt_addr_impl((a), 0) + /** Wrapper function of fmt_addr_impl(). It decorates IPv6 * addresses. */ #define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1) + const char *fmt_addr_impl(const tor_addr_t *addr, int decorate); const char *fmt_addrport(const tor_addr_t *addr, uint16_t port); const char * fmt_addr32(uint32_t addr); MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr)); + struct smartlist_t; -void interface_address6_list_free_(struct smartlist_t * addrs);// XXXX +void interface_address6_list_free_(struct smartlist_t * addrs); #define interface_address6_list_free(addrs) \ FREE_AND_NULL(struct smartlist_t, interface_address6_list_free_, (addrs)) + MOCK_DECL(struct smartlist_t *,get_interface_address6_list,(int severity, sa_family_t family, int include_internal)); @@ -246,6 +255,7 @@ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, uint64_t tor_addr_hash(const tor_addr_t *addr); struct sipkey; uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr); + int tor_addr_is_v4(const tor_addr_t *addr); int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening, const char *filename, int lineno); @@ -276,11 +286,13 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address, int tor_addr_parse_mask_ports(const char *s, unsigned flags, tor_addr_t *addr_out, maskbits_t *mask_out, uint16_t *port_min_out, uint16_t *port_max_out); + const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate); int tor_addr_parse(tor_addr_t *addr, const char *src); void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src); void tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src); + void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr); /** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host * order. */ @@ -291,6 +303,7 @@ void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes); #define tor_addr_from_in(dest, in) \ tor_addr_from_ipv4n((dest), (in)->s_addr); void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6); + int tor_addr_is_null(const tor_addr_t *addr); int tor_addr_is_loopback(const tor_addr_t *addr); @@ -299,6 +312,7 @@ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening); #define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \ tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening)) int tor_port_is_valid(uint16_t port, int for_listening); + /* Are addr and port both valid? */ #define tor_addr_port_is_valid(addr, port, for_listening) \ (tor_addr_is_valid((addr), (for_listening)) && \ @@ -329,9 +343,11 @@ int parse_port_range(const char *port, uint16_t *port_min_out, uint16_t *port_max_out); int addr_mask_get_bits(uint32_t mask); char *tor_dup_ip(uint32_t addr) ATTR_MALLOC; + MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr)); #define interface_address_list_free(lst)\ interface_address6_list_free(lst) + /** Return a smartlist of the IPv4 addresses of all interfaces on the server. * Excludes loopback and multicast addresses. Only includes internal addresses * if include_internal is true. (Note that a relay behind NAT may use an diff --git a/src/lib/net/inaddr.c b/src/lib/net/inaddr.c index 0d20d88901..d50ac2440c 100644 --- a/src/lib/net/inaddr.c +++ b/src/lib/net/inaddr.c @@ -11,7 +11,9 @@ #include "lib/net/inaddr.h" #include "lib/cc/torint.h" +#include "lib/container/smartlist.h" #include "lib/log/util_bug.h" +#include "lib/malloc/malloc.h" #include "lib/net/inaddr_st.h" #include "lib/string/compat_ctype.h" #include "lib/string/compat_string.h" @@ -39,8 +41,27 @@ tor_inet_aton(const char *str, struct in_addr *addr) { unsigned a, b, c, d; char more; + bool is_octal = false; + smartlist_t *sl = NULL; + if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a, &b, &c, &d, &more) != 4) return 0; + + /* Parse the octets and check them for leading zeros. */ + sl = smartlist_new(); + smartlist_split_string(sl, str, ".", 0, 0); + SMARTLIST_FOREACH(sl, const char *, octet, { + is_octal = (strlen(octet) > 1 && octet[0] == '0'); + if (is_octal) { + break; + } + }); + SMARTLIST_FOREACH(sl, char *, octet, tor_free(octet)); + smartlist_free(sl); + + if (is_octal) + return 0; + if (a > 255) return 0; if (b > 255) return 0; if (c > 255) return 0; diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c index af6c482c95..87055744a7 100644 --- a/src/lib/tls/buffers_tls.c +++ b/src/lib/tls/buffers_tls.c @@ -69,9 +69,9 @@ buf_read_from_tls(buf_t *buf, tor_tls_t *tls, size_t at_most) check_no_tls_errors(); IF_BUG_ONCE(buf->datalen >= INT_MAX) - return -1; + return TOR_TLS_ERROR_MISC; IF_BUG_ONCE(buf->datalen >= INT_MAX - at_most) - return -1; + return TOR_TLS_ERROR_MISC; while (at_most > total_read) { size_t readlen = at_most - total_read; @@ -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 7a76fcdd94..6d2ef33eec 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; @@ -161,30 +161,30 @@ pub(crate) fn get_supported_protocols_cstr() -> &'static CStr { "Cons=1-2 \ Desc=1-2 \ DirCache=1-2 \ + FlowCtrl=1 \ HSDir=1-2 \ HSIntro=3-4 \ HSRend=1-2 \ Link=1-5 \ LinkAuth=3 \ Microdesc=1-2 \ - Relay=1-2 \ Padding=2 \ - FlowCtrl=1" + Relay=1-2" ) } else { cstr!( "Cons=1-2 \ Desc=1-2 \ DirCache=1-2 \ + FlowCtrl=1 \ HSDir=1-2 \ HSIntro=3-4 \ HSRend=1-2 \ Link=1-5 \ LinkAuth=1,3 \ Microdesc=1-2 \ - Relay=1-2 \ Padding=2 \ - FlowCtrl=1" + Relay=1-2" ) } } diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py index 658f7cde12..ae537ff15b 100644 --- a/src/test/ed25519_exts_ref.py +++ b/src/test/ed25519_exts_ref.py @@ -152,7 +152,7 @@ class SelfTest(unittest.TestCase): # Check that identities match assert(identity == identity2) # Check that identity is the point (0,1) - assert(identity == [0L,1L]) + assert(identity == [0,1]) # Check identity element: a*E = E, where a is a random scalar scalar = random_scalar(os.urandom) @@ -186,22 +186,22 @@ BLINDING_PARAMS = [ PREFIX = "ED25519_" def writeArray(name, array): - print "static const char *{prefix}{name}[] = {{".format( - prefix=PREFIX,name=name) + print("static const char *{prefix}{name}[] = {{".format( + prefix=PREFIX,name=name)) for a in array: h = binascii.b2a_hex(a) if len(h) > 70: h1 = h[:70] h2 = h[70:] - print ' "{0}"\n "{1}",'.format(h1,h2) + print(' "{0}"\n "{1}",'.format(h1,h2)) else: - print ' "{0}",'.format(h) - print "};\n" + print(' "{0}",'.format(h)) + print("};\n") def comment(text, initial="/**"): - print initial - print textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * ") - print " */" + print(initial) + print(textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * ")) + print(" */") def makeTestVectors(): comment("""Test vectors for our ed25519 implementation and related @@ -257,7 +257,7 @@ def makeTestVectors(): if __name__ == '__main__': import sys if len(sys.argv) == 1 or sys.argv[1] not in ("SelfTest", "MakeVectors"): - print "You should specify one of 'SelfTest' or 'MakeVectors'" + print("You should specify one of 'SelfTest' or 'MakeVectors'") sys.exit(1) if sys.argv[1] == 'SelfTest': unittest.main() diff --git a/src/test/include.am b/src/test/include.am index 3590745ba7..de927836d6 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -61,13 +61,25 @@ TESTS += src/test/test src/test/test-slow src/test/test-memwipe \ $(TESTSCRIPTS) # These flavors are run using automake's test-driver and test-network.sh -TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v2-min hs-v3-min \ - single-onion-v23 + +# run a quick test or two +# this test only uses IPv4 +TEST_CHUTNEY_FLAVOR_QUICK = bridges+hs-v23 # only run if we can ping6 ::1 (localhost) +TEST_CHUTNEY_FLAVOR_QUICK_IPV6 = single-onion-v23-ipv6-md + +# run a basic set of tests, which only use IPv4 +TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v23-min single-onion-v23 + +# only run if we can ping ::1 (localhost) TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v23-ipv6-md \ single-onion-v23-ipv6-md + # only run if we can find a stable (or simply another) version of tor -TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v2 +TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v23 + +# only run if IPv6 and mixed networks are run +TEST_CHUTNEY_FLAVORS_IPV6_MIXED = mixed+hs-v23-ipv6 ### This is a lovely feature, but it requires automake >= 1.12, and Tor ### doesn't require that yet. diff --git a/src/test/test_addr.c b/src/test/test_addr.c index af3c125a20..1a19e405ed 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -659,12 +659,7 @@ test_addr_ip6_helpers(void *arg) tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x01010202); r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); - tt_int_op(r, OP_EQ, AF_INET); - tt_int_op(mask,OP_EQ,32); - tt_int_op(tor_addr_family(&t1),OP_EQ,AF_INET); - tt_int_op(tor_addr_to_ipv4h(&t1),OP_EQ,0x03041020); - tt_uint_op(port1, OP_EQ, 1); - tt_uint_op(port2, OP_EQ, 2); + tt_int_op(r, OP_EQ, -1); r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); tt_int_op(r, OP_EQ, AF_INET); tt_int_op(mask,OP_EQ,17); @@ -1653,6 +1648,29 @@ test_addr_rfc6598(void *arg) ; } +#define TEST_ADDR_ATON(a, rv) STMT_BEGIN \ + struct in_addr addr; \ + tt_int_op(tor_inet_aton(a, &addr), OP_EQ, rv); \ + STMT_END; + +static void +test_addr_octal(void *arg) +{ + (void)arg; + + /* Test non-octal IP addresses. */ + TEST_ADDR_ATON("0.1.2.3", 1); + TEST_ADDR_ATON("1.0.2.3", 1); + TEST_ADDR_ATON("1.2.3.0", 1); + + /* Test octal IP addresses. */ + TEST_ADDR_ATON("01.1.2.3", 0); + TEST_ADDR_ATON("1.02.3.4", 0); + TEST_ADDR_ATON("1.2.3.04", 0); + done: + ; +} + #ifndef COCCI #define ADDR_LEGACY(name) \ { #name, test_addr_ ## name , 0, NULL, NULL } @@ -1671,5 +1689,6 @@ struct testcase_t addr_tests[] = { { "is_loopback", test_addr_is_loopback, 0, NULL, NULL }, { "make_null", test_addr_make_null, 0, NULL, NULL }, { "rfc6598", test_addr_rfc6598, 0, NULL, NULL }, + { "octal", test_addr_octal, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c index 3fcf8c4d13..829ecd79e8 100644 --- a/src/test/test_address_set.c +++ b/src/test/test_address_set.c @@ -4,6 +4,7 @@ #include "core/or/or.h" #include "lib/crypt_ops/crypto_rand.h" #include "core/or/address_set.h" +#include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" @@ -31,6 +32,12 @@ mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f) return dummy_ns; } +static void +mock_dirlist_add_trusted_dir_addresses(void) +{ + return; +} + /* Number of address a single node_t can have. Default to the production * value. This is to control the size of the bloom filter. */ static int addr_per_node = 2; @@ -98,6 +105,8 @@ test_nodelist(void *arg) mock_networkstatus_get_latest_consensus_by_flavor); MOCK(get_estimated_address_per_node, mock_get_estimated_address_per_node); + MOCK(dirlist_add_trusted_dir_addresses, + mock_dirlist_add_trusted_dir_addresses); dummy_ns = tor_malloc_zero(sizeof(*dummy_ns)); dummy_ns->flavor = FLAV_MICRODESC; @@ -113,7 +122,10 @@ test_nodelist(void *arg) * (the_nodelist->node_addrs) so we will fail the contain test rarely. */ addr_per_node = 1024; - /* No node no nothing. The lookups should be empty. */ + /* No node no nothing. The lookups should be empty. We've mocked the + * dirlist_add_trusted_dir_addresses in order for _no_ authorities to be + * added to the filter else it makes this test to trigger many false + * positive. */ nodelist_set_consensus(dummy_ns); /* The address set should be empty. */ @@ -167,6 +179,7 @@ test_nodelist(void *arg) UNMOCK(networkstatus_get_latest_consensus); UNMOCK(networkstatus_get_latest_consensus_by_flavor); UNMOCK(get_estimated_address_per_node); + UNMOCK(dirlist_add_trusted_dir_addresses); } struct testcase_t address_set_tests[] = { diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c index 1da3796981..117783cafc 100644 --- a/src/test/test_bwmgt.c +++ b/src/test/test_bwmgt.c @@ -6,18 +6,70 @@ * \brief tests for bandwidth management / token bucket functions */ +#define CONFIG_PRIVATE +#define CONNECTION_PRIVATE +#define DIRAUTH_SYS_PRIVATE #define TOKEN_BUCKET_PRIVATE #include "core/or/or.h" -#include "test/test.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "feature/dirauth/dirauth_sys.h" +#include "feature/dircommon/directory.h" +#include "feature/nodelist/microdesc.h" +#include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerlist.h" +#include "lib/crypt_ops/crypto_rand.h" #include "lib/evloop/token_bucket.h" +#include "test/test.h" +#include "test/test_helpers.h" + +#include "app/config/or_options_st.h" +#include "core/or/connection_st.h" +#include "feature/dirauth/dirauth_options_st.h" +#include "feature/nodelist/microdesc_st.h" +#include "feature/nodelist/networkstatus_st.h" +#include "feature/nodelist/routerinfo_st.h" +#include "feature/nodelist/routerstatus_st.h" // an imaginary time, in timestamp units. Chosen so it will roll over. static const uint32_t START_TS = UINT32_MAX-10; static const int32_t KB = 1024; static const uint32_t GB = (UINT64_C(1) << 30); +static or_options_t mock_options; + +static const or_options_t * +mock_get_options(void) +{ + return &mock_options; +} + +static networkstatus_t *dummy_ns = NULL; +static networkstatus_t * +mock_networkstatus_get_latest_consensus(void) +{ + return dummy_ns; +} + +static networkstatus_t * +mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f) +{ + tor_assert(f == FLAV_MICRODESC); + return dummy_ns; +} + +/* Number of address a single node_t can have. Default to the production + * value. This is to control the size of the bloom filter. */ +static int addr_per_node = 2; +static int +mock_get_estimated_address_per_node(void) +{ + return addr_per_node; +} + static void test_bwmgt_token_buf_init(void *arg) { @@ -220,8 +272,167 @@ test_bwmgt_token_buf_helpers(void *arg) ; } +static void +test_bwmgt_dir_conn_global_write_low(void *arg) +{ + bool ret; + int addr_family; + connection_t *conn = NULL; + routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL; + tor_addr_t relay_addr; + dirauth_options_t *dirauth_opts = NULL; + + (void) arg; + + memset(&mock_options, 0, sizeof(or_options_t)); + MOCK(networkstatus_get_latest_consensus, + mock_networkstatus_get_latest_consensus); + MOCK(networkstatus_get_latest_consensus_by_flavor, + mock_networkstatus_get_latest_consensus_by_flavor); + MOCK(get_estimated_address_per_node, + mock_get_estimated_address_per_node); + + /* + * The following is rather complex but that is what it takes to add a dummy + * consensus with a valid routerlist which will populate our node address + * set that we need to lookup to test the known relay code path. + * + * We MUST do that before we MOCK(get_options) else it is another world of + * complexity. + */ + + /* This will be the address of our relay. */ + tor_addr_parse(&relay_addr, "1.2.3.4"); + + /* We'll now add a relay into our routerlist and see if we let it. */ + dummy_ns = tor_malloc_zero(sizeof(*dummy_ns)); + dummy_ns->flavor = FLAV_MICRODESC; + dummy_ns->routerstatus_list = smartlist_new(); + + md = tor_malloc_zero(sizeof(*md)); + ri = tor_malloc_zero(sizeof(*ri)); + rs = tor_malloc_zero(sizeof(*rs)); + crypto_rand(rs->identity_digest, sizeof(rs->identity_digest)); + crypto_rand(md->digest, sizeof(md->digest)); + memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN); + + /* Set IP address. */ + rs->addr = tor_addr_to_ipv4h(&relay_addr); + ri->addr = rs->addr; + /* Add the rs to the consensus becoming a node_t. */ + smartlist_add(dummy_ns->routerstatus_list, rs); + + /* Add all configured authorities (hardcoded) before we set the consensus so + * the address set exists. */ + ret = consider_adding_dir_servers(&mock_options, &mock_options); + tt_int_op(ret, OP_EQ, 0); + + /* This will make the nodelist bloom filter very large + * (the_nodelist->node_addrs) so we will fail the contain test rarely. */ + addr_per_node = 1024; + + nodelist_set_consensus(dummy_ns); + + dirauth_opts = tor_malloc_zero(sizeof(dirauth_options_t)); + dirauth_opts->AuthDirRejectRequestsUnderLoad = 0; + dirauth_set_options(dirauth_opts); + + /* Ok, now time to control which options we use. */ + MOCK(get_options, mock_get_options); + + /* Set ourselves as an authoritative dir. */ + mock_options.AuthoritativeDir = 1; + mock_options.V3AuthoritativeDir = 1; + mock_options.UseDefaultFallbackDirs = 0; + + /* This will set our global bucket to 1 byte and thus we will hit the + * banwdith limit in our test. */ + mock_options.BandwidthRate = 1; + mock_options.BandwidthBurst = 1; + + /* Else an IPv4 address screams. */ + mock_options.ClientUseIPv4 = 1; + mock_options.ClientUseIPv6 = 1; + + /* Initialize the global buckets. */ + connection_bucket_init(); + + /* The address "127.0.0.1" is set with this helper. */ + conn = test_conn_get_connection(DIR_CONN_STATE_MIN_, CONN_TYPE_DIR, + DIR_PURPOSE_MIN_); + tt_assert(conn); + + /* First try a non authority non relay IP thus a client but we are not + * configured to reject requests under load so we should get a false value + * that our limit is _not_ low. */ + addr_family = tor_addr_parse(&conn->addr, "1.1.1.1"); + tt_int_op(addr_family, OP_EQ, AF_INET); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 0); + + /* Now, we will reject requests under load so try again a non authority non + * relay IP thus a client. We should get a warning that our limit is too + * low. */ + dirauth_opts->AuthDirRejectRequestsUnderLoad = 1; + + addr_family = tor_addr_parse(&conn->addr, "1.1.1.1"); + tt_int_op(addr_family, OP_EQ, AF_INET); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 1); + + /* Now, lets try with a connection address from moria1. It should always + * pass even though our limit is too low. */ + addr_family = tor_addr_parse(&conn->addr, "128.31.0.39"); + tt_int_op(addr_family, OP_EQ, AF_INET); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 0); + + /* IPv6 testing of gabelmoo. */ + addr_family = tor_addr_parse(&conn->addr, "[2001:638:a000:4140::ffff:189]"); + tt_int_op(addr_family, OP_EQ, AF_INET6); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 0); + + /* Lets retry with a known relay address. It should pass. Possible due to + * our consensus setting above. */ + memcpy(&conn->addr, &relay_addr, sizeof(tor_addr_t)); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 0); + + /* Lets retry with a random IP that is not an authority nor a relay. */ + addr_family = tor_addr_parse(&conn->addr, "1.2.3.4"); + tt_int_op(addr_family, OP_EQ, AF_INET); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 0); + + /* Finally, just make sure it still denies an IP if we are _not_ a v3 + * directory authority. */ + mock_options.V3AuthoritativeDir = 0; + addr_family = tor_addr_parse(&conn->addr, "1.2.3.4"); + tt_int_op(addr_family, OP_EQ, AF_INET); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 1); + + /* Random IPv6 should not be allowed. */ + addr_family = tor_addr_parse(&conn->addr, "[CAFE::ACAB]"); + tt_int_op(addr_family, OP_EQ, AF_INET6); + ret = connection_dir_is_global_write_low(conn, INT_MAX); + tt_int_op(ret, OP_EQ, 1); + + done: + connection_free_minimal(conn); + routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md); + smartlist_clear(dummy_ns->routerstatus_list); + networkstatus_vote_free(dummy_ns); + + UNMOCK(get_estimated_address_per_node); + UNMOCK(networkstatus_get_latest_consensus); + UNMOCK(networkstatus_get_latest_consensus_by_flavor); + UNMOCK(get_options); +} + #define BWMGT(name) \ - { #name, test_bwmgt_ ## name , 0, NULL, NULL } + { #name, test_bwmgt_ ## name , TT_FORK, NULL, NULL } struct testcase_t bwmgt_tests[] = { BWMGT(token_buf_init), @@ -229,5 +440,7 @@ struct testcase_t bwmgt_tests[] = { BWMGT(token_buf_dec), BWMGT(token_buf_refill), BWMGT(token_buf_helpers), + + BWMGT(dir_conn_global_write_low), END_OF_TESTCASES }; diff --git a/src/test/test_controller.c b/src/test/test_controller.c index fb027d1a18..a69ec17db8 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -2027,6 +2027,91 @@ test_control_reply(void *arg) return; } +static void +test_control_getconf(void *arg) +{ + (void)arg; + control_connection_t conn; + char *args = NULL; + int r = -1; + + memset(&conn, 0, sizeof(conn)); + conn.current_cmd = tor_strdup("GETCONF"); + + MOCK(control_write_reply, mock_control_write_reply_list); + reply_strs = smartlist_new(); + + args = tor_strdup(""); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250 OK"); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + tor_free(args); + + args = tor_strdup("NoSuch"); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, + "552 Unrecognized configuration key \"NoSuch\""); + tor_free(args); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + + args = tor_strdup("NoSuch1 NoSuch2"); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + tt_int_op(smartlist_len(reply_strs), OP_EQ, 2); + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, + "552-Unrecognized configuration key \"NoSuch1\""); + tt_str_op((char *)smartlist_get(reply_strs, 1), OP_EQ, + "552 Unrecognized configuration key \"NoSuch2\""); + tor_free(args); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + + args = tor_strdup("ControlPort NoSuch"); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + /* Valid keys ignored if there are any invalid ones */ + tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, + "552 Unrecognized configuration key \"NoSuch\""); + tor_free(args); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + + args = tor_strdup("ClientOnly"); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); + /* According to config.c, this is an exception for the unit tests */ + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250 ClientOnly=0"); + tor_free(args); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + + args = tor_strdup("BridgeRelay ClientOnly"); + r = handle_control_command(&conn, (uint32_t)strlen(args), args); + tt_int_op(r, OP_EQ, 0); + tt_int_op(smartlist_len(reply_strs), OP_EQ, 2); + /* Change if config.c changes BridgeRelay default (unlikely) */ + tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250-BridgeRelay=0"); + tt_str_op((char *)smartlist_get(reply_strs, 1), OP_EQ, "250 ClientOnly=0"); + tor_free(args); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_clear(reply_strs); + + done: + tor_free(conn.current_cmd); + tor_free(args); + UNMOCK(control_write_reply); + SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); + smartlist_free(reply_strs); +} + #ifndef COCCI #define PARSER_TEST(type) \ { "parse/" #type, test_controller_parse_cmd, 0, &passthrough_setup, \ @@ -2060,5 +2145,6 @@ struct testcase_t controller_tests[] = { { "current_time", test_current_time, 0, NULL, NULL }, { "getinfo_md_all", test_getinfo_md_all, 0, NULL, NULL }, { "control_reply", test_control_reply, 0, NULL, NULL }, + { "control_getconf", test_control_getconf, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c index e9d09fbeef..60dfbd630a 100644 --- a/src/test/test_controller_events.c +++ b/src/test/test_controller_events.c @@ -19,6 +19,7 @@ #include "feature/control/control_fmt.h" #include "test/test.h" #include "test/test_helpers.h" +#include "test/log_test_helpers.h" #include "core/or/entry_connection_st.h" #include "core/or/or_circuit_st.h" @@ -399,6 +400,43 @@ test_cntev_dirboot_defer_orconn(void *arg) } static void +test_cntev_signal(void *arg) +{ + (void)arg; + int rv; + + MOCK(queue_control_event_string, mock_queue_control_event_string); + + /* Nothing is listening for signals, so no event should be queued. */ + rv = control_event_signal(SIGHUP); + tt_int_op(0, OP_EQ, rv); + tt_ptr_op(saved_event_str, OP_EQ, NULL); + + /* Now try with signals included in the event mask. */ + control_testing_set_global_event_mask(EVENT_MASK_(EVENT_GOT_SIGNAL)); + rv = control_event_signal(SIGHUP); + tt_int_op(0, OP_EQ, rv); + tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL RELOAD\r\n"); + + rv = control_event_signal(SIGACTIVE); + tt_int_op(0, OP_EQ, rv); + tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL ACTIVE\r\n"); + + /* Try a signal that doesn't exist. */ + setup_full_capture_of_logs(LOG_WARN); + tor_free(saved_event_str); + rv = control_event_signal(99999); + tt_int_op(-1, OP_EQ, rv); + tt_ptr_op(saved_event_str, OP_EQ, NULL); + expect_single_log_msg_containing("Unrecognized signal 99999"); + + done: + tor_free(saved_event_str); + teardown_capture_of_logs(); + UNMOCK(queue_control_event_string); +} + +static void setup_orconn_state(orconn_state_msg_t *msg, uint64_t gid, uint64_t chan, int proxy_type) { @@ -679,6 +717,7 @@ struct testcase_t controller_event_tests[] = { TEST(format_cell_stats, TT_FORK), TEST(event_mask, TT_FORK), TEST(format_stream, TT_FORK), + TEST(signal, TT_FORK), T_PUBSUB(dirboot_defer_desc, TT_FORK), T_PUBSUB(dirboot_defer_orconn, TT_FORK), T_PUBSUB(orconn_state, TT_FORK), diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 6293839b0d..cf310ebfe0 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -2084,8 +2084,8 @@ test_dir_handle_get_status_vote_d(void* data) const char *msg_out = NULL; int status_out = 0; - struct pending_vote_t *pv = dirvote_add_vote(VOTE_BODY_V3, &msg_out, - &status_out); + struct pending_vote_t *pv = dirvote_add_vote(VOTE_BODY_V3, 0, + &msg_out, &status_out); tt_assert(pv); status_vote_current_d_test(&header, &body, &body_used); @@ -2459,8 +2459,8 @@ test_dir_handle_get_status_vote_next_authority(void* data) time_t now = 1441223455 -1; voting_schedule_recalculate_timing(mock_options, now); - struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, &msg_out, - &status_out); + struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, + &msg_out, &status_out); tt_assert(vote); MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); @@ -2619,8 +2619,8 @@ test_dir_handle_get_status_vote_current_authority(void* data) time_t now = 1441223455; voting_schedule_recalculate_timing(mock_options, now-1); - struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, &msg_out, - &status_out); + struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, + &msg_out, &status_out); tt_assert(vote); // move the pending vote to previous vote @@ -2658,6 +2658,183 @@ test_dir_handle_get_status_vote_current_authority(void* data) dirvote_free_all(); } +/* Test that a late vote is rejected, but an on-time vote is accepted. */ +static void +test_dir_handle_get_status_vote_too_late(void* data) +{ + dir_connection_t *conn = NULL; + char *header = NULL, *body = NULL; + const char *msg_out = NULL; + int status_out = 0; + size_t body_used = 0; + const char digest[DIGEST_LEN] = ""; + + dir_server_t *ds = NULL; + const char* mode = (const char *)data; + + clear_dir_servers(); + routerlist_free_all(); + dirvote_free_all(); + + mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE, + strlen(TEST_CERTIFICATE), + NULL); + + /* create a trusted ds */ + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); + tt_assert(ds); + dir_server_add(ds); + + /* ds v3_identity_digest is the certificate's identity_key */ + base16_decode(ds->v3_identity_digest, DIGEST_LEN, + TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN); + + tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE, + TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL)); + + init_mock_options(); + mock_options->AuthoritativeDir = 1; + mock_options->V3AuthoritativeDir = 1; + + int base_delay = 0; + int vote_interval = 0; + int start_offset = 0; + + tt_assert(mode); + /* Set the required timings, see below for details */ + if (strcmp(mode, "min") == 0) { + /* The minimum valid test network timing */ + base_delay = 2; + vote_interval = 10; + start_offset = vote_interval - 5; + } else if (strcmp(mode, "chutney") == 0) { + /* The test network timing used by chutney */ + base_delay = 4; + vote_interval = 20; + start_offset = vote_interval - 5; + } else if (strcmp(mode, "half-public") == 0) { + /* The short consensus failure timing used in the public network */ + base_delay = 5*60; + vote_interval = 30*60; + start_offset = vote_interval - 9*60 - 5; + } else if (strcmp(mode, "public") == 0) { + /* The standard timing used in the public network */ + base_delay = 5*60; + vote_interval = 60*60; + start_offset = vote_interval - 9*60 - 5; + } + + tt_assert(base_delay > 0); + tt_assert(vote_interval > 0); + tt_assert(start_offset > 0); + + /* Skew the time to fit the fixed time in the vote */ + mock_options->TestingV3AuthVotingStartOffset = start_offset; + /* Calculate the rest of the timings */ + mock_options->TestingV3AuthInitialVotingInterval = vote_interval; + mock_options->TestingV3AuthInitialVoteDelay = base_delay; + mock_options->TestingV3AuthInitialDistDelay = base_delay; + + time_t now = 1441223455; + voting_schedule_recalculate_timing(mock_options, now-1); + const time_t voting_starts = voting_schedule.voting_starts; + const time_t fetch_missing = voting_schedule.fetch_missing_votes; + + struct pending_vote_t *vote = NULL; + + /* Next voting interval */ + vote = dirvote_add_vote(VOTE_BODY_V3, + fetch_missing + vote_interval, + &msg_out, &status_out); + tt_assert(!vote); + tt_int_op(status_out, OP_EQ, 400); + tt_str_op(msg_out, OP_EQ, + "Posted vote received too late, would be dangerous to count it"); + + /* Just after fetch missing */ + vote = dirvote_add_vote(VOTE_BODY_V3, + fetch_missing + 1, + &msg_out, &status_out); + tt_assert(!vote); + tt_int_op(status_out, OP_EQ, 400); + tt_str_op(msg_out, OP_EQ, + "Posted vote received too late, would be dangerous to count it"); + + /* On fetch missing */ + vote = dirvote_add_vote(VOTE_BODY_V3, + fetch_missing, + &msg_out, &status_out); + tt_assert(vote); + + /* Move the pending vote to previous vote */ + dirvote_act(mock_options, now+1); + /* And reset the timing */ + voting_schedule_recalculate_timing(mock_options, now-1); + + /* Between voting starts and fetch missing */ + vote = dirvote_add_vote(VOTE_BODY_V3, + voting_starts + 1, + &msg_out, &status_out); + tt_assert(vote); + + /* Move the pending vote to previous vote */ + dirvote_act(mock_options, now+1); + /* And reset the timing */ + voting_schedule_recalculate_timing(mock_options, now-1); + + /* On voting starts */ + vote = dirvote_add_vote(VOTE_BODY_V3, + voting_starts, + &msg_out, &status_out); + tt_assert(vote); + + /* Move the pending vote to previous vote */ + dirvote_act(mock_options, now+1); + /* And reset the timing */ + voting_schedule_recalculate_timing(mock_options, now-1); + + /* Just before voting starts */ + vote = dirvote_add_vote(VOTE_BODY_V3, + voting_starts - 1, + &msg_out, &status_out); + tt_assert(vote); + + /* Move the pending vote to previous vote */ + dirvote_act(mock_options, now+1); + + MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m); + MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); + + conn = new_dir_conn(); + tt_int_op(0, OP_EQ, directory_handle_command_get(conn, + GET("/tor/status-vote/current/authority"), NULL, 0)); + + fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, + &body, &body_used, strlen(VOTE_BODY_V3)+1, 0); + + tt_assert(header); + tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header); + tt_assert(strstr(header, "Content-Type: text/plain\r\n")); + tt_assert(strstr(header, "Content-Encoding: identity\r\n")); + tt_assert(strstr(header, "Content-Length: 4135\r\n")); + + tt_str_op(VOTE_BODY_V3, OP_EQ, body); + + done: + UNMOCK(connection_write_to_buf_impl_); + UNMOCK(get_my_v3_authority_cert); + connection_free_minimal(TO_CONN(conn)); + tor_free(header); + tor_free(body); + authority_cert_free(mock_cert); mock_cert = NULL; + or_options_free(mock_options); mock_options = NULL; + + clear_dir_servers(); + routerlist_free_all(); + dirvote_free_all(); +} + static void test_dir_handle_get_parse_accept_encoding(void *arg) { @@ -2708,6 +2885,16 @@ test_dir_handle_get_parse_accept_encoding(void *arg) #define DIR_HANDLE_CMD(name,flags) \ { #name, test_dir_handle_get_##name, (flags), NULL, NULL } +#ifdef COCCI +/* Coccinelle doesn't like the stringification in this macro */ +#define DIR_HANDLE_CMD_ARG(name,flags,arg) \ + DIR_HANDLE_CMD(name,flags) +#else +#define DIR_HANDLE_CMD_ARG(name,flags,arg) \ + { #name "/" arg, test_dir_handle_get_##name, (flags), \ + &passthrough_setup, (void *)(arg) } +#endif /* defined(COCCI) */ + struct testcase_t dir_handle_get_tests[] = { DIR_HANDLE_CMD(not_found, 0), DIR_HANDLE_CMD(bad_request, 0), @@ -2747,6 +2934,10 @@ struct testcase_t dir_handle_get_tests[] = { DIR_HANDLE_CMD(status_vote_next_not_found, 0), DIR_HANDLE_CMD(status_vote_current_authority_not_found, 0), DIR_HANDLE_CMD(status_vote_current_authority, 0), + DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "min"), + DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "chutney"), + DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "half-public"), + DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "public"), DIR_HANDLE_CMD(status_vote_next_authority_not_found, 0), DIR_HANDLE_CMD(status_vote_next_authority, 0), DIR_HANDLE_CMD(status_vote_next_bandwidth_not_found, 0), diff --git a/src/test/test_dns.c b/src/test/test_dns.c index ec17e9e91e..299321ab64 100644 --- a/src/test/test_dns.c +++ b/src/test/test_dns.c @@ -80,11 +80,11 @@ test_dns_clip_ttl(void *arg) { (void)arg; - uint32_t ttl_mid = MIN_DNS_TTL_AT_EXIT / 2 + MAX_DNS_TTL_AT_EXIT / 2; + uint32_t ttl_mid = MIN_DNS_TTL / 2 + MAX_DNS_TTL / 2; - tt_int_op(dns_clip_ttl(MIN_DNS_TTL_AT_EXIT - 1),OP_EQ,MIN_DNS_TTL_AT_EXIT); - tt_int_op(dns_clip_ttl(ttl_mid),OP_EQ,MAX_DNS_TTL_AT_EXIT); - tt_int_op(dns_clip_ttl(MAX_DNS_TTL_AT_EXIT + 1),OP_EQ,MAX_DNS_TTL_AT_EXIT); + tt_int_op(clip_dns_ttl(MIN_DNS_TTL - 1),OP_EQ,MIN_DNS_TTL); + tt_int_op(clip_dns_ttl(ttl_mid),OP_EQ,MAX_DNS_TTL); + tt_int_op(clip_dns_ttl(MAX_DNS_TTL + 1),OP_EQ,MAX_DNS_TTL); done: return; diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c index c1bff6eb7f..f25bba3584 100644 --- a/src/test/test_hs_cache.c +++ b/src/test/test_hs_cache.c @@ -648,6 +648,59 @@ test_client_cache_decrypt(void *arg) UNMOCK(networkstatus_get_live_consensus); } +static void +test_client_cache_remove(void *arg) +{ + int ret; + ed25519_keypair_t service_kp; + hs_descriptor_t *desc1 = NULL; + + (void) arg; + + hs_init(); + + MOCK(networkstatus_get_live_consensus, + mock_networkstatus_get_live_consensus); + + /* Set consensus time. Lookup will not return the entry if it has expired + * and it is checked against the consensus valid_after time. */ + parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", + &mock_ns.valid_after); + parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", + &mock_ns.fresh_until); + parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC", + &mock_ns.valid_until); + + /* Generate service keypair */ + tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0)); + + /* Build a descriptor and cache it. */ + { + char *encoded; + desc1 = hs_helper_build_hs_desc_with_ip(&service_kp); + tt_assert(desc1); + ret = hs_desc_encode_descriptor(desc1, &service_kp, NULL, &encoded); + tt_int_op(ret, OP_EQ, 0); + tt_assert(encoded); + + /* Store it */ + ret = hs_cache_store_as_client(encoded, &service_kp.pubkey); + tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK); + tor_free(encoded); + tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey)); + } + + /* Remove the cached entry. */ + hs_cache_remove_as_client(&service_kp.pubkey); + tt_assert(!hs_cache_lookup_as_client(&service_kp.pubkey)); + + done: + hs_descriptor_free(desc1); + hs_free_all(); + + UNMOCK(networkstatus_get_live_consensus); +} + struct testcase_t hs_cache[] = { /* Encoding tests. */ { "directory", test_directory, TT_FORK, @@ -662,6 +715,8 @@ struct testcase_t hs_cache[] = { NULL, NULL }, { "client_cache_decrypt", test_client_cache_decrypt, TT_FORK, NULL, NULL }, + { "client_cache_remove", test_client_cache_remove, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c index 88910e8ead..2e603ec259 100644 --- a/src/test/test_hs_client.c +++ b/src/test/test_hs_client.c @@ -80,6 +80,23 @@ mock_networkstatus_get_live_consensus(time_t now) } static int +mock_write_str_to_file(const char *path, const char *str, int bin) +{ + (void) bin; + (void) path; + (void) str; + return 0; +} + +static or_options_t mocked_options; + +static const or_options_t * +mock_get_options(void) +{ + return &mocked_options; +} + +static int helper_config_client(const char *conf, int validate_only) { int ret = 0; @@ -1331,6 +1348,85 @@ test_close_intro_circuit_failure(void *arg) hs_free_all(); } +static void +test_purge_ephemeral_client_auth(void *arg) +{ + ed25519_keypair_t service_kp; + hs_client_service_authorization_t *auth = NULL; + hs_client_register_auth_status_t status; + + (void) arg; + + /* We will try to write on disk client credentials. */ + MOCK(check_private_dir, mock_check_private_dir); + MOCK(get_options, mock_get_options); + MOCK(write_str_to_file, mock_write_str_to_file); + + /* Boggus directory so when we try to write the permanent client + * authorization data to disk, we don't fail. See + * store_permanent_client_auth_credentials() for more details. */ + mocked_options.ClientOnionAuthDir = tor_strdup("auth_dir"); + + hs_init(); + + /* Generate service keypair */ + tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0)); + + /* Generate a client authorization object. */ + auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t)); + + /* Set it up. No flags meaning it is ephemeral. */ + curve25519_secret_key_generate(&auth->enc_seckey, 0); + hs_build_address(&service_kp.pubkey, HS_VERSION_THREE, auth->onion_address); + auth->flags = 0; + + /* Confirm that there is nothing in the client auth map. It is unallocated + * until we add the first entry. */ + tt_assert(!get_hs_client_auths_map()); + + /* Add an entry to the client auth list. We loose ownership of the auth + * object so nullify it. */ + status = hs_client_register_auth_credentials(auth); + auth = NULL; + tt_int_op(status, OP_EQ, REGISTER_SUCCESS); + + /* We should have the entry now. */ + digest256map_t *client_auths = get_hs_client_auths_map(); + tt_assert(client_auths); + tt_int_op(digest256map_size(client_auths), OP_EQ, 1); + + /* Purge the cache that should remove all ephemeral values. */ + purge_ephemeral_client_auth(); + tt_int_op(digest256map_size(client_auths), OP_EQ, 0); + + /* Now add a new authorization object but permanent. */ + /* Generate a client authorization object. */ + auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t)); + curve25519_secret_key_generate(&auth->enc_seckey, 0); + hs_build_address(&service_kp.pubkey, HS_VERSION_THREE, auth->onion_address); + auth->flags = CLIENT_AUTH_FLAG_IS_PERMANENT; + + /* Add an entry to the client auth list. We loose ownership of the auth + * object so nullify it. */ + status = hs_client_register_auth_credentials(auth); + auth = NULL; + tt_int_op(status, OP_EQ, REGISTER_SUCCESS); + tt_int_op(digest256map_size(client_auths), OP_EQ, 1); + + /* Purge again, the entry should still be there. */ + purge_ephemeral_client_auth(); + tt_int_op(digest256map_size(client_auths), OP_EQ, 1); + + done: + client_service_authorization_free(auth); + hs_free_all(); + tor_free(mocked_options.ClientOnionAuthDir); + + UNMOCK(check_private_dir); + UNMOCK(get_options); + UNMOCK(write_str_to_file); +} + struct testcase_t hs_client_tests[] = { { "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy, TT_FORK, NULL, NULL }, @@ -1358,5 +1454,9 @@ struct testcase_t hs_client_tests[] = { /* SOCKS5 Extended Error Code. */ { "socks_hs_errors", test_socks_hs_errors, TT_FORK, NULL, NULL }, + /* Client authorization. */ + { "purge_ephemeral_client_auth", test_purge_ephemeral_client_auth, TT_FORK, + NULL, NULL }, + END_OF_TESTCASES }; diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c index dc0db18bdc..881479016f 100644 --- a/src/test/test_hs_control.c +++ b/src/test/test_hs_control.c @@ -218,6 +218,8 @@ test_hs_control_good_onion_client_auth_add(void *arg) char *cp1 = NULL; size_t sz; + hs_init(); + { /* Setup the control conn */ memset(&conn, 0, sizeof(control_connection_t)); TO_CONN(&conn)->outbuf = buf_new(); @@ -415,6 +417,8 @@ test_hs_control_bad_onion_client_auth_add(void *arg) size_t sz; char *args = NULL; + hs_init(); + { /* Setup the control conn */ memset(&conn, 0, sizeof(control_connection_t)); TO_CONN(&conn)->outbuf = buf_new(); @@ -493,6 +497,8 @@ test_hs_control_store_permanent_creds(void *arg) size_t sz; + hs_init(); + { /* Setup the control conn */ memset(&conn, 0, sizeof(control_connection_t)); TO_CONN(&conn)->outbuf = buf_new(); diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c index 96542ce7ac..1566b349ed 100644 --- a/src/test/test_link_handshake.c +++ b/src/test/test_link_handshake.c @@ -18,6 +18,7 @@ #include "feature/relay/routerkeys.h" #include "core/or/scheduler.h" #include "feature/nodelist/torcert.h" +#include "feature/relay/relay_handshake.h" #include "core/or/or_connection_st.h" #include "core/or/or_handshake_certs_st.h" diff --git a/src/test/test_protover.c b/src/test/test_protover.c index f1d1ef0d4a..7d08911021 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -2,6 +2,7 @@ /* See LICENSE for licensing information */ #define PROTOVER_PRIVATE +#define DIRVOTE_PRIVATE #include "orconfig.h" #include "test/test.h" @@ -12,6 +13,8 @@ #include "core/or/connection_or.h" #include "lib/tls/tortls.h" +#include "feature/dirauth/dirvote.h" + static void test_protover_parse(void *arg) { @@ -634,6 +637,43 @@ test_protover_vote_roundtrip(void *args) tor_free(result); } +static void +test_protover_vote_roundtrip_ours(void *args) +{ + (void) args; + const char *examples[] = { + protover_get_supported_protocols(), + DIRVOTE_RECCOMEND_RELAY_PROTO, + DIRVOTE_RECCOMEND_CLIENT_PROTO, + DIRVOTE_REQUIRE_RELAY_PROTO, + DIRVOTE_REQUIRE_CLIENT_PROTO, + }; + unsigned u; + smartlist_t *votes = smartlist_new(); + char *result = NULL; + + for (u = 0; u < ARRAY_LENGTH(examples); ++u) { + tt_assert(examples[u]); + const char *input = examples[u]; + const char *expected_output = examples[u]; + + smartlist_add(votes, (void*)input); + result = protover_compute_vote(votes, 1); + if (expected_output != NULL) { + tt_str_op(result, OP_EQ, expected_output); + } else { + tt_str_op(result, OP_EQ, ""); + } + + smartlist_clear(votes); + tor_free(result); + } + + done: + smartlist_free(votes); + tor_free(result); +} + #define PV_TEST(name, flags) \ { #name, test_protover_ ##name, (flags), NULL, NULL } @@ -647,5 +687,6 @@ struct testcase_t protover_tests[] = { PV_TEST(supports_version, 0), PV_TEST(supported_protocols, 0), PV_TEST(vote_roundtrip, 0), + PV_TEST(vote_roundtrip_ours, 0), END_OF_TESTCASES }; diff --git a/src/test/test_util.c b/src/test/test_util.c index 7a375b06be..b1e4335652 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1947,7 +1947,7 @@ test_util_expand_filename(void *arg) done: tor_free(str); } -#endif /* !defined(_WIN32) */ +#endif /* !defined(DISABLE_PWDB_TESTS) */ /** Test tor_escape_str_for_pt_args(). */ static void @@ -5792,7 +5792,7 @@ test_util_pwdb(void *arg) tor_free(dir); teardown_capture_of_logs(); } -#endif /* !(defined(_WIN32) || defined (__ANDROID__)) */ +#endif /* !defined(DISABLE_PWDB_TESTS) */ static void test_util_calloc_check(void *arg) diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h index be71c7987c..3c8f91d53b 100644 --- a/src/win32/orconfig.h +++ b/src/win32/orconfig.h @@ -217,7 +217,7 @@ #define USING_TWOS_COMPLEMENT /* Version number of package */ -#define VERSION "0.4.3.0-alpha-dev" +#define VERSION "0.4.4.0-alpha-dev" #define HAVE_STRUCT_SOCKADDR_IN6 #define HAVE_STRUCT_IN6_ADDR |