Exemplo n.º 1
0
Arquivo: test_hs.c Projeto: ageis/tor
/* Test encoding and decoding service authorization cookies */
static void
test_hs_auth_cookies(void *arg)
{
#define TEST_COOKIE_RAW ((const uint8_t *) "abcdefghijklmnop")
#define TEST_COOKIE_ENCODED "YWJjZGVmZ2hpamtsbW5vcA"
#define TEST_COOKIE_ENCODED_STEALTH "YWJjZGVmZ2hpamtsbW5vcB"
#define TEST_COOKIE_ENCODED_INVALID "YWJjZGVmZ2hpamtsbW5vcD"

  char *encoded_cookie;
  uint8_t raw_cookie[REND_DESC_COOKIE_LEN];
  rend_auth_type_t auth_type;
  char *err_msg;
  int re;

  (void)arg;

  /* Test that encoding gives the expected result */
  encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_BASIC_AUTH);
  tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED);
  tor_free(encoded_cookie);

  encoded_cookie = rend_auth_encode_cookie(TEST_COOKIE_RAW, REND_STEALTH_AUTH);
  tt_str_op(encoded_cookie, OP_EQ, TEST_COOKIE_ENCODED_STEALTH);
  tor_free(encoded_cookie);

  /* Decoding should give the original value */
  re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED, raw_cookie, &auth_type,
                               &err_msg);
  tt_assert(!re);
  tt_ptr_op(err_msg, OP_EQ, NULL);
  tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN);
  tt_int_op(auth_type, OP_EQ, REND_BASIC_AUTH);
  memset(raw_cookie, 0, sizeof(raw_cookie));

  re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_STEALTH, raw_cookie,
                               &auth_type, &err_msg);
  tt_assert(!re);
  tt_ptr_op(err_msg, OP_EQ, NULL);
  tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN);
  tt_int_op(auth_type, OP_EQ, REND_STEALTH_AUTH);
  memset(raw_cookie, 0, sizeof(raw_cookie));

  /* Decoding with padding characters should also work */
  re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED "==", raw_cookie, NULL,
                               &err_msg);
  tt_assert(!re);
  tt_ptr_op(err_msg, OP_EQ, NULL);
  tt_mem_op(raw_cookie, OP_EQ, TEST_COOKIE_RAW, REND_DESC_COOKIE_LEN);

  /* Decoding with an unknown type should fail */
  re = rend_auth_decode_cookie(TEST_COOKIE_ENCODED_INVALID, raw_cookie,
                               &auth_type, &err_msg);
  tt_int_op(re, OP_LT, 0);
  tt_assert(err_msg);
  tor_free(err_msg);

 done:
  return;
}
Exemplo n.º 2
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;
}