1 /* Copyright 2004 Roger Dingledine, Nick Mathewson. */
2 /* See LICENSE for licensing information */
8 * /brief Implementation for Tor's control-socket interface.
13 /* Protocol outline: a bidirectional stream, over which each side
14 * sends a series of messages. Each message has a two-byte length field,
15 * a two-byte typecode, and a variable-length body whose length is
16 * given in the length field.
18 * By default, the server only sends messages in response to client messages.
19 * Every client message gets a message in response. The client may, however,
20 * _request_ that other messages be delivered asynchronously.
23 * Every message type is either client-only or server-only, and every
24 * server message type is either synchronous-only (only occurs in
25 * response to a client request) or asynchronous-only (never is an
26 * answer to a client request.
28 * See control-spec.txt for full details.
31 /* Recognized message type codes. */
32 #define CONTROL_CMD_ERROR 0x0000
33 #define CONTROL_CMD_DONE 0x0001
34 #define CONTROL_CMD_SETCONF 0x0002
35 #define CONTROL_CMD_GETCONF 0x0003
36 #define CONTROL_CMD_CONFVALUE 0x0004
37 #define CONTROL_CMD_SETEVENTS 0x0005
38 #define CONTROL_CMD_EVENT 0x0006
39 #define CONTROL_CMD_AUTHENTICATE 0x0007
40 #define CONTROL_CMD_SAVECONF 0x0008
41 #define _CONTROL_CMD_MAX_RECOGNIZED 0x0008
43 /* Recognized error codes. */
44 #define ERR_UNSPECIFIED 0x0000
45 #define ERR_INTERNAL 0x0001
46 #define ERR_UNRECOGNIZED_TYPE 0x0002
47 #define ERR_SYNTAX 0x0003
48 #define ERR_UNRECOGNIZED_CONFIG_KEY 0x0004
49 #define ERR_INVALID_CONFIG_VALUE 0x0005
50 #define ERR_UNRECOGNIZED_EVENT_CODE 0x0006
51 #define ERR_UNAUTHORIZED 0x0007
52 #define ERR_REJECTED_AUTHENTICATION 0x0008
54 /* Recognized asynchronous event types. */
55 #define _EVENT_MIN 0x0001
56 #define EVENT_CIRCUIT_STATUS 0x0001
57 #define EVENT_STREAM_STATUS 0x0002
58 #define EVENT_OR_CONN_STATUS 0x0003
59 #define EVENT_BANDWIDTH_USED 0x0004
60 #define EVENT_WARNING 0x0005
61 #define _EVENT_MAX 0x0005
63 /** Array mapping from message type codes to human-readable message
65 static const char * CONTROL_COMMANDS
[] = {
77 /** Bitfield: The bit 1<<e is set if <b>any</b> open control
78 * connection is interested in events of type <b>e</b>. We use this
79 * so that we can decide to skip generating event messages that nobody
80 * has interest in without having to walk over the global connection
83 static uint32_t global_event_mask
= 0;
85 /** Macro: true if any control connection is interested in events of type
87 #define EVENT_IS_INTERESTING(e) (global_event_mask & (1<<(e)))
89 /** If we're using cookie-type authentication, how long should our cookies be?
91 #define AUTHENTICATION_COOKIE_LEN 32
93 /** If true, we've set authentication_cookie to a secret code and
94 * stored it to disk. */
95 static int authentication_cookie_is_set
= 0;
96 static char authentication_cookie
[AUTHENTICATION_COOKIE_LEN
];
98 static void update_global_event_mask(void);
99 static void send_control_message(connection_t
*conn
, uint16_t type
,
100 uint16_t len
, const char *body
);
101 static void send_control_done(connection_t
*conn
);
102 static void send_control_error(connection_t
*conn
, uint16_t error
,
103 const char *message
);
104 static void send_control_event(uint16_t event
, uint16_t len
, const char *body
);
105 static int handle_control_setconf(connection_t
*conn
, uint16_t len
,
107 static int handle_control_getconf(connection_t
*conn
, uint16_t len
,
109 static int handle_control_setevents(connection_t
*conn
, uint16_t len
,
111 static int handle_control_authenticate(connection_t
*conn
, uint16_t len
,
113 static int handle_control_saveconf(connection_t
*conn
, uint16_t len
,
116 /** Given a possibly invalid message type code <b>cmd</b>, return a
117 * human-readable string equivalent. */
118 static INLINE
const char *
119 control_cmd_to_string(uint16_t cmd
)
121 return (cmd
<=_CONTROL_CMD_MAX_RECOGNIZED
) ? CONTROL_COMMANDS
[cmd
] : "Unknown";
124 /** Set <b>global_event_mask</b> to the bitwise OR of each live control
125 * connection's event_mask field. */
126 static void update_global_event_mask(void)
128 connection_t
**conns
;
131 global_event_mask
= 0;
132 get_connection_array(&conns
, &n_conns
);
133 for (i
= 0; i
< n_conns
; ++i
) {
134 if (conns
[i
]->type
== CONN_TYPE_CONTROL
&&
135 conns
[i
]->state
== CONTROL_CONN_STATE_OPEN
) {
136 global_event_mask
|= conns
[i
]->event_mask
;
141 /** Send a message of type <b>type</b> containing <b>len</b> bytes
142 * from <b>body</b> along the control connection <b>conn</b> */
144 send_control_message(connection_t
*conn
, uint16_t type
, uint16_t len
,
149 tor_assert(len
|| !body
);
150 tor_assert(type
<= _CONTROL_CMD_MAX_RECOGNIZED
);
151 set_uint16(buf
, htons(len
));
152 set_uint16(buf
+2, htons(type
));
153 connection_write_to_buf(buf
, 4, conn
);
155 connection_write_to_buf(body
, len
, conn
);
158 /** Send a "DONE" message down the control connection <b>conn</b> */
160 send_control_done(connection_t
*conn
)
162 send_control_message(conn
, CONTROL_CMD_DONE
, 0, NULL
);
165 /** Send an error message with error code <b>error</b> and body
166 * <b>message</b> down the connection <b>conn</b> */
168 send_control_error(connection_t
*conn
, uint16_t error
, const char *message
)
172 set_uint16(buf
, htons(error
));
173 len
= strlen(message
);
174 tor_assert(len
< (256-2));
175 memcpy(buf
+2, message
, len
);
176 send_control_message(conn
, CONTROL_CMD_ERROR
, (uint16_t)(len
+2), buf
);
179 /** Send an 'event' message of event type <b>event</b>, containing
180 * <b>len</b> bytes in <b>body</b> to every control connection that
181 * is interested in it. */
183 send_control_event(uint16_t event
, uint16_t len
, const char *body
)
185 connection_t
**conns
;
191 buf
= tor_malloc_zero(buflen
);
192 set_uint16(buf
, htons(event
));
193 memcpy(buf
+2, body
, len
);
195 get_connection_array(&conns
, &n_conns
);
196 for (i
= 0; i
< n_conns
; ++i
) {
197 if (conns
[i
]->type
== CONN_TYPE_CONTROL
&&
198 conns
[i
]->state
== CONTROL_CONN_STATE_OPEN
&&
199 conns
[i
]->event_mask
& (1<<event
)) {
200 send_control_message(conns
[i
], CONTROL_CMD_EVENT
, (uint16_t)(buflen
), buf
);
207 /** Called when we receive a SETCONF message: parse the body and try
208 * to update our configuration. Reply with a DONE or ERROR message. */
210 handle_control_setconf(connection_t
*conn
, uint16_t len
, char *body
)
213 struct config_line_t
*lines
=NULL
;
215 if (config_get_lines(body
, &lines
) < 0) {
216 log_fn(LOG_WARN
,"Controller gave us config lines we can't parse.");
217 send_control_error(conn
, ERR_SYNTAX
, "Couldn't parse configuration");
221 if ((r
=config_trial_assign(lines
, 1)) < 0) {
222 log_fn(LOG_WARN
,"Controller gave us config lines that didn't validate.");
224 send_control_error(conn
, ERR_UNRECOGNIZED_CONFIG_KEY
,
225 "Unrecognized option");
227 send_control_error(conn
, ERR_INVALID_CONFIG_VALUE
,"Invalid option value");
229 config_free_lines(lines
);
233 config_free_lines(lines
);
234 if (options_act() < 0) { /* acting on them failed. die. */
235 log_fn(LOG_ERR
,"Acting on config options left us in a broken state. Dying.");
238 send_control_done(conn
);
242 /** Called when we receive a GETCONF message. Parse the request, and
243 * reply with a CONFVALUE or an ERROR message */
245 handle_control_getconf(connection_t
*conn
, uint16_t body_len
, const char *body
)
247 smartlist_t
*questions
= NULL
;
248 smartlist_t
*answers
= NULL
;
251 or_options_t
*options
= get_options();
253 questions
= smartlist_create();
254 smartlist_split_string(questions
, body
, "\n",
255 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
256 answers
= smartlist_create();
257 SMARTLIST_FOREACH(questions
, const char *, q
,
259 int recognized
= config_option_is_recognized(q
);
261 send_control_error(conn
, ERR_UNRECOGNIZED_CONFIG_KEY
, body
);
264 struct config_line_t
*answer
= config_get_assigned_option(options
,q
);
267 struct config_line_t
*next
;
268 size_t alen
= strlen(answer
->key
)+strlen(answer
->value
)+2;
269 char *astr
= tor_malloc(alen
);
270 tor_snprintf(astr
, alen
, "%s %s\n", answer
->key
, answer
->value
);
271 smartlist_add(answers
, astr
);
274 tor_free(answer
->key
);
275 tor_free(answer
->value
);
282 msg
= smartlist_join_strings(answers
, "", 0, &msg_len
);
283 send_control_message(conn
, CONTROL_CMD_CONFVALUE
,
284 (uint16_t)msg_len
, msg_len
?msg
:NULL
);
287 if (answers
) SMARTLIST_FOREACH(answers
, char *, cp
, tor_free(cp
));
288 if (questions
) SMARTLIST_FOREACH(questions
, char *, cp
, tor_free(cp
));
289 smartlist_free(answers
);
290 smartlist_free(questions
);
296 /** Called when we get a SETEVENTS message: update conn->event_mask,
297 * and reply with DONE or ERROR. */
299 handle_control_setevents(connection_t
*conn
, uint16_t len
, const char *body
)
302 uint32_t event_mask
= 0;
304 send_control_error(conn
, ERR_SYNTAX
,
305 "Odd number of bytes in setevents message");
309 for (; len
; len
-= 2, body
+= 2) {
310 event_code
= ntohs(get_uint16(body
));
311 if (event_code
< _EVENT_MIN
|| event_code
> _EVENT_MAX
) {
312 send_control_error(conn
, ERR_UNRECOGNIZED_EVENT_CODE
,
313 "Unrecognized event code");
316 event_mask
|= (1 << event_code
);
319 conn
->event_mask
= event_mask
;
321 update_global_event_mask();
322 send_control_done(conn
);
326 /** Called when we get an AUTHENTICATE message. Check whether the
327 * authentication is valid, and if so, update the connection's state to
328 * OPEN. Reply with DONE or ERROR.
331 handle_control_authenticate(connection_t
*conn
, uint16_t len
, const char *body
)
333 or_options_t
*options
= get_options();
334 if (options
->CookieAuthentication
) {
335 if (len
== AUTHENTICATION_COOKIE_LEN
&&
336 !memcmp(authentication_cookie
, body
, len
)) {
339 } else if (options
->HashedControlPassword
) {
340 char expected
[S2K_SPECIFIER_LEN
+DIGEST_LEN
];
341 char received
[DIGEST_LEN
];
342 if (base64_decode(expected
,sizeof(expected
),
343 options
->HashedControlPassword
,
344 strlen(options
->HashedControlPassword
))<0) {
345 log_fn(LOG_WARN
,"Couldn't decode HashedControlPassword: invalid base64");
348 secret_to_key(received
,DIGEST_LEN
,body
,len
,expected
);
349 if (!memcmp(expected
+S2K_SPECIFIER_LEN
, received
, DIGEST_LEN
))
354 /* if Tor doesn't demand any stronger authentication, then
355 * the controller can get in with a blank auth line. */
362 send_control_error(conn
, ERR_REJECTED_AUTHENTICATION
,"Authentication failed");
365 log_fn(LOG_INFO
, "Authenticated control connection (%d)", conn
->s
);
366 send_control_done(conn
);
367 conn
->state
= CONTROL_CONN_STATE_OPEN
;
372 handle_control_saveconf(connection_t
*conn
, uint16_t len
,
375 if (save_current_config()<0) {
376 send_control_error(conn
, ERR_INTERNAL
,
377 "Unable to write configuration to disk.");
379 send_control_done(conn
);
384 /** Called when <b>conn</b> has no more bytes left on its outbuf. */
386 connection_control_finished_flushing(connection_t
*conn
) {
388 tor_assert(conn
->type
== CONN_TYPE_CONTROL
);
390 connection_stop_writing(conn
);
394 /** Called when <b>conn</b> has gotten its socket closed. */
395 int connection_control_reached_eof(connection_t
*conn
) {
396 log_fn(LOG_INFO
,"Control connection reached EOF. Closing.");
397 connection_mark_for_close(conn
);
401 /** Called when <b>conn</b> has received more bytes on its inbuf.
404 connection_control_process_inbuf(connection_t
*conn
) {
405 uint16_t body_len
, command_type
;
409 tor_assert(conn
->type
== CONN_TYPE_CONTROL
);
412 /* Try to suck a control message from the buffer. */
413 switch(fetch_from_buf_control(conn
->inbuf
, &body_len
, &command_type
, &body
))
417 log_fn(LOG_WARN
, "Error in control command. Failing.");
420 /* Control command not all here yet. Wait. */
423 /* We got a command. Process it. */
429 /* We got a command. If we need authentication, only authentication
430 * commands will be considered. */
431 if (conn
->state
== CONTROL_CONN_STATE_NEEDAUTH
&&
432 command_type
!= CONTROL_CMD_AUTHENTICATE
) {
433 log_fn(LOG_WARN
, "Rejecting '%s' command; authentication needed.",
434 control_cmd_to_string(command_type
));
435 send_control_error(conn
, ERR_UNAUTHORIZED
, "Authentication required");
440 /* Okay, we're willing to process the command. */
443 case CONTROL_CMD_SETCONF
:
444 if (handle_control_setconf(conn
, body_len
, body
))
447 case CONTROL_CMD_GETCONF
:
448 if (handle_control_getconf(conn
, body_len
, body
))
451 case CONTROL_CMD_SETEVENTS
:
452 if (handle_control_setevents(conn
, body_len
, body
))
455 case CONTROL_CMD_AUTHENTICATE
:
456 if (handle_control_authenticate(conn
, body_len
, body
))
459 case CONTROL_CMD_SAVECONF
:
460 if (handle_control_saveconf(conn
, body_len
, body
))
463 case CONTROL_CMD_ERROR
:
464 case CONTROL_CMD_DONE
:
465 case CONTROL_CMD_CONFVALUE
:
466 case CONTROL_CMD_EVENT
:
467 log_fn(LOG_WARN
, "Received client-only '%s' command; ignoring.",
468 control_cmd_to_string(command_type
));
469 send_control_error(conn
, ERR_UNRECOGNIZED_TYPE
,
470 "Command type only valid from server to tor client");
473 log_fn(LOG_WARN
, "Received unrecognized command type %d; ignoring.",
475 send_control_error(conn
, ERR_UNRECOGNIZED_TYPE
,
476 "Unrecognized command type");
480 goto again
; /* There might be more data. */
483 /** Something has happened to circuit <b>circ</b>: tell any interested
484 * control connections. */
486 control_event_circuit_status(circuit_t
*circ
, circuit_status_event_t tp
)
490 if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS
))
493 tor_assert(CIRCUIT_IS_ORIGIN(circ
));
495 path
= circuit_list_path(circ
);
496 path_len
= strlen(path
);
497 msg
= tor_malloc(1+4+path_len
+1); /* event, circid, path, NUL. */
498 msg
[0] = (uint8_t) tp
;
499 set_uint32(msg
+1, htonl(circ
->global_identifier
));
500 strlcpy(msg
+5,path
,path_len
+1);
502 send_control_event(EVENT_STREAM_STATUS
, (uint16_t)(path_len
+6), msg
);
508 /** Something has happened to the stream associated with AP connection
509 * <b>conn</b>: tell any interested control connections. */
511 control_event_stream_status(connection_t
*conn
, stream_status_event_t tp
)
515 tor_assert(conn
->type
== CONN_TYPE_AP
);
516 tor_assert(conn
->socks_request
);
518 if (!EVENT_IS_INTERESTING(EVENT_STREAM_STATUS
))
521 len
= strlen(conn
->socks_request
->address
);
522 msg
= tor_malloc(5+len
+1);
523 msg
[0] = (uint8_t) tp
;
524 set_uint32(msg
+1, htonl(conn
->s
)); /* ???? Is this a security problem? */
525 strlcpy(msg
+5, conn
->socks_request
->address
, len
+1);
527 send_control_event(EVENT_STREAM_STATUS
, (uint16_t)(5+len
+1), msg
);
532 /** Something has happened to the OR connection <b>conn</b>: tell any
533 * interested control connections. */
535 control_event_or_conn_status(connection_t
*conn
,or_conn_status_event_t tp
)
537 char buf
[HEX_DIGEST_LEN
+3]; /* status, dollar, identity, NUL */
540 tor_assert(conn
->type
== CONN_TYPE_OR
);
542 if (!EVENT_IS_INTERESTING(EVENT_OR_CONN_STATUS
))
545 buf
[0] = (uint8_t)tp
;
546 strlcpy(buf
+1,conn
->nickname
,sizeof(buf
)-1);
548 send_control_event(EVENT_OR_CONN_STATUS
, (uint16_t)(len
+1), buf
);
552 /** A second or more has elapsed: tell any interested control
553 * connections how much bandwidth we used. */
555 control_event_bandwidth_used(uint32_t n_read
, uint32_t n_written
)
559 if (!EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED
))
562 set_uint32(buf
, htonl(n_read
));
563 set_uint32(buf
+4, htonl(n_written
));
564 send_control_event(EVENT_BANDWIDTH_USED
, 8, buf
);
569 /** We got a log message: tell any interested control connections. */
571 control_event_logmsg(int severity
, const char *msg
)
574 if (severity
> LOG_WARN
) /* Less important than warning? ignore for now. */
576 if (!EVENT_IS_INTERESTING(EVENT_WARNING
))
580 send_control_event(EVENT_WARNING
, (uint16_t)(len
+1), msg
);
583 /** Choose a random authentication cookie and write it to disk.
584 * Anybody who can read the cookie from disk will be considered
585 * authorized to use the control connection. */
587 init_cookie_authentication(int enabled
)
592 authentication_cookie_is_set
= 0;
594 tor_snprintf(fname
, sizeof(fname
), "%s/control_auth_cookie",
595 get_options()->DataDirectory
);
596 crypto_rand(authentication_cookie
, AUTHENTICATION_COOKIE_LEN
);
597 authentication_cookie_is_set
= 1;
598 if (write_bytes_to_file(fname
, authentication_cookie
,
599 AUTHENTICATION_COOKIE_LEN
, 1)) {
600 log_fn(LOG_WARN
,"Error writing authentication cookie.");