示例#1
0
/* copies entries from src into dst */
void strmap_merge(strmap* dst, const strmap* src)
{
    const strmap_node* node;
    strmap_foreach(src, node) {
        const char* key = strmap_node_key(node);
        const char* val = strmap_node_value(node);
        strmap_set(dst, key, val);
    }
    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);
}
示例#3
0
/** Helper function for threading unit tests: This function runs in a
 * subthread. It grabs its own mutex (start1 or start2) to make sure that it
 * should start, then it repeatedly alters _test_thread_strmap protected by
 * thread_test_mutex_. */
static void
thread_test_func_(void* _s)
{
  char *s = _s;
  int i, *count;
  tor_mutex_t *m;
  char buf[64];
  char **cp;
  if (!strcmp(s, "thread 1")) {
    m = thread_test_start1_;
    cp = &thread1_name_;
    count = &t1_count;
    thread_fn_tid1 = tor_get_thread_id();
  } else {
    m = thread_test_start2_;
    cp = &thread2_name_;
    count = &t2_count;
    thread_fn_tid2 = tor_get_thread_id();
  }

  tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
  *cp = tor_strdup(buf);

  tor_mutex_acquire(m);

  for (i=0; i<10000; ++i) {
    tor_mutex_acquire(thread_test_mutex_);
    strmap_set(thread_test_strmap_, "last to run", *cp);
    ++*count;
    tor_mutex_release(thread_test_mutex_);
  }
  tor_mutex_acquire(thread_test_mutex_);
  strmap_set(thread_test_strmap_, s, *cp);
  if (in_main_thread())
    ++thread_fns_failed;
  tor_mutex_release(thread_test_mutex_);

  tor_mutex_release(m);

  spawn_exit();
}
示例#4
0
文件: sandbox.c 项目: Archer-sys/tor
/* DOCDOC */
static int
prot_strings_helper(strmap_t *locations,
                    char **pr_mem_next_p,
                    size_t *pr_mem_left_p,
                    char **value_p)
{
  char *param_val;
  size_t param_size;
  void *location;

  if (*value_p == 0)
    return 0;

  param_val = (char*) *value_p;
  param_size = strlen(param_val) + 1;
  location = strmap_get(locations, param_val);

  if (location) {
    // We already interned this string.
    tor_free(param_val);
    *value_p = location;
    return 0;
  } else if (*pr_mem_left_p >= param_size) {
    // copy to protected
    location = *pr_mem_next_p;
    memcpy(location, param_val, param_size);

    // re-point el parameter to protected
    tor_free(param_val);
    *value_p = location;

    strmap_set(locations, location, location); /* good real estate advice */

    // move next available protected memory
    *pr_mem_next_p += param_size;
    *pr_mem_left_p -= param_size;
    return 0;
  } else {
    log_err(LD_BUG,"(Sandbox) insufficient protected memory!");
    return -1;
  }
}
示例#5
0
/* insert key/value into map as "key=value" with printf formatting */
int strmap_setf(strmap* map, const char* format, ...)
{
    va_list args;
    char* str = NULL;

    /* check that we have a format string */
    if (format == NULL) {
        return STRMAP_FAILURE;
    }

    /* compute the size of the string we need to allocate */
    va_start(args, format);
    int size = vsnprintf(NULL, 0, format, args) + 1;
    va_end(args);

    /* allocate and print the string */
    if (size > 0) {
        str = (char*) BAYER_MALLOC((size_t)size);

        va_start(args, format);
        vsnprintf(str, (size_t)size, format, args);
        va_end(args);

        /* break into key/value strings at '=' sign */
        char* key = str;
        char* val = str;
        char delim[] = "=";
        strsep(&val, delim);

        /* if we have a key and value, insert into map */
        int rc;
        if (val != NULL) {
            rc = strmap_set(map, key, val);
        }

        bayer_free(&str);
        return rc;
    }

    return STRMAP_FAILURE;
}
示例#6
0
/* unpack tree stored at buf into tree */
size_t strmap_unpack(const void* buf, strmap* tree)
{
    char* ptr = (char*) buf;

    /* TODO: convert size to network order */
    uint64_t size;
    ptr += bayer_unpack_uint64(ptr, &size);

    /* TODO: be sure we don't try to read past size bytes */
    char* end = (char*)buf + size;
    while (ptr < end) {
        char* key = ptr;
        ptr += strlen(key) + 1;

        char* value = ptr;
        ptr += strlen(value) + 1;

        strmap_set(tree, key, value);
    }

    return size;
}
示例#7
0
文件: dirserv.c 项目: unixninja92/Tor
/** Replace the v3 consensus networkstatus of type <b>flavor_name</b> that
 * we're serving with <b>networkstatus</b>, published at <b>published</b>.  No
 * validation is performed. */
void
dirserv_set_cached_consensus_networkstatus(const char *networkstatus,
                                           size_t networkstatus_len,
                                           const char *flavor_name,
                                           const common_digests_t *digests,
                                           const uint8_t *sha3_as_signed,
                                           time_t published)
{
  cached_dir_t *new_networkstatus;
  cached_dir_t *old_networkstatus;
  if (!cached_consensuses)
    cached_consensuses = strmap_new();

  new_networkstatus =
    new_cached_dir(tor_memdup_nulterm(networkstatus, networkstatus_len),
                   published);
  memcpy(&new_networkstatus->digests, digests, sizeof(common_digests_t));
  memcpy(&new_networkstatus->digest_sha3_as_signed, sha3_as_signed,
         DIGEST256_LEN);
  old_networkstatus = strmap_set(cached_consensuses, flavor_name,
                                 new_networkstatus);
  if (old_networkstatus)
    cached_dir_decref(old_networkstatus);
}
示例#8
0
/** Run unit tests for string-to-void* map functions */
static void
test_container_strmap(void)
{
  strmap_t *map;
  strmap_iter_t *iter;
  const char *k;
  void *v;
  char *visited = NULL;
  smartlist_t *found_keys = NULL;

  map = strmap_new();
  test_assert(map);
  test_eq(strmap_size(map), 0);
  test_assert(strmap_isempty(map));
  v = strmap_set(map, "K1", (void*)99);
  test_eq_ptr(v, NULL);
  test_assert(!strmap_isempty(map));
  v = strmap_set(map, "K2", (void*)101);
  test_eq_ptr(v, NULL);
  v = strmap_set(map, "K1", (void*)100);
  test_eq_ptr(v, (void*)99);
  test_eq_ptr(strmap_get(map,"K1"), (void*)100);
  test_eq_ptr(strmap_get(map,"K2"), (void*)101);
  test_eq_ptr(strmap_get(map,"K-not-there"), NULL);
  strmap_assert_ok(map);

  v = strmap_remove(map,"K2");
  strmap_assert_ok(map);
  test_eq_ptr(v, (void*)101);
  test_eq_ptr(strmap_get(map,"K2"), NULL);
  test_eq_ptr(strmap_remove(map,"K2"), NULL);

  strmap_set(map, "K2", (void*)101);
  strmap_set(map, "K3", (void*)102);
  strmap_set(map, "K4", (void*)103);
  test_eq(strmap_size(map), 4);
  strmap_assert_ok(map);
  strmap_set(map, "K5", (void*)104);
  strmap_set(map, "K6", (void*)105);
  strmap_assert_ok(map);

  /* Test iterator. */
  iter = strmap_iter_init(map);
  found_keys = smartlist_new();
  while (!strmap_iter_done(iter)) {
    strmap_iter_get(iter,&k,&v);
    smartlist_add(found_keys, tor_strdup(k));
    test_eq_ptr(v, strmap_get(map, k));

    if (!strcmp(k, "K2")) {
      iter = strmap_iter_next_rmv(map,iter);
    } else {
      iter = strmap_iter_next(map,iter);
    }
  }

  /* Make sure we removed K2, but not the others. */
  test_eq_ptr(strmap_get(map, "K2"), NULL);
  test_eq_ptr(strmap_get(map, "K5"), (void*)104);
  /* Make sure we visited everyone once */
  smartlist_sort_strings(found_keys);
  visited = smartlist_join_strings(found_keys, ":", 0, NULL);
  test_streq(visited, "K1:K2:K3:K4:K5:K6");

  strmap_assert_ok(map);
  /* Clean up after ourselves. */
  strmap_free(map, NULL);
  map = NULL;

  /* Now try some lc functions. */
  map = strmap_new();
  strmap_set_lc(map,"Ab.C", (void*)1);
  test_eq_ptr(strmap_get(map,"ab.c"), (void*)1);
  strmap_assert_ok(map);
  test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1);
  test_eq_ptr(strmap_get(map,"AB.C"), NULL);
  test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1);
  strmap_assert_ok(map);
  test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL);

 done:
  if (map)
    strmap_free(map,NULL);
  if (found_keys) {
    SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp));
    smartlist_free(found_keys);
  }
  tor_free(visited);
}
示例#9
0
/** Parse the content of a client_key file in <b>ckstr</b> and add
 * rend_authorized_client_t's for each parsed client to
 * <b>parsed_clients</b>. Return the number of parsed clients as result
 * or -1 for failure. */
int
rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr)
{
  int result = -1;
  smartlist_t *tokens;
  directory_token_t *tok;
  const char *current_entry = NULL;
  memarea_t *area = NULL;
  char *err_msg = NULL;
  if (!ckstr || strlen(ckstr) == 0)
    return -1;
  tokens = smartlist_new();
  /* Begin parsing with first entry, skipping comments or whitespace at the
   * beginning. */
  area = memarea_new();
  current_entry = eat_whitespace(ckstr);
  while (!strcmpstart(current_entry, "client-name ")) {
    rend_authorized_client_t *parsed_entry;
    /* Determine end of string. */
    const char *eos = strstr(current_entry, "\nclient-name ");
    if (!eos)
      eos = current_entry + strlen(current_entry);
    else
      eos = eos + 1;
    /* Free tokens and clear token list. */
    SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
    smartlist_clear(tokens);
    memarea_clear(area);
    /* Tokenize string. */
    if (tokenize_string(area, current_entry, eos, tokens,
                        client_keys_token_table, 0)) {
      log_warn(LD_REND, "Error tokenizing client keys file.");
      goto err;
    }
    /* Advance to next entry, if available. */
    current_entry = eos;
    /* Check minimum allowed length of token list. */
    if (smartlist_len(tokens) < 2) {
      log_warn(LD_REND, "Impossibly short client key entry.");
      goto err;
    }
    /* Parse client name. */
    tok = find_by_keyword(tokens, C_CLIENT_NAME);
    tor_assert(tok == smartlist_get(tokens, 0));
    tor_assert(tok->n_args == 1);

    if (!rend_valid_client_name(tok->args[0])) {
      log_warn(LD_CONFIG, "Illegal client name: %s. (Length must be "
               "between 1 and %d, and valid characters are "
               "[A-Za-z0-9+-_].)", tok->args[0], REND_CLIENTNAME_MAX_LEN);
      goto err;
    }
    /* Check if client name is duplicate. */
    if (strmap_get(parsed_clients, tok->args[0])) {
      log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains a "
               "duplicate client name: '%s'. Ignoring.", tok->args[0]);
      goto err;
    }
    parsed_entry = tor_malloc_zero(sizeof(rend_authorized_client_t));
    parsed_entry->client_name = tor_strdup(tok->args[0]);
    strmap_set(parsed_clients, parsed_entry->client_name, parsed_entry);
    /* Parse client key. */
    tok = find_opt_by_keyword(tokens, C_CLIENT_KEY);
    if (tok) {
      parsed_entry->client_key = tok->key;
      tok->key = NULL; /* Prevent free */
    }

    /* Parse descriptor cookie. */
    tok = find_by_keyword(tokens, C_DESCRIPTOR_COOKIE);
    tor_assert(tok->n_args == 1);
    if (rend_auth_decode_cookie(tok->args[0], parsed_entry->descriptor_cookie,
                                NULL, &err_msg) < 0) {
      tor_assert(err_msg);
      log_warn(LD_REND, "%s", err_msg);
      tor_free(err_msg);
      goto err;
    }
  }
  result = strmap_size(parsed_clients);
  goto done;
 err:
  result = -1;
 done:
  /* Free tokens and clear token list. */
  SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
  smartlist_free(tokens);
  if (area)
    memarea_drop_all(area);
  return result;
}