mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-09-21 05:26:20 +02:00
Merge branch 'tor-github/pr/842'
This commit is contained in:
commit
989b6325d6
4
changes/ticket29894
Normal file
4
changes/ticket29894
Normal file
@ -0,0 +1,4 @@
|
||||
o Code simplification and refactoring:
|
||||
- Split up the control.c file into several submodules, in preparation
|
||||
for distributing its current responsibilities throughout the codebase.
|
||||
Closes ticket 29894.
|
@ -59,13 +59,13 @@ problem function-size /src/core/or/relay.c:connection_edge_process_relay_cell_no
|
||||
problem function-size /src/core/or/relay.c:connection_edge_process_relay_cell() 520
|
||||
problem function-size /src/core/or/relay.c:connection_edge_package_raw_inbuf() 130
|
||||
problem function-size /src/core/or/relay.c:circuit_resume_edge_reading_helper() 148
|
||||
problem file-size /src/core/mainloop/mainloop.c 3050
|
||||
problem include-count /src/core/mainloop/mainloop.c 65
|
||||
problem file-size /src/core/mainloop/mainloop.c 3051
|
||||
problem include-count /src/core/mainloop/mainloop.c 66
|
||||
problem function-size /src/core/mainloop/mainloop.c:conn_close_if_marked() 108
|
||||
problem function-size /src/core/mainloop/mainloop.c:run_connection_housekeeping() 123
|
||||
problem function-size /src/core/mainloop/mainloop.c:CALLBACK() 116
|
||||
problem file-size /src/core/mainloop/connection.c 5547
|
||||
problem include-count /src/core/mainloop/connection.c 60
|
||||
problem file-size /src/core/mainloop/connection.c 5548
|
||||
problem include-count /src/core/mainloop/connection.c 61
|
||||
problem function-size /src/core/mainloop/connection.c:connection_free_minimal() 184
|
||||
problem function-size /src/core/mainloop/connection.c:connection_listener_new() 328
|
||||
problem function-size /src/core/mainloop/connection.c:connection_handle_listener_read() 161
|
||||
@ -79,8 +79,8 @@ problem function-size /src/core/mainloop/connection.c:connection_handle_write_im
|
||||
problem function-size /src/core/mainloop/connection.c:assert_connection_ok() 143
|
||||
problem function-size /src/app/config/confparse.c:config_assign_value() 205
|
||||
problem function-size /src/app/config/confparse.c:config_get_assigned_option() 129
|
||||
problem file-size /src/app/config/config.c 8488
|
||||
problem include-count /src/app/config/config.c 84
|
||||
problem file-size /src/app/config/config.c 8490
|
||||
problem include-count /src/app/config/config.c 86
|
||||
problem function-size /src/app/config/config.c:options_act_reversible() 296
|
||||
problem function-size /src/app/config/config.c:options_act() 588
|
||||
problem function-size /src/app/config/config.c:resolve_my_address() 192
|
||||
@ -96,7 +96,7 @@ problem function-size /src/app/config/config.c:parse_port_config() 452
|
||||
problem function-size /src/app/config/config.c:parse_ports() 170
|
||||
problem function-size /src/app/config/config.c:getinfo_helper_config() 116
|
||||
problem function-size /src/app/main/ntmain.c:nt_service_install() 125
|
||||
problem include-count /src/app/main/main.c 83
|
||||
problem include-count /src/app/main/main.c 85
|
||||
problem function-size /src/app/main/main.c:dumpstats() 102
|
||||
problem function-size /src/app/main/main.c:tor_init() 136
|
||||
problem function-size /src/app/main/main.c:sandbox_init_filter() 291
|
||||
@ -109,20 +109,20 @@ problem function-size /src/tools/tor-gencert.c:parse_commandline() 111
|
||||
problem function-size /src/feature/keymgt/loadkey.c:ed_key_init_from_file() 333
|
||||
problem function-size /src/feature/dircommon/consdiff.c:gen_ed_diff() 204
|
||||
problem function-size /src/feature/dircommon/consdiff.c:apply_ed_diff() 159
|
||||
problem file-size /src/feature/control/control.c 7592
|
||||
problem include-count /src/feature/control/control.c 83
|
||||
problem function-size /src/feature/control/control.c:handle_control_authenticate() 188
|
||||
problem function-size /src/feature/control/control.c:getinfo_helper_misc() 109
|
||||
problem function-size /src/feature/control/control.c:getinfo_helper_dir() 304
|
||||
problem function-size /src/feature/control/control.c:getinfo_helper_events() 236
|
||||
problem function-size /src/feature/control/control.c:handle_control_extendcircuit() 151
|
||||
problem function-size /src/feature/control/control.c:handle_control_authchallenge() 115
|
||||
problem function-size /src/feature/control/control.c:handle_control_hsfetch() 114
|
||||
problem function-size /src/feature/control/control.c:handle_control_hspost() 117
|
||||
problem function-size /src/feature/control/control.c:handle_control_add_onion() 293
|
||||
problem function-size /src/feature/control/control.c:add_onion_helper_keyarg() 125
|
||||
problem function-size /src/feature/control/control_auth.c:handle_control_authenticate() 188
|
||||
problem function-size /src/feature/control/control_auth.c:handle_control_authchallenge() 115
|
||||
problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_misc() 109
|
||||
problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_dir() 304
|
||||
problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_events() 236
|
||||
problem function-size /src/feature/control/control_cmd.c:handle_control_command() 104
|
||||
problem function-size /src/feature/control/control_cmd.c:handle_control_extendcircuit() 151
|
||||
problem function-size /src/feature/control/control_cmd.c:handle_control_hsfetch() 114
|
||||
problem function-size /src/feature/control/control_cmd.c:handle_control_hspost() 117
|
||||
problem function-size /src/feature/control/control_cmd.c:handle_control_add_onion() 293
|
||||
problem function-size /src/feature/control/control_cmd.c:add_onion_helper_keyarg() 125
|
||||
problem function-size /src/feature/control/control.c:connection_control_process_inbuf() 239
|
||||
problem function-size /src/feature/control/control.c:control_event_stream_status() 119
|
||||
problem function-size /src/feature/control/control_events.c:control_event_stream_status() 119
|
||||
problem include-count /src/feature/control/control_getinfo.c 52
|
||||
problem function-size /src/feature/stats/rephist.c:rep_hist_load_mtbf_data() 185
|
||||
problem function-size /src/feature/stats/rephist.c:rep_hist_format_exit_stats() 148
|
||||
problem function-size /src/feature/dircache/consdiffmgr.c:consdiffmgr_cleanup() 115
|
||||
|
@ -86,6 +86,8 @@
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_auth.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/bwauth.h"
|
||||
#include "feature/dirauth/guardfraction.h"
|
||||
#include "feature/dircache/consdiffmgr.h"
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "core/mainloop/mainloop.h"
|
||||
#include "core/mainloop/netstatus.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
#include "feature/stats/rephist.h"
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_auth.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/bwauth.h"
|
||||
#include "feature/dirauth/keypin.h"
|
||||
#include "feature/dirauth/process_descs.h"
|
||||
|
@ -70,7 +70,12 @@ LIBTOR_APP_A_SOURCES = \
|
||||
src/feature/control/btrack_orconn_cevent.c \
|
||||
src/feature/control/btrack_orconn_maps.c \
|
||||
src/feature/control/control.c \
|
||||
src/feature/control/control_auth.c \
|
||||
src/feature/control/control_bootstrap.c \
|
||||
src/feature/control/control_cmd.c \
|
||||
src/feature/control/control_events.c \
|
||||
src/feature/control/control_fmt.c \
|
||||
src/feature/control/control_getinfo.c \
|
||||
src/feature/control/fmt_serverstatus.c \
|
||||
src/feature/control/getinfo_geoip.c \
|
||||
src/feature/dirauth/keypin.c \
|
||||
@ -287,7 +292,12 @@ noinst_HEADERS += \
|
||||
src/feature/control/btrack_orconn_maps.h \
|
||||
src/feature/control/btrack_sys.h \
|
||||
src/feature/control/control.h \
|
||||
src/feature/control/control_auth.h \
|
||||
src/feature/control/control_cmd.h \
|
||||
src/feature/control/control_connection_st.h \
|
||||
src/feature/control/control_events.h \
|
||||
src/feature/control/control_fmt.h \
|
||||
src/feature/control/control_getinfo.h \
|
||||
src/feature/control/fmt_serverstatus.h \
|
||||
src/feature/control/getinfo_geoip.h \
|
||||
src/feature/dirauth/authmode.h \
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/authmode.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/authmode.h"
|
||||
#include "feature/dirauth/reachability.h"
|
||||
#include "feature/dircache/consdiffmgr.h"
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/nodelist/describe.h"
|
||||
#include "feature/nodelist/microdesc.h"
|
||||
|
@ -67,7 +67,7 @@
|
||||
#include "app/config/config.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "lib/crypt_ops/crypto_dh.h"
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "core/or/circuitstats.h"
|
||||
#include "app/config/config.h"
|
||||
#include "app/config/confparse.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "core/mainloop/mainloop.h"
|
||||
#include "feature/nodelist/networkstatus.h"
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/hs/hs_circuit.h"
|
||||
#include "feature/hs/hs_client.h"
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "core/or/dos.h"
|
||||
#include "core/or/onion.h"
|
||||
#include "core/or/relay.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
#include "feature/nodelist/describe.h"
|
||||
#include "feature/nodelist/nodelist.h"
|
||||
|
@ -78,7 +78,7 @@
|
||||
#include "feature/client/addressmap.h"
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/client/dnsserv.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "app/config/config.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "feature/dirauth/reachability.h"
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "feature/client/addressmap.h"
|
||||
#include "lib/buf/buffers.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "app/config/config.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "feature/relay/ext_orport.h"
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "core/or/circuituse.h"
|
||||
#include "app/config/config.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/relay/dns.h"
|
||||
#include "feature/nodelist/nodelist.h"
|
||||
#include "feature/nodelist/routerset.h"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "app/config/config.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "core/mainloop/mainloop.h"
|
||||
#include "core/mainloop/netstatus.h"
|
||||
#include "core/or/policies.h"
|
||||
|
@ -128,7 +128,7 @@
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/nodelist/describe.h"
|
||||
#include "feature/nodelist/microdesc.h"
|
||||
|
@ -100,7 +100,7 @@
|
||||
#include "app/config/statefile.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/relay/ext_orport.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/encoding/confline.h"
|
||||
#include "lib/encoding/kvline.h"
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "core/or/orconn_event.h"
|
||||
#include "feature/control/btrack_orconn.h"
|
||||
#include "feature/control/btrack_orconn_cevent.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
|
||||
/**
|
||||
* Have we completed our first OR connection?
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,84 +12,6 @@
|
||||
#ifndef TOR_CONTROL_H
|
||||
#define TOR_CONTROL_H
|
||||
|
||||
#include "core/or/ocirc_event.h"
|
||||
|
||||
/** Used to indicate the type of a CIRC_MINOR event passed to the controller.
|
||||
* The various types are defined in control-spec.txt . */
|
||||
typedef enum circuit_status_minor_event_t {
|
||||
CIRC_MINOR_EVENT_PURPOSE_CHANGED,
|
||||
CIRC_MINOR_EVENT_CANNIBALIZED,
|
||||
} circuit_status_minor_event_t;
|
||||
|
||||
#include "core/or/orconn_event.h"
|
||||
|
||||
/** Used to indicate the type of a stream event passed to the controller.
|
||||
* The various types are defined in control-spec.txt */
|
||||
typedef enum stream_status_event_t {
|
||||
STREAM_EVENT_SENT_CONNECT = 0,
|
||||
STREAM_EVENT_SENT_RESOLVE = 1,
|
||||
STREAM_EVENT_SUCCEEDED = 2,
|
||||
STREAM_EVENT_FAILED = 3,
|
||||
STREAM_EVENT_CLOSED = 4,
|
||||
STREAM_EVENT_NEW = 5,
|
||||
STREAM_EVENT_NEW_RESOLVE = 6,
|
||||
STREAM_EVENT_FAILED_RETRIABLE = 7,
|
||||
STREAM_EVENT_REMAP = 8
|
||||
} stream_status_event_t;
|
||||
|
||||
/** Used to indicate the type of a buildtime event */
|
||||
typedef enum buildtimeout_set_event_t {
|
||||
BUILDTIMEOUT_SET_EVENT_COMPUTED = 0,
|
||||
BUILDTIMEOUT_SET_EVENT_RESET = 1,
|
||||
BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2,
|
||||
BUILDTIMEOUT_SET_EVENT_DISCARD = 3,
|
||||
BUILDTIMEOUT_SET_EVENT_RESUME = 4
|
||||
} buildtimeout_set_event_t;
|
||||
|
||||
/** Enum describing various stages of bootstrapping, for use with controller
|
||||
* bootstrap status events. The values range from 0 to 100. */
|
||||
typedef enum {
|
||||
BOOTSTRAP_STATUS_UNDEF=-1,
|
||||
BOOTSTRAP_STATUS_STARTING=0,
|
||||
|
||||
/* Initial connection to any relay */
|
||||
|
||||
BOOTSTRAP_STATUS_CONN_PT=1,
|
||||
BOOTSTRAP_STATUS_CONN_DONE_PT=2,
|
||||
BOOTSTRAP_STATUS_CONN_PROXY=3,
|
||||
BOOTSTRAP_STATUS_CONN_DONE_PROXY=4,
|
||||
BOOTSTRAP_STATUS_CONN=5,
|
||||
BOOTSTRAP_STATUS_CONN_DONE=10,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE=14,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE_DONE=15,
|
||||
|
||||
/* Loading directory info */
|
||||
|
||||
BOOTSTRAP_STATUS_ONEHOP_CREATE=20,
|
||||
BOOTSTRAP_STATUS_REQUESTING_STATUS=25,
|
||||
BOOTSTRAP_STATUS_LOADING_STATUS=30,
|
||||
BOOTSTRAP_STATUS_LOADING_KEYS=40,
|
||||
BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45,
|
||||
BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50,
|
||||
BOOTSTRAP_STATUS_ENOUGH_DIRINFO=75,
|
||||
|
||||
/* Connecting to a relay for AP circuits */
|
||||
|
||||
BOOTSTRAP_STATUS_AP_CONN_PT=76,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE_PT=77,
|
||||
BOOTSTRAP_STATUS_AP_CONN_PROXY=78,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE_PROXY=79,
|
||||
BOOTSTRAP_STATUS_AP_CONN=80,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE=85,
|
||||
BOOTSTRAP_STATUS_AP_HANDSHAKE=89,
|
||||
BOOTSTRAP_STATUS_AP_HANDSHAKE_DONE=90,
|
||||
|
||||
/* Creating AP circuits */
|
||||
|
||||
BOOTSTRAP_STATUS_CIRCUIT_CREATE=95,
|
||||
BOOTSTRAP_STATUS_DONE=100
|
||||
} bootstrap_status_t;
|
||||
|
||||
control_connection_t *TO_CONTROL_CONN(connection_t *);
|
||||
|
||||
#define CONTROL_CONN_STATE_MIN_ 1
|
||||
@ -100,18 +22,6 @@ control_connection_t *TO_CONTROL_CONN(connection_t *);
|
||||
#define CONTROL_CONN_STATE_NEEDAUTH 2
|
||||
#define CONTROL_CONN_STATE_MAX_ 2
|
||||
|
||||
/** Reason for remapping an AP connection's address: we have a cached
|
||||
* answer. */
|
||||
#define REMAP_STREAM_SOURCE_CACHE 1
|
||||
/** Reason for remapping an AP connection's address: the exit node told us an
|
||||
* answer. */
|
||||
#define REMAP_STREAM_SOURCE_EXIT 2
|
||||
|
||||
void control_initialize_event_queue(void);
|
||||
|
||||
void control_update_global_event_mask(void);
|
||||
void control_adjust_event_log_severity(void);
|
||||
|
||||
void control_ports_write_to_file(void);
|
||||
|
||||
/** Log information about the connection <b>conn</b>, protecting it as with
|
||||
@ -132,300 +42,22 @@ void connection_control_closed(control_connection_t *conn);
|
||||
|
||||
int connection_control_process_inbuf(control_connection_t *conn);
|
||||
|
||||
#define EVENT_NS 0x000F
|
||||
int control_event_is_interesting(int event);
|
||||
|
||||
void control_per_second_events(void);
|
||||
int control_any_per_second_event_enabled(void);
|
||||
|
||||
int control_event_circuit_status(origin_circuit_t *circ,
|
||||
circuit_status_event_t e, int reason);
|
||||
int control_event_circuit_purpose_changed(origin_circuit_t *circ,
|
||||
int old_purpose);
|
||||
int control_event_circuit_cannibalized(origin_circuit_t *circ,
|
||||
int old_purpose,
|
||||
const struct timeval *old_tv_created);
|
||||
int control_event_stream_status(entry_connection_t *conn,
|
||||
stream_status_event_t e,
|
||||
int reason);
|
||||
int control_event_or_conn_status(or_connection_t *conn,
|
||||
or_conn_status_event_t e, int reason);
|
||||
int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
|
||||
int control_event_stream_bandwidth(edge_connection_t *edge_conn);
|
||||
int control_event_stream_bandwidth_used(void);
|
||||
int control_event_circ_bandwidth_used(void);
|
||||
int control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc);
|
||||
int control_event_conn_bandwidth(connection_t *conn);
|
||||
int control_event_conn_bandwidth_used(void);
|
||||
int control_event_circuit_cell_stats(void);
|
||||
void control_event_logmsg(int severity, uint32_t domain, const char *msg);
|
||||
void control_event_logmsg_pending(void);
|
||||
int control_event_descriptors_changed(smartlist_t *routers);
|
||||
int control_event_address_mapped(const char *from, const char *to,
|
||||
time_t expires, const char *error,
|
||||
const int cached);
|
||||
int control_event_my_descriptor_changed(void);
|
||||
int control_event_network_liveness_update(int liveness);
|
||||
int control_event_networkstatus_changed(smartlist_t *statuses);
|
||||
|
||||
int control_event_newconsensus(const networkstatus_t *consensus);
|
||||
int control_event_networkstatus_changed_single(const routerstatus_t *rs);
|
||||
int control_event_general_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
int control_event_client_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
int control_event_server_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
|
||||
int control_event_general_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
int control_event_client_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
int control_event_server_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
|
||||
int control_event_guard(const char *nickname, const char *digest,
|
||||
const char *status);
|
||||
int control_event_conf_changed(const smartlist_t *elements);
|
||||
int control_event_buildtimeout_set(buildtimeout_set_event_t type,
|
||||
const char *args);
|
||||
int control_event_signal(uintptr_t signal);
|
||||
|
||||
int init_control_cookie_authentication(int enabled);
|
||||
char *get_controller_cookie_file_name(void);
|
||||
struct config_line_t;
|
||||
smartlist_t *decode_hashed_passwords(struct config_line_t *passwords);
|
||||
void disable_control_logging(void);
|
||||
void enable_control_logging(void);
|
||||
|
||||
void monitor_owning_controller_process(const char *process_spec);
|
||||
|
||||
void control_event_bootstrap(bootstrap_status_t status, int progress);
|
||||
MOCK_DECL(void, control_event_bootstrap_prob_or,(const char *warn,
|
||||
int reason,
|
||||
or_connection_t *or_conn));
|
||||
void control_event_boot_dir(bootstrap_status_t status, int progress);
|
||||
void control_event_boot_first_orconn(void);
|
||||
void control_event_bootstrap_problem(const char *warn, const char *reason,
|
||||
const connection_t *conn, int dowarn);
|
||||
char *control_event_boot_last_msg(void);
|
||||
void control_event_bootstrap_reset(void);
|
||||
|
||||
void control_event_clients_seen(const char *controller_str);
|
||||
void control_event_transport_launched(const char *mode,
|
||||
const char *transport_name,
|
||||
tor_addr_t *addr, uint16_t port);
|
||||
void control_event_pt_log(const char *log);
|
||||
void control_event_pt_status(const char *status);
|
||||
const char *rend_auth_type_to_string(rend_auth_type_t auth_type);
|
||||
MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest));
|
||||
void control_event_hs_descriptor_requested(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const char *id_digest,
|
||||
const char *desc_id,
|
||||
const char *hsdir_index);
|
||||
void control_event_hs_descriptor_created(const char *onion_address,
|
||||
const char *desc_id,
|
||||
int replica);
|
||||
void control_event_hs_descriptor_upload(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hs_dir,
|
||||
const char *hsdir_index);
|
||||
void control_event_hs_descriptor_upload_end(const char *action,
|
||||
const char *onion_address,
|
||||
const char *hs_dir,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_uploaded(const char *hs_dir,
|
||||
const char *onion_address);
|
||||
/* Hidden service v2 HS_DESC specific. */
|
||||
void control_event_hsv2_descriptor_failed(const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason);
|
||||
void control_event_hsv2_descriptor_received(const char *onion_address,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest);
|
||||
/* Hidden service v3 HS_DESC specific. */
|
||||
void control_event_hsv3_descriptor_failed(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_id_digest,
|
||||
const char *reason);
|
||||
void control_event_hsv3_descriptor_received(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_id_digest);
|
||||
void control_event_hs_descriptor_upload_failed(const char *hs_dir,
|
||||
const char *onion_address,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_content(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_fp,
|
||||
const char *content);
|
||||
void control_free_all(void);
|
||||
|
||||
#ifdef CONTROL_PRIVATE
|
||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||
|
||||
/* Recognized asynchronous event types. It's okay to expand this list
|
||||
* because it is used both as a list of v0 event types, and as indices
|
||||
* into the bitfield to determine which controllers want which events.
|
||||
*/
|
||||
/* This bitfield has no event zero 0x0000 */
|
||||
#define EVENT_MIN_ 0x0001
|
||||
#define EVENT_CIRCUIT_STATUS 0x0001
|
||||
#define EVENT_STREAM_STATUS 0x0002
|
||||
#define EVENT_OR_CONN_STATUS 0x0003
|
||||
#define EVENT_BANDWIDTH_USED 0x0004
|
||||
#define EVENT_CIRCUIT_STATUS_MINOR 0x0005
|
||||
#define EVENT_NEW_DESC 0x0006
|
||||
#define EVENT_DEBUG_MSG 0x0007
|
||||
#define EVENT_INFO_MSG 0x0008
|
||||
#define EVENT_NOTICE_MSG 0x0009
|
||||
#define EVENT_WARN_MSG 0x000A
|
||||
#define EVENT_ERR_MSG 0x000B
|
||||
#define EVENT_ADDRMAP 0x000C
|
||||
/* There was an AUTHDIR_NEWDESCS event, but it no longer exists. We
|
||||
can reclaim 0x000D. */
|
||||
#define EVENT_DESCCHANGED 0x000E
|
||||
/* Exposed above */
|
||||
// #define EVENT_NS 0x000F
|
||||
#define EVENT_STATUS_CLIENT 0x0010
|
||||
#define EVENT_STATUS_SERVER 0x0011
|
||||
#define EVENT_STATUS_GENERAL 0x0012
|
||||
#define EVENT_GUARD 0x0013
|
||||
#define EVENT_STREAM_BANDWIDTH_USED 0x0014
|
||||
#define EVENT_CLIENTS_SEEN 0x0015
|
||||
#define EVENT_NEWCONSENSUS 0x0016
|
||||
#define EVENT_BUILDTIMEOUT_SET 0x0017
|
||||
#define EVENT_GOT_SIGNAL 0x0018
|
||||
#define EVENT_CONF_CHANGED 0x0019
|
||||
#define EVENT_CONN_BW 0x001A
|
||||
#define EVENT_CELL_STATS 0x001B
|
||||
/* UNUSED : 0x001C */
|
||||
#define EVENT_CIRC_BANDWIDTH_USED 0x001D
|
||||
#define EVENT_TRANSPORT_LAUNCHED 0x0020
|
||||
#define EVENT_HS_DESC 0x0021
|
||||
#define EVENT_HS_DESC_CONTENT 0x0022
|
||||
#define EVENT_NETWORK_LIVENESS 0x0023
|
||||
#define EVENT_PT_LOG 0x0024
|
||||
#define EVENT_PT_STATUS 0x0025
|
||||
#define EVENT_MAX_ 0x0025
|
||||
|
||||
/* sizeof(control_connection_t.event_mask) in bits, currently a uint64_t */
|
||||
#define EVENT_CAPACITY_ 0x0040
|
||||
|
||||
/* If EVENT_MAX_ ever hits 0x0040, we need to make the mask into a
|
||||
* different structure, as it can only handle a maximum left shift of 1<<63. */
|
||||
|
||||
#if EVENT_MAX_ >= EVENT_CAPACITY_
|
||||
#error control_connection_t.event_mask has an event greater than its capacity
|
||||
#endif
|
||||
|
||||
#define EVENT_MASK_(e) (((uint64_t)1)<<(e))
|
||||
|
||||
#define EVENT_MASK_NONE_ ((uint64_t)0x0)
|
||||
|
||||
#define EVENT_MASK_ABOVE_MIN_ ((~((uint64_t)0x0)) << EVENT_MIN_)
|
||||
#define EVENT_MASK_BELOW_MAX_ ((~((uint64_t)0x0)) \
|
||||
>> (EVENT_CAPACITY_ - EVENT_MAX_ \
|
||||
- EVENT_MIN_))
|
||||
|
||||
#define EVENT_MASK_ALL_ (EVENT_MASK_ABOVE_MIN_ \
|
||||
& EVENT_MASK_BELOW_MAX_)
|
||||
|
||||
/* Used only by control.c and test.c */
|
||||
STATIC size_t write_escaped_data(const char *data, size_t len, char **out);
|
||||
STATIC size_t read_escaped_data(const char *data, size_t len, char **out);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
MOCK_DECL(STATIC void,
|
||||
send_control_event_string,(uint16_t event, const char *msg));
|
||||
|
||||
MOCK_DECL(STATIC void,
|
||||
queue_control_event_string,(uint16_t event, char *msg));
|
||||
|
||||
void control_testing_set_global_event_mask(uint64_t mask);
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
|
||||
/** Helper structure: temporarily stores cell statistics for a circuit. */
|
||||
typedef struct cell_stats_t {
|
||||
/** Number of cells added in app-ward direction by command. */
|
||||
uint64_t added_cells_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells added in exit-ward direction by command. */
|
||||
uint64_t added_cells_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells removed in app-ward direction by command. */
|
||||
uint64_t removed_cells_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells removed in exit-ward direction by command. */
|
||||
uint64_t removed_cells_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Total waiting time of cells in app-ward direction by command. */
|
||||
uint64_t total_time_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Total waiting time of cells in exit-ward direction by command. */
|
||||
uint64_t total_time_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
} cell_stats_t;
|
||||
void sum_up_cell_stats_by_command(circuit_t *circ,
|
||||
cell_stats_t *cell_stats);
|
||||
void append_cell_stats_by_command(smartlist_t *event_parts,
|
||||
const char *key,
|
||||
const uint64_t *include_if_non_zero,
|
||||
const uint64_t *number_to_include);
|
||||
void format_cell_stats(char **event_string, circuit_t *circ,
|
||||
cell_stats_t *cell_stats);
|
||||
STATIC char *get_bw_samples(void);
|
||||
|
||||
/* ADD_ONION secret key to create an ephemeral service. The command supports
|
||||
* multiple versions so this union stores the key and passes it to the HS
|
||||
* subsystem depending on the requested version. */
|
||||
typedef union add_onion_secret_key_t {
|
||||
/* Hidden service v2 secret key. */
|
||||
crypto_pk_t *v2;
|
||||
/* Hidden service v3 secret key. */
|
||||
ed25519_secret_key_t *v3;
|
||||
} add_onion_secret_key_t;
|
||||
|
||||
STATIC int add_onion_helper_keyarg(const char *arg, int discard_pk,
|
||||
const char **key_new_alg_out,
|
||||
char **key_new_blob_out,
|
||||
add_onion_secret_key_t *decoded_key,
|
||||
int *hs_version, char **err_msg_out);
|
||||
|
||||
STATIC rend_authorized_client_t *
|
||||
add_onion_helper_clientauth(const char *arg, int *created, char **err_msg_out);
|
||||
|
||||
STATIC int getinfo_helper_onions(
|
||||
control_connection_t *control_conn,
|
||||
const char *question,
|
||||
char **answer,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_networkstatus(
|
||||
const char *flavor,
|
||||
download_status_t **dl_to_emit,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_cert(
|
||||
const char *fp_sk_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_desc(
|
||||
const char *desc_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_bridge(
|
||||
const char *bridge_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_downloads(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_dir(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_current_time(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
|
||||
#endif /* defined(CONTROL_PRIVATE) */
|
||||
#ifdef CONTROL_MODULE_PRIVATE
|
||||
struct signal_name_t {
|
||||
int sig;
|
||||
const char *signal_name;
|
||||
};
|
||||
extern const struct signal_name_t signal_table[];
|
||||
int get_cached_network_liveness(void);
|
||||
void set_cached_network_liveness(int liveness);
|
||||
#endif /* defined(CONTROL_MODULE_PRIVATE) */
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_H) */
|
||||
|
439
src/feature/control/control_auth.c
Normal file
439
src/feature/control/control_auth.c
Normal file
@ -0,0 +1,439 @@
|
||||
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control_auth.c
|
||||
* \brief Authentication for Tor's control-socket interface.
|
||||
**/
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "app/config/config.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_auth.h"
|
||||
#include "feature/control/control_connection_st.h"
|
||||
#include "feature/control/control_fmt.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "lib/encoding/confline.h"
|
||||
|
||||
#include "lib/crypt_ops/crypto_s2k.h"
|
||||
|
||||
/** If we're using cookie-type authentication, how long should our cookies be?
|
||||
*/
|
||||
#define AUTHENTICATION_COOKIE_LEN 32
|
||||
|
||||
/** If true, we've set authentication_cookie to a secret code and
|
||||
* stored it to disk. */
|
||||
static int authentication_cookie_is_set = 0;
|
||||
/** If authentication_cookie_is_set, a secret cookie that we've stored to disk
|
||||
* and which we're using to authenticate controllers. (If the controller can
|
||||
* read it off disk, it has permission to connect.) */
|
||||
static uint8_t *authentication_cookie = NULL;
|
||||
|
||||
#define SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT \
|
||||
"Tor safe cookie authentication server-to-controller hash"
|
||||
#define SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT \
|
||||
"Tor safe cookie authentication controller-to-server hash"
|
||||
#define SAFECOOKIE_SERVER_NONCE_LEN DIGEST256_LEN
|
||||
|
||||
/** Helper: Return a newly allocated string containing a path to the
|
||||
* file where we store our authentication cookie. */
|
||||
char *
|
||||
get_controller_cookie_file_name(void)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
if (options->CookieAuthFile && strlen(options->CookieAuthFile)) {
|
||||
return tor_strdup(options->CookieAuthFile);
|
||||
} else {
|
||||
return get_datadir_fname("control_auth_cookie");
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the cookie-based authentication system of the
|
||||
* ControlPort. If <b>enabled</b> is 0, then disable the cookie
|
||||
* authentication system. */
|
||||
int
|
||||
init_control_cookie_authentication(int enabled)
|
||||
{
|
||||
char *fname = NULL;
|
||||
int retval;
|
||||
|
||||
if (!enabled) {
|
||||
authentication_cookie_is_set = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fname = get_controller_cookie_file_name();
|
||||
retval = init_cookie_authentication(fname, "", /* no header */
|
||||
AUTHENTICATION_COOKIE_LEN,
|
||||
get_options()->CookieAuthFileGroupReadable,
|
||||
&authentication_cookie,
|
||||
&authentication_cookie_is_set);
|
||||
tor_free(fname);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Decode the hashed, base64'd passwords stored in <b>passwords</b>.
|
||||
* Return a smartlist of acceptable passwords (unterminated strings of
|
||||
* length S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on
|
||||
* failure.
|
||||
*/
|
||||
smartlist_t *
|
||||
decode_hashed_passwords(config_line_t *passwords)
|
||||
{
|
||||
char decoded[64];
|
||||
config_line_t *cl;
|
||||
smartlist_t *sl = smartlist_new();
|
||||
|
||||
tor_assert(passwords);
|
||||
|
||||
for (cl = passwords; cl; cl = cl->next) {
|
||||
const char *hashed = cl->value;
|
||||
|
||||
if (!strcmpstart(hashed, "16:")) {
|
||||
if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))
|
||||
!= S2K_RFC2440_SPECIFIER_LEN + DIGEST_LEN
|
||||
|| strlen(hashed+3) != (S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN)*2) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
|
||||
!= S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
smartlist_add(sl,
|
||||
tor_memdup(decoded, S2K_RFC2440_SPECIFIER_LEN+DIGEST_LEN));
|
||||
}
|
||||
|
||||
return sl;
|
||||
|
||||
err:
|
||||
SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
|
||||
smartlist_free(sl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Called when we get an AUTHCHALLENGE command. */
|
||||
int
|
||||
handle_control_authchallenge(control_connection_t *conn, uint32_t len,
|
||||
const char *body)
|
||||
{
|
||||
const char *cp = body;
|
||||
char *client_nonce;
|
||||
size_t client_nonce_len;
|
||||
char server_hash[DIGEST256_LEN];
|
||||
char server_hash_encoded[HEX_DIGEST256_LEN+1];
|
||||
char server_nonce[SAFECOOKIE_SERVER_NONCE_LEN];
|
||||
char server_nonce_encoded[(2*SAFECOOKIE_SERVER_NONCE_LEN) + 1];
|
||||
|
||||
cp += strspn(cp, " \t\n\r");
|
||||
if (!strcasecmpstart(cp, "SAFECOOKIE")) {
|
||||
cp += strlen("SAFECOOKIE");
|
||||
} else {
|
||||
connection_write_str_to_buf("513 AUTHCHALLENGE only supports SAFECOOKIE "
|
||||
"authentication\r\n", conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!authentication_cookie_is_set) {
|
||||
connection_write_str_to_buf("515 Cookie authentication is disabled\r\n",
|
||||
conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp += strspn(cp, " \t\n\r");
|
||||
if (*cp == '"') {
|
||||
const char *newcp =
|
||||
decode_escaped_string(cp, len - (cp - body),
|
||||
&client_nonce, &client_nonce_len);
|
||||
if (newcp == NULL) {
|
||||
connection_write_str_to_buf("513 Invalid quoted client nonce\r\n",
|
||||
conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
return -1;
|
||||
}
|
||||
cp = newcp;
|
||||
} else {
|
||||
size_t client_nonce_encoded_len = strspn(cp, "0123456789ABCDEFabcdef");
|
||||
|
||||
client_nonce_len = client_nonce_encoded_len / 2;
|
||||
client_nonce = tor_malloc_zero(client_nonce_len);
|
||||
|
||||
if (base16_decode(client_nonce, client_nonce_len,
|
||||
cp, client_nonce_encoded_len)
|
||||
!= (int) client_nonce_len) {
|
||||
connection_write_str_to_buf("513 Invalid base16 client nonce\r\n",
|
||||
conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
tor_free(client_nonce);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp += client_nonce_encoded_len;
|
||||
}
|
||||
|
||||
cp += strspn(cp, " \t\n\r");
|
||||
if (*cp != '\0' ||
|
||||
cp != body + len) {
|
||||
connection_write_str_to_buf("513 Junk at end of AUTHCHALLENGE command\r\n",
|
||||
conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
tor_free(client_nonce);
|
||||
return -1;
|
||||
}
|
||||
crypto_rand(server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
|
||||
|
||||
/* Now compute and send the server-to-controller response, and the
|
||||
* server's nonce. */
|
||||
tor_assert(authentication_cookie != NULL);
|
||||
|
||||
{
|
||||
size_t tmp_len = (AUTHENTICATION_COOKIE_LEN +
|
||||
client_nonce_len +
|
||||
SAFECOOKIE_SERVER_NONCE_LEN);
|
||||
char *tmp = tor_malloc_zero(tmp_len);
|
||||
char *client_hash = tor_malloc_zero(DIGEST256_LEN);
|
||||
memcpy(tmp, authentication_cookie, AUTHENTICATION_COOKIE_LEN);
|
||||
memcpy(tmp + AUTHENTICATION_COOKIE_LEN, client_nonce, client_nonce_len);
|
||||
memcpy(tmp + AUTHENTICATION_COOKIE_LEN + client_nonce_len,
|
||||
server_nonce, SAFECOOKIE_SERVER_NONCE_LEN);
|
||||
|
||||
crypto_hmac_sha256(server_hash,
|
||||
SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT,
|
||||
strlen(SAFECOOKIE_SERVER_TO_CONTROLLER_CONSTANT),
|
||||
tmp,
|
||||
tmp_len);
|
||||
|
||||
crypto_hmac_sha256(client_hash,
|
||||
SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT,
|
||||
strlen(SAFECOOKIE_CONTROLLER_TO_SERVER_CONSTANT),
|
||||
tmp,
|
||||
tmp_len);
|
||||
|
||||
conn->safecookie_client_hash = client_hash;
|
||||
|
||||
tor_free(tmp);
|
||||
}
|
||||
|
||||
base16_encode(server_hash_encoded, sizeof(server_hash_encoded),
|
||||
server_hash, sizeof(server_hash));
|
||||
base16_encode(server_nonce_encoded, sizeof(server_nonce_encoded),
|
||||
server_nonce, sizeof(server_nonce));
|
||||
|
||||
connection_printf_to_buf(conn,
|
||||
"250 AUTHCHALLENGE SERVERHASH=%s "
|
||||
"SERVERNONCE=%s\r\n",
|
||||
server_hash_encoded,
|
||||
server_nonce_encoded);
|
||||
|
||||
tor_free(client_nonce);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Called when we get an AUTHENTICATE message. Check whether the
|
||||
* authentication is valid, and if so, update the connection's state to
|
||||
* OPEN. Reply with DONE or ERROR.
|
||||
*/
|
||||
int
|
||||
handle_control_authenticate(control_connection_t *conn, uint32_t len,
|
||||
const char *body)
|
||||
{
|
||||
int used_quoted_string = 0;
|
||||
const or_options_t *options = get_options();
|
||||
const char *errstr = "Unknown error";
|
||||
char *password;
|
||||
size_t password_len;
|
||||
const char *cp;
|
||||
int i;
|
||||
int bad_cookie=0, bad_password=0;
|
||||
smartlist_t *sl = NULL;
|
||||
|
||||
if (!len) {
|
||||
password = tor_strdup("");
|
||||
password_len = 0;
|
||||
} else if (TOR_ISXDIGIT(body[0])) {
|
||||
cp = body;
|
||||
while (TOR_ISXDIGIT(*cp))
|
||||
++cp;
|
||||
i = (int)(cp - body);
|
||||
tor_assert(i>0);
|
||||
password_len = i/2;
|
||||
password = tor_malloc(password_len + 1);
|
||||
if (base16_decode(password, password_len+1, body, i)
|
||||
!= (int) password_len) {
|
||||
connection_write_str_to_buf(
|
||||
"551 Invalid hexadecimal encoding. Maybe you tried a plain text "
|
||||
"password? If so, the standard requires that you put it in "
|
||||
"double quotes.\r\n", conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
tor_free(password);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!decode_escaped_string(body, len, &password, &password_len)) {
|
||||
connection_write_str_to_buf("551 Invalid quoted string. You need "
|
||||
"to put the password in double quotes.\r\n", conn);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
return 0;
|
||||
}
|
||||
used_quoted_string = 1;
|
||||
}
|
||||
|
||||
if (conn->safecookie_client_hash != NULL) {
|
||||
/* The controller has chosen safe cookie authentication; the only
|
||||
* acceptable authentication value is the controller-to-server
|
||||
* response. */
|
||||
|
||||
tor_assert(authentication_cookie_is_set);
|
||||
|
||||
if (password_len != DIGEST256_LEN) {
|
||||
log_warn(LD_CONTROL,
|
||||
"Got safe cookie authentication response with wrong length "
|
||||
"(%d)", (int)password_len);
|
||||
errstr = "Wrong length for safe cookie response.";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tor_memneq(conn->safecookie_client_hash, password, DIGEST256_LEN)) {
|
||||
log_warn(LD_CONTROL,
|
||||
"Got incorrect safe cookie authentication response");
|
||||
errstr = "Safe cookie response did not match expected value.";
|
||||
goto err;
|
||||
}
|
||||
|
||||
tor_free(conn->safecookie_client_hash);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (!options->CookieAuthentication && !options->HashedControlPassword &&
|
||||
!options->HashedControlSessionPassword) {
|
||||
/* if Tor doesn't demand any stronger authentication, then
|
||||
* the controller can get in with anything. */
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (options->CookieAuthentication) {
|
||||
int also_password = options->HashedControlPassword != NULL ||
|
||||
options->HashedControlSessionPassword != NULL;
|
||||
if (password_len != AUTHENTICATION_COOKIE_LEN) {
|
||||
if (!also_password) {
|
||||
log_warn(LD_CONTROL, "Got authentication cookie with wrong length "
|
||||
"(%d)", (int)password_len);
|
||||
errstr = "Wrong length on authentication cookie.";
|
||||
goto err;
|
||||
}
|
||||
bad_cookie = 1;
|
||||
} else if (tor_memneq(authentication_cookie, password, password_len)) {
|
||||
if (!also_password) {
|
||||
log_warn(LD_CONTROL, "Got mismatched authentication cookie");
|
||||
errstr = "Authentication cookie did not match expected value.";
|
||||
goto err;
|
||||
}
|
||||
bad_cookie = 1;
|
||||
} else {
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
|
||||
if (options->HashedControlPassword ||
|
||||
options->HashedControlSessionPassword) {
|
||||
int bad = 0;
|
||||
smartlist_t *sl_tmp;
|
||||
char received[DIGEST_LEN];
|
||||
int also_cookie = options->CookieAuthentication;
|
||||
sl = smartlist_new();
|
||||
if (options->HashedControlPassword) {
|
||||
sl_tmp = decode_hashed_passwords(options->HashedControlPassword);
|
||||
if (!sl_tmp)
|
||||
bad = 1;
|
||||
else {
|
||||
smartlist_add_all(sl, sl_tmp);
|
||||
smartlist_free(sl_tmp);
|
||||
}
|
||||
}
|
||||
if (options->HashedControlSessionPassword) {
|
||||
sl_tmp = decode_hashed_passwords(options->HashedControlSessionPassword);
|
||||
if (!sl_tmp)
|
||||
bad = 1;
|
||||
else {
|
||||
smartlist_add_all(sl, sl_tmp);
|
||||
smartlist_free(sl_tmp);
|
||||
}
|
||||
}
|
||||
if (bad) {
|
||||
if (!also_cookie) {
|
||||
log_warn(LD_BUG,
|
||||
"Couldn't decode HashedControlPassword: invalid base16");
|
||||
errstr="Couldn't decode HashedControlPassword value in configuration.";
|
||||
goto err;
|
||||
}
|
||||
bad_password = 1;
|
||||
SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
|
||||
smartlist_free(sl);
|
||||
sl = NULL;
|
||||
} else {
|
||||
SMARTLIST_FOREACH(sl, char *, expected,
|
||||
{
|
||||
secret_to_key_rfc2440(received,DIGEST_LEN,
|
||||
password,password_len,expected);
|
||||
if (tor_memeq(expected + S2K_RFC2440_SPECIFIER_LEN,
|
||||
received, DIGEST_LEN))
|
||||
goto ok;
|
||||
});
|
||||
SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
|
||||
smartlist_free(sl);
|
||||
sl = NULL;
|
||||
|
||||
if (used_quoted_string)
|
||||
errstr = "Password did not match HashedControlPassword value from "
|
||||
"configuration";
|
||||
else
|
||||
errstr = "Password did not match HashedControlPassword value from "
|
||||
"configuration. Maybe you tried a plain text password? "
|
||||
"If so, the standard requires that you put it in double quotes.";
|
||||
bad_password = 1;
|
||||
if (!also_cookie)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/** We only get here if both kinds of authentication failed. */
|
||||
tor_assert(bad_password && bad_cookie);
|
||||
log_warn(LD_CONTROL, "Bad password or authentication cookie on controller.");
|
||||
errstr = "Password did not match HashedControlPassword *or* authentication "
|
||||
"cookie.";
|
||||
|
||||
err:
|
||||
tor_free(password);
|
||||
connection_printf_to_buf(conn, "515 Authentication failed: %s\r\n", errstr);
|
||||
connection_mark_for_close(TO_CONN(conn));
|
||||
if (sl) { /* clean up */
|
||||
SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
|
||||
smartlist_free(sl);
|
||||
}
|
||||
return 0;
|
||||
ok:
|
||||
log_info(LD_CONTROL, "Authenticated control connection ("TOR_SOCKET_T_FORMAT
|
||||
")", conn->base_.s);
|
||||
send_control_done(conn);
|
||||
conn->base_.state = CONTROL_CONN_STATE_OPEN;
|
||||
tor_free(password);
|
||||
if (sl) { /* clean up */
|
||||
SMARTLIST_FOREACH(sl, char *, str, tor_free(str));
|
||||
smartlist_free(sl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
control_auth_free_all(void)
|
||||
{
|
||||
if (authentication_cookie) /* Free the auth cookie */
|
||||
tor_free(authentication_cookie);
|
||||
authentication_cookie_is_set = 0;
|
||||
}
|
27
src/feature/control/control_auth.h
Normal file
27
src/feature/control/control_auth.h
Normal file
@ -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-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control_auth.h
|
||||
* \brief Header file for control_auth.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CONTROL_AUTH_H
|
||||
#define TOR_CONTROL_AUTH_H
|
||||
|
||||
int init_control_cookie_authentication(int enabled);
|
||||
char *get_controller_cookie_file_name(void);
|
||||
struct config_line_t;
|
||||
smartlist_t *decode_hashed_passwords(struct config_line_t *passwords);
|
||||
|
||||
int handle_control_authchallenge(control_connection_t *conn, uint32_t len,
|
||||
const char *body);
|
||||
int handle_control_authenticate(control_connection_t *conn,
|
||||
uint32_t cmd_data_len,
|
||||
const char *args);
|
||||
void control_auth_free_all(void);
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_AUTH_H) */
|
@ -14,7 +14,7 @@
|
||||
#include "core/or/connection_st.h"
|
||||
#include "core/or/or_connection_st.h"
|
||||
#include "core/or/reasons.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
#include "lib/malloc/malloc.h"
|
||||
|
||||
|
2323
src/feature/control/control_cmd.c
Normal file
2323
src/feature/control/control_cmd.c
Normal file
File diff suppressed because it is too large
Load Diff
48
src/feature/control/control_cmd.h
Normal file
48
src/feature/control/control_cmd.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control_cmd.h
|
||||
* \brief Header file for control_cmd.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CONTROL_CMD_H
|
||||
#define TOR_CONTROL_CMD_H
|
||||
|
||||
int handle_control_command(control_connection_t *conn,
|
||||
uint32_t cmd_data_len,
|
||||
char *args);
|
||||
void control_cmd_free_all(void);
|
||||
|
||||
#ifdef CONTROL_CMD_PRIVATE
|
||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||
|
||||
/* ADD_ONION secret key to create an ephemeral service. The command supports
|
||||
* multiple versions so this union stores the key and passes it to the HS
|
||||
* subsystem depending on the requested version. */
|
||||
typedef union add_onion_secret_key_t {
|
||||
/* Hidden service v2 secret key. */
|
||||
crypto_pk_t *v2;
|
||||
/* Hidden service v3 secret key. */
|
||||
ed25519_secret_key_t *v3;
|
||||
} add_onion_secret_key_t;
|
||||
|
||||
STATIC int add_onion_helper_keyarg(const char *arg, int discard_pk,
|
||||
const char **key_new_alg_out,
|
||||
char **key_new_blob_out,
|
||||
add_onion_secret_key_t *decoded_key,
|
||||
int *hs_version, char **err_msg_out);
|
||||
|
||||
STATIC rend_authorized_client_t *add_onion_helper_clientauth(const char *arg,
|
||||
int *created, char **err_msg_out);
|
||||
|
||||
#endif /* defined(CONTROL_CMD_PRIVATE) */
|
||||
|
||||
#ifdef CONTROL_MODULE_PRIVATE
|
||||
smartlist_t * get_detached_onion_services(void);
|
||||
#endif /* defined(CONTROL_MODULE_PRIVATE) */
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_CMD_H) */
|
2317
src/feature/control/control_events.c
Normal file
2317
src/feature/control/control_events.c
Normal file
File diff suppressed because it is too large
Load Diff
351
src/feature/control/control_events.h
Normal file
351
src/feature/control/control_events.h
Normal file
@ -0,0 +1,351 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control_events.h
|
||||
* \brief Header file for control_events.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CONTROL_EVENTS_H
|
||||
#define TOR_CONTROL_EVENTS_H
|
||||
|
||||
#include "core/or/ocirc_event.h"
|
||||
|
||||
/** Used to indicate the type of a CIRC_MINOR event passed to the controller.
|
||||
* The various types are defined in control-spec.txt . */
|
||||
typedef enum circuit_status_minor_event_t {
|
||||
CIRC_MINOR_EVENT_PURPOSE_CHANGED,
|
||||
CIRC_MINOR_EVENT_CANNIBALIZED,
|
||||
} circuit_status_minor_event_t;
|
||||
|
||||
#include "core/or/orconn_event.h"
|
||||
|
||||
/** Used to indicate the type of a stream event passed to the controller.
|
||||
* The various types are defined in control-spec.txt */
|
||||
typedef enum stream_status_event_t {
|
||||
STREAM_EVENT_SENT_CONNECT = 0,
|
||||
STREAM_EVENT_SENT_RESOLVE = 1,
|
||||
STREAM_EVENT_SUCCEEDED = 2,
|
||||
STREAM_EVENT_FAILED = 3,
|
||||
STREAM_EVENT_CLOSED = 4,
|
||||
STREAM_EVENT_NEW = 5,
|
||||
STREAM_EVENT_NEW_RESOLVE = 6,
|
||||
STREAM_EVENT_FAILED_RETRIABLE = 7,
|
||||
STREAM_EVENT_REMAP = 8
|
||||
} stream_status_event_t;
|
||||
|
||||
/** Used to indicate the type of a buildtime event */
|
||||
typedef enum buildtimeout_set_event_t {
|
||||
BUILDTIMEOUT_SET_EVENT_COMPUTED = 0,
|
||||
BUILDTIMEOUT_SET_EVENT_RESET = 1,
|
||||
BUILDTIMEOUT_SET_EVENT_SUSPENDED = 2,
|
||||
BUILDTIMEOUT_SET_EVENT_DISCARD = 3,
|
||||
BUILDTIMEOUT_SET_EVENT_RESUME = 4
|
||||
} buildtimeout_set_event_t;
|
||||
|
||||
/** Enum describing various stages of bootstrapping, for use with controller
|
||||
* bootstrap status events. The values range from 0 to 100. */
|
||||
typedef enum {
|
||||
BOOTSTRAP_STATUS_UNDEF=-1,
|
||||
BOOTSTRAP_STATUS_STARTING=0,
|
||||
|
||||
/* Initial connection to any relay */
|
||||
|
||||
BOOTSTRAP_STATUS_CONN_PT=1,
|
||||
BOOTSTRAP_STATUS_CONN_DONE_PT=2,
|
||||
BOOTSTRAP_STATUS_CONN_PROXY=3,
|
||||
BOOTSTRAP_STATUS_CONN_DONE_PROXY=4,
|
||||
BOOTSTRAP_STATUS_CONN=5,
|
||||
BOOTSTRAP_STATUS_CONN_DONE=10,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE=14,
|
||||
BOOTSTRAP_STATUS_HANDSHAKE_DONE=15,
|
||||
|
||||
/* Loading directory info */
|
||||
|
||||
BOOTSTRAP_STATUS_ONEHOP_CREATE=20,
|
||||
BOOTSTRAP_STATUS_REQUESTING_STATUS=25,
|
||||
BOOTSTRAP_STATUS_LOADING_STATUS=30,
|
||||
BOOTSTRAP_STATUS_LOADING_KEYS=40,
|
||||
BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS=45,
|
||||
BOOTSTRAP_STATUS_LOADING_DESCRIPTORS=50,
|
||||
BOOTSTRAP_STATUS_ENOUGH_DIRINFO=75,
|
||||
|
||||
/* Connecting to a relay for AP circuits */
|
||||
|
||||
BOOTSTRAP_STATUS_AP_CONN_PT=76,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE_PT=77,
|
||||
BOOTSTRAP_STATUS_AP_CONN_PROXY=78,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE_PROXY=79,
|
||||
BOOTSTRAP_STATUS_AP_CONN=80,
|
||||
BOOTSTRAP_STATUS_AP_CONN_DONE=85,
|
||||
BOOTSTRAP_STATUS_AP_HANDSHAKE=89,
|
||||
BOOTSTRAP_STATUS_AP_HANDSHAKE_DONE=90,
|
||||
|
||||
/* Creating AP circuits */
|
||||
|
||||
BOOTSTRAP_STATUS_CIRCUIT_CREATE=95,
|
||||
BOOTSTRAP_STATUS_DONE=100
|
||||
} bootstrap_status_t;
|
||||
|
||||
/** Reason for remapping an AP connection's address: we have a cached
|
||||
* answer. */
|
||||
#define REMAP_STREAM_SOURCE_CACHE 1
|
||||
/** Reason for remapping an AP connection's address: the exit node told us an
|
||||
* answer. */
|
||||
#define REMAP_STREAM_SOURCE_EXIT 2
|
||||
|
||||
void control_initialize_event_queue(void);
|
||||
|
||||
void control_update_global_event_mask(void);
|
||||
void control_adjust_event_log_severity(void);
|
||||
|
||||
#define EVENT_NS 0x000F
|
||||
int control_event_is_interesting(int event);
|
||||
|
||||
void control_per_second_events(void);
|
||||
int control_any_per_second_event_enabled(void);
|
||||
|
||||
int control_event_circuit_status(origin_circuit_t *circ,
|
||||
circuit_status_event_t e, int reason);
|
||||
int control_event_circuit_purpose_changed(origin_circuit_t *circ,
|
||||
int old_purpose);
|
||||
int control_event_circuit_cannibalized(origin_circuit_t *circ,
|
||||
int old_purpose,
|
||||
const struct timeval *old_tv_created);
|
||||
int control_event_stream_status(entry_connection_t *conn,
|
||||
stream_status_event_t e,
|
||||
int reason);
|
||||
int control_event_or_conn_status(or_connection_t *conn,
|
||||
or_conn_status_event_t e, int reason);
|
||||
int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
|
||||
int control_event_stream_bandwidth(edge_connection_t *edge_conn);
|
||||
int control_event_stream_bandwidth_used(void);
|
||||
int control_event_circ_bandwidth_used(void);
|
||||
int control_event_circ_bandwidth_used_for_circ(origin_circuit_t *ocirc);
|
||||
int control_event_conn_bandwidth(connection_t *conn);
|
||||
int control_event_conn_bandwidth_used(void);
|
||||
int control_event_circuit_cell_stats(void);
|
||||
void control_event_logmsg(int severity, uint32_t domain, const char *msg);
|
||||
void control_event_logmsg_pending(void);
|
||||
int control_event_descriptors_changed(smartlist_t *routers);
|
||||
int control_event_address_mapped(const char *from, const char *to,
|
||||
time_t expires, const char *error,
|
||||
const int cached);
|
||||
int control_event_my_descriptor_changed(void);
|
||||
int control_event_network_liveness_update(int liveness);
|
||||
int control_event_networkstatus_changed(smartlist_t *statuses);
|
||||
|
||||
int control_event_newconsensus(const networkstatus_t *consensus);
|
||||
int control_event_networkstatus_changed_single(const routerstatus_t *rs);
|
||||
int control_event_general_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
int control_event_client_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
int control_event_server_status(int severity, const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
|
||||
int control_event_general_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
int control_event_client_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
int control_event_server_error(const char *format, ...)
|
||||
CHECK_PRINTF(1,2);
|
||||
|
||||
int control_event_guard(const char *nickname, const char *digest,
|
||||
const char *status);
|
||||
int control_event_conf_changed(const smartlist_t *elements);
|
||||
int control_event_buildtimeout_set(buildtimeout_set_event_t type,
|
||||
const char *args);
|
||||
int control_event_signal(uintptr_t signal);
|
||||
|
||||
void control_event_bootstrap(bootstrap_status_t status, int progress);
|
||||
MOCK_DECL(void, control_event_bootstrap_prob_or,(const char *warn,
|
||||
int reason,
|
||||
or_connection_t *or_conn));
|
||||
void control_event_boot_dir(bootstrap_status_t status, int progress);
|
||||
void control_event_boot_first_orconn(void);
|
||||
void control_event_bootstrap_problem(const char *warn, const char *reason,
|
||||
const connection_t *conn, int dowarn);
|
||||
char *control_event_boot_last_msg(void);
|
||||
void control_event_bootstrap_reset(void);
|
||||
|
||||
void control_event_clients_seen(const char *controller_str);
|
||||
void control_event_transport_launched(const char *mode,
|
||||
const char *transport_name,
|
||||
tor_addr_t *addr, uint16_t port);
|
||||
void control_event_pt_log(const char *log);
|
||||
void control_event_pt_status(const char *status);
|
||||
|
||||
void control_event_hs_descriptor_requested(const char *onion_address,
|
||||
rend_auth_type_t auth_type,
|
||||
const char *id_digest,
|
||||
const char *desc_id,
|
||||
const char *hsdir_index);
|
||||
void control_event_hs_descriptor_created(const char *onion_address,
|
||||
const char *desc_id,
|
||||
int replica);
|
||||
void control_event_hs_descriptor_upload(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hs_dir,
|
||||
const char *hsdir_index);
|
||||
void control_event_hs_descriptor_upload_end(const char *action,
|
||||
const char *onion_address,
|
||||
const char *hs_dir,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_uploaded(const char *hs_dir,
|
||||
const char *onion_address);
|
||||
/* Hidden service v2 HS_DESC specific. */
|
||||
void control_event_hsv2_descriptor_failed(const rend_data_t *rend_data,
|
||||
const char *id_digest,
|
||||
const char *reason);
|
||||
void control_event_hsv2_descriptor_received(const char *onion_address,
|
||||
const rend_data_t *rend_data,
|
||||
const char *id_digest);
|
||||
/* Hidden service v3 HS_DESC specific. */
|
||||
void control_event_hsv3_descriptor_failed(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_id_digest,
|
||||
const char *reason);
|
||||
void control_event_hsv3_descriptor_received(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_id_digest);
|
||||
void control_event_hs_descriptor_upload_failed(const char *hs_dir,
|
||||
const char *onion_address,
|
||||
const char *reason);
|
||||
void control_event_hs_descriptor_content(const char *onion_address,
|
||||
const char *desc_id,
|
||||
const char *hsdir_fp,
|
||||
const char *content);
|
||||
|
||||
void control_events_free_all(void);
|
||||
|
||||
#ifdef CONTROL_MODULE_PRIVATE
|
||||
char *get_bw_samples(void);
|
||||
#endif /* defined(CONTROL_MODULE_PRIVATE) */
|
||||
|
||||
#ifdef CONTROL_EVENTS_PRIVATE
|
||||
/** Bitfield: The bit 1<<e is set if <b>any</b> open control
|
||||
* connection is interested in events of type <b>e</b>. We use this
|
||||
* so that we can decide to skip generating event messages that nobody
|
||||
* has interest in without having to walk over the global connection
|
||||
* list to find out.
|
||||
**/
|
||||
typedef uint64_t event_mask_t;
|
||||
|
||||
/* Recognized asynchronous event types. It's okay to expand this list
|
||||
* because it is used both as a list of v0 event types, and as indices
|
||||
* into the bitfield to determine which controllers want which events.
|
||||
*/
|
||||
/* This bitfield has no event zero 0x0000 */
|
||||
#define EVENT_MIN_ 0x0001
|
||||
#define EVENT_CIRCUIT_STATUS 0x0001
|
||||
#define EVENT_STREAM_STATUS 0x0002
|
||||
#define EVENT_OR_CONN_STATUS 0x0003
|
||||
#define EVENT_BANDWIDTH_USED 0x0004
|
||||
#define EVENT_CIRCUIT_STATUS_MINOR 0x0005
|
||||
#define EVENT_NEW_DESC 0x0006
|
||||
#define EVENT_DEBUG_MSG 0x0007
|
||||
#define EVENT_INFO_MSG 0x0008
|
||||
#define EVENT_NOTICE_MSG 0x0009
|
||||
#define EVENT_WARN_MSG 0x000A
|
||||
#define EVENT_ERR_MSG 0x000B
|
||||
#define EVENT_ADDRMAP 0x000C
|
||||
/* There was an AUTHDIR_NEWDESCS event, but it no longer exists. We
|
||||
can reclaim 0x000D. */
|
||||
#define EVENT_DESCCHANGED 0x000E
|
||||
/* Exposed above */
|
||||
// #define EVENT_NS 0x000F
|
||||
#define EVENT_STATUS_CLIENT 0x0010
|
||||
#define EVENT_STATUS_SERVER 0x0011
|
||||
#define EVENT_STATUS_GENERAL 0x0012
|
||||
#define EVENT_GUARD 0x0013
|
||||
#define EVENT_STREAM_BANDWIDTH_USED 0x0014
|
||||
#define EVENT_CLIENTS_SEEN 0x0015
|
||||
#define EVENT_NEWCONSENSUS 0x0016
|
||||
#define EVENT_BUILDTIMEOUT_SET 0x0017
|
||||
#define EVENT_GOT_SIGNAL 0x0018
|
||||
#define EVENT_CONF_CHANGED 0x0019
|
||||
#define EVENT_CONN_BW 0x001A
|
||||
#define EVENT_CELL_STATS 0x001B
|
||||
/* UNUSED : 0x001C */
|
||||
#define EVENT_CIRC_BANDWIDTH_USED 0x001D
|
||||
#define EVENT_TRANSPORT_LAUNCHED 0x0020
|
||||
#define EVENT_HS_DESC 0x0021
|
||||
#define EVENT_HS_DESC_CONTENT 0x0022
|
||||
#define EVENT_NETWORK_LIVENESS 0x0023
|
||||
#define EVENT_PT_LOG 0x0024
|
||||
#define EVENT_PT_STATUS 0x0025
|
||||
#define EVENT_MAX_ 0x0025
|
||||
|
||||
/* sizeof(control_connection_t.event_mask) in bits, currently a uint64_t */
|
||||
#define EVENT_CAPACITY_ 0x0040
|
||||
|
||||
/* If EVENT_MAX_ ever hits 0x0040, we need to make the mask into a
|
||||
* different structure, as it can only handle a maximum left shift of 1<<63. */
|
||||
|
||||
#if EVENT_MAX_ >= EVENT_CAPACITY_
|
||||
#error control_connection_t.event_mask has an event greater than its capacity
|
||||
#endif
|
||||
|
||||
#define EVENT_MASK_(e) (((uint64_t)1)<<(e))
|
||||
|
||||
#define EVENT_MASK_NONE_ ((uint64_t)0x0)
|
||||
|
||||
#define EVENT_MASK_ABOVE_MIN_ ((~((uint64_t)0x0)) << EVENT_MIN_)
|
||||
#define EVENT_MASK_BELOW_MAX_ ((~((uint64_t)0x0)) \
|
||||
>> (EVENT_CAPACITY_ - EVENT_MAX_ \
|
||||
- EVENT_MIN_))
|
||||
|
||||
#define EVENT_MASK_ALL_ (EVENT_MASK_ABOVE_MIN_ \
|
||||
& EVENT_MASK_BELOW_MAX_)
|
||||
|
||||
/** Helper structure: temporarily stores cell statistics for a circuit. */
|
||||
typedef struct cell_stats_t {
|
||||
/** Number of cells added in app-ward direction by command. */
|
||||
uint64_t added_cells_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells added in exit-ward direction by command. */
|
||||
uint64_t added_cells_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells removed in app-ward direction by command. */
|
||||
uint64_t removed_cells_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Number of cells removed in exit-ward direction by command. */
|
||||
uint64_t removed_cells_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Total waiting time of cells in app-ward direction by command. */
|
||||
uint64_t total_time_appward[CELL_COMMAND_MAX_ + 1];
|
||||
/** Total waiting time of cells in exit-ward direction by command. */
|
||||
uint64_t total_time_exitward[CELL_COMMAND_MAX_ + 1];
|
||||
} cell_stats_t;
|
||||
|
||||
void sum_up_cell_stats_by_command(circuit_t *circ,
|
||||
cell_stats_t *cell_stats);
|
||||
void append_cell_stats_by_command(smartlist_t *event_parts,
|
||||
const char *key,
|
||||
const uint64_t *include_if_non_zero,
|
||||
const uint64_t *number_to_include);
|
||||
void format_cell_stats(char **event_string, circuit_t *circ,
|
||||
cell_stats_t *cell_stats);
|
||||
|
||||
/** Helper structure: maps event values to their names. */
|
||||
struct control_event_t {
|
||||
uint16_t event_code;
|
||||
const char *event_name;
|
||||
};
|
||||
|
||||
extern const struct control_event_t control_event_table[];
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
MOCK_DECL(STATIC void,
|
||||
send_control_event_string,(uint16_t event, const char *msg));
|
||||
|
||||
MOCK_DECL(STATIC void,
|
||||
queue_control_event_string,(uint16_t event, char *msg));
|
||||
|
||||
void control_testing_set_global_event_mask(uint64_t mask);
|
||||
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
|
||||
#endif /* defined(CONTROL_EVENTS_PRIVATE) */
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_EVENTS_H) */
|
409
src/feature/control/control_fmt.c
Normal file
409
src/feature/control/control_fmt.c
Normal file
@ -0,0 +1,409 @@
|
||||
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control.c
|
||||
* \brief Formatting functions for controller data.
|
||||
*/
|
||||
|
||||
#include "core/or/or.h"
|
||||
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/circuitbuild.h"
|
||||
#include "core/or/circuitlist.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "feature/control/control_fmt.h"
|
||||
#include "feature/nodelist/nodelist.h"
|
||||
|
||||
#include "core/or/cpath_build_state_st.h"
|
||||
#include "core/or/entry_connection_st.h"
|
||||
#include "core/or/or_connection_st.h"
|
||||
#include "core/or/origin_circuit_st.h"
|
||||
#include "core/or/socks_request_st.h"
|
||||
#include "feature/control/control_connection_st.h"
|
||||
|
||||
/** Append a NUL-terminated string <b>s</b> to the end of
|
||||
* <b>conn</b>-\>outbuf.
|
||||
*/
|
||||
void
|
||||
connection_write_str_to_buf(const char *s, control_connection_t *conn)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
connection_buf_add(s, len, TO_CONN(conn));
|
||||
}
|
||||
|
||||
/** Acts like sprintf, but writes its formatted string to the end of
|
||||
* <b>conn</b>-\>outbuf. */
|
||||
void
|
||||
connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf = NULL;
|
||||
int len;
|
||||
|
||||
va_start(ap,format);
|
||||
len = tor_vasprintf(&buf, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len < 0) {
|
||||
log_err(LD_BUG, "Unable to format string for controller.");
|
||||
tor_assert(0);
|
||||
}
|
||||
|
||||
connection_buf_add(buf, (size_t)len, TO_CONN(conn));
|
||||
|
||||
tor_free(buf);
|
||||
}
|
||||
|
||||
/** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
|
||||
* <b>buf</b>, determine the address:port combination requested on
|
||||
* <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
|
||||
* failure. */
|
||||
int
|
||||
write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
|
||||
{
|
||||
char buf2[256];
|
||||
if (conn->chosen_exit_name)
|
||||
if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
|
||||
return -1;
|
||||
if (!conn->socks_request)
|
||||
return -1;
|
||||
if (tor_snprintf(buf, len, "%s%s%s:%d",
|
||||
conn->socks_request->address,
|
||||
conn->chosen_exit_name ? buf2 : "",
|
||||
!conn->chosen_exit_name && connection_edge_is_rendezvous_stream(
|
||||
ENTRY_TO_EDGE_CONN(conn)) ? ".onion" : "",
|
||||
conn->socks_request->port)<0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Figure out the best name for the target router of an OR connection
|
||||
* <b>conn</b>, and write it into the <b>len</b>-character buffer
|
||||
* <b>name</b>. */
|
||||
void
|
||||
orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
|
||||
{
|
||||
const node_t *node = node_get_by_id(conn->identity_digest);
|
||||
if (node) {
|
||||
tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
|
||||
node_get_verbose_nickname(node, name);
|
||||
} else if (! tor_digest_is_zero(conn->identity_digest)) {
|
||||
name[0] = '$';
|
||||
base16_encode(name+1, len-1, conn->identity_digest,
|
||||
DIGEST_LEN);
|
||||
} else {
|
||||
tor_snprintf(name, len, "%s:%d",
|
||||
conn->base_.address, conn->base_.port);
|
||||
}
|
||||
}
|
||||
|
||||
/** Allocate and return a description of <b>circ</b>'s current status,
|
||||
* including its path (if any). */
|
||||
char *
|
||||
circuit_describe_status_for_controller(origin_circuit_t *circ)
|
||||
{
|
||||
char *rv;
|
||||
smartlist_t *descparts = smartlist_new();
|
||||
|
||||
{
|
||||
char *vpath = circuit_list_path_for_controller(circ);
|
||||
if (*vpath) {
|
||||
smartlist_add(descparts, vpath);
|
||||
} else {
|
||||
tor_free(vpath); /* empty path; don't put an extra space in the result */
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
cpath_build_state_t *build_state = circ->build_state;
|
||||
smartlist_t *flaglist = smartlist_new();
|
||||
char *flaglist_joined;
|
||||
|
||||
if (build_state->onehop_tunnel)
|
||||
smartlist_add(flaglist, (void *)"ONEHOP_TUNNEL");
|
||||
if (build_state->is_internal)
|
||||
smartlist_add(flaglist, (void *)"IS_INTERNAL");
|
||||
if (build_state->need_capacity)
|
||||
smartlist_add(flaglist, (void *)"NEED_CAPACITY");
|
||||
if (build_state->need_uptime)
|
||||
smartlist_add(flaglist, (void *)"NEED_UPTIME");
|
||||
|
||||
/* Only emit a BUILD_FLAGS argument if it will have a non-empty value. */
|
||||
if (smartlist_len(flaglist)) {
|
||||
flaglist_joined = smartlist_join_strings(flaglist, ",", 0, NULL);
|
||||
|
||||
smartlist_add_asprintf(descparts, "BUILD_FLAGS=%s", flaglist_joined);
|
||||
|
||||
tor_free(flaglist_joined);
|
||||
}
|
||||
|
||||
smartlist_free(flaglist);
|
||||
}
|
||||
|
||||
smartlist_add_asprintf(descparts, "PURPOSE=%s",
|
||||
circuit_purpose_to_controller_string(circ->base_.purpose));
|
||||
|
||||
{
|
||||
const char *hs_state =
|
||||
circuit_purpose_to_controller_hs_state_string(circ->base_.purpose);
|
||||
|
||||
if (hs_state != NULL) {
|
||||
smartlist_add_asprintf(descparts, "HS_STATE=%s", hs_state);
|
||||
}
|
||||
}
|
||||
|
||||
if (circ->rend_data != NULL || circ->hs_ident != NULL) {
|
||||
char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
|
||||
const char *onion_address;
|
||||
if (circ->rend_data) {
|
||||
onion_address = rend_data_get_address(circ->rend_data);
|
||||
} else {
|
||||
hs_build_address(&circ->hs_ident->identity_pk, HS_VERSION_THREE, addr);
|
||||
onion_address = addr;
|
||||
}
|
||||
smartlist_add_asprintf(descparts, "REND_QUERY=%s", onion_address);
|
||||
}
|
||||
|
||||
{
|
||||
char tbuf[ISO_TIME_USEC_LEN+1];
|
||||
format_iso_time_nospace_usec(tbuf, &circ->base_.timestamp_created);
|
||||
|
||||
smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf);
|
||||
}
|
||||
|
||||
// Show username and/or password if available.
|
||||
if (circ->socks_username_len > 0) {
|
||||
char* socks_username_escaped = esc_for_log_len(circ->socks_username,
|
||||
(size_t) circ->socks_username_len);
|
||||
smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
|
||||
socks_username_escaped);
|
||||
tor_free(socks_username_escaped);
|
||||
}
|
||||
if (circ->socks_password_len > 0) {
|
||||
char* socks_password_escaped = esc_for_log_len(circ->socks_password,
|
||||
(size_t) circ->socks_password_len);
|
||||
smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
|
||||
socks_password_escaped);
|
||||
tor_free(socks_password_escaped);
|
||||
}
|
||||
|
||||
rv = smartlist_join_strings(descparts, " ", 0, NULL);
|
||||
|
||||
SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
|
||||
smartlist_free(descparts);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
|
||||
* terminated by CRLF, allocate a new string in *<b>out</b>, and copy the
|
||||
* contents of <b>data</b> into *<b>out</b>, adding a period before any period
|
||||
* that appears at the start of a line, and adding a period-CRLF line at
|
||||
* the end. Replace all LF characters sequences with CRLF. Return the number
|
||||
* of bytes in *<b>out</b>.
|
||||
*/
|
||||
size_t
|
||||
write_escaped_data(const char *data, size_t len, char **out)
|
||||
{
|
||||
tor_assert(len < SIZE_MAX - 9);
|
||||
size_t sz_out = len+8+1;
|
||||
char *outp;
|
||||
const char *start = data, *end;
|
||||
size_t i;
|
||||
int start_of_line;
|
||||
for (i=0; i < len; ++i) {
|
||||
if (data[i] == '\n') {
|
||||
sz_out += 2; /* Maybe add a CR; maybe add a dot. */
|
||||
if (sz_out >= SIZE_T_CEILING) {
|
||||
log_warn(LD_BUG, "Input to write_escaped_data was too long");
|
||||
*out = tor_strdup(".\r\n");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
*out = outp = tor_malloc(sz_out);
|
||||
end = data+len;
|
||||
start_of_line = 1;
|
||||
while (data < end) {
|
||||
if (*data == '\n') {
|
||||
if (data > start && data[-1] != '\r')
|
||||
*outp++ = '\r';
|
||||
start_of_line = 1;
|
||||
} else if (*data == '.') {
|
||||
if (start_of_line) {
|
||||
start_of_line = 0;
|
||||
*outp++ = '.';
|
||||
}
|
||||
} else {
|
||||
start_of_line = 0;
|
||||
}
|
||||
*outp++ = *data++;
|
||||
}
|
||||
if (outp < *out+2 || fast_memcmp(outp-2, "\r\n", 2)) {
|
||||
*outp++ = '\r';
|
||||
*outp++ = '\n';
|
||||
}
|
||||
*outp++ = '.';
|
||||
*outp++ = '\r';
|
||||
*outp++ = '\n';
|
||||
*outp = '\0'; /* NUL-terminate just in case. */
|
||||
tor_assert(outp >= *out);
|
||||
tor_assert((size_t)(outp - *out) <= sz_out);
|
||||
return outp - *out;
|
||||
}
|
||||
|
||||
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
|
||||
* terminated by CRLF, allocate a new string in *<b>out</b>, and copy
|
||||
* the contents of <b>data</b> into *<b>out</b>, removing any period
|
||||
* that appears at the start of a line, and replacing all CRLF sequences
|
||||
* with LF. Return the number of
|
||||
* bytes in *<b>out</b>. */
|
||||
size_t
|
||||
read_escaped_data(const char *data, size_t len, char **out)
|
||||
{
|
||||
char *outp;
|
||||
const char *next;
|
||||
const char *end;
|
||||
|
||||
*out = outp = tor_malloc(len+1);
|
||||
|
||||
end = data+len;
|
||||
|
||||
while (data < end) {
|
||||
/* we're at the start of a line. */
|
||||
if (*data == '.')
|
||||
++data;
|
||||
next = memchr(data, '\n', end-data);
|
||||
if (next) {
|
||||
size_t n_to_copy = next-data;
|
||||
/* Don't copy a CR that precedes this LF. */
|
||||
if (n_to_copy && *(next-1) == '\r')
|
||||
--n_to_copy;
|
||||
memcpy(outp, data, n_to_copy);
|
||||
outp += n_to_copy;
|
||||
data = next+1; /* This will point at the start of the next line,
|
||||
* or the end of the string, or a period. */
|
||||
} else {
|
||||
memcpy(outp, data, end-data);
|
||||
outp += (end-data);
|
||||
*outp = '\0';
|
||||
return outp - *out;
|
||||
}
|
||||
*outp++ = '\n';
|
||||
}
|
||||
|
||||
*outp = '\0';
|
||||
return outp - *out;
|
||||
}
|
||||
|
||||
/** Send a "DONE" message down the control connection <b>conn</b>. */
|
||||
void
|
||||
send_control_done(control_connection_t *conn)
|
||||
{
|
||||
connection_write_str_to_buf("250 OK\r\n", conn);
|
||||
}
|
||||
|
||||
/** If the first <b>in_len_max</b> characters in <b>start</b> contain a
|
||||
* double-quoted string with escaped characters, return the length of that
|
||||
* string (as encoded, including quotes). Otherwise return -1. */
|
||||
static inline int
|
||||
get_escaped_string_length(const char *start, size_t in_len_max,
|
||||
int *chars_out)
|
||||
{
|
||||
const char *cp, *end;
|
||||
int chars = 0;
|
||||
|
||||
if (*start != '\"')
|
||||
return -1;
|
||||
|
||||
cp = start+1;
|
||||
end = start+in_len_max;
|
||||
|
||||
/* Calculate length. */
|
||||
while (1) {
|
||||
if (cp >= end) {
|
||||
return -1; /* Too long. */
|
||||
} else if (*cp == '\\') {
|
||||
if (++cp == end)
|
||||
return -1; /* Can't escape EOS. */
|
||||
++cp;
|
||||
++chars;
|
||||
} else if (*cp == '\"') {
|
||||
break;
|
||||
} else {
|
||||
++cp;
|
||||
++chars;
|
||||
}
|
||||
}
|
||||
if (chars_out)
|
||||
*chars_out = chars;
|
||||
return (int)(cp - start+1);
|
||||
}
|
||||
|
||||
/** As decode_escaped_string, but does not decode the string: copies the
|
||||
* entire thing, including quotation marks. */
|
||||
const char *
|
||||
extract_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len)
|
||||
{
|
||||
int length = get_escaped_string_length(start, in_len_max, NULL);
|
||||
if (length<0)
|
||||
return NULL;
|
||||
*out_len = length;
|
||||
*out = tor_strndup(start, *out_len);
|
||||
return start+length;
|
||||
}
|
||||
|
||||
/** Given a pointer to a string starting at <b>start</b> containing
|
||||
* <b>in_len_max</b> characters, decode a string beginning with one double
|
||||
* quote, containing any number of non-quote characters or characters escaped
|
||||
* with a backslash, and ending with a final double quote. Place the resulting
|
||||
* string (unquoted, unescaped) into a newly allocated string in *<b>out</b>;
|
||||
* store its length in <b>out_len</b>. On success, return a pointer to the
|
||||
* character immediately following the escaped string. On failure, return
|
||||
* NULL. */
|
||||
const char *
|
||||
decode_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len)
|
||||
{
|
||||
const char *cp, *end;
|
||||
char *outp;
|
||||
int len, n_chars = 0;
|
||||
|
||||
len = get_escaped_string_length(start, in_len_max, &n_chars);
|
||||
if (len<0)
|
||||
return NULL;
|
||||
|
||||
end = start+len-1; /* Index of last quote. */
|
||||
tor_assert(*end == '\"');
|
||||
outp = *out = tor_malloc(len+1);
|
||||
*out_len = n_chars;
|
||||
|
||||
cp = start+1;
|
||||
while (cp < end) {
|
||||
if (*cp == '\\')
|
||||
++cp;
|
||||
*outp++ = *cp++;
|
||||
}
|
||||
*outp = '\0';
|
||||
tor_assert((outp - *out) == (int)*out_len);
|
||||
|
||||
return end+1;
|
||||
}
|
||||
|
||||
/** Return a longname the node whose identity is <b>id_digest</b>. If
|
||||
* node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is
|
||||
* returned instead.
|
||||
*
|
||||
* This function is not thread-safe. Each call to this function invalidates
|
||||
* previous values returned by this function.
|
||||
*/
|
||||
MOCK_IMPL(const char *,
|
||||
node_describe_longname_by_id,(const char *id_digest))
|
||||
{
|
||||
static char longname[MAX_VERBOSE_NICKNAME_LEN+1];
|
||||
node_get_verbose_nickname_by_id(id_digest, longname);
|
||||
return longname;
|
||||
}
|
36
src/feature/control/control_fmt.h
Normal file
36
src/feature/control/control_fmt.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control_fmt.h
|
||||
* \brief Header file for control_fmt.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CONTROL_FMT_H
|
||||
#define TOR_CONTROL_FMT_H
|
||||
|
||||
void connection_write_str_to_buf(const char *s, control_connection_t *conn);
|
||||
void connection_printf_to_buf(control_connection_t *conn,
|
||||
const char *format, ...)
|
||||
CHECK_PRINTF(2,3);
|
||||
|
||||
int write_stream_target_to_buf(entry_connection_t *conn, char *buf,
|
||||
size_t len);
|
||||
void orconn_target_get_name(char *buf, size_t len,
|
||||
or_connection_t *conn);
|
||||
char *circuit_describe_status_for_controller(origin_circuit_t *circ);
|
||||
|
||||
size_t write_escaped_data(const char *data, size_t len, char **out);
|
||||
size_t read_escaped_data(const char *data, size_t len, char **out);
|
||||
const char *extract_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len);
|
||||
const char *decode_escaped_string(const char *start, size_t in_len_max,
|
||||
char **out, size_t *out_len);
|
||||
void send_control_done(control_connection_t *conn);
|
||||
|
||||
MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest));
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_FMT_H) */
|
1662
src/feature/control/control_getinfo.c
Normal file
1662
src/feature/control/control_getinfo.c
Normal file
File diff suppressed because it is too large
Load Diff
57
src/feature/control/control_getinfo.h
Normal file
57
src/feature/control/control_getinfo.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright (c) 2001 Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file control.h
|
||||
* \brief Header file for control.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_CONTROL_GETINFO_H
|
||||
#define TOR_CONTROL_GETINFO_H
|
||||
|
||||
int handle_control_getinfo(control_connection_t *conn, uint32_t len,
|
||||
const char *body);
|
||||
|
||||
#ifdef CONTROL_GETINFO_PRIVATE
|
||||
STATIC int getinfo_helper_onions(
|
||||
control_connection_t *control_conn,
|
||||
const char *question,
|
||||
char **answer,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_networkstatus(
|
||||
const char *flavor,
|
||||
download_status_t **dl_to_emit,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_cert(
|
||||
const char *fp_sk_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_desc(
|
||||
const char *desc_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC void getinfo_helper_downloads_bridge(
|
||||
const char *bridge_req,
|
||||
download_status_t **dl_to_emit,
|
||||
smartlist_t **digest_list,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_downloads(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_dir(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
STATIC int getinfo_helper_current_time(
|
||||
control_connection_t *control_conn,
|
||||
const char *question, char **answer,
|
||||
const char **errmsg);
|
||||
#endif /* defined(CONTROL_GETINFO_PRIVATE) */
|
||||
|
||||
#endif /* !defined(TOR_CONTROL_GETINFO) */
|
@ -14,7 +14,7 @@
|
||||
#include "core/or/policies.h"
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/authmode.h"
|
||||
#include "feature/dirauth/dirvote.h"
|
||||
#include "feature/dirauth/shared_random.h"
|
||||
|
@ -35,7 +35,7 @@ hibernating, phase 2:
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/defs/time.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
|
@ -7,7 +7,7 @@
|
||||
**/
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_format.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "feature/hs/hs_client.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "app/config/config.h"
|
||||
#include "core/or/policies.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/authmode.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/nodelist/dirlist.h"
|
||||
|
@ -58,7 +58,7 @@
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/reachability.h"
|
||||
#include "feature/dircache/consdiffmgr.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include "core/or/protover.h"
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/process_descs.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
#include "feature/hs/hs_client.h"
|
||||
|
@ -67,7 +67,7 @@
|
||||
#include "core/mainloop/mainloop.h"
|
||||
#include "core/or/policies.h"
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/authmode.h"
|
||||
#include "feature/dirauth/process_descs.h"
|
||||
#include "feature/dirauth/reachability.h"
|
||||
|
@ -59,7 +59,7 @@
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/policies.h"
|
||||
#include "core/or/relay.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/relay/dns.h"
|
||||
#include "feature/relay/router.h"
|
||||
#include "feature/relay/routermode.h"
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "core/or/or.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "app/config/config.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
@ -659,4 +659,3 @@ ext_orport_free_all(void)
|
||||
if (ext_or_auth_cookie) /* Free the auth cookie */
|
||||
tor_free(ext_or_auth_cookie);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "core/or/policies.h"
|
||||
#include "core/or/protover.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirauth/process_descs.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
#include "feature/dirclient/dirclient.h"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#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/control/control_events.h"
|
||||
#include "feature/dirclient/dirclient.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/nodelist/authority_cert_st.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "core/or/connection_edge.h"
|
||||
#include "core/or/relay.h"
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirclient/dirclient.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/hs/hs_circuit.h"
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "core/or/circuitlist.h"
|
||||
#include "core/or/circuituse.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "feature/hs/hs_client.h"
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "core/or/policies.h"
|
||||
#include "core/or/relay.h"
|
||||
#include "feature/client/circpathbias.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dirclient/dirclient.h"
|
||||
#include "feature/dircommon/directory.h"
|
||||
#include "feature/hs/hs_common.h"
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "ht.h"
|
||||
#include "lib/buf/buffers.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/client/dnsserv.h"
|
||||
#include "core/or/dos.h"
|
||||
#include "lib/geoip/geoip.h"
|
||||
|
@ -1,11 +1,14 @@
|
||||
/* Copyright (c) 2015-2019, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_CMD_PRIVATE
|
||||
#define CONTROL_GETINFO_PRIVATE
|
||||
#include "core/or/or.h"
|
||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_cmd.h"
|
||||
#include "feature/control/control_getinfo.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/hs/hs_common.h"
|
||||
#include "feature/nodelist/networkstatus.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define CONNECTION_PRIVATE
|
||||
#define TOR_CHANNEL_INTERNAL_
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_EVENTS_PRIVATE
|
||||
#define OCIRC_EVENT_PRIVATE
|
||||
#define ORCONN_EVENT_PRIVATE
|
||||
#include "core/or/or.h"
|
||||
@ -13,7 +14,7 @@
|
||||
#include "core/or/ocirc_event.h"
|
||||
#include "core/or/orconn_event.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "test/test.h"
|
||||
|
||||
#include "core/or/or_circuit_st.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#define BWAUTH_PRIVATE
|
||||
#define CONFIG_PRIVATE
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_GETINFO_PRIVATE
|
||||
#define DIRCACHE_PRIVATE
|
||||
#define DIRCLIENT_PRIVATE
|
||||
#define DIRSERV_PRIVATE
|
||||
@ -32,7 +32,7 @@
|
||||
#include "core/or/versions.h"
|
||||
#include "feature/client/bridges.h"
|
||||
#include "feature/client/entrynodes.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_getinfo.h"
|
||||
#include "feature/dirauth/bwauth.h"
|
||||
#include "feature/dirauth/dirvote.h"
|
||||
#include "feature/dirauth/dsigs_parse.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/connection_or.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
#include "feature/relay/ext_orport.h"
|
||||
#include "core/mainloop/mainloop.h"
|
||||
|
@ -6,7 +6,7 @@
|
||||
* \brief Unit tests for hidden service.
|
||||
**/
|
||||
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_EVENTS_PRIVATE
|
||||
#define CIRCUITBUILD_PRIVATE
|
||||
#define RENDCOMMON_PRIVATE
|
||||
#define RENDSERVICE_PRIVATE
|
||||
@ -15,6 +15,8 @@
|
||||
#include "core/or/or.h"
|
||||
#include "test/test.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/control/control_fmt.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/hs/hs_common.h"
|
||||
#include "feature/rend/rendcommon.h"
|
||||
|
@ -6,11 +6,13 @@
|
||||
* \brief Unit tests for hidden service control port event and command.
|
||||
**/
|
||||
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_EVENTS_PRIVATE
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "test/test.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/control/control_fmt.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/hs/hs_common.h"
|
||||
#include "feature/hs/hs_control.h"
|
||||
|
@ -7,12 +7,13 @@
|
||||
#define PT_PRIVATE
|
||||
#define UTIL_PRIVATE
|
||||
#define STATEFILE_PRIVATE
|
||||
#define CONTROL_PRIVATE
|
||||
#define CONTROL_EVENTS_PRIVATE
|
||||
#define PROCESS_PRIVATE
|
||||
#include "core/or/or.h"
|
||||
#include "app/config/config.h"
|
||||
#include "app/config/confparse.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "core/or/circuitbuild.h"
|
||||
#include "app/config/statefile.h"
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "orconfig.h"
|
||||
#define COMPAT_PRIVATE
|
||||
#define COMPAT_TIME_PRIVATE
|
||||
#define CONTROL_PRIVATE
|
||||
#define UTIL_PRIVATE
|
||||
#define UTIL_MALLOC_PRIVATE
|
||||
#define SOCKET_PRIVATE
|
||||
@ -16,6 +15,7 @@
|
||||
#include "lib/buf/buffers.h"
|
||||
#include "app/config/config.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_fmt.h"
|
||||
#include "feature/client/transports.h"
|
||||
#include "lib/crypt_ops/crypto_format.h"
|
||||
#include "lib/crypt_ops/crypto_rand.h"
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "orconfig.h"
|
||||
#include "core/or/or.h"
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "app/config/config.h"
|
||||
#include "lib/crypt_ops/crypto_dh.h"
|
||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||
|
Loading…
Reference in New Issue
Block a user