aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml18
-rw-r--r--.travis.yml66
-rw-r--r--Makefile.am1
-rw-r--r--changes/bug316694
-rw-r--r--changes/bug330326
-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/bug337827
-rw-r--r--changes/doc329713
-rw-r--r--changes/ticket326724
-rw-r--r--changes/ticket327923
-rw-r--r--changes/ticket330295
-rw-r--r--changes/ticket331198
-rw-r--r--changes/ticket331885
-rw-r--r--changes/ticket331944
-rw-r--r--changes/ticket331954
-rw-r--r--changes/ticket332904
-rw-r--r--changes/ticket333613
-rw-r--r--changes/ticket334604
-rw-r--r--changes/ticket334916
-rw-r--r--changes/ticket336195
-rw-r--r--changes/ticket336232
-rw-r--r--changes/ticket336435
-rw-r--r--changes/ticket33643_part23
-rw-r--r--changes/ticket336464
-rw-r--r--changes/ticket33678_0433
-rw-r--r--changes/ticket338047
-rw-r--r--changes/trove_2020_0034
-rw-r--r--configure.ac6
-rw-r--r--contrib/win32build/tor-mingw.nsi.in2
-rw-r--r--doc/tor.1.txt680
-rw-r--r--scripts/maint/practracker/.enable_practracker_in_hooks1
-rw-r--r--scripts/maint/practracker/exceptions.txt2
-rwxr-xr-xscripts/maint/practracker/practracker.py10
-rw-r--r--src/app/config/config.c4
-rw-r--r--src/core/mainloop/connection.c59
-rw-r--r--src/core/mainloop/connection.h4
-rw-r--r--src/core/or/channel.c2
-rw-r--r--src/core/or/circuitmux.c8
-rw-r--r--src/core/or/circuitmux_ewma.c4
-rw-r--r--src/core/or/circuitmux_ewma.h9
-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/sendme.h2
-rw-r--r--src/feature/dirauth/dirauth_config.c9
-rw-r--r--src/feature/dirauth/dirauth_config.h16
-rw-r--r--src/feature/dirauth/dirauth_options.inc7
-rw-r--r--src/feature/dirauth/dirvote.c24
-rw-r--r--src/feature/dirauth/dirvote.h2
-rw-r--r--src/feature/dirauth/process_descs.c29
-rw-r--r--src/feature/dirauth/process_descs.h17
-rw-r--r--src/feature/dircache/dircache.c13
-rw-r--r--src/feature/dircache/dirserv.h4
-rw-r--r--src/feature/dirparse/parsecommon.c9
-rw-r--r--src/feature/hs/hs_client.c6
-rw-r--r--src/feature/hs/hs_descriptor.c14
-rw-r--r--src/feature/hs/hs_service.c6
-rw-r--r--src/feature/nodelist/dirlist.c31
-rw-r--r--src/feature/nodelist/dirlist.h2
-rw-r--r--src/feature/nodelist/networkstatus.c2
-rw-r--r--src/feature/nodelist/nodelist.c43
-rw-r--r--src/feature/nodelist/nodelist.h2
-rw-r--r--src/feature/relay/relay_config.c19
-rw-r--r--src/feature/relay/relay_config.h17
-rw-r--r--src/lib/cc/compat_compiler.h2
-rw-r--r--src/lib/confmgt/type_defs.c67
-rw-r--r--src/lib/confmgt/typedvar.c11
-rw-r--r--src/lib/confmgt/unitparse.c45
-rw-r--r--src/lib/confmgt/unitparse.h3
-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/evloop/procmon.c4
-rw-r--r--src/test/test_addr.c2
-rw-r--r--src/test/test_address_set.c15
-rw-r--r--src/test/test_bwmgt.c217
-rw-r--r--src/test/test_config.c2
-rw-r--r--src/test/test_connection.h2
-rw-r--r--src/test/test_crypto.c39
-rw-r--r--src/test/test_dos.c24
-rw-r--r--src/test/test_hs_control.c44
-rw-r--r--src/test/test_hs_descriptor.c26
-rw-r--r--src/test/test_options.c39
-rw-r--r--src/test/test_pem.c30
-rw-r--r--src/test/test_process_descs.c17
-rw-r--r--src/test/test_util.c4
-rw-r--r--src/test/testing_common.c15
-rw-r--r--src/win32/orconfig.h2
95 files changed, 1450 insertions, 579 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 7e08602fe3..dbe52d9ea4 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -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/.travis.yml b/.travis.yml
index af5052682f..5e99b04cfb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -41,34 +41,47 @@ env:
matrix:
## include creates builds with gcc, linux, unless we override those defaults
include:
- ## We run basic tests on macOS
+ ## We run chutney on macOS, because macOS Travis has IPv6
+ - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
+ os: osx
+
+ ## We also run basic tests on macOS
- compiler: clang
os: osx
## Turn off some newer features, turn on clang's -Wtypedef-redefinition
env: C_DIALECT_OPTIONS="-std=gnu99"
- ## We check NSS
- ## Use -std=gnu99 to turn off some newer features, and maybe turn on some
- ## extra gcc warnings?
- - env: NSS_OPTIONS="--enable-nss" C_DIALECT_OPTIONS="-std=gnu99"
+
## We run chutney on Linux, because it's faster than chutney on macOS
## Chutney is a fast job, clang is slower on Linux, so we do Chutney clang
- env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
compiler: clang
- ## We check asciidoc with distcheck, to make sure we remove doc products
- ## We use Linux clang, because there are no other Linux clang jobs
- - env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes"
- compiler: clang
- ## We include a single coverage build with the best options for coverage
- - env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS="" TOR_TEST_RNG_SEED="636f766572616765"
- ## We run rust on Linux, because it's faster than rust on macOS
- ## We check rust offline
- - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
+
## We check asciidoc with distcheck, to make sure we remove doc products
- env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes"
+
## We check disable module relay
- env: MODULES_OPTIONS="--disable-module-relay"
## We check disable module dirauth
- env: MODULES_OPTIONS="--disable-module-dirauth"
+
+ ## We run rust on Linux, because it's faster than rust on macOS
+ ## We check rust offline
+ - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
+
+ ## We check NSS
+ ## Use -std=gnu99 to turn off some newer features, and maybe turn on some
+ ## extra gcc warnings?
+ - env: NSS_OPTIONS="--enable-nss" C_DIALECT_OPTIONS="-std=gnu99"
+
+ ## We include a single coverage build with the best options for coverage
+ - env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS="" TOR_TEST_RNG_SEED="636f766572616765"
+
+ ## We clone our stem repo and run `make test-stem`
+ - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes"
+
+ ## We run `make doxygen` without `make check`.
+ - env: SKIP_MAKE_CHECK="yes" DOXYGEN="yes"
+
## macOS builds are very slow, and we have a limited number of
## concurrent macOS jobs. We're not actively developing Rust, so it is
## the lowest priority.
@@ -76,13 +89,6 @@ matrix:
#- env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
# compiler: clang
# os: osx
- ## We run chutney on macOS, because macOS Travis has IPv6
- - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
- os: osx
- ## We clone our stem repo and run `make test-stem`
- - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes"
- ## We run `make doxygen` without `make check`.
- - env: SKIP_MAKE_CHECK="yes" DOXYGEN="yes"
## Allow the build to report success (with non-required sub-builds
## continuing to run) if all required sub-builds have succeeded.
@@ -94,11 +100,17 @@ matrix:
## macOS rust and chutney are very slow, so we let the build finish before
## they are done. We'd like to fast finish, but still eventually show
## any failures in the build status. But Travis doesn't have that ability.
- - env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
- compiler: clang
- os: osx
- - env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
- os: osx
+
+ ## Since this job is disabled, there's not much point having an exception
+ ## for it
+ #- env: RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
+ # compiler: clang
+ # os: osx
+
+ ## Since we're actively developing IPv6, we want to require the IPv6
+ ## chutney tests
+ #- env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
+ # os: osx
## (Linux only) Use a recent Linux image (Ubuntu Bionic)
dist: bionic
@@ -247,7 +259,7 @@ after_failure:
## `make distcheck` puts it somewhere different.
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog || echo "make failed"; fi
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-core || echo "make failed"; fi
- - if [[ "$CHUTNEY" != "" ]]; then ls test_network_log || echo "ls failed"; cat test_network_log/* || echo "cat failed"; fi
+ - if [[ "$CHUTNEY" != "" ]]; then "$CHUTNEY_PATH/tools/diagnostics.sh" || echo "diagnostics failed"; ls test_network_log || echo "ls failed"; cat test_network_log/* || echo "cat failed"; fi
- if [[ "$TEST_STEM" != "" ]]; then tail -1000 "$STEM_SOURCE_DIR"/test/data/tor_log || echo "tail failed"; fi
- if [[ "$TEST_STEM" != "" ]]; then grep -v "SocketClosed" stem.log | tail -1000 || echo "grep | tail failed"; fi
diff --git a/Makefile.am b/Makefile.am
index ac61a990fc..8b55bf0e32 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -271,7 +271,6 @@ check-local: \
check-spaces \
check-changes \
check-includes \
- check-best-practices \
shellcheck \
check-cocci
diff --git a/changes/bug31669 b/changes/bug31669
new file mode 100644
index 0000000000..8079c98f62
--- /dev/null
+++ b/changes/bug31669
@@ -0,0 +1,4 @@
+ o Minor bugfixes (onion services v3):
+ - Relax severity of a log message that can appear naturally when decoding
+ onion service descriptors as a relay. Also add some diagnostics to debug
+ any future bugs in that area. Fixes bug 31669; bugfix on 0.3.0.1-alpha. \ No newline at end of file
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/bug33374 b/changes/bug33374
new file mode 100644
index 0000000000..d1141faf78
--- /dev/null
+++ b/changes/bug33374
@@ -0,0 +1,5 @@
+ o Minor bugfixes (coding best practices checks):
+ - Allow the "practracker" coding best practices checking script to read
+ unicode files, when using Python 2. We made the script use unicode
+ literals in 0.4.3.1-alpha, but didn't change the codec for opening files.
+ Fixes bug 33374; bugfix on 0.4.3.1-alpha.
diff --git a/changes/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/bug33782 b/changes/bug33782
new file mode 100644
index 0000000000..9d4a0e7a79
--- /dev/null
+++ b/changes/bug33782
@@ -0,0 +1,7 @@
+ o Testing:
+ - Avoid conflicts between the fake sockets in tor's unit tests, and real
+ file descriptors. Resolves issues running unit tests with GitHub Actions,
+ where the process that embeds or launches the tests has already opened a
+ large number of file descriptors.
+ Fixes bug 33782; bugfix on 0.2.8.1-alpha.
+ Found and fixed by Putta Khunchalee.
diff --git a/changes/doc32971 b/changes/doc32971
new file mode 100644
index 0000000000..014d2a7cec
--- /dev/null
+++ b/changes/doc32971
@@ -0,0 +1,3 @@
+ o Documentation (manpage):
+ - Document __OwningControllerProcess torrc option and specify polling
+ interval. Resolves issue 32971.
diff --git a/changes/ticket32672 b/changes/ticket32672
new file mode 100644
index 0000000000..351329ba2e
--- /dev/null
+++ b/changes/ticket32672
@@ -0,0 +1,4 @@
+ 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, but still allow the 0.3.5
+ series. Resolves ticket 32672. Patch by Neel Chauhan.
diff --git a/changes/ticket32792 b/changes/ticket32792
new file mode 100644
index 0000000000..553cf0ca81
--- /dev/null
+++ b/changes/ticket32792
@@ -0,0 +1,3 @@
+ o Testing:
+ - When a Travis chutney job fails, use chutney's new "diagnostics.sh" tool
+ to produce detailed diagnostic output. Closes ticket 32792.
diff --git a/changes/ticket33029 b/changes/ticket33029
new file mode 100644
index 0000000000..c32ee4ad84
--- /dev/null
+++ b/changes/ticket33029
@@ -0,0 +1,5 @@
+ o Major bugfixes (directory authority):
+ - Directory authorities will now send a 503 (not enough bandwidth) code to
+ clients when under bandwidth pressure. Known relays and other authorities
+ will always be answered regardless of the bandwidth situation. Fixes bug
+ 33029; bugfix on 0.1.2.5-alpha.
diff --git a/changes/ticket33119 b/changes/ticket33119
new file mode 100644
index 0000000000..11c20bc7a2
--- /dev/null
+++ b/changes/ticket33119
@@ -0,0 +1,8 @@
+ 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. We are also tracking
+ this issue as TROVE-2020-002.
diff --git a/changes/ticket33188 b/changes/ticket33188
new file mode 100644
index 0000000000..7bec15b99b
--- /dev/null
+++ b/changes/ticket33188
@@ -0,0 +1,5 @@
+ o Documentation (manpage):
+ - Alphabetize the Server and Directory server sections of the tor
+ manpage. Also split Statistics options into their own section
+ of the manpage. Closes ticket 33188. Work by Swati Thacker as
+ part of Google Season of Docs.
diff --git a/changes/ticket33194 b/changes/ticket33194
new file mode 100644
index 0000000000..b87e55348e
--- /dev/null
+++ b/changes/ticket33194
@@ -0,0 +1,4 @@
+ o Testing:
+ - Remove a redundant distcheck job. Closes ticket 33194.
+ - Sort the Travis jobs in order of speed. Putting the slowest jobs first
+ takes full advantage of Travis job concurrency. Closes ticket 33194.
diff --git a/changes/ticket33195 b/changes/ticket33195
new file mode 100644
index 0000000000..11abd4816e
--- /dev/null
+++ b/changes/ticket33195
@@ -0,0 +1,4 @@
+ o Testing:
+ - Stop allowing the Chutney IPv6 Travis job to fail. This job was
+ previously configured to fast_finish (which requires allow_failure), to
+ speed up the build. Closes ticket 33195.
diff --git a/changes/ticket33290 b/changes/ticket33290
new file mode 100644
index 0000000000..882764020e
--- /dev/null
+++ b/changes/ticket33290
@@ -0,0 +1,4 @@
+ o Minor features (diagnostic):
+ - Improve assertions and add some memory-poisoning code to try to track
+ down possible causes of a rare crash (32564) in the EWMA code.
+ Closes ticket 33290.
diff --git a/changes/ticket33361 b/changes/ticket33361
new file mode 100644
index 0000000000..bc9715d6a1
--- /dev/null
+++ b/changes/ticket33361
@@ -0,0 +1,3 @@
+ o Minor bugfix (relay, configuration):
+ - Now warn if the ContactInfo field is not set and mention that the relay
+ might get rejected if so. Fixes bug 33361; bugfix on 0.1.1.10-alpha.
diff --git a/changes/ticket33460 b/changes/ticket33460
new file mode 100644
index 0000000000..21e0fc966c
--- /dev/null
+++ b/changes/ticket33460
@@ -0,0 +1,4 @@
+ 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/ticket33619 b/changes/ticket33619
new file mode 100644
index 0000000000..3c52858b35
--- /dev/null
+++ b/changes/ticket33619
@@ -0,0 +1,5 @@
+ o Major bugfixes (circuit padding, memory leaks):
+ - 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.
diff --git a/changes/ticket33623 b/changes/ticket33623
new file mode 100644
index 0000000000..528af3ca02
--- /dev/null
+++ b/changes/ticket33623
@@ -0,0 +1,2 @@
+ o Minor feature (sendme, flow control):
+ - Default on sending SENDME version 1 cells. Closes ticket 33623.
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/changes/ticket33646 b/changes/ticket33646
new file mode 100644
index 0000000000..751c5d5bf2
--- /dev/null
+++ b/changes/ticket33646
@@ -0,0 +1,4 @@
+ o Minor bugfixes (build system):
+ - Correctly output the enabled module in the configure summary. Before that,
+ the list shown was just plain wrong. Fixes bug 33646; bugfix on
+ 0.4.3.2-alpha.
diff --git a/changes/ticket33678_043 b/changes/ticket33678_043
new file mode 100644
index 0000000000..12316262fd
--- /dev/null
+++ b/changes/ticket33678_043
@@ -0,0 +1,3 @@
+ o Code simplification and refactoring:
+ - Disable our coding standards best practices tracker in our git hooks.
+ (0.4.3 branches only.) Closes ticket 33678.
diff --git a/changes/ticket33804 b/changes/ticket33804
new file mode 100644
index 0000000000..254246dacf
--- /dev/null
+++ b/changes/ticket33804
@@ -0,0 +1,7 @@
+ o Minor bugfixes (client, SocksPort, IPv6):
+ - Revert PreferIPv6 set by default on the SocksPort because it brokes the
+ torsocks use case. Tor doesn't have a way for an application to request
+ the hostname to be resolved for a specific IP version but torsocks
+ requires that. Up until now, IPv4 was used by default so it is expecting
+ that, and can't handle a possible IPv6 being returned. Fixes bug 33804;
+ bugfix on 0.4.3.1-alpha.
diff --git a/changes/trove_2020_003 b/changes/trove_2020_003
new file mode 100644
index 0000000000..aa1a8f1c78
--- /dev/null
+++ b/changes/trove_2020_003
@@ -0,0 +1,4 @@
+ o Minor bugfixes (onion services v3):
+ - Fix 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 being tracked as TROVE-2020-003.
diff --git a/configure.ac b/configure.ac
index 1a5b6817b6..5af9d9862e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2019, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_PREREQ([2.63])
-AC_INIT([tor],[0.4.3.2-alpha-dev])
+AC_INIT([tor],[0.4.3.3-alpha])
AC_CONFIG_SRCDIR([src/app/main/tor_main.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -16,7 +16,7 @@ configure_flags="$*"
# version number changes. Tor uses it to make sure that it
# only shuts down for missing "required protocols" when those protocols
# are listed as required by a consensus after this date.
-AC_DEFINE(APPROX_RELEASE_DATE, ["2020-02-11"], # for 0.4.3.2-alpha-dev
+AC_DEFINE(APPROX_RELEASE_DATE, ["2020-03-10"], # for 0.4.3.3-alpha
[Approximate date when this software was released. (Updated when the version changes.)])
# "foreign" means we don't follow GNU package layout standards
@@ -2666,7 +2666,7 @@ PPRINT_SUBTITLE([Modules])
m4_foreach_w([mname], MODULES,
[
- test "xenable_module_mname" != "xno" && value=1 || value=0
+ AM_COND_IF(m4_join([], [BUILD_MODULE_], m4_toupper([]mname[])), value=1, value=0)
PPRINT_PROP_BOOL([mname (--disable-module-mname)], $value)
]
)
diff --git a/contrib/win32build/tor-mingw.nsi.in b/contrib/win32build/tor-mingw.nsi.in
index 8b7cafb4a5..b3328133b6 100644
--- a/contrib/win32build/tor-mingw.nsi.in
+++ b/contrib/win32build/tor-mingw.nsi.in
@@ -8,7 +8,7 @@
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.4.3.2-alpha-dev"
+!define VERSION "0.4.3.3-alpha"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index a9b9852b7d..b2014842cd 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -525,9 +525,9 @@ forward slash (/) in the configuration file and on the command line.
[[ExtendByEd25519ID]] **ExtendByEd25519ID** **0**|**1**|**auto**::
If this option is set to 1, we always try to include a relay's Ed25519 ID
- when telling the proceeding relay in a circuit to extend to it.
+ when telling the preceding relay in a circuit to extend to it.
If this option is set to 0, we never include Ed25519 IDs when extending
- circuits. If the option is set to "default", we obey a
+ circuits. If the option is set to "auto", we obey a
parameter in the consensus document. (Default: auto)
[[ExtORPort]] **ExtORPort** ['address'**:**]{empty}__port__|**auto**::
@@ -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
@@ -794,6 +799,11 @@ forward slash (/) in the configuration file and on the command line.
fetches by the relay (from authority or other relays), because that is considered
"client" activity. (Default: 0)
+[[RephistTrackTime]] **RephistTrackTime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**::
+ Tells an authority, or other node tracking node reliability and history,
+ that fine-grained information about nodes can be discarded when it hasn't
+ changed for a given amount of time. (Default: 24 hours)
+
[[RunAsDaemon]] **RunAsDaemon** **0**|**1**::
If 1, Tor forks and daemonizes to the background. This option has no effect
on Windows; instead you should use the --service command-line option.
@@ -1482,10 +1492,9 @@ The following options are useful only for clients (that is, if
requests on this connection. This option is only relevant when SOCKS5
is in use, because SOCKS4 can't handle IPv6. (Allowing IPv6 is the
default.)
- **NoPreferIPv6**;;
+ **PreferIPv6**;;
Tells exits that, if a host has both an IPv4 and an IPv6 address,
- we would prefer to connect to it via IPv4. (IPv6 is the default in
- recent versions of Tor.)
+ we would prefer to connect to it via IPv6. (IPv4 is the default.)
**NoDNSRequest**;;
Do not ask exits to resolve DNS addresses in SOCKS5 requests. Tor will
connect to IPv4 addresses, IPv6 addresses (if IPv6Traffic is set) and
@@ -1527,7 +1536,7 @@ The following options are useful only for clients (that is, if
When serving a hostname lookup request on this port that
should get automapped (according to AutomapHostsOnResolve),
if we could return either an IPv4 or an IPv6 answer, prefer
- an IPv4 answer. (Tor prefers IPv6 by default.)
+ an IPv4 answer. (Tor prefers IPv4 by default.)
**PreferSOCKSNoAuth**;;
Ordinarily, when an application offers both "username/password
authentication" and "no authentication" to Tor via SOCKS5, Tor
@@ -2060,9 +2069,58 @@ different from other Tor clients:
== SERVER OPTIONS
+// These options are in alphabetical order, with exceptions as noted.
+// Please keep them that way!
+
The following options are useful only for servers (that is, if ORPort
is non-zero):
+[[AccountingMax]] **AccountingMax** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**::
+ Limits the max number of bytes sent and received within a set time period
+ using a given calculation rule (see: AccountingStart, AccountingRule).
+ Useful if you need to stay under a specific bandwidth. By default, the
+ number used for calculation is the max of either the bytes sent or
+ received. For example, with AccountingMax set to 1 TByte, a server
+ could send 900 GBytes and receive 800 GBytes and continue running.
+ It will only hibernate once one of the two reaches 1 TByte. This can
+ be changed to use the sum of the both bytes received and sent by setting
+ the AccountingRule option to "sum" (total bandwidth in/out). When the
+ number of bytes remaining gets low, Tor will stop accepting new connections
+ and circuits. When the number of bytes is exhausted, Tor will hibernate
+ until some time in the next accounting period. To prevent all servers
+ from waking at the same time, Tor will also wait until a random point
+ in each period before waking up. If you have bandwidth cost issues,
+ enabling hibernation is preferable to setting a low bandwidth, since
+ it provides users with a collection of fast servers that are up some
+ of the time, which is more useful than a set of slow servers that are
+ always "available". +
+ +
+ Note that (as also described in the Bandwidth section) Tor uses
+ powers of two, not powers of ten: 1 GByte is 1024*1024*1024, not
+ one billion. Be careful: some internet service providers might count
+ GBytes differently.
+
+[[AccountingRule]] **AccountingRule** **sum**|**max**|**in**|**out**::
+ How we determine when our AccountingMax has been reached (when we
+ should hibernate) during a time interval. Set to "max" to calculate
+ using the higher of either the sent or received bytes (this is the
+ default functionality). Set to "sum" to calculate using the sent
+ plus received bytes. Set to "in" to calculate using only the
+ received bytes. Set to "out" to calculate using only the sent bytes.
+ (Default: max)
+
+[[AccountingStart]] **AccountingStart** **day**|**week**|**month** [__day__] __HH:MM__::
+ Specify how long accounting periods last. If **month** is given,
+ each accounting period runs from the time __HH:MM__ on the __dayth__ day of one
+ month to the same day and time of the next. The relay will go at full speed,
+ use all the quota you specify, then hibernate for the rest of the period. (The
+ day must be between 1 and 28.) If **week** is given, each accounting period
+ runs from the time __HH:MM__ of the __dayth__ day of one week to the same day
+ and time of the next week, with Monday as day 1 and Sunday as day 7. If **day**
+ is given, each accounting period runs from the time __HH:MM__ each day to the
+ same time on the next day. All times are local, and given in 24-hour time.
+ (Default: "month 1 0:00")
+
[[Address]] **Address** __address__::
The IPv4 address of this server, or a fully qualified domain name of
this server that resolves to an IPv4 address. You can leave this
@@ -2088,6 +2146,16 @@ is non-zero):
Note: make sure that no MyFamily lines are present in your torrc when
relay is configured in bridge mode.
+//Out of order because it logically belongs after BridgeRelay.
+[[BridgeRecordUsageByCountry]] **BridgeRecordUsageByCountry** **0**|**1**::
+ When this option is enabled and BridgeRelay is also enabled, and we have
+ GeoIP data, Tor keeps a per-country count of how many client
+ addresses have contacted it so that it can help the bridge authority guess
+ which countries have blocked access to it. If ExtraInfoStatistics is
+ enabled, it will be published as part of the extra-info document.
+ (Default: 1)
+
+//Out of order because it logically belongs after BridgeRelay.
[[BridgeDistribution]] **BridgeDistribution** __string__::
If set along with BridgeRelay, Tor will include a new line in its
bridge descriptor which indicates to the BridgeDB service how it
@@ -2108,21 +2176,11 @@ is non-zero):
relay or bridge. (Really, everybody running a relay or bridge should set
it.)
-
-[[ExitRelay]] **ExitRelay** **0**|**1**|**auto**::
- Tells Tor whether to run as an exit relay. If Tor is running as a
- non-bridge server, and ExitRelay is set to 1, then Tor allows traffic to
- exit according to the ExitPolicy option, the ReducedExitPolicy option,
- or the default ExitPolicy (if no other exit policy option is specified). +
- +
- If ExitRelay is set to 0, no traffic is allowed to exit, and the
- ExitPolicy, ReducedExitPolicy, and IPv6Exit options are ignored. +
- +
- If ExitRelay is set to "auto", then Tor checks the ExitPolicy,
- ReducedExitPolicy, and IPv6Exit options. If at least one of these options
- is set, Tor behaves as if ExitRelay were set to 1. If none of these exit
- policy options are set, Tor behaves as if ExitRelay were set to 0.
- (Default: auto)
+[[DisableOOSCheck]] **DisableOOSCheck** **0**|**1**::
+ This option disables the code that closes connections when Tor notices
+ that it is running low on sockets. Right now, it is on by default,
+ since the existing out-of-sockets mechanism tends to kill OR connections
+ more than it should. (Default: 1)
[[ExitPolicy]] **ExitPolicy** __policy__,__policy__,__...__::
Set an exit policy for this server. Each policy is of the form
@@ -2205,12 +2263,6 @@ is non-zero):
Since the default exit policy uses accept/reject *, it applies to both
IPv4 and IPv6 addresses.
-[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**::
- Reject all private (local) networks, along with the relay's advertised
- public IPv4 and IPv6 addresses, at the beginning of your exit policy.
- See above entry on ExitPolicy.
- (Default: 1)
-
[[ExitPolicyRejectLocalInterfaces]] **ExitPolicyRejectLocalInterfaces** **0**|**1**::
Reject all IPv4 and IPv6 addresses that the relay knows about, at the
beginning of your exit policy. This includes any OutboundBindAddress, the
@@ -2223,104 +2275,81 @@ is non-zero):
to disclose.
(Default: 0)
-[[ReducedExitPolicy]] **ReducedExitPolicy** **0**|**1**::
- If set, use a reduced exit policy rather than the default one. +
+[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**::
+ Reject all private (local) networks, along with the relay's advertised
+ public IPv4 and IPv6 addresses, at the beginning of your exit policy.
+ See above entry on ExitPolicy.
+ (Default: 1)
+
+[[ExitRelay]] **ExitRelay** **0**|**1**|**auto**::
+ Tells Tor whether to run as an exit relay. If Tor is running as a
+ non-bridge server, and ExitRelay is set to 1, then Tor allows traffic to
+ exit according to the ExitPolicy option, the ReducedExitPolicy option,
+ or the default ExitPolicy (if no other exit policy option is specified). +
+
- The reduced exit policy is an alternative to the default exit policy. It
- allows as many Internet services as possible while still blocking the
- majority of TCP ports. Currently, the policy allows approximately 65 ports.
- This reduces the odds that your node will be used for peer-to-peer
- applications. +
+ If ExitRelay is set to 0, no traffic is allowed to exit, and the
+ ExitPolicy, ReducedExitPolicy, and IPv6Exit options are ignored. +
+
- The reduced exit policy is:
-
- accept *:20-21
- accept *:22
- accept *:23
- accept *:43
- accept *:53
- accept *:79
- accept *:80-81
- accept *:88
- accept *:110
- accept *:143
- accept *:194
- accept *:220
- accept *:389
- accept *:443
- accept *:464
- accept *:465
- accept *:531
- accept *:543-544
- accept *:554
- accept *:563
- accept *:587
- accept *:636
- accept *:706
- accept *:749
- accept *:873
- accept *:902-904
- accept *:981
- accept *:989-990
- accept *:991
- accept *:992
- accept *:993
- accept *:994
- accept *:995
- accept *:1194
- accept *:1220
- accept *:1293
- accept *:1500
- accept *:1533
- accept *:1677
- accept *:1723
- accept *:1755
- accept *:1863
- accept *:2082
- accept *:2083
- accept *:2086-2087
- accept *:2095-2096
- accept *:2102-2104
- accept *:3128
- accept *:3389
- accept *:3690
- accept *:4321
- accept *:4643
- accept *:5050
- accept *:5190
- accept *:5222-5223
- accept *:5228
- accept *:5900
- accept *:6660-6669
- accept *:6679
- accept *:6697
- accept *:8000
- accept *:8008
- accept *:8074
- accept *:8080
- accept *:8082
- accept *:8087-8088
- accept *:8232-8233
- accept *:8332-8333
- accept *:8443
- accept *:8888
- accept *:9418
- accept *:9999
- accept *:10000
- accept *:11371
- accept *:19294
- accept *:19638
- accept *:50002
- accept *:64738
- reject *:*
+ If ExitRelay is set to "auto", then Tor checks the ExitPolicy,
+ ReducedExitPolicy, and IPv6Exit options. If at least one of these options
+ is set, Tor behaves as if ExitRelay were set to 1. If none of these exit
+ policy options are set, Tor behaves as if ExitRelay were set to 0.
+ (Default: auto)
+[[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**::
+ When this option is enabled, Tor will connect to relays on localhost,
+ RFC1918 addresses, and so on. In particular, Tor will make direct OR
+ connections, and Tor routers allow EXTEND requests, to these private
+ addresses. (Tor will always allow connections to bridges, proxies, and
+ pluggable transports configured on private addresses.) Enabling this
+ option can create security issues; you should probably leave it off.
(Default: 0)
+[[GeoIPFile]] **GeoIPFile** __filename__::
+ A filename containing IPv4 GeoIP data, for use with by-country statistics.
+
+[[GeoIPv6File]] **GeoIPv6File** __filename__::
+ A filename containing IPv6 GeoIP data, for use with by-country statistics.
+
+[[HeartbeatPeriod]] **HeartbeatPeriod** __N__ **minutes**|**hours**|**days**|**weeks**::
+ Log a heartbeat message every **HeartbeatPeriod** seconds. This is
+ a log level __notice__ message, designed to let you know your Tor
+ server is still alive and doing useful things. Settings this
+ to 0 will disable the heartbeat. Otherwise, it must be at least 30
+ minutes. (Default: 6 hours)
+
[[IPv6Exit]] **IPv6Exit** **0**|**1**::
If set, and we are an exit node, allow clients to use us for IPv6 traffic.
When this option is set and ExitRelay is auto, we act as if ExitRelay
is 1. (Default: 0)
+[[KeyDirectory]] **KeyDirectory** __DIR__::
+ Store secret keys in DIR. Can not be changed while tor is
+ running.
+ (Default: the "keys" subdirectory of DataDirectory.)
+
+[[KeyDirectoryGroupReadable]] **KeyDirectoryGroupReadable** **0**|**1**|**auto**::
+ If this option is set to 0, don't allow the filesystem group to read the
+ KeyDirectory. If the option is set to 1, make the KeyDirectory readable
+ by the default GID. If the option is "auto", then we use the
+ setting for DataDirectoryGroupReadable when the KeyDirectory is the
+ same as the DataDirectory, and 0 otherwise. (Default: auto)
+
+[[MainloopStats]] **MainloopStats** **0**|**1**::
+ Log main loop statistics every **HeartbeatPeriod** seconds. This is a log
+ level __notice__ message designed to help developers instrumenting Tor's
+ main event loop. (Default: 0)
+
+[[MaxMemInQueues]] **MaxMemInQueues** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**::
+ This option configures a threshold above which Tor will assume that it
+ needs to stop queueing or buffering data because it's about to run out of
+ memory. If it hits this threshold, it will begin killing circuits until
+ it has recovered at least 10% of this memory. Do not set this option too
+ low, or your relay may be unreliable under load. This option only
+ affects some queues, so the actual process size will be larger than
+ this. If this option is set to 0, Tor will try to pick a reasonable
+ default based on your system's physical memory. (Default: 0)
+
[[MaxOnionQueueDelay]] **MaxOnionQueueDelay** __NUM__ [**msec**|**second**]::
If we have more onionskins queued for processing than we can process in
this amount of time, reject new ones. (Default: 1750 msec)
@@ -2358,6 +2387,12 @@ is non-zero):
parallelizable operations. If this is set to 0, Tor will try to detect
how many CPUs you have, defaulting to 1 if it can't tell. (Default: 0)
+[[OfflineMasterKey]] **OfflineMasterKey** **0**|**1**::
+ If non-zero, the Tor relay will never generate or load its master secret
+ key. Instead, you'll have to use "tor --keygen" to manage the permanent
+ ed25519 master identity key, as well as the corresponding temporary
+ signing keys and certificates. (Default: 0)
+
[[ORPort]] **ORPort** ['address'**:**]{empty}__PORT__|**auto** [_flags_]::
Advertise this port to listen for connections from Tor clients and
servers. This option is required to be a Tor server.
@@ -2402,74 +2437,98 @@ is non-zero):
"publish as if you're a relay", and "bridge", meaning "publish as
if you're a bridge".
-[[ShutdownWaitLength]] **ShutdownWaitLength** __NUM__::
- When we get a SIGINT and we're a server, we begin shutting down:
- we close listeners and start refusing new circuits. After **NUM**
- seconds, we exit. If we get a second SIGINT, we exit immediately.
- (Default: 30 seconds)
-
-[[SSLKeyLifetime]] **SSLKeyLifetime** __N__ **minutes**|**hours**|**days**|**weeks**::
- When creating a link certificate for our outermost SSL handshake,
- set its lifetime to this amount of time. If set to 0, Tor will choose
- some reasonable random defaults. (Default: 0)
-
-[[HeartbeatPeriod]] **HeartbeatPeriod** __N__ **minutes**|**hours**|**days**|**weeks**::
- Log a heartbeat message every **HeartbeatPeriod** seconds. This is
- a log level __notice__ message, designed to let you know your Tor
- server is still alive and doing useful things. Settings this
- to 0 will disable the heartbeat. Otherwise, it must be at least 30
- minutes. (Default: 6 hours)
-
-[[MainloopStats]] **MainloopStats** **0**|**1**::
- Log main loop statistics every **HeartbeatPeriod** seconds. This is a log
- level __notice__ message designed to help developers instrumenting Tor's
- main event loop. (Default: 0)
-
-[[AccountingMax]] **AccountingMax** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**::
- Limits the max number of bytes sent and received within a set time period
- using a given calculation rule (see: AccountingStart, AccountingRule).
- Useful if you need to stay under a specific bandwidth. By default, the
- number used for calculation is the max of either the bytes sent or
- received. For example, with AccountingMax set to 1 TByte, a server
- could send 900 GBytes and receive 800 GBytes and continue running.
- It will only hibernate once one of the two reaches 1 TByte. This can
- be changed to use the sum of the both bytes received and sent by setting
- the AccountingRule option to "sum" (total bandwidth in/out). When the
- number of bytes remaining gets low, Tor will stop accepting new connections
- and circuits. When the number of bytes is exhausted, Tor will hibernate
- until some time in the next accounting period. To prevent all servers
- from waking at the same time, Tor will also wait until a random point
- in each period before waking up. If you have bandwidth cost issues,
- enabling hibernation is preferable to setting a low bandwidth, since
- it provides users with a collection of fast servers that are up some
- of the time, which is more useful than a set of slow servers that are
- always "available". +
+[[ReducedExitPolicy]] **ReducedExitPolicy** **0**|**1**::
+ If set, use a reduced exit policy rather than the default one. +
+
- Note that (as also described in the Bandwidth section) Tor uses
- powers of two, not powers of ten: 1 GByte is 1024*1024*1024, not
- one billion. Be careful: some internet service providers might count
- GBytes differently.
+ The reduced exit policy is an alternative to the default exit policy. It
+ allows as many Internet services as possible while still blocking the
+ majority of TCP ports. Currently, the policy allows approximately 65 ports.
+ This reduces the odds that your node will be used for peer-to-peer
+ applications. +
+ +
+ The reduced exit policy is:
-[[AccountingRule]] **AccountingRule** **sum**|**max**|**in**|**out**::
- How we determine when our AccountingMax has been reached (when we
- should hibernate) during a time interval. Set to "max" to calculate
- using the higher of either the sent or received bytes (this is the
- default functionality). Set to "sum" to calculate using the sent
- plus received bytes. Set to "in" to calculate using only the
- received bytes. Set to "out" to calculate using only the sent bytes.
- (Default: max)
+ accept *:20-21
+ accept *:22
+ accept *:23
+ accept *:43
+ accept *:53
+ accept *:79
+ accept *:80-81
+ accept *:88
+ accept *:110
+ accept *:143
+ accept *:194
+ accept *:220
+ accept *:389
+ accept *:443
+ accept *:464
+ accept *:465
+ accept *:531
+ accept *:543-544
+ accept *:554
+ accept *:563
+ accept *:587
+ accept *:636
+ accept *:706
+ accept *:749
+ accept *:873
+ accept *:902-904
+ accept *:981
+ accept *:989-990
+ accept *:991
+ accept *:992
+ accept *:993
+ accept *:994
+ accept *:995
+ accept *:1194
+ accept *:1220
+ accept *:1293
+ accept *:1500
+ accept *:1533
+ accept *:1677
+ accept *:1723
+ accept *:1755
+ accept *:1863
+ accept *:2082
+ accept *:2083
+ accept *:2086-2087
+ accept *:2095-2096
+ accept *:2102-2104
+ accept *:3128
+ accept *:3389
+ accept *:3690
+ accept *:4321
+ accept *:4643
+ accept *:5050
+ accept *:5190
+ accept *:5222-5223
+ accept *:5228
+ accept *:5900
+ accept *:6660-6669
+ accept *:6679
+ accept *:6697
+ accept *:8000
+ accept *:8008
+ accept *:8074
+ accept *:8080
+ accept *:8082
+ accept *:8087-8088
+ accept *:8232-8233
+ accept *:8332-8333
+ accept *:8443
+ accept *:8888
+ accept *:9418
+ accept *:9999
+ accept *:10000
+ accept *:11371
+ accept *:19294
+ accept *:19638
+ accept *:50002
+ accept *:64738
+ reject *:*
-[[AccountingStart]] **AccountingStart** **day**|**week**|**month** [__day__] __HH:MM__::
- Specify how long accounting periods last. If **month** is given,
- each accounting period runs from the time __HH:MM__ on the __dayth__ day of one
- month to the same day and time of the next. The relay will go at full speed,
- use all the quota you specify, then hibernate for the rest of the period. (The
- day must be between 1 and 28.) If **week** is given, each accounting period
- runs from the time __HH:MM__ of the __dayth__ day of one week to the same day
- and time of the next week, with Monday as day 1 and Sunday as day 7. If **day**
- is given, each accounting period runs from the time __HH:MM__ each day to the
- same time on the next day. All times are local, and given in 24-hour time.
- (Default: "month 1 0:00")
+ (Default: 0)
[[RefuseUnknownExits]] **RefuseUnknownExits** **0**|**1**|**auto**::
Prevent nodes that don't appear in the consensus from exiting using this
@@ -2478,6 +2537,34 @@ is non-zero):
whatever the authorities suggest in the consensus (and block if the consensus
is quiet on the issue). (Default: auto)
+[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**::
+ If this option is false, Tor exits immediately if there are problems
+ parsing the system DNS configuration or connecting to nameservers.
+ Otherwise, Tor continues to periodically retry the system nameservers until
+ it eventually succeeds. (Default: 1)
+
+[[ServerDNSAllowNonRFC953Hostnames]] **ServerDNSAllowNonRFC953Hostnames** **0**|**1**::
+ When this option is disabled, Tor does not try to resolve hostnames
+ containing illegal characters (like @ and :) rather than sending them to an
+ exit node to be resolved. This helps trap accidental attempts to resolve
+ URLs and so on. This option only affects name lookups that your server does
+ on behalf of clients. (Default: 0)
+
+[[ServerDNSDetectHijacking]] **ServerDNSDetectHijacking** **0**|**1**::
+ When this option is set to 1, we will test periodically to determine
+ whether our local nameservers have been configured to hijack failing DNS
+ requests (usually to an advertising site). If they are, we will attempt to
+ correct this. This option only affects name lookups that your server does
+ on behalf of clients. (Default: 1)
+
+[[ServerDNSRandomizeCase]] **ServerDNSRandomizeCase** **0**|**1**::
+ When this option is set, Tor sets the case of each character randomly in
+ outgoing DNS requests, and makes sure that the case matches in DNS replies.
+ This so-called "0x20 hack" helps resist some types of DNS poisoning attack.
+ For more information, see "Increased DNS Forgery Resistance through
+ 0x20-Bit Encoding". This option only affects name lookups that your server
+ does on behalf of clients. (Default: 1)
+
[[ServerDNSResolvConfFile]] **ServerDNSResolvConfFile** __filename__::
Overrides the default DNS configuration with the configuration in
__filename__. The file format is the same as the standard Unix
@@ -2486,12 +2573,6 @@ is non-zero):
(Defaults to use the system DNS configuration or a localhost DNS service
in case no nameservers are found in a given configuration.)
-[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**::
- If this option is false, Tor exits immediately if there are problems
- parsing the system DNS configuration or connecting to nameservers.
- Otherwise, Tor continues to periodically retry the system nameservers until
- it eventually succeeds. (Default: 1)
-
[[ServerDNSSearchDomains]] **ServerDNSSearchDomains** **0**|**1**::
If set to 1, then we will search for addresses in the local search domain.
For example, if this system is configured to believe it is in
@@ -2499,13 +2580,6 @@ is non-zero):
connected to "www.example.com". This option only affects name lookups that
your server does on behalf of clients. (Default: 0)
-[[ServerDNSDetectHijacking]] **ServerDNSDetectHijacking** **0**|**1**::
- When this option is set to 1, we will test periodically to determine
- whether our local nameservers have been configured to hijack failing DNS
- requests (usually to an advertising site). If they are, we will attempt to
- correct this. This option only affects name lookups that your server does
- on behalf of clients. (Default: 1)
-
[[ServerDNSTestAddresses]] **ServerDNSTestAddresses** __hostname__,__hostname__,__...__::
When we're detecting DNS hijacking, make sure that these __valid__ addresses
aren't getting redirected. If they are, then our DNS is completely useless,
@@ -2513,33 +2587,32 @@ is non-zero):
name lookups that your server does on behalf of clients. (Default:
"www.google.com, www.mit.edu, www.yahoo.com, www.slashdot.org")
-[[ServerDNSAllowNonRFC953Hostnames]] **ServerDNSAllowNonRFC953Hostnames** **0**|**1**::
- When this option is disabled, Tor does not try to resolve hostnames
- containing illegal characters (like @ and :) rather than sending them to an
- exit node to be resolved. This helps trap accidental attempts to resolve
- URLs and so on. This option only affects name lookups that your server does
- on behalf of clients. (Default: 0)
+[[ShutdownWaitLength]] **ShutdownWaitLength** __NUM__::
+ When we get a SIGINT and we're a server, we begin shutting down:
+ we close listeners and start refusing new circuits. After **NUM**
+ seconds, we exit. If we get a second SIGINT, we exit immediately.
+ (Default: 30 seconds)
-[[BridgeRecordUsageByCountry]] **BridgeRecordUsageByCountry** **0**|**1**::
- When this option is enabled and BridgeRelay is also enabled, and we have
- GeoIP data, Tor keeps a per-country count of how many client
- addresses have contacted it so that it can help the bridge authority guess
- which countries have blocked access to it. If ExtraInfoStatistics is
- enabled, it will be published as part of extra-info document. (Default: 1)
+[[SigningKeyLifetime]] **SigningKeyLifetime** __N__ **days**|**weeks**|**months**::
+ For how long should each Ed25519 signing key be valid? Tor uses a
+ permanent master identity key that can be kept offline, and periodically
+ generates new "signing" keys that it uses online. This option
+ configures their lifetime.
+ (Default: 30 days)
-[[ServerDNSRandomizeCase]] **ServerDNSRandomizeCase** **0**|**1**::
- When this option is set, Tor sets the case of each character randomly in
- outgoing DNS requests, and makes sure that the case matches in DNS replies.
- This so-called "0x20 hack" helps resist some types of DNS poisoning attack.
- For more information, see "Increased DNS Forgery Resistance through
- 0x20-Bit Encoding". This option only affects name lookups that your server
- does on behalf of clients. (Default: 1)
+[[SSLKeyLifetime]] **SSLKeyLifetime** __N__ **minutes**|**hours**|**days**|**weeks**::
+ When creating a link certificate for our outermost SSL handshake,
+ set its lifetime to this amount of time. If set to 0, Tor will choose
+ some reasonable random defaults. (Default: 0)
-[[GeoIPFile]] **GeoIPFile** __filename__::
- A filename containing IPv4 GeoIP data, for use with by-country statistics.
+== STATISTICS OPTIONS
-[[GeoIPv6File]] **GeoIPv6File** __filename__::
- A filename containing IPv6 GeoIP data, for use with by-country statistics.
+// These options are in alphabetical order, with exceptions as noted.
+// Please keep them that way!
+
+Relays publish most statistics in a document called the
+extra-info document. The following options affect the different
+types of statistics that Tor relays collect and publish:
[[CellStatistics]] **CellStatistics** **0**|**1**::
Relays only.
@@ -2549,16 +2622,16 @@ is non-zero):
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)
-[[PaddingStatistics]] **PaddingStatistics** **0**|**1**::
- Relays and bridges only.
- When this option is enabled, Tor collects statistics for padding cells
- sent and received by this relay, in addition to total cell counts.
- These statistics are rounded, and omitted if traffic is low. This
- information is important for load balancing decisions related to padding.
- If ExtraInfoStatistics is enabled, it will be published
- as a part of extra-info document. (Default: 1)
+[[ConnDirectionStatistics]] **ConnDirectionStatistics** **0**|**1**::
+ Relays only.
+ When this option is enabled, Tor writes statistics on the amounts of
+ traffic it passes between itself and other relays to disk every 24
+ hours. Enables relay operators to monitor how much their relay is
+ being used as middle node in the circuit. If ExtraInfoStatistics is
+ enabled, it will be published as part of the extra-info document.
+ (Default: 0)
[[DirReqStatistics]] **DirReqStatistics** **0**|**1**::
Relays and bridges only.
@@ -2567,7 +2640,7 @@ is non-zero):
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.
@@ -2576,7 +2649,7 @@ is non-zero):
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.
@@ -2584,90 +2657,34 @@ is non-zero):
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)
-[[ConnDirectionStatistics]] **ConnDirectionStatistics** **0**|**1**::
- Relays only.
- When this option is enabled, Tor writes statistics on the amounts of
- traffic it passes between itself and other relays to disk every 24
- hours. Enables relay operators to monitor how much their relay is
- being used as middle node in the circuit. If ExtraInfoStatistics is
- enabled, it will be published as part of extra-info document.
- (Default: 0)
-
-[[HiddenServiceStatistics]] **HiddenServiceStatistics** **0**|**1**::
- Relays only.
- When this option is enabled, a Tor relay writes obfuscated
- statistics on its role as hidden-service directory, introduction
- point, or rendezvous point to disk every 24 hours. If
- ExtraInfoStatistics is also enabled, these statistics are further
- published to the directory authorities. (Default: 1)
-
[[ExtraInfoStatistics]] **ExtraInfoStatistics** **0**|**1**::
When this option is enabled, Tor includes previously gathered statistics in
its extra-info documents that it uploads to the directory authorities.
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)
-[[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**::
- When this option is enabled, Tor will connect to relays on localhost,
- RFC1918 addresses, and so on. In particular, Tor will make direct OR
- connections, and Tor routers allow EXTEND requests, to these private
- addresses. (Tor will always allow connections to bridges, proxies, and
- pluggable transports configured on private addresses.) Enabling this
- option can create security issues; you should probably leave it off.
- (Default: 0)
-
-[[MaxMemInQueues]] **MaxMemInQueues** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**::
- This option configures a threshold above which Tor will assume that it
- needs to stop queueing or buffering data because it's about to run out of
- memory. If it hits this threshold, it will begin killing circuits until
- it has recovered at least 10% of this memory. Do not set this option too
- low, or your relay may be unreliable under load. This option only
- affects some queues, so the actual process size will be larger than
- this. If this option is set to 0, Tor will try to pick a reasonable
- default based on your system's physical memory. (Default: 0)
-
-[[DisableOOSCheck]] **DisableOOSCheck** **0**|**1**::
- This option disables the code that closes connections when Tor notices
- that it is running low on sockets. Right now, it is on by default,
- since the existing out-of-sockets mechanism tends to kill OR connections
- more than it should. (Default: 1)
-
-[[SigningKeyLifetime]] **SigningKeyLifetime** __N__ **days**|**weeks**|**months**::
- For how long should each Ed25519 signing key be valid? Tor uses a
- permanent master identity key that can be kept offline, and periodically
- generates new "signing" keys that it uses online. This option
- configures their lifetime.
- (Default: 30 days)
-
-[[OfflineMasterKey]] **OfflineMasterKey** **0**|**1**::
- If non-zero, the Tor relay will never generate or load its master secret
- key. Instead, you'll have to use "tor --keygen" to manage the permanent
- ed25519 master identity key, as well as the corresponding temporary
- signing keys and certificates. (Default: 0)
-
-[[KeyDirectory]] **KeyDirectory** __DIR__::
- Store secret keys in DIR. Can not be changed while tor is
- running.
- (Default: the "keys" subdirectory of DataDirectory.)
-
-[[KeyDirectoryGroupReadable]] **KeyDirectoryGroupReadable** **0**|**1**|**auto**::
- If this option is set to 0, don't allow the filesystem group to read the
- KeyDirectory. If the option is set to 1, make the KeyDirectory readable
- by the default GID. If the option is "auto", then we use the
- setting for DataDirectoryGroupReadable when the KeyDirectory is the
- same as the DataDirectory, and 0 otherwise. (Default: auto)
-
-[[RephistTrackTime]] **RephistTrackTime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**::
- Tells an authority, or other node tracking node reliability and history,
- that fine-grained information about nodes can be discarded when it hasn't
- changed for a given amount of time. (Default: 24 hours)
+[[HiddenServiceStatistics]] **HiddenServiceStatistics** **0**|**1**::
+ Relays only.
+ When this option is enabled, a Tor relay writes obfuscated
+ statistics on its role as hidden-service directory, introduction
+ point, or rendezvous point to disk every 24 hours. If ExtraInfoStatistics
+ is enabled, it will be published as part of the extra-info document.
+ (Default: 1)
+[[PaddingStatistics]] **PaddingStatistics** **0**|**1**::
+ Relays and bridges only.
+ When this option is enabled, Tor collects statistics for padding cells
+ sent and received by this relay, in addition to total cell counts.
+ These statistics are rounded, and omitted if traffic is low. This
+ information is important for load balancing decisions related to padding.
+ If ExtraInfoStatistics is enabled, it will be published
+ as a part of the extra-info document. (Default: 1)
== DIRECTORY SERVER OPTIONS
@@ -2675,11 +2692,19 @@ The following options are useful only for directory servers. (Relays with
enough bandwidth automatically become directory servers; see DirCache for
details.)
-[[DirPortFrontPage]] **DirPortFrontPage** __FILENAME__::
- When this option is set, it takes an HTML file and publishes it as "/" on
- the DirPort. Now relay operators can provide a disclaimer without needing
- to set up a separate webserver. There's a sample disclaimer in
- contrib/operator-tools/tor-exit-notice.html.
+[[DirCache]] **DirCache** **0**|**1**::
+ When this option is set, Tor caches all current directory documents except
+ extra info documents, and accepts client requests for them. If
+ **DownloadExtraInfo** is set, cached extra info documents are also cached.
+ Setting **DirPort** is not required for **DirCache**, because clients
+ connect via the ORPort by default. Setting either DirPort or BridgeRelay
+ and setting DirCache to 0 is not supported. (Default: 1)
+
+[[DirPolicy]] **DirPolicy** __policy__,__policy__,__...__::
+ Set an entrance policy for this server, to limit who can connect to the
+ directory ports. The policies have the same form as exit policies above,
+ except that port specifiers are ignored. Any address not matched by
+ some entry in the policy is accepted.
[[DirPort]] **DirPort** ['address'**:**]{empty}__PORT__|**auto** [_flags_]::
If this option is nonzero, advertise the directory service on this port.
@@ -2689,19 +2714,11 @@ details.)
+
The same flags are supported here as are supported by ORPort.
-[[DirPolicy]] **DirPolicy** __policy__,__policy__,__...__::
- Set an entrance policy for this server, to limit who can connect to the
- directory ports. The policies have the same form as exit policies above,
- except that port specifiers are ignored. Any address not matched by
- some entry in the policy is accepted.
-
-[[DirCache]] **DirCache** **0**|**1**::
- When this option is set, Tor caches all current directory documents except
- extra info documents, and accepts client requests for them. If
- **DownloadExtraInfo** is set, cached extra info documents are also cached.
- Setting **DirPort** is not required for **DirCache**, because clients
- connect via the ORPort by default. Setting either DirPort or BridgeRelay
- and setting DirCache to 0 is not supported. (Default: 1)
+[[DirPortFrontPage]] **DirPortFrontPage** __FILENAME__::
+ When this option is set, it takes an HTML file and publishes it as "/" on
+ the DirPort. Now relay operators can provide a disclaimer without needing
+ to set up a separate webserver. There's a sample disclaimer in
+ contrib/operator-tools/tor-exit-notice.html.
[[MaxConsensusAgeForDiffs]] **MaxConsensusAgeForDiffs** __N__ **minutes**|**hours**|**days**|**weeks**::
When this option is nonzero, Tor caches will not try to generate
@@ -3067,7 +3084,15 @@ on the public Tor network.
before it will treat advertised bandwidths as wholly
unreliable. (Default: 500)
-== HIDDEN SERVICE OPTIONS
+[[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**::
+ If set, the directory authority will start rejecting directory requests
+ from non relay connections by sending a 503 error code if it is under
+ bandwidth pressure (reaching the configured limit if any). Relays will
+ always tried to be answered even if this is on. (Default: 1)
+
+
+HIDDEN SERVICE OPTIONS
+----------------------
The following options are used to configure a hidden service. Some options
apply per service and some apply for the whole tor instance.
@@ -3670,14 +3695,15 @@ __DataDirectory__/**`hashed-fingerprint`**::
identity key. (That is, the hash of the hash of the identity key.)
__DataDirectory__/**`approved-routers`**::
- Only used by authoritative directory servers. This file lists the status
- and a fingerprint/pubkey. Each line lists a status and a fingerprint
- separated by whitespace. See your **fingerprint** file in the
- __DataDirectory__ for an example fingerprint line. If the status is
- **!reject** then descriptors from the given identity (fingerprint/pubkey)
- are rejected by this server. If it is **!invalid** then descriptors are
- accepted but marked in the directory as not valid, that is, not
- recommended.
+ Only used by authoritative directory servers. Each line lists a status and
+ an identity, separated by whitespace. Identities can be hex-encoded RSA
+ fingerprints, or base-64 encoded ed25519 public keys. See the
+ **fingerprint** file in a tor relay's __DataDirectory__ for an example
+ fingerprint line. If the status is **!reject**, then descriptors from the
+ given identity are rejected by this server. If it is **!invalid** then
+ descriptors are accepted, but marked in the directory as not valid, that
+ is, not recommended. In either case, the corresponding relays are not
+ included in the consensus.
__DataDirectory__/**`v3-status-votes`**::
Only for v3 authoritative directory servers. This file contains status
diff --git a/scripts/maint/practracker/.enable_practracker_in_hooks b/scripts/maint/practracker/.enable_practracker_in_hooks
deleted file mode 100644
index a9e707f5da..0000000000
--- a/scripts/maint/practracker/.enable_practracker_in_hooks
+++ /dev/null
@@ -1 +0,0 @@
-This file is present to tell our git hooks to run practracker on this branch.
diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index 70e6a55199..d89b80c1b3 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -73,7 +73,7 @@ problem function-size /src/core/mainloop/connection.c:connection_handle_read_imp
problem function-size /src/core/mainloop/connection.c:connection_buf_read_from_socket() 180
problem function-size /src/core/mainloop/connection.c:connection_handle_write_impl() 241
problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143
-problem dependency-violation /src/core/mainloop/connection.c 44
+problem dependency-violation /src/core/mainloop/connection.c 47
problem dependency-violation /src/core/mainloop/cpuworker.c 12
problem include-count /src/core/mainloop/mainloop.c 64
problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 108
diff --git a/scripts/maint/practracker/practracker.py b/scripts/maint/practracker/practracker.py
index 6149fb79cb..79b13cb056 100755
--- a/scripts/maint/practracker/practracker.py
+++ b/scripts/maint/practracker/practracker.py
@@ -24,7 +24,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
-import os, sys
+import codecs, os, sys
import metrics
import util
@@ -63,12 +63,8 @@ TOR_TOPDIR = None
#######################################################
-if sys.version_info[0] <= 2:
- def open_file(fname):
- return open(fname, 'r')
-else:
- def open_file(fname):
- return open(fname, 'r', encoding='utf-8')
+def open_file(fname):
+ return codecs.open(fname, 'r', encoding='utf-8')
def consider_file_size(fname, f):
"""Consider the size of 'f' and yield an FileSizeItem for it.
diff --git a/src/app/config/config.c b/src/app/config/config.c
index bbf984ad08..c7ac9d6315 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -5886,7 +5886,7 @@ port_cfg_new(size_t namelen)
port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t) + namelen + 1);
cfg->entry_cfg.ipv4_traffic = 1;
cfg->entry_cfg.ipv6_traffic = 1;
- cfg->entry_cfg.prefer_ipv6 = 1;
+ cfg->entry_cfg.prefer_ipv6 = 0;
cfg->entry_cfg.dns_request = 1;
cfg->entry_cfg.onion_traffic = 1;
cfg->entry_cfg.prefer_ipv6_virtaddr = 1;
@@ -6134,7 +6134,7 @@ port_parse_config(smartlist_t *out,
/* 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,
+ ipv4_traffic = 1, ipv6_traffic = 1, prefer_ipv6 = 0, dns_request = 1,
onion_traffic = 1,
cache_ipv4 = 0, use_cached_ipv4 = 0,
cache_ipv6 = 0, use_cached_ipv6 = 0,
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 4a2dc21f1c..57b48d49f3 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -91,6 +91,7 @@
#include "feature/control/control.h"
#include "feature/control/control_events.h"
#include "feature/dirauth/authmode.h"
+#include "feature/dirauth/dirauth_config.h"
#include "feature/dircache/dirserv.h"
#include "feature/dircommon/directory.h"
#include "feature/hibernate/hibernate.h"
@@ -1513,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 */
@@ -3137,7 +3139,7 @@ connection_mark_all_noncontrol_connections(void)
* uses pluggable transports, since we should then limit it even if it
* comes from an internal IP address. */
static int
-connection_is_rate_limited(connection_t *conn)
+connection_is_rate_limited(const connection_t *conn)
{
const or_options_t *options = get_options();
if (conn->linked)
@@ -3272,14 +3274,14 @@ connection_bucket_write_limit(connection_t *conn, time_t now)
global_bucket_val, conn_bucket);
}
-/** Return 1 if the global write buckets are low enough that we
+/** Return true iff the global write buckets are low enough that we
* shouldn't send <b>attempt</b> bytes of low-priority directory stuff
- * out to <b>conn</b>. Else return 0.
-
- * Priority was 1 for v1 requests (directories and running-routers),
- * and 2 for v2 requests and later (statuses and descriptors).
+ * out to <b>conn</b>.
+ *
+ * If we are a directory authority, always answer dir requests thus true is
+ * always returned.
*
- * There are a lot of parameters we could use here:
+ * Note: There are a lot of parameters we could use here:
* - global_relayed_write_bucket. Low is bad.
* - global_write_bucket. Low is bad.
* - bandwidthrate. Low is bad.
@@ -3291,39 +3293,40 @@ connection_bucket_write_limit(connection_t *conn, time_t now)
* mean is "total directory bytes added to outbufs recently", but
* that's harder to quantify and harder to keep track of.
*/
-int
-global_write_bucket_low(connection_t *conn, size_t attempt, int priority)
+bool
+connection_dir_is_global_write_low(const connection_t *conn, size_t attempt)
{
size_t smaller_bucket =
MIN(token_bucket_rw_get_write(&global_bucket),
token_bucket_rw_get_write(&global_relayed_bucket));
- if (authdir_mode(get_options()) && priority>1)
- return 0; /* there's always room to answer v2 if we're an auth dir */
+
+ /* Special case for authorities (directory only). */
+ if (authdir_mode_v3(get_options())) {
+ /* Are we configured to possibly reject requests under load? */
+ if (!dirauth_should_reject_requests_under_load()) {
+ /* Answer request no matter what. */
+ return false;
+ }
+ /* Always answer requests from a known relay which includes the other
+ * authorities. The following looks up the addresses for relays that we
+ * have their descriptor _and_ any configured trusted directories. */
+ if (nodelist_probably_contains_address(&conn->addr)) {
+ return false;
+ }
+ }
if (!connection_is_rate_limited(conn))
- return 0; /* local conns don't get limited */
+ return false; /* local conns don't get limited */
if (smaller_bucket < attempt)
- return 1; /* not enough space no matter the priority */
+ return true; /* not enough space. */
{
const time_t diff = approx_time() - write_buckets_last_empty_at;
if (diff <= 1)
- return 1; /* we're already hitting our limits, no more please */
+ return true; /* we're already hitting our limits, no more please */
}
-
- if (priority == 1) { /* old-style v1 query */
- /* Could we handle *two* of these requests within the next two seconds? */
- const or_options_t *options = get_options();
- size_t can_write = (size_t) (smaller_bucket
- + 2*(options->RelayBandwidthRate ? options->RelayBandwidthRate :
- options->BandwidthRate));
- if (can_write < 2*attempt)
- return 1;
- } else { /* v2 query */
- /* no further constraints yet */
- }
- return 0;
+ return false;
}
/** When did we last tell the accounting subsystem about transmitted
diff --git a/src/core/mainloop/connection.h b/src/core/mainloop/connection.h
index 0ab601d86f..bcd3d590a5 100644
--- a/src/core/mainloop/connection.h
+++ b/src/core/mainloop/connection.h
@@ -219,8 +219,8 @@ void connection_mark_all_noncontrol_listeners(void);
void connection_mark_all_noncontrol_connections(void);
ssize_t connection_bucket_write_limit(struct connection_t *conn, time_t now);
-int global_write_bucket_low(struct connection_t *conn,
- size_t attempt, int priority);
+bool connection_dir_is_global_write_low(const struct connection_t *conn,
+ size_t attempt);
void connection_bucket_init(void);
void connection_bucket_adjust(const struct or_options_t *options);
void connection_bucket_refill_all(time_t now,
diff --git a/src/core/or/channel.c b/src/core/or/channel.c
index d52dc14a32..18940bd81f 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.c b/src/core/or/circuitmux.c
index 0e932f032d..da95e93657 100644
--- a/src/core/or/circuitmux.c
+++ b/src/core/or/circuitmux.c
@@ -79,6 +79,8 @@
#include "core/or/or_circuit_st.h"
+#include "lib/crypt_ops/crypto_util.h"
+
/*
* Private typedefs for circuitmux.c
*/
@@ -921,7 +923,10 @@ circuitmux_detach_circuit,(circuitmux_t *cmux, circuit_t *circ))
/* Now remove it from the map */
HT_REMOVE(chanid_circid_muxinfo_map, cmux->chanid_circid_map, hashent);
- /* Free the hash entry */
+ /* Wipe and free the hash entry */
+ // This isn't sensitive, but we want to be sure to know if we're accessing
+ // this accidentally.
+ memwipe(hashent, 0xef, sizeof(*hashent));
tor_free(hashent);
}
}
@@ -1282,4 +1287,3 @@ circuitmux_compare_muxes, (circuitmux_t *cmux_1, circuitmux_t *cmux_2))
return 0;
}
}
-
diff --git a/src/core/or/circuitmux_ewma.c b/src/core/or/circuitmux_ewma.c
index 996d87f96d..b50f33528f 100644
--- a/src/core/or/circuitmux_ewma.c
+++ b/src/core/or/circuitmux_ewma.c
@@ -38,6 +38,7 @@
#include "core/or/circuitmux.h"
#include "core/or/circuitmux_ewma.h"
#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/crypt_ops/crypto_util.h"
#include "feature/nodelist/networkstatus.h"
#include "app/config/or_options_st.h"
@@ -186,6 +187,7 @@ ewma_free_cmux_data(circuitmux_t *cmux,
pol = TO_EWMA_POL_DATA(pol_data);
smartlist_free(pol->active_circuit_pqueue);
+ memwipe(pol, 0xda, sizeof(ewma_policy_data_t));
tor_free(pol);
}
@@ -252,7 +254,7 @@ ewma_free_circ_data(circuitmux_t *cmux,
if (!pol_circ_data) return;
cdata = TO_EWMA_POL_CIRC_DATA(pol_circ_data);
-
+ memwipe(cdata, 0xdc, sizeof(ewma_policy_circ_data_t));
tor_free(cdata);
}
diff --git a/src/core/or/circuitmux_ewma.h b/src/core/or/circuitmux_ewma.h
index fc7e7ebf7f..e41cf9e0f0 100644
--- a/src/core/or/circuitmux_ewma.h
+++ b/src/core/or/circuitmux_ewma.h
@@ -106,7 +106,9 @@ TO_EWMA_POL_DATA(circuitmux_policy_data_t *pol)
{
if (!pol) return NULL;
else {
- tor_assert(pol->magic == EWMA_POL_DATA_MAGIC);
+ tor_assertf(pol->magic == EWMA_POL_DATA_MAGIC,
+ "Mismatch: %"PRIu32" != %"PRIu32,
+ pol->magic, EWMA_POL_DATA_MAGIC);
return DOWNCAST(ewma_policy_data_t, pol);
}
}
@@ -121,7 +123,9 @@ TO_EWMA_POL_CIRC_DATA(circuitmux_policy_circ_data_t *pol)
{
if (!pol) return NULL;
else {
- tor_assert(pol->magic == EWMA_POL_CIRC_DATA_MAGIC);
+ tor_assertf(pol->magic == EWMA_POL_CIRC_DATA_MAGIC,
+ "Mismatch: %"PRIu32" != %"PRIu32,
+ pol->magic, EWMA_POL_CIRC_DATA_MAGIC);
return DOWNCAST(ewma_policy_circ_data_t, pol);
}
}
@@ -132,4 +136,3 @@ STATIC void cell_ewma_initialize_ticks(void);
#endif /* defined(CIRCUITMUX_EWMA_PRIVATE) */
#endif /* !defined(TOR_CIRCUITMUX_EWMA_H) */
-
diff --git a/src/core/or/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/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/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 3aeeab3b31..ca16dc8424 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -27,6 +27,7 @@
#include "feature/dirauth/authmode.h"
#include "feature/dirauth/bwauth.h"
#include "feature/dirauth/dirauth_periodic.h"
+#include "feature/dirauth/dirauth_sys.h"
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/guardfraction.h"
#include "feature/dirauth/dirauth_options_st.h"
@@ -45,6 +46,14 @@
#define YES_IF_CHANGED_INT(opt) \
if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
+/** Return true iff we are configured to reject request under load for non
+ * relay connections. */
+bool
+dirauth_should_reject_requests_under_load(void)
+{
+ return !!dirauth_get_options()->AuthDirRejectRequestsUnderLoad;
+}
+
/**
* Legacy validation/normalization function for the dirauth mode options in
* options. Uses old_options as the previous options.
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index 2ebafd917e..9042ff8779 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -35,6 +35,8 @@ int options_act_dirauth_mtbf(const struct or_options_t *old_options);
int options_act_dirauth_stats(const struct or_options_t *old_options,
bool *print_notice_out);
+bool dirauth_should_reject_requests_under_load(void);
+
extern const struct config_format_t dirauth_options_fmt;
#else /* !defined(HAVE_MODULE_DIRAUTH) */
@@ -67,16 +69,22 @@ 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)
#endif /* defined(HAVE_MODULE_DIRAUTH) */
diff --git a/src/feature/dirauth/dirauth_options.inc b/src/feature/dirauth/dirauth_options.inc
index 5939010fe7..21f4996c39 100644
--- a/src/feature/dirauth/dirauth_options.inc
+++ b/src/feature/dirauth/dirauth_options.inc
@@ -95,4 +95,11 @@ CONF_VAR(TestingMinFastFlagThreshold, MEMUNIT, 0, "0")
* versions? */
CONF_VAR(VersioningAuthoritativeDirectory, BOOL, 0, "0")
+/** Boolean: Under bandwidth pressure, if set to 1, the authority will always
+ * answer directory requests from relays but will start sending 503 error code
+ * for the other connections. If set to 0, all connections are considered the
+ * same and the authority will try to answer them all regardless of bandwidth
+ * pressure or not. */
+CONF_VAR(AuthDirRejectRequestsUnderLoad, BOOL, 0, "1")
+
END_CONF_STRUCT(dirauth_options_t)
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index 9490867e82..e230815ca3 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,
@@ -3564,6 +3567,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,
@@ -3626,7 +3637,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 f695e93abf..675f4ee148 100644
--- a/src/feature/dirauth/dirvote.h
+++ b/src/feature/dirauth/dirvote.h
@@ -162,7 +162,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/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 55b828ba64..1461ab697d 100644
--- a/src/feature/dirauth/process_descs.h
+++ b/src/feature/dirauth/process_descs.h
@@ -15,7 +15,7 @@
// for was_router_added_t.
#include "feature/nodelist/routerlist.h"
-#include "src/lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
struct authdir_config_t;
@@ -47,7 +47,7 @@ typedef struct authdir_config_t {
#define RTR_BADEXIT 16 /**< We'll tell clients not to use this as an exit. */
/* 32 Historically used to indicade Unnamed */
-#endif /* defined(TOR_UNIT_TESTS) */
+#endif /* defined(PROCESS_DESCS_PRIVATE) || defined(TOR_UNIT_TESTS) */
#ifdef TOR_UNIT_TESTS
@@ -55,7 +55,7 @@ void authdir_init_fingerprint_list(void);
authdir_config_t *authdir_return_fingerprint_list(void);
-#endif /* defined(PROCESS_DESCS_PRIVATE) || defined(TOR_UNIT_TESTS) */
+#endif /* defined(TOR_UNIT_TESTS) */
void dirserv_free_fingerprint_list(void);
@@ -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/dircache.c b/src/feature/dircache/dircache.c
index ef7054001e..3b8775968a 100644
--- a/src/feature/dircache/dircache.c
+++ b/src/feature/dircache/dircache.c
@@ -957,7 +957,7 @@ handle_get_current_consensus(dir_connection_t *conn,
goto done;
}
- if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) {
+ if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) {
log_debug(LD_DIRSERV,
"Client asked for network status lists, but we've been "
"writing too many bytes lately. Sending 503 Dir busy.");
@@ -1066,7 +1066,7 @@ handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
}
});
- if (global_write_bucket_low(TO_CONN(conn), estimated_len, 2)) {
+ if (connection_dir_is_global_write_low(TO_CONN(conn), estimated_len)) {
write_short_http_response(conn, 503, "Directory busy, try again later");
goto vote_done;
}
@@ -1125,7 +1125,7 @@ handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
write_short_http_response(conn, 404, "Not found");
goto done;
}
- if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) {
+ if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) {
log_info(LD_DIRSERV,
"Client asked for server descriptors, but we've been "
"writing too many bytes lately. Sending 503 Dir busy.");
@@ -1223,7 +1223,7 @@ handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
msg = "Not found";
write_short_http_response(conn, 404, msg);
} else {
- if (global_write_bucket_low(TO_CONN(conn), size_guess, 2)) {
+ if (connection_dir_is_global_write_low(TO_CONN(conn), size_guess)) {
log_info(LD_DIRSERV,
"Client asked for server descriptors, but we've been "
"writing too many bytes lately. Sending 503 Dir busy.");
@@ -1319,9 +1319,8 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
SMARTLIST_FOREACH(certs, authority_cert_t *, c,
len += c->cache_info.signed_descriptor_len);
- if (global_write_bucket_low(TO_CONN(conn),
- compress_method != NO_METHOD ? len/2 : len,
- 2)) {
+ if (connection_dir_is_global_write_low(TO_CONN(conn),
+ compress_method != NO_METHOD ? len/2 : len)) {
write_short_http_response(conn, 503, "Directory busy, try again later");
goto keys_done;
}
diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h
index 3a168c2035..73a64b1b7e 100644
--- a/src/feature/dircache/dirserv.h
+++ b/src/feature/dircache/dirserv.h
@@ -93,7 +93,7 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus,
const common_digests_t *digests,
const uint8_t *sha3_as_signed,
time_t published);
-#else
+#else /* !defined(HAVE_MODULE_DIRCACHE) */
#define have_module_dircache() (0)
#define directory_caches_unknown_auth_certs(opt) \
((void)(opt), 0)
@@ -112,7 +112,7 @@ void dirserv_set_cached_consensus_networkstatus(const char *consensus,
(void)(e); \
(void)(f); \
} STMT_END
-#endif
+#endif /* defined(HAVE_MODULE_DIRCACHE) */
void dirserv_clear_old_networkstatuses(time_t cutoff);
int dirserv_get_routerdesc_spool(smartlist_t *spools_out, const char *key,
diff --git a/src/feature/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_client.c b/src/feature/hs/hs_client.c
index 222261e604..af8cb0b410 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,
uint8_t subcredential[DIGEST256_LEN];
ed25519_public_key_t blinded_pubkey;
hs_client_service_authorization_t *client_auth = NULL;
- curve25519_secret_key_t *client_auht_sk = NULL;
+ curve25519_secret_key_t *client_auth_sk = NULL;
tor_assert(desc_str);
tor_assert(service_identity_pk);
@@ -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_descriptor.c b/src/feature/hs/hs_descriptor.c
index 65d6c7a581..4d4200bd64 100644
--- a/src/feature/hs/hs_descriptor.c
+++ b/src/feature/hs/hs_descriptor.c
@@ -56,6 +56,7 @@
#define HS_DESCRIPTOR_PRIVATE
#include "core/or/or.h"
+#include "app/config/config.h"
#include "trunnel/ed25519_cert.h" /* Trunnel interface. */
#include "feature/hs/hs_descriptor.h"
#include "core/or/circuitbuild.h"
@@ -1287,11 +1288,20 @@ cert_is_valid(tor_cert_t *cert, uint8_t type, const char *log_obj_type)
log_warn(LD_REND, "Signing key is NOT included for %s.", log_obj_type);
goto err;
}
+
/* The following will not only check if the signature matches but also the
* expiration date and overall validity. */
if (tor_cert_checksig(cert, &cert->signing_key, approx_time()) < 0) {
- log_warn(LD_REND, "Invalid signature for %s: %s", log_obj_type,
- tor_cert_describe_signature_status(cert));
+ if (cert->cert_expired) {
+ char expiration_str[ISO_TIME_LEN+1];
+ format_iso_time(expiration_str, cert->valid_until);
+ log_fn(LOG_PROTOCOL_WARN, LD_REND, "Invalid signature for %s: %s (%s)",
+ log_obj_type, tor_cert_describe_signature_status(cert),
+ expiration_str);
+ } else {
+ log_warn(LD_REND, "Invalid signature for %s: %s",
+ log_obj_type, tor_cert_describe_signature_status(cert));
+ }
goto err;
}
diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c
index 81b37eab40..b366ce83d9 100644
--- a/src/feature/hs/hs_service.c
+++ b/src/feature/hs/hs_service.c
@@ -3556,6 +3556,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/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index 06f4f5482b..ad3af0a143 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -49,6 +49,37 @@ static smartlist_t *trusted_dir_servers = NULL;
* and all fallback directory servers. */
static smartlist_t *fallback_dir_servers = NULL;
+/** Helper: From a given trusted directory entry, add the v4 or/and v6 address
+ * to the nodelist address set. */
+static void
+add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
+{
+ tor_assert(dir);
+ tor_assert(dir->is_authority);
+
+ /* Add IPv4 and then IPv6 if applicable. */
+ nodelist_add_addr4_to_address_set(dir->addr);
+ if (!tor_addr_is_null(&dir->ipv6_addr)) {
+ nodelist_add_addr6_to_address_set(&dir->ipv6_addr);
+ }
+}
+
+/** Go over the trusted directory server list and add their address(es) to the
+ * nodelist address set. This is called everytime a new consensus is set. */
+MOCK_IMPL(void,
+dirlist_add_trusted_dir_addresses, (void))
+{
+ if (!trusted_dir_servers) {
+ return;
+ }
+
+ SMARTLIST_FOREACH_BEGIN(trusted_dir_servers, const dir_server_t *, ent) {
+ if (ent->is_authority) {
+ add_trusted_dir_to_nodelist_addr_set(ent);
+ }
+ } SMARTLIST_FOREACH_END(ent);
+}
+
/** Return the number of directory authorities whose type matches some bit set
* in <b>type</b> */
int
diff --git a/src/feature/nodelist/dirlist.h b/src/feature/nodelist/dirlist.h
index 6bfc2e1b01..9201e76a9c 100644
--- a/src/feature/nodelist/dirlist.h
+++ b/src/feature/nodelist/dirlist.h
@@ -44,4 +44,6 @@ void dir_server_add(dir_server_t *ent);
void clear_dir_servers(void);
void dirlist_free_all(void);
+MOCK_DECL(void, dirlist_add_trusted_dir_addresses, (void));
+
#endif /* !defined(TOR_DIRLIST_H) */
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index 0d2ff96a6e..cc4b8e1c34 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -102,7 +102,7 @@
#include "feature/nodelist/routerlist_st.h"
#include "feature/dirauth/vote_microdesc_hash_st.h"
#include "feature/nodelist/vote_routerstatus_st.h"
-#include "routerstatus_st.h"
+#include "feature/nodelist/routerstatus_st.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index 94ff08826f..b7c7552561 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -455,22 +455,43 @@ node_add_to_address_set(const node_t *node)
if (node->rs) {
if (node->rs->addr)
- address_set_add_ipv4h(the_nodelist->node_addrs, node->rs->addr);
+ nodelist_add_addr4_to_address_set(node->rs->addr);
if (!tor_addr_is_null(&node->rs->ipv6_addr))
- address_set_add(the_nodelist->node_addrs, &node->rs->ipv6_addr);
+ nodelist_add_addr6_to_address_set(&node->rs->ipv6_addr);
}
if (node->ri) {
if (node->ri->addr)
- address_set_add_ipv4h(the_nodelist->node_addrs, node->ri->addr);
+ nodelist_add_addr4_to_address_set(node->ri->addr);
if (!tor_addr_is_null(&node->ri->ipv6_addr))
- address_set_add(the_nodelist->node_addrs, &node->ri->ipv6_addr);
+ nodelist_add_addr6_to_address_set(&node->ri->ipv6_addr);
}
if (node->md) {
if (!tor_addr_is_null(&node->md->ipv6_addr))
- address_set_add(the_nodelist->node_addrs, &node->md->ipv6_addr);
+ nodelist_add_addr6_to_address_set(&node->md->ipv6_addr);
}
}
+/** Add the given v4 address into the nodelist address set. */
+void
+nodelist_add_addr4_to_address_set(const uint32_t addr)
+{
+ if (!the_nodelist || !the_nodelist->node_addrs || addr == 0) {
+ return;
+ }
+ address_set_add_ipv4h(the_nodelist->node_addrs, addr);
+}
+
+/** Add the given v6 address into the nodelist address set. */
+void
+nodelist_add_addr6_to_address_set(const tor_addr_t *addr)
+{
+ if (BUG(!addr) || tor_addr_is_null(addr) || tor_addr_is_v4(addr) ||
+ !the_nodelist || !the_nodelist->node_addrs) {
+ return;
+ }
+ address_set_add(the_nodelist->node_addrs, addr);
+}
+
/** Return true if <b>addr</b> is the address of some node in the nodelist.
* If not, probably return false. */
int
@@ -612,9 +633,12 @@ nodelist_set_consensus(networkstatus_t *ns)
SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node,
node->rs = NULL);
- /* Conservatively estimate that every node will have 2 addresses. */
- const int estimated_addresses = smartlist_len(ns->routerstatus_list) *
- get_estimated_address_per_node();
+ /* Conservatively estimate that every node will have 2 addresses (v4 and
+ * v6). Then we add the number of configured trusted authorities we have. */
+ int estimated_addresses = smartlist_len(ns->routerstatus_list) *
+ get_estimated_address_per_node();
+ estimated_addresses += (get_n_authorities(V3_DIRINFO & BRIDGE_DIRINFO) *
+ get_estimated_address_per_node());
address_set_free(the_nodelist->node_addrs);
the_nodelist->node_addrs = address_set_new(estimated_addresses);
@@ -665,6 +689,9 @@ nodelist_set_consensus(networkstatus_t *ns)
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
node_add_to_address_set(node);
} SMARTLIST_FOREACH_END(node);
+ /* Then, add all trusted configured directories. Some might not be in the
+ * consensus so make sure we know them. */
+ dirlist_add_trusted_dir_addresses();
if (! authdir) {
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h
index 9742e3dff2..87020b81eb 100644
--- a/src/feature/nodelist/nodelist.h
+++ b/src/feature/nodelist/nodelist.h
@@ -35,6 +35,8 @@ node_t *nodelist_add_microdesc(microdesc_t *md);
void nodelist_set_consensus(networkstatus_t *ns);
void nodelist_ensure_freshness(networkstatus_t *ns);
int nodelist_probably_contains_address(const tor_addr_t *addr);
+void nodelist_add_addr4_to_address_set(const uint32_t addr);
+void nodelist_add_addr6_to_address_set(const tor_addr_t *addr);
void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
void nodelist_remove_routerinfo(routerinfo_t *ri);
diff --git a/src/feature/relay/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/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h
index 907622f942..1bb8c54a0c 100644
--- a/src/lib/cc/compat_compiler.h
+++ b/src/lib/cc/compat_compiler.h
@@ -238,6 +238,6 @@
#define POSSIBLE(expr) ((expr) || getenv("STATIC_ANALYZER_DEADCODE_DUMMY_"))
#else
#define POSSIBLE(expr) (expr)
-#endif
+#endif /* defined(__COVERITY__) || defined(__clang_analyzer__) */
#endif /* !defined(TOR_COMPAT_COMPILER_H) */
diff --git a/src/lib/confmgt/type_defs.c b/src/lib/confmgt/type_defs.c
index 3f66cba61a..d9e5e1e4c2 100644
--- a/src/lib/confmgt/type_defs.c
+++ b/src/lib/confmgt/type_defs.c
@@ -121,8 +121,9 @@ int_parse(void *target, const char *value, char **errmsg, const void *params)
int ok=0;
*p = (int)tor_parse_long(value, 10, pp->minval, pp->maxval, &ok, NULL);
if (!ok) {
- tor_asprintf(errmsg, "Integer %s is malformed or out of bounds.",
- value);
+ tor_asprintf(errmsg, "Integer %s is malformed or out of bounds. "
+ "Allowed values are between %d and %d.",
+ value, pp->minval, pp->maxval);
return -1;
}
return 0;
@@ -228,11 +229,17 @@ units_parse_u64(void *target, const char *value, char **errmsg,
tor_assert(table);
uint64_t *v = (uint64_t*)target;
int ok=1;
- *v = config_parse_units(value, table, &ok);
+ char *msg = NULL;
+ *v = config_parse_units(value, table, &ok, &msg);
if (!ok) {
- *errmsg = tor_strdup("Provided value is malformed or out of bounds.");
+ tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s",
+ msg);
+ tor_free(msg);
return -1;
}
+ if (BUG(msg)) {
+ tor_free(msg);
+ }
return 0;
}
@@ -244,11 +251,17 @@ units_parse_int(void *target, const char *value, char **errmsg,
tor_assert(table);
int *v = (int*)target;
int ok=1;
- uint64_t u64 = config_parse_units(value, table, &ok);
+ char *msg = NULL;
+ uint64_t u64 = config_parse_units(value, table, &ok, &msg);
if (!ok) {
- *errmsg = tor_strdup("Provided value is malformed or out of bounds.");
+ tor_asprintf(errmsg, "Provided value is malformed or out of bounds: %s",
+ msg);
+ tor_free(msg);
return -1;
}
+ if (BUG(msg)) {
+ tor_free(msg);
+ }
if (u64 > INT_MAX) {
tor_asprintf(errmsg, "Provided value %s is too large", value);
return -1;
@@ -348,11 +361,17 @@ typedef struct enumeration_table_t {
int value;
} enumeration_table_t;
+typedef struct enumeration_params_t {
+ const char *allowed_val_string;
+ const enumeration_table_t *table;
+} enumeration_params_t;
+
static int
enum_parse(void *target, const char *value, char **errmsg,
- const void *params)
+ const void *params_)
{
- const enumeration_table_t *table = params;
+ const enumeration_params_t *params = params_;
+ const enumeration_table_t *table = params->table;
int *p = (int *)target;
for (; table->name; ++table) {
if (!strcasecmp(value, table->name)) {
@@ -360,15 +379,17 @@ enum_parse(void *target, const char *value, char **errmsg,
return 0;
}
}
- tor_asprintf(errmsg, "Unrecognized value %s.", value);
+ tor_asprintf(errmsg, "Unrecognized value %s. %s",
+ value, params->allowed_val_string);
return -1;
}
static char *
-enum_encode(const void *value, const void *params)
+enum_encode(const void *value, const void *params_)
{
int v = *(const int*)value;
- const enumeration_table_t *table = params;
+ const enumeration_params_t *params = params_;
+ const enumeration_table_t *table = params->table;
for (; table->name; ++table) {
if (v == table->value)
return tor_strdup(table->name);
@@ -377,19 +398,21 @@ enum_encode(const void *value, const void *params)
}
static void
-enum_clear(void *value, const void *params)
+enum_clear(void *value, const void *params_)
{
int *p = (int*)value;
- const enumeration_table_t *table = params;
+ const enumeration_params_t *params = params_;
+ const enumeration_table_t *table = params->table;
tor_assert(table->name);
*p = table->value;
}
static bool
-enum_ok(const void *value, const void *params)
+enum_ok(const void *value, const void *params_)
{
int v = *(const int*)value;
- const enumeration_table_t *table = params;
+ const enumeration_params_t *params = params_;
+ const enumeration_table_t *table = params->table;
for (; table->name; ++table) {
if (v == table->value)
return true;
@@ -403,6 +426,11 @@ static const enumeration_table_t enum_table_bool[] = {
{ NULL, 0 },
};
+static const enumeration_params_t enum_params_bool = {
+ "Allowed values are 0 and 1.",
+ enum_table_bool
+};
+
static const enumeration_table_t enum_table_autobool[] = {
{ "0", 0 },
{ "1", 1 },
@@ -410,6 +438,11 @@ static const enumeration_table_t enum_table_autobool[] = {
{ NULL, 0 },
};
+static const enumeration_params_t enum_params_autobool = {
+ "Allowed values are 0, 1, and auto.",
+ enum_table_autobool
+};
+
static const var_type_fns_t enum_fns = {
.parse = enum_parse,
.encode = enum_encode,
@@ -740,10 +773,10 @@ const var_type_def_t DOUBLE_type_defn = {
.name="Float", .fns=&double_fns, };
const var_type_def_t BOOL_type_defn = {
.name="Boolean", .fns=&enum_fns,
- .params=&enum_table_bool };
+ .params=&enum_params_bool };
const var_type_def_t AUTOBOOL_type_defn = {
.name="Boolean+Auto", .fns=&enum_fns,
- .params=&enum_table_autobool };
+ .params=&enum_params_autobool };
const var_type_def_t ISOTIME_type_defn = {
.name="Time", .fns=&time_fns, };
const var_type_def_t CSV_type_defn = {
diff --git a/src/lib/confmgt/typedvar.c b/src/lib/confmgt/typedvar.c
index 3a188db953..1955302cdc 100644
--- a/src/lib/confmgt/typedvar.c
+++ b/src/lib/confmgt/typedvar.c
@@ -24,6 +24,7 @@
#include "lib/log/log.h"
#include "lib/log/util_bug.h"
#include "lib/malloc/malloc.h"
+#include "lib/string/printf.h"
#include "lib/string/util_string.h"
#include "lib/confmgt/var_type_def_st.h"
@@ -75,7 +76,15 @@ typed_var_kvassign(void *target, const config_line_t *line,
return def->fns->kv_parse(target, line, errmsg, def->params);
}
- return typed_var_assign(target, line->value, errmsg, def);
+ int rv = typed_var_assign(target, line->value, errmsg, def);
+ if (rv < 0 && *errmsg != NULL) {
+ /* typed_var_assign() didn't know the line's keyword, but we do.
+ * Let's add it to the error message. */
+ char *oldmsg = *errmsg;
+ tor_asprintf(errmsg, "Could not parse %s: %s", line->key, oldmsg);
+ tor_free(oldmsg);
+ }
+ return rv;
}
/**
diff --git a/src/lib/confmgt/unitparse.c b/src/lib/confmgt/unitparse.c
index 52c0eabb69..61edc60694 100644
--- a/src/lib/confmgt/unitparse.c
+++ b/src/lib/confmgt/unitparse.c
@@ -13,7 +13,9 @@
#include "lib/confmgt/unitparse.h"
#include "lib/log/log.h"
#include "lib/log/util_bug.h"
+#include "lib/malloc/malloc.h"
#include "lib/string/parse_int.h"
+#include "lib/string/printf.h"
#include "lib/string/util_string.h"
#include "lib/intmath/muldiv.h"
@@ -110,23 +112,30 @@ const struct unit_table_t time_msec_units[] = {
* table <b>u</b>, then multiply the number by the unit multiplier.
* On success, set *<b>ok</b> to 1 and return this product.
* Otherwise, set *<b>ok</b> to 0.
- * Warns user when overflow or a negative value is detected.
+ *
+ * If an error (like overflow or a negative value is detected), put an error
+ * message in *<b>errmsg_out</b> if that pointer is non-NULL, and otherwise
+ * log a warning.
*/
uint64_t
-config_parse_units(const char *val, const unit_table_t *u, int *ok)
+config_parse_units(const char *val, const unit_table_t *u, int *ok,
+ char **errmsg_out)
{
uint64_t v = 0;
double d = 0;
int use_float = 0;
char *cp;
+ char *errmsg = NULL;
tor_assert(ok);
v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
if (!*ok || (cp && *cp == '.')) {
d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp);
- if (!*ok)
+ if (!*ok) {
+ tor_asprintf(&errmsg, "Unable to parse %s as a number", val);
goto done;
+ }
use_float = 1;
}
@@ -148,8 +157,8 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok)
d = u->multiplier * d;
if (d < 0) {
- log_warn(LD_CONFIG, "Got a negative value while parsing %s %s",
- val, u->unit);
+ tor_asprintf(&errmsg, "Got a negative value while parsing %s %s",
+ val, u->unit);
*ok = 0;
goto done;
}
@@ -157,8 +166,8 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok)
// Some compilers may warn about casting a double to an unsigned type
// because they don't know if d is >= 0
if (d >= 0 && (d > (double)INT64_MAX || (uint64_t)d > INT64_MAX)) {
- log_warn(LD_CONFIG, "Overflow detected while parsing %s %s",
- val, u->unit);
+ tor_asprintf(&errmsg, "Overflow while parsing %s %s",
+ val, u->unit);
*ok = 0;
goto done;
}
@@ -168,8 +177,8 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok)
v = tor_mul_u64_nowrap(v, u->multiplier);
if (v > INT64_MAX) {
- log_warn(LD_CONFIG, "Overflow detected while parsing %s %s",
- val, u->unit);
+ tor_asprintf(&errmsg, "Overflow while parsing %s %s",
+ val, u->unit);
*ok = 0;
goto done;
}
@@ -179,10 +188,20 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok)
goto done;
}
}
- log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
+ tor_asprintf(&errmsg, "Unknown unit in %s", val);
*ok = 0;
done:
+ if (errmsg) {
+ tor_assert_nonfatal(!*ok);
+ if (errmsg_out) {
+ *errmsg_out = errmsg;
+ } else {
+ log_warn(LD_CONFIG, "%s", errmsg);
+ tor_free(errmsg);
+ }
+ }
+
if (*ok)
return v;
else
@@ -196,7 +215,7 @@ config_parse_units(const char *val, const unit_table_t *u, int *ok)
uint64_t
config_parse_memunit(const char *s, int *ok)
{
- uint64_t u = config_parse_units(s, memory_units, ok);
+ uint64_t u = config_parse_units(s, memory_units, ok, NULL);
return u;
}
@@ -208,7 +227,7 @@ int
config_parse_msec_interval(const char *s, int *ok)
{
uint64_t r;
- r = config_parse_units(s, time_msec_units, ok);
+ r = config_parse_units(s, time_msec_units, ok, NULL);
if (r > INT_MAX) {
log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
*ok = 0;
@@ -225,7 +244,7 @@ int
config_parse_interval(const char *s, int *ok)
{
uint64_t r;
- r = config_parse_units(s, time_units, ok);
+ r = config_parse_units(s, time_units, ok, NULL);
if (r > INT_MAX) {
log_warn(LD_CONFIG, "Interval '%s' is too long", s);
*ok = 0;
diff --git a/src/lib/confmgt/unitparse.h b/src/lib/confmgt/unitparse.h
index 3f4f039a0e..047e11b424 100644
--- a/src/lib/confmgt/unitparse.h
+++ b/src/lib/confmgt/unitparse.h
@@ -25,7 +25,8 @@ extern const unit_table_t memory_units[];
extern const unit_table_t time_units[];
extern const struct unit_table_t time_msec_units[];
-uint64_t config_parse_units(const char *val, const unit_table_t *u, int *ok);
+uint64_t config_parse_units(const char *val, const unit_table_t *u, int *ok,
+ char **errmsg_out);
uint64_t config_parse_memunit(const char *s, int *ok);
int config_parse_msec_interval(const char *s, int *ok);
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/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/test/test_addr.c b/src/test/test_addr.c
index af3c125a20..42232e467a 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -110,7 +110,7 @@ test_addr_basic(void *arg)
tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), OP_EQ, 1); \
t1.family = AF_INET6; \
if (tor_addr_is_internal(&t1, for_listening)) \
- TT_DIE(("%s was not internal", a)); \
+ TT_DIE(("%s was internal", a)); \
STMT_END
#ifndef COCCI
diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c
index 3fcf8c4d13..829ecd79e8 100644
--- a/src/test/test_address_set.c
+++ b/src/test/test_address_set.c
@@ -4,6 +4,7 @@
#include "core/or/or.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "core/or/address_set.h"
+#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
@@ -31,6 +32,12 @@ mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
return dummy_ns;
}
+static void
+mock_dirlist_add_trusted_dir_addresses(void)
+{
+ return;
+}
+
/* Number of address a single node_t can have. Default to the production
* value. This is to control the size of the bloom filter. */
static int addr_per_node = 2;
@@ -98,6 +105,8 @@ test_nodelist(void *arg)
mock_networkstatus_get_latest_consensus_by_flavor);
MOCK(get_estimated_address_per_node,
mock_get_estimated_address_per_node);
+ MOCK(dirlist_add_trusted_dir_addresses,
+ mock_dirlist_add_trusted_dir_addresses);
dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
dummy_ns->flavor = FLAV_MICRODESC;
@@ -113,7 +122,10 @@ test_nodelist(void *arg)
* (the_nodelist->node_addrs) so we will fail the contain test rarely. */
addr_per_node = 1024;
- /* No node no nothing. The lookups should be empty. */
+ /* No node no nothing. The lookups should be empty. We've mocked the
+ * dirlist_add_trusted_dir_addresses in order for _no_ authorities to be
+ * added to the filter else it makes this test to trigger many false
+ * positive. */
nodelist_set_consensus(dummy_ns);
/* The address set should be empty. */
@@ -167,6 +179,7 @@ test_nodelist(void *arg)
UNMOCK(networkstatus_get_latest_consensus);
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
UNMOCK(get_estimated_address_per_node);
+ UNMOCK(dirlist_add_trusted_dir_addresses);
}
struct testcase_t address_set_tests[] = {
diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c
index 1da3796981..117783cafc 100644
--- a/src/test/test_bwmgt.c
+++ b/src/test/test_bwmgt.c
@@ -6,18 +6,70 @@
* \brief tests for bandwidth management / token bucket functions
*/
+#define CONFIG_PRIVATE
+#define CONNECTION_PRIVATE
+#define DIRAUTH_SYS_PRIVATE
#define TOKEN_BUCKET_PRIVATE
#include "core/or/or.h"
-#include "test/test.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "feature/dirauth/dirauth_sys.h"
+#include "feature/dircommon/directory.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerlist.h"
+#include "lib/crypt_ops/crypto_rand.h"
#include "lib/evloop/token_bucket.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+
+#include "app/config/or_options_st.h"
+#include "core/or/connection_st.h"
+#include "feature/dirauth/dirauth_options_st.h"
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
// an imaginary time, in timestamp units. Chosen so it will roll over.
static const uint32_t START_TS = UINT32_MAX-10;
static const int32_t KB = 1024;
static const uint32_t GB = (UINT64_C(1) << 30);
+static or_options_t mock_options;
+
+static const or_options_t *
+mock_get_options(void)
+{
+ return &mock_options;
+}
+
+static networkstatus_t *dummy_ns = NULL;
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus(void)
+{
+ return dummy_ns;
+}
+
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
+{
+ tor_assert(f == FLAV_MICRODESC);
+ return dummy_ns;
+}
+
+/* Number of address a single node_t can have. Default to the production
+ * value. This is to control the size of the bloom filter. */
+static int addr_per_node = 2;
+static int
+mock_get_estimated_address_per_node(void)
+{
+ return addr_per_node;
+}
+
static void
test_bwmgt_token_buf_init(void *arg)
{
@@ -220,8 +272,167 @@ test_bwmgt_token_buf_helpers(void *arg)
;
}
+static void
+test_bwmgt_dir_conn_global_write_low(void *arg)
+{
+ bool ret;
+ int addr_family;
+ connection_t *conn = NULL;
+ routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
+ tor_addr_t relay_addr;
+ dirauth_options_t *dirauth_opts = NULL;
+
+ (void) arg;
+
+ memset(&mock_options, 0, sizeof(or_options_t));
+ MOCK(networkstatus_get_latest_consensus,
+ mock_networkstatus_get_latest_consensus);
+ MOCK(networkstatus_get_latest_consensus_by_flavor,
+ mock_networkstatus_get_latest_consensus_by_flavor);
+ MOCK(get_estimated_address_per_node,
+ mock_get_estimated_address_per_node);
+
+ /*
+ * The following is rather complex but that is what it takes to add a dummy
+ * consensus with a valid routerlist which will populate our node address
+ * set that we need to lookup to test the known relay code path.
+ *
+ * We MUST do that before we MOCK(get_options) else it is another world of
+ * complexity.
+ */
+
+ /* This will be the address of our relay. */
+ tor_addr_parse(&relay_addr, "1.2.3.4");
+
+ /* We'll now add a relay into our routerlist and see if we let it. */
+ dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
+ dummy_ns->flavor = FLAV_MICRODESC;
+ dummy_ns->routerstatus_list = smartlist_new();
+
+ md = tor_malloc_zero(sizeof(*md));
+ ri = tor_malloc_zero(sizeof(*ri));
+ rs = tor_malloc_zero(sizeof(*rs));
+ crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
+ crypto_rand(md->digest, sizeof(md->digest));
+ memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
+
+ /* Set IP address. */
+ rs->addr = tor_addr_to_ipv4h(&relay_addr);
+ ri->addr = rs->addr;
+ /* Add the rs to the consensus becoming a node_t. */
+ smartlist_add(dummy_ns->routerstatus_list, rs);
+
+ /* Add all configured authorities (hardcoded) before we set the consensus so
+ * the address set exists. */
+ ret = consider_adding_dir_servers(&mock_options, &mock_options);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* This will make the nodelist bloom filter very large
+ * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
+ addr_per_node = 1024;
+
+ nodelist_set_consensus(dummy_ns);
+
+ dirauth_opts = tor_malloc_zero(sizeof(dirauth_options_t));
+ dirauth_opts->AuthDirRejectRequestsUnderLoad = 0;
+ dirauth_set_options(dirauth_opts);
+
+ /* Ok, now time to control which options we use. */
+ MOCK(get_options, mock_get_options);
+
+ /* Set ourselves as an authoritative dir. */
+ mock_options.AuthoritativeDir = 1;
+ mock_options.V3AuthoritativeDir = 1;
+ mock_options.UseDefaultFallbackDirs = 0;
+
+ /* This will set our global bucket to 1 byte and thus we will hit the
+ * banwdith limit in our test. */
+ mock_options.BandwidthRate = 1;
+ mock_options.BandwidthBurst = 1;
+
+ /* Else an IPv4 address screams. */
+ mock_options.ClientUseIPv4 = 1;
+ mock_options.ClientUseIPv6 = 1;
+
+ /* Initialize the global buckets. */
+ connection_bucket_init();
+
+ /* The address "127.0.0.1" is set with this helper. */
+ conn = test_conn_get_connection(DIR_CONN_STATE_MIN_, CONN_TYPE_DIR,
+ DIR_PURPOSE_MIN_);
+ tt_assert(conn);
+
+ /* First try a non authority non relay IP thus a client but we are not
+ * configured to reject requests under load so we should get a false value
+ * that our limit is _not_ low. */
+ addr_family = tor_addr_parse(&conn->addr, "1.1.1.1");
+ tt_int_op(addr_family, OP_EQ, AF_INET);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Now, we will reject requests under load so try again a non authority non
+ * relay IP thus a client. We should get a warning that our limit is too
+ * low. */
+ dirauth_opts->AuthDirRejectRequestsUnderLoad = 1;
+
+ addr_family = tor_addr_parse(&conn->addr, "1.1.1.1");
+ tt_int_op(addr_family, OP_EQ, AF_INET);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 1);
+
+ /* Now, lets try with a connection address from moria1. It should always
+ * pass even though our limit is too low. */
+ addr_family = tor_addr_parse(&conn->addr, "128.31.0.39");
+ tt_int_op(addr_family, OP_EQ, AF_INET);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* IPv6 testing of gabelmoo. */
+ addr_family = tor_addr_parse(&conn->addr, "[2001:638:a000:4140::ffff:189]");
+ tt_int_op(addr_family, OP_EQ, AF_INET6);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Lets retry with a known relay address. It should pass. Possible due to
+ * our consensus setting above. */
+ memcpy(&conn->addr, &relay_addr, sizeof(tor_addr_t));
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Lets retry with a random IP that is not an authority nor a relay. */
+ addr_family = tor_addr_parse(&conn->addr, "1.2.3.4");
+ tt_int_op(addr_family, OP_EQ, AF_INET);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Finally, just make sure it still denies an IP if we are _not_ a v3
+ * directory authority. */
+ mock_options.V3AuthoritativeDir = 0;
+ addr_family = tor_addr_parse(&conn->addr, "1.2.3.4");
+ tt_int_op(addr_family, OP_EQ, AF_INET);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 1);
+
+ /* Random IPv6 should not be allowed. */
+ addr_family = tor_addr_parse(&conn->addr, "[CAFE::ACAB]");
+ tt_int_op(addr_family, OP_EQ, AF_INET6);
+ ret = connection_dir_is_global_write_low(conn, INT_MAX);
+ tt_int_op(ret, OP_EQ, 1);
+
+ done:
+ connection_free_minimal(conn);
+ routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
+ smartlist_clear(dummy_ns->routerstatus_list);
+ networkstatus_vote_free(dummy_ns);
+
+ UNMOCK(get_estimated_address_per_node);
+ UNMOCK(networkstatus_get_latest_consensus);
+ UNMOCK(networkstatus_get_latest_consensus_by_flavor);
+ UNMOCK(get_options);
+}
+
#define BWMGT(name) \
- { #name, test_bwmgt_ ## name , 0, NULL, NULL }
+ { #name, test_bwmgt_ ## name , TT_FORK, NULL, NULL }
struct testcase_t bwmgt_tests[] = {
BWMGT(token_buf_init),
@@ -229,5 +440,7 @@ struct testcase_t bwmgt_tests[] = {
BWMGT(token_buf_dec),
BWMGT(token_buf_refill),
BWMGT(token_buf_helpers),
+
+ BWMGT(dir_conn_global_write_low),
END_OF_TESTCASES
};
diff --git a/src/test/test_config.c b/src/test/test_config.c
index ee277104fb..7b9812f550 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -4159,7 +4159,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
tt_int_op(port_cfg->entry_cfg.dns_request, OP_EQ, 1);
tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 1);
tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 1);
- tt_int_op(port_cfg->entry_cfg.prefer_ipv6, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.prefer_ipv6, OP_EQ, 0);
tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
tt_int_op(port_cfg->entry_cfg.cache_ipv4_answers, OP_EQ, 0);
tt_int_op(port_cfg->entry_cfg.prefer_ipv6_virtaddr, OP_EQ, 1);
diff --git a/src/test/test_connection.h b/src/test/test_connection.h
index 9cf9efb8a4..bf327c0a3d 100644
--- a/src/test/test_connection.h
+++ b/src/test/test_connection.h
@@ -10,7 +10,7 @@
#define TEST_CONN_ADDRESS_2 "127.0.0.2"
#define TEST_CONN_PORT (12345)
#define TEST_CONN_ADDRESS_PORT "127.0.0.1:12345"
-#define TEST_CONN_FD_INIT 50
+#define TEST_CONN_FD_INIT 0x10000
void test_conn_lookup_addr_helper(const char *address,
int family, tor_addr_t *addr);
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_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_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_descriptor.c b/src/test/test_hs_descriptor.c
index 43ac5490a1..c5077f7143 100644
--- a/src/test/test_hs_descriptor.c
+++ b/src/test/test_hs_descriptor.c
@@ -14,6 +14,7 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "trunnel/ed25519_cert.h"
#include "core/or/or.h"
+#include "app/config/config.h"
#include "feature/hs/hs_descriptor.h"
#include "test/test.h"
#include "feature/nodelist/torcert.h"
@@ -37,7 +38,6 @@ test_cert_encoding(void *arg)
{
int ret;
char *encoded = NULL;
- time_t now = time(NULL);
ed25519_keypair_t kp;
ed25519_public_key_t signed_key;
ed25519_secret_key_t secret_key;
@@ -45,6 +45,10 @@ test_cert_encoding(void *arg)
(void) arg;
+ /* Change time to 03-01-2002 23:36 UTC */
+ update_approx_time(1010101010);
+ time_t now = approx_time();
+
ret = ed25519_keypair_generate(&kp, 0);
tt_int_op(ret, == , 0);
ret = ed25519_secret_key_generate(&secret_key, 0);
@@ -88,13 +92,31 @@ test_cert_encoding(void *arg)
/* The cert did have the signing key? */
ret= ed25519_pubkey_eq(&parsed_cert->signing_key, &kp.pubkey);
tt_int_op(ret, OP_EQ, 1);
- tor_cert_free(parsed_cert);
/* Get to the end part of the certificate. */
pos += b64_cert_len;
tt_int_op(strcmpstart(pos, "-----END ED25519 CERT-----"), OP_EQ, 0);
pos += strlen("-----END ED25519 CERT-----");
tt_str_op(pos, OP_EQ, "");
+
+ /* Check that certificate expiry works properly and emits the right log
+ message */
+ const char *msg = "fire";
+ /* Move us forward 4 hours so that the the certificate is definitely
+ expired */
+ update_approx_time(approx_time() + 3600*4);
+ setup_full_capture_of_logs(LOG_PROTOCOL_WARN);
+ ret = cert_is_valid(parsed_cert, CERT_TYPE_SIGNING_AUTH, msg);
+ tt_int_op(ret, OP_EQ, 0);
+ /* Since the current time at the creation of the cert was "03-01-2002
+ * 23:36", and the expiration date of the cert was two hours, the Tor code
+ * will ceiling that and make it 02:00. Make sure that the right log
+ * message is emitted */
+ expect_log_msg_containing("Invalid signature for fire: expired"
+ " (2002-01-04 02:00:00)");
+ teardown_capture_of_logs();
+
+ tor_cert_free(parsed_cert);
}
done:
diff --git a/src/test/test_options.c b/src/test/test_options.c
index b6a9a21501..9cd1d11d29 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -307,18 +307,10 @@ test_options_validate(void *arg)
WANT_ERR("BridgeRelay 1\nDirCache 0",
"We're a bridge but DirCache is disabled.", PH_VALIDATE);
- // XXXX We should replace this with a more full error message once #29211
- // XXXX is done. It is truncated for now because at the current stage
- // XXXX of refactoring, we can't give a full error message like before.
- WANT_ERR_LOG("HeartbeatPeriod 21 snarks",
- "malformed or out of bounds", LOG_WARN,
- "Unknown unit 'snarks'.",
- PH_ASSIGN);
- // XXXX As above.
- WANT_ERR_LOG("LogTimeGranularity 21 snarks",
- "malformed or out of bounds", LOG_WARN,
- "Unknown unit 'snarks'.",
- PH_ASSIGN);
+ WANT_ERR("HeartbeatPeriod 21 snarks",
+ "Unknown unit in 21 snarks", PH_ASSIGN);
+ WANT_ERR("LogTimeGranularity 21 snarks",
+ "Unknown unit in 21 snarks", PH_ASSIGN);
OK("HeartbeatPeriod 1 hour", PH_VALIDATE);
OK("LogTimeGranularity 100 milliseconds", PH_VALIDATE);
@@ -498,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);
@@ -644,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);
@@ -656,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:
@@ -4276,7 +4273,9 @@ test_options_trial_assign(void *arg)
tt_int_op(r, OP_EQ, 0);
v = options_trial_assign(lines, 0, &msg);
tt_int_op(v, OP_EQ, SETOPT_ERR_PARSE);
- tt_str_op(msg, OP_EQ, "Unrecognized value ambidextrous.");
+ tt_str_op(msg, OP_EQ,
+ "Could not parse UseBridges: Unrecognized value ambidextrous. "
+ "Allowed values are 0 and 1.");
tor_free(msg);
config_free_lines(lines);
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_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_util.c b/src/test/test_util.c
index 07c31f02d6..0d86a5ab5d 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1947,7 +1947,7 @@ test_util_expand_filename(void *arg)
done:
tor_free(str);
}
-#endif /* !defined(_WIN32) */
+#endif /* !defined(DISABLE_PWDB_TESTS) */
/** Test tor_escape_str_for_pt_args(). */
static void
@@ -5763,7 +5763,7 @@ test_util_pwdb(void *arg)
tor_free(dir);
teardown_capture_of_logs();
}
-#endif /* !(defined(_WIN32) || defined (__ANDROID__)) */
+#endif /* !defined(DISABLE_PWDB_TESTS) */
static void
test_util_calloc_check(void *arg)
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 655e36e336..e9aa4112c0 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();
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 7154b30f92..47ca863ce8 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -217,7 +217,7 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.4.3.2-alpha-dev"
+#define VERSION "0.4.3.3-alpha"
#define HAVE_STRUCT_SOCKADDR_IN6
#define HAVE_STRUCT_IN6_ADDR