Tor 0.4.9.3-alpha-dev
Loading...
Searching...
No Matches
control_fmt.c
Go to the documentation of this file.
1/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2 * Copyright (c) 2007-2021, 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
14#include "core/or/circuitlist.h"
19
27
28/** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
29 * <b>buf</b>, determine the address:port combination requested on
30 * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
31 * failure. */
32int
34{
35 char buf2[256];
36 if (conn->chosen_exit_name)
37 if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
38 return -1;
39 if (!conn->socks_request)
40 return -1;
41 if (tor_snprintf(buf, len, "%s%s%s:%d",
43 conn->chosen_exit_name ? buf2 : "",
45 ENTRY_TO_EDGE_CONN(conn)) ? ".onion" : "",
46 conn->socks_request->port)<0)
47 return -1;
48 return 0;
49}
50
51/** Figure out the best name for the target router of an OR connection
52 * <b>conn</b>, and write it into the <b>len</b>-character buffer
53 * <b>name</b>. */
54void
56{
57 const node_t *node = node_get_by_id(conn->identity_digest);
58 if (node) {
61 } else if (! tor_digest_is_zero(conn->identity_digest)) {
62 name[0] = '$';
63 base16_encode(name+1, len-1, conn->identity_digest,
65 } else {
66 tor_snprintf(name, len, "%s:%d",
67 conn->base_.address, conn->base_.port);
68 }
69}
70
71/** Allocate and return a description of <b>circ</b>'s current status,
72 * including its path (if any). */
73char *
75{
76 char *rv;
77 smartlist_t *descparts = smartlist_new();
78
79 {
80 char *vpath = circuit_list_path_for_controller(circ);
81 if (*vpath) {
82 smartlist_add(descparts, vpath);
83 } else {
84 tor_free(vpath); /* empty path; don't put an extra space in the result */
85 }
86 }
87
88 {
89 cpath_build_state_t *build_state = circ->build_state;
90 smartlist_t *flaglist = smartlist_new();
91 char *flaglist_joined;
92
93 if (build_state->onehop_tunnel)
94 smartlist_add(flaglist, (void *)"ONEHOP_TUNNEL");
95 if (build_state->is_internal)
96 smartlist_add(flaglist, (void *)"IS_INTERNAL");
97 if (build_state->need_capacity)
98 smartlist_add(flaglist, (void *)"NEED_CAPACITY");
99 if (build_state->need_uptime)
100 smartlist_add(flaglist, (void *)"NEED_UPTIME");
101
102 /* Only emit a BUILD_FLAGS argument if it will have a non-empty value. */
103 if (smartlist_len(flaglist)) {
104 flaglist_joined = smartlist_join_strings(flaglist, ",", 0, NULL);
105
106 smartlist_add_asprintf(descparts, "BUILD_FLAGS=%s", flaglist_joined);
107
108 tor_free(flaglist_joined);
109 }
110
111 smartlist_free(flaglist);
112 }
113
114 smartlist_add_asprintf(descparts, "PURPOSE=%s",
116
117 {
118 const char *hs_state =
120
121 if (hs_state != NULL) {
122 smartlist_add_asprintf(descparts, "HS_STATE=%s", hs_state);
123 }
124 }
125
126 if (circ->hs_ident != NULL) {
127 char addr[HS_SERVICE_ADDR_LEN_BASE32 + 1];
128 const char *onion_address;
130 onion_address = addr;
131 smartlist_add_asprintf(descparts, "REND_QUERY=%s", onion_address);
132 }
133
134 {
135 char tbuf[ISO_TIME_USEC_LEN+1];
137
138 smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf);
139 }
140
141 // Show username and/or password if available.
142 if (circ->socks_username_len > 0) {
143 char* socks_username_escaped = esc_for_log_len(circ->socks_username,
144 (size_t) circ->socks_username_len);
145 smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
146 socks_username_escaped);
147 tor_free(socks_username_escaped);
148 }
149 if (circ->socks_password_len > 0) {
150 char* socks_password_escaped = esc_for_log_len(circ->socks_password,
151 (size_t) circ->socks_password_len);
152 smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
153 socks_password_escaped);
154 tor_free(socks_password_escaped);
155 }
156
157 /* Attach the proof-of-work solution effort, if it's nonzero. Clients set
158 * this to the effort they've chosen, services set this to a value that
159 * was provided by the client and then verified by the service. */
160 if (circ->hs_pow_effort > 0) {
161 smartlist_add_asprintf(descparts, "HS_POW=v1,%u", circ->hs_pow_effort);
162 }
163
164 /* Add conflux id and RTT info, for accurate circuit display. The RTT is
165 * provided to indicate the primary (preferred) circuit of a set
166 * (which will have the lowest current RTT).
167 *
168 * NOTE: Because control port events can happen at arbitrary points, we
169 * must specifically check exactly what we need from the conflux object.
170 * We cannot use CIRCUIT_IS_CONFLUX() because this event may have been
171 * emitted while a set was under partial construction or teardown. */
172 if (TO_CIRCUIT(circ)->conflux || TO_CIRCUIT(circ)->conflux_pending_nonce) {
173 const uint8_t *nonce = conflux_get_nonce(TO_CIRCUIT(circ));
174 tor_assert(nonce);
175
176 /* The conflux nonce is an ephemeral cryptographic secret that if known in
177 * full, enables confirmation or data injection on a set by adding new legs
178 * at an exit from elsewhere. Only output half of it. */
179 smartlist_add_asprintf(descparts, "CONFLUX_ID=%s",
180 hex_str((const char *)nonce, DIGEST256_LEN/2));
181
182 /* If we have a conflux object that is fully linked, the circ has an RTT */
183 if (TO_CIRCUIT(circ)->conflux &&
184 TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED) {
185 uint64_t circ_rtt = conflux_get_circ_rtt(TO_CIRCUIT(circ));
186 if (circ_rtt) {
187 smartlist_add_asprintf(descparts, "CONFLUX_RTT=%" PRIu64, circ_rtt);
188 }
189 }
190 }
191
192 rv = smartlist_join_strings(descparts, " ", 0, NULL);
193
194 SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
195 smartlist_free(descparts);
196
197 return rv;
198}
199
200/** Allocate and return a description of <b>conn</b>'s current status. */
201char *
203{
204 char *rv;
205 smartlist_t *descparts = smartlist_new();
206
207 if (conn->socks_request != NULL) {
208 // Show username and/or password if available; used by IsolateSOCKSAuth.
209 if (conn->socks_request->usernamelen > 0) {
210 char* username_escaped = esc_for_log_len(conn->socks_request->username,
211 (size_t) conn->socks_request->usernamelen);
212 smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s",
213 username_escaped);
214 tor_free(username_escaped);
215 }
216 if (conn->socks_request->passwordlen > 0) {
217 char* password_escaped = esc_for_log_len(conn->socks_request->password,
218 (size_t) conn->socks_request->passwordlen);
219 smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s",
220 password_escaped);
221 tor_free(password_escaped);
222 }
223
224 const char *client_protocol;
225 // Show the client protocol; used by IsolateClientProtocol.
226 switch (conn->socks_request->listener_type)
227 {
229 switch (conn->socks_request->socks_version)
230 {
231 case 4: client_protocol = "SOCKS4"; break;
232 case 5: client_protocol = "SOCKS5"; break;
233 default: client_protocol = "UNKNOWN";
234 }
235 break;
236 case CONN_TYPE_AP_TRANS_LISTENER: client_protocol = "TRANS"; break;
237 case CONN_TYPE_AP_NATD_LISTENER: client_protocol = "NATD"; break;
238 case CONN_TYPE_AP_DNS_LISTENER: client_protocol = "DNS"; break;
240 client_protocol = "HTTPCONNECT"; break;
242 client_protocol = "METRICS"; break;
243 default: client_protocol = "UNKNOWN";
244 }
245 smartlist_add_asprintf(descparts, "CLIENT_PROTOCOL=%s",
246 client_protocol);
247 }
248
249 // Show newnym epoch; used for stream isolation when NEWNYM is used.
250 smartlist_add_asprintf(descparts, "NYM_EPOCH=%u",
251 conn->nym_epoch);
252
253 // Show session group; used for stream isolation of multiple listener ports.
254 smartlist_add_asprintf(descparts, "SESSION_GROUP=%d",
255 conn->entry_cfg.session_group);
256
257 // Show isolation flags.
258 smartlist_t *isoflaglist = smartlist_new();
259 char *isoflaglist_joined;
260 if (conn->entry_cfg.isolation_flags & ISO_DESTPORT) {
261 smartlist_add(isoflaglist, (void *)"DESTPORT");
262 }
263 if (conn->entry_cfg.isolation_flags & ISO_DESTADDR) {
264 smartlist_add(isoflaglist, (void *)"DESTADDR");
265 }
266 if (conn->entry_cfg.isolation_flags & ISO_SOCKSAUTH) {
267 smartlist_add(isoflaglist, (void *)"SOCKS_USERNAME");
268 smartlist_add(isoflaglist, (void *)"SOCKS_PASSWORD");
269 }
270 if (conn->entry_cfg.isolation_flags & ISO_CLIENTPROTO) {
271 smartlist_add(isoflaglist, (void *)"CLIENT_PROTOCOL");
272 }
273 if (conn->entry_cfg.isolation_flags & ISO_CLIENTADDR) {
274 smartlist_add(isoflaglist, (void *)"CLIENTADDR");
275 }
276 if (conn->entry_cfg.isolation_flags & ISO_SESSIONGRP) {
277 smartlist_add(isoflaglist, (void *)"SESSION_GROUP");
278 }
279 if (conn->entry_cfg.isolation_flags & ISO_NYM_EPOCH) {
280 smartlist_add(isoflaglist, (void *)"NYM_EPOCH");
281 }
282 isoflaglist_joined = smartlist_join_strings(isoflaglist, ",", 0, NULL);
283 smartlist_add_asprintf(descparts, "ISO_FIELDS=%s", isoflaglist_joined);
284 tor_free(isoflaglist_joined);
285 smartlist_free(isoflaglist);
286
287 rv = smartlist_join_strings(descparts, " ", 0, NULL);
288
289 SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
290 smartlist_free(descparts);
291
292 return rv;
293}
294
295/** Return a longname the node whose identity is <b>id_digest</b>. If
296 * node_get_by_id() returns NULL, base 16 encoding of <b>id_digest</b> is
297 * returned instead.
298 *
299 * This function is not thread-safe. Each call to this function invalidates
300 * previous values returned by this function.
301 */
302MOCK_IMPL(const char *,
303node_describe_longname_by_id,(const char *id_digest))
304{
305 static char longname[MAX_VERBOSE_NICKNAME_LEN+1];
306 node_get_verbose_nickname_by_id(id_digest, longname);
307 return longname;
308}
const char * hex_str(const char *from, size_t fromlen)
Definition binascii.c:34
void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Definition binascii.c:478
char * circuit_list_path_for_controller(origin_circuit_t *circ)
Header file for circuitbuild.c.
const char * circuit_purpose_to_controller_hs_state_string(uint8_t purpose)
const char * circuit_purpose_to_controller_string(uint8_t purpose)
Header file for circuitlist.c.
const char * name
Definition config.c:2472
const uint8_t * conflux_get_nonce(const circuit_t *circ)
uint64_t conflux_get_circ_rtt(const circuit_t *circ)
Header file for conflux_util.c.
Header file for connection.c.
#define CONN_TYPE_AP_HTTP_CONNECT_LISTENER
Definition connection.h:75
#define CONN_TYPE_METRICS_LISTENER
Definition connection.h:77
#define CONN_TYPE_AP_NATD_LISTENER
Definition connection.h:66
#define CONN_TYPE_AP_LISTENER
Definition connection.h:48
#define CONN_TYPE_AP_DNS_LISTENER
Definition connection.h:68
#define CONN_TYPE_AP_TRANS_LISTENER
Definition connection.h:63
int connection_edge_is_rendezvous_stream(const edge_connection_t *conn)
Header file for connection_edge.c.
Controller connection structure.
char * entry_connection_describe_status_for_controller(const entry_connection_t *conn)
char * circuit_describe_status_for_controller(origin_circuit_t *circ)
Definition control_fmt.c:74
const char * node_describe_longname_by_id(const char *id_digest)
void orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
Definition control_fmt.c:55
int write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
Definition control_fmt.c:33
Header file for control_fmt.c.
Header file for control_proto.c.
Circuit-build-stse structure.
#define DIGEST_LEN
#define DIGEST256_LEN
Entry connection structure.
#define ENTRY_TO_EDGE_CONN(c)
char * esc_for_log_len(const char *chars, size_t n)
Definition escape.c:110
void hs_build_address(const ed25519_public_key_t *key, uint8_t version, char *addr_out)
Definition hs_common.c:901
#define HS_VERSION_THREE
Definition hs_common.h:23
#define HS_SERVICE_ADDR_LEN_BASE32
Definition hs_common.h:73
#define tor_free(p)
Definition malloc.h:56
void node_get_verbose_nickname_by_id(const char *id_digest, char *verbose_name_out)
Definition nodelist.c:1587
const node_t * node_get_by_id(const char *identity_digest)
Definition nodelist.c:226
void node_get_verbose_nickname(const node_t *node, char *verbose_name_out)
Definition nodelist.c:1567
Header file for nodelist.c.
Master header file for Tor-specific functionality.
#define ISO_CLIENTPROTO
Definition or.h:966
#define ISO_DESTADDR
Definition or.h:962
#define ISO_SESSIONGRP
Definition or.h:970
#define TO_CIRCUIT(x)
Definition or.h:951
#define MAX_VERBOSE_NICKNAME_LEN
Definition or.h:118
#define ISO_SOCKSAUTH
Definition or.h:964
#define ISO_DESTPORT
Definition or.h:960
#define ISO_NYM_EPOCH
Definition or.h:972
#define ISO_CLIENTADDR
Definition or.h:968
OR connection structure.
Origin circuit structure.
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition printf.c:27
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition smartlist.c:36
char * smartlist_join_strings(smartlist_t *sl, const char *join, int terminate, size_t *len_out)
Definition smartlist.c:279
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Client request structure.
uint8_t purpose
Definition circuit_st.h:112
struct timeval timestamp_created
Definition circuit_st.h:179
socks_request_t * socks_request
ed25519_public_key_t identity_pk
Definition hs_ident.h:45
char identity_digest[DIGEST_LEN]
struct hs_ident_circuit_t * hs_ident
cpath_build_state_t * build_state
char address[MAX_SOCKS_ADDR_LEN]
#define MOCK_IMPL(rv, funcname, arglist)
void format_iso_time_nospace_usec(char *buf, const struct timeval *tv)
Definition time_fmt.c:354
#define tor_assert(expr)
Definition util_bug.h:103
int tor_digest_is_zero(const char *digest)
Definition util_string.c:98