aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml30
-rw-r--r--.travis.yml6
-rw-r--r--ChangeLog184
-rw-r--r--Makefile.am2
-rw-r--r--ReleaseNotes98
-rw-r--r--changes/bug330053
-rw-r--r--changes/ticket330393
-rw-r--r--changes/ticket332133
-rw-r--r--configure.ac40
-rwxr-xr-xcontrib/client-tools/tor-resolve.py10
-rw-r--r--contrib/win32build/tor-mingw.nsi.in2
-rw-r--r--doc/HACKING/HelpfulTools.md8
-rw-r--r--doc/tor.1.txt628
-rwxr-xr-xscripts/codegen/gen_server_ciphers.py14
-rwxr-xr-xscripts/codegen/get_mozilla_ciphers.py8
-rw-r--r--scripts/codegen/makedesc.py20
-rwxr-xr-xscripts/maint/format_changelog.py2
-rwxr-xr-xscripts/maint/locatemissingdoxygen.py6
-rwxr-xr-xscripts/maint/practracker/practracker.py30
-rw-r--r--scripts/maint/practracker/problem.py21
-rwxr-xr-xscripts/maint/practracker/test_practracker.sh12
-rw-r--r--scripts/maint/practracker/testdata/ex1-regen-expected.txt46
-rw-r--r--scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt45
-rwxr-xr-xscripts/maint/redox.py17
-rw-r--r--src/core/mainloop/connection.c6
-rw-r--r--src/core/mainloop/mainloop.c30
-rw-r--r--src/core/mainloop/mainloop.h2
-rw-r--r--src/ext/ed25519/ref10/base.py14
-rw-r--r--src/ext/ed25519/ref10/base2.py10
-rw-r--r--src/ext/ed25519/ref10/d.py2
-rw-r--r--src/ext/ed25519/ref10/d2.py2
-rw-r--r--src/ext/ed25519/ref10/sqrtm1.py2
-rw-r--r--src/feature/control/control.c4
-rw-r--r--src/feature/control/control_events.c32
-rw-r--r--src/feature/control/control_getinfo.c1
-rw-r--r--src/feature/hs/hs_cache.c36
-rw-r--r--src/feature/hs/hs_cache.h1
-rw-r--r--src/feature/hs/hs_client.c25
-rw-r--r--src/feature/hs/hs_client.h2
-rw-r--r--src/feature/rend/rendmid.c22
-rw-r--r--src/feature/stats/rephist.c2
-rw-r--r--src/lib/log/util_bug.h2
-rw-r--r--src/lib/net/address.h24
-rw-r--r--src/lib/tls/buffers_tls.c8
-rw-r--r--src/rust/protover/protover.rs2
-rw-r--r--src/test/ed25519_exts_ref.py20
-rw-r--r--src/test/test_controller_events.c39
-rw-r--r--src/test/test_hs_cache.c55
-rw-r--r--src/test/test_hs_client.c100
-rw-r--r--src/test/test_hs_control.c6
-rw-r--r--src/win32/orconfig.h2
51 files changed, 1201 insertions, 488 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d2d0d55dd4..402c7646c0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,33 +13,3 @@ build:
- make check || (e=$?; cat test-suite.log; exit $e)
- make install
-update:
- only:
- - schedules
- script:
- - "apt-get install -y --fix-missing git openssh-client"
-
- # Run ssh-agent (inside the build environment)
- - eval $(ssh-agent -s)
-
- # Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- - ssh-add <(echo "$DEPLOY_KEY")
-
- # For Docker builds disable host key checking. Be aware that by adding that
- # you are susceptible to man-in-the-middle attacks.
- # WARNING: Use this only with the Docker executor, if you use it with shell
- # you will overwrite your user's SSH config.
- - mkdir -p ~/.ssh
- - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- # In order to properly check the server's host key, assuming you created the
- # SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines
- # instead.
- - mkdir -p ~/.ssh
- - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
- - echo "merging from torgit"
- - git config --global user.email "labadmin@oniongit.eu"
- - git config --global user.name "gitadmin"
- - "mkdir tor"
- - "cd tor"
- - git clone --bare https://git.torproject.org/tor.git
- - git push --mirror git@oniongit.eu:network/tor.git
diff --git a/.travis.yml b/.travis.yml
index ccd2107fd2..af5052682f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -81,6 +81,8 @@ matrix:
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.
@@ -97,8 +99,6 @@ matrix:
os: osx
- env: CHUTNEY="yes" CHUTNEY_ALLOW_FAILURES="2" SKIP_MAKE_CHECK="yes"
os: osx
- ## test-stem sometimes hangs on Travis
- - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes"
## (Linux only) Use a recent Linux image (Ubuntu Bionic)
dist: bionic
@@ -129,6 +129,7 @@ addons:
- docbook-xsl
- docbook-xml
- xmlto
+ - doxygen
## Utilities
## preventing or diagnosing hangs
- timelimit
@@ -233,6 +234,7 @@ script:
## Diagnostic for bug 29437: kill stem if it hangs for 9.5 minutes
## Travis will kill the job after 10 minutes with no output
- if [[ "$TEST_STEM" != "" ]]; then make src/app/tor; timelimit -p -t 540 -s USR1 -T 30 -S ABRT python3 "$STEM_SOURCE_DIR"/run_tests.py --tor src/app/tor --integ --test control.controller --test control.base_controller --test process --log TRACE --log-file stem.log; fi
+ - if [[ "$DOXYGEN" != "" ]]; then make doxygen; fi
## If this build was one that produced coverage, upload it.
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then coveralls -b . --exclude src/test --exclude src/trunnel --gcov-options '\-p' || echo "Coverage failed"; fi
diff --git a/ChangeLog b/ChangeLog
index f64848a6ca..b5dc9f692a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,185 @@
+Changes in version 0.4.3.2-alpha - 2020-02-10
+ This is the second stable alpha release in the Tor 0.4.3.x series. It
+ fixes several bugs present in the previous alpha release. Anybody
+ running the previous alpha should upgrade, and look for bugs in this
+ one instead.
+
+ o Major bugfixes (onion service client, authorization):
+ - On a NEWNYM signal, purge entries from the ephemeral client
+ authorization cache. The permanent ones are kept. Fixes bug 33139;
+ bugfix on 0.4.3.1-alpha.
+
+ o Minor features (best practices tracker):
+ - Practracker now supports a --regen-overbroad option to regenerate
+ the exceptions file, but only to revise exceptions to be _less_
+ tolerant of best-practices violations. Closes ticket 32372.
+
+ o Minor features (continuous integration):
+ - Run Doxygen Makefile target on Travis, so we can learn about
+ regressions in our internal documentation. Closes ticket 32455.
+ - Stop allowing failures on the Travis CI stem tests job. It looks
+ like all the stem hangs we were seeing before are now fixed.
+ Closes ticket 33075.
+
+ o Minor bugfixes (build system):
+ - Revise configure options that were either missing or incorrect in
+ the configure summary. Fixes bug 32230; bugfix on 0.4.3.1-alpha.
+
+ o Minor bugfixes (controller protocol):
+ - Fix a memory leak introduced by refactoring of control reply
+ formatting code. Fixes bug 33039; bugfix on 0.4.3.1-alpha.
+ - Fix a memory leak in GETINFO responses. Fixes bug 33103; bugfix
+ on 0.4.3.1-alpha.
+ - When receiving "ACTIVE" or "DORMANT" signals on the control port,
+ report them as SIGNAL events. Previously we would log a bug
+ warning. Fixes bug 33104; bugfix on 0.4.0.1-alpha.
+
+ o Minor bugfixes (logging):
+ - If we encounter a bug when flushing a buffer to a TLS connection,
+ only log the bug once per invocation of the Tor process.
+ Previously we would log with every occurrence, which could cause
+ us to run out of disk space. Fixes bug 33093; bugfix
+ on 0.3.2.2-alpha.
+ - When logging a bug, do not say "Future instances of this warning
+ will be silenced" unless we are actually going to silence them.
+ Previously we would say this whenever a BUG() check failed in the
+ code. Fixes bug 33095; bugfix on 0.4.1.1-alpha.
+
+ o Minor bugfixes (onion service v2):
+ - Move a series of v2 onion service warnings to protocol-warning
+ level because they can all be triggered remotely by a malformed
+ request. Fixes bug 32706; bugfix on 0.1.1.14-alpha.
+
+ o Minor bugfixes (onion service v3, client authorization):
+ - When removing client authorization credentials using the control
+ port, also remove the associated descriptor, so the onion service
+ can no longer be contacted. Fixes bug 33148; bugfix
+ on 0.4.3.1-alpha.
+
+ o Minor bugfixes (pluggable transports):
+ - When receiving a message on standard error from a pluggable
+ transport, log it at info level, rather than as a warning. Fixes
+ bug 33005; bugfix on 0.4.0.1-alpha.
+
+ o Minor bugfixes (rust, build):
+ - Fix a syntax warning given by newer versions of Rust that was
+ creating problems for our continuous integration. Fixes bug 33212;
+ bugfix on 0.3.5.1-alpha.
+
+ o Minor bugfixes (TLS bug handling):
+ - When encountering a bug in buf_read_from_tls(), return a "MISC"
+ error code rather than "WANTWRITE". This change might help avoid
+ some CPU-wasting loops if the bug is ever triggered. Bug reported
+ by opara. Fixes bug 32673; bugfix on 0.3.0.4-alpha.
+
+ o Code simplification and refactoring (mainloop):
+ - Simplify the ip_address_changed() function by removing redundant
+ checks. Closes ticket 33091.
+
+ o Documentation (manpage):
+ - Split "Circuit Timeout" options and "Node Selection" options into
+ their own sections of the tor manpage. Closes tickets 32928 and
+ 32929. Work by Swati Thacker as part of Google Season of Docs.
+
+
+Changes in version 0.4.2.6 - 2020-01-30
+ This is the second stable release in the 0.4.2.x series. It backports
+ several bugfixes from 0.4.3.1-alpha, including some that had affected
+ the Linux seccomp2 sandbox or Windows services. If you're running with
+ one of those configurations, you'll probably want to upgrade;
+ otherwise, you should be fine with 0.4.2.5.
+
+ o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha):
+ - Correct how we use libseccomp. Particularly, stop assuming that
+ rules are applied in a particular order or that more rules are
+ processed after the first match. Neither is the case! In
+ libseccomp <2.4.0 this led to some rules having no effect.
+ libseccomp 2.4.0 changed how rules are generated, leading to a
+ different ordering, which in turn led to a fatal crash during
+ startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by
+ Peter Gerber.
+ - Fix crash when reloading logging configuration while the
+ experimental sandbox is enabled. Fixes bug 32841; bugfix on
+ 0.4.1.7. Patch by Peter Gerber.
+
+ o Minor bugfixes (correctness checks, backport from 0.4.3.1-alpha):
+ - Use GCC/Clang's printf-checking feature to make sure that
+ tor_assertf() arguments are correctly typed. Fixes bug 32765;
+ bugfix on 0.4.1.1-alpha.
+
+ o Minor bugfixes (logging, crash, backport from 0.4.3.1-alpha):
+ - Avoid a possible crash when trying to log a (fatal) assertion
+ failure about mismatched magic numbers in configuration objects.
+ Fixes bug 32771; bugfix on 0.4.2.1-alpha.
+
+ o Minor bugfixes (testing, backport from 0.4.3.1-alpha):
+ - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the
+ test_practracker.sh script. Doing so caused a test failure. Fixes
+ bug 32705; bugfix on 0.4.2.1-alpha.
+ - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr when
+ skipping practracker checks. Fixes bug 32705; bugfix
+ on 0.4.2.1-alpha.
+
+ o Minor bugfixes (windows service, backport from 0.4.3.1-alpha):
+ - Initialize the publish/subscribe system when running as a windows
+ service. Fixes bug 32778; bugfix on 0.4.1.1-alpha.
+
+ o Testing (backport from 0.4.3.1-alpha):
+ - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on
+ Ubuntu Bionic. Turning off the Sandbox is a work-around, until we
+ fix the sandbox errors in 32722. Closes ticket 32240.
+ - Re-enable the Travis CI macOS Chutney build, but don't let it
+ prevent the Travis job from finishing. (The Travis macOS jobs are
+ slow, so we don't want to have it delay the whole CI process.)
+ Closes ticket 32629.
+
+ o Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+
+Changes in version 0.4.1.8 - 2020-01-30
+ This release backports several bugfixes from later release series,
+ including some that had affected the Linux seccomp2 sandbox or Windows
+ services. If you're running with one of those configurations, you'll
+ probably want to upgrade; otherwise, you should be fine with your
+ current version of 0.4.1.x.
+
+ o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha):
+ - Correct how we use libseccomp. Particularly, stop assuming that
+ rules are applied in a particular order or that more rules are
+ processed after the first match. Neither is the case! In
+ libseccomp <2.4.0 this led to some rules having no effect.
+ libseccomp 2.4.0 changed how rules are generated, leading to a
+ different ordering, which in turn led to a fatal crash during
+ startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by
+ Peter Gerber.
+ - Fix crash when reloading logging configuration while the
+ experimental sandbox is enabled. Fixes bug 32841; bugfix on
+ 0.4.1.7. Patch by Peter Gerber.
+
+ o Minor bugfixes (crash, backport form 0.4.2.4-rc):
+ - When running Tor with an option like --verify-config or
+ --dump-config that does not start the event loop, avoid crashing
+ if we try to exit early because of an error. Fixes bug 32407;
+ bugfix on 0.3.3.1-alpha.
+
+ o Minor bugfixes (windows service, backport from 0.4.3.1-alpha):
+ - Initialize the publish/subscribe system when running as a windows
+ service. Fixes bug 32778; bugfix on 0.4.1.1-alpha.
+
+ o Testing (backport from 0.4.3.1-alpha):
+ - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on
+ Ubuntu Bionic. Turning off the Sandbox is a work-around, until we
+ fix the sandbox errors in 32722. Closes ticket 32240.
+ - Re-enable the Travis CI macOS Chutney build, but don't let it
+ prevent the Travis job from finishing. (The Travis macOS jobs are
+ slow, so we don't want to have it delay the whole CI process.)
+ Closes ticket 32629.
+
+ o Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+
Changes in version 0.4.3.1-alpha - 2020-01-22
This is the first alpha release in the 0.4.3.x series. It includes
improved support for application integration of onion services, support
@@ -48,7 +230,7 @@ Changes in version 0.4.3.1-alpha - 2020-01-22
- Correct how we use libseccomp. Particularly, stop assuming that
rules are applied in a particular order or that more rules are
processed after the first match. Neither is the case! In
- libseccomp <2.4.0 this lead to some rules having no effect.
+ libseccomp <2.4.0 this led to some rules having no effect.
libseccomp 2.4.0 changed how rules are generated, leading to a
different ordering, which in turn led to a fatal crash during
startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by
diff --git a/Makefile.am b/Makefile.am
index 811694f0b6..ac61a990fc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -196,6 +196,8 @@ EXTRA_DIST+= \
scripts/maint/practracker/testdata/ex1-expected.txt \
scripts/maint/practracker/testdata/ex1.txt \
scripts/maint/practracker/testdata/ex1-overbroad-expected.txt \
+ scripts/maint/practracker/testdata/ex1-regen-expected.txt \
+ scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt \
scripts/maint/practracker/testdata/ex.txt \
scripts/maint/practracker/testdata/header.h \
scripts/maint/practracker/testdata/not_c_file \
diff --git a/ReleaseNotes b/ReleaseNotes
index 97e16a6d8b..7d981e2c42 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -2,6 +2,104 @@ This document summarizes new features and bugfixes in each stable
release of Tor. If you want to see more detailed descriptions of the
changes in each development snapshot, see the ChangeLog file.
+Changes in version 0.4.2.6 - 2020-01-30
+ This is the second stable release in the 0.4.2.x series. It backports
+ several bugfixes from 0.4.3.1-alpha, including some that had affected
+ the Linux seccomp2 sandbox or Windows services. If you're running with
+ one of those configurations, you'll probably want to upgrade;
+ otherwise, you should be fine with 0.4.2.5.
+
+ o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha):
+ - Correct how we use libseccomp. Particularly, stop assuming that
+ rules are applied in a particular order or that more rules are
+ processed after the first match. Neither is the case! In
+ libseccomp <2.4.0 this led to some rules having no effect.
+ libseccomp 2.4.0 changed how rules are generated, leading to a
+ different ordering, which in turn led to a fatal crash during
+ startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by
+ Peter Gerber.
+ - Fix crash when reloading logging configuration while the
+ experimental sandbox is enabled. Fixes bug 32841; bugfix on
+ 0.4.1.7. Patch by Peter Gerber.
+
+ o Minor bugfixes (correctness checks, backport from 0.4.3.1-alpha):
+ - Use GCC/Clang's printf-checking feature to make sure that
+ tor_assertf() arguments are correctly typed. Fixes bug 32765;
+ bugfix on 0.4.1.1-alpha.
+
+ o Minor bugfixes (logging, crash, backport from 0.4.3.1-alpha):
+ - Avoid a possible crash when trying to log a (fatal) assertion
+ failure about mismatched magic numbers in configuration objects.
+ Fixes bug 32771; bugfix on 0.4.2.1-alpha.
+
+ o Minor bugfixes (testing, backport from 0.4.3.1-alpha):
+ - When TOR_DISABLE_PRACTRACKER is set, do not apply it to the
+ test_practracker.sh script. Doing so caused a test failure. Fixes
+ bug 32705; bugfix on 0.4.2.1-alpha.
+ - When TOR_DISABLE_PRACTRACKER is set, log a notice to stderr when
+ skipping practracker checks. Fixes bug 32705; bugfix
+ on 0.4.2.1-alpha.
+
+ o Minor bugfixes (windows service, backport from 0.4.3.1-alpha):
+ - Initialize the publish/subscribe system when running as a windows
+ service. Fixes bug 32778; bugfix on 0.4.1.1-alpha.
+
+ o Testing (backport from 0.4.3.1-alpha):
+ - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on
+ Ubuntu Bionic. Turning off the Sandbox is a work-around, until we
+ fix the sandbox errors in 32722. Closes ticket 32240.
+ - Re-enable the Travis CI macOS Chutney build, but don't let it
+ prevent the Travis job from finishing. (The Travis macOS jobs are
+ slow, so we don't want to have it delay the whole CI process.)
+ Closes ticket 32629.
+
+ o Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+
+Changes in version 0.4.1.8 - 2020-01-30
+ This release backports several bugfixes from later release series,
+ including some that had affected the Linux seccomp2 sandbox or Windows
+ services. If you're running with one of those configurations, you'll
+ probably want to upgrade; otherwise, you should be fine with your
+ current version of 0.4.1.x.
+
+ o Major bugfixes (linux seccomp sandbox, backport from 0.4.3.1-alpha):
+ - Correct how we use libseccomp. Particularly, stop assuming that
+ rules are applied in a particular order or that more rules are
+ processed after the first match. Neither is the case! In
+ libseccomp <2.4.0 this led to some rules having no effect.
+ libseccomp 2.4.0 changed how rules are generated, leading to a
+ different ordering, which in turn led to a fatal crash during
+ startup. Fixes bug 29819; bugfix on 0.2.5.1-alpha. Patch by
+ Peter Gerber.
+ - Fix crash when reloading logging configuration while the
+ experimental sandbox is enabled. Fixes bug 32841; bugfix on
+ 0.4.1.7. Patch by Peter Gerber.
+
+ o Minor bugfixes (crash, backport form 0.4.2.4-rc):
+ - When running Tor with an option like --verify-config or
+ --dump-config that does not start the event loop, avoid crashing
+ if we try to exit early because of an error. Fixes bug 32407;
+ bugfix on 0.3.3.1-alpha.
+
+ o Minor bugfixes (windows service, backport from 0.4.3.1-alpha):
+ - Initialize the publish/subscribe system when running as a windows
+ service. Fixes bug 32778; bugfix on 0.4.1.1-alpha.
+
+ o Testing (backport from 0.4.3.1-alpha):
+ - Turn off Tor's Sandbox in Chutney jobs, and run those jobs on
+ Ubuntu Bionic. Turning off the Sandbox is a work-around, until we
+ fix the sandbox errors in 32722. Closes ticket 32240.
+ - Re-enable the Travis CI macOS Chutney build, but don't let it
+ prevent the Travis job from finishing. (The Travis macOS jobs are
+ slow, so we don't want to have it delay the whole CI process.)
+ Closes ticket 32629.
+
+ o Testing (continuous integration, backport from 0.4.3.1-alpha):
+ - Use zstd in our Travis Linux builds. Closes ticket 32242.
+
+
Changes in version 0.4.2.5 - 2019-12-09
This is the first stable release in the 0.4.2.x series. This series
improves reliability and stability, and includes several stability and
diff --git a/changes/bug33005 b/changes/bug33005
deleted file mode 100644
index 30a8d01bb3..0000000000
--- a/changes/bug33005
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor bugfixes (pluggable transports):
- - Lower the log level of standard error messages from a PT from warning to
- info. Fixes bug 33005; bugfix on 0.4.0.1-alpha.
diff --git a/changes/ticket33039 b/changes/ticket33039
deleted file mode 100644
index 29eeabf45e..0000000000
--- a/changes/ticket33039
+++ /dev/null
@@ -1,3 +0,0 @@
- o Minor bugfixes (control port):
- - Fix a memory leak introduced by refactoring of control reply
- formatting code. Fixes bug 33039; bugfix on 0.4.3.1-alpha.
diff --git a/changes/ticket33213 b/changes/ticket33213
new file mode 100644
index 0000000000..f1da591bd1
--- /dev/null
+++ b/changes/ticket33213
@@ -0,0 +1,3 @@
+ o Minor bugfixes (continuous integration):
+ - Remove the buggy and unused mirroring job. Fixes bug 33213;
+ bugfix on 0.3.2.2-alpha.
diff --git a/configure.ac b/configure.ac
index 63e13d00be..aa511a3911 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2019, The Tor Project, Inc.
dnl See LICENSE for licensing information
AC_PREREQ([2.63])
-AC_INIT([tor],[0.4.3.1-alpha-dev])
+AC_INIT([tor],[0.4.4.0-alpha-dev])
AC_CONFIG_SRCDIR([src/app/main/tor_main.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -16,7 +16,7 @@ configure_flags="$*"
# version number changes. Tor uses it to make sure that it
# only shuts down for missing "required protocols" when those protocols
# are listed as required by a consensus after this date.
-AC_DEFINE(APPROX_RELEASE_DATE, ["2020-01-23"], # for 0.4.3.1-alpha-dev
+AC_DEFINE(APPROX_RELEASE_DATE, ["2020-02-11"], # for 0.4.4.0-alpha-dev
[Approximate date when this software was released. (Updated when the version changes.)])
# "foreign" means we don't follow GNU package layout standards
@@ -2591,21 +2591,18 @@ PPRINT_PROP_STRING([Compiler], [$CC])
PPRINT_PROP_STRING([Host OS], [$host_os])
AS_ECHO
-test "x$enable_gcc_warnings" = "xyes" && value=1 || value=0
-PPRINT_PROP_BOOL([Verbose Warnings (--enable-gcc-warnings)], $value)
-
test "x$enable_fatal_warnings" = "xyes" && value=1 || value=0
PPRINT_PROP_BOOL([Warnings are fatal (--enable-fatal-warnings)], $value)
test "x$enable_rust" = "xyes" && value=1 || value=0
PPRINT_PROP_BOOL([Rust support (--enable-rust)], $value)
+test "x$enable_cargo_online_mode" = "xyes" && value=1 || value=0
+PPRINT_PROP_BOOL([Cargo Online Fetch (--enable-cargo-online-mode)], $value)
+
test "x$enable_android" = "xyes" && value=1 || value=0
PPRINT_PROP_BOOL([Android support (--enable-android)], $value)
-test "x$enable_systemd" = "xyes" && value=1 || value=0
-PPRINT_PROP_BOOL([Systemd support (--enable-systemd)], $value)
-
AS_ECHO
PPRINT_SUBTITLE([Static Build])
@@ -2642,6 +2639,15 @@ PPRINT_PROP_BOOL([libseccomp (--disable-seccomp)], $value)
test "x$enable_libscrypt" != "xno" && value=1 || value=0
PPRINT_PROP_BOOL([libscrypt (--disable-libscrypt)], $value)
+test "x$enable_systemd" = "xyes" && value=1 || value=0
+PPRINT_PROP_BOOL([Systemd support (--enable-systemd)], $value)
+
+test "x$enable_lzma" = "xyes" && value=1 || value=0
+PPRINT_PROP_BOOL([liblzma (--enable-lzma)], $value)
+
+test "x$enable_zstd" = "xyes" && value=1 || value=0
+PPRINT_PROP_BOOL([libzstd (--enable-zstd)], $value)
+
AS_ECHO
PPRINT_SUBTITLE([Hardening])
@@ -2651,21 +2657,25 @@ PPRINT_PROP_BOOL([Compiler Hardening (--disable-gcc-hardening)], $value)
test "x$enable_linker_hardening" != "xno" && value=1 || value=0
PPRINT_PROP_BOOL([Linker Hardening (--disable-linker-hardening)], $value)
-test "x$enable_fragile_hardening" = "xyes" && value=1 || value=0
+test "x$fragile_hardening" = "xyes" && value=1 || value=0
PPRINT_PROP_BOOL([Fragile Hardening (--enable-fragile-hardening, dev only)], $value)
AS_ECHO
PPRINT_SUBTITLE([Modules])
-test "x$enable_module_dirauth" != "xno" && value=1 || value=0
-PPRINT_PROP_BOOL([Directory Authority (--disable-module-dirauth)], $value)
-
-test "x$enable_module_relay" != "xno" && value=1 || value=0
-PPRINT_PROP_BOOL([Relay (--disable-module-relay)], $value)
+m4_foreach_w([mname], MODULES,
+ [
+ test "xenable_module_mname" != "xno" && value=1 || value=0
+ PPRINT_PROP_BOOL([mname (--disable-module-mname)], $value)
+ ]
+)
AS_ECHO
PPRINT_SUBTITLE([Documentation])
+test "x$enable_asciidoc" != "xno" && value=1 || value=0
+PPRINT_PROP_BOOL([AsciiDoc (--disable-asciidoc)], $value)
+
test "x$enable_manpage" != "xno" && value=1 || value=0
PPRINT_PROP_BOOL([Man Pages (--disable-manpage)], $value)
@@ -2679,7 +2689,7 @@ test "x$enable_unittests" != "xno" && value=1 || value=0
PPRINT_PROP_BOOL([Unit tests (--disable-unittests)], $value)
test "x$enable_asserts_in_tests" = "xno" && value=1 || value=0
-PPRINT_PROP_BOOL([assert()s disabled (--disable-asserts-in-tests, dev only)], $value)
+PPRINT_PROP_BOOL([assert()s enabled (--enable-asserts-in-tests, dev only)], $value)
test "x$enable_coverage" = "xyes" && value=1 || value=0
PPRINT_PROP_BOOL([Code Coverage (--enable-coverage)], $value)
diff --git a/contrib/client-tools/tor-resolve.py b/contrib/client-tools/tor-resolve.py
index 593efc97d4..3562193715 100755
--- a/contrib/client-tools/tor-resolve.py
+++ b/contrib/client-tools/tor-resolve.py
@@ -87,7 +87,7 @@ def parseHostAndPort(h):
try:
port = int(h[i+1:])
except ValueError:
- print "Bad hostname %r"%h
+ print("Bad hostname %r"%h)
sys.exit(1)
elif h:
try:
@@ -123,15 +123,15 @@ def resolve(hostname, sockshost, socksport, socksver=4, reverse=0):
return None
answer += more
result = parse(answer)
- print "Got answer",result
+ print("Got answer",result)
m = s.recv(1)
if m:
- print "Got extra data too: %r"%m
+ print("Got extra data too: %r"%m)
return result
if __name__ == '__main__':
if len(sys.argv) not in (2,3,4):
- print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]"
+ print("Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]")
sys.exit(0)
socksver = 4
reverse = 0
@@ -146,7 +146,7 @@ if __name__ == '__main__':
break
if len(sys.argv) >= 4:
- print "Syntax: resolve.py [-x] [-4|-5] hostname [sockshost:socksport]"
+ print("Syntax: resolve.py [-x] [-4|-5] hostname [sockshost:socksport]")
sys.exit(0)
if len(sys.argv) == 3:
sh,sp = parseHostAndPort(sys.argv[2])
diff --git a/contrib/win32build/tor-mingw.nsi.in b/contrib/win32build/tor-mingw.nsi.in
index 3a4bd2c4b8..fb13a2eb36 100644
--- a/contrib/win32build/tor-mingw.nsi.in
+++ b/contrib/win32build/tor-mingw.nsi.in
@@ -8,7 +8,7 @@
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!insertmacro GetParameters
-!define VERSION "0.4.3.1-alpha-dev"
+!define VERSION "0.4.4.0-alpha-dev"
!define INSTALLER "tor-${VERSION}-win32.exe"
!define WEBSITE "https://www.torproject.org/"
!define LICENSE "LICENSE"
diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md
index 866b321287..ae892c34a2 100644
--- a/doc/HACKING/HelpfulTools.md
+++ b/doc/HACKING/HelpfulTools.md
@@ -251,16 +251,16 @@ Now you can run Tor with profiling enabled, and use the pprof utility to look at
performance! See the gperftools manual for more info, but basically:
2. Run `env CPUPROFILE=/tmp/profile src/app/tor -f <path/torrc>`. The profile file
- is not written to until Tor finishes execuction.
+ is not written to until Tor finishes execution.
-3. Run `pprof src/app/tor /tm/profile` to start the REPL.
+3. Run `pprof src/app/tor /tmp/profile` to start the REPL.
Generating and analyzing a callgraph
------------------------------------
0. Build Tor on linux or mac, ideally with -O0 or -fno-inline.
-1. Clone 'https://gitweb.torproject.org/user/nickm/calltool.git/' .
+1. Clone 'https://git.torproject.org/user/nickm/calltool.git/' .
Follow the README in that repository.
Note that currently the callgraph generator can't detect calls that pass
@@ -396,7 +396,7 @@ source code. Here's how to use it:
6. See the Doxygen manual for more information; this summary just
scratches the surface.
-Style and best-pratices checking
+Style and best-practices checking
--------------------------------
We use scripts to check for various problems in the formatting and style
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index a5108df805..a9b9852b7d 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -998,18 +998,6 @@ The following options are useful only for clients (that is, if
the documentation of the pluggable transport for details of what
arguments it supports.
-// Out of order because it logically belongs before the CircuitBuildTimeout option
-[[LearnCircuitBuildTimeout]] **LearnCircuitBuildTimeout** **0**|**1**::
- If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1)
-
-[[CircuitBuildTimeout]] **CircuitBuildTimeout** __NUM__::
-
- Try for at most NUM seconds when building circuits. If the circuit isn't
- open in that time, give up on it. If LearnCircuitBuildTimeout is 1, this
- value serves as the initial value to use before a timeout is learned. If
- LearnCircuitBuildTimeout is 0, this value is the only value used.
- (Default: 60 seconds)
-
[[CircuitPadding]] **CircuitPadding** **0**|**1**::
If set to 0, Tor will not pad client circuits with additional cover
traffic. Only clients may set this option. This option should be offered
@@ -1025,22 +1013,6 @@ The following options are useful only for clients (that is, if
via the UI to mobile users for use where bandwidth may be expensive.
(Default: 0)
-[[CircuitsAvailableTimeout]] **CircuitsAvailableTimeout** __NUM__::
- Tor will attempt to keep at least one open, unused circuit available for
- this amount of time. This option governs how long idle circuits are kept
- open, as well as the amount of time Tor will keep a circuit open to each
- of the recently used ports. This way when the Tor client is entirely
- idle, it can expire all of its circuits, and then expire its TLS
- connections. Note that the actual timeout value is uniformly randomized
- from the specified value to twice that amount. (Default: 30 minutes;
- Max: 24 hours)
-
-[[CircuitStreamTimeout]] **CircuitStreamTimeout** __NUM__::
- If non-zero, this option overrides our internal timeout schedule for how
- many seconds until we detach a stream from a circuit and try a new circuit.
- If your network is particularly slow, you might want to set this to a
- number like 60. (Default: 0)
-
[[ClientAutoIPv6ORPort]] **ClientAutoIPv6ORPort** **0**|**1**::
If this option is set to 1, Tor clients randomly prefer a node's IPv4 or
IPv6 ORPort. The random preference is set every time a node is loaded
@@ -1166,43 +1138,6 @@ The following options are useful only for clients (that is, if
addresses/ports. See SocksPort for an explanation of isolation
flags. (Default: 0)
-[[DormantCanceledByStartup]] **DormantCanceledByStartup** **0**|**1**::
- By default, Tor starts in active mode if it was active the last time
- it was shut down, and in dormant mode if it was dormant. But if
- this option is true, Tor treats every startup event as user
- activity, and Tor will never start in Dormant mode, even if it has
- been unused for a long time on previous runs. (Default: 0)
- +
- Note: Packagers and application developers should change the value of
- this option only with great caution: it has the potential to
- create spurious traffic on the network. This option should only
- be used if Tor is started by an affirmative user activity (like
- clicking on an applcation or running a command), and not if Tor
- is launched for some other reason (for example, by a startup
- process, or by an application that launches itself on every login.)
-
-[[DormantClientTimeout]] **DormantClientTimeout** __N__ **minutes**|**hours**|**days**|**weeks**::
- If Tor spends this much time without any client activity,
- enter a dormant state where automatic circuits are not built, and
- directory information is not fetched.
- Does not affect servers or onion services. Must be at least 10 minutes.
- (Default: 24 hours)
-
-[[DormantOnFirstStartup]] **DormantOnFirstStartup** **0**|**1**::
- If true, then the first time Tor starts up with a fresh DataDirectory,
- it starts in dormant mode, and takes no actions until the user has made
- a request. (This mode is recommended if installing a Tor client for a
- user who might not actually use it.) If false, Tor bootstraps the first
- time it is started, whether it sees a user request or not.
- +
- After the first time Tor starts, it begins in dormant mode if it was
- dormant before, and not otherwise. (Default: 0)
-
-[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams** **0**|**1**::
- If true, then any open client stream (even one not reading or writing)
- counts as client activity for the purpose of DormantClientTimeout.
- If false, then only network activity counts. (Default: 1)
-
[[DownloadExtraInfo]] **DownloadExtraInfo** **0**|**1**::
If true, Tor downloads and caches "extra-info" documents. These documents
contain information about servers other than the information in their
@@ -1214,76 +1149,6 @@ The following options are useful only for clients (that is, if
the same circuit. Currently, two addresses are "too close" if they lie in
the same /16 range. (Default: 1)
-[[EntryNodes]] **EntryNodes** __node__,__node__,__...__::
- A list of identity fingerprints and country codes of nodes
- to use for the first hop in your normal circuits.
- Normal circuits include all
- circuits except for direct connections to directory servers. The Bridge
- option overrides this option; if you have configured bridges and
- UseBridges is 1, the Bridges are used as your entry nodes. +
- +
- The ExcludeNodes option overrides this option: any node listed in both
- EntryNodes and ExcludeNodes is treated as excluded. See
- the **ExcludeNodes** option for more information on how to specify nodes.
-
-[[ExcludeNodes]] **ExcludeNodes** __node__,__node__,__...__::
- A list of identity fingerprints, country codes, and address
- patterns of nodes to avoid when building a circuit. Country codes are
- 2-letter ISO3166 codes, and must
- be wrapped in braces; fingerprints may be preceded by a dollar sign.
- (Example:
- ExcludeNodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
- +
- By default, this option is treated as a preference that Tor is allowed
- to override in order to keep working.
- For example, if you try to connect to a hidden service,
- but you have excluded all of the hidden service's introduction points,
- Tor will connect to one of them anyway. If you do not want this
- behavior, set the StrictNodes option (documented below). +
- +
- Note also that if you are a relay, this (and the other node selection
- options below) only affects your own circuits that Tor builds for you.
- Clients can still build circuits through you to any node. Controllers
- can tell Tor to build circuits through any node. +
- +
- Country codes are case-insensitive. The code "\{??}" refers to nodes whose
- country can't be identified. No country code, including \{??}, works if
- no GeoIPFile can be loaded. See also the GeoIPExcludeUnknown option below.
-
-// Out of order because it logically belongs after the ExcludeNodes option
-[[ExcludeExitNodes]] **ExcludeExitNodes** __node__,__node__,__...__::
- A list of identity fingerprints, country codes, and address
- patterns of nodes to never use when picking an exit node---that is, a
- node that delivers traffic for you *outside* the Tor network. Note that any
- node listed in ExcludeNodes is automatically considered to be part of this
- list too. See
- the **ExcludeNodes** option for more information on how to specify
- nodes. See also the caveats on the "ExitNodes" option below.
-
-[[ExitNodes]] **ExitNodes** __node__,__node__,__...__::
- A list of identity fingerprints, country codes, and address
- patterns of nodes to use as exit node---that is, a
- node that delivers traffic for you *outside* the Tor network. See
- the **ExcludeNodes** option for more information on how to specify nodes. +
- +
- Note that if you list too few nodes here, or if you exclude too many exit
- nodes with ExcludeExitNodes, you can degrade functionality. For example,
- if none of the exits you list allows traffic on port 80 or 443, you won't
- be able to browse the web. +
- +
- Note also that not every circuit is used to deliver traffic *outside* of
- the Tor network. It is normal to see non-exit circuits (such as those
- used to connect to hidden services, those that do directory fetches,
- those used for relay reachability self-tests, and so on) that end
- at a non-exit node. To
- keep a node from being used entirely, see ExcludeNodes and StrictNodes. +
- +
- The ExcludeNodes option overrides this option: any node listed in both
- ExitNodes and ExcludeNodes is treated as excluded. +
- +
- The .exit address notation, if enabled via MapAddress, overrides
- this option.
-
[[FascistFirewall]] **FascistFirewall** **0**|**1**::
If 1, Tor will only create outgoing connections to ORs running on ports
that your firewall allows (defaults to 80 and 443; see **FirewallPorts**).
@@ -1297,14 +1162,6 @@ The following options are useful only for clients (that is, if
**FascistFirewall** is set. This option is deprecated; use ReachableAddresses
instead. (Default: 80, 443)
-[[GeoIPExcludeUnknown]] **GeoIPExcludeUnknown** **0**|**1**|**auto**::
- If this option is set to 'auto', then whenever any country code is set in
- ExcludeNodes or ExcludeExitNodes, all nodes with unknown country (\{??} and
- possibly \{A1}) are treated as excluded as well. If this option is set to
- '1', then all unknown countries are treated as excluded in ExcludeNodes
- and ExcludeExitNodes. This option has no effect when a GeoIP file isn't
- configured or can't be found. (Default: auto)
-
[[HidServAuth]] **HidServAuth** __onion-address__ __auth-cookie__ [__service-name__]::
Client authorization for a v2 hidden service. Valid onion addresses contain 16
characters in a-z2-7 plus ".onion", and valid auth cookies contain 22
@@ -1315,116 +1172,6 @@ The following options are useful only for clients (that is, if
services can be configured to require authorization using the
**HiddenServiceAuthorizeClient** option.
-[[HSLayer2Nodes]] **HSLayer2Nodes** __node__,__node__,__...__::
- A list of identity fingerprints, nicknames, country codes, and
- address patterns of nodes that are allowed to be used as the
- second hop in all client or service-side Onion Service circuits.
- This option mitigates attacks where the adversary runs middle nodes
- and induces your client or service to create many circuits, in order
- to discover your primary guard node.
- (Default: Any node in the network may be used in the second hop.)
- +
- (Example:
- HSLayer2Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
- +
- When this is set, the resulting hidden service paths will
- look like:
- +
- C - G - L2 - M - Rend +
- C - G - L2 - M - HSDir +
- C - G - L2 - M - Intro +
- S - G - L2 - M - Rend +
- S - G - L2 - M - HSDir +
- S - G - L2 - M - Intro +
- +
- where C is this client, S is the service, G is the Guard node,
- L2 is a node from this option, and M is a random middle node.
- Rend, HSDir, and Intro point selection is not affected by this
- option.
- +
- This option may be combined with HSLayer3Nodes to create
- paths of the form:
- +
- C - G - L2 - L3 - Rend +
- C - G - L2 - L3 - M - HSDir +
- C - G - L2 - L3 - M - Intro +
- S - G - L2 - L3 - M - Rend +
- S - G - L2 - L3 - HSDir +
- S - G - L2 - L3 - Intro +
- +
- ExcludeNodes have higher priority than HSLayer2Nodes,
- which means that nodes specified in ExcludeNodes will not be
- picked.
- +
- When either this option or HSLayer3Nodes are set, the /16 subnet
- and node family restrictions are removed for hidden service
- circuits. Additionally, we allow the guard node to be present
- as the Rend, HSDir, and IP node, and as the hop before it. This
- is done to prevent the adversary from inferring information
- about our guard, layer2, and layer3 node choices at later points
- in the path.
- +
- This option is meant to be managed by a Tor controller such as
- https://github.com/mikeperry-tor/vanguards that selects and
- updates this set of nodes for you. Hence it does not do load
- balancing if fewer than 20 nodes are selected, and if no nodes in
- HSLayer2Nodes are currently available for use, Tor will not work.
- Please use extreme care if you are setting this option manually.
-
-[[HSLayer3Nodes]] **HSLayer3Nodes** __node__,__node__,__...__::
- A list of identity fingerprints, nicknames, country codes, and
- address patterns of nodes that are allowed to be used as the
- third hop in all client and service-side Onion Service circuits.
- This option mitigates attacks where the adversary runs middle nodes
- and induces your client or service to create many circuits, in order
- to discover your primary or Layer2 guard nodes.
- (Default: Any node in the network may be used in the third hop.)
- +
- (Example:
- HSLayer3Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
- +
- When this is set by itself, the resulting hidden service paths
- will look like: +
- C - G - M - L3 - Rend +
- C - G - M - L3 - M - HSDir +
- C - G - M - L3 - M - Intro +
- S - G - M - L3 - M - Rend +
- S - G - M - L3 - HSDir +
- S - G - M - L3 - Intro +
- where C is this client, S is the service, G is the Guard node,
- L2 is a node from this option, and M is a random middle node.
- Rend, HSDir, and Intro point selection is not affected by this
- option.
- +
- While it is possible to use this option by itself, it should be
- combined with HSLayer2Nodes to create paths of the form:
- +
- C - G - L2 - L3 - Rend +
- C - G - L2 - L3 - M - HSDir +
- C - G - L2 - L3 - M - Intro +
- S - G - L2 - L3 - M - Rend +
- S - G - L2 - L3 - HSDir +
- S - G - L2 - L3 - Intro +
- +
- ExcludeNodes have higher priority than HSLayer3Nodes,
- which means that nodes specified in ExcludeNodes will not be
- picked.
- +
- When either this option or HSLayer2Nodes are set, the /16 subnet
- and node family restrictions are removed for hidden service
- circuits. Additionally, we allow the guard node to be present
- as the Rend, HSDir, and IP node, and as the hop before it. This
- is done to prevent the adversary from inferring information
- about our guard, layer2, and layer3 node choices at later points
- in the path.
- +
- This option is meant to be managed by a Tor controller such as
- https://github.com/mikeperry-tor/vanguards that selects and
- updates this set of nodes for you. Hence it does not do load
- balancing if fewer than 20 nodes are selected, and if no nodes in
- HSLayer3Nodes are currently available for use, Tor will not work.
- Please use extreme care if you are setting this option manually.
-
[[HTTPTunnelPort]] **HTTPTunnelPort** ['address'**:**]{empty}__port__|**auto** [_isolation flags_]::
Open this port to listen for proxy connections using the "HTTP CONNECT"
protocol instead of SOCKS. Set this to
@@ -1510,26 +1257,6 @@ The following options are useful only for clients (that is, if
client streams. A circuit is pending if we have begun constructing it,
but it has not yet been completely constructed. (Default: 32)
-[[MiddleNodes]] **MiddleNodes** __node__,__node__,__...__::
- A list of identity fingerprints and country codes of nodes
- to use for "middle" hops in your normal circuits.
- Normal circuits include all circuits except for direct connections
- to directory servers. Middle hops are all hops other than exit and entry. +
-+
- This is an **experimental** feature that is meant to be used by researchers
- and developers to test new features in the Tor network safely. Using it
- without care will strongly influence your anonymity. This feature might get
- removed in the future.
-+
- The HSLayer2Node and HSLayer3Node options override this option for onion
- service circuits, if they are set. The vanguards addon will read this
- option, and if set, it will set HSLayer2Nodes and HSLayer3Nodes to nodes
- from this set.
-+
- The ExcludeNodes option overrides this option: any node listed in both
- MiddleNodes and ExcludeNodes is treated as excluded. See
- the **ExcludeNodes** option for more information on how to specify nodes.
-
[[NATDPort]] **NATDPort** ['address'**:**]{empty}__port__|**auto** [_isolation flags_]::
Open this port to listen for connections from old versions of ipfw (as
included in old versions of FreeBSD, etc) using the NATD protocol.
@@ -1546,16 +1273,6 @@ The following options are useful only for clients (that is, if
Every NUM seconds consider whether to build a new circuit. (Default: 30
seconds)
-[[NodeFamily]] **NodeFamily** __node__,__node__,__...__::
- The Tor servers, defined by their identity fingerprints,
- constitute a "family" of similar or co-administered servers, so never use
- any two of them in the same circuit. Defining a NodeFamily is only needed
- when a server doesn't list the family itself (with MyFamily). This option
- can be used multiple times; each instance defines a separate family. In
- addition to nodes, you can also list IP address and ranges and country
- codes in {curly braces}. See the **ExcludeNodes** option for more
- information on how to specify nodes.
-
[[OptimisticData]] **OptimisticData** **0**|**1**|**auto**::
When this option is set, and Tor is using an exit node that supports
the feature, it will try optimistically to send data to the exit node
@@ -1871,24 +1588,6 @@ The following options are useful only for clients (that is, if
line is used, and all earlier flags are ignored. No error is issued for
conflicting flags.
-[[SocksTimeout]] **SocksTimeout** __NUM__::
- Let a socks connection wait NUM seconds handshaking, and NUM seconds
- unattached waiting for an appropriate circuit, before we fail it. (Default:
- 2 minutes)
-
-[[StrictNodes]] **StrictNodes** **0**|**1**::
- If StrictNodes is set to 1, Tor will treat solely the ExcludeNodes option
- as a requirement to follow for all the circuits you generate, even if
- doing so will break functionality for you (StrictNodes does not apply to
- ExcludeExitNodes, ExitNodes, MiddleNodes, or MapAddress). If StrictNodes
- is set to 0, Tor will still try to avoid nodes in the ExcludeNodes list,
- but it will err on the side of avoiding unexpected errors.
- Specifically, StrictNodes 0 tells Tor that it is okay to use an excluded
- node when it is *necessary* to perform relay reachability self-tests,
- connect to a hidden service, provide a hidden service to a client,
- fulfill a .exit request, upload directory information, or download
- directory information. (Default: 0)
-
[[TokenBucketRefillInterval]] **TokenBucketRefillInterval** __NUM__ [**msec**|**second**]::
Set the refill delay interval of Tor's token bucket to NUM milliseconds.
NUM must be between 1 and 1000, inclusive. When Tor is out of bandwidth,
@@ -2033,6 +1732,331 @@ The following options are useful only for clients (that is, if
used IP. For local use, no change to the default VirtualAddrNetwork setting
is needed.
+== CIRCUIT TIMEOUT OPTIONS
+
+// These options are in alphabetical order, with exceptions as noted.
+// Please keep them that way!
+
+The following options are useful for configuring timeouts related
+to building Tor circuits and using them:
+
+[[CircuitsAvailableTimeout]] **CircuitsAvailableTimeout** __NUM__::
+ Tor will attempt to keep at least one open, unused circuit available for
+ this amount of time. This option governs how long idle circuits are kept
+ open, as well as the amount of time Tor will keep a circuit open to each
+ of the recently used ports. This way when the Tor client is entirely
+ idle, it can expire all of its circuits, and then expire its TLS
+ connections. Note that the actual timeout value is uniformly randomized
+ from the specified value to twice that amount. (Default: 30 minutes;
+ Max: 24 hours)
+
+// Out of order because it logically belongs before the CircuitBuildTimeout option
+[[LearnCircuitBuildTimeout]] **LearnCircuitBuildTimeout** **0**|**1**::
+ If 0, CircuitBuildTimeout adaptive learning is disabled. (Default: 1)
+
+[[CircuitBuildTimeout]] **CircuitBuildTimeout** __NUM__::
+ Try for at most NUM seconds when building circuits. If the circuit isn't
+ open in that time, give up on it. If LearnCircuitBuildTimeout is 1, this
+ value serves as the initial value to use before a timeout is learned. If
+ LearnCircuitBuildTimeout is 0, this value is the only value used.
+ (Default: 60 seconds)
+
+[[CircuitStreamTimeout]] **CircuitStreamTimeout** __NUM__::
+ If non-zero, this option overrides our internal timeout schedule for how
+ many seconds until we detach a stream from a circuit and try a new circuit.
+ If your network is particularly slow, you might want to set this to a
+ number like 60. (Default: 0)
+
+[[SocksTimeout]] **SocksTimeout** __NUM__::
+ Let a socks connection wait NUM seconds handshaking, and NUM seconds
+ unattached waiting for an appropriate circuit, before we fail it. (Default:
+ 2 minutes)
+
+== DORMANT MODE OPTIONS
+
+// These options are in alphabetical order, with exceptions as noted.
+// Please keep them that way!
+
+Tor can enter dormant mode to conserve power and network bandwidth.
+The following options control when Tor enters and leaves dormant mode:
+
+[[DormantCanceledByStartup]] **DormantCanceledByStartup** **0**|**1**::
+ By default, Tor starts in active mode if it was active the last time
+ it was shut down, and in dormant mode if it was dormant. But if
+ this option is true, Tor treats every startup event as user
+ activity, and Tor will never start in Dormant mode, even if it has
+ been unused for a long time on previous runs. (Default: 0)
+ +
+ Note: Packagers and application developers should change the value of
+ this option only with great caution: it has the potential to
+ create spurious traffic on the network. This option should only
+ be used if Tor is started by an affirmative user activity (like
+ clicking on an applcation or running a command), and not if Tor
+ is launched for some other reason (for example, by a startup
+ process, or by an application that launches itself on every login.)
+
+[[DormantClientTimeout]] **DormantClientTimeout** __N__ **minutes**|**hours**|**days**|**weeks**::
+ If Tor spends this much time without any client activity,
+ enter a dormant state where automatic circuits are not built, and
+ directory information is not fetched.
+ Does not affect servers or onion services. Must be at least 10 minutes.
+ (Default: 24 hours)
+
+[[DormantOnFirstStartup]] **DormantOnFirstStartup** **0**|**1**::
+ If true, then the first time Tor starts up with a fresh DataDirectory,
+ it starts in dormant mode, and takes no actions until the user has made
+ a request. (This mode is recommended if installing a Tor client for a
+ user who might not actually use it.) If false, Tor bootstraps the first
+ time it is started, whether it sees a user request or not.
+ +
+ After the first time Tor starts, it begins in dormant mode if it was
+ dormant before, and not otherwise. (Default: 0)
+
+[[DormantTimeoutDisabledByIdleStreams]] **DormantTimeoutDisabledByIdleStreams** **0**|**1**::
+ If true, then any open client stream (even one not reading or writing)
+ counts as client activity for the purpose of DormantClientTimeout.
+ If false, then only network activity counts. (Default: 1)
+
+== NODE SELECTION OPTIONS
+
+// These options are in alphabetical order, with exceptions as noted.
+// Please keep them that way!
+
+The following options restrict the nodes that a tor client
+(or onion service) can use while building a circuit.
+These options can weaken your anonymity by making your client behavior
+different from other Tor clients:
+
+[[EntryNodes]] **EntryNodes** __node__,__node__,__...__::
+ A list of identity fingerprints and country codes of nodes
+ to use for the first hop in your normal circuits.
+ Normal circuits include all
+ circuits except for direct connections to directory servers. The Bridge
+ option overrides this option; if you have configured bridges and
+ UseBridges is 1, the Bridges are used as your entry nodes. +
+ +
+ The ExcludeNodes option overrides this option: any node listed in both
+ EntryNodes and ExcludeNodes is treated as excluded. See
+ the **ExcludeNodes** option for more information on how to specify nodes.
+
+[[ExcludeNodes]] **ExcludeNodes** __node__,__node__,__...__::
+ A list of identity fingerprints, country codes, and address
+ patterns of nodes to avoid when building a circuit. Country codes are
+ 2-letter ISO3166 codes, and must
+ be wrapped in braces; fingerprints may be preceded by a dollar sign.
+ (Example:
+ ExcludeNodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
+ +
+ By default, this option is treated as a preference that Tor is allowed
+ to override in order to keep working.
+ For example, if you try to connect to a hidden service,
+ but you have excluded all of the hidden service's introduction points,
+ Tor will connect to one of them anyway. If you do not want this
+ behavior, set the StrictNodes option (documented below). +
+ +
+ Note also that if you are a relay, this (and the other node selection
+ options below) only affects your own circuits that Tor builds for you.
+ Clients can still build circuits through you to any node. Controllers
+ can tell Tor to build circuits through any node. +
+ +
+ Country codes are case-insensitive. The code "\{??}" refers to nodes whose
+ country can't be identified. No country code, including \{??}, works if
+ no GeoIPFile can be loaded. See also the GeoIPExcludeUnknown option below.
+
+// Out of order because it logically belongs after the ExcludeNodes option
+[[ExcludeExitNodes]] **ExcludeExitNodes** __node__,__node__,__...__::
+ A list of identity fingerprints, country codes, and address
+ patterns of nodes to never use when picking an exit node---that is, a
+ node that delivers traffic for you *outside* the Tor network. Note that any
+ node listed in ExcludeNodes is automatically considered to be part of this
+ list too. See
+ the **ExcludeNodes** option for more information on how to specify
+ nodes. See also the caveats on the "ExitNodes" option below.
+
+[[ExitNodes]] **ExitNodes** __node__,__node__,__...__::
+ A list of identity fingerprints, country codes, and address
+ patterns of nodes to use as exit node---that is, a
+ node that delivers traffic for you *outside* the Tor network. See
+ the **ExcludeNodes** option for more information on how to specify nodes. +
+ +
+ Note that if you list too few nodes here, or if you exclude too many exit
+ nodes with ExcludeExitNodes, you can degrade functionality. For example,
+ if none of the exits you list allows traffic on port 80 or 443, you won't
+ be able to browse the web. +
+ +
+ Note also that not every circuit is used to deliver traffic *outside* of
+ the Tor network. It is normal to see non-exit circuits (such as those
+ used to connect to hidden services, those that do directory fetches,
+ those used for relay reachability self-tests, and so on) that end
+ at a non-exit node. To
+ keep a node from being used entirely, see ExcludeNodes and StrictNodes. +
+ +
+ The ExcludeNodes option overrides this option: any node listed in both
+ ExitNodes and ExcludeNodes is treated as excluded. +
+ +
+ The .exit address notation, if enabled via MapAddress, overrides
+ this option.
+
+[[GeoIPExcludeUnknown]] **GeoIPExcludeUnknown** **0**|**1**|**auto**::
+ If this option is set to 'auto', then whenever any country code is set in
+ ExcludeNodes or ExcludeExitNodes, all nodes with unknown country (\{??} and
+ possibly \{A1}) are treated as excluded as well. If this option is set to
+ '1', then all unknown countries are treated as excluded in ExcludeNodes
+ and ExcludeExitNodes. This option has no effect when a GeoIP file isn't
+ configured or can't be found. (Default: auto)
+
+[[HSLayer2Nodes]] **HSLayer2Nodes** __node__,__node__,__...__::
+ A list of identity fingerprints, nicknames, country codes, and
+ address patterns of nodes that are allowed to be used as the
+ second hop in all client or service-side Onion Service circuits.
+ This option mitigates attacks where the adversary runs middle nodes
+ and induces your client or service to create many circuits, in order
+ to discover your primary guard node.
+ (Default: Any node in the network may be used in the second hop.)
+ +
+ (Example:
+ HSLayer2Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
+ +
+ When this is set, the resulting hidden service paths will
+ look like:
+ +
+ C - G - L2 - M - Rend +
+ C - G - L2 - M - HSDir +
+ C - G - L2 - M - Intro +
+ S - G - L2 - M - Rend +
+ S - G - L2 - M - HSDir +
+ S - G - L2 - M - Intro +
+ +
+ where C is this client, S is the service, G is the Guard node,
+ L2 is a node from this option, and M is a random middle node.
+ Rend, HSDir, and Intro point selection is not affected by this
+ option.
+ +
+ This option may be combined with HSLayer3Nodes to create
+ paths of the form:
+ +
+ C - G - L2 - L3 - Rend +
+ C - G - L2 - L3 - M - HSDir +
+ C - G - L2 - L3 - M - Intro +
+ S - G - L2 - L3 - M - Rend +
+ S - G - L2 - L3 - HSDir +
+ S - G - L2 - L3 - Intro +
+ +
+ ExcludeNodes have higher priority than HSLayer2Nodes,
+ which means that nodes specified in ExcludeNodes will not be
+ picked.
+ +
+ When either this option or HSLayer3Nodes are set, the /16 subnet
+ and node family restrictions are removed for hidden service
+ circuits. Additionally, we allow the guard node to be present
+ as the Rend, HSDir, and IP node, and as the hop before it. This
+ is done to prevent the adversary from inferring information
+ about our guard, layer2, and layer3 node choices at later points
+ in the path.
+ +
+ This option is meant to be managed by a Tor controller such as
+ https://github.com/mikeperry-tor/vanguards that selects and
+ updates this set of nodes for you. Hence it does not do load
+ balancing if fewer than 20 nodes are selected, and if no nodes in
+ HSLayer2Nodes are currently available for use, Tor will not work.
+ Please use extreme care if you are setting this option manually.
+
+[[HSLayer3Nodes]] **HSLayer3Nodes** __node__,__node__,__...__::
+ A list of identity fingerprints, nicknames, country codes, and
+ address patterns of nodes that are allowed to be used as the
+ third hop in all client and service-side Onion Service circuits.
+ This option mitigates attacks where the adversary runs middle nodes
+ and induces your client or service to create many circuits, in order
+ to discover your primary or Layer2 guard nodes.
+ (Default: Any node in the network may be used in the third hop.)
+ +
+ (Example:
+ HSLayer3Nodes ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
+ +
+ When this is set by itself, the resulting hidden service paths
+ will look like: +
+ C - G - M - L3 - Rend +
+ C - G - M - L3 - M - HSDir +
+ C - G - M - L3 - M - Intro +
+ S - G - M - L3 - M - Rend +
+ S - G - M - L3 - HSDir +
+ S - G - M - L3 - Intro +
+ where C is this client, S is the service, G is the Guard node,
+ L2 is a node from this option, and M is a random middle node.
+ Rend, HSDir, and Intro point selection is not affected by this
+ option.
+ +
+ While it is possible to use this option by itself, it should be
+ combined with HSLayer2Nodes to create paths of the form:
+ +
+ C - G - L2 - L3 - Rend +
+ C - G - L2 - L3 - M - HSDir +
+ C - G - L2 - L3 - M - Intro +
+ S - G - L2 - L3 - M - Rend +
+ S - G - L2 - L3 - HSDir +
+ S - G - L2 - L3 - Intro +
+ +
+ ExcludeNodes have higher priority than HSLayer3Nodes,
+ which means that nodes specified in ExcludeNodes will not be
+ picked.
+ +
+ When either this option or HSLayer2Nodes are set, the /16 subnet
+ and node family restrictions are removed for hidden service
+ circuits. Additionally, we allow the guard node to be present
+ as the Rend, HSDir, and IP node, and as the hop before it. This
+ is done to prevent the adversary from inferring information
+ about our guard, layer2, and layer3 node choices at later points
+ in the path.
+ +
+ This option is meant to be managed by a Tor controller such as
+ https://github.com/mikeperry-tor/vanguards that selects and
+ updates this set of nodes for you. Hence it does not do load
+ balancing if fewer than 20 nodes are selected, and if no nodes in
+ HSLayer3Nodes are currently available for use, Tor will not work.
+ Please use extreme care if you are setting this option manually.
+
+[[MiddleNodes]] **MiddleNodes** __node__,__node__,__...__::
+ A list of identity fingerprints and country codes of nodes
+ to use for "middle" hops in your normal circuits.
+ Normal circuits include all circuits except for direct connections
+ to directory servers. Middle hops are all hops other than exit and entry. +
++
+ This is an **experimental** feature that is meant to be used by researchers
+ and developers to test new features in the Tor network safely. Using it
+ without care will strongly influence your anonymity. This feature might get
+ removed in the future.
++
+ The HSLayer2Node and HSLayer3Node options override this option for onion
+ service circuits, if they are set. The vanguards addon will read this
+ option, and if set, it will set HSLayer2Nodes and HSLayer3Nodes to nodes
+ from this set.
++
+ The ExcludeNodes option overrides this option: any node listed in both
+ MiddleNodes and ExcludeNodes is treated as excluded. See
+ the **ExcludeNodes** option for more information on how to specify nodes.
+
+[[NodeFamily]] **NodeFamily** __node__,__node__,__...__::
+ The Tor servers, defined by their identity fingerprints,
+ constitute a "family" of similar or co-administered servers, so never use
+ any two of them in the same circuit. Defining a NodeFamily is only needed
+ when a server doesn't list the family itself (with MyFamily). This option
+ can be used multiple times; each instance defines a separate family. In
+ addition to nodes, you can also list IP address and ranges and country
+ codes in {curly braces}. See the **ExcludeNodes** option for more
+ information on how to specify nodes.
+
+[[StrictNodes]] **StrictNodes** **0**|**1**::
+ If StrictNodes is set to 1, Tor will treat solely the ExcludeNodes option
+ as a requirement to follow for all the circuits you generate, even if
+ doing so will break functionality for you (StrictNodes does not apply to
+ ExcludeExitNodes, ExitNodes, MiddleNodes, or MapAddress). If StrictNodes
+ is set to 0, Tor will still try to avoid nodes in the ExcludeNodes list,
+ but it will err on the side of avoiding unexpected errors.
+ Specifically, StrictNodes 0 tells Tor that it is okay to use an excluded
+ node when it is *necessary* to perform relay reachability self-tests,
+ connect to a hidden service, provide a hidden service to a client,
+ fulfill a .exit request, upload directory information, or download
+ directory information. (Default: 0)
== SERVER OPTIONS
@@ -3652,7 +3676,7 @@ __DataDirectory__/**`approved-routers`**::
__DataDirectory__ for an example fingerprint line. If the status is
**!reject** then descriptors from the given identity (fingerprint/pubkey)
are rejected by this server. If it is **!invalid** then descriptors are
- accepted but marked in the directory as not valid, that is, not
+ accepted but marked in the directory as not valid, that is, not
recommended.
__DataDirectory__/**`v3-status-votes`**::
diff --git a/scripts/codegen/gen_server_ciphers.py b/scripts/codegen/gen_server_ciphers.py
index dd295b7f7d..3b77952243 100755
--- a/scripts/codegen/gen_server_ciphers.py
+++ b/scripts/codegen/gen_server_ciphers.py
@@ -101,7 +101,7 @@ def parse_cipher(ciph):
fwsec, = m.groups()
return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a")
- print "/* Couldn't parse %s ! */"%ciph
+ print("/* Couldn't parse %s ! */"%ciph)
return None
@@ -125,12 +125,12 @@ for c in ALL_CIPHERS:
colon = ' ":"'
if c.name in MANDATORY:
- print "%s/* Required */"%indent
- print '%s%s%s'%(indent,c.name,colon)
+ print("%s/* Required */"%indent)
+ print('%s%s%s'%(indent,c.name,colon))
else:
- print "#ifdef %s"%c.name
- print '%s%s%s'%(indent,c.name,colon)
- print "#endif"
+ print("#ifdef %s"%c.name)
+ print('%s%s%s'%(indent,c.name,colon))
+ print("#endif")
-print '%s;'%indent
+print('%s;'%indent)
diff --git a/scripts/codegen/get_mozilla_ciphers.py b/scripts/codegen/get_mozilla_ciphers.py
index d149c71c27..165105736a 100755
--- a/scripts/codegen/get_mozilla_ciphers.py
+++ b/scripts/codegen/get_mozilla_ciphers.py
@@ -20,7 +20,7 @@ import re
import sys
if len(sys.argv) != 3:
- print >>sys.stderr, "Syntax: get_mozilla_ciphers.py <firefox-source-dir> <openssl-source-dir>"
+ print("Syntax: get_mozilla_ciphers.py <firefox-source-dir> <openssl-source-dir>", file=sys.stderr)
sys.exit(1)
ff_root = sys.argv[1]
@@ -176,13 +176,13 @@ for fl in oSSLinclude:
fp.close()
# Now generate the output.
-print """\
+print("""\
/* This is an include file used to define the list of ciphers clients should
* advertise. Before including it, you should define the CIPHER and XCIPHER
* macros.
*
* This file was automatically generated by get_mozilla_ciphers.py.
- */"""
+ */""")
# Go in order by the order in CipherPrefs
for firefox_macro in firefox_ciphers:
@@ -215,4 +215,4 @@ for firefox_macro in firefox_ciphers:
#else
XCIPHER(%(hex)s, %(macro)s)
#endif""" % format
- print res
+ print(res)
diff --git a/scripts/codegen/makedesc.py b/scripts/codegen/makedesc.py
index 7d8177f469..af926a6438 100644
--- a/scripts/codegen/makedesc.py
+++ b/scripts/codegen/makedesc.py
@@ -24,12 +24,16 @@ import os
import re
import struct
import time
-import UserDict
import slow_ed25519
import slownacl_curve25519
import ed25519_exts_ref
+try:
+ xrange # Python 2
+except NameError:
+ xrange = range # Python 3
+
# Pull in the openssl stuff we need.
crypt = ctypes.CDLL(ctypes.util.find_library('crypto'))
@@ -252,8 +256,8 @@ class OnDemandKeys(object):
def signdesc(body, args_out=None):
- rsa, ident_pem, id_digest = make_key()
- _, onion_pem, _ = make_key()
+ rsa, ident_pem, id_digest = make_rsa_key()
+ _, onion_pem, _ = make_rsa_key()
need_ed = '{ED25519-CERT}' in body or '{ED25519-SIGNATURE}' in body
if need_ed:
@@ -303,10 +307,10 @@ def signdesc(body, args_out=None):
return body.rstrip()
def print_c_string(ident, body):
- print "static const char %s[] =" % ident
+ print("static const char %s[] =" % ident)
for line in body.split("\n"):
- print ' "%s\\n"' %(line)
- print " ;"
+ print(' "%s\\n"' %(line))
+ print(" ;")
def emit_ri(name, body):
info = OnDemandKeys()
@@ -320,8 +324,8 @@ def emit_ei(name, body):
body = info.sign_desc(body)
print_c_string("EX_EI_%s"%name.upper(), body)
- print 'const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format(
- d=info, NAME=name.upper())
+ print('const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format(
+ d=info, NAME=name.upper()))
print_c_string("EX_EI_%s_KEY"%name.upper(), info.RSA_IDENTITY)
def analyze(s):
diff --git a/scripts/maint/format_changelog.py b/scripts/maint/format_changelog.py
index 5f04a44ef6..32085c3602 100755
--- a/scripts/maint/format_changelog.py
+++ b/scripts/maint/format_changelog.py
@@ -291,7 +291,7 @@ class ChangeLog(object):
self.curgraf.append(line)
else:
- assert "This" is "unreachable"
+ assert "This" is "unreachable" # noqa: F632
def lint_head(self, line, head):
m = re.match(r'^ *o ([^\(]+)((?:\([^\)]+\))?):', head)
diff --git a/scripts/maint/locatemissingdoxygen.py b/scripts/maint/locatemissingdoxygen.py
index 9e58bd3477..7733977359 100755
--- a/scripts/maint/locatemissingdoxygen.py
+++ b/scripts/maint/locatemissingdoxygen.py
@@ -34,10 +34,10 @@ def buildWarnings():
def count(fn):
if os.path.abspath(fn) not in warnings:
- print "0\t%s"%fn
+ print("0\t%s"%fn)
else:
n = len(warnings[os.path.abspath(fn)])
- print "%d\t%s"%(n,fn)
+ print("%d\t%s"%(n,fn))
def getIndentation(line):
s = line.lstrip()
@@ -67,7 +67,7 @@ def annotate(filename):
if __name__ == '__main__':
if len(sys.argv) == 1:
- print "Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log"
+ print("Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log")
sys.exit(1)
buildWarnings()
if sys.argv[1] == '-A':
diff --git a/scripts/maint/practracker/practracker.py b/scripts/maint/practracker/practracker.py
index e806aef3b4..6149fb79cb 100755
--- a/scripts/maint/practracker/practracker.py
+++ b/scripts/maint/practracker/practracker.py
@@ -30,6 +30,7 @@ import metrics
import util
import problem
import includes
+import shutil
# The filename of the exceptions file (it should be placed in the practracker directory)
EXCEPTIONS_FNAME = "./exceptions.txt"
@@ -185,6 +186,9 @@ def main(argv):
help="Regenerate the exceptions file")
parser.add_argument("--list-overbroad", action="store_true",
help="List over-broad exceptions")
+ parser.add_argument("--regen-overbroad", action="store_true",
+ help="Regenerate the exceptions file, "
+ "removing over-broad exceptions.")
parser.add_argument("--exceptions",
help="Override the location for the exceptions file")
parser.add_argument("--strict", action="store_true",
@@ -227,8 +231,9 @@ def main(argv):
filt.addThreshold(problem.DependencyViolationItem("*.c", int(args.max_dependency_violations)))
filt.addThreshold(problem.DependencyViolationItem("*.h", int(args.max_dependency_violations)))
- if args.list_overbroad and args.regen:
- print("Cannot use --regen with --list-overbroad",
+ if args.list_overbroad + args.regen + args.regen_overbroad > 1:
+ print("Cannot use more than one of --regen, --list-overbroad, and "
+ "--regen-overbroad.",
file=sys.stderr)
sys.exit(1)
@@ -247,13 +252,15 @@ def main(argv):
ProblemVault = problem.ProblemVault(exceptions_file)
problem_file = sys.stdout
- if args.list_overbroad:
- # If we're listing overbroad exceptions, don't list problems.
+ if args.list_overbroad or args.regen_overbroad:
+ # If we're looking for overbroad exceptions, don't list problems
+ # immediately to the problem file.
problem_file = util.NullFile()
# 2.1) Adjust the exceptions so that we warn only about small problems,
# and produce errors on big ones.
- if not (args.regen or args.list_overbroad or args.strict):
+ if not (args.regen or args.list_overbroad or args.regen_overbroad or
+ args.strict):
ProblemVault.set_tolerances(TOLERANCE_FNS)
# 3) Go through all the files and report problems if they are not exceptions
@@ -269,7 +276,17 @@ def main(argv):
if args.regen:
tmpfile.close()
- os.rename(tmpname, exceptions_file)
+ shutil.move(tmpname, exceptions_file)
+ sys.exit(0)
+
+ if args.regen_overbroad:
+ tmpname = exceptions_file + ".tmp"
+ tmpfile = open(tmpname, "w")
+ tmpfile.write(HEADER)
+ for item in ProblemVault.list_exceptions_without_overbroad():
+ print(item, file=tmpfile)
+ tmpfile.close()
+ shutil.move(tmpname, exceptions_file)
sys.exit(0)
# If new issues were found, try to give out some advice to the developer on how to resolve it.
@@ -296,6 +313,7 @@ variable.
else:
print(ex, "->", p.metric_value)
+
sys.exit(found_new_issues)
if __name__ == '__main__':
diff --git a/scripts/maint/practracker/problem.py b/scripts/maint/practracker/problem.py
index bee5eeb903..a3255dcc80 100644
--- a/scripts/maint/practracker/problem.py
+++ b/scripts/maint/practracker/problem.py
@@ -29,6 +29,8 @@ class ProblemVault(object):
def __init__(self, exception_fname=None):
# Exception dictionary: { problem.key() : Problem object }
self.exceptions = {}
+ # Exception list: list of Problem objects, in the order added.
+ self.exception_list = []
# Exception dictionary: maps key to the problem it was used to
# suppress.
self.used_exception_for = {}
@@ -63,6 +65,7 @@ class ProblemVault(object):
sys.exit(1)
self.exceptions[problem.key()] = problem
+ self.exception_list.append(problem)
#print "Registering exception: %s" % problem
def register_problem(self, problem):
@@ -98,6 +101,24 @@ class ProblemVault(object):
if p is None or e.is_worse_than(p):
yield (e, p)
+ def list_exceptions_without_overbroad(self):
+ """Return an iterator of new problems, such that overbroad
+ exceptions are replaced with minimally broad versions, or removed.
+ """
+ for e in self.exception_list:
+ p = self.used_exception_for.get(e.key())
+ if p is None:
+ # This exception wasn't needed at all.
+ continue
+ if e.is_worse_than(p):
+ # The exception is worse than the problem we found.
+ # Yield the problem as the new exception value.
+ yield p
+ else:
+ # The problem is as bad as the exception, or worse.
+ # Yield the exception.
+ yield e
+
def set_tolerances(self, fns):
"""Adjust the tolerances for the exceptions in this vault. Takes
a map of problem type to a function that adjusts the permitted
diff --git a/scripts/maint/practracker/test_practracker.sh b/scripts/maint/practracker/test_practracker.sh
index afc267a000..e29b9106de 100755
--- a/scripts/maint/practracker/test_practracker.sh
+++ b/scripts/maint/practracker/test_practracker.sh
@@ -82,3 +82,15 @@ run_practracker --exceptions "${DATA}/ex1.txt" --list-overbroad \
compare "${TMPDIR}/ex1-overbroad-received.txt" \
"${DATA}/ex1-overbroad-expected.txt"
+
+echo "ex1.regen:"
+
+cp "${DATA}/ex1.txt" "${TMPDIR}/ex1-copy.txt"
+run_practracker --exceptions "${TMPDIR}/ex1-copy.txt" --regen >/dev/null 2>&1
+compare "${TMPDIR}/ex1-copy.txt" "${DATA}/ex1-regen-expected.txt"
+
+echo "ex1.regen_overbroad:"
+
+cp "${DATA}/ex1.txt" "${TMPDIR}/ex1-copy.txt"
+run_practracker --exceptions "${TMPDIR}/ex1-copy.txt" --regen-overbroad >/dev/null 2>&1
+compare "${TMPDIR}/ex1-copy.txt" "${DATA}/ex1-regen-overbroad-expected.txt"
diff --git a/scripts/maint/practracker/testdata/ex1-regen-expected.txt b/scripts/maint/practracker/testdata/ex1-regen-expected.txt
new file mode 100644
index 0000000000..bdf3681edf
--- /dev/null
+++ b/scripts/maint/practracker/testdata/ex1-regen-expected.txt
@@ -0,0 +1,46 @@
+# Welcome to the exceptions file for Tor's best-practices tracker!
+#
+# Each line of this file represents a single violation of Tor's best
+# practices -- typically, a violation that we had before practracker.py
+# first existed.
+#
+# There are three kinds of problems that we recognize right now:
+# function-size -- a function of more than 100 lines.
+# file-size -- a .c file of more than 3000 lines, or a .h
+# file with more than 500 lines.
+# include-count -- a .c file with more than 50 #includes,
+# or a .h file with more than 15 #includes.
+# dependency-violation -- a file includes a header that it should
+# not, according to an advisory .may_include file.
+#
+# Each line below represents a single exception that practracker should
+# _ignore_. Each line has four parts:
+# 1. The word "problem".
+# 2. The kind of problem.
+# 3. The location of the problem: either a filename, or a
+# filename:functionname pair.
+# 4. The magnitude of the problem to ignore.
+#
+# So for example, consider this line:
+# problem file-size /src/core/or/connection_or.c 3200
+#
+# It tells practracker to allow the mentioned file to be up to 3200 lines
+# long, even though ordinarily it would warn about any file with more than
+# 3000 lines.
+#
+# You can either edit this file by hand, or regenerate it completely by
+# running `make practracker-regen`.
+#
+# Remember: It is better to fix the problem than to add a new exception!
+
+problem file-size a.c 41
+problem include-count a.c 6
+problem function-size a.c:i_am_a_function() 9
+problem function-size a.c:another_function() 12
+problem dependency-violation a.c 4
+problem file-size b.c 15
+problem function-size b.c:foo() 4
+problem function-size b.c:bar() 5
+problem file-size header.h 8
+problem include-count header.h 4
+problem dependency-violation header.h 3
diff --git a/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt b/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt
new file mode 100644
index 0000000000..4521029b10
--- /dev/null
+++ b/scripts/maint/practracker/testdata/ex1-regen-overbroad-expected.txt
@@ -0,0 +1,45 @@
+# Welcome to the exceptions file for Tor's best-practices tracker!
+#
+# Each line of this file represents a single violation of Tor's best
+# practices -- typically, a violation that we had before practracker.py
+# first existed.
+#
+# There are three kinds of problems that we recognize right now:
+# function-size -- a function of more than 100 lines.
+# file-size -- a .c file of more than 3000 lines, or a .h
+# file with more than 500 lines.
+# include-count -- a .c file with more than 50 #includes,
+# or a .h file with more than 15 #includes.
+# dependency-violation -- a file includes a header that it should
+# not, according to an advisory .may_include file.
+#
+# Each line below represents a single exception that practracker should
+# _ignore_. Each line has four parts:
+# 1. The word "problem".
+# 2. The kind of problem.
+# 3. The location of the problem: either a filename, or a
+# filename:functionname pair.
+# 4. The magnitude of the problem to ignore.
+#
+# So for example, consider this line:
+# problem file-size /src/core/or/connection_or.c 3200
+#
+# It tells practracker to allow the mentioned file to be up to 3200 lines
+# long, even though ordinarily it would warn about any file with more than
+# 3000 lines.
+#
+# You can either edit this file by hand, or regenerate it completely by
+# running `make practracker-regen`.
+#
+# Remember: It is better to fix the problem than to add a new exception!
+
+problem file-size a.c 41
+problem include-count a.c 6
+problem function-size a.c:i_am_a_function() 8
+problem function-size a.c:another_function() 11
+problem file-size b.c 15
+problem function-size b.c:bar() 5
+problem dependency-violation a.c 4
+problem dependency-violation header.h 3
+problem file-size header.h 8
+problem include-count header.h 4
diff --git a/scripts/maint/redox.py b/scripts/maint/redox.py
index 171c6d9699..3ad3e3f1b8 100755
--- a/scripts/maint/redox.py
+++ b/scripts/maint/redox.py
@@ -37,6 +37,11 @@ from __future__ import unicode_literals
import re
import sys
+try:
+ xrange # Python 2
+except NameError:
+ xrange = range # Python 3
+
# Which files should we ignore warning from? Mostly, these are external
# files that we've snarfed in from somebody else, whose C we do no intend
# to document for them.
@@ -78,7 +83,7 @@ def parsething(thing):
else:
m = THING_RE.match(thing)
if not m:
- print thing, "???? Format didn't match."
+ print(thing, "???? Format didn't match.")
return None, None
else:
name, tp, parent = m.groups()
@@ -155,7 +160,7 @@ def checkf(fn, errs):
"""
for skip in SKIP_FILES:
if fn.endswith(skip):
- print "Skipping",fn
+ print("Skipping",fn)
return
comments = []
@@ -174,8 +179,8 @@ def checkf(fn, errs):
ln = findline(lines, line, name)
if ln == None:
- print "Couldn't find the definition of %s allegedly on %s of %s"%(
- name, line, fn)
+ print("Couldn't find the definition of %s allegedly on %s of %s"%(
+ name, line, fn))
else:
if hasdocdoc(lines, line, kind):
# print "Has a DOCDOC"
@@ -220,12 +225,12 @@ def applyComments(fn, entries):
outf.write(line)
outf.close()
- print "Added %s DOCDOCs to %s" %(N, fn)
+ print("Added %s DOCDOCs to %s" %(N, fn))
e = read()
for fn, errs in e.iteritems():
- print `(fn, errs)`
+ print(repr((fn, errs)))
comments = checkf(fn, errs)
if comments:
applyComments(fn, comments)
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 223428a8f6..4a2dc21f1c 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -4970,10 +4970,10 @@ connection_finished_flushing(connection_t *conn)
}
}
-/** Called when our attempt to connect() to another server has just
- * succeeded.
+/** Called when our attempt to connect() to a server has just succeeded.
*
- * This function just passes conn to the connection-specific
+ * This function checks if the interface address has changed (clients only),
+ * and then passes conn to the connection-specific
* connection_*_finished_connecting() function.
*/
static int
diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c
index 7781b29fb1..260de181e5 100644
--- a/src/core/mainloop/mainloop.c
+++ b/src/core/mainloop/mainloop.c
@@ -2273,18 +2273,23 @@ systemd_watchdog_callback(periodic_timer_t *timer, void *arg)
#define UPTIME_CUTOFF_FOR_NEW_BANDWIDTH_TEST (6*60*60)
-/** Called when our IP address seems to have changed. <b>at_interface</b>
- * should be true if we detected a change in our interface, and false if we
- * detected a change in our published address. */
+/** Called when our IP address seems to have changed. <b>on_client_conn</b>
+ * should be true if:
+ * - we detected a change in our interface address, using an outbound
+ * connection, and therefore
+ * - our client TLS keys need to be rotated.
+ * Otherwise, it should be false, and:
+ * - we detected a change in our published address
+ * (using some other method), and therefore
+ * - the published addresses in our descriptor need to change.
+ */
void
-ip_address_changed(int at_interface)
+ip_address_changed(int on_client_conn)
{
const or_options_t *options = get_options();
int server = server_mode(options);
- int exit_reject_interfaces = (server && options->ExitRelay
- && options->ExitPolicyRejectLocalInterfaces);
- if (at_interface) {
+ if (on_client_conn) {
if (! server) {
/* Okay, change our keys. */
if (init_keys_client() < 0)
@@ -2296,15 +2301,14 @@ ip_address_changed(int at_interface)
reset_bandwidth_test();
reset_uptime();
router_reset_reachability();
+ /* All relays include their IP addresses as their ORPort addresses in
+ * their descriptor.
+ * Exit relays also incorporate interface addresses in their exit
+ * policies, when ExitPolicyRejectLocalInterfaces is set. */
+ mark_my_descriptor_dirty("IP address changed");
}
}
- /* Exit relays incorporate interface addresses in their exit policies when
- * ExitPolicyRejectLocalInterfaces is set */
- if (exit_reject_interfaces || (server && !at_interface)) {
- mark_my_descriptor_dirty("IP address changed");
- }
-
dns_servers_relaunch_checks();
}
diff --git a/src/core/mainloop/mainloop.h b/src/core/mainloop/mainloop.h
index f9a48a8e04..1ddfec2162 100644
--- a/src/core/mainloop/mainloop.h
+++ b/src/core/mainloop/mainloop.h
@@ -56,7 +56,7 @@ MOCK_DECL(int, connection_count_moribund, (void));
void directory_all_unreachable(time_t now);
void directory_info_has_arrived(time_t now, int from_cache, int suppress_logs);
-void ip_address_changed(int at_interface);
+void ip_address_changed(int on_client_conn);
void dns_servers_relaunch_checks(void);
void reset_all_main_loop_timers(void);
void reschedule_directory_downloads(void);
diff --git a/src/ext/ed25519/ref10/base.py b/src/ext/ed25519/ref10/base.py
index 8bfaab0568..3d477c5c39 100644
--- a/src/ext/ed25519/ref10/base.py
+++ b/src/ext/ed25519/ref10/base.py
@@ -56,15 +56,15 @@ def radix255(x):
Bi = B
for i in range(32):
- print "{"
+ print("{")
Bij = Bi
for j in range(8):
- print " {"
- print " {",radix255(Bij[1]+Bij[0]),"},"
- print " {",radix255(Bij[1]-Bij[0]),"},"
- print " {",radix255(2*d*Bij[0]*Bij[1]),"},"
+ print(" {")
+ print(" {",radix255(Bij[1]+Bij[0]),"},")
+ print(" {",radix255(Bij[1]-Bij[0]),"},")
+ print(" {",radix255(2*d*Bij[0]*Bij[1]),"},")
Bij = edwards(Bij,Bi)
- print " },"
- print "},"
+ print(" },")
+ print("},")
for k in range(8):
Bi = edwards(Bi,Bi)
diff --git a/src/ext/ed25519/ref10/base2.py b/src/ext/ed25519/ref10/base2.py
index 5923e43a7b..3f8e3d25d2 100644
--- a/src/ext/ed25519/ref10/base2.py
+++ b/src/ext/ed25519/ref10/base2.py
@@ -57,9 +57,9 @@ def radix255(x):
Bi = B
for i in range(8):
- print " {"
- print " {",radix255(Bi[1]+Bi[0]),"},"
- print " {",radix255(Bi[1]-Bi[0]),"},"
- print " {",radix255(2*d*Bi[0]*Bi[1]),"},"
- print " },"
+ print(" {")
+ print(" {",radix255(Bi[1]+Bi[0]),"},")
+ print(" {",radix255(Bi[1]-Bi[0]),"},")
+ print(" {",radix255(2*d*Bi[0]*Bi[1]),"},")
+ print(" },")
Bi = edwards(B,edwards(B,Bi))
diff --git a/src/ext/ed25519/ref10/d.py b/src/ext/ed25519/ref10/d.py
index 3fbb175077..5b875de666 100644
--- a/src/ext/ed25519/ref10/d.py
+++ b/src/ext/ed25519/ref10/d.py
@@ -30,4 +30,4 @@ def radix255(x):
return result
d = -121665 * inv(121666)
-print radix255(d)
+print(radix255(d))
diff --git a/src/ext/ed25519/ref10/d2.py b/src/ext/ed25519/ref10/d2.py
index 3e533730b7..f59a1bc62a 100644
--- a/src/ext/ed25519/ref10/d2.py
+++ b/src/ext/ed25519/ref10/d2.py
@@ -30,4 +30,4 @@ def radix255(x):
return result
d = -121665 * inv(121666)
-print radix255(d*2)
+print(radix255(d*2))
diff --git a/src/ext/ed25519/ref10/sqrtm1.py b/src/ext/ed25519/ref10/sqrtm1.py
index a276d4e673..df9f26ee1d 100644
--- a/src/ext/ed25519/ref10/sqrtm1.py
+++ b/src/ext/ed25519/ref10/sqrtm1.py
@@ -30,4 +30,4 @@ def radix255(x):
return result
I = expmod(2,(q-1)/4,q)
-print radix255(I)
+print(radix255(I))
diff --git a/src/feature/control/control.c b/src/feature/control/control.c
index b4f27cb820..ee1026359d 100644
--- a/src/feature/control/control.c
+++ b/src/feature/control/control.c
@@ -158,6 +158,10 @@ control_ports_write_to_file(void)
}
const struct signal_name_t signal_table[] = {
+ /* NOTE: this table is used for handling SIGNAL commands and generating
+ * SIGNAL events. Order is significant: if there are two entries for the
+ * same numeric signal, the first one is the canonical name generated
+ * for the events. */
{ SIGHUP, "RELOAD" },
{ SIGHUP, "HUP" },
{ SIGINT, "SHUTDOWN" },
diff --git a/src/feature/control/control_events.c b/src/feature/control/control_events.c
index b0a1a3f242..916ccea875 100644
--- a/src/feature/control/control_events.c
+++ b/src/feature/control/control_events.c
@@ -1559,29 +1559,17 @@ control_event_signal(uintptr_t signal_num)
if (!control_event_is_interesting(EVENT_GOT_SIGNAL))
return 0;
- switch (signal_num) {
- case SIGHUP:
- signal_string = "RELOAD";
+ for (unsigned i = 0; signal_table[i].signal_name != NULL; ++i) {
+ if ((int)signal_num == signal_table[i].sig) {
+ signal_string = signal_table[i].signal_name;
break;
- case SIGUSR1:
- signal_string = "DUMP";
- break;
- case SIGUSR2:
- signal_string = "DEBUG";
- break;
- case SIGNEWNYM:
- signal_string = "NEWNYM";
- break;
- case SIGCLEARDNSCACHE:
- signal_string = "CLEARDNSCACHE";
- break;
- case SIGHEARTBEAT:
- signal_string = "HEARTBEAT";
- break;
- default:
- log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal",
- (unsigned long)signal_num);
- return -1;
+ }
+ }
+
+ if (signal_string == NULL) {
+ log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal",
+ (unsigned long)signal_num);
+ return -1;
}
send_control_event(EVENT_GOT_SIGNAL, "650 SIGNAL %s\r\n",
diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c
index 6f30878d23..5dcc4b170d 100644
--- a/src/feature/control/control_getinfo.c
+++ b/src/feature/control/control_getinfo.c
@@ -1735,6 +1735,7 @@ handle_control_getinfo(control_connection_t *conn,
}
} else {
control_reply_add_one_kv(answers, 250, KV_RAW, q, ans);
+ tor_free(ans);
}
} SMARTLIST_FOREACH_END(q);
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index a7b41b835f..9cf408ca3e 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -847,6 +847,42 @@ hs_cache_store_as_client(const char *desc_str,
return ret;
}
+/** Remove and free a client cache descriptor entry for the given onion
+ * service ed25519 public key. If the descriptor is decoded, the intro
+ * circuits are closed if any.
+ *
+ * This does nothing if no descriptor exists for the given key. */
+void
+hs_cache_remove_as_client(const ed25519_public_key_t *key)
+{
+ hs_cache_client_descriptor_t *cached_desc = NULL;
+
+ tor_assert(key);
+
+ cached_desc = lookup_v3_desc_as_client(key->pubkey);
+ if (!cached_desc) {
+ return;
+ }
+ /* If we have a decrypted/decoded descriptor, attempt to close its
+ * introduction circuit(s). We shouldn't have circuit(s) without a
+ * descriptor else it will lead to a failure. */
+ if (cached_desc->desc) {
+ hs_client_close_intro_circuits_from_desc(cached_desc->desc);
+ }
+ /* Remove and free. */
+ remove_v3_desc_as_client(cached_desc);
+ cache_client_desc_free(cached_desc);
+
+ /* Logging. */
+ {
+ char key_b64[BASE64_DIGEST256_LEN + 1];
+ digest256_to_base64(key_b64, (const char *) key);
+ log_info(LD_REND, "Onion service v3 descriptor '%s' removed "
+ "from client cache",
+ safe_str_client(key_b64));
+ }
+}
+
/** Clean all client caches using the current time now. */
void
hs_cache_clean_as_client(time_t now)
diff --git a/src/feature/hs/hs_cache.h b/src/feature/hs/hs_cache.h
index ebe1621e88..bb3c77f224 100644
--- a/src/feature/hs/hs_cache.h
+++ b/src/feature/hs/hs_cache.h
@@ -85,6 +85,7 @@ const char *
hs_cache_lookup_encoded_as_client(const struct ed25519_public_key_t *key);
hs_desc_decode_status_t hs_cache_store_as_client(const char *desc_str,
const struct ed25519_public_key_t *identity_pk);
+void hs_cache_remove_as_client(const struct ed25519_public_key_t *key);
void hs_cache_clean_as_client(time_t now);
void hs_cache_purge_as_client(void);
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index bcb0495c6f..4599bde5bb 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1249,6 +1249,26 @@ can_client_refetch_desc(const ed25519_public_key_t *identity_pk,
return 0;
}
+/** Purge the client authorization cache of all ephemeral entries that is the
+ * entries that are not flagged with CLIENT_AUTH_FLAG_IS_PERMANENT.
+ *
+ * This is called from the hs_client_purge_state() used by a SIGNEWNYM. */
+STATIC void
+purge_ephemeral_client_auth(void)
+{
+ DIGEST256MAP_FOREACH_MODIFY(client_auths, key,
+ hs_client_service_authorization_t *, auth) {
+ /* Cleanup every entry that are _NOT_ permanent that is ephemeral. */
+ if (!(auth->flags & CLIENT_AUTH_FLAG_IS_PERMANENT)) {
+ MAP_DEL_CURRENT(key);
+ client_service_authorization_free(auth);
+ }
+ } DIGESTMAP_FOREACH_END;
+
+ log_info(LD_REND, "Client onion service ephemeral authorization "
+ "cache has been purged.");
+}
+
/** Return the client auth in the map using the service identity public key.
* Return NULL if it does not exist in the map. */
static hs_client_service_authorization_t *
@@ -1715,6 +1735,9 @@ hs_client_remove_auth_credentials(const char *hsaddress)
find_and_remove_client_auth_creds_file(cred);
}
+ /* Remove associated descriptor if any. */
+ hs_cache_remove_as_client(&service_identity_pk);
+
client_service_authorization_free(cred);
return REMOVAL_SUCCESS;
}
@@ -2433,6 +2456,8 @@ hs_client_purge_state(void)
hs_cache_purge_as_client();
/* Purge the last hidden service request cache. */
hs_purge_last_hid_serv_requests();
+ /* Purge ephemeral client authorization. */
+ purge_ephemeral_client_auth();
log_info(LD_REND, "Hidden service client state has been purged.");
}
diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h
index 56b24a4119..3660bfa96c 100644
--- a/src/feature/hs/hs_client.h
+++ b/src/feature/hs/hs_client.h
@@ -162,6 +162,8 @@ MOCK_DECL(STATIC hs_client_fetch_status_t,
STATIC void retry_all_socks_conn_waiting_for_desc(void);
+STATIC void purge_ephemeral_client_auth(void);
+
#ifdef TOR_UNIT_TESTS
STATIC void set_hs_client_auths_map(digest256map_t *map);
diff --git a/src/feature/rend/rendmid.c b/src/feature/rend/rendmid.c
index 752375b6d3..a473f0c7e1 100644
--- a/src/feature/rend/rendmid.c
+++ b/src/feature/rend/rendmid.c
@@ -59,7 +59,7 @@ rend_mid_establish_intro_legacy(or_circuit_t *circ, const uint8_t *request,
pk = crypto_pk_asn1_decode((char*)(request+2), asn1len);
if (!pk) {
reason = END_CIRC_REASON_TORPROTOCOL;
- log_warn(LD_PROTOCOL, "Couldn't decode public key.");
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Couldn't decode public key.");
goto err;
}
@@ -81,7 +81,7 @@ rend_mid_establish_intro_legacy(or_circuit_t *circ, const uint8_t *request,
(char*)request, 2+asn1len+DIGEST_LEN,
(char*)(request+2+DIGEST_LEN+asn1len),
request_len-(2+DIGEST_LEN+asn1len))<0) {
- log_warn(LD_PROTOCOL,
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Incorrect signature on ESTABLISH_INTRO cell; rejecting.");
reason = END_CIRC_REASON_TORPROTOCOL;
goto err;
@@ -162,9 +162,9 @@ rend_mid_introduce_legacy(or_circuit_t *circ, const uint8_t *request,
if (request_len < (DIGEST_LEN+(MAX_NICKNAME_LEN+1)+REND_COOKIE_LEN+
DH1024_KEY_LEN+CIPHER_KEY_LEN+
PKCS1_OAEP_PADDING_OVERHEAD)) {
- log_warn(LD_PROTOCOL, "Impossibly short INTRODUCE1 cell on circuit %u; "
- "responding with nack.",
- (unsigned)circ->p_circ_id);
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Impossibly short INTRODUCE1 cell on circuit %u; "
+ "responding with nack.", (unsigned)circ->p_circ_id);
goto err;
}
@@ -258,7 +258,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
}
if (circ->base_.n_chan) {
- log_warn(LD_PROTOCOL,
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Tried to establish rendezvous on non-edge circuit");
goto err;
}
@@ -270,8 +270,8 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const uint8_t *request,
}
if (hs_circuitmap_get_rend_circ_relay_side(request)) {
- log_warn(LD_PROTOCOL,
- "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS.");
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Duplicate rendezvous cookie in ESTABLISH_RENDEZVOUS.");
goto err;
}
@@ -313,9 +313,9 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
int reason = END_CIRC_REASON_INTERNAL;
if (circ->base_.purpose != CIRCUIT_PURPOSE_OR || circ->base_.n_chan) {
- log_info(LD_REND,
- "Tried to complete rendezvous on non-OR or non-edge circuit %u.",
- (unsigned)circ->p_circ_id);
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Tried to complete rendezvous on non-OR or non-edge circuit %u.",
+ (unsigned)circ->p_circ_id);
reason = END_CIRC_REASON_TORPROTOCOL;
goto err;
}
diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c
index b2817ee760..d229c755b4 100644
--- a/src/feature/stats/rephist.c
+++ b/src/feature/stats/rephist.c
@@ -1122,7 +1122,7 @@ static bw_array_t *dir_read_array = NULL;
directory protocol. */
static bw_array_t *dir_write_array = NULL;
-/** Set up [dir-]read_array and [dir-]write_array, freeing them if they
+/** Set up [dir_]read_array and [dir_]write_array, freeing them if they
* already exist. */
static void
bw_arrays_init(void)
diff --git a/src/lib/log/util_bug.h b/src/lib/log/util_bug.h
index f1831fd25b..ae3d125a08 100644
--- a/src/lib/log/util_bug.h
+++ b/src/lib/log/util_bug.h
@@ -198,7 +198,7 @@
STMT_END
#define BUG(cond) \
(ASSERT_PREDICT_UNLIKELY_(cond) ? \
- (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",1,NULL),1) \
+ (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \
: 0)
#endif /* defined(ALL_BUGS_ARE_FATAL) || ... */
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
index f04f319449..815fb02283 100644
--- a/src/lib/net/address.h
+++ b/src/lib/net/address.h
@@ -62,6 +62,7 @@
typedef uint8_t maskbits_t;
struct in_addr;
+
/** Holds an IPv4 or IPv6 address. (Uses less memory than struct
* sockaddr_storage.) */
typedef struct tor_addr_t
@@ -133,6 +134,7 @@ tor_addr_to_in6_assert(const tor_addr_t *a)
* Requires that <b>x</b> is actually an IPv6 address.
*/
#define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6_assert(x))
+
/** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t.
*
* Requires that <b>x</b> is actually an IPv6 address.
@@ -146,6 +148,7 @@ tor_addr_to_ipv4n(const tor_addr_t *a)
{
return a->family == AF_INET ? a->addr.in_addr.s_addr : 0;
}
+
/** Return an IPv4 address in host order for <b>a</b>, or 0 if
* <b>a</b> is not an IPv4 address. */
static inline uint32_t
@@ -153,10 +156,11 @@ tor_addr_to_ipv4h(const tor_addr_t *a)
{
return ntohl(tor_addr_to_ipv4n(a));
}
+
/** Given an IPv6 address, return its mapped IPv4 address in host order, or
* 0 if <b>a</b> is not an IPv6 address.
*
- * (Does not check whether the address is really a mapped address */
+ * (Does not check whether the address is really a mapped address.) */
static inline uint32_t
tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
{
@@ -165,14 +169,13 @@ tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
// Work around an incorrect NULL pointer dereference warning in
// "clang --analyze" due to limited analysis depth
addr32 = tor_addr_to_in6_addr32(a);
- // To improve performance, wrap this assertion in:
- // #if !defined(__clang_analyzer__) || PARANOIA
tor_assert(addr32);
return ntohl(addr32[3]);
} else {
return 0;
}
}
+
/** Return the address family of <b>a</b>. Possible values are:
* AF_INET6, AF_INET, AF_UNSPEC. */
static inline sa_family_t
@@ -180,6 +183,7 @@ tor_addr_family(const tor_addr_t *a)
{
return a->family;
}
+
/** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not
* an IPv4 address. */
static inline const struct in_addr *
@@ -187,6 +191,7 @@ tor_addr_to_in(const tor_addr_t *a)
{
return a->family == AF_INET ? &a->addr.in_addr : NULL;
}
+
/** Return true iff <b>a</b> is an IPv4 address equal to the host-ordered
* address in <b>u</b>. */
static inline int
@@ -209,19 +214,23 @@ char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC;
/** Wrapper function of fmt_addr_impl(). It does not decorate IPv6
* addresses. */
#define fmt_addr(a) fmt_addr_impl((a), 0)
+
/** Wrapper function of fmt_addr_impl(). It decorates IPv6
* addresses. */
#define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1)
+
const char *fmt_addr_impl(const tor_addr_t *addr, int decorate);
const char *fmt_addrport(const tor_addr_t *addr, uint16_t port);
const char * fmt_addr32(uint32_t addr);
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
tor_addr_t *addr));
+
struct smartlist_t;
-void interface_address6_list_free_(struct smartlist_t * addrs);// XXXX
+void interface_address6_list_free_(struct smartlist_t * addrs);
#define interface_address6_list_free(addrs) \
FREE_AND_NULL(struct smartlist_t, interface_address6_list_free_, (addrs))
+
MOCK_DECL(struct smartlist_t *,get_interface_address6_list,(int severity,
sa_family_t family,
int include_internal));
@@ -246,6 +255,7 @@ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
uint64_t tor_addr_hash(const tor_addr_t *addr);
struct sipkey;
uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr);
+
int tor_addr_is_v4(const tor_addr_t *addr);
int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
const char *filename, int lineno);
@@ -276,11 +286,13 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
int tor_addr_parse_mask_ports(const char *s, unsigned flags,
tor_addr_t *addr_out, maskbits_t *mask_out,
uint16_t *port_min_out, uint16_t *port_max_out);
+
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len,
int decorate);
int tor_addr_parse(tor_addr_t *addr, const char *src);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
void tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src);
+
void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
/** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host
* order. */
@@ -291,6 +303,7 @@ void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes);
#define tor_addr_from_in(dest, in) \
tor_addr_from_ipv4n((dest), (in)->s_addr);
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
+
int tor_addr_is_null(const tor_addr_t *addr);
int tor_addr_is_loopback(const tor_addr_t *addr);
@@ -299,6 +312,7 @@ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening);
#define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \
tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening))
int tor_port_is_valid(uint16_t port, int for_listening);
+
/* Are addr and port both valid? */
#define tor_addr_port_is_valid(addr, port, for_listening) \
(tor_addr_is_valid((addr), (for_listening)) && \
@@ -329,9 +343,11 @@ int parse_port_range(const char *port, uint16_t *port_min_out,
uint16_t *port_max_out);
int addr_mask_get_bits(uint32_t mask);
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
+
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
#define interface_address_list_free(lst)\
interface_address6_list_free(lst)
+
/** Return a smartlist of the IPv4 addresses of all interfaces on the server.
* Excludes loopback and multicast addresses. Only includes internal addresses
* if include_internal is true. (Note that a relay behind NAT may use an
diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c
index af6c482c95..87055744a7 100644
--- a/src/lib/tls/buffers_tls.c
+++ b/src/lib/tls/buffers_tls.c
@@ -69,9 +69,9 @@ buf_read_from_tls(buf_t *buf, tor_tls_t *tls, size_t at_most)
check_no_tls_errors();
IF_BUG_ONCE(buf->datalen >= INT_MAX)
- return -1;
+ return TOR_TLS_ERROR_MISC;
IF_BUG_ONCE(buf->datalen >= INT_MAX - at_most)
- return -1;
+ return TOR_TLS_ERROR_MISC;
while (at_most > total_read) {
size_t readlen = at_most - total_read;
@@ -146,10 +146,10 @@ buf_flush_to_tls(buf_t *buf, tor_tls_t *tls, size_t flushlen,
size_t flushed = 0;
ssize_t sz;
tor_assert(buf_flushlen);
- if (BUG(*buf_flushlen > buf->datalen)) {
+ IF_BUG_ONCE(*buf_flushlen > buf->datalen) {
*buf_flushlen = buf->datalen;
}
- if (BUG(flushlen > *buf_flushlen)) {
+ IF_BUG_ONCE(flushlen > *buf_flushlen) {
flushlen = *buf_flushlen;
}
sz = (ssize_t) flushlen;
diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs
index 7a76fcdd94..0ca960bd69 100644
--- a/src/rust/protover/protover.rs
+++ b/src/rust/protover/protover.rs
@@ -26,7 +26,7 @@ const FIRST_TOR_VERSION_TO_ADVERTISE_PROTOCOLS: &'static str = "0.2.9.3-alpha";
/// before concluding that someone is trying to DoS us
///
/// C_RUST_COUPLED: protover.c `MAX_PROTOCOLS_TO_EXPAND`
-const MAX_PROTOCOLS_TO_EXPAND: usize = (1 << 16);
+const MAX_PROTOCOLS_TO_EXPAND: usize = 1 << 16;
/// The maximum size an `UnknownProtocol`'s name may be.
pub(crate) const MAX_PROTOCOL_NAME_LENGTH: usize = 100;
diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py
index 658f7cde12..ae537ff15b 100644
--- a/src/test/ed25519_exts_ref.py
+++ b/src/test/ed25519_exts_ref.py
@@ -152,7 +152,7 @@ class SelfTest(unittest.TestCase):
# Check that identities match
assert(identity == identity2)
# Check that identity is the point (0,1)
- assert(identity == [0L,1L])
+ assert(identity == [0,1])
# Check identity element: a*E = E, where a is a random scalar
scalar = random_scalar(os.urandom)
@@ -186,22 +186,22 @@ BLINDING_PARAMS = [
PREFIX = "ED25519_"
def writeArray(name, array):
- print "static const char *{prefix}{name}[] = {{".format(
- prefix=PREFIX,name=name)
+ print("static const char *{prefix}{name}[] = {{".format(
+ prefix=PREFIX,name=name))
for a in array:
h = binascii.b2a_hex(a)
if len(h) > 70:
h1 = h[:70]
h2 = h[70:]
- print ' "{0}"\n "{1}",'.format(h1,h2)
+ print(' "{0}"\n "{1}",'.format(h1,h2))
else:
- print ' "{0}",'.format(h)
- print "};\n"
+ print(' "{0}",'.format(h))
+ print("};\n")
def comment(text, initial="/**"):
- print initial
- print textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * ")
- print " */"
+ print(initial)
+ print(textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * "))
+ print(" */")
def makeTestVectors():
comment("""Test vectors for our ed25519 implementation and related
@@ -257,7 +257,7 @@ def makeTestVectors():
if __name__ == '__main__':
import sys
if len(sys.argv) == 1 or sys.argv[1] not in ("SelfTest", "MakeVectors"):
- print "You should specify one of 'SelfTest' or 'MakeVectors'"
+ print("You should specify one of 'SelfTest' or 'MakeVectors'")
sys.exit(1)
if sys.argv[1] == 'SelfTest':
unittest.main()
diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c
index e9d09fbeef..60dfbd630a 100644
--- a/src/test/test_controller_events.c
+++ b/src/test/test_controller_events.c
@@ -19,6 +19,7 @@
#include "feature/control/control_fmt.h"
#include "test/test.h"
#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
#include "core/or/entry_connection_st.h"
#include "core/or/or_circuit_st.h"
@@ -399,6 +400,43 @@ test_cntev_dirboot_defer_orconn(void *arg)
}
static void
+test_cntev_signal(void *arg)
+{
+ (void)arg;
+ int rv;
+
+ MOCK(queue_control_event_string, mock_queue_control_event_string);
+
+ /* Nothing is listening for signals, so no event should be queued. */
+ rv = control_event_signal(SIGHUP);
+ tt_int_op(0, OP_EQ, rv);
+ tt_ptr_op(saved_event_str, OP_EQ, NULL);
+
+ /* Now try with signals included in the event mask. */
+ control_testing_set_global_event_mask(EVENT_MASK_(EVENT_GOT_SIGNAL));
+ rv = control_event_signal(SIGHUP);
+ tt_int_op(0, OP_EQ, rv);
+ tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL RELOAD\r\n");
+
+ rv = control_event_signal(SIGACTIVE);
+ tt_int_op(0, OP_EQ, rv);
+ tt_str_op(saved_event_str, OP_EQ, "650 SIGNAL ACTIVE\r\n");
+
+ /* Try a signal that doesn't exist. */
+ setup_full_capture_of_logs(LOG_WARN);
+ tor_free(saved_event_str);
+ rv = control_event_signal(99999);
+ tt_int_op(-1, OP_EQ, rv);
+ tt_ptr_op(saved_event_str, OP_EQ, NULL);
+ expect_single_log_msg_containing("Unrecognized signal 99999");
+
+ done:
+ tor_free(saved_event_str);
+ teardown_capture_of_logs();
+ UNMOCK(queue_control_event_string);
+}
+
+static void
setup_orconn_state(orconn_state_msg_t *msg, uint64_t gid, uint64_t chan,
int proxy_type)
{
@@ -679,6 +717,7 @@ struct testcase_t controller_event_tests[] = {
TEST(format_cell_stats, TT_FORK),
TEST(event_mask, TT_FORK),
TEST(format_stream, TT_FORK),
+ TEST(signal, TT_FORK),
T_PUBSUB(dirboot_defer_desc, TT_FORK),
T_PUBSUB(dirboot_defer_orconn, TT_FORK),
T_PUBSUB(orconn_state, TT_FORK),
diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c
index 9e0094d250..8ea550b65f 100644
--- a/src/test/test_hs_cache.c
+++ b/src/test/test_hs_cache.c
@@ -645,6 +645,59 @@ test_client_cache_decrypt(void *arg)
UNMOCK(networkstatus_get_live_consensus);
}
+static void
+test_client_cache_remove(void *arg)
+{
+ int ret;
+ ed25519_keypair_t service_kp;
+ hs_descriptor_t *desc1 = NULL;
+
+ (void) arg;
+
+ hs_init();
+
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+
+ /* Set consensus time. Lookup will not return the entry if it has expired
+ * and it is checked against the consensus valid_after time. */
+ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
+ &mock_ns.valid_after);
+ parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
+ &mock_ns.fresh_until);
+ parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC",
+ &mock_ns.valid_until);
+
+ /* Generate service keypair */
+ tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0));
+
+ /* Build a descriptor and cache it. */
+ {
+ char *encoded;
+ desc1 = hs_helper_build_hs_desc_with_ip(&service_kp);
+ tt_assert(desc1);
+ ret = hs_desc_encode_descriptor(desc1, &service_kp, NULL, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+
+ /* Store it */
+ ret = hs_cache_store_as_client(encoded, &service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, HS_DESC_DECODE_OK);
+ tor_free(encoded);
+ tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
+ }
+
+ /* Remove the cached entry. */
+ hs_cache_remove_as_client(&service_kp.pubkey);
+ tt_assert(!hs_cache_lookup_as_client(&service_kp.pubkey));
+
+ done:
+ hs_descriptor_free(desc1);
+ hs_free_all();
+
+ UNMOCK(networkstatus_get_live_consensus);
+}
+
struct testcase_t hs_cache[] = {
/* Encoding tests. */
{ "directory", test_directory, TT_FORK,
@@ -659,6 +712,8 @@ struct testcase_t hs_cache[] = {
NULL, NULL },
{ "client_cache_decrypt", test_client_cache_decrypt, TT_FORK,
NULL, NULL },
+ { "client_cache_remove", test_client_cache_remove, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 9f09cc3ecb..5f7fe9c404 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -80,6 +80,23 @@ mock_networkstatus_get_live_consensus(time_t now)
}
static int
+mock_write_str_to_file(const char *path, const char *str, int bin)
+{
+ (void) bin;
+ (void) path;
+ (void) str;
+ return 0;
+}
+
+static or_options_t mocked_options;
+
+static const or_options_t *
+mock_get_options(void)
+{
+ return &mocked_options;
+}
+
+static int
helper_config_client(const char *conf, int validate_only)
{
int ret = 0;
@@ -1330,6 +1347,85 @@ test_close_intro_circuit_failure(void *arg)
hs_free_all();
}
+static void
+test_purge_ephemeral_client_auth(void *arg)
+{
+ ed25519_keypair_t service_kp;
+ hs_client_service_authorization_t *auth = NULL;
+ hs_client_register_auth_status_t status;
+
+ (void) arg;
+
+ /* We will try to write on disk client credentials. */
+ MOCK(check_private_dir, mock_check_private_dir);
+ MOCK(get_options, mock_get_options);
+ MOCK(write_str_to_file, mock_write_str_to_file);
+
+ /* Boggus directory so when we try to write the permanent client
+ * authorization data to disk, we don't fail. See
+ * store_permanent_client_auth_credentials() for more details. */
+ mocked_options.ClientOnionAuthDir = tor_strdup("auth_dir");
+
+ hs_init();
+
+ /* Generate service keypair */
+ tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0));
+
+ /* Generate a client authorization object. */
+ auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t));
+
+ /* Set it up. No flags meaning it is ephemeral. */
+ curve25519_secret_key_generate(&auth->enc_seckey, 0);
+ hs_build_address(&service_kp.pubkey, HS_VERSION_THREE, auth->onion_address);
+ auth->flags = 0;
+
+ /* Confirm that there is nothing in the client auth map. It is unallocated
+ * until we add the first entry. */
+ tt_assert(!get_hs_client_auths_map());
+
+ /* Add an entry to the client auth list. We loose ownership of the auth
+ * object so nullify it. */
+ status = hs_client_register_auth_credentials(auth);
+ auth = NULL;
+ tt_int_op(status, OP_EQ, REGISTER_SUCCESS);
+
+ /* We should have the entry now. */
+ digest256map_t *client_auths = get_hs_client_auths_map();
+ tt_assert(client_auths);
+ tt_int_op(digest256map_size(client_auths), OP_EQ, 1);
+
+ /* Purge the cache that should remove all ephemeral values. */
+ purge_ephemeral_client_auth();
+ tt_int_op(digest256map_size(client_auths), OP_EQ, 0);
+
+ /* Now add a new authorization object but permanent. */
+ /* Generate a client authorization object. */
+ auth = tor_malloc_zero(sizeof(hs_client_service_authorization_t));
+ curve25519_secret_key_generate(&auth->enc_seckey, 0);
+ hs_build_address(&service_kp.pubkey, HS_VERSION_THREE, auth->onion_address);
+ auth->flags = CLIENT_AUTH_FLAG_IS_PERMANENT;
+
+ /* Add an entry to the client auth list. We loose ownership of the auth
+ * object so nullify it. */
+ status = hs_client_register_auth_credentials(auth);
+ auth = NULL;
+ tt_int_op(status, OP_EQ, REGISTER_SUCCESS);
+ tt_int_op(digest256map_size(client_auths), OP_EQ, 1);
+
+ /* Purge again, the entry should still be there. */
+ purge_ephemeral_client_auth();
+ tt_int_op(digest256map_size(client_auths), OP_EQ, 1);
+
+ done:
+ client_service_authorization_free(auth);
+ hs_free_all();
+ tor_free(mocked_options.ClientOnionAuthDir);
+
+ UNMOCK(check_private_dir);
+ UNMOCK(get_options);
+ UNMOCK(write_str_to_file);
+}
+
struct testcase_t hs_client_tests[] = {
{ "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy,
TT_FORK, NULL, NULL },
@@ -1357,5 +1453,9 @@ struct testcase_t hs_client_tests[] = {
/* SOCKS5 Extended Error Code. */
{ "socks_hs_errors", test_socks_hs_errors, TT_FORK, NULL, NULL },
+ /* Client authorization. */
+ { "purge_ephemeral_client_auth", test_purge_ephemeral_client_auth, TT_FORK,
+ NULL, NULL },
+
END_OF_TESTCASES
};
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
index dc0db18bdc..881479016f 100644
--- a/src/test/test_hs_control.c
+++ b/src/test/test_hs_control.c
@@ -218,6 +218,8 @@ test_hs_control_good_onion_client_auth_add(void *arg)
char *cp1 = NULL;
size_t sz;
+ hs_init();
+
{ /* Setup the control conn */
memset(&conn, 0, sizeof(control_connection_t));
TO_CONN(&conn)->outbuf = buf_new();
@@ -415,6 +417,8 @@ test_hs_control_bad_onion_client_auth_add(void *arg)
size_t sz;
char *args = NULL;
+ hs_init();
+
{ /* Setup the control conn */
memset(&conn, 0, sizeof(control_connection_t));
TO_CONN(&conn)->outbuf = buf_new();
@@ -493,6 +497,8 @@ test_hs_control_store_permanent_creds(void *arg)
size_t sz;
+ hs_init();
+
{ /* Setup the control conn */
memset(&conn, 0, sizeof(control_connection_t));
TO_CONN(&conn)->outbuf = buf_new();
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index adcd9df3ec..3c8f91d53b 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -217,7 +217,7 @@
#define USING_TWOS_COMPLEMENT
/* Version number of package */
-#define VERSION "0.4.3.1-alpha-dev"
+#define VERSION "0.4.4.0-alpha-dev"
#define HAVE_STRUCT_SOCKADDR_IN6
#define HAVE_STRUCT_IN6_ADDR