Tor  0.4.5.0-alpha-dev
control_fmt.c
Go to the documentation of this file.
1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2  * Copyright (c) 2007-2020, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 
5 /**
6  * \file control_fmt.c
7  * \brief Formatting functions for controller data.
8  */
9 
10 #include "core/or/or.h"
11 
13 #include "core/or/circuitbuild.h"
14 #include "core/or/circuitlist.h"
19 
26 
27 /** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
28  * <b>buf</b>, determine the address:port combination requested on
29  * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
30  * failure. */
31 int
32 write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
33 {
34  char buf2[256];
35  if (conn->chosen_exit_name)
36  if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
37  return -1;
38  if (!conn->socks_request)
39  return -1;
40  if (tor_snprintf(buf, len, "%s%s%s:%d",
41  conn->socks_request->address,
42  conn->chosen_exit_name ? buf2 : "",
44  ENTRY_TO_EDGE_CONN(conn)) ? ".onion" : "",
45  conn->socks_request->port)<0)
46  return -1;
47  return 0;
48 }
49 
50 /** Figure out the best name for the target router of an OR connection
51  * <b>conn</b>, and write it into the <b>len</b>-character buffer
52  * <b>name</b>. */
53 void
54 orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
55 {
56  const node_t *node = node_get_by_id(conn->identity_digest);
57  if (node) {
60  } else if (! tor_digest_is_zero(conn->identity_digest)) {
61  name[0] = '$';
62  base16_encode(name+1, len-1, conn->identity_digest,
63  DIGEST_LEN);
64  } else {
65  tor_snprintf(name, len, "%s:%d",
66  conn->base_.address, conn->base_.port);
67  }
68 }
69 
70 /** Allocate and return a description of <b>circ</b>'s current status,
71  * including its path (if any). */
72 char *
74 {
75  char *rv;
76  smartlist_t *descparts = smartlist_new();
77 
78  {
79  char *vpath = circuit_list_path_for_controller(circ);
80  if (*vpath) {
81  smartlist_add(descparts, vpath);
82  } else {
83  tor_free(vpath); /* empty path; don't put an extra space in the result */
84  }
85  }
86 
87  {
88  cpath_build_state_t *build_state = circ->build_state;
89  smartlist_t *flaglist = smartlist_new();
90  char *flaglist_joined;
91 
92  if (build_state->onehop_tunnel)
93  smartlist_add(flaglist, (void *)"ONEHOP_TUNNEL");
94  if (build_state->is_internal)
95  smartlist_add(flaglist, (void *)"IS_INTERNAL");
96  if (build_state->need_capacity)
97  smartlist_add(flaglist, (void *)"NEED_CAPACITY");
98  if (build_state->need_uptime)
99  smartlist_add(flaglist, (void *)"NEED_UPTIME");
100 
101  /* Only emit a BUILD_FLAGS argument if it will have a non-empty value. */
102  if (smartlist_len(flaglist)) {
103  flaglist_joined = smartlist_join_strings(flaglist, ",", 0, NULL);
104 
105  smartlist_add_asprintf(descparts, "BUILD_FLAGS=%s", flaglist_joined);
106 
107  tor_free(flaglist_joined);
108  }
109 
110  smartlist_free(flaglist);
111  }
112 
113  smartlist_add_asprintf(descparts, "PURPOSE=%s",
115 
116  {
117  const char *hs_state =
119 
120  if (hs_state != NULL) {
121  smartlist_add_asprintf(descparts, "HS_STATE=%s", hs_state);
122  }
123  }
124 
125  if (circ->rend_data != NULL || circ->hs_ident != NULL) {
126  char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
127  const char *onion_address;
128  if (circ->rend_data) {
129  onion_address = rend_data_get_address(circ->rend_data);
130  } else {
132  onion_address = addr;
133  }
134  smartlist_add_asprintf(descparts, "REND_QUERY=%s", onion_address);
135  }
136 
137  {
138  char tbuf[ISO_TIME_USEC_LEN+1];
140 
141  smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf);
142  }
143 
144  // Show username and/or password if available.
145  if (circ->socks_username_len > 0) {
146  char* socks_username_escaped = esc_for_log_len(circ->socks_username,
147  (size_t) circ->socks_username_len);
148  smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
149  socks_username_escaped);
150  tor_free(socks_username_escaped);
151  }
152  if (circ->socks_password_len > 0) {
153  char* socks_password_escaped = esc_for_log_len(circ->socks_password,
154  (size_t) circ->socks_password_len);
155  smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
156  socks_password_escaped);
157  tor_free(socks_password_escaped);
158  }
159 
160  rv = smartlist_join_strings(descparts, " ", 0, NULL);
161 
162  SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
163  smartlist_free(descparts);
164 
165  return rv;
166 }
167 
168 /** Allocate and return a description of <b>conn</b>'s current status. */
169 char *
171 {
172  char *rv;
173  smartlist_t *descparts = smartlist_new();
174 
175  if (conn->socks_request != NULL) {
176  // Show username and/or password if available; used by IsolateSOCKSAuth.
177  if (conn->socks_request->usernamelen > 0) {
178  char* username_escaped = esc_for_log_len(conn->socks_request->username,
179  (size_t) conn->socks_request->usernamelen);
180  smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
181  username_escaped);
182  tor_free(username_escaped);
183  }
184  if (conn->socks_request->passwordlen > 0) {
185  char* password_escaped = esc_for_log_len(conn->socks_request->password,
186  (size_t) conn->socks_request->passwordlen);
187  smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
188  password_escaped);
189  tor_free(password_escaped);
190  }
191 
192  const char *client_protocol;
193  // Show the client protocol; used by IsolateClientProtocol.
194  switch (conn->socks_request->listener_type)
195  {
197  switch (conn->socks_request->socks_version)
198  {
199  case 4: client_protocol = "SOCKS4"; break;
200  case 5: client_protocol = "SOCKS5"; break;
201  default: client_protocol = "UNKNOWN";
202  }
203  break;
204  case CONN_TYPE_AP_TRANS_LISTENER: client_protocol = "TRANS"; break;
205  case CONN_TYPE_AP_NATD_LISTENER: client_protocol = "NATD"; break;
206  case CONN_TYPE_AP_DNS_LISTENER: client_protocol = "DNS"; break;
208  client_protocol = "HTTPCONNECT"; break;
209  default: client_protocol = "UNKNOWN";
210  }
211  smartlist_add_asprintf(descparts, "CLIENT_PROTOCOL=%s",
212  client_protocol);
213  }
214 
215  // Show newnym epoch; used for stream isolation when NEWNYM is used.
216  smartlist_add_asprintf(descparts, "NYM_EPOCH=%u",
217  conn->nym_epoch);
218 
219  // Show session group; used for stream isolation of multiple listener ports.
220  smartlist_add_asprintf(descparts, "SESSION_GROUP=%d",
221  conn->entry_cfg.session_group);
222 
223  // Show isolation flags.
224  smartlist_t *isoflaglist = smartlist_new();
225  char *isoflaglist_joined;
226  if (conn->entry_cfg.isolation_flags & ISO_DESTPORT) {
227  smartlist_add(isoflaglist, (void *)"DESTPORT");
228  }
229  if (conn->entry_cfg.isolation_flags & ISO_DESTADDR) {
230  smartlist_add(isoflaglist, (void *)"DESTADDR");
231  }
232  if (conn->entry_cfg.isolation_flags & ISO_SOCKSAUTH) {
233  smartlist_add(isoflaglist, (void *)"SOCKS_USERNAME");
234  smartlist_add(isoflaglist, (void *)"SOCKS_PASSWORD");
235  }
236  if (conn->entry_cfg.isolation_flags & ISO_CLIENTPROTO) {
237  smartlist_add(isoflaglist, (void *)"CLIENT_PROTOCOL");
238  }
239  if (conn->entry_cfg.isolation_flags & ISO_CLIENTADDR) {
240  smartlist_add(isoflaglist, (void *)"CLIENTADDR");
241  }
242  if (conn->entry_cfg.isolation_flags & ISO_SESSIONGRP) {
243  smartlist_add(isoflaglist, (void *)"SESSION_GROUP");
244  }
245  if (conn->entry_cfg.isolation_flags & ISO_NYM_EPOCH) {
246  smartlist_add(isoflaglist, (void *)"NYM_EPOCH");
247  }
248  isoflaglist_joined = smartlist_join_strings(isoflaglist, ",", 0, NULL);
249  smartlist_add_asprintf(descparts, "ISO_FIELDS=%s", isoflaglist_joined);
250  tor_free(isoflaglist_joined);
251  smartlist_free(isoflaglist);
252 
253  rv = smartlist_join_strings(descparts, " ", 0, NULL);
254 
255  SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
256  smartlist_free(descparts);
257 
258  return rv;
259 }
260 
261 /** Return a longname the node whose identity is <b>id_digest</b>. If
262  * node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is
263  * returned instead.
264  *
265  * This function is not thread-safe. Each call to this function invalidates
266  * previous values returned by this function.
267  */
268 MOCK_IMPL(const char *,
269 node_describe_longname_by_id,(const char *id_digest))
270 {
271  static char longname[MAX_VERBOSE_NICKNAME_LEN+1];
272  node_get_verbose_nickname_by_id(id_digest, longname);
273  return longname;
274 }
format_iso_time_nospace_usec
void format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
Definition: time_fmt.c:323
tor_free
#define tor_free(p)
Definition: malloc.h:52
connection_edge.h
Header file for connection_edge.c.
ISO_NYM_EPOCH
#define ISO_NYM_EPOCH
Definition: or.h:986
circuit_t::purpose
uint8_t purpose
Definition: circuit_st.h:111
name
const char * name
Definition: config.c:2443
circuit_describe_status_for_controller
char * circuit_describe_status_for_controller(origin_circuit_t *circ)
Definition: control_fmt.c:73
entry_connection_st.h
Entry connection structure.
connection_t::address
char * address
Definition: connection_st.h:166
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
socks_request_t::password
char * password
Definition: socks_request_st.h:84
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
cpath_build_state_st.h
Circuit-build-stse structure.
hs_ident_circuit_t::identity_pk
ed25519_public_key_t identity_pk
Definition: hs_ident.h:45
esc_for_log_len
char * esc_for_log_len(const char *chars, size_t n)
Definition: escape.c:110
CONN_TYPE_AP_TRANS_LISTENER
#define CONN_TYPE_AP_TRANS_LISTENER
Definition: connection.h:63
base16_encode
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition: binascii.c:478
control_proto.h
Header file for control_proto.c.
cpath_build_state_t::is_internal
unsigned int is_internal
Definition: cpath_build_state_st.h:26
node_get_by_id
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:223
smartlist_add
void smartlist_add(smartlist_t *sl, void *element)
Definition: smartlist_core.c:117
entry_connection_t::nym_epoch
unsigned nym_epoch
Definition: entry_connection_st.h:33
CONN_TYPE_AP_DNS_LISTENER
#define CONN_TYPE_AP_DNS_LISTENER
Definition: connection.h:68
ISO_SESSIONGRP
#define ISO_SESSIONGRP
Definition: or.h:984
hs_build_address
void hs_build_address(const ed25519_public_key_t *key, uint8_t version, char *addr_out)
Definition: hs_common.c:1019
socks_request_t::listener_type
uint8_t listener_type
Definition: socks_request_st.h:49
entry_port_cfg_t::isolation_flags
uint8_t isolation_flags
Definition: entry_port_cfg_st.h:20
smartlist_new
smartlist_t * smartlist_new(void)
Definition: smartlist_core.c:26
socks_request_st.h
Client request structure.
socks_request_t::passwordlen
uint8_t passwordlen
Definition: socks_request_st.h:77
or_connection_t
Definition: or_connection_st.h:22
tor_snprintf
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
connection_t::port
uint16_t port
Definition: connection_st.h:146
SMARTLIST_FOREACH
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Definition: smartlist_foreach.h:112
ISO_CLIENTPROTO
#define ISO_CLIENTPROTO
Definition: or.h:980
ENTRY_TO_EDGE_CONN
#define ENTRY_TO_EDGE_CONN(c)
Definition: entry_connection_st.h:102
circuitlist.h
Header file for circuitlist.c.
node_get_verbose_nickname_by_id
void node_get_verbose_nickname_by_id(const char *id_digest, char *verbose_name_out)
Definition: nodelist.c:1472
DIGEST_LEN
#define DIGEST_LEN
Definition: digest_sizes.h:20
node_describe_longname_by_id
const char * node_describe_longname_by_id(const char *id_digest)
Definition: control_fmt.c:269
MAX_VERBOSE_NICKNAME_LEN
#define MAX_VERBOSE_NICKNAME_LEN
Definition: or.h:118
node_t
Definition: node_st.h:34
origin_circuit_t
Definition: origin_circuit_st.h:79
cpath_build_state_t::onehop_tunnel
unsigned int onehop_tunnel
Definition: cpath_build_state_st.h:32
tor_digest_is_zero
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:96
entry_connection_t::chosen_exit_name
char * chosen_exit_name
Definition: entry_connection_st.h:25
ISO_SOCKSAUTH
#define ISO_SOCKSAUTH
Definition: or.h:978
CONN_TYPE_AP_HTTP_CONNECT_LISTENER
#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER
Definition: connection.h:75
ISO_DESTPORT
#define ISO_DESTPORT
Definition: or.h:974
nodelist.h
Header file for nodelist.c.
circuit_purpose_to_controller_string
const char * circuit_purpose_to_controller_string(uint8_t purpose)
Definition: circuitlist.c:784
node_get_verbose_nickname
void node_get_verbose_nickname(const node_t *node, char *verbose_name_out)
Definition: nodelist.c:1452
circuit_t::timestamp_created
struct timeval timestamp_created
Definition: circuit_st.h:168
circuit_purpose_to_controller_hs_state_string
const char * circuit_purpose_to_controller_hs_state_string(uint8_t purpose)
Definition: circuitlist.c:845
socks_request_t::username
char * username
Definition: socks_request_st.h:81
entry_connection_t::socks_request
socks_request_t * socks_request
Definition: entry_connection_st.h:27
origin_circuit_t::build_state
cpath_build_state_t * build_state
Definition: origin_circuit_st.h:123
circuitbuild.h
Header file for circuitbuild.c.
connection_edge_is_rendezvous_stream
int connection_edge_is_rendezvous_stream(const edge_connection_t *conn)
Definition: connection_edge.c:4412
socks_request_t::socks_version
uint8_t socks_version
Definition: socks_request_st.h:41
cpath_build_state_t::need_capacity
unsigned int need_capacity
Definition: cpath_build_state_st.h:24
connection.h
Header file for connection.c.
cpath_build_state_t::need_uptime
unsigned int need_uptime
Definition: cpath_build_state_st.h:22
or_connection_st.h
OR connection structure.
origin_circuit_t::rend_data
rend_data_t * rend_data
Definition: origin_circuit_st.h:132
HS_VERSION_THREE
#define HS_VERSION_THREE
Definition: hs_common.h:26
entry_connection_describe_status_for_controller
char * entry_connection_describe_status_for_controller(const entry_connection_t *conn)
Definition: control_fmt.c:170
socks_request_t::usernamelen
size_t usernamelen
Definition: socks_request_st.h:75
ISO_CLIENTADDR
#define ISO_CLIENTADDR
Definition: or.h:982
socks_request_t::address
char address[MAX_SOCKS_ADDR_LEN]
Definition: socks_request_st.h:57
rend_data_get_address
const char * rend_data_get_address(const rend_data_t *rend_data)
Definition: hs_common.c:529
cpath_build_state_t
Definition: cpath_build_state_st.h:16
smartlist_add_asprintf
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
origin_circuit_t::hs_ident
struct hs_ident_circuit_t * hs_ident
Definition: origin_circuit_st.h:136
orconn_target_get_name
void orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
Definition: control_fmt.c:54
socks_request_t::port
uint16_t port
Definition: socks_request_st.h:59
CONN_TYPE_AP_LISTENER
#define CONN_TYPE_AP_LISTENER
Definition: connection.h:48
ISO_DESTADDR
#define ISO_DESTADDR
Definition: or.h:976
write_stream_target_to_buf
int write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
Definition: control_fmt.c:32
entry_connection_t
Definition: entry_connection_st.h:19
origin_circuit_st.h
Origin circuit structure.
or_connection_t::identity_digest
char identity_digest[DIGEST_LEN]
Definition: or_connection_st.h:27
smartlist_t
Definition: smartlist_core.h:26
entry_port_cfg_t::session_group
int session_group
Definition: entry_port_cfg_st.h:21
smartlist_join_strings
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition: smartlist.c:279
HS_SERVICE_ADDR_LEN_BASE32
#define HS_SERVICE_ADDR_LEN_BASE32
Definition: hs_common.h:83
control_fmt.h
Header file for control_fmt.c.
CONN_TYPE_AP_NATD_LISTENER
#define CONN_TYPE_AP_NATD_LISTENER
Definition: connection.h:66
control_connection_st.h
Controller connection structure.
or.h
Master header file for Tor-specific functionality.
circuit_list_path_for_controller
char * circuit_list_path_for_controller(origin_circuit_t *circ)
Definition: circuitbuild.c:342