diff options
75 files changed, 2398 insertions, 2058 deletions
diff --git a/changes/ticket_27864 b/changes/ticket_27864 new file mode 100644 index 0000000000..cf144101d2 --- /dev/null +++ b/changes/ticket_27864 @@ -0,0 +1,3 @@ + o Code simplification and refactoring: + - Split the router.c file into relay-only and shared components, + to help with future modularization. Closes ticket 27864. diff --git a/src/app/config/config.c b/src/app/config/config.c index 01b48e3c5f..91e2758650 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -60,61 +60,65 @@ #define CONFIG_PRIVATE #include "core/or/or.h" -#include "feature/client/bridges.h" -#include "feature/client/addressmap.h" +#include "app/config/config.h" +#include "app/config/confparse.h" +#include "app/config/statefile.h" +#include "app/main/main.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/cpuworker.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/or/channel.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuitmux.h" #include "core/or/circuitmux_ewma.h" #include "core/or/circuitstats.h" -#include "lib/compress/compress.h" -#include "app/config/config.h" -#include "lib/encoding/confline.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/dircache/consdiffmgr.h" +#include "core/or/dos.h" +#include "core/or/policies.h" +#include "core/or/relay.h" +#include "core/or/scheduler.h" +#include "feature/client/addressmap.h" +#include "feature/client/bridges.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/control/control.h" -#include "app/config/confparse.h" -#include "core/mainloop/cpuworker.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "lib/crypt_ops/crypto_init.h" -#ifdef ENABLE_NSS -#include "lib/crypt_ops/crypto_nss_mgt.h" -#else -#include "lib/crypt_ops/crypto_openssl_mgt.h" -#endif #include "feature/dirauth/bwauth.h" -#include "feature/dircache/dirserv.h" #include "feature/dirauth/guardfraction.h" -#include "feature/relay/dns.h" -#include "core/or/dos.h" -#include "feature/client/entrynodes.h" -#include "lib/log/git_revision.h" -#include "feature/stats/geoip.h" +#include "feature/dircache/consdiffmgr.h" +#include "feature/dircache/dirserv.h" +#include "feature/dircommon/voting_schedule.h" #include "feature/hibernate/hibernate.h" -#include "app/main/main.h" -#include "core/mainloop/mainloop.h" +#include "feature/hs/hs_config.h" +#include "feature/nodelist/dirlist.h" #include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "core/or/relay.h" +#include "feature/nodelist/routerset.h" +#include "feature/relay/dns.h" +#include "feature/relay/ext_orport.h" +#include "feature/relay/routermode.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendservice.h" -#include "feature/hs/hs_config.h" +#include "feature/stats/geoip.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "lib/sandbox/sandbox.h" -#include "feature/nodelist/dirlist.h" -#include "feature/nodelist/routerset.h" -#include "core/or/scheduler.h" -#include "app/config/statefile.h" -#include "feature/client/transports.h" -#include "feature/relay/ext_orport.h" -#include "feature/dircommon/voting_schedule.h" +#include "lib/compress/compress.h" +#include "lib/crypt_ops/crypto_init.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/encoding/confline.h" +#include "lib/log/git_revision.h" #include "lib/net/resolve.h" +#include "lib/sandbox/sandbox.h" + +#ifdef ENABLE_NSS +#include "lib/crypt_ops/crypto_nss_mgt.h" +#else +#include "lib/crypt_ops/crypto_openssl_mgt.h" +#endif + #ifdef _WIN32 #include <shlobj.h> #endif @@ -144,7 +148,7 @@ #include "feature/dirauth/dirvote.h" #include "feature/dirauth/recommend_pkg.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "core/or/connection_st.h" #include "core/or/port_cfg_st.h" diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index 208189db44..510b8964b2 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -40,6 +40,7 @@ #include "feature/hibernate/hibernate.h" #include "feature/stats/rephist.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "lib/sandbox/sandbox.h" #include "app/config/statefile.h" #include "lib/encoding/confline.h" diff --git a/src/app/main/main.c b/src/app/main/main.c index d71e1c7bf2..90bc8c510f 100644 --- a/src/app/main/main.c +++ b/src/app/main/main.c @@ -11,62 +11,64 @@ #include "core/or/or.h" -#include "feature/client/addressmap.h" -#include "lib/err/backtrace.h" -#include "feature/client/bridges.h" -#include "lib/container/buffers.h" +#include "app/config/config.h" +#include "app/config/statefile.h" +#include "app/main/main.h" +#include "app/main/ntmain.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/cpuworker.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/or/channel.h" -#include "core/or/channeltls.h" #include "core/or/channelpadding.h" +#include "core/or/channeltls.h" #include "core/or/circuitlist.h" #include "core/or/circuitmux_ewma.h" #include "core/or/command.h" -#include "lib/compress/compress.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/dircache/consdiffmgr.h" +#include "core/or/policies.h" +#include "core/or/protover.h" +#include "core/or/relay.h" +#include "core/or/scheduler.h" +#include "core/or/status.h" +#include "feature/api/tor_api.h" +#include "feature/api/tor_api_internal.h" +#include "feature/client/addressmap.h" +#include "feature/client/bridges.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/control/control.h" -#include "core/mainloop/cpuworker.h" -#include "lib/crypt_ops/crypto_s2k.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "feature/dircache/dirserv.h" #include "feature/dirauth/bwauth.h" +#include "feature/dirauth/keypin.h" #include "feature/dirauth/process_descs.h" -#include "feature/relay/dns.h" -#include "feature/client/entrynodes.h" -#include "feature/stats/geoip.h" +#include "feature/dircache/consdiffmgr.h" +#include "feature/dircache/dirserv.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_cache.h" -#include "feature/dirauth/keypin.h" -#include "app/main/main.h" -#include "core/mainloop/mainloop.h" +#include "feature/nodelist/authcert.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "app/main/ntmain.h" +#include "feature/nodelist/routerlist.h" +#include "feature/nodelist/routerparse.h" +#include "feature/relay/dns.h" +#include "feature/relay/ext_orport.h" #include "feature/relay/onion_queue.h" -#include "core/or/policies.h" -#include "core/or/protover.h" -#include "feature/client/transports.h" -#include "core/or/relay.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendservice.h" +#include "feature/stats/geoip.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" -#include "feature/nodelist/authcert.h" -#include "feature/nodelist/routerlist.h" -#include "feature/nodelist/routerparse.h" -#include "core/or/scheduler.h" -#include "app/config/statefile.h" -#include "core/or/status.h" -#include "feature/api/tor_api.h" -#include "feature/api/tor_api_internal.h" +#include "lib/compress/compress.h" +#include "lib/container/buffers.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_s2k.h" +#include "lib/err/backtrace.h" #include "lib/process/waitpid.h" -#include "feature/relay/ext_orport.h" + #include "lib/meminfo/meminfo.h" #include "lib/osinfo/uname.h" #include "lib/sandbox/sandbox.h" @@ -81,7 +83,7 @@ #include <event2/event.h> #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/shared_random.h" #include "core/or/or_connection_st.h" diff --git a/src/core/include.am b/src/core/include.am index 0bd4626c49..64a593ca51 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -20,6 +20,7 @@ LIBTOR_APP_A_SOURCES = \ src/core/mainloop/connection.c \ src/core/mainloop/cpuworker.c \ src/core/mainloop/mainloop.c \ + src/core/mainloop/netstatus.c \ src/core/mainloop/periodic.c \ src/core/or/address_set.c \ src/core/or/channel.c \ @@ -86,13 +87,18 @@ LIBTOR_APP_A_SOURCES = \ src/feature/hs/hs_stats.c \ src/feature/hs_common/replaycache.c \ src/feature/hs_common/shared_random_client.c \ + src/feature/keymgt/loadkey.c \ + src/feature/dirauth/keypin.c \ src/feature/nodelist/authcert.c \ + src/feature/nodelist/describe.c \ src/feature/nodelist/dirlist.c \ src/feature/nodelist/microdesc.c \ src/feature/nodelist/networkstatus.c \ + src/feature/nodelist/nickname.c \ src/feature/nodelist/nodelist.c \ src/feature/nodelist/node_select.c \ src/feature/nodelist/parsecommon.c \ + src/feature/nodelist/routerinfo.c \ src/feature/nodelist/routerlist.c \ src/feature/nodelist/routerparse.c \ src/feature/nodelist/routerset.c \ @@ -103,6 +109,8 @@ LIBTOR_APP_A_SOURCES = \ src/feature/relay/onion_queue.c \ src/feature/relay/router.c \ src/feature/relay/routerkeys.c \ + src/feature/relay/routermode.c \ + src/feature/relay/selftest.c \ src/feature/rend/rendcache.c \ src/feature/rend/rendclient.c \ src/feature/rend/rendcommon.c \ @@ -135,6 +143,7 @@ LIBTOR_APP_TESTING_A_SOURCES = $(LIBTOR_APP_A_SOURCES) # The Directory Authority module. MODULE_DIRAUTH_SOURCES = \ + src/feature/dirauth/authmode.c \ src/feature/dirauth/dircollate.c \ src/feature/dirauth/dirvote.c \ src/feature/dirauth/shared_random.c \ @@ -179,6 +188,7 @@ noinst_HEADERS += \ src/core/mainloop/connection.h \ src/core/mainloop/cpuworker.h \ src/core/mainloop/mainloop.h \ + src/core/mainloop/netstatus.h \ src/core/mainloop/periodic.h \ src/core/or/addr_policy_st.h \ src/core/or/address_set.h \ @@ -243,12 +253,12 @@ noinst_HEADERS += \ src/feature/control/control.h \ src/feature/control/control_connection_st.h \ src/feature/control/fmt_serverstatus.h \ + src/feature/dirauth/authmode.h \ src/feature/dirauth/bwauth.h \ src/feature/dirauth/dircollate.h \ src/feature/dirauth/dirvote.h \ src/feature/dirauth/guardfraction.h \ src/feature/dirauth/keypin.h \ - src/feature/dirauth/mode.h \ src/feature/dirauth/ns_detached_signatures_st.h \ src/feature/dirauth/reachability.h \ src/feature/dirauth/recommend_pkg.h \ @@ -289,8 +299,10 @@ noinst_HEADERS += \ src/feature/hs/hsdir_index_st.h \ src/feature/hs_common/replaycache.h \ src/feature/hs_common/shared_random_client.h \ + src/feature/keymgt/loadkey.h \ src/feature/nodelist/authcert.h \ src/feature/nodelist/authority_cert_st.h \ + src/feature/nodelist/describe.h \ src/feature/nodelist/desc_store_st.h \ src/feature/nodelist/dirlist.h \ src/feature/nodelist/document_signature_st.h \ @@ -301,10 +313,12 @@ noinst_HEADERS += \ src/feature/nodelist/networkstatus_sr_info_st.h \ src/feature/nodelist/networkstatus_st.h \ src/feature/nodelist/networkstatus_voter_info_st.h \ + src/feature/nodelist/nickname.h \ src/feature/nodelist/node_st.h \ src/feature/nodelist/nodelist.h \ src/feature/nodelist/node_select.h \ src/feature/nodelist/parsecommon.h \ + src/feature/nodelist/routerinfo.h \ src/feature/nodelist/routerinfo_st.h \ src/feature/nodelist/routerlist.h \ src/feature/nodelist/routerlist_st.h \ @@ -321,6 +335,8 @@ noinst_HEADERS += \ src/feature/relay/onion_queue.h \ src/feature/relay/router.h \ src/feature/relay/routerkeys.h \ + src/feature/relay/routermode.h \ + src/feature/relay/selftest.h \ src/feature/rend/rend_authorized_client_st.h \ src/feature/rend/rend_encoded_v2_service_descriptor_st.h \ src/feature/rend/rend_intro_point_st.h \ diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 4231bec014..18863fc04f 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -59,49 +59,53 @@ #include "feature/client/bridges.h" #include "lib/container/buffers.h" #include "lib/tls/buffers_tls.h" +#include "lib/err/backtrace.h" + /* * Define this so we get channel internal functions, since we're implementing * part of a subclass (channel_tls_t). */ #define TOR_CHANNEL_INTERNAL_ #define CONNECTION_PRIVATE -#include "lib/err/backtrace.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/or/channel.h" #include "core/or/channeltls.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/control/control.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" -#include "feature/dircache/dirserv.h" -#include "feature/relay/dns.h" -#include "feature/client/dnsserv.h" #include "core/or/dos.h" +#include "core/or/policies.h" +#include "core/or/reasons.h" +#include "core/or/relay.h" +#include "core/proto/proto_http.h" +#include "core/proto/proto_socks.h" +#include "feature/client/dnsserv.h" #include "feature/client/entrynodes.h" -#include "feature/relay/ext_orport.h" -#include "feature/stats/geoip.h" -#include "core/mainloop/mainloop.h" +#include "feature/client/transports.h" +#include "feature/control/control.h" +#include "feature/dirauth/authmode.h" +#include "feature/dircache/dirserv.h" +#include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_common.h" #include "feature/hs/hs_ident.h" #include "feature/nodelist/nodelist.h" -#include "core/proto/proto_http.h" -#include "core/proto/proto_socks.h" -#include "core/or/policies.h" -#include "core/or/reasons.h" -#include "core/or/relay.h" +#include "feature/nodelist/routerlist.h" +#include "feature/nodelist/routerparse.h" +#include "feature/relay/dns.h" +#include "feature/relay/ext_orport.h" +#include "feature/relay/routermode.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" +#include "feature/stats/geoip.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/nodelist/routerlist.h" -#include "feature/client/transports.h" -#include "feature/nodelist/routerparse.h" +#include "lib/crypt_ops/crypto_util.h" + #include "lib/sandbox/sandbox.h" #include "lib/net/buffers_net.h" #include "lib/tls/tortls.h" diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 06d6de9a27..4a9da43c9c 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -49,59 +49,63 @@ #define MAINLOOP_PRIVATE #include "core/or/or.h" -#include "feature/client/addressmap.h" -#include "lib/err/backtrace.h" -#include "feature/client/bridges.h" -#include "lib/container/buffers.h" -#include "lib/tls/buffers_tls.h" +#include "app/config/config.h" +#include "app/config/statefile.h" +#include "app/main/ntmain.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/cpuworker.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" +#include "core/mainloop/periodic.h" #include "core/or/channel.h" -#include "core/or/channeltls.h" #include "core/or/channelpadding.h" +#include "core/or/channeltls.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/dircache/consdiffmgr.h" -#include "feature/control/control.h" -#include "core/mainloop/cpuworker.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "feature/dircommon/directory.h" -#include "feature/dircache/dirserv.h" -#include "feature/dirauth/reachability.h" -#include "feature/relay/dns.h" -#include "feature/client/dnsserv.h" #include "core/or/dos.h" +#include "core/or/status.h" +#include "feature/client/addressmap.h" +#include "feature/client/bridges.h" +#include "feature/client/dnsserv.h" #include "feature/client/entrynodes.h" -#include "feature/stats/geoip.h" +#include "feature/client/transports.h" +#include "feature/control/control.h" +#include "feature/dirauth/authmode.h" +#include "feature/dirauth/reachability.h" +#include "feature/dircache/consdiffmgr.h" +#include "feature/dircache/dirserv.h" +#include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_cache.h" #include "feature/hs/hs_client.h" #include "feature/hs/hs_service.h" -#include "core/mainloop/mainloop.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "app/main/ntmain.h" -#include "core/mainloop/periodic.h" -#include "feature/client/transports.h" +#include "feature/nodelist/routerlist.h" +#include "feature/relay/dns.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendservice.h" +#include "feature/stats/geoip.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" -#include "feature/nodelist/routerlist.h" -#include "app/config/statefile.h" -#include "core/or/status.h" +#include "lib/container/buffers.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/err/backtrace.h" +#include "lib/tls/buffers_tls.h" + #include "lib/net/buffers_net.h" #include "lib/evloop/compat_libevent.h" #include <event2/event.h> #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "core/or/cell_st.h" #include "core/or/entry_connection_st.h" diff --git a/src/core/mainloop/netstatus.c b/src/core/mainloop/netstatus.c new file mode 100644 index 0000000000..f026474494 --- /dev/null +++ b/src/core/mainloop/netstatus.c @@ -0,0 +1,28 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "core/or/or.h" +#include "core/mainloop/netstatus.h" +#include "app/config/config.h" +#include "feature/hibernate/hibernate.h" + +/** Return true iff our network is in some sense disabled or shutting down: + * either we're hibernating, entering hibernation, or the network is turned + * off with DisableNetwork. */ +int +net_is_disabled(void) +{ + return get_options()->DisableNetwork || we_are_hibernating(); +} + +/** Return true iff our network is in some sense "completely disabled" either + * we're fully hibernating or the network is turned off with + * DisableNetwork. */ +int +net_is_completely_disabled(void) +{ + return get_options()->DisableNetwork || we_are_fully_hibernating(); +} diff --git a/src/core/mainloop/netstatus.h b/src/core/mainloop/netstatus.h new file mode 100644 index 0000000000..e9310c2929 --- /dev/null +++ b/src/core/mainloop/netstatus.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef TOR_NETSTATUS_H +#define TOR_NETSTATUS_H + +int net_is_disabled(void); +int net_is_completely_disabled(void); + +#endif diff --git a/src/core/or/channelpadding.c b/src/core/or/channelpadding.c index 6a38d13e32..db34f0f027 100644 --- a/src/core/or/channelpadding.c +++ b/src/core/or/channelpadding.c @@ -20,6 +20,7 @@ #include "core/mainloop/mainloop.h" #include "feature/stats/rephist.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "lib/time/compat_time.h" #include "feature/rend/rendservice.h" #include "lib/evloop/timers.h" diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index c81a00b497..883acacf37 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -53,6 +53,7 @@ #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" diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index 2f404d1794..26f0fc4d4f 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -28,44 +28,47 @@ #define CIRCUITBUILD_PRIVATE #include "core/or/or.h" -#include "feature/client/bridges.h" +#include "app/config/config.h" +#include "app/config/confparse.h" +#include "core/crypto/hs_ntor.h" +#include "core/crypto/onion_crypto.h" +#include "core/crypto/onion_fast.h" +#include "core/crypto/onion_tap.h" +#include "core/crypto/relay_crypto.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/channel.h" -#include "feature/client/circpathbias.h" -#define CIRCUITBUILD_PRIVATE #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuitstats.h" #include "core/or/circuituse.h" #include "core/or/command.h" -#include "app/config/config.h" -#include "app/config/confparse.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" +#include "core/or/onion.h" +#include "core/or/policies.h" +#include "core/or/relay.h" +#include "feature/client/bridges.h" +#include "feature/client/circpathbias.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/control/control.h" -#include "lib/crypt_ops/crypto_rand.h" #include "feature/dircommon/directory.h" -#include "feature/client/entrynodes.h" -#include "core/crypto/hs_ntor.h" -#include "core/mainloop/mainloop.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" -#include "core/or/onion.h" -#include "core/crypto/onion_crypto.h" -#include "core/crypto/onion_tap.h" -#include "core/crypto/onion_fast.h" -#include "core/or/policies.h" -#include "core/or/relay.h" -#include "core/crypto/relay_crypto.h" -#include "feature/rend/rendcommon.h" -#include "feature/stats/rephist.h" -#include "feature/relay/router.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" +#include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" -#include "feature/client/transports.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" +#include "feature/rend/rendcommon.h" +#include "feature/stats/rephist.h" +#include "lib/crypt_ops/crypto_rand.h" #include "core/or/cell_st.h" #include "core/or/cpath_build_state_st.h" diff --git a/src/core/or/circuitstats.c b/src/core/or/circuitstats.c index 2f37cdfa1a..0429f2c86e 100644 --- a/src/core/or/circuitstats.c +++ b/src/core/or/circuitstats.c @@ -43,6 +43,7 @@ #include "lib/math/fp.h" #include "lib/time/tvdiff.h" #include "lib/encoding/confline.h" +#include "feature/dirauth/authmode.h" #include "core/or/crypt_path_st.h" #include "core/or/origin_circuit_st.h" diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 7b1f31559c..d035d66ea2 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -28,34 +28,36 @@ **/ #include "core/or/or.h" -#include "feature/client/addressmap.h" -#include "feature/client/bridges.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" #include "core/or/channel.h" -#include "feature/client/circpathbias.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuitstats.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" +#include "core/or/policies.h" +#include "feature/client/addressmap.h" +#include "feature/client/bridges.h" +#include "feature/client/circpathbias.h" +#include "feature/client/entrynodes.h" #include "feature/control/control.h" #include "feature/dircommon/directory.h" -#include "feature/client/entrynodes.h" -#include "feature/hs/hs_common.h" -#include "feature/hs/hs_client.h" #include "feature/hs/hs_circuit.h" +#include "feature/hs/hs_client.h" +#include "feature/hs/hs_common.h" #include "feature/hs/hs_ident.h" #include "feature/hs/hs_stats.h" -#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" -#include "core/or/policies.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerlist.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendservice.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/nodelist/routerlist.h" #include "lib/math/fp.h" #include "lib/time/tvdiff.h" diff --git a/src/core/or/command.c b/src/core/or/command.c index f93eb8d857..cbe7f622e7 100644 --- a/src/core/or/command.c +++ b/src/core/or/command.c @@ -37,25 +37,26 @@ * called when channels are created in circuitbuild.c */ #include "core/or/or.h" +#include "app/config/config.h" +#include "core/crypto/onion_crypto.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/cpuworker.h" #include "core/or/channel.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/command.h" -#include "core/mainloop/connection.h" #include "core/or/connection_or.h" -#include "app/config/config.h" -#include "feature/control/control.h" -#include "core/mainloop/cpuworker.h" -#include "lib/crypt_ops/crypto_util.h" #include "core/or/dos.h" -#include "feature/hibernate/hibernate.h" -#include "feature/nodelist/nodelist.h" #include "core/or/onion.h" -#include "core/crypto/onion_crypto.h" -#include "feature/stats/rephist.h" #include "core/or/relay.h" -#include "feature/relay/router.h" +#include "feature/control/control.h" +#include "feature/hibernate/hibernate.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" +#include "feature/relay/routermode.h" +#include "feature/stats/rephist.h" +#include "lib/crypt_ops/crypto_util.h" #include "core/or/cell_st.h" #include "core/or/or_circuit_st.h" diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index daf978b998..d8b45fe350 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -59,43 +59,45 @@ #include "lib/err/backtrace.h" -#include "feature/client/addressmap.h" -#include "lib/container/buffers.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/channel.h" -#include "feature/client/circpathbias.h" +#include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/control/control.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/relay/dns.h" +#include "core/or/policies.h" +#include "core/or/reasons.h" +#include "core/or/relay.h" +#include "core/proto/proto_http.h" +#include "core/proto/proto_socks.h" +#include "feature/client/addressmap.h" +#include "feature/client/circpathbias.h" #include "feature/client/dnsserv.h" -#include "feature/dircommon/directory.h" +#include "feature/control/control.h" #include "feature/dircache/dirserv.h" +#include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" -#include "feature/hs/hs_common.h" #include "feature/hs/hs_cache.h" -#include "feature/hs/hs_client.h" #include "feature/hs/hs_circuit.h" -#include "core/mainloop/mainloop.h" +#include "feature/hs/hs_client.h" +#include "feature/hs/hs_common.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "core/proto/proto_http.h" -#include "core/proto/proto_socks.h" -#include "core/or/reasons.h" -#include "core/or/relay.h" +#include "feature/nodelist/routerlist.h" +#include "feature/nodelist/routerset.h" +#include "feature/relay/dns.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendservice.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/nodelist/routerlist.h" -#include "feature/nodelist/routerset.h" -#include "core/or/circuitbuild.h" +#include "lib/container/buffers.h" +#include "lib/crypt_ops/crypto_util.h" #include "core/or/cell_st.h" #include "core/or/cpath_build_state_st.h" diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c index ca69fa00d4..4a724a24d3 100644 --- a/src/core/or/connection_or.c +++ b/src/core/or/connection_or.c @@ -56,12 +56,14 @@ #include "feature/stats/rephist.h" #include "feature/relay/router.h" #include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/routerlist.h" #include "feature/relay/ext_orport.h" #include "core/or/scheduler.h" #include "feature/nodelist/torcert.h" #include "core/or/channelpadding.h" +#include "feature/dirauth/authmode.h" #include "core/or/cell_st.h" #include "core/or/cell_queue_st.h" diff --git a/src/core/or/dos.c b/src/core/or/dos.c index a75c2070d8..c59e2f6361 100644 --- a/src/core/or/dos.c +++ b/src/core/or/dos.c @@ -19,7 +19,7 @@ #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "core/or/relay.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "core/or/dos.h" diff --git a/src/core/or/policies.c b/src/core/or/policies.c index 3443a17107..fc359627b9 100644 --- a/src/core/or/policies.c +++ b/src/core/or/policies.c @@ -25,6 +25,7 @@ #include "feature/nodelist/nodelist.h" #include "core/or/policies.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/nodelist/routerparse.h" #include "feature/stats/geoip.h" #include "ht.h" diff --git a/src/core/or/relay.c b/src/core/or/relay.c index 47be0f4039..88bcdf0703 100644 --- a/src/core/or/relay.c +++ b/src/core/or/relay.c @@ -77,7 +77,7 @@ #include "core/crypto/relay_crypto.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendcommon.h" -#include "feature/relay/router.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "core/or/scheduler.h" diff --git a/src/core/or/status.c b/src/core/or/status.c index 45b8217d9a..d8a9da0a55 100644 --- a/src/core/or/status.c +++ b/src/core/or/status.c @@ -21,6 +21,7 @@ #include "feature/nodelist/nodelist.h" #include "core/or/relay.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "core/or/circuitlist.h" #include "core/mainloop/mainloop.h" #include "feature/stats/rephist.h" diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c index e8afb5a924..47a4249556 100644 --- a/src/feature/client/bridges.c +++ b/src/feature/client/bridges.c @@ -14,22 +14,22 @@ #define TOR_BRIDGES_PRIVATE #include "core/or/or.h" -#include "feature/client/bridges.h" -#include "core/or/circuitbuild.h" #include "app/config/config.h" #include "core/mainloop/connection.h" -#include "feature/dircommon/directory.h" +#include "core/or/circuitbuild.h" +#include "core/or/policies.h" +#include "feature/client/bridges.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" -#include "feature/client/entrynodes.h" -#include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "feature/relay/router.h" +#include "feature/dircommon/directory.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/dirlist.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" - #include "feature/nodelist/routerset.h" -#include "feature/client/transports.h" #include "core/or/extend_info_st.h" #include "feature/nodelist/node_st.h" diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index 521bf33b57..8ad16af6d6 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -113,40 +113,41 @@ #define ENTRYNODES_PRIVATE #include "core/or/or.h" +#include "app/config/config.h" +#include "app/config/confparse.h" +#include "app/config/statefile.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/channel.h" -#include "feature/client/bridges.h" -#include "feature/client/circpathbias.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" -#include "core/or/circuituse.h" #include "core/or/circuitstats.h" -#include "app/config/config.h" -#include "app/config/confparse.h" -#include "core/mainloop/connection.h" +#include "core/or/circuituse.h" +#include "core/or/policies.h" +#include "feature/client/bridges.h" +#include "feature/client/circpathbias.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/control/control.h" -#include "lib/crypt_ops/crypto_rand.h" #include "feature/dircommon/directory.h" -#include "feature/client/entrynodes.h" -#include "core/mainloop/mainloop.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "feature/relay/router.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" +#include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" -#include "feature/client/transports.h" -#include "app/config/statefile.h" -#include "lib/math/fp.h" +#include "feature/relay/router.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/digestset.h" #include "lib/encoding/confline.h" +#include "lib/math/fp.h" #include "feature/nodelist/node_st.h" #include "core/or/origin_circuit_st.h" #include "app/config/or_state_st.h" -#include "lib/crypt_ops/digestset.h" - /** A list of existing guard selection contexts. */ static smartlist_t *guard_contexts = NULL; /** The currently enabled guard selection context. */ diff --git a/src/feature/control/control.c b/src/feature/control/control.c index f307101ed5..d8d08f2c86 100644 --- a/src/feature/control/control.c +++ b/src/feature/control/control.c @@ -36,9 +36,11 @@ #define CONTROL_PRIVATE #include "core/or/or.h" -#include "feature/client/addressmap.h" -#include "feature/client/bridges.h" -#include "lib/container/buffers.h" +#include "app/config/config.h" +#include "app/config/confparse.h" +#include "app/main/main.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/channel.h" #include "core/or/channeltls.h" #include "core/or/circuitbuild.h" @@ -46,47 +48,48 @@ #include "core/or/circuitstats.h" #include "core/or/circuituse.h" #include "core/or/command.h" -#include "lib/evloop/compat_libevent.h" -#include "app/config/config.h" -#include "app/config/confparse.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" +#include "core/or/policies.h" +#include "core/or/reasons.h" +#include "core/proto/proto_control0.h" +#include "core/proto/proto_http.h" +#include "feature/client/addressmap.h" +#include "feature/client/bridges.h" +#include "feature/client/dnsserv.h" +#include "feature/client/entrynodes.h" #include "feature/control/control.h" #include "feature/control/fmt_serverstatus.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" +#include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" -#include "feature/dircache/dirserv.h" -#include "feature/client/dnsserv.h" -#include "feature/client/entrynodes.h" -#include "feature/stats/geoip.h" +#include "feature/dircommon/directory.h" #include "feature/hibernate/hibernate.h" #include "feature/hs/hs_cache.h" #include "feature/hs/hs_common.h" #include "feature/hs/hs_control.h" -#include "app/main/main.h" -#include "core/mainloop/mainloop.h" +#include "feature/hs_common/shared_random_client.h" +#include "feature/nodelist/authcert.h" +#include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "core/proto/proto_control0.h" -#include "core/proto/proto_http.h" -#include "core/or/reasons.h" +#include "feature/nodelist/routerinfo.h" +#include "feature/nodelist/routerlist.h" +#include "feature/nodelist/routerparse.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendservice.h" +#include "feature/stats/geoip.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/nodelist/authcert.h" -#include "feature/nodelist/dirlist.h" -#include "feature/nodelist/routerlist.h" -#include "feature/nodelist/routerparse.h" -#include "feature/hs_common/shared_random_client.h" +#include "lib/container/buffers.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "lib/encoding/confline.h" +#include "lib/evloop/compat_libevent.h" #include "feature/dircache/cached_dir_st.h" #include "feature/control/control_connection_st.h" diff --git a/src/feature/control/fmt_serverstatus.c b/src/feature/control/fmt_serverstatus.c index f150832ce3..eef85d356c 100644 --- a/src/feature/control/fmt_serverstatus.c +++ b/src/feature/control/fmt_serverstatus.c @@ -7,9 +7,10 @@ #include "feature/control/fmt_serverstatus.h" #include "app/config/config.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/voteflags.h"// XXXX remove #include "feature/nodelist/nodelist.h" -#include "feature/relay/router.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/node_st.h" #include "feature/nodelist/routerinfo_st.h" diff --git a/src/feature/dirauth/authmode.c b/src/feature/dirauth/authmode.c new file mode 100644 index 0000000000..7c900ea7bf --- /dev/null +++ b/src/feature/dirauth/authmode.c @@ -0,0 +1,70 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file authmode.c + * \brief What kind of directory authority are we? + * + * If we're not an authority, these functions are all replaced with 0 in + * authmode.h. + **/ + +#include "core/or/or.h" +#include "app/config/config.h" +#include "feature/dirauth/authmode.h" + +#include "feature/nodelist/routerinfo_st.h" + +/** Return true iff we believe ourselves to be an authoritative + * directory server. + */ +int +authdir_mode(const or_options_t *options) +{ + return options->AuthoritativeDir != 0; +} +/** Return true iff we are an authoritative directory server that is + * authoritative about receiving and serving descriptors of type + * <b>purpose</b> on its dirport. + */ +int +authdir_mode_handles_descs(const or_options_t *options, int purpose) +{ + if (BUG(purpose < 0)) /* Deprecated. */ + return authdir_mode(options); + else if (purpose == ROUTER_PURPOSE_GENERAL) + return authdir_mode_v3(options); + else if (purpose == ROUTER_PURPOSE_BRIDGE) + return authdir_mode_bridge(options); + else + return 0; +} +/** Return true iff we are an authoritative directory server that + * publishes its own network statuses. + */ +int +authdir_mode_publishes_statuses(const or_options_t *options) +{ + if (authdir_mode_bridge(options)) + return 0; + return authdir_mode(options); +} +/** Return true iff we are an authoritative directory server that + * tests reachability of the descriptors it learns about. + */ +int +authdir_mode_tests_reachability(const or_options_t *options) +{ + return authdir_mode(options); +} +/** Return true iff we believe ourselves to be a bridge authoritative + * directory server. + */ +int +authdir_mode_bridge(const or_options_t *options) +{ + return authdir_mode(options) && options->BridgeAuthoritativeDir != 0; +} diff --git a/src/feature/dirauth/authmode.h b/src/feature/dirauth/authmode.h new file mode 100644 index 0000000000..3ca127b829 --- /dev/null +++ b/src/feature/dirauth/authmode.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2018-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file authmode.h + * \brief Header file for directory authority mode. + **/ + +#ifndef TOR_DIRAUTH_MODE_H +#define TOR_DIRAUTH_MODE_H + +#include "feature/relay/router.h" + +#ifdef HAVE_MODULE_DIRAUTH + +int authdir_mode(const or_options_t *options); +int authdir_mode_handles_descs(const or_options_t *options, int purpose); +int authdir_mode_publishes_statuses(const or_options_t *options); +int authdir_mode_tests_reachability(const or_options_t *options); +int authdir_mode_bridge(const or_options_t *options); + +/* Return true iff we believe ourselves to be a v3 authoritative directory + * server. */ +static inline int +authdir_mode_v3(const or_options_t *options) +{ + return authdir_mode(options) && options->V3AuthoritativeDir != 0; +} + +#else /* HAVE_MODULE_DIRAUTH */ + +#define authdir_mode(options) (((void)(options)),0) +#define authdir_mode_handles_descs(options,purpose) \ + (((void)(options)),((void)(purpose)),0) +#define authdir_mode_publishes_statuses(options) (((void)(options)),0) +#define authdir_mode_tests_reachability(options) (((void)(options)),0) +#define authdir_mode_bridge(options) (((void)(options)),0) +#define authdir_mode_v3(options) (((void)(options)),0) + +#endif /* HAVE_MODULE_DIRAUTH */ + +#endif /* TOR_MODE_H */ diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index a1fe0d4234..edb0ad2aea 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -34,7 +34,7 @@ #include "feature/dircommon/voting_schedule.h" #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/shared_random_state.h" #include "feature/nodelist/authority_cert_st.h" diff --git a/src/feature/dirauth/mode.h b/src/feature/dirauth/mode.h deleted file mode 100644 index 8bb961dffb..0000000000 --- a/src/feature/dirauth/mode.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2018-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file mode.h - * \brief Standalone header file for directory authority mode. - **/ - -#ifndef TOR_DIRAUTH_MODE_H -#define TOR_DIRAUTH_MODE_H - -#ifdef HAVE_MODULE_DIRAUTH - -#include "feature/relay/router.h" - -/* Return true iff we believe ourselves to be a v3 authoritative directory - * server. */ -static inline int -authdir_mode_v3(const or_options_t *options) -{ - return authdir_mode(options) && options->V3AuthoritativeDir != 0; -} - -#else /* HAVE_MODULE_DIRAUTH */ - -/* Without the dirauth module, we can't be a v3 directory authority, ever. */ - -static inline int -authdir_mode_v3(const or_options_t *options) -{ - (void) options; - return 0; -} - -#endif /* HAVE_MODULE_DIRAUTH */ - -#endif /* TOR_MODE_H */ - diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c index 1cf31f85c8..823a1b8791 100644 --- a/src/feature/dirauth/process_descs.c +++ b/src/feature/dirauth/process_descs.c @@ -21,8 +21,10 @@ #include "feature/dirauth/reachability.h" #include "feature/dirclient/dlstatus.h" #include "feature/dircommon/directory.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/torcert.h" diff --git a/src/feature/dirauth/reachability.c b/src/feature/dirauth/reachability.c index abc7249b65..122c239f9a 100644 --- a/src/feature/dirauth/reachability.c +++ b/src/feature/dirauth/reachability.c @@ -16,10 +16,12 @@ #include "core/or/channel.h" #include "core/or/channeltls.h" #include "core/or/command.h" +#include "feature/dirauth/authmode.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/torcert.h" -#include "feature/relay/router.h" #include "feature/stats/rephist.h" #include "feature/nodelist/node_st.h" diff --git a/src/feature/dirauth/shared_random.c b/src/feature/dirauth/shared_random.c index 85ec82ac00..db4f9d328c 100644 --- a/src/feature/dirauth/shared_random.c +++ b/src/feature/dirauth/shared_random.c @@ -102,7 +102,7 @@ #include "feature/dircommon/voting_schedule.h" #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/nodelist/authority_cert_st.h" #include "feature/nodelist/networkstatus_st.h" diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index 7bfc539829..76bde0b787 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -11,7 +11,7 @@ #include "core/mainloop/connection.h" #include "core/or/relay.h" #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/process_descs.h" #include "feature/dircache/conscache.h" #include "feature/dircache/consdiffmgr.h" @@ -23,7 +23,7 @@ #include "feature/nodelist/authcert.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/routerlist.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/rend/rendcache.h" #include "feature/stats/geoip.h" #include "feature/stats/rephist.h" diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 65c3d6d91a..4fa3cd7f93 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -15,6 +15,7 @@ #include "feature/nodelist/microdesc.h" #include "feature/nodelist/routerlist.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/stats/rephist.h" #include "feature/dircache/cached_dir_st.h" diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 6e8836a6dc..334012602c 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -15,8 +15,8 @@ #include "feature/client/bridges.h" #include "feature/client/entrynodes.h" #include "feature/control/control.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" #include "feature/dirauth/shared_random.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" @@ -28,14 +28,17 @@ #include "feature/hs/hs_client.h" #include "feature/hs/hs_control.h" #include "feature/nodelist/authcert.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/node_select.h" #include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerset.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" diff --git a/src/feature/dirclient/dlstatus.c b/src/feature/dirclient/dlstatus.c index 017281e00c..aea17bdacb 100644 --- a/src/feature/dirclient/dlstatus.c +++ b/src/feature/dirclient/dlstatus.c @@ -11,7 +11,7 @@ #include "feature/client/entrynodes.h" #include "feature/dirclient/dlstatus.h" #include "feature/nodelist/networkstatus.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "lib/crypt_ops/crypto_rand.h" #include "feature/dirclient/download_status_st.h" diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index 70760e013b..092781d7ed 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -8,27 +8,26 @@ #define HS_CIRCUIT_PRIVATE #include "core/or/or.h" -#include "feature/client/circpathbias.h" +#include "app/config/config.h" +#include "core/crypto/hs_ntor.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "lib/crypt_ops/crypto_dh.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/nodelist/nodelist.h" #include "core/or/policies.h" #include "core/or/relay.h" -#include "feature/rend/rendservice.h" -#include "feature/stats/rephist.h" -#include "feature/relay/router.h" - +#include "feature/client/circpathbias.h" #include "feature/hs/hs_cell.h" +#include "feature/hs/hs_circuit.h" #include "feature/hs/hs_circuitmap.h" #include "feature/hs/hs_ident.h" -#include "core/crypto/hs_ntor.h" #include "feature/hs/hs_service.h" -#include "feature/hs/hs_circuit.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/nodelist.h" +#include "feature/rend/rendservice.h" +#include "feature/stats/rephist.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" /* Trunnel. */ #include "trunnel/ed25519_cert.h" diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index edfd47c727..24365853cc 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -9,18 +9,17 @@ #define HS_CLIENT_PRIVATE #include "core/or/or.h" -#include "feature/client/circpathbias.h" +#include "app/config/config.h" +#include "core/crypto/hs_ntor.h" +#include "core/mainloop/connection.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" -#include "lib/crypt_ops/crypto_format.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" +#include "core/or/reasons.h" +#include "feature/client/circpathbias.h" #include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" #include "feature/hs/hs_cache.h" #include "feature/hs/hs_cell.h" #include "feature/hs/hs_circuit.h" @@ -29,13 +28,14 @@ #include "feature/hs/hs_control.h" #include "feature/hs/hs_descriptor.h" #include "feature/hs/hs_ident.h" -#include "core/crypto/hs_ntor.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "core/or/reasons.h" -#include "feature/rend/rendclient.h" -#include "feature/relay/router.h" #include "feature/nodelist/routerset.h" +#include "feature/rend/rendclient.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "core/or/cpath_build_state_st.h" #include "feature/dircommon/dir_connection_st.h" diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index c36892e0f8..4bad4ae6e6 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -15,23 +15,23 @@ #include "app/config/config.h" #include "core/or/circuitbuild.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" +#include "core/or/policies.h" +#include "feature/dirauth/shared_random_state.h" #include "feature/hs/hs_cache.h" -#include "feature/hs/hs_common.h" +#include "feature/hs/hs_circuitmap.h" #include "feature/hs/hs_client.h" +#include "feature/hs/hs_common.h" #include "feature/hs/hs_ident.h" #include "feature/hs/hs_service.h" -#include "feature/hs/hs_circuitmap.h" -#include "core/or/policies.h" +#include "feature/hs_common/shared_random_client.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerset.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendservice.h" -#include "feature/nodelist/routerset.h" -#include "feature/relay/router.h" -#include "feature/hs_common/shared_random_client.h" -#include "feature/dirauth/shared_random_state.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "core/or/edge_connection_st.h" #include "feature/nodelist/networkstatus_st.h" diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index dc7bb41ee1..78654bfb23 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -9,28 +9,29 @@ #define HS_SERVICE_PRIVATE #include "core/or/or.h" -#include "feature/client/circpathbias.h" +#include "app/config/config.h" +#include "app/config/statefile.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "lib/crypt_ops/crypto_ope.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "feature/dircommon/directory.h" +#include "core/or/relay.h" +#include "feature/client/circpathbias.h" #include "feature/dirclient/dirclient.h" -#include "core/mainloop/mainloop.h" +#include "feature/dircommon/directory.h" +#include "feature/hs_common/shared_random_client.h" +#include "feature/keymgt/loadkey.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" +#include "feature/nodelist/node_select.h" #include "feature/nodelist/nodelist.h" -#include "core/or/relay.h" #include "feature/rend/rendservice.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" -#include "feature/nodelist/node_select.h" -#include "feature/hs_common/shared_random_client.h" -#include "app/config/statefile.h" +#include "lib/crypt_ops/crypto_ope.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "feature/hs/hs_circuit.h" #include "feature/hs/hs_common.h" diff --git a/src/feature/keymgt/loadkey.c b/src/feature/keymgt/loadkey.c new file mode 100644 index 0000000000..4621e39c54 --- /dev/null +++ b/src/feature/keymgt/loadkey.c @@ -0,0 +1,755 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file loadkey.c + * \brief Read keys from disk, creating as needed + * + * This code is shared by relays and onion services, which both need + * this functionality. + **/ + +#include "core/or/or.h" +#include "app/config/config.h" +#include "app/main/main.h" +#include "feature/keymgt/loadkey.h" +#include "feature/nodelist/torcert.h" + +#include "lib/crypt_ops/crypto_pwbox.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/term/getpass.h" +#include "lib/crypt_ops/crypto_format.h" + +#define ENC_KEY_HEADER "Boxed Ed25519 key" +#define ENC_KEY_TAG "master" + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist + * and <b>generate</b> is true, create a new RSA key and save it in + * <b>fname</b>. Return the read/created key, or NULL on error. Log all + * errors at level <b>severity</b>. If <b>created_out/b> is non-NULL and a + * new key was created, set *<b>created_out</b> to true. + */ +crypto_pk_t * +init_key_from_file(const char *fname, int generate, int severity, + bool *created_out) +{ + crypto_pk_t *prkey = NULL; + + if (created_out) { + *created_out = false; + } + + if (!(prkey = crypto_pk_new())) { + tor_log(severity, LD_GENERAL,"Error constructing key"); + goto error; + } + + switch (file_status(fname)) { + case FN_DIR: + case FN_ERROR: + tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname); + goto error; + /* treat empty key files as if the file doesn't exist, and, + * if generate is set, replace the empty file in + * crypto_pk_write_private_key_to_filename() */ + case FN_NOENT: + case FN_EMPTY: + if (generate) { + if (!have_lockfile()) { + if (try_locking(get_options(), 0)<0) { + /* Make sure that --list-fingerprint only creates new keys + * if there is no possibility for a deadlock. */ + tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". " + "Not writing any new keys.", fname); + /*XXXX The 'other process' might make a key in a second or two; + * maybe we should wait for it. */ + goto error; + } + } + log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.", + fname); + if (crypto_pk_generate_key(prkey)) { + tor_log(severity, LD_GENERAL,"Error generating onion key"); + goto error; + } + if (! crypto_pk_is_valid_private_key(prkey)) { + tor_log(severity, LD_GENERAL,"Generated key seems invalid"); + goto error; + } + log_info(LD_GENERAL, "Generated key seems valid"); + if (created_out) { + *created_out = true; + } + if (crypto_pk_write_private_key_to_filename(prkey, fname)) { + tor_log(severity, LD_FS, + "Couldn't write generated key to \"%s\".", fname); + goto error; + } + } else { + tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname); + goto error; + } + return prkey; + case FN_FILE: + if (crypto_pk_read_private_key_from_filename(prkey, fname)) { + tor_log(severity, LD_GENERAL,"Error loading private key."); + goto error; + } + return prkey; + default: + tor_assert(0); + } + + error: + if (prkey) + crypto_pk_free(prkey); + return NULL; +} + +/* DOCDOC */ +static ssize_t +do_getpass(const char *prompt, char *buf, size_t buflen, + int twice, const or_options_t *options) +{ + if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) { + tor_assert(buflen); + buf[0] = 0; + return 0; + } + + char *prompt2 = NULL; + char *buf2 = NULL; + int fd = -1; + ssize_t length = -1; + + if (options->use_keygen_passphrase_fd) { + twice = 0; + fd = options->keygen_passphrase_fd; + length = read_all_from_fd(fd, buf, buflen-1); + if (length >= 0) + buf[length] = 0; + goto done_reading; + } + + if (twice) { + const char msg[] = "One more time:"; + size_t p2len = strlen(prompt) + 1; + if (p2len < sizeof(msg)) + p2len = sizeof(msg); + prompt2 = tor_malloc(p2len); + memset(prompt2, ' ', p2len); + memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg)); + + buf2 = tor_malloc_zero(buflen); + } + + while (1) { + length = tor_getpass(prompt, buf, buflen); + if (length < 0) + goto done_reading; + + if (! twice) + break; + + ssize_t length2 = tor_getpass(prompt2, buf2, buflen); + + if (length != length2 || tor_memneq(buf, buf2, length)) { + fprintf(stderr, "That didn't match.\n"); + } else { + break; + } + } + + done_reading: + if (twice) { + tor_free(prompt2); + memwipe(buf2, 0, buflen); + tor_free(buf2); + } + + if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0) + return -1; + + return length; +} + +/* DOCDOC */ +int +read_encrypted_secret_key(ed25519_secret_key_t *out, + const char *fname) +{ + int r = -1; + uint8_t *secret = NULL; + size_t secret_len = 0; + char pwbuf[256]; + uint8_t encrypted_key[256]; + char *tag = NULL; + int saved_errno = 0; + + ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname, + ENC_KEY_HEADER, + &tag, + encrypted_key, + sizeof(encrypted_key)); + if (encrypted_len < 0) { + saved_errno = errno; + log_info(LD_OR, "%s is missing", fname); + r = 0; + goto done; + } + if (strcmp(tag, ENC_KEY_TAG)) { + saved_errno = EINVAL; + goto done; + } + + while (1) { + ssize_t pwlen = + do_getpass("Enter passphrase for master key:", pwbuf, sizeof(pwbuf), 0, + get_options()); + if (pwlen < 0) { + saved_errno = EINVAL; + goto done; + } + const int r_unbox = crypto_unpwbox(&secret, &secret_len, + encrypted_key, encrypted_len, + pwbuf, pwlen); + if (r_unbox == UNPWBOX_CORRUPTED) { + log_err(LD_OR, "%s is corrupted.", fname); + saved_errno = EINVAL; + goto done; + } else if (r_unbox == UNPWBOX_OKAY) { + break; + } + + /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets + * it right. */ + } + + if (secret_len != ED25519_SECKEY_LEN) { + log_err(LD_OR, "%s is corrupted.", fname); + saved_errno = EINVAL; + goto done; + } + memcpy(out->seckey, secret, ED25519_SECKEY_LEN); + r = 1; + + done: + memwipe(encrypted_key, 0, sizeof(encrypted_key)); + memwipe(pwbuf, 0, sizeof(pwbuf)); + tor_free(tag); + if (secret) { + memwipe(secret, 0, secret_len); + tor_free(secret); + } + if (saved_errno) + errno = saved_errno; + return r; +} + +/* DOCDOC */ +int +write_encrypted_secret_key(const ed25519_secret_key_t *key, + const char *fname) +{ + int r = -1; + char pwbuf0[256]; + uint8_t *encrypted_key = NULL; + size_t encrypted_len = 0; + + if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1, + get_options()) < 0) { + log_warn(LD_OR, "NO/failed passphrase"); + return -1; + } + + if (strlen(pwbuf0) == 0) { + if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON) + return -1; + else + return 0; + } + + if (crypto_pwbox(&encrypted_key, &encrypted_len, + key->seckey, sizeof(key->seckey), + pwbuf0, strlen(pwbuf0), 0) < 0) { + log_warn(LD_OR, "crypto_pwbox failed!?"); + goto done; + } + if (crypto_write_tagged_contents_to_file(fname, + ENC_KEY_HEADER, + ENC_KEY_TAG, + encrypted_key, encrypted_len) < 0) + goto done; + r = 1; + done: + if (encrypted_key) { + memwipe(encrypted_key, 0, encrypted_len); + tor_free(encrypted_key); + } + memwipe(pwbuf0, 0, sizeof(pwbuf0)); + return r; +} + +/* DOCDOC */ +static int +write_secret_key(const ed25519_secret_key_t *key, int encrypted, + const char *fname, + const char *fname_tag, + const char *encrypted_fname) +{ + if (encrypted) { + int r = write_encrypted_secret_key(key, encrypted_fname); + if (r == 1) { + /* Success! */ + + /* Try to unlink the unencrypted key, if any existed before */ + if (strcmp(fname, encrypted_fname)) + unlink(fname); + return r; + } else if (r != 0) { + /* Unrecoverable failure! */ + return r; + } + + fprintf(stderr, "Not encrypting the secret key.\n"); + } + return ed25519_seckey_write_to_file(key, fname, fname_tag); +} + +/** + * Read an ed25519 key and associated certificates from files beginning with + * <b>fname</b>, with certificate type <b>cert_type</b>. On failure, return + * NULL; on success return the keypair. + * + * The <b>options</b> is used to look at the change_key_passphrase value when + * writing to disk a secret key. It is safe to be NULL even in that case. + * + * If INIT_ED_KEY_CREATE is set in <b>flags</b>, then create the key (and + * certificate if requested) if it doesn't exist, and save it to disk. + * + * If INIT_ED_KEY_NEEDCERT is set in <b>flags</b>, load/create a certificate + * too and store it in *<b>cert_out</b>. Fail if the cert can't be + * found/created. To create a certificate, <b>signing_key</b> must be set to + * the key that should sign it; <b>now</b> to the current time, and + * <b>lifetime</b> to the lifetime of the key. + * + * If INIT_ED_KEY_REPLACE is set in <b>flags</b>, then create and save new key + * whether we can read the old one or not. + * + * If INIT_ED_KEY_EXTRA_STRONG is set in <b>flags</b>, set the extra_strong + * flag when creating the secret key. + * + * If INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT is set in <b>flags</b>, and + * we create a new certificate, create it with the signing key embedded. + * + * If INIT_ED_KEY_SPLIT is set in <b>flags</b>, and we create a new key, + * store the public key in a separate file from the secret key. + * + * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a + * public key file but no secret key file, return successfully anyway. + * + * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not try to load a + * secret key unless no public key is found. Do not return a secret key. (but + * create and save one if needed). + * + * If INIT_ED_KEY_TRY_ENCRYPTED is set, we look for an encrypted secret key + * and consider encrypting any new secret key. + * + * If INIT_ED_KEY_NO_REPAIR is set, and there is any issue loading the keys + * from disk _other than their absence_ (full or partial), we do not try to + * replace them. + * + * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures + * refer to the --keygen option. + * + * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the + * secret key file, encrypted or not. + * + * If INIT_ED_KEY_OFFLINE_SECRET is set, we won't try to load the master + * secret key and we log a message at <b>severity</b> that we've done so. + */ +ed25519_keypair_t * +ed_key_init_from_file(const char *fname, uint32_t flags, + int severity, + const ed25519_keypair_t *signing_key, + time_t now, + time_t lifetime, + uint8_t cert_type, + struct tor_cert_st **cert_out, + const or_options_t *options) +{ + char *secret_fname = NULL; + char *encrypted_secret_fname = NULL; + char *public_fname = NULL; + char *cert_fname = NULL; + const char *loaded_secret_fname = NULL; + int created_pk = 0, created_sk = 0, created_cert = 0; + const int try_to_load = ! (flags & INIT_ED_KEY_REPLACE); + const int encrypt_key = !! (flags & INIT_ED_KEY_TRY_ENCRYPTED); + const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR); + const int split = !! (flags & INIT_ED_KEY_SPLIT); + const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET); + const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET); + const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME); + + /* we don't support setting both of these flags at once. */ + tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) != + (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)); + + char tag[8]; + tor_snprintf(tag, sizeof(tag), "type%d", (int)cert_type); + + tor_cert_t *cert = NULL; + char *got_tag = NULL; + ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); + + if (explicit_fname) { + secret_fname = tor_strdup(fname); + encrypted_secret_fname = tor_strdup(fname); + } else { + tor_asprintf(&secret_fname, "%s_secret_key", fname); + tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname); + } + tor_asprintf(&public_fname, "%s_public_key", fname); + tor_asprintf(&cert_fname, "%s_cert", fname); + + /* Try to read the secret key. */ + int have_secret = 0; + int load_secret = try_to_load && + !offline_secret && + (!omit_secret || file_status(public_fname)==FN_NOENT); + if (load_secret) { + int rv = ed25519_seckey_read_from_file(&keypair->seckey, + &got_tag, secret_fname); + if (rv == 0) { + have_secret = 1; + loaded_secret_fname = secret_fname; + tor_assert(got_tag); + } else { + if (errno != ENOENT && norepair) { + tor_log(severity, LD_OR, "Unable to read %s: %s", secret_fname, + strerror(errno)); + goto err; + } + } + } + + /* Should we try for an encrypted key? */ + int have_encrypted_secret_file = 0; + if (!have_secret && try_to_load && encrypt_key) { + int r = read_encrypted_secret_key(&keypair->seckey, + encrypted_secret_fname); + if (r > 0) { + have_secret = 1; + have_encrypted_secret_file = 1; + tor_free(got_tag); /* convince coverity we aren't leaking */ + got_tag = tor_strdup(tag); + loaded_secret_fname = encrypted_secret_fname; + } else if (errno != ENOENT && norepair) { + tor_log(severity, LD_OR, "Unable to read %s: %s", + encrypted_secret_fname, strerror(errno)); + goto err; + } + } else { + if (try_to_load) { + /* Check if it's there anyway, so we don't replace it. */ + if (file_status(encrypted_secret_fname) != FN_NOENT) + have_encrypted_secret_file = 1; + } + } + + if (have_secret) { + if (strcmp(got_tag, tag)) { + tor_log(severity, LD_OR, "%s has wrong tag", loaded_secret_fname); + goto err; + } + /* Derive the public key */ + if (ed25519_public_key_generate(&keypair->pubkey, &keypair->seckey)<0) { + tor_log(severity, LD_OR, "%s can't produce a public key", + loaded_secret_fname); + goto err; + } + } + + /* If we do split keys here, try to read the pubkey. */ + int found_public = 0; + if (try_to_load && (!have_secret || split)) { + ed25519_public_key_t pubkey_tmp; + tor_free(got_tag); + found_public = ed25519_pubkey_read_from_file(&pubkey_tmp, + &got_tag, public_fname) == 0; + if (!found_public && errno != ENOENT && norepair) { + tor_log(severity, LD_OR, "Unable to read %s: %s", public_fname, + strerror(errno)); + goto err; + } + if (found_public && strcmp(got_tag, tag)) { + tor_log(severity, LD_OR, "%s has wrong tag", public_fname); + goto err; + } + if (found_public) { + if (have_secret) { + /* If we have a secret key and we're reloading the public key, + * the key must match! */ + if (! ed25519_pubkey_eq(&keypair->pubkey, &pubkey_tmp)) { + tor_log(severity, LD_OR, "%s does not match %s! If you are trying " + "to restore from backup, make sure you didn't mix up the " + "key files. If you are absolutely sure that %s is the right " + "key for this relay, delete %s or move it out of the way.", + public_fname, loaded_secret_fname, + loaded_secret_fname, public_fname); + goto err; + } + } else { + /* We only have the public key; better use that. */ + tor_assert(split); + memcpy(&keypair->pubkey, &pubkey_tmp, sizeof(pubkey_tmp)); + } + } else { + /* We have no public key file, but we do have a secret key, make the + * public key file! */ + if (have_secret) { + if (ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) + < 0) { + tor_log(severity, LD_OR, "Couldn't repair %s", public_fname); + goto err; + } else { + tor_log(LOG_NOTICE, LD_OR, + "Found secret key but not %s. Regenerating.", + public_fname); + } + } + } + } + + /* If the secret key is absent and it's not allowed to be, fail. */ + if (!have_secret && found_public && + !(flags & INIT_ED_KEY_MISSING_SECRET_OK)) { + if (have_encrypted_secret_file) { + tor_log(severity, LD_OR, "We needed to load a secret key from %s, " + "but it was encrypted. Try 'tor --keygen' instead, so you " + "can enter the passphrase.", + secret_fname); + } else if (offline_secret) { + tor_log(severity, LD_OR, "We wanted to load a secret key from %s, " + "but you're keeping it offline. (OfflineMasterKey is set.)", + secret_fname); + } else { + tor_log(severity, LD_OR, "We needed to load a secret key from %s, " + "but couldn't find it. %s", secret_fname, + (flags & INIT_ED_KEY_SUGGEST_KEYGEN) ? + "If you're keeping your master secret key offline, you will " + "need to run 'tor --keygen' to generate new signing keys." : + "Did you forget to copy it over when you copied the rest of the " + "signing key material?"); + } + goto err; + } + + /* If it's absent, and we're not supposed to make a new keypair, fail. */ + if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE)) { + if (split) { + tor_log(severity, LD_OR, "No key found in %s or %s.", + secret_fname, public_fname); + } else { + tor_log(severity, LD_OR, "No key found in %s.", secret_fname); + } + goto err; + } + + /* If the secret key is absent, but the encrypted key would be present, + * that's an error */ + if (!have_secret && !found_public && have_encrypted_secret_file) { + tor_assert(!encrypt_key); + tor_log(severity, LD_OR, "Found an encrypted secret key, " + "but not public key file %s!", public_fname); + goto err; + } + + /* if it's absent, make a new keypair... */ + if (!have_secret && !found_public) { + tor_free(keypair); + keypair = ed_key_new(signing_key, flags, now, lifetime, + cert_type, &cert); + if (!keypair) { + tor_log(severity, LD_OR, "Couldn't create keypair"); + goto err; + } + created_pk = created_sk = created_cert = 1; + } + + /* Write it to disk if we're supposed to do with a new passphrase, or if + * we just created it. */ + if (created_sk || (have_secret && options != NULL && + options->change_key_passphrase)) { + if (write_secret_key(&keypair->seckey, + encrypt_key, + secret_fname, tag, encrypted_secret_fname) < 0 + || + (split && + ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) < 0) + || + (cert && + crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", + tag, cert->encoded, cert->encoded_len) < 0)) { + tor_log(severity, LD_OR, "Couldn't write keys or cert to file."); + goto err; + } + goto done; + } + + /* If we're not supposed to get a cert, we're done. */ + if (! (flags & INIT_ED_KEY_NEEDCERT)) + goto done; + + /* Read a cert. */ + tor_free(got_tag); + uint8_t certbuf[256]; + ssize_t cert_body_len = crypto_read_tagged_contents_from_file( + cert_fname, "ed25519v1-cert", + &got_tag, certbuf, sizeof(certbuf)); + if (cert_body_len >= 0 && !strcmp(got_tag, tag)) + cert = tor_cert_parse(certbuf, cert_body_len); + + /* If we got it, check it to the extent we can. */ + int bad_cert = 0; + + if (! cert) { + tor_log(severity, LD_OR, "Cert was unparseable"); + bad_cert = 1; + } else if (!tor_memeq(cert->signed_key.pubkey, keypair->pubkey.pubkey, + ED25519_PUBKEY_LEN)) { + tor_log(severity, LD_OR, "Cert was for wrong key"); + bad_cert = 1; + } else if (signing_key && + tor_cert_checksig(cert, &signing_key->pubkey, now) < 0) { + tor_log(severity, LD_OR, "Can't check certificate: %s", + tor_cert_describe_signature_status(cert)); + bad_cert = 1; + } else if (cert->cert_expired) { + tor_log(severity, LD_OR, "Certificate is expired"); + bad_cert = 1; + } else if (signing_key && cert->signing_key_included && + ! ed25519_pubkey_eq(&signing_key->pubkey, &cert->signing_key)) { + tor_log(severity, LD_OR, "Certificate signed by unexpectd key!"); + bad_cert = 1; + } + + if (bad_cert) { + tor_cert_free(cert); + cert = NULL; + } + + /* If we got a cert, we're done. */ + if (cert) + goto done; + + /* If we didn't get a cert, and we're not supposed to make one, fail. */ + if (!signing_key || !(flags & INIT_ED_KEY_CREATE)) { + tor_log(severity, LD_OR, "Without signing key, can't create certificate"); + goto err; + } + + /* We have keys but not a certificate, so make one. */ + uint32_t cert_flags = 0; + if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) + cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; + cert = tor_cert_create(signing_key, cert_type, + &keypair->pubkey, + now, lifetime, + cert_flags); + + if (! cert) { + tor_log(severity, LD_OR, "Couldn't create certificate"); + goto err; + } + + /* Write it to disk. */ + created_cert = 1; + if (crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", + tag, cert->encoded, cert->encoded_len) < 0) { + tor_log(severity, LD_OR, "Couldn't write cert to disk."); + goto err; + } + + done: + if (cert_out) + *cert_out = cert; + else + tor_cert_free(cert); + + goto cleanup; + + err: + if (keypair) + memwipe(keypair, 0, sizeof(*keypair)); + tor_free(keypair); + tor_cert_free(cert); + if (cert_out) + *cert_out = NULL; + if (created_sk) + unlink(secret_fname); + if (created_pk) + unlink(public_fname); + if (created_cert) + unlink(cert_fname); + + cleanup: + tor_free(encrypted_secret_fname); + tor_free(secret_fname); + tor_free(public_fname); + tor_free(cert_fname); + tor_free(got_tag); + + return keypair; +} + +/** + * Create a new signing key and (optionally) certficiate; do not read or write + * from disk. See ed_key_init_from_file() for more information. + */ +ed25519_keypair_t * +ed_key_new(const ed25519_keypair_t *signing_key, + uint32_t flags, + time_t now, + time_t lifetime, + uint8_t cert_type, + struct tor_cert_st **cert_out) +{ + if (cert_out) + *cert_out = NULL; + + const int extra_strong = !! (flags & INIT_ED_KEY_EXTRA_STRONG); + ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); + if (ed25519_keypair_generate(keypair, extra_strong) < 0) + goto err; + + if (! (flags & INIT_ED_KEY_NEEDCERT)) + return keypair; + + tor_assert(signing_key); + tor_assert(cert_out); + uint32_t cert_flags = 0; + if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) + cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; + tor_cert_t *cert = tor_cert_create(signing_key, cert_type, + &keypair->pubkey, + now, lifetime, + cert_flags); + if (! cert) + goto err; + + *cert_out = cert; + return keypair; + + err: + tor_free(keypair); + return NULL; +} diff --git a/src/feature/keymgt/loadkey.h b/src/feature/keymgt/loadkey.h new file mode 100644 index 0000000000..7717bda29e --- /dev/null +++ b/src/feature/keymgt/loadkey.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file loadkey.h + * \brief Header file for loadkey.c + **/ + +#ifndef TOR_LOADKEY_H +#define TOR_LOADKEY_H + +#include "lib/crypt_ops/crypto_ed25519.h" + +crypto_pk_t *init_key_from_file(const char *fname, int generate, + int severity, bool *created_out); + +#define INIT_ED_KEY_CREATE (1u<<0) +#define INIT_ED_KEY_REPLACE (1u<<1) +#define INIT_ED_KEY_SPLIT (1u<<2) +#define INIT_ED_KEY_MISSING_SECRET_OK (1u<<3) +#define INIT_ED_KEY_NEEDCERT (1u<<4) +#define INIT_ED_KEY_EXTRA_STRONG (1u<<5) +#define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6) +#define INIT_ED_KEY_OMIT_SECRET (1u<<7) +#define INIT_ED_KEY_TRY_ENCRYPTED (1u<<8) +#define INIT_ED_KEY_NO_REPAIR (1u<<9) +#define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10) +#define INIT_ED_KEY_OFFLINE_SECRET (1u<<11) +#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<12) + +struct tor_cert_st; +ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags, + int severity, + const ed25519_keypair_t *signing_key, + time_t now, + time_t lifetime, + uint8_t cert_type, + struct tor_cert_st **cert_out, + const or_options_t *options); +ed25519_keypair_t *ed_key_new(const ed25519_keypair_t *signing_key, + uint32_t flags, + time_t now, + time_t lifetime, + uint8_t cert_type, + struct tor_cert_st **cert_out); + +int read_encrypted_secret_key(ed25519_secret_key_t *out, + const char *fname); +int write_encrypted_secret_key(const ed25519_secret_key_t *out, + const char *fname); + +#endif diff --git a/src/feature/nodelist/authcert.c b/src/feature/nodelist/authcert.c index e070cb1424..2624ed5eef 100644 --- a/src/feature/nodelist/authcert.c +++ b/src/feature/nodelist/authcert.c @@ -23,6 +23,7 @@ #include "core/mainloop/mainloop.h" #include "core/or/policies.h" #include "feature/client/bridges.h" +#include "feature/dirauth/authmode.h" #include "feature/dircommon/directory.h" #include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" @@ -34,7 +35,7 @@ #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "core/or/connection_st.h" #include "feature/dirclient/dir_server_st.h" diff --git a/src/feature/nodelist/describe.c b/src/feature/nodelist/describe.c new file mode 100644 index 0000000000..6df3da1965 --- /dev/null +++ b/src/feature/nodelist/describe.c @@ -0,0 +1,183 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file describe.c + * \brief Format short descriptions of relays. + */ + +#include "core/or/or.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/routerinfo.h" + +#include "core/or/extend_info_st.h" +#include "feature/nodelist/node_st.h" +#include "feature/nodelist/routerinfo_st.h" +#include "feature/nodelist/routerstatus_st.h" + +/** + * Longest allowed output of format_node_description, plus 1 character for + * NUL. This allows space for: + * "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF~xxxxxxxxxxxxxxxxxxx at" + * " [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]" + * plus a terminating NUL. + */ +#define NODE_DESC_BUF_LEN (MAX_VERBOSE_NICKNAME_LEN+4+TOR_ADDR_BUF_LEN) + +/** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to + * hold a human-readable description of a node with identity digest + * <b>id_digest</b>, named-status <b>is_named</b>, nickname <b>nickname</b>, + * and address <b>addr</b> or <b>addr32h</b>. + * + * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to + * NULL. The <b>addr32h</b> field is optional and may be set to 0. + * + * Return a pointer to the front of <b>buf</b>. + */ +static const char * +format_node_description(char *buf, + const char *id_digest, + int is_named, + const char *nickname, + const tor_addr_t *addr, + uint32_t addr32h) +{ + char *cp; + + if (!buf) + return "<NULL BUFFER>"; + + buf[0] = '$'; + base16_encode(buf+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN); + cp = buf+1+HEX_DIGEST_LEN; + if (nickname) { + buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~'; + strlcpy(buf+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1); + cp += strlen(cp); + } + if (addr32h || addr) { + memcpy(cp, " at ", 4); + cp += 4; + if (addr) { + tor_addr_to_str(cp, addr, TOR_ADDR_BUF_LEN, 0); + } else { + struct in_addr in; + in.s_addr = htonl(addr32h); + tor_inet_ntoa(&in, cp, INET_NTOA_BUF_LEN); + } + } + return buf; +} + +/** Return a human-readable description of the routerinfo_t <b>ri</b>. + * + * This function is not thread-safe. Each call to this function invalidates + * previous values returned by this function. + */ +const char * +router_describe(const routerinfo_t *ri) +{ + static char buf[NODE_DESC_BUF_LEN]; + + if (!ri) + return "<null>"; + return format_node_description(buf, + ri->cache_info.identity_digest, + 0, + ri->nickname, + NULL, + ri->addr); +} + +/** Return a human-readable description of the node_t <b>node</b>. + * + * This function is not thread-safe. Each call to this function invalidates + * previous values returned by this function. + */ +const char * +node_describe(const node_t *node) +{ + static char buf[NODE_DESC_BUF_LEN]; + const char *nickname = NULL; + uint32_t addr32h = 0; + int is_named = 0; + + if (!node) + return "<null>"; + + if (node->rs) { + nickname = node->rs->nickname; + is_named = node->rs->is_named; + addr32h = node->rs->addr; + } else if (node->ri) { + nickname = node->ri->nickname; + addr32h = node->ri->addr; + } + + return format_node_description(buf, + node->identity, + is_named, + nickname, + NULL, + addr32h); +} + +/** Return a human-readable description of the routerstatus_t <b>rs</b>. + * + * This function is not thread-safe. Each call to this function invalidates + * previous values returned by this function. + */ +const char * +routerstatus_describe(const routerstatus_t *rs) +{ + static char buf[NODE_DESC_BUF_LEN]; + + if (!rs) + return "<null>"; + return format_node_description(buf, + rs->identity_digest, + rs->is_named, + rs->nickname, + NULL, + rs->addr); +} + +/** Return a human-readable description of the extend_info_t <b>ei</b>. + * + * This function is not thread-safe. Each call to this function invalidates + * previous values returned by this function. + */ +const char * +extend_info_describe(const extend_info_t *ei) +{ + static char buf[NODE_DESC_BUF_LEN]; + + if (!ei) + return "<null>"; + return format_node_description(buf, + ei->identity_digest, + 0, + ei->nickname, + &ei->addr, + 0); +} + +/** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the + * verbose representation of the identity of <b>router</b>. The format is: + * A dollar sign. + * The upper-case hexadecimal encoding of the SHA1 hash of router's identity. + * A "=" if the router is named (no longer implemented); a "~" if it is not. + * The router's nickname. + **/ +void +router_get_verbose_nickname(char *buf, const routerinfo_t *router) +{ + buf[0] = '$'; + base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest, + DIGEST_LEN); + buf[1+HEX_DIGEST_LEN] = '~'; + strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1); +} diff --git a/src/feature/nodelist/describe.h b/src/feature/nodelist/describe.h new file mode 100644 index 0000000000..e5723bb933 --- /dev/null +++ b/src/feature/nodelist/describe.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file describe.h + * \brief Header file for describe.c. + **/ + +#ifndef TOR_DESCRIBE_H +#define TOR_DESCRIBE_H + +struct extend_info_t; +struct node_t; +struct routerinfo_t; +struct routerstatus_t; + +const char *extend_info_describe(const struct extend_info_t *ei); +const char *node_describe(const struct node_t *node); +const char *router_describe(const struct routerinfo_t *ri); +const char *routerstatus_describe(const struct routerstatus_t *ri); + +#endif diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index 0935145d88..c14d7df0f0 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -29,6 +29,7 @@ #include "app/config/config.h" #include "core/or/policies.h" #include "feature/control/control.h" +#include "feature/dirauth/authmode.h" #include "feature/dircommon/directory.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/networkstatus.h" diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index c6a51aefc7..67b5a1d046 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -38,48 +38,50 @@ #define NETWORKSTATUS_PRIVATE #include "core/or/or.h" -#include "feature/client/bridges.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/or/channel.h" +#include "core/or/channelpadding.h" #include "core/or/circuitmux.h" #include "core/or/circuitmux_ewma.h" #include "core/or/circuitstats.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/dircache/consdiffmgr.h" +#include "core/or/dos.h" +#include "core/or/protover.h" +#include "core/or/relay.h" +#include "core/or/scheduler.h" +#include "feature/client/bridges.h" +#include "feature/client/entrynodes.h" +#include "feature/client/transports.h" #include "feature/control/control.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" +#include "feature/dirauth/reachability.h" +#include "feature/dircache/consdiffmgr.h" +#include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" -#include "feature/dircache/dirserv.h" -#include "feature/dirauth/reachability.h" -#include "core/or/dos.h" -#include "feature/client/entrynodes.h" +#include "feature/dircommon/directory.h" +#include "feature/dircommon/voting_schedule.h" #include "feature/hibernate/hibernate.h" -#include "core/mainloop/mainloop.h" -#include "feature/nodelist/microdesc.h" -#include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" -#include "core/or/protover.h" -#include "core/or/relay.h" -#include "feature/relay/router.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/dirlist.h" +#include "feature/nodelist/fmt_routerstatus.h" +#include "feature/nodelist/microdesc.h" +#include "feature/nodelist/networkstatus.h" #include "feature/nodelist/node_select.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" -#include "core/or/scheduler.h" -#include "feature/client/transports.h" #include "feature/nodelist/torcert.h" -#include "core/or/channelpadding.h" -#include "feature/dircommon/voting_schedule.h" -#include "feature/nodelist/fmt_routerstatus.h" +#include "feature/relay/routermode.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "feature/dirauth/dirvote.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/dirauth/shared_random.h" #include "feature/dirauth/voteflags.h" diff --git a/src/feature/nodelist/nickname.c b/src/feature/nodelist/nickname.c new file mode 100644 index 0000000000..7b0b29a934 --- /dev/null +++ b/src/feature/nodelist/nickname.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file nickname.c + * \brief Check and manipulate relay nicknames. + */ + +#include "core/or/or.h" +#include "feature/nodelist/nickname.h" + +/** Return true iff <b>s</b> is a valid server nickname. (That is, a string + * containing between 1 and MAX_NICKNAME_LEN characters from + * LEGAL_NICKNAME_CHARACTERS.) */ +int +is_legal_nickname(const char *s) +{ + size_t len; + tor_assert(s); + len = strlen(s); + return len > 0 && len <= MAX_NICKNAME_LEN && + strspn(s,LEGAL_NICKNAME_CHARACTERS) == len; +} + +/** Return true iff <b>s</b> is a valid server nickname or + * hex-encoded identity-key digest. */ +int +is_legal_nickname_or_hexdigest(const char *s) +{ + if (*s!='$') + return is_legal_nickname(s); + else + return is_legal_hexdigest(s); +} + +/** Return true iff <b>s</b> is a valid hex-encoded identity-key + * digest. (That is, an optional $, followed by 40 hex characters, + * followed by either nothing, or = or ~ followed by a nickname, or + * a character other than =, ~, or a hex character.) + */ +int +is_legal_hexdigest(const char *s) +{ + size_t len; + tor_assert(s); + if (s[0] == '$') s++; + len = strlen(s); + if (len > HEX_DIGEST_LEN) { + if (s[HEX_DIGEST_LEN] == '=' || + s[HEX_DIGEST_LEN] == '~') { + if (!is_legal_nickname(s+HEX_DIGEST_LEN+1)) + return 0; + } else { + return 0; + } + } + return (len >= HEX_DIGEST_LEN && + strspn(s,HEX_CHARACTERS)==HEX_DIGEST_LEN); +} diff --git a/src/feature/nodelist/nickname.h b/src/feature/nodelist/nickname.h new file mode 100644 index 0000000000..86d4309918 --- /dev/null +++ b/src/feature/nodelist/nickname.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file nickname.h + * \brief Header file for nickname.c. + **/ + +#ifndef TOR_NICKNAME_H +#define TOR_NICKNAME_H + +int is_legal_nickname(const char *s); +int is_legal_nickname_or_hexdigest(const char *s); +int is_legal_hexdigest(const char *s); + +#endif diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c index aab0bbe9f5..04a24de9a1 100644 --- a/src/feature/nodelist/node_select.c +++ b/src/feature/nodelist/node_select.c @@ -18,8 +18,9 @@ #include "core/or/policies.h" #include "core/or/reasons.h" #include "feature/client/entrynodes.h" -#include "feature/dircommon/directory.h" #include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" @@ -28,6 +29,7 @@ #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerset.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/math/fp.h" diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index ce77d71c64..e3b77d562c 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -41,35 +41,36 @@ #define NODELIST_PRIVATE #include "core/or/or.h" -#include "lib/net/address.h" +#include "app/config/config.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" #include "core/or/address_set.h" +#include "core/or/policies.h" +#include "core/or/protover.h" #include "feature/client/bridges.h" -#include "app/config/config.h" +#include "feature/client/entrynodes.h" #include "feature/control/control.h" -#include "feature/dircache/dirserv.h" #include "feature/dirauth/process_descs.h" -#include "feature/client/entrynodes.h" -#include "feature/stats/geoip.h" -#include "feature/hs/hs_common.h" +#include "feature/dircache/dirserv.h" #include "feature/hs/hs_client.h" -#include "core/mainloop/mainloop.h" +#include "feature/hs/hs_common.h" +#include "feature/nodelist/describe.h" +#include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "core/or/protover.h" -#include "feature/rend/rendservice.h" -#include "feature/relay/router.h" -#include "feature/nodelist/dirlist.h" #include "feature/nodelist/node_select.h" +#include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" #include "feature/nodelist/torcert.h" +#include "feature/rend/rendservice.h" +#include "feature/stats/geoip.h" +#include "lib/net/address.h" #include <string.h> -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" #include "feature/dirclient/dir_server_st.h" #include "feature/nodelist/microdesc_st.h" diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c new file mode 100644 index 0000000000..601de78d60 --- /dev/null +++ b/src/feature/nodelist/routerinfo.c @@ -0,0 +1,79 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "core/or/or.h" + +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" + +#include "feature/nodelist/node_st.h" +#include "feature/nodelist/routerinfo_st.h" + +/** Copy the primary (IPv4) OR port (IP address and TCP port) for + * <b>router</b> into *<b>ap_out</b>. */ +void +router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) +{ + tor_assert(ap_out != NULL); + tor_addr_from_ipv4h(&ap_out->addr, router->addr); + ap_out->port = router->or_port; +} + +int +router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) +{ + return + (tor_addr_eq_ipv4h(&orport->addr, router->addr) && + orport->port == router->or_port) || + (tor_addr_eq(&orport->addr, &router->ipv6_addr) && + orport->port == router->ipv6_orport); +} + +/** Return a smartlist of tor_addr_port_t's with all the OR ports of + <b>ri</b>. Note that freeing of the items in the list as well as + the smartlist itself is the callers responsibility. */ +smartlist_t * +router_get_all_orports(const routerinfo_t *ri) +{ + tor_assert(ri); + node_t fake_node; + memset(&fake_node, 0, sizeof(fake_node)); + /* we don't modify ri, fake_node is passed as a const node_t * + */ + fake_node.ri = (routerinfo_t *)ri; + return node_get_all_orports(&fake_node); +} + +/** Given a router purpose, convert it to a string. Don't call this on + * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't + * know its string representation. */ +const char * +router_purpose_to_string(uint8_t p) +{ + switch (p) + { + case ROUTER_PURPOSE_GENERAL: return "general"; + case ROUTER_PURPOSE_BRIDGE: return "bridge"; + case ROUTER_PURPOSE_CONTROLLER: return "controller"; + default: + tor_assert(0); + } + return NULL; +} + +/** Given a string, convert it to a router purpose. */ +uint8_t +router_purpose_from_string(const char *s) +{ + if (!strcmp(s, "general")) + return ROUTER_PURPOSE_GENERAL; + else if (!strcmp(s, "bridge")) + return ROUTER_PURPOSE_BRIDGE; + else if (!strcmp(s, "controller")) + return ROUTER_PURPOSE_CONTROLLER; + else + return ROUTER_PURPOSE_UNKNOWN; +} diff --git a/src/feature/nodelist/routerinfo.h b/src/feature/nodelist/routerinfo.h new file mode 100644 index 0000000000..b4b245bb23 --- /dev/null +++ b/src/feature/nodelist/routerinfo.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file routerinfo.h + * \brief Header file for routerinfo.c. + **/ + +#ifndef TOR_ROUTERINFO_H +#define TOR_ROUTERINFO_H + +void router_get_prim_orport(const routerinfo_t *router, + tor_addr_port_t *addr_port_out); +int router_has_orport(const routerinfo_t *router, + const tor_addr_port_t *orport); + +void router_get_verbose_nickname(char *buf, const routerinfo_t *router); + +smartlist_t *router_get_all_orports(const routerinfo_t *ri); + +const char *router_purpose_to_string(uint8_t p); +uint8_t router_purpose_from_string(const char *s); + +#endif diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index 5c6a104779..20956d8cca 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -68,24 +68,26 @@ #include "core/or/policies.h" #include "feature/client/bridges.h" #include "feature/control/control.h" -#include "feature/dirauth/mode.h" -#include "feature/dircommon/directory.h" -#include "feature/dirclient/dirclient.h" +#include "feature/dirauth/authmode.h" +#include "feature/dirauth/process_descs.h" +#include "feature/dirauth/reachability.h" #include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient.h" #include "feature/dirclient/dlstatus.h" -#include "feature/dirauth/reachability.h" -#include "feature/dirauth/process_descs.h" +#include "feature/dircommon/directory.h" #include "feature/nodelist/authcert.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" #include "feature/nodelist/node_select.h" +#include "feature/nodelist/nodelist.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" #include "feature/nodelist/torcert.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/stats/rephist.h" #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_rand.h" diff --git a/src/feature/nodelist/routerparse.c b/src/feature/nodelist/routerparse.c index a72cf98f56..c12f411e87 100644 --- a/src/feature/nodelist/routerparse.c +++ b/src/feature/nodelist/routerparse.c @@ -56,29 +56,32 @@ #define ROUTERPARSE_PRIVATE #include "core/or/or.h" -#include "core/or/circuitstats.h" #include "app/config/config.h" -#include "lib/crypt_ops/crypto_format.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dirauth/shared_random.h" +#include "core/or/circuitstats.h" +#include "core/or/policies.h" +#include "core/or/protover.h" #include "feature/client/entrynodes.h" -#include "lib/memarea/memarea.h" +#include "feature/dirauth/shared_random.h" +#include "feature/dircommon/voting_schedule.h" +#include "feature/hs_common/shared_random_client.h" +#include "feature/nodelist/authcert.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/microdesc.h" #include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/parsecommon.h" -#include "core/or/policies.h" -#include "core/or/protover.h" -#include "feature/rend/rendcommon.h" -#include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" +#include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" -#include "feature/nodelist/authcert.h" -#include "lib/sandbox/sandbox.h" -#include "feature/hs_common/shared_random_client.h" #include "feature/nodelist/torcert.h" -#include "feature/dircommon/voting_schedule.h" +#include "feature/relay/router.h" +#include "feature/relay/routerkeys.h" +#include "feature/rend/rendcommon.h" +#include "feature/stats/rephist.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/memarea/memarea.h" +#include "lib/sandbox/sandbox.h" #include "feature/dirauth/dirvote.h" diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index cd42697748..08124835ae 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -28,13 +28,13 @@ n * Copyright (c) 2001-2004, Roger Dingledine. #define ROUTERSET_PRIVATE #include "core/or/or.h" +#include "core/or/policies.h" #include "feature/client/bridges.h" -#include "feature/stats/geoip.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" -#include "feature/relay/router.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" +#include "feature/stats/geoip.h" #include "core/or/addr_policy_st.h" #include "core/or/extend_info_st.h" diff --git a/src/feature/nodelist/torcert.c b/src/feature/nodelist/torcert.c index fe67e56403..675d5c97b7 100644 --- a/src/feature/nodelist/torcert.c +++ b/src/feature/nodelist/torcert.c @@ -638,6 +638,43 @@ or_handshake_certs_ed25519_ok(int severity, return 1; } +/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it + * is, -1 if it isn't. */ +MOCK_IMPL(int, +check_tap_onion_key_crosscert,(const uint8_t *crosscert, + int crosscert_len, + const crypto_pk_t *onion_pkey, + const ed25519_public_key_t *master_id_pkey, + const uint8_t *rsa_id_digest)) +{ + uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey)); + int cc_len = + crypto_pk_public_checksig(onion_pkey, + (char*)cc, + crypto_pk_keysize(onion_pkey), + (const char*)crosscert, + crosscert_len); + if (cc_len < 0) { + goto err; + } + if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) { + log_warn(LD_DIR, "Short signature on cross-certification with TAP key"); + goto err; + } + if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) || + tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey, + ED25519_PUBKEY_LEN)) { + log_warn(LD_DIR, "Incorrect cross-certification with TAP key"); + goto err; + } + + tor_free(cc); + return 0; + err: + tor_free(cc); + return -1; +} + /** * Check the Ed certificates and/or the RSA certificates, as appropriate. If * we obtained an Ed25519 identity, set *ed_id_out. If we obtained an RSA diff --git a/src/feature/nodelist/torcert.h b/src/feature/nodelist/torcert.h index 5fa97679df..cb5e23cc33 100644 --- a/src/feature/nodelist/torcert.h +++ b/src/feature/nodelist/torcert.h @@ -107,4 +107,10 @@ void or_handshake_certs_check_both(int severity, int tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out); +MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert, + int crosscert_len, + const crypto_pk_t *onion_pkey, + const ed25519_public_key_t *master_id_pkey, + const uint8_t *rsa_id_digest)); + #endif /* !defined(TORCERT_H_INCLUDED) */ diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c index 6e9be5e2e7..bc507d47f6 100644 --- a/src/feature/relay/dns.c +++ b/src/feature/relay/dns.c @@ -50,25 +50,28 @@ #define DNS_PRIVATE #include "core/or/or.h" -#include "core/or/circuitlist.h" -#include "core/or/circuituse.h" #include "app/config/config.h" #include "core/mainloop/connection.h" -#include "core/or/connection_edge.h" -#include "feature/control/control.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "feature/relay/dns.h" #include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" +#include "core/or/circuitlist.h" +#include "core/or/circuituse.h" +#include "core/or/connection_edge.h" #include "core/or/policies.h" #include "core/or/relay.h" +#include "feature/control/control.h" +#include "feature/relay/dns.h" #include "feature/relay/router.h" -#include "ht.h" -#include "lib/sandbox/sandbox.h" +#include "feature/relay/routermode.h" +#include "lib/crypt_ops/crypto_rand.h" #include "lib/evloop/compat_libevent.h" +#include "lib/sandbox/sandbox.h" #include "core/or/edge_connection_st.h" #include "core/or/or_circuit_st.h" +#include "ht.h" + #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 622cfeb86d..8629ad9561 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -7,60 +7,57 @@ #define ROUTER_PRIVATE #include "core/or/or.h" -#include "core/or/circuitbuild.h" -#include "core/or/circuitlist.h" -#include "core/or/circuituse.h" #include "app/config/config.h" -#include "core/mainloop/connection.h" -#include "feature/control/control.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "lib/crypt_ops/crypto_curve25519.h" -#include "feature/dircommon/directory.h" -#include "feature/dirclient/dirclient.h" -#include "feature/dircache/dirserv.h" -#include "feature/dirauth/process_descs.h" -#include "feature/relay/dns.h" -#include "feature/stats/geoip.h" -#include "feature/hibernate/hibernate.h" +#include "app/config/statefile.h" #include "app/main/main.h" +#include "core/mainloop/connection.h" #include "core/mainloop/mainloop.h" -#include "feature/nodelist/networkstatus.h" -#include "feature/nodelist/nodelist.h" +#include "core/mainloop/netstatus.h" #include "core/or/policies.h" #include "core/or/protover.h" -#include "core/or/relay.h" -#include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" +#include "feature/client/transports.h" +#include "feature/control/control.h" +#include "feature/dirauth/process_descs.h" +#include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" +#include "feature/hibernate/hibernate.h" +#include "feature/keymgt/loadkey.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/dirlist.h" +#include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" +#include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" -#include "app/config/statefile.h" #include "feature/nodelist/torcert.h" -#include "feature/client/transports.h" -#include "feature/nodelist/routerset.h" +#include "feature/relay/dns.h" +#include "feature/relay/router.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" +#include "feature/stats/geoip.h" +#include "feature/stats/rephist.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_init.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" +#include "lib/encoding/confline.h" +#include "lib/osinfo/uname.h" +#include "lib/tls/tortls.h" -#include "feature/dirauth/mode.h" +#include "feature/dirauth/authmode.h" -#include "feature/nodelist/authority_cert_st.h" -#include "core/or/crypt_path_st.h" -#include "feature/dircommon/dir_connection_st.h" +#include "app/config/or_state_st.h" +#include "core/or/port_cfg_st.h" #include "feature/dirclient/dir_server_st.h" -#include "core/or/extend_info_st.h" +#include "feature/dircommon/dir_connection_st.h" +#include "feature/nodelist/authority_cert_st.h" #include "feature/nodelist/extrainfo_st.h" #include "feature/nodelist/node_st.h" -#include "core/or/origin_circuit_st.h" -#include "app/config/or_state_st.h" -#include "core/or/port_cfg_st.h" #include "feature/nodelist/routerinfo_st.h" - -#include "lib/osinfo/uname.h" -#include "lib/tls/tortls.h" -#include "lib/encoding/confline.h" -#include "lib/crypt_ops/crypto_format.h" -#include "lib/crypt_ops/crypto_init.h" +#include "feature/nodelist/routerstatus_st.h" /** * \file router.c @@ -130,13 +127,6 @@ static authority_cert_t *legacy_key_certificate = NULL; * used by tor-gencert to sign new signing keys and make new key * certificates. */ -const char *format_node_description(char *buf, - const char *id_digest, - int is_named, - const char *nickname, - const tor_addr_t *addr, - uint32_t addr32h); - /** Return a readonly string with human readable description * of <b>err</b>. */ @@ -540,85 +530,6 @@ log_new_relay_greeting(void) already_logged = 1; } -/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist - * and <b>generate</b> is true, create a new RSA key and save it in - * <b>fname</b>. Return the read/created key, or NULL on error. Log all - * errors at level <b>severity</b>. If <b>log_greeting</b> is non-zero and a - * new key was created, log_new_relay_greeting() is called. - */ -crypto_pk_t * -init_key_from_file(const char *fname, int generate, int severity, - int log_greeting) -{ - crypto_pk_t *prkey = NULL; - - if (!(prkey = crypto_pk_new())) { - tor_log(severity, LD_GENERAL,"Error constructing key"); - goto error; - } - - switch (file_status(fname)) { - case FN_DIR: - case FN_ERROR: - tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname); - goto error; - /* treat empty key files as if the file doesn't exist, and, - * if generate is set, replace the empty file in - * crypto_pk_write_private_key_to_filename() */ - case FN_NOENT: - case FN_EMPTY: - if (generate) { - if (!have_lockfile()) { - if (try_locking(get_options(), 0)<0) { - /* Make sure that --list-fingerprint only creates new keys - * if there is no possibility for a deadlock. */ - tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". " - "Not writing any new keys.", fname); - /*XXXX The 'other process' might make a key in a second or two; - * maybe we should wait for it. */ - goto error; - } - } - log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.", - fname); - if (crypto_pk_generate_key(prkey)) { - tor_log(severity, LD_GENERAL,"Error generating onion key"); - goto error; - } - if (! crypto_pk_is_valid_private_key(prkey)) { - tor_log(severity, LD_GENERAL,"Generated key seems invalid"); - goto error; - } - log_info(LD_GENERAL, "Generated key seems valid"); - if (log_greeting) { - log_new_relay_greeting(); - } - if (crypto_pk_write_private_key_to_filename(prkey, fname)) { - tor_log(severity, LD_FS, - "Couldn't write generated key to \"%s\".", fname); - goto error; - } - } else { - tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname); - goto error; - } - return prkey; - case FN_FILE: - if (crypto_pk_read_private_key_from_filename(prkey, fname)) { - tor_log(severity, LD_GENERAL,"Error loading private key."); - goto error; - } - return prkey; - default: - tor_assert(0); - } - - error: - if (prkey) - crypto_pk_free(prkey); - return NULL; -} - /** Load a curve25519 keypair from the file <b>fname</b>, writing it into * <b>keys_out</b>. If the file isn't found, or is empty, and <b>generate</b> * is true, create a new keypair and write it into the file. If there are @@ -708,7 +619,7 @@ load_authority_keyset(int legacy, crypto_pk_t **key_out, fname = get_keydir_fname( legacy ? "legacy_signing_key" : "authority_signing_key"); - signing_key = init_key_from_file(fname, 0, LOG_ERR, 0); + signing_key = init_key_from_file(fname, 0, LOG_ERR, NULL); if (!signing_key) { log_warn(LD_DIR, "No version 3 directory key found in %s", fname); goto done; @@ -1042,9 +953,12 @@ init_keys(void) /* 1b. Read identity key. Make it if none is found. */ keydir = get_keydir_fname("secret_id_key"); log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir); - prkey = init_key_from_file(keydir, 1, LOG_ERR, 1); + bool created = false; + prkey = init_key_from_file(keydir, 1, LOG_ERR, &created); tor_free(keydir); if (!prkey) return -1; + if (created) + log_new_relay_greeting(); set_server_identity_key(prkey); /* 1c. If we are configured as a bridge, generate a client key; @@ -1070,7 +984,9 @@ init_keys(void) /* 2. Read onion key. Make it if none is found. */ keydir = get_keydir_fname("secret_onion_key"); log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir); - prkey = init_key_from_file(keydir, 1, LOG_ERR, 1); + prkey = init_key_from_file(keydir, 1, LOG_ERR, &created); + if (created) + log_new_relay_greeting(); tor_free(keydir); if (!prkey) return -1; set_onion_key(prkey); @@ -1242,68 +1158,6 @@ init_keys(void) return 0; /* success */ } -/* Keep track of whether we should upload our server descriptor, - * and what type of server we are. - */ - -/** Whether we can reach our ORPort from the outside. */ -static int can_reach_or_port = 0; -/** Whether we can reach our DirPort from the outside. */ -static int can_reach_dir_port = 0; - -/** Forget what we have learned about our reachability status. */ -void -router_reset_reachability(void) -{ - can_reach_or_port = can_reach_dir_port = 0; -} - -/** Return 1 if we won't do reachability checks, because: - * - AssumeReachable is set, or - * - the network is disabled. - * Otherwise, return 0. - */ -static int -router_reachability_checks_disabled(const or_options_t *options) -{ - return options->AssumeReachable || - net_is_disabled(); -} - -/** Return 0 if we need to do an ORPort reachability check, because: - * - no reachability check has been done yet, or - * - we've initiated reachability checks, but none have succeeded. - * Return 1 if we don't need to do an ORPort reachability check, because: - * - we've seen a successful reachability check, or - * - AssumeReachable is set, or - * - the network is disabled. - */ -int -check_whether_orport_reachable(const or_options_t *options) -{ - int reach_checks_disabled = router_reachability_checks_disabled(options); - return reach_checks_disabled || - can_reach_or_port; -} - -/** Return 0 if we need to do a DirPort reachability check, because: - * - no reachability check has been done yet, or - * - we've initiated reachability checks, but none have succeeded. - * Return 1 if we don't need to do a DirPort reachability check, because: - * - we've seen a successful reachability check, or - * - there is no DirPort set, or - * - AssumeReachable is set, or - * - the network is disabled. - */ -int -check_whether_dirport_reachable(const or_options_t *options) -{ - int reach_checks_disabled = router_reachability_checks_disabled(options) || - !options->DirPort_set; - return reach_checks_disabled || - can_reach_dir_port; -} - /** The lower threshold of remaining bandwidth required to advertise (or * automatically provide) directory services */ /* XXX Should this be increased? */ @@ -1312,7 +1166,7 @@ check_whether_dirport_reachable(const or_options_t *options) /** Return true iff we have enough configured bandwidth to advertise or * automatically provide directory services from cache directory * information. */ -static int +int router_has_bandwidth_to_be_dirserver(const or_options_t *options) { if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRSERVER) { @@ -1392,19 +1246,6 @@ router_should_be_dirserver(const or_options_t *options, int dir_port) return advertising; } -/** Return 1 if we are configured to accept either relay or directory requests - * from clients and we aren't at risk of exceeding our bandwidth limits, thus - * we should be a directory server. If not, return 0. - */ -int -dir_server_mode(const or_options_t *options) -{ - if (!options->DirCache) - return 0; - return options->DirPort_set || - (server_mode(options) && router_has_bandwidth_to_be_dirserver(options)); -} - /** Look at a variety of factors, and return 0 if we don't want to * advertise the fact that we have a DirPort open or begindir support, else * return 1. @@ -1445,7 +1286,7 @@ decide_to_advertise_dir_impl(const or_options_t *options, * advertise the fact that we have a DirPort open, else return the * DirPort we want to advertise. */ -static int +int router_should_advertise_dirport(const or_options_t *options, uint16_t dir_port) { /* supports_tunnelled_dir_requests is not relevant, pass 0 */ @@ -1464,297 +1305,6 @@ router_should_advertise_begindir(const or_options_t *options, supports_tunnelled_dir_requests); } -/** Allocate and return a new extend_info_t that can be used to build - * a circuit to or through the router <b>r</b>. Uses the primary - * address of the router, so should only be called on a server. */ -static extend_info_t * -extend_info_from_router(const routerinfo_t *r) -{ - crypto_pk_t *rsa_pubkey; - extend_info_t *info; - tor_addr_port_t ap; - tor_assert(r); - - /* Make sure we don't need to check address reachability */ - tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0)); - - const ed25519_public_key_t *ed_id_key; - if (r->cache_info.signing_key_cert) - ed_id_key = &r->cache_info.signing_key_cert->signing_key; - else - ed_id_key = NULL; - - router_get_prim_orport(r, &ap); - rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len); - info = extend_info_new(r->nickname, r->cache_info.identity_digest, - ed_id_key, - rsa_pubkey, r->onion_curve25519_pkey, - &ap.addr, ap.port); - crypto_pk_free(rsa_pubkey); - return info; -} - -/**See if we currently believe our ORPort or DirPort to be - * unreachable. If so, return 1 else return 0. - */ -static int -router_should_check_reachability(int test_or, int test_dir) -{ - const routerinfo_t *me = router_get_my_routerinfo(); - const or_options_t *options = get_options(); - - if (!me) - return 0; - - if (routerset_contains_router(options->ExcludeNodes, me, -1) && - options->StrictNodes) { - /* If we've excluded ourself, and StrictNodes is set, we can't test - * ourself. */ - if (test_or || test_dir) { -#define SELF_EXCLUDED_WARN_INTERVAL 3600 - static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL); - log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC, - "Can't peform self-tests for this relay: we have " - "listed ourself in ExcludeNodes, and StrictNodes is set. " - "We cannot learn whether we are usable, and will not " - "be able to advertise ourself."); - } - return 0; - } - return 1; -} - -/** Some time has passed, or we just got new directory information. - * See if we currently believe our ORPort or DirPort to be - * unreachable. If so, launch a new test for it. - * - * For ORPort, we simply try making a circuit that ends at ourselves. - * Success is noticed in onionskin_answer(). - * - * For DirPort, we make a connection via Tor to our DirPort and ask - * for our own server descriptor. - * Success is noticed in connection_dir_client_reached_eof(). - */ -void -router_do_reachability_checks(int test_or, int test_dir) -{ - const routerinfo_t *me = router_get_my_routerinfo(); - const or_options_t *options = get_options(); - int orport_reachable = check_whether_orport_reachable(options); - tor_addr_t addr; - - if (router_should_check_reachability(test_or, test_dir)) { - if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) { - extend_info_t *ei = extend_info_from_router(me); - /* XXX IPv6 self testing */ - log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.", - !orport_reachable ? "reachability" : "bandwidth", - fmt_addr32(me->addr), me->or_port); - circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei, - CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL); - extend_info_free(ei); - } - - /* XXX IPv6 self testing */ - tor_addr_from_ipv4h(&addr, me->addr); - if (test_dir && !check_whether_dirport_reachable(options) && - !connection_get_by_type_addr_port_purpose( - CONN_TYPE_DIR, &addr, me->dir_port, - DIR_PURPOSE_FETCH_SERVERDESC)) { - tor_addr_port_t my_orport, my_dirport; - memcpy(&my_orport.addr, &addr, sizeof(addr)); - memcpy(&my_dirport.addr, &addr, sizeof(addr)); - my_orport.port = me->or_port; - my_dirport.port = me->dir_port; - /* ask myself, via tor, for my server descriptor. */ - directory_request_t *req = - directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC); - directory_request_set_or_addr_port(req, &my_orport); - directory_request_set_dir_addr_port(req, &my_dirport); - directory_request_set_directory_id_digest(req, - me->cache_info.identity_digest); - // ask via an anon circuit, connecting to our dirport. - directory_request_set_indirection(req, DIRIND_ANON_DIRPORT); - directory_request_set_resource(req, "authority.z"); - directory_initiate_request(req); - directory_request_free(req); - } - } -} - -/** Annotate that we found our ORPort reachable. */ -void -router_orport_found_reachable(void) -{ - const routerinfo_t *me = router_get_my_routerinfo(); - const or_options_t *options = get_options(); - if (!can_reach_or_port && me) { - char *address = tor_dup_ip(me->addr); - log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from " - "the outside. Excellent.%s", - options->PublishServerDescriptor_ != NO_DIRINFO - && check_whether_dirport_reachable(options) ? - " Publishing server descriptor." : ""); - can_reach_or_port = 1; - mark_my_descriptor_dirty("ORPort found reachable"); - /* This is a significant enough change to upload immediately, - * at least in a test network */ - if (options->TestingTorNetwork == 1) { - reschedule_descriptor_update_check(); - } - control_event_server_status(LOG_NOTICE, - "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d", - address, me->or_port); - tor_free(address); - } -} - -/** Annotate that we found our DirPort reachable. */ -void -router_dirport_found_reachable(void) -{ - const routerinfo_t *me = router_get_my_routerinfo(); - const or_options_t *options = get_options(); - if (!can_reach_dir_port && me) { - char *address = tor_dup_ip(me->addr); - log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable " - "from the outside. Excellent.%s", - options->PublishServerDescriptor_ != NO_DIRINFO - && check_whether_orport_reachable(options) ? - " Publishing server descriptor." : ""); - can_reach_dir_port = 1; - if (router_should_advertise_dirport(options, me->dir_port)) { - mark_my_descriptor_dirty("DirPort found reachable"); - /* This is a significant enough change to upload immediately, - * at least in a test network */ - if (options->TestingTorNetwork == 1) { - reschedule_descriptor_update_check(); - } - } - control_event_server_status(LOG_NOTICE, - "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d", - address, me->dir_port); - tor_free(address); - } -} - -/** We have enough testing circuits open. Send a bunch of "drop" - * cells down each of them, to exercise our bandwidth. */ -void -router_perform_bandwidth_test(int num_circs, time_t now) -{ - int num_cells = (int)(get_options()->BandwidthRate * 10 / - CELL_MAX_NETWORK_SIZE); - int max_cells = num_cells < CIRCWINDOW_START ? - num_cells : CIRCWINDOW_START; - int cells_per_circuit = max_cells / num_circs; - origin_circuit_t *circ = NULL; - - log_notice(LD_OR,"Performing bandwidth self-test...done."); - while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL, - CIRCUIT_PURPOSE_TESTING))) { - /* dump cells_per_circuit drop cells onto this circ */ - int i = cells_per_circuit; - if (circ->base_.state != CIRCUIT_STATE_OPEN) - continue; - circ->base_.timestamp_dirty = now; - while (i-- > 0) { - if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), - RELAY_COMMAND_DROP, - NULL, 0, circ->cpath->prev)<0) { - return; /* stop if error */ - } - } - } -} - -/** Return true iff our network is in some sense disabled or shutting down: - * either we're hibernating, entering hibernation, or the network is turned - * off with DisableNetwork. */ -int -net_is_disabled(void) -{ - return get_options()->DisableNetwork || we_are_hibernating(); -} - -/** Return true iff our network is in some sense "completely disabled" either - * we're fully hibernating or the network is turned off with - * DisableNetwork. */ -int -net_is_completely_disabled(void) -{ - return get_options()->DisableNetwork || we_are_fully_hibernating(); -} - -/** Return true iff we believe ourselves to be an authoritative - * directory server. - */ -int -authdir_mode(const or_options_t *options) -{ - return options->AuthoritativeDir != 0; -} -/** Return true iff we are an authoritative directory server that is - * authoritative about receiving and serving descriptors of type - * <b>purpose</b> on its dirport. - */ -int -authdir_mode_handles_descs(const or_options_t *options, int purpose) -{ - if (BUG(purpose < 0)) /* Deprecated. */ - return authdir_mode(options); - else if (purpose == ROUTER_PURPOSE_GENERAL) - return authdir_mode_v3(options); - else if (purpose == ROUTER_PURPOSE_BRIDGE) - return authdir_mode_bridge(options); - else - return 0; -} -/** Return true iff we are an authoritative directory server that - * publishes its own network statuses. - */ -int -authdir_mode_publishes_statuses(const or_options_t *options) -{ - if (authdir_mode_bridge(options)) - return 0; - return authdir_mode(options); -} -/** Return true iff we are an authoritative directory server that - * tests reachability of the descriptors it learns about. - */ -int -authdir_mode_tests_reachability(const or_options_t *options) -{ - return authdir_mode(options); -} -/** Return true iff we believe ourselves to be a bridge authoritative - * directory server. - */ -int -authdir_mode_bridge(const or_options_t *options) -{ - return authdir_mode(options) && options->BridgeAuthoritativeDir != 0; -} - -/** Return true iff we are trying to be a server. - */ -MOCK_IMPL(int, -server_mode,(const or_options_t *options)) -{ - if (options->ClientOnly) return 0; - return (options->ORPort_set); -} - -/** Return true iff we are trying to be a non-bridge server. - */ -MOCK_IMPL(int, -public_server_mode,(const or_options_t *options)) -{ - if (!server_mode(options)) return 0; - return (!options->BridgeRelay); -} - /** Return true iff the combination of options in <b>options</b> and parameters * in the consensus mean that we don't want to allow exits from circuits * we got from addresses not known to be servers. */ @@ -1768,42 +1318,6 @@ should_refuse_unknown_exits(const or_options_t *options) } } -/** Remember if we've advertised ourselves to the dirservers. */ -static int server_is_advertised=0; - -/** Return true iff we have published our descriptor lately. - */ -MOCK_IMPL(int, -advertised_server_mode,(void)) -{ - return server_is_advertised; -} - -/** - * Called with a boolean: set whether we have recently published our - * descriptor. - */ -static void -set_server_advertised(int s) -{ - server_is_advertised = s; -} - -/** Return true iff we are trying to proxy client connections. */ -int -proxy_mode(const or_options_t *options) -{ - (void)options; - SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { - if (p->type == CONN_TYPE_AP_LISTENER || - p->type == CONN_TYPE_AP_TRANS_LISTENER || - p->type == CONN_TYPE_AP_DNS_LISTENER || - p->type == CONN_TYPE_AP_NATD_LISTENER) - return 1; - } SMARTLIST_FOREACH_END(p); - return 0; -} - /** Decide if we're a publishable server. We are a publishable server if: * - We don't have the ClientOnly option set * and @@ -3267,36 +2781,6 @@ router_dump_exit_policy_to_string(const routerinfo_t *router, include_ipv6); } -/** Copy the primary (IPv4) OR port (IP address and TCP port) for - * <b>router</b> into *<b>ap_out</b>. */ -void -router_get_prim_orport(const routerinfo_t *router, tor_addr_port_t *ap_out) -{ - tor_assert(ap_out != NULL); - tor_addr_from_ipv4h(&ap_out->addr, router->addr); - ap_out->port = router->or_port; -} - -/** Return 1 if any of <b>router</b>'s addresses are <b>addr</b>. - * Otherwise return 0. */ -int -router_has_addr(const routerinfo_t *router, const tor_addr_t *addr) -{ - return - tor_addr_eq_ipv4h(addr, router->addr) || - tor_addr_eq(&router->ipv6_addr, addr); -} - -int -router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport) -{ - return - (tor_addr_eq_ipv4h(&orport->addr, router->addr) && - orport->port == router->or_port) || - (tor_addr_eq(&orport->addr, &router->ipv6_addr) && - orport->port == router->ipv6_orport); -} - /** Load the contents of <b>filename</b>, find the last line starting with * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in * the past or more than 1 hour in the future with respect to <b>now</b>, @@ -3566,219 +3050,6 @@ extrainfo_dump_to_string(char **s_out, extrainfo_t *extrainfo, return result; } -/** Return true iff <b>s</b> is a valid server nickname. (That is, a string - * containing between 1 and MAX_NICKNAME_LEN characters from - * LEGAL_NICKNAME_CHARACTERS.) */ -int -is_legal_nickname(const char *s) -{ - size_t len; - tor_assert(s); - len = strlen(s); - return len > 0 && len <= MAX_NICKNAME_LEN && - strspn(s,LEGAL_NICKNAME_CHARACTERS) == len; -} - -/** Return true iff <b>s</b> is a valid server nickname or - * hex-encoded identity-key digest. */ -int -is_legal_nickname_or_hexdigest(const char *s) -{ - if (*s!='$') - return is_legal_nickname(s); - else - return is_legal_hexdigest(s); -} - -/** Return true iff <b>s</b> is a valid hex-encoded identity-key - * digest. (That is, an optional $, followed by 40 hex characters, - * followed by either nothing, or = or ~ followed by a nickname, or - * a character other than =, ~, or a hex character.) - */ -int -is_legal_hexdigest(const char *s) -{ - size_t len; - tor_assert(s); - if (s[0] == '$') s++; - len = strlen(s); - if (len > HEX_DIGEST_LEN) { - if (s[HEX_DIGEST_LEN] == '=' || - s[HEX_DIGEST_LEN] == '~') { - if (!is_legal_nickname(s+HEX_DIGEST_LEN+1)) - return 0; - } else { - return 0; - } - } - return (len >= HEX_DIGEST_LEN && - strspn(s,HEX_CHARACTERS)==HEX_DIGEST_LEN); -} - -/** - * Longest allowed output of format_node_description, plus 1 character for - * NUL. This allows space for: - * "$FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF~xxxxxxxxxxxxxxxxxxx at" - * " [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]" - * plus a terminating NUL. - */ -#define NODE_DESC_BUF_LEN (MAX_VERBOSE_NICKNAME_LEN+4+TOR_ADDR_BUF_LEN) - -/** Use <b>buf</b> (which must be at least NODE_DESC_BUF_LEN bytes long) to - * hold a human-readable description of a node with identity digest - * <b>id_digest</b>, named-status <b>is_named</b>, nickname <b>nickname</b>, - * and address <b>addr</b> or <b>addr32h</b>. - * - * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to - * NULL. The <b>addr32h</b> field is optional and may be set to 0. - * - * Return a pointer to the front of <b>buf</b>. - */ -const char * -format_node_description(char *buf, - const char *id_digest, - int is_named, - const char *nickname, - const tor_addr_t *addr, - uint32_t addr32h) -{ - char *cp; - - if (!buf) - return "<NULL BUFFER>"; - - buf[0] = '$'; - base16_encode(buf+1, HEX_DIGEST_LEN+1, id_digest, DIGEST_LEN); - cp = buf+1+HEX_DIGEST_LEN; - if (nickname) { - buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~'; - strlcpy(buf+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1); - cp += strlen(cp); - } - if (addr32h || addr) { - memcpy(cp, " at ", 4); - cp += 4; - if (addr) { - tor_addr_to_str(cp, addr, TOR_ADDR_BUF_LEN, 0); - } else { - struct in_addr in; - in.s_addr = htonl(addr32h); - tor_inet_ntoa(&in, cp, INET_NTOA_BUF_LEN); - } - } - return buf; -} - -/** Return a human-readable description of the routerinfo_t <b>ri</b>. - * - * This function is not thread-safe. Each call to this function invalidates - * previous values returned by this function. - */ -const char * -router_describe(const routerinfo_t *ri) -{ - static char buf[NODE_DESC_BUF_LEN]; - - if (!ri) - return "<null>"; - return format_node_description(buf, - ri->cache_info.identity_digest, - 0, - ri->nickname, - NULL, - ri->addr); -} - -/** Return a human-readable description of the node_t <b>node</b>. - * - * This function is not thread-safe. Each call to this function invalidates - * previous values returned by this function. - */ -const char * -node_describe(const node_t *node) -{ - static char buf[NODE_DESC_BUF_LEN]; - const char *nickname = NULL; - uint32_t addr32h = 0; - int is_named = 0; - - if (!node) - return "<null>"; - - if (node->rs) { - nickname = node->rs->nickname; - is_named = node->rs->is_named; - addr32h = node->rs->addr; - } else if (node->ri) { - nickname = node->ri->nickname; - addr32h = node->ri->addr; - } - - return format_node_description(buf, - node->identity, - is_named, - nickname, - NULL, - addr32h); -} - -/** Return a human-readable description of the routerstatus_t <b>rs</b>. - * - * This function is not thread-safe. Each call to this function invalidates - * previous values returned by this function. - */ -const char * -routerstatus_describe(const routerstatus_t *rs) -{ - static char buf[NODE_DESC_BUF_LEN]; - - if (!rs) - return "<null>"; - return format_node_description(buf, - rs->identity_digest, - rs->is_named, - rs->nickname, - NULL, - rs->addr); -} - -/** Return a human-readable description of the extend_info_t <b>ei</b>. - * - * This function is not thread-safe. Each call to this function invalidates - * previous values returned by this function. - */ -const char * -extend_info_describe(const extend_info_t *ei) -{ - static char buf[NODE_DESC_BUF_LEN]; - - if (!ei) - return "<null>"; - return format_node_description(buf, - ei->identity_digest, - 0, - ei->nickname, - &ei->addr, - 0); -} - -/** Set <b>buf</b> (which must have MAX_VERBOSE_NICKNAME_LEN+1 bytes) to the - * verbose representation of the identity of <b>router</b>. The format is: - * A dollar sign. - * The upper-case hexadecimal encoding of the SHA1 hash of router's identity. - * A "=" if the router is named (no longer implemented); a "~" if it is not. - * The router's nickname. - **/ -void -router_get_verbose_nickname(char *buf, const routerinfo_t *router) -{ - buf[0] = '$'; - base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest, - DIGEST_LEN); - buf[1+HEX_DIGEST_LEN] = '~'; - strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1); -} - /** Forget that we have issued any router-related warnings, so that we'll * warn again if we see the same errors. */ void @@ -3790,37 +3061,6 @@ router_reset_warnings(void) } } -/** Given a router purpose, convert it to a string. Don't call this on - * ROUTER_PURPOSE_UNKNOWN: The whole point of that value is that we don't - * know its string representation. */ -const char * -router_purpose_to_string(uint8_t p) -{ - switch (p) - { - case ROUTER_PURPOSE_GENERAL: return "general"; - case ROUTER_PURPOSE_BRIDGE: return "bridge"; - case ROUTER_PURPOSE_CONTROLLER: return "controller"; - default: - tor_assert(0); - } - return NULL; -} - -/** Given a string, convert it to a router purpose. */ -uint8_t -router_purpose_from_string(const char *s) -{ - if (!strcmp(s, "general")) - return ROUTER_PURPOSE_GENERAL; - else if (!strcmp(s, "bridge")) - return ROUTER_PURPOSE_BRIDGE; - else if (!strcmp(s, "controller")) - return ROUTER_PURPOSE_CONTROLLER; - else - return ROUTER_PURPOSE_UNKNOWN; -} - /** Release all static resources held in router.c */ void router_free_all(void) @@ -3846,22 +3086,6 @@ router_free_all(void) smartlist_free(warned_nonexistent_family); } } - -/** Return a smartlist of tor_addr_port_t's with all the OR ports of - <b>ri</b>. Note that freeing of the items in the list as well as - the smartlist itself is the callers responsibility. */ -smartlist_t * -router_get_all_orports(const routerinfo_t *ri) -{ - tor_assert(ri); - node_t fake_node; - memset(&fake_node, 0, sizeof(fake_node)); - /* we don't modify ri, fake_node is passed as a const node_t * - */ - fake_node.ri = (routerinfo_t *)ri; - return node_get_all_orports(&fake_node); -} - /* From the given RSA key object, convert it to ASN-1 encoded format and set * the newly allocated object in onion_pkey_out. The length of the key is set * in onion_pkey_len_out. */ diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index cf0d27a456..4575172afb 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -39,8 +39,6 @@ crypto_pk_t *get_my_v3_legacy_signing_key(void); void dup_onion_keys(crypto_pk_t **key, crypto_pk_t **last); void expire_old_onion_keys(void); void rotate_onion_key(void); -crypto_pk_t *init_key_from_file(const char *fname, int generate, - int severity, int log_greeting); void v3_authority_check_key_expiry(void); int get_onion_key_lifetime(void); int get_onion_key_grace_period(void); @@ -58,23 +56,6 @@ int router_initialize_tls_context(void); int init_keys(void); int init_keys_client(void); -int check_whether_orport_reachable(const or_options_t *options); -int check_whether_dirport_reachable(const or_options_t *options); -int dir_server_mode(const or_options_t *options); -void router_do_reachability_checks(int test_or, int test_dir); -void router_orport_found_reachable(void); -void router_dirport_found_reachable(void); -void router_perform_bandwidth_test(int num_circs, time_t now); - -int net_is_disabled(void); -int net_is_completely_disabled(void); - -int authdir_mode(const or_options_t *options); -int authdir_mode_handles_descs(const or_options_t *options, int purpose); -int authdir_mode_publishes_statuses(const or_options_t *options); -int authdir_mode_tests_reachability(const or_options_t *options); -int authdir_mode_bridge(const or_options_t *options); - uint16_t router_get_active_listener_port_by_type_af(int listener_type, sa_family_t family); uint16_t router_get_advertised_or_port(const or_options_t *options); @@ -83,10 +64,9 @@ uint16_t router_get_advertised_or_port_by_af(const or_options_t *options, uint16_t router_get_advertised_dir_port(const or_options_t *options, uint16_t dirport); -MOCK_DECL(int, server_mode, (const or_options_t *options)); -MOCK_DECL(int, public_server_mode, (const or_options_t *options)); -MOCK_DECL(int, advertised_server_mode, (void)); -int proxy_mode(const or_options_t *options); +int router_should_advertise_dirport(const or_options_t *options, + uint16_t dir_port); + void consider_publishable_server(int force); int should_refuse_unknown_exits(const or_options_t *options); @@ -95,6 +75,7 @@ void mark_my_descriptor_dirty_if_too_old(time_t now); void mark_my_descriptor_dirty(const char *reason); void check_descriptor_bandwidth_changed(time_t now); void check_descriptor_ipaddress_changed(time_t now); +int router_has_bandwidth_to_be_dirserver(const or_options_t *options); void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn); int router_compare_to_my_exit_policy(const tor_addr_t *addr, uint16_t port); @@ -121,41 +102,17 @@ char *router_dump_router_to_string(routerinfo_t *router, char *router_dump_exit_policy_to_string(const routerinfo_t *router, int include_ipv4, int include_ipv6); -void router_get_prim_orport(const routerinfo_t *router, - tor_addr_port_t *addr_port_out); -void router_get_pref_orport(const routerinfo_t *router, - tor_addr_port_t *addr_port_out); -void router_get_pref_ipv6_orport(const routerinfo_t *router, - tor_addr_port_t *addr_port_out); -int router_ipv6_preferred(const routerinfo_t *router); -int router_has_addr(const routerinfo_t *router, const tor_addr_t *addr); -int router_has_orport(const routerinfo_t *router, - const tor_addr_port_t *orport); int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo, crypto_pk_t *ident_key, const struct ed25519_keypair_t *signing_keypair); -int is_legal_nickname(const char *s); -int is_legal_nickname_or_hexdigest(const char *s); -int is_legal_hexdigest(const char *s); - -const char *router_describe(const routerinfo_t *ri); -const char *node_describe(const node_t *node); -const char *routerstatus_describe(const routerstatus_t *ri); -const char *extend_info_describe(const extend_info_t *ei); const char *routerinfo_err_to_string(int err); int routerinfo_err_is_transient(int err); -void router_get_verbose_nickname(char *buf, const routerinfo_t *router); void router_reset_warnings(void); void router_reset_reachability(void); void router_free_all(void); -const char *router_purpose_to_string(uint8_t p); -uint8_t router_purpose_from_string(const char *s); - -smartlist_t *router_get_all_orports(const routerinfo_t *ri); - #ifdef ROUTER_PRIVATE /* Used only by router.c and test.c */ STATIC void get_platform_str(char *platform, size_t len); diff --git a/src/feature/relay/routerkeys.c b/src/feature/relay/routerkeys.c index 47af0f812c..2499d7c8ff 100644 --- a/src/feature/relay/routerkeys.c +++ b/src/feature/relay/routerkeys.c @@ -18,14 +18,13 @@ #include "app/config/config.h" #include "feature/relay/router.h" #include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" +#include "feature/keymgt/loadkey.h" #include "feature/nodelist/torcert.h" -#include "lib/crypt_ops/crypto_pwbox.h" #include "lib/crypt_ops/crypto_util.h" -#include "lib/term/getpass.h" #include "lib/tls/tortls.h" #include "lib/tls/x509.h" -#include "lib/crypt_ops/crypto_format.h" #define ENC_KEY_HEADER "Boxed Ed25519 key" #define ENC_KEY_TAG "master" @@ -34,647 +33,6 @@ #include <unistd.h> #endif -/* DOCDOC */ -static ssize_t -do_getpass(const char *prompt, char *buf, size_t buflen, - int twice, const or_options_t *options) -{ - if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) { - tor_assert(buflen); - buf[0] = 0; - return 0; - } - - char *prompt2 = NULL; - char *buf2 = NULL; - int fd = -1; - ssize_t length = -1; - - if (options->use_keygen_passphrase_fd) { - twice = 0; - fd = options->keygen_passphrase_fd; - length = read_all_from_fd(fd, buf, buflen-1); - if (length >= 0) - buf[length] = 0; - goto done_reading; - } - - if (twice) { - const char msg[] = "One more time:"; - size_t p2len = strlen(prompt) + 1; - if (p2len < sizeof(msg)) - p2len = sizeof(msg); - prompt2 = tor_malloc(p2len); - memset(prompt2, ' ', p2len); - memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg)); - - buf2 = tor_malloc_zero(buflen); - } - - while (1) { - length = tor_getpass(prompt, buf, buflen); - if (length < 0) - goto done_reading; - - if (! twice) - break; - - ssize_t length2 = tor_getpass(prompt2, buf2, buflen); - - if (length != length2 || tor_memneq(buf, buf2, length)) { - fprintf(stderr, "That didn't match.\n"); - } else { - break; - } - } - - done_reading: - if (twice) { - tor_free(prompt2); - memwipe(buf2, 0, buflen); - tor_free(buf2); - } - - if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0) - return -1; - - return length; -} - -/* DOCDOC */ -int -read_encrypted_secret_key(ed25519_secret_key_t *out, - const char *fname) -{ - int r = -1; - uint8_t *secret = NULL; - size_t secret_len = 0; - char pwbuf[256]; - uint8_t encrypted_key[256]; - char *tag = NULL; - int saved_errno = 0; - - ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname, - ENC_KEY_HEADER, - &tag, - encrypted_key, - sizeof(encrypted_key)); - if (encrypted_len < 0) { - saved_errno = errno; - log_info(LD_OR, "%s is missing", fname); - r = 0; - goto done; - } - if (strcmp(tag, ENC_KEY_TAG)) { - saved_errno = EINVAL; - goto done; - } - - while (1) { - ssize_t pwlen = - do_getpass("Enter passphrase for master key:", pwbuf, sizeof(pwbuf), 0, - get_options()); - if (pwlen < 0) { - saved_errno = EINVAL; - goto done; - } - const int r_unbox = crypto_unpwbox(&secret, &secret_len, - encrypted_key, encrypted_len, - pwbuf, pwlen); - if (r_unbox == UNPWBOX_CORRUPTED) { - log_err(LD_OR, "%s is corrupted.", fname); - saved_errno = EINVAL; - goto done; - } else if (r_unbox == UNPWBOX_OKAY) { - break; - } - - /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets - * it right. */ - } - - if (secret_len != ED25519_SECKEY_LEN) { - log_err(LD_OR, "%s is corrupted.", fname); - saved_errno = EINVAL; - goto done; - } - memcpy(out->seckey, secret, ED25519_SECKEY_LEN); - r = 1; - - done: - memwipe(encrypted_key, 0, sizeof(encrypted_key)); - memwipe(pwbuf, 0, sizeof(pwbuf)); - tor_free(tag); - if (secret) { - memwipe(secret, 0, secret_len); - tor_free(secret); - } - if (saved_errno) - errno = saved_errno; - return r; -} - -/* DOCDOC */ -int -write_encrypted_secret_key(const ed25519_secret_key_t *key, - const char *fname) -{ - int r = -1; - char pwbuf0[256]; - uint8_t *encrypted_key = NULL; - size_t encrypted_len = 0; - - if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1, - get_options()) < 0) { - log_warn(LD_OR, "NO/failed passphrase"); - return -1; - } - - if (strlen(pwbuf0) == 0) { - if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON) - return -1; - else - return 0; - } - - if (crypto_pwbox(&encrypted_key, &encrypted_len, - key->seckey, sizeof(key->seckey), - pwbuf0, strlen(pwbuf0), 0) < 0) { - log_warn(LD_OR, "crypto_pwbox failed!?"); - goto done; - } - if (crypto_write_tagged_contents_to_file(fname, - ENC_KEY_HEADER, - ENC_KEY_TAG, - encrypted_key, encrypted_len) < 0) - goto done; - r = 1; - done: - if (encrypted_key) { - memwipe(encrypted_key, 0, encrypted_len); - tor_free(encrypted_key); - } - memwipe(pwbuf0, 0, sizeof(pwbuf0)); - return r; -} - -/* DOCDOC */ -static int -write_secret_key(const ed25519_secret_key_t *key, int encrypted, - const char *fname, - const char *fname_tag, - const char *encrypted_fname) -{ - if (encrypted) { - int r = write_encrypted_secret_key(key, encrypted_fname); - if (r == 1) { - /* Success! */ - - /* Try to unlink the unencrypted key, if any existed before */ - if (strcmp(fname, encrypted_fname)) - unlink(fname); - return r; - } else if (r != 0) { - /* Unrecoverable failure! */ - return r; - } - - fprintf(stderr, "Not encrypting the secret key.\n"); - } - return ed25519_seckey_write_to_file(key, fname, fname_tag); -} - -/** - * Read an ed25519 key and associated certificates from files beginning with - * <b>fname</b>, with certificate type <b>cert_type</b>. On failure, return - * NULL; on success return the keypair. - * - * The <b>options</b> is used to look at the change_key_passphrase value when - * writing to disk a secret key. It is safe to be NULL even in that case. - * - * If INIT_ED_KEY_CREATE is set in <b>flags</b>, then create the key (and - * certificate if requested) if it doesn't exist, and save it to disk. - * - * If INIT_ED_KEY_NEEDCERT is set in <b>flags</b>, load/create a certificate - * too and store it in *<b>cert_out</b>. Fail if the cert can't be - * found/created. To create a certificate, <b>signing_key</b> must be set to - * the key that should sign it; <b>now</b> to the current time, and - * <b>lifetime</b> to the lifetime of the key. - * - * If INIT_ED_KEY_REPLACE is set in <b>flags</b>, then create and save new key - * whether we can read the old one or not. - * - * If INIT_ED_KEY_EXTRA_STRONG is set in <b>flags</b>, set the extra_strong - * flag when creating the secret key. - * - * If INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT is set in <b>flags</b>, and - * we create a new certificate, create it with the signing key embedded. - * - * If INIT_ED_KEY_SPLIT is set in <b>flags</b>, and we create a new key, - * store the public key in a separate file from the secret key. - * - * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a - * public key file but no secret key file, return successfully anyway. - * - * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not try to load a - * secret key unless no public key is found. Do not return a secret key. (but - * create and save one if needed). - * - * If INIT_ED_KEY_TRY_ENCRYPTED is set, we look for an encrypted secret key - * and consider encrypting any new secret key. - * - * If INIT_ED_KEY_NO_REPAIR is set, and there is any issue loading the keys - * from disk _other than their absence_ (full or partial), we do not try to - * replace them. - * - * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures - * refer to the --keygen option. - * - * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the - * secret key file, encrypted or not. - * - * If INIT_ED_KEY_OFFLINE_SECRET is set, we won't try to load the master - * secret key and we log a message at <b>severity</b> that we've done so. - */ -ed25519_keypair_t * -ed_key_init_from_file(const char *fname, uint32_t flags, - int severity, - const ed25519_keypair_t *signing_key, - time_t now, - time_t lifetime, - uint8_t cert_type, - struct tor_cert_st **cert_out, - const or_options_t *options) -{ - char *secret_fname = NULL; - char *encrypted_secret_fname = NULL; - char *public_fname = NULL; - char *cert_fname = NULL; - const char *loaded_secret_fname = NULL; - int created_pk = 0, created_sk = 0, created_cert = 0; - const int try_to_load = ! (flags & INIT_ED_KEY_REPLACE); - const int encrypt_key = !! (flags & INIT_ED_KEY_TRY_ENCRYPTED); - const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR); - const int split = !! (flags & INIT_ED_KEY_SPLIT); - const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET); - const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET); - const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME); - - /* we don't support setting both of these flags at once. */ - tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) != - (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)); - - char tag[8]; - tor_snprintf(tag, sizeof(tag), "type%d", (int)cert_type); - - tor_cert_t *cert = NULL; - char *got_tag = NULL; - ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); - - if (explicit_fname) { - secret_fname = tor_strdup(fname); - encrypted_secret_fname = tor_strdup(fname); - } else { - tor_asprintf(&secret_fname, "%s_secret_key", fname); - tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname); - } - tor_asprintf(&public_fname, "%s_public_key", fname); - tor_asprintf(&cert_fname, "%s_cert", fname); - - /* Try to read the secret key. */ - int have_secret = 0; - int load_secret = try_to_load && - !offline_secret && - (!omit_secret || file_status(public_fname)==FN_NOENT); - if (load_secret) { - int rv = ed25519_seckey_read_from_file(&keypair->seckey, - &got_tag, secret_fname); - if (rv == 0) { - have_secret = 1; - loaded_secret_fname = secret_fname; - tor_assert(got_tag); - } else { - if (errno != ENOENT && norepair) { - tor_log(severity, LD_OR, "Unable to read %s: %s", secret_fname, - strerror(errno)); - goto err; - } - } - } - - /* Should we try for an encrypted key? */ - int have_encrypted_secret_file = 0; - if (!have_secret && try_to_load && encrypt_key) { - int r = read_encrypted_secret_key(&keypair->seckey, - encrypted_secret_fname); - if (r > 0) { - have_secret = 1; - have_encrypted_secret_file = 1; - tor_free(got_tag); /* convince coverity we aren't leaking */ - got_tag = tor_strdup(tag); - loaded_secret_fname = encrypted_secret_fname; - } else if (errno != ENOENT && norepair) { - tor_log(severity, LD_OR, "Unable to read %s: %s", - encrypted_secret_fname, strerror(errno)); - goto err; - } - } else { - if (try_to_load) { - /* Check if it's there anyway, so we don't replace it. */ - if (file_status(encrypted_secret_fname) != FN_NOENT) - have_encrypted_secret_file = 1; - } - } - - if (have_secret) { - if (strcmp(got_tag, tag)) { - tor_log(severity, LD_OR, "%s has wrong tag", loaded_secret_fname); - goto err; - } - /* Derive the public key */ - if (ed25519_public_key_generate(&keypair->pubkey, &keypair->seckey)<0) { - tor_log(severity, LD_OR, "%s can't produce a public key", - loaded_secret_fname); - goto err; - } - } - - /* If we do split keys here, try to read the pubkey. */ - int found_public = 0; - if (try_to_load && (!have_secret || split)) { - ed25519_public_key_t pubkey_tmp; - tor_free(got_tag); - found_public = ed25519_pubkey_read_from_file(&pubkey_tmp, - &got_tag, public_fname) == 0; - if (!found_public && errno != ENOENT && norepair) { - tor_log(severity, LD_OR, "Unable to read %s: %s", public_fname, - strerror(errno)); - goto err; - } - if (found_public && strcmp(got_tag, tag)) { - tor_log(severity, LD_OR, "%s has wrong tag", public_fname); - goto err; - } - if (found_public) { - if (have_secret) { - /* If we have a secret key and we're reloading the public key, - * the key must match! */ - if (! ed25519_pubkey_eq(&keypair->pubkey, &pubkey_tmp)) { - tor_log(severity, LD_OR, "%s does not match %s! If you are trying " - "to restore from backup, make sure you didn't mix up the " - "key files. If you are absolutely sure that %s is the right " - "key for this relay, delete %s or move it out of the way.", - public_fname, loaded_secret_fname, - loaded_secret_fname, public_fname); - goto err; - } - } else { - /* We only have the public key; better use that. */ - tor_assert(split); - memcpy(&keypair->pubkey, &pubkey_tmp, sizeof(pubkey_tmp)); - } - } else { - /* We have no public key file, but we do have a secret key, make the - * public key file! */ - if (have_secret) { - if (ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) - < 0) { - tor_log(severity, LD_OR, "Couldn't repair %s", public_fname); - goto err; - } else { - tor_log(LOG_NOTICE, LD_OR, - "Found secret key but not %s. Regenerating.", - public_fname); - } - } - } - } - - /* If the secret key is absent and it's not allowed to be, fail. */ - if (!have_secret && found_public && - !(flags & INIT_ED_KEY_MISSING_SECRET_OK)) { - if (have_encrypted_secret_file) { - tor_log(severity, LD_OR, "We needed to load a secret key from %s, " - "but it was encrypted. Try 'tor --keygen' instead, so you " - "can enter the passphrase.", - secret_fname); - } else if (offline_secret) { - tor_log(severity, LD_OR, "We wanted to load a secret key from %s, " - "but you're keeping it offline. (OfflineMasterKey is set.)", - secret_fname); - } else { - tor_log(severity, LD_OR, "We needed to load a secret key from %s, " - "but couldn't find it. %s", secret_fname, - (flags & INIT_ED_KEY_SUGGEST_KEYGEN) ? - "If you're keeping your master secret key offline, you will " - "need to run 'tor --keygen' to generate new signing keys." : - "Did you forget to copy it over when you copied the rest of the " - "signing key material?"); - } - goto err; - } - - /* If it's absent, and we're not supposed to make a new keypair, fail. */ - if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE)) { - if (split) { - tor_log(severity, LD_OR, "No key found in %s or %s.", - secret_fname, public_fname); - } else { - tor_log(severity, LD_OR, "No key found in %s.", secret_fname); - } - goto err; - } - - /* If the secret key is absent, but the encrypted key would be present, - * that's an error */ - if (!have_secret && !found_public && have_encrypted_secret_file) { - tor_assert(!encrypt_key); - tor_log(severity, LD_OR, "Found an encrypted secret key, " - "but not public key file %s!", public_fname); - goto err; - } - - /* if it's absent, make a new keypair... */ - if (!have_secret && !found_public) { - tor_free(keypair); - keypair = ed_key_new(signing_key, flags, now, lifetime, - cert_type, &cert); - if (!keypair) { - tor_log(severity, LD_OR, "Couldn't create keypair"); - goto err; - } - created_pk = created_sk = created_cert = 1; - } - - /* Write it to disk if we're supposed to do with a new passphrase, or if - * we just created it. */ - if (created_sk || (have_secret && options != NULL && - options->change_key_passphrase)) { - if (write_secret_key(&keypair->seckey, - encrypt_key, - secret_fname, tag, encrypted_secret_fname) < 0 - || - (split && - ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) < 0) - || - (cert && - crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", - tag, cert->encoded, cert->encoded_len) < 0)) { - tor_log(severity, LD_OR, "Couldn't write keys or cert to file."); - goto err; - } - goto done; - } - - /* If we're not supposed to get a cert, we're done. */ - if (! (flags & INIT_ED_KEY_NEEDCERT)) - goto done; - - /* Read a cert. */ - tor_free(got_tag); - uint8_t certbuf[256]; - ssize_t cert_body_len = crypto_read_tagged_contents_from_file( - cert_fname, "ed25519v1-cert", - &got_tag, certbuf, sizeof(certbuf)); - if (cert_body_len >= 0 && !strcmp(got_tag, tag)) - cert = tor_cert_parse(certbuf, cert_body_len); - - /* If we got it, check it to the extent we can. */ - int bad_cert = 0; - - if (! cert) { - tor_log(severity, LD_OR, "Cert was unparseable"); - bad_cert = 1; - } else if (!tor_memeq(cert->signed_key.pubkey, keypair->pubkey.pubkey, - ED25519_PUBKEY_LEN)) { - tor_log(severity, LD_OR, "Cert was for wrong key"); - bad_cert = 1; - } else if (signing_key && - tor_cert_checksig(cert, &signing_key->pubkey, now) < 0) { - tor_log(severity, LD_OR, "Can't check certificate: %s", - tor_cert_describe_signature_status(cert)); - bad_cert = 1; - } else if (cert->cert_expired) { - tor_log(severity, LD_OR, "Certificate is expired"); - bad_cert = 1; - } else if (signing_key && cert->signing_key_included && - ! ed25519_pubkey_eq(&signing_key->pubkey, &cert->signing_key)) { - tor_log(severity, LD_OR, "Certificate signed by unexpectd key!"); - bad_cert = 1; - } - - if (bad_cert) { - tor_cert_free(cert); - cert = NULL; - } - - /* If we got a cert, we're done. */ - if (cert) - goto done; - - /* If we didn't get a cert, and we're not supposed to make one, fail. */ - if (!signing_key || !(flags & INIT_ED_KEY_CREATE)) { - tor_log(severity, LD_OR, "Without signing key, can't create certificate"); - goto err; - } - - /* We have keys but not a certificate, so make one. */ - uint32_t cert_flags = 0; - if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) - cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; - cert = tor_cert_create(signing_key, cert_type, - &keypair->pubkey, - now, lifetime, - cert_flags); - - if (! cert) { - tor_log(severity, LD_OR, "Couldn't create certificate"); - goto err; - } - - /* Write it to disk. */ - created_cert = 1; - if (crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", - tag, cert->encoded, cert->encoded_len) < 0) { - tor_log(severity, LD_OR, "Couldn't write cert to disk."); - goto err; - } - - done: - if (cert_out) - *cert_out = cert; - else - tor_cert_free(cert); - - goto cleanup; - - err: - if (keypair) - memwipe(keypair, 0, sizeof(*keypair)); - tor_free(keypair); - tor_cert_free(cert); - if (cert_out) - *cert_out = NULL; - if (created_sk) - unlink(secret_fname); - if (created_pk) - unlink(public_fname); - if (created_cert) - unlink(cert_fname); - - cleanup: - tor_free(encrypted_secret_fname); - tor_free(secret_fname); - tor_free(public_fname); - tor_free(cert_fname); - tor_free(got_tag); - - return keypair; -} - -/** - * Create a new signing key and (optionally) certficiate; do not read or write - * from disk. See ed_key_init_from_file() for more information. - */ -ed25519_keypair_t * -ed_key_new(const ed25519_keypair_t *signing_key, - uint32_t flags, - time_t now, - time_t lifetime, - uint8_t cert_type, - struct tor_cert_st **cert_out) -{ - if (cert_out) - *cert_out = NULL; - - const int extra_strong = !! (flags & INIT_ED_KEY_EXTRA_STRONG); - ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); - if (ed25519_keypair_generate(keypair, extra_strong) < 0) - goto err; - - if (! (flags & INIT_ED_KEY_NEEDCERT)) - return keypair; - - tor_assert(signing_key); - tor_assert(cert_out); - uint32_t cert_flags = 0; - if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) - cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; - tor_cert_t *cert = tor_cert_create(signing_key, cert_type, - &keypair->pubkey, - now, lifetime, - cert_flags); - if (! cert) - goto err; - - *cert_out = cert; - return keypair; - - err: - tor_free(keypair); - return NULL; -} - static ed25519_keypair_t *master_identity_key = NULL; static ed25519_keypair_t *master_signing_key = NULL; static ed25519_keypair_t *current_auth_key = NULL; @@ -1363,43 +721,6 @@ make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, return tor_memdup(signature, r); } -/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it - * is, -1 if it isn't. */ -MOCK_IMPL(int, -check_tap_onion_key_crosscert,(const uint8_t *crosscert, - int crosscert_len, - const crypto_pk_t *onion_pkey, - const ed25519_public_key_t *master_id_pkey, - const uint8_t *rsa_id_digest)) -{ - uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey)); - int cc_len = - crypto_pk_public_checksig(onion_pkey, - (char*)cc, - crypto_pk_keysize(onion_pkey), - (const char*)crosscert, - crosscert_len); - if (cc_len < 0) { - goto err; - } - if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) { - log_warn(LD_DIR, "Short signature on cross-certification with TAP key"); - goto err; - } - if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) || - tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey, - ED25519_PUBKEY_LEN)) { - log_warn(LD_DIR, "Incorrect cross-certification with TAP key"); - goto err; - } - - tor_free(cc); - return 0; - err: - tor_free(cc); - return -1; -} - void routerkeys_free_all(void) { diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h index f52ed0f306..c5a58e553d 100644 --- a/src/feature/relay/routerkeys.h +++ b/src/feature/relay/routerkeys.h @@ -6,35 +6,6 @@ #include "lib/crypt_ops/crypto_ed25519.h" -#define INIT_ED_KEY_CREATE (1u<<0) -#define INIT_ED_KEY_REPLACE (1u<<1) -#define INIT_ED_KEY_SPLIT (1u<<2) -#define INIT_ED_KEY_MISSING_SECRET_OK (1u<<3) -#define INIT_ED_KEY_NEEDCERT (1u<<4) -#define INIT_ED_KEY_EXTRA_STRONG (1u<<5) -#define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6) -#define INIT_ED_KEY_OMIT_SECRET (1u<<7) -#define INIT_ED_KEY_TRY_ENCRYPTED (1u<<8) -#define INIT_ED_KEY_NO_REPAIR (1u<<9) -#define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10) -#define INIT_ED_KEY_OFFLINE_SECRET (1u<<11) -#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<12) - -struct tor_cert_st; -ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags, - int severity, - const ed25519_keypair_t *signing_key, - time_t now, - time_t lifetime, - uint8_t cert_type, - struct tor_cert_st **cert_out, - const or_options_t *options); -ed25519_keypair_t *ed_key_new(const ed25519_keypair_t *signing_key, - uint32_t flags, - time_t now, - time_t lifetime, - uint8_t cert_type, - struct tor_cert_st **cert_out); const ed25519_public_key_t *get_master_identity_key(void); const ed25519_keypair_t *get_master_signing_keypair(void); const struct tor_cert_st *get_master_signing_key_cert(void); @@ -58,23 +29,12 @@ uint8_t *make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, const crypto_pk_t *rsa_id_key, int *len_out); -MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert, - int crosscert_len, - const crypto_pk_t *onion_pkey, - const ed25519_public_key_t *master_id_pkey, - const uint8_t *rsa_id_digest)); - int log_cert_expiration(void); int load_ed_keys(const or_options_t *options, time_t now); int should_make_new_ed_keys(const or_options_t *options, const time_t now); int generate_ed_link_cert(const or_options_t *options, time_t now, int force); -int read_encrypted_secret_key(ed25519_secret_key_t *out, - const char *fname); -int write_encrypted_secret_key(const ed25519_secret_key_t *out, - const char *fname); - void routerkeys_free_all(void); #ifdef TOR_UNIT_TESTS @@ -83,4 +43,3 @@ void init_mock_ed_keys(const crypto_pk_t *rsa_identity_key); #endif #endif /* !defined(TOR_ROUTERKEYS_H) */ - diff --git a/src/feature/relay/routermode.c b/src/feature/relay/routermode.c new file mode 100644 index 0000000000..3f87cda505 --- /dev/null +++ b/src/feature/relay/routermode.c @@ -0,0 +1,80 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "core/or/or.h" + +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/or/port_cfg_st.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" + +/** Return 1 if we are configured to accept either relay or directory requests + * from clients and we aren't at risk of exceeding our bandwidth limits, thus + * we should be a directory server. If not, return 0. + */ +int +dir_server_mode(const or_options_t *options) +{ + if (!options->DirCache) + return 0; + return options->DirPort_set || + (server_mode(options) && router_has_bandwidth_to_be_dirserver(options)); +} + +/** Return true iff we are trying to proxy client connections. */ +int +proxy_mode(const or_options_t *options) +{ + (void)options; + SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { + if (p->type == CONN_TYPE_AP_LISTENER || + p->type == CONN_TYPE_AP_TRANS_LISTENER || + p->type == CONN_TYPE_AP_DNS_LISTENER || + p->type == CONN_TYPE_AP_NATD_LISTENER) + return 1; + } SMARTLIST_FOREACH_END(p); + return 0; +} + +/** Return true iff we are trying to be a server. + */ +MOCK_IMPL(int, +server_mode,(const or_options_t *options)) +{ + if (options->ClientOnly) return 0; + return (options->ORPort_set); +} + +/** Return true iff we are trying to be a non-bridge server. + */ +MOCK_IMPL(int, +public_server_mode,(const or_options_t *options)) +{ + if (!server_mode(options)) return 0; + return (!options->BridgeRelay); +} + +/** Remember if we've advertised ourselves to the dirservers. */ +static int server_is_advertised=0; + +/** Return true iff we have published our descriptor lately. + */ +MOCK_IMPL(int, +advertised_server_mode,(void)) +{ + return server_is_advertised; +} + +/** + * Called with a boolean: set whether we have recently published our + * descriptor. + */ +void +set_server_advertised(int s) +{ + server_is_advertised = s; +} diff --git a/src/feature/relay/routermode.h b/src/feature/relay/routermode.h new file mode 100644 index 0000000000..1442d706dd --- /dev/null +++ b/src/feature/relay/routermode.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file routermode.h + * \brief Header file for routermode.c. + **/ + +#ifndef TOR_ROUTERMODE_H +#define TOR_ROUTERMODE_H + +int dir_server_mode(const or_options_t *options); + +MOCK_DECL(int, server_mode, (const or_options_t *options)); +MOCK_DECL(int, public_server_mode, (const or_options_t *options)); +MOCK_DECL(int, advertised_server_mode, (void)); +int proxy_mode(const or_options_t *options); + +void set_server_advertised(int s); + +#endif /* !defined(TOR_ROUTERMODE_H) */ diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c new file mode 100644 index 0000000000..26205aad0f --- /dev/null +++ b/src/feature/relay/selftest.c @@ -0,0 +1,301 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file selftest.c + * \brief Relay self-testing + * + * Relays need to make sure that their own ports are reasonable, and estimate + * their own bandwidth, before publishing. + */ + +#define SELFTEST_PRIVATE + +#include "core/or/or.h" + +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" +#include "core/or/circuitbuild.h" +#include "core/or/circuitlist.h" +#include "core/or/circuituse.h" +#include "core/or/crypt_path_st.h" +#include "core/or/origin_circuit_st.h" +#include "core/or/relay.h" +#include "feature/control/control.h" +#include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" +#include "feature/nodelist/authority_cert_st.h" +#include "feature/nodelist/routerinfo.h" +#include "feature/nodelist/routerinfo_st.h" +#include "feature/nodelist/routerlist.h" // but... +#include "feature/nodelist/routerset.h" +#include "feature/nodelist/torcert.h" +#include "feature/relay/router.h" +#include "feature/relay/selftest.h" + +/** Whether we can reach our ORPort from the outside. */ +static int can_reach_or_port = 0; +/** Whether we can reach our DirPort from the outside. */ +static int can_reach_dir_port = 0; + +/** Forget what we have learned about our reachability status. */ +void +router_reset_reachability(void) +{ + can_reach_or_port = can_reach_dir_port = 0; +} + +/** Return 1 if we won't do reachability checks, because: + * - AssumeReachable is set, or + * - the network is disabled. + * Otherwise, return 0. + */ +static int +router_reachability_checks_disabled(const or_options_t *options) +{ + return options->AssumeReachable || + net_is_disabled(); +} + +/** Return 0 if we need to do an ORPort reachability check, because: + * - no reachability check has been done yet, or + * - we've initiated reachability checks, but none have succeeded. + * Return 1 if we don't need to do an ORPort reachability check, because: + * - we've seen a successful reachability check, or + * - AssumeReachable is set, or + * - the network is disabled. + */ +int +check_whether_orport_reachable(const or_options_t *options) +{ + int reach_checks_disabled = router_reachability_checks_disabled(options); + return reach_checks_disabled || + can_reach_or_port; +} + +/** Return 0 if we need to do a DirPort reachability check, because: + * - no reachability check has been done yet, or + * - we've initiated reachability checks, but none have succeeded. + * Return 1 if we don't need to do a DirPort reachability check, because: + * - we've seen a successful reachability check, or + * - there is no DirPort set, or + * - AssumeReachable is set, or + * - the network is disabled. + */ +int +check_whether_dirport_reachable(const or_options_t *options) +{ + int reach_checks_disabled = router_reachability_checks_disabled(options) || + !options->DirPort_set; + return reach_checks_disabled || + can_reach_dir_port; +} + +/** See if we currently believe our ORPort or DirPort to be + * unreachable. If so, return 1 else return 0. + */ +static int +router_should_check_reachability(int test_or, int test_dir) +{ + const routerinfo_t *me = router_get_my_routerinfo(); + const or_options_t *options = get_options(); + + if (!me) + return 0; + + if (routerset_contains_router(options->ExcludeNodes, me, -1) && + options->StrictNodes) { + /* If we've excluded ourself, and StrictNodes is set, we can't test + * ourself. */ + if (test_or || test_dir) { +#define SELF_EXCLUDED_WARN_INTERVAL 3600 + static ratelim_t warning_limit=RATELIM_INIT(SELF_EXCLUDED_WARN_INTERVAL); + log_fn_ratelim(&warning_limit, LOG_WARN, LD_CIRC, + "Can't peform self-tests for this relay: we have " + "listed ourself in ExcludeNodes, and StrictNodes is set. " + "We cannot learn whether we are usable, and will not " + "be able to advertise ourself."); + } + return 0; + } + return 1; +} + +/** Allocate and return a new extend_info_t that can be used to build + * a circuit to or through the router <b>r</b>. Uses the primary + * address of the router, so should only be called on a server. */ +static extend_info_t * +extend_info_from_router(const routerinfo_t *r) +{ + crypto_pk_t *rsa_pubkey; + extend_info_t *info; + tor_addr_port_t ap; + tor_assert(r); + + /* Make sure we don't need to check address reachability */ + tor_assert_nonfatal(router_skip_or_reachability(get_options(), 0)); + + const ed25519_public_key_t *ed_id_key; + if (r->cache_info.signing_key_cert) + ed_id_key = &r->cache_info.signing_key_cert->signing_key; + else + ed_id_key = NULL; + + router_get_prim_orport(r, &ap); + rsa_pubkey = router_get_rsa_onion_pkey(r->onion_pkey, r->onion_pkey_len); + info = extend_info_new(r->nickname, r->cache_info.identity_digest, + ed_id_key, + rsa_pubkey, r->onion_curve25519_pkey, + &ap.addr, ap.port); + crypto_pk_free(rsa_pubkey); + return info; +} + +/** Some time has passed, or we just got new directory information. + * See if we currently believe our ORPort or DirPort to be + * unreachable. If so, launch a new test for it. + * + * For ORPort, we simply try making a circuit that ends at ourselves. + * Success is noticed in onionskin_answer(). + * + * For DirPort, we make a connection via Tor to our DirPort and ask + * for our own server descriptor. + * Success is noticed in connection_dir_client_reached_eof(). + */ +void +router_do_reachability_checks(int test_or, int test_dir) +{ + const routerinfo_t *me = router_get_my_routerinfo(); + const or_options_t *options = get_options(); + int orport_reachable = check_whether_orport_reachable(options); + tor_addr_t addr; + + if (router_should_check_reachability(test_or, test_dir)) { + if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) { + extend_info_t *ei = extend_info_from_router(me); + /* XXX IPv6 self testing */ + log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.", + !orport_reachable ? "reachability" : "bandwidth", + fmt_addr32(me->addr), me->or_port); + circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei, + CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL); + extend_info_free(ei); + } + + /* XXX IPv6 self testing */ + tor_addr_from_ipv4h(&addr, me->addr); + if (test_dir && !check_whether_dirport_reachable(options) && + !connection_get_by_type_addr_port_purpose( + CONN_TYPE_DIR, &addr, me->dir_port, + DIR_PURPOSE_FETCH_SERVERDESC)) { + tor_addr_port_t my_orport, my_dirport; + memcpy(&my_orport.addr, &addr, sizeof(addr)); + memcpy(&my_dirport.addr, &addr, sizeof(addr)); + my_orport.port = me->or_port; + my_dirport.port = me->dir_port; + /* ask myself, via tor, for my server descriptor. */ + directory_request_t *req = + directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC); + directory_request_set_or_addr_port(req, &my_orport); + directory_request_set_dir_addr_port(req, &my_dirport); + directory_request_set_directory_id_digest(req, + me->cache_info.identity_digest); + // ask via an anon circuit, connecting to our dirport. + directory_request_set_indirection(req, DIRIND_ANON_DIRPORT); + directory_request_set_resource(req, "authority.z"); + directory_initiate_request(req); + directory_request_free(req); + } + } +} + +/** Annotate that we found our ORPort reachable. */ +void +router_orport_found_reachable(void) +{ + const routerinfo_t *me = router_get_my_routerinfo(); + const or_options_t *options = get_options(); + if (!can_reach_or_port && me) { + char *address = tor_dup_ip(me->addr); + log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from " + "the outside. Excellent.%s", + options->PublishServerDescriptor_ != NO_DIRINFO + && check_whether_dirport_reachable(options) ? + " Publishing server descriptor." : ""); + can_reach_or_port = 1; + mark_my_descriptor_dirty("ORPort found reachable"); + /* This is a significant enough change to upload immediately, + * at least in a test network */ + if (options->TestingTorNetwork == 1) { + reschedule_descriptor_update_check(); + } + control_event_server_status(LOG_NOTICE, + "REACHABILITY_SUCCEEDED ORADDRESS=%s:%d", + address, me->or_port); + tor_free(address); + } +} + +/** Annotate that we found our DirPort reachable. */ +void +router_dirport_found_reachable(void) +{ + const routerinfo_t *me = router_get_my_routerinfo(); + const or_options_t *options = get_options(); + if (!can_reach_dir_port && me) { + char *address = tor_dup_ip(me->addr); + log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable " + "from the outside. Excellent.%s", + options->PublishServerDescriptor_ != NO_DIRINFO + && check_whether_orport_reachable(options) ? + " Publishing server descriptor." : ""); + can_reach_dir_port = 1; + if (router_should_advertise_dirport(options, me->dir_port)) { + mark_my_descriptor_dirty("DirPort found reachable"); + /* This is a significant enough change to upload immediately, + * at least in a test network */ + if (options->TestingTorNetwork == 1) { + reschedule_descriptor_update_check(); + } + } + control_event_server_status(LOG_NOTICE, + "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d", + address, me->dir_port); + tor_free(address); + } +} + +/** We have enough testing circuits open. Send a bunch of "drop" + * cells down each of them, to exercise our bandwidth. */ +void +router_perform_bandwidth_test(int num_circs, time_t now) +{ + int num_cells = (int)(get_options()->BandwidthRate * 10 / + CELL_MAX_NETWORK_SIZE); + int max_cells = num_cells < CIRCWINDOW_START ? + num_cells : CIRCWINDOW_START; + int cells_per_circuit = max_cells / num_circs; + origin_circuit_t *circ = NULL; + + log_notice(LD_OR,"Performing bandwidth self-test...done."); + while ((circ = circuit_get_next_by_pk_and_purpose(circ, NULL, + CIRCUIT_PURPOSE_TESTING))) { + /* dump cells_per_circuit drop cells onto this circ */ + int i = cells_per_circuit; + if (circ->base_.state != CIRCUIT_STATE_OPEN) + continue; + circ->base_.timestamp_dirty = now; + while (i-- > 0) { + if (relay_send_command_from_edge(0, TO_CIRCUIT(circ), + RELAY_COMMAND_DROP, + NULL, 0, circ->cpath->prev)<0) { + return; /* stop if error */ + } + } + } +} diff --git a/src/feature/relay/selftest.h b/src/feature/relay/selftest.h new file mode 100644 index 0000000000..26034c9e8e --- /dev/null +++ b/src/feature/relay/selftest.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file selftest.h + * \brief Header file for selftest.c. + **/ + +#ifndef TOR_SELFTEST_H +#define TOR_SELFTEST_H + +struct or_options_t; +int check_whether_orport_reachable(const struct or_options_t *options); +int check_whether_dirport_reachable(const struct or_options_t *options); + +void router_do_reachability_checks(int test_or, int test_dir); +void router_orport_found_reachable(void); +void router_dirport_found_reachable(void); +void router_perform_bandwidth_test(int num_circs, time_t now); + +#endif diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c index d1310699fc..10b67ceda9 100644 --- a/src/feature/rend/rendclient.c +++ b/src/feature/rend/rendclient.c @@ -8,32 +8,32 @@ **/ #include "core/or/or.h" -#include "feature/client/circpathbias.h" +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/mainloop/mainloop.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" -#include "core/mainloop/connection.h" #include "core/or/connection_edge.h" +#include "core/or/relay.h" +#include "feature/client/circpathbias.h" #include "feature/control/control.h" -#include "lib/crypt_ops/crypto_dh.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" #include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" #include "feature/hs/hs_circuit.h" #include "feature/hs/hs_client.h" #include "feature/hs/hs_common.h" -#include "core/mainloop/mainloop.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" -#include "core/or/relay.h" +#include "feature/nodelist/routerlist.h" +#include "feature/nodelist/routerset.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" -#include "feature/nodelist/routerlist.h" -#include "feature/nodelist/routerset.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "lib/encoding/confline.h" #include "core/or/cpath_build_state_st.h" diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c index 7966ab8463..8257919ac4 100644 --- a/src/feature/rend/rendservice.c +++ b/src/feature/rend/rendservice.c @@ -10,33 +10,36 @@ #define RENDSERVICE_PRIVATE #include "core/or/or.h" -#include "feature/client/circpathbias.h" + +#include "app/config/config.h" +#include "core/mainloop/mainloop.h" #include "core/or/circuitbuild.h" #include "core/or/circuitlist.h" #include "core/or/circuituse.h" -#include "app/config/config.h" +#include "core/or/policies.h" +#include "core/or/relay.h" +#include "feature/client/circpathbias.h" #include "feature/control/control.h" -#include "lib/crypt_ops/crypto_dh.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "lib/crypt_ops/crypto_util.h" -#include "feature/dircommon/directory.h" #include "feature/dirclient/dirclient.h" +#include "feature/dircommon/directory.h" #include "feature/hs/hs_common.h" #include "feature/hs/hs_config.h" -#include "core/mainloop/mainloop.h" +#include "feature/hs_common/replaycache.h" +#include "feature/keymgt/loadkey.h" +#include "feature/nodelist/describe.h" #include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" +#include "feature/nodelist/node_select.h" #include "feature/nodelist/nodelist.h" -#include "core/or/policies.h" +#include "feature/nodelist/routerparse.h" +#include "feature/nodelist/routerset.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendcommon.h" #include "feature/rend/rendservice.h" -#include "feature/relay/router.h" -#include "core/or/relay.h" #include "feature/stats/rephist.h" -#include "feature/hs_common/replaycache.h" -#include "feature/nodelist/node_select.h" -#include "feature/nodelist/routerparse.h" -#include "feature/nodelist/routerset.h" +#include "lib/crypt_ops/crypto_dh.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/crypt_ops/crypto_util.h" #include "lib/encoding/confline.h" #include "lib/net/resolve.h" @@ -1363,7 +1366,7 @@ rend_service_key_on_disk(const char *directory_path) /* Load key */ fname = hs_path_from_filename(directory_path, private_key_fname); - pk = init_key_from_file(fname, 0, LOG_DEBUG, 0); + pk = init_key_from_file(fname, 0, LOG_DEBUG, NULL); if (pk) { ret = 1; } @@ -1535,7 +1538,7 @@ rend_service_load_keys(rend_service_t *s) /* Load key */ fname = rend_service_path(s, private_key_fname); - s->private_key = init_key_from_file(fname, 1, LOG_ERR, 0); + s->private_key = init_key_from_file(fname, 1, LOG_ERR, NULL); if (!s->private_key) goto err; diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c index a2dbb0ff16..fa4bd0ba4e 100644 --- a/src/feature/stats/rephist.c +++ b/src/feature/stats/rephist.c @@ -83,12 +83,14 @@ #include "feature/nodelist/networkstatus.h" #include "feature/nodelist/nodelist.h" #include "feature/stats/rephist.h" -#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" #include "feature/nodelist/routerlist.h" #include "ht.h" #include "core/or/channelpadding.h" #include "core/or/connection_or.h" #include "app/config/statefile.h" +#include "feature/dirauth/authmode.h" #include "feature/nodelist/networkstatus_st.h" #include "core/or/or_circuit_st.h" diff --git a/src/test/fuzz/fuzz_descriptor.c b/src/test/fuzz/fuzz_descriptor.c index 5a56f4081a..2babdce4bf 100644 --- a/src/test/fuzz/fuzz_descriptor.c +++ b/src/test/fuzz/fuzz_descriptor.c @@ -4,7 +4,8 @@ #include "core/or/or.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerlist.h" -#include "feature/relay/routerkeys.h" +#include "feature/nodelist/torcert.h" +#include "feature/keymgt/loadkey.h" #include "test/fuzz/fuzzing.h" static int @@ -76,4 +77,3 @@ fuzz_main(const uint8_t *data, size_t sz) } return 0; } - diff --git a/src/test/test_config.c b/src/test/test_config.c index 4dc1b8c0ec..77c0d248c2 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -38,6 +38,7 @@ #include "feature/rend/rendclient.h" #include "feature/rend/rendservice.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "feature/nodelist/dirlist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerset.h" diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 686b039492..aa1c706b1f 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -24,47 +24,49 @@ #define VOTEFLAGS_PRIVATE #include "core/or/or.h" -#include "feature/client/bridges.h" -#include "core/mainloop/connection.h" -#include "app/config/confparse.h" #include "app/config/config.h" +#include "app/config/confparse.h" +#include "core/mainloop/connection.h" +#include "core/or/relay.h" +#include "feature/client/bridges.h" +#include "feature/client/entrynodes.h" #include "feature/control/control.h" -#include "lib/encoding/confline.h" -#include "lib/crypt_ops/crypto_ed25519.h" -#include "lib/crypt_ops/crypto_format.h" -#include "lib/crypt_ops/crypto_rand.h" -#include "feature/dircommon/directory.h" -#include "feature/dirclient/dirclient.h" -#include "feature/dirclient/dlstatus.h" #include "feature/dirauth/bwauth.h" -#include "feature/dircache/dircache.h" -#include "feature/dircache/dirserv.h" -#include "feature/dirauth/process_descs.h" #include "feature/dirauth/dirvote.h" +#include "feature/dirauth/process_descs.h" #include "feature/dirauth/recommend_pkg.h" +#include "feature/dirauth/shared_random_state.h" #include "feature/dirauth/voteflags.h" -#include "feature/client/entrynodes.h" +#include "feature/dircache/dircache.h" +#include "feature/dircache/dirserv.h" +#include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dlstatus.h" +#include "feature/dircommon/directory.h" #include "feature/dircommon/fp_pair.h" +#include "feature/dircommon/voting_schedule.h" #include "feature/hibernate/hibernate.h" -#include "lib/memarea/memarea.h" -#include "lib/osinfo/uname.h" -#include "feature/nodelist/networkstatus.h" -#include "feature/relay/router.h" -#include "feature/relay/routerkeys.h" #include "feature/nodelist/authcert.h" #include "feature/nodelist/dirlist.h" +#include "feature/nodelist/networkstatus.h" +#include "feature/nodelist/nickname.h" #include "feature/nodelist/node_select.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerset.h" -#include "feature/dirauth/shared_random_state.h" -#include "test/test.h" -#include "test/test_dir_common.h" #include "feature/nodelist/torcert.h" -#include "core/or/relay.h" -#include "test/log_test_helpers.h" -#include "feature/dircommon/voting_schedule.h" +#include "feature/relay/router.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" #include "lib/compress/compress.h" +#include "lib/crypt_ops/crypto_ed25519.h" +#include "lib/crypt_ops/crypto_format.h" +#include "lib/crypt_ops/crypto_rand.h" +#include "lib/encoding/confline.h" +#include "lib/memarea/memarea.h" +#include "lib/osinfo/uname.h" +#include "test/log_test_helpers.h" +#include "test/test.h" +#include "test/test_dir_common.h" #include "core/or/addr_policy_st.h" #include "feature/nodelist/authority_cert_st.h" diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c index b62aea113e..f05401ba0d 100644 --- a/src/test/test_routerkeys.c +++ b/src/test/test_routerkeys.c @@ -11,6 +11,7 @@ #include "feature/relay/routerkeys.h" #include "lib/crypt_ops/crypto_cipher.h" #include "lib/crypt_ops/crypto_format.h" +#include "feature/keymgt/loadkey.h" #include "feature/nodelist/torcert.h" #include "test/test.h" diff --git a/src/test/test_status.c b/src/test/test_status.c index 46dbd9dcd1..3ceba77a84 100644 --- a/src/test/test_status.c +++ b/src/test/test_status.c @@ -21,6 +21,7 @@ #include "feature/stats/rephist.h" #include "core/or/relay.h" #include "feature/relay/router.h" +#include "feature/relay/routermode.h" #include "core/mainloop/mainloop.h" #include "feature/nodelist/nodelist.h" #include "app/config/statefile.h" |