aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml22
-rw-r--r--.gitignore89
-rw-r--r--.travis.yml13
-rw-r--r--ChangeLog340
-rw-r--r--README5
-rw-r--r--ReleaseNotes340
-rw-r--r--changes/bug325884
-rw-r--r--changes/bug330326
-rw-r--r--changes/bug330877
-rw-r--r--changes/bug333745
-rw-r--r--changes/bug336085
-rw-r--r--changes/bug336684
-rw-r--r--changes/bug336736
-rw-r--r--changes/bug336744
-rw-r--r--changes/doc334173
-rw-r--r--changes/ticket321434
-rw-r--r--changes/ticket329056
-rw-r--r--changes/ticket329943
-rw-r--r--changes/ticket330295
-rw-r--r--changes/ticket331885
-rw-r--r--changes/ticket332133
-rw-r--r--changes/ticket332904
-rw-r--r--changes/ticket334003
-rw-r--r--changes/ticket334513
-rw-r--r--changes/ticket334584
-rw-r--r--changes/ticket334604
-rw-r--r--changes/ticket334916
-rw-r--r--changes/ticket336424
-rw-r--r--changes/ticket336435
-rw-r--r--changes/ticket33643_part23
-rw-r--r--configure.ac8
-rw-r--r--doc/HACKING/CircuitPaddingQuickStart.md3
-rw-r--r--doc/HACKING/CodeStructure.md1
-rw-r--r--doc/HACKING/CodingStandards.md60
-rw-r--r--doc/HACKING/CodingStandardsRust.md60
-rw-r--r--doc/HACKING/EndOfLifeTor.md8
-rw-r--r--doc/HACKING/Fuzzing.md2
-rw-r--r--doc/HACKING/GettingStarted.md71
-rw-r--r--doc/HACKING/GettingStartedRust.md48
-rw-r--r--doc/HACKING/HelpfulTools.md61
-rw-r--r--doc/HACKING/HowToReview.md18
-rw-r--r--doc/HACKING/Module.md8
-rw-r--r--doc/HACKING/README.1st.md43
-rw-r--r--doc/HACKING/ReleasingTor.md20
-rw-r--r--doc/HACKING/Tracing.md12
-rw-r--r--doc/HACKING/WritingTests.md45
-rw-r--r--doc/HACKING/android/Simpleperf.md1
-rw-r--r--doc/tor.1.txt40
-rwxr-xr-xscripts/git/git-install-tools.sh189
-rwxr-xr-xscripts/git/git-list-tor-branches.sh153
-rwxr-xr-xscripts/git/git-merge-forward.sh77
-rwxr-xr-xscripts/git/git-pull-all.sh59
-rwxr-xr-xscripts/git/git-push-all.sh51
-rwxr-xr-xscripts/git/git-setup-dirs.sh48
-rw-r--r--scripts/maint/practracker/exceptions.txt80
-rw-r--r--src/app/config/config.c199
-rw-r--r--src/app/config/config.h4
-rw-r--r--src/app/config/or_options_st.h3
-rw-r--r--src/core/mainloop/connection.c3
-rw-r--r--src/core/or/addr_policy_st.h2
-rw-r--r--src/core/or/channel.c2
-rw-r--r--src/core/or/circuitmux_ewma.c4
-rw-r--r--src/core/or/circuitpadding.c9
-rw-r--r--src/core/or/dos.c4
-rw-r--r--src/core/or/dos.h3
-rw-r--r--src/core/or/policies.c17
-rw-r--r--src/core/or/policies.h1
-rw-r--r--src/core/or/sendme.h2
-rw-r--r--src/feature/client/bridges.c3
-rw-r--r--src/feature/dirauth/dirauth_config.h12
-rw-r--r--src/feature/dirauth/dirvote.c24
-rw-r--r--src/feature/dirauth/dirvote.h2
-rw-r--r--src/feature/dirauth/guardfraction.c2
-rw-r--r--src/feature/dirauth/process_descs.c29
-rw-r--r--src/feature/dirauth/process_descs.h11
-rw-r--r--src/feature/dircache/conscache.c15
-rw-r--r--src/feature/dirclient/dirclient.c2
-rw-r--r--src/feature/dirparse/parsecommon.c9
-rw-r--r--src/feature/hs/hs_cache.c64
-rw-r--r--src/feature/hs/hs_cell.c2
-rw-r--r--src/feature/hs/hs_client.c6
-rw-r--r--src/feature/hs/hs_service.c106
-rw-r--r--src/feature/hs/hs_service.h3
-rw-r--r--src/feature/nodelist/networkstatus.c2
-rw-r--r--src/feature/nodelist/routerlist.c2
-rw-r--r--src/feature/relay/ext_orport.c2
-rw-r--r--src/feature/relay/relay_config.c19
-rw-r--r--src/feature/relay/relay_config.h17
-rw-r--r--src/feature/relay/router.c85
-rw-r--r--src/feature/relay/router.h2
-rw-r--r--src/feature/relay/routerkeys.h4
-rw-r--r--src/lib/crypt_ops/crypto_ed25519.c2
-rw-r--r--src/lib/crypt_ops/crypto_rsa.c27
-rw-r--r--src/lib/crypt_ops/crypto_rsa.h5
-rw-r--r--src/lib/crypt_ops/crypto_rsa_nss.c14
-rw-r--r--src/lib/crypt_ops/crypto_rsa_openssl.c70
-rw-r--r--src/lib/encoding/pem.c8
-rw-r--r--src/lib/err/torerr.c26
-rw-r--r--src/lib/err/torerr.h2
-rw-r--r--src/lib/err/torerr_sys.c6
-rw-r--r--src/lib/evloop/procmon.c4
-rw-r--r--src/lib/log/log.c60
-rw-r--r--src/lib/log/log.h2
-rw-r--r--src/lib/log/util_bug.c2
-rw-r--r--src/lib/net/address.h2
-rw-r--r--src/lib/osinfo/uname.c2
-rw-r--r--src/test/conf_examples/large_1/expected1
-rw-r--r--src/test/conf_examples/large_1/expected_no_dirauth1
-rw-r--r--src/test/conf_examples/large_1/torrc1
-rw-r--r--src/test/conf_examples/relay_30/error_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/relay_30/expected2
-rw-r--r--src/test/conf_examples/relay_30/expected_log1
-rw-r--r--src/test/conf_examples/relay_30/torrc3
-rw-r--r--src/test/conf_examples/relay_31/error_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/relay_31/expected3
-rw-r--r--src/test/conf_examples/relay_31/expected_log1
-rw-r--r--src/test/conf_examples/relay_31/torrc4
-rw-r--r--src/test/conf_examples/relay_32/error_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/relay_32/expected3
-rw-r--r--src/test/conf_examples/relay_32/expected_log1
-rw-r--r--src/test/conf_examples/relay_32/torrc4
-rw-r--r--src/test/conf_examples/relay_33/error_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/relay_33/expected3
-rw-r--r--src/test/conf_examples/relay_33/expected_log1
-rw-r--r--src/test/conf_examples/relay_33/torrc4
-rw-r--r--src/test/conf_examples/relay_34/error_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/relay_34/expected4
-rw-r--r--src/test/conf_examples/relay_34/expected_log1
-rw-r--r--src/test/conf_examples/relay_34/torrc5
-rw-r--r--src/test/test_circuitbuild.c8
-rw-r--r--src/test/test_config.c66
-rw-r--r--src/test/test_crypto.c39
-rw-r--r--src/test/test_dir.c10
-rw-r--r--src/test/test_dos.c24
-rw-r--r--src/test/test_hs_client.c46
-rw-r--r--src/test/test_hs_control.c44
-rw-r--r--src/test/test_hs_intropoint.c3
-rw-r--r--src/test/test_hs_service.c165
-rw-r--r--src/test/test_options.c19
-rw-r--r--src/test/test_pem.c30
-rw-r--r--src/test/test_policy.c54
-rw-r--r--src/test/test_process_descs.c17
-rw-r--r--src/test/test_protover.c6
-rw-r--r--src/test/test_router.c117
-rw-r--r--src/test/test_util.c2
-rw-r--r--src/test/test_util_process.c2
-rw-r--r--src/test/testing_common.c15
147 files changed, 2623 insertions, 1081 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 7e08602fe3..fefc7d05e7 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -18,7 +18,7 @@ environment:
- target: i686-w64-mingw32
compiler_path: mingw32
mingw_prefix: mingw-w64-i686
- hardening:
+ hardening: --enable-all-bugs-are-fatal
- target: x86_64-w64-mingw32
compiler_path: mingw64
mingw_prefix: mingw-w64-x86_64
@@ -36,7 +36,7 @@ matrix:
target: i686-w64-mingw32
compiler_path: mingw32
mingw_prefix: mingw-w64-i686
- hardening:
+ hardening: --enable-all-bugs-are-fatal
- image: Visual Studio 2015
target: x86_64-w64-mingw32
compiler_path: mingw64
@@ -61,6 +61,9 @@ install:
# unprefixed packages are from MSYS2, which is like Cygwin. Avoid them.
#
# Use pacman --debug to show package downloads and install locations
+ #
+ # All installed library dlls must be copied to the test and app
+ # directories, before running tor's tests. (See below.)
#>
Execute-Command "C:\msys64\usr\bin\pacman" -Sy --verbose --needed --noconfirm ${env:mingw_prefix}-libevent ${env:mingw_prefix}-openssl ${env:mingw_prefix}-pkg-config ${env:mingw_prefix}-xz ${env:mingw_prefix}-zstd ;
@@ -95,9 +98,18 @@ test_script:
$buildpath = @("C:\msys64\${env:compiler_path}\bin") + $oldpath
$env:Path = $buildpath -join ';'
Set-Location "${env:build}"
- Copy-Item "C:/msys64/${env:compiler_path}/bin/libssp-0.dll" -Destination "${env:build}/src/test"
- Copy-Item "C:/msys64/${env:compiler_path}/bin/zlib1.dll" -Destination "${env:build}/src/test"
- Execute-Bash "VERBOSE=1 make -k -j2 check"
+ <# Some compiler dlls must be copied to the test and app
+ # directories, before running tor's tests.
+ #>
+ Copy-Item "C:/msys64/${env:compiler_path}/bin/libssp-0.dll","C:/msys64/${env:compiler_path}/bin/zlib1.dll" -Destination "${env:build}/src/test"
+ Copy-Item "C:/msys64/${env:compiler_path}/bin/libssp-0.dll","C:/msys64/${env:compiler_path}/bin/zlib1.dll" -Destination "${env:build}/src/app"
+ <# All installed library dlls must be copied to the test and app
+ # directories, before running tor's tests.
+ # (See install command above.)
+ #>
+ Copy-Item "C:/${env:compiler_path}/bin/libcrypto*.dll","C:/${env:compiler_path}/bin/libssl*.dll","C:/${env:compiler_path}/bin/liblzma*.dll","C:/${env:compiler_path}/bin/libevent*.dll","C:/${env:compiler_path}/bin/libzstd*.dll" -Destination "${env:build}/src/test"
+ Copy-Item "C:/${env:compiler_path}/bin/libcrypto*.dll","C:/${env:compiler_path}/bin/libssl*.dll","C:/${env:compiler_path}/bin/liblzma*.dll","C:/${env:compiler_path}/bin/libevent*.dll","C:/${env:compiler_path}/bin/libzstd*.dll" -Destination "${env:build}/src/app"
+ Execute-Bash "VERBOSE=1 TOR_SKIP_TESTCASES=crypto/openssl_version make -k -j2 check"
}
on_finish:
diff --git a/.gitignore b/.gitignore
index 469bbd39a5..ea6b68ec5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.swo
# C stuff
*.o
+*.a
*.obj
# Diff droppings
*.orig
@@ -77,7 +78,6 @@ uptime-*.json
/coverage_html/
/callgraph/
-
# /contrib/
/contrib/dist/tor.sh
/contrib/dist/torctl
@@ -137,9 +137,6 @@ uptime-*.json
/src/Makefile
/src/Makefile.in
-# /src/trace
-/src/trace/libor-trace.a
-
# /src/config/
/src/config/Makefile
/src/config/Makefile.in
@@ -149,89 +146,10 @@ uptime-*.json
/src/config/torrc.minimal
# /src/ext/
-/src/ext/ed25519/ref10/libed25519_ref10.a
/src/ext/ed25519/ref10/libed25519_ref10.lib
-/src/ext/ed25519/donna/libed25519_donna.a
/src/ext/ed25519/donna/libed25519_donna.lib
-/src/ext/keccak-tiny/libkeccak-tiny.a
/src/ext/keccak-tiny/libkeccak-tiny.lib
-# /src/lib
-/src/lib/libcurve25519_donna.a
-/src/lib/libtor-buf.a
-/src/lib/libtor-buf-testing.a
-/src/lib/libtor-compress.a
-/src/lib/libtor-compress-testing.a
-/src/lib/libtor-confmgt.a
-/src/lib/libtor-confmgt-testing.a
-/src/lib/libtor-container.a
-/src/lib/libtor-container-testing.a
-/src/lib/libtor-crypt-ops.a
-/src/lib/libtor-crypt-ops-testing.a
-/src/lib/libtor-ctime.a
-/src/lib/libtor-ctime-testing.a
-/src/lib/libtor-dispatch.a
-/src/lib/libtor-dispatch-testing.a
-/src/lib/libtor-encoding.a
-/src/lib/libtor-encoding-testing.a
-/src/lib/libtor-evloop.a
-/src/lib/libtor-evloop-testing.a
-/src/lib/libtor-err.a
-/src/lib/libtor-err-testing.a
-/src/lib/libtor-fdio.a
-/src/lib/libtor-fdio-testing.a
-/src/lib/libtor-fs.a
-/src/lib/libtor-fs-testing.a
-/src/lib/libtor-geoip.a
-/src/lib/libtor-geoip-testing.a
-/src/lib/libtor-intmath.a
-/src/lib/libtor-intmath-testing.a
-/src/lib/libtor-llharden.a
-/src/lib/libtor-llharden-testing.a
-/src/lib/libtor-lock.a
-/src/lib/libtor-lock-testing.a
-/src/lib/libtor-log.a
-/src/lib/libtor-log-testing.a
-/src/lib/libtor-malloc.a
-/src/lib/libtor-malloc-testing.a
-/src/lib/libtor-math.a
-/src/lib/libtor-math-testing.a
-/src/lib/libtor-memarea.a
-/src/lib/libtor-memarea-testing.a
-/src/lib/libtor-meminfo.a
-/src/lib/libtor-meminfo-testing.a
-/src/lib/libtor-net.a
-/src/lib/libtor-net-testing.a
-/src/lib/libtor-osinfo.a
-/src/lib/libtor-osinfo-testing.a
-/src/lib/libtor-process.a
-/src/lib/libtor-process-testing.a
-/src/lib/libtor-pubsub.a
-/src/lib/libtor-pubsub-testing.a
-/src/lib/libtor-sandbox.a
-/src/lib/libtor-sandbox-testing.a
-/src/lib/libtor-string.a
-/src/lib/libtor-string-testing.a
-/src/lib/libtor-smartlist-core.a
-/src/lib/libtor-smartlist-core-testing.a
-/src/lib/libtor-term.a
-/src/lib/libtor-term-testing.a
-/src/lib/libtor-thread.a
-/src/lib/libtor-thread-testing.a
-/src/lib/libtor-time.a
-/src/lib/libtor-time-testing.a
-/src/lib/libtor-tls.a
-/src/lib/libtor-tls-testing.a
-/src/lib/libtor-trace.a
-/src/lib/libtor-version.a
-/src/lib/libtor-version-testing.a
-/src/lib/libtor-wallclock.a
-/src/lib/libtor-wallclock-testing.a
-
-# /src/tor
-/src/core/libtor-app.a
-/src/core/libtor-app-testing.a
-
# /src/app
/src/app/tor
/src/app/tor.exe
@@ -277,7 +195,6 @@ uptime-*.json
/src/test/fuzz/lf-fuzz-*
# /src/tools/
-/src/tools/libtorrunner.a
/src/tools/tor-checkkey
/src/tools/tor-resolve
/src/tools/tor-cov-resolve
@@ -293,10 +210,6 @@ uptime-*.json
/src/tools/Makefile
/src/tools/Makefile.in
-# /src/trunnel/
-/src/trunnel/libor-trunnel-testing.a
-/src/trunnel/libor-trunnel.a
-
# /src/win32/
/src/win32/Makefile
/src/win32/Makefile.in
diff --git a/.travis.yml b/.travis.yml
index 16d2e432df..01343e65d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,7 @@ env:
- MAKEFLAGS="-k -j 2"
## We turn on hardening by default
## Also known as --enable-fragile-hardening in 0.3.0.3-alpha and later
- - HARDENING_OPTIONS="--enable-expensive-hardening"
+ - HARDENING_OPTIONS="--enable-all-bugs-are-fatal --enable-expensive-hardening"
## We turn off asciidoc by default, because it's slow
- ASCIIDOC_OPTIONS="--disable-asciidoc"
## Our default rust version is the minimum supported version
@@ -52,7 +52,8 @@ matrix:
- compiler: clang
os: osx
## Turn off some newer features, turn on clang's -Wtypedef-redefinition
- env: C_DIALECT_OPTIONS="-std=gnu99"
+ ## Also, disable ALL_BUGS_ARE_FATAL macro.
+ env: C_DIALECT_OPTIONS="-std=gnu99" HARDENING_OPTIONS="--enable-expensive-hardening"
## 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
@@ -63,9 +64,9 @@ matrix:
- env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes"
## We check disable module relay
- - env: MODULES_OPTIONS="--disable-module-relay"
+ - env: MODULES_OPTIONS="--disable-module-relay" HARDENING_OPTIONS="--enable-expensive-hardening"
## We check disable module dirauth
- - env: MODULES_OPTIONS="--disable-module-dirauth"
+ - env: MODULES_OPTIONS="--disable-module-dirauth" HARDENING_OPTIONS="--enable-expensive-hardening"
## We run rust on Linux, because it's faster than rust on macOS
## We check rust offline
@@ -74,7 +75,7 @@ matrix:
## 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"
+ - env: NSS_OPTIONS="--enable-nss" C_DIALECT_OPTIONS="-std=gnu99" HARDENING_OPTIONS="--enable-expensive-hardening"
## We include a single coverage build with the best options for coverage
- env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS="" TOR_TEST_RNG_SEED="636f766572616765"
@@ -241,7 +242,7 @@ script:
- ./autogen.sh
- CONFIGURE_FLAGS="$ASCIIDOC_OPTIONS $COVERAGE_OPTIONS $HARDENING_OPTIONS $MODULES_OPTIONS $NSS_OPTIONS $OPENSSL_OPTIONS $RUST_OPTIONS --enable-fatal-warnings --disable-silent-rules"
- echo "Configure flags are $CONFIGURE_FLAGS CC=\"$CC $C_DIALECT_OPTIONS\""
- - ./configure $CONFIGURE_FLAGS CC="$CC $C_DIALECT_OPTIONS"
+ - ./configure $CONFIGURE_FLAGS CC="$CC $C_DIALECT_OPTIONS";
## 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
diff --git a/ChangeLog b/ChangeLog
index b5dc9f692a..15dd22a930 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,343 @@
+Changes in version 0.4.3.3-alpha - 2020-03-18
+ Tor 0.4.3.3-alpha fixes several bugs in previous releases, including
+ TROVE-2020-002, a major denial-of-service vulnerability that affected
+ all released Tor instances since 0.2.1.5-alpha. Using this
+ vulnerability, an attacker could cause Tor instances to consume a huge
+ amount of CPU, disrupting their operations for several seconds or
+ minutes. This attack could be launched by anybody against a relay, or
+ by a directory cache against any client that had connected to it. The
+ attacker could launch this attack as much as they wanted, thereby
+ disrupting service or creating patterns that could aid in traffic
+ analysis. This issue was found by OSS-Fuzz, and is also tracked
+ as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ 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.
+
+ 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.
+
+ o Minor features (directory authorities):
+ - Directory authorities now reject descriptors from relays running
+ Tor versions from the 0.2.9 and 0.4.0 series. The 0.3.5 series is
+ still allowed. Resolves ticket 32672. Patch by Neel Chauhan.
+
+ o Minor features (usability):
+ - Include more information when failing to parse a configuration
+ value. This should make it easier to tell what's going wrong when
+ a configuration file doesn't parse. Closes ticket 33460.
+
+ o Minor bugfix (relay, configuration):
+ - Warn if the ContactInfo field is not set, and tell the relay
+ operator that not having a ContactInfo field set might cause their
+ relay to get rejected in the future. Fixes bug 33361; bugfix
+ on 0.1.1.10-alpha.
+
+ o Minor bugfixes (coding best practices checks):
+ - Allow the "practracker" 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.
+
+ o Minor bugfixes (continuous integration):
+ - Remove the buggy and unused mirroring job. Fixes bug 33213; bugfix
+ on 0.3.2.2-alpha.
+
+ o Minor bugfixes (onion service v3, client):
+ - Remove a BUG() warning that would cause a stack trace if an onion
+ service descriptor was freed while we were waiting for a
+ rendezvous circuit to complete. Fixes bug 28992; bugfix
+ on 0.3.2.1-alpha.
+
+ o Minor bugfixes (onion services v3):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ 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.
+ - Document the __OwningControllerProcess torrc option and specify
+ its polling interval. Resolves issue 32971.
+
+ o Testing (Travis CI):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.4.2.7 - 2020-03-18
+ This is the third stable release in the 0.4.2.x series. It backports
+ numerous fixes from later releases, including a fix for TROVE-2020-
+ 002, a major denial-of-service vulnerability that affected all
+ released Tor instances since 0.2.1.5-alpha. Using this vulnerability,
+ an attacker could cause Tor instances to consume a huge amount of CPU,
+ disrupting their operations for several seconds or minutes. This
+ attack could be launched by anybody against a relay, or by a directory
+ cache against any client that had connected to it. The attacker could
+ launch this attack as much as they wanted, thereby disrupting service
+ or creating patterns that could aid in traffic analysis. This issue
+ was found by OSS-Fuzz, and is also tracked as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak, backport from 0.4.3.3-alpha):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ o Major bugfixes (directory authority, backport from 0.4.3.3-alpha):
+ - 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.
+
+ o Minor features (continuous integration, backport from 0.4.3.2-alpha):
+ - 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 (bridges, backport from 0.4.3.1-alpha):
+ - 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.4.1.9 - 2020-03-18
+ Tor 0.4.1.9 backports important fixes from later Tor releases,
+ including a fix for TROVE-2020-002, a major denial-of-service
+ vulnerability that affected all released Tor instances since
+ 0.2.1.5-alpha. Using this vulnerability, an attacker could cause Tor
+ instances to consume a huge amount of CPU, disrupting their operations
+ for several seconds or minutes. This attack could be launched by
+ anybody against a relay, or by a directory cache against any client
+ that had connected to it. The attacker could launch this attack as
+ much as they wanted, thereby disrupting service or creating patterns
+ that could aid in traffic analysis. This issue was found by OSS-Fuzz,
+ and is also tracked as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak, backport from 0.4.3.3-alpha):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ o Minor bugfixes (bridges, backport from 0.4.3.1-alpha):
+ - 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.3.5.10 - 2020-03-18
+ Tor 0.3.5.10 backports many fixes from later Tor releases, including a
+ fix for TROVE-2020-002, a major denial-of-service vulnerability that
+ affected all released Tor instances since 0.2.1.5-alpha. Using this
+ vulnerability, an attacker could cause Tor instances to consume a huge
+ amount of CPU, disrupting their operations for several seconds or
+ minutes. This attack could be launched by anybody against a relay, or
+ by a directory cache against any client that had connected to it. The
+ attacker could launch this attack as much as they wanted, thereby
+ disrupting service or creating patterns that could aid in traffic
+ analysis. This issue was found by OSS-Fuzz, and is also tracked
+ as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ 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 lead 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.
+
+ o Minor features (continuous integration, backport from 0.4.3.2-alpha):
+ - 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 (bridges, backport from 0.4.3.1-alpha):
+ - 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 (crash, backport from 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (backport from 0.4.3.1-alpha):
+ - 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.
+ - 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 Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+ o Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - Stop allowing the Chutney IPv6 Travis job to fail. This job was
+ previously configured to fast_finish (which requires
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
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
diff --git a/README b/README
index 9e0f4b8241..9bbf027d70 100644
--- a/README
+++ b/README
@@ -24,9 +24,8 @@ Making applications work with Tor:
Frequently Asked Questions:
https://www.torproject.org/docs/faq.html
+Release timeline:
+ https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/CoreTorReleases
To get started working on Tor development:
See the doc/HACKING directory.
-
-Release timeline:
- https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/CoreTorReleases
diff --git a/ReleaseNotes b/ReleaseNotes
index 7d981e2c42..a9adbfe342 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -2,6 +2,346 @@ 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.3.3-alpha - 2020-03-18
+ Tor 0.4.3.3-alpha fixes several bugs in previous releases, including
+ TROVE-2020-002, a major denial-of-service vulnerability that affected
+ all released Tor instances since 0.2.1.5-alpha. Using this
+ vulnerability, an attacker could cause Tor instances to consume a huge
+ amount of CPU, disrupting their operations for several seconds or
+ minutes. This attack could be launched by anybody against a relay, or
+ by a directory cache against any client that had connected to it. The
+ attacker could launch this attack as much as they wanted, thereby
+ disrupting service or creating patterns that could aid in traffic
+ analysis. This issue was found by OSS-Fuzz, and is also tracked
+ as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ 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.
+
+ 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.
+
+ o Minor features (directory authorities):
+ - Directory authorities now reject descriptors from relays running
+ Tor versions from the 0.2.9 and 0.4.0 series. The 0.3.5 series is
+ still allowed. Resolves ticket 32672. Patch by Neel Chauhan.
+
+ o Minor features (usability):
+ - Include more information when failing to parse a configuration
+ value. This should make it easier to tell what's going wrong when
+ a configuration file doesn't parse. Closes ticket 33460.
+
+ o Minor bugfix (relay, configuration):
+ - Warn if the ContactInfo field is not set, and tell the relay
+ operator that not having a ContactInfo field set might cause their
+ relay to get rejected in the future. Fixes bug 33361; bugfix
+ on 0.1.1.10-alpha.
+
+ o Minor bugfixes (coding best practices checks):
+ - Allow the "practracker" 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.
+
+ o Minor bugfixes (continuous integration):
+ - Remove the buggy and unused mirroring job. Fixes bug 33213; bugfix
+ on 0.3.2.2-alpha.
+
+ o Minor bugfixes (onion service v3, client):
+ - Remove a BUG() warning that would cause a stack trace if an onion
+ service descriptor was freed while we were waiting for a
+ rendezvous circuit to complete. Fixes bug 28992; bugfix
+ on 0.3.2.1-alpha.
+
+ o Minor bugfixes (onion services v3):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ 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.
+ - Document the __OwningControllerProcess torrc option and specify
+ its polling interval. Resolves issue 32971.
+
+ o Testing (Travis CI):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.4.2.7 - 2020-03-18
+ This is the third stable release in the 0.4.2.x series. It backports
+ numerous fixes from later releases, including a fix for TROVE-2020-
+ 002, a major denial-of-service vulnerability that affected all
+ released Tor instances since 0.2.1.5-alpha. Using this vulnerability,
+ an attacker could cause Tor instances to consume a huge amount of CPU,
+ disrupting their operations for several seconds or minutes. This
+ attack could be launched by anybody against a relay, or by a directory
+ cache against any client that had connected to it. The attacker could
+ launch this attack as much as they wanted, thereby disrupting service
+ or creating patterns that could aid in traffic analysis. This issue
+ was found by OSS-Fuzz, and is also tracked as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak, backport from 0.4.3.3-alpha):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ o Major bugfixes (directory authority, backport from 0.4.3.3-alpha):
+ - 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.
+
+ o Minor features (continuous integration, backport from 0.4.3.2-alpha):
+ - 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 (bridges, backport from 0.4.3.1-alpha):
+ - 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.4.1.9 - 2020-03-18
+ Tor 0.4.1.9 backports important fixes from later Tor releases,
+ including a fix for TROVE-2020-002, a major denial-of-service
+ vulnerability that affected all released Tor instances since
+ 0.2.1.5-alpha. Using this vulnerability, an attacker could cause Tor
+ instances to consume a huge amount of CPU, disrupting their operations
+ for several seconds or minutes. This attack could be launched by
+ anybody against a relay, or by a directory cache against any client
+ that had connected to it. The attacker could launch this attack as
+ much as they wanted, thereby disrupting service or creating patterns
+ that could aid in traffic analysis. This issue was found by OSS-Fuzz,
+ and is also tracked as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ o Major bugfixes (circuit padding, memory leak, backport from 0.4.3.3-alpha):
+ - Avoid a remotely triggered memory leak in the case that a circuit
+ padding machine is somehow negotiated twice on the same circuit.
+ Fixes bug 33619; bugfix on 0.4.0.1-alpha. Found by Tobias Pulls.
+ This is also tracked as TROVE-2020-004 and CVE-2020-10593.
+
+ o Minor bugfixes (bridges, backport from 0.4.3.1-alpha):
+ - 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - 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.
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
+Changes in version 0.3.5.10 - 2020-03-18
+ Tor 0.3.5.10 backports many fixes from later Tor releases, including a
+ fix for TROVE-2020-002, a major denial-of-service vulnerability that
+ affected all released Tor instances since 0.2.1.5-alpha. Using this
+ vulnerability, an attacker could cause Tor instances to consume a huge
+ amount of CPU, disrupting their operations for several seconds or
+ minutes. This attack could be launched by anybody against a relay, or
+ by a directory cache against any client that had connected to it. The
+ attacker could launch this attack as much as they wanted, thereby
+ disrupting service or creating patterns that could aid in traffic
+ analysis. This issue was found by OSS-Fuzz, and is also tracked
+ as CVE-2020-10592.
+
+ We do not have reason to believe that this attack is currently being
+ exploited in the wild, but nonetheless we advise everyone to upgrade
+ as soon as packages are available.
+
+ o Major bugfixes (security, denial-of-service, backport from 0.4.3.3-alpha):
+ - Fix a denial-of-service bug that could be used by anyone to
+ consume a bunch of CPU on any Tor relay or authority, or by
+ directories to consume a bunch of CPU on clients or hidden
+ services. Because of the potential for CPU consumption to
+ introduce observable timing patterns, we are treating this as a
+ high-severity security issue. Fixes bug 33119; bugfix on
+ 0.2.1.5-alpha. Found by OSS-Fuzz. We are also tracking this issue
+ as TROVE-2020-002 and CVE-2020-10592.
+
+ 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 lead 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.
+
+ o Minor features (continuous integration, backport from 0.4.3.2-alpha):
+ - 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 (bridges, backport from 0.4.3.1-alpha):
+ - 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 (crash, backport from 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 (logging, backport from 0.4.3.2-alpha):
+ - 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.
+
+ o Minor bugfixes (onion services v3, backport from 0.4.3.3-alpha):
+ - Fix an assertion failure that could result from a corrupted
+ ADD_ONION control port command. Found by Saibato. Fixes bug 33137;
+ bugfix on 0.3.3.1-alpha. This issue is also tracked
+ as TROVE-2020-003.
+
+ o Minor bugfixes (rust, build, backport from 0.4.3.2-alpha):
+ - 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 Testing (backport from 0.4.3.1-alpha):
+ - 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.
+ - 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 Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+ o Testing (Travis CI, backport from 0.4.3.3-alpha):
+ - 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.
+ - Stop allowing the Chutney IPv6 Travis job to fail. This job was
+ previously configured to fast_finish (which requires
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh"
+ tool to produce detailed diagnostic output. Closes ticket 32792.
+
+
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
diff --git a/changes/bug32588 b/changes/bug32588
new file mode 100644
index 0000000000..f31f2ce1ad
--- /dev/null
+++ b/changes/bug32588
@@ -0,0 +1,4 @@
+ o Minor bugfixes (relays):
+ - Stop advertising incorrect IPv6 ORPorts in relay and bridge descriptors,
+ when the IPv6 port was configured as "auto".
+ Fixes bug 32588; bugfix on 0.2.3.9-alpha
diff --git a/changes/bug33032 b/changes/bug33032
new file mode 100644
index 0000000000..0c665f25df
--- /dev/null
+++ b/changes/bug33032
@@ -0,0 +1,6 @@
+ o Minor bugfixes (key portability):
+ - When reading PEM-encoded key data, tolerate CRLF line-endings even if
+ we are not running on Windows. Previously, non-Windows hosts
+ would reject these line-endings in certain positions, making
+ certain key files hard to move from one host to another.
+ Fixes bug 33032; bugfix on 0.3.5.1-alpha.
diff --git a/changes/bug33087 b/changes/bug33087
new file mode 100644
index 0000000000..ab6df58cc6
--- /dev/null
+++ b/changes/bug33087
@@ -0,0 +1,7 @@
+ o Minor bugfixes (logging):
+ - Stop closing stderr and stdout during shutdown. Closing these file
+ descriptors can hide sanitiser logs.
+ Fixes bug 33087; bugfix on 0.4.1.6.
+ - Flush stderr, stdout, and file logs during shutdown, if supported by the
+ OS. This change helps make sure that any final logs are recorded.
+ Fixes bug 33087; bugfix on 0.4.1.6.
diff --git a/changes/bug33374 b/changes/bug33374
deleted file mode 100644
index d1141faf78..0000000000
--- a/changes/bug33374
+++ /dev/null
@@ -1,5 +0,0 @@
- 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/bug33608 b/changes/bug33608
new file mode 100644
index 0000000000..0e82a8eec9
--- /dev/null
+++ b/changes/bug33608
@@ -0,0 +1,5 @@
+ o Minor bugfixes (client IPv6):
+ - Stop forcing all non-SOCKSPorts to prefer IPv6 exit connections. Instead,
+ prefer IPv6 connections by default, but allow users to change their
+ configs using the "NoPreferIPv6" port flag.
+ Fixes bug 33608; bugfix on 0.4.3.1-alpha.
diff --git a/changes/bug33668 b/changes/bug33668
new file mode 100644
index 0000000000..2b0830d6d8
--- /dev/null
+++ b/changes/bug33668
@@ -0,0 +1,4 @@
+ o Minor bugfixes (--disable-module-relay):
+ - Fix an assertion failure when Tor is build without the relay module,
+ and then invoked with the "User" option. Fixes bug 33668; bugfix on
+ 0.4.3.1-alpha.
diff --git a/changes/bug33673 b/changes/bug33673
new file mode 100644
index 0000000000..37c00f2e6e
--- /dev/null
+++ b/changes/bug33673
@@ -0,0 +1,6 @@
+ o Testing:
+ - In our Appveyor Windows CI, copy required DLLs to test and app, before
+ running tor's tests. This ensures that tor.exe and test*.exe use the
+ correct version of each DLL. This fix is not required, but we hope it
+ will avoid DLL search issues in future.
+ Fixes bug 33673; bugfix on 0.3.4.2-alpha.
diff --git a/changes/bug33674 b/changes/bug33674
new file mode 100644
index 0000000000..bcc3fcab03
--- /dev/null
+++ b/changes/bug33674
@@ -0,0 +1,4 @@
+ o Minor bugfixes (--disable-module-relay,--disable-module-dirauth):
+ - Set some output arguments in the relay and dirauth module stubs, to
+ guard against future stub argument handling bugs like 33668.
+ Fixes bug 33674; bugfix on 0.4.3.1-alpha.
diff --git a/changes/doc33417 b/changes/doc33417
new file mode 100644
index 0000000000..0fc868fc65
--- /dev/null
+++ b/changes/doc33417
@@ -0,0 +1,3 @@
+ o Documentation (manpage):
+ - Refrain from mentioning nicknames in manpage section for MyFamily torrc
+ option. Resolves issue 33417.
diff --git a/changes/ticket32143 b/changes/ticket32143
new file mode 100644
index 0000000000..7f8a809ba5
--- /dev/null
+++ b/changes/ticket32143
@@ -0,0 +1,4 @@
+ o Minor features (continuous integration):
+ - Run unit-test and integration test (Stem, Chutney) jobs with
+ ALL_BUGS_ARE_FATAL macro being enabled on Travis and Appveyor.
+ Resolves ticket 32143.
diff --git a/changes/ticket32905 b/changes/ticket32905
new file mode 100644
index 0000000000..6f420ec693
--- /dev/null
+++ b/changes/ticket32905
@@ -0,0 +1,6 @@
+ o Removed features:
+ - Remove the ClientAutoIPv6ORPort option. This option attempted
+ to randomly choose between IPv4 and IPv6 for client connections,
+ and isn't a true implementation of Happy Eyeballs. Often, this
+ option failed on IPv4-only or IPv6-only connections. Closes
+ ticket 32905. Patch by Neel Chauhan.
diff --git a/changes/ticket32994 b/changes/ticket32994
new file mode 100644
index 0000000000..43a32afa78
--- /dev/null
+++ b/changes/ticket32994
@@ -0,0 +1,3 @@
+ o Code simplification and refactoring:
+ - Rewrite port_parse_config() to use the default port flags from
+ port_cfg_new(). Closes ticket 32994. Patch by MrSquanchee.
diff --git a/changes/ticket33029 b/changes/ticket33029
deleted file mode 100644
index c32ee4ad84..0000000000
--- a/changes/ticket33029
+++ /dev/null
@@ -1,5 +0,0 @@
- 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
deleted file mode 100644
index 7bec15b99b..0000000000
--- a/changes/ticket33188
+++ /dev/null
@@ -1,5 +0,0 @@
- 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/ticket33213 b/changes/ticket33213
deleted file mode 100644
index f1da591bd1..0000000000
--- a/changes/ticket33213
+++ /dev/null
@@ -1,3 +0,0 @@
- 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/ticket33290 b/changes/ticket33290
deleted file mode 100644
index 882764020e..0000000000
--- a/changes/ticket33290
+++ /dev/null
@@ -1,4 +0,0 @@
- 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/ticket33400 b/changes/ticket33400
new file mode 100644
index 0000000000..7603890765
--- /dev/null
+++ b/changes/ticket33400
@@ -0,0 +1,3 @@
+ o Minor feature (onion service v3):
+ - Log at INFO level why the service can not upload its descriptor(s). Closes
+ ticket 33400; bugfix on 0.3.2.1-alpha.
diff --git a/changes/ticket33451 b/changes/ticket33451
new file mode 100644
index 0000000000..74dd6d1ad8
--- /dev/null
+++ b/changes/ticket33451
@@ -0,0 +1,3 @@
+ o Minor features (developer tools):
+ - Add a script ("git-install-tools.sh") to install git hooks and helper
+ scripts. Closes ticket 33451.
diff --git a/changes/ticket33458 b/changes/ticket33458
new file mode 100644
index 0000000000..885c6dc505
--- /dev/null
+++ b/changes/ticket33458
@@ -0,0 +1,4 @@
+ o Minor bugfix (onion service v3):
+ - When cleaning the client descriptor cache, an attempt at closing circuits
+ for a non decrypted descriptor (lacking client authorization) lead to an
+ assert(). Fixes bug 33458; bugfix on 0.4.2.1-alpha.
diff --git a/changes/ticket33460 b/changes/ticket33460
deleted file mode 100644
index 21e0fc966c..0000000000
--- a/changes/ticket33460
+++ /dev/null
@@ -1,4 +0,0 @@
- o Minor features (usability):
- - Include more information when failing to parse a configuration value.
- This should make it easier to tell what's going wrong when a
- configuration file doesn't parse. Closes ticket 33460.
diff --git a/changes/ticket33491 b/changes/ticket33491
new file mode 100644
index 0000000000..595ea863ea
--- /dev/null
+++ b/changes/ticket33491
@@ -0,0 +1,6 @@
+ o Major bugfixes (DoS defenses, bridges, pluggable transport):
+ - DoS subsystem was not given the transport name of the client connection
+ when tor is a bridge and thus failing to find the GeoIP cache entry for
+ that client address. This resulted in failing to apply DoS defenses on
+ bridges with a pluggable transport. Fixes bug 33491; bugfix on
+ 0.3.3.2-alpha.
diff --git a/changes/ticket33642 b/changes/ticket33642
new file mode 100644
index 0000000000..b81edf7613
--- /dev/null
+++ b/changes/ticket33642
@@ -0,0 +1,4 @@
+ o Minor features (developer tooling):
+ - Refrain from listing all .a files that are generated by Tor build in
+ .gitignore. Add a single wildcard *.a entry that covers all of them for
+ present and future. Closes ticket 33642.
diff --git a/changes/ticket33643 b/changes/ticket33643
new file mode 100644
index 0000000000..7fddab74eb
--- /dev/null
+++ b/changes/ticket33643
@@ -0,0 +1,5 @@
+ o Minor features (testing):
+ - The unit tests now support a "TOR_SKIP_TESTCASES" environment variable
+ to specify a list of space-separated test cases that should not be
+ executed. We will use this to disable certain tests that are failing on
+ Appveyor because of mismatched OpenSSL libraries. Part of ticket 33643.
diff --git a/changes/ticket33643_part2 b/changes/ticket33643_part2
new file mode 100644
index 0000000000..28193d2af5
--- /dev/null
+++ b/changes/ticket33643_part2
@@ -0,0 +1,3 @@
+ o Testing (CI):
+ - On appveyor, skip the crypto/openssl_version test, which is failing
+ because of a mismatched library installation. Fix for 33643.
diff --git a/configure.ac b/configure.ac
index aa511a3911..87e7ea0cad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -228,6 +228,13 @@ if test "x$enable_expensive_hardening" = "xyes" || test "x$enable_fragile_harden
AC_DEFINE(DEBUG_SMARTLIST, 1, [Enable smartlist debugging])
fi
+AC_ARG_ENABLE(all-bugs-are-fatal,
+ AS_HELP_STRING(--enable-all-bugs-are-fatal, [force all soft asserts in Tor codebase (tor_assert_nonfatal(), BUG(), etc.) to act as hard asserts (tor_assert() and equivalents); makes Tor fragile; only recommended for dev builds]))
+
+if test "x$enable_all_bugs_are_fatal" = "xyes"; then
+ AC_DEFINE(ALL_BUGS_ARE_FATAL, 1, [All assert failures are fatal])
+fi
+
dnl Linker hardening options
dnl Currently these options are ELF specific - you can't use this with MacOSX
AC_ARG_ENABLE(linker-hardening,
@@ -649,6 +656,7 @@ AC_CHECK_FUNCS(
explicit_bzero \
timingsafe_memcmp \
flock \
+ fsync \
ftime \
get_current_dir_name \
getaddrinfo \
diff --git a/doc/HACKING/CircuitPaddingQuickStart.md b/doc/HACKING/CircuitPaddingQuickStart.md
index 167ff9f292..2780b5c6ea 100644
--- a/doc/HACKING/CircuitPaddingQuickStart.md
+++ b/doc/HACKING/CircuitPaddingQuickStart.md
@@ -47,6 +47,7 @@ If you want to install on your localsystem, run `make install`. For our case we
just want the tor binary at `src/app/tor`.
## Use tor in TB and at a relay
+
Download and install a fresh Tor Browser (TB) from torproject.org. Make sure it
works. From the command line, relative to the folder created when you extracted
TB, run `./Browser/start-tor-browser --verbose` to get some basic log output.
@@ -75,6 +76,7 @@ relay. Start TB, visit a website, and manually confirm that the middle is used
by looking at the circuit display.
## Add a bare-bones APE padding machine
+
Now the fun part. We have several resources at our disposal (mind that links
might be broken in the future, just search for the headings):
- The official [Circuit Padding Developer
@@ -192,6 +194,7 @@ register our machines:
We run `make` to get a new `tor` binary and copy it to our local TB.
## Run the machine
+
To be able
to view circuit info events in the console as we launch TB, we add `Log
[circ]info notice stdout` to `torrc` of TB.
diff --git a/doc/HACKING/CodeStructure.md b/doc/HACKING/CodeStructure.md
index fffafcaed1..d387018f9b 100644
--- a/doc/HACKING/CodeStructure.md
+++ b/doc/HACKING/CodeStructure.md
@@ -1,3 +1,4 @@
+# Code Structure
TODO: revise this to talk about how things are, rather than how things
have changed.
diff --git a/doc/HACKING/CodingStandards.md b/doc/HACKING/CodingStandards.md
index 7999724166..a181759d60 100644
--- a/doc/HACKING/CodingStandards.md
+++ b/doc/HACKING/CodingStandards.md
@@ -1,5 +1,4 @@
-Coding conventions for Tor
-==========================
+# Coding conventions for Tor
tl;dr:
@@ -10,8 +9,7 @@ tl;dr:
- Run `make distcheck` if you have made changes to build system components
- Add a file in `changes` for your branch.
-Patch checklist
----------------
+## Patch checklist
If possible, send your patch as one of these (in descending order of
preference)
@@ -34,7 +32,7 @@ Did you remember...
If you are submitting a major patch or new feature, or want to in the future...
- - Set up Chutney and Stem, see HACKING/WritingTests.md
+ - Set up Chutney and Stem, see `doc/HACKING/WritingTests.md`
- Run `make test-full` to test against all unit and integration tests.
If you have changed build system components:
@@ -42,9 +40,7 @@ If you have changed build system components:
- For example, if you have changed Makefiles, autoconf files, or anything
else that affects the build system.
-
-License issues
-==============
+## License issues
Tor is distributed under the license terms in the LICENSE -- in
brief, the "3-clause BSD license". If you send us code to
@@ -58,9 +54,7 @@ Some compatible licenses include:
- 2-clause BSD
- CC0 Public Domain Dedication
-
-How we use Git branches
-=======================
+## How we use Git branches
Each main development series (like 0.2.1, 0.2.2, etc) has its main work
applied to a single branch. At most one series can be the development series
@@ -91,9 +85,7 @@ conflicts in the ChangeLog when it comes time to merge your branch into Tor.
Best advice: don't try to keep an independent branch forked for more than 6
months and expect it to merge cleanly. Try to merge pieces early and often.
-
-How we log changes
-==================
+## How we log changes
When you do a commit that needs a ChangeLog entry, add a new file to
the `changes` toplevel subdirectory. It should have the format of a
@@ -199,8 +191,7 @@ Why use changes files instead of entries in the ChangeLog?
* Having every single commit touch the ChangeLog file tended to create
zillions of merge conflicts.
-Whitespace and C conformance
-----------------------------
+## Whitespace and C conformance
Invoke `make check-spaces` from time to time, so it can tell you about
deviations from our C whitespace style. Generally, we use:
@@ -231,8 +222,7 @@ you're using gcc, you should invoke the configure script with the
option `--enable-fatal-warnings`. This will tell the compiler
to make all warnings into errors.
-Functions to use; functions not to use
---------------------------------------
+## Functions to use; functions not to use
We have some wrapper functions like `tor_malloc`, `tor_free`, `tor_strdup`, and
`tor_gettimeofday;` use them instead of their generic equivalents. (They
@@ -250,7 +240,6 @@ available containers in `src/lib/containers/*.h`. You should probably
familiarize yourself with these modules before you write too much code, or
else you'll wind up reinventing the wheel.
-
We don't use `strcat` or `strcpy` or `sprintf` of any of those notoriously
broken old C functions. We also avoid `strncat` and `strncpy`. Use
`strlcat`, `strlcpy`, or `tor_snprintf/tor_asprintf` instead.
@@ -281,9 +270,7 @@ version prefixed with `tor_` instead: strtok_r, memmem, memstr,
asprintf, localtime_r, gmtime_r, inet_aton, inet_ntop, inet_pton,
getpass, ntohll, htonll. (This list is incomplete.)
-
-What code can use what other code?
-----------------------------------
+## What code can use what other code?
We're trying to simplify Tor's structure over time. In the long run, we want
Tor to be structured as a set of modules with *no circular dependencies*.
@@ -300,8 +287,7 @@ included except those specifically permitted by the `.may_include` file.
When editing one of these files, please make sure that you are not
introducing any cycles into Tor's dependency graph.
-Floating point math is hard
----------------------------
+## Floating point math is hard
Floating point arithmetic as typically implemented by computers is
very counterintuitive. Failure to adequately analyze floating point
@@ -360,8 +346,7 @@ For more detailed (and math-intensive) background, see [What Every
Computer Scientist Should Know About Floating-Point
Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).
-Other C conventions
--------------------
+## Other C conventions
The `a ? b : c` trinary operator only goes inside other expressions;
don't use it as a replacement for if. (You can ignore this inside macro
@@ -370,8 +355,7 @@ definitions when necessary.)
Assignment operators shouldn't nest inside other expressions. (You can
ignore this inside macro definitions when necessary.)
-Binary data and wire formats
-----------------------------
+## Binary data and wire formats
Use pointer to `char` when representing NUL-terminated string. To represent
arbitrary binary data, use pointer to `uint8_t`. (Many older Tor APIs ignore
@@ -390,8 +374,7 @@ for more information about trunnel.
For information on adding new trunnel code to Tor, see src/trunnel/README
-Calling and naming conventions
-------------------------------
+## Calling and naming conventions
Whenever possible, functions should return -1 on error and 0 on success.
@@ -414,17 +397,15 @@ probably time to create an enum. If you find that you are passing three or
more flags to a function, it's probably time to create a flags argument that
takes a bitfield.
-What To Optimize
-----------------
+## What To Optimize
Don't optimize anything if it's not in the critical path. Right now, the
critical path seems to be AES, logging, and the network itself. Feel free to
do your own profiling to determine otherwise.
-Log conventions
----------------
+## Log conventions
-`https://www.torproject.org/docs/faq#LogLevel`
+[FAQ - Log Levels](https://www.torproject.org/docs/faq#LogLevel)
No error or warning messages should be expected during normal OR or OP
operation.
@@ -438,8 +419,7 @@ end-users that they aren't expected to understand the message (perhaps
with a string like "internal error"). Option (A) is to be preferred to
option (B).
-Assertions In Tor
------------------
+## Assertions In Tor
Assertions should be used for bug-detection only. Don't use assertions to
detect bad user inputs, network errors, resource exhaustion, or similar
@@ -458,8 +438,7 @@ macro, as in:
if (BUG(ptr == NULL))
return -1;
-Allocator conventions
----------------------
+## Allocator conventions
By convention, any tor type with a name like `abc_t` should be allocated
by a function named `abc_new()`. This function should never return
@@ -500,8 +479,7 @@ to use it as a function callback), define it with a name like
When deallocating, don't say e.g. `if (x) tor_free(x)`. The convention is to
have deallocators do nothing when NULL pointer is passed.
-Doxygen comment conventions
----------------------------
+## Doxygen comment conventions
Say what functions do as a series of one or more imperative sentences, as
though you were telling somebody how to be the function. In other words, DO
diff --git a/doc/HACKING/CodingStandardsRust.md b/doc/HACKING/CodingStandardsRust.md
index b570e10dc7..97026c9b7c 100644
--- a/doc/HACKING/CodingStandardsRust.md
+++ b/doc/HACKING/CodingStandardsRust.md
@@ -1,39 +1,36 @@
+# Rust Coding Standards
- Rust Coding Standards
-=======================
-
-You MUST follow the standards laid out in `.../doc/HACKING/CodingStandards.md`,
+You MUST follow the standards laid out in `doc/HACKING/CodingStandards.md`,
where applicable.
- Module/Crate Declarations
----------------------------
+## Module/Crate Declarations
Each Tor C module which is being rewritten MUST be in its own crate.
-See the structure of `.../src/rust` for examples.
+See the structure of `src/rust` for examples.
In your crate, you MUST use `lib.rs` ONLY for pulling in external
crates (e.g. `extern crate libc;`) and exporting public objects from
other Rust modules (e.g. `pub use mymodule::foo;`). For example, if
-you create a crate in `.../src/rust/yourcrate`, your Rust code should
-live in `.../src/rust/yourcrate/yourcode.rs` and the public interface
-to it should be exported in `.../src/rust/yourcrate/lib.rs`.
+you create a crate in `src/rust/yourcrate`, your Rust code should
+live in `src/rust/yourcrate/yourcode.rs` and the public interface
+to it should be exported in `src/rust/yourcrate/lib.rs`.
If your code is to be called from Tor C code, you MUST define a safe
`ffi.rs`. See the "Safety" section further down for more details.
For example, in a hypothetical `tor_addition` Rust module:
-In `.../src/rust/tor_addition/addition.rs`:
+In `src/rust/tor_addition/addition.rs`:
pub fn get_sum(a: i32, b: i32) -> i32 {
a + b
}
-In `.../src/rust/tor_addition/lib.rs`:
+In `src/rust/tor_addition/lib.rs`:
pub use addition::*;
-In `.../src/rust/tor_addition/ffi.rs`:
+In `src/rust/tor_addition/ffi.rs`:
#[no_mangle]
pub extern "C" fn tor_get_sum(a: c_int, b: c_int) -> c_int {
@@ -42,7 +39,7 @@ In `.../src/rust/tor_addition/ffi.rs`:
If your Rust code must call out to parts of Tor's C code, you must
declare the functions you are calling in the `external` crate, located
-at `.../src/rust/external`.
+at `src/rust/external`.
<!-- XXX get better examples of how to declare these externs, when/how they -->
<!-- XXX are unsafe, what they are expected to do —isis -->
@@ -54,8 +51,7 @@ If you have any external modules as dependencies (e.g. `extern crate
libc;`), you MUST declare them in your crate's `lib.rs` and NOT in any
other module.
- Dependencies and versions
----------------------------
+## Dependencies and versions
In general, we use modules from only the Rust standard library
whenever possible. We will review including external crates on a
@@ -81,8 +77,7 @@ Currently, Tor requires that you use the latest stable Rust version. At
some point in the future, we will freeze on a given stable Rust version,
to ensure backward compatibility with stable distributions that ship it.
- Updating/Adding Dependencies
-------------------------------
+## Updating/Adding Dependencies
To add/remove/update dependencies, first add your dependencies,
exactly specifying their versions, into the appropriate *crate-level*
@@ -101,14 +96,13 @@ Next, run `/scripts/maint/updateRustDependencies.sh`. Then, go into
`src/ext/rust` and commit the changes to the `tor-rust-dependencies`
repo.
- Documentation
----------------
+## Documentation
You MUST include `#![deny(missing_docs)]` in your crate.
For function/method comments, you SHOULD include a one-sentence, "first person"
description of function behaviour (see requirements for documentation as
-described in `.../src/HACKING/CodingStandards.md`), then an `# Inputs` section
+described in `src/HACKING/CodingStandards.md`), then an `# Inputs` section
for inputs or initialisation values, a `# Returns` section for return
values/types, a `# Warning` section containing warnings for unsafe behaviours or
panics that could happen. For publicly accessible
@@ -118,14 +112,12 @@ types/constants/objects/functions/methods, you SHOULD also include an
You MUST document your module with _module docstring_ comments,
i.e. `//!` at the beginning of each line.
- Style
--------
+## Style
You SHOULD consider breaking up large literal numbers with `_` when it makes it
more human readable to do so, e.g. `let x: u64 = 100_000_000_000`.
- Testing
----------
+## Testing
All code MUST be unittested and integration tested.
@@ -134,7 +126,7 @@ describing how the function/object is expected to be used.
Integration tests SHOULD go into a `tests/` directory inside your
crate. Unittests SHOULD go into their own module inside the module
-they are testing, e.g. in `.../src/rust/tor_addition/addition.rs` you
+they are testing, e.g. in `src/rust/tor_addition/addition.rs` you
should put:
#[cfg(test)]
@@ -148,8 +140,7 @@ should put:
}
}
- Benchmarking
---------------
+## Benchmarking
The external `test` crate can be used for most benchmarking. However, using
this crate requires nightly Rust. Since we may want to switch to a more
@@ -173,7 +164,7 @@ for basic benchmarks, is only used when running benchmarks via `cargo
bench --features bench`.
Finally, to write your benchmark code, in
-`.../src/rust/tor_addition/addition.rs` you SHOULD put:
+`src/rust/tor_addition/addition.rs` you SHOULD put:
#[cfg(all(test, features = "bench"))]
mod bench {
@@ -186,23 +177,20 @@ Finally, to write your benchmark code, in
}
}
- Fuzzing
----------
+## Fuzzing
If you wish to fuzz parts of your code, please see the
-[`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz) crate, which uses
+[cargo fuzz](https://github.com/rust-fuzz/cargo-fuzz) crate, which uses
[libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer-sys).
- Whitespace & Formatting
--------------------------
+## Whitespace & Formatting
You MUST run `rustfmt` (https://github.com/rust-lang-nursery/rustfmt)
on your code before your code will be merged. You can install rustfmt
by doing `cargo install rustfmt-nightly` and then run it with `cargo
fmt`.
- Safety
---------
+## Safety
You SHOULD read [the nomicon](https://doc.rust-lang.org/nomicon/) before writing
Rust FFI code. It is *highly advised* that you read and write normal Rust code
diff --git a/doc/HACKING/EndOfLifeTor.md b/doc/HACKING/EndOfLifeTor.md
index 2fece2ca9d..0735dc311a 100644
--- a/doc/HACKING/EndOfLifeTor.md
+++ b/doc/HACKING/EndOfLifeTor.md
@@ -1,13 +1,11 @@
-
-End of Life on an old release series
-------------------------------------
+# End of Life on an old release series
Here are the steps that the maintainer should take when an old Tor release
series reaches End of Life. Note that they are _only_ for entire series that
have reached their planned EOL: they do not apply to security-related
deprecations of individual versions.
-### 0. Preliminaries
+## 0. Preliminaries
0. A few months before End of Life:
Write a deprecation announcement.
@@ -17,7 +15,7 @@ deprecations of individual versions.
Send the announcement to tor-announce, tor-talk, tor-relays, and the
packagers.
-### 1. On the day
+## 1. On the day
1. Open tickets to remove the release from:
- the jenkins builds
diff --git a/doc/HACKING/Fuzzing.md b/doc/HACKING/Fuzzing.md
index c2db7e9853..41853a8a23 100644
--- a/doc/HACKING/Fuzzing.md
+++ b/doc/HACKING/Fuzzing.md
@@ -11,7 +11,6 @@ To run the fuzzing test cases in a deterministic fashion, use:
This won't actually fuzz Tor! It will just run all the fuzz binaries
on our existing set of testcases for the fuzzer.
-
## Different kinds of fuzzing
Right now we support three different kinds of fuzzer.
@@ -51,7 +50,6 @@ But the fuzzing harness should crash if tor fails an assertion, triggers a
bug, or accesses memory it shouldn't. This helps fuzzing frameworks detect
"interesting" cases.
-
## Guided Fuzzing with AFL
There is no HTTPS, hash, or signature for American Fuzzy Lop's source code, so
diff --git a/doc/HACKING/GettingStarted.md b/doc/HACKING/GettingStarted.md
index 7d5397d70c..c2ca74d960 100644
--- a/doc/HACKING/GettingStarted.md
+++ b/doc/HACKING/GettingStarted.md
@@ -1,24 +1,19 @@
-
-Getting started in Tor development
-==================================
+# Getting started in Tor development
Congratulations! You've found this file, and you're reading it! This
means that you might be interested in getting started in developing Tor.
-(This guide is just about Tor itself--the small network program at the
+(_This guide is just about Tor itself--the small network program at the
heart of the Tor network--and not about all the other programs in the
-whole Tor ecosystem.)
-
+whole Tor ecosystem._)
If you are looking for a more bare-bones, less user-friendly information
dump of important information, you might like reading the
-doxygen output at https://src-ref.docs.torproject.org/tor/index.html .
-You should probably skim some of the topic headings there before you write
+[doxygen output](https://src-ref.docs.torproject.org/tor/index.html).
+You probably should skim some of the topic headings there before you write
your first patch.
-
-Required background
--------------------
+## Required background
First, I'm going to assume that you can build Tor from source, and that
you know enough of the C language to read and write it. (See the README
@@ -27,22 +22,20 @@ and any high-quality guide to C for information on programming.)
I'm also going to assume that you know a little bit about how to use
Git, or that you're able to follow one of the several excellent guides
-at http://git-scm.org to learn.
+at [git-scm](http://git-scm.org) to learn.
-Most Tor developers develop using some Unix-based system, such as Linux,
-BSD, or OSX. It's okay to develop on Windows if you want, but you're
+Most Tor developers develop using some Unix-based system, such as GNU/Linux,
+BSD, or macOS. It's okay to develop on Windows if you want, but you're
going to have a more difficult time.
-
-Getting your first patch into Tor
----------------------------------
+## Getting your first patch into Tor
Once you've reached this point, here's what you need to know.
1. Get the source.
We keep our source under version control in Git. To get the latest
- version, run
+ version, run:
git clone https://git.torproject.org/git/tor
@@ -52,18 +45,16 @@ Once you've reached this point, here's what you need to know.
git checkout maint-0.4.3
- 2. Find your way around the source
-
- Our overall code structure is explained in our source documentation,
- currently at
+ 2. Find your way around the source.
- https://src-ref.docs.torproject.org/tor/index.html
+ Our overall code structure is explained in our
+ [source documentation](https://src-ref.docs.torproject.org/tor/index.html).
Find a part of the code that looks interesting to you, and start
looking around it to see how it fits together!
We do some unusual things in our codebase. Our testing-related
- practices and kludges are explained in doc/WritingTests.txt.
+ practices and kludges are explained in `doc/HACKING/WritingTests.md`.
If you see something that doesn't make sense, we love to get
questions!
@@ -75,10 +66,10 @@ Once you've reached this point, here's what you need to know.
Many people have gotten started by looking for an area where they
personally felt Tor was underperforming, and investigating ways to
- fix it. If you're looking for ideas, you can head to our bug
- tracker at trac.torproject.org and look for tickets that have
- received the "easy" tag: these are ones that developers think would
- be pretty simple for a new person to work on. For a bigger
+ fix it. If you're looking for ideas, you can head to
+ [trac](https://trac.torproject.org) our bug tracking tool and look for
+ tickets that have received the "easy" tag: these are ones that developers
+ think would be pretty simple for a new person to work on. For a bigger
challenge, you might want to look for tickets with the "lorax"
keyword: these are tickets that the developers think might be a
good idea to build, but which we have no time to work on any time
@@ -97,7 +88,7 @@ Once you've reached this point, here's what you need to know.
4. Meet the developers!
- We discuss stuff on the tor-dev mailing list and on the #tor-dev
+ We discuss stuff on the tor-dev mailing list and on the `#tor-dev`
IRC channel on OFTC. We're generally friendly and approachable,
and we like to talk about how Tor fits together. If we have ideas
about how something should be implemented, we'll be happy to share
@@ -114,8 +105,8 @@ Once you've reached this point, here's what you need to know.
protocols, there needs to be a written design proposal before it
can be merged. (We use this process to manage changes in the
protocols.) To write one, see the instructions at
- https://gitweb.torproject.org/torspec.git/tree/proposals/001-process.txt
- . If you'd like help writing a proposal, just ask! We're happy to
+ [the Tor proposal process](https://gitweb.torproject.org/torspec.git/plain/proposals/001-process.txt).
+ If you'd like help writing a proposal, just ask! We're happy to
help out with good ideas.
You might also like to look around the rest of that directory, to
@@ -126,7 +117,7 @@ Once you've reached this point, here's what you need to know.
As you write your code, you'll probably want it to fit in with the
standards of the rest of the Tor codebase so it will be easy for us
to review and merge. You can learn our coding standards in
- doc/HACKING.
+ `doc/HACKING` directory.
If your patch is large and/or is divided into multiple logical
components, remember to divide it into a series of Git commits. A
@@ -138,16 +129,16 @@ Once you've reached this point, here's what you need to know.
ensure that it runs correctly. Also, all code should actually be
_run_ by somebody, to make sure it works.
- See doc/WritingTests.txt for more information on how we test things
+ See `doc/HACKING/WritingTests.md` for more information on how we test things
in Tor. If you'd like any help writing tests, just ask! We're
glad to help out.
8. Submitting your patch
We review patches through tickets on our bugtracker at
- trac.torproject.org. You can either upload your patches there, or
+ [trac](https://trac.torproject.org). You can either upload your patches there, or
put them at a public git repository somewhere we can fetch them
- (like github or bitbucket) and then paste a link on the appropriate
+ (like gitlab, github or bitbucket) and then paste a link on the appropriate
trac ticket.
Once your patches are available, write a short explanation of what
@@ -164,17 +155,17 @@ Once you've reached this point, here's what you need to know.
When your patch is reviewed, one of these things will happen:
- * The reviewer will say "looks good to me" and your
+ * The reviewer will say "_looks good to me_" and your
patch will get merged right into Tor. [Assuming we're not
in the middle of a code-freeze window. If the codebase is
frozen, your patch will go into the next release series.]
- * OR the reviewer will say "looks good, just needs some small
- changes!" And then the reviewer will make those changes,
+ * OR the reviewer will say "_looks good, just needs some small
+ changes!_" And then the reviewer will make those changes,
and merge the modified patch into Tor.
- * OR the reviewer will say "Here are some questions and
- comments," followed by a bunch of stuff that the reviewer
+ * OR the reviewer will say "_Here are some questions and
+ comments,_" followed by a bunch of stuff that the reviewer
thinks should change in your code, or questions that the
reviewer has.
diff --git a/doc/HACKING/GettingStartedRust.md b/doc/HACKING/GettingStartedRust.md
index aa29c097da..247ea5c695 100644
--- a/doc/HACKING/GettingStartedRust.md
+++ b/doc/HACKING/GettingStartedRust.md
@@ -1,12 +1,9 @@
+# Hacking on Rust in Tor
- Hacking on Rust in Tor
-========================
-
- Getting Started
------------------
+## Getting Started
Please read or review our documentation on Rust coding standards
-(`.../doc/HACKING/CodingStandardsRust.md`) before doing anything.
+(`doc/HACKING/CodingStandardsRust.md`) before doing anything.
Please also read
[the Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). We
@@ -23,8 +20,7 @@ Please be patient with the other people who are working on getting more
Rust code into Tor, because they are graciously donating their free time
to contribute to this effort.
- Resources for learning Rust
------------------------------
+## Resources for learning Rust
**Beginning resources**
@@ -49,8 +45,7 @@ is
For learning more about FFI and Rust, see Jake Goulding's
[Rust FFI Omnibus](http://jakegoulding.com/rust-ffi-omnibus/).
- Compiling Tor with Rust enabled
----------------------------------
+## Compiling Tor with Rust enabled
You will need to run the `configure` script with the `--enable-rust`
flag to explicitly build with Rust. Additionally, you will need to
@@ -79,7 +74,7 @@ you are in the top level of the repository) configure tor with:
TOR_RUST_DEPENDENCIES='path_to_dependencies_directory' ./configure --enable-rust
-(Note that TOR_RUST_DEPENDENCIES must be the full path to the directory; it
+(Note that `TOR_RUST_DEPENDENCIES` must be the full path to the directory; it
cannot be relative.)
Assuming you used the above `git submodule` commands and you're in the
@@ -87,9 +82,7 @@ topmost directory of the repository, this would be:
TOR_RUST_DEPENDENCIES=`pwd`/src/ext/rust/crates ./configure --enable-rust
-
- Identifying which modules to rewrite
-======================================
+## Identifying which modules to rewrite
The places in the Tor codebase that are good candidates for porting to
Rust are:
@@ -117,12 +110,11 @@ interconnected your target module is.
The output will tell you each module name, along with a set of every module that
the module calls. Modules which call fewer other modules are better targets.
- Writing your Rust module
-==========================
+## Writing your Rust module
Strive to change the C API as little as possible.
-We are currently targetting Rust stable. (See CodingStandardsRust.md for more
+We are currently targetting Rust stable. (See `CodingStandardsRust.md` for more
details.)
It is on our TODO list to try to cultivate good
@@ -134,19 +126,17 @@ If parts of your Rust code needs to stay in sync with C code (such as
handling enums across the FFI boundary), annonotate these places in a
comment structured as follows:
- /// C_RUST_COUPLED: <path_to_file> `<name_of_c_object>`
+ `/// C_RUST_COUPLED: <path_to_file> <name_of_c_object>`
-Where <name_of_c_object> can be an enum, struct, constant, etc. Then,
+Where `<name_of_c_object>` can be an enum, struct, constant, etc. Then,
do the same in the C code, to note that rust will need to be changed
when the C does.
-
- Adding your Rust module to Tor's build system
------------------------------------------------
+## Adding your Rust module to Tor's build system
0. Your translation of the C module should live in its own crate(s)
- in the `.../tor/src/rust/` directory.
-1. Add your crate to `.../tor/src/rust/Cargo.toml`, in the
+ in the `src/rust/` directory.
+1. Add your crate to `src/rust/Cargo.toml`, in the
`[workspace.members]` section.
2. Add your crate's files to src/rust/include.am
@@ -156,12 +146,11 @@ dependency of other Rust modules):
`src/rust/tor_util/Cargo.toml` and include it in
`src/rust/tor_rust/lib.rs`
- How to test your Rust code
-----------------------------
+## How to test your Rust code
Everything should be tested full stop. Even non-public functionality.
-Be sure to edit `.../tor/src/test/test_rust.sh` to add the name of your
+Be sure to edit `src/test/test_rust.sh` to add the name of your
crate to the `crates` variable! This will ensure that `cargo test` is
run on your crate.
@@ -177,7 +166,6 @@ Tor's integration tests should also pass:
make test-stem
- Submitting a patch
-=====================
+## Submitting a patch
-Please follow the instructions in `.../doc/HACKING/GettingStarted.md`.
+Please follow the instructions in `doc/HACKING/GettingStarted.md`.
diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md
index ae892c34a2..15bd153318 100644
--- a/doc/HACKING/HelpfulTools.md
+++ b/doc/HACKING/HelpfulTools.md
@@ -1,11 +1,10 @@
-Useful tools
-============
+# Useful tools
These aren't strictly necessary for hacking on Tor, but they can help track
down bugs.
-Travis/Appveyor CI
-------------------
+## Travis/Appveyor CI
+
It's CI.
Looks like this:
@@ -29,8 +28,7 @@ for your fork to build commits outside of PRs too:
Builds should show up on the web at travis-ci.com and on IRC at #tor-ci on
OFTC. If they don't, ask #tor-dev (also on OFTC).
-Jenkins
--------
+## Jenkins
It's CI/builders. Looks like this: https://jenkins.torproject.org
@@ -43,8 +41,7 @@ Builds Linux and Windows cross-compilation. Runs Linux tests.
Builds should show up on the web at jenkins.torproject.org and on IRC at
#tor-bots on OFTC. If they don't, ask #tor-dev (also on OFTC).
-Valgrind
---------
+## Valgrind
valgrind --leak-check=yes --error-limit=no --show-reachable=yes src/app/tor
@@ -52,16 +49,14 @@ Valgrind
pass `--undef-value-errors=no` to valgrind, or rebuild your openssl
with `-DPURIFY`.)
-Coverity
---------
+## Coverity
Nick regularly runs the coverity static analyzer on the Tor codebase.
The preprocessor define `__COVERITY__` is used to work around instances
where coverity picks up behavior that we wish to permit.
-clang Static Analyzer
----------------------
+## clang Static Analyzer
The clang static analyzer can be run on the Tor codebase using Xcode (WIP)
or a command-line build.
@@ -69,8 +64,7 @@ or a command-line build.
The preprocessor define `__clang_analyzer__` is used to work around instances
where clang picks up behavior that we wish to permit.
-clang Runtime Sanitizers
-------------------------
+## clang Runtime Sanitizers
To build the Tor codebase with the clang Address and Undefined Behavior
sanitizers, see the file `contrib/clang/sanitize_blacklist.txt`.
@@ -78,8 +72,7 @@ sanitizers, see the file `contrib/clang/sanitize_blacklist.txt`.
Preprocessor workarounds for instances where clang picks up behavior that
we wish to permit are also documented in the blacklist file.
-Running lcov for unit test coverage
------------------------------------
+## Running lcov for unit test coverage
Lcov is a utility that generates pretty HTML reports of test code coverage.
To generate such a report:
@@ -96,8 +89,7 @@ output directory, use `make coverage-html HTML_COVER_DIR=./funky_new_cov_dir`.
Coverage diffs using lcov are not currently implemented, but are being
investigated (as of July 2014).
-Running the unit tests
-----------------------
+## Running the unit tests
To quickly run all the tests distributed with Tor:
@@ -123,8 +115,7 @@ working connection to the internet:
make test-full-online
-Running gcov for unit test coverage
------------------------------------
+## Running gcov for unit test coverage
./configure --enable-coverage
make
@@ -164,8 +155,7 @@ lines?
If you run ./scripts/test/cov-exclude, it marks excluded unreached
lines with 'x', and excluded reached lines with '!!!'.
-Running integration tests
--------------------------
+## Running integration tests
We have the beginnings of a set of scripts to run integration tests using
Chutney. To try them, set CHUTNEY_PATH to your chutney source directory, and
@@ -174,14 +164,12 @@ run `make test-network`.
We also have scripts to run integration tests using Stem. To try them, set
`STEM_SOURCE_DIR` to your Stem source directory, and run `test-stem`.
-Profiling Tor
--------------
+## Profiling Tor
Ongoing notes about Tor profiling can be found at
https://pad.riseup.net/p/profiling-tor
-Profiling Tor with oprofile
----------------------------
+## Profiling Tor with oprofile
The oprofile tool runs (on Linux only!) to tell you what functions Tor is
spending its CPU time in, so we can identify performance bottlenecks.
@@ -206,8 +194,7 @@ Here are some basic instructions
* `opreport -l that_dir/*`
- Profit
-Profiling Tor with perf
------------------------
+## Profiling Tor with perf
This works with a running Tor, and requires root.
@@ -236,8 +223,7 @@ This works with a running Tor, and requires root.
report -g > <FILENAME>.out`. Then you can compress that and put it somewhere
public.
-Profiling Tor with gperftools aka Google-performance-tools
-----------------------------------------------------------
+## Profiling Tor with gperftools aka Google-performance-tools
This should work on nearly any unixy system. It doesn't seem to be compatible
with RunAsDaemon though.
@@ -255,8 +241,7 @@ performance! See the gperftools manual for more info, but basically:
3. Run `pprof src/app/tor /tmp/profile` to start the REPL.
-Generating and analyzing a callgraph
-------------------------------------
+## Generating and analyzing a callgraph
0. Build Tor on linux or mac, ideally with -O0 or -fno-inline.
@@ -266,8 +251,7 @@ Generating and analyzing a callgraph
Note that currently the callgraph generator can't detect calls that pass
through function pointers.
-Getting emacs to edit Tor source properly
------------------------------------------
+## Getting emacs to edit Tor source properly
Nick likes to put the following snippet in his .emacs file:
@@ -315,8 +299,7 @@ If you use emacs for editing Tor and nothing else, you could always just say:
There is probably a better way to do this. No, we are probably not going
to clutter the files with emacs stuff.
-Building a tag file (code index)
---------------------------------
+## Building a tag file (code index)
Many functions in tor use `MOCK_IMPL` wrappers for unit tests. Your
tag-building program must be told how to handle this syntax.
@@ -340,8 +323,7 @@ instead:
A vim-compatible tag file will be generated by default. If you use emacs, add
the `-e` flag to generate an emacs-compatible tag file.
-Doxygen
--------
+## Doxygen
We use the 'doxygen' utility to generate documentation from our
source code. Here's how to use it:
@@ -396,8 +378,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-practices checking
---------------------------------
+## Style and best-practices checking
We use scripts to check for various problems in the formatting and style
of our source code. The "check-spaces" test detects a bunch of violations
diff --git a/doc/HACKING/HowToReview.md b/doc/HACKING/HowToReview.md
index 2325e70175..7815e76632 100644
--- a/doc/HACKING/HowToReview.md
+++ b/doc/HACKING/HowToReview.md
@@ -1,5 +1,4 @@
-How to review a patch
-=====================
+# How to review a patch
Some folks have said that they'd like to review patches more often, but they
don't know how.
@@ -9,9 +8,7 @@ So, here are a bunch of things to check for when reviewing a patch!
Note that if you can't do every one of these, that doesn't mean you can't do
a good review! Just make it clear what you checked for and what you didn't.
-
-Top-level smell-checks
-----------------------
+## Top-level smell-checks
(Difficulty: easy)
@@ -37,10 +34,9 @@ Top-level smell-checks
- If this changes anything in the code, is there a "changes" file?
-Let's look at the code!
------------------------
+## Let's look at the code!
-- Does the code conform to CodingStandards.txt?
+- Does the code conform to `CodingStandards.md`?
- Does the code leak memory?
@@ -60,8 +56,7 @@ Let's look at the code!
- Is there duplicated code that could be turned into a function?
-Let's look at the documentation!
---------------------------------
+## Let's look at the documentation!
- Does the documentation conform to CodingStandards.txt?
@@ -70,8 +65,7 @@ Let's look at the documentation!
- Can you predict what the function will do from its documentation?
-Let's think about security!
----------------------------
+## Let's think about security!
- If there are any arrays, buffers, are you 100% sure that they cannot
overflow?
diff --git a/doc/HACKING/Module.md b/doc/HACKING/Module.md
index 781bb978f2..f8a9773d47 100644
--- a/doc/HACKING/Module.md
+++ b/doc/HACKING/Module.md
@@ -1,9 +1,9 @@
-# Modules in Tor #
+# Modules in Tor
This document describes the build system and coding standards when writing a
module in Tor.
-## What is a module? ##
+## What is a module?
In the context of the tor code base, a module is a subsystem that we can
selectively enable or disable, at `configure` time.
@@ -27,7 +27,7 @@ because you would actually want to run one without the other.)
To disable a module, pass `--disable-module-{dirauth,relay}` at configure
time. All modules are currently enabled by default.
-## Build System ##
+## Build System
The changes to the build system are pretty straightforward.
@@ -55,7 +55,7 @@ Finally, your module will automatically be included in the
`TOR_MODULES_ALL_ENABLED` variable which is used to build the unit tests.
They always build everything in order to test everything.
-## Coding ##
+## Coding
As mentioned above, a module should be isolated in its own directories,
suffixed with the name of the module, in `src/*/`.
diff --git a/doc/HACKING/README.1st.md b/doc/HACKING/README.1st.md
index 8299fe634a..2278a61d6c 100644
--- a/doc/HACKING/README.1st.md
+++ b/doc/HACKING/README.1st.md
@@ -1,17 +1,18 @@
+# README.1st
-In this directory
------------------
+## In this directory
This directory has helpful information about what you need to know to
hack on Tor!
-First, read `GettingStarted.md` to learn how to get a start in Tor
-development.
+First, read `GettingStarted.md` and `GettingStartedRust.md`
+to learn how to get a start in Tor development.
-If you've decided to write a patch, `CodingStandards.txt` will give
-you a bunch of information about how we structure our code.
+If you've decided to write a patch, `CodingStandards.md` and
+`CodingStandardsRust.md` will give you a bunch of information
+about how we structure our code.
-It's important to get code right! Reading `WritingTests.md` will
+It's important to get the code right! Reading `WritingTests.md` will
tell you how to write and run tests in the Tor codebase.
There are a bunch of other programs we use to help maintain and
@@ -21,42 +22,26 @@ with Tor.
If it's your job to put out Tor releases, see `ReleasingTor.md` so
that you don't miss any steps!
-
------------------------
+## Additional Information
For full information on how Tor is supposed to work, look at the files in
-`https://gitweb.torproject.org/torspec.git/tree`.
+[Tor specification](https://gitweb.torproject.org/torspec.git/tree).
For an explanation of how to change Tor's design to work differently, look at
-`https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/001-process.txt`.
+[the Tor proposal process](https://gitweb.torproject.org/torspec.git/plain/proposals/001-process.txt).
For the latest version of the code, get a copy of git, and
git clone https://git.torproject.org/git/tor
+## Stay in touch
+
We talk about Tor on the `tor-talk` mailing list. Design proposals and
discussion belong on the `tor-dev` mailing list. We hang around on
-irc.oftc.net, with general discussion happening on #tor and development
+irc.oftc.net, with general discussion happening on `#tor` and development
happening on `#tor-dev`.
The other files in this `HACKING` directory may also be useful as you
get started working with Tor.
Happy hacking!
-
-
------------------------
-
-XXXXX also describe
-
-doc/HACKING/WritingTests.md
-
-torguts.git
-
-torspec.git
-
-The design paper
-
-freehaven.net/anonbib
-
-XXXX describe these and add links.
diff --git a/doc/HACKING/ReleasingTor.md b/doc/HACKING/ReleasingTor.md
index 0f453ca2aa..2464d8afb4 100644
--- a/doc/HACKING/ReleasingTor.md
+++ b/doc/HACKING/ReleasingTor.md
@@ -1,11 +1,9 @@
-
-Putting out a new release
--------------------------
+# Putting out a new release
Here are the steps that the maintainer should take when putting out a
new Tor release:
-### 0. Preliminaries
+## 0. Preliminaries
1. Get at least two of weasel/arma/Sebastian to put the new
version number in their approved versions list. Give them a few
@@ -18,7 +16,7 @@ new Tor release:
date of a TB that contains it. See note below in "commit, upload,
announce".
-### I. Make sure it works
+## I. Make sure it works
1. Make sure that CI passes: have a look at Travis
(https://travis-ci.org/torproject/tor/branches), Appveyor
@@ -51,9 +49,7 @@ new Tor release:
libevent and openssl, so using valgrind will sometimes find extra
memory leaks.)
-
-### II. Write a changelog
-
+## II. Write a changelog
1a. (Alpha release variant)
@@ -138,8 +134,7 @@ new Tor release:
to start sorting and condensing entries. (Generally, we don't edit the
text of existing entries, though.)
-
-### III. Making the source release.
+## III. Making the source release.
1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
`make update-versions` to update version numbers in other
@@ -165,7 +160,7 @@ new Tor release:
If it is not, you'll need to poke Roger, Weasel, and Sebastian again: see
item 0.1 at the start of this document.
-### IV. Commit, upload, announce
+## IV. Commit, upload, announce
1. Sign the tarball, then sign and push the git tag:
@@ -215,7 +210,6 @@ new Tor release:
Include a link to the changelog.
-
4. Add the version number to Trac. To do this, go to Trac, log in,
select "Admin" near the top of the screen, then select "Versions" from
the menu on the left. At the right, there will be an "Add version"
@@ -241,7 +235,7 @@ new Tor release:
For templates to use when announcing, see:
https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/AnnouncementTemplates
-### V. Aftermath and cleanup
+## V. Aftermath and cleanup
1. If it's a stable release, bump the version number in the
`maint-x.y.z` branch to "newversion-dev", and do a `merge -s ours`
diff --git a/doc/HACKING/Tracing.md b/doc/HACKING/Tracing.md
index 24fa761310..e1e97abe6d 100644
--- a/doc/HACKING/Tracing.md
+++ b/doc/HACKING/Tracing.md
@@ -1,16 +1,16 @@
-# Tracing #
+# Tracing
This document describes how the event tracing subsystem works in tor so
developers can add events to the code base but also hook them to an event
tracing framework.
-## Basics ###
+## Basics
Event tracing is separated in two concepts, trace events and a tracer. The
tracing subsystem can be found in `src/trace`. The `events.h` header file is
the main file that maps the different tracers to trace events.
-### Events ###
+### Events
A trace event is basically a function from which we can pass any data that
we want to collect. In addition, we specify a context for the event such as
@@ -39,7 +39,7 @@ How `argc` is collected or used has nothing to do with the instrumentation
the trace events and collection framework (tracer) are decoupled. You _can_
have trace events without a tracer.
-### Tracer ###
+### Tracer
In `src/trace/events.h`, we map the `tor_trace()` function to the right
tracer. A tracer support is only enabled at compile time. For instance, the
@@ -47,7 +47,7 @@ file `src/trace/debug.h` contains the mapping of the generic tracing function
`tor_trace()` to the `log_debug()` function. More specialized function can be
mapped depending on the tracepoint.
-## Build System ##
+## Build System
This section describes how it is integrated into the build system of tor.
@@ -66,7 +66,7 @@ configure option:
--enable-tracing-debug
-## Instrument Tor ##
+## Instrument Tor
This is pretty easy. Let's say you want to add a trace event in
`src/feature/rend/rendcache.c`, you only have to add this include statement:
diff --git a/doc/HACKING/WritingTests.md b/doc/HACKING/WritingTests.md
index 05de8e0be8..d212020525 100644
--- a/doc/HACKING/WritingTests.md
+++ b/doc/HACKING/WritingTests.md
@@ -1,6 +1,4 @@
-
-Writing tests for Tor: an incomplete guide
-==========================================
+# Writing tests for Tor: an incomplete guide
Tor uses a variety of testing frameworks and methodologies to try to
keep from introducing bugs. The major ones are:
@@ -19,8 +17,7 @@ keep from introducing bugs. The major ones are:
5. The Shadow network simulator.
-How to run these tests
-----------------------
+## How to run these tests
### The easy version
@@ -64,7 +61,7 @@ The former are those that should finish in a few seconds; the latter tend to
take more time, and may include CPU-intensive operations, deliberate delays,
and stuff like that.
-### Finding test coverage
+## Finding test coverage
Test coverage is a measurement of which lines your tests actually visit.
@@ -112,7 +109,7 @@ To count new or modified uncovered lines in D2, you can run:
./scripts/test/cov-diff ${D1} ${D2}" | grep '^+ *\#' | wc -l
-### Marking lines as unreachable by tests
+## Marking lines as unreachable by tests
You can mark a specific line as unreachable by using the special
string LCOV_EXCL_LINE. You can mark a range of lines as unreachable
@@ -126,9 +123,7 @@ unreached lines with 'x', and excluded reached lines with '!!!'.
Note: you should never do this unless the line is meant to 100%
unreachable by actual code.
-
-What kinds of test should I write?
-----------------------------------
+## What kinds of test should I write?
Integration testing and unit testing are complementary: it's probably a
good idea to make sure that your code is hit by both if you can.
@@ -143,8 +138,7 @@ If your code adds new externally visible functionality to Tor, it would
be great to have a test for that functionality. That's where
integration tests more usually come in.
-Unit and regression tests: Does this function do what it's supposed to?
------------------------------------------------------------------------
+## Unit and regression tests: Does this function do what it's supposed to?
Most of Tor's unit tests are made using the "tinytest" testing framework.
You can see a guide to using it in the tinytest manual at
@@ -165,7 +159,7 @@ If you have created a new test file, you will need to:
I use the term "unit test" and "regression tests" very sloppily here.
-### A simple example
+## A simple example
Here's an example of a test function for a simple function in util.c:
@@ -207,7 +201,7 @@ Finally, remember that by convention, all `*_free()` functions that
Tor defines are defined to accept NULL harmlessly. Thus, you don't
need to say `if (contents)` in the cleanup block.
-### Exposing static functions for testing
+## Exposing static functions for testing
Sometimes you need to test a function, but you don't want to expose
it outside its usual module.
@@ -228,7 +222,7 @@ For example, `crypto_curve25519.h` contains:
The `crypto_curve25519.c` file and the `test_crypto.c` file both define
`CRYPTO_CURVE25519_PRIVATE`, so they can see this declaration.
-### STOP! Does this test really test?
+## STOP! Does this test really test?
When writing tests, it's not enough to just generate coverage on all the
lines of the code that you're testing: It's important to make sure that
@@ -269,8 +263,7 @@ it's supposed to do, and fail otherwise. Try to design your tests so
that they check for the code's intended and documented functionality
as much as possible.
-
-### Mock functions for testing in isolation
+## Mock functions for testing in isolation
Often we want to test that a function works right, but the function to
be tested depends on other functions whose behavior is hard to observe,
@@ -311,7 +304,7 @@ And later, you can restore the original function with:
For more information, see the definitions of this mocking logic in
`testsupport.h`.
-### Okay but what should my tests actually do?
+## Okay but what should my tests actually do?
We talk above about "test coverage" -- making sure that your tests visit
every line of code, or every branch of code. But visiting the code isn't
@@ -382,8 +375,7 @@ Based on the implementation, we now see three more edge cases to test:
* Removing an element from the end of the list
* Removing an element from a position other than the end of the list.
-
-### What should my tests NOT do?
+## What should my tests NOT do?
Tests shouldn't require a network connection.
@@ -401,8 +393,7 @@ When possible, tests should not be over-fit to the implementation. That is,
the test should verify that the documented behavior is implemented, but
should not break if other permissible behavior is later implemented.
-
-### Advanced techniques: Namespaces
+## Advanced techniques: Namespaces
Sometimes, when you're doing a lot of mocking at once, it's convenient to
isolate your identifiers within a single namespace. If this were C++, we'd
@@ -414,9 +405,7 @@ them, you define `NS_MODULE` to a prefix to be used for your identifiers, and
then use other macros in place of identifier names. See `src/test/test.h` for
more documentation.
-
-Integration tests: Calling Tor from the outside
------------------------------------------------
+## Integration tests: Calling Tor from the outside
Some tests need to invoke Tor from the outside, and shouldn't run from the
same process as the Tor test program. Reasons for doing this might include:
@@ -436,8 +425,7 @@ wrapped, add a new shell script to `TESTS`, and the new program to
makefile (eg `${PYTHON}` for a python interpreter), then make sure that the
makefile exports them.
-Writing integration tests with Stem
------------------------------------
+## Writing integration tests with Stem
The 'stem' library includes extensive tests for the Tor controller protocol.
You can run stem tests from tor with `make test-stem`, or see
@@ -483,8 +471,7 @@ you notice any strange behaviour that seems totally unreasonable.
Check out the `test_exit_policy()` function in abovementioned file to see the
final implementation for this test.
-System testing with Chutney
----------------------------
+## System testing with Chutney
The 'chutney' program configures and launches a set of Tor relays,
authorities, and clients on your local host. It has a `test network`
diff --git a/doc/HACKING/android/Simpleperf.md b/doc/HACKING/android/Simpleperf.md
index 25f39a3d23..c7e63a7c86 100644
--- a/doc/HACKING/android/Simpleperf.md
+++ b/doc/HACKING/android/Simpleperf.md
@@ -95,4 +95,3 @@ was spend on the call.
Start Tor the normal way via Orbot and collect the logs from your computer using
$ adb logcat
-
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 9f428cb797..ba9b9bb5e0 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -760,6 +760,11 @@ forward slash (/) in the configuration file and on the command line.
This setting will be ignored for connections to the loopback
addresses (127.0.0.0/8 and ::1).
+[[OwningControllerProcess]] **{dbl_}OwningControllerProcess** __PID__::
+ Make Tor instance periodically check for presence of a controller process
+ with given PID and terminate itself if this process is no longer alive.
+ Polling interval is 15 seconds.
+
[[PerConnBWBurst]] **PerConnBWBurst** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**::
If this option is set manually, or via the "perconnbwburst" consensus
field, Tor will use it for separate rate limiting for each connection
@@ -1018,13 +1023,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)
-[[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
- from a new consensus or bridge config. When this option is set to 1,
- **ClientPreferIPv6ORPort** is ignored. (Default: 0) (DEPRECATED: This
- option is unreliable if a connection isn't reliably dual-stack.)
-
[[ClientBootstrapConsensusAuthorityDownloadInitialDelay]] **ClientBootstrapConsensusAuthorityDownloadInitialDelay** __N__::
Initial delay in seconds for when clients should download consensuses from authorities
if they are bootstrapping (that is, they don't have a usable, reasonably
@@ -2149,7 +2147,8 @@ is non-zero):
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)
+ enabled, it will be published as part of the extra-info document.
+ (Default: 1)
//Out of order because it logically belongs after BridgeRelay.
[[BridgeDistribution]] **BridgeDistribution** __string__::
@@ -2363,14 +2362,11 @@ is non-zero):
list itself, but it won't hurt if it does.) Do not list any bridge relay as it would
compromise its concealment. +
+
- When listing a node, it's better to list it by fingerprint than by
- nickname: fingerprints are more reliable. +
- +
If you run more than one relay, the MyFamily option on each relay
**must** list all other relays, as described above. +
+
Note: do not use MyFamily when configuring your Tor instance as a
- brigde.
+ bridge.
[[Nickname]] **Nickname** __name__::
Set the server's nickname to \'name'. Nicknames must be between 1 and 19
@@ -2618,7 +2614,7 @@ types of statistics that Tor relays collect and publish:
circuit) and writes them into disk every 24 hours. Onion router
operators may use the statistics for performance monitoring.
If ExtraInfoStatistics is enabled, it will published as part of
- extra-info document. (Default: 0)
+ the extra-info document. (Default: 0)
[[ConnDirectionStatistics]] **ConnDirectionStatistics** **0**|**1**::
Relays only.
@@ -2626,7 +2622,7 @@ types of statistics that Tor relays collect and publish:
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.
+ enabled, it will be published as part of the extra-info document.
(Default: 0)
[[DirReqStatistics]] **DirReqStatistics** **0**|**1**::
@@ -2636,7 +2632,7 @@ types of statistics that Tor relays collect and publish:
hours. Enables relay and bridge operators to monitor how much their
server is being used by clients to learn about Tor network.
If ExtraInfoStatistics is enabled, it will published as part of
- extra-info document. (Default: 1)
+ the extra-info document. (Default: 1)
[[EntryStatistics]] **EntryStatistics** **0**|**1**::
Relays only.
@@ -2645,7 +2641,7 @@ types of statistics that Tor relays collect and publish:
operators to monitor how much inbound traffic that originates from
Tor clients passes through their server to go further down the
Tor network. If ExtraInfoStatistics is enabled, it will be published
- as part of extra-info document. (Default: 0)
+ as part of the extra-info document. (Default: 0)
[[ExitPortStatistics]] **ExitPortStatistics** **0**|**1**::
Exit relays only.
@@ -2653,7 +2649,7 @@ types of statistics that Tor relays collect and publish:
relayed bytes and opened stream per exit port to disk every 24 hours.
Enables exit relay operators to measure and monitor amounts of traffic
that leaves Tor network through their exit node. If ExtraInfoStatistics
- is enabled, it will be published as part of extra-info document.
+ is enabled, it will be published as part of the extra-info document.
(Default: 0)
[[ExtraInfoStatistics]] **ExtraInfoStatistics** **0**|**1**::
@@ -2661,7 +2657,7 @@ types of statistics that Tor relays collect and publish:
its extra-info documents that it uploads to the directory authorities.
Disabling this option also removes bandwidth usage statistics, and
GeoIPFile and GeoIPv6File hashes from the extra-info file. Bridge
- ServerTransportPlugin lines are always includes in the extra-info file,
+ ServerTransportPlugin lines are always included in the extra-info file,
because they are required by BridgeDB.
(Default: 1)
@@ -2669,9 +2665,9 @@ types of statistics that Tor relays collect and publish:
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)
+ point, or rendezvous point to disk every 24 hours. If ExtraInfoStatistics
+ is enabled, it will be published as part of the extra-info document.
+ (Default: 1)
[[PaddingStatistics]] **PaddingStatistics** **0**|**1**::
Relays and bridges only.
@@ -2680,7 +2676,7 @@ types of statistics that Tor relays collect and publish:
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)
+ as a part of the extra-info document. (Default: 1)
== DIRECTORY SERVER OPTIONS
diff --git a/scripts/git/git-install-tools.sh b/scripts/git/git-install-tools.sh
new file mode 100755
index 0000000000..ef8623a018
--- /dev/null
+++ b/scripts/git/git-install-tools.sh
@@ -0,0 +1,189 @@
+#!/usr/bin/env bash
+
+SCRIPT_NAME=$(basename "$0")
+SCRIPTS_DIR=$(dirname "$0")
+
+TOOL_NAMES=(push-all pull-all merge-forward list-tor-branches)
+
+function usage()
+{
+ echo "$SCRIPT_NAME [-h] [-n] [-v] [-f] <all|hooks|tools|aliases>"
+ echo
+ echo " flags:"
+ echo " -h: show this help text"
+ echo " -n: dry-run"
+ echo " -v: verbose mode"
+ echo " -f: force-install even if \$TOR_DEVTOOLS_DIR looks fishy"
+ echo
+ echo " modes:"
+ echo " hooks: install git hooks in this repository."
+ echo " tools: install scripts in \$TOR_DEVTOOLS_DIR"
+ echo " aliases: set up global git aliases for git tools in \$TOR_DEVTOOLS_DIR"
+ echo " all: all of the above."
+}
+
+INSTALL_HOOKS=0
+INSTALL_TOOLS=0
+INSTALL_ALIASES=0
+
+DRY_RUN=0
+VERBOSE=0
+FORCE=0
+
+while getopts "hnfv" opt; do
+ case "$opt" in
+ h) usage
+ exit 0
+ ;;
+ n) DRY_RUN=1
+ ;;
+ v) VERBOSE=1
+ ;;
+ f) FORCE=1
+ ;;
+ *) echo
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+for item in "${@:$OPTIND}"; do
+ case "$item" in
+ hooks) INSTALL_HOOKS=1
+ ;;
+ tools) INSTALL_TOOLS=1
+ ;;
+ aliases) INSTALL_ALIASES=1
+ ;;
+ all) INSTALL_HOOKS=1
+ INSTALL_TOOLS=1
+ INSTALL_ALIASES=1
+ ;;
+ *) echo "Unrecognized mode '$item'"
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+if [[ $VERBOSE = 1 ]]; then
+ function note()
+ {
+ echo "$@"
+ }
+else
+ function note()
+ {
+ true
+ }
+fi
+
+function fail()
+{
+ echo "$@" 1>&2
+ exit 1
+}
+
+if [[ $INSTALL_HOOKS = 0 && $INSTALL_TOOLS = 0 && $INSTALL_ALIASES = 0 ]]; then
+ echo "Nothing to do. Try $SCRIPT_NAME -h for a list of commands."
+ exit 0
+fi
+
+if [[ $INSTALL_TOOLS = 1 || $INSTALL_ALIASES = 1 ]]; then
+ if [[ -z "$TOR_DEVTOOLS_DIR" ]] ; then
+ fail "\$TOR_DEVTOOLS_DIR was not set."
+ fi
+ note "Checking whether \$TOR_DEVTOOLS_DIR ($TOR_DEVTOOLS_DIR) is a git repo..."
+ GITDIR=$(cd "$TOR_DEVTOOLS_DIR" && git rev-parse --git-dir 2>/dev/null)
+ note "GITDIR is $GITDIR"
+ if [[ -n "$GITDIR" ]] ; then
+ cat <<EOF
+You have asked me to install to \$TOR_DEVTOOLS_DIR ($TOR_DEVTOOLS_DIR).
+That is inside a git repository, so you might not want to install there:
+depending on what you pull or push, you might find yourself giving somebody
+else write access to your scripts. I think you should just use ~/bin or
+something.
+EOF
+
+ echo
+ if [[ "$FORCE" = 1 ]] ; then
+ echo "I will install anyway, since you said '-f'."
+ else
+ echo "I will not install. You can tell me -f if you are really sure."
+ exit 1
+ fi
+ else
+ note "It was not."
+ fi
+fi
+
+if [[ ! -d "$SCRIPTS_DIR" || ! -e "$SCRIPTS_DIR/git-push-all.sh" ]]; then
+ fail "Couldn't find scripts in '$SCRIPTS_DIR'"
+fi
+
+if [[ $DRY_RUN = 1 ]]; then
+ echo "** DRY RUN **"
+ RUN="echo >>"
+else
+ RUN=
+fi
+
+set -e
+
+# ======================================================================
+if [[ $INSTALL_HOOKS = 1 ]]; then
+ HOOKS_DIR=$(git rev-parse --git-path hooks)
+
+ note "Looking for hooks directory"
+
+ if [[ -z "$HOOKS_DIR" || ! -d "$HOOKS_DIR" ]]; then
+ fail "Couldn't find git hooks directory."
+ fi
+
+ note "Found hooks directory in $HOOKS_DIR"
+
+ note "Installing hooks"
+ for fn in "$SCRIPTS_DIR"/*.git-hook; do
+ name=$(basename "$fn")
+ $RUN install --backup "$fn" "${HOOKS_DIR}/${name%.git-hook}"
+ done
+fi
+
+
+# ======================================================================
+if [[ $INSTALL_TOOLS = 1 ]]; then
+ note "Installing tools."
+ note "Looking for \$TOR_DEVTOOLS_DIR ($TOR_DEVTOOLS_DIR)"
+
+ if [[ ! -d "$TOR_DEVTOOLS_DIR" ]]; then
+ note "Creating directory"
+ $RUN mkdir -p "$TOR_DEVTOOLS_DIR"
+ fi
+
+ note "Copying scripts"
+ for tool in "${TOOL_NAMES[@]}"; do
+ $RUN install --backup "${SCRIPTS_DIR}/git-${tool}.sh" "${TOR_DEVTOOLS_DIR}/"
+ done
+fi
+
+# ======================================================================
+if [[ $INSTALL_ALIASES = 1 ]]; then
+ note "Installing aliases."
+ note "Looking for \$TOR_DEVTOOLS_DIR ($TOR_DEVTOOLS_DIR)"
+
+ note "Checking for ${TOR_DEVTOOLS_DIR}/git-push-all.sh"
+ if [[ ! -x "${TOR_DEVTOOLS_DIR}/git-push-all.sh" ]]; then
+ if [[ $DRY_RUN = 0 ]]; then
+ fail "Could not find scripts in \$TOR_DEVTOOLS_DIR"
+ fi
+ fi
+
+ note "Setting aliases"
+ for tool in "${TOOL_NAMES[@]}"; do
+ $RUN git config --global "alias.$tool" \!"${TOR_DEVTOOLS_DIR}/git-${tool}.sh"
+ done
+
+fi
+
+note Done.
diff --git a/scripts/git/git-list-tor-branches.sh b/scripts/git/git-list-tor-branches.sh
new file mode 100755
index 0000000000..d6b30f064f
--- /dev/null
+++ b/scripts/git/git-list-tor-branches.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+# Script to be used by other git scripts, and provide a single place
+# that lists our supported branches. To change which branches are
+# supported, look at the end of the file that says 'edit here'.
+
+SCRIPT_NAME=$(basename "$0")
+
+function usage()
+{
+ echo "$SCRIPT_NAME [-h] [-l|-s|-b|-m] [-R]"
+ echo
+ echo " arguments:"
+ echo " -h: show this help text"
+ echo
+ echo " -l: list the active tor branches (default)"
+ echo " -s: list the suffixes to be used with the active tor branches"
+ echo " -b: write bash code setting WORKTREE to an array of ( branch path ) arrays"
+ echo " -m: write bash code setting WORKTREE to an array of"
+ echo " ( branch parent path suffix parent_suffix ) arrays"
+ echo
+ echo " -R: omit release branches."
+}
+
+# list : just a list of branch names.
+# branch_path : For git-setup-dirs.sh and git-pull-all.sh
+# suffix: write a list of suffixes.
+# merge: branch, upstream, path, suffix, upstream suffix.
+mode="list"
+skip_release_branches="no"
+
+while getopts "hblmsR" opt ; do
+ case "$opt" in
+ h) usage
+ exit 0
+ ;;
+ b) mode="branch_path"
+ ;;
+ l) mode="list"
+ ;;
+ s) mode="suffix"
+ ;;
+ m) mode="merge"
+ ;;
+ R) skip_release_branches="yes"
+ ;;
+ *) echo "Unknown option"
+ exit 1
+ ;;
+ esac
+done
+
+all_branch_vars=()
+
+prev_maint_branch=""
+prev_maint_suffix=""
+
+branch() {
+ # The name of the branch. (Supplied by caller) Ex: maint-0.4.3
+ brname="$1"
+
+ # The name of the branch with no dots. Ex: maint-043
+ brname_nodots="${brname//./}"
+ # The name of the branch with no dots, and _ instead of -. Ex: maint_043
+ brname_nodots_uscore="${brname_nodots//-/_}"
+ # Name to use for a variable to represent the branch. Ex: MAINT_043
+ varname="${brname_nodots_uscore^^}"
+
+ is_maint="no"
+
+ # suffix: a suffix to place at the end of branches we generate with respect
+ # to this branch. Ex: _043
+
+ # location: where the branch can be found.
+
+ if [[ "$brname" == "master" ]]; then
+ suffix="_master"
+ location="\$GIT_PATH/\$TOR_MASTER_NAME"
+ elif [[ "$brname" =~ ^maint- ]]; then
+ suffix="_${brname_nodots#maint-}"
+ location="\$GIT_PATH/\$TOR_WKT_NAME/$brname"
+ is_maint="yes"
+ elif [[ "$brname" =~ ^release- ]]; then
+ suffix="_r${brname_nodots#release-}"
+ location="\$GIT_PATH/\$TOR_WKT_NAME/$brname"
+
+ if [[ "$skip_release_branches" = "yes" ]]; then
+ return
+ fi
+ else
+ echo "Unrecognized branch type '${brname}'" >&2
+ exit 1
+ fi
+
+ all_branch_vars+=("$varname")
+
+ # Now emit the per-branch information
+ if [[ "$mode" == "branch_path" ]]; then
+ echo "${varname}=( \"$brname\" \"$location\" )"
+ elif [[ "$mode" == "merge" ]]; then
+ echo "${varname}=( \"$brname\" \"$prev_maint_branch\" \"$location\" \"$suffix\" \"$prev_maint_suffix\" )"
+ elif [[ "$mode" == "list" ]]; then
+ echo "$brname"
+ elif [[ "$mode" == "suffix" ]]; then
+ echo "$suffix"
+ else
+ echo "unknown mode $mode" >&2
+ exit 1
+ fi
+
+ if [[ "$is_maint" == "yes" ]]; then
+ prev_maint_branch="$brname"
+ prev_maint_suffix="$suffix"
+ fi
+}
+
+finish() {
+ if [[ "$mode" == branch_path ]] || [[ "$mode" == merge ]]; then
+ echo "WORKTREE=("
+ for v in "${all_branch_vars[@]}"; do
+ echo " ${v}[@]"
+ done
+ echo ")"
+ elif [[ "$mode" == list ]] || [[ "$mode" == suffix ]]; then
+ # nothing to do
+ :
+ else
+ echo "unknown mode $mode" >&2
+ exit 1
+ fi
+}
+
+# ==============================
+# EDIT HERE
+# ==============================
+# List of all branches. These must be in order, from oldest to newest, with
+# maint before release.
+
+branch maint-0.3.5
+branch release-0.3.5
+
+branch maint-0.4.1
+branch release-0.4.1
+
+branch maint-0.4.2
+branch release-0.4.2
+
+branch maint-0.4.3
+branch release-0.4.3
+
+branch master
+
+finish
diff --git a/scripts/git/git-merge-forward.sh b/scripts/git/git-merge-forward.sh
index 247c605436..7c72f8478d 100755
--- a/scripts/git/git-merge-forward.sh
+++ b/scripts/git/git-merge-forward.sh
@@ -91,41 +91,11 @@ TOR_WKT_NAME=${TOR_WKT_NAME:-"tor-wkt"}
# But it's the earliest maint branch, so we don't merge forward into it.
# Since we don't merge forward into it, the second and fifth items must be
# blank ("").
-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_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_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_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
# from that repository.
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_041[0]}
-${MAINT_042[0]}
-${MAINT_043[0]}
-${MAINT_MASTER[0]}
-${RELEASE_035[0]}
-${RELEASE_041[0]}
-${RELEASE_042[0]}
-${RELEASE_043[0]}
-EOF
-
#######################
# Argument processing #
#######################
@@ -170,49 +140,16 @@ done
# Git worktrees to manage #
###########################
+set -e
if [ -z "$TEST_BRANCH_PREFIX" ]; then
-
# maint/release merge mode
- #
- # List of all worktrees to merge forward into. All defined above.
- # Ordering is important. Always the maint-* branch BEFORE the release-*.
- WORKTREE=(
- # We don't merge forward into MAINT_035_TB[@], because it's the earliest
- # maint branch
- RELEASE_035[@]
-
- MAINT_041[@]
- RELEASE_041[@]
-
- MAINT_042[@]
- RELEASE_042[@]
-
- MAINT_043[@]
- RELEASE_043[@]
-
- MAINT_MASTER[@]
- )
-
+ eval "$(git-list-tor-branches.sh -m)"
+ # Remove first element: we don't merge forward into it.
+ WORKTREE=( "${WORKTREE[@]:1}" )
else
-
- # Test branch mode: base test branches on maint branches only
- #
- # List of all worktrees to create test branches from. All defined above.
- # Ordering is important. All maint-* branches, including the earliest one.
- WORKTREE=(
- # We want a test branch based on the earliest maint branch
- MAINT_035_TB[@]
-
- MAINT_041[@]
-
- MAINT_042[@]
-
- MAINT_043[@]
-
- MAINT_MASTER[@]
- )
-
+ eval "$(git-list-tor-branches.sh -m -R)"
fi
+set +e
COUNT=${#WORKTREE[@]}
diff --git a/scripts/git/git-pull-all.sh b/scripts/git/git-pull-all.sh
index eb3e1c8881..7f82eda296 100755
--- a/scripts/git/git-pull-all.sh
+++ b/scripts/git/git-pull-all.sh
@@ -2,7 +2,7 @@
SCRIPT_NAME=$(basename "$0")
-function usage()
+usage()
{
echo "$SCRIPT_NAME [-h] [-n]"
echo
@@ -47,66 +47,15 @@ TOR_WKT_NAME=${TOR_WKT_NAME:-"tor-wkt"}
# Git branches to manage #
##########################
-# Configuration of the branches that need pulling. The values are in order:
-# (1) Branch name to pull (update).
-# (2) Full path of the git worktree.
-#
-# As an example:
-# $ cd <PATH/TO/WORKTREE> (3)
-# $ git checkout maint-0.3.5 (1)
-# $ git pull
-#
-# 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_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_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" )
+set -e
+eval "$(git-list-tor-branches.sh -b)"
+set +e
# 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
# from that repository.
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_041[0]}
-${MAINT_042[0]}
-${MAINT_043[0]}
-${MAINT_MASTER[0]}
-${RELEASE_035[0]}
-${RELEASE_041[0]}
-${RELEASE_042[0]}
-${RELEASE_043[0]}
-EOF
-
-###########################
-# Git worktrees to manage #
-###########################
-
-# List of all worktrees to pull. All defined above. Ordering is not important.
-WORKTREE=(
- MAINT_035[@]
- RELEASE_035[@]
-
- 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 cb7bb5269b..558ea8d01c 100755
--- a/scripts/git/git-push-all.sh
+++ b/scripts/git/git-push-all.sh
@@ -168,63 +168,42 @@ echo "Calling $GIT_PUSH" "$@" "<branches>"
# Git upstream remote branches #
################################
+set -e
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.3.5 \
- )
+ for br in $(git-list-tor-branches.sh -l); do
+ DEFAULT_UPSTREAM_BRANCHES="${DEFAULT_UPSTREAM_BRANCHES} ${DEFAULT_UPSTREAM_REMOTE}/${br}"
+ done
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.3.5 \
- )
+UPSTREAM_BRANCHES=
+for br in $(git-list-tor-branches.sh -l); do
+ UPSTREAM_BRANCHES="${UPSTREAM_BRANCHES} ${UPSTREAM_REMOTE}/${br}"
+done
########################
# Git branches to push #
########################
-PUSH_BRANCHES=$(echo \
- master \
- {release,maint}-0.4.3 \
- {release,maint}-0.4.2 \
- {release,maint}-0.4.1 \
- {release,maint}-0.3.5 \
- )
-
if [ -z "$TEST_BRANCH_PREFIX" ]; then
# maint/release push mode: push all branches.
#
# 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.3.5 \
- )
+ PUSH_BRANCHES="$(git-list-tor-branches.sh -l)"
else
# Test branch push mode: push test branches, based on each maint branch.
#
# 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}_035 \
- "
+ PUSH_BRANCHES=""
+ for suffix in $(git-list-tor-branches.sh -s -R); do
+ PUSH_BRANCHES="${PUSH_BRANCHES} ${TEST_BRANCH_PREFIX}${suffix}"
+ done
fi
+set +e
+
###############
# Entry point #
###############
diff --git a/scripts/git/git-setup-dirs.sh b/scripts/git/git-setup-dirs.sh
index 2d16cc1d66..1f61eb8b83 100755
--- a/scripts/git/git-setup-dirs.sh
+++ b/scripts/git/git-setup-dirs.sh
@@ -90,41 +90,15 @@ GITHUB_PUSH=${TOR_GITHUB_PUSH:-"No_Pushing_To_GitHub"}
# The branches and worktrees need to be modified when there is a new branch,
# and when an old branch is no longer supported.
-# Configuration of the branches that needs merging. The values are in order:
-# (0) current maint/release branch name
-# (1) Full path of the git worktree
-#
-# 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_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_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" )
+set -e
+eval "$(git-list-tor-branches.sh -b)"
+set +e
# 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
# from that repository.
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_041[0]}
-${MAINT_042[0]}
-${MAINT_043[0]}
-${MAINT_MASTER[0]}
-${RELEASE_035[0]}
-${RELEASE_041[0]}
-${RELEASE_042[0]}
-${RELEASE_043[0]}
-EOF
-
#######################
# Argument processing #
#######################
@@ -161,22 +135,6 @@ done
# Git worktrees to manage #
###########################
-WORKTREE=(
- MAINT_035[@]
- RELEASE_035[@]
-
- MAINT_041[@]
- RELEASE_041[@]
-
- MAINT_042[@]
- RELEASE_042[@]
-
- MAINT_043[@]
- RELEASE_043[@]
-
- MAINT_MASTER[@]
-)
-
COUNT=${#WORKTREE[@]}
#############
diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index b4ef1e51aa..f41a8f4c81 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -33,21 +33,21 @@
#
# Remember: It is better to fix the problem than to add a new exception!
-problem file-size /src/app/config/config.c 7400
+problem file-size /src/app/config/config.c 7527
problem include-count /src/app/config/config.c 80
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
+problem function-size /src/app/config/config.c:resolve_my_address() 191
+problem function-size /src/app/config/config.c:options_validate_cb() 794
problem function-size /src/app/config/config.c:options_init_from_torrc() 188
problem function-size /src/app/config/config.c:options_init_from_string() 103
problem function-size /src/app/config/config.c:options_init_logs() 125
problem function-size /src/app/config/config.c:parse_bridge_line() 104
-problem function-size /src/app/config/config.c:pt_parse_transport_line() 189
+problem function-size /src/app/config/config.c:pt_parse_transport_line() 190
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 1053
+problem file-size /src/app/config/or_options_st.h 1050
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
@@ -60,8 +60,8 @@ problem dependency-violation /src/core/crypto/onion_crypto.c 5
problem dependency-violation /src/core/crypto/onion_fast.c 1
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 file-size /src/core/mainloop/connection.c 5680
+problem include-count /src/core/mainloop/connection.c 65
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
@@ -74,7 +74,7 @@ problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143
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
+problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 107
problem function-size /src/core/mainloop/mainloop.c:run_connection_housekeeping() 123
problem dependency-violation /src/core/mainloop/mainloop.c 50
problem dependency-violation /src/core/mainloop/mainloop_pubsub.c 1
@@ -93,7 +93,7 @@ problem function-size /src/core/or/channeltls.c:channel_tls_process_versions_cel
problem function-size /src/core/or/channeltls.c:channel_tls_process_netinfo_cell() 214
problem function-size /src/core/or/channeltls.c:channel_tls_process_certs_cell() 246
problem function-size /src/core/or/channeltls.c:channel_tls_process_authenticate_cell() 202
-problem dependency-violation /src/core/or/channeltls.c 10
+problem dependency-violation /src/core/or/channeltls.c 11
problem include-count /src/core/or/circuitbuild.c 54
problem function-size /src/core/or/circuitbuild.c:get_unique_circ_id_by_chan() 128
problem function-size /src/core/or/circuitbuild.c:circuit_extend() 147
@@ -109,7 +109,7 @@ problem dependency-violation /src/core/or/circuitlist.h 1
problem function-size /src/core/or/circuitmux.c:circuitmux_set_policy() 109
problem function-size /src/core/or/circuitmux.c:circuitmux_attach_circuit() 113
problem dependency-violation /src/core/or/circuitmux_ewma.c 2
-problem file-size /src/core/or/circuitpadding.c 3098
+problem file-size /src/core/or/circuitpadding.c 3101
problem function-size /src/core/or/circuitpadding.c:circpad_machine_schedule_padding() 113
problem dependency-violation /src/core/or/circuitpadding.c 6
problem file-size /src/core/or/circuitpadding.h 813
@@ -118,7 +118,7 @@ problem function-size /src/core/or/circuitpadding_machines.c:circpad_machine_cli
problem dependency-violation /src/core/or/circuitpadding_machines.c 1
problem function-size /src/core/or/circuitstats.c:circuit_build_times_parse_state() 123
problem dependency-violation /src/core/or/circuitstats.c 11
-problem file-size /src/core/or/circuituse.c 3162
+problem file-size /src/core/or/circuituse.c 3195
problem function-size /src/core/or/circuituse.c:circuit_is_acceptable() 128
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
@@ -130,7 +130,7 @@ problem dependency-violation /src/core/or/circuituse.c 24
problem function-size /src/core/or/command.c:command_process_create_cell() 156
problem function-size /src/core/or/command.c:command_process_relay_cell() 132
problem dependency-violation /src/core/or/command.c 8
-problem file-size /src/core/or/connection_edge.c 4640
+problem file-size /src/core/or/connection_edge.c 4655
problem include-count /src/core/or/connection_edge.c 65
problem function-size /src/core/or/connection_edge.c:connection_ap_expire_beginning() 117
problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_rewrite() 193
@@ -142,23 +142,21 @@ problem function-size /src/core/or/connection_edge.c:connection_exit_begin_conn(
problem function-size /src/core/or/connection_edge.c:connection_exit_connect() 102
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 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 dependency-violation /src/core/or/connection_or.c 20
+problem dependency-violation /src/core/or/connection_or.c 21
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 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 3195
+problem file-size /src/core/or/policies.c 3182
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
@@ -173,7 +171,7 @@ problem dependency-violation /src/core/or/scheduler_kist.c 2
problem function-size /src/core/or/scheduler_vanilla.c:vanilla_scheduler_run() 109
problem dependency-violation /src/core/or/scheduler_vanilla.c 1
problem dependency-violation /src/core/or/sendme.c 2
-problem dependency-violation /src/core/or/status.c 12
+problem dependency-violation /src/core/or/status.c 13
problem function-size /src/core/or/versions.c:tor_version_parse() 104
problem dependency-violation /src/core/proto/proto_cell.c 3
problem dependency-violation /src/core/proto/proto_control0.c 1
@@ -182,53 +180,53 @@ problem dependency-violation /src/core/proto/proto_http.c 1
problem function-size /src/core/proto/proto_socks.c:parse_socks_client() 110
problem dependency-violation /src/core/proto/proto_socks.c 8
problem function-size /src/feature/client/addressmap.c:addressmap_rewrite() 109
-problem function-size /src/feature/client/bridges.c:rewrite_node_address_for_bridge() 126
+problem function-size /src/feature/client/bridges.c:rewrite_node_address_for_bridge() 125
problem function-size /src/feature/client/circpathbias.c:pathbias_measure_close_rate() 108
problem function-size /src/feature/client/dnsserv.c:evdns_server_callback() 153
-problem file-size /src/feature/client/entrynodes.c 3825
+problem file-size /src/feature/client/entrynodes.c 3827
problem function-size /src/feature/client/entrynodes.c:entry_guards_upgrade_waiting_circuits() 155
problem function-size /src/feature/client/entrynodes.c:entry_guard_parse_from_state() 246
problem file-size /src/feature/client/entrynodes.h 639
problem function-size /src/feature/client/transports.c:handle_proxy_line() 108
problem function-size /src/feature/client/transports.c:parse_method_line_helper() 110
-problem function-size /src/feature/client/transports.c:create_managed_proxy_environment() 109
+problem function-size /src/feature/client/transports.c:create_managed_proxy_environment() 111
problem function-size /src/feature/control/control.c:connection_control_process_inbuf() 113
problem function-size /src/feature/control/control_auth.c:handle_control_authenticate() 186
problem function-size /src/feature/control/control_cmd.c:handle_control_extendcircuit() 150
problem function-size /src/feature/control/control_cmd.c:handle_control_add_onion() 256
problem function-size /src/feature/control/control_cmd.c:add_onion_helper_keyarg() 118
problem function-size /src/feature/control/control_events.c:control_event_stream_status() 124
-problem include-count /src/feature/control/control_getinfo.c 54
+problem include-count /src/feature/control/control_getinfo.c 56
problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_misc() 108
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 4687
-problem include-count /src/feature/dirauth/dirvote.c 53
+problem file-size /src/feature/dirauth/dirvote.c 4734
+problem include-count /src/feature/dirauth/dirvote.c 55
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() 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_add_vote() 161
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() 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
problem function-size /src/feature/dirauth/shared_random.c:should_keep_commit() 109
-problem function-size /src/feature/dirauth/voteflags.c:dirserv_compute_performance_thresholds() 172
+problem function-size /src/feature/dirauth/voteflags.c:dirserv_compute_performance_thresholds() 175
problem function-size /src/feature/dircache/consdiffmgr.c:consdiffmgr_cleanup() 115
problem function-size /src/feature/dircache/consdiffmgr.c:consdiffmgr_rescan_flavor_() 111
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 3156
-problem include-count /src/feature/dirclient/dirclient.c 51
+problem file-size /src/feature/dirclient/dirclient.c 3204
+problem include-count /src/feature/dirclient/dirclient.c 54
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
problem function-size /src/feature/dirclient/dirclient.c:directory_send_command() 239
problem function-size /src/feature/dirclient/dirclient.c:dir_client_decompress_response_body() 111
-problem function-size /src/feature/dirclient/dirclient.c:connection_dir_client_reached_eof() 189
+problem function-size /src/feature/dirclient/dirclient.c:connection_dir_client_reached_eof() 199
problem function-size /src/feature/dirclient/dirclient.c:handle_response_fetch_consensus() 104
problem function-size /src/feature/dircommon/consdiff.c:gen_ed_diff() 203
problem function-size /src/feature/dircommon/consdiff.c:apply_ed_diff() 158
@@ -237,50 +235,49 @@ problem function-size /src/feature/dirparse/ns_parse.c:routerstatus_parse_entry_
problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_verify_bw_weights() 389
problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_parse_vote_from_string() 635
problem function-size /src/feature/dirparse/parsecommon.c:tokenize_string() 101
-problem function-size /src/feature/dirparse/parsecommon.c:get_next_token() 158
+problem function-size /src/feature/dirparse/parsecommon.c:get_next_token() 165
problem function-size /src/feature/dirparse/routerparse.c:router_parse_entry_from_string() 554
problem function-size /src/feature/dirparse/routerparse.c:extrainfo_parse_entry_from_string() 208
problem function-size /src/feature/hibernate/hibernate.c:accounting_parse_options() 109
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_cell.c:hs_cell_parse_introduce2() 134
+problem function-size /src/feature/hs/hs_client.c:send_introduce1() 108
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
-problem function-size /src/feature/hs/hs_descriptor.c:desc_encode_v3() 101
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 4131
+problem file-size /src/feature/hs/hs_service.c 4247
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() 158
problem function-size /src/feature/nodelist/microdesc.c:microdesc_cache_rebuild() 134
-problem include-count /src/feature/nodelist/networkstatus.c 63
+problem include-count /src/feature/nodelist/networkstatus.c 65
problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_check_consensus_signature() 175
problem function-size /src/feature/nodelist/networkstatus.c:networkstatus_set_current_consensus() 289
problem function-size /src/feature/nodelist/node_select.c:router_pick_directory_server_impl() 122
-problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 203
+problem function-size /src/feature/nodelist/node_select.c:compute_weighted_bandwidths() 204
problem function-size /src/feature/nodelist/node_select.c:router_pick_trusteddirserver_impl() 112
problem function-size /src/feature/nodelist/nodelist.c:compute_frac_paths_available() 190
-problem file-size /src/feature/nodelist/routerlist.c 3239
+problem file-size /src/feature/nodelist/routerlist.c 3247
problem function-size /src/feature/nodelist/routerlist.c:router_rebuild_store() 148
problem function-size /src/feature/nodelist/routerlist.c:router_add_to_routerlist() 168
problem function-size /src/feature/nodelist/routerlist.c:routerlist_remove_old_routers() 121
-problem function-size /src/feature/nodelist/routerlist.c:update_consensus_router_descriptor_downloads() 135
+problem function-size /src/feature/nodelist/routerlist.c:update_consensus_router_descriptor_downloads() 142
problem function-size /src/feature/nodelist/routerlist.c:update_extrainfo_downloads() 103
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 file-size /src/feature/relay/router.c 3600
problem include-count /src/feature/relay/router.c 57
-problem function-size /src/feature/relay/router.c:init_keys() 252
+problem function-size /src/feature/relay/router.c:init_keys() 254
problem function-size /src/feature/relay/router.c:get_my_declared_family() 114
-problem function-size /src/feature/relay/router.c:router_build_fresh_unsigned_routerinfo() 136
-problem function-size /src/feature/relay/router.c:router_dump_router_to_string() 367
+problem function-size /src/feature/relay/router.c:router_build_fresh_unsigned_routerinfo() 113
+problem function-size /src/feature/relay/router.c:router_dump_router_to_string() 372
problem function-size /src/feature/relay/routerkeys.c:load_ed_keys() 294
problem function-size /src/feature/rend/rendcache.c:rend_cache_store_v2_desc_as_client() 190
problem function-size /src/feature/rend/rendclient.c:rend_client_send_introduction() 219
@@ -315,7 +312,6 @@ problem function-size /src/lib/net/address.c:tor_addr_parse_mask_ports() 194
problem function-size /src/lib/net/address.c:tor_addr_compare_masked() 110
problem function-size /src/lib/net/inaddr.c:tor_inet_pton() 107
problem function-size /src/lib/net/socketpair.c:tor_ersatz_socketpair() 102
-problem function-size /src/lib/osinfo/uname.c:get_uname() 116
problem function-size /src/lib/process/process_unix.c:process_unix_exec() 213
problem function-size /src/lib/process/process_win32.c:process_win32_exec() 151
problem function-size /src/lib/process/process_win32.c:process_win32_create_pipe() 109
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 9d5344838a..4becae4756 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -366,7 +366,7 @@ static const config_var_t option_vars_[] = {
#endif /* defined(HAVE_MODULE_RELAY) || defined(TOR_UNIT_TESTS) */
V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"),
V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"),
- V(ClientAutoIPv6ORPort, BOOL, "0"),
+ OBSOLETE("ClientAutoIPv6ORPort"),
V(ClientRejectInternalAddresses, BOOL, "1"),
V(ClientTransportPlugin, LINELIST, NULL),
V(ClientUseIPv6, BOOL, "0"),
@@ -825,9 +825,6 @@ static char *get_windows_conf_root(void);
static int options_check_transition_cb(const void *old,
const void *new,
char **msg);
-static int parse_ports(or_options_t *options, int validate_only,
- char **msg_out, int *n_ports_out,
- int *world_writable_control_socket);
static int validate_data_directories(or_options_t *options);
static int write_configuration_file(const char *fname,
const or_options_t *options);
@@ -2908,7 +2905,8 @@ resolve_my_address(int warn_severity, const or_options_t *options,
/* make sure we're ok with publishing an internal IP */
if (using_default_dir_authorities(options)) {
/* if they are using the default authorities, disallow internal IPs
- * always. */
+ * always. For IPv6 ORPorts, this check is done in
+ * router_get_advertised_ipv6_or_ap(). See #33681. */
log_fn(warn_severity, LD_CONFIG,
"Address '%s' resolves to private IP address '%s'. "
"Tor servers that use the default DirAuthorities must have "
@@ -5880,18 +5878,28 @@ parse_dir_fallback_line(const char *line,
return r;
}
-/** Allocate and return a new port_cfg_t with reasonable defaults. */
+/** Allocate and return a new port_cfg_t with reasonable defaults.
+ *
+ * <b>namelen</b> is the length of the unix socket name
+ * (typically the filesystem path), not including the trailing NUL.
+ * It should be 0 for ports that are not zunix sockets. */
port_cfg_t *
port_cfg_new(size_t namelen)
{
tor_assert(namelen <= SIZE_T_CEILING - sizeof(port_cfg_t) - 1);
port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t) + namelen + 1);
+
+ /* entry_cfg flags */
cfg->entry_cfg.ipv4_traffic = 1;
cfg->entry_cfg.ipv6_traffic = 1;
cfg->entry_cfg.prefer_ipv6 = 1;
cfg->entry_cfg.dns_request = 1;
cfg->entry_cfg.onion_traffic = 1;
cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
+ cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
+ cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
+
+ /* Other flags default to 0 due to tor_malloc_zero */
return cfg;
}
@@ -6000,7 +6008,7 @@ port_cfg_line_extract_addrport(const char *line,
size_t sz;
*is_unix_out = 1;
*addrport_out = NULL;
- line += strlen(unix_socket_prefix); /*No q: Keep the quote */
+ line += strlen(unix_socket_prefix); /* No 'unix:', but keep the quote */
*rest_out = unescape_string(line, addrport_out, &sz);
if (!*rest_out || (*addrport_out && sz != strlen(*addrport_out))) {
tor_free(*addrport_out);
@@ -6095,11 +6103,12 @@ port_parse_config(smartlist_t *out,
const unsigned is_unix_socket = flags & CL_PORT_IS_UNIXSOCKET;
int got_zero_port=0, got_nonzero_port=0;
char *unix_socket_path = NULL;
+ port_cfg_t *cfg = NULL;
/* If there's no FooPort, then maybe make a default one. */
if (! ports) {
if (defaultport && defaultaddr && out) {
- port_cfg_t *cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
+ cfg = port_cfg_new(is_unix_socket ? strlen(defaultaddr) : 0);
cfg->type = listener_type;
if (is_unix_socket) {
tor_addr_make_unspec(&cfg->addr);
@@ -6109,8 +6118,6 @@ port_parse_config(smartlist_t *out,
cfg->port = defaultport;
tor_addr_parse(&cfg->addr, defaultaddr);
}
- cfg->entry_cfg.session_group = SESSION_GROUP_UNSET;
- cfg->entry_cfg.isolation_flags = ISO_DEFAULT;
smartlist_add(out, cfg);
}
return 0;
@@ -6124,28 +6131,12 @@ port_parse_config(smartlist_t *out,
for (; ports; ports = ports->next) {
tor_addr_t addr;
tor_addr_make_unspec(&addr);
-
- int port;
- int sessiongroup = SESSION_GROUP_UNSET;
- unsigned isolation = ISO_DEFAULT;
- int prefer_no_auth = 0;
- int socks_iso_keep_alive = 0;
-
+ int port, ok,
+ has_used_unix_socket_only_option = 0,
+ is_unix_tagged_addr = 0;
uint16_t ptmp=0;
- int ok;
- /* This must be kept in sync with port_cfg_new's defaults */
- int no_listen = 0, no_advertise = 0, all_addrs = 0,
- bind_ipv4_only = 0, bind_ipv6_only = 0,
- ipv4_traffic = 1, ipv6_traffic = 1, prefer_ipv6 = 1, dns_request = 1,
- onion_traffic = 1,
- cache_ipv4 = 0, use_cached_ipv4 = 0,
- cache_ipv6 = 0, use_cached_ipv6 = 0,
- prefer_ipv6_automap = 1, world_writable = 0, group_writable = 0,
- relax_dirmode_check = 0,
- has_used_unix_socket_only_option = 0, extended_errors = 0;
-
- int is_unix_tagged_addr = 0;
const char *rest_of_line = NULL;
+
if (port_cfg_line_extract_addrport(ports->value,
&addrport, &is_unix_tagged_addr, &rest_of_line)<0) {
log_warn(LD_CONFIG, "Invalid %sPort line with unparsable address",
@@ -6221,17 +6212,20 @@ port_parse_config(smartlist_t *out,
}
}
+ /* Default port_cfg_t object initialization */
+ cfg = port_cfg_new(unix_socket_path ? strlen(unix_socket_path) : 0);
+
if (unix_socket_path && default_to_group_writable)
- group_writable = 1;
+ cfg->is_group_writable = 1;
/* Now parse the rest of the options, if any. */
if (use_server_options) {
/* This is a server port; parse advertising options */
SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
if (!strcasecmp(elt, "NoAdvertise")) {
- no_advertise = 1;
+ cfg->server_cfg.no_advertise = 1;
} else if (!strcasecmp(elt, "NoListen")) {
- no_listen = 1;
+ cfg->server_cfg.no_listen = 1;
#if 0
/* not implemented yet. */
} else if (!strcasecmp(elt, "AllAddrs")) {
@@ -6239,33 +6233,36 @@ port_parse_config(smartlist_t *out,
all_addrs = 1;
#endif /* 0 */
} else if (!strcasecmp(elt, "IPv4Only")) {
- bind_ipv4_only = 1;
+ cfg->server_cfg.bind_ipv4_only = 1;
} else if (!strcasecmp(elt, "IPv6Only")) {
- bind_ipv6_only = 1;
+ cfg->server_cfg.bind_ipv6_only = 1;
} else {
log_warn(LD_CONFIG, "Unrecognized %sPort option '%s'",
portname, escaped(elt));
}
} SMARTLIST_FOREACH_END(elt);
- if (no_advertise && no_listen) {
+ if (cfg->server_cfg.no_advertise && cfg->server_cfg.no_listen) {
log_warn(LD_CONFIG, "Tried to set both NoListen and NoAdvertise "
"on %sPort line '%s'",
portname, escaped(ports->value));
goto err;
}
- if (bind_ipv4_only && bind_ipv6_only) {
+ if (cfg->server_cfg.bind_ipv4_only &&
+ cfg->server_cfg.bind_ipv6_only) {
log_warn(LD_CONFIG, "Tried to set both IPv4Only and IPv6Only "
"on %sPort line '%s'",
portname, escaped(ports->value));
goto err;
}
- if (bind_ipv4_only && tor_addr_family(&addr) != AF_INET) {
+ if (cfg->server_cfg.bind_ipv4_only &&
+ tor_addr_family(&addr) != AF_INET) {
log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv4",
portname);
goto err;
}
- if (bind_ipv6_only && tor_addr_family(&addr) != AF_INET6) {
+ if (cfg->server_cfg.bind_ipv6_only &&
+ tor_addr_family(&addr) != AF_INET6) {
log_warn(LD_CONFIG, "Could not interpret %sPort address as IPv6",
portname);
goto err;
@@ -6284,12 +6281,12 @@ port_parse_config(smartlist_t *out,
portname, escaped(elt));
goto err;
}
- if (sessiongroup >= 0) {
+ if (cfg->entry_cfg.session_group >= 0) {
log_warn(LD_CONFIG, "Multiple SessionGroup options on %sPort",
portname);
goto err;
}
- sessiongroup = group;
+ cfg->entry_cfg.session_group = group;
continue;
}
@@ -6299,15 +6296,15 @@ port_parse_config(smartlist_t *out,
}
if (!strcasecmp(elt, "GroupWritable")) {
- group_writable = !no;
+ cfg->is_group_writable = !no;
has_used_unix_socket_only_option = 1;
continue;
} else if (!strcasecmp(elt, "WorldWritable")) {
- world_writable = !no;
+ cfg->is_world_writable = !no;
has_used_unix_socket_only_option = 1;
continue;
} else if (!strcasecmp(elt, "RelaxDirModeCheck")) {
- relax_dirmode_check = !no;
+ cfg->relax_dirmode_check = !no;
has_used_unix_socket_only_option = 1;
continue;
}
@@ -6320,19 +6317,19 @@ port_parse_config(smartlist_t *out,
if (takes_hostnames) {
if (!strcasecmp(elt, "IPv4Traffic")) {
- ipv4_traffic = ! no;
+ cfg->entry_cfg.ipv4_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "IPv6Traffic")) {
- ipv6_traffic = ! no;
+ cfg->entry_cfg.ipv6_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "PreferIPv6")) {
- prefer_ipv6 = ! no;
+ cfg->entry_cfg.prefer_ipv6 = ! no;
continue;
} else if (!strcasecmp(elt, "DNSRequest")) {
- dns_request = ! no;
+ cfg->entry_cfg.dns_request = ! no;
continue;
} else if (!strcasecmp(elt, "OnionTraffic")) {
- onion_traffic = ! no;
+ cfg->entry_cfg.onion_traffic = ! no;
continue;
} else if (!strcasecmp(elt, "OnionTrafficOnly")) {
/* Only connect to .onion addresses. Equivalent to
@@ -6343,46 +6340,50 @@ port_parse_config(smartlist_t *out,
"DNSRequest, IPv4Traffic, and/or IPv6Traffic instead.",
portname, escaped(elt));
} else {
- ipv4_traffic = ipv6_traffic = dns_request = 0;
+ cfg->entry_cfg.ipv4_traffic = 0;
+ cfg->entry_cfg.ipv6_traffic = 0;
+ cfg->entry_cfg.dns_request = 0;
}
continue;
}
}
if (!strcasecmp(elt, "CacheIPv4DNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv4 = ! no;
+ cfg->entry_cfg.cache_ipv4_answers = ! no;
continue;
} else if (!strcasecmp(elt, "CacheIPv6DNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv6 = ! no;
+ cfg->entry_cfg.cache_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "CacheDNS")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- cache_ipv4 = cache_ipv6 = ! no;
+ cfg->entry_cfg.cache_ipv4_answers = ! no;
+ cfg->entry_cfg.cache_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseIPv4Cache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv4 = ! no;
+ cfg->entry_cfg.use_cached_ipv4_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseIPv6Cache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv6 = ! no;
+ cfg->entry_cfg.use_cached_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "UseDNSCache")) {
warn_client_dns_cache(elt, no); // since 0.2.9.2-alpha
- use_cached_ipv4 = use_cached_ipv6 = ! no;
+ cfg->entry_cfg.use_cached_ipv4_answers = ! no;
+ cfg->entry_cfg.use_cached_ipv6_answers = ! no;
continue;
} else if (!strcasecmp(elt, "PreferIPv6Automap")) {
- prefer_ipv6_automap = ! no;
+ cfg->entry_cfg.prefer_ipv6_virtaddr = ! no;
continue;
} else if (!strcasecmp(elt, "PreferSOCKSNoAuth")) {
- prefer_no_auth = ! no;
+ cfg->entry_cfg.socks_prefer_no_auth = ! no;
continue;
} else if (!strcasecmp(elt, "KeepAliveIsolateSOCKSAuth")) {
- socks_iso_keep_alive = ! no;
+ cfg->entry_cfg.socks_iso_keep_alive = ! no;
continue;
} else if (!strcasecmp(elt, "ExtendedErrors")) {
- extended_errors = ! no;
+ cfg->entry_cfg.extended_socks5_codes = ! no;
continue;
}
@@ -6405,9 +6406,9 @@ port_parse_config(smartlist_t *out,
}
if (no) {
- isolation &= ~isoflag;
+ cfg->entry_cfg.isolation_flags &= ~isoflag;
} else {
- isolation |= isoflag;
+ cfg->entry_cfg.isolation_flags |= isoflag;
}
} SMARTLIST_FOREACH_END(elt);
}
@@ -6417,51 +6418,51 @@ port_parse_config(smartlist_t *out,
else
got_zero_port = 1;
- if (dns_request == 0 && listener_type == CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.dns_request == 0 &&
+ listener_type == CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with DNS disabled; that "
"won't work.", portname);
goto err;
}
-
- if (ipv4_traffic == 0 && ipv6_traffic == 0 && onion_traffic == 0
- && listener_type != CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.ipv4_traffic == 0 &&
+ cfg->entry_cfg.ipv6_traffic == 0 &&
+ cfg->entry_cfg.onion_traffic == 0 &&
+ listener_type != CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with all of IPv4 and "
"IPv6 and .onion disabled; that won't work.", portname);
goto err;
}
-
- if (dns_request == 1 && ipv4_traffic == 0 && ipv6_traffic == 0
- && listener_type != CONN_TYPE_AP_DNS_LISTENER) {
+ if (cfg->entry_cfg.dns_request == 1 &&
+ cfg->entry_cfg.ipv4_traffic == 0 &&
+ cfg->entry_cfg.ipv6_traffic == 0 &&
+ listener_type != CONN_TYPE_AP_DNS_LISTENER) {
log_warn(LD_CONFIG, "You have a %sPort entry with DNSRequest enabled, "
"but IPv4 and IPv6 disabled; DNS-based sites won't work.",
portname);
goto err;
}
-
if ( has_used_unix_socket_only_option && ! unix_socket_path) {
log_warn(LD_CONFIG, "You have a %sPort entry with GroupWritable, "
"WorldWritable, or RelaxDirModeCheck, but it is not a "
"unix socket.", portname);
goto err;
}
-
- if (!(isolation & ISO_SOCKSAUTH) && socks_iso_keep_alive) {
+ if (!(cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH) &&
+ cfg->entry_cfg.socks_iso_keep_alive) {
log_warn(LD_CONFIG, "You have a %sPort entry with both "
"NoIsolateSOCKSAuth and KeepAliveIsolateSOCKSAuth set.",
portname);
goto err;
}
-
- if (unix_socket_path && (isolation & ISO_CLIENTADDR)) {
+ if (unix_socket_path &&
+ (cfg->entry_cfg.isolation_flags & ISO_CLIENTADDR)) {
/* `IsolateClientAddr` is nonsensical in the context of AF_LOCAL.
* just silently remove the isolation flag.
*/
- isolation &= ~ISO_CLIENTADDR;
+ cfg->entry_cfg.isolation_flags &= ~ISO_CLIENTADDR;
}
-
if (out && port) {
size_t namelen = unix_socket_path ? strlen(unix_socket_path) : 0;
- port_cfg_t *cfg = port_cfg_new(namelen);
if (unix_socket_path) {
tor_addr_make_unspec(&cfg->addr);
memcpy(cfg->unix_addr, unix_socket_path, namelen + 1);
@@ -6472,33 +6473,13 @@ port_parse_config(smartlist_t *out,
cfg->port = port;
}
cfg->type = listener_type;
- cfg->is_world_writable = world_writable;
- cfg->is_group_writable = group_writable;
- cfg->relax_dirmode_check = relax_dirmode_check;
- cfg->entry_cfg.isolation_flags = isolation;
- cfg->entry_cfg.session_group = sessiongroup;
- cfg->server_cfg.no_advertise = no_advertise;
- cfg->server_cfg.no_listen = no_listen;
- cfg->server_cfg.all_addrs = all_addrs;
- cfg->server_cfg.bind_ipv4_only = bind_ipv4_only;
- cfg->server_cfg.bind_ipv6_only = bind_ipv6_only;
- cfg->entry_cfg.ipv4_traffic = ipv4_traffic;
- cfg->entry_cfg.ipv6_traffic = ipv6_traffic;
- cfg->entry_cfg.prefer_ipv6 = prefer_ipv6;
- cfg->entry_cfg.dns_request = dns_request;
- cfg->entry_cfg.onion_traffic = onion_traffic;
- cfg->entry_cfg.cache_ipv4_answers = cache_ipv4;
- cfg->entry_cfg.cache_ipv6_answers = cache_ipv6;
- cfg->entry_cfg.use_cached_ipv4_answers = use_cached_ipv4;
- cfg->entry_cfg.use_cached_ipv6_answers = use_cached_ipv6;
- cfg->entry_cfg.prefer_ipv6_virtaddr = prefer_ipv6_automap;
- cfg->entry_cfg.socks_prefer_no_auth = prefer_no_auth;
- if (! (isolation & ISO_SOCKSAUTH))
+ if (! (cfg->entry_cfg.isolation_flags & ISO_SOCKSAUTH))
cfg->entry_cfg.socks_prefer_no_auth = 1;
- cfg->entry_cfg.socks_iso_keep_alive = socks_iso_keep_alive;
- cfg->entry_cfg.extended_socks5_codes = extended_errors;
-
smartlist_add(out, cfg);
+ /* out owns cfg now, don't re-use or free it */
+ cfg = NULL;
+ } else {
+ tor_free(cfg);
}
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
smartlist_clear(elts);
@@ -6524,10 +6505,22 @@ port_parse_config(smartlist_t *out,
retval = 0;
err:
+ /* There are two ways we can error out:
+ * 1. part way through the loop: cfg needs to be freed;
+ * 2. ending the loop normally: cfg is always NULL.
+ * In this case, cfg has either been:
+ * - added to out, then set to NULL, or
+ * - freed and set to NULL (because out is NULL, or port is 0).
+ */
+ tor_free(cfg);
+
+ /* Free the other variables from the loop.
+ * elts is always non-NULL here, but it may or may not be empty. */
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
smartlist_free(elts);
tor_free(unix_socket_path);
tor_free(addrport);
+
return retval;
}
@@ -6559,7 +6552,7 @@ port_count_real_listeners(const smartlist_t *ports, int listenertype,
* If <b>validate_only</b> is false, set configured_client_ports to the
* new list of ports parsed from <b>options</b>.
**/
-static int
+STATIC int
parse_ports(or_options_t *options, int validate_only,
char **msg, int *n_ports_out,
int *world_writable_control_socket)
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 04d877e9da..311e27917a 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -319,6 +319,10 @@ int options_validate(const or_options_t *old_options,
char **msg);
#endif
+STATIC int parse_ports(or_options_t *options, int validate_only,
+ char **msg, int *n_ports_out,
+ int *world_writable_control_socket);
+
#endif /* defined(CONFIG_PRIVATE) */
#endif /* !defined(TOR_CONFIG_H) */
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 35ba15a9e2..bf58205f89 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -662,9 +662,6 @@ struct or_options_t {
* accessing this value directly. */
int ClientPreferIPv6DirPort;
- /** If true, prefer an IPv4 or IPv6 OR port at random. */
- int ClientAutoIPv6ORPort;
-
/** The length of time that we think a consensus should be fresh. */
int V3AuthVotingInterval;
/** The length of time we think it will take to distribute votes. */
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 4965c2a1f4..9602978458 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -1514,10 +1514,11 @@ connection_listener_new(const struct sockaddr *listensockaddr,
}
}
+ /* Force IPv4 and IPv6 traffic on for non-SOCKSPorts.
+ * Forcing options on isn't a good idea, see #32994 and #33607. */
if (type != CONN_TYPE_AP_LISTENER) {
lis_conn->entry_cfg.ipv4_traffic = 1;
lis_conn->entry_cfg.ipv6_traffic = 1;
- lis_conn->entry_cfg.prefer_ipv6 = 1;
}
if (connection_add(conn) < 0) { /* no space, forget it */
diff --git a/src/core/or/addr_policy_st.h b/src/core/or/addr_policy_st.h
index 5a2b7f6fb3..08d16ee616 100644
--- a/src/core/or/addr_policy_st.h
+++ b/src/core/or/addr_policy_st.h
@@ -38,7 +38,7 @@ struct addr_policy_t {
/** Base address to accept or reject.
*
* Note that wildcards are treated
- * differntly depending on address family. An AF_UNSPEC address means
+ * differently depending on address family. An AF_UNSPEC address means
* "All addresses, IPv4 or IPv6." An AF_INET address with maskbits==0 means
* "All IPv4 addresses" and an AF_INET6 address with maskbits == 0 means
* "All IPv6 addresses".
diff --git a/src/core/or/channel.c b/src/core/or/channel.c
index ce1c31914c..160ab587f5 100644
--- a/src/core/or/channel.c
+++ b/src/core/or/channel.c
@@ -1859,7 +1859,7 @@ channel_do_open_actions(channel_t *chan)
tor_free(transport_name);
/* Notify the DoS subsystem of a new client. */
if (tlschan && tlschan->conn) {
- dos_new_client_conn(tlschan->conn);
+ dos_new_client_conn(tlschan->conn, transport_name);
}
}
/* Otherwise the underlying transport can't tell us this, so skip it */
diff --git a/src/core/or/circuitmux_ewma.c b/src/core/or/circuitmux_ewma.c
index b50f33528f..0dcd22e8a7 100644
--- a/src/core/or/circuitmux_ewma.c
+++ b/src/core/or/circuitmux_ewma.c
@@ -423,7 +423,7 @@ ewma_cmp_cmux(circuitmux_t *cmux_1, circuitmux_policy_data_t *pol_data_1,
/* Pick whichever one has the better best circuit */
return compare_cell_ewma_counts(ce1, ce2);
} else {
- if (ce1 != NULL ) {
+ if (ce1 != NULL) {
/* We only have a circuit on cmux_1, so prefer it */
return -1;
} else if (ce2 != NULL) {
@@ -609,7 +609,7 @@ cmux_ewma_set_options(const or_options_t *options,
/* convert halflife into halflife-per-tick. */
halflife /= EWMA_TICK_LEN;
/* compute per-tick scale factor. */
- ewma_scale_factor = exp( LOG_ONEHALF / halflife );
+ ewma_scale_factor = exp(LOG_ONEHALF / halflife);
log_info(LD_OR,
"Enabled cell_ewma algorithm because of value in %s; "
"scale factor is %f per %d seconds",
diff --git a/src/core/or/circuitpadding.c b/src/core/or/circuitpadding.c
index 3853e9fdc4..43f4a31624 100644
--- a/src/core/or/circuitpadding.c
+++ b/src/core/or/circuitpadding.c
@@ -2446,9 +2446,12 @@ circpad_setup_machine_on_circ(circuit_t *on_circ,
return;
}
- tor_assert_nonfatal(on_circ->padding_machine[machine->machine_index]
- == NULL);
- tor_assert_nonfatal(on_circ->padding_info[machine->machine_index] == NULL);
+ IF_BUG_ONCE(on_circ->padding_machine[machine->machine_index] != NULL) {
+ return;
+ }
+ IF_BUG_ONCE(on_circ->padding_info[machine->machine_index] != NULL) {
+ return;
+ }
/* Log message */
if (CIRCUIT_IS_ORIGIN(on_circ)) {
diff --git a/src/core/or/dos.c b/src/core/or/dos.c
index be64b6286e..5f99280030 100644
--- a/src/core/or/dos.c
+++ b/src/core/or/dos.c
@@ -680,7 +680,7 @@ dos_log_heartbeat(void)
/* Called when a new client connection has been established on the given
* address. */
void
-dos_new_client_conn(or_connection_t *or_conn)
+dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
{
clientmap_entry_t *entry;
@@ -701,7 +701,7 @@ dos_new_client_conn(or_connection_t *or_conn)
}
/* We are only interested in client connection from the geoip cache. */
- entry = geoip_lookup_client(&or_conn->real_addr, NULL,
+ entry = geoip_lookup_client(&or_conn->real_addr, transport_name,
GEOIP_CLIENT_CONNECT);
if (BUG(entry == NULL)) {
/* Should never happen because we note down the address in the geoip
diff --git a/src/core/or/dos.h b/src/core/or/dos.h
index b7b1d3f635..b3eca058b8 100644
--- a/src/core/or/dos.h
+++ b/src/core/or/dos.h
@@ -53,7 +53,8 @@ int dos_enabled(void);
void dos_log_heartbeat(void);
void dos_geoip_entry_about_to_free(const struct clientmap_entry_t *geoip_ent);
-void dos_new_client_conn(or_connection_t *or_conn);
+void dos_new_client_conn(or_connection_t *or_conn,
+ const char *transport_name);
void dos_close_client_conn(const or_connection_t *or_conn);
int dos_should_refuse_single_hop_client(void);
diff --git a/src/core/or/policies.c b/src/core/or/policies.c
index 4ac598fce3..dd4feaadfc 100644
--- a/src/core/or/policies.c
+++ b/src/core/or/policies.c
@@ -463,8 +463,7 @@ fascist_firewall_use_ipv6(const or_options_t *options)
* ClientPreferIPv6DirPort is deprecated, but check it anyway. */
return (options->ClientUseIPv6 == 1 || options->ClientUseIPv4 == 0 ||
options->ClientPreferIPv6ORPort == 1 ||
- options->ClientPreferIPv6DirPort == 1 || options->UseBridges == 1 ||
- options->ClientAutoIPv6ORPort == 1);
+ options->ClientPreferIPv6DirPort == 1 || options->UseBridges == 1);
}
/** Do we prefer to connect to IPv6, ignoring ClientPreferIPv6ORPort and
@@ -491,15 +490,6 @@ fascist_firewall_prefer_ipv6_impl(const or_options_t *options)
return -1;
}
-/* Choose whether we prefer IPv4 or IPv6 by randomly choosing an address
- * family. Return 0 for IPv4, and 1 for IPv6. */
-MOCK_IMPL(int,
-fascist_firewall_rand_prefer_ipv6_addr, (void))
-{
- /* TODO: Check for failures, and infer our preference based on this. */
- return crypto_rand_int(2);
-}
-
/** Do we prefer to connect to IPv6 ORPorts?
* Use node_ipv6_or_preferred() whenever possible: it supports bridge client
* per-node IPv6 preferences.
@@ -514,10 +504,7 @@ fascist_firewall_prefer_ipv6_orport(const or_options_t *options)
}
/* We can use both IPv4 and IPv6 - which do we prefer? */
- if (options->ClientAutoIPv6ORPort == 1) {
- /* If ClientAutoIPv6ORPort is 1, we prefer IPv4 or IPv6 at random. */
- return fascist_firewall_rand_prefer_ipv6_addr();
- } else if (options->ClientPreferIPv6ORPort == 1) {
+ if (options->ClientPreferIPv6ORPort == 1) {
return 1;
}
diff --git a/src/core/or/policies.h b/src/core/or/policies.h
index b9477b2db1..72a37d62b0 100644
--- a/src/core/or/policies.h
+++ b/src/core/or/policies.h
@@ -70,7 +70,6 @@ typedef struct short_policy_t {
int firewall_is_fascist_or(void);
int firewall_is_fascist_dir(void);
int fascist_firewall_use_ipv6(const or_options_t *options);
-MOCK_DECL(int, fascist_firewall_rand_prefer_ipv6_addr, (void));
int fascist_firewall_prefer_ipv6_orport(const or_options_t *options);
int fascist_firewall_prefer_ipv6_dirport(const or_options_t *options);
diff --git a/src/core/or/sendme.h b/src/core/or/sendme.h
index d5b2f8c93f..05d37ec3bb 100644
--- a/src/core/or/sendme.h
+++ b/src/core/or/sendme.h
@@ -48,7 +48,7 @@ void sendme_record_sending_cell_digest(circuit_t *circ, crypt_path_t *cpath);
#define SENDME_MAX_SUPPORTED_VERSION 1
/* The cell version constants for when emitting a cell. */
-#define SENDME_EMIT_MIN_VERSION_DEFAULT 0
+#define SENDME_EMIT_MIN_VERSION_DEFAULT 1
#define SENDME_EMIT_MIN_VERSION_MIN 0
#define SENDME_EMIT_MIN_VERSION_MAX UINT8_MAX
diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c
index 2b52a1173d..66b04f3bc2 100644
--- a/src/feature/client/bridges.c
+++ b/src/feature/client/bridges.c
@@ -844,8 +844,7 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
}
}
- if (options->ClientPreferIPv6ORPort == -1 ||
- options->ClientAutoIPv6ORPort == 0) {
+ if (options->ClientPreferIPv6ORPort == -1) {
/* Mark which address to use based on which bridge_t we got. */
node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 &&
!tor_addr_is_null(&node->ri->ipv6_addr));
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index 1ec599717c..9042ff8779 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -69,16 +69,20 @@ options_validate_dirauth_mode(const struct or_options_t *old_options,
(((void)(old_options)),((void)(options)),((void)(msg)),0)
#define options_validate_dirauth_testing(old_options, options, msg) \
(((void)(old_options)),((void)(options)),((void)(msg)),0)
-#define options_validate_dirauth_testing(old_options, options, msg) \
- (((void)(old_options)),((void)(options)),((void)(msg)),0)
#define options_act_dirauth(old_options) \
(((void)(old_options)),0)
#define options_act_dirauth_mtbf(old_options) \
(((void)(old_options)),0)
-#define options_act_dirauth_stats(old_options, print_notice_out) \
- (((void)(old_options)),((void)(print_notice_out)),0)
+static inline int
+options_act_dirauth_stats(const struct or_options_t *old_options,
+ bool *print_notice_out)
+{
+ (void)old_options;
+ *print_notice_out = 0;
+ return 0;
+}
#define dirauth_should_reject_requests_under_load() (false)
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index edf1662ced..7eb2b720a6 100644
--- a/src/feature/dirauth/dirvote.c
+++ b/src/feature/dirauth/dirvote.c
@@ -2527,9 +2527,12 @@ compute_consensus_package_lines(smartlist_t *votes)
* any new signatures in <b>src_voter_list</b> that should be added to
* <b>target</b>. (A signature should be added if we have no signature for that
* voter in <b>target</b> yet, or if we have no verifiable signature and the
- * new signature is verifiable.) Return the number of signatures added or
- * changed, or -1 if the document signed by <b>sigs</b> isn't the same
- * document as <b>target</b>. */
+ * new signature is verifiable.)
+ *
+ * Return the number of signatures added or changed, or -1 if the document
+ * signatures are invalid. Sets *<b>msg_out</b> to a string constant
+ * describing the signature status.
+ */
STATIC int
networkstatus_add_detached_signatures(networkstatus_t *target,
ns_detached_signatures_t *sigs,
@@ -3595,6 +3598,14 @@ dirvote_add_signatures_to_pending_consensus(
return r;
}
+/** Helper: we just got the <b>detached_signatures_body</b> sent to us as
+ * signatures on the currently pending consensus. Add them to the pending
+ * consensus (if we have one).
+ *
+ * Set *<b>msg</b> to a string constant describing the status, regardless of
+ * success or failure.
+ *
+ * Return negative on failure, nonnegative on success. */
static int
dirvote_add_signatures_to_all_pending_consensuses(
const char *detached_signatures_body,
@@ -3657,7 +3668,12 @@ dirvote_add_signatures_to_all_pending_consensuses(
/** Helper: we just got the <b>detached_signatures_body</b> sent to us as
* signatures on the currently pending consensus. Add them to the pending
* consensus (if we have one); otherwise queue them until we have a
- * consensus. Return negative on failure, nonnegative on success. */
+ * consensus.
+ *
+ * Set *<b>msg</b> to a string constant describing the status, regardless of
+ * success or failure.
+ *
+ * Return negative on failure, nonnegative on success. */
int
dirvote_add_signatures(const char *detached_signatures_body,
const char *source,
diff --git a/src/feature/dirauth/dirvote.h b/src/feature/dirauth/dirvote.h
index f2dbee20e5..fa7b1da4ab 100644
--- a/src/feature/dirauth/dirvote.h
+++ b/src/feature/dirauth/dirvote.h
@@ -167,7 +167,7 @@ dirvote_add_signatures(const char *detached_signatures_body,
{
(void) detached_signatures_body;
(void) source;
- (void) msg_out;
+ *msg_out = "No directory authority support";
/* If the dirauth module is disabled, this should NEVER be called else we
* failed to safeguard the dirauth module. */
tor_assert_nonfatal_unreached();
diff --git a/src/feature/dirauth/guardfraction.c b/src/feature/dirauth/guardfraction.c
index 40189ce494..b84f804f5f 100644
--- a/src/feature/dirauth/guardfraction.c
+++ b/src/feature/dirauth/guardfraction.c
@@ -188,7 +188,7 @@ guardfraction_file_parse_inputs_line(const char *inputs_line,
*
* guardfraction-file-version 1
* written-at <date and time>
- * n-inputs <number of consesuses parsed> <number of days considered>
+ * n-inputs <number of consensuses parsed> <number of days considered>
*
* guard-seen <fpr 1> <guardfraction percentage> <consensus appearances>
* guard-seen <fpr 2> <guardfraction percentage> <consensus appearances>
diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c
index baf8f8c217..5025d0ae39 100644
--- a/src/feature/dirauth/process_descs.c
+++ b/src/feature/dirauth/process_descs.c
@@ -285,7 +285,7 @@ dirserv_load_fingerprint_file(void)
* Return the appropriate router status.
*
* If the status is 'RTR_REJECT' and <b>msg</b> is provided, set
- * *<b>msg</b> to an explanation of why. */
+ * *<b>msg</b> to a string constant explaining why. */
uint32_t
dirserv_router_get_status(const routerinfo_t *router, const char **msg,
int severity)
@@ -399,22 +399,21 @@ dirserv_rejects_tor_version(const char *platform,
static const char please_upgrade_string[] =
"Tor version is insecure or unsupported. Please upgrade!";
- /* Versions before Tor 0.2.9 are unsupported. Versions between 0.2.9.0 and
- * 0.2.9.4 suffer from bug #20499, where relays don't keep their consensus
- * up to date */
- if (!tor_version_as_new_as(platform,"0.2.9.5-alpha")) {
+ /* Versions before Tor 0.3.5 are unsupported.
+ *
+ * Also, reject unstable versions of 0.3.5, since (as of this writing)
+ * they are almost none of the network. */
+ if (!tor_version_as_new_as(platform,"0.3.5.7")) {
if (msg)
*msg = please_upgrade_string;
return true;
}
- /* Series between Tor 0.3.0 and 0.3.4 inclusive are unsupported, and some
- * have bug #27841, which makes them broken as intro points. Reject them.
- *
- * Also reject unstable versions of 0.3.5, since (as of this writing)
- * they are almost none of the network. */
- if (tor_version_as_new_as(platform,"0.3.0.0-alpha-dev") &&
- !tor_version_as_new_as(platform,"0.3.5.7")) {
+ /* Series between Tor 0.3.6 and 0.4.1.4-rc inclusive are unsupported.
+ * Reject them. 0.3.6.0-alpha-dev only existed for a short time, before
+ * it was renamed to 0.4.0.0-alpha-dev. */
+ if (tor_version_as_new_as(platform,"0.3.6.0-alpha-dev") &&
+ !tor_version_as_new_as(platform,"0.4.1.5")) {
if (msg) {
*msg = please_upgrade_string;
}
@@ -564,7 +563,8 @@ dirserv_router_has_valid_address(routerinfo_t *ri)
/** Check whether we, as a directory server, want to accept <b>ri</b>. If so,
* set its is_valid,running fields and return 0. Otherwise, return -1.
*
- * If the router is rejected, set *<b>msg</b> to an explanation of why.
+ * If the router is rejected, set *<b>msg</b> to a string constant explining
+ * why.
*
* If <b>complain</b> then explain at log-level 'notice' why we refused
* a descriptor; else explain at log-level 'info'.
@@ -730,7 +730,8 @@ dirserv_add_multiple_descriptors(const char *desc, size_t desclen,
* That means the caller must not access <b>ri</b> after this function
* returns, since it might have been freed.
*
- * Return the status of the operation.
+ * Return the status of the operation, and set *<b>msg</b> to a string
+ * constant describing the status.
*
* This function is only called when fresh descriptors are posted, not when
* we re-load the cache.
diff --git a/src/feature/dirauth/process_descs.h b/src/feature/dirauth/process_descs.h
index 9c13692778..1461ab697d 100644
--- a/src/feature/dirauth/process_descs.h
+++ b/src/feature/dirauth/process_descs.h
@@ -98,7 +98,7 @@ dirserv_add_multiple_descriptors(const char *desc, size_t desclen,
(void)desclen;
(void)purpose;
(void)source;
- (void)msg;
+ *msg = "No directory authority support";
return (enum was_router_added_t)0;
}
static inline enum was_router_added_t
@@ -107,8 +107,8 @@ dirserv_add_descriptor(routerinfo_t *ri,
const char *source)
{
(void)ri;
- (void)msg;
(void)source;
+ *msg = "No directory authority support";
return (enum was_router_added_t)0;
}
static inline int
@@ -125,9 +125,9 @@ authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
int *valid_out)
{
(void)ri;
- (void)msg;
(void)complain;
- (void)valid_out;
+ *msg = "No directory authority support";
+ *valid_out = 0;
return 0;
}
static inline int
@@ -143,8 +143,9 @@ dirserv_router_get_status(const routerinfo_t *router,
int severity)
{
(void)router;
- (void)msg;
(void)severity;
+ if (msg)
+ *msg = "No directory authority support";
return 0;
}
static inline void
diff --git a/src/feature/dircache/conscache.c b/src/feature/dircache/conscache.c
index ceba410a5f..d9aaccddc1 100644
--- a/src/feature/dircache/conscache.c
+++ b/src/feature/dircache/conscache.c
@@ -132,6 +132,15 @@ consensus_cache_may_overallocate(consensus_cache_t *cache)
#endif
}
+// HACK: GCC on Appveyor hates that we may assert before returning. Work around
+// the error.
+#ifdef _WIN32
+#ifndef COCCI
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#endif
+#endif
+
/**
* Tell the sandbox (if any) configured by <b>cfg</b> to allow the
* operations that <b>cache</b> will need.
@@ -156,6 +165,12 @@ consensus_cache_register_with_sandbox(consensus_cache_t *cache,
return storage_dir_register_with_sandbox(cache->dir, cfg);
}
+#ifdef _WIN32
+#ifndef COCCI
+#pragma GCC diagnostic pop
+#endif
+#endif
+
/**
* Helper: clear all entries from <b>cache</b> (but do not delete
* any that aren't marked for removal
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index e7bec89cad..2072dddadd 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -1984,7 +1984,7 @@ dirclient_dump_total_dls(void)
for (int bootstrapped = 0; bootstrapped < 2; ++bootstrapped) {
bool first_time = true;
for (int i=0; i < DIR_PURPOSE_MAX_; ++i) {
- uint64_t n = total_dl[i][0];
+ uint64_t n = total_dl[i][bootstrapped];
if (n == 0)
continue;
if (options->SafeLogging_ != SAFELOG_SCRUB_NONE &&
diff --git a/src/feature/dirparse/parsecommon.c b/src/feature/dirparse/parsecommon.c
index 75ef70d4ee..0c63cd4846 100644
--- a/src/feature/dirparse/parsecommon.c
+++ b/src/feature/dirparse/parsecommon.c
@@ -403,12 +403,19 @@ get_next_token(memarea_t *area,
}
if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */
+ if (o_syn != NEED_KEY && o_syn != NEED_KEY_1024 && o_syn != OBJ_OK) {
+ RET_ERR("Unexpected public key.");
+ }
tok->key = crypto_pk_asn1_decode(tok->object_body, tok->object_size);
if (! tok->key)
RET_ERR("Couldn't parse public key.");
} else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */
+ if (o_syn != NEED_SKEY_1024 && o_syn != OBJ_OK) {
+ RET_ERR("Unexpected private key.");
+ }
tok->key = crypto_pk_asn1_decode_private(tok->object_body,
- tok->object_size);
+ tok->object_size,
+ 1024);
if (! tok->key)
RET_ERR("Couldn't parse private key.");
}
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index 9cf408ca3e..44cd2505fd 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -27,6 +27,21 @@
static int cached_client_descriptor_has_expired(time_t now,
const hs_cache_client_descriptor_t *cached_desc);
+/** Helper function: Return true iff the cache entry has a decrypted
+ * descriptor.
+ *
+ * A NULL desc object in the entry means that we were not able to decrypt the
+ * descriptor because we are likely lacking client authorization. It is still
+ * a valid entry but some operations can't be done without the decrypted
+ * descriptor thus this function MUST be used to safe guard access to the
+ * decrypted desc object. */
+static inline bool
+entry_has_decrypted_descriptor(const hs_cache_client_descriptor_t *entry)
+{
+ tor_assert(entry);
+ return (entry->desc != NULL);
+}
+
/********************** Directory HS cache ******************/
/** Directory descriptor cache. Map indexed by blinded key. */
@@ -341,8 +356,23 @@ static digest256map_t *hs_cache_client_intro_state;
static size_t
cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry)
{
- return sizeof(*entry) +
- strlen(entry->encoded_desc) + hs_desc_obj_size(entry->desc);
+ size_t size = 0;
+
+ if (entry == NULL) {
+ goto end;
+ }
+ size += sizeof(*entry);
+
+ if (entry->encoded_desc) {
+ size += strlen(entry->encoded_desc);
+ }
+
+ if (entry_has_decrypted_descriptor(entry)) {
+ size += hs_desc_obj_size(entry->desc);
+ }
+
+ end:
+ return size;
}
/** Remove a given descriptor from our cache. */
@@ -659,14 +689,20 @@ cache_store_as_client(hs_cache_client_descriptor_t *client_desc)
* client authorization. */
cache_entry = lookup_v3_desc_as_client(client_desc->key.pubkey);
if (cache_entry != NULL) {
- /* Signalling an undecrypted descriptor. We'll always replace the one we
- * have with the new one just fetched. */
- if (cache_entry->desc == NULL) {
+ /* If the current or the new cache entry don't have a decrypted descriptor
+ * (missing client authorization), we always replace the current one with
+ * the new one. Reason is that we can't inspect the revision counter
+ * within the plaintext data so we blindly replace. */
+ if (!entry_has_decrypted_descriptor(cache_entry) ||
+ !entry_has_decrypted_descriptor(client_desc)) {
remove_v3_desc_as_client(cache_entry);
cache_client_desc_free(cache_entry);
goto store;
}
+ /* From this point on, we know that the decrypted descriptor is in the
+ * current entry and new object thus safe to access. */
+
/* If we have an entry in our cache that has a revision counter greater
* than the one we just fetched, discard the one we fetched. */
if (cache_entry->desc->plaintext_data.revision_counter >
@@ -740,11 +776,15 @@ cache_clean_v3_as_client(time_t now)
MAP_DEL_CURRENT(key);
entry_size = cache_get_client_entry_size(entry);
bytes_removed += entry_size;
+
/* We just removed an old descriptor. We need to close all intro circuits
- * so we don't have leftovers that can be selected while lacking a
- * descriptor. We leave the rendezvous circuits opened because they could
- * be in use. */
- hs_client_close_intro_circuits_from_desc(entry->desc);
+ * if the descriptor is decrypted so we don't have leftovers that can be
+ * selected while lacking a descriptor. Circuits are selected by intro
+ * authentication key thus we need the descriptor. We leave the rendezvous
+ * circuits opened because they could be in use. */
+ if (entry_has_decrypted_descriptor(entry)) {
+ hs_client_close_intro_circuits_from_desc(entry->desc);
+ }
/* Entry is not in the cache anymore, destroy it. */
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
@@ -793,7 +833,7 @@ hs_cache_lookup_as_client(const ed25519_public_key_t *key)
tor_assert(key);
cached_desc = lookup_v3_desc_as_client(key->pubkey);
- if (cached_desc && cached_desc->desc) {
+ if (cached_desc && entry_has_decrypted_descriptor(cached_desc)) {
return cached_desc->desc;
}
@@ -866,7 +906,7 @@ hs_cache_remove_as_client(const ed25519_public_key_t *key)
/* 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) {
+ if (entry_has_decrypted_descriptor(cached_desc)) {
hs_client_close_intro_circuits_from_desc(cached_desc->desc);
}
/* Remove and free. */
@@ -995,7 +1035,7 @@ hs_cache_client_new_auth_parse(const ed25519_public_key_t *service_pk)
}
cached_desc = lookup_v3_desc_as_client(service_pk->pubkey);
- if (cached_desc == NULL || cached_desc->desc != NULL) {
+ if (cached_desc == NULL || entry_has_decrypted_descriptor(cached_desc)) {
/* No entry for that service or the descriptor is already decoded. */
goto end;
}
diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c
index dd5fefd7e7..fc9f4a2654 100644
--- a/src/feature/hs/hs_cell.c
+++ b/src/feature/hs/hs_cell.c
@@ -758,7 +758,7 @@ hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
* INTRO2 MAC to ensure that the keys are the right ones.
*
* Return NULL on failure to either produce the key material or on MAC
- * valication. Else a newly allocated intro keys object. */
+ * validation. Else return a newly allocated intro keys object. */
static hs_ntor_intro_cell_keys_t *
get_introduce2_keys_and_verify_mac(hs_cell_introduce2_data_t *data,
const uint8_t *encrypted_section,
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index d5c1c5ca9a..cc1b01d2ef 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1848,7 +1848,7 @@ hs_client_decode_descriptor(const char *desc_str,
hs_subcredential_t subcredential;
ed25519_public_key_t blinded_pubkey;
hs_client_service_authorization_t *client_auth = NULL;
- curve25519_secret_key_t *client_auht_sk = NULL;
+ curve25519_secret_key_t *client_auth_sk = NULL;
tor_assert(desc_str);
tor_assert(service_identity_pk);
@@ -1857,7 +1857,7 @@ hs_client_decode_descriptor(const char *desc_str,
/* Check if we have a client authorization for this service in the map. */
client_auth = find_client_auth(service_identity_pk);
if (client_auth) {
- client_auht_sk = &client_auth->enc_seckey;
+ client_auth_sk = &client_auth->enc_seckey;
}
/* Create subcredential for this HS so that we can decrypt */
@@ -1870,7 +1870,7 @@ hs_client_decode_descriptor(const char *desc_str,
/* Parse descriptor */
ret = hs_desc_decode_descriptor(desc_str, &subcredential,
- client_auht_sk, desc);
+ client_auth_sk, desc);
memwipe(&subcredential, 0, sizeof(subcredential));
if (ret != HS_DESC_DECODE_OK) {
goto err;
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 8c30b56b04..0a5cb4277c 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -707,8 +707,8 @@ get_extend_info_from_intro_point(const hs_service_intro_point_t *ip,
/** Return the number of introduction points that are established for the
* given descriptor. */
-static unsigned int
-count_desc_circuit_established(const hs_service_descriptor_t *desc)
+MOCK_IMPL(STATIC unsigned int,
+count_desc_circuit_established, (const hs_service_descriptor_t *desc))
{
unsigned int count = 0;
@@ -3055,13 +3055,85 @@ service_desc_hsdirs_changed(const hs_service_t *service,
return should_reupload;
}
+/** These are all the reasons why a descriptor upload can't occur. We use
+ * those to log the reason properly with the right rate limiting and for the
+ * right descriptor. */
+typedef enum {
+ LOG_DESC_UPLOAD_REASON_MISSING_IPS = 0,
+ LOG_DESC_UPLOAD_REASON_IP_NOT_ESTABLISHED = 1,
+ LOG_DESC_UPLOAD_REASON_NOT_TIME = 2,
+ LOG_DESC_UPLOAD_REASON_NO_LIVE_CONSENSUS = 3,
+ LOG_DESC_UPLOAD_REASON_NO_DIRINFO = 4,
+} log_desc_upload_reason_t;
+
+/** Maximum number of reasons. This is used to allocate the static array of
+ * all rate limiting objects. */
+#define LOG_DESC_UPLOAD_REASON_MAX LOG_DESC_UPLOAD_REASON_NO_DIRINFO
+
+/** Log the reason why we can't upload the given descriptor for the given
+ * service. This takes a message string (allocated by the caller) and a
+ * reason.
+ *
+ * Depending on the reason and descriptor, different rate limit applies. This
+ * is done because this function will basically be called every second. Each
+ * descriptor for each reason uses its own log rate limit object in order to
+ * avoid message suppression for different reasons and descriptors. */
+static void
+log_cant_upload_desc(const hs_service_t *service,
+ const hs_service_descriptor_t *desc, const char *msg,
+ const log_desc_upload_reason_t reason)
+{
+ /* Writing the log every minute shouldn't be too annoying for log rate limit
+ * since this can be emitted every second for each descriptor.
+ *
+ * However, for one specific case, we increase it to 10 minutes because it
+ * is hit constantly, as an expected behavior, which is the reason
+ * indicating that it is not the time to upload. */
+ static ratelim_t limits[2][LOG_DESC_UPLOAD_REASON_MAX + 1] =
+ { { RATELIM_INIT(60), RATELIM_INIT(60), RATELIM_INIT(60 * 10),
+ RATELIM_INIT(60), RATELIM_INIT(60) },
+ { RATELIM_INIT(60), RATELIM_INIT(60), RATELIM_INIT(60 * 10),
+ RATELIM_INIT(60), RATELIM_INIT(60) },
+ };
+ bool is_next_desc = false;
+ unsigned int rlim_pos = 0;
+ ratelim_t *rlim = NULL;
+
+ tor_assert(service);
+ tor_assert(desc);
+ tor_assert(msg);
+
+ /* Make sure the reason value is valid. It should never happen because we
+ * control that value in the code flow but will be apparent during
+ * development if a reason is added but LOG_DESC_UPLOAD_REASON_NUM_ is not
+ * updated. */
+ if (BUG(reason > LOG_DESC_UPLOAD_REASON_MAX || reason < 0)) {
+ return;
+ }
+
+ /* Ease our life. Flag that tells us if the descriptor is the next one. */
+ is_next_desc = (service->desc_next == desc);
+
+ /* Current descriptor is the first element in the ratelimit object array.
+ * The next descriptor is the second element. */
+ rlim_pos = (is_next_desc ? 1 : 0);
+ /* Get the ratelimit object for the reason _and_ right descriptor. */
+ rlim = &limits[rlim_pos][reason];
+
+ log_fn_ratelim(rlim, LOG_INFO, LD_REND,
+ "Service %s can't upload its %s descriptor: %s",
+ safe_str_client(service->onion_address),
+ (is_next_desc) ? "next" : "current", msg);
+}
+
/** Return 1 if the given descriptor from the given service can be uploaded
* else return 0 if it can not. */
static int
should_service_upload_descriptor(const hs_service_t *service,
const hs_service_descriptor_t *desc, time_t now)
{
- unsigned int num_intro_points;
+ char *msg = NULL;
+ unsigned int num_intro_points, count_ip_established;
tor_assert(service);
tor_assert(desc);
@@ -3081,34 +3153,54 @@ should_service_upload_descriptor(const hs_service_t *service,
* upload descriptor in this case. We need at least one for the service to
* be reachable. */
if (desc->missing_intro_points && num_intro_points == 0) {
+ msg = tor_strdup("Missing intro points");
+ log_cant_upload_desc(service, desc, msg,
+ LOG_DESC_UPLOAD_REASON_MISSING_IPS);
goto cannot;
}
/* Check if all our introduction circuit have been established for all the
* intro points we have selected. */
- if (count_desc_circuit_established(desc) != num_intro_points) {
+ count_ip_established = count_desc_circuit_established(desc);
+ if (count_ip_established != num_intro_points) {
+ tor_asprintf(&msg, "Intro circuits aren't yet all established (%d/%d).",
+ count_ip_established, num_intro_points);
+ log_cant_upload_desc(service, desc, msg,
+ LOG_DESC_UPLOAD_REASON_IP_NOT_ESTABLISHED);
goto cannot;
}
/* Is it the right time to upload? */
if (desc->next_upload_time > now) {
+ tor_asprintf(&msg, "Next upload time is %ld, it is now %ld.",
+ (long int) desc->next_upload_time, (long int) now);
+ log_cant_upload_desc(service, desc, msg,
+ LOG_DESC_UPLOAD_REASON_NOT_TIME);
goto cannot;
}
/* Don't upload desc if we don't have a live consensus */
if (!networkstatus_get_live_consensus(now)) {
+ msg = tor_strdup("No live consensus");
+ log_cant_upload_desc(service, desc, msg,
+ LOG_DESC_UPLOAD_REASON_NO_LIVE_CONSENSUS);
goto cannot;
}
/* Do we know enough router descriptors to have adequate vision of the HSDir
hash ring? */
if (!router_have_minimum_dir_info()) {
+ msg = tor_strdup("Not enough directory information");
+ log_cant_upload_desc(service, desc, msg,
+ LOG_DESC_UPLOAD_REASON_NO_DIRINFO);
goto cannot;
}
/* Can upload! */
return 1;
+
cannot:
+ tor_free(msg);
return 0;
}
@@ -3569,6 +3661,12 @@ hs_service_add_ephemeral(ed25519_secret_key_t *sk, smartlist_t *ports,
goto err;
}
+ if (ed25519_validate_pubkey(&service->keys.identity_pk) < 0) {
+ log_warn(LD_CONFIG, "Bad ed25519 private key was provided");
+ ret = RSAE_BADPRIVKEY;
+ goto err;
+ }
+
/* Make sure we have at least one port. */
if (smartlist_len(service->config.ports) == 0) {
log_warn(LD_CONFIG, "At least one VIRTPORT/TARGET must be specified "
diff --git a/src/feature/hs/hs_service.h b/src/feature/hs/hs_service.h
index 94a73b2fec..3fe14878ed 100644
--- a/src/feature/hs/hs_service.h
+++ b/src/feature/hs/hs_service.h
@@ -384,6 +384,9 @@ STATIC hs_service_t *get_first_service(void);
STATIC hs_service_intro_point_t *service_intro_point_find_by_ident(
const hs_service_t *service,
const hs_ident_circuit_t *ident);
+
+MOCK_DECL(STATIC unsigned int, count_desc_circuit_established,
+ (const hs_service_descriptor_t *desc));
#endif /* defined(TOR_UNIT_TESTS) */
/* Service accessors. */
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index 2188e47177..e07d58c91c 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -2167,7 +2167,7 @@ networkstatus_set_current_consensus(const char *consensus,
warn_early_consensus(c, flavor, now);
- /* We got a new consesus. Reset our md fetch fail cache */
+ /* We got a new consensus. Reset our md fetch fail cache */
microdesc_reset_outdated_dirservers_list();
router_dir_info_changed();
diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c
index f4e1215a40..80c1aa6893 100644
--- a/src/feature/nodelist/routerlist.c
+++ b/src/feature/nodelist/routerlist.c
@@ -2922,7 +2922,7 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
(r1->bandwidthburst != r2->bandwidthburst))
return 0;
- /* Did more than 12 hours pass? */
+ /* Has enough time passed between the publication times? */
if (r1->cache_info.published_on + ROUTER_MAX_COSMETIC_TIME_DIFFERENCE
< r2->cache_info.published_on)
return 0;
diff --git a/src/feature/relay/ext_orport.c b/src/feature/relay/ext_orport.c
index 5568dacf1a..cff5f42cc7 100644
--- a/src/feature/relay/ext_orport.c
+++ b/src/feature/relay/ext_orport.c
@@ -602,7 +602,7 @@ connection_ext_or_process_inbuf(or_connection_t *or_conn)
command->body, command->len) < 0)
goto err;
} else {
- log_notice(LD_NET,"Got Extended ORPort command we don't regognize (%u).",
+ log_notice(LD_NET,"Got Extended ORPort command we don't recognize (%u).",
command->cmd);
}
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c
index 8d20e97eb6..3e9961f47e 100644
--- a/src/feature/relay/relay_config.c
+++ b/src/feature/relay/relay_config.c
@@ -231,8 +231,8 @@ check_server_ports(const smartlist_t *ports,
}
/** Parse all relay ports from <b>options</b>. On success, add parsed ports to
- * <b>ports</b>, and return 0. On failure, set *<b>msg</b> to a description
- * of the problem and return -1.
+ * <b>ports</b>, and return 0. On failure, set *<b>msg</b> to a newly
+ * allocated string describing the problem, and return -1.
**/
int
port_parse_ports_relay(or_options_t *options,
@@ -334,7 +334,8 @@ port_update_port_set_relay(or_options_t *options,
* Legacy validation function, which checks that the current OS is usable in
* relay mode, if options is set to a relay mode.
*
- * Warns about OSes with potential issues. Always returns 0.
+ * Warns about OSes with potential issues. Does not set *<b>msg</b>.
+ * Always returns 0.
*/
int
options_validate_relay_os(const or_options_t *old_options,
@@ -400,10 +401,14 @@ options_validate_relay_info(const or_options_t *old_options,
}
}
- if (server_mode(options) && !options->ContactInfo)
- log_notice(LD_CONFIG, "Your ContactInfo config option is not set. "
- "Please consider setting it, so we can contact you if your server is "
- "misconfigured or something else goes wrong.");
+ if (server_mode(options) && !options->ContactInfo) {
+ log_warn(LD_CONFIG,
+ "Your ContactInfo config option is not set. Please strongly "
+ "consider setting it, so we can contact you if your relay is "
+ "misconfigured, end-of-life, or something else goes wrong. "
+ "It is also possible that your relay might get rejected from "
+ "the network due to a missing valid contact address.");
+ }
const char *ContactInfo = options->ContactInfo;
if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h
index 7a05561c26..c70c322d88 100644
--- a/src/feature/relay/relay_config.h
+++ b/src/feature/relay/relay_config.h
@@ -125,6 +125,20 @@ options_validate_relay_mode(const struct or_options_t *old_options,
return 0;
}
+static inline int
+port_parse_ports_relay(or_options_t *options,
+ char **msg,
+ smartlist_t *ports_out,
+ int *have_low_ports_out)
+{
+ (void)options;
+ (void)msg;
+ (void)ports_out;
+ if (*have_low_ports_out < 0)
+ *have_low_ports_out = 0;
+ return 0;
+}
+
#define relay_get_dirportfrontpage() \
(NULL)
#define relay_config_free_all() \
@@ -138,9 +152,6 @@ options_validate_relay_mode(const struct or_options_t *old_options,
#define port_warn_nonlocal_ext_orports(ports, portname) \
(((void)(ports)),((void)(portname)))
-#define port_parse_ports_relay(options, msg, ports_out, have_low_ports_out) \
- (((void)(options)),((void)(msg)),((void)(ports_out)), \
- ((void)(have_low_ports_out)),0)
#define port_update_port_set_relay(options, ports) \
(((void)(options)),((void)(ports)))
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index e24e499971..9b62bb385c 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -748,8 +748,8 @@ v3_authority_check_key_expiry(void)
}
/** Get the lifetime of an onion key in days. This value is defined by the
- * network consesus parameter "onion-key-rotation-days". Always returns a value
- * between <b>MIN_ONION_KEY_LIFETIME_DAYS</b> and
+ * network consensus parameter "onion-key-rotation-days". Always returns a
+ * value between <b>MIN_ONION_KEY_LIFETIME_DAYS</b> and
* <b>MAX_ONION_KEY_LIFETIME_DAYS</b>.
*/
static int
@@ -763,7 +763,7 @@ get_onion_key_rotation_days_(void)
}
/** Get the current lifetime of an onion key in seconds. This value is defined
- * by the network consesus parameter "onion-key-rotation-days", but the value
+ * by the network consensus parameter "onion-key-rotation-days", but the value
* is converted to seconds.
*/
int
@@ -773,7 +773,7 @@ get_onion_key_lifetime(void)
}
/** Get the grace period of an onion key in seconds. This value is defined by
- * the network consesus parameter "onion-key-grace-period-days", but the value
+ * the network consensus parameter "onion-key-grace-period-days", but the value
* is converted to seconds.
*/
int
@@ -1446,6 +1446,50 @@ router_get_advertised_or_port_by_af(const or_options_t *options,
return port;
}
+/** As router_get_advertised_or_port(), but returns the IPv6 address and
+ * port in ipv6_ap_out, which must not be NULL. Returns a null address and
+ * zero port, if no ORPort is found. */
+void
+router_get_advertised_ipv6_or_ap(const or_options_t *options,
+ tor_addr_port_t *ipv6_ap_out)
+{
+ /* Bug in calling function, we can't return a sensible result, and it
+ * shouldn't use the NULL pointer once we return. */
+ tor_assert(ipv6_ap_out);
+
+ /* If there is no valid IPv6 ORPort, return a null address and port. */
+ tor_addr_make_null(&ipv6_ap_out->addr, AF_INET6);
+ ipv6_ap_out->port = 0;
+
+ const tor_addr_t *addr = get_first_advertised_addr_by_type_af(
+ CONN_TYPE_OR_LISTENER,
+ AF_INET6);
+ const uint16_t port = router_get_advertised_or_port_by_af(
+ options,
+ AF_INET6);
+
+ if (!addr || port == 0) {
+ log_info(LD_CONFIG, "There is no advertised IPv6 ORPort.");
+ return;
+ }
+
+ /* If the relay is configured using the default authorities, disallow
+ * internal IPs. Otherwise, allow them. For IPv4 ORPorts and DirPorts,
+ * this check is done in resolve_my_address(). See #33681. */
+ const int default_auth = using_default_dir_authorities(options);
+ if (tor_addr_is_internal(addr, 0) && default_auth) {
+ log_warn(LD_CONFIG,
+ "Unable to use configured IPv6 ORPort \"%s\" in a "
+ "descriptor. Skipping it. "
+ "Try specifying a globally reachable address explicitly.",
+ fmt_addrport(addr, port));
+ return;
+ }
+
+ tor_addr_copy(&ipv6_ap_out->addr, addr);
+ ipv6_ap_out->port = port;
+}
+
/** Return the port that we should advertise as our DirPort;
* this is one of three possibilities:
* The one that is passed as <b>dirport</b> if the DirPort option is 0, or
@@ -1990,34 +2034,11 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
sizeof(curve25519_public_key_t));
/* For now, at most one IPv6 or-address is being advertised. */
- {
- const port_cfg_t *ipv6_orport = NULL;
- SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) {
- if (p->type == CONN_TYPE_OR_LISTENER &&
- ! p->server_cfg.no_advertise &&
- ! p->server_cfg.bind_ipv4_only &&
- tor_addr_family(&p->addr) == AF_INET6) {
- /* Like IPv4, if the relay is configured using the default
- * authorities, disallow internal IPs. Otherwise, allow them. */
- const int default_auth = using_default_dir_authorities(options);
- if (! tor_addr_is_internal(&p->addr, 0) || ! default_auth) {
- ipv6_orport = p;
- break;
- } else {
- char addrbuf[TOR_ADDR_BUF_LEN];
- log_warn(LD_CONFIG,
- "Unable to use configured IPv6 address \"%s\" in a "
- "descriptor. Skipping it. "
- "Try specifying a globally reachable address explicitly.",
- tor_addr_to_str(addrbuf, &p->addr, sizeof(addrbuf), 1));
- }
- }
- } SMARTLIST_FOREACH_END(p);
- if (ipv6_orport) {
- tor_addr_copy(&ri->ipv6_addr, &ipv6_orport->addr);
- ri->ipv6_orport = ipv6_orport->port;
- }
- }
+ tor_addr_port_t ipv6_orport;
+ router_get_advertised_ipv6_or_ap(options, &ipv6_orport);
+ /* If there is no valud IPv6 ORPort, the address and port are null. */
+ tor_addr_copy(&ri->ipv6_addr, &ipv6_orport.addr);
+ ri->ipv6_orport = ipv6_orport.port;
ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
if (BUG(crypto_pk_get_digest(ri->identity_pkey,
diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h
index 2e07df2e88..d1b4ce5f8f 100644
--- a/src/feature/relay/router.h
+++ b/src/feature/relay/router.h
@@ -66,6 +66,8 @@ int init_keys_client(void);
uint16_t router_get_active_listener_port_by_type_af(int listener_type,
sa_family_t family);
uint16_t router_get_advertised_or_port(const or_options_t *options);
+void router_get_advertised_ipv6_or_ap(const or_options_t *options,
+ tor_addr_port_t *ipv6_ap_out);
uint16_t router_get_advertised_or_port_by_af(const or_options_t *options,
sa_family_t family);
uint16_t router_get_advertised_dir_port(const or_options_t *options,
diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h
index 2b5f03a2a3..1fb5d724e9 100644
--- a/src/feature/relay/routerkeys.h
+++ b/src/feature/relay/routerkeys.h
@@ -95,7 +95,7 @@ make_ntor_onion_key_crosscert(const curve25519_keypair_t *onion_key,
(void)master_id_key;
(void)now;
(void)lifetime;
- (void)sign_out;
+ *sign_out = 0;
tor_assert_nonfatal_unreached();
return NULL;
}
@@ -108,7 +108,7 @@ make_tap_onion_key_crosscert(const crypto_pk_t *onion_key,
(void)onion_key;
(void)master_id_key;
(void)rsa_id_key;
- (void)len_out;
+ *len_out = 0;
tor_assert_nonfatal_unreached();
return NULL;
}
diff --git a/src/lib/crypt_ops/crypto_ed25519.c b/src/lib/crypt_ops/crypto_ed25519.c
index bd97f76284..f242c7011e 100644
--- a/src/lib/crypt_ops/crypto_ed25519.c
+++ b/src/lib/crypt_ops/crypto_ed25519.c
@@ -795,7 +795,7 @@ ed25519_point_is_identity_element(const uint8_t *point)
int
ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
{
- uint8_t result[32] = {9};
+ uint8_t result[32] = {0};
/* First check that we were not given the identity element */
if (ed25519_point_is_identity_element(pubkey->pubkey)) {
diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c
index 4b33ed98e5..195e4bbaf9 100644
--- a/src/lib/crypt_ops/crypto_rsa.c
+++ b/src/lib/crypt_ops/crypto_rsa.c
@@ -490,7 +490,7 @@ crypto_pk_write_private_key_to_string(crypto_pk_t *env,
static int
crypto_pk_read_from_string_generic(crypto_pk_t *env, const char *src,
size_t len, int severity,
- bool private_key)
+ bool private_key, int max_bits)
{
if (len == (size_t)-1) // "-1" indicates "use the length of the string."
len = strlen(src);
@@ -510,7 +510,7 @@ crypto_pk_read_from_string_generic(crypto_pk_t *env, const char *src,
}
crypto_pk_t *pk = private_key
- ? crypto_pk_asn1_decode_private((const char*)buf, n)
+ ? crypto_pk_asn1_decode_private((const char*)buf, n, max_bits)
: crypto_pk_asn1_decode((const char*)buf, n);
if (! pk) {
log_fn(severity, LD_CRYPTO,
@@ -539,7 +539,8 @@ int
crypto_pk_read_public_key_from_string(crypto_pk_t *env,
const char *src, size_t len)
{
- return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, false);
+ return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, false,
+ -1);
}
/** Read a PEM-encoded private key from the <b>len</b>-byte string <b>src</b>
@@ -550,7 +551,21 @@ int
crypto_pk_read_private_key_from_string(crypto_pk_t *env,
const char *src, ssize_t len)
{
- return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true);
+ return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true,
+ -1);
+}
+
+/**
+ * As crypto_pk_read_private_key_from_string(), but reject any key
+ * with a modulus longer than 1024 bits before doing any expensive
+ * validation on it.
+ */
+int
+crypto_pk_read_private_key1024_from_string(crypto_pk_t *env,
+ const char *src, ssize_t len)
+{
+ return crypto_pk_read_from_string_generic(env, src, len, LOG_INFO, true,
+ 1024);
}
/** If a file is longer than this, we won't try to decode its private key */
@@ -578,7 +593,7 @@ crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
}
int rv = crypto_pk_read_from_string_generic(env, buf, (ssize_t)st.st_size,
- LOG_WARN, true);
+ LOG_WARN, true, -1);
if (rv < 0) {
log_warn(LD_CRYPTO, "Unable to decode private key from file %s",
escaped(keyfile));
@@ -662,7 +677,7 @@ crypto_pk_base64_decode_private(const char *str, size_t len)
goto out;
}
- pk = crypto_pk_asn1_decode_private(der, der_len);
+ pk = crypto_pk_asn1_decode_private(der, der_len, -1);
out:
memwipe(der, 0, len+1);
diff --git a/src/lib/crypt_ops/crypto_rsa.h b/src/lib/crypt_ops/crypto_rsa.h
index 38934e7f32..ab2e9db80d 100644
--- a/src/lib/crypt_ops/crypto_rsa.h
+++ b/src/lib/crypt_ops/crypto_rsa.h
@@ -61,6 +61,8 @@ int crypto_pk_read_public_key_from_string(crypto_pk_t *env,
const char *src, size_t len);
int crypto_pk_read_private_key_from_string(crypto_pk_t *env,
const char *s, ssize_t len);
+int crypto_pk_read_private_key1024_from_string(crypto_pk_t *env,
+ const char *src, ssize_t len);
int crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
const char *fname);
@@ -95,7 +97,8 @@ int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len);
crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len);
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk,
char *dest, size_t dest_len);
-crypto_pk_t *crypto_pk_asn1_decode_private(const char *str, size_t len);
+crypto_pk_t *crypto_pk_asn1_decode_private(const char *str, size_t len,
+ int max_bits);
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out);
void crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in);
diff --git a/src/lib/crypt_ops/crypto_rsa_nss.c b/src/lib/crypt_ops/crypto_rsa_nss.c
index 0a5041aad4..66f325e868 100644
--- a/src/lib/crypt_ops/crypto_rsa_nss.c
+++ b/src/lib/crypt_ops/crypto_rsa_nss.c
@@ -679,9 +679,12 @@ crypto_pk_asn1_encode_private(const crypto_pk_t *pk,
/** Given a buffer containing the DER representation of the
* private key <b>str</b>, decode and return the result on success, or NULL
* on failure.
+ *
+ * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits
+ * without performing any expensive validation on it.
*/
crypto_pk_t *
-crypto_pk_asn1_decode_private(const char *str, size_t len)
+crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
{
tor_assert(str);
tor_assert(len < INT_MAX);
@@ -731,6 +734,15 @@ crypto_pk_asn1_decode_private(const char *str, size_t len)
output = NULL;
}
+ if (output) {
+ const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey);
+ if (max_bits >= 0 && bits > max_bits) {
+ log_info(LD_CRYPTO, "Private key longer than expected.");
+ crypto_pk_free(output);
+ output = NULL;
+ }
+ }
+
if (slot)
PK11_FreeSlot(slot);
diff --git a/src/lib/crypt_ops/crypto_rsa_openssl.c b/src/lib/crypt_ops/crypto_rsa_openssl.c
index e5025108ae..d54db43b92 100644
--- a/src/lib/crypt_ops/crypto_rsa_openssl.c
+++ b/src/lib/crypt_ops/crypto_rsa_openssl.c
@@ -33,6 +33,7 @@ ENABLE_GCC_WARNING("-Wredundant-decls")
#include "lib/encoding/binascii.h"
#include <string.h>
+#include <stdbool.h>
/** Declaration for crypto_pk_t structure. */
struct crypto_pk_t
@@ -564,11 +565,71 @@ crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest,
return len;
}
+/** Check whether any component of a private key is too large in a way that
+ * seems likely to make verification too expensive. Return true if it's too
+ * long, and false otherwise. */
+static bool
+rsa_private_key_too_long(RSA *rsa, int max_bits)
+{
+ const BIGNUM *n, *e, *p, *q, *d, *dmp1, *dmq1, *iqmp;
+#ifdef OPENSSL_1_1_API
+
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,1)
+ n = RSA_get0_n(rsa);
+ e = RSA_get0_e(rsa);
+ p = RSA_get0_p(rsa);
+ q = RSA_get0_q(rsa);
+ d = RSA_get0_d(rsa);
+ dmp1 = RSA_get0_dmp1(rsa);
+ dmq1 = RSA_get0_dmq1(rsa);
+ iqmp = RSA_get0_iqmp(rsa);
+#else
+ /* The accessors above did not exist in openssl 1.1.0. */
+ p = q = dmp1 = dmq1 = iqmp = NULL;
+ RSA_get0_key(rsa, &n, &e, &d);
+#endif
+
+ if (RSA_bits(rsa) > max_bits)
+ return true;
+#else
+ n = rsa->n;
+ e = rsa->e;
+ p = rsa->p;
+ q = rsa->q;
+ d = rsa->d;
+ dmp1 = rsa->dmp1;
+ dmq1 = rsa->dmq1;
+ iqmp = rsa->iqmp;
+#endif
+
+ if (n && BN_num_bits(n) > max_bits)
+ return true;
+ if (e && BN_num_bits(e) > max_bits)
+ return true;
+ if (p && BN_num_bits(p) > max_bits)
+ return true;
+ if (q && BN_num_bits(q) > max_bits)
+ return true;
+ if (d && BN_num_bits(d) > max_bits)
+ return true;
+ if (dmp1 && BN_num_bits(dmp1) > max_bits)
+ return true;
+ if (dmq1 && BN_num_bits(dmq1) > max_bits)
+ return true;
+ if (iqmp && BN_num_bits(iqmp) > max_bits)
+ return true;
+
+ return false;
+}
+
/** Decode an ASN.1-encoded private key from <b>str</b>; return the result on
* success and NULL on failure.
+ *
+ * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits
+ * without performing any expensive validation on it.
*/
crypto_pk_t *
-crypto_pk_asn1_decode_private(const char *str, size_t len)
+crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
{
RSA *rsa;
unsigned char *buf;
@@ -578,7 +639,12 @@ crypto_pk_asn1_decode_private(const char *str, size_t len)
rsa = d2i_RSAPrivateKey(NULL, &cp, len);
tor_free(buf);
if (!rsa) {
- crypto_openssl_log_errors(LOG_WARN,"decoding public key");
+ crypto_openssl_log_errors(LOG_WARN,"decoding private key");
+ return NULL;
+ }
+ if (max_bits >= 0 && rsa_private_key_too_long(rsa, max_bits)) {
+ log_info(LD_CRYPTO, "Private key longer than expected.");
+ RSA_free(rsa);
return NULL;
}
crypto_pk_t *result = crypto_new_pk_from_openssl_rsa_(rsa);
diff --git a/src/lib/encoding/pem.c b/src/lib/encoding/pem.c
index c48f1016ae..6c9f10e085 100644
--- a/src/lib/encoding/pem.c
+++ b/src/lib/encoding/pem.c
@@ -85,13 +85,19 @@ pem_decode(uint8_t *dest, size_t destlen, const char *src, size_t srclen,
src = eat_whitespace_eos(src, eos);
char *tag = NULL;
- tor_asprintf(&tag, "-----BEGIN %s-----\n", objtype);
+ tor_asprintf(&tag, "-----BEGIN %s-----", objtype);
if ((size_t)(eos-src) < strlen(tag) || fast_memneq(src, tag, strlen(tag))) {
tor_free(tag);
return -1;
}
src += strlen(tag);
tor_free(tag);
+ /* At this point we insist on spaces (including CR), then an LF. */
+ src = eat_whitespace_eos_no_nl(src, eos);
+ if (src == eos || *src != '\n') {
+ /* Extra junk at end of line: this isn't valid. */
+ return -1;
+ }
// NOTE lack of trailing \n. We do not enforce its presence.
tor_asprintf(&tag, "\n-----END %s-----", objtype);
diff --git a/src/lib/err/torerr.c b/src/lib/err/torerr.c
index 92ef80e56a..2de75c0be4 100644
--- a/src/lib/err/torerr.c
+++ b/src/lib/err/torerr.c
@@ -151,29 +151,27 @@ tor_log_reset_sigsafe_err_fds(void)
}
/**
- * Close the list of fds that get errors from inside a signal handler or
+ * Flush the list of fds that get errors from inside a signal handler or
* other emergency condition. These fds are shared with the logging code:
- * closing them flushes the log buffers, and prevents any further logging.
+ * flushing them also flushes the log buffers.
*
- * This function closes stderr, so it should only be called immediately before
- * process shutdown.
+ * This function is safe to call during signal handlers.
*/
void
-tor_log_close_sigsafe_err_fds(void)
+tor_log_flush_sigsafe_err_fds(void)
{
+ /* If we don't have fsync() in unistd.h, we can't flush the logs. */
+#ifdef HAVE_FSYNC
int n_fds, i;
const int *fds = NULL;
n_fds = tor_log_get_sigsafe_err_fds(&fds);
for (i = 0; i < n_fds; ++i) {
- /* tor_log_close_sigsafe_err_fds_on_error() is called on error and on
- * shutdown, so we can't log or take any useful action if close()
- * fails. */
- (void)close(fds[i]);
+ /* This function is called on error and on shutdown, so we don't log, or
+ * take any other action, if fsync() fails. */
+ (void)fsync(fds[i]);
}
-
- /* Don't even try logging, we've closed all the log fds. */
- tor_log_set_sigsafe_err_fds(NULL, 0);
+#endif /* defined(HAVE_FSYNC) */
}
/**
@@ -217,13 +215,13 @@ tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr,
/**
* Call the abort() function to kill the current process with a fatal
- * error. But first, close the raw error file descriptors, so error messages
+ * error. But first, flush the raw error file descriptors, so error messages
* are written before process termination.
**/
void
tor_raw_abort_(void)
{
- tor_log_close_sigsafe_err_fds();
+ tor_log_flush_sigsafe_err_fds();
abort();
}
diff --git a/src/lib/err/torerr.h b/src/lib/err/torerr.h
index f5b36eef9c..ce1b049c47 100644
--- a/src/lib/err/torerr.h
+++ b/src/lib/err/torerr.h
@@ -40,7 +40,7 @@ void tor_log_err_sigsafe(const char *m, ...);
int tor_log_get_sigsafe_err_fds(const int **out);
void tor_log_set_sigsafe_err_fds(const int *fds, int n);
void tor_log_reset_sigsafe_err_fds(void);
-void tor_log_close_sigsafe_err_fds(void);
+void tor_log_flush_sigsafe_err_fds(void);
void tor_log_sigsafe_err_set_granularity(int ms);
void tor_raw_abort_(void) ATTR_NORETURN;
diff --git a/src/lib/err/torerr_sys.c b/src/lib/err/torerr_sys.c
index aa49ba36bd..46fc853550 100644
--- a/src/lib/err/torerr_sys.c
+++ b/src/lib/err/torerr_sys.c
@@ -27,11 +27,9 @@ subsys_torerr_initialize(void)
static void
subsys_torerr_shutdown(void)
{
- /* Stop handling signals with backtraces, then close the logs. */
+ /* Stop handling signals with backtraces, then flush the logs. */
clean_up_backtrace_handler();
- /* We can't log any log messages after this point: we've closed all the log
- * fds, including stdio. */
- tor_log_close_sigsafe_err_fds();
+ tor_log_flush_sigsafe_err_fds();
}
const subsys_fns_t sys_torerr = {
diff --git a/src/lib/evloop/procmon.c b/src/lib/evloop/procmon.c
index 3276cb1808..718c7d4777 100644
--- a/src/lib/evloop/procmon.c
+++ b/src/lib/evloop/procmon.c
@@ -165,8 +165,8 @@ tor_validate_process_specifier(const char *process_spec,
return parse_process_specifier(process_spec, &ppspec, msg);
}
-/* DOCDOC poll_interval_tv */
-static const struct timeval poll_interval_tv = {15, 0};
+/* We check this often for presence of owning controller process. */
+static const struct timeval poll_interval_tv = {15, 0}; // 15 seconds.
/** Create a process-termination monitor for the process specifier
* given in <b>process_spec</b>. Return a newly allocated
diff --git a/src/lib/log/log.c b/src/lib/log/log.c
index 9ebe7350b2..9ee87c0668 100644
--- a/src/lib/log/log.c
+++ b/src/lib/log/log.c
@@ -665,24 +665,15 @@ tor_log_update_sigsafe_err_fds(void)
const logfile_t *lf;
int found_real_stderr = 0;
- /* log_fds and err_fds contain matching entries: log_fds are the fds used by
- * the log module, and err_fds are the fds used by the err module.
- * For stdio logs, the log_fd and err_fd values are identical,
- * and the err module closes the fd on shutdown.
- * For file logs, the err_fd is a dup() of the log_fd,
- * and the log and err modules both close their respective fds on shutdown.
- * (Once all fds representing a file are closed, the underlying file is
- * closed.)
- */
- int log_fds[TOR_SIGSAFE_LOG_MAX_FDS];
- int err_fds[TOR_SIGSAFE_LOG_MAX_FDS];
+ /* The fds are the file descriptors of tor's stdout, stderr, and file
+ * logs. The log and err modules flush these fds during their shutdowns. */
+ int fds[TOR_SIGSAFE_LOG_MAX_FDS];
int n_fds;
LOCK_LOGS();
/* Reserve the first one for stderr. This is safe because when we daemonize,
- * we dup2 /dev/null to stderr.
- * For stderr, log_fds and err_fds are the same. */
- log_fds[0] = err_fds[0] = STDERR_FILENO;
+ * we dup2 /dev/null to stderr. */
+ fds[0] = STDERR_FILENO;
n_fds = 1;
for (lf = logfiles; lf; lf = lf->next) {
@@ -697,21 +688,11 @@ tor_log_update_sigsafe_err_fds(void)
(LD_BUG|LD_GENERAL)) {
if (lf->fd == STDERR_FILENO)
found_real_stderr = 1;
- /* Avoid duplicates by checking the log module fd against log_fds */
- if (int_array_contains(log_fds, n_fds, lf->fd))
+ /* Avoid duplicates by checking the log module fd against fds */
+ if (int_array_contains(fds, n_fds, lf->fd))
continue;
- /* Update log_fds using the log module's fd */
- log_fds[n_fds] = lf->fd;
- if (lf->needs_close) {
- /* File log fds are duplicated, because close_log() closes the log
- * module's fd, and tor_log_close_sigsafe_err_fds() closes the err
- * module's fd. Both refer to the same file. */
- err_fds[n_fds] = dup(lf->fd);
- } else {
- /* stdio log fds are not closed by the log module.
- * tor_log_close_sigsafe_err_fds() closes stdio logs. */
- err_fds[n_fds] = lf->fd;
- }
+ /* Update fds using the log module's fd */
+ fds[n_fds] = lf->fd;
n_fds++;
if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS)
break;
@@ -719,20 +700,19 @@ tor_log_update_sigsafe_err_fds(void)
}
if (!found_real_stderr &&
- int_array_contains(log_fds, n_fds, STDOUT_FILENO)) {
+ int_array_contains(fds, n_fds, STDOUT_FILENO)) {
/* Don't use a virtual stderr when we're also logging to stdout.
* If we reached max_fds logs, we'll now have (max_fds - 1) logs.
* That's ok, max_fds is large enough that most tor instances don't exceed
* it. */
raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */
--n_fds;
- log_fds[0] = log_fds[n_fds];
- err_fds[0] = err_fds[n_fds];
+ fds[0] = fds[n_fds];
}
UNLOCK_LOGS();
- tor_log_set_sigsafe_err_fds(err_fds, n_fds);
+ tor_log_set_sigsafe_err_fds(fds, n_fds);
}
/** Add to <b>out</b> a copy of every currently configured log file name. Used
@@ -841,16 +821,16 @@ logs_free_all(void)
* log mutex. */
}
-/** Close signal-safe log files.
- * Closing the log files makes the process and OS flush log buffers.
+/** Flush the signal-safe log files.
*
- * This function is safe to call from a signal handler. It should only be
- * called when shutting down the log or err modules. It is currenly called
- * by the err module, when terminating the process on an abnormal condition.
+ * This function is safe to call from a signal handler. It is currenly called
+ * by the BUG() macros, when terminating the process on an abnormal condition.
*/
void
-logs_close_sigsafe(void)
+logs_flush_sigsafe(void)
{
+ /* If we don't have fsync() in unistd.h, we can't flush the logs. */
+#ifdef HAVE_FSYNC
logfile_t *victim, *next;
/* We can't LOCK_LOGS() in a signal handler, because it may call
* signal-unsafe functions. And we can't deallocate memory, either. */
@@ -860,9 +840,11 @@ logs_close_sigsafe(void)
victim = next;
next = next->next;
if (victim->needs_close) {
- close_log_sigsafe(victim);
+ /* We can't do anything useful if the flush fails. */
+ (void)fsync(victim->fd);
}
}
+#endif /* defined(HAVE_FSYNC) */
}
/** Remove and free the log entry <b>victim</b> from the linked-list
diff --git a/src/lib/log/log.h b/src/lib/log/log.h
index cb588635d7..aafbf9be2f 100644
--- a/src/lib/log/log.h
+++ b/src/lib/log/log.h
@@ -186,7 +186,7 @@ void logs_set_domain_logging(int enabled);
int get_min_log_level(void);
void switch_logs_debug(void);
void logs_free_all(void);
-void logs_close_sigsafe(void);
+void logs_flush_sigsafe(void);
void add_default_log(int min_severity);
void close_temp_logs(void);
void rollback_log_changes(void);
diff --git a/src/lib/log/util_bug.c b/src/lib/log/util_bug.c
index 83045ebb90..d698ddd8a6 100644
--- a/src/lib/log/util_bug.c
+++ b/src/lib/log/util_bug.c
@@ -170,7 +170,7 @@ tor_bug_occurred_(const char *fname, unsigned int line,
void
tor_abort_(void)
{
- logs_close_sigsafe();
+ logs_flush_sigsafe();
tor_raw_abort_();
}
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
index 815fb02283..4984494939 100644
--- a/src/lib/net/address.h
+++ b/src/lib/net/address.h
@@ -177,7 +177,7 @@ tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
}
/** Return the address family of <b>a</b>. Possible values are:
- * AF_INET6, AF_INET, AF_UNSPEC. */
+ * AF_INET6, AF_INET, AF_UNSPEC, AF_UNIX. */
static inline sa_family_t
tor_addr_family(const tor_addr_t *a)
{
diff --git a/src/lib/osinfo/uname.c b/src/lib/osinfo/uname.c
index 800acdddb6..f7f5ede307 100644
--- a/src/lib/osinfo/uname.c
+++ b/src/lib/osinfo/uname.c
@@ -59,7 +59,7 @@ static struct {
{ 0, 0, NULL, NULL }
// clang-format on
};
-#endif
+#endif /* defined(_WIN32) */
/** Return a pointer to a description of our platform.
*/
diff --git a/src/test/conf_examples/large_1/expected b/src/test/conf_examples/large_1/expected
index 5866f5823e..99a12ffc84 100644
--- a/src/test/conf_examples/large_1/expected
+++ b/src/test/conf_examples/large_1/expected
@@ -15,7 +15,6 @@ CellStatistics 1
CircuitBuildTimeout 200
CircuitsAvailableTimeout 10
CircuitStreamTimeout 20
-ClientAutoIPv6ORPort 1
ClientOnly 1
ClientPreferIPv6DirPort 1
ClientPreferIPv6ORPort 1
diff --git a/src/test/conf_examples/large_1/expected_no_dirauth b/src/test/conf_examples/large_1/expected_no_dirauth
index 17c11f85fc..26a33bdc7c 100644
--- a/src/test/conf_examples/large_1/expected_no_dirauth
+++ b/src/test/conf_examples/large_1/expected_no_dirauth
@@ -15,7 +15,6 @@ CellStatistics 1
CircuitBuildTimeout 200
CircuitsAvailableTimeout 10
CircuitStreamTimeout 20
-ClientAutoIPv6ORPort 1
ClientOnly 1
ClientPreferIPv6DirPort 1
ClientPreferIPv6ORPort 1
diff --git a/src/test/conf_examples/large_1/torrc b/src/test/conf_examples/large_1/torrc
index e99acd9fb7..20ddf00e16 100644
--- a/src/test/conf_examples/large_1/torrc
+++ b/src/test/conf_examples/large_1/torrc
@@ -16,7 +16,6 @@ CircuitBuildTimeout 200
CircuitPadding 1
CircuitsAvailableTimeout 10
CircuitStreamTimeout 20
-ClientAutoIPv6ORPort 1
ClientOnly 1
ClientPreferIPv6DirPort 1
ClientPreferIPv6ORPort 1
diff --git a/src/test/conf_examples/relay_30/error_no_dirauth_relay b/src/test/conf_examples/relay_30/error_no_dirauth_relay
new file mode 100644
index 0000000000..9f9c0fd8f3
--- /dev/null
+++ b/src/test/conf_examples/relay_30/error_no_dirauth_relay
@@ -0,0 +1 @@
+This tor was built with relay mode disabled.
diff --git a/src/test/conf_examples/relay_30/expected b/src/test/conf_examples/relay_30/expected
new file mode 100644
index 0000000000..3a4e9feb3f
--- /dev/null
+++ b/src/test/conf_examples/relay_30/expected
@@ -0,0 +1,2 @@
+Nickname Unnamed
+ORPort auto
diff --git a/src/test/conf_examples/relay_30/expected_log b/src/test/conf_examples/relay_30/expected_log
new file mode 100644
index 0000000000..d5478c1a15
--- /dev/null
+++ b/src/test/conf_examples/relay_30/expected_log
@@ -0,0 +1 @@
+Your ContactInfo config option is not set \ No newline at end of file
diff --git a/src/test/conf_examples/relay_30/torrc b/src/test/conf_examples/relay_30/torrc
new file mode 100644
index 0000000000..bf8487fe16
--- /dev/null
+++ b/src/test/conf_examples/relay_30/torrc
@@ -0,0 +1,3 @@
+# Relay tests
+# default (IPv4) ORPort auto
+ORPort auto
diff --git a/src/test/conf_examples/relay_31/error_no_dirauth_relay b/src/test/conf_examples/relay_31/error_no_dirauth_relay
new file mode 100644
index 0000000000..9f9c0fd8f3
--- /dev/null
+++ b/src/test/conf_examples/relay_31/error_no_dirauth_relay
@@ -0,0 +1 @@
+This tor was built with relay mode disabled.
diff --git a/src/test/conf_examples/relay_31/expected b/src/test/conf_examples/relay_31/expected
new file mode 100644
index 0000000000..9a40cdd588
--- /dev/null
+++ b/src/test/conf_examples/relay_31/expected
@@ -0,0 +1,3 @@
+DirPort auto
+Nickname Unnamed
+ORPort auto
diff --git a/src/test/conf_examples/relay_31/expected_log b/src/test/conf_examples/relay_31/expected_log
new file mode 100644
index 0000000000..d5478c1a15
--- /dev/null
+++ b/src/test/conf_examples/relay_31/expected_log
@@ -0,0 +1 @@
+Your ContactInfo config option is not set \ No newline at end of file
diff --git a/src/test/conf_examples/relay_31/torrc b/src/test/conf_examples/relay_31/torrc
new file mode 100644
index 0000000000..e662bb71b3
--- /dev/null
+++ b/src/test/conf_examples/relay_31/torrc
@@ -0,0 +1,4 @@
+# Relay tests
+# default (IPv4) ORPort and DirPort auto
+ORPort auto
+DirPort auto
diff --git a/src/test/conf_examples/relay_32/error_no_dirauth_relay b/src/test/conf_examples/relay_32/error_no_dirauth_relay
new file mode 100644
index 0000000000..9f9c0fd8f3
--- /dev/null
+++ b/src/test/conf_examples/relay_32/error_no_dirauth_relay
@@ -0,0 +1 @@
+This tor was built with relay mode disabled.
diff --git a/src/test/conf_examples/relay_32/expected b/src/test/conf_examples/relay_32/expected
new file mode 100644
index 0000000000..14b36c8259
--- /dev/null
+++ b/src/test/conf_examples/relay_32/expected
@@ -0,0 +1,3 @@
+Nickname Unnamed
+ORPort auto
+ORPort [::1]:auto
diff --git a/src/test/conf_examples/relay_32/expected_log b/src/test/conf_examples/relay_32/expected_log
new file mode 100644
index 0000000000..d5478c1a15
--- /dev/null
+++ b/src/test/conf_examples/relay_32/expected_log
@@ -0,0 +1 @@
+Your ContactInfo config option is not set \ No newline at end of file
diff --git a/src/test/conf_examples/relay_32/torrc b/src/test/conf_examples/relay_32/torrc
new file mode 100644
index 0000000000..95a66c4852
--- /dev/null
+++ b/src/test/conf_examples/relay_32/torrc
@@ -0,0 +1,4 @@
+# Relay tests
+# default (IPv4) ORPort auto and IPv6 ORPort auto
+ORPort auto
+ORPort [::1]:auto
diff --git a/src/test/conf_examples/relay_33/error_no_dirauth_relay b/src/test/conf_examples/relay_33/error_no_dirauth_relay
new file mode 100644
index 0000000000..9f9c0fd8f3
--- /dev/null
+++ b/src/test/conf_examples/relay_33/error_no_dirauth_relay
@@ -0,0 +1 @@
+This tor was built with relay mode disabled.
diff --git a/src/test/conf_examples/relay_33/expected b/src/test/conf_examples/relay_33/expected
new file mode 100644
index 0000000000..22567cbe2e
--- /dev/null
+++ b/src/test/conf_examples/relay_33/expected
@@ -0,0 +1,3 @@
+Nickname Unnamed
+ORPort 127.0.0.1:auto
+ORPort [::1]:auto
diff --git a/src/test/conf_examples/relay_33/expected_log b/src/test/conf_examples/relay_33/expected_log
new file mode 100644
index 0000000000..d5478c1a15
--- /dev/null
+++ b/src/test/conf_examples/relay_33/expected_log
@@ -0,0 +1 @@
+Your ContactInfo config option is not set \ No newline at end of file
diff --git a/src/test/conf_examples/relay_33/torrc b/src/test/conf_examples/relay_33/torrc
new file mode 100644
index 0000000000..44d16ad31a
--- /dev/null
+++ b/src/test/conf_examples/relay_33/torrc
@@ -0,0 +1,4 @@
+# Relay tests
+# explicit IPv4 ORPort auto and IPv6 ORPort auto
+ORPort 127.0.0.1:auto
+ORPort [::1]:auto
diff --git a/src/test/conf_examples/relay_34/error_no_dirauth_relay b/src/test/conf_examples/relay_34/error_no_dirauth_relay
new file mode 100644
index 0000000000..9f9c0fd8f3
--- /dev/null
+++ b/src/test/conf_examples/relay_34/error_no_dirauth_relay
@@ -0,0 +1 @@
+This tor was built with relay mode disabled.
diff --git a/src/test/conf_examples/relay_34/expected b/src/test/conf_examples/relay_34/expected
new file mode 100644
index 0000000000..bccde684f3
--- /dev/null
+++ b/src/test/conf_examples/relay_34/expected
@@ -0,0 +1,4 @@
+DirPort 127.0.0.1:auto
+Nickname Unnamed
+ORPort 127.0.0.1:auto
+ORPort [::1]:auto
diff --git a/src/test/conf_examples/relay_34/expected_log b/src/test/conf_examples/relay_34/expected_log
new file mode 100644
index 0000000000..d5478c1a15
--- /dev/null
+++ b/src/test/conf_examples/relay_34/expected_log
@@ -0,0 +1 @@
+Your ContactInfo config option is not set \ No newline at end of file
diff --git a/src/test/conf_examples/relay_34/torrc b/src/test/conf_examples/relay_34/torrc
new file mode 100644
index 0000000000..01010a5c38
--- /dev/null
+++ b/src/test/conf_examples/relay_34/torrc
@@ -0,0 +1,5 @@
+# Relay tests
+# explicit IPv4 ORPort and DirPort auto and IPv6 ORPort auto
+ORPort 127.0.0.1:auto
+ORPort [::1]:auto
+DirPort 127.0.0.1:auto
diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c
index 70920c0c52..10d78abc35 100644
--- a/src/test/test_circuitbuild.c
+++ b/src/test/test_circuitbuild.c
@@ -114,6 +114,14 @@ test_new_route_len_unhandled_exit(void *arg)
int r;
(void)arg;
+#ifdef ALL_BUGS_ARE_FATAL
+ /* Coverity (and maybe clang analyser) complain that the code following
+ * tt_skip() is unconditionally unreachable. */
+#if !defined(__COVERITY__) && !defined(__clang_analyzer__)
+ tt_skip();
+#endif
+#endif
+
MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
tor_capture_bugs_(1);
diff --git a/src/test/test_config.c b/src/test/test_config.c
index ee277104fb..9ccdbc72c0 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -4956,6 +4956,71 @@ test_config_parse_port_config__ports__server_options(void *data)
}
static void
+test_config_get_first_advertised(void *data)
+{
+ (void)data;
+ int r, w=0, n=0;
+ char *msg=NULL;
+ or_options_t *opts = options_new();
+ int port;
+ const tor_addr_t *addr;
+
+ // no ports are configured? We get NULL.
+ port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET);
+ tt_int_op(port, OP_EQ, 0);
+ addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET);
+ tt_ptr_op(addr, OP_EQ, NULL);
+
+ port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET6);
+ tt_int_op(port, OP_EQ, 0);
+ addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET6);
+ tt_ptr_op(addr, OP_EQ, NULL);
+
+ config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:8080");
+ config_line_append(&opts->ORPort_lines, "ORPort",
+ "1.2.3.4:9999 noadvertise");
+ config_line_append(&opts->ORPort_lines, "ORPort",
+ "5.6.7.8:9911 nolisten");
+
+ r = parse_ports(opts, 0, &msg, &n, &w);
+ tt_assert(r == 0);
+
+ // UNSPEC gets us nothing.
+ port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_UNSPEC);
+ tt_int_op(port, OP_EQ, 0);
+ addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_UNSPEC);
+ tt_ptr_op(addr, OP_EQ, NULL);
+
+ // Try AF_INET.
+ port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET);
+ tt_int_op(port, OP_EQ, 9911);
+ addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET);
+ tt_ptr_op(addr, OP_NE, NULL);
+ tt_str_op(fmt_addrport(addr,port), OP_EQ, "5.6.7.8:9911");
+
+ // Try AF_INET6
+ port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET6);
+ tt_int_op(port, OP_EQ, 8080);
+ addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+ AF_INET6);
+ tt_ptr_op(addr, OP_NE, NULL);
+ tt_str_op(fmt_addrport(addr,port), OP_EQ, "[1234::5678]:8080");
+
+ done:
+ or_options_free(opts);
+ config_free_all();
+}
+
+static void
test_config_parse_log_severity(void *data)
{
int ret;
@@ -6203,6 +6268,7 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(parse_port_config__ports__no_ports_given, 0),
CONFIG_TEST(parse_port_config__ports__server_options, 0),
CONFIG_TEST(parse_port_config__ports__ports_given, 0),
+ CONFIG_TEST(get_first_advertised, TT_FORK),
CONFIG_TEST(parse_log_severity, 0),
CONFIG_TEST(include_limit, 0),
CONFIG_TEST(include_does_not_exist, 0),
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 46e1a19ca8..0d75a212e9 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1336,6 +1336,44 @@ test_crypto_pk_pem_encrypted(void *arg)
}
static void
+test_crypto_pk_bad_size(void *arg)
+{
+ (void)arg;
+ crypto_pk_t *pk1 = pk_generate(0);
+ crypto_pk_t *pk2 = NULL;
+ char buf[2048];
+ int n = crypto_pk_asn1_encode_private(pk1, buf, sizeof(buf));
+ tt_int_op(n, OP_GT, 0);
+
+ /* Set the max bit count smaller: we should refuse to decode the key.*/
+ pk2 = crypto_pk_asn1_decode_private(buf, n, 1020);
+ tt_assert(! pk2);
+
+ /* Set the max bit count one bit smaller: we should refuse to decode the
+ key.*/
+ pk2 = crypto_pk_asn1_decode_private(buf, n, 1023);
+ tt_assert(! pk2);
+
+ /* Correct size: should work. */
+ pk2 = crypto_pk_asn1_decode_private(buf, n, 1024);
+ tt_assert(pk2);
+ crypto_pk_free(pk2);
+
+ /* One bit larger: should work. */
+ pk2 = crypto_pk_asn1_decode_private(buf, n, 1025);
+ tt_assert(pk2);
+ crypto_pk_free(pk2);
+
+ /* Set the max bit count larger: it should decode fine. */
+ pk2 = crypto_pk_asn1_decode_private(buf, n, 2048);
+ tt_assert(pk2);
+
+ done:
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
+}
+
+static void
test_crypto_pk_invalid_private_key(void *arg)
{
(void)arg;
@@ -3000,6 +3038,7 @@ struct testcase_t crypto_tests[] = {
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
{ "pk_base64", test_crypto_pk_base64, TT_FORK, NULL, NULL },
{ "pk_pem_encrypted", test_crypto_pk_pem_encrypted, TT_FORK, NULL, NULL },
+ { "pk_bad_size", test_crypto_pk_bad_size, 0, NULL, NULL },
{ "pk_invalid_private_key", test_crypto_pk_invalid_private_key, 0,
NULL, NULL },
CRYPTO_LEGACY(digests),
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index b66938d7c0..bf9a04b079 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -3005,6 +3005,7 @@ test_dir_param_voting_lookup(void *arg)
tt_int_op(99, OP_EQ,
dirvote_get_intermediate_param_value(lst, "abcd", 1000));
+#ifndef ALL_BUGS_ARE_FATAL
/* moomin appears twice. That's a bug. */
tor_capture_bugs_(1);
tt_int_op(-100, OP_EQ,
@@ -3040,6 +3041,7 @@ test_dir_param_voting_lookup(void *arg)
tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
"!(!ok)");
tor_end_capture_bugs_();
+#endif
done:
SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
@@ -4989,6 +4991,14 @@ test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
{
(void)arg;
+#ifdef ALL_BUGS_ARE_FATAL
+ /* Coverity (and maybe clang analyser) complain that the code following
+ * tt_skip() is unconditionally unreachable. */
+#if !defined(__COVERITY__) && !defined(__clang_analyzer__)
+ tt_skip();
+#endif
+#endif
+
tor_capture_bugs_(1);
setup_full_capture_of_logs(LOG_WARN);
tt_int_op(1, OP_EQ, purpose_needs_anonymity(0, 0, NULL));
diff --git a/src/test/test_dos.c b/src/test/test_dos.c
index b6a83210b7..527e5bbe7f 100644
--- a/src/test/test_dos.c
+++ b/src/test/test_dos.c
@@ -79,7 +79,7 @@ test_dos_conn_creation(void *arg)
{ /* Register many conns from this client but not enough to get it blocked */
unsigned int i;
for (i = 0; i < max_concurrent_conns; i++) {
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
}
}
@@ -88,7 +88,7 @@ test_dos_conn_creation(void *arg)
dos_conn_addr_get_defense_type(addr));
/* Register another conn and check that new conns are not allowed anymore */
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
dos_conn_addr_get_defense_type(addr));
@@ -98,7 +98,7 @@ test_dos_conn_creation(void *arg)
dos_conn_addr_get_defense_type(addr));
/* Register another conn and see that defense measures get reactivated */
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
dos_conn_addr_get_defense_type(addr));
@@ -153,7 +153,7 @@ test_dos_circuit_creation(void *arg)
* circuit counting subsystem */
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
for (i = 0; i < min_conc_conns_for_cc ; i++) {
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
}
/* Register new circuits for this client and conn, but not enough to get
@@ -217,7 +217,7 @@ test_dos_bucket_refill(void *arg)
/* Register this client */
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
/* Fetch this client from the geoip cache and get its DoS structs */
clientmap_entry_t *entry = geoip_lookup_client(addr, NULL,
@@ -460,11 +460,11 @@ test_known_relay(void *arg)
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0);
/* Suppose we have 5 connections in rapid succession, the counter should
* always be 0 because we should ignore this. */
- dos_new_client_conn(&or_conn);
- dos_new_client_conn(&or_conn);
- dos_new_client_conn(&or_conn);
- dos_new_client_conn(&or_conn);
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
+ dos_new_client_conn(&or_conn, NULL);
+ dos_new_client_conn(&or_conn, NULL);
+ dos_new_client_conn(&or_conn, NULL);
+ dos_new_client_conn(&or_conn, NULL);
entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT);
tt_assert(entry);
/* We should have a count of 0. */
@@ -474,8 +474,8 @@ test_known_relay(void *arg)
* connection and see if we do get it. */
tor_addr_parse(&or_conn.real_addr, "42.42.42.43");
geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0);
- dos_new_client_conn(&or_conn);
- dos_new_client_conn(&or_conn);
+ dos_new_client_conn(&or_conn, NULL);
+ dos_new_client_conn(&or_conn, NULL);
entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT);
tt_assert(entry);
/* We should have a count of 2. */
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 2e603ec259..3d6422a83c 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -966,6 +966,7 @@ test_close_intro_circuits_new_desc(void *arg)
(void) arg;
hs_init();
+ rend_cache_init();
/* This is needed because of the client cache expiration timestamp is based
* on having a consensus. See cached_client_descriptor_has_expired(). */
@@ -990,6 +991,51 @@ test_close_intro_circuits_new_desc(void *arg)
circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING;
ocirc = TO_ORIGIN_CIRCUIT(circ);
+ /* Build a descriptor _without_ client authorization and thus not
+ * decryptable. Make sure the close circuit code path is not triggered. */
+ {
+ char *desc_encoded = NULL;
+ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
+ curve25519_keypair_t client_kp;
+ hs_descriptor_t *desc = NULL;
+
+ tt_int_op(0, OP_EQ, curve25519_keypair_generate(&client_kp, 0));
+ crypto_rand((char *) descriptor_cookie, sizeof(descriptor_cookie));
+
+ desc = hs_helper_build_hs_desc_with_client_auth(descriptor_cookie,
+ &client_kp.pubkey,
+ &service_kp);
+ tt_assert(desc);
+ ret = hs_desc_encode_descriptor(desc, &service_kp, descriptor_cookie,
+ &desc_encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ /* Associate descriptor intro key with the dummy circuit. */
+ const hs_desc_intro_point_t *ip =
+ smartlist_get(desc->encrypted_data.intro_points, 0);
+ tt_assert(ip);
+ ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey);
+ ed25519_pubkey_copy(&ocirc->hs_ident->intro_auth_pk,
+ &ip->auth_key_cert->signed_key);
+ hs_descriptor_free(desc);
+ tt_assert(desc_encoded);
+ /* Put it in the cache. Should not be decrypted since the client
+ * authorization creds were not added to the global map. */
+ ret = hs_cache_store_as_client(desc_encoded, &service_kp.pubkey);
+ tor_free(desc_encoded);
+ tt_int_op(ret, OP_EQ, HS_DESC_DECODE_NEED_CLIENT_AUTH);
+
+ /* Clean cache with a future timestamp. It will trigger the clean up and
+ * attempt to close the circuit but only if the descriptor is decryptable.
+ * Cache object should be removed and circuit untouched. */
+ hs_cache_clean_as_client(mock_ns.valid_after + (60 * 60 * 24));
+ tt_assert(!hs_cache_lookup_as_client(&service_kp.pubkey));
+
+ /* Make sure the circuit still there. */
+ tt_assert(circuit_get_next_intro_circ(NULL, true));
+ /* Get rid of the ident, it will be replaced in the next tests. */
+ hs_ident_circuit_free(ocirc->hs_ident);
+ }
+
/* Build the first descriptor and cache it. */
{
char *encoded;
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
index 881479016f..9277711d2a 100644
--- a/src/test/test_hs_control.c
+++ b/src/test/test_hs_control.c
@@ -638,6 +638,48 @@ test_hs_control_store_permanent_creds(void *arg)
hs_client_free_all();
}
+/** Test that ADD_ONION properly handles an attacker passing it a bad private
+ * key. */
+static void
+test_hs_control_add_onion_with_bad_pubkey(void *arg)
+{
+ (void) arg;
+
+ MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
+
+ int retval;
+ control_connection_t conn;
+ char *args = NULL;
+ 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();
+ conn.current_cmd = tor_strdup("ADD_ONION");
+ }
+
+ args = tor_strdup("ED25519-V3:AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ "Port=9735,127.0.0.1 Flags=DiscardPK");
+
+ retval = handle_control_command(&conn, (uint32_t) strlen(args), args);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Check control port response */
+ cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ, "551 Failed to generate onion address\r\n");
+
+ done:
+ tor_free(args);
+ tor_free(cp1);
+ buf_free(TO_CONN(&conn)->outbuf);
+ tor_free(conn.current_cmd);
+}
+
struct testcase_t hs_control_tests[] = {
{ "hs_desc_event", test_hs_desc_event, TT_FORK,
NULL, NULL },
@@ -649,6 +691,8 @@ struct testcase_t hs_control_tests[] = {
NULL, NULL },
{ "hs_control_store_permanent_creds",
test_hs_control_store_permanent_creds, TT_FORK, NULL, NULL },
+ { "hs_control_add_onion_with_bad_pubkey",
+ test_hs_control_add_onion_with_bad_pubkey, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c
index 5337188427..3b6e3fd213 100644
--- a/src/test/test_hs_intropoint.c
+++ b/src/test/test_hs_intropoint.c
@@ -757,12 +757,15 @@ test_introduce1_validation(void *arg)
cell = helper_create_introduce1_cell();
tt_assert(cell);
+#ifndef ALL_BUGS_ARE_FATAL
/* It should NOT be a legacy cell which will trigger a BUG(). */
memset(cell->legacy_key_id, 'a', sizeof(cell->legacy_key_id));
tor_capture_bugs_(1);
ret = validate_introduce1_parsed_cell(cell);
tor_end_capture_bugs_();
tt_int_op(ret, OP_EQ, -1);
+#endif
+
/* Reset legacy ID and make sure it's correct. */
memset(cell->legacy_key_id, 0, sizeof(cell->legacy_key_id));
ret = validate_introduce1_parsed_cell(cell);
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index 685f4c25a7..9966bd108d 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -89,6 +89,13 @@ mock_networkstatus_get_live_consensus(time_t now)
return &mock_ns;
}
+static networkstatus_t *
+mock_networkstatus_get_live_consensus_null(time_t now)
+{
+ (void) now;
+ return NULL;
+}
+
static or_state_t *dummy_state = NULL;
/* Mock function to get fake or state (used for rev counters) */
@@ -136,6 +143,20 @@ mock_relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
return 0;
}
+static unsigned int num_intro_points = 0;
+static unsigned int
+mock_count_desc_circuit_established(const hs_service_descriptor_t *desc)
+{
+ (void) desc;
+ return num_intro_points;
+}
+
+static int
+mock_router_have_minimum_dir_info_false(void)
+{
+ return 0;
+}
+
/* Helper: from a set of options in conf, configure a service which will add
* it to the staging list of the HS subsytem. */
static int
@@ -2520,6 +2541,148 @@ test_intro2_handling(void *arg)
UNMOCK(launch_rendezvous_point_circuit);
}
+static void
+test_cannot_upload_descriptors(void *arg)
+{
+ int ret;
+ time_t now;
+ hs_service_t *service;
+
+ (void) arg;
+
+ hs_init();
+ MOCK(get_or_state,
+ get_or_state_replacement);
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+
+ dummy_state = or_state_new();
+
+ ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
+ &mock_ns.valid_after);
+ tt_int_op(ret, OP_EQ, 0);
+ ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
+ &mock_ns.fresh_until);
+ tt_int_op(ret, OP_EQ, 0);
+ dirauth_sched_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ update_approx_time(mock_ns.valid_after + 1);
+ now = mock_ns.valid_after + 1;
+
+ /* Create a service with no descriptor. It's added to the global map. */
+ service = hs_service_new(get_options());
+ tt_assert(service);
+ service->config.version = HS_VERSION_THREE;
+ ed25519_secret_key_generate(&service->keys.identity_sk, 0);
+ ed25519_public_key_generate(&service->keys.identity_pk,
+ &service->keys.identity_sk);
+ /* Register service to global map. */
+ ret = register_service(get_hs_service_map(), service);
+ tt_int_op(ret, OP_EQ, 0);
+ /* But first, build our descriptor. */
+ build_all_descriptors(now);
+
+ /* 1. Testing missing intro points reason. */
+ {
+ digest256map_t *cur = service->desc_current->intro_points.map;
+ digest256map_t *tmp = digest256map_new();
+ service->desc_current->intro_points.map = tmp;
+ service->desc_current->missing_intro_points = 1;
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ digest256map_free(tmp, tor_free_);
+ service->desc_current->intro_points.map = cur;
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "Missing intro points");
+ teardown_capture_of_logs();
+ /* Reset. */
+ service->desc_current->missing_intro_points = 0;
+ }
+
+ /* 2. Testing non established intro points. */
+ {
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "Intro circuits aren't yet all established (0/3).");
+ teardown_capture_of_logs();
+ }
+
+ /* We need to pass the established circuit tests and thus from now on, we
+ * MOCK this to return 3 intro points. */
+ MOCK(count_desc_circuit_established, mock_count_desc_circuit_established);
+ num_intro_points = 3;
+
+ /* 3. Testing non established intro points. */
+ {
+ service->desc_current->next_upload_time = now + 1000;
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "Next upload time is");
+ teardown_capture_of_logs();
+ /* Reset. */
+ service->desc_current->next_upload_time = 0;
+ }
+
+ /* 4. Testing missing live consensus. */
+ {
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus_null);
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "No live consensus");
+ teardown_capture_of_logs();
+ /* Reset. */
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+ }
+
+ /* 5. Test missing minimum directory information. */
+ {
+ MOCK(router_have_minimum_dir_info,
+ mock_router_have_minimum_dir_info_false);
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "Not enough directory information");
+ teardown_capture_of_logs();
+
+ /* Running it again shouldn't trigger anything due to rate limitation. */
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_no_log_entry();
+ teardown_capture_of_logs();
+ UNMOCK(router_have_minimum_dir_info);
+ }
+
+ /* Increase time and redo test (5) in order to test the rate limiting. */
+ update_approx_time(mock_ns.valid_after + 61);
+ {
+ MOCK(router_have_minimum_dir_info,
+ mock_router_have_minimum_dir_info_false);
+ setup_full_capture_of_logs(LOG_INFO);
+ run_upload_descriptor_event(now);
+ expect_log_msg_containing(
+ "Service [scrubbed] can't upload its current descriptor: "
+ "Not enough directory information");
+ teardown_capture_of_logs();
+ UNMOCK(router_have_minimum_dir_info);
+ }
+
+ done:
+ hs_free_all();
+ UNMOCK(count_desc_circuit_established);
+ UNMOCK(networkstatus_get_live_consensus);
+ UNMOCK(get_or_state);
+}
+
struct testcase_t hs_service_tests[] = {
{ "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK,
NULL, NULL },
@@ -2557,6 +2720,8 @@ struct testcase_t hs_service_tests[] = {
NULL, NULL },
{ "upload_descriptors", test_upload_descriptors, TT_FORK,
NULL, NULL },
+ { "cannot_upload_descriptors", test_cannot_upload_descriptors, TT_FORK,
+ NULL, NULL },
{ "rendezvous1_parsing", test_rendezvous1_parsing, TT_FORK,
NULL, NULL },
{ "authorized_client_config_equal", test_authorized_client_config_equal,
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 636d3c0e54..9cd1d11d29 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -490,7 +490,8 @@ test_options_validate__uname_for_server(void *ignored)
#endif
options_test_data_t *tdata = get_options_test_data(
- "ORPort 127.0.0.1:5555");
+ "ORPort 127.0.0.1:5555\n"
+ "ContactInfo nobody@example.com");
setup_capture_of_logs(LOG_WARN);
MOCK(get_uname, fixed_get_uname);
@@ -636,9 +637,11 @@ test_options_validate__contactinfo(void *ignored)
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, 0);
expect_log_msg(
- "Your ContactInfo config option is not"
- " set. Please consider setting it, so we can contact you if your"
- " server is misconfigured or something else goes wrong.\n");
+ "Your ContactInfo config option is not set. Please strongly "
+ "consider setting it, so we can contact you if your relay is "
+ "misconfigured, end-of-life, or something else goes wrong. It "
+ "is also possible that your relay might get rejected from the "
+ "network due to a missing valid contact address.\n");
tor_free(msg);
free_options_test_data(tdata);
@@ -648,9 +651,11 @@ test_options_validate__contactinfo(void *ignored)
ret = options_validate(NULL, tdata->opt, &msg);
tt_int_op(ret, OP_EQ, 0);
expect_no_log_msg(
- "Your ContactInfo config option is not"
- " set. Please consider setting it, so we can contact you if your"
- " server is misconfigured or something else goes wrong.\n");
+ "Your ContactInfo config option is not set. Please strongly "
+ "consider setting it, so we can contact you if your relay is "
+ "misconfigured, end-of-life, or something else goes wrong. It "
+ "is also possible that your relay might get rejected from the "
+ "network due to a missing valid contact address.\n");
tor_free(msg);
done:
diff --git a/src/test/test_pem.c b/src/test/test_pem.c
index 8f9f10f787..9772be124b 100644
--- a/src/test/test_pem.c
+++ b/src/test/test_pem.c
@@ -115,8 +115,38 @@ test_crypto_pem_decode(void *arg)
;
}
+static void
+test_crypto_pem_decode_crlf(void *arg)
+{
+ (void)arg;
+ char crlf_version[4096];
+ uint8_t buf[4096];
+
+ /* Convert 'expected' to a version with CRLF instead of LF. */
+ const char *inp = expected;
+ char *outp = crlf_version;
+ while (*inp) {
+ if (*inp == '\n') {
+ *outp++ = '\r';
+ }
+ *outp++ = *inp++;
+ }
+ *outp = 0;
+
+ /* Decoding should succeed (or else we have bug 33032 again) */
+ int n = pem_decode(buf, sizeof(buf),
+ crlf_version, strlen(crlf_version),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ tt_mem_op(buf, OP_EQ, example_pre, n);
+
+ done:
+ ;
+}
+
struct testcase_t pem_tests[] = {
{ "encode", test_crypto_pem_encode, 0, NULL, NULL },
{ "decode", test_crypto_pem_decode, 0, NULL, NULL },
+ { "decode_crlf", test_crypto_pem_decode_crlf, 0, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 762241249c..7949e90e9e 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -62,8 +62,8 @@ test_policy_summary_helper_family_flags(const char *policy_str,
short_policy_t *short_policy = NULL;
int success = 0;
- line.key = (char*)"foo";
- line.value = (char *)policy_str;
+ line.key = (char *) "foo";
+ line.value = (char *) policy_str;
line.next = NULL;
r = policies_parse_exit_policy(&line, &policy,
@@ -2124,20 +2124,6 @@ test_policies_fascist_firewall_allows_address(void *arg)
teardown_capture_of_logs(); \
STMT_END
-/** Mock the preferred address function to return zero (prefer IPv4). */
-static int
-mock_fascist_firewall_rand_prefer_ipv6_addr_use_ipv4(void)
-{
- return 0;
-}
-
-/** Mock the preferred address function to return one (prefer IPv6). */
-static int
-mock_fascist_firewall_rand_prefer_ipv6_addr_use_ipv6(void)
-{
- return 1;
-}
-
/** Run unit tests for fascist_firewall_choose_address */
static void
test_policies_fascist_firewall_choose_address(void *arg)
@@ -2536,42 +2522,6 @@ test_policies_fascist_firewall_choose_address(void *arg)
CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_DIR_CONNECTION, 1, 1,
ipv4_dir_ap);
- /* Test ClientAutoIPv6ORPort and pretend we prefer IPv4. */
- memset(&mock_options, 0, sizeof(or_options_t));
- mock_options.ClientAutoIPv6ORPort = 1;
- mock_options.ClientUseIPv4 = 1;
- mock_options.ClientUseIPv6 = 1;
- MOCK(fascist_firewall_rand_prefer_ipv6_addr,
- mock_fascist_firewall_rand_prefer_ipv6_addr_use_ipv4);
- /* Simulate the initialisation of fake_node.ipv6_preferred */
- fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport(
- &mock_options);
-
- CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1,
- ipv4_or_ap);
- CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1,
- ipv4_or_ap);
-
- UNMOCK(fascist_firewall_rand_prefer_ipv6_addr);
-
- /* Test ClientAutoIPv6ORPort and pretend we prefer IPv6. */
- memset(&mock_options, 0, sizeof(or_options_t));
- mock_options.ClientAutoIPv6ORPort = 1;
- mock_options.ClientUseIPv4 = 1;
- mock_options.ClientUseIPv6 = 1;
- MOCK(fascist_firewall_rand_prefer_ipv6_addr,
- mock_fascist_firewall_rand_prefer_ipv6_addr_use_ipv6);
- /* Simulate the initialisation of fake_node.ipv6_preferred */
- fake_node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport(
- &mock_options);
-
- CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 0, 1,
- ipv6_or_ap);
- CHECK_CHOSEN_ADDR_RN(fake_rs, fake_node, FIREWALL_OR_CONNECTION, 1, 1,
- ipv6_or_ap);
-
- UNMOCK(fascist_firewall_rand_prefer_ipv6_addr);
-
/* Test firewall_choose_address_ls(). To do this, we make a fake link
* specifier. */
smartlist_t *lspecs = smartlist_new(),
diff --git a/src/test/test_process_descs.c b/src/test/test_process_descs.c
index 0e9cc9d253..14865cff13 100644
--- a/src/test/test_process_descs.c
+++ b/src/test/test_process_descs.c
@@ -20,13 +20,10 @@ test_process_descs_versions(void *arg)
{ "Tor 0.1.2.3-alpha", true },
// a non-tor program: don't reject.
{ "Wombat 0.1.2.3-alpha", false },
- // a slightly old version: reject
- { "Tor 0.2.9.4-alpha", true },
- // a slightly old version: just new enough to support.
- { "Tor 0.2.9.5-alpha", false },
- // a newer 0.2.9 version: supported.
- { "Tor 0.2.9.100", false },
// some unsupported versions: reject.
+ { "Tor 0.2.9.4-alpha", true },
+ { "Tor 0.2.9.5-alpha", true },
+ { "Tor 0.2.9.100", true },
{ "Tor 0.3.0.0-alpha-dev", true },
{ "Tor 0.3.0.2-alpha", true },
{ "Tor 0.3.0.5", true },
@@ -37,11 +34,17 @@ test_process_descs_versions(void *arg)
{ "Tor 0.3.4.100", true },
{ "Tor 0.3.5.1-alpha", true },
{ "Tor 0.3.5.6-rc", true},
+ { "Tor 0.4.0.1-alpha", true },
+ { "Tor 0.4.0.5", true },
+ { "Tor 0.4.1.1-alpha", true },
+ { "Tor 0.4.1.4-rc", true },
// new enough to be supported
{ "Tor 0.3.5.7", false },
{ "Tor 0.3.5.8", false },
- { "Tor 0.4.0.1-alpha", false },
{ "Tor 0.4.1.5", false },
+ { "Tor 0.4.2.1-alpha", false },
+ { "Tor 0.4.2.4-rc", false },
+ { "Tor 0.4.3.0-alpha-dev", false },
// Very far in the future
{ "Tor 100.100.1.5", false },
};
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index 7d08911021..c33fbcae2c 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -317,6 +317,7 @@ test_protover_all_supported(void *arg)
tt_assert(protover_all_supported("Fribble=", &msg));
tt_ptr_op(msg, OP_EQ, NULL);
+#ifndef ALL_BUGS_ARE_FATAL
/* If we get a completely unparseable list, protover_all_supported should
* hit a fatal assertion for BUG(entries == NULL). */
tor_capture_bugs_(1);
@@ -328,9 +329,10 @@ test_protover_all_supported(void *arg)
tor_capture_bugs_(1);
tt_assert(protover_all_supported("Sleen=1-4294967295", &msg));
tor_end_capture_bugs_();
+#endif /* !defined(ALL_BUGS_ARE_FATAL) */
/* Protocol name too long */
-#ifndef HAVE_RUST // XXXXXX ?????
+#if !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL)
tor_capture_bugs_(1);
tt_assert(protover_all_supported(
"DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -338,7 +340,7 @@ test_protover_all_supported(void *arg)
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaa=1-65536", &msg));
tor_end_capture_bugs_();
-#endif /* !defined(HAVE_RUST) */
+#endif /* !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL) */
done:
tor_end_capture_bugs_();
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 572ddceaa7..cf0c2b3dd1 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -8,11 +8,13 @@
**/
#define CONFIG_PRIVATE
+#define CONNECTION_PRIVATE
#define ROUTER_PRIVATE
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/mainloop.h"
+#include "core/mainloop/connection.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/networkstatus_st.h"
@@ -27,6 +29,8 @@
#include "lib/crypt_ops/crypto_ed25519.h"
#include "lib/encoding/confline.h"
+#include "core/or/listener_connection_st.h"
+
/* Test suite stuff */
#include "test/test.h"
#include "test/log_test_helpers.h"
@@ -486,6 +490,117 @@ test_router_get_my_family(void *arg)
#undef CLEAR
}
+static smartlist_t *fake_connection_array = NULL;
+static smartlist_t *
+mock_get_connection_array(void)
+{
+ return fake_connection_array;
+}
+
+static void
+test_router_get_advertised_or_port(void *arg)
+{
+ (void)arg;
+ int r, w=0, n=0;
+ char *msg=NULL;
+ or_options_t *opts = options_new();
+ listener_connection_t *listener = NULL;
+ tor_addr_port_t ipv6;
+
+ // Test one failing case of router_get_advertised_ipv6_or_ap().
+ router_get_advertised_ipv6_or_ap(opts, &ipv6);
+ tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+
+ // And one failing case of router_get_advertised_or_port().
+ tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+ tt_int_op(0, OP_EQ, router_get_advertised_or_port(opts));
+
+ // Set up a couple of configured ports.
+ config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:auto");
+ config_line_append(&opts->ORPort_lines, "ORPort", "5.6.7.8:9999");
+ r = parse_ports(opts, 0, &msg, &n, &w);
+ tt_assert(r == 0);
+
+ // There are no listeners, so the "auto" case will turn up no results.
+ tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+ router_get_advertised_ipv6_or_ap(opts, &ipv6);
+ tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+
+ // This will return the matching value from the configured port.
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
+
+ // Now set up a dummy listener.
+ MOCK(get_connection_array, mock_get_connection_array);
+ fake_connection_array = smartlist_new();
+ listener = listener_connection_new(CONN_TYPE_OR_LISTENER, AF_INET6);
+ TO_CONN(listener)->port = 54321;
+ smartlist_add(fake_connection_array, TO_CONN(listener));
+
+ // We should get a port this time.
+ tt_int_op(54321, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+
+ // Test one succeeding case of router_get_advertised_ipv6_or_ap().
+ router_get_advertised_ipv6_or_ap(opts, &ipv6);
+ tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ,
+ "[1234::5678]:54321");
+
+ // This will return the matching value from the configured port.
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
+
+ done:
+ or_options_free(opts);
+ config_free_all();
+ smartlist_free(fake_connection_array);
+ connection_free_minimal(TO_CONN(listener));
+ UNMOCK(get_connection_array);
+}
+
+static void
+test_router_get_advertised_or_port_localhost(void *arg)
+{
+ (void)arg;
+ int r, w=0, n=0;
+ char *msg=NULL;
+ or_options_t *opts = options_new();
+ tor_addr_port_t ipv6;
+
+ // Set up a couple of configured ports on localhost.
+ config_line_append(&opts->ORPort_lines, "ORPort", "[::1]:9999");
+ config_line_append(&opts->ORPort_lines, "ORPort", "127.0.0.1:8888");
+ r = parse_ports(opts, 0, &msg, &n, &w);
+ tt_assert(r == 0);
+
+ // We should refuse to advertise them, since we have default dirauths.
+ router_get_advertised_ipv6_or_ap(opts, &ipv6);
+ tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+ // But the lower-level function should still report the correct value
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+
+ // The IPv4 checks are done in resolve_my_address(), which doesn't use
+ // ORPorts so we can't test them here. (See #33681.) Both these lower-level
+ // functions should still report the correct value.
+ tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+ tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
+
+ // Now try with a fake authority set up.
+ config_line_append(&opts->DirAuthorities, "DirAuthority",
+ "127.0.0.1:1066 "
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+
+ tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+ router_get_advertised_ipv6_or_ap(opts, &ipv6);
+ tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::1]:9999");
+
+ tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+ tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
+
+ done:
+ or_options_free(opts);
+ config_free_all();
+}
+
#define ROUTER_TEST(name, flags) \
{ #name, test_router_ ## name, flags, NULL, NULL }
@@ -494,5 +609,7 @@ struct testcase_t router_tests[] = {
ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
ROUTER_TEST(mark_if_too_old, TT_FORK),
ROUTER_TEST(get_my_family, TT_FORK),
+ ROUTER_TEST(get_advertised_or_port, TT_FORK),
+ ROUTER_TEST(get_advertised_or_port_localhost, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 234ae06745..b2ee7cd35c 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -6419,7 +6419,7 @@ test_util_map_anon_nofork(void *arg)
#else
#define UTIL_TEST_PWDB(n, f) UTIL_TEST(n, (f))
#endif
-#endif
+#endif /* !defined(COCCI) */
struct testcase_t util_tests[] = {
UTIL_LEGACY(time),
diff --git a/src/test/test_util_process.c b/src/test/test_util_process.c
index f0e7334a9b..fc79fe9b1f 100644
--- a/src/test/test_util_process.c
+++ b/src/test/test_util_process.c
@@ -73,7 +73,7 @@ test_util_process_clear_waitpid_callback(void *ignored)
#else
#define TEST(name) { (#name), NULL, TT_SKIP, NULL, NULL }
#endif
-#endif
+#endif /* !defined(COCCI) */
struct testcase_t util_process_tests[] = {
TEST(set_waitpid_callback),
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 16a62bd532..b3337f24b0 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -358,6 +358,21 @@ main(int c, const char **v)
atexit(remove_directory);
+ /* Look for TOR_SKIP_TESTCASES: a space-separated list of tests to skip. */
+ const char *skip_tests = getenv("TOR_SKIP_TESTCASES");
+ if (skip_tests) {
+ smartlist_t *skip = smartlist_new();
+ smartlist_split_string(skip, skip_tests, NULL,
+ SPLIT_IGNORE_BLANK, -1);
+ int n = 0;
+ SMARTLIST_FOREACH_BEGIN(skip, char *, cp) {
+ n += tinytest_skip(testgroups, cp);
+ tor_free(cp);
+ } SMARTLIST_FOREACH_END(cp);
+ printf("Skipping %d testcases.\n", n);
+ smartlist_free(skip);
+ }
+
int have_failed = (tinytest_main(c, v, testgroups) != 0);
free_pregenerated_keys();