control.c 129 KB
Newer Older
1
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
Karsten Loesing's avatar
Karsten Loesing committed
2
 * Copyright (c) 2007-2009, The Tor Project, Inc. */
3
4
/* See LICENSE for licensing information */

Nick Mathewson's avatar
Nick Mathewson committed
5
/**
6
7
 * \file control.c
 * \brief Implementation for Tor's control-socket interface.
Roger Dingledine's avatar
Roger Dingledine committed
8
 *   See doc/spec/control-spec.txt for full details on protocol.
9
 **/
Nick Mathewson's avatar
Nick Mathewson committed
10

11
12
#define CONTROL_PRIVATE

13
14
#include "or.h"

15
16
/** Yield true iff <b>s</b> is the state of a control_connection_t that has
 * finished authentication and is accepting commands. */
17
#define STATE_IS_OPEN(s) ((s) == CONTROL_CONN_STATE_OPEN)
18

19
/* Recognized asynchronous event types.  It's okay to expand this list
20
 * because it is used both as a list of v0 event types, and as indices
21
22
 * into the bitfield to determine which controllers want which events.
 */
Roger Dingledine's avatar
Roger Dingledine committed
23
24
25
26
27
#define _EVENT_MIN             0x0001
#define EVENT_CIRCUIT_STATUS   0x0001
#define EVENT_STREAM_STATUS    0x0002
#define EVENT_OR_CONN_STATUS   0x0003
#define EVENT_BANDWIDTH_USED   0x0004
28
#define EVENT_LOG_OBSOLETE     0x0005 /* Can reclaim this. */
Roger Dingledine's avatar
Roger Dingledine committed
29
30
31
32
33
34
35
#define EVENT_NEW_DESC         0x0006
#define EVENT_DEBUG_MSG        0x0007
#define EVENT_INFO_MSG         0x0008
#define EVENT_NOTICE_MSG       0x0009
#define EVENT_WARN_MSG         0x000A
#define EVENT_ERR_MSG          0x000B
#define EVENT_ADDRMAP          0x000C
36
// #define EVENT_AUTHDIR_NEWDESCS 0x000D
Roger Dingledine's avatar
Roger Dingledine committed
37
#define EVENT_DESCCHANGED      0x000E
38
// #define EVENT_NS               0x000F
39
40
41
#define EVENT_STATUS_CLIENT    0x0010
#define EVENT_STATUS_SERVER    0x0011
#define EVENT_STATUS_GENERAL   0x0012
42
#define EVENT_GUARD            0x0013
43
#define EVENT_STREAM_BANDWIDTH_USED   0x0014
44
#define EVENT_CLIENTS_SEEN     0x0015
45
46
#define EVENT_NEWCONSENSUS     0x0016
#define _EVENT_MAX             0x0016
47
/* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
48

49
/** Bitfield: The bit 1&lt;&lt;e is set if <b>any</b> open control
Nick Mathewson's avatar
Nick Mathewson committed
50
51
 * connection is interested in events of type <b>e</b>.  We use this
 * so that we can decide to skip generating event messages that nobody
Roger Dingledine's avatar
Roger Dingledine committed
52
 * has interest in without having to walk over the global connection
Nick Mathewson's avatar
Nick Mathewson committed
53
54
 * list to find out.
 **/
55
typedef uint32_t event_mask_t;
56

57
58
59
/** An event mask of all the events that any controller is interested in
 * receiving. */
static event_mask_t global_event_mask = 0;
60

61
62
63
/** True iff we have disabled log messages from being sent to the controller */
static int disable_log_messages = 0;

Nick Mathewson's avatar
Nick Mathewson committed
64
65
/** Macro: true if any control connection is interested in events of type
 * <b>e</b>. */
66
#define EVENT_IS_INTERESTING(e) \
67
  (global_event_mask & (1<<(e)))
Nick Mathewson's avatar
Nick Mathewson committed
68
69
70

/** If we're using cookie-type authentication, how long should our cookies be?
 */
71
#define AUTHENTICATION_COOKIE_LEN 32
Nick Mathewson's avatar
Nick Mathewson committed
72
73
74

/** If true, we've set authentication_cookie to a secret code and
 * stored it to disk. */
75
static int authentication_cookie_is_set = 0;
76
77
78
/** If authentication_cookie_is_set, a secret cookie that we've stored to disk
 * and which we're using to authenticate controllers.  (If the controller can
 * read it off disk, it has permission to connect. */
79
80
static char authentication_cookie[AUTHENTICATION_COOKIE_LEN];

81
82
83
84
85
86
87
/** A sufficiently large size to record the last bootstrap phase string. */
#define BOOTSTRAP_MSG_LEN 1024

/** What was the last bootstrap phase message we sent? We keep track
 * of this so we can respond to getinfo status/bootstrap-phase queries. */
static char last_sent_bootstrap_message[BOOTSTRAP_MSG_LEN];

88
89
/** Flag for event_format_t.  Indicates that we should use the one standard
    format.
90
 */
91
#define ALL_FORMATS 1
92
93

/** Bit field of flags to select how to format a controller event.  Recognized
94
 * flag is ALL_FORMATS. */
95
typedef int event_format_t;
96

97
static void connection_printf_to_buf(control_connection_t *conn,
98
                                     const char *format, ...)
99
  CHECK_PRINTF(2,3);
100
static void send_control_done(control_connection_t *conn);
101
102
static void send_control_event(uint16_t event, event_format_t which,
                               const char *format, ...)
103
  CHECK_PRINTF(3,4);
104
static int handle_control_setconf(control_connection_t *conn, uint32_t len,
105
                                  char *body);
106
static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
107
                                    char *body);
108
static int handle_control_getconf(control_connection_t *conn, uint32_t len,
109
                                  const char *body);
110
111
static int handle_control_loadconf(control_connection_t *conn, uint32_t len,
                                  const char *body);
112
static int handle_control_setevents(control_connection_t *conn, uint32_t len,
113
                                    const char *body);
114
115
static int handle_control_authenticate(control_connection_t *conn,
                                       uint32_t len,
116
                                       const char *body);
117
static int handle_control_saveconf(control_connection_t *conn, uint32_t len,
118
                                   const char *body);
119
static int handle_control_signal(control_connection_t *conn, uint32_t len,
120
                                 const char *body);
121
static int handle_control_mapaddress(control_connection_t *conn, uint32_t len,
122
                                     const char *body);
123
static char *list_getinfo_options(void);
124
static int handle_control_getinfo(control_connection_t *conn, uint32_t len,
125
                                  const char *body);
126
127
static int handle_control_extendcircuit(control_connection_t *conn,
                                        uint32_t len,
128
                                        const char *body);
129
130
static int handle_control_setcircuitpurpose(control_connection_t *conn,
                                            uint32_t len, const char *body);
131
132
static int handle_control_attachstream(control_connection_t *conn,
                                       uint32_t len,
133
                                        const char *body);
134
135
static int handle_control_postdescriptor(control_connection_t *conn,
                                         uint32_t len,
136
                                         const char *body);
137
138
static int handle_control_redirectstream(control_connection_t *conn,
                                         uint32_t len,
139
                                         const char *body);
140
static int handle_control_closestream(control_connection_t *conn, uint32_t len,
141
                                      const char *body);
142
143
static int handle_control_closecircuit(control_connection_t *conn,
                                       uint32_t len,
144
                                       const char *body);
145
146
static int handle_control_resolve(control_connection_t *conn, uint32_t len,
                                  const char *body);
147
148
149
static int handle_control_usefeature(control_connection_t *conn,
                                     uint32_t len,
                                     const char *body);
150
static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
151
                                      size_t len);
152
static void orconn_target_get_name(char *buf, size_t len,
153
                                   or_connection_t *conn);
154
static char *get_cookie_file(void);
155

156
157
/** Given a control event code for a message event, return the corresponding
 * log severity. */
158
159
160
161
162
163
164
165
166
167
168
169
170
static INLINE int
event_to_log_severity(int event)
{
  switch (event) {
    case EVENT_DEBUG_MSG: return LOG_DEBUG;
    case EVENT_INFO_MSG: return LOG_INFO;
    case EVENT_NOTICE_MSG: return LOG_NOTICE;
    case EVENT_WARN_MSG: return LOG_WARN;
    case EVENT_ERR_MSG: return LOG_ERR;
    default: return -1;
  }
}

171
/** Given a log severity, return the corresponding control event code. */
172
173
174
175
176
177
178
179
180
181
182
183
184
static INLINE int
log_severity_to_event(int severity)
{
  switch (severity) {
    case LOG_DEBUG: return EVENT_DEBUG_MSG;
    case LOG_INFO: return EVENT_INFO_MSG;
    case LOG_NOTICE: return EVENT_NOTICE_MSG;
    case LOG_WARN: return EVENT_WARN_MSG;
    case LOG_ERR: return EVENT_ERR_MSG;
    default: return -1;
  }
}

185
186
/** Set <b>global_event_mask*</b> to the bitwise OR of each live control
 * connection's event_mask field. */
187
188
void
control_update_global_event_mask(void)
189
{
190
  smartlist_t *conns = get_connection_array();
191
  event_mask_t old_mask, new_mask;
192
  old_mask = global_event_mask;
193

194
  global_event_mask = 0;
195
196
197
198
199
  SMARTLIST_FOREACH(conns, connection_t *, _conn,
  {
    if (_conn->type == CONN_TYPE_CONTROL &&
        STATE_IS_OPEN(_conn->state)) {
      control_connection_t *conn = TO_CONTROL_CONN(_conn);
200
      global_event_mask |= conn->event_mask;
201
    }
202
  });
203

204
  new_mask = global_event_mask;
205
206
207

  /* Handle the aftermath.  Set up the log callback to tell us only what
   * we want to hear...*/
208
  control_adjust_event_log_severity();
209
210
211
212
213

  /* ...then, if we've started logging stream bw, clear the appropriate
   * fields. */
  if (! (old_mask & EVENT_STREAM_BANDWIDTH_USED) &&
      (new_mask & EVENT_STREAM_BANDWIDTH_USED)) {
214
215
216
217
218
    SMARTLIST_FOREACH(conns, connection_t *, conn,
    {
      if (conn->type == CONN_TYPE_AP) {
        edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
        edge_conn->n_written = edge_conn->n_read = 0;
219
      }
220
    });
221
  }
222
223
}

224
225
226
/** Adjust the log severities that result in control_event_logmsg being called
 * to match the severity of log messages that any controllers are interested
 * in. */
227
void
228
control_adjust_event_log_severity(void)
229
{
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  int i;
  int min_log_event=EVENT_ERR_MSG, max_log_event=EVENT_DEBUG_MSG;

  for (i = EVENT_DEBUG_MSG; i <= EVENT_ERR_MSG; ++i) {
    if (EVENT_IS_INTERESTING(i)) {
      min_log_event = i;
      break;
    }
  }
  for (i = EVENT_ERR_MSG; i >= EVENT_DEBUG_MSG; --i) {
    if (EVENT_IS_INTERESTING(i)) {
      max_log_event = i;
      break;
    }
  }
245
246
  if (EVENT_IS_INTERESTING(EVENT_LOG_OBSOLETE) ||
      EVENT_IS_INTERESTING(EVENT_STATUS_GENERAL)) {
247
248
249
250
251
    if (min_log_event > EVENT_NOTICE_MSG)
      min_log_event = EVENT_NOTICE_MSG;
    if (max_log_event < EVENT_ERR_MSG)
      max_log_event = EVENT_ERR_MSG;
  }
252
253
254
255
256
257
258
  if (min_log_event <= max_log_event)
    change_callback_log_severity(event_to_log_severity(min_log_event),
                                 event_to_log_severity(max_log_event),
                                 control_event_logmsg);
  else
    change_callback_log_severity(LOG_ERR, LOG_ERR,
                                 control_event_logmsg);
259
260
}

261
262
263
264
265
266
267
268
269
270
/** Return true iff the event with code <b>c</b> is being sent to any current
 * control connection.  This is useful if the amount of work needed to prepare
 * to call the appropriate control_event_...() function is high.
 */
int
control_event_is_interesting(int event)
{
  return EVENT_IS_INTERESTING(event);
}

271
/** Append a NUL-terminated string <b>s</b> to the end of
272
 * <b>conn</b>-\>outbuf.
273
 */
274
static INLINE void
275
connection_write_str_to_buf(const char *s, control_connection_t *conn)
276
277
{
  size_t len = strlen(s);
278
  connection_write_to_buf(s, len, TO_CONN(conn));
279
280
}

281
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
282
283
284
285
286
 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy the
 * contents of <b>data</b> into *<b>out</b>, adding a period before any period
 * that that appears at the start of a line, and adding a period-CRLF line at
 * the end. Replace all LF characters sequences with CRLF.  Return the number
 * of bytes in *<b>out</b>.
287
288
 */
/* static */ size_t
289
write_escaped_data(const char *data, size_t len, char **out)
290
291
292
{
  size_t sz_out = len+8;
  char *outp;
293
  const char *start = data, *end;
294
295
  int i;
  int start_of_line;
Nick Mathewson's avatar
Nick Mathewson committed
296
  for (i=0; i<(int)len; ++i) {
297
    if (data[i]== '\n')
298
      sz_out += 2; /* Maybe add a CR; maybe add a dot. */
299
300
301
302
303
304
  }
  *out = outp = tor_malloc(sz_out+1);
  end = data+len;
  start_of_line = 1;
  while (data < end) {
    if (*data == '\n') {
305
      if (data > start && data[-1] != '\r')
306
307
308
309
310
311
312
313
314
315
316
317
        *outp++ = '\r';
      start_of_line = 1;
    } else if (*data == '.') {
      if (start_of_line) {
        start_of_line = 0;
        *outp++ = '.';
      }
    } else {
      start_of_line = 0;
    }
    *outp++ = *data++;
  }
318
319
320
321
  if (outp < *out+2 || memcmp(outp-2, "\r\n", 2)) {
    *outp++ = '\r';
    *outp++ = '\n';
  }
322
323
324
  *outp++ = '.';
  *outp++ = '\r';
  *outp++ = '\n';
325
  *outp = '\0'; /* NUL-terminate just in case. */
326
  tor_assert((outp - *out) <= (int)sz_out);
327
328
329
  return outp - *out;
}

330
331
332
/** Given a <b>len</b>-character string in <b>data</b>, made of lines
 * terminated by CRLF, allocate a new string in *<b>out</b>, and copy
 * the contents of <b>data</b> into *<b>out</b>, removing any period
333
334
 * that appears at the start of a line, and replacing all CRLF sequences
 * with LF.   Return the number of
335
 * bytes in *<b>out</b>. */
336
/* static */ size_t
337
read_escaped_data(const char *data, size_t len, char **out)
338
339
340
{
  char *outp;
  const char *next;
341
342
343
  const char *end;

  *out = outp = tor_malloc(len+1);
344

345
  end = data+len;
346

347
  while (data < end) {
348
    /* we're at the start of a line. */
349
350
    if (*data == '.')
      ++data;
351
    next = memchr(data, '\n', end-data);
352
    if (next) {
353
354
355
356
357
358
359
360
      size_t n_to_copy = next-data;
      /* Don't copy a CR that precedes this LF. */
      if (n_to_copy && *(next-1) == '\r')
        --n_to_copy;
      memcpy(outp, data, n_to_copy);
      outp += n_to_copy;
      data = next+1; /* This will point at the start of the next line,
                      * or the end of the string, or a period. */
361
    } else {
362
363
364
      memcpy(outp, data, end-data);
      outp += (end-data);
      *outp = '\0';
365
366
      return outp - *out;
    }
367
    *outp++ = '\n';
368
369
  }

370
  *outp = '\0';
371
372
  return outp - *out;
}
373

374
/** If the first <b>in_len_max</b> characters in <b>start</b> contain a
375
376
377
378
379
 * double-quoted string with escaped characters, return the length of that
 * string (as encoded, including quotes).  Otherwise return -1. */
static INLINE int
get_escaped_string_length(const char *start, size_t in_len_max,
                          int *chars_out)
380
381
{
  const char *cp, *end;
382
  int chars = 0;
383
384

  if (*start != '\"')
385
    return -1;
386
387
388
389
390
391

  cp = start+1;
  end = start+in_len_max;

  /* Calculate length. */
  while (1) {
392
393
394
    if (cp >= end) {
      return -1; /* Too long. */
    } else if (*cp == '\\') {
395
      if (++cp == end)
396
        return -1; /* Can't escape EOS. */
397
      ++cp;
398
      ++chars;
399
400
401
402
    } else if (*cp == '\"') {
      break;
    } else {
      ++cp;
403
      ++chars;
404
405
    }
  }
406
407
  if (chars_out)
    *chars_out = chars;
408
  return (int)(cp - start+1);
409
}
410

411
412
413
414
415
416
417
418
419
420
/** As decode_escaped_string, but does not decode the string: copies the
 * entire thing, including quotation marks. */
static const char *
extract_escaped_string(const char *start, size_t in_len_max,
                       char **out, size_t *out_len)
{
  int length = get_escaped_string_length(start, in_len_max, NULL);
  if (length<0)
    return NULL;
  *out_len = length;
421
  *out = tor_strndup(start, *out_len);
422
  return start+length;
423
424
}

425
/** Given a pointer to a string starting at <b>start</b> containing
426
 * <b>in_len_max</b> characters, decode a string beginning with one double
427
 * quote, containing any number of non-quote characters or characters escaped
428
 * with a backslash, and ending with a final double quote.  Place the resulting
429
430
431
 * string (unquoted, unescaped) into a newly allocated string in *<b>out</b>;
 * store its length in <b>out_len</b>.  On success, return a pointer to the
 * character immediately following the escaped string.  On failure, return
Roger Dingledine's avatar
Roger Dingledine committed
432
 * NULL. */
433
static const char *
434
decode_escaped_string(const char *start, size_t in_len_max,
435
                   char **out, size_t *out_len)
436
{
437
438
  const char *cp, *end;
  char *outp;
439
  int len, n_chars = 0;
440

441
442
  len = get_escaped_string_length(start, in_len_max, &n_chars);
  if (len<0)
443
444
    return NULL;

445
446
  end = start+len-1; /* Index of last quote. */
  tor_assert(*end == '\"');
447
  outp = *out = tor_malloc(len+1);
448
  *out_len = n_chars;
449

450
451
452
453
454
455
456
  cp = start+1;
  while (cp < end) {
    if (*cp == '\\')
      ++cp;
    *outp++ = *cp++;
  }
  *outp = '\0';
457
  tor_assert((outp - *out) == (int)*out_len);
458
459
460
461

  return end+1;
}

462
463
464
/** Acts like sprintf, but writes its formatted string to the end of
 * <b>conn</b>-\>outbuf.  The message may be truncated if it is too long,
 * but it will always end with a CRLF sequence.
465
466
 *
 * Currently the length of the message is limited to 1024 (including the
467
 * ending CR LF NUL ("\\r\\n\\0"). */
468
static void
469
connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
470
{
471
#define CONNECTION_PRINTF_TO_BUF_BUFFERSIZE 1024
472
  va_list ap;
473
  char buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE];
474
475
476
  int r;
  size_t len;
  va_start(ap,format);
477
  r = tor_vsnprintf(buf, sizeof(buf), format, ap);
478
  va_end(ap);
479
480
481
482
  if (r<0) {
    log_warn(LD_BUG, "Unable to format string for controller.");
    return;
  }
483
484
  len = strlen(buf);
  if (memcmp("\r\n\0", buf+len-2, 3)) {
485
486
487
    buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0';
    buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
    buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
488
  }
489
  connection_write_to_buf(buf, len, TO_CONN(conn));
490
491
}

492
/** Send a "DONE" message down the control connection <b>conn</b>. */
493
static void
494
send_control_done(control_connection_t *conn)
495
{
496
  connection_write_str_to_buf("250 OK\r\n", conn);
497
498
}

499
/** Send an event to all v1 controllers that are listening for code
500
501
 * <b>event</b>.  The event's body is given by <b>msg</b>.
 *
502
503
 * If <b>which</b> & SHORT_NAMES, the event contains short-format names: send
 * it to controllers that haven't enabled the VERBOSE_NAMES feature.  If
504
 * <b>which</b> & LONG_NAMES, the event contains long-format names: send it
Nick Mathewson's avatar
Nick Mathewson committed
505
 * to controllers that <em>have</em> enabled VERBOSE_NAMES.
506
 *
507
 * The EXTENDED_FORMAT and NONEXTENDED_FORMAT flags behave similarly with
508
 * respect to the EXTENDED_EVENTS feature. */
509
static void
510
511
send_control_event_string(uint16_t event, event_format_t which,
                          const char *msg)
512
{
513
  smartlist_t *conns = get_connection_array();
514
  (void)which;
515
516
  tor_assert(event >= _EVENT_MIN && event <= _EVENT_MAX);

517
  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
518
519
520
521
    if (conn->type == CONN_TYPE_CONTROL &&
        !conn->marked_for_close &&
        conn->state == CONTROL_CONN_STATE_OPEN) {
      control_connection_t *control_conn = TO_CONTROL_CONN(conn);
522

523
      if (control_conn->event_mask & (1<<event)) {
524
        int is_err = 0;
525
526
        connection_write_to_buf(msg, strlen(msg), TO_CONN(control_conn));
        if (event == EVENT_ERR_MSG)
527
528
529
530
531
532
533
534
          is_err = 1;
        else if (event == EVENT_STATUS_GENERAL)
          is_err = !strcmpstart(msg, "STATUS_GENERAL ERR ");
        else if (event == EVENT_STATUS_CLIENT)
          is_err = !strcmpstart(msg, "STATUS_CLIENT ERR ");
        else if (event == EVENT_STATUS_SERVER)
          is_err = !strcmpstart(msg, "STATUS_SERVER ERR ");
        if (is_err)
535
          connection_handle_write(TO_CONN(control_conn), 1);
536
      }
537
    }
538
  } SMARTLIST_FOREACH_END(conn);
539
540
}

541
542
543
544
545
546
/** Helper for send_control1_event and send_control1_event_extended:
 * Send an event to all v1 controllers that are listening for code
 * <b>event</b>.  The event's body is created by the printf-style format in
 * <b>format</b>, and other arguments as provided.
 *
 * Currently the length of the message is limited to 1024 (including the
547
 * ending \\r\\n\\0). */
548
static void
549
550
send_control_event_impl(uint16_t event, event_format_t which,
                         const char *format, va_list ap)
551
{
552
553
  /* This is just a little longer than the longest allowed log message */
#define SEND_CONTROL1_EVENT_BUFFERSIZE 10064
554
  int r;
555
  char buf[SEND_CONTROL1_EVENT_BUFFERSIZE];
556
557
558
  size_t len;

  r = tor_vsnprintf(buf, sizeof(buf), format, ap);
559
560
561
562
  if (r<0) {
    log_warn(LD_BUG, "Unable to format event for controller.");
    return;
  }
563
564
565
566
567
568
569
570
571

  len = strlen(buf);
  if (memcmp("\r\n\0", buf+len-2, 3)) {
    /* if it is not properly terminated, do it now */
    buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0';
    buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n';
    buf[SEND_CONTROL1_EVENT_BUFFERSIZE-3] = '\r';
  }

572
  send_control_event_string(event, which|ALL_FORMATS, buf);
573
574
}

575
/** Send an event to all v1 controllers that are listening for code
576
577
578
579
 * <b>event</b>.  The event's body is created by the printf-style format in
 * <b>format</b>, and other arguments as provided.
 *
 * Currently the length of the message is limited to 1024 (including the
580
 * ending \\n\\r\\0. */
581
static void
582
send_control_event(uint16_t event, event_format_t which,
583
                   const char *format, ...)
584
585
586
{
  va_list ap;
  va_start(ap, format);
587
  send_control_event_impl(event, which, format, ap);
588
  va_end(ap);
589
590
}

591
/** Given a text circuit <b>id</b>, return the corresponding circuit. */
592
static origin_circuit_t *
593
594
get_circ(const char *id)
{
595
  uint32_t n_id;
596
  int ok;
597
  n_id = (uint32_t) tor_parse_ulong(id, 10, 0, UINT32_MAX, &ok, NULL);
598
599
600
601
602
  if (!ok)
    return NULL;
  return circuit_get_by_global_id(n_id);
}

603
/** Given a text stream <b>id</b>, return the corresponding AP connection. */
604
static edge_connection_t *
605
606
get_stream(const char *id)
{
607
  uint64_t n_id;
608
  int ok;
609
610
  connection_t *conn;
  n_id = tor_parse_uint64(id, 10, 0, UINT64_MAX, &ok, NULL);
611
612
613
  if (!ok)
    return NULL;
  conn = connection_get_by_global_id(n_id);
614
  if (!conn || conn->type != CONN_TYPE_AP || conn->marked_for_close)
615
    return NULL;
616
  return TO_EDGE_CONN(conn);
617
618
}

619
/** Helper for setconf and resetconf. Acts like setconf, except
620
621
 * it passes <b>use_defaults</b> on to options_trial_assign().  Modifies the
 * contents of body.
622
 */
623
static int
624
control_setconf_helper(control_connection_t *conn, uint32_t len, char *body,
625
                       int use_defaults)
626
{
627
  setopt_err_t opt_err;
628
  config_line_t *lines=NULL;
629
  char *start = body;
630
  char *errstring = NULL;
631
  const int clear_first = 1;
632

633
634
635
636
637
638
639
640
641
642
643
644
645
646
  char *config;
  smartlist_t *entries = smartlist_create();

  /* We have a string, "body", of the format '(key(=val|="val")?)' entries
   * separated by space.  break it into a list of configuration entries. */
  while (*body) {
    char *eq = body;
    char *key;
    char *entry;
    while (!TOR_ISSPACE(*eq) && *eq != '=')
      ++eq;
    key = tor_strndup(body, eq-body);
    body = eq+1;
    if (*eq == '=') {
Roger Dingledine's avatar
Roger Dingledine committed
647
648
      char *val=NULL;
      size_t val_len=0;
649
650
651
652
653
654
655
      size_t ent_len;
      if (*body != '\"') {
        char *val_start = body;
        while (!TOR_ISSPACE(*body))
          body++;
        val = tor_strndup(val_start, body-val_start);
        val_len = strlen(val);
656
      } else {
657
658
        body = (char*)extract_escaped_string(body, (len - (body-start)),
                                             &val, &val_len);
659
660
661
662
        if (!body) {
          connection_write_str_to_buf("551 Couldn't parse string\r\n", conn);
          SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp));
          smartlist_free(entries);
663
          tor_free(key);
664
665
          return 0;
        }
666
      }
667
668
669
670
671
672
673
      ent_len = strlen(key)+val_len+3;
      entry = tor_malloc(ent_len+1);
      tor_snprintf(entry, ent_len, "%s %s", key, val);
      tor_free(key);
      tor_free(val);
    } else {
      entry = key;
674
    }
675
676
677
678
    smartlist_add(entries, entry);
    while (TOR_ISSPACE(*body))
      ++body;
  }
679

680
681
682
683
  smartlist_add(entries, tor_strdup(""));
  config = smartlist_join_strings(entries, "\n", 0, NULL);
  SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp));
  smartlist_free(entries);
684

685
686
687
688
  if (config_get_lines(config, &lines) < 0) {
    log_warn(LD_CONTROL,"Controller gave us config lines we can't parse.");
    connection_write_str_to_buf("551 Couldn't parse configuration\r\n",
                                conn);
689
    tor_free(config);
690
    return 0;
691
  }
692
  tor_free(config);
693

694
695
  opt_err = options_trial_assign(lines, use_defaults, clear_first, &errstring);
  {
696
    const char *msg;
697
698
    switch (opt_err) {
      case SETOPT_ERR_MISC:
699
        msg = "552 Unrecognized option";
700
        break;
701
      case SETOPT_ERR_PARSE:
Roger Dingledine's avatar
Roger Dingledine committed
702
        msg = "513 Unacceptable option value";
703
        break;
704
      case SETOPT_ERR_TRANSITION:
705
        msg = "553 Transition not allowed";
706
        break;
707
      case SETOPT_ERR_SETTING:
708
      default:
709
        msg = "553 Unable to set option";
710
        break;
711
      case SETOPT_OK:
712
713
714
        config_free_lines(lines);
        send_control_done(conn);
        return 0;
715
    }
716
717
718
    log_warn(LD_CONTROL,
             "Controller gave us config lines that didn't validate: %s",
             errstring);
719
    connection_printf_to_buf(conn, "%s: %s\r\n", msg, errstring);
720
    config_free_lines(lines);
721
    tor_free(errstring);
722
723
    return 0;
  }
724
}
725

726
/** Called when we receive a SETCONF message: parse the body and try
727
728
 * to update our configuration.  Reply with a DONE or ERROR message.
 * Modifies the contents of body.*/
729
static int
730
handle_control_setconf(control_connection_t *conn, uint32_t len, char *body)
731
{
732
  return control_setconf_helper(conn, len, body, 0);
733
734
735
}

/** Called when we receive a RESETCONF message: parse the body and try
736
737
 * to update our configuration.  Reply with a DONE or ERROR message.
 * Modifies the contents of body. */
738
static int
739
handle_control_resetconf(control_connection_t *conn, uint32_t len, char *body)
740
{
741
  return control_setconf_helper(conn, len, body, 1);
742
743
}

Nick Mathewson's avatar
Nick Mathewson committed
744
745
/** Called when we receive a GETCONF message.  Parse the request, and
 * reply with a CONFVALUE or an ERROR message */
746
static int
747
748
handle_control_getconf(control_connection_t *conn, uint32_t body_len,
                       const char *body)
749
{
750
751
752
  smartlist_t *questions = smartlist_create();
  smartlist_t *answers = smartlist_create();
  smartlist_t *unrecognized = smartlist_create();
753
754
  char *msg = NULL;
  size_t msg_len;
755
  or_options_t *options = get_options();
756
  int i, len;
757

Nick Mathewson's avatar
Nick Mathewson committed
758
  (void) body_len; /* body is NUL-terminated; so we can ignore len. */
759
760
  smartlist_split_string(questions, body, " ",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
761
  SMARTLIST_FOREACH(questions, const char *, q,
762
  {
763
    if (!option_is_recognized(q)) {
764
      smartlist_add(unrecognized, (char*) q);
765
    } else {
766
      config_line_t *answer = option_get_assignment(options,q);
767
      if (!answer) {
768
        const char *name = option_get_canonical_name(q);
769
        size_t alen = strlen(name)+8;
770
        char *astr = tor_malloc(alen);
771
        tor_snprintf(astr, alen, "250-%s\r\n", name);
772
773
        smartlist_add(answers, astr);
      }
774

775
      while (answer) {
776
        config_line_t *next;
777
        size_t alen = strlen(answer->key)+strlen(answer->value)+8;
778
        char *astr = tor_malloc(alen);
779
780
        tor_snprintf(astr, alen, "250-%s=%s\r\n",
                     answer->key, answer->value);
781
782
        smartlist_add(answers, astr);

783
        next = answer->next;
784
785
        tor_free(answer->key);
        tor_free(answer->value);
786
787
788
789
        tor_free(answer);
        answer = next;
      }
    }
790
  });
791

792
793
794
  if ((len = smartlist_len(unrecognized))) {
    for (i=0; i < len-1; ++i)
      connection_printf_to_buf(conn,
795
796
                               "552-Unrecognized configuration key \"%s\"\r\n",
                               (char*)smartlist_get(unrecognized, i));
797
798
799
800
801
802
803
804
805
806
807
    connection_printf_to_buf(conn,
                             "552 Unrecognized configuration key \"%s\"\r\n",
                             (char*)smartlist_get(unrecognized, len-1));
  } else if ((len = smartlist_len(answers))) {
    char *tmp = smartlist_get(answers, len-1);
    tor_assert(strlen(tmp)>4);
    tmp[3] = ' ';
    msg = smartlist_join_strings(answers, "", 0, &msg_len);
    connection_write_to_buf(msg, msg_len, TO_CONN(conn));
  } else {
    connection_write_str_to_buf("250 OK\r\n", conn);
808
  }
809

810
811
812
813
  SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
  smartlist_free(answers);
  SMARTLIST_FOREACH(questions, char *, cp, tor_free(cp));
  smartlist_free(questions);
814
  smartlist_free(unrecognized);
815

816
817
  tor_free(msg);

818
819
  return 0;
}
820

821
822
823
824
825
/** Called when we get a +LOADCONF message. */
static int
handle_control_loadconf(control_connection_t *conn, uint32_t len,
                         const char *body)
{
826
  setopt_err_t retval;
827
  char *errstring = NULL;
828
829
  const char *msg = NULL;
  (void) len;
830
831
832

  retval = options_init_from_string(body, CMD_RUN_TOR, NULL, &errstring);

833
  if (retval != SETOPT_OK)
834
835
836
    log_warn(LD_CONTROL,
             "Controller gave us config file that didn't validate: %s",
             errstring);
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855

  switch (retval) {
  case SETOPT_ERR_PARSE:
    msg = "552 Invalid config file";
    break;
  case SETOPT_ERR_TRANSITION:
    msg = "553 Transition not allowed";
    break;
  case SETOPT_ERR_SETTING:
    msg = "553 Unable to set option";
    break;
  case SETOPT_ERR_MISC:
  default:
    msg = "550 Unable to load config";
    break;
  case SETOPT_OK:
    break;
  }
  if (msg) {
856
857
858
859
    if (*errstring)
      connection_printf_to_buf(conn, "%s: %s\r\n", msg, errstring);
    else
      connection_printf_to_buf(conn, "%s\r\n", msg);
860
861
  } else {
    send_control_done(conn);
862
863
864
865
  }
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
866
867
868
/** Called when we get a SETEVENTS message: update conn->event_mask,
 * and reply with DONE or ERROR. */
static int
869
870
handle_control_setevents(control_connection_t *conn, uint32_t len,
                         const char *body)
871
872
873
{
  uint16_t event_code;
  uint32_t event_mask = 0;
874
875
  smartlist_t *events = smartlist_create();

876
  (void) len;
877

878
879
  smartlist_split_string(events, body, " ",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
880
  SMARTLIST_FOREACH_BEGIN(events, const char *, ev)
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
    {
      if (!strcasecmp(ev, "EXTENDED")) {
        continue;
      } else if (!strcasecmp(ev, "CIRC"))
        event_code = EVENT_CIRCUIT_STATUS;
      else if (!strcasecmp(ev, "STREAM"))
        event_code = EVENT_STREAM_STATUS;
      else if (!strcasecmp(ev, "ORCONN"))
        event_code = EVENT_OR_CONN_STATUS;
      else if (!strcasecmp(ev, "BW"))
        event_code = EVENT_BANDWIDTH_USED;
      else if (!strcasecmp(ev, "DEBUG"))
        event_code = EVENT_DEBUG_MSG;
      else if (!strcasecmp(ev, "INFO"))
        event_code = EVENT_INFO_MSG;
      else if (!strcasecmp(ev, "NOTICE"))
        event_code = EVENT_NOTICE_MSG;
      else if (!strcasecmp(ev, "WARN"))
        event_code = EVENT_WARN_MSG;
      else if (!strcasecmp(ev, "ERR"))
        event_code = EVENT_ERR_MSG;
      else if (!strcasecmp(ev, "NEWDESC"))
        event_code = EVENT_NEW_DESC;
      else if (!strcasecmp(ev, "ADDRMAP"))
        event_code = EVENT_ADDRMAP;
      else if (!strcasecmp(ev, "AUTHDIR_NEWDESCS"))
        event_code = EVENT_AUTHDIR_NEWDESCS;
      else if (!strcasecmp(ev, "DESCCHANGED"))
        event_code = EVENT_DESCCHANGED;
      else if (!strcasecmp(ev, "NS"))
        event_code = EVENT_NS;
      else if (!strcasecmp(ev, "STATUS_GENERAL"))
        event_code = EVENT_STATUS_GENERAL;
      else if (!strcasecmp(ev, "STATUS_CLIENT"))
        event_code = EVENT_STATUS_CLIENT;
      else if (!strcasecmp(ev, "STATUS_SERVER"))
        event_code = EVENT_STATUS_SERVER;
      else if (!strcasecmp(ev, "GUARD"))
        event_code = EVENT_GUARD;