Migrate a few more files to domained logging
[tor.git] / src / or / control.c
bloba3c65d64f39299d6656b3c05d6329dfb36de3877
1 /* Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
2 /* See LICENSE for licensing information */
3 /* $Id$ */
4 const char control_c_id[] = "$Id$";
6 /**
7 * \file control.c
8 * \brief Implementation for Tor's control-socket interface.
9 **/
11 #define NEW_LOG_INTERFACE
12 #include "or.h"
14 #define STATE_IS_OPEN(s) ((s) == CONTROL_CONN_STATE_OPEN_V0 || \
15 (s) == CONTROL_CONN_STATE_OPEN_V1)
16 #define STATE_IS_V0(s) ((s) == CONTROL_CONN_STATE_NEEDAUTH_V0 || \
17 (s) == CONTROL_CONN_STATE_OPEN_V0)
20 * See control-spec.txt and control-spec-v0.txt for full details on protocol(s).
23 /* Recognized message type codes. */
24 #define CONTROL0_CMD_ERROR 0x0000
25 #define CONTROL0_CMD_DONE 0x0001
26 #define CONTROL0_CMD_SETCONF 0x0002
27 #define CONTROL0_CMD_GETCONF 0x0003
28 #define CONTROL0_CMD_CONFVALUE 0x0004
29 #define CONTROL0_CMD_SETEVENTS 0x0005
30 #define CONTROL0_CMD_EVENT 0x0006
31 #define CONTROL0_CMD_AUTHENTICATE 0x0007
32 #define CONTROL0_CMD_SAVECONF 0x0008
33 #define CONTROL0_CMD_SIGNAL 0x0009
34 #define CONTROL0_CMD_MAPADDRESS 0x000A
35 #define CONTROL0_CMD_GETINFO 0x000B
36 #define CONTROL0_CMD_INFOVALUE 0x000C
37 #define CONTROL0_CMD_EXTENDCIRCUIT 0x000D
38 #define CONTROL0_CMD_ATTACHSTREAM 0x000E
39 #define CONTROL0_CMD_POSTDESCRIPTOR 0x000F
40 #define CONTROL0_CMD_FRAGMENTHEADER 0x0010
41 #define CONTROL0_CMD_FRAGMENT 0x0011
42 #define CONTROL0_CMD_REDIRECTSTREAM 0x0012
43 #define CONTROL0_CMD_CLOSESTREAM 0x0013
44 #define CONTROL0_CMD_CLOSECIRCUIT 0x0014
45 #define _CONTROL0_CMD_MAX_RECOGNIZED 0x0014
47 /* Recognized error codes. */
48 #define ERR_UNSPECIFIED 0x0000
49 #define ERR_INTERNAL 0x0001
50 #define ERR_UNRECOGNIZED_TYPE 0x0002
51 #define ERR_SYNTAX 0x0003
52 #define ERR_UNRECOGNIZED_CONFIG_KEY 0x0004
53 #define ERR_INVALID_CONFIG_VALUE 0x0005
54 #define ERR_UNRECOGNIZED_EVENT_CODE 0x0006
55 #define ERR_UNAUTHORIZED 0x0007
56 #define ERR_REJECTED_AUTHENTICATION 0x0008
57 #define ERR_RESOURCE_EXHAUSETED 0x0009
58 #define ERR_NO_STREAM 0x000A
59 #define ERR_NO_CIRC 0x000B
60 #define ERR_NO_ROUTER 0x000C
62 /* Recognized asynchronous event types. */
63 #define _EVENT_MIN 0x0001
64 #define EVENT_CIRCUIT_STATUS 0x0001
65 #define EVENT_STREAM_STATUS 0x0002
66 #define EVENT_OR_CONN_STATUS 0x0003
67 #define EVENT_BANDWIDTH_USED 0x0004
68 #define EVENT_LOG_OBSOLETE 0x0005
69 #define EVENT_NEW_DESC 0x0006
70 #define EVENT_DEBUG_MSG 0x0007
71 #define EVENT_INFO_MSG 0x0008
72 #define EVENT_NOTICE_MSG 0x0009
73 #define EVENT_WARN_MSG 0x000A
74 #define EVENT_ERR_MSG 0x000B
75 #define LAST_V0_EVENT 0x000B
76 #define EVENT_ADDRMAP 0x000C
77 #define _EVENT_MAX 0x000C
79 /** Array mapping from message type codes to human-readable message
80 * type names. Used for compatibility with version 0 of the control
81 * protocol. */
82 static const char * CONTROL0_COMMANDS[_CONTROL0_CMD_MAX_RECOGNIZED+1] = {
83 "error",
84 "done",
85 "setconf",
86 "getconf",
87 "confvalue",
88 "setevents",
89 "events",
90 "authenticate",
91 "saveconf",
92 "signal",
93 "mapaddress",
94 "getinfo",
95 "infovalue",
96 "extendcircuit",
97 "attachstream",
98 "postdescriptor",
99 "fragmentheader",
100 "fragment",
103 /** Bitfield: The bit 1&lt;&lt;e is set if <b>any</b> open control
104 * connection is interested in events of type <b>e</b>. We use this
105 * so that we can decide to skip generating event messages that nobody
106 * has interest in without having to walk over the global connection
107 * list to find out.
109 static uint32_t global_event_mask0 = 0;
110 static uint32_t global_event_mask1 = 0;
112 /** True iff we have disabled log messages from being sent to the controller */
113 static int disable_log_messages = 0;
115 /** Macro: true if any control connection is interested in events of type
116 * <b>e</b>. */
117 #define EVENT_IS_INTERESTING0(e) (global_event_mask0 & (1<<(e)))
118 #define EVENT_IS_INTERESTING1(e) (global_event_mask1 & (1<<(e)))
119 #define EVENT_IS_INTERESTING(e) \
120 ((global_event_mask0|global_event_mask1) & (1<<(e)))
122 /** If we're using cookie-type authentication, how long should our cookies be?
124 #define AUTHENTICATION_COOKIE_LEN 32
126 /** If true, we've set authentication_cookie to a secret code and
127 * stored it to disk. */
128 static int authentication_cookie_is_set = 0;
129 static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];
131 static void connection_printf_to_buf(connection_t *conn, const char *format, ...)
132 CHECK_PRINTF(2,3);
133 /*static*/ size_t write_escaped_data(const char *data, size_t len,
134 int translate_newlines, char **out);
135 /*static*/ size_t read_escaped_data(const char *data, size_t len,
136 int translate_newlines, char **out);
137 static void send_control0_message(connection_t *conn, uint16_t type,
138 uint32_t len, const char *body);
139 static void send_control_done(connection_t *conn);
140 static void send_control_done2(connection_t *conn, const char *msg, size_t len);
141 static void send_control0_error(connection_t *conn, uint16_t error,
142 const char *message);
143 static void send_control0_event(uint16_t event, uint32_t len, const char *body);
144 static void send_control1_event(uint16_t event, const char *format, ...)
145 CHECK_PRINTF(2,3);
146 static int handle_control_setconf(connection_t *conn, uint32_t len,
147 char *body);
148 static int handle_control_resetconf(connection_t *conn, uint32_t len,
149 char *body);
150 static int handle_control_getconf(connection_t *conn, uint32_t len,
151 const char *body);
152 static int handle_control_setevents(connection_t *conn, uint32_t len,
153 const char *body);
154 static int handle_control_authenticate(connection_t *conn, uint32_t len,
155 const char *body);
156 static int handle_control_saveconf(connection_t *conn, uint32_t len,
157 const char *body);
158 static int handle_control_signal(connection_t *conn, uint32_t len,
159 const char *body);
160 static int handle_control_mapaddress(connection_t *conn, uint32_t len,
161 const char *body);
162 static int handle_control_getinfo(connection_t *conn, uint32_t len,
163 const char *body);
164 static int handle_control_extendcircuit(connection_t *conn, uint32_t len,
165 const char *body);
166 static int handle_control_attachstream(connection_t *conn, uint32_t len,
167 const char *body);
168 static int handle_control_postdescriptor(connection_t *conn, uint32_t len,
169 const char *body);
170 static int handle_control_redirectstream(connection_t *conn, uint32_t len,
171 const char *body);
172 static int handle_control_closestream(connection_t *conn, uint32_t len,
173 const char *body);
174 static int handle_control_closecircuit(connection_t *conn, uint32_t len,
175 const char *body);
176 static int write_stream_target_to_buf(connection_t *conn, char *buf, size_t len);
178 /** Given a possibly invalid message type code <b>cmd</b>, return a
179 * human-readable string equivalent. */
180 static INLINE const char *
181 control_cmd_to_string(uint16_t cmd)
183 return (cmd<=_CONTROL0_CMD_MAX_RECOGNIZED) ? CONTROL0_COMMANDS[cmd] : "Unknown";
186 /** Given a control event code for a message event, return the corresponding
187 * log severity. */
188 static INLINE int
189 event_to_log_severity(int event)
191 switch (event) {
192 case EVENT_DEBUG_MSG: return LOG_DEBUG;
193 case EVENT_INFO_MSG: return LOG_INFO;
194 case EVENT_NOTICE_MSG: return LOG_NOTICE;
195 case EVENT_WARN_MSG: return LOG_WARN;
196 case EVENT_ERR_MSG: return LOG_ERR;
197 default: return -1;
201 /** Given a log severity, return the corresponding control event code. */
202 static INLINE int
203 log_severity_to_event(int severity)
205 switch (severity) {
206 case LOG_DEBUG: return EVENT_DEBUG_MSG;
207 case LOG_INFO: return EVENT_INFO_MSG;
208 case LOG_NOTICE: return EVENT_NOTICE_MSG;
209 case LOG_WARN: return EVENT_WARN_MSG;
210 case LOG_ERR: return EVENT_ERR_MSG;
211 default: return -1;
215 /** Set <b>global_event_maskX</b> (where X is 0 or 1) to the bitwise OR
216 * of each live control connection's event_mask field. */
217 void
218 control_update_global_event_mask(void)
220 connection_t **conns;
221 int n_conns, i;
222 global_event_mask0 = 0;
223 global_event_mask1 = 0;
224 get_connection_array(&conns, &n_conns);
225 for (i = 0; i < n_conns; ++i) {
226 if (conns[i]->type == CONN_TYPE_CONTROL &&
227 STATE_IS_OPEN(conns[i]->state)) {
228 if (STATE_IS_V0(conns[i]->state))
229 global_event_mask0 |= conns[i]->event_mask;
230 else
231 global_event_mask1 |= conns[i]->event_mask;
235 control_adjust_event_log_severity();
238 /** Adjust the log severities that result in control_event_logmsg being called
239 * to match the severity of log messages that any controllers are interested
240 * in. */
241 void
242 control_adjust_event_log_severity(void)
244 int i;
245 int min_log_event=EVENT_ERR_MSG, max_log_event=EVENT_DEBUG_MSG;
247 for (i = EVENT_DEBUG_MSG; i <= EVENT_ERR_MSG; ++i) {
248 if (EVENT_IS_INTERESTING(i)) {
249 min_log_event = i;
250 break;
253 for (i = EVENT_ERR_MSG; i >= EVENT_DEBUG_MSG; --i) {
254 if (EVENT_IS_INTERESTING(i)) {
255 max_log_event = i;
256 break;
259 if (EVENT_IS_INTERESTING(EVENT_LOG_OBSOLETE)) {
260 if (min_log_event > EVENT_NOTICE_MSG)
261 min_log_event = EVENT_NOTICE_MSG;
262 if (max_log_event < EVENT_ERR_MSG)
263 max_log_event = EVENT_ERR_MSG;
265 change_callback_log_severity(event_to_log_severity(min_log_event),
266 event_to_log_severity(max_log_event),
267 control_event_logmsg);
270 /** Append a NUL-terminated string <b>s</b> to the end of
271 * <b>conn</b>-\>outbuf
273 static INLINE void
274 connection_write_str_to_buf(const char *s, connection_t *conn)
276 size_t len = strlen(s);
277 connection_write_to_buf(s, len, conn);
280 /** Given a <b>len</b>-character string in <b>data</b>, made of lines
281 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy
282 * the contents of <b>data</b> into *<b>out</b>, adding a period
283 * before any period that that appears at the start of a line, and
284 * adding a period-CRLF line at the end. If <b>translate_newlines</b>
285 * is true, replace all LF characters sequences with CRLF. Return the
286 * number of bytes in *<b>out</b>.
288 /* static */ size_t
289 write_escaped_data(const char *data, size_t len, int translate_newlines,
290 char **out)
292 size_t sz_out = len+8;
293 char *outp;
294 const char *end;
295 int i;
296 int start_of_line;
297 for (i=0; i<(int)len; ++i) {
298 if (data[i]== '\n')
299 sz_out += 2; /* Maybe add a CR; maybe add a dot. */
301 *out = outp = tor_malloc(sz_out+1);
302 end = data+len;
303 start_of_line = 1;
304 while (data < end) {
305 if (*data == '\n') {
306 if (translate_newlines)
307 *outp++ = '\r';
308 start_of_line = 1;
309 } else if (*data == '.') {
310 if (start_of_line) {
311 start_of_line = 0;
312 *outp++ = '.';
314 } else {
315 start_of_line = 0;
317 *outp++ = *data++;
319 if (outp < *out+2 || memcmp(outp-2, "\r\n", 2)) {
320 *outp++ = '\r';
321 *outp++ = '\n';
323 *outp++ = '.';
324 *outp++ = '\r';
325 *outp++ = '\n';
326 *outp = '\0'; /* NUL-terminate just in case. */
327 tor_assert((outp - *out) <= (int)sz_out);
328 return outp - *out;
331 /** Given a <b>len</b>-character string in <b>data</b>, made of lines
332 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy
333 * the contents of <b>data</b> into *<b>out</b>, removing any period
334 * that appears at the start of a line. If <b>translate_newlines</b>
335 * is true, replace all CRLF sequences with LF. Return the number of
336 * bytes in *<b>out</b>. */
337 /*static*/ size_t
338 read_escaped_data(const char *data, size_t len, int translate_newlines,
339 char **out)
341 char *outp;
342 const char *next;
343 const char *end;
345 *out = outp = tor_malloc(len+1);
347 end = data+len;
349 while (data < end) {
350 if (*data == '.')
351 ++data;
352 if (translate_newlines)
353 next = tor_memmem(data, end-data, "\r\n", 2);
354 else
355 next = tor_memmem(data, end-data, "\r\n.", 3);
356 if (next) {
357 memcpy(outp, data, next-data);
358 outp += (next-data);
359 data = next+2;
360 } else {
361 memcpy(outp, data, end-data);
362 outp += (end-data);
363 *outp = '\0';
364 return outp - *out;
366 if (translate_newlines) {
367 *outp++ = '\n';
368 } else {
369 *outp++ = '\r';
370 *outp++ = '\n';
374 *outp = '\0';
375 return outp - *out;
378 /** Given a pointer to a string starting at <b>start</b> containing
379 * <b>in_len_max</b> characters, decode a string beginning with a single
380 * quote, containing any number of non-quote characters or characters escaped
381 * with a backslash, and ending with a final quote. Place the resulting
382 * string (unquoted, unescaped) into a newly allocated string in *<b>out</b>;
383 * store its length in <b>out_len</b>. On success, return a pointer to the
384 * character immediately following the escaped string. On failure, return
385 * NULL. */
386 static const char *
387 get_escaped_string(const char *start, size_t in_len_max,
388 char **out, size_t *out_len)
390 const char *cp, *end;
391 char *outp;
392 size_t len=0;
394 if (*start != '\"')
395 return NULL;
397 cp = start+1;
398 end = start+in_len_max;
400 /* Calculate length. */
401 while (1) {
402 if (cp >= end)
403 return NULL;
404 else if (*cp == '\\') {
405 if (++cp == end)
406 return NULL; /* Can't escape EOS. */
407 ++cp;
408 ++len;
409 } else if (*cp == '\"') {
410 break;
411 } else {
412 ++cp;
413 ++len;
416 end = cp;
417 outp = *out = tor_malloc(len+1);
418 *out_len = len;
420 cp = start+1;
421 while (cp < end) {
422 if (*cp == '\\')
423 ++cp;
424 *outp++ = *cp++;
426 *outp = '\0';
427 tor_assert((outp - *out) == (int)*out_len);
429 return end+1;
432 /** Acts like sprintf, but writes its formatted string to the end of
433 * <b>conn</b>-\>outbuf. The message may be truncated if it is too long,
434 * but it will always end with a CRLF sequence.
436 * Currently the length of the message is limited to 1024 (including the
437 * ending \n\r\0. */
438 static void
439 connection_printf_to_buf(connection_t *conn, const char *format, ...)
441 #define CONNECTION_PRINTF_TO_BUF_BUFFERSIZE 1024
442 va_list ap;
443 char buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE];
444 int r;
445 size_t len;
446 va_start(ap,format);
447 r = tor_vsnprintf(buf, sizeof(buf), format, ap);
448 va_end(ap);
449 len = strlen(buf);
450 if (memcmp("\r\n\0", buf+len-2, 3)) {
451 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0';
452 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
453 buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
455 connection_write_to_buf(buf, len, conn);
458 /** Send a message of type <b>type</b> containing <b>len</b> bytes
459 * from <b>body</b> along the control connection <b>conn</b> */
460 static void
461 send_control0_message(connection_t *conn, uint16_t type, uint32_t len,
462 const char *body)
464 char buf[10];
465 tor_assert(conn);
466 tor_assert(STATE_IS_V0(conn->state));
467 tor_assert(len || !body);
468 tor_assert(type <= _CONTROL0_CMD_MAX_RECOGNIZED);
469 if (len < 65536) {
470 set_uint16(buf, htons(len));
471 set_uint16(buf+2, htons(type));
472 connection_write_to_buf(buf, 4, conn);
473 if (len)
474 connection_write_to_buf(body, len, conn);
475 } else {
476 set_uint16(buf, htons(65535));
477 set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENTHEADER));
478 set_uint16(buf+4, htons(type));
479 set_uint32(buf+6, htonl(len));
480 connection_write_to_buf(buf, 10, conn);
481 connection_write_to_buf(body, 65535-6, conn);
482 len -= (65535-6);
483 body += (65535-6);
484 while (len) {
485 size_t chunklen = (len<65535)?len:65535;
486 set_uint16(buf, htons((uint16_t)chunklen));
487 set_uint16(buf+2, htons(CONTROL0_CMD_FRAGMENT));
488 connection_write_to_buf(buf, 4, conn);
489 connection_write_to_buf(body, chunklen, conn);
490 len -= chunklen;
491 body += chunklen;
496 /** Send a "DONE" message down the control connection <b>conn</b> */
497 static void
498 send_control_done(connection_t *conn)
500 if (STATE_IS_V0(conn->state)) {
501 send_control0_message(conn, CONTROL0_CMD_DONE, 0, NULL);
502 } else {
503 connection_write_str_to_buf("250 OK\r\n", conn);
507 /** Send a "DONE" message down the v0 control message <b>conn</b>, with body
508 * as provided in the <b>len</b> bytes at <b>msg</b>.
510 static void
511 send_control_done2(connection_t *conn, const char *msg, size_t len)
513 if (len==0)
514 len = strlen(msg);
515 send_control0_message(conn, CONTROL0_CMD_DONE, len, msg);
518 /** Send an error message with error code <b>error</b> and body
519 * <b>message</b> down the connection <b>conn</b> */
520 static void
521 send_control0_error(connection_t *conn, uint16_t error, const char *message)
523 char buf[256];
524 size_t len;
525 set_uint16(buf, htons(error));
526 len = strlen(message);
527 tor_assert(len < (256-2));
528 memcpy(buf+2, message, len);
529 send_control0_message(conn, CONTROL0_CMD_ERROR, (uint16_t)(len+2), buf);
532 /** Send an 'event' message of event type <b>event</b>, containing
533 * <b>len</b> bytes in <b>body</b> to every control connection that
534 * is interested in it. */
535 static void
536 send_control0_event(uint16_t event, uint32_t len, const char *body)
538 connection_t **conns;
539 int n_conns, i;
540 size_t buflen;
541 char *buf;
543 tor_assert(event >= _EVENT_MIN && event <= LAST_V0_EVENT);
545 buflen = len + 2;
546 buf = tor_malloc_zero(buflen);
547 set_uint16(buf, htons(event));
548 memcpy(buf+2, body, len);
550 get_connection_array(&conns, &n_conns);
551 for (i = 0; i < n_conns; ++i) {
552 if (conns[i]->type == CONN_TYPE_CONTROL &&
553 !conns[i]->marked_for_close &&
554 conns[i]->state == CONTROL_CONN_STATE_OPEN_V0 &&
555 conns[i]->event_mask & (1<<event)) {
556 send_control0_message(conns[i], CONTROL0_CMD_EVENT, buflen, buf);
557 if (event == EVENT_ERR_MSG)
558 _connection_controller_force_write(conns[i]);
562 tor_free(buf);
565 /* Send an event to all v1 controllers that are listening for code
566 * <b>event</b>. The event's body is given by <b>msg</b>. */
567 static void
568 send_control1_event_string(uint16_t event, const char *msg)
570 connection_t **conns;
571 int n_conns, i;
573 tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);
575 get_connection_array(&conns, &n_conns);
576 for (i = 0; i < n_conns; ++i) {
577 if (conns[i]->type == CONN_TYPE_CONTROL &&
578 !conns[i]->marked_for_close &&
579 conns[i]->state == CONTROL_CONN_STATE_OPEN_V1 &&
580 conns[i]->event_mask & (1<<event)) {
581 connection_write_to_buf(msg, strlen(msg), conns[i]);
582 if (event == EVENT_ERR_MSG)
583 _connection_controller_force_write(conns[i]);
588 /* Send an event to all v1 controllers that are listening for code
589 * <b>event</b>. The event's body is created by the printf-style format in
590 * <b>format</b>, and other arguments as provided.
592 * Currently the length of the message is limited to 1024 (including the
593 * ending \n\r\0. */
594 static void
595 send_control1_event(uint16_t event, const char *format, ...)
597 #define SEND_CONTROL1_EVENT_BUFFERSIZE 1024
598 int r;
599 char buf[SEND_CONTROL1_EVENT_BUFFERSIZE]; /* XXXX Length */
600 va_list ap;
601 size_t len;
603 va_start(ap, format);
604 r = tor_vsnprintf(buf, sizeof(buf), format, ap);
605 va_end(ap);
607 len = strlen(buf);
608 if (memcmp("\r\n\0", buf+len-2, 3)) {
609 /* if it is not properly terminated, do it now */
610 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0';
611 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n';
612 buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
615 send_control1_event_string(event, buf);
618 /** Given a text circuit <b>id</b>, return the corresponding circuit. */
619 static circuit_t *
620 get_circ(const char *id)
622 unsigned long n_id;
623 int ok;
624 n_id = tor_parse_ulong(id, 10, 0, ULONG_MAX, &ok, NULL);
625 if (!ok)
626 return NULL;
627 return circuit_get_by_global_id(n_id);
630 /** Given a text stream <b>id</b>, return the corresponding AP connection. */
631 static connection_t *
632 get_stream(const char *id)
634 unsigned long n_id;
635 int ok;
636 connection_t *conn;
637 n_id = tor_parse_ulong(id, 10, 0, ULONG_MAX, &ok, NULL);
638 if (!ok)
639 return NULL;
640 conn = connection_get_by_global_id(n_id);
641 if (!conn || conn->type != CONN_TYPE_AP)
642 return NULL;
643 return conn;
646 /** Helper for setconf and resetconf. Acts like setconf, except
647 * it passes <b>use_defaults</b> on to options_trial_assign().
649 static int
650 control_setconf_helper(connection_t *conn, uint32_t len, char *body,
651 int use_defaults, int clear_first)
653 int r;
654 config_line_t *lines=NULL;
655 char *start = body;
656 int v0 = STATE_IS_V0(conn->state);
658 if (!v0) {
659 char *config = tor_malloc(len+1);
660 char *outp = config;
661 while (*body) {
662 char *eq = body;
663 while (!TOR_ISSPACE(*eq) && *eq != '=')
664 ++eq;
665 memcpy(outp, body, eq-body);
666 outp += (eq-body);
667 *outp++ = ' ';
668 body = eq+1;
669 if (*eq == '=') {
670 if (*body != '\"') {
671 while (!TOR_ISSPACE(*body))
672 *outp++ = *body++;
673 } else {
674 char *val;
675 size_t val_len;
676 body = (char*)get_escaped_string(body, (len - (body-start)),
677 &val, &val_len);
678 if (!body) {
679 connection_write_str_to_buf("551 Couldn't parse string\r\n", conn);
680 tor_free(config);
681 return 0;
683 memcpy(outp, val, val_len);
684 outp += val_len;
685 tor_free(val);
688 while (TOR_ISSPACE(*body))
689 ++body;
690 *outp++ = '\n';
692 *outp = '\0';
694 if (config_get_lines(config, &lines) < 0) {
695 warn(LD_CONTROL,"Controller gave us config lines we can't parse.");
696 connection_write_str_to_buf("551 Couldn't parse configuration\r\n", conn);
697 tor_free(config);
698 return 0;
700 tor_free(config);
701 } else {
702 if (config_get_lines(body, &lines) < 0) {
703 warn(LD_CONTROL,"Controller gave us config lines we can't parse.");
704 send_control0_error(conn, ERR_SYNTAX, "Couldn't parse configuration");
705 return 0;
709 if ((r=options_trial_assign(lines, use_defaults, clear_first)) < 0) {
710 int v0_err;
711 const char *msg;
712 warn(LD_CONTROL,"Controller gave us config lines that didn't validate.");
713 switch (r) {
714 case -1:
715 v0_err = ERR_UNRECOGNIZED_CONFIG_KEY;
716 msg = "Unrecognized option";
717 break;
718 case -2:
719 v0_err = ERR_INVALID_CONFIG_VALUE;
720 msg = "Unrecognized option value";
721 break;
722 case -3:
723 v0_err = ERR_INVALID_CONFIG_VALUE;
724 msg = "Transition not allowed";
725 break;
726 case -4:
727 default:
728 v0_err = ERR_INVALID_CONFIG_VALUE;
729 msg = "Unable to set option";
730 break;
732 if (v0) {
733 send_control0_error(conn, v0_err, msg);
734 } else {
735 connection_printf_to_buf(conn, "552 %s\r\n", msg);
737 config_free_lines(lines);
738 return 0;
740 config_free_lines(lines);
741 send_control_done(conn);
742 return 0;
745 /** Called when we receive a SETCONF message: parse the body and try
746 * to update our configuration. Reply with a DONE or ERROR message. */
747 static int
748 handle_control_setconf(connection_t *conn, uint32_t len, char *body)
750 return control_setconf_helper(conn, len, body, 0, 1);
753 /** Called when we receive a RESETCONF message: parse the body and try
754 * to update our configuration. Reply with a DONE or ERROR message. */
755 static int
756 handle_control_resetconf(connection_t *conn, uint32_t len, char *body)
758 int v0 = STATE_IS_V0(conn->state);
759 tor_assert(!v0);
760 return control_setconf_helper(conn, len, body, 1, 1);
763 /** Called when we receive a GETCONF message. Parse the request, and
764 * reply with a CONFVALUE or an ERROR message */
765 static int
766 handle_control_getconf(connection_t *conn, uint32_t body_len, const char *body)
768 smartlist_t *questions = NULL;
769 smartlist_t *answers = NULL;
770 smartlist_t *unrecognized = NULL;
771 char *msg = NULL;
772 size_t msg_len;
773 or_options_t *options = get_options();
774 int v0 = STATE_IS_V0(conn->state);
776 questions = smartlist_create();
777 if (v0) {
778 smartlist_split_string(questions, body, "\n",
779 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
780 } else {
781 smartlist_split_string(questions, body, " ",
782 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
784 answers = smartlist_create();
785 unrecognized = smartlist_create();
786 SMARTLIST_FOREACH(questions, char *, q,
788 if (!option_is_recognized(q)) {
789 if (v0) {
790 send_control0_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, q);
791 goto done;
792 } else {
793 smartlist_add(unrecognized, q);
795 } else {
796 config_line_t *answer = option_get_assignment(options,q);
797 if (!v0 && !answer) {
798 const char *name = option_get_canonical_name(q);
799 size_t alen = strlen(name)+8;
800 char *astr = tor_malloc(alen);
801 tor_snprintf(astr, alen, "250-%s\r\n", name);
802 smartlist_add(answers, astr);
805 while (answer) {
806 config_line_t *next;
807 size_t alen = strlen(answer->key)+strlen(answer->value)+8;
808 char *astr = tor_malloc(alen);
809 if (v0)
810 tor_snprintf(astr, alen, "%s %s\n", answer->key, answer->value);
811 else
812 tor_snprintf(astr, alen, "250-%s=%s\r\n", answer->key, answer->value);
813 smartlist_add(answers, astr);
815 next = answer->next;
816 tor_free(answer->key);
817 tor_free(answer->value);
818 tor_free(answer);
819 answer = next;
824 if (v0) {
825 msg = smartlist_join_strings(answers, "", 0, &msg_len);
826 send_control0_message(conn, CONTROL0_CMD_CONFVALUE,
827 (uint16_t)msg_len, msg_len?msg:NULL);
828 } else {
829 int i,len;
830 if ((len = smartlist_len(unrecognized))) {
831 for (i=0; i < len-1; ++i)
832 connection_printf_to_buf(conn,
833 "552-Unrecognized configuration key \"%s\"\r\n",
834 (char*)smartlist_get(unrecognized, i));
835 connection_printf_to_buf(conn,
836 "552 Unrecognized configuration key \"%s\"\r\n",
837 (char*)smartlist_get(unrecognized, len-1));
838 } else if ((len = smartlist_len(answers))) {
839 char *tmp = smartlist_get(answers, len-1);
840 tor_assert(strlen(tmp)>4);
841 tmp[3] = ' ';
842 msg = smartlist_join_strings(answers, "", 0, &msg_len);
843 connection_write_to_buf(msg, msg_len, conn);
844 } else {
845 connection_write_str_to_buf("250 OK\r\n", conn);
849 done:
850 if (answers) SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
851 if (questions) SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
852 smartlist_free(answers);
853 smartlist_free(questions);
854 smartlist_free(unrecognized);
855 tor_free(msg);
857 return 0;
860 /** Called when we get a SETEVENTS message: update conn->event_mask,
861 * and reply with DONE or ERROR. */
862 static int
863 handle_control_setevents(connection_t *conn, uint32_t len, const char *body)
865 uint16_t event_code;
866 uint32_t event_mask = 0;
867 unsigned int extended = 0;
869 if (STATE_IS_V0(conn->state)) {
870 if (len % 2) {
871 send_control0_error(conn, ERR_SYNTAX,
872 "Odd number of bytes in setevents message");
873 return 0;
876 for (; len; len -= 2, body += 2) {
877 event_code = ntohs(get_uint16(body));
878 if (event_code < _EVENT_MIN || event_code > LAST_V0_EVENT) {
879 send_control0_error(conn, ERR_UNRECOGNIZED_EVENT_CODE,
880 "Unrecognized event code");
881 return 0;
883 event_mask |= (1 << event_code);
885 } else {
886 smartlist_t *events = smartlist_create();
887 smartlist_split_string(events, body, " ",
888 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
889 SMARTLIST_FOREACH(events, const char *, ev,
891 if (!strcasecmp(ev, "EXTENDED")) {
892 extended = 1;
893 continue;
894 } else if (!strcasecmp(ev, "CIRC"))
895 event_code = EVENT_CIRCUIT_STATUS;
896 else if (!strcasecmp(ev, "STREAM"))
897 event_code = EVENT_STREAM_STATUS;
898 else if (!strcasecmp(ev, "ORCONN"))
899 event_code = EVENT_OR_CONN_STATUS;
900 else if (!strcasecmp(ev, "BW"))
901 event_code = EVENT_BANDWIDTH_USED;
902 else if (!strcasecmp(ev, "DEBUG"))
903 event_code = EVENT_DEBUG_MSG;
904 else if (!strcasecmp(ev, "INFO"))
905 event_code = EVENT_INFO_MSG;
906 else if (!strcasecmp(ev, "NOTICE"))
907 event_code = EVENT_NOTICE_MSG;
908 else if (!strcasecmp(ev, "WARN"))
909 event_code = EVENT_WARN_MSG;
910 else if (!strcasecmp(ev, "ERR"))
911 event_code = EVENT_ERR_MSG;
912 else if (!strcasecmp(ev, "NEWDESC"))
913 event_code = EVENT_NEW_DESC;
914 else if (!strcasecmp(ev, "ADDRMAP"))
915 event_code = EVENT_ADDRMAP;
916 else {
917 connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
918 ev);
919 SMARTLIST_FOREACH(events, char *, e, tor_free(e));
920 smartlist_free(events);
921 return 0;
923 event_mask |= (1 << event_code);
925 SMARTLIST_FOREACH(events, char *, e, tor_free(e));
926 smartlist_free(events);
928 conn->event_mask = event_mask;
929 conn->control_events_are_extended = extended;
931 control_update_global_event_mask();
932 send_control_done(conn);
933 return 0;
936 /** Decode the hashed, base64'd password stored in <b>hashed</b>. If
937 * <b>buf</b> is provided, store the hashed password in the first
938 * S2K_SPECIFIER_LEN+DIGEST_LEN bytes of <b>buf</b>. Return 0 on
939 * success, -1 on failure.
942 decode_hashed_password(char *buf, const char *hashed)
944 char decoded[64];
945 if (!strcmpstart(hashed, "16:")) {
946 if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))<0
947 || strlen(hashed+3) != (S2K_SPECIFIER_LEN+DIGEST_LEN)*2) {
948 return -1;
950 } else {
951 if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
952 != S2K_SPECIFIER_LEN+DIGEST_LEN) {
953 return -1;
956 if (buf)
957 memcpy(buf, decoded, S2K_SPECIFIER_LEN+DIGEST_LEN);
958 return 0;
961 /** Called when we get an AUTHENTICATE message. Check whether the
962 * authentication is valid, and if so, update the connection's state to
963 * OPEN. Reply with DONE or ERROR.
965 static int
966 handle_control_authenticate(connection_t *conn, uint32_t len, const char *body)
968 int used_quoted_string = 0;
969 or_options_t *options = get_options();
970 char *password;
971 size_t password_len;
972 if (STATE_IS_V0(conn->state)) {
973 password = (char*)body;
974 password_len = len;
975 } else {
976 if (TOR_ISXDIGIT(body[0])) {
977 int i = 0;
978 while (TOR_ISXDIGIT(body[i]))
979 ++i;
980 password = tor_malloc(i/2 + 1);
981 if (base16_decode(password, i/2+1, body, i)<0) {
982 connection_write_str_to_buf("551 Invalid hexadecimal encoding. Maybe you tried a plain text password? If so, the standard requires you put it in double quotes.\r\n", conn);
983 tor_free(password);
984 return 0;
986 password_len = i/2;
987 } else if (TOR_ISSPACE(body[0])) {
988 password = tor_strdup("");
989 password_len = 0;
990 } else {
991 if (!get_escaped_string(body, len, &password, &password_len)) {
992 connection_write_str_to_buf("551 Invalid quoted string. You need to put the password in double quotes.\r\n", conn);
993 return 0;
995 used_quoted_string = 1;
998 if (options->CookieAuthentication) {
999 if (len == AUTHENTICATION_COOKIE_LEN &&
1000 !memcmp(authentication_cookie, password, password_len)) {
1001 goto ok;
1003 } else if (options->HashedControlPassword) {
1004 char expected[S2K_SPECIFIER_LEN+DIGEST_LEN];
1005 char received[DIGEST_LEN];
1006 if (decode_hashed_password(expected, options->HashedControlPassword)<0) {
1007 warn(LD_CONTROL,"Couldn't decode HashedControlPassword: invalid base16");
1008 goto err;
1010 secret_to_key(received,DIGEST_LEN,password,password_len,expected);
1011 if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
1012 goto ok;
1013 goto err;
1014 } else {
1015 /* if Tor doesn't demand any stronger authentication, then
1016 * the controller can get in with anything. */
1017 goto ok;
1020 err:
1021 if (STATE_IS_V0(conn->state))
1022 send_control0_error(conn,ERR_REJECTED_AUTHENTICATION,"Authentication failed");
1023 else {
1024 tor_free(password);
1025 if (used_quoted_string)
1026 connection_write_str_to_buf("515 Authentication failed\r\n", conn);
1027 else
1028 connection_write_str_to_buf("515 Authentication failed. Maybe you tried a plain text password? If so, the standard requires you put it in double quotes.\r\n", conn);
1030 return 0;
1032 info(LD_CONTROL, "Authenticated control connection (%d)", conn->s);
1033 send_control_done(conn);
1034 if (STATE_IS_V0(conn->state))
1035 conn->state = CONTROL_CONN_STATE_OPEN_V0;
1036 else {
1037 conn->state = CONTROL_CONN_STATE_OPEN_V1;
1038 tor_free(password);
1040 return 0;
1043 /** Called when we get a SAVECONF command. Try to flush the current options to
1044 * disk, and report success or failure. */
1045 static int
1046 handle_control_saveconf(connection_t *conn, uint32_t len,
1047 const char *body)
1049 if (options_save_current()<0) {
1050 if (STATE_IS_V0(conn->state))
1051 send_control0_error(conn, ERR_INTERNAL,
1052 "Unable to write configuration to disk.");
1053 else
1054 connection_write_str_to_buf("551 Unable to write configuration to disk.",
1055 conn);
1056 } else {
1057 send_control_done(conn);
1059 return 0;
1062 /** Called when we get a SIGNAL command. React to the provided signal, and
1063 * report success or failure. (If the signal results in a shutdown, success
1064 * may not be reported.) */
1065 static int
1066 handle_control_signal(connection_t *conn, uint32_t len,
1067 const char *body)
1069 int sig;
1070 if (STATE_IS_V0(conn->state)) {
1071 if (len != 1) {
1072 send_control0_error(conn, ERR_SYNTAX,
1073 "Body of SIGNAL command too long or too short.");
1074 return 0;
1075 } else {
1076 sig = (uint8_t)body[0];
1078 } else {
1079 int n = 0;
1080 char *s;
1081 while (body[n] && ! TOR_ISSPACE(body[n]))
1082 ++n;
1083 s = tor_strndup(body, n);
1084 if (!strcasecmp(s, "RELOAD") || !strcasecmp(s, "HUP"))
1085 sig = SIGHUP;
1086 else if (!strcasecmp(s, "SHUTDOWN") || !strcasecmp(s, "INT"))
1087 sig = SIGINT;
1088 else if (!strcasecmp(s, "DUMP") || !strcasecmp(s, "USR1"))
1089 sig = SIGUSR1;
1090 else if (!strcasecmp(s, "DEBUG") || !strcasecmp(s, "USR2"))
1091 sig = SIGUSR2;
1092 else if (!strcasecmp(s, "HALT") || !strcasecmp(s, "TERM"))
1093 sig = SIGTERM;
1094 else {
1095 connection_printf_to_buf(conn, "552 Unrecognized signal code \"%s\"\r\n",
1096 body);
1097 sig = -1;
1099 tor_free(s);
1100 if (sig<0)
1101 return 0;
1104 if (control_signal_act(sig) < 0) {
1105 if (STATE_IS_V0(conn->state))
1106 send_control0_error(conn, ERR_SYNTAX, "Unrecognized signal number.");
1107 else
1108 connection_write_str_to_buf("551 Internal error acting on signal\r\n",
1109 conn);
1110 } else {
1111 send_control_done(conn);
1113 return 0;
1116 /** Called when we get a MAPADDRESS command; try to bind all listed addresses,
1117 * and report success or failrue. */
1118 static int
1119 handle_control_mapaddress(connection_t *conn, uint32_t len, const char *body)
1121 smartlist_t *elts;
1122 smartlist_t *lines;
1123 smartlist_t *reply;
1124 char *r;
1125 size_t sz;
1126 int v0 = STATE_IS_V0(conn->state);
1127 lines = smartlist_create();
1128 elts = smartlist_create();
1129 reply = smartlist_create();
1130 if (v0)
1131 smartlist_split_string(lines, body, "\n",
1132 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1133 else
1134 smartlist_split_string(lines, body, " ",
1135 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1136 /* XXXX Make errors conformant. */
1137 SMARTLIST_FOREACH(lines, char *, line,
1139 tor_strlower(line);
1140 if (v0)
1141 smartlist_split_string(elts, line, " ", 0, 2);
1142 else
1143 smartlist_split_string(elts, line, "=", 0, 2);
1144 if (smartlist_len(elts) == 2) {
1145 const char *from = smartlist_get(elts,0);
1146 const char *to = smartlist_get(elts,1);
1147 if (!is_plausible_address(from)) {
1148 warn(LD_CONTROL,"Skipping invalid argument '%s' in MapAddress msg",from);
1149 } else if (!is_plausible_address(to)) {
1150 warn(LD_CONTROL,"Skipping invalid argument '%s' in MapAddress msg",to);
1151 } else if (!strcmp(from, ".") || !strcmp(from, "0.0.0.0")) {
1152 const char *address = addressmap_register_virtual_address(
1153 !strcmp(from,".") ? RESOLVED_TYPE_HOSTNAME : RESOLVED_TYPE_IPV4,
1154 tor_strdup(to));
1155 if (!address) {
1156 warn(LD_CONTROL,
1157 "Unable to allocate address for '%s' in MapAddress msg",
1158 safe_str(line));
1159 } else {
1160 size_t anslen = strlen(address)+strlen(to)+8;
1161 char *ans = tor_malloc(anslen);
1162 if (v0)
1163 tor_snprintf(ans, anslen, "%s %s", address, to);
1164 else
1165 tor_snprintf(ans, anslen, "250-%s=%s", address, to);
1166 smartlist_add(reply, ans);
1168 } else {
1169 addressmap_register(from, tor_strdup(to), 1);
1170 if (v0)
1171 smartlist_add(reply, tor_strdup(line));
1172 else {
1173 size_t anslen = strlen(line)+8;
1174 char *ans = tor_malloc(anslen);
1175 tor_snprintf(ans, anslen, "250-%s", line);
1176 smartlist_add(reply, ans);
1179 } else {
1180 warn(LD_CONTROL, "Skipping MapAddress line with wrong number of items.");
1182 SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
1183 smartlist_clear(elts);
1185 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
1186 smartlist_free(lines);
1187 smartlist_free(elts);
1189 if (v0) {
1190 r = smartlist_join_strings(reply, "\n", 1, &sz);
1191 send_control_done2(conn,r,sz);
1192 } else {
1193 if (smartlist_len(reply))
1194 ((char*)smartlist_get(reply,smartlist_len(reply)-1))[3] = ' ';
1195 r = smartlist_join_strings(reply, "\r\n", 1, &sz);
1196 connection_write_to_buf(r, sz, conn);
1199 SMARTLIST_FOREACH(reply, char *, cp, tor_free(cp));
1200 smartlist_free(reply);
1201 tor_free(r);
1202 return 0;
1205 /** Return a newly allocated string listing all valid GETINFO fields as
1206 * required by GETINFO info/names. */
1207 static char *
1208 list_getinfo_options(void)
1210 return tor_strdup(
1211 "accounting/bytes Number of bytes read/written so far in interval.\n"
1212 "accounting/bytes-left Number of bytes left to read/write in interval.\n"
1213 "accounting/enabled Is accounting currently enabled?\n"
1214 "accounting/hibernating Are we hibernating or awake?\n"
1215 "accounting/interval-end Time when interval ends.\n"
1216 "accounting/interval-start Time when interval starts.\n"
1217 "accounting/interval-wake Time to wake up in this interval.\n"
1218 "addr-mappings/all All current remapped addresses.\n"
1219 "addr-mappings/cache Addresses remapped by DNS cache.\n"
1220 "addr-mappings/configl Addresses remapped from configuration options.\n"
1221 "addr-mappings/control Addresses remapped by a controller.\n"
1222 "circuit-status Status of each current circuit.\n"
1223 "config/names List of configuration options, types, and documentation.\n"
1224 "desc/id/* Server descriptor by hex ID\n"
1225 "desc/name/* Server descriptor by nickname.\n"
1226 "helper-nodes Which nodes will we use as helpers?\n"
1227 "info/names List of GETINFO options, types, and documentation.\n"
1228 "network-status List of hex IDs, nicknames, server statuses.\n"
1229 "orconn-status Status of each current OR connection.\n"
1230 "stream-status Status of each current application stream.\n"
1231 "version The current version of Tor.\n");
1234 /** Lookup the 'getinfo' entry <b>question</b>, and return
1235 * the answer in <b>*answer</b> (or NULL if key not recognized).
1236 * Return 0 if success, or -1 if internal error. */
1237 static int
1238 handle_getinfo_helper(const char *question, char **answer)
1240 *answer = NULL; /* unrecognized key by default */
1241 if (!strcmp(question, "version")) {
1242 *answer = tor_strdup(VERSION);
1243 } else if (!strcmp(question, "config-file")) {
1244 *answer = tor_strdup(get_torrc_fname());
1245 } else if (!strcmpstart(question, "accounting/")) {
1246 return accounting_getinfo_helper(question, answer);
1247 } else if (!strcmpstart(question, "helper-nodes")) {
1248 return helper_nodes_getinfo_helper(question, answer);
1249 } else if (!strcmpstart(question, "config/")) {
1250 return config_getinfo_helper(question, answer);
1251 } else if (!strcmp(question, "info/names")) {
1252 *answer = list_getinfo_options();
1253 } else if (!strcmpstart(question, "desc/id/")) {
1254 routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
1255 if (ri && ri->signed_descriptor)
1256 *answer = tor_strdup(ri->signed_descriptor);
1257 } else if (!strcmpstart(question, "desc/name/")) {
1258 routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"),1);
1259 if (ri && ri->signed_descriptor)
1260 *answer = tor_strdup(ri->signed_descriptor);
1261 } else if (!strcmpstart(question, "unregistered-servers-")) {
1262 *answer = dirserver_getinfo_unregistered(question +
1263 strlen("unregistered-servers-"));
1264 } else if (!strcmp(question, "network-status")) {
1265 routerlist_t *routerlist = router_get_routerlist();
1266 if (!routerlist || !routerlist->routers ||
1267 list_server_status(routerlist->routers, answer) < 0) {
1268 return -1;
1270 } else if (!strcmp(question, "circuit-status")) {
1271 circuit_t *circ;
1272 smartlist_t *status = smartlist_create();
1273 for (circ = _circuit_get_global_list(); circ; circ = circ->next) {
1274 char *s, *path;
1275 size_t slen;
1276 const char *state;
1277 if (! CIRCUIT_IS_ORIGIN(circ) || circ->marked_for_close)
1278 continue;
1279 path = circuit_list_path(circ,0);
1280 if (circ->state == CIRCUIT_STATE_OPEN)
1281 state = "BUILT";
1282 else if (strlen(path))
1283 state = "EXTENDED";
1284 else
1285 state = "LAUNCHED";
1287 slen = strlen(path)+strlen(state)+20;
1288 s = tor_malloc(slen+1);
1289 tor_snprintf(s, slen, "%lu %s %s", (unsigned long)circ->global_identifier,
1290 state, path);
1291 smartlist_add(status, s);
1292 tor_free(path);
1294 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1295 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1296 smartlist_free(status);
1297 } else if (!strcmp(question, "stream-status")) {
1298 connection_t **conns;
1299 int n_conns, i;
1300 char buf[256];
1301 smartlist_t *status = smartlist_create();
1302 get_connection_array(&conns, &n_conns);
1303 for (i=0; i < n_conns; ++i) {
1304 const char *state;
1305 char *s;
1306 size_t slen;
1307 circuit_t *circ;
1308 if (conns[i]->type != CONN_TYPE_AP ||
1309 conns[i]->marked_for_close ||
1310 conns[i]->state == AP_CONN_STATE_SOCKS_WAIT)
1311 continue;
1312 switch (conns[i]->state)
1314 case AP_CONN_STATE_CONTROLLER_WAIT:
1315 case AP_CONN_STATE_CIRCUIT_WAIT:
1316 if (conns[i]->socks_request &&
1317 conns[i]->socks_request->command == SOCKS_COMMAND_RESOLVE)
1318 state = "NEWRESOLVE";
1319 else
1320 state = "NEW";
1321 break;
1322 case AP_CONN_STATE_RENDDESC_WAIT:
1323 case AP_CONN_STATE_CONNECT_WAIT:
1324 state = "SENTCONNECT"; break;
1325 case AP_CONN_STATE_RESOLVE_WAIT:
1326 state = "SENTRESOLVE"; break;
1327 case AP_CONN_STATE_OPEN:
1328 state = "SUCCEEDED"; break;
1329 default:
1330 warn(LD_GENERAL, "Asked for stream in unknown state %d",
1331 conns[i]->state);
1332 continue;
1334 circ = circuit_get_by_edge_conn(conns[i]);
1335 write_stream_target_to_buf(conns[i], buf, sizeof(buf));
1336 slen = strlen(buf)+strlen(state)+32;
1337 s = tor_malloc(slen+1);
1338 tor_snprintf(s, slen, "%lu %s %lu %s",
1339 (unsigned long) conns[i]->global_identifier,state,
1340 circ?(unsigned long)circ->global_identifier : 0ul,
1341 buf);
1342 smartlist_add(status, s);
1344 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1345 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1346 smartlist_free(status);
1347 } else if (!strcmp(question, "orconn-status")) {
1348 connection_t **conns;
1349 int n_conns, i;
1350 smartlist_t *status = smartlist_create();
1351 get_connection_array(&conns, &n_conns);
1352 for (i=0; i < n_conns; ++i) {
1353 const char *state;
1354 char *s;
1355 size_t slen;
1356 if (conns[i]->type != CONN_TYPE_OR || conns[i]->marked_for_close)
1357 continue;
1358 if (conns[i]->state == OR_CONN_STATE_OPEN)
1359 state = "CONNECTED";
1360 else
1361 state = "LAUNCHED";
1362 slen = strlen(conns[i]->nickname)+strlen(state)+2;
1363 s = tor_malloc(slen+1);
1364 tor_snprintf(s, slen, "%s %s",conns[i]->nickname,state);
1365 smartlist_add(status, s);
1367 *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
1368 SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
1369 smartlist_free(status);
1370 } else if (!strcmpstart(question, "addr-mappings/")) {
1371 time_t min_e, max_e;
1372 smartlist_t *mappings;
1373 if (!strcmp(question, "addr-mappings/all")) {
1374 min_e = 0; max_e = TIME_MAX;
1375 } else if (!strcmp(question, "addr-mappings/cache")) {
1376 min_e = 2; max_e = TIME_MAX;
1377 } else if (!strcmp(question, "addr-mappings/config")) {
1378 min_e = 0; max_e = 0;
1379 } else if (!strcmp(question, "addr-mappings/control")) {
1380 min_e = 1; max_e = 1;
1381 } else {
1382 return 0;
1384 mappings = smartlist_create();
1385 addressmap_get_mappings(mappings, min_e, max_e);
1386 *answer = smartlist_join_strings(mappings, "\n", 0, NULL);
1387 SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
1388 smartlist_free(mappings);
1390 return 0;
1393 /** Called when we receive a GETINFO command. Try to fetch all requested
1394 * information, and reply with information or error message. */
1395 static int
1396 handle_control_getinfo(connection_t *conn, uint32_t len, const char *body)
1398 smartlist_t *questions = NULL;
1399 smartlist_t *answers = NULL;
1400 smartlist_t *unrecognized = NULL;
1401 char *msg = NULL, *ans = NULL;
1402 size_t msg_len;
1403 int v0 = STATE_IS_V0(conn->state);
1405 questions = smartlist_create();
1406 if (v0)
1407 smartlist_split_string(questions, body, "\n",
1408 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1409 else
1410 smartlist_split_string(questions, body, " ",
1411 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1412 answers = smartlist_create();
1413 unrecognized = smartlist_create();
1414 SMARTLIST_FOREACH(questions, const char *, q,
1416 if (handle_getinfo_helper(q, &ans) < 0) {
1417 if (v0)
1418 send_control0_error(conn, ERR_INTERNAL, body);
1419 else
1420 connection_write_str_to_buf("551 Internal error\r\n", conn);
1421 goto done;
1423 if (!ans) {
1424 if (v0) {
1425 send_control0_error(conn, ERR_UNRECOGNIZED_CONFIG_KEY, body);
1426 goto done;
1427 } else
1428 smartlist_add(unrecognized, (char*)q);
1429 } else {
1430 smartlist_add(answers, tor_strdup(q));
1431 smartlist_add(answers, ans);
1434 if (smartlist_len(unrecognized)) {
1435 int i;
1436 tor_assert(!v0);
1437 for (i=0; i < smartlist_len(unrecognized)-1; ++i)
1438 connection_printf_to_buf(conn,
1439 "552-Unrecognized key \"%s\"\r\n",
1440 (char*)smartlist_get(unrecognized, i));
1441 connection_printf_to_buf(conn,
1442 "552 Unrecognized key \"%s\"\r\n",
1443 (char*)smartlist_get(unrecognized, i));
1444 goto done;
1447 if (v0) {
1448 msg = smartlist_join_strings2(answers, "\0", 1, 1, &msg_len);
1449 tor_assert(msg_len > 0); /* it will at least be terminated */
1450 send_control0_message(conn, CONTROL0_CMD_INFOVALUE,
1451 msg_len, msg);
1452 } else if (smartlist_len(answers)) {
1453 int i;
1454 for (i = 0; i < smartlist_len(answers); i += 2) {
1455 char *k = smartlist_get(answers, i);
1456 char *v = smartlist_get(answers, i+1);
1457 /*XXXX Not an adequate test! XXXX011 */
1458 if (!strchr(v, '\n') && !strchr(v, '\r')) {
1459 connection_printf_to_buf(conn, "250-%s=", k);
1460 connection_write_str_to_buf(v, conn);
1461 connection_write_str_to_buf("\r\n", conn);
1462 } else {
1463 char *esc = NULL;
1464 size_t len;
1465 len = write_escaped_data(v, strlen(v), 1, &esc);
1466 connection_printf_to_buf(conn, "250+%s=\r\n", k);
1467 connection_write_to_buf(esc, len, conn);
1468 tor_free(esc);
1471 connection_write_str_to_buf("250 OK\r\n", conn);
1474 done:
1475 if (answers) SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
1476 if (questions) SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
1477 smartlist_free(answers);
1478 smartlist_free(questions);
1479 smartlist_free(unrecognized);
1480 tor_free(msg);
1482 return 0;
1485 /** Called when we get an EXTENDCIRCUIT message. Try to extend the listed
1486 * circuit, and report success or failure. */
1487 static int
1488 handle_control_extendcircuit(connection_t *conn, uint32_t len,
1489 const char *body)
1491 smartlist_t *router_nicknames=NULL, *routers=NULL;
1492 uint32_t circ_id;
1493 circuit_t *circ = NULL;
1494 int zero_circ, v0;
1495 char reply[4];
1497 v0 = STATE_IS_V0(conn->state);
1498 router_nicknames = smartlist_create();
1500 if (v0) {
1501 if (len<5) {
1502 send_control0_error(conn, ERR_SYNTAX, "extendcircuit message too short");
1503 goto done;
1505 smartlist_split_string(router_nicknames, body+4, ",", 0, 0);
1506 circ_id = ntohl(get_uint32(body));
1507 if (!circ_id) {
1508 /* start a new circuit */
1509 zero_circ = 1;
1510 } else {
1511 circ = circuit_get_by_global_id(circ_id);
1512 zero_circ = 0;
1513 if (!circ) {
1514 send_control0_error(conn, ERR_NO_CIRC,
1515 "No circuit found with given ID");
1516 goto done;
1519 } else { /* v1 */
1520 smartlist_t *args;
1521 args = smartlist_create();
1522 smartlist_split_string(args, body, " ",
1523 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1524 if (smartlist_len(args)<2)
1525 connection_printf_to_buf(conn,"512 Missing argument to EXTENDCIRCUIT\r\n");
1527 zero_circ = !strcmp("0", (char*)smartlist_get(args,0));
1528 if (!zero_circ && !(circ = get_circ(smartlist_get(args,0)))) {
1529 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
1530 (char*)smartlist_get(args, 0));
1532 smartlist_split_string(router_nicknames, smartlist_get(args,1), ",", 0, 0);
1534 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
1535 smartlist_free(args);
1536 if (!zero_circ && !circ) {
1537 goto done;
1541 routers = smartlist_create();
1542 SMARTLIST_FOREACH(router_nicknames, const char *, n,
1544 routerinfo_t *r = router_get_by_nickname(n, 1);
1545 if (!r) {
1546 if (v0)
1547 send_control0_error(conn, ERR_NO_ROUTER, n);
1548 else
1549 connection_printf_to_buf(conn, "552 No such router \"%s\"\r\n", n);
1550 goto done;
1552 smartlist_add(routers, r);
1554 if (!smartlist_len(routers)) {
1555 if (v0)
1556 send_control0_error(conn, ERR_SYNTAX, "No router names provided");
1557 else
1558 connection_write_str_to_buf("512 No router names provided\r\n", conn);
1559 goto done;
1562 if (zero_circ) {
1563 /* start a new circuit */
1564 circ = circuit_init(CIRCUIT_PURPOSE_C_GENERAL, 0, 0, 0);
1567 /* now circ refers to something that is ready to be extended */
1568 SMARTLIST_FOREACH(routers, routerinfo_t *, r,
1570 extend_info_t *info = extend_info_from_router(r);
1571 circuit_append_new_exit(circ, info);
1572 extend_info_free(info);
1575 /* now that we've populated the cpath, start extending */
1576 if (zero_circ) {
1577 if (circuit_handle_first_hop(circ) < 0) {
1578 circuit_mark_for_close(circ);
1579 if (v0)
1580 send_control0_error(conn, ERR_INTERNAL, "couldn't start circuit");
1581 else
1582 connection_write_str_to_buf("551 Couldn't start circuit\r\n", conn);
1583 goto done;
1585 } else {
1586 if (circ->state == CIRCUIT_STATE_OPEN) {
1587 circ->state = CIRCUIT_STATE_BUILDING;
1588 if (circuit_send_next_onion_skin(circ) < 0) {
1589 info(LD_CONTROL,"send_next_onion_skin failed; circuit marked for closing.");
1590 circuit_mark_for_close(circ);
1591 if (v0)
1592 send_control0_error(conn, ERR_INTERNAL, "couldn't send onion skin");
1593 else
1594 connection_write_str_to_buf("551 Couldn't send onion skinr\n", conn);
1595 goto done;
1600 if (v0) {
1601 set_uint32(reply, htonl(circ->global_identifier));
1602 send_control_done2(conn, reply, sizeof(reply));
1603 } else {
1604 connection_printf_to_buf(conn, "250 EXTENDED %lu\r\n",
1605 (unsigned long)circ->global_identifier);
1607 done:
1608 SMARTLIST_FOREACH(router_nicknames, char *, n, tor_free(n));
1609 smartlist_free(router_nicknames);
1610 if (routers)
1611 smartlist_free(routers);
1612 return 0;
1615 /** Called when we get an ATTACHSTREAM message. Try to attach the requested
1616 * stream, and report success or failure. */
1617 static int
1618 handle_control_attachstream(connection_t *conn, uint32_t len,
1619 const char *body)
1621 connection_t *ap_conn = NULL;
1622 circuit_t *circ = NULL;
1623 int zero_circ;
1625 if (STATE_IS_V0(conn->state)) {
1626 uint32_t conn_id;
1627 uint32_t circ_id;
1628 if (len < 8) {
1629 send_control0_error(conn, ERR_SYNTAX, "attachstream message too short");
1630 return 0;
1633 conn_id = ntohl(get_uint32(body));
1634 circ_id = ntohl(get_uint32(body+4));
1635 zero_circ = circ_id == 0;
1637 if (!(ap_conn = connection_get_by_global_id(conn_id))) {
1638 send_control0_error(conn, ERR_NO_STREAM,
1639 "No connection found with given ID");
1640 return 0;
1642 if (circ_id && !(circ = circuit_get_by_global_id(circ_id))) {
1643 send_control0_error(conn, ERR_NO_CIRC, "No circuit found with given ID");
1644 return 0;
1646 } else {
1647 smartlist_t *args;
1648 args = smartlist_create();
1649 smartlist_split_string(args, body, " ",
1650 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1651 if (smartlist_len(args)<2)
1652 connection_printf_to_buf(conn,"512 Missing argument to ATTACHSTREAM\r\n");
1654 zero_circ = !strcmp("0", (char*)smartlist_get(args,1));
1656 if (!(ap_conn = get_stream(smartlist_get(args, 0)))) {
1657 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
1658 (char*)smartlist_get(args, 0));
1659 } else if (!zero_circ && !(circ = get_circ(smartlist_get(args, 1)))) {
1660 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
1661 (char*)smartlist_get(args, 1));
1663 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
1664 smartlist_free(args);
1665 if (!ap_conn || (!zero_circ && !circ))
1666 return 0;
1669 if (ap_conn->state != AP_CONN_STATE_CONTROLLER_WAIT) {
1670 if (STATE_IS_V0(conn->state)) {
1671 send_control0_error(conn, ERR_NO_STREAM,
1672 "Connection is not managed by controller.");
1673 } else {
1674 connection_write_str_to_buf(
1675 "555 Connection is not managed by controller.\r\n",
1676 conn);
1678 return 0;
1681 if (zero_circ) {
1682 ap_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
1683 if (connection_ap_handshake_attach_circuit(ap_conn)<0)
1684 connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_CANT_ATTACH);
1685 send_control_done(conn);
1686 return 0;
1688 if (circ->state != CIRCUIT_STATE_OPEN) {
1689 if (STATE_IS_V0(conn->state))
1690 send_control0_error(conn, ERR_INTERNAL, "Refuse to attach stream to non-open circ.");
1691 else
1692 connection_write_str_to_buf(
1693 "551 Can't attach stream to non-open circuit\r\n",
1694 conn);
1695 return 0;
1697 if (connection_ap_handshake_attach_chosen_circuit(ap_conn, circ) != 1) {
1698 if (STATE_IS_V0(conn->state))
1699 send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
1700 else
1701 connection_write_str_to_buf("551 Unable to attach stream\r\n", conn);
1702 return 0;
1704 send_control_done(conn);
1705 return 0;
1708 /** Called when we get a POSTDESCRIPTOR message. Try to learn the provided
1709 * descriptor, and report success or failure. */
1710 static int
1711 handle_control_postdescriptor(connection_t *conn, uint32_t len,
1712 const char *body)
1714 char *desc;
1715 int v0 = STATE_IS_V0(conn->state);
1716 const char *msg=NULL;
1718 if (v0)
1719 desc = (char*)body;
1720 else {
1721 const char *cp = memchr(body, '\n', len);
1722 tor_assert(cp);
1723 read_escaped_data(cp, len-(cp-body), 1, &desc);
1726 switch (router_load_single_router(desc, &msg)) {
1727 case -1:
1728 if (!msg) msg = "Could not parse descriptor";
1729 if (v0)
1730 send_control0_error(conn,ERR_SYNTAX,msg);
1731 else
1732 connection_printf_to_buf(conn, "554 %s\r\n", msg);
1733 break;
1734 case 0:
1735 if (!msg) msg = "Descriptor not added";
1736 if (v0)
1737 send_control_done2(conn,msg,0);
1738 else
1739 connection_printf_to_buf(conn, "251 %s\r\n",msg);
1740 break;
1741 case 1:
1742 send_control_done(conn);
1743 break;
1746 if (!v0)
1747 tor_free(desc);
1748 return 0;
1751 /** Called when we receive a REDIRECTSTERAM command. Try to change the target
1752 * adderess of the named AP steream, and report success or failure. */
1753 static int
1754 handle_control_redirectstream(connection_t *conn, uint32_t len,
1755 const char *body)
1757 connection_t *ap_conn = NULL;
1758 uint32_t conn_id;
1759 char *new_addr = NULL;
1760 if (STATE_IS_V0(conn->state)) {
1761 if (len < 6) {
1762 send_control0_error(conn, ERR_SYNTAX, "redirectstream message too short");
1763 return 0;
1765 conn_id = ntohl(get_uint32(body));
1767 if (!(ap_conn = connection_get_by_global_id(conn_id))
1768 || ap_conn->state != CONN_TYPE_AP
1769 || !ap_conn->socks_request) {
1770 send_control0_error(conn, ERR_NO_STREAM,
1771 "No AP connection found with given ID");
1772 return 0;
1774 new_addr = tor_strdup(body+4);
1775 } else {
1776 smartlist_t *args;
1777 args = smartlist_create();
1778 smartlist_split_string(args, body, " ",
1779 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1780 if (smartlist_len(args)<2)
1781 connection_printf_to_buf(conn,"512 Missing argument to REDIRECTSTREAM\r\n");
1782 else if (!(ap_conn = get_stream(smartlist_get(args, 0)))
1783 || !ap_conn->socks_request) {
1784 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
1785 (char*)smartlist_get(args, 0));
1786 } else {
1787 new_addr = tor_strdup(smartlist_get(args, 1));
1790 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
1791 smartlist_free(args);
1792 if (!new_addr)
1793 return 0;
1796 strlcpy(ap_conn->socks_request->address, new_addr,
1797 sizeof(ap_conn->socks_request->address));
1798 tor_free(new_addr);
1799 send_control_done(conn);
1800 return 0;
1803 /** Called when we get a CLOSESTREAM command; try to close the named stream
1804 * and report success or failure. */
1805 static int
1806 handle_control_closestream(connection_t *conn, uint32_t len,
1807 const char *body)
1809 connection_t *ap_conn=NULL;
1810 uint8_t reason=0;
1812 if (STATE_IS_V0(conn->state)) {
1813 uint32_t conn_id;
1814 if (len < 6) {
1815 send_control0_error(conn, ERR_SYNTAX, "closestream message too short");
1816 return 0;
1819 conn_id = ntohl(get_uint32(body));
1820 reason = *(uint8_t*)(body+4);
1822 if (!(ap_conn = connection_get_by_global_id(conn_id))
1823 || ap_conn->state != CONN_TYPE_AP
1824 || !ap_conn->socks_request) {
1825 send_control0_error(conn, ERR_NO_STREAM,
1826 "No AP connection found with given ID");
1827 return 0;
1829 } else {
1830 smartlist_t *args;
1831 int ok;
1832 args = smartlist_create();
1833 smartlist_split_string(args, body, " ",
1834 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1835 if (smartlist_len(args)<2)
1836 connection_printf_to_buf(conn, "512 Missing argument to CLOSESTREAM\r\n");
1837 else if (!(ap_conn = get_stream(smartlist_get(args, 0))))
1838 connection_printf_to_buf(conn, "552 Unknown stream \"%s\"\r\n",
1839 (char*)smartlist_get(args, 0));
1840 else {
1841 reason = (uint8_t) tor_parse_ulong(smartlist_get(args,1), 10, 0, 255,
1842 &ok, NULL);
1843 if (!ok) {
1844 connection_printf_to_buf(conn, "552 Unrecognized reason \"%s\"\r\n",
1845 (char*)smartlist_get(args, 1));
1846 ap_conn = NULL;
1849 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
1850 smartlist_free(args);
1851 if (!ap_conn)
1852 return 0;
1855 connection_mark_unattached_ap(ap_conn, reason);
1856 send_control_done(conn);
1857 return 0;
1860 /** Called when we get a CLOSECIRCUIT command; try to close the named circuit
1861 * and report success or failure. */
1862 static int
1863 handle_control_closecircuit(connection_t *conn, uint32_t len,
1864 const char *body)
1866 circuit_t *circ = NULL;
1867 int safe = 0;
1869 if (STATE_IS_V0(conn->state)) {
1870 uint32_t circ_id;
1871 if (len < 5) {
1872 send_control0_error(conn, ERR_SYNTAX, "closecircuit message too short");
1873 return 0;
1875 circ_id = ntohl(get_uint32(body));
1876 safe = (*(uint8_t*)(body+4)) & 1;
1878 if (!(circ = circuit_get_by_global_id(circ_id))) {
1879 send_control0_error(conn, ERR_NO_CIRC,
1880 "No circuit found with given ID");
1881 return 0;
1883 } else {
1884 smartlist_t *args;
1885 args = smartlist_create();
1886 smartlist_split_string(args, body, " ",
1887 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
1888 if (smartlist_len(args)<1)
1889 connection_printf_to_buf(conn, "512 Missing argument to CLOSECIRCUIT\r\n");
1890 else if (!(circ=get_circ(smartlist_get(args, 0))))
1891 connection_printf_to_buf(conn, "552 Unknown circuit \"%s\"\r\n",
1892 (char*)smartlist_get(args, 0));
1893 else {
1894 int i;
1895 for (i=1; i < smartlist_len(args); ++i) {
1896 if (!strcasecmp(smartlist_get(args, i), "IfUnused"))
1897 safe = 1;
1898 else
1899 info(LD_CONTROL, "Skipping unknown option %s",
1900 (char*)smartlist_get(args,i));
1903 SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
1904 smartlist_free(args);
1905 if (!circ)
1906 return 0;
1909 if (!safe || !circ->p_streams) {
1910 circuit_mark_for_close(circ);
1913 send_control_done(conn);
1914 return 0;
1917 /** Called when we get a v0 FRAGMENTHEADER or FRAGMENT command; try to append
1918 * the data to conn->incoming_cmd, setting conn->incoming_(type|len|cur_len)
1919 * as appropriate. If the command is malformed, drop it and all pending
1920 * fragments and report failure.
1922 static int
1923 handle_control_fragments(connection_t *conn, uint16_t command_type,
1924 uint32_t body_len, char *body)
1926 if (command_type == CONTROL0_CMD_FRAGMENTHEADER) {
1927 if (conn->incoming_cmd) {
1928 warn(LD_CONTROL, "Dropping incomplete fragmented command");
1929 tor_free(conn->incoming_cmd);
1931 if (body_len < 6) {
1932 send_control0_error(conn, ERR_SYNTAX, "FRAGMENTHEADER too short.");
1933 return 0;
1935 conn->incoming_cmd_type = ntohs(get_uint16(body));
1936 conn->incoming_cmd_len = ntohl(get_uint32(body+2));
1937 conn->incoming_cmd_cur_len = 0;
1938 conn->incoming_cmd = tor_malloc(conn->incoming_cmd_len);
1939 body += 6;
1940 body_len -= 6;
1941 } else if (command_type == CONTROL0_CMD_FRAGMENT) {
1942 if (!conn->incoming_cmd) {
1943 send_control0_error(conn, ERR_SYNTAX, "Out-of-place FRAGMENT");
1944 return 0;
1946 } else {
1947 tor_assert(0);
1950 if (conn->incoming_cmd_cur_len + body_len > conn->incoming_cmd_len) {
1951 tor_free(conn->incoming_cmd);
1952 send_control0_error(conn, ERR_SYNTAX,
1953 "Fragmented data exceeds declared length");
1954 return 0;
1956 memcpy(conn->incoming_cmd + conn->incoming_cmd_cur_len,
1957 body, body_len);
1958 conn->incoming_cmd_cur_len += body_len;
1959 return 0;
1962 /** Called when <b>conn</b> has no more bytes left on its outbuf. */
1964 connection_control_finished_flushing(connection_t *conn)
1966 tor_assert(conn);
1967 tor_assert(conn->type == CONN_TYPE_CONTROL);
1969 connection_stop_writing(conn);
1970 return 0;
1973 /** Called when <b>conn</b> has gotten its socket closed. */
1975 connection_control_reached_eof(connection_t *conn)
1977 tor_assert(conn);
1978 tor_assert(conn->type == CONN_TYPE_CONTROL);
1980 info(LD_CONTROL,"Control connection reached EOF. Closing.");
1981 connection_mark_for_close(conn);
1982 return 0;
1985 /** Called when data has arrived on a v1 control connection: Try to fetch
1986 * commands from conn->inbuf, and execute them.
1988 static int
1989 connection_control_process_inbuf_v1(connection_t *conn)
1991 size_t data_len;
1992 int cmd_len;
1993 char *args;
1995 tor_assert(conn);
1996 tor_assert(conn->type == CONN_TYPE_CONTROL);
1997 tor_assert(conn->state == CONTROL_CONN_STATE_OPEN_V1 ||
1998 conn->state == CONTROL_CONN_STATE_NEEDAUTH_V1);
2000 if (!conn->incoming_cmd) {
2001 conn->incoming_cmd = tor_malloc(1024);
2002 conn->incoming_cmd_len = 1024;
2003 conn->incoming_cmd_cur_len = 0;
2006 again:
2007 while (1) {
2008 size_t last_idx;
2009 int r;
2010 /* First, fetch a line. */
2011 do {
2012 data_len = conn->incoming_cmd_len - conn->incoming_cmd_cur_len;
2013 r = fetch_from_buf_line(conn->inbuf,
2014 conn->incoming_cmd+conn->incoming_cmd_cur_len,
2015 &data_len);
2016 if (r == 0)
2017 /* Line not all here yet. Wait. */
2018 return 0;
2019 else if (r == -1) {
2020 while (conn->incoming_cmd_len < data_len+conn->incoming_cmd_cur_len)
2021 conn->incoming_cmd_len *= 2;
2022 conn->incoming_cmd = tor_realloc(conn->incoming_cmd,
2023 conn->incoming_cmd_len);
2025 } while (r != 1);
2027 tor_assert(data_len);
2029 last_idx = conn->incoming_cmd_cur_len;
2030 conn->incoming_cmd_cur_len += data_len;
2032 /* We have appended a line to incoming_cmd. Is the command done? */
2033 if (last_idx == 0 && *conn->incoming_cmd != '+')
2034 /* One line command, didn't start with '+'. */
2035 break;
2036 if (last_idx+3 == conn->incoming_cmd_cur_len &&
2037 !memcmp(conn->incoming_cmd + last_idx, ".\r\n", 3)) {
2038 /* Just appended ".\r\n"; we're done. Remove it. */
2039 conn->incoming_cmd_cur_len -= 3;
2040 break;
2042 /* Otherwise, read another line. */
2044 data_len = conn->incoming_cmd_cur_len;
2045 /* Okay, we now have a command sitting on conn->incoming_cmd. See if we
2046 * recognize it.
2048 cmd_len = 0;
2049 while ((size_t)cmd_len < data_len
2050 && !TOR_ISSPACE(conn->incoming_cmd[cmd_len]))
2051 ++cmd_len;
2053 data_len -= cmd_len;
2054 conn->incoming_cmd[cmd_len]='\0';
2055 args = conn->incoming_cmd+cmd_len+1;
2056 while (*args == ' ' || *args == '\t') {
2057 ++args;
2058 --data_len;
2061 if (!strcasecmp(conn->incoming_cmd, "QUIT")) {
2062 connection_write_str_to_buf("250 closing connection\r\n", conn);
2063 connection_mark_for_close(conn);
2064 return 0;
2067 if (conn->state == CONTROL_CONN_STATE_NEEDAUTH_V1 &&
2068 strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
2069 connection_write_str_to_buf("514 Authentication required.\r\n", conn);
2070 conn->incoming_cmd_cur_len = 0;
2071 goto again;
2074 if (!strcasecmp(conn->incoming_cmd, "SETCONF")) {
2075 if (handle_control_setconf(conn, data_len, args))
2076 return -1;
2077 } else if (!strcasecmp(conn->incoming_cmd, "RESETCONF")) {
2078 if (handle_control_resetconf(conn, data_len, args))
2079 return -1;
2080 } else if (!strcasecmp(conn->incoming_cmd, "GETCONF")) {
2081 if (handle_control_getconf(conn, data_len, args))
2082 return -1;
2083 } else if (!strcasecmp(conn->incoming_cmd, "SETEVENTS")) {
2084 if (handle_control_setevents(conn, data_len, args))
2085 return -1;
2086 } else if (!strcasecmp(conn->incoming_cmd, "AUTHENTICATE")) {
2087 if (handle_control_authenticate(conn, data_len, args))
2088 return -1;
2089 } else if (!strcasecmp(conn->incoming_cmd, "SAVECONF")) {
2090 if (handle_control_saveconf(conn, data_len, args))
2091 return -1;
2092 } else if (!strcasecmp(conn->incoming_cmd, "SIGNAL")) {
2093 if (handle_control_signal(conn, data_len, args))
2094 return -1;
2095 } else if (!strcasecmp(conn->incoming_cmd, "MAPADDRESS")) {
2096 if (handle_control_mapaddress(conn, data_len, args))
2097 return -1;
2098 } else if (!strcasecmp(conn->incoming_cmd, "GETINFO")) {
2099 if (handle_control_getinfo(conn, data_len, args))
2100 return -1;
2101 } else if (!strcasecmp(conn->incoming_cmd, "EXTENDCIRCUIT")) {
2102 if (handle_control_extendcircuit(conn, data_len, args))
2103 return -1;
2104 } else if (!strcasecmp(conn->incoming_cmd, "ATTACHSTREAM")) {
2105 if (handle_control_attachstream(conn, data_len, args))
2106 return -1;
2107 } else if (!strcasecmp(conn->incoming_cmd, "+POSTDESCRIPTOR")) {
2108 if (handle_control_postdescriptor(conn, data_len, args))
2109 return -1;
2110 } else if (!strcasecmp(conn->incoming_cmd, "REDIRECTSTREAM")) {
2111 if (handle_control_redirectstream(conn, data_len, args))
2112 return -1;
2113 } else if (!strcasecmp(conn->incoming_cmd, "CLOSESTREAM")) {
2114 if (handle_control_closestream(conn, data_len, args))
2115 return -1;
2116 } else if (!strcasecmp(conn->incoming_cmd, "CLOSECIRCUIT")) {
2117 if (handle_control_closecircuit(conn, data_len, args))
2118 return -1;
2119 } else {
2120 connection_printf_to_buf(conn, "510 Unrecognized command \"%s\"\r\n",
2121 conn->incoming_cmd);
2124 conn->incoming_cmd_cur_len = 0;
2125 goto again;
2128 /** Called when data has arrived on a v0 control connection: Try to fetch
2129 * commands from conn->inbuf, and execute them.
2131 static int
2132 connection_control_process_inbuf_v0(connection_t *conn)
2134 uint32_t body_len;
2135 uint16_t command_type;
2136 char *body=NULL;
2138 again:
2139 /* Try to suck a control message from the buffer. */
2140 switch (fetch_from_buf_control0(conn->inbuf, &body_len, &command_type, &body,
2141 conn->state == CONTROL_CONN_STATE_NEEDAUTH_V0))
2143 case -2:
2144 tor_free(body);
2145 info(LD_CONTROL, "Detected v1 control protocol on connection (fd %d)",
2146 conn->s);
2147 conn->state = CONTROL_CONN_STATE_NEEDAUTH_V1;
2148 return connection_control_process_inbuf_v1(conn);
2149 case -1:
2150 tor_free(body);
2151 warn(LD_CONTROL, "Error in control command. Failing.");
2152 return -1;
2153 case 0:
2154 /* Control command not all here yet. Wait. */
2155 return 0;
2156 case 1:
2157 /* We got a command. Process it. */
2158 break;
2159 default:
2160 tor_assert(0);
2163 /* We got a command. If we need authentication, only authentication
2164 * commands will be considered. */
2165 if (conn->state == CONTROL_CONN_STATE_NEEDAUTH_V0 &&
2166 command_type != CONTROL0_CMD_AUTHENTICATE) {
2167 info(LD_CONTROL, "Rejecting '%s' command; authentication needed.",
2168 control_cmd_to_string(command_type));
2169 send_control0_error(conn, ERR_UNAUTHORIZED, "Authentication required");
2170 tor_free(body);
2171 goto again;
2174 if (command_type == CONTROL0_CMD_FRAGMENTHEADER ||
2175 command_type == CONTROL0_CMD_FRAGMENT) {
2176 if (handle_control_fragments(conn, command_type, body_len, body))
2177 return -1;
2178 tor_free(body);
2179 if (conn->incoming_cmd_cur_len != conn->incoming_cmd_len)
2180 goto again;
2182 command_type = conn->incoming_cmd_type;
2183 body_len = conn->incoming_cmd_len;
2184 body = conn->incoming_cmd;
2185 conn->incoming_cmd = NULL;
2186 } else if (conn->incoming_cmd) {
2187 warn(LD_CONTROL, "Dropping incomplete fragmented command");
2188 tor_free(conn->incoming_cmd);
2191 /* Okay, we're willing to process the command. */
2192 switch (command_type)
2194 case CONTROL0_CMD_SETCONF:
2195 if (handle_control_setconf(conn, body_len, body))
2196 return -1;
2197 break;
2198 case CONTROL0_CMD_GETCONF:
2199 if (handle_control_getconf(conn, body_len, body))
2200 return -1;
2201 break;
2202 case CONTROL0_CMD_SETEVENTS:
2203 if (handle_control_setevents(conn, body_len, body))
2204 return -1;
2205 break;
2206 case CONTROL0_CMD_AUTHENTICATE:
2207 if (handle_control_authenticate(conn, body_len, body))
2208 return -1;
2209 break;
2210 case CONTROL0_CMD_SAVECONF:
2211 if (handle_control_saveconf(conn, body_len, body))
2212 return -1;
2213 break;
2214 case CONTROL0_CMD_SIGNAL:
2215 if (handle_control_signal(conn, body_len, body))
2216 return -1;
2217 break;
2218 case CONTROL0_CMD_MAPADDRESS:
2219 if (handle_control_mapaddress(conn, body_len, body))
2220 return -1;
2221 break;
2222 case CONTROL0_CMD_GETINFO:
2223 if (handle_control_getinfo(conn, body_len, body))
2224 return -1;
2225 break;
2226 case CONTROL0_CMD_EXTENDCIRCUIT:
2227 if (handle_control_extendcircuit(conn, body_len, body))
2228 return -1;
2229 break;
2230 case CONTROL0_CMD_ATTACHSTREAM:
2231 if (handle_control_attachstream(conn, body_len, body))
2232 return -1;
2233 break;
2234 case CONTROL0_CMD_POSTDESCRIPTOR:
2235 if (handle_control_postdescriptor(conn, body_len, body))
2236 return -1;
2237 break;
2238 case CONTROL0_CMD_REDIRECTSTREAM:
2239 if (handle_control_redirectstream(conn, body_len, body))
2240 return -1;
2241 break;
2242 case CONTROL0_CMD_CLOSESTREAM:
2243 if (handle_control_closestream(conn, body_len, body))
2244 return -1;
2245 break;
2246 case CONTROL0_CMD_CLOSECIRCUIT:
2247 if (handle_control_closecircuit(conn, body_len, body))
2248 return -1;
2249 break;
2250 case CONTROL0_CMD_ERROR:
2251 case CONTROL0_CMD_DONE:
2252 case CONTROL0_CMD_CONFVALUE:
2253 case CONTROL0_CMD_EVENT:
2254 case CONTROL0_CMD_INFOVALUE:
2255 warn(LD_CONTROL, "Received client-only '%s' command; ignoring.",
2256 control_cmd_to_string(command_type));
2257 send_control0_error(conn, ERR_UNRECOGNIZED_TYPE,
2258 "Command type only valid from server to tor client");
2259 break;
2260 case CONTROL0_CMD_FRAGMENTHEADER:
2261 case CONTROL0_CMD_FRAGMENT:
2262 warn(LD_CONTROL, "Recieved command fragment out of order; ignoring.");
2263 send_control0_error(conn, ERR_SYNTAX, "Bad fragmentation on command.");
2264 default:
2265 warn(LD_CONTROL, "Received unrecognized command type %d; ignoring.",
2266 (int)command_type);
2267 send_control0_error(conn, ERR_UNRECOGNIZED_TYPE,
2268 "Unrecognized command type");
2269 break;
2271 tor_free(body);
2272 goto again; /* There might be more data. */
2275 /** Called when <b>conn</b> has received more bytes on its inbuf.
2278 connection_control_process_inbuf(connection_t *conn)
2280 tor_assert(conn);
2281 tor_assert(conn->type == CONN_TYPE_CONTROL);
2283 if (STATE_IS_V0(conn->state))
2284 return connection_control_process_inbuf_v0(conn);
2285 else
2286 return connection_control_process_inbuf_v1(conn);
2289 /** Something has happened to circuit <b>circ</b>: tell any interested
2290 * control connections. */
2292 control_event_circuit_status(circuit_t *circ, circuit_status_event_t tp)
2294 char *path, *msg;
2295 if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS))
2296 return 0;
2297 tor_assert(circ);
2298 tor_assert(CIRCUIT_IS_ORIGIN(circ));
2300 path = circuit_list_path(circ,0);
2301 if (EVENT_IS_INTERESTING0(EVENT_CIRCUIT_STATUS)) {
2302 size_t path_len = strlen(path);
2303 msg = tor_malloc(1+4+path_len+1); /* event, circid, path, NUL. */
2304 msg[0] = (uint8_t) tp;
2305 set_uint32(msg+1, htonl(circ->global_identifier));
2306 strlcpy(msg+5,path,path_len+1);
2308 send_control0_event(EVENT_CIRCUIT_STATUS, (uint32_t)(path_len+6), msg);
2309 tor_free(msg);
2311 if (EVENT_IS_INTERESTING1(EVENT_CIRCUIT_STATUS)) {
2312 const char *status;
2313 switch (tp)
2315 case CIRC_EVENT_LAUNCHED: status = "LAUNCHED"; break;
2316 case CIRC_EVENT_BUILT: status = "BUILT"; break;
2317 case CIRC_EVENT_EXTENDED: status = "EXTENDED"; break;
2318 case CIRC_EVENT_FAILED: status = "FAILED"; break;
2319 case CIRC_EVENT_CLOSED: status = "CLOSED"; break;
2320 default:
2321 warn(LD_GENERAL, "Unrecognized status code %d", (int)tp);
2322 return 0;
2324 send_control1_event(EVENT_CIRCUIT_STATUS,
2325 "650 CIRC %lu %s %s\r\n",
2326 (unsigned long)circ->global_identifier,
2327 status, path);
2329 tor_free(path);
2331 return 0;
2334 /** Given an AP connection <b>conn</b> and a <b>len</b>-character buffer
2335 * <b>buf</b>, determine the address:port combination requested on
2336 * <b>conn</b>, and write it to <b>buf</b>. Return 0 on success, -1 on
2337 * failure. */
2338 static int
2339 write_stream_target_to_buf(connection_t *conn, char *buf, size_t len)
2341 char buf2[256];
2342 if (conn->chosen_exit_name)
2343 if (tor_snprintf(buf2, sizeof(buf2), ".%s.exit", conn->chosen_exit_name)<0)
2344 return -1;
2345 if (tor_snprintf(buf, len, "%s%s:%d",
2346 conn->socks_request->address,
2347 conn->chosen_exit_name ? buf2 : "",
2348 conn->socks_request->port)<0)
2349 return -1;
2350 return 0;
2353 /** Something has happened to the stream associated with AP connection
2354 * <b>conn</b>: tell any interested control connections. */
2356 control_event_stream_status(connection_t *conn, stream_status_event_t tp)
2358 char *msg;
2359 size_t len;
2360 char buf[256];
2361 tor_assert(conn->type == CONN_TYPE_AP);
2362 tor_assert(conn->socks_request);
2364 if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS))
2365 return 0;
2367 write_stream_target_to_buf(conn, buf, sizeof(buf));
2368 if (EVENT_IS_INTERESTING0(EVENT_STREAM_STATUS)) {
2369 len = strlen(buf);
2370 msg = tor_malloc(5+len+1);
2371 msg[0] = (uint8_t) tp;
2372 set_uint32(msg+1, htonl(conn->global_identifier));
2373 strlcpy(msg+5, buf, len+1);
2375 send_control0_event(EVENT_STREAM_STATUS, (uint32_t)(5+len+1), msg);
2376 tor_free(msg);
2378 if (EVENT_IS_INTERESTING1(EVENT_STREAM_STATUS)) {
2379 const char *status;
2380 circuit_t *circ;
2381 switch (tp)
2383 case STREAM_EVENT_SENT_CONNECT: status = "SENTCONNECT"; break;
2384 case STREAM_EVENT_SENT_RESOLVE: status = "SENTRESOLVE"; break;
2385 case STREAM_EVENT_SUCCEEDED: status = "SUCCEEDED"; break;
2386 case STREAM_EVENT_FAILED: status = "FAILED"; break;
2387 case STREAM_EVENT_CLOSED: status = "CLOSED"; break;
2388 case STREAM_EVENT_NEW: status = "NEW"; break;
2389 case STREAM_EVENT_NEW_RESOLVE: status = "NEWRESOLVE"; break;
2390 case STREAM_EVENT_FAILED_RETRIABLE: status = "DETACHED"; break;
2391 default:
2392 warn(LD_GENERAL, "Unrecognized status code %d", (int)tp);
2393 return 0;
2395 circ = circuit_get_by_edge_conn(conn);
2396 send_control1_event(EVENT_STREAM_STATUS,
2397 "650 STREAM %lu %s %lu %s\r\n",
2398 (unsigned long)conn->global_identifier, status,
2399 circ?(unsigned long)circ->global_identifier : 0ul,
2400 buf);
2401 /* XXX need to specify its intended exit, etc? */
2403 return 0;
2406 /** Something has happened to the OR connection <b>conn</b>: tell any
2407 * interested control connections. */
2409 control_event_or_conn_status(connection_t *conn,or_conn_status_event_t tp)
2411 char buf[HEX_DIGEST_LEN+3]; /* status, dollar, identity, NUL */
2412 size_t len;
2414 tor_assert(conn->type == CONN_TYPE_OR);
2416 if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS))
2417 return 0;
2419 if (EVENT_IS_INTERESTING0(EVENT_OR_CONN_STATUS)) {
2420 buf[0] = (uint8_t)tp;
2421 strlcpy(buf+1,conn->nickname,sizeof(buf)-1);
2422 len = strlen(buf+1);
2423 send_control0_event(EVENT_OR_CONN_STATUS, (uint32_t)(len+1), buf);
2425 if (EVENT_IS_INTERESTING1(EVENT_OR_CONN_STATUS)) {
2426 const char *status;
2427 switch (tp)
2429 case OR_CONN_EVENT_LAUNCHED: status = "LAUNCHED"; break;
2430 case OR_CONN_EVENT_CONNECTED: status = "CONNECTED"; break;
2431 case OR_CONN_EVENT_FAILED: status = "FAILED"; break;
2432 case OR_CONN_EVENT_CLOSED: status = "CLOSED"; break;
2433 default:
2434 warn(LD_GENERAL, "Unrecognized status code %d", (int)tp);
2435 return 0;
2437 send_control1_event(EVENT_OR_CONN_STATUS,
2438 "650 ORCONN %s %s\r\n",
2439 conn->nickname, status);
2441 return 0;
2444 /** A second or more has elapsed: tell any interested control
2445 * connections how much bandwidth we used. */
2447 control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
2449 char buf[8];
2451 if (EVENT_IS_INTERESTING0(EVENT_BANDWIDTH_USED)) {
2452 set_uint32(buf, htonl(n_read));
2453 set_uint32(buf+4, htonl(n_written));
2454 send_control0_event(EVENT_BANDWIDTH_USED, 8, buf);
2456 if (EVENT_IS_INTERESTING1(EVENT_BANDWIDTH_USED)) {
2457 send_control1_event(EVENT_BANDWIDTH_USED,
2458 "650 BW %lu %lu\r\n",
2459 (unsigned long)n_read,
2460 (unsigned long)n_written);
2463 return 0;
2466 /** Called when we are sending a log message to the controllers: suspend
2467 * sending further log messages to the controllers until we're done. Used by
2468 * CONN_LOG_PROTECT. */
2469 void
2470 disable_control_logging(void)
2472 ++disable_log_messages;
2475 /** We're done sending a log message to the controllers: re-enable controller
2476 * logging. Used by CONN_LOG_PROTECT. */
2477 void
2478 enable_control_logging(void)
2480 if (--disable_log_messages < 0)
2481 tor_assert(0);
2484 /** We got a log message: tell any interested control connections. */
2485 void
2486 control_event_logmsg(int severity, int domain, const char *msg)
2488 int oldlog, event;
2490 if (disable_log_messages)
2491 return;
2493 oldlog = EVENT_IS_INTERESTING0(EVENT_LOG_OBSOLETE) &&
2494 (severity == LOG_NOTICE || severity == LOG_WARN || severity == LOG_ERR);
2495 event = log_severity_to_event(severity);
2497 if (event<0 || !EVENT_IS_INTERESTING0(event))
2498 event = 0;
2500 if (oldlog || event) {
2501 size_t len = strlen(msg);
2502 ++disable_log_messages;
2503 if (event)
2504 send_control0_event(event, (uint32_t)(len+1), msg);
2505 if (oldlog)
2506 send_control0_event(EVENT_LOG_OBSOLETE, (uint32_t)(len+1), msg);
2507 --disable_log_messages;
2510 event = log_severity_to_event(severity);
2511 if (event >= 0 && EVENT_IS_INTERESTING1(event)) {
2512 char *b = NULL;
2513 const char *s;
2514 if (strchr(msg, '\n')) {
2515 char *cp;
2516 b = tor_strdup(msg);
2517 for (cp = b; *cp; ++cp)
2518 if (*cp == '\r' || *cp == '\n')
2519 *cp = ' ';
2521 switch (severity) {
2522 case LOG_DEBUG: s = "DEBUG"; break;
2523 case LOG_INFO: s = "INFO"; break;
2524 case LOG_NOTICE: s = "NOTICE"; break;
2525 case LOG_WARN: s = "WARN"; break;
2526 case LOG_ERR: s = "ERR"; break;
2527 default: s = "UnknownLogSeverity"; break;
2529 ++disable_log_messages;
2530 send_control1_event(event, "650 %s %s\r\n", s, b?b:msg);
2531 --disable_log_messages;
2532 tor_free(b);
2536 /** Called whenever we receive new router descriptors: tell any
2537 * interested control connections. <b>routers</b> is a list of
2538 * DIGEST_LEN-byte identity digests.
2541 control_event_descriptors_changed(smartlist_t *routers)
2543 size_t len;
2544 char *msg;
2545 smartlist_t *identities;
2546 char buf[HEX_DIGEST_LEN+1];
2548 if (!EVENT_IS_INTERESTING(EVENT_NEW_DESC))
2549 return 0;
2550 identities = smartlist_create();
2551 SMARTLIST_FOREACH(routers, routerinfo_t *, r,
2553 base16_encode(buf,sizeof(buf),r->identity_digest,DIGEST_LEN);
2554 smartlist_add(identities, tor_strdup(buf));
2556 if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC)) {
2557 msg = smartlist_join_strings(identities, ",", 0, &len);
2558 send_control0_event(EVENT_NEW_DESC, len+1, msg);
2559 tor_free(msg);
2561 if (EVENT_IS_INTERESTING1(EVENT_NEW_DESC)) {
2562 msg = smartlist_join_strings(identities, " ", 0, &len);
2563 send_control1_event(EVENT_NEW_DESC, "650 NEWDESC %s\r\n", msg);
2564 tor_free(msg);
2566 SMARTLIST_FOREACH(identities, char *, cp, tor_free(cp));
2567 smartlist_free(identities);
2569 return 0;
2572 /** Called whenever an address mapping on <b>from<b> from changes to <b>to</b>.
2573 * <b>expires</b> values less than 3 are special; see connection_edge.c. */
2575 control_event_address_mapped(const char *from, const char *to, time_t expires)
2577 if (!EVENT_IS_INTERESTING1(EVENT_ADDRMAP))
2578 return 0;
2580 if (expires < 3)
2581 send_control1_event(EVENT_ADDRMAP, "650 ADDRMAP %s %s NEVER\r\n", from, to);
2582 else {
2583 char buf[ISO_TIME_LEN+1];
2584 format_local_iso_time(buf,expires);
2585 send_control1_event(EVENT_ADDRMAP, "650 ADDRMAP %s %s \"%s\"\r\n",
2586 from, to, buf);
2589 return 0;
2592 /** Choose a random authentication cookie and write it to disk.
2593 * Anybody who can read the cookie from disk will be considered
2594 * authorized to use the control connection. */
2596 init_cookie_authentication(int enabled)
2598 char fname[512];
2600 if (!enabled) {
2601 authentication_cookie_is_set = 0;
2602 return 0;
2605 tor_snprintf(fname, sizeof(fname), "%s/control_auth_cookie",
2606 get_options()->DataDirectory);
2607 crypto_rand(authentication_cookie, AUTHENTICATION_COOKIE_LEN);
2608 authentication_cookie_is_set = 1;
2609 if (write_bytes_to_file(fname, authentication_cookie,
2610 AUTHENTICATION_COOKIE_LEN, 1)) {
2611 warn(LD_FS,"Error writing authentication cookie.");
2612 return -1;
2615 return 0;