commit 7589995111b452cf7e92f5e9b5d94df244cbdbb9 Merge: 3c97ab3c2 046183714 Author: Nick Mathewson nickm@torproject.org Date: Tue Sep 17 09:16:52 2019 -0400
Merge branch 'maint-0.3.5' into bug31107_035
.appveyor.yml | 119 + .gitignore | 139 +- .gitlab-ci.yml | 45 + .gitmodules | 3 + .travis.yml | 78 +- CODE_OF_CONDUCT | 7 + CONTRIBUTING | 39 + ChangeLog | 9099 +++++++++++++++++++- Doxyfile.in | 1184 ++- INSTALL | 34 - LICENSE | 32 +- Makefile.am | 276 +- README | 3 + ReleaseNotes | 7319 +++++++++++++++- acinclude.m4 | 25 +- autogen.sh | 4 +- changes/29241_diagnostic | 4 + changes/bug13221 | 5 + changes/bug21394.2 | 7 - changes/bug22619 | 3 + changes/bug23512 | 6 - changes/bug23681 | 5 - changes/bug23790 | 6 - changes/bug24104 | 4 - changes/bug24661 | 3 + changes/bug24903 | 5 - changes/bug25113 | 5 - changes/bug25116 | 4 - changes/bug25733 | 4 - changes/bug27073 | 4 - changes/bug27197 | 3 + changes/bug27199 | 3 + changes/bug27316 | 3 - changes/bug27658 | 6 - changes/bug27709 | 4 - changes/bug27740 | 4 + changes/bug27741 | 5 + changes/bug27750 | 6 + changes/bug27800 | 4 + changes/bug27804 | 3 + changes/bug27841 | 7 + changes/bug27963_timeradd | 4 + changes/bug27968 | 3 + changes/bug28115 | 3 + changes/bug28127 | 7 + changes/bug28183 | 4 + changes/bug28298 | 4 + changes/bug28303 | 3 + changes/bug28348_034 | 5 + changes/bug28399 | 4 + changes/bug28419 | 3 + changes/bug28435 | 3 + changes/bug28441 | 4 + changes/bug28454 | 4 + changes/bug28485 | 3 + changes/bug28524 | 4 + changes/bug28554 | 3 + changes/bug28562 | 5 + changes/bug28568 | 4 + changes/bug28569 | 3 + changes/bug28612 | 4 + changes/bug28619 | 6 + changes/bug28656 | 3 + changes/bug28698 | 3 + changes/bug28895 | 5 + changes/bug28920 | 6 + changes/bug28938 | 4 + changes/bug28974 | 3 + changes/bug28979 | 4 + changes/bug28981 | 5 + changes/bug28995 | 5 + changes/bug29017 | 4 + changes/bug29034 | 5 + changes/bug29040 | 4 + changes/bug29042 | 5 + changes/bug29135 | 5 + changes/bug29144 | 5 + changes/bug29161 | 3 + changes/bug29175_035 | 4 + changes/bug29241 | 6 + changes/bug29244 | 4 + changes/bug29530_035 | 5 + changes/bug29601 | 6 + changes/bug29670 | 4 + changes/bug29875 | 11 + changes/bug29922 | 4 + changes/bug30011 | 4 + changes/bug30040 | 9 + changes/bug30148 | 4 + changes/bug30189 | 4 + changes/bug30190 | 3 + changes/bug30316 | 4 + changes/bug30452 | 3 + changes/bug30475 | 4 + changes/bug30713 | 5 + changes/bug30744 | 3 + changes/bug30894 | 4 + changes/bug31003 | 4 + changes/bug31463 | 3 + changes/cid1444119 | 3 + changes/geoip-2018-09-06 | 4 - changes/geoip-2018-10-09 | 4 - changes/rust_asan | 8 + changes/ticket19566 | 6 + changes/ticket27252 | 6 - changes/ticket27471 | 5 + changes/ticket27738 | 4 - changes/ticket27751 | 2 + changes/ticket27838 | 4 + changes/ticket27913 | 3 + changes/ticket27995 | 4 + changes/ticket28026 | 3 + changes/ticket28113 | 5 + changes/ticket28128 | 4 + changes/ticket28229_diag | 3 + changes/ticket28275 | 4 + changes/ticket28318 | 3 + changes/ticket28459 | 4 + changes/ticket28574 | 4 + changes/ticket28668 | 3 + changes/ticket28669 | 6 + changes/ticket28838 | 8 + changes/ticket28851 | 4 + changes/ticket28879 | 5 + changes/ticket28881 | 4 + changes/ticket28883 | 4 + changes/ticket28912 | 6 + changes/ticket28924 | 4 + changes/ticket28973 | 6 + changes/ticket29026 | 4 + changes/ticket29160 | 4 + changes/ticket29168 | 5 + changes/ticket29435 | 3 + changes/ticket29617 | 4 + changes/ticket29702 | 4 + changes/ticket29806 | 7 + changes/ticket29962 | 3 + changes/ticket30117 | 4 + changes/ticket30234 | 2 + changes/ticket30454 | 10 + changes/ticket30591 | 3 + changes/ticket30694 | 3 + changes/ticket30871 | 6 + changes/ticket31554 | 4 + config.rust.in | 24 + configure.ac | 967 ++- contrib/dist/tor.service.in | 2 +- contrib/include.am | 1 - contrib/operator-tools/linux-tor-prio.sh | 2 +- contrib/win32build/package_nsis-mingw.sh | 95 - contrib/win32build/tor-mingw.nsi.in | 2 +- doc/HACKING/CodeStructure.md | 129 + doc/HACKING/CodingStandards.md | 237 +- doc/HACKING/CodingStandardsRust.md | 523 ++ doc/HACKING/Fuzzing.md | 123 + doc/HACKING/GettingStarted.md | 5 +- doc/HACKING/GettingStartedRust.md | 183 + doc/HACKING/HelpfulTools.md | 132 +- doc/HACKING/HowToReview.md | 3 + doc/HACKING/Module.md | 111 + doc/HACKING/ReleasingTor.md | 135 +- doc/HACKING/Tracing.md | 91 + doc/HACKING/WritingTests.md | 12 +- doc/HACKING/android/Simpleperf.md | 98 + doc/include.am | 28 +- doc/tor-print-ed-signing-cert.1.txt | 32 + doc/tor-resolve.1.txt | 2 +- doc/tor.1.txt | 1706 ++-- doc/torify.1.txt | 20 +- doc/torrc_format.txt | 15 +- m4/ax_check_sign.m4 | 4 +- m4/pc_from_ucontext.m4 | 20 +- scripts/README | 6 + scripts/coccinelle/ceil_div.cocci | 6 + scripts/coccinelle/test-operator-cleanup | 11 + scripts/coccinelle/test_assert_int.cocci | 49 + scripts/coccinelle/test_assert_null.cocci | 11 + scripts/coccinelle/test_assert_zero.cocci | 5 + scripts/codegen/fuzzing_include_am.py | 154 + scripts/codegen/gen_server_ciphers.py | 64 +- scripts/codegen/get_mozilla_ciphers.py | 15 +- scripts/codegen/makedesc.py | 2 +- scripts/codegen/run_trunnel.sh | 10 +- scripts/maint/analyze_callgraph.py | 259 - scripts/maint/annotate_ifdef_directives | 74 + scripts/maint/checkIncludes.py | 115 + scripts/maint/checkOptionDocs.pl.in | 2 +- scripts/maint/checkSpace.pl | 148 +- scripts/maint/display_callgraph.py | 41 - scripts/maint/fallback.blacklist | 229 - scripts/maint/fallback.whitelist | 525 +- scripts/maint/format_changelog.py | 4 +- scripts/maint/generateFallbackDirLine.py | 38 + scripts/maint/generate_callgraph.sh | 14 - scripts/maint/lintChanges.py | 72 +- scripts/maint/lookupFallbackDirContact.py | 28 + scripts/maint/rectify_include_paths.py | 60 + scripts/maint/redox.py | 4 +- scripts/maint/run_calltool.sh | 29 + scripts/maint/sortChanges.py | 2 +- scripts/maint/updateCopyright.pl | 4 +- scripts/maint/updateFallbackDirs.py | 815 +- scripts/maint/updateRustDependencies.sh | 45 + scripts/test/appveyor-irc-notify.py | 219 + scripts/test/chutney-git-bisect.sh | 62 + scripts/test/cov-diff | 14 +- scripts/test/cov-exclude | 6 + scripts/test/coverage | 8 +- scripts/test/scan-build.sh | 61 +- src/{or => app/config}/auth_dirs.inc | 0 src/app/config/config.c | 8521 ++++++++++++++++++ src/app/config/config.h | 300 + src/app/config/confparse.c | 1207 +++ src/app/config/confparse.h | 233 + src/{or => app/config}/fallback_dirs.inc | 0 src/app/config/or_options_st.h | 1077 +++ src/app/config/or_state_st.h | 92 + src/app/config/statefile.c | 728 ++ src/app/config/statefile.h | 36 + src/app/include.am | 35 + src/app/main/main.c | 1519 ++++ src/app/main/main.h | 31 + src/app/main/ntmain.c | 785 ++ src/app/main/ntmain.h | 28 + src/app/main/tor_main.c | 42 + src/common/Makefile.nmake | 28 - src/common/address.c | 2162 ----- src/common/address.h | 379 - src/common/address_set.c | 129 - src/common/address_set.h | 35 - src/common/aes.c | 404 - src/common/aes.h | 27 - src/common/backtrace.c | 248 - src/common/backtrace.h | 21 - src/common/ciphers.inc | 140 - src/common/compat.c | 3555 -------- src/common/compat.h | 747 -- src/common/compat_libevent.c | 285 - src/common/compat_libevent.h | 75 - src/common/compat_openssl.h | 47 - src/common/compat_pthreads.c | 349 - src/common/compat_threads.c | 332 - src/common/compat_threads.h | 151 - src/common/compat_time.c | 656 -- src/common/compat_time.h | 162 - src/common/compat_winthreads.c | 250 - src/common/container.c | 1517 ---- src/common/container.h | 725 -- src/common/crypto.c | 3432 -------- src/common/crypto.h | 340 - src/common/crypto_curve25519.c | 354 - src/common/crypto_curve25519.h | 87 - src/common/crypto_ed25519.c | 736 -- src/common/crypto_ed25519.h | 131 - src/common/crypto_format.c | 277 - src/common/crypto_format.h | 46 - src/common/crypto_pwbox.c | 212 - src/common/crypto_pwbox.h | 20 - src/common/crypto_s2k.c | 468 - src/common/crypto_s2k.h | 73 - src/common/di_ops.c | 274 - src/common/di_ops.h | 50 - src/common/handles.h | 153 - src/common/include.am | 175 - src/common/log.c | 1395 --- src/common/memarea.c | 306 - src/common/memarea.h | 24 - src/common/procmon.c | 343 - src/common/procmon.h | 33 - src/common/pubsub.c | 129 - src/common/pubsub.h | 179 - src/common/sandbox.c | 2016 ----- src/common/sandbox.h | 182 - src/common/testsupport.h | 90 - src/common/timers.c | 293 - src/common/timers.h | 24 - src/common/torgzip.c | 586 -- src/common/torgzip.h | 72 - src/common/torint.h | 367 - src/common/torlog.h | 251 - src/common/tortls.c | 2579 ------ src/common/tortls.h | 265 - src/common/util.c | 5774 ------------- src/common/util.h | 561 -- src/common/util_bug.c | 115 - src/common/util_bug.h | 204 - src/common/util_format.c | 562 -- src/common/util_format.h | 34 - src/common/util_process.c | 158 - src/common/util_process.h | 26 - src/common/workqueue.c | 538 -- src/common/workqueue.h | 49 - src/config/torrc.minimal.in-staging | 18 +- src/config/torrc.sample.in | 49 +- src/core/crypto/hs_ntor.c | 620 ++ src/core/crypto/hs_ntor.h | 69 + src/core/crypto/onion_crypto.c | 311 + src/core/crypto/onion_crypto.h | 47 + src/core/crypto/onion_fast.c | 144 + src/core/crypto/onion_fast.h | 41 + src/core/crypto/onion_ntor.c | 341 + src/core/crypto/onion_ntor.h | 65 + src/core/crypto/onion_tap.c | 246 + src/core/crypto/onion_tap.h | 40 + src/core/crypto/relay_crypto.c | 332 + src/core/crypto/relay_crypto.h | 31 + src/core/include.am | 404 + src/core/mainloop/connection.c | 5504 ++++++++++++ src/core/mainloop/connection.h | 353 + src/core/mainloop/cpuworker.c | 600 ++ src/core/mainloop/cpuworker.h | 37 + src/core/mainloop/mainloop.c | 2942 +++++++ src/core/mainloop/mainloop.h | 114 + src/core/mainloop/netstatus.c | 28 + src/core/mainloop/netstatus.h | 13 + src/core/mainloop/periodic.c | 174 + src/core/mainloop/periodic.h | 88 + src/core/or/addr_policy_st.h | 46 + src/core/or/address_set.c | 71 + src/core/or/address_set.h | 31 + src/core/or/cell_queue_st.h | 29 + src/core/or/cell_st.h | 20 + src/core/or/channel.c | 3476 ++++++++ src/core/or/channel.h | 780 ++ src/core/or/channelpadding.c | 794 ++ src/core/or/channelpadding.h | 43 + src/core/or/channeltls.c | 2485 ++++++ src/core/or/channeltls.h | 79 + src/core/or/circuit_st.h | 182 + src/core/or/circuitbuild.c | 3012 +++++++ src/core/or/circuitbuild.h | 102 + src/core/or/circuitlist.c | 2853 ++++++ src/core/or/circuitlist.h | 250 + src/core/or/circuitmux.c | 1364 +++ src/core/or/circuitmux.h | 162 + src/core/or/circuitmux_ewma.c | 829 ++ src/core/or/circuitmux_ewma.h | 30 + src/core/or/circuitstats.c | 1951 +++++ src/core/or/circuitstats.h | 213 + src/core/or/circuituse.c | 3142 +++++++ src/core/or/circuituse.h | 93 + src/core/or/command.c | 703 ++ src/core/or/command.h | 31 + src/core/or/connection_edge.c | 4534 ++++++++++ src/core/or/connection_edge.h | 279 + src/core/or/connection_or.c | 3026 +++++++ src/core/or/connection_or.h | 166 + src/core/or/connection_st.h | 149 + src/core/or/cpath_build_state_st.h | 38 + src/core/or/crypt_path_reference_st.h | 23 + src/core/or/crypt_path_st.h | 70 + src/core/or/destroy_cell_queue_st.h | 27 + src/core/or/dos.c | 801 ++ src/core/or/dos.h | 140 + src/core/or/edge_connection_st.h | 77 + src/core/or/entry_connection_st.h | 100 + src/core/or/entry_port_cfg_st.h | 54 + src/core/or/extend_info_st.h | 30 + src/core/or/half_edge_st.h | 34 + src/core/or/listener_connection_st.h | 25 + src/core/or/onion.c | 720 ++ src/core/or/onion.h | 90 + src/core/or/or.h | 1094 +++ src/core/or/or_circuit_st.h | 80 + src/core/or/or_connection_st.h | 92 + src/core/or/or_handshake_certs_st.h | 40 + src/core/or/or_handshake_state_st.h | 78 + src/core/or/origin_circuit_st.h | 294 + src/core/or/policies.c | 3145 +++++++ src/core/or/policies.h | 187 + src/core/or/port_cfg_st.h | 35 + src/core/or/protover.c | 942 ++ src/core/or/protover.h | 97 + src/core/or/protover_rust.c | 34 + src/core/or/reasons.c | 497 ++ src/core/or/reasons.h | 34 + src/core/or/relay.c | 3169 +++++++ src/core/or/relay.h | 124 + src/core/or/relay_crypto_st.h | 31 + src/core/or/scheduler.c | 768 ++ src/core/or/scheduler.h | 218 + src/core/or/scheduler_kist.c | 844 ++ src/core/or/scheduler_vanilla.c | 175 + src/core/or/server_port_cfg_st.h | 20 + src/core/or/socks_request_st.h | 77 + src/core/or/status.c | 252 + src/core/or/status.h | 18 + src/core/or/tor_version_st.h | 32 + src/core/or/var_cell_st.h | 23 + src/core/or/versions.c | 422 + src/core/or/versions.h | 44 + src/core/proto/proto_cell.c | 86 + src/core/proto/proto_cell.h | 17 + src/core/proto/proto_control0.c | 26 + src/core/proto/proto_control0.h | 14 + src/core/proto/proto_ext_or.c | 40 + src/core/proto/proto_ext_or.h | 22 + src/core/proto/proto_http.c | 171 + src/core/proto/proto_http.h | 24 + src/core/proto/proto_socks.c | 1133 +++ src/core/proto/proto_socks.h | 21 + src/ext/OpenBSD_malloc_Linux.c | 2 +- src/ext/byteorder.h | 71 + src/ext/csiphash.c | 50 +- src/ext/curve25519_donna/curve25519-donna-c64.c | 2 +- src/ext/curve25519_donna/curve25519-donna.c | 2 +- src/ext/ed25519/donna/ed25519-donna-impl-base.h | 12 +- .../donna/ed25519-donna-portable-identify.h | 2 +- src/ext/ed25519/donna/ed25519-hash-custom.h | 31 + src/ext/ed25519/donna/ed25519-randombytes-custom.h | 2 +- src/ext/ed25519/donna/ed25519_donna_tor.h | 7 +- src/ext/ed25519/donna/ed25519_tor.c | 43 +- src/ext/ed25519/ref10/blinding.c | 51 +- src/ext/ed25519/ref10/crypto_hash_sha512.h | 30 +- src/ext/ed25519/ref10/crypto_int32.h | 2 +- src/ext/ed25519/ref10/crypto_int64.h | 2 +- src/ext/ed25519/ref10/crypto_uint32.h | 2 +- src/ext/ed25519/ref10/crypto_uint64.h | 2 +- src/ext/ed25519/ref10/crypto_verify_32.h | 3 +- src/ext/ed25519/ref10/ed25519_ref10.h | 6 +- src/ext/ed25519/ref10/keypair.c | 4 +- src/ext/ed25519/ref10/randombytes.h | 2 +- src/ext/getdelim.c | 79 + src/ext/ht.h | 4 +- src/ext/include.am | 4 +- src/ext/keccak-tiny/keccak-tiny-unrolled.c | 21 +- src/ext/keccak-tiny/keccak-tiny.h | 2 +- src/ext/mulodi/mulodi4.c | 2 +- src/ext/rust | 1 + src/ext/siphash.h | 1 + src/ext/timeouts/timeout-bitops.c | 3 +- src/ext/timeouts/timeout.c | 4 +- src/ext/tinytest.c | 13 +- src/ext/trunnel/trunnel-impl.h | 5 +- src/ext/trunnel/trunnel.c | 10 +- src/ext/trunnel/trunnel.h | 4 +- src/feature/api/tor_api.c | 167 + src/feature/api/tor_api.h | 129 + src/feature/api/tor_api_internal.h | 29 + src/feature/client/addressmap.c | 1156 +++ src/feature/client/addressmap.h | 65 + src/feature/client/bridges.c | 1029 +++ src/feature/client/bridges.h | 80 + src/feature/client/circpathbias.c | 1641 ++++ src/feature/client/circpathbias.h | 29 + src/feature/client/dnsserv.c | 415 + src/feature/client/dnsserv.h | 27 + src/feature/client/entrynodes.c | 3824 ++++++++ src/feature/client/entrynodes.h | 639 ++ src/feature/client/transports.c | 1738 ++++ src/feature/client/transports.h | 147 + src/feature/control/control.c | 7902 +++++++++++++++++ src/feature/control/control.h | 417 + src/feature/control/control_connection_st.h | 46 + src/feature/control/fmt_serverstatus.c | 104 + src/feature/control/fmt_serverstatus.h | 18 + src/feature/control/getinfo_geoip.c | 45 + src/feature/control/getinfo_geoip.h | 14 + src/feature/dirauth/authmode.c | 70 + src/feature/dirauth/authmode.h | 46 + src/feature/dirauth/bwauth.c | 459 + src/feature/dirauth/bwauth.h | 58 + src/feature/dirauth/dircollate.c | 327 + src/feature/dirauth/dircollate.h | 70 + src/feature/dirauth/dirvote.c | 4658 ++++++++++ src/feature/dirauth/dirvote.h | 250 + src/feature/dirauth/dsigs_parse.c | 282 + src/feature/dirauth/dsigs_parse.h | 22 + src/feature/dirauth/guardfraction.c | 333 + src/feature/dirauth/guardfraction.h | 24 + src/feature/dirauth/keypin.c | 515 ++ src/feature/dirauth/keypin.h | 47 + src/feature/dirauth/ns_detached_signatures_st.h | 22 + src/feature/dirauth/process_descs.c | 839 ++ src/feature/dirauth/process_descs.h | 38 + src/feature/dirauth/reachability.c | 207 + src/feature/dirauth/reachability.h | 36 + src/feature/dirauth/recommend_pkg.c | 90 + src/feature/dirauth/recommend_pkg.h | 17 + src/feature/dirauth/shared_random.c | 1291 +++ src/feature/dirauth/shared_random.h | 194 + src/feature/dirauth/shared_random_state.c | 1340 +++ src/feature/dirauth/shared_random_state.h | 148 + src/feature/dirauth/vote_microdesc_hash_st.h | 22 + src/feature/dirauth/voteflags.c | 644 ++ src/feature/dirauth/voteflags.h | 31 + src/feature/dircache/cached_dir_st.h | 25 + src/feature/dircache/conscache.c | 627 ++ src/feature/dircache/conscache.h | 66 + src/feature/dircache/consdiffmgr.c | 1945 +++++ src/feature/dircache/consdiffmgr.h | 75 + src/feature/dircache/dircache.c | 1740 ++++ src/feature/dircache/dircache.h | 43 + src/feature/dircache/dirserv.c | 918 ++ src/feature/dircache/dirserv.h | 119 + src/feature/dirclient/dir_server_st.h | 54 + src/feature/dirclient/dirclient.c | 3206 +++++++ src/feature/dirclient/dirclient.h | 172 + src/feature/dirclient/dlstatus.c | 422 + src/feature/dirclient/dlstatus.h | 58 + src/feature/dirclient/download_status_st.h | 65 + src/feature/dircommon/consdiff.c | 1414 +++ src/feature/dircommon/consdiff.h | 99 + src/feature/dircommon/dir_connection_st.h | 67 + src/feature/dircommon/directory.c | 651 ++ src/feature/dircommon/directory.h | 129 + src/feature/dircommon/fp_pair.c | 315 + src/feature/dircommon/fp_pair.h | 56 + src/feature/dircommon/vote_timing_st.h | 24 + src/feature/dircommon/voting_schedule.c | 194 + src/feature/dircommon/voting_schedule.h | 65 + src/feature/dirparse/authcert_members.i | 13 + src/feature/dirparse/authcert_parse.c | 207 + src/feature/dirparse/authcert_parse.h | 18 + src/feature/dirparse/microdesc_parse.c | 267 + src/feature/dirparse/microdesc_parse.h | 20 + src/feature/dirparse/ns_parse.c | 1685 ++++ src/feature/dirparse/ns_parse.h | 45 + src/feature/dirparse/parsecommon.c | 458 + src/feature/dirparse/parsecommon.h | 324 + src/feature/dirparse/policy_parse.c | 224 + src/feature/dirparse/policy_parse.h | 25 + src/feature/dirparse/routerparse.c | 1245 +++ src/feature/dirparse/routerparse.h | 49 + src/feature/dirparse/sigcommon.c | 185 + src/feature/dirparse/sigcommon.h | 48 + src/feature/dirparse/signing.c | 98 + src/feature/dirparse/signing.h | 23 + src/feature/dirparse/unparseable.c | 591 ++ src/feature/dirparse/unparseable.h | 56 + src/feature/hibernate/hibernate.c | 1267 +++ src/feature/hibernate/hibernate.h | 61 + src/feature/hs/hs_cache.c | 986 +++ src/feature/hs/hs_cache.h | 130 + src/feature/hs/hs_cell.c | 952 ++ src/feature/hs/hs_cell.h | 109 + src/feature/hs/hs_circuit.c | 1271 +++ src/feature/hs/hs_circuit.h | 75 + src/feature/hs/hs_circuitmap.c | 585 ++ src/feature/hs/hs_circuitmap.h | 112 + src/feature/hs/hs_client.c | 1945 +++++ src/feature/hs/hs_client.h | 119 + src/feature/hs/hs_common.c | 1829 ++++ src/feature/hs/hs_common.h | 288 + src/feature/hs/hs_config.c | 696 ++ src/feature/hs/hs_config.h | 25 + src/feature/hs/hs_control.c | 261 + src/feature/hs/hs_control.h | 52 + src/feature/hs/hs_descriptor.c | 3073 +++++++ src/feature/hs/hs_descriptor.h | 346 + src/feature/hs/hs_ident.c | 127 + src/feature/hs/hs_ident.h | 150 + src/feature/hs/hs_intropoint.c | 609 ++ src/feature/hs/hs_intropoint.h | 64 + src/feature/hs/hs_service.c | 4170 +++++++++ src/feature/hs/hs_service.h | 444 + src/feature/hs/hs_stats.c | 58 + src/feature/hs/hs_stats.h | 14 + src/feature/hs/hsdir_index_st.h | 24 + src/feature/hs_common/replaycache.c | 209 + src/feature/hs_common/replaycache.h | 67 + src/feature/hs_common/shared_random_client.c | 293 + src/feature/hs_common/shared_random_client.h | 48 + src/feature/keymgt/loadkey.c | 755 ++ src/feature/keymgt/loadkey.h | 55 + src/feature/nodelist/authcert.c | 1208 +++ src/feature/nodelist/authcert.h | 60 + src/feature/nodelist/authority_cert_st.h | 32 + src/feature/nodelist/desc_store_st.h | 39 + src/feature/nodelist/describe.c | 183 + src/feature/nodelist/describe.h | 25 + src/feature/nodelist/dirlist.c | 422 + src/feature/nodelist/dirlist.h | 47 + src/feature/nodelist/document_signature_st.h | 29 + src/feature/nodelist/extrainfo_st.h | 30 + src/feature/nodelist/fmt_routerstatus.c | 253 + src/feature/nodelist/fmt_routerstatus.h | 41 + src/feature/nodelist/microdesc.c | 1063 +++ src/feature/nodelist/microdesc.h | 60 + src/feature/nodelist/microdesc_st.h | 80 + src/feature/nodelist/networkstatus.c | 2723 ++++++ src/feature/nodelist/networkstatus.h | 160 + src/feature/nodelist/networkstatus_sr_info_st.h | 23 + src/feature/nodelist/networkstatus_st.h | 104 + src/feature/nodelist/networkstatus_voter_info_st.h | 30 + src/feature/nodelist/nickname.c | 62 + src/feature/nodelist/nickname.h | 19 + src/feature/nodelist/node_select.c | 1111 +++ src/feature/nodelist/node_select.h | 102 + src/feature/nodelist/node_st.h | 102 + src/feature/nodelist/nodelist.c | 2620 ++++++ src/feature/nodelist/nodelist.h | 169 + src/feature/nodelist/routerinfo.c | 79 + src/feature/nodelist/routerinfo.h | 27 + src/feature/nodelist/routerinfo_st.h | 115 + src/feature/nodelist/routerlist.c | 3234 +++++++ src/feature/nodelist/routerlist.h | 207 + src/feature/nodelist/routerlist_st.h | 40 + src/feature/nodelist/routerset.c | 463 + src/feature/nodelist/routerset.h | 89 + src/feature/nodelist/routerstatus_st.h | 80 + src/feature/nodelist/signed_descriptor_st.h | 61 + src/feature/nodelist/torcert.c | 764 ++ src/feature/nodelist/torcert.h | 116 + src/feature/nodelist/vote_routerstatus_st.h | 41 + src/feature/relay/dns.c | 2187 +++++ src/feature/relay/dns.h | 72 + src/feature/relay/dns_structs.h | 102 + src/feature/relay/ext_orport.c | 662 ++ src/feature/relay/ext_orport.h | 64 + src/feature/relay/onion_queue.c | 361 + src/feature/relay/onion_queue.h | 23 + src/feature/relay/router.c | 3128 +++++++ src/feature/relay/router.h | 122 + src/feature/relay/routerkeys.c | 740 ++ src/feature/relay/routerkeys.h | 45 + src/feature/relay/routermode.c | 80 + src/feature/relay/routermode.h | 24 + src/feature/relay/selftest.c | 301 + src/feature/relay/selftest.h | 24 + src/feature/rend/rend_authorized_client_st.h | 18 + .../rend/rend_encoded_v2_service_descriptor_st.h | 17 + src/feature/rend/rend_intro_point_st.h | 76 + src/feature/rend/rend_service_descriptor_st.h | 34 + src/feature/rend/rendcache.c | 1008 +++ src/feature/rend/rendcache.h | 130 + src/feature/rend/rendclient.c | 1228 +++ src/feature/rend/rendclient.h | 51 + src/feature/rend/rendcommon.c | 1047 +++ src/feature/rend/rendcommon.h | 82 + src/feature/rend/rendmid.c | 370 + src/feature/rend/rendmid.h | 25 + src/feature/rend/rendparse.c | 600 ++ src/feature/rend/rendparse.h | 32 + src/feature/rend/rendservice.c | 4487 ++++++++++ src/feature/rend/rendservice.h | 222 + src/feature/stats/geoip_stats.c | 1425 +++ src/feature/stats/geoip_stats.h | 139 + src/feature/stats/predict_ports.c | 313 + src/feature/stats/predict_ports.h | 30 + src/feature/stats/rephist.c | 2933 +++++++ src/feature/stats/rephist.h | 133 + src/include.am | 43 +- src/lib/arch/.may_include | 2 + src/lib/arch/bytes.h | 182 + src/lib/arch/include.am | 3 + src/lib/cc/.may_include | 1 + src/lib/cc/compat_compiler.h | 220 + src/lib/cc/include.am | 4 + src/lib/cc/torint.h | 128 + src/lib/compress/.may_include | 12 + src/lib/compress/compress.c | 681 ++ src/lib/compress/compress.h | 99 + src/lib/compress/compress_buf.c | 83 + src/lib/compress/compress_lzma.c | 362 + src/lib/compress/compress_lzma.h | 46 + src/lib/compress/compress_none.c | 54 + src/lib/compress/compress_none.h | 20 + src/lib/compress/compress_zlib.c | 304 + src/lib/compress/compress_zlib.h | 46 + src/lib/compress/compress_zstd.c | 541 ++ src/lib/compress/compress_zstd.h | 53 + src/lib/compress/include.am | 26 + src/lib/container/.may_include | 18 + src/lib/container/bitarray.h | 86 + src/lib/container/bloomfilt.c | 113 + src/lib/container/bloomfilt.h | 41 + src/lib/container/buffers.c | 932 ++ src/lib/container/buffers.h | 122 + src/lib/container/handles.h | 153 + src/lib/container/include.am | 27 + src/lib/container/map.c | 413 + src/lib/container/map.h | 261 + src/lib/container/order.c | 48 + src/lib/container/order.h | 60 + src/lib/container/smartlist.c | 866 ++ src/lib/container/smartlist.h | 168 + src/lib/crypt_ops/.may_include | 24 + src/lib/crypt_ops/aes.h | 31 + src/lib/crypt_ops/aes_nss.c | 106 + src/lib/crypt_ops/aes_openssl.c | 410 + src/lib/crypt_ops/compat_openssl.h | 57 + src/lib/crypt_ops/crypto_cipher.c | 190 + src/lib/crypt_ops/crypto_cipher.h | 57 + src/lib/crypt_ops/crypto_curve25519.c | 366 + src/lib/crypt_ops/crypto_curve25519.h | 85 + src/lib/crypt_ops/crypto_dh.c | 113 + src/lib/crypt_ops/crypto_dh.h | 64 + src/lib/crypt_ops/crypto_dh_nss.c | 209 + src/lib/crypt_ops/crypto_dh_openssl.c | 477 + src/lib/crypt_ops/crypto_digest.c | 828 ++ src/lib/crypt_ops/crypto_digest.h | 132 + src/lib/crypt_ops/crypto_ed25519.c | 821 ++ src/lib/crypt_ops/crypto_ed25519.h | 144 + src/lib/crypt_ops/crypto_format.c | 305 + src/lib/crypt_ops/crypto_format.h | 50 + src/lib/crypt_ops/crypto_hkdf.c | 201 + src/lib/crypt_ops/crypto_hkdf.h | 27 + src/lib/crypt_ops/crypto_init.c | 204 + src/lib/crypt_ops/crypto_init.h | 36 + src/lib/crypt_ops/crypto_nss_mgt.c | 132 + src/lib/crypt_ops/crypto_nss_mgt.h | 34 + src/lib/crypt_ops/crypto_ope.c | 185 + src/lib/crypt_ops/crypto_ope.h | 46 + src/lib/crypt_ops/crypto_openssl_mgt.c | 398 + src/lib/crypt_ops/crypto_openssl_mgt.h | 89 + src/lib/crypt_ops/crypto_pwbox.c | 219 + src/lib/crypt_ops/crypto_pwbox.h | 28 + src/lib/crypt_ops/crypto_rand.c | 731 ++ src/lib/crypt_ops/crypto_rand.h | 53 + src/lib/crypt_ops/crypto_rsa.c | 672 ++ src/lib/crypt_ops/crypto_rsa.h | 145 + src/lib/crypt_ops/crypto_rsa_nss.c | 738 ++ src/lib/crypt_ops/crypto_rsa_openssl.c | 590 ++ src/lib/crypt_ops/crypto_s2k.c | 525 ++ src/lib/crypt_ops/crypto_s2k.h | 78 + src/lib/crypt_ops/crypto_util.c | 111 + src/lib/crypt_ops/crypto_util.h | 21 + src/lib/crypt_ops/digestset.c | 58 + src/lib/crypt_ops/digestset.h | 29 + src/lib/crypt_ops/include.am | 70 + src/lib/ctime/.may_include | 5 + src/lib/ctime/di_ops.c | 278 + src/lib/ctime/di_ops.h | 55 + src/lib/ctime/include.am | 25 + src/lib/defs/.may_include | 1 + src/lib/defs/dh_sizes.h | 22 + src/lib/defs/digest_sizes.h | 27 + src/lib/defs/include.am | 5 + src/lib/defs/x25519_sizes.h | 36 + src/lib/encoding/.may_include | 10 + src/lib/encoding/binascii.c | 520 ++ src/lib/encoding/binascii.h | 60 + src/lib/encoding/confline.c | 402 + src/lib/encoding/confline.h | 78 + src/lib/encoding/cstring.c | 138 + src/lib/encoding/cstring.h | 19 + src/lib/encoding/include.am | 26 + src/lib/encoding/keyval.c | 52 + src/lib/encoding/keyval.h | 17 + src/lib/encoding/pem.c | 106 + src/lib/encoding/pem.h | 26 + src/lib/encoding/time_fmt.c | 516 ++ src/lib/encoding/time_fmt.h | 44 + src/lib/err/.may_include | 3 + src/lib/err/backtrace.c | 286 + src/lib/err/backtrace.h | 35 + src/lib/err/include.am | 19 + src/lib/err/torerr.c | 238 + src/lib/err/torerr.h | 47 + src/lib/evloop/.may_include | 16 + src/lib/evloop/compat_libevent.c | 535 ++ src/lib/evloop/compat_libevent.h | 104 + src/lib/evloop/include.am | 26 + src/lib/evloop/procmon.c | 339 + src/lib/evloop/procmon.h | 34 + src/lib/evloop/timers.c | 328 + src/lib/evloop/timers.h | 35 + src/lib/evloop/token_bucket.c | 258 + src/lib/evloop/token_bucket.h | 117 + src/lib/evloop/workqueue.c | 682 ++ src/lib/evloop/workqueue.h | 70 + src/lib/fdio/.may_include | 4 + src/lib/fdio/fdio.c | 115 + src/lib/fdio/fdio.h | 23 + src/lib/fdio/include.am | 17 + src/lib/fs/.may_include | 16 + src/lib/fs/conffile.c | 174 + src/lib/fs/conffile.h | 23 + src/lib/fs/dir.c | 367 + src/lib/fs/dir.h | 33 + src/lib/fs/files.c | 721 ++ src/lib/fs/files.h | 145 + src/lib/fs/freespace.c | 63 + src/lib/fs/include.am | 37 + src/lib/fs/lockfile.c | 145 + src/lib/fs/lockfile.h | 20 + src/lib/fs/mmap.c | 240 + src/lib/fs/mmap.h | 41 + src/lib/fs/path.c | 295 + src/lib/fs/path.h | 30 + src/lib/fs/storagedir.c | 606 ++ src/lib/fs/storagedir.h | 64 + src/lib/fs/userdb.c | 138 + src/lib/fs/userdb.h | 26 + src/lib/fs/winlib.c | 30 + src/lib/fs/winlib.h | 22 + src/lib/geoip/.may_include | 13 + src/lib/geoip/country.h | 16 + src/lib/geoip/geoip.c | 510 ++ src/lib/geoip/geoip.h | 50 + src/lib/geoip/include.am | 17 + src/lib/include.libdonna.am | 24 + src/lib/intmath/.may_include | 4 + src/lib/intmath/addsub.c | 28 + src/lib/intmath/addsub.h | 19 + src/lib/intmath/bits.c | 94 + src/lib/intmath/bits.h | 22 + src/lib/intmath/cmp.h | 39 + src/lib/intmath/include.am | 25 + src/lib/intmath/logic.h | 20 + src/lib/intmath/muldiv.c | 81 + src/lib/intmath/muldiv.h | 28 + src/lib/intmath/weakrng.c | 60 + src/lib/intmath/weakrng.h | 31 + src/lib/lock/.may_include | 5 + src/lib/lock/compat_mutex.c | 40 + src/lib/lock/compat_mutex.h | 66 + src/lib/lock/compat_mutex_pthreads.c | 103 + src/lib/lock/compat_mutex_winthreads.c | 46 + src/lib/lock/include.am | 24 + src/lib/log/.may_include | 15 + src/lib/log/escape.c | 137 + src/lib/log/escape.h | 23 + src/lib/log/git_revision.c | 24 + src/lib/log/git_revision.h | 12 + src/lib/log/include.am | 36 + src/lib/log/log.c | 1483 ++++ src/lib/log/log.h | 276 + src/lib/log/ratelim.c | 60 + src/lib/log/ratelim.h | 53 + src/lib/log/util_bug.c | 161 + src/lib/log/util_bug.h | 246 + src/lib/log/win32err.c | 61 + src/lib/log/win32err.h | 22 + src/lib/malloc/.may_include | 6 + src/lib/malloc/include.am | 21 + src/lib/malloc/malloc.c | 230 + src/lib/malloc/malloc.h | 92 + src/lib/math/.may_include | 5 + src/lib/math/fp.c | 119 + src/lib/math/fp.h | 23 + src/lib/math/include.am | 20 + src/lib/math/laplace.c | 73 + src/lib/math/laplace.h | 22 + src/lib/memarea/.may_include | 7 + src/lib/memarea/include.am | 17 + src/lib/memarea/memarea.c | 403 + src/lib/memarea/memarea.h | 35 + src/lib/meminfo/.may_include | 8 + src/lib/meminfo/include.am | 17 + src/lib/meminfo/meminfo.c | 180 + src/lib/meminfo/meminfo.h | 21 + src/lib/net/.may_include | 15 + src/lib/net/address.c | 2057 +++++ src/lib/net/address.h | 388 + src/lib/net/alertsock.c | 295 + src/lib/net/alertsock.h | 45 + src/lib/net/buffers_net.c | 202 + src/lib/net/buffers_net.h | 27 + src/lib/net/gethostname.c | 30 + src/lib/net/gethostname.h | 19 + src/lib/net/inaddr.c | 267 + src/lib/net/inaddr.h | 27 + src/lib/net/inaddr_st.h | 107 + src/lib/net/include.am | 34 + src/lib/net/nettypes.h | 44 + src/lib/net/resolve.c | 424 + src/lib/net/resolve.h | 58 + src/lib/net/socket.c | 697 ++ src/lib/net/socket.h | 118 + src/lib/net/socketpair.c | 214 + src/lib/net/socketpair.h | 19 + src/lib/net/socks5_status.h | 32 + src/lib/osinfo/.may_include | 5 + src/lib/osinfo/include.am | 17 + src/lib/osinfo/uname.c | 149 + src/lib/osinfo/uname.h | 18 + src/lib/process/.may_include | 17 + src/lib/process/daemon.c | 187 + src/lib/process/daemon.h | 21 + src/lib/process/env.c | 224 + src/lib/process/env.h | 41 + src/lib/process/include.am | 29 + src/lib/process/pidfile.c | 52 + src/lib/process/pidfile.h | 16 + src/lib/process/restrict.c | 285 + src/lib/process/restrict.h | 27 + src/lib/process/setuid.c | 386 + src/lib/process/setuid.h | 22 + src/lib/process/subprocess.c | 1236 +++ src/lib/process/subprocess.h | 134 + src/lib/process/waitpid.c | 154 + src/lib/process/waitpid.h | 29 + src/lib/sandbox/.may_include | 15 + src/lib/sandbox/include.am | 18 + src/{common => lib/sandbox}/linux_syscalls.inc | 0 src/lib/sandbox/sandbox.c | 1808 ++++ src/lib/sandbox/sandbox.h | 150 + src/lib/smartlist_core/.may_include | 7 + src/lib/smartlist_core/include.am | 21 + src/lib/smartlist_core/smartlist_core.c | 234 + src/lib/smartlist_core/smartlist_core.h | 100 + src/lib/smartlist_core/smartlist_foreach.h | 133 + src/lib/smartlist_core/smartlist_split.c | 92 + src/lib/smartlist_core/smartlist_split.h | 20 + src/lib/string/.may_include | 10 + src/lib/string/compat_ctype.c | 72 + src/lib/string/compat_ctype.h | 67 + src/lib/string/compat_string.c | 74 + src/lib/string/compat_string.h | 62 + src/lib/string/include.am | 27 + src/lib/string/parse_int.c | 131 + src/lib/string/parse_int.h | 25 + src/lib/string/printf.c | 167 + src/lib/string/printf.h | 30 + src/lib/string/scanf.c | 317 + src/lib/string/scanf.h | 24 + src/lib/string/util_string.c | 543 ++ src/lib/string/util_string.h | 57 + src/lib/term/.may_include | 9 + src/lib/term/getpass.c | 120 + src/lib/term/getpass.h | 18 + src/lib/term/include.am | 24 + src/lib/testsupport/.may_include | 0 src/lib/testsupport/include.am | 3 + src/lib/testsupport/testsupport.h | 103 + src/lib/thread/.may_include | 7 + src/lib/thread/compat_pthreads.c | 270 + src/lib/thread/compat_threads.c | 111 + src/lib/thread/compat_winthreads.c | 223 + src/lib/thread/include.am | 27 + src/lib/thread/numcpus.c | 98 + src/lib/thread/numcpus.h | 16 + src/lib/thread/threads.h | 168 + src/lib/time/.may_include | 11 + src/lib/time/compat_time.c | 869 ++ src/lib/time/compat_time.h | 235 + src/lib/time/include.am | 19 + src/lib/time/tvdiff.c | 189 + src/lib/time/tvdiff.h | 23 + src/lib/tls/.may_include | 17 + src/lib/tls/buffers_tls.c | 182 + src/lib/tls/buffers_tls.h | 23 + src/lib/tls/ciphers.inc | 100 + src/lib/tls/include.am | 40 + src/lib/tls/nss_countbytes.c | 244 + src/lib/tls/nss_countbytes.h | 25 + src/lib/tls/tortls.c | 442 + src/lib/tls/tortls.h | 160 + src/lib/tls/tortls_internal.h | 76 + src/lib/tls/tortls_nss.c | 833 ++ src/lib/tls/tortls_openssl.c | 1795 ++++ src/lib/tls/tortls_st.h | 75 + src/lib/tls/x509.c | 143 + src/lib/tls/x509.h | 75 + src/lib/tls/x509_internal.h | 53 + src/lib/tls/x509_nss.c | 458 + src/lib/tls/x509_openssl.c | 464 + src/lib/trace/.may_include | 3 + src/lib/trace/debug.h | 30 + src/lib/trace/events.h | 45 + src/lib/trace/include.am | 18 + src/lib/trace/trace.c | 17 + src/lib/trace/trace.h | 14 + src/lib/wallclock/.may_include | 6 + src/lib/wallclock/approx_time.c | 43 + src/lib/wallclock/approx_time.h | 25 + src/lib/wallclock/include.am | 22 + src/lib/wallclock/time_to_tm.c | 200 + src/lib/wallclock/time_to_tm.h | 22 + src/lib/wallclock/timeval.h | 65 + src/lib/wallclock/tor_gettimeofday.c | 82 + src/lib/wallclock/tor_gettimeofday.h | 20 + src/or/Makefile.nmake | 78 - src/or/addressmap.c | 1125 --- src/or/addressmap.h | 65 - src/or/buffers.c | 2065 ----- src/or/buffers.h | 101 - src/or/channel.c | 4617 ---------- src/or/channel.h | 609 -- src/or/channeltls.c | 2208 ----- src/or/channeltls.h | 76 - src/or/circpathbias.c | 1546 ---- src/or/circpathbias.h | 29 - src/or/circuitbuild.c | 2553 ------ src/or/circuitbuild.h | 78 - src/or/circuitlist.c | 2435 ------ src/or/circuitlist.h | 91 - src/or/circuitmux.c | 1990 ----- src/or/circuitmux.h | 160 - src/or/circuitmux_ewma.c | 765 -- src/or/circuitmux_ewma.h | 24 - src/or/circuitstats.c | 1734 ---- src/or/circuitstats.h | 98 - src/or/circuituse.c | 2624 ------ src/or/circuituse.h | 63 - src/or/command.c | 642 -- src/or/command.h | 31 - src/or/config.c | 8013 ----------------- src/or/config.h | 205 - src/or/confparse.c | 1364 --- src/or/confparse.h | 143 - src/or/connection.c | 5177 ----------- src/or/connection.h | 290 - src/or/connection_edge.c | 3825 -------- src/or/connection_edge.h | 192 - src/or/connection_or.c | 2454 ------ src/or/connection_or.h | 107 - src/or/control.c | 7190 ---------------- src/or/control.h | 292 - src/or/cpuworker.c | 572 -- src/or/cpuworker.h | 29 - src/or/dircollate.c | 353 - src/or/dircollate.h | 68 - src/or/directory.c | 4316 ---------- src/or/directory.h | 175 - src/or/dirserv.c | 3913 --------- src/or/dirserv.h | 143 - src/or/dirvote.c | 4012 --------- src/or/dirvote.h | 240 - src/or/dns.c | 2120 ----- src/or/dns.h | 70 - src/or/dns_structs.h | 102 - src/or/dnsserv.c | 396 - src/or/dnsserv.h | 27 - src/or/dos.c | 794 -- src/or/dos.h | 140 - src/or/entrynodes.c | 2561 ------ src/or/entrynodes.h | 187 - src/or/ext_orport.c | 653 -- src/or/ext_orport.h | 42 - src/or/fp_pair.c | 315 - src/or/fp_pair.h | 45 - src/or/geoip.c | 1875 ---- src/or/geoip.h | 100 - src/or/hibernate.c | 1125 --- src/or/hibernate.h | 59 - src/or/include.am | 222 - src/or/keypin.c | 498 -- src/or/keypin.h | 47 - src/or/main.c | 3533 -------- src/or/main.h | 98 - src/or/microdesc.c | 968 --- src/or/microdesc.h | 56 - src/or/networkstatus.c | 2535 ------ src/or/networkstatus.h | 135 - src/or/nodelist.c | 2026 ----- src/or/nodelist.h | 131 - src/or/ntmain.c | 781 -- src/or/ntmain.h | 28 - src/or/onion.c | 1247 --- src/or/onion.h | 121 - src/or/onion_fast.c | 142 - src/or/onion_fast.h | 39 - src/or/onion_ntor.c | 335 - src/or/onion_ntor.h | 61 - src/or/onion_tap.c | 247 - src/or/onion_tap.h | 38 - src/or/or.h | 5392 ------------ src/or/periodic.c | 126 - src/or/periodic.h | 37 - src/or/policies.c | 3040 ------- src/or/policies.h | 147 - src/or/protover.c | 793 -- src/or/protover.h | 74 - src/or/reasons.c | 444 - src/or/reasons.h | 31 - src/or/relay.c | 3068 ------- src/or/relay.h | 115 - src/or/rendcache.c | 1013 --- src/or/rendcache.h | 115 - src/or/rendclient.c | 1567 ---- src/or/rendclient.h | 58 - src/or/rendcommon.c | 1118 --- src/or/rendcommon.h | 87 - src/or/rendmid.c | 382 - src/or/rendmid.h | 25 - src/or/rendservice.c | 4438 ---------- src/or/rendservice.h | 205 - src/or/rephist.c | 3299 ------- src/or/rephist.h | 123 - src/or/replaycache.c | 216 - src/or/replaycache.h | 66 - src/or/router.c | 3658 -------- src/or/router.h | 163 - src/or/routerkeys.c | 1147 --- src/or/routerkeys.h | 77 - src/or/routerlist.c | 5820 ------------- src/or/routerlist.h | 258 - src/or/routerparse.c | 6364 -------------- src/or/routerparse.h | 131 - src/or/routerset.c | 445 - src/or/routerset.h | 84 - src/or/scheduler.c | 707 -- src/or/scheduler.h | 57 - src/or/shared_random.c | 1363 --- src/or/shared_random.h | 168 - src/or/shared_random_state.c | 1360 --- src/or/shared_random_state.h | 149 - src/or/statefile.c | 684 -- src/or/statefile.h | 28 - src/or/status.c | 210 - src/or/status.h | 18 - src/or/tor_main.c | 40 - src/or/torcert.c | 297 - src/or/torcert.h | 76 - src/or/transports.c | 1744 ---- src/or/transports.h | 139 - src/rust/.cargo/config.in | 12 + src/rust/.rustfmt.toml | 12 + src/rust/Cargo.lock | 122 + src/rust/Cargo.toml | 26 + src/rust/build.rs | 190 + src/rust/crypto/Cargo.toml | 37 + src/rust/crypto/digests/mod.rs | 7 + src/rust/crypto/digests/sha2.rs | 234 + src/rust/crypto/lib.rs | 46 + src/rust/crypto/rand/mod.rs | 6 + src/rust/crypto/rand/rng.rs | 145 + src/rust/external/Cargo.toml | 20 + src/rust/external/crypto_digest.rs | 454 + src/rust/external/crypto_rand.rs | 84 + src/rust/external/external.rs | 37 + src/rust/external/lib.rs | 19 + src/rust/include.am | 41 + src/rust/protover/Cargo.toml | 33 + src/rust/protover/errors.rs | 57 + src/rust/protover/ffi.rs | 245 + src/rust/protover/lib.rs | 40 + src/rust/protover/protoset.rs | 689 ++ src/rust/protover/protover.rs | 971 +++ src/rust/protover/tests/protover.rs | 404 + src/rust/smartlist/Cargo.toml | 18 + src/rust/smartlist/lib.rs | 17 + src/rust/smartlist/smartlist.rs | 115 + src/rust/tor_allocate/Cargo.toml | 18 + src/rust/tor_allocate/lib.rs | 20 + src/rust/tor_allocate/tor_allocate.rs | 104 + src/rust/tor_log/Cargo.toml | 21 + src/rust/tor_log/lib.rs | 16 + src/rust/tor_log/tor_log.rs | 265 + src/rust/tor_rust/Cargo.toml | 22 + src/rust/tor_rust/include.am | 28 + src/rust/tor_rust/lib.rs | 5 + src/rust/tor_util/Cargo.toml | 24 + src/rust/tor_util/ffi.rs | 27 + src/rust/tor_util/lib.rs | 14 + src/rust/tor_util/strings.rs | 140 + src/test/Makefile.nmake | 4 +- src/test/bench.c | 125 +- src/test/bt_test.py | 2 +- src/test/ed25519_exts_ref.py | 38 +- src/test/ed25519_vectors.inc | 32 +- src/test/fakechans.h | 3 +- src/test/fuzz/dict/consensus | 52 + src/test/fuzz/dict/descriptor | 41 + src/test/fuzz/dict/extrainfo | 32 + src/test/fuzz/dict/hsdescv2 | 8 + src/test/fuzz/dict/hsdescv3 | 6 + src/test/fuzz/dict/http | 24 + src/test/fuzz/dict/iptsv2 | 6 + src/test/fuzz/dict/microdesc | 7 + src/test/fuzz/fixup_filenames.sh | 19 + src/test/fuzz/fuzz_consensus.c | 81 + src/test/fuzz/fuzz_descriptor.c | 81 + src/test/fuzz/fuzz_diff.c | 69 + src/test/fuzz/fuzz_diff_apply.c | 65 + src/test/fuzz/fuzz_extrainfo.c | 67 + src/test/fuzz/fuzz_hsdescv2.c | 52 + src/test/fuzz/fuzz_hsdescv3.c | 99 + src/test/fuzz/fuzz_http.c | 134 + src/test/fuzz/fuzz_http_connect.c | 109 + src/test/fuzz/fuzz_iptsv2.c | 50 + src/test/fuzz/fuzz_microdesc.c | 49 + src/test/fuzz/fuzz_multi.sh | 34 + src/test/fuzz/fuzz_socks.c | 50 + src/test/fuzz/fuzz_vrs.c | 87 + src/test/fuzz/fuzzing.h | 13 + src/test/fuzz/fuzzing_common.c | 197 + src/test/fuzz/include.am | 440 + src/test/fuzz/minimize.sh | 14 + src/test/fuzz_static_testcases.sh | 27 + src/test/hs_build_address.py | 38 + src/test/hs_indexes.py | 70 + src/test/hs_ntor_ref.py | 428 + src/test/hs_test_helpers.c | 325 + src/test/hs_test_helpers.h | 25 + src/test/include.am | 224 +- src/test/log_test_helpers.c | 6 +- src/test/log_test_helpers.h | 45 +- src/test/ntor_ref.py | 2 +- src/test/ope_ref.py | 40 + src/test/rend_test_helpers.c | 31 +- src/test/rend_test_helpers.h | 7 +- src/test/rust_supp.txt | 1 + src/test/test-child.c | 4 +- src/test/test-memwipe.c | 17 +- src/test/test-network.sh | 4 +- src/test/test-timers.c | 31 +- src/test/test.c | 568 +- src/test/test.h | 79 +- src/test/test_accounting.c | 16 +- src/test/test_addr.c | 248 +- src/test/test_address.c | 147 +- src/test/test_address_set.c | 26 +- src/test/test_bridges.c | 704 ++ src/test/test_bt_cl.c | 27 +- src/test/test_buffers.c | 548 +- src/test/test_bwmgt.c | 233 + src/test/test_cell_formats.c | 66 +- src/test/test_cell_queue.c | 19 +- src/test/test_channel.c | 1931 ++--- src/test/test_channelpadding.c | 1104 +++ src/test/test_channeltls.c | 67 +- src/test/test_checkdir.c | 16 +- src/test/test_circuitbuild.c | 182 + src/test/test_circuitlist.c | 192 +- src/test/test_circuitmux.c | 69 +- src/test/test_circuitstats.c | 206 + src/test/test_circuituse.c | 310 + src/test/test_compat_libevent.c | 71 +- src/test/test_config.c | 1983 +++-- src/test/test_connection.c | 558 +- src/test/test_connection.h | 13 + src/test/test_conscache.c | 340 + src/test/test_consdiff.c | 1185 +++ src/test/test_consdiffmgr.c | 900 ++ src/test/test_containers.c | 150 +- src/test/test_controller.c | 667 +- src/test/test_controller_events.c | 160 +- src/test/test_crypto.c | 538 +- src/test/test_crypto_ope.c | 154 + src/test/test_crypto_openssl.c | 106 + src/test/test_crypto_slow.c | 50 +- src/test/test_data.c | 4 +- src/test/test_dir.c | 2531 ++++-- src/test/test_dir_common.c | 28 +- src/test/test_dir_common.h | 7 +- src/test/test_dir_handle_get.c | 376 +- src/test/test_dns.c | 88 +- src/test/test_dos.c | 31 +- src/test/test_entryconn.c | 202 +- src/test/test_entrynodes.c | 3519 ++++++-- src/test/test_extorport.c | 86 +- src/test/test_geoip.c | 580 ++ src/test/test_guardfraction.c | 81 +- src/test/test_handles.c | 13 +- src/test/test_helpers.c | 229 +- src/test/test_helpers.h | 22 +- src/test/test_hs.c | 613 +- src/test/test_hs_cache.c | 566 ++ src/test/test_hs_cell.c | 131 + src/test/test_hs_client.c | 1010 +++ src/test/test_hs_common.c | 1839 ++++ src/test/test_hs_config.c | 517 ++ src/test/test_hs_control.c | 194 + src/test/test_hs_descriptor.c | 965 +++ src/test/test_hs_descriptor.inc | 224 + src/test/test_hs_intropoint.c | 930 ++ src/test/test_hs_ntor.c | 115 + src/test/test_hs_ntor.sh | 11 + src/test/test_hs_ntor_cl.c | 259 + src/test/test_hs_service.c | 2145 +++++ src/test/test_introduce.c | 20 +- src/test/test_key_expiration.sh | 138 + src/test/test_keygen.sh | 112 +- src/test/test_keypin.c | 112 +- src/test/test_link_handshake.c | 941 +- src/test/test_logging.c | 28 +- src/test/test_mainloop.c | 142 + src/test/test_microdesc.c | 135 +- src/test/test_nodelist.c | 140 +- src/test/test_ntor_cl.c | 18 +- src/test/test_oom.c | 83 +- src/test/test_oos.c | 37 +- src/test/test_options.c | 981 +-- src/test/test_pem.c | 122 + src/test/test_periodic_event.c | 333 + src/test/test_policy.c | 492 +- src/test/test_procmon.c | 10 +- src/test/test_proto_http.c | 213 + src/test/test_proto_misc.c | 265 + src/test/test_protover.c | 363 +- src/test/test_pt.c | 74 +- src/test/test_pubsub.c | 85 - src/test/test_rebind.py | 145 + src/test/test_rebind.sh | 32 + src/test/test_relay.c | 59 +- src/test/test_relaycell.c | 837 +- src/test/test_relaycrypt.c | 190 + src/test/test_rendcache.c | 114 +- src/test/test_replay.c | 34 +- src/test/test_router.c | 119 +- src/test/test_routerkeys.c | 334 +- src/test/test_routerlist.c | 432 +- src/test/test_routerset.c | 130 +- src/test/test_rust.sh | 27 + src/test/test_scheduler.c | 1115 ++- src/test/test_shared_random.c | 508 +- src/test/test_slow.c | 6 +- src/test/test_socks.c | 671 +- src/test/test_status.c | 57 +- src/test/test_storagedir.c | 376 + src/test/test_switch_id.c | 17 +- src/test/test_threads.c | 20 +- src/test/test_tortls.c | 2860 +----- src/test/test_tortls.h | 13 + src/test/test_tortls_openssl.c | 2316 +++++ src/test/test_util.c | 1553 +++- src/test/test_util_format.c | 99 +- src/test/test_util_process.c | 12 +- src/test/test_util_slow.c | 45 +- src/test/test_voting_schedule.c | 64 + src/test/test_workqueue.c | 79 +- src/test/test_x509.c | 205 + src/test/test_zero_length_keys.sh | 6 +- src/test/testing_common.c | 181 +- src/test/testing_rsakeys.c | 546 ++ src/test/zero_length_keys.sh | 3 +- src/tools/Makefile.nmake | 5 +- src/tools/include.am | 80 +- src/tools/tor-checkkey.c | 89 - src/tools/tor-fw-helper/README | 10 - src/tools/tor-gencert.c | 110 +- src/tools/tor-print-ed-signing-cert.c | 65 + src/tools/tor-resolve.c | 72 +- src/tools/tor_runner.c | 112 + src/trunnel/channelpadding_negotiation.c | 281 + src/trunnel/channelpadding_negotiation.h | 98 + src/trunnel/channelpadding_negotiation.trunnel | 17 + src/trunnel/ed25519_cert.c | 2312 ++++- src/trunnel/ed25519_cert.h | 678 +- src/trunnel/ed25519_cert.trunnel | 64 +- src/trunnel/hs/cell_common.c | 595 ++ src/trunnel/hs/cell_common.h | 203 + src/trunnel/hs/cell_common.trunnel | 12 + src/trunnel/hs/cell_establish_intro.c | 735 ++ src/trunnel/hs/cell_establish_intro.h | 276 + src/trunnel/hs/cell_establish_intro.trunnel | 41 + src/trunnel/hs/cell_introduce1.c | 1347 +++ src/trunnel/hs/cell_introduce1.h | 500 ++ src/trunnel/hs/cell_introduce1.trunnel | 75 + src/trunnel/hs/cell_rendezvous.c | 470 + src/trunnel/hs/cell_rendezvous.h | 187 + src/trunnel/hs/cell_rendezvous.trunnel | 29 + src/trunnel/include.am | 36 +- src/trunnel/link_handshake.c | 212 +- src/trunnel/link_handshake.h | 148 +- src/trunnel/pwbox.c | 54 +- src/trunnel/pwbox.h | 38 +- src/trunnel/socks5.c | 3978 +++++++++ src/trunnel/socks5.h | 995 +++ src/trunnel/socks5.trunnel | 94 + src/trunnel/trunnel-local.h | 6 +- src/win32/orconfig.h | 2 +- warning_flags.in | 1 + 1347 files changed, 319206 insertions(+), 195287 deletions(-)
diff --cc src/core/or/channeltls.c index 000000000,91a424728..4db283d20 mode 000000,100644..100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@@ -1,0 -1,2477 +1,2485 @@@ + /* * Copyright (c) 2012-2019, The Tor Project, Inc. */ + /* See LICENSE for licensing information */ + + /** + * \file channeltls.c + * + * \brief A concrete subclass of channel_t using or_connection_t to transfer + * cells between Tor instances. + * + * This module fills in the various function pointers in channel_t, to + * implement the channel_tls_t channels as used in Tor today. These channels + * are created from channel_tls_connect() and + * channel_tls_handle_incoming(). Each corresponds 1:1 to or_connection_t + * object, as implemented in connection_or.c. These channels transmit cells + * to the underlying or_connection_t by calling + * connection_or_write_*_cell_to_buf(), and receive cells from the underlying + * or_connection_t when connection_or_process_cells_from_inbuf() calls + * channel_tls_handle_*_cell(). + * + * Here we also implement the server (responder) side of the v3+ Tor link + * handshake, which uses CERTS and AUTHENTICATE cell to negotiate versions, + * exchange expected and observed IP and time information, and bootstrap a + * level of authentication higher than we have gotten on the raw TLS + * handshake. + * + * NOTE: Since there is currently only one type of channel, there are probably + * more than a few cases where functionality that is currently in + * channeltls.c, connection_or.c, and channel.c ought to be divided up + * differently. The right time to do this is probably whenever we introduce + * our next channel type. + **/ + + /* + * Define this so channel.h gives us things only channel_t subclasses + * should touch. + */ + #define TOR_CHANNEL_INTERNAL_ + + #define CHANNELTLS_PRIVATE + + #include "core/or/or.h" + #include "core/or/channel.h" + #include "core/or/channeltls.h" + #include "core/or/circuitmux.h" + #include "core/or/circuitmux_ewma.h" + #include "core/or/command.h" + #include "app/config/config.h" + #include "core/mainloop/connection.h" + #include "core/or/connection_or.h" + #include "feature/control/control.h" + #include "feature/client/entrynodes.h" + #include "trunnel/link_handshake.h" + #include "core/or/relay.h" + #include "feature/stats/rephist.h" + #include "feature/relay/router.h" + #include "feature/relay/routermode.h" + #include "feature/nodelist/dirlist.h" + #include "core/or/scheduler.h" + #include "feature/nodelist/torcert.h" + #include "feature/nodelist/networkstatus.h" + #include "trunnel/channelpadding_negotiation.h" + #include "core/or/channelpadding.h" + + #include "core/or/cell_st.h" + #include "core/or/cell_queue_st.h" + #include "core/or/extend_info_st.h" + #include "core/or/or_connection_st.h" + #include "core/or/or_handshake_certs_st.h" + #include "core/or/or_handshake_state_st.h" + #include "feature/nodelist/routerinfo_st.h" + #include "core/or/var_cell_st.h" + + #include "lib/tls/tortls.h" + #include "lib/tls/x509.h" + + /** How many CELL_PADDING cells have we received, ever? */ + uint64_t stats_n_padding_cells_processed = 0; + /** How many CELL_VERSIONS cells have we received, ever? */ + uint64_t stats_n_versions_cells_processed = 0; + /** How many CELL_NETINFO cells have we received, ever? */ + uint64_t stats_n_netinfo_cells_processed = 0; + /** How many CELL_VPADDING cells have we received, ever? */ + uint64_t stats_n_vpadding_cells_processed = 0; + /** How many CELL_CERTS cells have we received, ever? */ + uint64_t stats_n_certs_cells_processed = 0; + /** How many CELL_AUTH_CHALLENGE cells have we received, ever? */ + uint64_t stats_n_auth_challenge_cells_processed = 0; + /** How many CELL_AUTHENTICATE cells have we received, ever? */ + uint64_t stats_n_authenticate_cells_processed = 0; + /** How many CELL_AUTHORIZE cells have we received, ever? */ + uint64_t stats_n_authorize_cells_processed = 0; + + /** Active listener, if any */ + static channel_listener_t *channel_tls_listener = NULL; + + /* channel_tls_t method declarations */ + + static void channel_tls_close_method(channel_t *chan); + static const char * channel_tls_describe_transport_method(channel_t *chan); + static void channel_tls_free_method(channel_t *chan); + static double channel_tls_get_overhead_estimate_method(channel_t *chan); + static int + channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out); + static int + channel_tls_get_transport_name_method(channel_t *chan, char **transport_out); + static const char * + channel_tls_get_remote_descr_method(channel_t *chan, int flags); + static int channel_tls_has_queued_writes_method(channel_t *chan); + static int channel_tls_is_canonical_method(channel_t *chan, int req); + static int + channel_tls_matches_extend_info_method(channel_t *chan, + extend_info_t *extend_info); + static int channel_tls_matches_target_method(channel_t *chan, + const tor_addr_t *target); + static int channel_tls_num_cells_writeable_method(channel_t *chan); + static size_t channel_tls_num_bytes_queued_method(channel_t *chan); + static int channel_tls_write_cell_method(channel_t *chan, + cell_t *cell); + static int channel_tls_write_packed_cell_method(channel_t *chan, + packed_cell_t *packed_cell); + static int channel_tls_write_var_cell_method(channel_t *chan, + var_cell_t *var_cell); + + /* channel_listener_tls_t method declarations */ + + static void channel_tls_listener_close_method(channel_listener_t *chan_l); + static const char * + channel_tls_listener_describe_transport_method(channel_listener_t *chan_l); + + /** Handle incoming cells for the handshake stuff here rather than + * passing them on up. */ + + static void channel_tls_process_versions_cell(var_cell_t *cell, + channel_tls_t *tlschan); + static void channel_tls_process_netinfo_cell(cell_t *cell, + channel_tls_t *tlschan); + static int command_allowed_before_handshake(uint8_t command); + static int enter_v3_handshake_with_cell(var_cell_t *cell, + channel_tls_t *tlschan); + static void channel_tls_process_padding_negotiate_cell(cell_t *cell, + channel_tls_t *chan); + + /** + * Do parts of channel_tls_t initialization common to channel_tls_connect() + * and channel_tls_handle_incoming(). + */ + STATIC void + channel_tls_common_init(channel_tls_t *tlschan) + { + channel_t *chan; + + tor_assert(tlschan); + + chan = &(tlschan->base_); + channel_init(chan); + chan->magic = TLS_CHAN_MAGIC; + chan->state = CHANNEL_STATE_OPENING; + chan->close = channel_tls_close_method; + chan->describe_transport = channel_tls_describe_transport_method; + chan->free_fn = channel_tls_free_method; + chan->get_overhead_estimate = channel_tls_get_overhead_estimate_method; + chan->get_remote_addr = channel_tls_get_remote_addr_method; + chan->get_remote_descr = channel_tls_get_remote_descr_method; + chan->get_transport_name = channel_tls_get_transport_name_method; + chan->has_queued_writes = channel_tls_has_queued_writes_method; + chan->is_canonical = channel_tls_is_canonical_method; + chan->matches_extend_info = channel_tls_matches_extend_info_method; + chan->matches_target = channel_tls_matches_target_method; + chan->num_bytes_queued = channel_tls_num_bytes_queued_method; + chan->num_cells_writeable = channel_tls_num_cells_writeable_method; + chan->write_cell = channel_tls_write_cell_method; + chan->write_packed_cell = channel_tls_write_packed_cell_method; + chan->write_var_cell = channel_tls_write_var_cell_method; + + chan->cmux = circuitmux_alloc(); + /* We only have one policy for now so always set it to EWMA. */ + circuitmux_set_policy(chan->cmux, &ewma_policy); + } + + /** + * Start a new TLS channel. + * + * Launch a new OR connection to <b>addr</b>:<b>port</b> and expect to + * handshake with an OR with identity digest <b>id_digest</b>, and wrap + * it in a channel_tls_t. + */ + channel_t * + channel_tls_connect(const tor_addr_t *addr, uint16_t port, + const char *id_digest, + const ed25519_public_key_t *ed_id) + { + channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan)); + channel_t *chan = &(tlschan->base_); + + channel_tls_common_init(tlschan); + + log_debug(LD_CHANNEL, + "In channel_tls_connect() for channel %p " + "(global id %"PRIu64 ")", + tlschan, + (chan->global_identifier)); + + if (is_local_addr(addr)) { + log_debug(LD_CHANNEL, + "Marking new outgoing channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); + channel_mark_local(chan); + } else { + log_debug(LD_CHANNEL, + "Marking new outgoing channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); + channel_mark_remote(chan); + } + + channel_mark_outgoing(chan); + + /* Set up or_connection stuff */ + tlschan->conn = connection_or_connect(addr, port, id_digest, ed_id, tlschan); + /* connection_or_connect() will fill in tlschan->conn */ + if (!(tlschan->conn)) { + chan->reason_for_closing = CHANNEL_CLOSE_FOR_ERROR; + channel_change_state(chan, CHANNEL_STATE_ERROR); + goto err; + } + + log_debug(LD_CHANNEL, + "Got orconn %p for channel with global id %"PRIu64, + tlschan->conn, (chan->global_identifier)); + + goto done; + + err: + circuitmux_free(chan->cmux); + tor_free(tlschan); + chan = NULL; + + done: + /* If we got one, we should register it */ + if (chan) channel_register(chan); + + return chan; + } + + /** + * Return the current channel_tls_t listener. + * + * Returns the current channel listener for incoming TLS connections, or + * NULL if none has been established + */ + channel_listener_t * + channel_tls_get_listener(void) + { + return channel_tls_listener; + } + + /** + * Start a channel_tls_t listener if necessary. + * + * Return the current channel_tls_t listener, or start one if we haven't yet, + * and return that. + */ + channel_listener_t * + channel_tls_start_listener(void) + { + channel_listener_t *listener; + + if (!channel_tls_listener) { + listener = tor_malloc_zero(sizeof(*listener)); + channel_init_listener(listener); + listener->state = CHANNEL_LISTENER_STATE_LISTENING; + listener->close = channel_tls_listener_close_method; + listener->describe_transport = + channel_tls_listener_describe_transport_method; + + channel_tls_listener = listener; + + log_debug(LD_CHANNEL, + "Starting TLS channel listener %p with global id %"PRIu64, + listener, (listener->global_identifier)); + + channel_listener_register(listener); + } else listener = channel_tls_listener; + + return listener; + } + + /** + * Free everything on shutdown. + * + * Not much to do here, since channel_free_all() takes care of a lot, but let's + * get rid of the listener. + */ + void + channel_tls_free_all(void) + { + channel_listener_t *old_listener = NULL; + + log_debug(LD_CHANNEL, + "Shutting down TLS channels..."); + + if (channel_tls_listener) { + /* + * When we close it, channel_tls_listener will get nulled out, so save + * a pointer so we can free it. + */ + old_listener = channel_tls_listener; + log_debug(LD_CHANNEL, + "Closing channel_tls_listener with ID %"PRIu64 + " at %p.", + (old_listener->global_identifier), + old_listener); + channel_listener_unregister(old_listener); + channel_listener_mark_for_close(old_listener); + channel_listener_free(old_listener); + tor_assert(channel_tls_listener == NULL); + } + + log_debug(LD_CHANNEL, + "Done shutting down TLS channels"); + } + + /** + * Create a new channel around an incoming or_connection_t. + */ + channel_t * + channel_tls_handle_incoming(or_connection_t *orconn) + { + channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan)); + channel_t *chan = &(tlschan->base_); + + tor_assert(orconn); + tor_assert(!(orconn->chan)); + + channel_tls_common_init(tlschan); + + /* Link the channel and orconn to each other */ + tlschan->conn = orconn; + orconn->chan = tlschan; + + if (is_local_addr(&(TO_CONN(orconn)->addr))) { + log_debug(LD_CHANNEL, + "Marking new incoming channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); + channel_mark_local(chan); + } else { + log_debug(LD_CHANNEL, + "Marking new incoming channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); + channel_mark_remote(chan); + } + + channel_mark_incoming(chan); + + /* Register it */ + channel_register(chan); + + return chan; + } + + /********* + * Casts * + ********/ + + /** + * Cast a channel_tls_t to a channel_t. + */ + channel_t * + channel_tls_to_base(channel_tls_t *tlschan) + { + if (!tlschan) return NULL; + + return &(tlschan->base_); + } + + /** + * Cast a channel_t to a channel_tls_t, with appropriate type-checking + * asserts. + */ + channel_tls_t * + channel_tls_from_base(channel_t *chan) + { + if (!chan) return NULL; + + tor_assert(chan->magic == TLS_CHAN_MAGIC); + + return (channel_tls_t *)(chan); + } + + /******************************************** + * Method implementations for channel_tls_t * + *******************************************/ + + /** + * Close a channel_tls_t. + * + * This implements the close method for channel_tls_t. + */ + static void + channel_tls_close_method(channel_t *chan) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + + if (tlschan->conn) connection_or_close_normally(tlschan->conn, 1); + else { + /* Weird - we'll have to change the state ourselves, I guess */ + log_info(LD_CHANNEL, + "Tried to close channel_tls_t %p with NULL conn", + tlschan); + channel_change_state(chan, CHANNEL_STATE_ERROR); + } + } + + /** + * Describe the transport for a channel_tls_t. + * + * This returns the string "TLS channel on connection <id>" to the upper + * layer. + */ + static const char * + channel_tls_describe_transport_method(channel_t *chan) + { + static char *buf = NULL; + uint64_t id; + channel_tls_t *tlschan; + const char *rv = NULL; + + tor_assert(chan); + + tlschan = BASE_CHAN_TO_TLS(chan); + + if (tlschan->conn) { + id = TO_CONN(tlschan->conn)->global_identifier; + + if (buf) tor_free(buf); + tor_asprintf(&buf, + "TLS channel (connection %"PRIu64 ")", + (id)); + + rv = buf; + } else { + rv = "TLS channel (no connection)"; + } + + return rv; + } + + /** + * Free a channel_tls_t. + * + * This is called by the generic channel layer when freeing a channel_tls_t; + * this happens either on a channel which has already reached + * CHANNEL_STATE_CLOSED or CHANNEL_STATE_ERROR from channel_run_cleanup() or + * on shutdown from channel_free_all(). In the latter case we might still + * have an orconn active (which connection_free_all() will get to later), + * so we should null out its channel pointer now. + */ + static void + channel_tls_free_method(channel_t *chan) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + + if (tlschan->conn) { + tlschan->conn->chan = NULL; + tlschan->conn = NULL; + } + } + + /** + * Get an estimate of the average TLS overhead for the upper layer. + */ + static double + channel_tls_get_overhead_estimate_method(channel_t *chan) + { + double overhead = 1.0; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(tlschan->conn); + + /* Just return 1.0f if we don't have sensible data */ + if (tlschan->conn->bytes_xmitted > 0 && + tlschan->conn->bytes_xmitted_by_tls >= + tlschan->conn->bytes_xmitted) { + overhead = ((double)(tlschan->conn->bytes_xmitted_by_tls)) / + ((double)(tlschan->conn->bytes_xmitted)); + + /* + * Never estimate more than 2.0; otherwise we get silly large estimates + * at the very start of a new TLS connection. + */ + if (overhead > 2.0) + overhead = 2.0; + } + + log_debug(LD_CHANNEL, + "Estimated overhead ratio for TLS chan %"PRIu64 " is %f", + (chan->global_identifier), overhead); + + return overhead; + } + + /** + * Get the remote address of a channel_tls_t. + * + * This implements the get_remote_addr method for channel_tls_t; copy the + * remote endpoint of the channel to addr_out and return 1 (always + * succeeds for this transport). + */ + static int + channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out) + { + int rv = 0; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(addr_out); + + if (tlschan->conn) { + tor_addr_copy(addr_out, &(tlschan->conn->real_addr)); + rv = 1; + } else tor_addr_make_unspec(addr_out); + + return rv; + } + + /** + * Get the name of the pluggable transport used by a channel_tls_t. + * + * This implements the get_transport_name for channel_tls_t. If the + * channel uses a pluggable transport, copy its name to + * <b>transport_out</b> and return 0. If the channel did not use a + * pluggable transport, return -1. + */ + static int + channel_tls_get_transport_name_method(channel_t *chan, char **transport_out) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(transport_out); + tor_assert(tlschan->conn); + + if (!tlschan->conn->ext_or_transport) + return -1; + + *transport_out = tor_strdup(tlschan->conn->ext_or_transport); + return 0; + } + + /** + * Get endpoint description of a channel_tls_t. + * + * This implements the get_remote_descr method for channel_tls_t; it returns + * a text description of the remote endpoint of the channel suitable for use + * in log messages. The req parameter is 0 for the canonical address or 1 for + * the actual address seen. + */ + static const char * + channel_tls_get_remote_descr_method(channel_t *chan, int flags) + { + #define MAX_DESCR_LEN 32 + + static char buf[MAX_DESCR_LEN + 1]; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + connection_t *conn; + const char *answer = NULL; + char *addr_str; + + tor_assert(tlschan); + + if (tlschan->conn) { + conn = TO_CONN(tlschan->conn); + switch (flags) { + case 0: + /* Canonical address with port*/ + tor_snprintf(buf, MAX_DESCR_LEN + 1, + "%s:%u", conn->address, conn->port); + answer = buf; + break; + case GRD_FLAG_ORIGINAL: + /* Actual address with port */ + addr_str = tor_addr_to_str_dup(&(tlschan->conn->real_addr)); + tor_snprintf(buf, MAX_DESCR_LEN + 1, + "%s:%u", addr_str, conn->port); + tor_free(addr_str); + answer = buf; + break; + case GRD_FLAG_ADDR_ONLY: + /* Canonical address, no port */ + strlcpy(buf, conn->address, sizeof(buf)); + answer = buf; + break; + case GRD_FLAG_ORIGINAL|GRD_FLAG_ADDR_ONLY: + /* Actual address, no port */ + addr_str = tor_addr_to_str_dup(&(tlschan->conn->real_addr)); + strlcpy(buf, addr_str, sizeof(buf)); + tor_free(addr_str); + answer = buf; + break; + default: + /* Something's broken in channel.c */ + tor_assert_nonfatal_unreached_once(); + } + } else { + strlcpy(buf, "(No connection)", sizeof(buf)); + answer = buf; + } + + return answer; + } + + /** + * Tell the upper layer if we have queued writes. + * + * This implements the has_queued_writes method for channel_tls t_; it returns + * 1 iff we have queued writes on the outbuf of the underlying or_connection_t. + */ + static int + channel_tls_has_queued_writes_method(channel_t *chan) + { + size_t outbuf_len; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + if (!(tlschan->conn)) { + log_info(LD_CHANNEL, + "something called has_queued_writes on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + } + + outbuf_len = (tlschan->conn != NULL) ? + connection_get_outbuf_len(TO_CONN(tlschan->conn)) : + 0; + + return (outbuf_len > 0); + } + + /** + * Tell the upper layer if we're canonical. + * + * This implements the is_canonical method for channel_tls_t; if req is zero, + * it returns whether this is a canonical channel, and if it is one it returns + * whether that can be relied upon. + */ + static int + channel_tls_is_canonical_method(channel_t *chan, int req) + { + int answer = 0; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + + if (tlschan->conn) { + switch (req) { + case 0: + answer = tlschan->conn->is_canonical; + break; + case 1: + /* + * Is the is_canonical bit reliable? In protocols version 2 and up + * we get the canonical address from a NETINFO cell, but in older + * versions it might be based on an obsolete descriptor. + */ + answer = (tlschan->conn->link_proto >= 2); + break; + default: + /* This shouldn't happen; channel.c is broken if it does */ + tor_assert_nonfatal_unreached_once(); + } + } + /* else return 0 for tlschan->conn == NULL */ + + return answer; + } + + /** + * Check if we match an extend_info_t. + * + * This implements the matches_extend_info method for channel_tls_t; the upper + * layer wants to know if this channel matches an extend_info_t. + */ + static int + channel_tls_matches_extend_info_method(channel_t *chan, + extend_info_t *extend_info) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(extend_info); + + /* Never match if we have no conn */ + if (!(tlschan->conn)) { + log_info(LD_CHANNEL, + "something called matches_extend_info on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + return 0; + } + + return (tor_addr_eq(&(extend_info->addr), + &(TO_CONN(tlschan->conn)->addr)) && + (extend_info->port == TO_CONN(tlschan->conn)->port)); + } + + /** + * Check if we match a target address; return true iff we do. + * + * This implements the matches_target method for channel_tls t_; the upper + * layer wants to know if this channel matches a target address when extending + * a circuit. + */ + static int + channel_tls_matches_target_method(channel_t *chan, + const tor_addr_t *target) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(target); + + /* Never match if we have no conn */ + if (!(tlschan->conn)) { + log_info(LD_CHANNEL, + "something called matches_target on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + return 0; + } + + /* real_addr is the address this connection came from. + * base_.addr is updated by connection_or_init_conn_from_address() + * to be the address in the descriptor. It may be tempting to + * allow either address to be allowed, but if we did so, it would + * enable someone who steals a relay's keys to impersonate/MITM it + * from anywhere on the Internet! (Because they could make long-lived + * TLS connections from anywhere to all relays, and wait for them to + * be used for extends). + */ + return tor_addr_eq(&(tlschan->conn->real_addr), target); + } + + /** + * Tell the upper layer how many bytes we have queued and not yet + * sent. + */ + static size_t + channel_tls_num_bytes_queued_method(channel_t *chan) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + + tor_assert(tlschan); + tor_assert(tlschan->conn); + + return connection_get_outbuf_len(TO_CONN(tlschan->conn)); + } + + /** + * Tell the upper layer how many cells we can accept to write. + * + * This implements the num_cells_writeable method for channel_tls_t; it + * returns an estimate of the number of cells we can accept with + * channel_tls_write_*_cell(). + */ + static int + channel_tls_num_cells_writeable_method(channel_t *chan) + { + size_t outbuf_len; + ssize_t n; + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + size_t cell_network_size; + + tor_assert(tlschan); + tor_assert(tlschan->conn); + + cell_network_size = get_cell_network_size(tlschan->conn->wide_circ_ids); + outbuf_len = connection_get_outbuf_len(TO_CONN(tlschan->conn)); + /* Get the number of cells */ + n = CEIL_DIV(OR_CONN_HIGHWATER - outbuf_len, cell_network_size); + if (n < 0) n = 0; + #if SIZEOF_SIZE_T > SIZEOF_INT + if (n > INT_MAX) n = INT_MAX; + #endif + + return (int)n; + } + + /** + * Write a cell to a channel_tls_t. + * + * This implements the write_cell method for channel_tls_t; given a + * channel_tls_t and a cell_t, transmit the cell_t. + */ + static int + channel_tls_write_cell_method(channel_t *chan, cell_t *cell) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + int written = 0; + + tor_assert(tlschan); + tor_assert(cell); + + if (tlschan->conn) { + connection_or_write_cell_to_buf(cell, tlschan->conn); + ++written; + } else { + log_info(LD_CHANNEL, + "something called write_cell on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + } + + return written; + } + + /** + * Write a packed cell to a channel_tls_t. + * + * This implements the write_packed_cell method for channel_tls_t; given a + * channel_tls_t and a packed_cell_t, transmit the packed_cell_t. + * + * Return 0 on success or negative value on error. The caller must free the + * packed cell. + */ + static int + channel_tls_write_packed_cell_method(channel_t *chan, + packed_cell_t *packed_cell) + { + tor_assert(chan); + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + size_t cell_network_size = get_cell_network_size(chan->wide_circ_ids); + + tor_assert(tlschan); + tor_assert(packed_cell); + + if (tlschan->conn) { + connection_buf_add(packed_cell->body, cell_network_size, + TO_CONN(tlschan->conn)); + } else { + log_info(LD_CHANNEL, + "something called write_packed_cell on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + return -1; + } + + return 0; + } + + /** + * Write a variable-length cell to a channel_tls_t. + * + * This implements the write_var_cell method for channel_tls_t; given a + * channel_tls_t and a var_cell_t, transmit the var_cell_t. + */ + static int + channel_tls_write_var_cell_method(channel_t *chan, var_cell_t *var_cell) + { + channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan); + int written = 0; + + tor_assert(tlschan); + tor_assert(var_cell); + + if (tlschan->conn) { + connection_or_write_var_cell_to_buf(var_cell, tlschan->conn); + ++written; + } else { + log_info(LD_CHANNEL, + "something called write_var_cell on a tlschan " + "(%p with ID %"PRIu64 " but no conn", + chan, (chan->global_identifier)); + } + + return written; + } + + /************************************************* + * Method implementations for channel_listener_t * + ************************************************/ + + /** + * Close a channel_listener_t. + * + * This implements the close method for channel_listener_t. + */ + static void + channel_tls_listener_close_method(channel_listener_t *chan_l) + { + tor_assert(chan_l); + + /* + * Listeners we just go ahead and change state through to CLOSED, but + * make sure to check if they're channel_tls_listener to NULL it out. + */ + if (chan_l == channel_tls_listener) + channel_tls_listener = NULL; + + if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSING || + chan_l->state == CHANNEL_LISTENER_STATE_CLOSED || + chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) { + channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSING); + } + + if (chan_l->incoming_list) { + SMARTLIST_FOREACH_BEGIN(chan_l->incoming_list, + channel_t *, ichan) { + channel_mark_for_close(ichan); + } SMARTLIST_FOREACH_END(ichan); + + smartlist_free(chan_l->incoming_list); + chan_l->incoming_list = NULL; + } + + if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSED || + chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) { + channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSED); + } + } + + /** + * Describe the transport for a channel_listener_t. + * + * This returns the string "TLS channel (listening)" to the upper + * layer. + */ + static const char * + channel_tls_listener_describe_transport_method(channel_listener_t *chan_l) + { + tor_assert(chan_l); + + return "TLS channel (listening)"; + } + + /******************************************************* + * Functions for handling events on an or_connection_t * + ******************************************************/ + + /** + * Handle an orconn state change. + * + * This function will be called by connection_or.c when the or_connection_t + * associated with this channel_tls_t changes state. + */ + void + channel_tls_handle_state_change_on_orconn(channel_tls_t *chan, + or_connection_t *conn, + uint8_t old_state, + uint8_t state) + { + channel_t *base_chan; + + tor_assert(chan); + tor_assert(conn); + tor_assert(conn->chan == chan); + tor_assert(chan->conn == conn); + /* Shut the compiler up without triggering -Wtautological-compare */ + (void)old_state; + + base_chan = TLS_CHAN_TO_BASE(chan); + + /* Make sure the base connection state makes sense - shouldn't be error + * or closed. */ + + tor_assert(CHANNEL_IS_OPENING(base_chan) || + CHANNEL_IS_OPEN(base_chan) || + CHANNEL_IS_MAINT(base_chan) || + CHANNEL_IS_CLOSING(base_chan)); + + /* Did we just go to state open? */ + if (state == OR_CONN_STATE_OPEN) { + /* + * We can go to CHANNEL_STATE_OPEN from CHANNEL_STATE_OPENING or + * CHANNEL_STATE_MAINT on this. + */ + channel_change_state_open(base_chan); + /* We might have just become writeable; check and tell the scheduler */ + if (connection_or_num_cells_writeable(conn) > 0) { + scheduler_channel_wants_writes(base_chan); + } + } else { + /* + * Not open, so from CHANNEL_STATE_OPEN we go to CHANNEL_STATE_MAINT, + * otherwise no change. + */ + if (CHANNEL_IS_OPEN(base_chan)) { + channel_change_state(base_chan, CHANNEL_STATE_MAINT); + } + } + } + + #ifdef KEEP_TIMING_STATS + + /** + * Timing states wrapper. + * + * This is a wrapper function around the actual function that processes the + * <b>cell</b> that just arrived on <b>chan</b>. Increment <b>*time</b> + * by the number of microseconds used by the call to <b>*func(cell, chan)</b>. + */ + static void + channel_tls_time_process_cell(cell_t *cell, channel_tls_t *chan, int *time, + void (*func)(cell_t *, channel_tls_t *)) + { + struct timeval start, end; + long time_passed; + + tor_gettimeofday(&start); + + (*func)(cell, chan); + + tor_gettimeofday(&end); + time_passed = tv_udiff(&start, &end) ; + + if (time_passed > 10000) { /* more than 10ms */ + log_debug(LD_OR,"That call just took %ld ms.",time_passed/1000); + } + + if (time_passed < 0) { + log_info(LD_GENERAL,"That call took us back in time!"); + time_passed = 0; + } + + *time += time_passed; + } + #endif /* defined(KEEP_TIMING_STATS) */ + + /** + * Handle an incoming cell on a channel_tls_t. + * + * This is called from connection_or.c to handle an arriving cell; it checks + * for cell types specific to the handshake for this transport protocol and + * handles them, and queues all other cells to the channel_t layer, which + * eventually will hand them off to command.c. + * + * The channel layer itself decides whether the cell should be queued or + * can be handed off immediately to the upper-layer code. It is responsible + * for copying in the case that it queues; we merely pass pointers through + * which we get from connection_or_process_cells_from_inbuf(). + */ + void + channel_tls_handle_cell(cell_t *cell, or_connection_t *conn) + { + channel_tls_t *chan; + int handshaking; + + #ifdef KEEP_TIMING_STATS + #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN { \ + ++num ## tp; \ + channel_tls_time_process_cell(cl, cn, & tp ## time , \ + channel_tls_process_ ## tp ## _cell); \ + } STMT_END + #else /* !(defined(KEEP_TIMING_STATS)) */ + #define PROCESS_CELL(tp, cl, cn) channel_tls_process_ ## tp ## _cell(cl, cn) + #endif /* defined(KEEP_TIMING_STATS) */ + + tor_assert(cell); + tor_assert(conn); + + chan = conn->chan; + + if (!chan) { + log_warn(LD_CHANNEL, + "Got a cell_t on an OR connection with no channel"); + return; + } + + handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN); + + if (conn->base_.marked_for_close) + return; + + /* Reject all but VERSIONS and NETINFO when handshaking. */ + /* (VERSIONS should actually be impossible; it's variable-length.) */ + if (handshaking && cell->command != CELL_VERSIONS && + cell->command != CELL_NETINFO) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received unexpected cell command %d in chan state %s / " + "conn state %s; closing the connection.", + (int)cell->command, + channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state), + conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state)); + connection_or_close_for_error(conn, 0); + return; + } + + if (conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) + or_handshake_state_record_cell(conn, conn->handshake_state, cell, 1); + + /* We note that we're on the internet whenever we read a cell. This is + * a fast operation. */ + entry_guards_note_internet_connectivity(get_guard_selection_info()); + rep_hist_padding_count_read(PADDING_TYPE_TOTAL); + + if (TLS_CHAN_TO_BASE(chan)->currently_padding) + rep_hist_padding_count_read(PADDING_TYPE_ENABLED_TOTAL); + + switch (cell->command) { + case CELL_PADDING: + rep_hist_padding_count_read(PADDING_TYPE_CELL); + if (TLS_CHAN_TO_BASE(chan)->currently_padding) + rep_hist_padding_count_read(PADDING_TYPE_ENABLED_CELL); + ++stats_n_padding_cells_processed; + /* do nothing */ + break; + case CELL_VERSIONS: - tor_fragile_assert(); ++ /* A VERSIONS cell should always be a variable-length cell, and ++ * so should never reach this function (which handles constant-sized ++ * cells). But if the connection is using the (obsolete) v1 link ++ * protocol, all cells will be treated as constant-sized, and so ++ * it's possible we'll reach this code. ++ */ ++ log_fn(LOG_PROTOCOL_WARN, LD_CHANNEL, ++ "Received unexpected VERSIONS cell on a channel using link " ++ "protocol %d; ignoring.", conn->link_proto); + break; + case CELL_NETINFO: + ++stats_n_netinfo_cells_processed; + PROCESS_CELL(netinfo, cell, chan); + break; + case CELL_PADDING_NEGOTIATE: + ++stats_n_netinfo_cells_processed; + PROCESS_CELL(padding_negotiate, cell, chan); + break; + case CELL_CREATE: + case CELL_CREATE_FAST: + case CELL_CREATED: + case CELL_CREATED_FAST: + case CELL_RELAY: + case CELL_RELAY_EARLY: + case CELL_DESTROY: + case CELL_CREATE2: + case CELL_CREATED2: + /* + * These are all transport independent and we pass them up through the + * channel_t mechanism. They are ultimately handled in command.c. + */ + channel_process_cell(TLS_CHAN_TO_BASE(chan), cell); + break; + default: + log_fn(LOG_INFO, LD_PROTOCOL, + "Cell of unknown type (%d) received in channeltls.c. " + "Dropping.", + cell->command); + break; + } + } + + /** + * Handle an incoming variable-length cell on a channel_tls_t. + * + * Process a <b>var_cell</b> that was just received on <b>conn</b>. Keep + * internal statistics about how many of each cell we've processed so far + * this second, and the total number of microseconds it took to + * process each type of cell. All the var_cell commands are handshake- + * related and live below the channel_t layer, so no variable-length + * cells ever get delivered in the current implementation, but I've left + * the mechanism in place for future use. + * + * If we were handing them off to the upper layer, the channel_t queueing + * code would be responsible for memory management, and we'd just be passing + * pointers through from connection_or_process_cells_from_inbuf(). That + * caller always frees them after this function returns, so this function + * should never free var_cell. + */ + void + channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn) + { + channel_tls_t *chan; + + #ifdef KEEP_TIMING_STATS + /* how many of each cell have we seen so far this second? needs better + * name. */ + static int num_versions = 0, num_certs = 0; + static time_t current_second = 0; /* from previous calls to time */ + time_t now = time(NULL); + + if (current_second == 0) current_second = now; + if (now > current_second) { /* the second has rolled over */ + /* print stats */ + log_info(LD_OR, + "At end of second: %d versions (%d ms), %d certs (%d ms)", + num_versions, versions_time / ((now - current_second) * 1000), + num_certs, certs_time / ((now - current_second) * 1000)); + + num_versions = num_certs = 0; + versions_time = certs_time = 0; + + /* remember which second it is, for next time */ + current_second = now; + } + #endif /* defined(KEEP_TIMING_STATS) */ + + tor_assert(var_cell); + tor_assert(conn); + + chan = conn->chan; + + if (!chan) { + log_warn(LD_CHANNEL, + "Got a var_cell_t on an OR connection with no channel"); + return; + } + + if (TO_CONN(conn)->marked_for_close) + return; + + switch (TO_CONN(conn)->state) { + case OR_CONN_STATE_OR_HANDSHAKING_V2: + if (var_cell->command != CELL_VERSIONS) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received a cell with command %d in unexpected " + "orconn state "%s" [%d], channel state "%s" [%d]; " + "closing the connection.", + (int)(var_cell->command), + conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state), + TO_CONN(conn)->state, + channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state), + (int)(TLS_CHAN_TO_BASE(chan)->state)); + /* + * The code in connection_or.c will tell channel_t to close for + * error; it will go to CHANNEL_STATE_CLOSING, and then to + * CHANNEL_STATE_ERROR when conn is closed. + */ + connection_or_close_for_error(conn, 0); + return; + } + break; + case OR_CONN_STATE_TLS_HANDSHAKING: + /* If we're using bufferevents, it's entirely possible for us to + * notice "hey, data arrived!" before we notice "hey, the handshake + * finished!" And we need to be accepting both at once to handle both + * the v2 and v3 handshakes. */ + /* But that should be happening any longer've disabled bufferevents. */ + tor_assert_nonfatal_unreached_once(); + + /* fall through */ + case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING: + if (!(command_allowed_before_handshake(var_cell->command))) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received a cell with command %d in unexpected " + "orconn state "%s" [%d], channel state "%s" [%d]; " + "closing the connection.", + (int)(var_cell->command), + conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state), + (int)(TO_CONN(conn)->state), + channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state), + (int)(TLS_CHAN_TO_BASE(chan)->state)); + /* see above comment about CHANNEL_STATE_ERROR */ + connection_or_close_for_error(conn, 0); + return; + } else { + if (enter_v3_handshake_with_cell(var_cell, chan) < 0) + return; + } + break; + case OR_CONN_STATE_OR_HANDSHAKING_V3: + if (var_cell->command != CELL_AUTHENTICATE) + or_handshake_state_record_var_cell(conn, conn->handshake_state, + var_cell, 1); + break; /* Everything is allowed */ + case OR_CONN_STATE_OPEN: + if (conn->link_proto < 3) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received a variable-length cell with command %d in orconn " + "state %s [%d], channel state %s [%d] with link protocol %d; " + "ignoring it.", + (int)(var_cell->command), + conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state), + (int)(TO_CONN(conn)->state), + channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state), + (int)(TLS_CHAN_TO_BASE(chan)->state), + (int)(conn->link_proto)); + return; + } + break; + default: + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received var-length cell with command %d in unexpected " + "orconn state "%s" [%d], channel state "%s" [%d]; " + "ignoring it.", + (int)(var_cell->command), + conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state), + (int)(TO_CONN(conn)->state), + channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state), + (int)(TLS_CHAN_TO_BASE(chan)->state)); + return; + } + + /* We note that we're on the internet whenever we read a cell. This is + * a fast operation. */ + entry_guards_note_internet_connectivity(get_guard_selection_info()); + + /* Now handle the cell */ + + switch (var_cell->command) { + case CELL_VERSIONS: + ++stats_n_versions_cells_processed; + PROCESS_CELL(versions, var_cell, chan); + break; + case CELL_VPADDING: + ++stats_n_vpadding_cells_processed; + /* Do nothing */ + break; + case CELL_CERTS: + ++stats_n_certs_cells_processed; + PROCESS_CELL(certs, var_cell, chan); + break; + case CELL_AUTH_CHALLENGE: + ++stats_n_auth_challenge_cells_processed; + PROCESS_CELL(auth_challenge, var_cell, chan); + break; + case CELL_AUTHENTICATE: + ++stats_n_authenticate_cells_processed; + PROCESS_CELL(authenticate, var_cell, chan); + break; + case CELL_AUTHORIZE: + ++stats_n_authorize_cells_processed; + /* Ignored so far. */ + break; + default: + log_fn(LOG_INFO, LD_PROTOCOL, + "Variable-length cell of unknown type (%d) received.", + (int)(var_cell->command)); + break; + } + } + + /** + * Update channel marks after connection_or.c has changed an address. + * + * This is called from connection_or_init_conn_from_address() after the + * connection's _base.addr or real_addr fields have potentially been changed + * so we can recalculate the local mark. Notably, this happens when incoming + * connections are reverse-proxied and we only learn the real address of the + * remote router by looking it up in the consensus after we finish the + * handshake and know an authenticated identity digest. + */ + void + channel_tls_update_marks(or_connection_t *conn) + { + channel_t *chan = NULL; + + tor_assert(conn); + tor_assert(conn->chan); + + chan = TLS_CHAN_TO_BASE(conn->chan); + + if (is_local_addr(&(TO_CONN(conn)->addr))) { + if (!channel_is_local(chan)) { + log_debug(LD_CHANNEL, + "Marking channel %"PRIu64 " at %p as local", + (chan->global_identifier), chan); + channel_mark_local(chan); + } + } else { + if (channel_is_local(chan)) { + log_debug(LD_CHANNEL, + "Marking channel %"PRIu64 " at %p as remote", + (chan->global_identifier), chan); + channel_mark_remote(chan); + } + } + } + + /** + * Check if this cell type is allowed before the handshake is finished. + * + * Return true if <b>command</b> is a cell command that's allowed to start a + * V3 handshake. + */ + static int + command_allowed_before_handshake(uint8_t command) + { + switch (command) { + case CELL_VERSIONS: + case CELL_VPADDING: + case CELL_AUTHORIZE: + return 1; + default: + return 0; + } + } + + /** + * Start a V3 handshake on an incoming connection. + * + * Called when we as a server receive an appropriate cell while waiting + * either for a cell or a TLS handshake. Set the connection's state to + * "handshaking_v3', initializes the or_handshake_state field as needed, + * and add the cell to the hash of incoming cells.) + */ + static int + enter_v3_handshake_with_cell(var_cell_t *cell, channel_tls_t *chan) + { + int started_here = 0; + + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + started_here = connection_or_nonopen_was_started_here(chan->conn); + + tor_assert(TO_CONN(chan->conn)->state == OR_CONN_STATE_TLS_HANDSHAKING || + TO_CONN(chan->conn)->state == + OR_CONN_STATE_TLS_SERVER_RENEGOTIATING); + + if (started_here) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a cell while TLS-handshaking, not in " + "OR_HANDSHAKING_V3, on a connection we originated."); + } + connection_or_block_renegotiation(chan->conn); + chan->conn->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3; + if (connection_init_or_handshake_state(chan->conn, started_here) < 0) { + connection_or_close_for_error(chan->conn, 0); + return -1; + } + or_handshake_state_record_var_cell(chan->conn, + chan->conn->handshake_state, cell, 1); + return 0; + } + + /** + * Process a 'versions' cell. + * + * This function is called to handle an incoming VERSIONS cell; the current + * link protocol version must be 0 to indicate that no version has yet been + * negotiated. We compare the versions in the cell to the list of versions + * we support, pick the highest version we have in common, and continue the + * negotiation from there. + */ + static void + channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan) + { + int highest_supported_version = 0; + int started_here = 0; + + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + if ((cell->payload_len % 2) == 1) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a VERSION cell with odd payload length %d; " + "closing connection.",cell->payload_len); + connection_or_close_for_error(chan->conn, 0); + return; + } + + started_here = connection_or_nonopen_was_started_here(chan->conn); + + if (chan->conn->link_proto != 0 || + (chan->conn->handshake_state && + chan->conn->handshake_state->received_versions)) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a VERSIONS cell on a connection with its version " + "already set to %d; dropping", + (int)(chan->conn->link_proto)); + return; + } + switch (chan->conn->base_.state) + { + case OR_CONN_STATE_OR_HANDSHAKING_V2: + case OR_CONN_STATE_OR_HANDSHAKING_V3: + break; + case OR_CONN_STATE_TLS_HANDSHAKING: + case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING: + default: + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "VERSIONS cell while in unexpected state"); + return; + } + + tor_assert(chan->conn->handshake_state); + + { + int i; + const uint8_t *cp = cell->payload; + for (i = 0; i < cell->payload_len / 2; ++i, cp += 2) { + uint16_t v = ntohs(get_uint16(cp)); + if (is_or_protocol_version_known(v) && v > highest_supported_version) + highest_supported_version = v; + } + } + if (!highest_supported_version) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Couldn't find a version in common between my version list and the " + "list in the VERSIONS cell; closing connection."); + connection_or_close_for_error(chan->conn, 0); + return; + } else if (highest_supported_version == 1) { + /* Negotiating version 1 makes no sense, since version 1 has no VERSIONS + * cells. */ + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Used version negotiation protocol to negotiate a v1 connection. " + "That's crazily non-compliant. Closing connection."); + connection_or_close_for_error(chan->conn, 0); + return; + } else if (highest_supported_version < 3 && + chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Negotiated link protocol 2 or lower after doing a v3 TLS " + "handshake. Closing connection."); + connection_or_close_for_error(chan->conn, 0); + return; + } else if (highest_supported_version != 2 && + chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V2) { + /* XXXX This should eventually be a log_protocol_warn */ + log_fn(LOG_WARN, LD_OR, + "Negotiated link with non-2 protocol after doing a v2 TLS " + "handshake with %s. Closing connection.", + fmt_addr(&chan->conn->base_.addr)); + connection_or_close_for_error(chan->conn, 0); + return; + } + + rep_hist_note_negotiated_link_proto(highest_supported_version, started_here); + + chan->conn->link_proto = highest_supported_version; + chan->conn->handshake_state->received_versions = 1; + + if (chan->conn->link_proto == 2) { + log_info(LD_OR, + "Negotiated version %d with %s:%d; sending NETINFO.", + highest_supported_version, + safe_str_client(chan->conn->base_.address), + chan->conn->base_.port); + + if (connection_or_send_netinfo(chan->conn) < 0) { + connection_or_close_for_error(chan->conn, 0); + return; + } + } else { + const int send_versions = !started_here; + /* If we want to authenticate, send a CERTS cell */ + const int send_certs = !started_here || public_server_mode(get_options()); + /* If we're a host that got a connection, ask for authentication. */ + const int send_chall = !started_here; + /* If our certs cell will authenticate us, we can send a netinfo cell + * right now. */ + const int send_netinfo = !started_here; + const int send_any = + send_versions || send_certs || send_chall || send_netinfo; + tor_assert(chan->conn->link_proto >= 3); + + log_info(LD_OR, + "Negotiated version %d with %s:%d; %s%s%s%s%s", + highest_supported_version, + safe_str_client(chan->conn->base_.address), + chan->conn->base_.port, + send_any ? "Sending cells:" : "Waiting for CERTS cell", + send_versions ? " VERSIONS" : "", + send_certs ? " CERTS" : "", + send_chall ? " AUTH_CHALLENGE" : "", + send_netinfo ? " NETINFO" : ""); + + #ifdef DISABLE_V3_LINKPROTO_SERVERSIDE + if (1) { + connection_or_close_normally(chan->conn, 1); + return; + } + #endif /* defined(DISABLE_V3_LINKPROTO_SERVERSIDE) */ + + if (send_versions) { + if (connection_or_send_versions(chan->conn, 1) < 0) { + log_warn(LD_OR, "Couldn't send versions cell"); + connection_or_close_for_error(chan->conn, 0); + return; + } + } + + /* We set this after sending the versions cell. */ + /*XXXXX symbolic const.*/ + TLS_CHAN_TO_BASE(chan)->wide_circ_ids = + chan->conn->link_proto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS; + chan->conn->wide_circ_ids = TLS_CHAN_TO_BASE(chan)->wide_circ_ids; + + TLS_CHAN_TO_BASE(chan)->padding_enabled = + chan->conn->link_proto >= MIN_LINK_PROTO_FOR_CHANNEL_PADDING; + + if (send_certs) { + if (connection_or_send_certs_cell(chan->conn) < 0) { + log_warn(LD_OR, "Couldn't send certs cell"); + connection_or_close_for_error(chan->conn, 0); + return; + } + } + if (send_chall) { + if (connection_or_send_auth_challenge_cell(chan->conn) < 0) { + log_warn(LD_OR, "Couldn't send auth_challenge cell"); + connection_or_close_for_error(chan->conn, 0); + return; + } + } + if (send_netinfo) { + if (connection_or_send_netinfo(chan->conn) < 0) { + log_warn(LD_OR, "Couldn't send netinfo cell"); + connection_or_close_for_error(chan->conn, 0); + return; + } + } + } + } + + /** + * Process a 'padding_negotiate' cell. + * + * This function is called to handle an incoming PADDING_NEGOTIATE cell; + * enable or disable padding accordingly, and read and act on its timeout + * value contents. + */ + static void + channel_tls_process_padding_negotiate_cell(cell_t *cell, channel_tls_t *chan) + { + channelpadding_negotiate_t *negotiation; + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + if (chan->conn->link_proto < MIN_LINK_PROTO_FOR_CHANNEL_PADDING) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a PADDING_NEGOTIATE cell on v%d connection; dropping.", + chan->conn->link_proto); + return; + } + + if (channelpadding_negotiate_parse(&negotiation, cell->payload, + CELL_PAYLOAD_SIZE) < 0) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received malformed PADDING_NEGOTIATE cell on v%d connection; " + "dropping.", chan->conn->link_proto); + + return; + } + + channelpadding_update_padding_for_channel(TLS_CHAN_TO_BASE(chan), + negotiation); + + channelpadding_negotiate_free(negotiation); + } + + /** + * Helper: compute the absolute value of a time_t. + * + * (we need this because labs() doesn't always work for time_t, since + * long can be shorter than time_t.) + */ + static inline time_t + time_abs(time_t val) + { + return (val < 0) ? -val : val; + } + + /** + * Process a 'netinfo' cell + * + * This function is called to handle an incoming NETINFO cell; read and act + * on its contents, and set the connection state to "open". + */ + static void + channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan) + { + time_t timestamp; + uint8_t my_addr_type; + uint8_t my_addr_len; + const uint8_t *my_addr_ptr; + const uint8_t *cp, *end; + uint8_t n_other_addrs; + time_t now = time(NULL); + const routerinfo_t *me = router_get_my_routerinfo(); + + time_t apparent_skew = 0; + tor_addr_t my_apparent_addr = TOR_ADDR_NULL; + int started_here = 0; + const char *identity_digest = NULL; + + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + if (chan->conn->link_proto < 2) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a NETINFO cell on %s connection; dropping.", + chan->conn->link_proto == 0 ? "non-versioned" : "a v1"); + return; + } + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V2 && + chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a NETINFO cell on non-handshaking connection; dropping."); + return; + } + tor_assert(chan->conn->handshake_state && + chan->conn->handshake_state->received_versions); + started_here = connection_or_nonopen_was_started_here(chan->conn); + identity_digest = chan->conn->identity_digest; + + if (chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) { + tor_assert(chan->conn->link_proto >= 3); + if (started_here) { + if (!(chan->conn->handshake_state->authenticated)) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Got a NETINFO cell from server, " + "but no authentication. Closing the connection."); + connection_or_close_for_error(chan->conn, 0); + return; + } + } else { + /* we're the server. If the client never authenticated, we have + some housekeeping to do.*/ + if (!(chan->conn->handshake_state->authenticated)) { + tor_assert(tor_digest_is_zero( + (const char*)(chan->conn->handshake_state-> + authenticated_rsa_peer_id))); + tor_assert(tor_mem_is_zero( + (const char*)(chan->conn->handshake_state-> + authenticated_ed25519_peer_id.pubkey), 32)); + /* If the client never authenticated, it's a tor client or bridge + * relay, and we must not use it for EXTEND requests (nor could we, as + * there are no authenticated peer IDs) */ + channel_mark_client(TLS_CHAN_TO_BASE(chan)); + channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL, + chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS); + + connection_or_init_conn_from_address(chan->conn, + &(chan->conn->base_.addr), + chan->conn->base_.port, + /* zero, checked above */ + (const char*)(chan->conn->handshake_state-> + authenticated_rsa_peer_id), + NULL, /* Ed25519 ID: Also checked as zero */ + 0); + } + } + } + + /* Decode the cell. */ + timestamp = ntohl(get_uint32(cell->payload)); + const time_t sent_versions_at = + chan->conn->handshake_state->sent_versions_at; + if (now > sent_versions_at && (now - sent_versions_at) < 180) { + /* If we have gotten the NETINFO cell reasonably soon after having + * sent our VERSIONS cell, maybe we can learn skew information from it. */ + apparent_skew = now - timestamp; + } + + my_addr_type = (uint8_t) cell->payload[4]; + my_addr_len = (uint8_t) cell->payload[5]; + my_addr_ptr = (uint8_t*) cell->payload + 6; + end = cell->payload + CELL_PAYLOAD_SIZE; + cp = cell->payload + 6 + my_addr_len; + + /* We used to check: + * if (my_addr_len >= CELL_PAYLOAD_SIZE - 6) { + * + * This is actually never going to happen, since my_addr_len is at most 255, + * and CELL_PAYLOAD_LEN - 6 is 503. So we know that cp is < end. */ + + if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) { + tor_addr_from_ipv4n(&my_apparent_addr, get_uint32(my_addr_ptr)); + + if (!get_options()->BridgeRelay && me && + get_uint32(my_addr_ptr) == htonl(me->addr)) { + TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer = 1; + } + + } else if (my_addr_type == RESOLVED_TYPE_IPV6 && my_addr_len == 16) { + tor_addr_from_ipv6_bytes(&my_apparent_addr, (const char *) my_addr_ptr); + + if (!get_options()->BridgeRelay && me && + !tor_addr_is_null(&me->ipv6_addr) && + tor_addr_eq(&my_apparent_addr, &me->ipv6_addr)) { + TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer = 1; + } + } + + n_other_addrs = (uint8_t) *cp++; + while (n_other_addrs && cp < end-2) { + /* Consider all the other addresses; if any matches, this connection is + * "canonical." */ + tor_addr_t addr; + const uint8_t *next = + decode_address_from_payload(&addr, cp, (int)(end-cp)); + if (next == NULL) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Bad address in netinfo cell; closing connection."); + connection_or_close_for_error(chan->conn, 0); + return; + } + /* A relay can connect from anywhere and be canonical, so + * long as it tells you from where it came. This may sound a bit + * concerning... but that's what "canonical" means: that the + * address is one that the relay itself has claimed. The relay + * might be doing something funny, but nobody else is doing a MITM + * on the relay's TCP. + */ + if (tor_addr_eq(&addr, &(chan->conn->real_addr))) { + connection_or_set_canonical(chan->conn, 1); + break; + } + cp = next; + --n_other_addrs; + } + + if (me && !TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer && + channel_is_canonical(TLS_CHAN_TO_BASE(chan))) { + const char *descr = + TLS_CHAN_TO_BASE(chan)->get_remote_descr(TLS_CHAN_TO_BASE(chan), 0); + log_info(LD_OR, + "We made a connection to a relay at %s (fp=%s) but we think " + "they will not consider this connection canonical. They " + "think we are at %s, but we think its %s.", + safe_str(descr), + safe_str(hex_str(identity_digest, DIGEST_LEN)), + safe_str(tor_addr_is_null(&my_apparent_addr) ? + "<none>" : fmt_and_decorate_addr(&my_apparent_addr)), + safe_str(fmt_addr32(me->addr))); + } + + /* Act on apparent skew. */ + /** Warn when we get a netinfo skew with at least this value. */ + #define NETINFO_NOTICE_SKEW 3600 + if (time_abs(apparent_skew) > NETINFO_NOTICE_SKEW && + (started_here || + connection_or_digest_is_known_relay(chan->conn->identity_digest))) { + int trusted = router_digest_is_trusted_dir(chan->conn->identity_digest); + clock_skew_warning(TO_CONN(chan->conn), apparent_skew, trusted, LD_GENERAL, + "NETINFO cell", "OR"); + } + + /* XXX maybe act on my_apparent_addr, if the source is sufficiently + * trustworthy. */ + + if (! chan->conn->handshake_state->sent_netinfo) { + /* If we were prepared to authenticate, but we never got an AUTH_CHALLENGE + * cell, then we would not previously have sent a NETINFO cell. Do so + * now. */ + if (connection_or_send_netinfo(chan->conn) < 0) { + connection_or_close_for_error(chan->conn, 0); + return; + } + } + + if (connection_or_set_state_open(chan->conn) < 0) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Got good NETINFO cell from %s:%d; but " + "was unable to make the OR connection become open.", + safe_str_client(chan->conn->base_.address), + chan->conn->base_.port); + connection_or_close_for_error(chan->conn, 0); + } else { + log_info(LD_OR, + "Got good NETINFO cell from %s:%d; OR connection is now " + "open, using protocol version %d. Its ID digest is %s. " + "Our address is apparently %s.", + safe_str_client(chan->conn->base_.address), + chan->conn->base_.port, + (int)(chan->conn->link_proto), + hex_str(identity_digest, DIGEST_LEN), + tor_addr_is_null(&my_apparent_addr) ? + "<none>" : + safe_str_client(fmt_and_decorate_addr(&my_apparent_addr))); + } + assert_connection_ok(TO_CONN(chan->conn),time(NULL)); + } + + /** Types of certificates that we know how to parse from CERTS cells. Each + * type corresponds to a different encoding format. */ + typedef enum cert_encoding_t { + CERT_ENCODING_UNKNOWN, /**< We don't recognize this. */ + CERT_ENCODING_X509, /**< It's an RSA key, signed with RSA, encoded in x509. + * (Actually, it might not be RSA. We test that later.) */ + CERT_ENCODING_ED25519, /**< It's something signed with an Ed25519 key, + * encoded asa a tor_cert_t.*/ + CERT_ENCODING_RSA_CROSSCERT, /**< It's an Ed key signed with an RSA key. */ + } cert_encoding_t; + + /** + * Given one of the certificate type codes used in a CERTS cell, + * return the corresponding cert_encoding_t that we should use to parse + * the certificate. + */ + static cert_encoding_t + certs_cell_typenum_to_cert_type(int typenum) + { + switch (typenum) { + case CERTTYPE_RSA1024_ID_LINK: + case CERTTYPE_RSA1024_ID_ID: + case CERTTYPE_RSA1024_ID_AUTH: + return CERT_ENCODING_X509; + case CERTTYPE_ED_ID_SIGN: + case CERTTYPE_ED_SIGN_LINK: + case CERTTYPE_ED_SIGN_AUTH: + return CERT_ENCODING_ED25519; + case CERTTYPE_RSA1024_ID_EDID: + return CERT_ENCODING_RSA_CROSSCERT; + default: + return CERT_ENCODING_UNKNOWN; + } + } + + /** + * Process a CERTS cell from a channel. + * + * This function is called to process an incoming CERTS cell on a + * channel_tls_t: + * + * If the other side should not have sent us a CERTS cell, or the cell is + * malformed, or it is supposed to authenticate the TLS key but it doesn't, + * then mark the connection. + * + * If the cell has a good cert chain and we're doing a v3 handshake, then + * store the certificates in or_handshake_state. If this is the client side + * of the connection, we then authenticate the server or mark the connection. + * If it's the server side, wait for an AUTHENTICATE cell. + */ + STATIC void + channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan) + { + #define MAX_CERT_TYPE_WANTED CERTTYPE_RSA1024_ID_EDID + /* These arrays will be sparse, since a cert type can be at most one + * of ed/x509 */ + tor_x509_cert_t *x509_certs[MAX_CERT_TYPE_WANTED + 1]; + tor_cert_t *ed_certs[MAX_CERT_TYPE_WANTED + 1]; + uint8_t *rsa_ed_cc_cert = NULL; + size_t rsa_ed_cc_cert_len = 0; + + int n_certs, i; + certs_cell_t *cc = NULL; + + int send_netinfo = 0, started_here = 0; + + memset(x509_certs, 0, sizeof(x509_certs)); + memset(ed_certs, 0, sizeof(ed_certs)); + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + #define ERR(s) \ + do { \ + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, \ + "Received a bad CERTS cell from %s:%d: %s", \ + safe_str(chan->conn->base_.address), \ + chan->conn->base_.port, (s)); \ + connection_or_close_for_error(chan->conn, 0); \ + goto err; \ + } while (0) + + /* Can't use connection_or_nonopen_was_started_here(); its conn->tls + * check looks like it breaks + * test_link_handshake_recv_certs_ok_server(). */ + started_here = chan->conn->handshake_state->started_here; + + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) + ERR("We're not doing a v3 handshake!"); + if (chan->conn->link_proto < 3) + ERR("We're not using link protocol >= 3"); + if (chan->conn->handshake_state->received_certs_cell) + ERR("We already got one"); + if (chan->conn->handshake_state->authenticated) { + /* Should be unreachable, but let's make sure. */ + ERR("We're already authenticated!"); + } + if (cell->payload_len < 1) + ERR("It had no body"); + if (cell->circ_id) + ERR("It had a nonzero circuit ID"); + + if (certs_cell_parse(&cc, cell->payload, cell->payload_len) < 0) + ERR("It couldn't be parsed."); + + n_certs = cc->n_certs; + + for (i = 0; i < n_certs; ++i) { + certs_cell_cert_t *c = certs_cell_get_certs(cc, i); + + uint16_t cert_type = c->cert_type; + uint16_t cert_len = c->cert_len; + uint8_t *cert_body = certs_cell_cert_getarray_body(c); + + if (cert_type > MAX_CERT_TYPE_WANTED) + continue; + const cert_encoding_t ct = certs_cell_typenum_to_cert_type(cert_type); + switch (ct) { + default: + case CERT_ENCODING_UNKNOWN: + break; + case CERT_ENCODING_X509: { + tor_x509_cert_t *x509_cert = tor_x509_cert_decode(cert_body, cert_len); + if (!x509_cert) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received undecodable certificate in CERTS cell from %s:%d", + safe_str(chan->conn->base_.address), + chan->conn->base_.port); + } else { + if (x509_certs[cert_type]) { + tor_x509_cert_free(x509_cert); + ERR("Duplicate x509 certificate"); + } else { + x509_certs[cert_type] = x509_cert; + } + } + break; + } + case CERT_ENCODING_ED25519: { + tor_cert_t *ed_cert = tor_cert_parse(cert_body, cert_len); + if (!ed_cert) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Received undecodable Ed certificate " + "in CERTS cell from %s:%d", + safe_str(chan->conn->base_.address), + chan->conn->base_.port); + } else { + if (ed_certs[cert_type]) { + tor_cert_free(ed_cert); + ERR("Duplicate Ed25519 certificate"); + } else { + ed_certs[cert_type] = ed_cert; + } + } + break; + } + + case CERT_ENCODING_RSA_CROSSCERT: { + if (rsa_ed_cc_cert) { + ERR("Duplicate RSA->Ed25519 crosscert"); + } else { + rsa_ed_cc_cert = tor_memdup(cert_body, cert_len); + rsa_ed_cc_cert_len = cert_len; + } + break; + } + } + } + + /* Move the certificates we (might) want into the handshake_state->certs + * structure. */ + tor_x509_cert_t *id_cert = x509_certs[CERTTYPE_RSA1024_ID_ID]; + tor_x509_cert_t *auth_cert = x509_certs[CERTTYPE_RSA1024_ID_AUTH]; + tor_x509_cert_t *link_cert = x509_certs[CERTTYPE_RSA1024_ID_LINK]; + chan->conn->handshake_state->certs->auth_cert = auth_cert; + chan->conn->handshake_state->certs->link_cert = link_cert; + chan->conn->handshake_state->certs->id_cert = id_cert; + x509_certs[CERTTYPE_RSA1024_ID_ID] = + x509_certs[CERTTYPE_RSA1024_ID_AUTH] = + x509_certs[CERTTYPE_RSA1024_ID_LINK] = NULL; + + tor_cert_t *ed_id_sign = ed_certs[CERTTYPE_ED_ID_SIGN]; + tor_cert_t *ed_sign_link = ed_certs[CERTTYPE_ED_SIGN_LINK]; + tor_cert_t *ed_sign_auth = ed_certs[CERTTYPE_ED_SIGN_AUTH]; + chan->conn->handshake_state->certs->ed_id_sign = ed_id_sign; + chan->conn->handshake_state->certs->ed_sign_link = ed_sign_link; + chan->conn->handshake_state->certs->ed_sign_auth = ed_sign_auth; + ed_certs[CERTTYPE_ED_ID_SIGN] = + ed_certs[CERTTYPE_ED_SIGN_LINK] = + ed_certs[CERTTYPE_ED_SIGN_AUTH] = NULL; + + chan->conn->handshake_state->certs->ed_rsa_crosscert = rsa_ed_cc_cert; + chan->conn->handshake_state->certs->ed_rsa_crosscert_len = + rsa_ed_cc_cert_len; + rsa_ed_cc_cert = NULL; + + int severity; + /* Note that this warns more loudly about time and validity if we were + * _trying_ to connect to an authority, not necessarily if we _did_ connect + * to one. */ + if (started_here && + router_digest_is_trusted_dir(TLS_CHAN_TO_BASE(chan)->identity_digest)) + severity = LOG_WARN; + else + severity = LOG_PROTOCOL_WARN; + + const ed25519_public_key_t *checked_ed_id = NULL; + const common_digests_t *checked_rsa_id = NULL; + or_handshake_certs_check_both(severity, + chan->conn->handshake_state->certs, + chan->conn->tls, + time(NULL), + &checked_ed_id, + &checked_rsa_id); + + if (!checked_rsa_id) + ERR("Invalid certificate chain!"); + + if (started_here) { + /* No more information is needed. */ + + chan->conn->handshake_state->authenticated = 1; + chan->conn->handshake_state->authenticated_rsa = 1; + { + const common_digests_t *id_digests = checked_rsa_id; + crypto_pk_t *identity_rcvd; + if (!id_digests) + ERR("Couldn't compute digests for key in ID cert"); + + identity_rcvd = tor_tls_cert_get_key(id_cert); + if (!identity_rcvd) { + ERR("Couldn't get RSA key from ID cert."); + } + memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id, + id_digests->d[DIGEST_SHA1], DIGEST_LEN); + channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd, + chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS); + crypto_pk_free(identity_rcvd); + } + + if (checked_ed_id) { + chan->conn->handshake_state->authenticated_ed25519 = 1; + memcpy(&chan->conn->handshake_state->authenticated_ed25519_peer_id, + checked_ed_id, sizeof(ed25519_public_key_t)); + } + + log_debug(LD_HANDSHAKE, "calling client_learned_peer_id from " + "process_certs_cell"); + + if (connection_or_client_learned_peer_id(chan->conn, + chan->conn->handshake_state->authenticated_rsa_peer_id, + checked_ed_id) < 0) + ERR("Problem setting or checking peer id"); + + log_info(LD_HANDSHAKE, + "Got some good certificates from %s:%d: Authenticated it with " + "RSA%s", + safe_str(chan->conn->base_.address), chan->conn->base_.port, + checked_ed_id ? " and Ed25519" : ""); + + if (!public_server_mode(get_options())) { + /* If we initiated the connection and we are not a public server, we + * aren't planning to authenticate at all. At this point we know who we + * are talking to, so we can just send a netinfo now. */ + send_netinfo = 1; + } + } else { + /* We can't call it authenticated till we see an AUTHENTICATE cell. */ + log_info(LD_OR, + "Got some good RSA%s certificates from %s:%d. " + "Waiting for AUTHENTICATE.", + checked_ed_id ? " and Ed25519" : "", + safe_str(chan->conn->base_.address), + chan->conn->base_.port); + /* XXXX check more stuff? */ + } + + chan->conn->handshake_state->received_certs_cell = 1; + + if (send_netinfo) { + if (connection_or_send_netinfo(chan->conn) < 0) { + log_warn(LD_OR, "Couldn't send netinfo cell"); + connection_or_close_for_error(chan->conn, 0); + goto err; + } + } + + err: + for (unsigned u = 0; u < ARRAY_LENGTH(x509_certs); ++u) { + tor_x509_cert_free(x509_certs[u]); + } + for (unsigned u = 0; u < ARRAY_LENGTH(ed_certs); ++u) { + tor_cert_free(ed_certs[u]); + } + tor_free(rsa_ed_cc_cert); + certs_cell_free(cc); + #undef ERR + } + + /** + * Process an AUTH_CHALLENGE cell from a channel_tls_t. + * + * This function is called to handle an incoming AUTH_CHALLENGE cell on a + * channel_tls_t; if we weren't supposed to get one (for example, because we're + * not the originator of the channel), or it's ill-formed, or we aren't doing + * a v3 handshake, mark the channel. If the cell is well-formed but we don't + * want to authenticate, just drop it. If the cell is well-formed *and* we + * want to authenticate, send an AUTHENTICATE cell and then a NETINFO cell. + */ + STATIC void + channel_tls_process_auth_challenge_cell(var_cell_t *cell, channel_tls_t *chan) + { + int n_types, i, use_type = -1; + auth_challenge_cell_t *ac = NULL; + + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + #define ERR(s) \ + do { \ + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, \ + "Received a bad AUTH_CHALLENGE cell from %s:%d: %s", \ + safe_str(chan->conn->base_.address), \ + chan->conn->base_.port, (s)); \ + connection_or_close_for_error(chan->conn, 0); \ + goto done; \ + } while (0) + + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) + ERR("We're not currently doing a v3 handshake"); + if (chan->conn->link_proto < 3) + ERR("We're not using link protocol >= 3"); + if (!(chan->conn->handshake_state->started_here)) + ERR("We didn't originate this connection"); + if (chan->conn->handshake_state->received_auth_challenge) + ERR("We already received one"); + if (!(chan->conn->handshake_state->received_certs_cell)) + ERR("We haven't gotten a CERTS cell yet"); + if (cell->circ_id) + ERR("It had a nonzero circuit ID"); + + if (auth_challenge_cell_parse(&ac, cell->payload, cell->payload_len) < 0) + ERR("It was not well-formed."); + + n_types = ac->n_methods; + + /* Now see if there is an authentication type we can use */ + for (i = 0; i < n_types; ++i) { + uint16_t authtype = auth_challenge_cell_get_methods(ac, i); + if (authchallenge_type_is_supported(authtype)) { + if (use_type == -1 || + authchallenge_type_is_better(authtype, use_type)) { + use_type = authtype; + } + } + } + + chan->conn->handshake_state->received_auth_challenge = 1; + + if (! public_server_mode(get_options())) { + /* If we're not a public server then we don't want to authenticate on a + connection we originated, and we already sent a NETINFO cell when we + got the CERTS cell. We have nothing more to do. */ + goto done; + } + + if (use_type >= 0) { + log_info(LD_OR, + "Got an AUTH_CHALLENGE cell from %s:%d: Sending " + "authentication type %d", + safe_str(chan->conn->base_.address), + chan->conn->base_.port, + use_type); + + if (connection_or_send_authenticate_cell(chan->conn, use_type) < 0) { + log_warn(LD_OR, + "Couldn't send authenticate cell"); + connection_or_close_for_error(chan->conn, 0); + goto done; + } + } else { + log_info(LD_OR, + "Got an AUTH_CHALLENGE cell from %s:%d, but we don't " + "know any of its authentication types. Not authenticating.", + safe_str(chan->conn->base_.address), + chan->conn->base_.port); + } + + if (connection_or_send_netinfo(chan->conn) < 0) { + log_warn(LD_OR, "Couldn't send netinfo cell"); + connection_or_close_for_error(chan->conn, 0); + goto done; + } + + done: + auth_challenge_cell_free(ac); + + #undef ERR + } + + /** + * Process an AUTHENTICATE cell from a channel_tls_t. + * + * If it's ill-formed or we weren't supposed to get one or we're not doing a + * v3 handshake, then mark the connection. If it does not authenticate the + * other side of the connection successfully (because it isn't signed right, + * we didn't get a CERTS cell, etc) mark the connection. Otherwise, accept + * the identity of the router on the other side of the connection. + */ + STATIC void + channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan) + { + var_cell_t *expected_cell = NULL; + const uint8_t *auth; + int authlen; + int authtype; + int bodylen; + + tor_assert(cell); + tor_assert(chan); + tor_assert(chan->conn); + + #define ERR(s) \ + do { \ + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, \ + "Received a bad AUTHENTICATE cell from %s:%d: %s", \ + safe_str(chan->conn->base_.address), \ + chan->conn->base_.port, (s)); \ + connection_or_close_for_error(chan->conn, 0); \ + var_cell_free(expected_cell); \ + return; \ + } while (0) + + if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) + ERR("We're not doing a v3 handshake"); + if (chan->conn->link_proto < 3) + ERR("We're not using link protocol >= 3"); + if (chan->conn->handshake_state->started_here) + ERR("We originated this connection"); + if (chan->conn->handshake_state->received_authenticate) + ERR("We already got one!"); + if (chan->conn->handshake_state->authenticated) { + /* Should be impossible given other checks */ + ERR("The peer is already authenticated"); + } + if (!(chan->conn->handshake_state->received_certs_cell)) + ERR("We never got a certs cell"); + if (chan->conn->handshake_state->certs->id_cert == NULL) + ERR("We never got an identity certificate"); + if (cell->payload_len < 4) + ERR("Cell was way too short"); + + auth = cell->payload; + { + uint16_t type = ntohs(get_uint16(auth)); + uint16_t len = ntohs(get_uint16(auth+2)); + if (4 + len > cell->payload_len) + ERR("Authenticator was truncated"); + + if (! authchallenge_type_is_supported(type)) + ERR("Authenticator type was not recognized"); + authtype = type; + + auth += 4; + authlen = len; + } + + if (authlen < V3_AUTH_BODY_LEN + 1) + ERR("Authenticator was too short"); + + expected_cell = connection_or_compute_authenticate_cell_body( + chan->conn, authtype, NULL, NULL, 1); + if (! expected_cell) + ERR("Couldn't compute expected AUTHENTICATE cell body"); + + int sig_is_rsa; + if (authtype == AUTHTYPE_RSA_SHA256_TLSSECRET || + authtype == AUTHTYPE_RSA_SHA256_RFC5705) { + bodylen = V3_AUTH_BODY_LEN; + sig_is_rsa = 1; + } else { + tor_assert(authtype == AUTHTYPE_ED25519_SHA256_RFC5705); + /* Our earlier check had better have made sure we had room + * for an ed25519 sig (inadvertently) */ + tor_assert(V3_AUTH_BODY_LEN > ED25519_SIG_LEN); + bodylen = authlen - ED25519_SIG_LEN; + sig_is_rsa = 0; + } + if (expected_cell->payload_len != bodylen+4) { + ERR("Expected AUTHENTICATE cell body len not as expected."); + } + + /* Length of random part. */ + if (BUG(bodylen < 24)) { + // LCOV_EXCL_START + ERR("Bodylen is somehow less than 24, which should really be impossible"); + // LCOV_EXCL_STOP + } + + if (tor_memneq(expected_cell->payload+4, auth, bodylen-24)) + ERR("Some field in the AUTHENTICATE cell body was not as expected"); + + if (sig_is_rsa) { + if (chan->conn->handshake_state->certs->ed_id_sign != NULL) + ERR("RSA-signed AUTHENTICATE response provided with an ED25519 cert"); + + if (chan->conn->handshake_state->certs->auth_cert == NULL) + ERR("We never got an RSA authentication certificate"); + + crypto_pk_t *pk = tor_tls_cert_get_key( + chan->conn->handshake_state->certs->auth_cert); + char d[DIGEST256_LEN]; + char *signed_data; + size_t keysize; + int signed_len; + + if (! pk) { + ERR("Couldn't get RSA key from AUTH cert."); + } + crypto_digest256(d, (char*)auth, V3_AUTH_BODY_LEN, DIGEST_SHA256); + + keysize = crypto_pk_keysize(pk); + signed_data = tor_malloc(keysize); + signed_len = crypto_pk_public_checksig(pk, signed_data, keysize, + (char*)auth + V3_AUTH_BODY_LEN, + authlen - V3_AUTH_BODY_LEN); + crypto_pk_free(pk); + if (signed_len < 0) { + tor_free(signed_data); + ERR("RSA signature wasn't valid"); + } + if (signed_len < DIGEST256_LEN) { + tor_free(signed_data); + ERR("Not enough data was signed"); + } + /* Note that we deliberately allow *more* than DIGEST256_LEN bytes here, + * in case they're later used to hold a SHA3 digest or something. */ + if (tor_memneq(signed_data, d, DIGEST256_LEN)) { + tor_free(signed_data); + ERR("Signature did not match data to be signed."); + } + tor_free(signed_data); + } else { + if (chan->conn->handshake_state->certs->ed_id_sign == NULL) + ERR("We never got an Ed25519 identity certificate."); + if (chan->conn->handshake_state->certs->ed_sign_auth == NULL) + ERR("We never got an Ed25519 authentication certificate."); + + const ed25519_public_key_t *authkey = + &chan->conn->handshake_state->certs->ed_sign_auth->signed_key; + ed25519_signature_t sig; + tor_assert(authlen > ED25519_SIG_LEN); + memcpy(&sig.sig, auth + authlen - ED25519_SIG_LEN, ED25519_SIG_LEN); + if (ed25519_checksig(&sig, auth, authlen - ED25519_SIG_LEN, authkey)<0) { + ERR("Ed25519 signature wasn't valid."); + } + } + + /* Okay, we are authenticated. */ + chan->conn->handshake_state->received_authenticate = 1; + chan->conn->handshake_state->authenticated = 1; + chan->conn->handshake_state->authenticated_rsa = 1; + chan->conn->handshake_state->digest_received_data = 0; + { + tor_x509_cert_t *id_cert = chan->conn->handshake_state->certs->id_cert; + crypto_pk_t *identity_rcvd = tor_tls_cert_get_key(id_cert); + const common_digests_t *id_digests = tor_x509_cert_get_id_digests(id_cert); + const ed25519_public_key_t *ed_identity_received = NULL; + + if (! sig_is_rsa) { + chan->conn->handshake_state->authenticated_ed25519 = 1; + ed_identity_received = + &chan->conn->handshake_state->certs->ed_id_sign->signing_key; + memcpy(&chan->conn->handshake_state->authenticated_ed25519_peer_id, + ed_identity_received, sizeof(ed25519_public_key_t)); + } + + /* This must exist; we checked key type when reading the cert. */ + tor_assert(id_digests); + + memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id, + id_digests->d[DIGEST_SHA1], DIGEST_LEN); + + channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd, + chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS); + crypto_pk_free(identity_rcvd); + + log_debug(LD_HANDSHAKE, + "Calling connection_or_init_conn_from_address for %s " + " from %s, with%s ed25519 id.", + safe_str(chan->conn->base_.address), + __func__, + ed_identity_received ? "" : "out"); + + connection_or_init_conn_from_address(chan->conn, + &(chan->conn->base_.addr), + chan->conn->base_.port, + (const char*)(chan->conn->handshake_state-> + authenticated_rsa_peer_id), + ed_identity_received, + 0); + + log_debug(LD_HANDSHAKE, + "Got an AUTHENTICATE cell from %s:%d, type %d: Looks good.", + safe_str(chan->conn->base_.address), + chan->conn->base_.port, + authtype); + } + + var_cell_free(expected_cell); + + #undef ERR + }
tor-commits@lists.torproject.org