Ver código fonte

Merge branch 'maint-0.3.3' of https://git.torproject.org/tor into maint-0.3.3

David Goulet 5 anos atrás
pai
commit
0431bb61ca
100 arquivos alterados com 1336 adições e 1432 exclusões
  1. 165 112
      .travis.yml
  2. 2 1
      Makefile.am
  3. 4 0
      changes/27286
  4. 4 0
      changes/bug20424_029_minimal
  5. 5 0
      changes/bug25440
  6. 3 0
      changes/bug25505
  7. 5 0
      changes/bug25512
  8. 5 0
      changes/bug25705
  9. 5 0
      changes/bug26269
  10. 4 0
      changes/bug26485
  11. 3 0
      changes/bug26497
  12. 3 0
      changes/bug26497-backport
  13. 4 0
      changes/bug26497-cd
  14. 7 0
      changes/bug26627
  15. 4 0
      changes/bug26779
  16. 4 0
      changes/bug26785
  17. 3 0
      changes/bug26787
  18. 3 0
      changes/bug26830
  19. 3 0
      changes/bug26853
  20. 4 0
      changes/bug26873
  21. 4 0
      changes/bug26876
  22. 4 0
      changes/bug26924
  23. 4 0
      changes/bug26927
  24. 3 0
      changes/bug26932
  25. 4 0
      changes/bug26948
  26. 4 0
      changes/bug27081
  27. 5 0
      changes/bug27088
  28. 3 0
      changes/bug27090
  29. 3 0
      changes/bug27093
  30. 4 0
      changes/bug27164
  31. 4 0
      changes/bug27177
  32. 3 0
      changes/bug27185
  33. 4 0
      changes/bug27206
  34. 5 0
      changes/bug27226
  35. 3 0
      changes/bug27295
  36. 4 0
      changes/bug27335
  37. 4 0
      changes/bug27344
  38. 5 0
      changes/bug27345
  39. 3 0
      changes/bug27418
  40. 3 0
      changes/bug27453
  41. 5 0
      changes/bug27461
  42. 3 0
      changes/bug27463
  43. 5 0
      changes/bug27465
  44. 4 0
      changes/bug27649
  45. 6 0
      changes/bug27658
  46. 4 0
      changes/bug27687
  47. 4 0
      changes/bug27708
  48. 4 0
      changes/geoip-2018-07-03
  49. 4 0
      changes/geoip-2018-08-07
  50. 4 0
      changes/geoip-2018-09-06
  51. 4 0
      changes/task26771
  52. 3 0
      changes/ticket24629
  53. 3 0
      changes/ticket24629-backport
  54. 3 0
      changes/ticket26560
  55. 4 0
      changes/ticket26647
  56. 3 0
      changes/ticket26952-cargo
  57. 3 0
      changes/ticket26952-ccache
  58. 3 0
      changes/ticket27087
  59. 6 0
      changes/ticket27252
  60. 5 0
      changes/ticket27252-032
  61. 62 6
      configure.ac
  62. 1 1
      contrib/win32build/tor-mingw.nsi.in
  63. 5 3
      doc/HACKING/GettingStartedRust.md
  64. 4 1
      src/common/address.c
  65. 2 3
      src/common/compat_threads.c
  66. 11 8
      src/common/compat_threads.h
  67. 4 0
      src/common/compress_zstd.c
  68. 1 1
      src/common/sandbox.c
  69. 12 5
      src/common/tortls.c
  70. 225 505
      src/config/geoip
  71. 212 650
      src/config/geoip6
  72. 10 2
      src/ext/tinytest.c
  73. 2 2
      src/or/auth_dirs.inc
  74. 7 2
      src/or/channelpadding.c
  75. 34 11
      src/or/circuituse.c
  76. 9 1
      src/or/config.c
  77. 0 1
      src/or/connection_edge.c
  78. 9 5
      src/or/connection_or.c
  79. 12 1
      src/or/control.c
  80. 41 10
      src/or/dirserv.c
  81. 1 2
      src/or/dirserv.h
  82. 8 1
      src/or/dirvote.c
  83. 14 6
      src/or/hs_circuit.c
  84. 24 12
      src/or/hs_service.c
  85. 3 2
      src/or/hs_service.h
  86. 13 4
      src/or/main.c
  87. 9 0
      src/or/rendclient.c
  88. 9 6
      src/or/router.c
  89. 3 0
      src/rust/protover/errors.rs
  90. 67 28
      src/rust/protover/protoset.rs
  91. 36 6
      src/rust/protover/protover.rs
  92. 7 7
      src/rust/protover/tests/protover.rs
  93. 0 2
      src/rust/tor_rust/include.am
  94. 1 1
      src/test/include.am
  95. 2 8
      src/test/test.c
  96. 2 0
      src/test/test_bt.sh
  97. 18 13
      src/test/test_config.c
  98. 52 1
      src/test/test_dir.c
  99. 6 0
      src/test/test_entrynodes.c
  100. 2 2
      src/test/test_hs_cell.c

+ 165 - 112
.travis.yml

@@ -1,75 +1,60 @@
 language: c
 
-## Comment out the compiler list for now to allow an explicit build
-## matrix.
-# compiler:
-#   - gcc
-#   - clang
+cache:
+  ccache: true
+  ## cargo: true
+  directories:
+    - $HOME/.cargo
+    ## where we point CARGO_TARGET_DIR in all our cargo invocations
+    - $TRAVIS_BUILD_DIR/src/rust/target
 
-notifications:
-  irc:
-    channels:
-      - "irc.oftc.net#tor-ci"
-    template:
-      - "%{repository} %{branch} %{commit} - %{author}: %{commit_subject}"
-      - "Build #%{build_number} %{result}. Details: %{build_url}"
-    on_success: change
-    on_failure: change
-  email:
-    on_success: never
-    on_failure: change
+compiler:
+  - gcc
+  - clang
 
 os:
   - linux
-  ## Uncomment the following line to also run the entire build matrix on OSX.
-  ## This will make your CI builds take roughly ten times longer to finish.
-  # - osx
-
-## Use the Ubuntu Trusty images.
-dist: trusty
-
-## We don't need sudo. (The "apt:" stanza after this allows us to not need sudo;
-## otherwise, we would need it for getting dependencies.)
-##
-## We override this in the explicit build matrix to work around a
-## Travis CI environment regression
-## https://github.com/travis-ci/travis-ci/issues/9033
-sudo: false
+  - osx
 
-## (Linux only) Download our dependencies
-addons:
-  apt:
-    packages:
-      ## Required dependencies
-      - libevent-dev
-      - libseccomp2
-      - zlib1g-dev
-      ## Optional dependencies
-      - liblzma-dev
-      - libscrypt-dev
-      ## zstd doesn't exist in Ubuntu Trusty
-      #- libzstd
-
-## The build matrix in the following two stanzas expands into four builds (per OS):
-##
-##  * with GCC, with Rust
-##  * with GCC, without Rust
-##  * with Clang, with Rust
-##  * with Clang, without Rust
+## The build matrix in the following stanza expands into builds for each
+## OS and compiler.
 env:
   global:
     ## The Travis CI environment allows us two cores, so let's use both.
     - MAKEFLAGS="-j 2"
+    ## We turn on hardening by default
+    ## Also known as --enable-fragile-hardening in 0.3.0.3-alpha and later
+    - HARDENING_OPTIONS="--enable-expensive-hardening"
+    ## We turn off asciidoc by default, because it's slow
+    - ASCIIDOC_OPTIONS="--disable-asciidoc"
   matrix:
-    ## Leave at least one entry here or Travis seems to generate a
-    ## matrix entry with empty matrix environment variables.  Leaving
-    ## more than one entry causes unwanted matrix entries with
-    ## unspecified compilers.
-    - RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
-    # - RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
-    # - RUST_OPTIONS=""
+    ## We want to use each build option at least once
+    ##
+    ## We don't list default variable values, because we set the defaults
+    ## in global (or the default is unset)
+    -
+    ## We turn off hardening for Rust builds, because they are incompatible,
+    ## and it's going to take a while for them to be fixed. See:
+    ##   https:/trac.torproject.org/projects/tor/ticket/25386
+    ##   https:/trac.torproject.org/projects/tor/ticket/26398
+    ## TOR_RUST_DEPENDENCIES is spelt RUST_DEPENDENCIES in 0.3.2
+    - RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true HARDENING_OPTIONS=""
 
 matrix:
+  ## include creates builds with gcc, linux, sudo: false
+  include:
+    ## We include a single coverage build with the best options for coverage
+    - env: COVERAGE_OPTIONS="--enable-coverage" HARDENING_OPTIONS=""
+    ## We only want to check these build option combinations once
+    ## (they shouldn't vary by compiler or OS)
+    ## We run rust and coverage with hardening off, which seems like enough
+    # - env: HARDENING_OPTIONS=""
+    ## We check asciidoc with distcheck, to make sure we remove doc products
+    - env: DISTCHECK="yes" ASCIIDOC_OPTIONS=""
+    ## Check rust online with distcheck, to make sure we remove rust products
+    ## But without hardening (see above)
+    - env: DISTCHECK="yes" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" HARDENING_OPTIONS=""
+
   ## Uncomment to allow the build to report success (with non-required
   ## sub-builds continuing to run) if all required sub-builds have
   ## succeeded.  This is somewhat buggy currently: it can cause
@@ -78,87 +63,155 @@ matrix:
   ## https://github.com/travis-ci/travis-ci/issues/1696
   # fast_finish: true
 
-  ## Uncomment the appropriate lines below to allow the build to
-  ## report success even if some less-critical sub-builds fail and it
-  ## seems likely to take a while for someone to fix it.  Currently
-  ## Travis CI doesn't distinguish "all builds succeeded" from "some
-  ## non-required sub-builds failed" except on the individual build's
-  ## page, which makes it somewhat annoying to detect from the
-  ## branches and build history pages.  See
-  ## https://github.com/travis-ci/travis-ci/issues/8716
-  allow_failures:
-    # - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
-    # - env: RUST_OPTIONS="--enable-rust --enable-cargo-online-mode
-    # - compiler: clang
-
-  ## Create explicit matrix entries to work around a Travis CI
-  ## environment issue.  Missing keys inherit from the first list
-  ## entry under that key outside the "include" clause.
-  include:
-    - compiler: gcc
-    - compiler: gcc
-      env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
+  ## Careful! We use global envs, which makes it hard to exclude or
+  ## allow failures by env:
+  ## https://docs.travis-ci.com/user/customizing-the-build#matching-jobs-with-allow_failures
+  exclude:
+    ## Clang doesn't work in containerized builds, see below.
+    - compiler: clang
+      sudo: false
+    ## Non-containerized gcc are slow and redundant.
     - compiler: gcc
-      env: RUST_OPTIONS=""
+      sudo: required
+    ## gcc on OSX is less useful, because the default compiler is clang.
     - compiler: gcc
-      env: COVERAGE_OPTIONS="--enable-coverage"
+      os: osx
+    ## gcc on Linux with no env is redundant, because all the custom builds use
+    ## gcc on Linux
     - compiler: gcc
-      env: DISTCHECK="yes" RUST_OPTIONS=""
+      os: linux
+      env:
+    ## offline rust builds for gcc on Linux are redundant, because we do an
+    ## online rust build for gcc on Linux
     - compiler: gcc
-      env: DISTCHECK="yes" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
-    ## The "sudo: required" forces non-containerized builds, working
-    ## around a Travis CI environment issue: clang LeakAnalyzer fails
-    ## because it requires ptrace and the containerized environment no
-    ## longer allows ptrace.
-    - compiler: clang
-      sudo: required
-    - compiler: clang
-      sudo: required
-      env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
-    - compiler: clang
-      sudo: required
-      env: RUST_OPTIONS=""
+      os: linux
+      ## TOR_RUST_DEPENDENCIES is spelt RUST_DEPENDENCIES in 0.3.2
+      env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true HARDENING_OPTIONS=""
+
+## We don't need sudo. (The "apt:" stanza after this allows us to not need
+## sudo; otherwise, we would need it for getting dependencies.)
+##
+## But we use "sudo: required" to force non-containerized builds, working
+## around a Travis CI environment issue: clang LeakAnalyzer fails
+## because it requires ptrace and the containerized environment no
+## longer allows ptrace.
+## https://github.com/travis-ci/travis-ci/issues/9033
+##
+## In the matrix above, we exclude redundant combinations.
+sudo:
+  - false
+  - required
+
+## (Linux only) Use the latest Linux image (Ubuntu Trusty)
+dist: trusty
+
+## (Linux only) Download our dependencies
+addons:
+  apt:
+    packages:
+      ## Required dependencies
+      - libevent-dev
+      - zlib1g-dev
+      ## Optional dependencies
+      - libcap-dev
+      - liblzma-dev
+      - libscrypt-dev
+      - libseccomp-dev
+      ## zstd doesn't exist in Ubuntu Trusty
+      #- libzstd
+      ## Conditional dependencies
+      ## Always installed, so we don't need sudo
+      - asciidoc
+      - docbook-xsl
+      - docbook-xml
+      - xmlto
+
+## (OSX only) Use the default OSX image
+## See https://docs.travis-ci.com/user/reference/osx#os-x-version
+## Default is Xcode 9.4 on macOS 10.13 as of August 2018
+#osx_image: xcode9.4
 
 before_install:
-  ## If we're on OSX, homebrew usually needs to updated first
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
-  ## Download rustup
-  - if [[ "$RUST_OPTIONS" != "" ]]; then curl -Ssf -o rustup.sh https://sh.rustup.rs; fi
-  - if [[ "$COVERAGE_OPTIONS" != "" ]]; then pip install --user cpp-coveralls; fi
+  ## If we're on OSX, homebrew usually needs to be updated first
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
+  ## We might be upgrading some useless packages, but that's better than missing an upgrade
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew upgrade; fi
+  ## Create empty rust directories for non-Rust builds, so caching succeeds
+  - if [[ "$RUST_OPTIONS" == "" ]]; then mkdir -p $HOME/.cargo $TRAVIS_BUILD_DIR/src/rust/target; fi
 
 install:
+  ## If we're on OSX use brew to install ccache (ccache is automatically installed on Linux)
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ccache; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi
   ## If we're on OSX use brew to install required dependencies (for Linux, see the "apt:" section above)
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated openssl    || brew upgrade openssl;    }; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated libevent   || brew upgrade libevent;   }; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated pkg-config || brew upgrade pkg-config; }; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libevent; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install pkg-config; fi
+  ## macOS comes with zlib by default, so the homebrew install is keg-only
+  # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install zlib; fi
   ## If we're on OSX also install the optional dependencies
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated xz         || brew upgrade xz;         }; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated libscrypt  || brew upgrade libscrypt;  }; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated zstd       || brew upgrade zstd;       }; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libscrypt; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install xz; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install zstd; fi
+  ## If we're on OSX, OpenSSL is keg-only, so tor 0.2.9 and later need to be configured --with-openssl-dir= to build
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then OPENSSL_OPTIONS=--with-openssl-dir=`brew --prefix openssl`; fi
+  ## Install conditional features
+  ## Install coveralls
+  - if [[ "$COVERAGE_OPTIONS" != "" ]]; then pip install --user cpp-coveralls; fi
+  ## If we're on OSX, and using asciidoc, install asciidoc
+  - if [[ "$ASCIIDOC_OPTIONS" == "" ]] && [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install asciidoc; fi
+  - if [[ "$ASCIIDOC_OPTIONS" == "" ]] && [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install xmlto; fi
+  - if [[ "$ASCIIDOC_OPTIONS" == "" ]] && [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export XML_CATALOG_FILES="/usr/local/etc/xml/catalog"; fi
+  ## If we're using Rust, download rustup
+  - if [[ "$RUST_OPTIONS" != "" ]]; then curl -Ssf -o rustup.sh https://sh.rustup.rs; fi
   ## Install the stable channels of rustc and cargo and setup our toolchain environment
   - if [[ "$RUST_OPTIONS" != "" ]]; then sh rustup.sh -y --default-toolchain stable; fi
   - if [[ "$RUST_OPTIONS" != "" ]]; then source $HOME/.cargo/env; fi
-  ## Get some info about rustc and cargo
+  ## If we're testing rust builds in offline-mode, then set up our vendored dependencies
+  - if [[ "$TOR_RUST_DEPENDENCIES" == "true" ]]; then export TOR_RUST_DEPENDENCIES=$PWD/src/ext/rust/crates; fi
+  ##
+  ## Finally, list installed package versions
+  - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then dpkg-query --show; fi
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew list --versions; fi
+  ## Get some info about rustup, rustc and cargo
+  - if [[ "$RUST_OPTIONS" != "" ]]; then which rustup; fi
   - if [[ "$RUST_OPTIONS" != "" ]]; then which rustc; fi
   - if [[ "$RUST_OPTIONS" != "" ]]; then which cargo; fi
+  - if [[ "$RUST_OPTIONS" != "" ]]; then rustup --version; fi
   - if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
   - if [[ "$RUST_OPTIONS" != "" ]]; then cargo --version; fi
-  ## If we're testing rust builds in offline-mode, then set up our vendored dependencies
-  - if [[ "$TOR_RUST_DEPENDENCIES" == "true" ]]; then export TOR_RUST_DEPENDENCIES=$PWD/src/ext/rust/crates; fi
 
 script:
   - ./autogen.sh
-  - ./configure $RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
+  - CONFIGURE_FLAGS="$ASCIIDOC_OPTIONS $COVERAGE_OPTIONS $HARDENING_OPTIONS $OPENSSL_OPTIONS $RUST_OPTIONS --enable-fatal-warnings --disable-silent-rules"
+  - echo "Configure flags are $CONFIGURE_FLAGS"
+  - ./configure $CONFIGURE_FLAGS
   ## We run `make check` because that's what https://jenkins.torproject.org does.
   - if [[ "$DISTCHECK" == "" ]]; then make check; fi
-  - if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
+  - if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$CONFIGURE_FLAGS"; fi
 
 after_failure:
+  ## configure will leave a log file with more details of config failures.
+  ## But the log is too long for travis' rendered view, so tail it.
+  - tail -1000 config.log || echo "tail failed"
   ## `make check` will leave a log file with more details of test failures.
-  - if [[ "$DISTCHECK" == "" ]]; then cat test-suite.log; fi
+  - if [[ "$DISTCHECK" == "" ]]; then cat test-suite.log || echo "cat failed"; fi
   ## `make distcheck` puts it somewhere different.
-  - if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog; fi
+  - if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog || echo "make failed"; fi
 
 after_success:
   ## 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'; fi
+
+notifications:
+  irc:
+    channels:
+      - "irc.oftc.net#tor-ci"
+    template:
+      - "%{repository} %{branch} %{commit} - %{author}: %{commit_subject}"
+      - "Build #%{build_number} %{result}. Details: %{build_url}"
+    on_success: change
+    on_failure: change
+  email:
+    on_success: never
+    on_failure: change

+ 2 - 1
Makefile.am

@@ -125,6 +125,7 @@ test-network: need-chutney-path $(TESTING_TOR_BINARY) src/tools/tor-gencert
 # because they're incompatible
 test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert
 	mkdir -p $(TEST_NETWORK_ALL_LOG_DIR)
+	rm -f $(TEST_NETWORK_ALL_LOG_DIR)/*.log $(TEST_NETWORK_ALL_LOG_DIR)/*.trs
 	@flavors="$(TEST_CHUTNEY_FLAVORS)"; \
 	if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1 || ping -6 -c 1 -W 1 ::1 >/dev/null 2>&1; then \
 		echo "ping6 ::1 or ping ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
@@ -148,7 +149,7 @@ test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/
 		$(top_srcdir)/src/test/test-network.sh $(TEST_NETWORK_WARNING_FLAGS); \
 	done; \
 	echo "Log and result files are available in $(TEST_NETWORK_ALL_LOG_DIR)."; \
-	! grep -q FAIL test_network_log/*.trs
+	! grep -q FAIL $(TEST_NETWORK_ALL_LOG_DIR)/*.trs
 
 need-stem-path:
 	@if test ! -d "$$STEM_SOURCE_DIR"; then \

+ 4 - 0
changes/27286

@@ -0,0 +1,4 @@
+  o Minor features (directory authorities):
+    - Authorities no longer vote to make the subprotocol version "LinkAuth=1"
+      a requirement: it is unsupportable with NSS, and hasn't been needed
+      since Tor 0.3.0.1-alpha. Closes ticket 27286.

+ 4 - 0
changes/bug20424_029_minimal

@@ -0,0 +1,4 @@
+  o Minor bugfixes (compilation):
+    - When compiling with --enable-openbsd-malloc or --enable-tcmalloc, tell
+      the compiler not to include the system malloc implementation. Fixes bug
+      20424; bugfix on 0.2.0.20-rc.

+ 5 - 0
changes/bug25440

@@ -0,0 +1,5 @@
+  o Minor bugfixes (linux seccomp2 sandbox):
+    - Fix a bug in out sandboxing rules for the openat() syscall.
+      Previously, no openat() call would be permitted, which would break
+      filesystem operations on recent glibc versions. Fixes bug 25440;
+      bugfix on 0.2.9.15. Diagnosis and patch from Daniel Pinto.

+ 3 - 0
changes/bug25505

@@ -0,0 +1,3 @@
+  o Minor bugfixes (netflow padding):
+    - Ensure circuitmux queues are empty before scheduling or sending padding.
+      Fixes bug 25505; bugfix on 0.3.1.1-alpha.

+ 5 - 0
changes/bug25512

@@ -0,0 +1,5 @@
+  o Minor bugfixes (restart-in-process):
+    - When shutting down, Tor now clears all the flags in the control.c
+      module. This should prevent a bug where authentication cookies
+      are not generated on restart. Fixes bug 25512; bugfix on 0.3.3.1-alpha.
+

+ 5 - 0
changes/bug25705

@@ -0,0 +1,5 @@
+  o Minor bugfixes (circuit path selection):
+    - Don't count path selection failures as circuit build failures. This
+      should eliminate cases where Tor blames its guard or the network
+      for situations like insufficient microdescriptors and/or overly
+      restrictive torrc settings. Fixes bug 25705; bugfix on 0.3.3.1-alpha.

+ 5 - 0
changes/bug26269

@@ -0,0 +1,5 @@
+  o Minor bugfixes (compilation):
+    - Fix a compilation warning on some versions of GCC when
+      building code that calls routerinfo_get_my_routerinfo() twice,
+      assuming that the second call will succeed if the first one did.
+      Fixes bug 26269; bugfix on 0.2.8.2-alpha.

+ 4 - 0
changes/bug26485

@@ -0,0 +1,4 @@
+  o Minor bugfixes (directory authority):
+    - When voting for recommended versions, make sure that all of the
+      versions are well-formed and parsable. Fixes bug 26485; bugfix on
+      0.1.1.6-alpha.

+ 3 - 0
changes/bug26497

@@ -0,0 +1,3 @@
+  o Minor bugfixes (rust):
+    - Stop setting $CARGO_HOME. cargo will use the user's $CARGO_HOME, or
+      $HOME/.cargo by default. Fixes bug 26497; bugfix on 0.3.1.5-alpha.

+ 3 - 0
changes/bug26497-backport

@@ -0,0 +1,3 @@
+  o Minor bugfixes (rust):
+    - Backport test_rust.sh from master.
+      Fixes bug 26497; bugfix on 0.3.1.5-alpha.

+ 4 - 0
changes/bug26497-cd

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - cd to ${abs_top_builddir}/src/rust before running cargo in
+      src/test/test_rust.sh. This makes the working directory consistent
+      between builds and tests. Fixes bug 26497; bugfix on 0.3.3.2-alpha.

+ 7 - 0
changes/bug26627

@@ -0,0 +1,7 @@
+  o Minor bugfixes (v3 onion services):
+    - Stop sending ed25519 link specifiers in v3 onion service introduce
+      cells, when the rendezvous point doesn't support ed25519 link
+      authentication. Fixes bug 26627; bugfix on 0.3.2.4-alpha.
+    - Stop putting ed25519 link specifiers in v3 onion service descriptors,
+      when the intro point doesn't support ed25519 link authentication.
+      Fixes bug 26627; bugfix on 0.3.2.4-alpha.

+ 4 - 0
changes/bug26779

@@ -0,0 +1,4 @@
+  o Minor features (bug workaround):
+    - Compile correctly on systems that provide the C11 stdatomic.h header,
+      but where C11 atomic functions don't actually compile.
+      Closes ticket 26779; workaround for Debian issue 903709.

+ 4 - 0
changes/bug26785

@@ -0,0 +1,4 @@
+  o Minor bugfixes (compilation, portability):
+    - Don't try to use a pragma to temporarily disable
+      -Wunused-const-variable if the compiler doesn't support it.
+      Fixes bug 26785; bugfix on 0.3.2.11.

+ 3 - 0
changes/bug26787

@@ -0,0 +1,3 @@
+  o Minor bugfixes (testing):
+    - Disable core dumps in test_bt.sh, to avoid failures in "make
+      distcheck". Fixes bug 26787; bugfix on 0.2.5.2-alpha.

+ 3 - 0
changes/bug26830

@@ -0,0 +1,3 @@
+  o Minor bugfixes (continuous integration):
+    - Skip an unreliable key generation test on Windows, until the underlying
+      issue in bug 26076 is resolved. Fixes bug 26830; bugfix on 0.2.7.3-rc.

+ 3 - 0
changes/bug26853

@@ -0,0 +1,3 @@
+  o Minor bugfixes (continuous integration):
+    - Skip an unreliable key expiration test on Windows, until the underlying
+      issue in bug 26076 is resolved. Fixes bug 26853; bugfix on 0.3.2.1-alpha.

+ 4 - 0
changes/bug26873

@@ -0,0 +1,4 @@
+  o Minor bugfixes (portability):
+    - Fix compilation of the unit tests on GNU/Hurd, which does not
+      define PATH_MAX. Fixes bug 26873; bugfix on 0.3.3.1-alpha.
+      Patch from "paulusASol".

+ 4 - 0
changes/bug26876

@@ -0,0 +1,4 @@
+  o Minor bugfixes (portability):
+    - Work around two different bugs in the OS X 10.10 and later SDKs that
+      would prevent us from successfully targeting earlier versions of OS X.
+      Fixes bug 26876; bugfix on 0.3.3.1-alpha.

+ 4 - 0
changes/bug26924

@@ -0,0 +1,4 @@
+  o Minor bugfixes (single onion services, Tor2web):
+    - Log a protocol warning when single onion services or Tor2web clients
+      fail to authenticate direct connections to relays.
+      Fixes bug 26924; bugfix on 0.2.9.1-alpha.

+ 4 - 0
changes/bug26927

@@ -0,0 +1,4 @@
+  o Minor bugfixes (logging):
+    - Improve the log message when connection initiators fail to authenticate
+      direct connections to relays.
+      Fixes bug 26927; bugfix on 0.3.0.1-alpha.

+ 3 - 0
changes/bug26932

@@ -0,0 +1,3 @@
+  o Minor bugfixes (onion services):
+    - Fix bug that causes services to not ever rotate their descriptors if they
+      were getting SIGHUPed often. Fixes bug 26932; bugfix on 0.3.2.1-alpha.

+ 4 - 0
changes/bug26948

@@ -0,0 +1,4 @@
+  o Minor bugfixes (in-process restart):
+    - Always call tor_free_all() when leaving tor_run_main(). When we
+      did not, restarting tor in-process would cause an assertion failure.
+      Fixes bug 26948; bugfix on 0.3.3.1-alpha.

+ 4 - 0
changes/bug27081

@@ -0,0 +1,4 @@
+  o Minor bugfixes (compilation, windows):
+    - Don't link or search for pthreads when building for Windows, even if we
+      are using build environment (like mingw) that provides a pthreads
+      library. Fixes bug 27081; bugfix on 0.1.0.1-rc.

+ 5 - 0
changes/bug27088

@@ -0,0 +1,5 @@
+  o Minor bugfixes (continuous integration):
+    - Pass the module flags to distcheck configure, and
+      log the flags before running configure. (Backported
+      to 0.2.9 and later as a precaution.)
+      Fixes bug 27088; bugfix on 0.3.4.1-alpha.

+ 3 - 0
changes/bug27090

@@ -0,0 +1,3 @@
+  o Minor bugfixes (continuous integration):
+    - Build with zstd on macOS.
+      Fixes bug 27090; bugfix on 0.3.1.5-alpha.

+ 3 - 0
changes/bug27093

@@ -0,0 +1,3 @@
+  o Minor bugfixes (rust):
+    - Consistently use ../../.. as a fallback for $abs_top_srcdir in
+      test_rust.sh. Fixes bug 27093; bugfix on 0.3.4.3-alpha.

+ 4 - 0
changes/bug27164

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - Protover parsing was ignoring a 2nd hyphen and everything after it,
+      accepting entries like "Link=1-5-foo". Fixes bug 27164; bugfix on
+      0.3.3.1-alpha.

+ 4 - 0
changes/bug27177

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - Protover parsing was accepting the presence of whitespace in version
+      strings, which the C implementation would choke on, e.g. "Desc=1\t,2".
+      Fixes bug 27177; bugfix on 0.3.3.5-rc.

+ 3 - 0
changes/bug27185

@@ -0,0 +1,3 @@
+  o Minor bugfixes (Windows, compilation):
+    - Silence a compilation warning on MSVC 2017 and clang-cl.
+      Fixes bug 27185; bugfix on 0.2.2.2-alpha.

+ 4 - 0
changes/bug27206

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - protover_all_supported() would attempt to allocate up to 16GB on some
+      inputs, leading to a potential memory DoS. Fixes bug 27206; bugfix on
+      0.3.3.5-rc.

+ 5 - 0
changes/bug27226

@@ -0,0 +1,5 @@
+  o Minor bugfixes (testing, openssl compatibility):
+    - Our "tortls/cert_matches_key" unit test no longer relies on OpenSSL
+      internals.  Previously, it relied on unsupported OpenSSL behavior in
+      a way that caused it to crash with OpenSSL 1.0.2p. Fixes bug 27226;
+      bugfix on 0.2.5.1-alpha.

+ 3 - 0
changes/bug27295

@@ -0,0 +1,3 @@
+  o Minor bugfixes (testing, chutney):
+    - Before running make test-network-all, delete old logs and test result
+      files, to avoid spurious failures. Fixes bug 27295; bugfix on 0.2.7.3-rc.

+ 4 - 0
changes/bug27335

@@ -0,0 +1,4 @@
+  o Minor bugfixes (hidden service v3):
+    - In case the hidden service directory can't be created or has wrong
+      permissions, do not BUG() on it which lead to a non fatal stacktrace.
+      Fixes bug 27335; bugfix on 0.3.2.1.

+ 4 - 0
changes/bug27344

@@ -0,0 +1,4 @@
+  o Minor features (compatibility):
+    - Tell OpenSSL to maintain backward compatibility with previous
+      RSA1024/DH1024 users in Tor. With OpenSSL 1.1.1-pre6, these ciphers
+      are disabled by default. Closes ticket 27344.

+ 5 - 0
changes/bug27345

@@ -0,0 +1,5 @@
+  o Minor bugfixes (testing):
+    - When running make test-network-all, use the mixed+hs-v2 network.
+      (A previous fix to chutney removed v3 onion services from the
+      mixed+hs-v23 network, so seeing "mixed+hs-v23" in tests is
+      confusing.) Fixes bug 27345; bugfix on 0.3.2.1-alpha.

+ 3 - 0
changes/bug27418

@@ -0,0 +1,3 @@
+  o Minor bugfixes (continuous integration):
+    - When we use echo in Travis, don't pass a --flag as the first argument.
+      Fixes bug 27418; bugfix on 0.3.4.7-rc.

+ 3 - 0
changes/bug27453

@@ -0,0 +1,3 @@
+  o Minor bugfixes (continuous integration):
+    - When a Travis build fails, and showing a log fails, keep trying to
+      show the other logs. Fixes bug 27453; bugfix on 0.3.4.7-rc.

+ 5 - 0
changes/bug27461

@@ -0,0 +1,5 @@
+  o Minor bugfixes (compilation):
+    - Stop calling SetProcessDEPPolicy() on 64-bit Windows. It is not
+      supported, and always fails. Some compilers warn about the function
+      pointer cast on 64-bit Windows.
+      Fixes bug 27461; bugfix on 0.2.2.23-alpha.

+ 3 - 0
changes/bug27463

@@ -0,0 +1,3 @@
+  o Minor bugfixes (onion services):
+    - Silence a spurious compiler warning in rend_client_send_introduction().
+      Fixes bug 27463; bugfix on 0.1.1.2-alpha.

+ 5 - 0
changes/bug27465

@@ -0,0 +1,5 @@
+  o Minor bugfixes (compilation):
+    - Silence a spurious compiler warning on the GetAdaptersAddresses
+      function pointer cast. This issue is already fixed by 26481 in
+      0.3.5 and later, by removing the lookup and cast.
+      Fixes bug 27465; bugfix on 0.2.3.11-alpha.

+ 4 - 0
changes/bug27649

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - The protover rewrite in 24031 allowed repeated votes from the same
+      voter for the same protocol version to be counted multiple times in
+      protover_compute_vote(). Fixes bug 27649; bugfix on 0.3.3.5-rc.

+ 6 - 0
changes/bug27658

@@ -0,0 +1,6 @@
+  o Minor bugfixes (testing):
+    - If a unit test running in a subprocess exits abnormally or with a
+      nonzero status code, treat the test as having failed, even if
+      the test reported success. Without this fix, memory leaks don't cause
+      cause the tests to fail, even with LeakSanitizer. Fixes bug 27658;
+      bugfix on 0.2.2.4-alpha.

+ 4 - 0
changes/bug27687

@@ -0,0 +1,4 @@
+  o Minor bugfixes (rust):
+    - protover parsed and accepted unknown protocol names containing invalid
+      characters outside the range [A-Za-z0-9-]. Fixes bug 27687; bugfix on
+      0.3.3.1-alpha.

+ 4 - 0
changes/bug27708

@@ -0,0 +1,4 @@
+  o Major bugfixes (restart-in-process):
+    - Fix a use-after-free error that could be caused by passing Tor an
+      impossible set of options that would fail during options_act().
+      Fixes bug 27708; bugfix on 0.3.3.1-alpha.

+ 4 - 0
changes/geoip-2018-07-03

@@ -0,0 +1,4 @@
+  o Minor features (geoip):
+    - Update geoip and geoip6 to the July 3 2018 Maxmind GeoLite2
+      Country database. Closes ticket 26674.
+

+ 4 - 0
changes/geoip-2018-08-07

@@ -0,0 +1,4 @@
+  o Minor features (geoip):
+    - Update geoip and geoip6 to the August 7 2018 Maxmind GeoLite2
+      Country database. Closes ticket 27089.
+

+ 4 - 0
changes/geoip-2018-09-06

@@ -0,0 +1,4 @@
+  o Minor features (geoip):
+    - Update geoip and geoip6 to the September 6 2018 Maxmind GeoLite2
+      Country database. Closes ticket 27631.
+

+ 4 - 0
changes/task26771

@@ -0,0 +1,4 @@
+  o Directory authority changes:
+    - The "Bifroest" bridge authority has been retired; the new bridge
+      authority is "Serge", and it is operated by George from the
+      TorBSD project. Closes ticket 26771.

+ 3 - 0
changes/ticket24629

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration):
+    - Enable macOS builds in our Travis CI configuration.
+      Closes ticket 24629.

+ 3 - 0
changes/ticket24629-backport

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration):
+    - Backport Travis rust distcheck to 0.3.3.
+      Closes ticket 24629.

+ 3 - 0
changes/ticket26560

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration):
+    - Install libcap-dev and libseccomp2-dev so these optional
+      dependencies get tested on Travis CI.  Closes ticket 26560.

+ 4 - 0
changes/ticket26647

@@ -0,0 +1,4 @@
+  o Minor features (controller):
+    - The control port now exposes the list of HTTPTunnelPorts and
+      ExtOrPorts via GETINFO net/listeners/httptunnel and net/listeners/extor
+      respectively.  Closes ticket 26647.

+ 3 - 0
changes/ticket26952-cargo

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration, rust):
+    - Use cargo cache in our Travis CI configuration.
+      Closes ticket 26952.

+ 3 - 0
changes/ticket26952-ccache

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration):
+    - Use ccache in our Travis CI configuration.
+      Closes ticket 26952.

+ 3 - 0
changes/ticket27087

@@ -0,0 +1,3 @@
+  o Minor features (continuous integration):
+    - Run asciidoc during Travis CI.
+      Implements ticket 27087.

+ 6 - 0
changes/ticket27252

@@ -0,0 +1,6 @@
+  o Minor features (continuous integration):
+    - Skip gcc on OSX in Travis CI, it's rarely used.
+      Skip a duplicate hardening-off build in Travis on Tor 0.2.9.
+      Skip gcc on Linux with default settings, because all the non-default
+      builds use gcc on Linux.
+      Implements ticket 27252.

+ 5 - 0
changes/ticket27252-032

@@ -0,0 +1,5 @@
+  o Minor features (continuous integration):
+    - Only run one online rust build in Travis, to reduce network errors.
+      Skip offline rust builds on Travis for Linux gcc, because they're
+      redundant.
+      Implements ticket 27252.

+ 62 - 6
configure.ac

@@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2017, The Tor Project, Inc.
 dnl See LICENSE for licensing information
 
 AC_PREREQ([2.63])
-AC_INIT([tor],[0.3.3.7-dev])
+AC_INIT([tor],[0.3.3.10-dev])
 AC_CONFIG_SRCDIR([src/or/main.c])
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -515,8 +515,10 @@ if test "$LIBS" != "$saved_LIBS"; then
    have_rt=yes
 fi
 
-AC_SEARCH_LIBS(pthread_create, [pthread])
-AC_SEARCH_LIBS(pthread_detach, [pthread])
+if test "$bwin32" = "false"; then
+  AC_SEARCH_LIBS(pthread_create, [pthread])
+  AC_SEARCH_LIBS(pthread_detach, [pthread])
+fi
 
 AM_CONDITIONAL(THREADS_WIN32, test "$bwin32" = "true")
 AM_CONDITIONAL(THREADS_PTHREADS, test "$bwin32" = "false")
@@ -548,7 +550,6 @@ AC_CHECK_FUNCS(
         llround \
         localtime_r \
         lround \
-	mach_approximate_time \
         memmem \
         memset_s \
 	pipe \
@@ -574,9 +575,36 @@ AC_CHECK_FUNCS(
 	_vscprintf
 )
 
-# Apple messed up when they added two functions functions in Sierra: they
+# Apple messed up when they added some functions: they
 # forgot to decorate them with appropriate AVAILABLE_MAC_OS_VERSION
-# checks. So we should only probe for those functions if we are sure that we
+# checks.
+
+# We should only probe for these functions if we are sure that we
+# are not targeting OS X 10.9 or earlier.
+AC_MSG_CHECKING([for a pre-Yosemite OS X build target])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef __APPLE__
+#  include <AvailabilityMacros.h>
+#  ifndef MAC_OS_X_VERSION_10_10
+#    define MAC_OS_X_VERSION_10_10 101000
+#  endif
+#  if defined(MAC_OS_X_VERSION_MIN_REQUIRED)
+#    if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
+#      error "Running on Mac OS X 10.9 or earlier"
+#    endif
+#  endif
+#endif
+]], [[]])],
+   [on_macos_pre_10_10=no ; AC_MSG_RESULT([no])],
+   [on_macos_pre_10_10=yes; AC_MSG_RESULT([yes])])
+
+if test "$on_macos_pre_10_10" = "no"; then
+  AC_CHECK_FUNCS(
+        mach_approximate_time \
+  )
+fi
+
+# We should only probe for these functions if we are sure that we
 # are not targeting OSX 10.11 or earlier.
 AC_MSG_CHECKING([for a pre-Sierra OSX build target])
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -828,6 +856,7 @@ AC_CHECK_FUNCS([ \
                 SSL_get_client_ciphers \
                 SSL_get_client_random \
 		SSL_CIPHER_find \
+                SSL_CTX_set_security_level \
 		TLS_method
 	       ])
 
@@ -1531,6 +1560,26 @@ AC_CHECK_SIZEOF(socklen_t, , [AC_INCLUDES_DEFAULT()
 
 AC_CHECK_SIZEOF(cell_t)
 
+# Let's see if stdatomic works. (There are some debian clangs that screw it
+# up; see Tor bug #26779 and debian bug 903709.)
+AC_CACHE_CHECK([whether C11 stdatomic.h actually works],
+               tor_cv_stdatomic_works,
+[AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include <stdatomic.h>
+struct x { atomic_size_t y; };
+void try_atomic_init(struct x *xx)
+{
+  atomic_init(&xx->y, 99);
+  atomic_fetch_add(&xx->y, 1);
+}
+]])], [tor_cv_stdatomic_works=yes], [tor_cv_stdatomic_works=no])])
+
+if test "$tor_cv_stdatomic_works" = "yes"; then
+   AC_DEFINE(STDATOMIC_WORKS, 1, [Set to 1 if we can compile a simple stdatomic example.])
+elif test "$ac_cv_header_stdatomic_h" = "yes"; then
+   AC_MSG_WARN([Your compiler provides the stdatomic.h header, but it doesn't seem to work.  I'll pretend it isn't there. If you are using Clang on Debian, maybe this is because of https://bugs.debian.org/903709 ])
+fi
+
 # Now make sure that NULL can be represented as zero bytes.
 AC_CACHE_CHECK([whether memset(0) sets pointers to NULL], tor_cv_null_is_zero,
 [AC_RUN_IFELSE([AC_LANG_SOURCE(
@@ -1698,6 +1747,10 @@ fi
 if test "$using_custom_malloc" = "no"; then
    AC_CHECK_FUNCS(mallinfo)
 fi
+if test "$using_custom_malloc" = "yes"; then
+  # Tell the C compiler not to use the system allocator functions.
+  TOR_CHECK_CFLAGS([-fno-builtin-malloc -fno-builtin-realloc -fno-builtin-calloc -fno-builtin-free])
+fi
 
 # By default, we're going to assume we don't have mlockall()
 # bionic and other platforms have various broken mlockall subsystems.
@@ -2172,6 +2225,9 @@ dnl     -Wthread-safety-precise
   if test "$tor_cv_cflags__Woverlength_strings" = "yes"; then
     AC_DEFINE([HAVE_CFLAG_WOVERLENGTH_STRINGS], 1, [True if we have -Woverlength-strings])
   fi
+  if test "$tor_cv_cflags__warn_unused_const_variable_2" = "yes"; then
+    AC_DEFINE([HAVE_CFLAG_WUNUSED_CONST_VARIABLE], 1, [True if we have -Wunused-const-variable])
+  fi
 
   if test "x$enable_fatal_warnings" = "xyes"; then
     # I'd like to use TOR_CHECK_CFLAGS here, but I can't, since the

+ 1 - 1
contrib/win32build/tor-mingw.nsi.in

@@ -8,7 +8,7 @@
 !include "LogicLib.nsh"
 !include "FileFunc.nsh"
 !insertmacro GetParameters
-!define VERSION "0.3.3.7-dev"
+!define VERSION "0.3.3.10-dev"
 !define INSTALLER "tor-${VERSION}-win32.exe"
 !define WEBSITE "https://www.torproject.org/"
 !define LICENSE "LICENSE"

+ 5 - 3
doc/HACKING/GettingStartedRust.md

@@ -122,9 +122,10 @@ the module calls.  Modules which call fewer other modules are better targets.
 
 Strive to change the C API as little as possible.
 
-We are currently targeting Rust nightly, *for now*. We expect this to
-change moving forward, as we understand more about which nightly
-features we need. It is on our TODO list to try to cultivate good
+We are currently targetting Rust stable. (See CodingStandardsRust.md for more
+details.)
+
+It is on our TODO list to try to cultivate good
 standing with various distro maintainers of `rustc` and `cargo`, in
 order to ensure that whatever version we solidify on is readily
 available.
@@ -139,6 +140,7 @@ Where <name_of_c_object> can be an enum, struct, constant, etc.  Then,
 do the same in the C code, to note that rust will need to be changed
 when the C does.
 
+
  Adding your Rust module to Tor's build system
 -----------------------------------------------
 

+ 4 - 1
src/common/address.c

@@ -1496,7 +1496,10 @@ get_interface_addresses_win32(int severity, sa_family_t family)
     goto done;
   }
 
-  if (!(fn = (GetAdaptersAddresses_fn_t)
+  /* Cast through a void function pointer, to silence a spurious compiler
+   * warning on 64-bit Windows. This cast is safe, because we are casting to
+   * the correct type for GetAdaptersAddresses(). */
+  if (!(fn = (GetAdaptersAddresses_fn_t)(void(*)(void))
                   GetProcAddress(lib, "GetAdaptersAddresses"))) {
     log_fn(severity, LD_NET, "Unable to obtain pointer to "
            "GetAdaptersAddresses");

+ 2 - 3
src/common/compat_threads.c

@@ -352,7 +352,7 @@ alert_sockets_close(alert_sockets_t *socks)
   socks->read_fd = socks->write_fd = -1;
 }
 
-#ifndef HAVE_STDATOMIC_H
+#ifndef HAVE_WORKING_STDATOMIC
 /** Initialize a new atomic counter with the value 0 */
 void
 atomic_counter_init(atomic_counter_t *counter)
@@ -403,5 +403,4 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
   tor_mutex_release(&counter->mutex);
   return oldval;
 }
-#endif /* !defined(HAVE_STDATOMIC_H) */
-
+#endif /* !defined(HAVE_WORKING_STDATOMIC) */

+ 11 - 8
src/common/compat_threads.h

@@ -14,7 +14,11 @@
 #include <pthread.h>
 #endif
 
-#ifdef HAVE_STDATOMIC_H
+#if defined(HAVE_STDATOMIC_H) && defined(STDATOMIC_WORKS)
+#define HAVE_WORKING_STDATOMIC
+#endif
+
+#ifdef HAVE_WORKING_STDATOMIC
 #include <stdatomic.h>
 #endif
 
@@ -156,18 +160,18 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
 /**
  * Atomic counter type; holds a size_t value.
  */
-#ifdef HAVE_STDATOMIC_H
+#ifdef HAVE_WORKING_STDATOMIC
 typedef struct atomic_counter_t {
   atomic_size_t val;
 } atomic_counter_t;
 #define ATOMIC_LINKAGE static
-#else /* !(defined(HAVE_STDATOMIC_H)) */
+#else /* !(defined(HAVE_WORKING_STDATOMIC)) */
 typedef struct atomic_counter_t {
   tor_mutex_t mutex;
   size_t val;
 } atomic_counter_t;
 #define ATOMIC_LINKAGE
-#endif /* defined(HAVE_STDATOMIC_H) */
+#endif /* defined(HAVE_WORKING_STDATOMIC) */
 
 ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
 ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
@@ -178,7 +182,7 @@ ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter,
                                               size_t newval);
 #undef ATOMIC_LINKAGE
 
-#ifdef HAVE_STDATOMIC_H
+#ifdef HAVE_WORKING_STDATOMIC
 /** Initialize a new atomic counter with the value 0 */
 static inline void
 atomic_counter_init(atomic_counter_t *counter)
@@ -216,8 +220,7 @@ atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
   return atomic_exchange(&counter->val, newval);
 }
 
-#else /* !(defined(HAVE_STDATOMIC_H)) */
-#endif /* defined(HAVE_STDATOMIC_H) */
+#else /* !(defined(HAVE_WORKING_STDATOMIC)) */
+#endif /* defined(HAVE_WORKING_STDATOMIC) */
 
 #endif /* !defined(TOR_COMPAT_THREADS_H) */
-

+ 4 - 0
src/common/compress_zstd.c

@@ -19,10 +19,14 @@
 #include "compress_zstd.h"
 
 #ifdef HAVE_ZSTD
+#ifdef HAVE_CFLAG_WUNUSED_CONST_VARIABLE
 DISABLE_GCC_WARNING(unused-const-variable)
+#endif
 #include <zstd.h>
+#ifdef HAVE_CFLAG_WUNUSED_CONST_VARIABLE
 ENABLE_GCC_WARNING(unused-const-variable)
 #endif
+#endif
 
 /** Total number of bytes allocated for Zstandard state. */
 static atomic_counter_t total_zstd_allocation;

+ 1 - 1
src/common/sandbox.c

@@ -450,7 +450,7 @@ allow_file_open(scmp_filter_ctx ctx, int use_openat, const char *file)
 {
   if (use_openat) {
     return seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat),
-                              SCMP_CMP_STR(0, SCMP_CMP_EQ, AT_FDCWD),
+                              SCMP_CMP(0, SCMP_CMP_EQ, (unsigned int)AT_FDCWD),
                               SCMP_CMP_STR(1, SCMP_CMP_EQ, file));
   } else {
     return seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open),

+ 12 - 5
src/common/tortls.c

@@ -896,18 +896,20 @@ tor_tls_cert_get_key(tor_x509_cert_t *cert)
 MOCK_IMPL(int,
 tor_tls_cert_matches_key,(const tor_tls_t *tls, const tor_x509_cert_t *cert))
 {
-  X509 *peercert = SSL_get_peer_certificate(tls->ssl);
+  tor_x509_cert_t *peer = tor_tls_get_peer_cert((tor_tls_t *)tls);
+  if (!peer)
+    return 0;
+
+  X509 *peercert = peer->cert;
   EVP_PKEY *link_key = NULL, *cert_key = NULL;
   int result;
 
-  if (!peercert)
-    return 0;
   link_key = X509_get_pubkey(peercert);
   cert_key = X509_get_pubkey(cert->cert);
 
   result = link_key && cert_key && EVP_PKEY_cmp(cert_key, link_key) == 1;
 
-  X509_free(peercert);
+  tor_x509_cert_free(peer);
   if (link_key)
     EVP_PKEY_free(link_key);
   if (cert_key)
@@ -1170,6 +1172,12 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
   if (!(result->ctx = SSL_CTX_new(SSLv23_method())))
     goto error;
 #endif /* defined(HAVE_TLS_METHOD) */
+
+#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
+  /* Level 1 re-enables RSA1024 and DH1024 for compatibility with old tors */
+  SSL_CTX_set_security_level(result->ctx, 1);
+#endif
+
   SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2);
   SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv3);
 
@@ -2639,4 +2647,3 @@ evaluate_ecgroup_for_tls(const char *ecgroup)
 
   return ret;
 }
-

Diferenças do arquivo suprimidas por serem muito extensas
+ 225 - 505
src/config/geoip


Diferenças do arquivo suprimidas por serem muito extensas
+ 212 - 650
src/config/geoip6


+ 10 - 2
src/ext/tinytest.c

@@ -207,12 +207,20 @@ testcase_run_forked_(const struct testgroup_t *group,
 		r = (int)read(outcome_pipe[0], b, 1);
 		if (r == 0) {
 			printf("[Lost connection!] ");
-			return 0;
+			return FAIL;
 		} else if (r != 1) {
 			perror("read outcome from pipe");
 		}
-		waitpid(pid, &status, 0);
+		r = waitpid(pid, &status, 0);
 		close(outcome_pipe[0]);
+		if (r == -1) {
+			perror("waitpid");
+			return FAIL;
+		}
+                if (! WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+			printf("[did not exit cleanly.]");
+			return FAIL;
+                }
 		return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL);
 	}
 #endif

+ 2 - 2
src/or/auth_dirs.inc

@@ -8,8 +8,8 @@
 "dizum orport=443 "
   "v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
   "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
-"Bifroest orport=443 bridge "
-  "37.218.247.217:80 1D8F 3A91 C37C 5D1C 4C19 B1AD 1D0C FBE8 BF72 D8E1",
+"Serge orport=9001 bridge "
+  "66.111.2.131:9030 BA44 A889 E64B 93FA A2B1 14E0 2C2A 279A 8555 C533",
 "gabelmoo orport=443 "
   "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 "
   "ipv6=[2001:638:a000:4140::ffff:189]:443 "

+ 7 - 2
src/or/channelpadding.c

@@ -379,7 +379,8 @@ channelpadding_send_padding_cell_for_callback(channel_t *chan)
   chan->pending_padding_callback = 0;
 
   if (monotime_coarse_is_zero(&chan->next_padding_time) ||
-      chan->has_queued_writes(chan)) {
+      chan->has_queued_writes(chan) ||
+      (chan->cmux && circuitmux_num_cells(chan->cmux))) {
     /* We must have been active before the timer fired */
     monotime_coarse_zero(&chan->next_padding_time);
     return;
@@ -755,7 +756,11 @@ channelpadding_decide_to_pad_channel(channel_t *chan)
     return CHANNELPADDING_WONTPAD;
   }
 
-  if (!chan->has_queued_writes(chan)) {
+  /* There should always be a cmux on the circuit. After that,
+   * only schedule padding if there are no queued writes and no
+   * queued cells in circuitmux queues. */
+  if (chan->cmux && !chan->has_queued_writes(chan) &&
+      !circuitmux_num_cells(chan->cmux)) {
     int is_client_channel = 0;
 
     if (CHANNEL_IS_CLIENT(chan, options)) {

+ 34 - 11
src/or/circuituse.c

@@ -1757,6 +1757,39 @@ circuit_build_failed(origin_circuit_t *circ)
    * the last hop or an earlier hop. then use this info below.
    */
   int failed_at_last_hop = 0;
+
+  /* First, check to see if this was a path failure, rather than build
+   * failure.
+   *
+   * Note that we deliberately use circuit_get_cpath_len() (and not
+   * circuit_get_cpath_opened_len()) because we only want to ensure
+   * that a full path is *chosen*. This is different than a full path
+   * being *built*. We only want to count *build* failures below.
+   *
+   * Path selection failures can happen spuriously for a number
+   * of reasons (such as aggressive/invalid user-specified path
+   * restrictions in the torrc, insufficient microdescriptors, and
+   * non-user reasons like exitpolicy issues), and so should not be
+   * counted as failures below.
+   */
+  if (circuit_get_cpath_len(circ) < circ->build_state->desired_path_len) {
+    static ratelim_t pathfail_limit = RATELIM_INIT(3600);
+    log_fn_ratelim(&pathfail_limit, LOG_NOTICE, LD_CIRC,
+             "Our circuit %u (id: %" PRIu32 ") died due to an invalid "
+             "selected path, purpose %s. This may be a torrc "
+             "configuration issue, or a bug.",
+              TO_CIRCUIT(circ)->n_circ_id, circ->global_identifier,
+              circuit_purpose_to_string(TO_CIRCUIT(circ)->purpose));
+
+    /* If the path failed on an RP, retry it. */
+    if (TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND)
+      hs_circ_retry_service_rendezvous_point(circ);
+
+    /* In all other cases, just bail. The rest is just failure accounting
+     * that we don't want to do */
+    return;
+  }
+
   /* If the last hop isn't open, and the second-to-last is, we failed
    * at the last hop. */
   if (circ->cpath &&
@@ -1806,18 +1839,8 @@ circuit_build_failed(origin_circuit_t *circ)
        * If we have guard state (new guard API) and our path selection
        * code actually chose a full path, then blame the failure of this
        * circuit on the guard.
-       *
-       * Note that we deliberately use circuit_get_cpath_len() (and not
-       * circuit_get_cpath_opened_len()) because we only want to ensure
-       * that a full path is *chosen*. This is different than a full path
-       * being *built*. We only want to blame *build* failures on this
-       * guard. Path selection failures can happen spuriously for a number
-       * of reasons (such as aggressive/invalid user-specified path
-       * restrictions in the torrc, as well as non-user reasons like
-       * exitpolicy issues), and so should not be counted here.
        */
-      if (circ->guard_state &&
-          circuit_get_cpath_len(circ) >= circ->build_state->desired_path_len)
+      if (circ->guard_state)
         entry_guard_failed(&circ->guard_state);
       /* if there are any one-hop streams waiting on this circuit, fail
        * them now so they can retry elsewhere. */

+ 9 - 1
src/or/config.c

@@ -868,6 +868,7 @@ set_options(or_options_t *new_val, char **msg)
               "Acting on config options left us in a broken state. Dying.");
       tor_shutdown_event_loop_and_exit(1);
     }
+    global_options = old_options;
     return -1;
   }
   /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
@@ -3472,6 +3473,14 @@ options_validate(or_options_t *old_options, or_options_t *options,
          !options->RecommendedServerVersions))
       REJECT("Versioning authoritative dir servers must set "
              "Recommended*Versions.");
+
+    char *t;
+    /* Call these functions to produce warnings only. */
+    t = format_recommended_version_list(options->RecommendedClientVersions, 1);
+    tor_free(t);
+    t = format_recommended_version_list(options->RecommendedServerVersions, 1);
+    tor_free(t);
+
     if (options->UseEntryGuards) {
       log_info(LD_CONFIG, "Authoritative directory servers can't set "
                "UseEntryGuards. Disabling.");
@@ -8399,4 +8408,3 @@ init_cookie_authentication(const char *fname, const char *header,
   tor_free(cookie_file_str);
   return retval;
 }
-

+ 0 - 1
src/or/connection_edge.c

@@ -4166,4 +4166,3 @@ connection_edge_free_all(void)
   smartlist_free(pending_entry_connections);
   pending_entry_connections = NULL;
 }
-

+ 9 - 5
src/or/connection_or.c

@@ -50,6 +50,7 @@
 #include "proto_cell.h"
 #include "reasons.h"
 #include "relay.h"
+#include "rendcommon.h"
 #include "rephist.h"
 #include "router.h"
 #include "routerkeys.h"
@@ -1923,10 +1924,13 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
                                                    conn->identity_digest);
     const int is_authority_fingerprint = router_digest_is_trusted_dir(
                                                    conn->identity_digest);
+    const int non_anonymous_mode = rend_non_anonymous_mode_enabled(options);
     int severity;
     const char *extra_log = "";
 
-    if (server_mode(options)) {
+    /* Relays, Single Onion Services, and Tor2web make direct connections using
+     * untrusted authentication keys. */
+    if (server_mode(options) || non_anonymous_mode) {
       severity = LOG_PROTOCOL_WARN;
     } else {
       if (using_hardcoded_fingerprints) {
@@ -1950,8 +1954,8 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
     }
 
     log_fn(severity, LD_HANDSHAKE,
-           "Tried connecting to router at %s:%d, but RSA identity key was not "
-           "as expected: wanted %s + %s but got %s + %s.%s",
+           "Tried connecting to router at %s:%d, but RSA + ed25519 identity "
+           "keys were not as expected: wanted %s + %s but got %s + %s.%s",
            conn->base_.address, conn->base_.port,
            expected_rsa, expected_ed, seen_rsa, seen_ed, extra_log);
 
@@ -1968,8 +1972,8 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
   }
 
   if (!expected_ed_key && ed_peer_id) {
-    log_info(LD_HANDSHAKE, "(we had no Ed25519 ID in mind when we made this "
-             "connection.");
+    log_info(LD_HANDSHAKE, "(We had no Ed25519 ID in mind when we made this "
+             "connection.)");
     connection_or_set_identity_digest(conn,
                                       (const char*)rsa_peer_id, ed_peer_id);
     changed_identity = 1;

+ 12 - 1
src/or/control.c

@@ -1896,6 +1896,8 @@ getinfo_helper_listeners(control_connection_t *control_conn,
 
   if (!strcmp(question, "net/listeners/or"))
     type = CONN_TYPE_OR_LISTENER;
+  else if (!strcmp(question, "net/listeners/extor"))
+    type = CONN_TYPE_EXT_OR_LISTENER;
   else if (!strcmp(question, "net/listeners/dir"))
     type = CONN_TYPE_DIR_LISTENER;
   else if (!strcmp(question, "net/listeners/socks"))
@@ -1904,6 +1906,8 @@ getinfo_helper_listeners(control_connection_t *control_conn,
     type = CONN_TYPE_AP_TRANS_LISTENER;
   else if (!strcmp(question, "net/listeners/natd"))
     type = CONN_TYPE_AP_NATD_LISTENER;
+  else if (!strcmp(question, "net/listeners/httptunnel"))
+    type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER;
   else if (!strcmp(question, "net/listeners/dns"))
     type = CONN_TYPE_AP_DNS_LISTENER;
   else if (!strcmp(question, "net/listeners/control"))
@@ -7610,6 +7614,14 @@ control_free_all(void)
     tor_event_free(flush_queued_events_event);
     flush_queued_events_event = NULL;
   }
+  bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
+  notice_bootstrap_percent = 0;
+  bootstrap_problems = 0;
+  authentication_cookie_is_set = 0;
+  global_event_mask = 0;
+  disable_log_messages = 0;
+  memset(last_sent_bootstrap_message, 0, sizeof(last_sent_bootstrap_message));
+  flush_queued_event_pending = 0;
 }
 
 #ifdef TOR_UNIT_TESTS
@@ -7620,4 +7632,3 @@ control_testing_set_global_event_mask(uint64_t mask)
   global_event_mask = mask;
 }
 #endif /* defined(TOR_UNIT_TESTS) */
-

+ 41 - 10
src/or/dirserv.c

@@ -74,7 +74,6 @@
 static int routers_with_measured_bw = 0;
 
 static void directory_remove_invalid(void);
-static char *format_versions_list(config_line_t *ln);
 struct authdir_config_t;
 static uint32_t
 dirserv_get_status_impl(const char *fp, const char *nickname,
@@ -1061,8 +1060,8 @@ list_server_status_v1(smartlist_t *routers, char **router_status_out,
  * allocate and return a new string containing the version numbers, in order,
  * separated by commas.  Used to generate Recommended(Client|Server)?Versions
  */
-static char *
-format_versions_list(config_line_t *ln)
+char *
+format_recommended_version_list(const config_line_t *ln, int warn)
 {
   smartlist_t *versions;
   char *result;
@@ -1071,6 +1070,37 @@ format_versions_list(config_line_t *ln)
     smartlist_split_string(versions, ln->value, ",",
                            SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
   }
+
+  /* Handle the case where a dirauth operator has accidentally made some
+   * versions space-separated instead of comma-separated. */
+  smartlist_t *more_versions = smartlist_new();
+  SMARTLIST_FOREACH_BEGIN(versions, char *, v) {
+    if (strchr(v, ' ')) {
+      if (warn)
+        log_warn(LD_DIRSERV, "Unexpected space in versions list member %s. "
+                 "(These are supposed to be comma-separated; I'll pretend you "
+                 "used commas instead.)", escaped(v));
+      SMARTLIST_DEL_CURRENT(versions, v);
+      smartlist_split_string(more_versions, v, NULL,
+                             SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+      tor_free(v);
+    }
+  } SMARTLIST_FOREACH_END(v);
+  smartlist_add_all(versions, more_versions);
+  smartlist_free(more_versions);
+
+  /* Check to make sure everything looks like a version. */
+  if (warn) {
+    SMARTLIST_FOREACH_BEGIN(versions, const char *, v) {
+      tor_version_t ver;
+      if (tor_version_parse(v, &ver) < 0) {
+        log_warn(LD_DIRSERV, "Recommended version %s does not look valid. "
+                 " (I'll include it anyway, since you told me to.)",
+                 escaped(v));
+      }
+    } SMARTLIST_FOREACH_END(v);
+  }
+
   sort_version_list(versions, 1);
   result = smartlist_join_strings(versions,",",0,NULL);
   SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
@@ -2911,8 +2941,10 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
   }
 
   if (options->VersioningAuthoritativeDir) {
-    client_versions = format_versions_list(options->RecommendedClientVersions);
-    server_versions = format_versions_list(options->RecommendedServerVersions);
+    client_versions =
+      format_recommended_version_list(options->RecommendedClientVersions, 0);
+    server_versions =
+      format_recommended_version_list(options->RecommendedServerVersions, 0);
   }
 
   contact = get_options()->ContactInfo;
@@ -3076,16 +3108,16 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
   /* These are hardwired, to avoid disaster. */
   v3_out->recommended_relay_protocols =
     tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
-               "Link=4 LinkAuth=1 Microdesc=1-2 Relay=2");
+               "Link=4 Microdesc=1-2 Relay=2");
   v3_out->recommended_client_protocols =
     tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
-               "Link=4 LinkAuth=1 Microdesc=1-2 Relay=2");
+               "Link=4 Microdesc=1-2 Relay=2");
   v3_out->required_client_protocols =
     tor_strdup("Cons=1-2 Desc=1-2 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
-               "Link=4 LinkAuth=1 Microdesc=1-2 Relay=2");
+               "Link=4 Microdesc=1-2 Relay=2");
   v3_out->required_relay_protocols =
     tor_strdup("Cons=1 Desc=1 DirCache=1 HSDir=1 HSIntro=3 HSRend=1 "
-               "Link=3-4 LinkAuth=1 Microdesc=1 Relay=1-2");
+               "Link=3-4 Microdesc=1 Relay=1-2");
 
   /* We are not allowed to vote to require anything we don't have. */
   tor_assert(protover_all_supported(v3_out->required_relay_protocols, NULL));
@@ -4062,4 +4094,3 @@ dirserv_free_all(void)
 
   dirserv_clear_measured_bw_cache();
 }
-

+ 1 - 2
src/or/dirserv.h

@@ -155,7 +155,7 @@ char *routerstatus_format_entry(
 void dirserv_free_all(void);
 void cached_dir_decref(cached_dir_t *d);
 cached_dir_t *new_cached_dir(char *s, time_t published);
-
+char *format_recommended_version_list(const config_line_t *line, int warn);
 int validate_recommended_package_line(const char *line);
 
 #ifdef DIRSERV_PRIVATE
@@ -208,4 +208,3 @@ void dirserv_spool_sort(dir_connection_t *conn);
 void dir_conn_clear_spool(dir_connection_t *conn);
 
 #endif /* !defined(TOR_DIRSERV_H) */
-

+ 8 - 1
src/or/dirvote.c

@@ -707,6 +707,14 @@ compute_consensus_versions_list(smartlist_t *lst, int n_versioning)
   int min = n_versioning / 2;
   smartlist_t *good = smartlist_new();
   char *result;
+  SMARTLIST_FOREACH_BEGIN(lst, const char *, v) {
+    if (strchr(v, ' ')) {
+      log_warn(LD_DIR, "At least one authority has voted for a version %s "
+               "that contains a space. This probably wasn't intentional, and "
+               "is likely to cause trouble. Please tell them to stop it.",
+               escaped(v));
+    }
+  } SMARTLIST_FOREACH_END(v);
   sort_version_list(lst, 0);
   get_frequent_members(good, lst, min);
   result = smartlist_join_strings(good, ",", 0, NULL);
@@ -4077,4 +4085,3 @@ vote_routerstatus_find_microdesc_hash(char *digest256_out,
   }
   return -1;
 }
-

+ 14 - 6
src/or/hs_circuit.c

@@ -559,10 +559,14 @@ retry_service_rendezvous_point(const origin_circuit_t *circ)
   return;
 }
 
-/* Add all possible link specifiers in node to lspecs.
- * legacy ID is mandatory thus MUST be present in node. If the primary address
- * is not IPv4, log a BUG() warning, and return an empty smartlist.
- * Includes ed25519 id and IPv6 link specifiers if present in the node. */
+/* Add all possible link specifiers in node to lspecs:
+ *  - legacy ID is mandatory thus MUST be present in node;
+ *  - include ed25519 link specifier if present in the node, and the node
+ *    supports ed25519 link authentication, even if its link versions are not
+ *    compatible with us;
+ *  - include IPv4 link specifier, if the primary address is not IPv4, log a
+ *    BUG() warning, and return an empty smartlist;
+ *  - include IPv6 link specifier if present in the node. */
 static void
 get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
 {
@@ -600,8 +604,12 @@ get_lspecs_from_node(const node_t *node, smartlist_t *lspecs)
   link_specifier_set_ls_len(ls, link_specifier_getlen_un_legacy_id(ls));
   smartlist_add(lspecs, ls);
 
-  /* ed25519 ID is only included if the node has it. */
-  if (!ed25519_public_key_is_zero(&node->ed25519_id)) {
+  /* ed25519 ID is only included if the node has it, and the node declares a
+     protocol version that supports ed25519 link authentication, even if that
+     link version is not compatible with us. (We are sending the ed25519 key
+     to another tor, which may support different link versions.) */
+  if (!ed25519_public_key_is_zero(&node->ed25519_id) &&
+      node_supports_ed25519_link_authentication(node, 0)) {
     ls = link_specifier_new();
     link_specifier_set_ls_type(ls, LS_ED25519_ID);
     memcpy(link_specifier_getarray_un_ed25519_id(ls), &node->ed25519_id,

+ 24 - 12
src/or/hs_service.c

@@ -376,17 +376,21 @@ service_intro_point_free_void(void *obj)
 }
 
 /* Return a newly allocated service intro point and fully initialized from the
- * given extend_info_t ei if non NULL. If is_legacy is true, we also generate
- * the legacy key. On error, NULL is returned.
+ * given extend_info_t ei if non NULL.
+ * If is_legacy is true, we also generate the legacy key.
+ * If supports_ed25519_link_handshake_any is true, we add the relay's ed25519
+ * key to the link specifiers.
  *
  * If ei is NULL, returns a hs_service_intro_point_t with an empty link
  * specifier list and no onion key. (This is used for testing.)
+ * On any other error, NULL is returned.
  *
  * ei must be an extend_info_t containing an IPv4 address. (We will add supoort
  * for IPv6 in a later release.) When calling extend_info_from_node(), pass
  * 0 in for_direct_connection to make sure ei always has an IPv4 address. */
 STATIC hs_service_intro_point_t *
-service_intro_point_new(const extend_info_t *ei, unsigned int is_legacy)
+service_intro_point_new(const extend_info_t *ei, unsigned int is_legacy,
+                        unsigned int supports_ed25519_link_handshake_any)
 {
   hs_desc_link_specifier_t *ls;
   hs_service_intro_point_t *ip;
@@ -453,10 +457,13 @@ service_intro_point_new(const extend_info_t *ei, unsigned int is_legacy)
   }
   smartlist_add(ip->base.link_specifiers, ls);
 
-  /* ed25519 identity key is optional for intro points */
-  ls = hs_desc_link_specifier_new(ei, LS_ED25519_ID);
-  if (ls) {
-    smartlist_add(ip->base.link_specifiers, ls);
+  /* ed25519 identity key is optional for intro points. If the node supports
+   * ed25519 link authentication, we include it. */
+  if (supports_ed25519_link_handshake_any) {
+    ls = hs_desc_link_specifier_new(ei, LS_ED25519_ID);
+    if (ls) {
+      smartlist_add(ip->base.link_specifiers, ls);
+    }
   }
 
   /* IPv6 is not supported in this release. */
@@ -847,6 +854,7 @@ move_hs_state(hs_service_t *src_service, hs_service_t *dst_service)
     replaycache_free(dst->replay_cache_rend_cookie);
   }
   dst->replay_cache_rend_cookie = src->replay_cache_rend_cookie;
+  dst->next_rotation_time = src->next_rotation_time;
 
   src->replay_cache_rend_cookie = NULL; /* steal pointer reference */
 }
@@ -975,9 +983,9 @@ load_service_keys(hs_service_t *service)
    * files to that directory so make sure it exists and has the right
    * permissions. We do this here because at this stage we know that Tor is
    * actually running and the service we have has been validated. */
-  if (BUG(hs_check_service_private_dir(get_options()->User,
-                                       config->directory_path,
-                                       config->dir_group_readable, 1) < 0)) {
+  if (hs_check_service_private_dir(get_options()->User,
+                                   config->directory_path,
+                                   config->dir_group_readable, 1) < 0) {
     goto end;
   }
 
@@ -1586,8 +1594,12 @@ pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes)
     tor_assert_nonfatal(!ed25519_public_key_is_zero(&info->ed_identity));
   }
 
-  /* Create our objects and populate them with the node information. */
-  ip = service_intro_point_new(info, !node_supports_ed25519_hs_intro(node));
+  /* Create our objects and populate them with the node information.
+   * We don't care if the intro's link auth is compatible with us, because
+   * we are sending the ed25519 key to a remote client via the descriptor. */
+  ip = service_intro_point_new(info, !node_supports_ed25519_hs_intro(node),
+                               node_supports_ed25519_link_authentication(node,
+                                                                         0));
   if (ip == NULL) {
     goto err;
   }

+ 3 - 2
src/or/hs_service.h

@@ -307,8 +307,9 @@ STATIC void remove_service(hs_service_ht *map, hs_service_t *service);
 STATIC int register_service(hs_service_ht *map, hs_service_t *service);
 /* Service introduction point functions. */
 STATIC hs_service_intro_point_t *service_intro_point_new(
-                                         const extend_info_t *ei,
-                                         unsigned int is_legacy);
+                            const extend_info_t *ei,
+                            unsigned int is_legacy,
+                            unsigned int supports_ed25519_link_handshake_any);
 STATIC void service_intro_point_free_(hs_service_intro_point_t *ip);
 #define service_intro_point_free(ip)                            \
   FREE_AND_NULL(hs_service_intro_point_t,             \

+ 13 - 4
src/or/main.c

@@ -3995,6 +3995,13 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
 #endif
   /* On heap corruption, just give up; don't try to play along. */
   HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+
+  /* SetProcessDEPPolicy is only supported on 32-bit Windows.
+   * (On 64-bit Windows it always fails, and some compilers don't like the
+   * PSETDEP cast.)
+   * 32-bit Windows defines _WIN32.
+   * 64-bit Windows defines _WIN32 and _WIN64. */
+#ifndef _WIN64
   /* Call SetProcessDEPPolicy to permanently enable DEP.
      The function will not resolve on earlier versions of Windows,
      and failure is not dangerous. */
@@ -4008,6 +4015,7 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
       setdeppolicy(3);
     }
   }
+#endif /* !defined(_WIN64) */
 #endif /* defined(_WIN32) */
 
   configure_backtrace_handler(get_version());
@@ -4035,10 +4043,10 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
 #endif /* defined(NT_SERVICE) */
   {
     int init_rv = tor_init(argc, argv);
-    if (init_rv < 0)
-      return -1;
-    else if (init_rv > 0)
-      return 0;
+    if (init_rv) {
+      tor_free_all(0);
+      return (init_rv < 0) ? -1 : 0;
+    }
   }
 
   if (get_options()->Sandbox && get_options()->command == CMD_RUN_TOR) {
@@ -4046,6 +4054,7 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
 
     if (sandbox_init(cfg)) {
       log_err(LD_BUG,"Failed to create syscall sandbox filter");
+      tor_free_all(0);
       return -1;
     }
 

+ 9 - 0
src/or/rendclient.c

@@ -238,6 +238,15 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
     dh_offset = v3_shift+7+DIGEST_LEN+2+klen+REND_COOKIE_LEN;
   } else {
     /* Version 0. */
+
+    /* Some compilers are smart enough to work out that nickname can be more
+     * than 19 characters, when it's a hexdigest. They warn that strncpy()
+     * will truncate hexdigests without NUL-terminating them. But we only put
+     * hexdigests in HSDir and general circuit exits. */
+    if (BUG(strlen(rendcirc->build_state->chosen_exit->nickname)
+            > MAX_NICKNAME_LEN)) {
+      goto perm_err;
+    }
     strncpy(tmp, rendcirc->build_state->chosen_exit->nickname,
             (MAX_NICKNAME_LEN+1)); /* nul pads */
     memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_data->rend_cookie,

+ 9 - 6
src/or/router.c

@@ -1950,10 +1950,11 @@ router_compare_to_my_exit_policy(const tor_addr_t *addr, uint16_t port)
 MOCK_IMPL(int,
 router_my_exit_policy_is_reject_star,(void))
 {
-  if (!router_get_my_routerinfo()) /* make sure routerinfo exists */
+  const routerinfo_t *me = router_get_my_routerinfo();
+  if (!me) /* make sure routerinfo exists */
     return -1;
 
-  return router_get_my_routerinfo()->policy_is_reject_star;
+  return me->policy_is_reject_star;
 }
 
 /** Return true iff I'm a server and <b>digest</b> is equal to
@@ -2522,10 +2523,11 @@ check_descriptor_bandwidth_changed(time_t now)
 {
   static time_t last_changed = 0;
   uint64_t prev, cur;
-  if (!router_get_my_routerinfo())
+  const routerinfo_t *my_ri = router_get_my_routerinfo();
+  if (!my_ri) /* make sure routerinfo exists */
     return;
 
-  prev = router_get_my_routerinfo()->bandwidthcapacity;
+  prev = my_ri->bandwidthcapacity;
   cur = we_are_hibernating() ? 0 : rep_hist_bandwidth_assess();
   if ((prev != cur && (!prev || !cur)) ||
       cur > prev*2 ||
@@ -2576,14 +2578,15 @@ check_descriptor_ipaddress_changed(time_t now)
   const or_options_t *options = get_options();
   const char *method = NULL;
   char *hostname = NULL;
+  const routerinfo_t *my_ri = router_get_my_routerinfo();
 
   (void) now;
 
-  if (router_get_my_routerinfo() == NULL)
+  if (my_ri == NULL) /* make sure routerinfo exists */
     return;
 
   /* XXXX ipv6 */
-  prev = router_get_my_routerinfo()->addr;
+  prev = my_ri->addr;
   if (resolve_my_address(LOG_INFO, options, &cur, &method, &hostname) < 0) {
     log_info(LD_CONFIG,"options->Address didn't resolve into an IP.");
     return;

+ 3 - 0
src/rust/protover/errors.rs

@@ -18,6 +18,7 @@ pub enum ProtoverError {
     ExceedsExpansionLimit,
     UnknownProtocol,
     ExceedsNameLimit,
+    InvalidProtocol,
 }
 
 /// Descriptive error messages for `ProtoverError` variants.
@@ -38,6 +39,8 @@ impl Display for ProtoverError {
                 => write!(f, "A protocol in the protover string we attempted to parse is unknown."),
             ProtoverError::ExceedsNameLimit
                 => write!(f, "An unrecognised protocol name was too long."),
+            ProtoverError::InvalidProtocol
+                => write!(f, "A protocol name includes invalid characters."),
         }
     }
 }

+ 67 - 28
src/rust/protover/protoset.rs

@@ -4,6 +4,8 @@
 
 //! Sets for lazily storing ordered, non-overlapping ranges of integers.
 
+use std::cmp;
+use std::iter;
 use std::slice;
 use std::str::FromStr;
 use std::u32;
@@ -174,7 +176,7 @@ impl ProtoSet {
             if low == u32::MAX || high == u32::MAX {
                 return Err(ProtoverError::ExceedsMax);
             }
-            if low < last_high {
+            if low <= last_high {
                 return Err(ProtoverError::Overlap);
             } else if low > high {
                 return Err(ProtoverError::LowGreaterThanHigh);
@@ -240,8 +242,8 @@ impl ProtoSet {
         false
     }
 
-    /// Retain only the `Version`s in this `ProtoSet` for which the predicate
-    /// `F` returns `true`.
+    /// Returns all the `Version`s in `self` which are not also in the `other`
+    /// `ProtoSet`.
     ///
     /// # Examples
     ///
@@ -250,24 +252,45 @@ impl ProtoSet {
     /// use protover::protoset::ProtoSet;
     ///
     /// # fn do_test() -> Result<bool, ProtoverError> {
-    /// let mut protoset: ProtoSet = "1,3-5,9".parse()?;
+    /// let protoset: ProtoSet = "1,3-6,10-12,15-16".parse()?;
+    /// let other: ProtoSet = "2,5-7,9-11,14-20".parse()?;
     ///
-    /// // Keep only versions less than or equal to 8:
-    /// protoset.retain(|x| x <= &8);
+    /// let subset: ProtoSet = protoset.and_not_in(&other);
     ///
-    /// assert_eq!(protoset.expand(), vec![1, 3, 4, 5]);
+    /// assert_eq!(subset.expand(), vec![1, 3, 4, 12]);
     /// #
     /// # Ok(true)
     /// # }
     /// # fn main() { do_test(); }  // wrap the test so we can use the ? operator
     /// ```
-    // XXX we could probably do something more efficient here. —isis
-    pub fn retain<F>(&mut self, f: F)
-        where F: FnMut(&Version) -> bool
-    {
-        let mut expanded: Vec<Version> = self.clone().expand();
-        expanded.retain(f);
-        *self = expanded.into();
+    pub fn and_not_in(&self, other: &Self) -> Self {
+        if self.is_empty() || other.is_empty() {
+            return self.clone();
+        }
+
+        let pairs = self.iter().flat_map(|&(lo, hi)| {
+            let the_end = (hi + 1, hi + 1); // special case to mark the end of the range.
+            let excluded_ranges = other
+                .iter()
+                .cloned() // have to be owned tuples, to match iter::once(the_end).
+                .skip_while(move|&(_, hi2)| hi2 < lo) // skip the non-overlapping ranges.
+                .take_while(move|&(lo2, _)| lo2 <= hi) // take all the overlapping ones.
+                .chain(iter::once(the_end));
+
+            let mut nextlo = lo;
+            excluded_ranges.filter_map(move |(excluded_lo, excluded_hi)| {
+                let pair = if nextlo < excluded_lo {
+                    Some((nextlo, excluded_lo - 1))
+                } else {
+                    None
+                };
+                nextlo = cmp::min(excluded_hi, u32::MAX - 1) + 1;
+                pair
+            })
+        });
+
+        let pairs = pairs.collect();
+        ProtoSet::is_ok(ProtoSet{ pairs }).expect("should be already sorted")
     }
 }
 
@@ -340,15 +363,13 @@ impl FromStr for ProtoSet {
     /// ```
     fn from_str(version_string: &str) -> Result<Self, Self::Err> {
         let mut pairs: Vec<(Version, Version)> = Vec::new();
-        let pieces: ::std::str::Split<char> = version_string.trim().split(',');
-
-        for piece in pieces {
-            let p: &str = piece.trim();
+        let pieces: ::std::str::Split<char> = version_string.split(',');
 
+        for p in pieces {
             if p.is_empty() {
                 continue;
             } else if p.contains('-') {
-                let mut pair = p.split('-');
+                let mut pair = p.splitn(2, '-');
 
                 let low  = pair.next().ok_or(ProtoverError::Unparseable)?;
                 let high = pair.next().ok_or(ProtoverError::Unparseable)?;
@@ -369,7 +390,7 @@ impl FromStr for ProtoSet {
                 pairs.push((v, v));
             }
         }
-        // If we were passed in an empty string, or a bunch of whitespace, or
+        // If we were passed in an empty string, or
         // simply a comma, or a pile of commas, then return an empty ProtoSet.
         if pairs.len() == 0 {
             return Ok(ProtoSet::default());
@@ -522,7 +543,6 @@ mod test {
         test_protoset_contains_versions!(&[1], "1");
         test_protoset_contains_versions!(&[1, 2], "1,2");
         test_protoset_contains_versions!(&[1, 2, 3], "1-3");
-        test_protoset_contains_versions!(&[0, 1], "0-1");
         test_protoset_contains_versions!(&[1, 2, 5], "1-2,5");
         test_protoset_contains_versions!(&[1, 3, 4, 5], "1,3-5");
         test_protoset_contains_versions!(&[42, 55, 56, 57, 58], "42,55-58");
@@ -538,6 +558,18 @@ mod test {
         assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("-1"));
     }
 
+    #[test]
+    fn test_versions_from_str_hyphens() {
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("--1"));
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("-1-2"));
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1--2"));
+    }
+
+    #[test]
+    fn test_versions_from_str_triple() {
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1-2-3"));
+    }
+
     #[test]
     fn test_versions_from_str_1exclam() {
         assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1,!"));
@@ -548,6 +580,13 @@ mod test {
         assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("%="));
     }
 
+    #[test]
+    fn test_versions_from_str_whitespace() {
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1,2\n"));
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1\r,2"));
+        assert_eq!(Err(ProtoverError::Unparseable), ProtoSet::from_str("1,\t2"));
+    }
+
     #[test]
     fn test_versions_from_str_overlap() {
         assert_eq!(Err(ProtoverError::Overlap), ProtoSet::from_str("1-3,2-4"));
@@ -570,9 +609,9 @@ mod test {
 
     #[test]
     fn test_protoset_contains() {
-        let protoset: ProtoSet = ProtoSet::from_slice(&[(0, 5), (7, 9), (13, 14)]).unwrap();
+        let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 5), (7, 9), (13, 14)]).unwrap();
 
-        for x in 0..6   { assert!(protoset.contains(&x), format!("should contain {}", x)); }
+        for x in 1..6   { assert!(protoset.contains(&x), format!("should contain {}", x)); }
         for x in 7..10  { assert!(protoset.contains(&x), format!("should contain {}", x)); }
         for x in 13..15 { assert!(protoset.contains(&x), format!("should contain {}", x)); }
 
@@ -582,10 +621,10 @@ mod test {
     }
 
     #[test]
-    fn test_protoset_contains_0_3() {
-        let protoset: ProtoSet = ProtoSet::from_slice(&[(0, 3)]).unwrap();
+    fn test_protoset_contains_1_3() {
+        let protoset: ProtoSet = ProtoSet::from_slice(&[(1, 3)]).unwrap();
 
-        for x in 0..4 { assert!(protoset.contains(&x), format!("should contain {}", x)); }
+        for x in 1..4 { assert!(protoset.contains(&x), format!("should contain {}", x)); }
     }
 
     macro_rules! assert_protoset_from_vec_contains_all {
@@ -605,8 +644,8 @@ mod test {
     }
 
     #[test]
-    fn test_protoset_from_vec_0_315() {
-        assert_protoset_from_vec_contains_all!(0, 1, 2, 3, 15);
+    fn test_protoset_from_vec_1_315() {
+        assert_protoset_from_vec_contains_all!(1, 2, 3, 15);
     }
 
     #[test]

+ 36 - 6
src/rust/protover/protover.rs

@@ -113,11 +113,17 @@ impl fmt::Display for UnknownProtocol {
     }
 }
 
+fn is_valid_proto(s: &str) -> bool {
+    s.chars().all(|c| c.is_ascii_alphanumeric() || c == '-')
+}
+
 impl FromStr for UnknownProtocol {
     type Err = ProtoverError;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        if s.len() <= MAX_PROTOCOL_NAME_LENGTH {
+        if !is_valid_proto(s) {
+            Err(ProtoverError::InvalidProtocol)
+        } else if s.len() <= MAX_PROTOCOL_NAME_LENGTH {
             Ok(UnknownProtocol(s.to_string()))
         } else {
             Err(ProtoverError::ExceedsNameLimit)
@@ -129,6 +135,9 @@ impl UnknownProtocol {
     /// Create an `UnknownProtocol`, ignoring whether or not it
     /// exceeds MAX_PROTOCOL_NAME_LENGTH.
     fn from_str_any_len(s: &str) -> Result<Self, ProtoverError> {
+        if !is_valid_proto(s) {
+            return Err(ProtoverError::InvalidProtocol);
+        }
         Ok(UnknownProtocol(s.to_string()))
     }
 }
@@ -356,7 +365,6 @@ impl UnvalidatedProtoEntry {
 
             let maybe_supported_versions: Option<&ProtoSet> = supported.get(&supported_protocol);
             let supported_versions: &ProtoSet;
-            let mut unsupported_versions: ProtoSet;
 
             // If the protocol wasn't in the map, then we don't know about it
             // and don't support any of its versions.  Add its versions to the
@@ -369,8 +377,7 @@ impl UnvalidatedProtoEntry {
             } else {
                 supported_versions = maybe_supported_versions.unwrap();
             }
-            unsupported_versions = versions.clone();
-            unsupported_versions.retain(|x| !supported_versions.contains(x));
+            let unsupported_versions = versions.and_not_in(supported_versions);
 
             if !unsupported_versions.is_empty() {
                 unsupported.insert(protocol.clone(), unsupported_versions);
@@ -777,6 +784,29 @@ mod test {
 
     use super::*;
 
+    macro_rules! parse_proto {
+        ($e:expr) => {{
+            let proto: Result<UnknownProtocol, _> = $e.parse();
+            let proto2 = UnknownProtocol::from_str_any_len($e);
+            assert_eq!(proto, proto2);
+            proto
+        }};
+    }
+
+    #[test]
+    fn test_protocol_from_str() {
+        assert!(parse_proto!("Cons").is_ok());
+        assert!(parse_proto!("123").is_ok());
+        assert!(parse_proto!("1-2-3").is_ok());
+
+        let err = Err(ProtoverError::InvalidProtocol);
+        assert_eq!(err, parse_proto!("a_b_c"));
+        assert_eq!(err, parse_proto!("a b"));
+        assert_eq!(err, parse_proto!("a,"));
+        assert_eq!(err, parse_proto!("b."));
+        assert_eq!(err, parse_proto!("é"));
+    }
+
     macro_rules! assert_protoentry_is_parseable {
         ($e:expr) => (
             let protoentry: Result<ProtoEntry, ProtoverError> = $e.parse();
@@ -867,10 +897,10 @@ mod test {
 
     #[test]
     fn test_protoentry_all_supported_unsupported_low_version() {
-        let protocols: UnvalidatedProtoEntry = "Cons=0-1".parse().unwrap();
+        let protocols: UnvalidatedProtoEntry = "HSIntro=2-3".parse().unwrap();
         let unsupported: Option<UnvalidatedProtoEntry> = protocols.all_supported();
         assert_eq!(true, unsupported.is_some());
-        assert_eq!("Cons=0", &unsupported.unwrap().to_string());
+        assert_eq!("HSIntro=2", &unsupported.unwrap().to_string());
     }
 
     #[test]

+ 7 - 7
src/rust/protover/tests/protover.rs

@@ -106,10 +106,10 @@ fn protocol_all_supported_with_unsupported_versions() {
 
 #[test]
 fn protocol_all_supported_with_unsupported_low_version() {
-    let protocols: UnvalidatedProtoEntry = "Cons=0-1".parse().unwrap();
+    let protocols: UnvalidatedProtoEntry = "HSIntro=2-3".parse().unwrap();
     let unsupported: Option<UnvalidatedProtoEntry> = protocols.all_supported();
     assert_eq!(true, unsupported.is_some());
-    assert_eq!("Cons=0", &unsupported.unwrap().to_string());
+    assert_eq!("HSIntro=2", &unsupported.unwrap().to_string());
 }
 
 #[test]
@@ -354,18 +354,18 @@ fn protover_all_supported_should_exclude_some_versions_and_entire_protocols() {
 
 #[test]
 fn protover_all_supported_should_not_dos_anyones_computer() {
-    let proto: UnvalidatedProtoEntry = "Sleen=0-2147483648".parse().unwrap();
+    let proto: UnvalidatedProtoEntry = "Link=1-2147483648".parse().unwrap();
     let result: String = proto.all_supported().unwrap().to_string();
 
-    assert_eq!(result, "Sleen=0-2147483648".to_string());
+    assert_eq!(result, "Link=6-2147483648".to_string());
 }
 
 #[test]
 fn protover_all_supported_should_not_dos_anyones_computer_max_versions() {
-    let proto: UnvalidatedProtoEntry = "Sleen=0-4294967294".parse().unwrap();
+    let proto: UnvalidatedProtoEntry = "Link=1-4294967294".parse().unwrap();
     let result: String = proto.all_supported().unwrap().to_string();
 
-    assert_eq!(result, "Sleen=0-4294967294".to_string());
+    assert_eq!(result, "Link=6-4294967294".to_string());
 }
 
 #[test]
@@ -388,7 +388,7 @@ fn protover_unvalidatedprotoentry_should_err_entirely_unparseable_things() {
 
 #[test]
 fn protover_all_supported_over_maximum_limit() {
-    let proto: Result<UnvalidatedProtoEntry, ProtoverError> = "Sleen=0-4294967295".parse();
+    let proto: Result<UnvalidatedProtoEntry, ProtoverError> = "Sleen=1-4294967295".parse();
 
     assert_eq!(Err(ProtoverError::ExceedsMax), proto);
 }

+ 0 - 2
src/rust/tor_rust/include.am

@@ -7,7 +7,6 @@ EXTRA_CARGO_OPTIONS=
 src/rust/target/release/@TOR_RUST_STATIC_NAME@: FORCE
 	( cd "$(abs_top_builddir)/src/rust" ; \
 		CARGO_TARGET_DIR="$(abs_top_builddir)/src/rust/target" \
-		CARGO_HOME="$(abs_top_builddir)/src/rust" \
 		$(CARGO) build --release $(EXTRA_CARGO_OPTIONS) \
 	        $(CARGO_ONLINE) \
                 --manifest-path "$(abs_top_srcdir)/src/rust/tor_rust/Cargo.toml" )
@@ -15,7 +14,6 @@ src/rust/target/release/@TOR_RUST_STATIC_NAME@: FORCE
 distclean-rust:
 	( cd "$(abs_top_builddir)/src/rust" ; \
 		CARGO_TARGET_DIR="$(abs_top_builddir)/src/rust/target" \
-		CARGO_HOME="$(abs_top_builddir)/src/rust" \
 		$(CARGO) clean $(EXTRA_CARGO_OPTIONS) \
 	        $(CARGO_ONLINE) \
                 --manifest-path "$(abs_top_srcdir)/src/rust/tor_rust/Cargo.toml" )

+ 1 - 1
src/test/include.am

@@ -48,7 +48,7 @@ TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v2-min hs-v3-min \
 TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v23-ipv6-md \
 	single-onion-ipv6-md
 # only run if we can find a stable (or simply another) version of tor
-TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v23
+TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v2
 
 ### This is a lovely feature, but it requires automake >= 1.12, and Tor
 ###  doesn't require that yet.

+ 2 - 8
src/test/test.c

@@ -22,6 +22,8 @@
 #include <dirent.h>
 #endif /* defined(_WIN32) */
 
+#include <math.h>
+
 /* These macros pull in declarations for some functions and structures that
  * are typically file-private. */
 #define GEOIP_PRIVATE
@@ -31,14 +33,6 @@
 #define MAIN_PRIVATE
 #define STATEFILE_PRIVATE
 
-/*
- * Linux doesn't provide lround in math.h by default, but mac os does...
- * It's best just to leave math.h out of the picture entirely.
- */
-//#include <math.h>
-long int lround(double x);
-double fabs(double x);
-
 #include "or.h"
 #include "backtrace.h"
 #include "buffers.h"

+ 2 - 0
src/test/test_bt.sh

@@ -3,6 +3,8 @@
 
 exitcode=0
 
+ulimit -c 0
+
 export ASAN_OPTIONS="handle_segv=0:allow_user_segv_handler=1"
 "${builddir:-.}/src/test/test-bt-cl" backtraces || exit $?
 "${builddir:-.}/src/test/test-bt-cl" assert 2>&1 | "${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/bt_test.py" || exitcode="$?"

+ 18 - 13
src/test/test_config.c

@@ -5540,6 +5540,12 @@ test_config_include_opened_file_list(void *data)
 
   config_line_t *result = NULL;
   smartlist_t *opened_files = smartlist_new();
+  char *torrcd = NULL;
+  char *subfolder = NULL;
+  char *path = NULL;
+  char *empty = NULL;
+  char *file = NULL;
+  char *dot = NULL;
   char *dir = tor_strdup(get_fname("test_include_opened_file_list"));
   tt_ptr_op(dir, OP_NE, NULL);
 
@@ -5549,8 +5555,7 @@ test_config_include_opened_file_list(void *data)
   tt_int_op(mkdir(dir, 0700), OP_EQ, 0);
 #endif
 
-  char torrcd[PATH_MAX+1];
-  tor_snprintf(torrcd, sizeof(torrcd), "%s"PATH_SEPARATOR"%s", dir, "torrc.d");
+  tor_asprintf(&torrcd, "%s"PATH_SEPARATOR"%s", dir, "torrc.d");
 
 #ifdef _WIN32
   tt_int_op(mkdir(torrcd), OP_EQ, 0);
@@ -5558,9 +5563,7 @@ test_config_include_opened_file_list(void *data)
   tt_int_op(mkdir(torrcd, 0700), OP_EQ, 0);
 #endif
 
-  char subfolder[PATH_MAX+1];
-  tor_snprintf(subfolder, sizeof(subfolder), "%s"PATH_SEPARATOR"%s", torrcd,
-               "subfolder");
+  tor_asprintf(&subfolder, "%s"PATH_SEPARATOR"%s", torrcd, "subfolder");
 
 #ifdef _WIN32
   tt_int_op(mkdir(subfolder), OP_EQ, 0);
@@ -5568,21 +5571,17 @@ test_config_include_opened_file_list(void *data)
   tt_int_op(mkdir(subfolder, 0700), OP_EQ, 0);
 #endif
 
-  char path[PATH_MAX+1];
-  tor_snprintf(path, sizeof(path), "%s"PATH_SEPARATOR"%s", subfolder,
+  tor_asprintf(&path, "%s"PATH_SEPARATOR"%s", subfolder,
                "01_file_in_subfolder");
   tt_int_op(write_str_to_file(path, "Test 1\n", 0), OP_EQ, 0);
 
-  char empty[PATH_MAX+1];
-  tor_snprintf(empty, sizeof(empty), "%s"PATH_SEPARATOR"%s", torrcd, "empty");
+  tor_asprintf(&empty, "%s"PATH_SEPARATOR"%s", torrcd, "empty");
   tt_int_op(write_str_to_file(empty, "", 0), OP_EQ, 0);
 
-  char file[PATH_MAX+1];
-  tor_snprintf(file, sizeof(file), "%s"PATH_SEPARATOR"%s", torrcd, "file");
+  tor_asprintf(&file, "%s"PATH_SEPARATOR"%s", torrcd, "file");
   tt_int_op(write_str_to_file(file, "Test 2\n", 0), OP_EQ, 0);
 
-  char dot[PATH_MAX+1];
-  tor_snprintf(dot, sizeof(dot), "%s"PATH_SEPARATOR"%s", torrcd, ".dot");
+  tor_asprintf(&dot, "%s"PATH_SEPARATOR"%s", torrcd, ".dot");
   tt_int_op(write_str_to_file(dot, "Test 3\n", 0), OP_EQ, 0);
 
   char torrc_contents[1000];
@@ -5609,6 +5608,12 @@ test_config_include_opened_file_list(void *data)
   SMARTLIST_FOREACH(opened_files, char *, f, tor_free(f));
   smartlist_free(opened_files);
   config_free_lines(result);
+  tor_free(torrcd);
+  tor_free(subfolder);
+  tor_free(path);
+  tor_free(empty);
+  tor_free(file);
+  tor_free(dot);
   tor_free(dir);
 }
 

+ 52 - 1
src/test/test_dir.c

@@ -5853,6 +5853,57 @@ test_dir_networkstatus_consensus_has_ipv6(void *arg)
   UNMOCK(networkstatus_get_latest_consensus_by_flavor);
 }
 
+static void
+test_dir_format_versions_list(void *arg)
+{
+  (void)arg;
+  char *s = NULL;
+  config_line_t *lines = NULL;
+
+  setup_capture_of_logs(LOG_WARN);
+  s = format_recommended_version_list(lines, 1);
+  tt_str_op(s, OP_EQ, "");
+
+  tor_free(s);
+  config_line_append(&lines, "ignored", "0.3.4.1, 0.2.9.111-alpha, 4.4.4-rc");
+  s = format_recommended_version_list(lines, 1);
+  tt_str_op(s, OP_EQ,  "0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
+
+  tor_free(s);
+  config_line_append(&lines, "ignored", "0.1.2.3,0.2.9.10   ");
+  s = format_recommended_version_list(lines, 1);
+  tt_str_op(s, OP_EQ,  "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,4.4.4-rc");
+
+  /* There should be no warnings so far. */
+  expect_no_log_entry();
+
+  /* Now try a line with a space in it. */
+  tor_free(s);
+  config_line_append(&lines, "ignored", "1.3.3.8 1.3.3.7");
+  s = format_recommended_version_list(lines, 1);
+  tt_str_op(s, OP_EQ,  "0.1.2.3,0.2.9.10,0.2.9.111-alpha,0.3.4.1,"
+            "1.3.3.7,1.3.3.8,4.4.4-rc");
+
+  expect_single_log_msg_containing(
+          "Unexpected space in versions list member \"1.3.3.8 1.3.3.7\"." );
+
+  /* Start over, with a line containing a bogus version */
+  config_free_lines(lines);
+  lines = NULL;
+  tor_free(s);
+  mock_clean_saved_logs();
+  config_line_append(&lines, "ignored", "0.1.2.3, alpha-complex, 0.1.1.8-rc");
+  s = format_recommended_version_list(lines,1);
+  tt_str_op(s, OP_EQ, "0.1.1.8-rc,0.1.2.3,alpha-complex");
+  expect_single_log_msg_containing(
+        "Recommended version \"alpha-complex\" does not look valid.");
+
+ done:
+  tor_free(s);
+  config_free_lines(lines);
+  teardown_capture_of_logs();
+}
+
 #define DIR_LEGACY(name)                             \
   { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
 
@@ -5921,6 +5972,6 @@ struct testcase_t dir_tests[] = {
   DIR(networkstatus_compute_bw_weights_v10, 0),
   DIR(platform_str, 0),
   DIR(networkstatus_consensus_has_ipv6, TT_FORK),
+  DIR(format_versions_list, TT_FORK),
   END_OF_TESTCASES
 };
-

+ 6 - 0
src/test/test_entrynodes.c

@@ -1125,6 +1125,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
   for (i = 0; i < 5; ++i) {
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, i);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     n->is_possible_guard = 0;
   }
 
@@ -1163,6 +1164,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
   {
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, 0);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     n->is_possible_guard = 1;
   }
   {
@@ -1170,6 +1172,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
      */
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, 5);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     smartlist_remove(big_fake_net_nodes, n);
     tor_free(n->rs);
     tor_free(n->md);
@@ -1228,6 +1231,7 @@ test_entry_guard_update_from_consensus_repair(void *arg)
     /* these will get a date. */
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, i);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     n->is_possible_guard = 0;
     g->currently_listed = 0;
   }
@@ -1293,6 +1297,7 @@ test_entry_guard_update_from_consensus_remove(void *arg)
   {
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, 0);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     n->is_possible_guard = 0;
     g->currently_listed = 0;
     g->unlisted_since_date = one_day_ago;
@@ -1302,6 +1307,7 @@ test_entry_guard_update_from_consensus_remove(void *arg)
   {
     entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, 1);
     node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
+    tt_assert(n);
     n->is_possible_guard = 0;
     g->currently_listed = 0;
     g->unlisted_since_date = one_year_ago;

+ 2 - 2
src/test/test_hs_cell.c

@@ -38,7 +38,7 @@ test_gen_establish_intro_cell(void *arg)
      attempt to parse it. */
   {
     /* We only need the auth key pair here. */
-    hs_service_intro_point_t *ip = service_intro_point_new(NULL, 0);
+    hs_service_intro_point_t *ip = service_intro_point_new(NULL, 0, 0);
     /* Auth key pair is generated in the constructor so we are all set for
      * using this IP object. */
     ret = hs_cell_build_establish_intro(circ_nonce, ip, buf);
@@ -106,7 +106,7 @@ test_gen_establish_intro_cell_bad(void *arg)
      ed25519_sign_prefixed() function and make it fail. */
   cell = trn_cell_establish_intro_new();
   tt_assert(cell);
-  ip = service_intro_point_new(NULL, 0);
+  ip = service_intro_point_new(NULL, 0, 0);
   cell_len = hs_cell_build_establish_intro(circ_nonce, ip, NULL);
   service_intro_point_free(ip);
   expect_log_msg_containing("Unable to make signature for "

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff