Beispiel #1
0
static void
test_rend_cache_decrement_allocation(void *data)
{
  (void)data;

  // Test when the cache has enough allocations
  rend_cache_total_allocation = 10;
  rend_cache_decrement_allocation(3);
  tt_int_op(rend_cache_total_allocation, OP_EQ, 7);

  // Test when there are not enough allocations
  rend_cache_total_allocation = 1;
  setup_full_capture_of_logs(LOG_WARN);
  rend_cache_decrement_allocation(2);
  tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
  expect_single_log_msg_containing(
                    "Underflow in rend_cache_decrement_allocation");
  teardown_capture_of_logs();

  // And again
  rend_cache_decrement_allocation(2);
  tt_int_op(rend_cache_total_allocation, OP_EQ, 0);

 done:
  teardown_capture_of_logs();
}
Beispiel #2
0
static void
test_rend_cache_increment_allocation(void *data)
{
  (void)data;

  // Test when the cache is not overflowing
  rend_cache_total_allocation = 5;
  rend_cache_increment_allocation(3);
  tt_int_op(rend_cache_total_allocation, OP_EQ, 8);

  // Test when there are too many allocations
  rend_cache_total_allocation = SIZE_MAX-1;
  setup_full_capture_of_logs(LOG_WARN);
  rend_cache_increment_allocation(2);
  tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
  expect_single_log_msg_containing(
                    "Overflow in rend_cache_increment_allocation");
  teardown_capture_of_logs();

  // And again
  rend_cache_increment_allocation(2);
  tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);

 done:
  teardown_capture_of_logs();
}
Beispiel #3
0
/* Try sending an ESTABLISH_INTRO cell on a circuit that is already an intro
 * point. Should fail. */
static void
test_establish_intro_wrong_purpose(void *arg)
{
  int retval;
  ssize_t cell_len = 0;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void)arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  memcpy(intro_circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);

  /* Set a bad circuit purpose!! :) */
  circuit_change_purpose(TO_CIRCUIT(intro_circ), CIRCUIT_PURPOSE_INTRO_POINT);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     attempt to parse it. */
  cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
  tt_i64_op(cell_len, OP_GT, 0);

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
  expect_log_msg_containing("Rejecting ESTABLISH_INTRO on non-OR circuit.");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Beispiel #4
0
/* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should
 * fail. */
static void
test_establish_intro_wrong_sig(void *arg)
{
  int retval;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  ssize_t cell_len = 0;
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void) arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     attempt to parse it. */
  cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
  tt_i64_op(cell_len, OP_GT, 0);

  /* Mutate the last byte (signature)! :) */
  cell_body[cell_len - 1]++;

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body,
                                             (size_t)cell_len);
  expect_log_msg_containing("Failed to verify ESTABLISH_INTRO cell.");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Beispiel #5
0
/** We simulate a failure to create an ESTABLISH_INTRO cell */
static void
test_gen_establish_intro_cell_bad(void *arg)
{
  (void) arg;
  ssize_t cell_len = 0;
  trn_cell_establish_intro_t *cell = NULL;
  char circ_nonce[DIGEST_LEN] = {0};
  hs_service_intro_point_t *ip = NULL;

  MOCK(ed25519_sign_prefixed, mock_ed25519_sign_prefixed);

  crypto_rand(circ_nonce, sizeof(circ_nonce));

  setup_full_capture_of_logs(LOG_WARN);
  /* Easiest way to make that function fail is to mock the
     ed25519_sign_prefixed() function and make it fail. */
  cell = trn_cell_establish_intro_new();
  tt_assert(cell);
  ip = service_intro_point_new(NULL);
  cell_len = hs_cell_build_establish_intro(circ_nonce, ip, NULL);
  service_intro_point_free(ip);
  expect_log_msg_containing("Unable to make signature for "
                            "ESTABLISH_INTRO cell.");
  teardown_capture_of_logs();
  tt_i64_op(cell_len, OP_EQ, -1);

 done:
  trn_cell_establish_intro_free(cell);
  UNMOCK(ed25519_sign_prefixed);
}
Beispiel #6
0
static void
test_address_get_if_addrs6_list_no_internal(void *arg)
{
  smartlist_t *results = NULL;

  (void)arg;

  /* We might drop a log_err */
  setup_full_capture_of_logs(LOG_ERR);
  results = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
  tt_int_op(smartlist_len(mock_saved_logs()), OP_LE, 1);
  if (smartlist_len(mock_saved_logs()) == 1) {
    expect_log_msg_containing_either4("connect() failed",
                                      "unable to create socket",
                                      "Address that we determined via UDP "
                                      "socket magic is unsuitable for public "
                                      "comms.",
                                      "getsockname() to determine interface "
                                      "failed");
  }
  teardown_capture_of_logs();

  tt_ptr_op(results, OP_NE, NULL);
  /* Work even on systems without IPv6 interfaces */
  tt_int_op(smartlist_len(results),OP_GE,0);

  tt_assert(!smartlist_contains_localhost_tor_addr(results));
  tt_assert(!smartlist_contains_multicast_tor_addr(results));
  tt_assert(!smartlist_contains_internal_tor_addr(results));
  tt_assert(!smartlist_contains_null_tor_addr(results));

  /* if there are any addresses, they must be IPv6 */
  tt_assert(!smartlist_contains_ipv4_tor_addr(results));
  if (smartlist_len(results) > 0) {
    tt_assert(smartlist_contains_ipv6_tor_addr(results));
  }

 done:
  teardown_capture_of_logs();
  interface_address6_list_free(results);
  return;
}
static void
test_conn_edge_ap_handshake_rewrite_and_attach_closes_conn_for_excluded_exit(void *data)
{
  entry_connection_t *conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  addressmap_init();
  origin_circuit_t *circuit = NULL;
  crypt_path_t *path = NULL;
  (void) data;

  MOCK(get_options, get_options_mock);
  MOCK(connection_ap_handshake_rewrite, connection_ap_handshake_rewrite_mock);
  MOCK(connection_mark_unattached_ap_, connection_mark_unattached_ap_mock);
  MOCK(node_get_by_nickname, node_get_by_nickname_mock);

  init_rewrite_mock();
  init_exit_node_mock();
  init_mock_options();

  rewrite_mock->should_close = 0;
  rewrite_mock->exit_source = ADDRMAPSRC_NONE;
  SET_SOCKS_ADDRESS(conn->socks_request, "http://www.wellformed.exit");
  conn->socks_request->command = SOCKS_COMMAND_CONNECT;
  strlcpy(exit_node_mock->rs->nickname, "wellformed", MAX_NICKNAME_LEN+1);

  options_mock->AllowDotExit = 1;
  options_mock->StrictNodes = 0;
  options_mock->SafeLogging_ = SAFELOG_SCRUB_NONE;

  excluded_nodes = routerset_new();
  smartlist_add(excluded_nodes->list, tor_strdup("wellformed"));
  strmap_set(excluded_nodes->names, tor_strdup("wellformed"), exit_node_mock);
  options_mock->ExcludeExitNodes = excluded_nodes;

  int prev_log = setup_capture_of_logs(LOG_INFO);
  int res = connection_ap_handshake_rewrite_and_attach(conn, circuit, path);

  tt_int_op(unattachment_reason_spy, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
  tt_int_op(res, OP_EQ, -1);
  tt_str_op(mock_saved_log_at(-1), OP_EQ, "Excluded relay in exit address 'http://www.exit'. Refusing.\n");

  done:
    UNMOCK(get_options);
    UNMOCK(connection_ap_handshake_rewrite);
    UNMOCK(connection_mark_unattached_ap_);
    UNMOCK(node_get_by_nickname);

    destroy_rewrite_mock();
    destroy_mock_options();
    destroy_exit_node_mock();
    tor_free(excluded_nodes);
    tor_free(circuit);
    tor_free(path);
    teardown_capture_of_logs(prev_log);
}
Beispiel #8
0
/** Test warn_early_consensus(), expecting no warning  */
static void
test_warn_early_consensus_no(const networkstatus_t *c, time_t now,
                             long offset)
{
  mock_apparent_skew = 0;
  setup_capture_of_logs(LOG_WARN);
  warn_early_consensus(c, "microdesc", now + offset);
  expect_no_log_msg_containing("behind the time published in the consensus");
  tt_int_op(mock_apparent_skew, OP_EQ, 0);
 done:
  teardown_capture_of_logs();
}
Beispiel #9
0
/** Test warn_early_consensus(), expecting a warning */
static void
test_warn_early_consensus_yes(const networkstatus_t *c, time_t now,
                              long offset)
{
  mock_apparent_skew = 0;
  setup_capture_of_logs(LOG_WARN);
  warn_early_consensus(c, "microdesc", now + offset);
  /* Can't use expect_single_log_msg() because of unrecognized authorities */
  expect_log_msg_containing("behind the time published in the consensus");
  tt_int_op(mock_apparent_skew, OP_EQ, offset);
 done:
  teardown_capture_of_logs();
}
Beispiel #10
0
/** Test non-early consensus */
static void
test_timely_consensus(void *arg)
{
  time_t now = time(NULL);
  unsigned long offset = 0;
  int retval = 0;

  retval = test_skew_common(arg, now, &offset);
  (void)offset;
  expect_no_log_msg_containing("behind the time published in the consensus");
  tt_int_op(retval, OP_EQ, 0);
  tt_int_op(mock_apparent_skew, OP_EQ, 0);
 done:
  teardown_capture_of_logs();
  UNMOCK(clock_skew_warning);
}
Beispiel #11
0
/** Test early consensus  */
static void
test_early_consensus(void *arg)
{
  time_t now = time(NULL);
  unsigned long offset = 0;
  int retval = 0;

  retval = test_skew_common(arg, now, &offset);
  /* Can't use expect_single_log_msg() because of unrecognized authorities */
  expect_log_msg_containing("behind the time published in the consensus");
  tt_int_op(retval, OP_EQ, 0);
  /* This depends on construct_consensus() setting valid_after=now+1000 */
  tt_int_op(mock_apparent_skew, OP_EQ, offset - 1000);
 done:
  teardown_capture_of_logs();
  UNMOCK(clock_skew_warning);
}
Beispiel #12
0
static void
test_util_process_clear_waitpid_callback(void *ignored)
{
  (void)ignored;
  waitpid_callback_t *res;
  int previous_log = setup_capture_of_logs(LOG_WARN);
  pid_t pid = (pid_t)43;

  clear_waitpid_callback(NULL);

  res = set_waitpid_callback(pid, temp_callback, NULL);
  clear_waitpid_callback(res);
  clear_waitpid_callback(res);

  // done:
  teardown_capture_of_logs(previous_log);
}
Beispiel #13
0
static void
test_util_process_set_waitpid_callback(void *ignored)
{
  (void)ignored;
  waitpid_callback_t *res;
  int previous_log = setup_capture_of_logs(LOG_WARN);
  pid_t pid = (pid_t)42;

  res = set_waitpid_callback(pid, temp_callback, NULL);
  tt_assert(res);

  res = set_waitpid_callback(pid, temp_callback, NULL);
  tt_assert(res);
  tt_str_op(mock_saved_log_at(0), OP_EQ, "Replaced a waitpid monitor on pid 42. That should be impossible.\n");

 done:
  teardown_capture_of_logs(previous_log);
}
Beispiel #14
0
/* Send a legit ESTABLISH_INTRO cell but with a wrong sig length. Should
 * fail. */
static void
test_establish_intro_wrong_sig_len(void *arg)
{
  int retval;
  char circ_nonce[DIGEST_LEN] = {0};
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  ssize_t cell_len = 0;
  size_t bad_sig_len = ED25519_SIG_LEN - 1;
  trn_cell_establish_intro_t *cell = NULL;
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void) arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
   * attempt to parse it. */
  cell_len = new_establish_intro_cell(circ_nonce, &cell);
  tt_i64_op(cell_len, OP_GT, 0);
  tt_assert(cell);

  /* Mangle the signature length. */
  trn_cell_establish_intro_set_sig_len(cell, bad_sig_len);
  trn_cell_establish_intro_setlen_sig(cell, bad_sig_len);
  /* Encode cell. */
  cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
                                             cell);
  tt_int_op(cell_len, OP_GT, 0);

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
  expect_log_msg_containing("ESTABLISH_INTRO sig len is invalid");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  trn_cell_establish_intro_free(cell);
  circuit_free_(TO_CIRCUIT(intro_circ));
}
static void
test_conn_edge_ap_handshake_rewrite_and_attach_closes_conn_for_unrecognized_exit_address(void *data)
{
  entry_connection_t *conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  addressmap_init();
  origin_circuit_t *circuit = NULL;
  crypt_path_t *path = NULL;
  (void) data;

  MOCK(get_options, get_options_mock);
  MOCK(connection_ap_handshake_rewrite, connection_ap_handshake_rewrite_mock);
  MOCK(connection_mark_unattached_ap_, connection_mark_unattached_ap_mock);

  init_rewrite_mock();
  init_mock_options();

  rewrite_mock->should_close = 0;
  rewrite_mock->exit_source = ADDRMAPSRC_NONE;
  SET_SOCKS_ADDRESS(conn->socks_request, "http://www.wellformed.exit");
  conn->socks_request->command = SOCKS_COMMAND_CONNECT;
  options_mock->AllowDotExit = 1;
  options_mock->SafeLogging_ = SAFELOG_SCRUB_NONE;

  int prev_log = setup_capture_of_logs(LOG_INFO);
  int res = connection_ap_handshake_rewrite_and_attach(conn, circuit, path);

  tt_int_op(unattachment_reason_spy, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
  tt_int_op(res, OP_EQ, -1);
  tt_str_op(mock_saved_log_at(-1), OP_EQ, "Unrecognized relay in exit address 'http://www.exit'. Refusing.\n");

  done:
    UNMOCK(get_options);
    UNMOCK(connection_ap_handshake_rewrite);
    UNMOCK(connection_mark_unattached_ap_);

    destroy_rewrite_mock();
    destroy_mock_options();
    tor_free(circuit);
    tor_free(path);
    teardown_capture_of_logs(prev_log);
}
Beispiel #16
0
static void
test_util_process_set_waitpid_callback(void *ignored)
{
  (void)ignored;
  waitpid_callback_t *res1 = NULL, *res2 = NULL;
  int previous_log = setup_capture_of_logs(LOG_WARN);
  pid_t pid = (pid_t)42;

  res1 = set_waitpid_callback(pid, temp_callback, NULL);
  tt_assert(res1);

  res2 = set_waitpid_callback(pid, temp_callback, NULL);
  tt_assert(res2);
  expect_log_msg("Replaced a waitpid monitor on pid 42. That should be "
            "impossible.\n");

 done:
  teardown_capture_of_logs(previous_log);
  clear_waitpid_callback(res1);
  clear_waitpid_callback(res2);
}
static void
test_conn_edge_ap_handshake_rewrite_and_attach_closes_conn_when_hostname_is_bogus(void *data)
{
  entry_connection_t *conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  addressmap_init();
  origin_circuit_t *circuit = NULL;
  crypt_path_t *path = NULL;
  (void) data;

  MOCK(get_options, get_options_mock);
  MOCK(connection_ap_handshake_rewrite, connection_ap_handshake_rewrite_mock);
  MOCK(connection_mark_unattached_ap_, connection_mark_unattached_ap_mock);

  init_mock_options();
  init_rewrite_mock();

  options_mock->SafeLogging_ = SAFELOG_SCRUB_NONE;
  rewrite_mock->should_close = 0;
  SET_SOCKS_ADDRESS(conn->socks_request, "http://www.bogus.onion");
  conn->socks_request->command = SOCKS_COMMAND_CONNECT;

  int prev_log = setup_capture_of_logs(LOG_INFO);
  int res = connection_ap_handshake_rewrite_and_attach(conn, circuit, path);

  tt_int_op(unattachment_reason_spy, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
  tt_int_op(res, OP_EQ, -1);
  tt_str_op(mock_saved_log_at(-1), OP_EQ, "Invalid onion hostname bogus; rejecting\n");

  done:
    UNMOCK(get_options);
    UNMOCK(connection_ap_handshake_rewrite);
    UNMOCK(connection_mark_unattached_ap_);

    destroy_rewrite_mock();
    tor_free(circuit);
    tor_free(path);
    destroy_mock_options();
    teardown_capture_of_logs(prev_log);
}
Beispiel #18
0
/* Send an empty ESTABLISH_INTRO cell. Should fail. */
static void
test_establish_intro_wrong_keytype(void *arg)
{
  int retval;
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);
  char circ_nonce[DIGEST_LEN] = {0};

  (void) arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Receive the cell. Should fail. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, (uint8_t *) "", 0);
  expect_log_msg_containing("Empty ESTABLISH_INTRO cell.");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Beispiel #19
0
static void
test_util_process_clear_waitpid_callback(void *ignored)
{
  (void)ignored;
  waitpid_callback_t *res;
  int previous_log = setup_capture_of_logs(LOG_WARN);
  pid_t pid = (pid_t)43;

  clear_waitpid_callback(NULL);

  res = set_waitpid_callback(pid, temp_callback, NULL);
  clear_waitpid_callback(res);
  expect_no_log_entry();

#if 0
  /* No.  This is use-after-free.  We don't _do_ that. XXXX */
  clear_waitpid_callback(res);
  expect_log_msg("Couldn't remove waitpid monitor for pid 43.\n");
#endif

 done:
  teardown_capture_of_logs(previous_log);
}
Beispiel #20
0
static void
test_virtaddrmap_persist(void *data)
{
  (void)data;
  const char *a, *b, *c;
  tor_addr_t addr;
  char *ones = NULL;

  addressmap_init();

  // Try a hostname.
  a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
                                          tor_strdup("foobar.baz"));
  tt_assert(a);
  tt_assert(!strcmpend(a, ".virtual"));

  // mock crypto_rand to repeat the same result twice; make sure we get
  // different outcomes.  (Because even though the odds for receiving the
  // same 80-bit address twice is only 1/2^40, it could still happen for
  // some user -- but running our test through 2^40 iterations isn't
  // reasonable.)
  canned_data = "1234567890" // the first call returns this.
                "1234567890" // the second call returns this.
                "abcdefghij"; // the third call returns this.
  canned_data_len = 30;
  MOCK(crypto_rand, crypto_canned);

  a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
                                          tor_strdup("quuxit.baz"));
  b = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
                                          tor_strdup("nescio.baz"));
  tt_assert(a);
  tt_assert(b);
  tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual");
  tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual");

  // Now try something to get us an ipv4 address
  UNMOCK(crypto_rand);
  tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16",
                                                AF_INET, 0, NULL));
  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("foobar.baz"));
  tt_assert(a);
  tt_assert(!strcmpstart(a, "192.168."));
  tor_addr_parse(&addr, a);
  tt_int_op(AF_INET, OP_EQ, tor_addr_family(&addr));

  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("quuxit.baz"));
  tt_str_op(b, OP_NE, a);
  tt_assert(!strcmpstart(b, "192.168."));

  // Try some canned entropy and verify all the we discard duplicates,
  // addresses that end with 0, and addresses that end with 255.
  MOCK(crypto_rand, crypto_canned);
  canned_data = "\x01\x02\x03\x04" // okay
                "\x01\x02\x03\x04" // duplicate
                "\x03\x04\x00\x00" // bad ending 1
                "\x05\x05\x00\xff" // bad ending 2
                "\x05\x06\x07\xf0"; // okay
  canned_data_len = 20;
  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("wumble.onion"));
  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("wumpus.onion"));
  tt_str_op(a, OP_EQ, "192.168.3.4");
  tt_str_op(b, OP_EQ, "192.168.7.240");

  // Now try IPv6!
  UNMOCK(crypto_rand);
  tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20",
                                                AF_INET6, 0, NULL));
  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
                                          tor_strdup("foobar.baz"));
  tt_assert(a);
  tt_assert(!strcmpstart(a, "[1010:f"));
  tor_addr_parse(&addr, a);
  tt_int_op(AF_INET6, OP_EQ, tor_addr_family(&addr));

  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
                                          tor_strdup("quuxit.baz"));
  tt_str_op(b, OP_NE, a);
  tt_assert(!strcmpstart(b, "[1010:f"));

  // Try IPv6 with canned entropy, to make sure we detect duplicates.
  MOCK(crypto_rand, crypto_canned);
  canned_data = "acanthopterygian" // okay
                "cinematographist" // okay
                "acanthopterygian" // duplicate
                "acanthopterygian" // duplicate
                "acanthopterygian" // duplicate
                "cinematographist" // duplicate
                "coadministration"; // okay
  canned_data_len = 16 * 7;
  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
                                          tor_strdup("wuffle.baz"));
  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
                                          tor_strdup("gribble.baz"));
  c = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
                                      tor_strdup("surprisingly-legible.baz"));
  tt_str_op(a, OP_EQ, "[1010:f16e:7468:6f70:7465:7279:6769:616e]");
  tt_str_op(b, OP_EQ, "[1010:fe65:6d61:746f:6772:6170:6869:7374]");
  tt_str_op(c, OP_EQ, "[1010:f164:6d69:6e69:7374:7261:7469:6f6e]");

  // Try address exhaustion: make sure we can actually fail if we
  // get too many already-existing addresses.
  canned_data_len = 128*1024;
  canned_data = ones = tor_malloc(canned_data_len);
  memset(ones, 1, canned_data_len);
  // There is some chance this one will fail if a previous random
  // allocation gave out the address already.
  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("might-work.onion"));
  if (a) {
    tt_str_op(a, OP_EQ, "192.168.1.1");
  }
  setup_capture_of_logs(LOG_WARN);
  // This one will definitely fail, since we've set up the RNG to hand
  // out "1" forever.
  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
                                          tor_strdup("wont-work.onion"));
  tt_assert(b == NULL);
  expect_single_log_msg_containing("Ran out of virtual addresses!");

 done:
  UNMOCK(crypto_rand);
  tor_free(ones);
  addressmap_free_all();
  teardown_capture_of_logs();
}
Beispiel #21
0
static void
test_channel_duplicates(void *arg)
{
  channel_t *chan = NULL;
  routerstatus_t rs;

  (void) arg;

  setup_full_capture_of_logs(LOG_INFO);
  /* Try a flat call with channel nor connections. */
  channel_check_for_duplicates();
  expect_log_msg_containing(
    "Found 0 connections to 0 relays. Found 0 current canonical "
    "connections, in 0 of which we were a non-canonical peer. "
    "0 relays had more than 1 connection, 0 had more than 2, and "
    "0 had more than 4 connections.");

  mock_ns = tor_malloc_zero(sizeof(*mock_ns));
  mock_ns->routerstatus_list = smartlist_new();
  MOCK(networkstatus_get_latest_consensus,
       mock_networkstatus_get_latest_consensus);

  chan = new_fake_channel();
  tt_assert(chan);
  chan->is_canonical = test_chan_is_canonical;
  memset(chan->identity_digest, 'A', sizeof(chan->identity_digest));
  channel_add_to_digest_map(chan);
  tt_ptr_op(channel_find_by_remote_identity(chan->identity_digest, NULL),
            OP_EQ, chan);

  /* No relay has been associated with this channel. */
  channel_check_for_duplicates();
  expect_log_msg_containing(
    "Found 0 connections to 0 relays. Found 0 current canonical "
    "connections, in 0 of which we were a non-canonical peer. "
    "0 relays had more than 1 connection, 0 had more than 2, and "
    "0 had more than 4 connections.");

  /* Associate relay to this connection in the consensus. */
  memset(&rs, 0, sizeof(rs));
  memset(rs.identity_digest, 'A', sizeof(rs.identity_digest));
  smartlist_add(mock_ns->routerstatus_list, &rs);

  /* Non opened channel. */
  chan->state = CHANNEL_STATE_CLOSING;
  channel_check_for_duplicates();
  expect_log_msg_containing(
    "Found 0 connections to 0 relays. Found 0 current canonical "
    "connections, in 0 of which we were a non-canonical peer. "
    "0 relays had more than 1 connection, 0 had more than 2, and "
    "0 had more than 4 connections.");
  chan->state = CHANNEL_STATE_OPEN;

  channel_check_for_duplicates();
  expect_log_msg_containing(
    "Found 1 connections to 1 relays. Found 0 current canonical "
    "connections, in 0 of which we were a non-canonical peer. "
    "0 relays had more than 1 connection, 0 had more than 2, and "
    "0 had more than 4 connections.");

  test_chan_should_be_canonical = 1;
  channel_check_for_duplicates();
  expect_log_msg_containing(
    "Found 1 connections to 1 relays. Found 1 current canonical "
    "connections, in 1 of which we were a non-canonical peer. "
    "0 relays had more than 1 connection, 0 had more than 2, and "
    "0 had more than 4 connections.");
  teardown_capture_of_logs();

 done:
  free_fake_channel(chan);
  smartlist_clear(mock_ns->routerstatus_list);
  networkstatus_vote_free(mock_ns);
  UNMOCK(networkstatus_get_latest_consensus);
}
Beispiel #22
0
/* Send a legit ESTABLISH_INTRO cell but with a wrong MAC. Should fail. */
static void
test_establish_intro_wrong_mac(void *arg)
{
  int retval;
  char circ_nonce[DIGEST_LEN] = {0};
  ssize_t cell_len = 0;
  uint8_t cell_body[RELAY_PAYLOAD_SIZE];
  trn_cell_establish_intro_t *cell = NULL;
  or_circuit_t *intro_circ = or_circuit_new(0,NULL);

  (void) arg;

  /* Get the auth key of the intro point */
  crypto_rand(circ_nonce, sizeof(circ_nonce));
  helper_prepare_circ_for_intro(intro_circ, circ_nonce);

  /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
   * attempt to parse it. */
  cell_len = new_establish_intro_cell(circ_nonce, &cell);
  tt_i64_op(cell_len, OP_GT, 0);
  tt_assert(cell);

  /* Mangle one byte of the MAC. */
  uint8_t *handshake_ptr =
    trn_cell_establish_intro_getarray_handshake_mac(cell);
  handshake_ptr[TRUNNEL_SHA3_256_LEN - 1]++;
  /* We need to resign the payload with that change. */
  {
    ed25519_signature_t sig;
    ed25519_keypair_t key_struct;
    /* New keypair for the signature since we don't have access to the private
     * key material generated earlier when creating the cell. */
    retval = ed25519_keypair_generate(&key_struct, 0);
    tt_int_op(retval, OP_EQ, 0);
    uint8_t *auth_key_ptr =
      trn_cell_establish_intro_getarray_auth_key(cell);
    memcpy(auth_key_ptr, key_struct.pubkey.pubkey, ED25519_PUBKEY_LEN);
    /* Encode payload so we can sign it. */
    cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
                                               cell);
    tt_i64_op(cell_len, OP_GT, 0);

    retval = ed25519_sign_prefixed(&sig, cell_body,
                                   cell_len -
                                   (ED25519_SIG_LEN + sizeof(cell->sig_len)),
                                   ESTABLISH_INTRO_SIG_PREFIX, &key_struct);
    tt_int_op(retval, OP_EQ, 0);
    /* And write the signature to the cell */
    uint8_t *sig_ptr =
      trn_cell_establish_intro_getarray_sig(cell);
    memcpy(sig_ptr, sig.sig, cell->sig_len);
    /* Re-encode with the new signature. */
    cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
                                               cell);
    tt_i64_op(cell_len, OP_GT, 0);
  }

  /* Receive the cell. Should fail because our MAC is wrong. */
  setup_full_capture_of_logs(LOG_INFO);
  retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
  expect_log_msg_containing("ESTABLISH_INTRO handshake_auth not as expected");
  teardown_capture_of_logs();
  tt_int_op(retval, OP_EQ, -1);

 done:
  trn_cell_establish_intro_free(cell);
  circuit_free_(TO_CIRCUIT(intro_circ));
}
Beispiel #23
0
static void
test_router_get_my_family(void *arg)
{
  (void)arg;
  or_options_t *options = options_new();
  smartlist_t *sl = NULL;
  char *join = NULL;
  // Overwrite the result of router_get_my_identity_digest().  This
  // happens to be okay, but only for testing.
  set_server_identity_key_digest_testing(
                                   (const uint8_t*)"holeinthebottomofthe");

  setup_capture_of_logs(LOG_WARN);

  // No family listed -- so there's no list.
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_EQ, NULL);
  expect_no_log_entry();

#define CLEAR() do {                                    \
    if (sl) {                                           \
      SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));  \
      smartlist_free(sl);                               \
    }                                                   \
    tor_free(join);                                     \
    mock_clean_saved_logs();                            \
  } while (0)

  // Add a single nice friendly hex member.  This should be enough
  // to have our own ID added.
  tt_ptr_op(options->MyFamily, OP_EQ, NULL);
  config_line_append(&options->MyFamily, "MyFamily",
                     "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");

  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_NE, NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 2);
  join = smartlist_join_strings(sl, " ", 0, NULL);
  tt_str_op(join, OP_EQ,
            "$686F6C65696E746865626F74746F6D6F66746865 "
            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  expect_no_log_entry();
  CLEAR();

  // Add a hex member with a ~.  The ~ part should get removed.
  config_line_append(&options->MyFamily, "MyFamily",
                     "$0123456789abcdef0123456789abcdef01234567~Muffin");
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_NE, NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 3);
  join = smartlist_join_strings(sl, " ", 0, NULL);
  tt_str_op(join, OP_EQ,
            "$0123456789ABCDEF0123456789ABCDEF01234567 "
            "$686F6C65696E746865626F74746F6D6F66746865 "
            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  expect_no_log_entry();
  CLEAR();

  // Nickname lookup will fail, so a nickname will appear verbatim.
  config_line_append(&options->MyFamily, "MyFamily",
                     "BAGEL");
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_NE, NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 4);
  join = smartlist_join_strings(sl, " ", 0, NULL);
  tt_str_op(join, OP_EQ,
            "$0123456789ABCDEF0123456789ABCDEF01234567 "
            "$686F6C65696E746865626F74746F6D6F66746865 "
            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
            "bagel");
  expect_single_log_msg_containing(
           "There is a router named \"BAGEL\" in my declared family, but "
           "I have no descriptor for it.");
  CLEAR();

  // A bogus digest should fail entirely.
  config_line_append(&options->MyFamily, "MyFamily",
                     "$painauchocolat");
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_NE, NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 4);
  join = smartlist_join_strings(sl, " ", 0, NULL);
  tt_str_op(join, OP_EQ,
            "$0123456789ABCDEF0123456789ABCDEF01234567 "
            "$686F6C65696E746865626F74746F6D6F66746865 "
            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
            "bagel");
  // "BAGEL" is still there, but it won't make a warning, because we already
  // warned about it.
  expect_single_log_msg_containing(
           "There is a router named \"$painauchocolat\" in my declared "
           "family, but that isn't a legal digest or nickname. Skipping it.");
  CLEAR();

  // Let's introduce a node we can look up by nickname
  memset(&fake_node, 0, sizeof(fake_node));
  memcpy(fake_node.identity, "whydoyouasknonononon", DIGEST_LEN);
  MOCK(node_get_by_nickname, mock_node_get_by_nickname);

  config_line_append(&options->MyFamily, "MyFamily",
                     "CRUmpeT");
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_NE, NULL);
  tt_int_op(smartlist_len(sl), OP_EQ, 5);
  join = smartlist_join_strings(sl, " ", 0, NULL);
  tt_str_op(join, OP_EQ,
            "$0123456789ABCDEF0123456789ABCDEF01234567 "
            "$686F6C65696E746865626F74746F6D6F66746865 "
            "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E "
            "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
            "bagel");
  // "BAGEL" is still there, but it won't make a warning, because we already
  // warned about it.  Some with "$painauchocolat".
  expect_single_log_msg_containing(
           "There is a router named \"CRUmpeT\" in my declared "
           "family, but it wasn't listed by digest. Please consider saying "
           "$776879646F796F7561736B6E6F6E6F6E6F6E6F6E instead, if that's "
           "what you meant.");
  CLEAR();
  UNMOCK(node_get_by_nickname);

  // Try a singleton list containing only us: It should give us NULL.
  config_free_lines(options->MyFamily);
  config_line_append(&options->MyFamily, "MyFamily",
                     "$686F6C65696E746865626F74746F6D6F66746865");
  sl = get_my_declared_family(options);
  tt_ptr_op(sl, OP_EQ, NULL);
  expect_no_log_entry();

 done:
  or_options_free(options);
  teardown_capture_of_logs();
  CLEAR();
  UNMOCK(node_get_by_nickname);

#undef CLEAR
}
Beispiel #24
0
static void
test_router_check_descriptor_bandwidth_changed(void *arg)
{
  (void)arg;
  routerinfo_t routerinfo;
  memset(&routerinfo, 0, sizeof(routerinfo));
  mock_router_get_my_routerinfo_result = NULL;

  MOCK(we_are_hibernating, mock_we_are_not_hibernating);
  MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
  mock_router_get_my_routerinfo_result = &routerinfo;

  /* When uptime is less than 24h, no previous bandwidth, no last_changed
   * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
  routerinfo.bandwidthcapacity = 0;
  MOCK(get_uptime, mock_get_uptime_3h);
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL));
  expect_log_msg_not_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  teardown_capture_of_logs();

  /* When uptime is less than 24h, previous bandwidth,
   * last_changed more than 3h ago
   * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
  routerinfo.bandwidthcapacity = 10000;
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL));
  expect_log_msg_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  teardown_capture_of_logs();

  /* When uptime is less than 24h, previous bandwidth,
   * last_changed more than 3h ago, and hibernating
   * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */

  UNMOCK(we_are_hibernating);
  MOCK(we_are_hibernating, mock_we_are_hibernating);
  routerinfo.bandwidthcapacity = 10000;
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL));
  expect_log_msg_not_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  teardown_capture_of_logs();
  UNMOCK(we_are_hibernating);
  MOCK(we_are_hibernating, mock_we_are_not_hibernating);

  /* When uptime is less than 24h, last_changed is not more than 3h ago
   * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL));
  expect_log_msg_not_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  teardown_capture_of_logs();

  /* When uptime is less than 24h and bandwidthcapacity does not change
   * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
  MOCK(rep_hist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
  expect_log_msg_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  UNMOCK(get_uptime);
  UNMOCK(rep_hist_bandwidth_assess);
  teardown_capture_of_logs();

  /* When uptime is more than 24h */
  MOCK(get_uptime, mock_get_uptime_1d);
  setup_full_capture_of_logs(LOG_INFO);
  check_descriptor_bandwidth_changed(time(NULL));
  expect_log_msg_not_containing(
     "Measured bandwidth has changed; rebuilding descriptor.");
  teardown_capture_of_logs();

 done:
  UNMOCK(get_uptime);
  UNMOCK(router_get_my_routerinfo);
  UNMOCK(we_are_hibernating);
}
Beispiel #25
0
static void
test_invalid_service_v2(void *arg)
{
  int validate_only = 1, ret;

  (void) arg;

  /* Try with a missing port configuration. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("with no ports configured.");
    teardown_capture_of_logs();
  }

  /* Too many introduction points. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80\n"
      "HiddenServiceNumIntroductionPoints 11\n"; /* One too many. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceNumIntroductionPoints should "
                              "be between 0 and 10, not 11");
    teardown_capture_of_logs();
  }

  /* Too little introduction points. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80\n"
      "HiddenServiceNumIntroductionPoints -1\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceNumIntroductionPoints should "
                              "be between 0 and 10, not -1");
    teardown_capture_of_logs();
  }

  /* Bad authorized client type. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80\n"
      "HiddenServiceAuthorizeClient blah alice,bob\n"; /* blah is no good. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceAuthorizeClient contains "
                              "unrecognized auth-type");
    teardown_capture_of_logs();
  }

 done:
  ;
}
Beispiel #26
0
static void
test_invalid_service_v3(void *arg)
{
  int validate_only = 1, ret;

  (void) arg;

  /* Try with a missing port configuration. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 3\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("with no ports configured.");
    teardown_capture_of_logs();
  }

  /* Too many introduction points. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 3\n"
      "HiddenServicePort 80\n"
      "HiddenServiceNumIntroductionPoints 21\n"; /* One too many. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
                              "be between 3 and 20, not 21.");
    teardown_capture_of_logs();
  }

  /* Too little introduction points. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 3\n"
      "HiddenServicePort 80\n"
      "HiddenServiceNumIntroductionPoints 1\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
                              "be between 3 and 20, not 1.");
    teardown_capture_of_logs();
  }

  /* v2-specific HiddenServiceAuthorizeClient set. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 3\n"
      "HiddenServiceAuthorizeClient stealth client1\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, validate_only);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("Hidden service option "
                              "HiddenServiceAuthorizeClient is incompatible "
                              "with version 3 of service in "
                              "/tmp/tor-test-hs-RANDOM/hs1");
    teardown_capture_of_logs();
  }

 done:
  ;
}
Beispiel #27
0
static void
test_invalid_service(void *arg)
{
  int ret;

  (void) arg;

  /* Try with a missing port configuration. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 1\n"; /* Wrong not supported version. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceVersion must be between 2 and 3");
    teardown_capture_of_logs();
  }

  /* Bad value of HiddenServiceAllowUnknownPorts. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServiceAllowUnknownPorts 2\n"; /* Should be 0 or 1. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceAllowUnknownPorts must be "
                              "between 0 and 1, not 2");
    teardown_capture_of_logs();
  }

  /* Bad value of HiddenServiceDirGroupReadable */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServiceDirGroupReadable 2\n"; /* Should be 0 or 1. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceDirGroupReadable must be "
                              "between 0 and 1, not 2");
    teardown_capture_of_logs();
  }

  /* Bad value of HiddenServiceMaxStreamsCloseCircuit */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServiceMaxStreamsCloseCircuit 2\n"; /* Should be 0 or 1. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceMaxStreamsCloseCircuit must "
                              "be between 0 and 1, not 2");
    teardown_capture_of_logs();
  }

  /* Too much max streams. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80\n"
      "HiddenServiceMaxStreams 65536\n"; /* One too many. */
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceMaxStreams must be between "
                              "0 and 65535, not 65536");
    teardown_capture_of_logs();
  }

  /* Duplicate directory directive. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80\n"
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 81\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("Another hidden service is already "
                              "configured for directory");
    teardown_capture_of_logs();
  }

  /* Bad port. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 65536\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("Missing or invalid port");
    teardown_capture_of_logs();
  }

  /* Bad target addr:port separation. */
  {
    const char *conf =
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServiceVersion 2\n"
      "HiddenServicePort 80 127.0.0.1 8000\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServicePort parse error: "
                              "invalid port mapping");
    teardown_capture_of_logs();
  }

  /* Out of order directives. */
  {
    const char *conf =
      "HiddenServiceVersion 2\n"
      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      "HiddenServicePort 80\n";
    setup_full_capture_of_logs(LOG_WARN);
    ret = helper_config_service(conf, 1);
    tt_int_op(ret, OP_EQ, -1);
    expect_log_msg_containing("HiddenServiceVersion with no preceding "
                              "HiddenServiceDir directive");
    teardown_capture_of_logs();
  }

 done:
  ;
}
Beispiel #28
0
/** Test that we will use our directory guards to fetch mds even if we don't
 *  have any dirinfo (tests bug #23862). */
static void
test_directory_guard_fetch_with_no_dirinfo(void *arg)
{
  int retval;
  char *consensus_text_md = NULL;
  or_options_t *options = get_options_mutable();
  time_t now = time(NULL);

  (void) arg;

  hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);

  /* Initialize the SRV subsystem */
  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
  mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1,
                                               strlen(AUTHORITY_CERT_1),
                                               NULL);
  sr_init(0);
  UNMOCK(get_my_v3_authority_cert);

  /* Initialize the entry node configuration from the ticket */
  options->UseEntryGuards = 1;
  options->StrictNodes = 1;
  get_options_mutable()->EntryNodes = routerset_new();
  routerset_parse(get_options_mutable()->EntryNodes,
                  "2121212121212121212121212121212121212121", "foo");

  /* Mock some functions */
  dummy_state = tor_malloc_zero(sizeof(or_state_t));
  MOCK(get_or_state, get_or_state_replacement);
  MOCK(directory_initiate_request, mock_directory_initiate_request);
  /* we need to mock this one to avoid memleaks */
  MOCK(circuit_guard_state_new, mock_circuit_guard_state_new);

  /* Call guards_update_all() to simulate loading our state file (see
   * entry_guards_load_guards_from_state() and ticket #23989). */
  guards_update_all();

  /* Test logic: Simulate the arrival of a new consensus when we have no
   * dirinfo at all. Tor will need to fetch the mds from the consensus. Make
   * sure that Tor will use the specified entry guard instead of relying on the
   * fallback directories. */

  /* Fixup the dirconn that will deliver the consensus */
  dir_connection_t *conn = dir_connection_new(AF_INET);
  tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
  conn->base_.port = 8800;
  TO_CONN(conn)->address = tor_strdup("127.0.0.1");
  conn->base_.purpose = DIR_PURPOSE_FETCH_CONSENSUS;
  conn->requested_resource = tor_strdup("ns");

  /* Construct a consensus */
  construct_consensus(&consensus_text_md, now);
  tt_assert(consensus_text_md);

  /* Place the consensus in the dirconn */
  response_handler_args_t args;
  memset(&args, 0, sizeof(response_handler_args_t));
  args.status_code = 200;
  args.body = consensus_text_md;
  args.body_len = strlen(consensus_text_md);

  /* Update approx time so that the consensus is considered live */
  update_approx_time(now+1010);

  setup_capture_of_logs(LOG_DEBUG);

  /* Now handle the consensus */
  retval = handle_response_fetch_consensus(conn, &args);
  tt_int_op(retval, OP_EQ, 0);

  /* Make sure that our primary guard was chosen */
  expect_log_msg_containing("Selected primary guard router3");

 done:
  tor_free(consensus_text_md);
  tor_free(dummy_state);
  connection_free_minimal(TO_CONN(conn));
  entry_guards_free_all();
  teardown_capture_of_logs();
}