test_options.c 161 KB
Newer Older
1
2
/* Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
Nick Mathewson's avatar
Nick Mathewson committed
3
 * Copyright (c) 2007-2019, The Tor Project, Inc. */
4
5
6
/* See LICENSE for licensing information */

#define CONFIG_PRIVATE
7
8
9
#include "core/or/or.h"
#include "app/config/confparse.h"
#include "app/config/config.h"
Nick Mathewson's avatar
Nick Mathewson committed
10
#include "test/test.h"
11
#include "lib/geoip/geoip.h"
Ola Bini's avatar
Ola Bini committed
12
13

#define ROUTERSET_PRIVATE
14
#include "feature/nodelist/routerset.h"
15
#include "core/mainloop/mainloop.h"
Nick Mathewson's avatar
Nick Mathewson committed
16
17
#include "test/log_test_helpers.h"

18
#include "lib/sandbox/sandbox.h"
19
#include "lib/memarea/memarea.h"
20
#include "lib/osinfo/uname.h"
21
#include "lib/encoding/confline.h"
22
#include "core/or/policies.h"
Nick Mathewson's avatar
Nick Mathewson committed
23
#include "test/test_helpers.h"
24
#include "lib/net/resolve.h"
Ola Bini's avatar
Ola Bini committed
25

26
27
28
29
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

Ola Bini's avatar
Ola Bini committed
30
#define NS_MODULE test_options
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

typedef struct {
  int severity;
  uint32_t domain;
  char *msg;
} logmsg_t;

static smartlist_t *messages = NULL;

static void
log_cback(int severity, uint32_t domain, const char *msg)
{
  logmsg_t *x = tor_malloc(sizeof(*x));
  x->severity = severity;
  x->domain = domain;
  x->msg = tor_strdup(msg);
  if (!messages)
    messages = smartlist_new();
  smartlist_add(messages, x);
}

static void
setup_log_callback(void)
{
  log_severity_list_t lst;
  memset(&lst, 0, sizeof(lst));
  lst.masks[LOG_ERR - LOG_ERR] = ~0;
  lst.masks[LOG_WARN - LOG_ERR] = ~0;
  lst.masks[LOG_NOTICE - LOG_ERR] = ~0;
  add_callback_log(&lst, log_cback);
61
  mark_logs_temp();
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
}

static char *
dump_logs(void)
{
  smartlist_t *msgs;
  char *out;
  if (! messages)
    return tor_strdup("");
  msgs = smartlist_new();
  SMARTLIST_FOREACH_BEGIN(messages, logmsg_t *, x) {
    smartlist_add_asprintf(msgs, "[%s] %s",
                           log_level_to_string(x->severity), x->msg);
  } SMARTLIST_FOREACH_END(x);
  out = smartlist_join_strings(msgs, "", 0, NULL);
  SMARTLIST_FOREACH(msgs, char *, cp, tor_free(cp));
  smartlist_free(msgs);
  return out;
}

static void
clear_log_messages(void)
{
  if (!messages)
    return;
  SMARTLIST_FOREACH(messages, logmsg_t *, m,
                    { tor_free(m->msg); tor_free(m); });
  smartlist_free(messages);
  messages = NULL;
}

93
94
95
96
97
98
99
100
101
102
#define setup_options(opt,dflt)              \
  do {                                       \
    opt = options_new();                     \
    opt->command = CMD_RUN_TOR;              \
    options_init(opt);                       \
                                             \
    dflt = config_dup(&options_format, opt); \
    clear_log_messages();                    \
  } while (0)

Ola Bini's avatar
Ola Bini committed
103
104
105
106
107
108
109
110
111
112
113
114
#define VALID_DIR_AUTH "DirAuthority dizum orport=443 v3ident=E8A9C45"  \
  "EDE6D711294FADF8E7951F4DE6CA56B58 194.109.206.212:80 7EA6 EAD6 FD83" \
  " 083C 538F 4403 8BBF A077 587D D755\n"
#define VALID_ALT_BRIDGE_AUTH \
  "AlternateBridgeAuthority dizum orport=443 v3ident=E8A9C45"           \
  "EDE6D711294FADF8E7951F4DE6CA56B58 194.109.206.212:80 7EA6 EAD6 FD83" \
  " 083C 538F 4403 8BBF A077 587D D755\n"
#define VALID_ALT_DIR_AUTH \
  "AlternateDirAuthority dizum orport=443 v3ident=E8A9C45"           \
  "EDE6D711294FADF8E7951F4DE6CA56B58 194.109.206.212:80 7EA6 EAD6 FD83" \
  " 083C 538F 4403 8BBF A077 587D D755\n"

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
static int
test_options_checklog(const char *configuration, int expect_log_severity,
                      const char *expect_log)
{
  int found = 0, ret = -1;
  char *actual_log = NULL;

  if (messages) {
    SMARTLIST_FOREACH_BEGIN(messages, logmsg_t *, m) {
      if (m->severity == expect_log_severity &&
          strstr(m->msg, expect_log)) {
        found = 1;
        break;
      }
    } SMARTLIST_FOREACH_END(m);
  }
  if (!found) {
    actual_log = dump_logs();
    TT_DIE(("Expected log message [%s] %s from <%s>, but got <%s>.",
            log_level_to_string(expect_log_severity), expect_log,
            configuration, actual_log));
  }
  ret = 0;

 done:
  tor_free(actual_log);
  return ret;
}

Taylor Yu's avatar
Taylor Yu committed
144
145
146
147
148
149
static int
test_options_checkmsgs(const char *configuration,
                       const char *expect_errmsg,
                       int expect_log_severity,
                       const char *expect_log,
                       char *msg)
150
151
152
153
154
155
156
157
158
159
160
161
{
  if (expect_errmsg && !msg) {
    TT_DIE(("Expected error message <%s> from <%s>, but got none.",
            expect_errmsg, configuration));
  } else if (expect_errmsg && !strstr(msg, expect_errmsg)) {
    TT_DIE(("Expected error message <%s> from <%s>, but got <%s>.",
            expect_errmsg, configuration, msg));
  } else if (!expect_errmsg && msg) {
    TT_DIE(("Expected no error message from <%s> but got <%s>.",
            configuration, msg));
  }
  if (expect_log) {
162
163
    return test_options_checklog(configuration, expect_log_severity,
                                 expect_log);
164
  }
Taylor Yu's avatar
Taylor Yu committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  return 0;

 done:
  return -1;
}

/* Which phases of config parsing/validation to check for messages/logs */
enum { PH_GETLINES, PH_ASSIGN, PH_VALIDATE };

static void
test_options_validate_impl(const char *configuration,
                           const char *expect_errmsg,
                           int expect_log_severity,
                           const char *expect_log,
                           int phase)
{
  or_options_t *opt=NULL;
  or_options_t *dflt;
  config_line_t *cl=NULL;
  char *msg=NULL;
  int r;

  setup_options(opt, dflt);

  r = config_get_lines(configuration, &cl, 1);
  if (phase == PH_GETLINES) {
    if (test_options_checkmsgs(configuration, expect_errmsg,
                               expect_log_severity,
                               expect_log, msg))
      goto done;
  }
Taylor Yu's avatar
Taylor Yu committed
196
197
  if (r)
    goto done;
Taylor Yu's avatar
Taylor Yu committed
198
199
200
201
202
203
204
205
206

  r = config_assign(&options_format, opt, cl, 0, &msg);
  if (phase == PH_ASSIGN) {
    if (test_options_checkmsgs(configuration, expect_errmsg,
                               expect_log_severity,
                               expect_log, msg))
      goto done;
  }
  tt_int_op((r == 0), OP_EQ, (msg == NULL));
207
208
  if (r)
    goto done;
Taylor Yu's avatar
Taylor Yu committed
209
210
211
212
213
214
215
216
217

  r = options_validate(NULL, opt, dflt, 0, &msg);
  if (phase == PH_VALIDATE) {
    if (test_options_checkmsgs(configuration, expect_errmsg,
                               expect_log_severity,
                               expect_log, msg))
      goto done;
  }
  tt_int_op((r == 0), OP_EQ, (msg == NULL));
218
219

 done:
Ola Bini's avatar
Ola Bini committed
220
221
  escaped(NULL);
  policies_free_all();
222
223
224
225
226
227
228
  config_free_lines(cl);
  or_options_free(opt);
  or_options_free(dflt);
  tor_free(msg);
  clear_log_messages();
}

Taylor Yu's avatar
Taylor Yu committed
229
230
231
232
233
234
235
236
#define WANT_ERR(config, msg, ph)                               \
  test_options_validate_impl((config), (msg), 0, NULL, (ph))
#define WANT_LOG(config, severity, msg, ph)                             \
  test_options_validate_impl((config), NULL, (severity), (msg), (ph))
#define WANT_ERR_LOG(config, msg, severity, logmsg, ph)                 \
  test_options_validate_impl((config), (msg), (severity), (logmsg), (ph))
#define OK(config, ph)                                          \
  test_options_validate_impl((config), NULL, 0, NULL, (ph))
237
238
239
240
241
242

static void
test_options_validate(void *arg)
{
  (void)arg;
  setup_log_callback();
Ola Bini's avatar
Ola Bini committed
243
  sandbox_disable_getaddrinfo_cache();
244

Taylor Yu's avatar
Taylor Yu committed
245
  WANT_ERR("ExtORPort 500000", "Invalid ExtORPort", PH_VALIDATE);
Nick Mathewson's avatar
Nick Mathewson committed
246

247
248
  WANT_ERR_LOG("ServerTransportOptions trebuchet",
               "ServerTransportOptions did not parse",
Taylor Yu's avatar
Taylor Yu committed
249
250
251
               LOG_WARN, "Too few arguments", PH_VALIDATE);
  OK("ServerTransportOptions trebuchet sling=snappy", PH_VALIDATE);
  OK("ServerTransportOptions trebuchet sling=", PH_VALIDATE);
252
253
  WANT_ERR_LOG("ServerTransportOptions trebuchet slingsnappy",
               "ServerTransportOptions did not parse",
Taylor Yu's avatar
Taylor Yu committed
254
               LOG_WARN, "\"slingsnappy\" is not a k=v", PH_VALIDATE);
255

256
  WANT_ERR("DirPort 8080\nDirCache 0",
Taylor Yu's avatar
Taylor Yu committed
257
           "DirPort configured but DirCache disabled.", PH_VALIDATE);
258
  WANT_ERR("BridgeRelay 1\nDirCache 0",
Taylor Yu's avatar
Taylor Yu committed
259
260
261
262
263
264
265
266
267
268
269
270
           "We're a bridge but DirCache is disabled.", PH_VALIDATE);

  WANT_ERR_LOG("HeartbeatPeriod 21 snarks",
               "Interval 'HeartbeatPeriod 21 snarks' is malformed or"
               " out of bounds.", LOG_WARN, "Unknown unit 'snarks'.",
               PH_ASSIGN);
  WANT_ERR_LOG("LogTimeGranularity 21 snarks",
               "Msec interval 'LogTimeGranularity 21 snarks' is malformed or"
               " out of bounds.", LOG_WARN, "Unknown unit 'snarks'.",
               PH_ASSIGN);
  OK("HeartbeatPeriod 1 hour", PH_VALIDATE);
  OK("LogTimeGranularity 100 milliseconds", PH_VALIDATE);
271

Taylor Yu's avatar
Taylor Yu committed
272
273
274
275
276
277
278
  WANT_LOG("ControlSocket \"string with trailing garbage\" bogus", LOG_WARN,
           "Error while parsing configuration: "
           "Excess data after quoted string", PH_GETLINES);
  WANT_LOG("ControlSocket \"bogus escape \\@\"", LOG_WARN,
           "Error while parsing configuration: "
           "Invalid escape sequence in quoted string", PH_GETLINES);

279
  close_temp_logs();
280
  clear_log_messages();
281
282
283
  return;
}

284
#define MEGABYTEIFY(mb) (UINT64_C(mb) << 20)
285
286
287
288
289
static void
test_have_enough_mem_for_dircache(void *arg)
{
  (void)arg;
  or_options_t *opt=NULL;
290
  or_options_t *dflt=NULL;
291
  config_line_t *cl=NULL;
292
  char *msg=NULL;
293
294
295
296
297
298
299
300
301
302
  int r;
  const char *configuration = "ORPort 8080\nDirCache 1", *expect_errmsg;

  setup_options(opt, dflt);
  setup_log_callback();
  (void)dflt;

  r = config_get_lines(configuration, &cl, 1);
  tt_int_op(r, OP_EQ, 0);

303
  r = config_assign(&options_format, opt, cl, 0, &msg);
304
305
306
307
308
  tt_int_op(r, OP_EQ, 0);

  /* 300 MB RAM available, DirCache enabled */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(300), &msg);
  tt_int_op(r, OP_EQ, 0);
309
  tt_ptr_op(msg, OP_EQ, NULL);
310
311
312
313
314
315
316
317
318
319
320

  /* 200 MB RAM available, DirCache enabled */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(200), &msg);
  tt_int_op(r, OP_EQ, -1);
  expect_errmsg = "Being a directory cache (default) with less than ";
  if (!strstr(msg, expect_errmsg)) {
    TT_DIE(("Expected error message <%s> from <%s>, but got <%s>.",
            expect_errmsg, configuration, msg));
  }
  tor_free(msg);

321
  config_free_lines(cl); cl = NULL;
322
323
324
325
  configuration = "ORPort 8080\nDirCache 1\nBridgeRelay 1";
  r = config_get_lines(configuration, &cl, 1);
  tt_int_op(r, OP_EQ, 0);

326
  r = config_assign(&options_format, opt, cl, 0, &msg);
327
328
329
330
331
  tt_int_op(r, OP_EQ, 0);

  /* 300 MB RAM available, DirCache enabled, Bridge */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(300), &msg);
  tt_int_op(r, OP_EQ, 0);
332
  tt_ptr_op(msg, OP_EQ, NULL);
333
334
335
336
337
338
339
340
341
342
343

  /* 200 MB RAM available, DirCache enabled, Bridge */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(200), &msg);
  tt_int_op(r, OP_EQ, -1);
  expect_errmsg = "Running a Bridge with less than ";
  if (!strstr(msg, expect_errmsg)) {
    TT_DIE(("Expected error message <%s> from <%s>, but got <%s>.",
            expect_errmsg, configuration, msg));
  }
  tor_free(msg);

344
  config_free_lines(cl); cl = NULL;
345
346
347
348
  configuration = "ORPort 8080\nDirCache 0";
  r = config_get_lines(configuration, &cl, 1);
  tt_int_op(r, OP_EQ, 0);

349
  r = config_assign(&options_format, opt, cl, 0, &msg);
350
351
352
353
354
  tt_int_op(r, OP_EQ, 0);

  /* 200 MB RAM available, DirCache disabled */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(200), &msg);
  tt_int_op(r, OP_EQ, 0);
355
  tt_ptr_op(msg, OP_EQ, NULL);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

  /* 300 MB RAM available, DirCache disabled */
  r = have_enough_mem_for_dircache(opt, MEGABYTEIFY(300), &msg);
  tt_int_op(r, OP_EQ, -1);
  expect_errmsg = "DirCache is disabled and we are configured as a ";
  if (!strstr(msg, expect_errmsg)) {
    TT_DIE(("Expected error message <%s> from <%s>, but got <%s>.",
            expect_errmsg, configuration, msg));
  }
  tor_free(msg);

  clear_log_messages();

 done:
  if (msg)
    tor_free(msg);
372
  or_options_free(dflt);
373
  or_options_free(opt);
374
  config_free_lines(cl);
375
376
377
  return;
}

Ola Bini's avatar
Ola Bini committed
378
static const char *fixed_get_uname_result = NULL;
Ola Bini's avatar
Ola Bini committed
379
380
381
382
383
384
385
386

static const char *
fixed_get_uname(void)
{
  return fixed_get_uname_result;
}

#define TEST_OPTIONS_OLD_VALUES   "TestingV3AuthInitialVotingInterval 1800\n" \
387
  "ClientBootstrapConsensusMaxInProgressTries 3\n" \
388
  "TestingV3AuthInitialVoteDelay 300\n"   \
Ola Bini's avatar
Ola Bini committed
389
390
391
392
  "TestingV3AuthInitialDistDelay 300\n" \
  "TestingClientMaxIntervalWithoutRequest 600\n" \
  "TestingDirConnectionMaxStall 600\n" \

Ola Bini's avatar
Ola Bini committed
393
394
#define TEST_OPTIONS_DEFAULT_VALUES TEST_OPTIONS_OLD_VALUES \
  "MaxClientCircuitsPending 1\n"                                        \
Ola Bini's avatar
Ola Bini committed
395
396
397
398
399
400
401
  "RendPostPeriod 1000\n"                                               \
  "KeepAlivePeriod 1\n"                                                 \
  "ConnLimit 1\n"                                                       \
  "V3AuthVotingInterval 300\n"                                          \
  "V3AuthVoteDelay 20\n"                                                \
  "V3AuthDistDelay 20\n"                                                \
  "V3AuthNIntervalsValid 3\n"                                           \
402
  "ClientUseIPv4 1\n"                                                   \
Ola Bini's avatar
Ola Bini committed
403
404
  "VirtualAddrNetworkIPv4 127.192.0.0/10\n"                             \
  "VirtualAddrNetworkIPv6 [FE80::]/10\n"                                \
405
  "UseEntryGuards 1\n"                                                  \
406
407
  "Schedulers Vanilla\n"                                                \
  "ClientDNSRejectInternalAddresses 1\n"
Ola Bini's avatar
Ola Bini committed
408
409
410
411
412
413
414

typedef struct {
  or_options_t *old_opt;
  or_options_t *opt;
  or_options_t *def_opt;
} options_test_data_t;

415
416
static void free_options_test_data(options_test_data_t *td);

Ola Bini's avatar
Ola Bini committed
417
static options_test_data_t *
Ola Bini's avatar
Ola Bini committed
418
get_options_test_data(const char *conf)
Ola Bini's avatar
Ola Bini committed
419
{
420
421
  int rv = -1;
  char *msg = NULL;
Ola Bini's avatar
Ola Bini committed
422
423
424
425
426
  config_line_t *cl=NULL;
  options_test_data_t *result = tor_malloc(sizeof(options_test_data_t));
  result->opt = options_new();
  result->old_opt = options_new();
  result->def_opt = options_new();
Mike Perry's avatar
Mike Perry committed
427
428
429
430
431
432

  // XXX: Really, all of these options should be set to defaults
  // with options_init(), but about a dozen tests break when I do that.
  // Being kinda lame and just fixing the immedate breakage for now..
  result->opt->ConnectionPadding = -1; // default must be "auto"

433
  rv = config_get_lines(conf, &cl, 1);
434
  tt_int_op(rv, OP_EQ, 0);
435
  rv = config_assign(&options_format, result->opt, cl, 0, &msg);
436
437
438
439
  if (msg) {
    /* Display the parse error message by comparing it with an empty string */
    tt_str_op(msg, OP_EQ, "");
  }
440
  tt_int_op(rv, OP_EQ, 0);
Ola Bini's avatar
Ola Bini committed
441
  config_free_lines(cl);
Ola Bini's avatar
Ola Bini committed
442
443
  result->opt->LogTimeGranularity = 1;
  result->opt->TokenBucketRefillInterval = 1;
444
  rv = config_get_lines(TEST_OPTIONS_OLD_VALUES, &cl, 1);
445
  tt_int_op(rv, OP_EQ, 0);
446
  rv = config_assign(&options_format, result->def_opt, cl, 0, &msg);
447
448
449
450
  if (msg) {
    /* Display the parse error message by comparing it with an empty string */
    tt_str_op(msg, OP_EQ, "");
  }
451
  tt_int_op(rv, OP_EQ, 0);
452

453
 done:
Ola Bini's avatar
Ola Bini committed
454
  config_free_lines(cl);
455
456
457
458
459
460
461
  if (rv != 0) {
    free_options_test_data(result);
    result = NULL;
    /* Callers expect a non-NULL result, so just die if we can't provide one.
     */
    tor_assert(0);
  }
Ola Bini's avatar
Ola Bini committed
462
463
464
465
466
467
  return result;
}

static void
free_options_test_data(options_test_data_t *td)
{
Ola Bini's avatar
Ola Bini committed
468
  if (!td) return;
Ola Bini's avatar
Ola Bini committed
469
470
471
472
473
474
475
476
477
478
479
  or_options_free(td->old_opt);
  or_options_free(td->opt);
  or_options_free(td->def_opt);
  tor_free(td);
}

static void
test_options_validate__uname_for_server(void *ignored)
{
  (void)ignored;
  char *msg;
480

481
#ifndef _WIN32
482
483
484
  int unset_home_env = 0;
  if (setenv("HOME", "/home/john", 0) == 0)
    unset_home_env = 1;
485
#endif
486

Ola Bini's avatar
Ola Bini committed
487
  options_test_data_t *tdata = get_options_test_data(
488
489
                                      "ORPort 127.0.0.1:5555\n"
                                      "ContactInfo nobody@example.com");
490
  setup_capture_of_logs(LOG_WARN);
Ola Bini's avatar
Ola Bini committed
491
492
493
494

  MOCK(get_uname, fixed_get_uname);
  fixed_get_uname_result = "Windows 95";
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
495
  expect_log_msg("Tor is running as a server, but you"
Ola Bini's avatar
Ola Bini committed
496
497
           " are running Windows 95; this probably won't work. See https://www"
           ".torproject.org/docs/faq.html#BestOSForRelay for details.\n");
Ola Bini's avatar
Ola Bini committed
498
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
499
500
501
502

  fixed_get_uname_result = "Windows 98";
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
503
  expect_log_msg("Tor is running as a server, but you"
Ola Bini's avatar
Ola Bini committed
504
505
           " are running Windows 98; this probably won't work. See https://www"
           ".torproject.org/docs/faq.html#BestOSForRelay for details.\n");
Ola Bini's avatar
Ola Bini committed
506
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
507
508
509
510

  fixed_get_uname_result = "Windows Me";
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
511
  expect_log_msg("Tor is running as a server, but you"
Ola Bini's avatar
Ola Bini committed
512
513
           " are running Windows Me; this probably won't work. See https://www"
           ".torproject.org/docs/faq.html#BestOSForRelay for details.\n");
Ola Bini's avatar
Ola Bini committed
514
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
515
516
517
518

  fixed_get_uname_result = "Windows 2000";
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
519
  expect_no_log_entry();
Ola Bini's avatar
Ola Bini committed
520
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
521
522
523
524
525

 done:
  UNMOCK(get_uname);
  free_options_test_data(tdata);
  tor_free(msg);
526
  teardown_capture_of_logs();
527
#ifndef _WIN32
528
529
  if (unset_home_env)
    unsetenv("HOME");
530
#endif
Ola Bini's avatar
Ola Bini committed
531
532
533
534
535
536
537
538
}

static void
test_options_validate__outbound_addresses(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
Ola Bini's avatar
Ola Bini committed
539
540
  options_test_data_t *tdata = get_options_test_data(
                                    "OutboundBindAddress xxyy!!!sdfaf");
Ola Bini's avatar
Ola Bini committed
541
542
543

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
544
545
  tt_str_op(msg, OP_EQ, "Multiple outbound bind addresses configured: "
                        "xxyy!!!sdfaf");
Ola Bini's avatar
Ola Bini committed
546
547
548
549
550
551
552
553
554
555
556
557

 done:
  free_options_test_data(tdata);
  tor_free(msg);
}

static void
test_options_validate__data_directory(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
Ola Bini's avatar
Ola Bini committed
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  options_test_data_t *tdata = get_options_test_data(
                                                "DataDirectory longreallyl"
                                                "ongLONGLONGlongreallylong"
                                                "LONGLONGlongreallylongLON"
                                                "GLONGlongreallylongLONGLO"
                                                "NGlongreallylongLONGLONGl"
                                                "ongreallylongLONGLONGlong"
                                                "reallylongLONGLONGlongrea"
                                                "llylongLONGLONGlongreally"
                                                "longLONGLONGlongreallylon"
                                                "gLONGLONGlongreallylongLO"
                                                "NGLONGlongreallylongLONGL"
                                                "ONGlongreallylongLONGLONG"
                                                "longreallylongLONGLONGlon"
                                                "greallylongLONGLONGlongre"
                                                "allylongLONGLONGlongreall"
                                                "ylongLONGLONGlongreallylo"
                                                "ngLONGLONGlongreallylongL"
                                                "ONGLONGlongreallylongLONG"
                                                "LONG"); // 440 characters
Ola Bini's avatar
Ola Bini committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
  tt_str_op(msg, OP_EQ, "Invalid DataDirectory");

 done:
  free_options_test_data(tdata);
  tor_free(msg);
}

static void
test_options_validate__nickname(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
Ola Bini's avatar
Ola Bini committed
594
595
  options_test_data_t *tdata = get_options_test_data(
                                        "Nickname ThisNickNameIsABitTooLong");
Ola Bini's avatar
Ola Bini committed
596
597
598

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
599
  tt_str_op(msg, OP_EQ,
600
601
602
            "Nickname 'ThisNickNameIsABitTooLong', nicknames must be between "
            "1 and 19 characters inclusive, and must contain only the "
            "characters [a-zA-Z0-9].");
Ola Bini's avatar
Ola Bini committed
603
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
604
605
606
607
608

  free_options_test_data(tdata);
  tdata = get_options_test_data("Nickname AMoreValidNick");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
609
610
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
611
612
613
614
615

  free_options_test_data(tdata);
  tdata = get_options_test_data("DataDirectory /tmp/somewhere");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
616
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
Ola Bini's avatar
Ola Bini committed
617
618
619
620
621
622
623
624
625
626
627
628

 done:
  free_options_test_data(tdata);
  tor_free(msg);
}

static void
test_options_validate__contactinfo(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
Ola Bini's avatar
Ola Bini committed
629
  options_test_data_t *tdata = get_options_test_data(
630
                                "ORPort 127.0.0.1:5555");
631
  setup_capture_of_logs(LOG_DEBUG);
Ola Bini's avatar
Ola Bini committed
632
633
634
635
  tdata->opt->ContactInfo = NULL;

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
636
  expect_log_msg(
637
638
639
640
641
           "Your ContactInfo config option is not set. Please strongly "
           "consider setting it, so we can contact you if your relay is "
           "misconfigured, end-of-life, or something else goes wrong. It "
           "is also possible that your relay might get rejected from the "
           "network due to a missing valid contact address.\n");
Ola Bini's avatar
Ola Bini committed
642
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
643
644

  free_options_test_data(tdata);
645
  tdata = get_options_test_data("ORPort 127.0.0.1:5555\n"
Ola Bini's avatar
Ola Bini committed
646
                                "ContactInfo hella@example.org");
Ola Bini's avatar
Ola Bini committed
647
648
649
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
650
  expect_no_log_msg(
651
652
653
654
655
           "Your ContactInfo config option is not set. Please strongly "
           "consider setting it, so we can contact you if your relay is "
           "misconfigured, end-of-life, or something else goes wrong. It "
           "is also possible that your relay might get rejected from the "
           "network due to a missing valid contact address.\n");
Ola Bini's avatar
Ola Bini committed
656
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
657
658

 done:
659
  teardown_capture_of_logs();
Ola Bini's avatar
Ola Bini committed
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  free_options_test_data(tdata);
  tor_free(msg);
}

static void
test_options_validate__logs(void *ignored)
{
  (void)ignored;
  int ret;
  (void)ret;
  char *msg;
  int orig_quiet_level = quiet_level;
  options_test_data_t *tdata = get_options_test_data("");
  tdata->opt->Logs = NULL;
  tdata->opt->RunAsDaemon = 0;

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_str_op(tdata->opt->Logs->key, OP_EQ, "Log");
  tt_str_op(tdata->opt->Logs->value, OP_EQ, "notice stdout");
Ola Bini's avatar
Ola Bini committed
679
  tor_free(msg);
680
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
681

Ola Bini's avatar
Ola Bini committed
682
683
  free_options_test_data(tdata);
  tdata = get_options_test_data("");
Ola Bini's avatar
Ola Bini committed
684
  tdata->opt->Logs = NULL;
Ola Bini's avatar
Ola Bini committed
685
  tdata->opt->RunAsDaemon = 0;
Ola Bini's avatar
Ola Bini committed
686
687
688
689
  quiet_level = 1;
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_str_op(tdata->opt->Logs->key, OP_EQ, "Log");
  tt_str_op(tdata->opt->Logs->value, OP_EQ, "warn stdout");
Ola Bini's avatar
Ola Bini committed
690
  tor_free(msg);
691
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
692

Ola Bini's avatar
Ola Bini committed
693
694
  free_options_test_data(tdata);
  tdata = get_options_test_data("");
Ola Bini's avatar
Ola Bini committed
695
  tdata->opt->Logs = NULL;
Ola Bini's avatar
Ola Bini committed
696
  tdata->opt->RunAsDaemon = 0;
Ola Bini's avatar
Ola Bini committed
697
698
699
  quiet_level = 2;
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_assert(!tdata->opt->Logs);
Ola Bini's avatar
Ola Bini committed
700
  tor_free(msg);
701
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
702

Ola Bini's avatar
Ola Bini committed
703
704
  free_options_test_data(tdata);
  tdata = get_options_test_data("");
Ola Bini's avatar
Ola Bini committed
705
  tdata->opt->Logs = NULL;
Ola Bini's avatar
Ola Bini committed
706
  tdata->opt->RunAsDaemon = 0;
Ola Bini's avatar
Ola Bini committed
707
708
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 1, &msg);
  tt_assert(!tdata->opt->Logs);
Ola Bini's avatar
Ola Bini committed
709
  tor_free(msg);
710
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
711

Ola Bini's avatar
Ola Bini committed
712
713
714
  free_options_test_data(tdata);
  tdata = get_options_test_data("");
  tdata->opt->Logs = NULL;
Ola Bini's avatar
Ola Bini committed
715
716
717
  tdata->opt->RunAsDaemon = 1;
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_assert(!tdata->opt->Logs);
Ola Bini's avatar
Ola Bini committed
718
  tor_free(msg);
719
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
720

Ola Bini's avatar
Ola Bini committed
721
722
723
  free_options_test_data(tdata);
  tdata = get_options_test_data("");
  tdata->opt->RunAsDaemon = 0;
Ola Bini's avatar
Ola Bini committed
724
725
726
727
728
  config_line_t *cl=NULL;
  config_get_lines("Log foo", &cl, 1);
  tdata->opt->Logs = cl;
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op((intptr_t)tdata->opt->Logs, OP_EQ, (intptr_t)cl);
729
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

 done:
  quiet_level = orig_quiet_level;
  free_options_test_data(tdata);
  tor_free(msg);
}

/* static config_line_t * */
/* mock_config_line(const char *key, const char *val) */
/* { */
/*   config_line_t *config_line = tor_malloc(sizeof(config_line_t)); */
/*   memset(config_line, 0, sizeof(config_line_t)); */
/*   config_line->key = tor_strdup(key); */
/*   config_line->value = tor_strdup(val); */
/*   return config_line; */
/* } */

static void
test_options_validate__authdir(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
753
  setup_capture_of_logs(LOG_INFO);
Ola Bini's avatar
Ola Bini committed
754
755
  options_test_data_t *tdata = get_options_test_data(
                                 "AuthoritativeDirectory 1\n"
756
                                 "Address this.should.not!exist!.example.org");
Ola Bini's avatar
Ola Bini committed
757

Ola Bini's avatar
Ola Bini committed
758
759
  sandbox_disable_getaddrinfo_cache();

760
  MOCK(tor_addr_lookup, mock_tor_addr_lookup__fail_on_bad_addrs);
Ola Bini's avatar
Ola Bini committed
761
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
762
  UNMOCK(tor_addr_lookup);
Ola Bini's avatar
Ola Bini committed
763
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
764
765
  tt_str_op(msg, OP_EQ, "Failed to resolve/guess local address. See logs for"
            " details.");
766
  expect_log_msg("Could not resolve local Address "
767
            "'this.should.not!exist!.example.org'. Failing.\n");
Ola Bini's avatar
Ola Bini committed
768
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
769
770
771
772
773
774
775

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1");
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
776
777
778
  tt_str_op(msg, OP_EQ, "Authoritative directory servers must set "
                        "ContactInfo");
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
779
780
781

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
782
                                "Address 100.200.10.1\n");
Ola Bini's avatar
Ola Bini committed
783
784
785
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
786
787
  tt_str_op(msg, OP_EQ,
            "Authoritative directory servers must set ContactInfo");
Ola Bini's avatar
Ola Bini committed
788
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
789
790
791
792

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
793
                                "TestingTorNetwork 1\n");
Ola Bini's avatar
Ola Bini committed
794
795
796
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
797
798
  tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
            "AuthoritativeDir is set.");
Ola Bini's avatar
Ola Bini committed
799
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
800
801
802
803

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
804
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
805
806
807
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
808
809
  tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
            "AuthoritativeDir is set.");
Ola Bini's avatar
Ola Bini committed
810
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
811
812
813
814
815

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "RecommendedVersions 1.2, 3.14\n"
816
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
817
818
819
820
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "1.2, 3.14");
  tt_str_op(tdata->opt->RecommendedServerVersions->value, OP_EQ, "1.2, 3.14");
Ola Bini's avatar
Ola Bini committed
821
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
822
823
824
825
826
827
828

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "RecommendedVersions 1.2, 3.14\n"
                                "RecommendedClientVersions 25\n"
                                "RecommendedServerVersions 4.18\n"
829
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
830
831
832
833
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_str_op(tdata->opt->RecommendedClientVersions->value, OP_EQ, "25");
  tt_str_op(tdata->opt->RecommendedServerVersions->value, OP_EQ, "4.18");
Ola Bini's avatar
Ola Bini committed
834
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
835
836
837
838
839
840
841
842

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "VersioningAuthoritativeDirectory 1\n"
                                "RecommendedVersions 1.2, 3.14\n"
                                "RecommendedClientVersions 25\n"
                                "RecommendedServerVersions 4.18\n"
843
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
844
845
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
846
847
  tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
            "AuthoritativeDir is set.");
Ola Bini's avatar
Ola Bini committed
848
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
849
850
851
852
853
854

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "VersioningAuthoritativeDirectory 1\n"
                                "RecommendedServerVersions 4.18\n"
855
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
856
857
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
858
859
  tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set "
            "Recommended*Versions.");
Ola Bini's avatar
Ola Bini committed
860
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
861
862
863
864
865
866

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "VersioningAuthoritativeDirectory 1\n"
                                "RecommendedClientVersions 4.18\n"
867
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
868
869
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
870
871
  tt_str_op(msg, OP_EQ, "Versioning authoritative dir servers must set "
            "Recommended*Versions.");
Ola Bini's avatar
Ola Bini committed
872
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
873
874
875
876
877

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "UseEntryGuards 1\n"
878
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
879
880
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
881
  expect_log_msg("Authoritative directory servers "
Ola Bini's avatar
Ola Bini committed
882
            "can't set UseEntryGuards. Disabling.\n");
Ola Bini's avatar
Ola Bini committed
883
  tt_int_op(tdata->opt->UseEntryGuards, OP_EQ, 0);
Ola Bini's avatar
Ola Bini committed
884
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
885
886
887
888
889

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "V3AuthoritativeDir 1\n"
890
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
891
892
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
893
  expect_log_msg("Authoritative directories always try"
Ola Bini's avatar
Ola Bini committed
894
            " to download extra-info documents. Setting DownloadExtraInfo.\n");
Ola Bini's avatar
Ola Bini committed
895
  tt_int_op(tdata->opt->DownloadExtraInfo, OP_EQ, 1);
Ola Bini's avatar
Ola Bini committed
896
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
897
898
899
900
901
902

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "DownloadExtraInfo 1\n"
                                "V3AuthoritativeDir 1\n"
903
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
904
905
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
906
  expect_no_log_msg("Authoritative directories always try"
Ola Bini's avatar
Ola Bini committed
907
            " to download extra-info documents. Setting DownloadExtraInfo.\n");
Ola Bini's avatar
Ola Bini committed
908
  tt_int_op(tdata->opt->DownloadExtraInfo, OP_EQ, 1);
Ola Bini's avatar
Ola Bini committed
909
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
910
911
912
913

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
914
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
915
916
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
917
918
  tt_str_op(msg, OP_EQ, "AuthoritativeDir is set, but none of (Bridge/V3)"
            "AuthoritativeDir is set.");
Ola Bini's avatar
Ola Bini committed
919
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
920
921
922
923
924
925

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "BridgeAuthoritativeDir 1\n"
                                "ContactInfo hello@hello.com\n"
926
                                "V3BandwidthsFile non-existent-file\n");
Ola Bini's avatar
Ola Bini committed
927
928
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
929
930
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no DirPort set.");
Ola Bini's avatar
Ola Bini committed
931
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
932
933
934
935
936
937

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "BridgeAuthoritativeDir 1\n"
                                "ContactInfo hello@hello.com\n"
938
                                "V3BandwidthsFile non-existent-file\n");
Ola Bini's avatar
Ola Bini committed
939
940
  mock_clean_saved_logs();
  options_validate(NULL, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
941
942
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no DirPort set.");
Ola Bini's avatar
Ola Bini committed
943
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
944
945
946
947
948
949

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "BridgeAuthoritativeDir 1\n"
                                "ContactInfo hello@hello.com\n"
950
                                "GuardfractionFile non-existent-file\n");
Ola Bini's avatar
Ola Bini committed
951
952
  mock_clean_saved_logs();
  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
953
954
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no DirPort set.");
Ola Bini's avatar
Ola Bini committed
955
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
956
957
958
959
960
961

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "BridgeAuthoritativeDir 1\n"
                                "ContactInfo hello@hello.com\n"
962
                                "GuardfractionFile non-existent-file\n");
Ola Bini's avatar
Ola Bini committed
963
964
  mock_clean_saved_logs();
  options_validate(NULL, tdata->opt, tdata->def_opt, 0, &msg);
Ola Bini's avatar
Ola Bini committed
965
966
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no DirPort set.");
Ola Bini's avatar
Ola Bini committed
967
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
968
969
970
971
972

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "BridgeAuthoritativeDir 1\n"
973
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
974
975
976
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
977
978
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no DirPort set.");
Ola Bini's avatar
Ola Bini committed
979
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
980
981
982
983
984
985

  free_options_test_data(tdata);
  tdata = get_options_test_data("AuthoritativeDirectory 1\n"
                                "Address 100.200.10.1\n"
                                "DirPort 999\n"
                                "BridgeAuthoritativeDir 1\n"
986
                                "ContactInfo hello@hello.com\n");
Ola Bini's avatar
Ola Bini committed
987
988
989
  mock_clean_saved_logs();
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
Ola Bini's avatar
Ola Bini committed
990
991
  tt_str_op(msg, OP_EQ,
            "Running as authoritative directory, but no ORPort set.");
Ola Bini's avatar
Ola Bini committed
992
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
993

Ola Bini's avatar
Ola Bini committed
994
995
  // TODO: This case can't be reached, since clientonly is used to
  // check when parsing port lines as well.
Ola Bini's avatar
Ola Bini committed
996
997
998
999
1000
1001
1002
  /* free_options_test_data(tdata); */
  /* tdata = get_options_test_data("AuthoritativeDirectory 1\n" */
  /*                               "Address 100.200.10.1\n" */
  /*                               "DirPort 999\n" */
  /*                               "ORPort 888\n" */
  /*                               "ClientOnly 1\n" */
  /*                               "BridgeAuthoritativeDir 1\n" */
1003
  /*                               "ContactInfo hello@hello.com\n" ); */
Ola Bini's avatar
Ola Bini committed
1004
  /* mock_clean_saved_logs(); */
Ola Bini's avatar
Ola Bini committed
1005
1006
  /* ret = options_validate(tdata->old_opt, tdata->opt, */
  /*                        tdata->def_opt, 0, &msg); */
Ola Bini's avatar
Ola Bini committed
1007
  /* tt_int_op(ret, OP_EQ, -1); */
Ola Bini's avatar
Ola Bini committed
1008
1009
  /* tt_str_op(msg, OP_EQ, "Running as authoritative directory, " */
  /*           "but ClientOnly also set."); */
Ola Bini's avatar
Ola Bini committed
1010
1011

 done:
1012
  teardown_capture_of_logs();
1013
  //  sandbox_free_getaddrinfo_cache();
Ola Bini's avatar
Ola Bini committed
1014
1015
1016
1017
1018
1019
1020
1021
1022
  free_options_test_data(tdata);
  tor_free(msg);
}

static void
test_options_validate__relay_with_hidden_services(void *ignored)
{
  (void)ignored;
  char *msg;
1023
  setup_capture_of_logs(LOG_DEBUG);
Ola Bini's avatar
Ola Bini committed
1024
  options_test_data_t *tdata = get_options_test_data(
1025
                                  "ORPort 127.0.0.1:5555\n"
Ola Bini's avatar
Ola Bini committed
1026
1027
1028
                                  "HiddenServiceDir "
                                  "/Library/Tor/var/lib/tor/hidden_service/\n"
                                  "HiddenServicePort 80 127.0.0.1:8080\n"
Ola Bini's avatar
Ola Bini committed
1029
1030
1031
                                                     );

  options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
1032
  expect_log_msg(
Ola Bini's avatar
Ola Bini committed
1033
1034
1035
            "Tor is currently configured as a relay and a hidden service. "
            "That's not very secure: you should probably run your hidden servi"
            "ce in a separate Tor process, at least -- see "
Ola Bini's avatar
Ola Bini committed
1036
1037
1038
            "https://trac.torproject.org/8742\n");

 done:
1039
  teardown_capture_of_logs();
Ola Bini's avatar
Ola Bini committed
1040
1041
1042
1043
  free_options_test_data(tdata);
  tor_free(msg);
}

Ola Bini's avatar
Ola Bini committed
1044
1045
// TODO: it doesn't seem possible to hit the case of having no port lines at
// all, since there will be a default created for SocksPort
Ola Bini's avatar
Ola Bini committed
1046
1047
1048
1049
1050
1051
/* static void */
/* test_options_validate__ports(void *ignored) */
/* { */
/*   (void)ignored; */
/*   int ret; */
/*   char *msg; */
1052
/*   setup_capture_of_logs(LOG_WARN); */
Ola Bini's avatar
Ola Bini committed
1053
/*   options_test_data_t *tdata = get_options_test_data(""); */
Ola Bini's avatar
Ola Bini committed
1054
1055
/*   ret = options_validate(tdata->old_opt, tdata->opt, */
/*                          tdata->def_opt, 0, &msg); */
1056
1057
1058
/*   expect_log_msg("SocksPort, TransPort, NATDPort, DNSPort, and ORPort " */
/*           "are all undefined, and there aren't any hidden services " */
/*           "configured. " */
Ola Bini's avatar
Ola Bini committed
1059
/*           " Tor will still run, but probably won't do anything.\n"); */
Ola Bini's avatar
Ola Bini committed
1060
/*  done: */
1061
/*   teardown_capture_of_logs(); */
Ola Bini's avatar
Ola Bini committed
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
/*   free_options_test_data(tdata); */
/*   tor_free(msg); */
/* } */

static void
test_options_validate__transproxy(void *ignored)
{
  (void)ignored;
  int ret;
  char *msg;
  options_test_data_t *tdata;

#ifdef USE_TRANSPARENT
  // Test default trans proxy
  tdata = get_options_test_data("TransProxyType default\n");

  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
  tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_DEFAULT);
Ola Bini's avatar
Ola Bini committed
1081
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
1082
1083
1084
1085
1086
1087
1088

  // Test pf-divert trans proxy
  free_options_test_data(tdata);
  tdata = get_options_test_data("TransProxyType pf-divert\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);

1089
#if !defined(OpenBSD) && !defined( DARWIN )
Ola Bini's avatar
Ola Bini committed
1090
1091
  tt_str_op(msg, OP_EQ,
          "pf-divert is a OpenBSD-specific and OS X/Darwin-specific feature.");
Ola Bini's avatar
Ola Bini committed
1092
1093
#else
  tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_PF_DIVERT);
Ola Bini's avatar
Ola Bini committed
1094
  tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without "
1095
            "any valid TransPort.");
1096
#endif /* !defined(OpenBSD) && !defined( DARWIN ) */
Ola Bini's avatar
Ola Bini committed
1097
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

  // Test tproxy trans proxy
  free_options_test_data(tdata);
  tdata = get_options_test_data("TransProxyType tproxy\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);

#if !defined(__linux__)
  tt_str_op(msg, OP_EQ, "TPROXY is a Linux-specific feature.");
#else
  tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_TPROXY);
Ola Bini's avatar
Ola Bini committed
1109
  tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without any valid "
1110
            "TransPort.");
1111
#endif /* !defined(__linux__) */
Ola Bini's avatar
Ola Bini committed
1112
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
1113
1114
1115
1116
1117
1118
1119

  // Test ipfw trans proxy
  free_options_test_data(tdata);
  tdata = get_options_test_data("TransProxyType ipfw\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);

1120
#ifndef KERNEL_MAY_SUPPORT_IPFW
1121
  tt_str_op(msg, OP_EQ, "ipfw is a FreeBSD-specific and OS X/Darwin-specific "
Ola Bini's avatar
Ola Bini committed
1122
            "feature.");
Ola Bini's avatar
Ola Bini committed
1123
1124
#else
  tt_int_op(tdata->opt->TransProxyType_parsed, OP_EQ, TPT_IPFW);
Ola Bini's avatar
Ola Bini committed
1125
  tt_str_op(msg, OP_EQ, "Cannot use TransProxyType without any valid "
1126
            "TransPort.");
1127
#endif /* !defined(KERNEL_MAY_SUPPORT_IPFW) */
Ola Bini's avatar
Ola Bini committed
1128
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
1129
1130
1131

  // Test unknown trans proxy
  free_options_test_data(tdata);
1132
  tdata = get_options_test_data("TransProxyType non-existent\n");
Ola Bini's avatar
Ola Bini committed
1133
1134
1135
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
  tt_str_op(msg, OP_EQ, "Unrecognized value for TransProxyType");
Ola Bini's avatar
Ola Bini committed
1136
  tor_free(msg);
Ola Bini's avatar
Ola Bini committed
1137
1138
1139

  // Test trans proxy success
  free_options_test_data(tdata);
1140
  tdata = NULL;
Ola Bini's avatar
Ola Bini committed
1141

1142
#if defined(__linux__)
Ola Bini's avatar
Ola Bini committed
1143
1144
1145
1146
  tdata = get_options_test_data("TransProxyType tproxy\n"
                                "TransPort 127.0.0.1:123\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
1147
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
1148
#elif defined(KERNEL_MAY_SUPPORT_IPFW)
Ola Bini's avatar
Ola Bini committed
1149
1150
1151
1152
  tdata = get_options_test_data("TransProxyType ipfw\n"
                                "TransPort 127.0.0.1:123\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
1153
1154
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
  tor_free(msg);
1155
#elif defined(OpenBSD)
Ola Bini's avatar
Ola Bini committed
1156
1157
1158
1159
  tdata = get_options_test_data("TransProxyType pf-divert\n"
                                "TransPort 127.0.0.1:123\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
1160
1161
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
  tor_free(msg);
1162
#elif defined(__NetBSD__)
1163
1164
1165
1166
  tdata = get_options_test_data("TransProxyType default\n"
                                "TransPort 127.0.0.1:123\n");
  ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
  tt_int_op(ret, OP_EQ, -1);
1167
1168
  tt_str_op(msg, OP_EQ, "ConnLimit must be greater than 0, but was set to 0");
  tor_free(msg);
1169
#endif /* defined(__linux__) || ... */
Ola Bini's avatar
Ola Bini committed
1170

1171
1172
1173
  // Assert that a test has run for some TransProxyType
  tt_assert(tdata);

1174
#else /* !(defined(USE_TRANSPARENT)) */