Exemplo n.º 1
0
/** Update digest from the payload of cell. Assign integrity part to
 * cell.
 */
static void
relay_set_digest(crypto_digest_t *digest, cell_t *cell)
{
  char integrity[4];
  relay_header_t rh;

  crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, integrity, 4);
//  log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
//    integrity[0], integrity[1], integrity[2], integrity[3]);
  relay_header_unpack(&rh, cell->payload);
  memcpy(rh.integrity, integrity, 4);
  relay_header_pack(cell->payload, &rh);
}
Exemplo n.º 2
0
/** Does the digest for this circuit indicate that this cell is for us?
 *
 * Update digest from the payload of cell (with the integrity part set
 * to 0). If the integrity part is valid, return 1, else restore digest
 * and cell to their original state and return 0.
 */
static int
relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
{
  uint32_t received_integrity, calculated_integrity;
  relay_header_t rh;
  crypto_digest_checkpoint_t backup_digest;

  crypto_digest_checkpoint(&backup_digest, digest);

  relay_header_unpack(&rh, cell->payload);
  memcpy(&received_integrity, rh.integrity, 4);
  memset(rh.integrity, 0, 4);
  relay_header_pack(cell->payload, &rh);

//  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
//    received_integrity[0], received_integrity[1],
//    received_integrity[2], received_integrity[3]);

  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);

  int rv = 1;

  if (calculated_integrity != received_integrity) {
//    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity);
    /* restore digest to its old form */
    crypto_digest_restore(digest, &backup_digest);
    /* restore the relay header */
    memcpy(rh.integrity, &received_integrity, 4);
    relay_header_pack(cell->payload, &rh);
    rv = 0;
  }

  memwipe(&backup_digest, 0, sizeof(backup_digest));
  return rv;
}
Exemplo n.º 3
0
static void
make_relay_cell(cell_t *out, uint8_t command,
                const void *body, size_t bodylen)
{
  relay_header_t rh;

  memset(&rh, 0, sizeof(rh));
  rh.stream_id = 5;
  rh.command = command;
  rh.length = bodylen;

  out->command = CELL_RELAY;
  out->circ_id = 10;
  relay_header_pack(out->payload, &rh);

  memcpy(out->payload + RELAY_HEADER_SIZE, body, bodylen);
}
Exemplo n.º 4
0
static void
test_cfmt_relay_header(void *arg)
{
  relay_header_t rh;
  const uint8_t hdr_1[RELAY_HEADER_SIZE] =
    "\x03" "\x00\x00" "\x21\x22" "ABCD" "\x01\x03";
  uint8_t hdr_out[RELAY_HEADER_SIZE];
  (void)arg;

  tt_int_op(sizeof(hdr_1), ==, RELAY_HEADER_SIZE);
  relay_header_unpack(&rh, hdr_1);
  tt_int_op(rh.command, ==, 3);
  tt_int_op(rh.recognized, ==, 0);
  tt_int_op(rh.stream_id, ==, 0x2122);
  test_mem_op(rh.integrity, ==, "ABCD", 4);
  tt_int_op(rh.length, ==, 0x103);

  relay_header_pack(hdr_out, &rh);
  test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE);

 done:
  ;
}
Exemplo n.º 5
0
static void
test_circbw_relay(void *arg)
{
  cell_t cell;
  relay_header_t rh;
  tor_addr_t addr;
  edge_connection_t *edgeconn;
  entry_connection_t *entryconn1=NULL;
  origin_circuit_t *circ;
  int delivered = 0;
  int overhead = 0;

  (void)arg;

  MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
  MOCK(connection_start_reading, mock_start_reading);
  MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
  MOCK(relay_send_command_from_edge_, mock_send_command);
  MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);

  circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  circ->cpath->deliver_window = CIRCWINDOW_START;

  entryconn1 = fake_entry_conn(circ, 1);
  edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);

  /* Stream id 0: Not counted */
  PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Stream id 1: Counted */
  PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* Properly formatted connect cell: counted */
  PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  tor_addr_parse(&addr, "30.40.50.60");
  rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
                                            &addr, 1024);
  relay_header_pack((uint8_t*)&cell.payload, &rh);                    \
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* Properly formatted resolved cell in correct state: counted */
  edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
  entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
  edgeconn->on_circuit = TO_CIRCUIT(circ);
  PACK_CELL(1, RELAY_COMMAND_RESOLVED,
            "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  edgeconn->base_.state = AP_CONN_STATE_OPEN;
  entryconn1->socks_request->has_finished = 1;

  /* Connected cell after open: not counted */
  PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Resolved cell after open: not counted */
  PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Drop cell: not counted */
  PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Data cell on stream 0: not counted */
  PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Data cell on open connection: counted */
  ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* Empty Data cell on open connection: not counted */
  ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  PACK_CELL(1, RELAY_COMMAND_DATA, "");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Sendme on valid stream: counted */
  edgeconn->package_window -= STREAMWINDOW_INCREMENT;
  ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* Sendme on valid stream with full window: not counted */
  ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  edgeconn->package_window = STREAMWINDOW_START;
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Sendme on unknown stream: not counted */
  ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Sendme on circuit with full window: not counted */
  PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Sendme on circuit with non-full window: counted */
  PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
  circ->cpath->package_window = 900;
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* Invalid extended cell: not counted */
  PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Invalid extended cell: not counted */
  PACK_CELL(1, RELAY_COMMAND_EXTENDED, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Invalid HS cell: not counted */
  PACK_CELL(1, RELAY_COMMAND_ESTABLISH_INTRO, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* "Valid" HS cell in expected state: counted */
  TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
  PACK_CELL(1, RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* End cell on non-closed connection: counted */
  PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
                                     circ->cpath);
  ASSERT_COUNTED_BW();

  /* End cell on connection that already got one: not counted */
  PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
                                     circ->cpath);
  ASSERT_UNCOUNTED_BW();

  /* Simulate closed stream on entryconn, then test: */
  if (!subtest_circbw_halfclosed(circ, 2))
    goto done;

  circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING;
  if (!subtest_circbw_halfclosed(circ, 6))
    goto done;

  /* Path bias: truncated */
  tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
  PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
  pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);

 done:
  UNMOCK(connection_start_reading);
  UNMOCK(connection_mark_unattached_ap_);
  UNMOCK(connection_mark_for_close_internal_);
  UNMOCK(relay_send_command_from_edge_);
  UNMOCK(circuit_mark_for_close_);
  circuit_free_(TO_CIRCUIT(circ));
  connection_free_minimal(ENTRY_TO_CONN(entryconn1));
}