Merge branch 'tor-github/pr/842'

This commit is contained in:
George Kadianakis 2019-03-26 16:41:07 +02:00
commit 989b6325d6
59 changed files with 7782 additions and 7498 deletions

4
changes/ticket29894 Normal file
View 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.

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 \

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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) */

View 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;
}

View 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) */

View File

@ -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"

File diff suppressed because it is too large Load Diff

View 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) */

File diff suppressed because it is too large Load Diff

View 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&lt;&lt;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) */

View 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;
}

View 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) */

File diff suppressed because it is too large Load Diff

View 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) */

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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);
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"