GitLab is used only for code review, issue tracking and project management. Canonical locations for source code are still https://gitweb.torproject.org/ https://git.torproject.org/ and git-rw.torproject.org.

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 "