r11629@catbus: nickm | 2007-02-02 15:06:17 -0500
[tor.git] / src / or / control.c
blobb02bbd34e3710fa229674975175728f67a0b0428
1 /* Copyright 2004-2006 Roger Dingledine, Nick Mathewson. */
2 /* See LICENSE for licensing information */
3 /* $Id$ */
4 const char control_c_id[] =
5 "$Id$";
7 /**
8 * \file control.c
9 * \brief Implementation for Tor's control-socket interface.
10 **/
12 #include "or.h"
14 /** DOCDOC */
15 #define STATE_IS_OPEN(s) ((s) == CONTROL_CONN_STATE_OPEN_V0 || \
16 (s) == CONTROL_CONN_STATE_OPEN_V1)
17 /** DOCDOC */
18 #define STATE_IS_V0(s) ((s) == CONTROL_CONN_STATE_NEEDAUTH_V0 || \
19 (s) == CONTROL_CONN_STATE_OPEN_V0)
22 * See control-spec.txt and control-spec-v0.txt for full details on
23 * protocol(s).
27 /* Recognized version 0 message type codes; do not add new codes to this list.
28 * Version 0 is dead; version 1 doesn't use codes. */
29 #define CONTROL0_CMD_ERROR 0x0000
30 #define CONTROL0_CMD_DONE 0x0001
31 #define CONTROL0_CMD_SETCONF 0x0002
32 #define CONTROL0_CMD_GETCONF 0x0003
33 #define CONTROL0_CMD_CONFVALUE 0x0004
34 #define CONTROL0_CMD_SETEVENTS 0x0005
35 #define CONTROL0_CMD_EVENT 0x0006
36 #define CONTROL0_CMD_AUTHENTICATE 0x0007
37 #define CONTROL0_CMD_SAVECONF 0x0008
38 #define CONTROL0_CMD_SIGNAL 0x0009
39 #define CONTROL0_CMD_MAPADDRESS 0x000A
40 #define CONTROL0_CMD_GETINFO 0x000B
41 #define CONTROL0_CMD_INFOVALUE 0x000C
42 #define CONTROL0_CMD_EXTENDCIRCUIT 0x000D
43 #define CONTROL0_CMD_ATTACHSTREAM 0x000E
44 #define CONTROL0_CMD_POSTDESCRIPTOR 0x000F
45 #define CONTROL0_CMD_FRAGMENTHEADER 0x0010
46 #define CONTROL0_CMD_FRAGMENT 0x0011
47 #define CONTROL0_CMD_REDIRECTSTREAM 0x0012
48 #define CONTROL0_CMD_CLOSESTREAM 0x0013
49 #define CONTROL0_CMD_CLOSECIRCUIT 0x0014
50 #define _CONTROL0_CMD_MAX_RECOGNIZED 0x0014
52 /* Recognized version 0 error codes. Do not expand. */
53 #define ERR_UNSPECIFIED 0x0000
54 #define ERR_INTERNAL 0x0001
55 #define ERR_UNRECOGNIZED_TYPE 0x0002
56 #define ERR_SYNTAX 0x0003
57 #define ERR_UNRECOGNIZED_CONFIG_KEY 0x0004
58 #define ERR_INVALID_CONFIG_VALUE 0x0005
59 #define ERR_UNRECOGNIZED_EVENT_CODE 0x0006
60 #define ERR_UNAUTHORIZED 0x0007
61 #define ERR_REJECTED_AUTHENTICATION 0x0008
62 #define ERR_RESOURCE_EXHAUSETED 0x0009
63 #define ERR_NO_STREAM 0x000A
64 #define ERR_NO_CIRC 0x000B
65 #define ERR_NO_ROUTER 0x000C
67 /* Recognized asynchronous event types. It's okay to expand this list
68 * because it is used both as a list of v0 event types, and as indices
69 * into the bitfield to determine which controllers want which events.
71 #define _EVENT_MIN 0x0001
72 #define EVENT_CIRCUIT_STATUS 0x0001
73 #define EVENT_STREAM_STATUS 0x0002
74 #define EVENT_OR_CONN_STATUS 0x0003
75 #define EVENT_BANDWIDTH_USED 0x0004
76 #define EVENT_LOG_OBSOLETE 0x0005
77 #define EVENT_NEW_DESC 0x0006
78 #define EVENT_DEBUG_MSG 0x0007
79 #define EVENT_INFO_MSG 0x0008
80 #define EVENT_NOTICE_MSG 0x0009
81 #define EVENT_WARN_MSG 0x000A
82 #define EVENT_ERR_MSG 0x000B
83 #define LAST_V0_EVENT 0x000B
84 #define EVENT_ADDRMAP 0x000C
85 #define EVENT_AUTHDIR_NEWDESCS 0x000D
86 #define EVENT_DESCCHANGED 0x000E
87 #define EVENT_NS 0x000F
88 #define EVENT_STATUS_CLIENT 0x0010
89 #define EVENT_STATUS_SERVER 0x0011
90 #define EVENT_STATUS_GENERAL 0x0012
91 #define EVENT_GUARD 0x0013
92 #define _EVENT_MAX 0x0013
93 /* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
95 /** Array mapping from message type codes to human-readable message
96 * type names. Used for compatibility with version 0 of the control
97 * protocol. Do not add new items to this list. */
98 static const char * CONTROL0_COMMANDS[_CONTROL0_CMD_MAX_RECOGNIZED+1] = {
99 "error",
100 "done",
101 "setconf",
102 "getconf",
103 "confvalue",
104 "setevents",
105 "events",
106 "authenticate",
107 "saveconf",
108 "signal",
109 "mapaddress",
110 "getinfo",
111 "infovalue",
112 "extendcircuit",
113 "attachstream",
114 "postdescriptor",
115 "fragmentheader",
116 "fragment",
117 "redirectstream",
118 "closestream",
119 "closecircuit",
122 /** Bitfield: The bit 1&lt;&lt;e is set if <b>any</b> open control
123 * connection is interested in events of type <b>e</b>. We use this
124 * so that we can decide to skip generating event messages that nobody
125 * has interest in without having to walk over the global connection
126 * list to find out.
128 static uint32_t global_event_mask0 = 0;
129 static uint32_t global_event_mask1long = 0;
130 static uint32_t global_event_mask1short = 0;
132 /** True iff we have disabled log messages from being sent to the controller */
133 static int disable_log_messages = 0;
135 /** Macro: true if any control connection is interested in events of type
136 * <b>e</b>. */
137 #define EVENT_IS_INTERESTING0(e) (global_event_mask0 & (1<<(e)))
138 #define EVENT_IS_INTERESTING1(e) \
139 ((global_event_mask1long|global_event_mask1short) & (1<<(e)))
140 #define EVENT_IS_INTERESTING1L(e) (global_event_mask1long & (1<<(e)))
141 #define EVENT_IS_INTERESTING1S(e) (global_event_mask1short & (1<<(e)))
142 #define EVENT_IS_INTERESTING(e) \
143 ((global_event_mask0|global_event_mask1short|global_event_mask1long) \
144 & (1<<(e)))
146 /** If we're using cookie-type authentication, how long should our cookies be?
148 #define AUTHENTICATION_COOKIE_LEN 32
150 /** If true, we've set authentication_cookie to a secret code and
151 * stored it to disk. */
152 static int authentication_cookie_is_set = 0;
153 static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
155 #define SHORT_NAMES 1
156 #define LONG_NAMES 2
157 #define ALL_NAMES (SHORT_NAMES|LONG_NAMES)
158 #define EXTENDED_FORMAT 4
159 #define NONEXTENDED_FORMAT 8
160 #define ALL_FORMATS (EXTENDED_FORMAT|NONEXTENDED_FORMAT)
161 typedef int event_format_t;
163 static void connection_printf_to_buf(control_connection_t *conn,
164 const char *format, ...)
165 CHECK_PRINTF(2,3);
166 /*static*/ size_t write_escaped_data(const char *data, size_t len,
167 int translate_newlines, char **out);
168 /*static*/ size_t read_escaped_data(const char *data, size_t len,
169 int translate_newlines, char **out);
170 static void send_control0_message(control_connection_t *conn, uint16_t type,
171 uint32_t len, const char *body);
172 static void send_control_done(control_connection_t *conn);
173 static void send_control_done2(control_connection_t *conn, const char *msg,
174 size_t len);
175 static void send_control0_error(control_connection_t *conn, uint16_t error,
176 const char *message);
177 static void send_control0_event(uint16_t event, uint32_t len,
178 const char *body);
179 static void send_control1_event(uint16_t event, event_format_t which,
180 const char *format, ...)
181 CHECK_PRINTF(3,4);
182 static void send_control1_event_extended(uint16_t event, event_format_t which,
183 const char *format, ...)
184 CHECK_PRINTF(3,4);
185 static int handle_control_setconf(control_connection_t *conn, uint32_t len,
186 char *body);
187 static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
188 char *body);
189 static int handle_control_getconf(control_connection_t *conn, uint32_t len,
190 const char *body);
191 static int handle_control_setevents(control_connection_t *conn, uint32_t len,
192 const char *body);
193 static int handle_control_authenticate(control_connection_t *conn,
194 uint32_t len,
195 const char *body);
196 static int handle_control_saveconf(control_connection_t *conn, uint32_t len,
197 const char *body);
198 static int handle_control_signal(control_connection_t *conn, uint32_t len,
199 const char *body);
200 static int handle_control_mapaddress(control_connection_t *conn, uint32_t len,
201 const char *body);
202 static char *list_getinfo_options(void);
203 static int handle_control_getinfo(control_connection_t *conn, uint32_t len,
204 const char *body);
205 static int handle_control_extendcircuit(control_connection_t *conn,
206 uint32_t len,
207 const char *body);
208 static int handle_control_setpurpose(control_connection_t *conn,
209 int for_circuits,
210 uint32_t len, const char *body);
211 static int handle_control_attachstream(control_connection_t *conn,
212 uint32_t len,
213 const char *body);
214 static int handle_control_postdescriptor(control_connection_t *conn,
215 uint32_t len,
216 const char *body);
217 static int handle_control_redirectstream(control_connection_t *conn,
218 uint32_t len,
219 const char *body);
220 static int handle_control_closestream(control_connection_t *conn, uint32_t len,
221 const char *body);
222 static int handle_control_closecircuit(control_connection_t *conn,
223 uint32_t len,
224 const char *body);
225 static int handle_control_usefeature(control_connection_t *conn,
226 uint32_t len,
227 const char *body);
228 static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
229 size_t len);
230 static void orconn_target_get_name(int long_names, char *buf, size_t len,
231 or_connection_t *conn);
233 /** Given a possibly invalid message type code <b>cmd</b>, return a
234 * human-readable string equivalent. */
235 static INLINE const char *
236 control_cmd_to_string(uint16_t cmd)
238 return (cmd<=_CONTROL0_CMD_MAX_RECOGNIZED) ?
239 CONTROL0_COMMANDS[cmd] : "Unknown";
242 /** Given a control event code for a message event, return the corresponding
243 * log severity. */
244 static INLINE int
245 event_to_log_severity(int event)
247 switch (event) {
248 case EVENT_DEBUG_MSG: return LOG_DEBUG;
249 case EVENT_INFO_MSG: return LOG_INFO;
250 case EVENT_NOTICE_MSG: return LOG_NOTICE;
251 case EVENT_WARN_MSG: return LOG_WARN;
252 case EVENT_ERR_MSG: return LOG_ERR;
253 default: return -1;
257 /** Given a log severity, return the corresponding control event code. */
258 static INLINE int
259 log_severity_to_event(int severity)
261 switch (severity) {
262 case LOG_DEBUG: return EVENT_DEBUG_MSG;
263 case LOG_INFO: return EVENT_INFO_MSG;
264 case LOG_NOTICE: return EVENT_NOTICE_MSG;
265 case LOG_WARN: return EVENT_WARN_MSG;
266 case LOG_ERR: return EVENT_ERR_MSG;
267 default: return -1;
271 /** Set <b>global_event_mask*</b> to the bitwise OR of each live control
272 * connection's event_mask field. */
273 void
274 control_update_global_event_mask(void)
276 connection_t **conns;
277 int n_conns, i;
278 global_event_mask0 = 0;
279 global_event_mask1short = 0;
280 global_event_mask1long = 0;
281 get_connection_array(&conns, &n_conns);
282 for (i = 0; i < n_conns; ++i) {
283 if (conns[i]->type == CONN_TYPE_CONTROL &&
284 STATE_IS_OPEN(conns[i]->state)) {
285 control_connection_t *conn = TO_CONTROL_CONN(conns[i]);
286 if (STATE_IS_V0(conn->_base.state))
287 global_event_mask0 |= conn->event_mask;
288 else if (conn->use_long_names)
289 global_event_mask1long |= conn->event_mask;
290 else
291 global_event_mask1short |= conn->event_mask;
295 control_adjust_event_log_severity();
298 /** Adjust the log severities that result in control_event_logmsg being called
299 * to match the severity of log messages that any controllers are interested
300 * in. */
301 void
302 control_adjust_event_log_severity(void)
304 int i;
305 int min_log_event=EVENT_ERR_MSG, max_log_event=EVENT_DEBUG_MSG;
307 for (i = EVENT_DEBUG_MSG; i <= EVENT_ERR_MSG; ++i) {
308 if (EVENT_IS_INTERESTING(i)) {
309 min_log_event = i;
310 break;
313 for (i = EVENT_ERR_MSG; i >= EVENT_DEBUG_MSG; --i) {
314 if (EVENT_IS_INTERESTING(i)) {
315 max_log_event = i;
316 break;
319 if (EVENT_IS_INTERESTING(EVENT_LOG_OBSOLETE) ||
320 EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL)) {
321 if (min_log_event > EVENT_NOTICE_MSG)
322 min_log_event = EVENT_NOTICE_MSG;
323 if (max_log_event < EVENT_ERR_MSG)
324 max_log_event = EVENT_ERR_MSG;
326 change_callback_log_severity(event_to_log_severity(min_log_event),
327 event_to_log_severity(max_log_event),
328 control_event_logmsg);
331 /** Append a NUL-terminated string <b>s</b> to the end of
332 * <b>conn</b>-\>outbuf
334 static INLINE void
335 connection_write_str_to_buf(const char *s, control_connection_t *conn)
337 size_t len = strlen(s);
338 connection_write_to_buf(s, len, TO_CONN(conn));
341 /** Given a <b>len</b>-character string in <b>data</b>, made of lines
342 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy
343 * the contents of <b>data</b> into *<b>out</b>, adding a period
344 * before any period that that appears at the start of a line, and
345 * adding a period-CRLF line at the end. If <b>translate_newlines</b>
346 * is true, replace all LF characters sequences with CRLF. Return the
347 * number of bytes in *<b>out</b>.
349 /* static */ size_t
350 write_escaped_data(const char *data, size_t len, int translate_newlines,
351 char **out)
353 size_t sz_out = len+8;
354 char *outp;
355 const char *end;
356 int i;
357 int start_of_line;
358 for (i=0; i<(int)len; ++i) {
359 if (data[i]== '\n')
360 sz_out += 2; /* Maybe add a CR; maybe add a dot. */
362 *out = outp = tor_malloc(sz_out+1);
363 end = data+len;
364 start_of_line = 1;
365 while (data < end) {
366 if (*data == '\n') {
367 if (translate_newlines)
368 *outp++ = '\r';
369 start_of_line = 1;
370 } else if (*data == '.') {
371 if (start_of_line) {
372 start_of_line = 0;
373 *outp++ = '.';
375 } else {
376 start_of_line = 0;
378 *outp++ = *data++;
380 if (outp < *out+2 || memcmp(outp-2, "\r\n", 2)) {
381 *outp++ = '\r';
382 *outp++ = '\n';
384 *outp++ = '.';
385 *outp++ = '\r';
386 *outp++ = '\n';
387 *outp = '\0'; /* NUL-terminate just in case. */
388 tor_assert((outp - *out) <= (int)sz_out);
389 return outp - *out;
392 /** Given a <b>len</b>-character string in <b>data</b>, made of lines
393 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy
394 * the contents of <b>data</b> into *<b>out</b>, removing any period
395 * that appears at the start of a line. If <b>translate_newlines</b>
396 * is true, replace all CRLF sequences with LF. Return the number of
397 * bytes in *<b>out</b>. */
398 /*static*/ size_t
399 read_escaped_data(const char *data, size_t len, int translate_newlines,
400 char **out)
402 char *outp;
403 const char *next;
404 const char *end;
406 *out = outp = tor_malloc(len+1);
408 end = data+len;
410 while (data < end) {
411 if (*data == '.')
412 ++data;
413 if (translate_newlines)
414 next = tor_memmem(data, end-data, "\r\n", 2);
415 else
416 next = tor_memmem(data, end-data, "\r\n.", 3);
417 if (next) {
418 memcpy(outp, data, next-data);
419 outp += (next-data);
420 data = next+2;
421 } else {
422 memcpy(outp, data, end-data);
423 outp += (end-data);
424 *outp = '\0';
425 return outp - *out;
427 if (translate_newlines) {
428 *outp++ = '\n';
429 } else {
430 *outp++ = '\r';
431 *outp++ = '\n';
435 *outp = '\0';
436 return outp - *out;
439 /** Given a pointer to a string starting at <b>start</b> containing
440 * <b>in_len_max</b> characters, decode a string beginning with a single
441 * quote, containing any number of non-quote characters or characters escaped
442 * with a backslash, and ending with a final quote. Place the resulting
443 * string (unquoted, unescaped) into a newly allocated string in *<b>out</b>;
444 * store its length in <b>out_len</b>. On success, return a pointer to the
445 * character immediately following the escaped string. On failure, return
446 * NULL. */
447 static const char *
448 get_escaped_string(const char *start, size_t in_len_max,
449 char **out, size_t *out_len)
451 const char *cp, *end;
452 char *outp;
453 size_t len=0;
455 if (*start != '\"')
456 return NULL;
458 cp = start+1;
459 end = start+in_len_max;
461 /* Calculate length. */
462 while (1) {
463 if (cp >= end)
464 return NULL;
465 else if (*cp == '\\') {
466 if (++cp == end)
467 return NULL; /* Can't escape EOS. */
468 ++cp;
469 ++len;
470 } else if (*cp == '\"') {
471 break;
472 } else {
473 ++cp;
474 ++len;
477 end = cp;
478 outp = *out = tor_malloc(len+1);
479 *out_len = len;
481 cp = start+1;
482 while (cp < end) {
483 if (*cp == '\\')
484 ++cp;
485 *outp++ = *cp++;
487 *outp = '\0';
488 tor_assert((outp - *out) == (int)*out_len);
490 return end+1;
493 /** Acts like sprintf, but writes its formatted string to the end of
494 * <b>conn</b>-\>outbuf. The message may be truncated if it is too long,
495 * but it will always end with a CRLF sequence.
497 * Currently the length of the message is limited to 1024 (including the
498 * ending \n\r\0. */
499 static void
500 connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
502 #define CONNECTION_PRINTF_TO_BUF_BUFFERSIZE 1024
503 va_list ap;
504 char buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE];
505 int r;
506 size_t len;
507 va_start(ap,format);
508 r = tor_vsnprintf(buf, sizeof(buf), format, ap);
509 va_end(ap);
510 if (r<0) {
511 log_warn(LD_BUG, "Unable to format string for controller.");
512 return;
514 len = strlen(buf);
515 if (memcmp("\r\n\0", buf+len-2, 3)) {
516 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0';
517 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
518 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
520 connection_write_to_buf(buf, len, TO_CONN(conn));
523 /** Send a message of type <b>type</b> containing <b>len</b> bytes
524 * from <b>body</b> along the control connection <b>conn</b> */
525 static void
526 send_control0_message(control_connection_t *conn, uint16_t type, uint32_t len,
527 const char *body)
529 char buf[10];
530 tor_assert(conn);
531 tor_assert(STATE_IS_V0(conn->_base.state));
532 tor_assert(len || !body);
533 tor_assert(type <= _CONTROL0_CMD_MAX_RECOGNIZED);
534 if (len < 65536) {
535 set_uint16(buf, htons(len));
536 set_uint16(buf+2, htons(type));
537 connection_write_to_buf(buf, 4, TO_CONN(conn));
538 if (len)
539 connection_write_to_buf(body, len, TO_CONN(conn));
540 } else {
541 set_uint16(buf, htons(65535));
542 set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENTHEADER));
543 set_uint16(buf+4, htons(type));
544 set_uint32(buf+6, htonl(len));
545 connection_write_to_buf(buf, 10, TO_CONN(conn));
546 connection_write_to_buf(body, 65535-6, TO_CONN(conn));
547 len -= (65535-6);
548 body += (65535-6);
549 while (len) {
550 size_t chunklen = (len<65535)?len:65535;
551 set_uint16(buf, htons((uint16_t)chunklen));
552 set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENT));
553 connection_write_to_buf(buf, 4, TO_CONN(conn));
554 connection_write_to_buf(body, chunklen, TO_CONN(conn));
555 len -= chunklen;
556 body += chunklen;
561 /** Send a "DONE" message down the control connection <b>conn</b> */
562 static void
563 send_control_done(control_connection_t *conn)
565 if (STATE_IS_V0(conn->_base.state)) {
566 send_control0_message(conn, CONTROL0_CMD_DONE, 0, NULL);
567 } else {
568 connection_write_str_to_buf("250 OK\r\n", conn);
572 /** Send a "DONE" message down the v0 control message <b>conn</b>, with body
573 * as provided in the <b>len</b> bytes at <b>msg</b>.
575 static void
576 send_control_done2(control_connection_t *conn, const char *msg, size_t len)
578 if (len==0)
579 len = strlen(msg);
580 send_control0_message(conn, CONTROL0_CMD_DONE, len, msg);
583 /** Send an error message with error code <b>error</b> and body
584 * <b>message</b> down the connection <b>conn</b> */
585 static void
586 send_control0_error(control_connection_t *conn, uint16_t error,
587 const char *message)
589 char buf[256];
590 size_t len;
591 set_uint16(buf, htons(error));
592 len = strlen(message);
593 tor_assert(len < (256-2));
594 memcpy(buf+2, message, len);
595 send_control0_message(conn, CONTROL0_CMD_ERROR, (uint16_t)(len+2), buf);
598 /** Send an 'event' message of event type <b>event</b>, containing
599 * <b>len</b> bytes in <b>body</b> to every control connection that
600 * is interested in it. */
601 static void
602 send_control0_event(uint16_t event, uint32_t len, const char *body)
604 connection_t **conns;
605 int n_conns, i;
606 size_t buflen;
607 char *buf;
609 tor_assert(event >= _EVENT_MIN && event <= LAST_V0_EVENT);
611 buflen = len + 2;
612 buf = tor_malloc_zero(buflen);
613 set_uint16(buf, htons(event));
614 memcpy(buf+2, body, len);
616 get_connection_array(&conns, &n_conns);
617 for (i = 0; i < n_conns; ++i) {
618 if (conns[i]->type == CONN_TYPE_CONTROL &&
619 !conns[i]->marked_for_close &&
620 conns[i]->state == CONTROL_CONN_STATE_OPEN_V0) {
621 control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
622 if (control_conn->event_mask & (1<<event)) {
623 send_control0_message(control_conn, CONTROL0_CMD_EVENT, buflen, buf);
624 if (event == EVENT_ERR_MSG)
625 connection_handle_write(TO_CONN(control_conn), 1);
630 tor_free(buf);
633 /* Send an event to all v1 controllers that are listening for code
634 * <b>event</b>. The event's body is given by <b>msg</b>.
636 * If <b>which</b> & SHORT_NAMES, the event contains short-format names: send
637 * it to controllers that haven't enabled the VERBOSE_NAMES feature. If
638 * <b>which</b> & LONG_NAMES, the event contains long-format names: sent it
639 * to contollers that <em>have</em> enabled VERBOSE_NAMES.
641 * The EXTENDED_FORMAT and NONEXTENDED_FORMAT flags behaves similarly with
642 * respect to the EXTENDED_EVENTS feature. */
643 static void
644 send_control1_event_string(uint16_t event, event_format_t which,
645 const char *msg)
647 connection_t **conns;
648 int n_conns, i;
650 tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
652 get_connection_array(&conns, &n_conns);
653 for (i = 0; i < n_conns; ++i) {
654 if (conns[i]->type == CONN_TYPE_CONTROL &&
655 !conns[i]->marked_for_close &&
656 conns[i]->state == CONTROL_CONN_STATE_OPEN_V1) {
657 control_connection_t *control_conn = TO_CONTROL_CONN(conns[i]);
658 if (control_conn->use_long_names) {
659 if (!(which & LONG_NAMES))
660 continue;
661 } else {
662 if (!(which & SHORT_NAMES))
663 continue;
665 if (control_conn->use_extended_events) {
666 if (!(which & EXTENDED_FORMAT))
667 continue;
668 } else {
669 if (!(which & NONEXTENDED_FORMAT))
670 continue;
672 if (control_conn->event_mask & (1<<event)) {
673 int is_err = 0;
674 connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
675 if (event == EVENT_ERR_MSG)
676 is_err = 1;
677 else if (event == EVENT_STATUS_GENERAL)
678 is_err = !strcmpstart(msg, "STATUS_GENERAL ERR ");
679 else if (event == EVENT_STATUS_CLIENT)
680 is_err = !strcmpstart(msg, "STATUS_CLIENT ERR ");
681 else if (event == EVENT_STATUS_SERVER)
682 is_err = !strcmpstart(msg, "STATUS_SERVER ERR ");
683 if (is_err)
684 connection_handle_write(TO_CONN(control_conn), 1);
690 /** DOCDOC */
691 static void
692 send_control1_event_impl(uint16_t event, event_format_t which, int extended,
693 const char *format, va_list ap)
695 #define SEND_CONTROL1_EVENT_BUFFERSIZE 1024
696 int r;
697 char buf[SEND_CONTROL1_EVENT_BUFFERSIZE]; /* XXXX Length */
698 size_t len;
699 char *cp;
701 r = tor_vsnprintf(buf, sizeof(buf), format, ap);
702 if (r<0) {
703 log_warn(LD_BUG, "Unable to format event for controller.");
704 return;
707 len = strlen(buf);
708 if (memcmp("\r\n\0", buf+len-2, 3)) {
709 /* if it is not properly terminated, do it now */
710 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0';
711 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n';
712 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
715 if (extended && (cp = strchr(buf, '@'))) {
716 which &= ~ALL_FORMATS;
717 *cp = ' ';
718 send_control1_event_string(event, which|EXTENDED_FORMAT, buf);
719 memcpy(cp, "\r\n\0", 3);
720 send_control1_event_string(event, which|NONEXTENDED_FORMAT, buf);
721 } else {
722 send_control1_event_string(event, which|ALL_FORMATS, buf);
726 /* Send an event to all v1 controllers that are listening for code
727 * <b>event</b>. The event's body is created by the printf-style format in
728 * <b>format</b>, and other arguments as provided.
730 * Currently the length of the message is limited to 1024 (including the
731 * ending \n\r\0. */
732 static void
733 send_control1_event(uint16_t event, event_format_t which,
734 const char *format, ...)
736 va_list ap;
737 va_start(ap, format);
738 send_control1_event_impl(event, which, 0, format, ap);
739 va_end(ap);
742 /* Send an event to all v1 controllers that are listening for code
743 * <b>event</b>. The event's body is created by the printf-style format in
744 * <b>format</b>, and other arguments as provided.
746 * If the format contains a single '@' character, it will be replaced with a
747 * space and all text after that character will be sent only to controllers
748 * that have enabled extended events.
750 * Currently the length of the message is limited to 1024 (including the
751 * ending \n\r\0. */
752 static void
753 send_control1_event_extended(uint16_t event, event_format_t which,
754 const char *format, ...)
756 va_list ap;
757 va_start(ap, format);
758 send_control1_event_impl(event, which, 1, format, ap);
759 va_end(ap);
762 /** Given a text circuit <b>id</b>, return the corresponding circuit. */
763 static origin_circuit_t *
764 get_circ(const char *id)
766 unsigned long n_id;
767 int ok;
768 n_id = tor_parse_ulong(id, 10, 0, ULONG_MAX, &ok, NULL);
769 if (!ok)
770 return NULL;
771 return circuit_get_by_global_id(n_id);
774 /** Given a text stream <b>id</b>, return the corresponding AP connection. */
775 static edge_connection_t *
776 get_stream(const char *id)
778 unsigned long n_id;
779 int ok;
780 edge_connection_t *conn;
781 n_id = tor_parse_ulong(id, 10, 0, ULONG_MAX, &ok, NULL);
782 if (!ok)
783 return NULL;
784 conn = connection_get_by_global_id(n_id);
785 if (!conn || conn->_base.type != CONN_TYPE_AP)
786 return NULL;
787 return conn;
790 /** Helper for setconf and resetconf. Acts like setconf, except
791 * it passes <b>use_defaults</b> on to options_trial_assign(). Modifies the
792 * contents of body.
794 static int
795 control_setconf_helper(control_connection_t *conn, uint32_t len, char *body,
796 int use_defaults, int clear_first)
798 int r;
799 config_line_t *lines=NULL;
800 char *start = body;
801 char *errstring = NULL;
802 int v0 = STATE_IS_V0(conn->_base.state);
804 if (!v0) {
805 char *config = tor_malloc(len+1);
806 char *outp = config;
807 while (*body) {
808 char *eq = body;
809 while (!TOR_ISSPACE(*eq) && *eq != '=')
810 ++eq;
811 memcpy(outp, body, eq-body);
812 outp += (eq-body);
813 *outp++ = ' ';
814 body = eq+1;
815 if (*eq == '=') {
816 if (*body != '\"') {
817 while (!TOR_ISSPACE(*body))
818 *outp++ = *body++;
819 } else {
820 char *val;
821 size_t val_len;
822 body = (char*)get_escaped_string(body, (len - (body-start)),
823 &val, &val_len);
824 if (!body) {
825 connection_write_str_to_buf("551 Couldn't parse string\r\n", conn);
826 tor_free(config);
827 return 0;
829 memcpy(outp, val, val_len);
830 outp += val_len;
831 tor_free(val);
834 while (TOR_ISSPACE(*body))
835 ++body;
836 *outp++ = '\n';
838 *outp = '\0';
840 if (config_get_lines(config, &lines) < 0) {
841 log_warn(LD_CONTROL,"Controller gave us config lines we can't parse.");
842 connection_write_str_to_buf("551 Couldn't parse configuration\r\n",
843 conn);
844 tor_free(config);
845 return 0;
847 tor_free(config);
848 } else {
849 if (config_get_lines(body, &lines) < 0) {
850 log_warn(LD_CONTROL,
851 "V0 controller gave us config lines we can't parse.");
852 send_control0_error(conn, ERR_SYNTAX, "Couldn't parse configuration");
853 return 0;
857 if ((r=options_trial_assign(lines, use_defaults,
858 clear_first, &errstring)) < 0) {
859 int v0_err;
860 const char *msg;
861 log_warn(LD_CONTROL,
862 "Controller gave us config lines that didn't validate: %s.",
863 errstring);
864 switch (r) {
865 case -1:
866 v0_err = ERR_UNRECOGNIZED_CONFIG_KEY;
867 msg = "552 Unrecognized option";
868 break;
869 case -2:
870 v0_err = ERR_INVALID_CONFIG_VALUE;
871 msg = "513 Unacceptable option value";
872 break;
873 case -3:
874 v0_err = ERR_INVALID_CONFIG_VALUE;
875 msg = "553 Transition not allowed";
876 break;
877 case -4:
878 default:
879 v0_err = ERR_INVALID_CONFIG_VALUE;
880 msg = "553 Unable to set option";
881 break;
883 if (v0) {
884 send_control0_error(conn, v0_err, msg);
885 } else {
886 connection_printf_to_buf(conn, "%s: %s\r\n", msg, errstring);
888 config_free_lines(lines);
889 tor_free(errstring);
890 return 0;
892 config_free_lines(lines);
893 send_control_done(conn);
894 return 0;
897 /** Called when we receive a SETCONF message: parse the body and try
898 * to update our configuration. Reply with a DONE or ERROR message.
899 * Modifies the contents of body.*/
900 static int
901 handle_control_setconf(control_connection_t *conn, uint32_t len, char *body)
903 return control_setconf_helper(conn, len, body, 0, 1);
906 /** Called when we receive a RESETCONF message: parse the body and try
907 * to update our configuration. Reply with a DONE or ERROR message.
908 * Modifies the contents of body. */
909 static int
910 handle_control_resetconf(control_connection_t *conn, uint32_t len, char *body)
912 int v0 = STATE_IS_V0(conn->_base.state);
913 tor_assert(!v0);
914 return control_setconf_helper(conn, len, body, 1, 1);
917 /** Called when we receive a GETCONF message. Parse the request, and
918 * reply with a CONFVALUE or an ERROR message */
919 static int
920 handle_control_getconf(control_connection_t *conn, uint32_t body_len,
921 const char *body)
923 smartlist_t *questions = NULL;
924 smartlist_t *answers = NULL;
925 smartlist_t *unrecognized = NULL;
926 char *msg = NULL;
927 size_t msg_len;
928 or_options_t *options = get_options();
929 int v0 = STATE_IS_V0(conn->_base.state);
931 questions = smartlist_create();
932 (void) body_len; /* body is nul-terminated; so we can ignore len. */
933 if (v0) {
934 smartlist_split_string(questions, body, "\n",
935 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
936 } else {
937 smartlist_split_string(questions, body, " ",
938 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
940 answers = smartlist_create();
941 unrecognized = smartlist_create();
942 SMARTLIST_FOREACH(questions, char *, q,
944 if (!option_is_recognized(q)) {
945 if (v0) {
946 send_control0_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, q);
947 goto done;
948 } else {
949 smartlist_add(unrecognized, q);
951 } else {
952 config_line_t *answer = option_get_assignment(options,q);
953 if (!v0 && !answer) {
954 const char *name = option_get_canonical_name(q);
955 size_t alen = strlen(name)+8;
956 char *astr = tor_malloc(alen);
957 tor_snprintf(astr, alen, "250-%s\r\n", name);
958 smartlist_add(answers, astr);
961 while (answer) {
962 config_line_t *next;
963 size_t alen = strlen(answer->key)+strlen(answer->value)+8;
964 char *astr = tor_malloc(alen);
965 if (v0)
966 tor_snprintf(astr, alen, "%s %s\n", answer->key, answer->value);
967 else
968 tor_snprintf(astr, alen, "250-%s=%s\r\n",
969 answer->key, answer->value);
970 smartlist_add(answers, astr);
972 next = answer->next;
973 tor_free(answer->key);
974 tor_free(answer->value);
975 tor_free(answer);
976 answer = next;
981 if (v0) {
982 msg = smartlist_join_strings(answers, "", 0, &msg_len);
983 send_control0_message(conn, CONTROL0_CMD_CONFVALUE,
984 (uint16_t)msg_len, msg_len?msg:NULL);
985 } else {
986 int i,len;
987 if ((len = smartlist_len(unrecognized))) {
988 for (i=0; i < len-1; ++i)
989 connection_printf_to_buf(conn,
990 "552-Unrecognized configuration key \"%s\"\r\n",
991 (char*)smartlist_get(unrecognized, i));
992 connection_printf_to_buf(conn,
993 "552 Unrecognized configuration key \"%s\"\r\n",
994 (char*)smartlist_get(unrecognized, len-1));
995 } else if ((len = smartlist_len(answers))) {
996 char *tmp = smartlist_get(answers, len-1);
997 tor_assert(strlen(tmp)>4);
998 tmp[3] = ' ';
999 msg = smartlist_join_strings(answers, "", 0, &msg_len);
1000 connection_write_to_buf(msg, msg_len, TO_CONN(conn));
1001 } else {
1002 connection_write_str_to_buf("250 OK\r\n", conn);
1006 done:
1007 if (answers) {
1008 SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
1009 smartlist_free(answers);
1011 if (questions) {
1012 SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
1013 smartlist_free(questions);
1015 smartlist_free(unrecognized);
1016 tor_free(msg);
1018 return 0;
1021 /** Called when we get a SETEVENTS message: update conn->event_mask,
1022 * and reply with DONE or ERROR. */
1023 static int
1024 handle_control_setevents(control_connection_t *conn, uint32_t len,
1025 const char *body)
1027 uint16_t event_code;
1028 uint32_t event_mask = 0;
1029 unsigned int extended = 0;
1031 if (STATE_IS_V0(conn->_base.state)) {
1032 if (len % 2) {
1033 send_control0_error(conn, ERR_SYNTAX,
1034 "Odd number of bytes in setevents message");
1035 return 0;
1038 for (; len; len -= 2, body += 2) {
1039 event_code = ntohs(get_uint16(body));
1040 if (event_code < _EVENT_MIN || event_code > LAST_V0_EVENT) {
1041 send_control0_error(conn, ERR_UNRECOGNIZED_EVENT_CODE,
1042 "Unrecognized event code");
1043 return 0;
1045 event_mask |= (1 << event_code);
1047 } else {
1048 smartlist_t *events = smartlist_create();
1049 smartlist_split_string(events, body, " ",
1050 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1051 SMARTLIST_FOREACH(events, const char *, ev,
1053 if (!strcasecmp(ev, "EXTENDED")) {
1054 extended = 1;
1055 continue;
1056 } else if (!strcasecmp(ev, "CIRC"))
1057 event_code = EVENT_CIRCUIT_STATUS;
1058 else if (!strcasecmp(ev, "STREAM"))
1059 event_code = EVENT_STREAM_STATUS;
1060 else if (!strcasecmp(ev, "ORCONN"))
1061 event_code = EVENT_OR_CONN_STATUS;
1062 else if (!strcasecmp(ev, "BW"))
1063 event_code = EVENT_BANDWIDTH_USED;
1064 else if (!strcasecmp(ev, "DEBUG"))
1065 event_code = EVENT_DEBUG_MSG;
1066 else if (!strcasecmp(ev, "INFO"))
1067 event_code = EVENT_INFO_MSG;
1068 else if (!strcasecmp(ev, "NOTICE"))
1069 event_code = EVENT_NOTICE_MSG;
1070 else if (!strcasecmp(ev, "WARN"))
1071 event_code = EVENT_WARN_MSG;
1072 else if (!strcasecmp(ev, "ERR"))
1073 event_code = EVENT_ERR_MSG;
1074 else if (!strcasecmp(ev, "NEWDESC"))
1075 event_code = EVENT_NEW_DESC;
1076 else if (!strcasecmp(ev, "ADDRMAP"))
1077 event_code = EVENT_ADDRMAP;
1078 else if (!strcasecmp(ev, "AUTHDIR_NEWDESCS"))
1079 event_code = EVENT_AUTHDIR_NEWDESCS;
1080 else if (!strcasecmp(ev, "DESCCHANGED"))
1081 event_code = EVENT_DESCCHANGED;
1082 else if (!strcasecmp(ev, "NS"))
1083 event_code = EVENT_NS;
1084 else if (!strcasecmp(ev, "STATUS_GENERAL"))
1085 event_code = EVENT_STATUS_GENERAL;
1086 else if (!strcasecmp(ev, "STATUS_CLIENT"))
1087 event_code = EVENT_STATUS_CLIENT;
1088 else if (!strcasecmp(ev, "STATUS_SERVER"))
1089 event_code = EVENT_STATUS_SERVER;
1090 else if (!strcasecmp(ev, "GUARD"))
1091 event_code = EVENT_GUARD;
1092 else {
1093 connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
1094 ev);
1095 SMARTLIST_FOREACH(events, char *, e, tor_free(e));
1096 smartlist_free(events);
1097 return 0;
1099 event_mask |= (1 << event_code);
1101 SMARTLIST_FOREACH(events, char *, e, tor_free(e));
1102 smartlist_free(events);
1104 conn->event_mask = event_mask;
1105 if (extended)
1106 conn->use_extended_events = 1;
1108 control_update_global_event_mask();
1109 send_control_done(conn);
1110 return 0;
1113 /** Decode the hashed, base64'd password stored in <b>hashed</b>. If
1114 * <b>buf</b> is provided, store the hashed password in the first
1115 * S2K_SPECIFIER_LEN+DIGEST_LEN bytes of <b>buf</b>. Return 0 on
1116 * success, -1 on failure.
1119 decode_hashed_password(char *buf, const char *hashed)
1121 char decoded[64];
1122 if (!strcmpstart(hashed, "16:")) {
1123 if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))<0
1124 || strlen(hashed+3) != (S2K_SPECIFIER_LEN+DIGEST_LEN)*2) {
1125 return -1;
1127 } else {
1128 if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
1129 != S2K_SPECIFIER_LEN+DIGEST_LEN) {
1130 return -1;
1133 if (buf)
1134 memcpy(buf, decoded, S2K_SPECIFIER_LEN+DIGEST_LEN);
1135 return 0;
1138 /** Called when we get an AUTHENTICATE message. Check whether the
1139 * authentication is valid, and if so, update the connection's state to
1140 * OPEN. Reply with DONE or ERROR.
1142 static int
1143 handle_control_authenticate(control_connection_t *conn, uint32_t len,
1144 const char *body)
1146 int used_quoted_string = 0;
1147 or_options_t *options = get_options();
1148 const char *errstr = NULL;
1149 char *password;
1150 size_t password_len;
1151 if (STATE_IS_V0(conn->_base.state)) {
1152 password = (char*)body;
1153 password_len = len;
1154 } else {
1155 if (TOR_ISXDIGIT(body[0])) {
1156 int i = 0;
1157 while (TOR_ISXDIGIT(body[i]))
1158 ++i;
1159 password = tor_malloc(i/2 + 1);
1160 if (base16_decode(password, i/2+1, body, i)<0) {
1161 connection_write_str_to_buf(
1162 "551 Invalid hexadecimal encoding. Maybe you tried a plain text "
1163 "password? If so, the standard requires that you put it in "
1164 "double quotes.\r\n", conn);
1165 tor_free(password);
1166 return 0;
1168 password_len = i/2;
1169 } else if (TOR_ISSPACE(body[0])) {
1170 password = tor_strdup("");
1171 password_len = 0;
1172 } else {
1173 if (!get_escaped_string(body, len, &password, &password_len)) {
1174 connection_write_str_to_buf("551 Invalid quoted string. You need "
1175 "to put the password in double quotes.\r\n", conn);
1176 return 0;
1178 used_quoted_string = 1;
1181 if (options->CookieAuthentication && authentication_cookie_is_set) {
1182 if (password_len != AUTHENTICATION_COOKIE_LEN) {
1183 log_warn(LD_CONTROL, "Got authentication cookie with wrong length (%d)",
1184 (int)password_len);
1185 errstr = "Wrong length on authentication cookie.";
1186 goto err;
1187 } else if (memcmp(authentication_cookie, password, password_len)) {
1188 log_warn(LD_CONTROL, "Got mismatched authentication cookie");
1189 errstr = "Authentication cookie did not match expected value.";
1190 goto err;
1191 } else {
1192 goto ok;
1194 } else if (options->HashedControlPassword) {
1195 char expected[S2K_SPECIFIER_LEN+DIGEST_LEN];
1196 char received[DIGEST_LEN];
1197 if (decode_hashed_password(expected, options->HashedControlPassword)<0) {
1198 log_warn(LD_CONTROL,
1199 "Couldn't decode HashedControlPassword: invalid base16");
1200 errstr = "Couldn't decode HashedControlPassword value in configuration.";
1201 goto err;
1203 secret_to_key(received,DIGEST_LEN,password,password_len,expected);
1204 if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
1205 goto ok;
1207 if (used_quoted_string)
1208 errstr = "Password did not match HashedControlPassword value from "
1209 "configuration";
1210 else
1211 errstr = "Password did not match HashedControlPassword value from "
1212 "configuration. Maybe you tried a plain text password? "
1213 "If so, the standard requires that you put it in double quotes.";
1214 goto err;
1215 } else {
1216 /* if Tor doesn't demand any stronger authentication, then
1217 * the controller can get in with anything. */
1218 goto ok;
1221 err:
1222 if (STATE_IS_V0(conn->_base.state))
1223 send_control0_error(conn,ERR_REJECTED_AUTHENTICATION,
1224 "Authentication failed");
1225 else {
1226 tor_free(password);
1227 if (!errstr)
1228 errstr = "Unknown reason.";
1229 connection_printf_to_buf(conn, "515 Authentication failed: %s\r\n",
1230 errstr);
1232 return 0;
1234 log_info(LD_CONTROL, "Authenticated control connection (%d)", conn->_base.s);
1235 send_control_done(conn);
1236 if (STATE_IS_V0(conn->_base.state))
1237 conn->_base.state = CONTROL_CONN_STATE_OPEN_V0;
1238 else {
1239 conn->_base.state = CONTROL_CONN_STATE_OPEN_V1;
1240 tor_free(password);
1242 return 0;
1245 /** Called when we get a SAVECONF command. Try to flush the current options to
1246 * disk, and report success or failure. */
1247 static int
1248 handle_control_saveconf(control_connection_t *conn, uint32_t len,
1249 const char *body)
1251 (void) len;
1252 (void) body;
1253 if (options_save_current()<0) {
1254 if (STATE_IS_V0(conn->_base.state))
1255 send_control0_error(conn, ERR_INTERNAL,
1256 "Unable to write configuration to disk.");
1257 else
1258 connection_write_str_to_buf(
1259 "551 Unable to write configuration to disk.\r\n", conn);
1260 } else {
1261 send_control_done(conn);
1263 return 0;
1266 /** Called when we get a SIGNAL command. React to the provided signal, and
1267 * report success or failure. (If the signal results in a shutdown, success
1268 * may not be reported.) */
1269 static int
1270 handle_control_signal(control_connection_t *conn, uint32_t len,
1271 const char *body)
1273 int sig;
1274 if (STATE_IS_V0(conn->_base.state)) {
1275 if (len != 1) {
1276 send_control0_error(conn, ERR_SYNTAX,
1277 "Body of SIGNAL command too long or too short.");
1278 return 0;
1279 } else {
1280 sig = (uint8_t)body[0];
1281 switch (sig)
1283 case 1: sig = SIGHUP; break;
1284 case 2: sig = SIGINT; break;
1285 case 10: sig = SIGUSR1; break;
1286 case 12: sig = SIGUSR2; break;
1287 case 15: sig = SIGTERM; break;
1288 case SIGNEWNYM: break;
1289 default:
1290 send_control0_error(conn, ERR_SYNTAX, "Unrecognized signal number.");
1291 return 0;
1294 } else {
1295 int n = 0;
1296 char *s;
1297 while (body[n] && ! TOR_ISSPACE(body[n]))
1298 ++n;
1299 s = tor_strndup(body, n);
1300 if (!strcasecmp(s, "RELOAD") || !strcasecmp(s, "HUP"))
1301 sig = SIGHUP;
1302 else if (!strcasecmp(s, "SHUTDOWN") || !strcasecmp(s, "INT"))
1303 sig = SIGINT;
1304 else if (!strcasecmp(s, "DUMP") || !strcasecmp(s, "USR1"))
1305 sig = SIGUSR1;
1306 else if (!strcasecmp(s, "DEBUG") || !strcasecmp(s, "USR2"))
1307 sig = SIGUSR2;
1308 else if (!strcasecmp(s, "HALT") || !strcasecmp(s, "TERM"))
1309 sig = SIGTERM;
1310 else if (!strcasecmp(s, "NEWNYM"))
1311 sig = SIGNEWNYM;
1312 else if (!strcasecmp(s, "CLEARDNSCACHE"))
1313 sig = SIGCLEARDNSCACHE;
1314 else {
1315 connection_printf_to_buf(conn, "552 Unrecognized signal code \"%s\"\r\n",
1317 sig = -1;
1319 tor_free(s);
1320 if (sig<0)
1321 return 0;
1324 /* Send DONE first, in case the signal makes us shut down. */
1325 send_control_done(conn);
1326 control_signal_act(sig);
1327 return 0;
1330 /** Called when we get a MAPADDRESS command; try to bind all listed addresses,
1331 * and report success or failrue. */
1332 static int
1333 handle_control_mapaddress(control_connection_t *conn, uint32_t len,
1334 const char *body)
1336 smartlist_t *elts;
1337 smartlist_t *lines;
1338 smartlist_t *reply;
1339 char *r;
1340 size_t sz;
1341 int v0 = STATE_IS_V0(conn->_base.state);
1342 (void) len; /* body is nul-terminated, so it's safe to ignore the length. */
1344 lines = smartlist_create();
1345 elts = smartlist_create();
1346 reply = smartlist_create();
1347 if (v0)
1348 smartlist_split_string(lines, body, "\n",
1349 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1350 else
1351 smartlist_split_string(lines, body, " ",
1352 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1353 SMARTLIST_FOREACH(lines, char *, line,
1355 tor_strlower(line);
1356 if (v0)
1357 smartlist_split_string(elts, line, " ", 0, 2);
1358 else
1359 smartlist_split_string(elts, line, "=", 0, 2);
1360 if (smartlist_len(elts) == 2) {
1361 const char *from = smartlist_get(elts,0);
1362 const char *to = smartlist_get(elts,1);
1363 size_t anslen = strlen(line)+512;
1364 char *ans = tor_malloc(anslen);
1365 if (address_is_invalid_destination(to, 1)) {
1366 if (!v0) {
1367 tor_snprintf(ans, anslen,
1368 "512-syntax error: invalid address '%s'", to);
1369 smartlist_add(reply, ans);
1370 } else
1371 tor_free(ans); /* don't respond if v0 */
1372 log_warn(LD_CONTROL,
1373 "Skipping invalid argument '%s' in MapAddress msg", to);
1374 } else if (!strcmp(from, ".") || !strcmp(from, "0.0.0.0")) {
1375 const char *address = addressmap_register_virtual_address(
1376 !strcmp(from,".") ? RESOLVED_TYPE_HOSTNAME : RESOLVED_TYPE_IPV4,
1377 tor_strdup(to));
1378 if (!address) {
1379 if (!v0) {
1380 tor_snprintf(ans, anslen,
1381 "451-resource exhausted: skipping '%s'", line);
1382 smartlist_add(reply, ans);
1383 } else
1384 tor_free(ans); /* don't respond if v0 */
1385 log_warn(LD_CONTROL,
1386 "Unable to allocate address for '%s' in MapAddress msg",
1387 safe_str(line));
1388 } else {
1389 if (v0)
1390 tor_snprintf(ans, anslen, "%s %s", address, to);
1391 else
1392 tor_snprintf(ans, anslen, "250-%s=%s", address, to);
1393 smartlist_add(reply, ans);
1395 } else {
1396 addressmap_register(from, tor_strdup(to), 1);
1397 if (v0)
1398 tor_snprintf(ans, anslen, "%s", line);
1399 else
1400 tor_snprintf(ans, anslen, "250-%s", line);
1401 smartlist_add(reply, ans);
1403 } else {
1404 if (!v0) {
1405 size_t anslen = strlen(line)+256;
1406 char *ans = tor_malloc(anslen);
1407 tor_snprintf(ans, anslen, "512-syntax error: mapping '%s' is "
1408 "not of expected form 'foo=bar'.", line);
1409 smartlist_add(reply, ans);
1411 log_info(LD_CONTROL, "Skipping MapAddress '%s': wrong "
1412 "number of items.", safe_str(line));
1414 SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
1415 smartlist_clear(elts);
1417 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
1418 smartlist_free(lines);
1419 smartlist_free(elts);
1421 if (v0) {
1422 r = smartlist_join_strings(reply, "\n", 1, &sz);
1423 send_control_done2(conn,r,sz);
1424 tor_free(r);
1425 } else {
1426 if (smartlist_len(reply)) {
1427 ((char*)smartlist_get(reply,smartlist_len(reply)-1))[3] = ' ';
1428 r = smartlist_join_strings(reply, "\r\n", 1, &sz);
1429 connection_write_to_buf(r, sz, TO_CONN(conn));
1430 tor_free(r);
1431 } else {
1432 const char *response =
1433 "512 syntax error: not enough arguments to mapaddress.\r\n";
1434 connection_write_to_buf(response, strlen(response), TO_CONN(conn));
1438 SMARTLIST_FOREACH(reply, char *, cp, tor_free(cp));
1439 smartlist_free(reply);
1440 return 0;
1443 /** DOCDOC */
1444 static int
1445 getinfo_helper_misc(control_connection_t *conn, const char *question,
1446 char **answer)
1448 (void) conn;
1449 if (!strcmp(question, "version")) {
1450 *answer = tor_strdup(VERSION);
1451 } else if (!strcmp(question, "config-file")) {
1452 *answer = tor_strdup(get_torrc_fname());
1453 } else if (!strcmp(question, "info/names")) {
1454 *answer = list_getinfo_options();
1455 } else if (!strcmp(question, "events/names")) {
1456 *answer = tor_strdup("CIRC STREAM ORCONN BW DEBUG INFO NOTICE WARN ERR "
1457 "NEWDESC ADDRMAP AUTHDIR_NEWDESCS DESCCHANGED "
1458 "NS STATUS_GENERAL STATUS_CLIENT STATUS_SERVER");
1459 } else if (!strcmp(question, "features/names")) {
1460 *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS");
1461 } else if (!strcmp(question, "address")) {
1462 uint32_t addr;
1463 if (router_pick_published_address(get_options(), &addr) < 0)
1464 return -1;
1465 *answer = tor_dup_addr(addr);
1466 } else if (!strcmp(question, "dir-usage")) {
1467 *answer = directory_dump_request_log();
1468 } else if (!strcmp(question, "fingerprint")) {
1469 routerinfo_t *me = router_get_my_routerinfo();
1470 if (!me) {
1471 *answer = tor_strdup("");
1472 } else {
1473 *answer = tor_malloc(HEX_DIGEST_LEN+1);
1474 base16_encode(*answer, HEX_DIGEST_LEN+1, me->cache_info.identity_digest,
1475 DIGEST_LEN);
1478 return 0;
1481 /** DOCDOC */
1482 static int
1483 getinfo_helper_dir(control_connection_t *control_conn,
1484 const char *question, char **answer)
1486 if (!strcmpstart(question, "desc/id/")) {
1487 routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
1488 if (ri) {
1489 const char *body = signed_descriptor_get_body(&ri->cache_info);
1490 if (body)
1491 *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
1493 } else if (!strcmpstart(question, "desc/name/")) {
1494 routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"),1);
1495 if (ri) {
1496 const char *body = signed_descriptor_get_body(&ri->cache_info);
1497 if (body)
1498 *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
1500 } else if (!strcmp(question, "desc/all-recent")) {
1501 routerlist_t *routerlist = router_get_routerlist();
1502 smartlist_t *sl = smartlist_create();
1503 if (routerlist && routerlist->routers) {
1504 SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
1506 const char *body = signed_descriptor_get_body(&ri->cache_info);
1507 if (body)
1508 smartlist_add(sl,
1509 tor_strndup(body, ri->cache_info.signed_descriptor_len));
1512 *answer = smartlist_join_strings(sl, "", 0, NULL);
1513 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
1514 smartlist_free(sl);
1515 } else if (!strcmpstart(question, "dir/server/")) {
1516 size_t answer_len = 0, url_len = strlen(question)+2;
1517 char *url = tor_malloc(url_len);
1518 smartlist_t *descs = smartlist_create();
1519 const char *msg;
1520 int res;
1521 char *cp;
1522 tor_snprintf(url, url_len, "/tor/%s", question+4);
1523 res = dirserv_get_routerdescs(descs, url, &msg);
1524 if (res) {
1525 log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg);
1526 return -1;
1528 SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
1529 answer_len += sd->signed_descriptor_len);
1530 cp = *answer = tor_malloc(answer_len+1);
1531 SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
1533 memcpy(cp, signed_descriptor_get_body(sd),
1534 sd->signed_descriptor_len);
1535 cp += sd->signed_descriptor_len;
1537 *cp = '\0';
1538 tor_free(url);
1539 smartlist_free(descs);
1540 } else if (!strcmpstart(question, "dir/status/")) {
1541 if (get_options()->DirPort) {
1542 size_t len=0;
1543 char *cp;
1544 smartlist_t *status_list = smartlist_create();
1545 dirserv_get_networkstatus_v2(status_list,
1546 question+strlen("dir/status/"));
1547 SMARTLIST_FOREACH(status_list, cached_dir_t *, d, len += d->dir_len);
1548 cp = *answer = tor_malloc(len+1);
1549 SMARTLIST_FOREACH(status_list, cached_dir_t *, d, {
1550 memcpy(cp, d->dir, d->dir_len);
1551 cp += d->dir_len;
1553 *cp = '\0';
1554 smartlist_free(status_list);
1555 } else {
1556 smartlist_t *fp_list = smartlist_create();
1557 smartlist_t *status_list = smartlist_create();
1558 size_t fn_len = strlen(get_options()->DataDirectory)+HEX_DIGEST_LEN+32;
1559 char *fn = tor_malloc(fn_len+1);
1560 char hex_id[HEX_DIGEST_LEN+1];
1561 dirserv_get_networkstatus_v2_fingerprints(
1562 fp_list, question+strlen("dir/status/"));
1563 SMARTLIST_FOREACH(fp_list, const char *, fp, {
1564 char *s;
1565 base16_encode(hex_id, sizeof(hex_id), fp, DIGEST_LEN);
1566 tor_snprintf(fn, fn_len, "%s/cached-status/%s",
1567 get_options()->DataDirectory, hex_id);
1568 s = read_file_to_str(fn, 0, NULL);
1569 if (s)
1570 smartlist_add(status_list, s);
1572 SMARTLIST_FOREACH(fp_list, char *, fp, tor_free(fp));
1573 smartlist_free(fp_list);
1574 *answer = smartlist_join_strings(status_list, "", 0, NULL);
1575 SMARTLIST_FOREACH(status_list, char *, s, tor_free(s));
1576 smartlist_free(status_list);
1578 } else if (!strcmp(question, "network-status")) {
1579 routerlist_t *routerlist = router_get_routerlist();
1580 int verbose = control_conn->use_long_names;
1581 if (!routerlist || !routerlist->routers ||
1582 list_server_status(routerlist->routers, answer, verbose ? 2 : 1) < 0) {
1583 return -1;
1586 return 0;
1589 /** DOCDOC */
1590 static int
1591 getinfo_helper_events(control_connection_t *control_conn,
1592 const char *question, char **answer)
1594 if (!strcmp(question, "circuit-status")) {
1595 circuit_t *circ;
1596 smartlist_t *status = smartlist_create();
1597 for (circ = _circuit_get_global_list(); circ; circ = circ->next) {
1598 char *s, *path;
1599 size_t slen;
1600 const char *state;
1601 if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close)
1602 continue;
1603 if (control_conn->use_long_names)
1604 path = circuit_list_path_for_controller(TO_ORIGIN_CIRCUIT(circ));
1605 else
1606 path = circuit_list_path(TO_ORIGIN_CIRCUIT(circ),0);
1607 if (circ->state == CIRCUIT_STATE_OPEN)
1608 state = "BUILT";
1609 else if (strlen(path))
1610 state = "EXTENDED";
1611 else
1612 state = "LAUNCHED";
1614 slen = strlen(path)+strlen(state)+20;
1615 s = tor_malloc(slen+1);
1616 tor_snprintf(s, slen, "%lu %s %s",
1617 (unsigned long)TO_ORIGIN_CIRCUIT(circ)->global_identifier,
1618 state, path);
1619 smartlist_add(status, s);
1620 tor_free(path);
1622 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1623 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1624 smartlist_free(status);
1625 } else if (!strcmp(question, "stream-status")) {
1626 connection_t **conns;
1627 int n_conns, i;
1628 char buf[256];
1629 smartlist_t *status = smartlist_create();
1630 get_connection_array(&conns, &n_conns);
1631 for (i=0; i < n_conns; ++i) {
1632 const char *state;
1633 edge_connection_t *conn;
1634 char *s;
1635 size_t slen;
1636 circuit_t *circ;
1637 origin_circuit_t *origin_circ = NULL;
1638 if (conns[i]->type != CONN_TYPE_AP ||
1639 conns[i]->marked_for_close ||
1640 conns[i]->state == AP_CONN_STATE_SOCKS_WAIT ||
1641 conns[i]->state == AP_CONN_STATE_NATD_WAIT)
1642 continue;
1643 conn = TO_EDGE_CONN(conns[i]);
1644 switch (conn->_base.state)
1646 case AP_CONN_STATE_CONTROLLER_WAIT:
1647 case AP_CONN_STATE_CIRCUIT_WAIT:
1648 if (conn->socks_request &&
1649 SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
1650 state = "NEWRESOLVE";
1651 else
1652 state = "NEW";
1653 break;
1654 case AP_CONN_STATE_RENDDESC_WAIT:
1655 case AP_CONN_STATE_CONNECT_WAIT:
1656 state = "SENTCONNECT"; break;
1657 case AP_CONN_STATE_RESOLVE_WAIT:
1658 state = "SENTRESOLVE"; break;
1659 case AP_CONN_STATE_OPEN:
1660 state = "SUCCEEDED"; break;
1661 default:
1662 log_warn(LD_BUG, "Asked for stream in unknown state %d",
1663 conn->_base.state);
1664 continue;
1666 circ = circuit_get_by_edge_conn(conn);
1667 if (circ && CIRCUIT_IS_ORIGIN(circ))
1668 origin_circ = TO_ORIGIN_CIRCUIT(circ);
1669 write_stream_target_to_buf(conn, buf, sizeof(buf));
1670 slen = strlen(buf)+strlen(state)+32;
1671 s = tor_malloc(slen+1);
1672 tor_snprintf(s, slen, "%lu %s %lu %s",
1673 (unsigned long) conn->global_identifier,state,
1674 origin_circ?
1675 (unsigned long)origin_circ->global_identifier : 0ul,
1676 buf);
1677 smartlist_add(status, s);
1679 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1680 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1681 smartlist_free(status);
1682 } else if (!strcmp(question, "orconn-status")) {
1683 connection_t **conns;
1684 int n_conns, i;
1685 smartlist_t *status = smartlist_create();
1686 get_connection_array(&conns, &n_conns);
1687 for (i=0; i < n_conns; ++i) {
1688 const char *state;
1689 char *s;
1690 char name[128];
1691 size_t slen;
1692 or_connection_t *conn;
1693 if (conns[i]->type != CONN_TYPE_OR || conns[i]->marked_for_close)
1694 continue;
1695 conn = TO_OR_CONN(conns[i]);
1696 if (conn->_base.state == OR_CONN_STATE_OPEN)
1697 state = "CONNECTED";
1698 else if (conn->nickname)
1699 state = "LAUNCHED";
1700 else
1701 state = "NEW";
1702 orconn_target_get_name(control_conn->use_long_names, name, sizeof(name),
1703 conn);
1704 slen = strlen(name)+strlen(state)+2;
1705 s = tor_malloc(slen+1);
1706 tor_snprintf(s, slen, "%s %s", name, state);
1707 smartlist_add(status, s);
1709 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1710 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1711 smartlist_free(status);
1712 } else if (!strcmpstart(question, "addr-mappings/")) {
1713 time_t min_e, max_e;
1714 smartlist_t *mappings;
1715 if (!strcmp(question, "addr-mappings/all")) {
1716 min_e = 0; max_e = TIME_MAX;
1717 } else if (!strcmp(question, "addr-mappings/cache")) {
1718 min_e = 2; max_e = TIME_MAX;
1719 } else if (!strcmp(question, "addr-mappings/config")) {
1720 min_e = 0; max_e = 0;
1721 } else if (!strcmp(question, "addr-mappings/control")) {
1722 min_e = 1; max_e = 1;
1723 } else {
1724 return 0;
1726 mappings = smartlist_create();
1727 addressmap_get_mappings(mappings, min_e, max_e);
1728 *answer = smartlist_join_strings(mappings, "\r\n", 0, NULL);
1729 SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
1730 smartlist_free(mappings);
1732 return 0;
1735 /** DOCDOC */
1736 typedef int (*getinfo_helper_t)(control_connection_t *,
1737 const char *q, char **a);
1739 /** DOCDOC */
1740 typedef struct getinfo_item_t {
1741 const char *varname;
1742 getinfo_helper_t fn;
1743 const char *desc;
1744 int is_prefix;
1745 } getinfo_item_t;
1747 #define ITEM(name, fn, desc) { name, getinfo_helper_##fn, desc, 0 }
1748 #define PREFIX(name, fn, desc) { name, getinfo_helper_##fn, desc, 1 }
1749 #define DOC(name, desc) { name, NULL, desc, 0 }
1751 /** DOCDOC */
1752 static const getinfo_item_t getinfo_items[] = {
1753 ITEM("version", misc, "The current version of Tor."),
1754 ITEM("config-file", misc, "Current location of the \"torrc\" file."),
1755 ITEM("accounting/bytes", accounting,
1756 "Number of bytes read/written so far in the accounting interval."),
1757 ITEM("accounting/bytes-left", accounting,
1758 "Number of bytes left to write/read so far in the accounting interval."),
1759 ITEM("accounting/enabled", accounting, "Is accounting currently enabled?"),
1760 ITEM("accounting/hibernating", accounting, "Are we hibernating or awake?"),
1761 ITEM("accounting/interval-start", accounting,
1762 "Time when the accounting period starts."),
1763 ITEM("accounting/interval-end", accounting,
1764 "Time when the accounting period ends."),
1765 ITEM("accounting/interval-wake", accounting,
1766 "Time to wake up in this accounting period."),
1767 ITEM("helper-nodes", entry_guards, NULL), /* deprecated */
1768 ITEM("entry-guards", entry_guards,
1769 "Which nodes are we using as entry guards?"),
1770 ITEM("fingerprint", misc, NULL),
1771 PREFIX("config/", config, "Current configuration values."),
1772 DOC("config/names",
1773 "List of configuration options, types, and documentation."),
1774 ITEM("info/names", misc,
1775 "List of GETINFO options, types, and documentation."),
1776 ITEM("events/names", misc,
1777 "Events that the controller can ask for with SETEVENTS."),
1778 ITEM("features/names", misc, "What arguments can USEFEATURE take?"),
1779 PREFIX("desc/id/", dir, "Router descriptors by ID."),
1780 PREFIX("desc/name/", dir, "Router descriptors by nickname."),
1781 ITEM("desc/all-recent", dir,
1782 "All non-expired, non-superseded router descriptors."),
1783 ITEM("ns/all", networkstatus,
1784 "Brief summary of router status (v2 directory format)"),
1785 PREFIX("ns/id/", networkstatus,
1786 "Brief summary of router status by ID (v2 directory format)."),
1787 PREFIX("ns/name/", networkstatus,
1788 "Brief summary of router status by nickname (v2 directory format)."),
1790 PREFIX("unregisterd-servers-", dirserv_unregistered, NULL),
1791 ITEM("network-status", dir,
1792 "Brief summary of router status (v1 directory format)"),
1793 ITEM("circuit-status", events, "List of current circuits originating here."),
1794 ITEM("stream-status", events,"List of current streams."),
1795 ITEM("orconn-status", events, "A list of current OR connections."),
1796 PREFIX("addr-mappings/", events, NULL),
1797 DOC("addr-mappings/all", "Current address mappings."),
1798 DOC("addr-mappings/cache", "Current cached DNS replies."),
1799 DOC("addr-mappings/config", "Current address mappings from configuration."),
1800 DOC("addr-mappings/control", "Current address mappings from controller."),
1802 ITEM("address", misc, "IP address of this Tor host, if we can guess it."),
1803 ITEM("dir-usage", misc, "Breakdown of bytes transferred over DirPort."),
1804 PREFIX("dir/server/", dir,"Router descriptors as retrieved from a DirPort."),
1805 PREFIX("dir/status/", dir,"Networkstatus docs as retrieved from a DirPort."),
1806 PREFIX("exit-policy/default", policies,
1807 "The default value appended to the configured exit policy."),
1809 { NULL, NULL, NULL, 0 }
1812 static char *
1813 list_getinfo_options(void)
1815 int i;
1816 char buf[300];
1817 smartlist_t *lines = smartlist_create();
1818 char *ans;
1819 for (i = 0; getinfo_items[i].varname; ++i) {
1820 if (!getinfo_items[i].desc)
1821 continue;
1823 tor_snprintf(buf, sizeof(buf), "%s%s -- %s\n",
1824 getinfo_items[i].varname,
1825 getinfo_items[i].is_prefix ? "*" : "",
1826 getinfo_items[i].desc);
1827 smartlist_add(lines, tor_strdup(buf));
1829 smartlist_sort_strings(lines);
1831 ans = smartlist_join_strings(lines, "", 0, NULL);
1832 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
1833 smartlist_free(lines);
1835 return ans;
1838 /** Lookup the 'getinfo' entry <b>question</b>, and return
1839 * the answer in <b>*answer</b> (or NULL if key not recognized).
1840 * Return 0 if success or unrecognized, or -1 if recognized but
1841 * internal error. */
1842 static int
1843 handle_getinfo_helper(control_connection_t *control_conn,
1844 const char *question, char **answer)
1846 int i;
1847 *answer = NULL; /* unrecognized key by default */
1849 for (i = 0; getinfo_items[i].varname; ++i) {
1850 int match;
1851 if (getinfo_items[i].is_prefix)
1852 match = !strcmpstart(question, getinfo_items[i].varname);
1853 else
1854 match = !strcmp(question, getinfo_items[i].varname);
1855 if (match) {
1856 tor_assert(getinfo_items[i].fn);
1857 return getinfo_items[i].fn(control_conn, question, answer);
1861 return 0; /* unrecognized */
1864 /** Called when we receive a GETINFO command. Try to fetch all requested
1865 * information, and reply with information or error message. */
1866 static int
1867 handle_control_getinfo(control_connection_t *conn, uint32_t len,
1868 const char *body)
1870 smartlist_t *questions = NULL;
1871 smartlist_t *answers = NULL;
1872 smartlist_t *unrecognized = NULL;
1873 char *msg = NULL, *ans = NULL;
1874 size_t msg_len;
1875 int v0 = STATE_IS_V0(conn->_base.state);
1876 (void) len; /* body is nul-terminated, so it's safe to ignore the length. */
1878 questions = smartlist_create();
1879 if (v0)
1880 smartlist_split_string(questions, body, "\n",
1881 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1882 else
1883 smartlist_split_string(questions, body, " ",
1884 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1885 answers = smartlist_create();
1886 unrecognized = smartlist_create();
1887 SMARTLIST_FOREACH(questions, const char *, q,
1889 if (handle_getinfo_helper(conn, q, &ans) < 0) {
1890 if (v0)
1891 send_control0_error(conn, ERR_INTERNAL, body);
1892 else
1893 connection_write_str_to_buf("551 Internal error\r\n", conn);
1894 goto done;
1896 if (!ans) {
1897 if (v0) {
1898 send_control0_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
1899 goto done;
1900 } else
1901 smartlist_add(unrecognized, (char*)q);
1902 } else {
1903 smartlist_add(answers, tor_strdup(q));
1904 smartlist_add(answers, ans);
1907 if (smartlist_len(unrecognized)) {
1908 int i;
1909 tor_assert(!v0);
1910 for (i=0; i < smartlist_len(unrecognized)-1; ++i)
1911 connection_printf_to_buf(conn,
1912 "552-Unrecognized key \"%s\"\r\n",
1913 (char*)smartlist_get(unrecognized, i));
1914 connection_printf_to_buf(conn,
1915 "552 Unrecognized key \"%s\"\r\n",
1916 (char*)smartlist_get(unrecognized, i));
1917 goto done;
1920 if (v0) {
1921 msg = smartlist_join_strings2(answers, "\0", 1, 1, &msg_len);
1922 tor_assert(msg_len > 0); /* it will at least be terminated */
1923 send_control0_message(conn, CONTROL0_CMD_INFOVALUE,
1924 msg_len, msg);
1925 } else {
1926 int i;
1927 for (i = 0; i < smartlist_len(answers); i += 2) {
1928 char *k = smartlist_get(answers, i);
1929 char *v = smartlist_get(answers, i+1);
1930 if (!strchr(v, '\n') && !strchr(v, '\r')) {
1931 connection_printf_to_buf(conn, "250-%s=", k);
1932 connection_write_str_to_buf(v, conn);
1933 connection_write_str_to_buf("\r\n", conn);
1934 } else {
1935 char *esc = NULL;
1936 size_t len;
1937 len = write_escaped_data(v, strlen(v), 1, &esc);
1938 connection_printf_to_buf(conn, "250+%s=\r\n", k);
1939 connection_write_to_buf(esc, len, TO_CONN(conn));
1940 tor_free(esc);
1943 connection_write_str_to_buf("250 OK\r\n", conn);
1946 done:
1947 if (answers) {
1948 SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
1949 smartlist_free(answers);
1951 if (questions) {
1952 SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
1953 smartlist_free(questions);
1955 smartlist_free(unrecognized);
1956 tor_free(msg);
1958 return 0;
1961 /** If *<b>string</b> contains a recognized purpose (for
1962 * circuits if <b>for_circuits</b> is 1, else for routers),
1963 * possibly prefaced with the string "purpose=", then assign it
1964 * and return 0. Otherwise return -1.
1966 * If it's prefaced with "purpose=", then set *<b>string</b> to
1967 * the remainder of the string. */
1968 static int
1969 get_purpose(char **string, int for_circuits, uint8_t *purpose)
1971 if (!strcmpstart(*string, "purpose="))
1972 *string += strlen("purpose=");
1974 if (!strcmp(*string, "general"))
1975 *purpose = for_circuits ? CIRCUIT_PURPOSE_C_GENERAL :
1976 ROUTER_PURPOSE_GENERAL;
1977 else if (!strcmp(*string, "controller"))
1978 *purpose = for_circuits ? CIRCUIT_PURPOSE_CONTROLLER :
1979 ROUTER_PURPOSE_GENERAL;
1980 else { /* not a recognized purpose */
1981 return -1;
1983 return 0;
1986 /** Called when we get an EXTENDCIRCUIT message. Try to extend the listed
1987 * circuit, and report success or failure. */
1988 static int
1989 handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
1990 const char *body)
1992 smartlist_t *router_nicknames=NULL, *routers=NULL;
1993 uint32_t circ_id;
1994 origin_circuit_t *circ = NULL;
1995 int zero_circ, v0;
1996 char reply[4];
1997 uint8_t intended_purpose = CIRCUIT_PURPOSE_C_GENERAL;
1999 v0 = STATE_IS_V0(conn->_base.state);
2000 router_nicknames = smartlist_create();
2002 if (v0) {
2003 if (len<5) {
2004 send_control0_error(conn, ERR_SYNTAX, "extendcircuit message too short");
2005 goto done;
2007 smartlist_split_string(router_nicknames, body+4, ",", 0, 0);
2008 circ_id = ntohl(get_uint32(body));
2009 if (!circ_id) {
2010 /* start a new circuit */
2011 zero_circ = 1;
2012 } else {
2013 circ = circuit_get_by_global_id(circ_id);
2014 zero_circ = 0;
2015 if (!circ) {
2016 send_control0_error(conn, ERR_NO_CIRC,
2017 "No circuit found with given ID");
2018 goto done;
2021 } else { /* v1 */
2022 smartlist_t *args;
2023 args = smartlist_create();
2024 smartlist_split_string(args, body, " ",
2025 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2026 if (smartlist_len(args)<2) {
2027 connection_printf_to_buf(conn,
2028 "512 Missing argument to EXTENDCIRCUIT\r\n");
2029 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2030 smartlist_free(args);
2031 goto done;
2034 zero_circ = !strcmp("0", (char*)smartlist_get(args,0));
2035 if (!zero_circ && !(circ = get_circ(smartlist_get(args,0)))) {
2036 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
2037 (char*)smartlist_get(args, 0));
2039 smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0);
2041 if (zero_circ && smartlist_len(args)>2) {
2042 char *purp = smartlist_get(args,2);
2043 if (get_purpose(&purp, 1, &intended_purpose) < 0) {
2044 connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
2045 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2046 smartlist_free(args);
2047 goto done;
2050 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2051 smartlist_free(args);
2052 if (!zero_circ && !circ) {
2053 goto done;
2057 routers = smartlist_create();
2058 SMARTLIST_FOREACH(router_nicknames, const char *, n,
2060 routerinfo_t *r = router_get_by_nickname(n, 1);
2061 if (!r) {
2062 if (v0)
2063 send_control0_error(conn, ERR_NO_ROUTER, n);
2064 else
2065 connection_printf_to_buf(conn, "552 No such router \"%s\"\r\n", n);
2066 goto done;
2068 smartlist_add(routers, r);
2070 if (!smartlist_len(routers)) {
2071 if (v0)
2072 send_control0_error(conn, ERR_SYNTAX, "No router names provided");
2073 else
2074 connection_write_str_to_buf("512 No router names provided\r\n", conn);
2075 goto done;
2078 if (zero_circ) {
2079 /* start a new circuit */
2080 circ = origin_circuit_init(intended_purpose, 0, 0, 0, 0);
2083 /* now circ refers to something that is ready to be extended */
2084 SMARTLIST_FOREACH(routers, routerinfo_t *, r,
2086 extend_info_t *info = extend_info_from_router(r);
2087 circuit_append_new_exit(circ, info);
2088 extend_info_free(info);
2091 /* now that we've populated the cpath, start extending */
2092 if (zero_circ) {
2093 int err_reason = 0;
2094 if ((err_reason = circuit_handle_first_hop(circ)) < 0) {
2095 circuit_mark_for_close(TO_CIRCUIT(circ), -err_reason);
2096 if (v0)
2097 send_control0_error(conn, ERR_INTERNAL, "couldn't start circuit");
2098 else
2099 connection_write_str_to_buf("551 Couldn't start circuit\r\n", conn);
2100 goto done;
2102 } else {
2103 if (circ->_base.state == CIRCUIT_STATE_OPEN) {
2104 int err_reason = 0;
2105 circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_BUILDING);
2106 if ((err_reason = circuit_send_next_onion_skin(circ)) < 0) {
2107 log_info(LD_CONTROL,
2108 "send_next_onion_skin failed; circuit marked for closing.");
2109 circuit_mark_for_close(TO_CIRCUIT(circ), -err_reason);
2110 if (v0)
2111 send_control0_error(conn, ERR_INTERNAL, "couldn't send onion skin");
2112 else
2113 connection_write_str_to_buf("551 Couldn't send onion skinr\n", conn);
2114 goto done;
2119 if (v0) {
2120 set_uint32(reply, htonl(circ->global_identifier));
2121 send_control_done2(conn, reply, sizeof(reply));
2122 } else {
2123 connection_printf_to_buf(conn, "250 EXTENDED %lu\r\n",
2124 (unsigned long)circ->global_identifier);
2126 done:
2127 SMARTLIST_FOREACH(router_nicknames, char *, n, tor_free(n));
2128 smartlist_free(router_nicknames);
2129 if (routers)
2130 smartlist_free(routers);
2131 return 0;
2134 /** Called when we get a SETCIRCUITPURPOSE (if <b>for_circuits</b>
2135 * is 1) or SETROUTERPURPOSE message. If we can find
2136 * the circuit/router and it's a valid purpose, change it. */
2137 static int
2138 handle_control_setpurpose(control_connection_t *conn, int for_circuits,
2139 uint32_t len, const char *body)
2141 origin_circuit_t *circ = NULL;
2142 routerinfo_t *ri = NULL;
2143 uint8_t new_purpose;
2144 smartlist_t *args = smartlist_create();
2145 (void) len; /* body is nul-terminated, so it's safe to ignore the length. */
2146 smartlist_split_string(args, body, " ",
2147 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2148 if (smartlist_len(args)<2) {
2149 connection_printf_to_buf(conn,
2150 "512 Missing argument to SET%sPURPOSE\r\n",
2151 for_circuits ? "CIRCUIT" : "ROUTER");
2152 goto done;
2155 if (for_circuits) {
2156 if (!(circ = get_circ(smartlist_get(args,0)))) {
2157 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
2158 (char*)smartlist_get(args, 0));
2159 goto done;
2161 } else {
2162 if (!(ri = router_get_by_nickname(smartlist_get(args,0), 0))) {
2163 connection_printf_to_buf(conn, "552 Unknown router \"%s\"\r\n",
2164 (char*)smartlist_get(args, 0));
2165 goto done;
2170 char *purp = smartlist_get(args,1);
2171 if (get_purpose(&purp, for_circuits, &new_purpose) < 0) {
2172 connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n", purp);
2173 goto done;
2177 if (for_circuits)
2178 circ->_base.purpose = new_purpose;
2179 else
2180 ri->purpose = new_purpose;
2181 connection_write_str_to_buf("250 OK\r\n", conn);
2183 done:
2184 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2185 smartlist_free(args);
2186 return 0;
2189 /** Called when we get an ATTACHSTREAM message. Try to attach the requested
2190 * stream, and report success or failure. */
2191 static int
2192 handle_control_attachstream(control_connection_t *conn, uint32_t len,
2193 const char *body)
2195 edge_connection_t *ap_conn = NULL;
2196 origin_circuit_t *circ = NULL;
2197 int zero_circ;
2199 if (STATE_IS_V0(conn->_base.state)) {
2200 uint32_t conn_id;
2201 uint32_t circ_id;
2202 if (len < 8) {
2203 send_control0_error(conn, ERR_SYNTAX, "attachstream message too short");
2204 return 0;
2207 conn_id = ntohl(get_uint32(body));
2208 circ_id = ntohl(get_uint32(body+4));
2209 zero_circ = circ_id == 0;
2211 if (!(ap_conn = connection_get_by_global_id(conn_id))) {
2212 send_control0_error(conn, ERR_NO_STREAM,
2213 "No connection found with given ID");
2214 return 0;
2216 if (circ_id && !(circ = circuit_get_by_global_id(circ_id))) {
2217 send_control0_error(conn, ERR_NO_CIRC, "No circuit found with given ID");
2218 return 0;
2220 } else {
2221 smartlist_t *args;
2222 args = smartlist_create();
2223 smartlist_split_string(args, body, " ",
2224 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2225 if (smartlist_len(args)<2) {
2226 connection_printf_to_buf(conn,
2227 "512 Missing argument to ATTACHSTREAM\r\n");
2228 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2229 smartlist_free(args);
2230 return 0;
2233 zero_circ = !strcmp("0", (char*)smartlist_get(args,1));
2235 if (!(ap_conn = get_stream(smartlist_get(args, 0)))) {
2236 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
2237 (char*)smartlist_get(args, 0));
2238 } else if (!zero_circ && !(circ = get_circ(smartlist_get(args, 1)))) {
2239 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
2240 (char*)smartlist_get(args, 1));
2242 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2243 smartlist_free(args);
2244 if (!ap_conn || (!zero_circ && !circ))
2245 return 0;
2248 if (ap_conn->_base.state != AP_CONN_STATE_CONTROLLER_WAIT &&
2249 ap_conn->_base.state != AP_CONN_STATE_CONNECT_WAIT &&
2250 ap_conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT) {
2251 if (STATE_IS_V0(conn->_base.state)) {
2252 send_control0_error(conn, ERR_NO_STREAM,
2253 "Connection is not managed by controller.");
2254 } else {
2255 connection_write_str_to_buf(
2256 "555 Connection is not managed by controller.\r\n",
2257 conn);
2259 return 0;
2262 /* Do we need to detach it first? */
2263 if (ap_conn->_base.state != AP_CONN_STATE_CONTROLLER_WAIT) {
2264 circuit_t *tmpcirc = circuit_get_by_edge_conn(ap_conn);
2265 connection_edge_end(ap_conn, END_STREAM_REASON_TIMEOUT,
2266 ap_conn->cpath_layer);
2267 /* Un-mark it as ending, since we're going to reuse it. */
2268 ap_conn->_base.edge_has_sent_end = 0;
2269 ap_conn->end_reason = 0;
2270 if (tmpcirc)
2271 circuit_detach_stream(tmpcirc,ap_conn);
2272 ap_conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
2275 if (circ && (circ->_base.state != CIRCUIT_STATE_OPEN)) {
2276 if (STATE_IS_V0(conn->_base.state))
2277 send_control0_error(conn, ERR_INTERNAL,
2278 "Refuse to attach stream to non-open, origin circ.");
2279 else
2280 connection_write_str_to_buf(
2281 "551 Can't attach stream to non-open, origin circuit\r\n",
2282 conn);
2283 return 0;
2285 if (circ && circuit_get_cpath_len(circ) < 2) {
2286 if (STATE_IS_V0(conn->_base.state))
2287 send_control0_error(conn, ERR_INTERNAL,
2288 "Refuse to attach stream to one-hop circuit.");
2289 else
2290 connection_write_str_to_buf(
2291 "551 Can't attach stream to one-hop circuit.\r\n",
2292 conn);
2293 return 0;
2295 if (connection_ap_handshake_rewrite_and_attach(ap_conn, circ) < 0) {
2296 if (STATE_IS_V0(conn->_base.state))
2297 send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
2298 else
2299 connection_write_str_to_buf("551 Unable to attach stream\r\n", conn);
2300 return 0;
2302 send_control_done(conn);
2303 return 0;
2306 /** Called when we get a POSTDESCRIPTOR message. Try to learn the provided
2307 * descriptor, and report success or failure. */
2308 static int
2309 handle_control_postdescriptor(control_connection_t *conn, uint32_t len,
2310 const char *body)
2312 char *desc;
2313 int v0 = STATE_IS_V0(conn->_base.state);
2314 const char *msg=NULL;
2315 uint8_t purpose = ROUTER_PURPOSE_GENERAL;
2317 if (v0)
2318 desc = (char*)body;
2319 else {
2320 char *cp = memchr(body, '\n', len);
2321 smartlist_t *args = smartlist_create();
2322 tor_assert(cp);
2323 *cp++ = '\0';
2324 smartlist_split_string(args, body, " ",
2325 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2326 if (smartlist_len(args)) {
2327 char *purp = smartlist_get(args,0);
2328 if (get_purpose(&purp, 0, &purpose) < 0) {
2329 connection_printf_to_buf(conn, "552 Unknown purpose \"%s\"\r\n",
2330 purp);
2331 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2332 smartlist_free(args);
2333 return 0;
2336 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2337 smartlist_free(args);
2338 read_escaped_data(cp, len-(cp-body), 1, &desc);
2341 switch (router_load_single_router(desc, purpose, &msg)) {
2342 case -1:
2343 if (!msg) msg = "Could not parse descriptor";
2344 if (v0)
2345 send_control0_error(conn,ERR_SYNTAX,msg);
2346 else
2347 connection_printf_to_buf(conn, "554 %s\r\n", msg);
2348 break;
2349 case 0:
2350 if (!msg) msg = "Descriptor not added";
2351 if (v0)
2352 send_control_done2(conn,msg,0);
2353 else
2354 connection_printf_to_buf(conn, "251 %s\r\n",msg);
2355 break;
2356 case 1:
2357 send_control_done(conn);
2358 break;
2361 if (!v0)
2362 tor_free(desc);
2363 return 0;
2366 /** Called when we receive a REDIRECTSTERAM command. Try to change the target
2367 * address of the named AP stream, and report success or failure. */
2368 static int
2369 handle_control_redirectstream(control_connection_t *conn, uint32_t len,
2370 const char *body)
2372 edge_connection_t *ap_conn = NULL;
2373 uint32_t conn_id;
2374 char *new_addr = NULL;
2375 uint16_t new_port = 0;
2376 if (STATE_IS_V0(conn->_base.state)) {
2377 if (len < 6) {
2378 send_control0_error(conn, ERR_SYNTAX,
2379 "redirectstream message too short");
2380 return 0;
2382 conn_id = ntohl(get_uint32(body));
2384 if (!(ap_conn = connection_get_by_global_id(conn_id))
2385 || ap_conn->_base.state != CONN_TYPE_AP
2386 || ap_conn->socks_request) {
2387 send_control0_error(conn, ERR_NO_STREAM,
2388 "No AP connection found with given ID");
2389 return 0;
2391 new_addr = tor_strdup(body+4);
2392 } else {
2393 smartlist_t *args;
2394 args = smartlist_create();
2395 smartlist_split_string(args, body, " ",
2396 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2397 if (smartlist_len(args) < 2)
2398 connection_printf_to_buf(conn,
2399 "512 Missing argument to REDIRECTSTREAM\r\n");
2400 else if (!(ap_conn = get_stream(smartlist_get(args, 0)))
2401 || !ap_conn->socks_request) {
2402 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
2403 (char*)smartlist_get(args, 0));
2404 } else {
2405 int ok;
2406 if (smartlist_len(args) > 2) { /* they included a port too */
2407 new_port = (uint16_t) tor_parse_ulong(smartlist_get(args, 2),
2408 10, 1, 65535, &ok, NULL);
2410 if (!ok) {
2411 connection_printf_to_buf(conn, "512 Cannot parse port \"%s\"\r\n",
2412 (char*)smartlist_get(args, 2));
2413 } else {
2414 new_addr = tor_strdup(smartlist_get(args, 1));
2418 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2419 smartlist_free(args);
2420 if (!new_addr)
2421 return 0;
2424 strlcpy(ap_conn->socks_request->address, new_addr,
2425 sizeof(ap_conn->socks_request->address));
2426 if (new_port)
2427 ap_conn->socks_request->port = new_port;
2428 tor_free(new_addr);
2429 send_control_done(conn);
2430 return 0;
2433 /** Called when we get a CLOSESTREAM command; try to close the named stream
2434 * and report success or failure. */
2435 static int
2436 handle_control_closestream(control_connection_t *conn, uint32_t len,
2437 const char *body)
2439 edge_connection_t *ap_conn=NULL;
2440 uint8_t reason=0;
2442 if (STATE_IS_V0(conn->_base.state)) {
2443 uint32_t conn_id;
2444 if (len < 6) {
2445 send_control0_error(conn, ERR_SYNTAX, "closestream message too short");
2446 return 0;
2449 conn_id = ntohl(get_uint32(body));
2450 reason = *(uint8_t*)(body+4);
2452 if (!(ap_conn = connection_get_by_global_id(conn_id))
2453 || ap_conn->_base.state != CONN_TYPE_AP
2454 || ap_conn->socks_request) {
2455 send_control0_error(conn, ERR_NO_STREAM,
2456 "No AP connection found with given ID");
2457 return 0;
2459 } else {
2460 smartlist_t *args;
2461 int ok;
2462 args = smartlist_create();
2463 smartlist_split_string(args, body, " ",
2464 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2465 if (smartlist_len(args)<2)
2466 connection_printf_to_buf(conn,
2467 "512 Missing argument to CLOSESTREAM\r\n");
2468 else if (!(ap_conn = get_stream(smartlist_get(args, 0))))
2469 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
2470 (char*)smartlist_get(args, 0));
2471 else {
2472 reason = (uint8_t) tor_parse_ulong(smartlist_get(args,1), 10, 0, 255,
2473 &ok, NULL);
2474 if (!ok) {
2475 connection_printf_to_buf(conn, "552 Unrecognized reason \"%s\"\r\n",
2476 (char*)smartlist_get(args, 1));
2477 ap_conn = NULL;
2480 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2481 smartlist_free(args);
2482 if (!ap_conn)
2483 return 0;
2486 connection_mark_unattached_ap(ap_conn, reason);
2487 send_control_done(conn);
2488 return 0;
2491 /** Called when we get a CLOSECIRCUIT command; try to close the named circuit
2492 * and report success or failure. */
2493 static int
2494 handle_control_closecircuit(control_connection_t *conn, uint32_t len,
2495 const char *body)
2497 origin_circuit_t *circ = NULL;
2498 int safe = 0;
2500 if (STATE_IS_V0(conn->_base.state)) {
2501 uint32_t circ_id;
2502 if (len < 5) {
2503 send_control0_error(conn, ERR_SYNTAX, "closecircuit message too short");
2504 return 0;
2506 circ_id = ntohl(get_uint32(body));
2507 safe = (*(uint8_t*)(body+4)) & 1;
2509 if (!(circ = circuit_get_by_global_id(circ_id))) {
2510 send_control0_error(conn, ERR_NO_CIRC,
2511 "No circuit found with given ID");
2512 return 0;
2514 } else {
2515 smartlist_t *args;
2516 args = smartlist_create();
2517 smartlist_split_string(args, body, " ",
2518 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2519 if (smartlist_len(args)<1)
2520 connection_printf_to_buf(conn,
2521 "512 Missing argument to CLOSECIRCUIT\r\n");
2522 else if (!(circ=get_circ(smartlist_get(args, 0))))
2523 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
2524 (char*)smartlist_get(args, 0));
2525 else {
2526 int i;
2527 for (i=1; i < smartlist_len(args); ++i) {
2528 if (!strcasecmp(smartlist_get(args, i), "IfUnused"))
2529 safe = 1;
2530 else
2531 log_info(LD_CONTROL, "Skipping unknown option %s",
2532 (char*)smartlist_get(args,i));
2535 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2536 smartlist_free(args);
2537 if (!circ)
2538 return 0;
2541 if (!safe || !circ->p_streams) {
2542 circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_REQUESTED);
2545 send_control_done(conn);
2546 return 0;
2549 /** DOCDOC */
2550 static int
2551 handle_control_usefeature(control_connection_t *conn,
2552 uint32_t len,
2553 const char *body)
2555 smartlist_t *args;
2556 int verbose_names = 0, extended_events = 0;
2557 int bad = 0;
2558 (void) len; /* body is nul-terminated; it's safe to ignore the length */
2559 tor_assert(! STATE_IS_V0(conn->_base.state));
2560 args = smartlist_create();
2561 smartlist_split_string(args, body, " ",
2562 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
2563 SMARTLIST_FOREACH(args, const char *, arg, {
2564 if (!strcasecmp(arg, "VERBOSE_NAMES"))
2565 verbose_names = 1;
2566 else if (!strcasecmp(arg, "EXTENDED_EVENTS")) /* <- documented */
2567 extended_events = 1;
2568 else if (!strcasecmp(arg, "EXTENDED_FORMAT")) {
2569 /* remove this in 0.1.2.4; EXTENDED_FORMAT only ever worked for a
2570 * little while during 0.1.2.2-alpha-dev. */
2571 log_warn(LD_GENERAL,
2572 "EXTENDED_FORMAT is deprecated; use EXTENDED_EVENTS "
2573 "instead.");
2574 extended_events = 1;
2575 } else {
2576 connection_printf_to_buf(conn, "552 Unrecognized feature \"%s\"\r\n",
2577 arg);
2578 bad = 1;
2579 break;
2583 if (!bad) {
2584 if (verbose_names) {
2585 conn->use_long_names = 1;
2586 control_update_global_event_mask();
2588 if (extended_events)
2589 conn->use_extended_events = 1;
2590 send_control_done(conn);
2593 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
2594 smartlist_free(args);
2595 return 0;
2598 /** Called when we get a v0 FRAGMENTHEADER or FRAGMENT command; try to append
2599 * the data to conn->incoming_cmd, setting conn->incoming_(type|len|cur_len)
2600 * as appropriate. If the command is malformed, drop it and all pending
2601 * fragments and report failure.
2603 static int
2604 handle_control_fragments(control_connection_t *conn, uint16_t command_type,
2605 uint32_t body_len, const char *body)
2607 if (command_type == CONTROL0_CMD_FRAGMENTHEADER) {
2608 if (conn->incoming_cmd) {
2609 log_warn(LD_CONTROL, "Dropping incomplete fragmented command; new "
2610 "fragmented command was begun.");
2611 tor_free(conn->incoming_cmd);
2613 if (body_len < 6) {
2614 send_control0_error(conn, ERR_SYNTAX, "FRAGMENTHEADER too short.");
2615 return 0;
2617 conn->incoming_cmd_type = ntohs(get_uint16(body));
2618 conn->incoming_cmd_len = ntohl(get_uint32(body+2));
2619 conn->incoming_cmd_cur_len = 0;
2620 conn->incoming_cmd = tor_malloc(conn->incoming_cmd_len);
2621 body += 6;
2622 body_len -= 6;
2623 } else if (command_type == CONTROL0_CMD_FRAGMENT) {
2624 if (!conn->incoming_cmd) {
2625 send_control0_error(conn, ERR_SYNTAX, "Out-of-place FRAGMENT");
2626 return 0;
2628 } else {
2629 tor_assert(0);
2632 if (conn->incoming_cmd_cur_len + body_len > conn->incoming_cmd_len) {
2633 tor_free(conn->incoming_cmd);
2634 send_control0_error(conn, ERR_SYNTAX,
2635 "Fragmented data exceeds declared length");
2636 return 0;
2638 memcpy(conn->incoming_cmd + conn->incoming_cmd_cur_len,
2639 body, body_len);
2640 conn->incoming_cmd_cur_len += body_len;
2641 return 0;
2644 /** Called when <b>conn</b> has no more bytes left on its outbuf. */
2646 connection_control_finished_flushing(control_connection_t *conn)
2648 tor_assert(conn);
2650 connection_stop_writing(TO_CONN(conn));
2651 return 0;
2654 /** Called when <b>conn</b> has gotten its socket closed. */
2656 connection_control_reached_eof(control_connection_t *conn)
2658 tor_assert(conn);
2660 log_info(LD_CONTROL,"Control connection reached EOF. Closing.");
2661 connection_mark_for_close(TO_CONN(conn));
2662 return 0;
2665 /** Called when data has arrived on a v1 control connection: Try to fetch
2666 * commands from conn->inbuf, and execute them.
2668 static int
2669 connection_control_process_inbuf_v1(control_connection_t *conn)
2671 size_t data_len;
2672 int cmd_len;
2673 char *args;
2675 tor_assert(conn);
2676 tor_assert(conn->_base.state == CONTROL_CONN_STATE_OPEN_V1 ||
2677 conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V1);
2679 if (!conn->incoming_cmd) {
2680 conn->incoming_cmd = tor_malloc(1024);
2681 conn->incoming_cmd_len = 1024;
2682 conn->incoming_cmd_cur_len = 0;
2685 again:
2686 while (1) {
2687 size_t last_idx;
2688 int r;
2689 /* First, fetch a line. */
2690 do {
2691 data_len = conn->incoming_cmd_len - conn->incoming_cmd_cur_len;
2692 r = fetch_from_buf_line(conn->_base.inbuf,
2693 conn->incoming_cmd+conn->incoming_cmd_cur_len,
2694 &data_len);
2695 if (r == 0)
2696 /* Line not all here yet. Wait. */
2697 return 0;
2698 else if (r == -1) {
2699 while (conn->incoming_cmd_len < data_len+conn->incoming_cmd_cur_len)
2700 conn->incoming_cmd_len *= 2;
2701 conn->incoming_cmd = tor_realloc(conn->incoming_cmd,
2702 conn->incoming_cmd_len);
2704 } while (r != 1);
2706 tor_assert(data_len);
2708 last_idx = conn->incoming_cmd_cur_len;
2709 conn->incoming_cmd_cur_len += data_len;
2711 /* We have appended a line to incoming_cmd. Is the command done? */
2712 if (last_idx == 0 && *conn->incoming_cmd != '+')
2713 /* One line command, didn't start with '+'. */
2714 break;
2715 if (last_idx+3 == conn->incoming_cmd_cur_len &&
2716 !memcmp(conn->incoming_cmd + last_idx, ".\r\n", 3)) {
2717 /* Just appended ".\r\n"; we're done. Remove it. */
2718 conn->incoming_cmd_cur_len -= 3;
2719 break;
2721 /* Otherwise, read another line. */
2723 data_len = conn->incoming_cmd_cur_len;
2724 /* Okay, we now have a command sitting on conn->incoming_cmd. See if we
2725 * recognize it.
2727 cmd_len = 0;
2728 while ((size_t)cmd_len < data_len
2729 && !TOR_ISSPACE(conn->incoming_cmd[cmd_len]))
2730 ++cmd_len;
2732 data_len -= cmd_len;
2733 conn->incoming_cmd[cmd_len]='\0';
2734 args = conn->incoming_cmd+cmd_len+1;
2735 while (*args == ' ' || *args == '\t') {
2736 ++args;
2737 --data_len;
2740 if (!strcasecmp(conn->incoming_cmd, "QUIT")) {
2741 connection_write_str_to_buf("250 closing connection\r\n", conn);
2742 connection_mark_for_close(TO_CONN(conn));
2743 return 0;
2746 if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
2747 strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
2748 connection_write_str_to_buf("514 Authentication required.\r\n", conn);
2749 conn->incoming_cmd_cur_len = 0;
2750 goto again;
2753 if (!strcasecmp(conn->incoming_cmd, "SETCONF")) {
2754 if (handle_control_setconf(conn, data_len, args))
2755 return -1;
2756 } else if (!strcasecmp(conn->incoming_cmd, "RESETCONF")) {
2757 if (handle_control_resetconf(conn, data_len, args))
2758 return -1;
2759 } else if (!strcasecmp(conn->incoming_cmd, "GETCONF")) {
2760 if (handle_control_getconf(conn, data_len, args))
2761 return -1;
2762 } else if (!strcasecmp(conn->incoming_cmd, "SETEVENTS")) {
2763 if (handle_control_setevents(conn, data_len, args))
2764 return -1;
2765 } else if (!strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
2766 if (handle_control_authenticate(conn, data_len, args))
2767 return -1;
2768 } else if (!strcasecmp(conn->incoming_cmd, "SAVECONF")) {
2769 if (handle_control_saveconf(conn, data_len, args))
2770 return -1;
2771 } else if (!strcasecmp(conn->incoming_cmd, "SIGNAL")) {
2772 if (handle_control_signal(conn, data_len, args))
2773 return -1;
2774 } else if (!strcasecmp(conn->incoming_cmd, "MAPADDRESS")) {
2775 if (handle_control_mapaddress(conn, data_len, args))
2776 return -1;
2777 } else if (!strcasecmp(conn->incoming_cmd, "GETINFO")) {
2778 if (handle_control_getinfo(conn, data_len, args))
2779 return -1;
2780 } else if (!strcasecmp(conn->incoming_cmd, "EXTENDCIRCUIT")) {
2781 if (handle_control_extendcircuit(conn, data_len, args))
2782 return -1;
2783 } else if (!strcasecmp(conn->incoming_cmd, "SETCIRCUITPURPOSE")) {
2784 if (handle_control_setpurpose(conn, 1, data_len, args))
2785 return -1;
2786 } else if (!strcasecmp(conn->incoming_cmd, "SETROUTERPURPOSE")) {
2787 if (handle_control_setpurpose(conn, 0, data_len, args))
2788 return -1;
2789 } else if (!strcasecmp(conn->incoming_cmd, "ATTACHSTREAM")) {
2790 if (handle_control_attachstream(conn, data_len, args))
2791 return -1;
2792 } else if (!strcasecmp(conn->incoming_cmd, "+POSTDESCRIPTOR")) {
2793 if (handle_control_postdescriptor(conn, data_len, args))
2794 return -1;
2795 } else if (!strcasecmp(conn->incoming_cmd, "REDIRECTSTREAM")) {
2796 if (handle_control_redirectstream(conn, data_len, args))
2797 return -1;
2798 } else if (!strcasecmp(conn->incoming_cmd, "CLOSESTREAM")) {
2799 if (handle_control_closestream(conn, data_len, args))
2800 return -1;
2801 } else if (!strcasecmp(conn->incoming_cmd, "CLOSECIRCUIT")) {
2802 if (handle_control_closecircuit(conn, data_len, args))
2803 return -1;
2804 } else if (!strcasecmp(conn->incoming_cmd, "USEFEATURE")) {
2805 if (handle_control_usefeature(conn, data_len, args))
2806 return -1;
2807 } else {
2808 connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n",
2809 conn->incoming_cmd);
2812 conn->incoming_cmd_cur_len = 0;
2813 goto again;
2816 /** Called when data has arrived on a v0 control connection: Try to fetch
2817 * commands from conn->inbuf, and execute them.
2819 static int
2820 connection_control_process_inbuf_v0(control_connection_t *conn)
2822 uint32_t body_len;
2823 uint16_t command_type;
2824 char *body=NULL;
2826 again:
2827 /* Try to suck a control message from the buffer. */
2828 switch (fetch_from_buf_control0(conn->_base.inbuf, &body_len, &command_type,
2829 &body,
2830 conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V0))
2832 case -2:
2833 tor_free(body);
2834 log_info(LD_CONTROL,
2835 "Detected v1 control protocol on connection (fd %d)",
2836 conn->_base.s);
2837 conn->_base.state = CONTROL_CONN_STATE_NEEDAUTH_V1;
2838 return connection_control_process_inbuf_v1(conn);
2839 case -1:
2840 tor_free(body);
2841 log_warn(LD_CONTROL, "Error in control command. Failing.");
2842 return -1;
2843 case 0:
2844 /* Control command not all here yet. Wait. */
2845 return 0;
2846 case 1:
2847 /* We got a command. Process it. */
2848 break;
2849 default:
2850 tor_assert(0);
2853 /* We got a command. If we need authentication, only authentication
2854 * commands will be considered. */
2855 if (conn->_base.state == CONTROL_CONN_STATE_NEEDAUTH_V0 &&
2856 command_type != CONTROL0_CMD_AUTHENTICATE) {
2857 log_info(LD_CONTROL, "Rejecting '%s' command; authentication needed.",
2858 control_cmd_to_string(command_type));
2859 send_control0_error(conn, ERR_UNAUTHORIZED, "Authentication required");
2860 tor_free(body);
2861 goto again;
2864 if (command_type == CONTROL0_CMD_FRAGMENTHEADER ||
2865 command_type == CONTROL0_CMD_FRAGMENT) {
2866 if (handle_control_fragments(conn, command_type, body_len, body))
2867 return -1;
2868 tor_free(body);
2869 if (conn->incoming_cmd_cur_len != conn->incoming_cmd_len)
2870 goto again;
2872 command_type = conn->incoming_cmd_type;
2873 body_len = conn->incoming_cmd_len;
2874 body = conn->incoming_cmd;
2875 conn->incoming_cmd = NULL;
2876 } else if (conn->incoming_cmd) {
2877 log_warn(LD_CONTROL, "Dropping incomplete fragmented command");
2878 tor_free(conn->incoming_cmd);
2881 /* Okay, we're willing to process the command. */
2882 switch (command_type)
2884 case CONTROL0_CMD_SETCONF:
2885 if (handle_control_setconf(conn, body_len, body))
2886 return -1;
2887 break;
2888 case CONTROL0_CMD_GETCONF:
2889 if (handle_control_getconf(conn, body_len, body))
2890 return -1;
2891 break;
2892 case CONTROL0_CMD_SETEVENTS:
2893 if (handle_control_setevents(conn, body_len, body))
2894 return -1;
2895 break;
2896 case CONTROL0_CMD_AUTHENTICATE:
2897 if (handle_control_authenticate(conn, body_len, body))
2898 return -1;
2899 break;
2900 case CONTROL0_CMD_SAVECONF:
2901 if (handle_control_saveconf(conn, body_len, body))
2902 return -1;
2903 break;
2904 case CONTROL0_CMD_SIGNAL:
2905 if (handle_control_signal(conn, body_len, body))
2906 return -1;
2907 break;
2908 case CONTROL0_CMD_MAPADDRESS:
2909 if (handle_control_mapaddress(conn, body_len, body))
2910 return -1;
2911 break;
2912 case CONTROL0_CMD_GETINFO:
2913 if (handle_control_getinfo(conn, body_len, body))
2914 return -1;
2915 break;
2916 case CONTROL0_CMD_EXTENDCIRCUIT:
2917 if (handle_control_extendcircuit(conn, body_len, body))
2918 return -1;
2919 break;
2920 case CONTROL0_CMD_ATTACHSTREAM:
2921 if (handle_control_attachstream(conn, body_len, body))
2922 return -1;
2923 break;
2924 case CONTROL0_CMD_POSTDESCRIPTOR:
2925 if (handle_control_postdescriptor(conn, body_len, body))
2926 return -1;
2927 break;
2928 case CONTROL0_CMD_REDIRECTSTREAM:
2929 if (handle_control_redirectstream(conn, body_len, body))
2930 return -1;
2931 break;
2932 case CONTROL0_CMD_CLOSESTREAM:
2933 if (handle_control_closestream(conn, body_len, body))
2934 return -1;
2935 break;
2936 case CONTROL0_CMD_CLOSECIRCUIT:
2937 if (handle_control_closecircuit(conn, body_len, body))
2938 return -1;
2939 break;
2940 case CONTROL0_CMD_ERROR:
2941 case CONTROL0_CMD_DONE:
2942 case CONTROL0_CMD_CONFVALUE:
2943 case CONTROL0_CMD_EVENT:
2944 case CONTROL0_CMD_INFOVALUE:
2945 log_warn(LD_CONTROL, "Received client-only '%s' command; ignoring.",
2946 control_cmd_to_string(command_type));
2947 send_control0_error(conn, ERR_UNRECOGNIZED_TYPE,
2948 "Command type only valid from server to tor client");
2949 break;
2950 case CONTROL0_CMD_FRAGMENTHEADER:
2951 case CONTROL0_CMD_FRAGMENT:
2952 log_warn(LD_CONTROL,
2953 "Recieved command fragment out of order; ignoring.");
2954 send_control0_error(conn, ERR_SYNTAX, "Bad fragmentation on command.");
2955 default:
2956 log_warn(LD_CONTROL, "Received unrecognized command type %d; ignoring.",
2957 (int)command_type);
2958 send_control0_error(conn, ERR_UNRECOGNIZED_TYPE,
2959 "Unrecognized command type");
2960 break;
2962 tor_free(body);
2963 goto again; /* There might be more data. */
2966 /** Called when <b>conn</b> has received more bytes on its inbuf.
2969 connection_control_process_inbuf(control_connection_t *conn)
2971 tor_assert(conn);
2973 if (STATE_IS_V0(conn->_base.state))
2974 return connection_control_process_inbuf_v0(conn);
2975 else
2976 return connection_control_process_inbuf_v1(conn);
2979 /** DOCDOC */
2980 static const char *
2981 circuit_end_reason_to_string(int reason)
2983 if (reason >= 0 && reason & END_CIRC_REASON_FLAG_REMOTE)
2984 reason &= ~END_CIRC_REASON_FLAG_REMOTE;
2985 switch (reason) {
2986 case END_CIRC_AT_ORIGIN:
2987 /* This shouldn't get passed here; it's a catch-all reason. */
2988 return "ORIGIN";
2989 case END_CIRC_REASON_NONE:
2990 /* This shouldn't get passed here; it's a catch-all reason. */
2991 return "NONE";
2992 case END_CIRC_REASON_TORPROTOCOL:
2993 return "TORPROTOCOL";
2994 case END_CIRC_REASON_INTERNAL:
2995 return "INTERNAL";
2996 case END_CIRC_REASON_REQUESTED:
2997 return "REQUESTED";
2998 case END_CIRC_REASON_HIBERNATING:
2999 return "HIBERNATING";
3000 case END_CIRC_REASON_RESOURCELIMIT:
3001 return "RESOURCELIMIT";
3002 case END_CIRC_REASON_CONNECTFAILED:
3003 return "CONNECTFAILED";
3004 case END_CIRC_REASON_OR_IDENTITY:
3005 return "OR_IDENTITY";
3006 case END_CIRC_REASON_OR_CONN_CLOSED:
3007 return "OR_CONN_CLOSED";
3008 case END_CIRC_REASON_FINISHED:
3009 return "FINISHED";
3010 case END_CIRC_REASON_TIMEOUT:
3011 return "TIMEOUT";
3012 case END_CIRC_REASON_DESTROYED:
3013 return "DESTROYED";
3014 case END_CIRC_REASON_NOPATH:
3015 return "NOPATH";
3016 case END_CIRC_REASON_NOSUCHSERVICE:
3017 return "NOSUCHSERVICE";
3018 default:
3019 log_warn(LD_BUG, "Unrecognized reason code %d", (int)reason);
3020 return NULL;
3024 /** Something has happened to circuit <b>circ</b>: tell any interested
3025 * control connections. */
3027 control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
3028 int reason_code)
3030 char *path=NULL, *msg;
3031 if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
3032 return 0;
3033 tor_assert(circ);
3035 if (EVENT_IS_INTERESTING0(EVENT_CIRCUIT_STATUS) ||
3036 EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS))
3037 path = circuit_list_path(circ,0);
3038 if (EVENT_IS_INTERESTING0(EVENT_CIRCUIT_STATUS)) {
3039 size_t path_len = strlen(path);
3040 msg = tor_malloc(1+4+path_len+1); /* event, circid, path, NUL. */
3041 msg[0] = (uint8_t) tp;
3042 set_uint32(msg+1, htonl(circ->global_identifier));
3043 strlcpy(msg+5,path,path_len+1);
3045 send_control0_event(EVENT_CIRCUIT_STATUS, (uint32_t)(path_len+6), msg);
3046 tor_free(msg);
3048 if (EVENT_IS_INTERESTING1(EVENT_CIRCUIT_STATUS)) {
3049 const char *status;
3050 char reason_buf[64];
3051 int providing_reason=0;
3052 switch (tp)
3054 case CIRC_EVENT_LAUNCHED: status = "LAUNCHED"; break;
3055 case CIRC_EVENT_BUILT: status = "BUILT"; break;
3056 case CIRC_EVENT_EXTENDED: status = "EXTENDED"; break;
3057 case CIRC_EVENT_FAILED: status = "FAILED"; break;
3058 case CIRC_EVENT_CLOSED: status = "CLOSED"; break;
3059 default:
3060 log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
3061 return 0;
3064 if (tp == CIRC_EVENT_FAILED || tp == CIRC_EVENT_CLOSED) {
3065 const char *reason_str = circuit_end_reason_to_string(reason_code);
3066 char *reason = NULL;
3067 providing_reason=1;
3068 if (!reason_str) {
3069 reason = tor_malloc(16);
3070 tor_snprintf(reason, 16, "UNKNOWN_%d", reason_code);
3071 reason_str = reason;
3073 if (reason_code > 0 && reason_code & END_CIRC_REASON_FLAG_REMOTE) {
3074 tor_snprintf(reason_buf, sizeof(reason_buf),
3075 "REASON=DESTROYED REMOTE_REASON=%s", reason_str);
3076 } else {
3077 tor_snprintf(reason_buf, sizeof(reason_buf),
3078 "REASON=%s", reason_str);
3080 tor_free(reason);
3083 if (EVENT_IS_INTERESTING1S(EVENT_CIRCUIT_STATUS)) {
3084 const char *sp = strlen(path) ? " " : "";
3085 if (providing_reason)
3086 send_control1_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
3087 "650 CIRC %lu %s%s%s@%s\r\n",
3088 (unsigned long)circ->global_identifier,
3089 status, sp, path, reason_buf);
3090 else
3091 send_control1_event_extended(EVENT_CIRCUIT_STATUS, SHORT_NAMES,
3092 "650 CIRC %lu %s%s%s\r\n",
3093 (unsigned long)circ->global_identifier,
3094 status, sp, path);
3096 if (EVENT_IS_INTERESTING1L(EVENT_CIRCUIT_STATUS)) {
3097 char *vpath = circuit_list_path_for_controller(circ);
3098 const char *sp = strlen(vpath) ? " " : "";
3099 if (providing_reason)
3100 send_control1_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES,
3101 "650 CIRC %lu %s%s%s@%s\r\n",
3102 (unsigned long)circ->global_identifier,
3103 status, sp, vpath, reason_buf);
3104 else
3105 send_control1_event_extended(EVENT_CIRCUIT_STATUS, LONG_NAMES,
3106 "650 CIRC %lu %s%s%s\r\n",
3107 (unsigned long)circ->global_identifier,
3108 status, sp, vpath);
3109 tor_free(vpath);
3112 tor_free(path);
3114 return 0;
3117 /** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
3118 * <b>buf</b>, determine the address:port combination requested on
3119 * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
3120 * failure. */
3121 static int
3122 write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
3124 char buf2[256];
3125 if (conn->chosen_exit_name)
3126 if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
3127 return -1;
3128 if (tor_snprintf(buf, len, "%s%s%s:%d",
3129 conn->socks_request->address,
3130 conn->chosen_exit_name ? buf2 : "",
3131 !conn->chosen_exit_name &&
3132 connection_edge_is_rendezvous_stream(conn) ? ".onion" : "",
3133 conn->socks_request->port)<0)
3134 return -1;
3135 return 0;
3138 /** Convert the reason for ending a stream <b>reason</b> into the format used
3139 * in STREAM events. Return NULL if the reason is unrecognized.*/
3140 static const char *
3141 stream_end_reason_to_string(int reason)
3143 reason &= ~END_CIRC_REASON_FLAG_REMOTE;
3144 switch (reason) {
3145 case END_STREAM_REASON_MISC: return "MISC";
3146 case END_STREAM_REASON_RESOLVEFAILED: return "RESOLVEFAILED";
3147 case END_STREAM_REASON_CONNECTREFUSED: return "CONNECTREFUSED";
3148 case END_STREAM_REASON_EXITPOLICY: return "EXITPOLICY";
3149 case END_STREAM_REASON_DESTROY: return "DESTROY";
3150 case END_STREAM_REASON_DONE: return "DONE";
3151 case END_STREAM_REASON_TIMEOUT: return "TIMEOUT";
3152 case END_STREAM_REASON_HIBERNATING: return "HIBERNATING";
3153 case END_STREAM_REASON_INTERNAL: return "INTERNAL";
3154 case END_STREAM_REASON_RESOURCELIMIT: return "RESOURCELIMIT";
3155 case END_STREAM_REASON_CONNRESET: return "CONNRESET";
3156 case END_STREAM_REASON_TORPROTOCOL: return "TORPROTOCOL";
3157 case END_STREAM_REASON_NOTDIRECTORY: return "NOTDIRECTORY";
3159 case END_STREAM_REASON_ALREADY_SOCKS_REPLIED: return "INTERNAL";
3160 case END_STREAM_REASON_CANT_ATTACH: return "CANT_ATTACH";
3161 case END_STREAM_REASON_NET_UNREACHABLE: return "NET_UNREACHABLE";
3162 case END_STREAM_REASON_SOCKSPROTOCOL: return "SOCKS_PROTOCOL";
3164 default: return NULL;
3168 /** Something has happened to the stream associated with AP connection
3169 * <b>conn</b>: tell any interested control connections. */
3171 control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
3172 int reason_code)
3174 char *msg;
3175 size_t len;
3176 char buf[256];
3177 tor_assert(conn->socks_request);
3179 if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
3180 return 0;
3182 write_stream_target_to_buf(conn, buf, sizeof(buf));
3183 if (EVENT_IS_INTERESTING0(EVENT_STREAM_STATUS)) {
3184 len = strlen(buf);
3185 msg = tor_malloc(5+len+1);
3186 msg[0] = (uint8_t) tp;
3187 set_uint32(msg+1, htonl(conn->global_identifier));
3188 strlcpy(msg+5, buf, len+1);
3190 send_control0_event(EVENT_STREAM_STATUS, (uint32_t)(5+len+1), msg);
3191 tor_free(msg);
3193 if (EVENT_IS_INTERESTING1(EVENT_STREAM_STATUS)) {
3194 char reason_buf[64];
3195 const char *status;
3196 circuit_t *circ;
3197 origin_circuit_t *origin_circ = NULL;
3198 reason_buf[0] = '\0';
3199 switch (tp)
3201 case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
3202 case STREAM_EVENT_SENT_RESOLVE: status = "SENTRESOLVE"; break;
3203 case STREAM_EVENT_SUCCEEDED: status = "SUCCEEDED"; break;
3204 case STREAM_EVENT_FAILED: status = "FAILED"; break;
3205 case STREAM_EVENT_CLOSED: status = "CLOSED"; break;
3206 case STREAM_EVENT_NEW: status = "NEW"; break;
3207 case STREAM_EVENT_NEW_RESOLVE: status = "NEWRESOLVE"; break;
3208 case STREAM_EVENT_FAILED_RETRIABLE: status = "DETACHED"; break;
3209 default:
3210 log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
3211 return 0;
3213 if (reason_code && (tp == STREAM_EVENT_FAILED ||
3214 tp == STREAM_EVENT_CLOSED ||
3215 tp == STREAM_EVENT_FAILED_RETRIABLE)) {
3216 const char *reason_str = stream_end_reason_to_string(reason_code);
3217 char *r = NULL;
3218 if (!reason_str) {
3219 r = tor_malloc(16);
3220 tor_snprintf(r, 16, "UNKNOWN_%d", reason_code);
3221 reason_str = r;
3223 if (reason_code & END_STREAM_REASON_FLAG_REMOTE)
3224 tor_snprintf(reason_buf, sizeof(reason_buf),
3225 "REASON=END REMOTE_REASON=%s", reason_str);
3226 else
3227 tor_snprintf(reason_buf, sizeof(reason_buf),
3228 "REASON=%s", reason_str);
3229 tor_free(r);
3231 circ = circuit_get_by_edge_conn(conn);
3232 if (circ && CIRCUIT_IS_ORIGIN(circ))
3233 origin_circ = TO_ORIGIN_CIRCUIT(circ);
3234 send_control1_event_extended(EVENT_STREAM_STATUS, ALL_NAMES,
3235 "650 STREAM %lu %s %lu %s@%s\r\n",
3236 (unsigned long)conn->global_identifier, status,
3237 origin_circ?
3238 (unsigned long)origin_circ->global_identifier : 0ul,
3239 buf, reason_buf);
3240 /* XXX need to specify its intended exit, etc? */
3242 return 0;
3245 /** DOCDOC */
3246 static void
3247 orconn_target_get_name(int long_names,
3248 char *name, size_t len, or_connection_t *conn)
3250 if (! long_names) {
3251 if (conn->nickname)
3252 strlcpy(name, conn->nickname, len);
3253 else
3254 tor_snprintf(name, len, "%s:%d",
3255 conn->_base.address, conn->_base.port);
3256 } else {
3257 routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
3258 if (ri) {
3259 tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
3260 router_get_verbose_nickname(name, ri);
3261 } else if (! tor_digest_is_zero(conn->identity_digest)) {
3262 name[0] = '$';
3263 base16_encode(name+1, len-1, conn->identity_digest,
3264 DIGEST_LEN);
3265 } else {
3266 tor_snprintf(name, len, "%s:%d",
3267 conn->_base.address, conn->_base.port);
3272 /** DOCDOC */
3274 control_tls_error_to_reason(int e)
3276 switch (e) {
3277 case TOR_TLS_ERROR_IO:
3278 return END_OR_CONN_REASON_TLS_IO_ERROR;
3279 case TOR_TLS_ERROR_CONNREFUSED:
3280 return END_OR_CONN_REASON_TCP_REFUSED;
3281 case TOR_TLS_ERROR_CONNRESET:
3282 return END_OR_CONN_REASON_TLS_CONNRESET;
3283 case TOR_TLS_ERROR_NO_ROUTE:
3284 return END_OR_CONN_REASON_TLS_NO_ROUTE;
3285 case TOR_TLS_ERROR_TIMEOUT:
3286 return END_OR_CONN_REASON_TLS_TIMEOUT;
3287 case TOR_TLS_WANTREAD:
3288 case TOR_TLS_WANTWRITE:
3289 case TOR_TLS_CLOSE:
3290 case TOR_TLS_DONE:
3291 return END_OR_CONN_REASON_DONE;
3292 default:
3293 return END_OR_CONN_REASON_TLS_MISC;
3297 /** DOCDOC */
3298 static const char *
3299 or_conn_end_reason_to_string(int r)
3301 switch (r) {
3302 case END_OR_CONN_REASON_DONE:
3303 return "REASON=DONE";
3304 case END_OR_CONN_REASON_TCP_REFUSED:
3305 return "REASON=CONNECTREFUSED";
3306 case END_OR_CONN_REASON_OR_IDENTITY:
3307 return "REASON=IDENTITY";
3308 case END_OR_CONN_REASON_TLS_CONNRESET:
3309 return "REASON=CONNECTRESET";
3310 case END_OR_CONN_REASON_TLS_TIMEOUT:
3311 return "REASON=TIMEOUT";
3312 case END_OR_CONN_REASON_TLS_NO_ROUTE:
3313 return "REASON=NOROUTE";
3314 case END_OR_CONN_REASON_TLS_IO_ERROR:
3315 return "REASON=IOERROR";
3316 case END_OR_CONN_REASON_TLS_MISC:
3317 return "REASON=MISC";
3318 case 0:
3319 return "";
3320 default:
3321 log_warn(LD_BUG, "Unrecognized or_conn reason code %d", r);
3322 return "REASON=BOGUS";
3326 /** DOCDOC */
3328 control_event_or_conn_status(or_connection_t *conn,or_conn_status_event_t tp,
3329 int reason)
3331 char buf[HEX_DIGEST_LEN+3]; /* status, dollar, identity, NUL */
3332 size_t len;
3333 int ncircs = 0;
3335 if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
3336 return 0;
3338 if (EVENT_IS_INTERESTING0(EVENT_OR_CONN_STATUS)) {
3339 buf[0] = (uint8_t)tp;
3340 strlcpy(buf+1,conn->nickname ? conn->nickname : "",sizeof(buf)-1);
3341 len = strlen(buf+1);
3342 send_control0_event(EVENT_OR_CONN_STATUS, (uint32_t)(len+1), buf);
3344 if (EVENT_IS_INTERESTING1(EVENT_OR_CONN_STATUS)) {
3345 const char *status;
3346 char name[128];
3347 char ncircs_buf[32] = {0}; /* > 8 + log10(2^32)=10 + 2 */
3348 switch (tp)
3350 case OR_CONN_EVENT_LAUNCHED: status = "LAUNCHED"; break;
3351 case OR_CONN_EVENT_CONNECTED: status = "CONNECTED"; break;
3352 case OR_CONN_EVENT_FAILED: status = "FAILED"; break;
3353 case OR_CONN_EVENT_CLOSED: status = "CLOSED"; break;
3354 case OR_CONN_EVENT_NEW: status = "NEW"; break;
3355 default:
3356 log_warn(LD_BUG, "Unrecognized status code %d", (int)tp);
3357 return 0;
3359 ncircs = connection_or_count_pending_circs(conn);
3360 ncircs += conn->n_circuits;
3361 if (ncircs && (tp == OR_CONN_EVENT_FAILED || tp == OR_CONN_EVENT_CLOSED)) {
3362 tor_snprintf(ncircs_buf, sizeof(ncircs_buf), "%sNCIRCS=%d",
3363 reason ? " " : "", ncircs);
3366 if (EVENT_IS_INTERESTING1S(EVENT_OR_CONN_STATUS)) {
3367 orconn_target_get_name(0, name, sizeof(name), conn);
3368 send_control1_event_extended(EVENT_OR_CONN_STATUS, SHORT_NAMES,
3369 "650 ORCONN %s %s@%s%s\r\n",
3370 name, status,
3371 or_conn_end_reason_to_string(reason), ncircs_buf);
3373 if (EVENT_IS_INTERESTING1L(EVENT_OR_CONN_STATUS)) {
3374 orconn_target_get_name(1, name, sizeof(name), conn);
3375 send_control1_event_extended(EVENT_OR_CONN_STATUS, LONG_NAMES,
3376 "650 ORCONN %s %s@%s%s\r\n",
3377 name, status,
3378 or_conn_end_reason_to_string(reason), ncircs_buf);
3381 return 0;
3384 /** A second or more has elapsed: tell any interested control
3385 * connections how much bandwidth we used. */
3387 control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
3389 char buf[8];
3391 if (EVENT_IS_INTERESTING0(EVENT_BANDWIDTH_USED)) {
3392 set_uint32(buf, htonl(n_read));
3393 set_uint32(buf+4, htonl(n_written));
3394 send_control0_event(EVENT_BANDWIDTH_USED, 8, buf);
3396 if (EVENT_IS_INTERESTING1(EVENT_BANDWIDTH_USED)) {
3397 send_control1_event(EVENT_BANDWIDTH_USED, ALL_NAMES,
3398 "650 BW %lu %lu\r\n",
3399 (unsigned long)n_read,
3400 (unsigned long)n_written);
3403 return 0;
3406 /** Called when we are sending a log message to the controllers: suspend
3407 * sending further log messages to the controllers until we're done. Used by
3408 * CONN_LOG_PROTECT. */
3409 void
3410 disable_control_logging(void)
3412 ++disable_log_messages;
3415 /** We're done sending a log message to the controllers: re-enable controller
3416 * logging. Used by CONN_LOG_PROTECT. */
3417 void
3418 enable_control_logging(void)
3420 if (--disable_log_messages < 0)
3421 tor_assert(0);
3424 /** We got a log message: tell any interested control connections. */
3425 void
3426 control_event_logmsg(int severity, uint32_t domain, const char *msg)
3428 int oldlog, event;
3430 if (disable_log_messages)
3431 return;
3433 if (domain == LD_BUG && EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL) &&
3434 severity <= LOG_NOTICE) {
3435 char *esc = esc_for_log(msg);
3436 ++disable_log_messages;
3437 control_event_general_status(severity, "BUG REASON=\"%s\"", esc);
3438 --disable_log_messages;
3439 tor_free(esc);
3442 oldlog = EVENT_IS_INTERESTING0(EVENT_LOG_OBSOLETE) &&
3443 (severity == LOG_NOTICE || severity == LOG_WARN || severity == LOG_ERR);
3444 event = log_severity_to_event(severity);
3446 if (event<0 || !EVENT_IS_INTERESTING0(event))
3447 event = 0;
3449 if (oldlog || event) {
3450 size_t len = strlen(msg);
3451 ++disable_log_messages;
3452 if (event)
3453 send_control0_event(event, (uint32_t)(len+1), msg);
3454 if (oldlog)
3455 send_control0_event(EVENT_LOG_OBSOLETE, (uint32_t)(len+1), msg);
3456 --disable_log_messages;
3459 event = log_severity_to_event(severity);
3460 if (event >= 0 && EVENT_IS_INTERESTING1(event)) {
3461 char *b = NULL;
3462 const char *s;
3463 if (strchr(msg, '\n')) {
3464 char *cp;
3465 b = tor_strdup(msg);
3466 for (cp = b; *cp; ++cp)
3467 if (*cp == '\r' || *cp == '\n')
3468 *cp = ' ';
3470 switch (severity) {
3471 case LOG_DEBUG: s = "DEBUG"; break;
3472 case LOG_INFO: s = "INFO"; break;
3473 case LOG_NOTICE: s = "NOTICE"; break;
3474 case LOG_WARN: s = "WARN"; break;
3475 case LOG_ERR: s = "ERR"; break;
3476 default: s = "UnknownLogSeverity"; break;
3478 ++disable_log_messages;
3479 send_control1_event(event, ALL_NAMES, "650 %s %s\r\n", s, b?b:msg);
3480 --disable_log_messages;
3481 tor_free(b);
3485 /** Called whenever we receive new router descriptors: tell any
3486 * interested control connections. <b>routers</b> is a list of
3487 * DIGEST_LEN-byte identity digests.
3490 control_event_descriptors_changed(smartlist_t *routers)
3492 size_t len;
3493 char *msg;
3494 smartlist_t *identities = NULL;
3495 char buf[HEX_DIGEST_LEN+1];
3497 if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
3498 return 0;
3499 if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC) ||
3500 EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
3501 identities = smartlist_create();
3502 SMARTLIST_FOREACH(routers, routerinfo_t *, r,
3504 base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
3505 smartlist_add(identities, tor_strdup(buf));
3508 if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC)) {
3509 msg = smartlist_join_strings(identities, ",", 0, &len);
3510 send_control0_event(EVENT_NEW_DESC, len+1, msg);
3511 tor_free(msg);
3513 if (EVENT_IS_INTERESTING1S(EVENT_NEW_DESC)) {
3514 char *ids = smartlist_join_strings(identities, " ", 0, &len);
3515 size_t len = strlen(ids)+32;
3516 msg = tor_malloc(len);
3517 tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
3518 send_control1_event_string(EVENT_NEW_DESC, SHORT_NAMES|ALL_FORMATS, msg);
3519 tor_free(ids);
3520 tor_free(msg);
3522 if (EVENT_IS_INTERESTING1L(EVENT_NEW_DESC)) {
3523 smartlist_t *names = smartlist_create();
3524 char *ids;
3525 size_t len;
3526 SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
3527 char *b = tor_malloc(MAX_VERBOSE_NICKNAME_LEN+1);
3528 router_get_verbose_nickname(b, ri);
3529 smartlist_add(names, b);
3531 ids = smartlist_join_strings(names, " ", 0, &len);
3532 len = strlen(ids)+32;
3533 msg = tor_malloc(len);
3534 tor_snprintf(msg, len, "650 NEWDESC %s\r\n", ids);
3535 send_control1_event_string(EVENT_NEW_DESC, LONG_NAMES|ALL_FORMATS, msg);
3536 tor_free(ids);
3537 tor_free(msg);
3538 SMARTLIST_FOREACH(names, char *, cp, tor_free(cp));
3539 smartlist_free(names);
3541 if (identities) {
3542 SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
3543 smartlist_free(identities);
3545 return 0;
3548 /** Called whenever an address mapping on <b>from<b> from changes to <b>to</b>.
3549 * <b>expires</b> values less than 3 are special; see connection_edge.c. */
3551 control_event_address_mapped(const char *from, const char *to, time_t expires)
3553 if (!EVENT_IS_INTERESTING1(EVENT_ADDRMAP))
3554 return 0;
3556 if (expires < 3)
3557 send_control1_event(EVENT_ADDRMAP, ALL_NAMES,
3558 "650 ADDRMAP %s %s NEVER\r\n", from, to);
3559 else {
3560 char buf[ISO_TIME_LEN+1];
3561 format_local_iso_time(buf,expires);
3562 send_control1_event(EVENT_ADDRMAP, ALL_NAMES,
3563 "650 ADDRMAP %s %s \"%s\"\r\n",
3564 from, to, buf);
3567 return 0;
3570 /** The authoritative dirserver has received a new descriptor that
3571 * has passed basic syntax checks and is properly self-signed.
3573 * Notify any interested party of the new descriptor and what has
3574 * been done with it, and also optionally give an explanation/reason. */
3576 control_event_or_authdir_new_descriptor(const char *action,
3577 const char *descriptor,
3578 const char *msg)
3580 char firstline[1024];
3581 char *buf;
3582 int totallen;
3583 char *esc = NULL;
3584 size_t esclen;
3586 if (!EVENT_IS_INTERESTING(EVENT_AUTHDIR_NEWDESCS))
3587 return 0;
3589 tor_snprintf(firstline, sizeof(firstline),
3590 "650+AUTHDIR_NEWDESC=\r\n%s\r\n%s\r\n",
3591 action,
3592 msg ? msg : "");
3594 /* Escape the server descriptor properly */
3595 esclen = write_escaped_data(descriptor, strlen(descriptor), 1, &esc);
3597 totallen = strlen(firstline) + esclen + 1;
3598 buf = tor_malloc(totallen);
3599 strlcpy(buf, firstline, totallen);
3600 strlcpy(buf+strlen(firstline), esc, totallen);
3601 send_control1_event_string(EVENT_AUTHDIR_NEWDESCS, ALL_NAMES|ALL_FORMATS,
3602 buf);
3604 tor_free(esc);
3605 tor_free(buf);
3607 return 0;
3610 /** Called when the local_routerstatus_ts <b>statuses</b> have changed: sends
3611 * an NS event to any controller that cares. */
3613 control_event_networkstatus_changed(smartlist_t *statuses)
3615 smartlist_t *strs;
3616 char *s;
3617 if (!EVENT_IS_INTERESTING(EVENT_NS) || !smartlist_len(statuses))
3618 return 0;
3620 strs = smartlist_create();
3621 smartlist_add(strs, tor_strdup("650+NS\r\n"));
3622 SMARTLIST_FOREACH(statuses, local_routerstatus_t *, rs,
3624 s = networkstatus_getinfo_helper_single(&rs->status);
3625 if (!s) continue;
3626 smartlist_add(strs, s);
3628 smartlist_add(strs, tor_strdup("\r\n.\r\n"));
3630 s = smartlist_join_strings(strs, "", 0, NULL);
3631 SMARTLIST_FOREACH(strs, char *, cp, tor_free(cp));
3632 smartlist_free(strs);
3633 send_control1_event_string(EVENT_NS, ALL_NAMES|ALL_FORMATS, s);
3634 tor_free(s);
3635 return 0;
3638 /** Called when a single local_routerstatus_t has changed: Sends an NS event
3639 * to any countroller that cares. */
3641 control_event_networkstatus_changed_single(local_routerstatus_t *rs)
3643 smartlist_t *statuses;
3644 int r;
3646 if (!EVENT_IS_INTERESTING(EVENT_NS))
3647 return 0;
3649 statuses = smartlist_create();
3650 smartlist_add(statuses, rs);
3651 r = control_event_networkstatus_changed(statuses);
3652 smartlist_free(statuses);
3653 return r;
3656 /** Our own router descriptor has changed; tell any controllers that care.
3659 control_event_my_descriptor_changed(void)
3661 send_control1_event(EVENT_DESCCHANGED, ALL_NAMES, "650 DESCCHANGED\r\n");
3662 return 0;
3665 /** Helper: sents a status event where <b>type</b> is one of
3666 * EVENT_STATUS_{GENERAL,CLIENT,SERVER}, where <b>severity</b> is one of
3667 * LOG_{NOTICE,WARN,ERR}, and where <b>format</b> is a print-style format
3668 * string corresponding to <b>args</b>. */
3669 static int
3670 control_event_status(int type, int severity, const char *format, va_list args)
3672 char format_buf[160];
3673 const char *status, *sev;
3675 switch (type) {
3676 case EVENT_STATUS_GENERAL:
3677 status = "STATUS_GENERAL";
3678 break;
3679 case EVENT_STATUS_CLIENT:
3680 status = "STATUS_CLIENT";
3681 break;
3682 case EVENT_STATUS_SERVER:
3683 status = "STATUS_SEVER";
3684 break;
3685 default:
3686 log_warn(LD_BUG, "Unrecognized status type %d", type);
3687 return -1;
3689 switch (severity) {
3690 case LOG_NOTICE:
3691 sev = "NOTICE";
3692 break;
3693 case LOG_WARN:
3694 sev = "WARN";
3695 break;
3696 case LOG_ERR:
3697 sev = "ERR";
3698 break;
3699 default:
3700 log_warn(LD_BUG, "Unrecognized status severity %d", severity);
3701 return -1;
3703 if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s %s\r\n",
3704 status, sev, format)<0) {
3705 log_warn(LD_BUG, "Format string too long.");
3706 return -1;
3709 send_control1_event_impl(type, ALL_NAMES|ALL_FORMATS, 0, format_buf, args);
3710 return 0;
3713 /** Format and send an EVENT_STATUS_GENERAL event whose main text is obtained
3714 * by formatting the arguments using the printf-style <b>format</b> */
3716 control_event_general_status(int severity, const char *format, ...)
3718 va_list ap;
3719 int r;
3720 if (!EVENT_IS_INTERESTING1(EVENT_STATUS_GENERAL))
3721 return 0;
3723 va_start(ap, format);
3724 r = control_event_status(EVENT_STATUS_GENERAL, severity, format, ap);
3725 va_end(ap);
3726 return r;
3729 /** Format and send an EVENT_STATUS_CLIENT event whose main text is obtained
3730 * by formatting the arguments using the printf-style <b>format</b> */
3732 control_event_client_status(int severity, const char *format, ...)
3734 va_list ap;
3735 int r;
3736 if (!EVENT_IS_INTERESTING1(EVENT_STATUS_CLIENT))
3737 return 0;
3739 va_start(ap, format);
3740 r = control_event_status(EVENT_STATUS_CLIENT, severity, format, ap);
3741 va_end(ap);
3742 return r;
3745 /** Format and send an EVENT_STATUS_SERVER event whose main text is obtained
3746 * by formatting the arguments using the printf-style <b>format</b> */
3748 control_event_server_status(int severity, const char *format, ...)
3750 va_list ap;
3751 int r;
3752 if (!EVENT_IS_INTERESTING1(EVENT_STATUS_SERVER))
3753 return 0;
3755 va_start(ap, format);
3756 r = control_event_status(EVENT_STATUS_SERVER, severity, format, ap);
3757 va_end(ap);
3758 return r;
3761 /** Called when the status of an entry guard with the given <b>nickname</b>
3762 * and identity <b>digest</b> has changed to <b>status</b>: tells any
3763 * controllers that care. */
3765 control_event_guard(const char *nickname, const char *digest,
3766 const char *status)
3768 char hbuf[HEX_DIGEST_LEN+1];
3769 base16_encode(hbuf, sizeof(hbuf), digest, DIGEST_LEN);
3770 if (!EVENT_IS_INTERESTING1(EVENT_GUARD))
3771 return 0;
3773 if (EVENT_IS_INTERESTING1L(EVENT_GUARD)) {
3774 char buf[MAX_VERBOSE_NICKNAME_LEN+1];
3775 routerinfo_t *ri = router_get_by_digest(digest);
3776 if (ri) {
3777 router_get_verbose_nickname(buf, ri);
3778 } else {
3779 tor_snprintf(buf, sizeof(buf), "$%s~%s", hbuf, nickname);
3781 send_control1_event(EVENT_GUARD, LONG_NAMES,
3782 "650 GUARD ENTRY %s %s\r\n", buf, status);
3784 if (EVENT_IS_INTERESTING1S(EVENT_GUARD)) {
3785 send_control1_event(EVENT_GUARD, SHORT_NAMES,
3786 "650 GUARD ENTRY $%s %s\r\n", hbuf, status);
3788 return 0;
3791 /** Choose a random authentication cookie and write it to disk.
3792 * Anybody who can read the cookie from disk will be considered
3793 * authorized to use the control connection. */
3795 init_cookie_authentication(int enabled)
3797 char fname[512];
3799 if (!enabled) {
3800 authentication_cookie_is_set = 0;
3801 return 0;
3804 tor_snprintf(fname, sizeof(fname), "%s/control_auth_cookie",
3805 get_options()->DataDirectory);
3806 crypto_rand(authentication_cookie, AUTHENTICATION_COOKIE_LEN);
3807 authentication_cookie_is_set = 1;
3808 if (write_bytes_to_file(fname, authentication_cookie,
3809 AUTHENTICATION_COOKIE_LEN, 1)) {
3810 log_warn(LD_FS,"Error writing authentication cookie.");
3811 return -1;
3814 return 0;