35#define CONTROL_MODULE_PRIVATE
36#define CONTROL_PRIVATE
99 const int is_owner = !!(flags & CC_LOCAL_FD_IS_OWNER);
100 const int is_authenticated = !!(flags & CC_LOCAL_FD_IS_AUTHENTICATED);
106 conn->
address = tor_strdup(
"<local socket>");
113 connection_add(conn) < 0) {
114 connection_free(conn);
121 connection_mark_for_close(conn);
125 if (is_authenticated) {
149 if (conn->socket_family == AF_UNIX) {
155 } SMARTLIST_FOREACH_END(conn);
166 log_warn(
LD_FS,
"Unable to make %s group-readable.",
173 smartlist_free(lines);
176const struct signal_name_t signal_table[] = {
181 { SIGHUP,
"RELOAD" },
183 { SIGINT,
"SHUTDOWN" },
186 { SIGUSR2,
"DEBUG" },
191 { SIGNEWNYM,
"NEWNYM" },
192 { SIGCLEARDNSCACHE,
"CLEARDNSCACHE"},
193 { SIGHEARTBEAT,
"HEARTBEAT"},
194 { SIGACTIVE,
"ACTIVE" },
195 { SIGDORMANT,
"DORMANT" },
213 log_info(
LD_CONTROL,
"Control connection reached EOF. Closing.");
214 connection_mark_for_close(
TO_CONN(conn));
223 log_notice(
LD_CONTROL,
"Owning controller %s has %s -- exiting now.",
224 owner_type, loss_manner);
226 activate_signal(SIGTERM);
249 } SMARTLIST_FOREACH_END(cp);
264 if (!strcasecmp(cmd,
"PROTOCOLINFO"))
267 if (!strcasecmp(cmd,
"AUTHCHALLENGE"))
269 if (!strcasecmp(cmd,
"AUTHENTICATE") ||
270 !strcasecmp(cmd,
"QUIT"))
278#define MAX_COMMAND_LINE_LENGTH (1024*1024)
305 char **current_cmd_out)
307 const bool is_multiline = *data_len && incoming_cmd[0] ==
'+';
309 while (cmd_len < *data_len
310 && !TOR_ISSPACE(incoming_cmd[cmd_len]))
313 *current_cmd_out = tor_memdup_nulterm(incoming_cmd, cmd_len);
314 char *args = incoming_cmd+cmd_len;
316 *data_len -= cmd_len;
320 while ((*args ==
'\t' || *args ==
' ') && *data_len) {
325 while (TOR_ISSPACE(*args) && *data_len) {
334static const char CONTROLPORT_IS_NOT_AN_HTTP_PROXY_MSG[] =
335 "HTTP/1.0 501 Tor ControlPort is not an HTTP proxy"
336 "\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n"
339 "<title>Tor's ControlPort is not an HTTP proxy</title>\n"
342 "<h1>Tor's ControlPort is not an HTTP proxy</h1>\n"
344 "It appears you have configured your web browser to use Tor's control port"
345 " as an HTTP proxy.\n"
346 "This is not correct: Tor's default SOCKS proxy port is 9050.\n"
347 "Please configure your client accordingly.\n"
350 "See <a href=\"https://www.torproject.org/documentation.html\">"
351 "https://www.torproject.org/documentation.html</a> for more "
353 "<!-- Plus this comment, to make the body response more than 512 bytes, so "
354 " IE will be willing to display it. Comment comment comment comment "
355 " comment comment comment comment comment comment comment comment.-->\n"
369 strlcpy(buf+6,
"The v0 control protocol is not supported by Tor 0.1.2.17 "
370 "and later; upgrade your controller.",
372 body_len = 2+strlen(buf+6)+2;
374 connection_buf_add(buf, 4+body_len,
TO_CONN(conn));
376 connection_mark_and_flush(
TO_CONN(conn));
385 log_notice(
LD_CONTROL,
"Received HTTP request on ControlPort");
386 connection_mark_and_flush(
TO_CONN(conn));
406 peek_connection_has_http_command(
TO_CONN(conn))) {
421 uint32_t cmd_data_len;
455 connection_mark_and_flush(
TO_CONN(conn));
501 if (
TO_CONN(conn)->marked_for_close) {
508 connection_mark_and_flush(
TO_CONN(conn));
515 connection_mark_for_close(
TO_CONN(conn));
519 if (data_len >= UINT32_MAX) {
521 connection_mark_for_close(
TO_CONN(conn));
525 cmd_data_len = (uint32_t)data_len;
539get_cached_network_liveness(
void)
545set_cached_network_liveness(
int liveness)
579 if ((process_spec != NULL) && !strcmp(process_spec,
598 if (process_spec == NULL)
610 log_err(
LD_BUG,
"Couldn't create process-termination monitor for "
611 "owning controller: %s. Exiting.",
622 control_auth_free_all();
623 control_events_free_all();
624 control_cmd_free_all();
void tor_addr_make_unspec(tor_addr_t *a)
static void set_uint16(void *cp, uint16_t v)
struct event_base * tor_libevent_get_base(void)
const or_options_t * get_options(void)
Header file for config.c.
int connection_buf_get_line(connection_t *conn, char *data, size_t *data_len)
int connection_init_accepted_conn(connection_t *conn, const listener_connection_t *listener)
control_connection_t * control_connection_new(int socket_family)
Header file for connection.c.
#define CONN_TYPE_CONTROL_LISTENER
Header file for connection_or.c.
void control_ports_write_to_file(void)
static void control_send_http_reject(control_connection_t *conn)
static int peek_connection_has_control0_command(connection_t *conn)
int control_connection_add_local_fd(tor_socket_t sock, unsigned flags)
#define MAX_COMMAND_LINE_LENGTH
static int is_valid_initial_command(control_connection_t *conn, const char *cmd)
static char * owning_controller_process_spec
control_connection_t * TO_CONTROL_CONN(connection_t *c)
void control_free_all(void)
STATIC char * control_split_incoming_command(char *incoming_cmd, size_t *data_len, char **current_cmd_out)
static void lost_owning_controller(const char *owner_type, const char *loss_manner)
int connection_control_reached_eof(control_connection_t *conn)
void connection_control_closed(control_connection_t *conn)
static void owning_controller_procmon_cb(void *unused)
static tor_process_monitor_t * owning_controller_process_monitor
const control_connection_t * CONST_TO_CONTROL_CONN(const connection_t *c)
void monitor_owning_controller_process(const char *process_spec)
static int network_is_live
int connection_control_finished_flushing(control_connection_t *conn)
static void control_send_v0_reject(control_connection_t *conn)
static bool control_protocol_is_valid(control_connection_t *conn)
int connection_control_process_inbuf(control_connection_t *conn)
Header file for control.c.
#define CONTROL_CONN_STATE_OPEN
#define CONTROL_CONN_STATE_NEEDAUTH
Header file for control_auth.c.
void control_event_bootstrap_reset(void)
int handle_control_command(control_connection_t *conn, uint32_t cmd_data_len, char *args)
Header file for control_cmd.c.
Controller connection structure.
void control_update_global_event_mask(void)
Header file for control_events.c.
void control_write_endreply(control_connection_t *conn, int code, const char *s)
void connection_write_str_to_buf(const char *s, control_connection_t *conn)
Header file for control_proto.c.
int tor_memeq(const void *a, const void *b, size_t sz)
int write_str_to_file(const char *fname, const char *str, int bin)
int hs_address_is_valid(const char *address)
Header file containing common data for the whole HS subsystem.
int hs_service_del_ephemeral(const char *address)
Header file containing service data for the HS subsystem.
void connection_stop_reading(connection_t *conn)
smartlist_t * get_connection_array(void)
void tor_shutdown_event_loop_and_exit(int exitcode)
Header file for mainloop.c.
Master header file for Tor-specific functionality.
#define DOWNCAST(to, ptr)
tor_process_monitor_t * tor_process_monitor_new(struct event_base *base, const char *process_spec, log_domain_mask_t log_domain, tor_procmon_callback_t cb, void *cb_arg, const char **msg)
int peek_buf_has_control0_command(buf_t *buf)
Header for proto_control0.c.
int peek_buf_has_http_command(const buf_t *buf)
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
smartlist_t * smartlist_new(void)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
int set_socket_nonblocking(tor_socket_t sock)
void tor_take_socket_ownership(tor_socket_t s)
smartlist_t * ephemeral_onion_services
char * safecookie_client_hash
unsigned int is_owning_control_connection
uint32_t incoming_cmd_cur_len
uint32_t incoming_cmd_len
unsigned int have_sent_protocolinfo
char * ControlPortWriteToFile
int ControlPortFileGroupReadable
#define tor_fragile_assert()