Exemple #1
0
static void
test_replaycache_realtime(void *arg)
{
  replaycache_t *r = NULL;
  /*
   * Negative so we fail if replaycache_add_test_and_elapsed() doesn't
   * write to elapsed.
   */
  time_t elapsed = -1;
  int result;

  /* Test the realtime as well as *_internal() entry points */
  (void)arg;
  r = replaycache_new(600, 300);
  tt_assert(r != NULL);

  /* This should miss */
  result =
    replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
  tt_int_op(result,OP_EQ, 0);

  /* This should hit */
  result =
    replaycache_add_and_test(r, test_buffer, strlen(test_buffer));
  tt_int_op(result,OP_EQ, 1);

  /* This should hit and return a small elapsed time */
  result =
    replaycache_add_test_and_elapsed(r, test_buffer,
                                     strlen(test_buffer), &elapsed);
  tt_int_op(result,OP_EQ, 1);
  tt_assert(elapsed >= 0);
  tt_assert(elapsed <= 5);

  /* Scrub it to exercise that entry point too */
  replaycache_scrub_if_needed(r);

 done:
  if (r) replaycache_free(r);
  return;
}
Exemple #2
0
/* We just received an INTRODUCE2 cell on the established introduction circuit
 * circ.  Handle the INTRODUCE2 payload of size payload_len for the given
 * circuit and service. This cell is associated with the intro point object ip
 * and the subcredential. Return 0 on success else a negative value. */
int
hs_circ_handle_introduce2(const hs_service_t *service,
                          const origin_circuit_t *circ,
                          hs_service_intro_point_t *ip,
                          const uint8_t *subcredential,
                          const uint8_t *payload, size_t payload_len)
{
  int ret = -1;
  time_t elapsed;
  hs_cell_introduce2_data_t data;

  tor_assert(service);
  tor_assert(circ);
  tor_assert(ip);
  tor_assert(subcredential);
  tor_assert(payload);

  /* Populate the data structure with everything we need for the cell to be
   * parsed, decrypted and key material computed correctly. */
  data.auth_pk = &ip->auth_key_kp.pubkey;
  data.enc_kp = &ip->enc_key_kp;
  data.subcredential = subcredential;
  data.payload = payload;
  data.payload_len = payload_len;
  data.link_specifiers = smartlist_new();
  data.replay_cache = ip->replay_cache;

  if (hs_cell_parse_introduce2(&data, circ, service) < 0) {
    goto done;
  }

  /* Check whether we've seen this REND_COOKIE before to detect repeats. */
  if (replaycache_add_test_and_elapsed(
           service->state.replay_cache_rend_cookie,
           data.rendezvous_cookie, sizeof(data.rendezvous_cookie),
           &elapsed)) {
    /* A Tor client will send a new INTRODUCE1 cell with the same REND_COOKIE
     * as its previous one if its intro circ times out while in state
     * CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT. If we received the first
     * INTRODUCE1 cell (the intro-point relay converts it into an INTRODUCE2
     * cell), we are already trying to connect to that rend point (and may
     * have already succeeded); drop this cell. */
    log_info(LD_REND, "We received an INTRODUCE2 cell with same REND_COOKIE "
                      "field %ld seconds ago. Dropping cell.",
             (long int) elapsed);
    goto done;
  }

  /* At this point, we just confirmed that the full INTRODUCE2 cell is valid
   * so increment our counter that we've seen one on this intro point. */
  ip->introduce2_count++;

  /* Launch rendezvous circuit with the onion key and rend cookie. */
  launch_rendezvous_point_circuit(service, ip, &data);
  /* Success. */
  ret = 0;

 done:
  SMARTLIST_FOREACH(data.link_specifiers, link_specifier_t *, lspec,
                    link_specifier_free(lspec));
  smartlist_free(data.link_specifiers);
  memwipe(&data, 0, sizeof(data));
  return ret;
}