Example #1
0
File: onion.c Project: ageis/tor
static int
extend_cell_from_extend1_cell_body(extend_cell_t *cell_out,
                                   const extend1_cell_body_t *cell)
{
  tor_assert(cell_out);
  tor_assert(cell);
  memset(cell_out, 0, sizeof(*cell_out));
  tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
  tor_addr_make_unspec(&cell_out->orport_ipv6.addr);

  cell_out->cell_type = RELAY_COMMAND_EXTEND;
  tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, cell->ipv4addr);
  cell_out->orport_ipv4.port = cell->port;
  if (tor_memeq(cell->onionskin, NTOR_CREATE_MAGIC, 16)) {
    cell_out->create_cell.cell_type = CELL_CREATE2;
    cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_NTOR;
    cell_out->create_cell.handshake_len = NTOR_ONIONSKIN_LEN;
    memcpy(cell_out->create_cell.onionskin, cell->onionskin + 16,
           NTOR_ONIONSKIN_LEN);
  } else {
    cell_out->create_cell.cell_type = CELL_CREATE;
    cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
    cell_out->create_cell.handshake_len = TAP_ONIONSKIN_CHALLENGE_LEN;
    memcpy(cell_out->create_cell.onionskin, cell->onionskin,
           TAP_ONIONSKIN_CHALLENGE_LEN);
  }
  memcpy(cell_out->node_id, cell->identity, DIGEST_LEN);
  return 0;
}
Example #2
0
File: onion.c Project: ageis/tor
static int
extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
                                   const extend2_cell_body_t *cell)
{
  tor_assert(cell_out);
  tor_assert(cell);
  int found_ipv4 = 0, found_ipv6 = 0, found_rsa_id = 0, found_ed_id = 0;
  memset(cell_out, 0, sizeof(*cell_out));
  tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
  tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
  cell_out->cell_type = RELAY_COMMAND_EXTEND2;

  unsigned i;
  for (i = 0; i < cell->n_spec; ++i) {
    const link_specifier_t *ls = extend2_cell_body_getconst_ls(cell, i);
    switch (ls->ls_type) {
      case LS_IPV4:
        if (found_ipv4)
          continue;
        found_ipv4 = 1;
        tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, ls->un_ipv4_addr);
        cell_out->orport_ipv4.port = ls->un_ipv4_port;
        break;
      case LS_IPV6:
        if (found_ipv6)
          continue;
        found_ipv6 = 1;
        tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
                                 (const char *)ls->un_ipv6_addr);
        cell_out->orport_ipv6.port = ls->un_ipv6_port;
        break;
      case LS_LEGACY_ID:
        if (found_rsa_id)
          return -1;
        found_rsa_id = 1;
        memcpy(cell_out->node_id, ls->un_legacy_id, 20);
        break;
      case LS_ED25519_ID:
        if (found_ed_id)
          return -1;
        found_ed_id = 1;
        memcpy(cell_out->ed_pubkey.pubkey, ls->un_ed25519_id, 32);
        break;
      default:
        /* Ignore this, whatever it is. */
        break;
    }
  }

  if (!found_rsa_id || !found_ipv4) /* These are mandatory */
    return -1;

  return create_cell_from_create2_cell_body(&cell_out->create_cell,
                                            cell->create2);
}
Example #3
0
static void
test_addr_is_loopback(void *data)
{
  static const struct loopback_item {
    const char *name;
    int is_loopback;
  } loopback_items[] = {
    { "::1", 1 },
    { "127.0.0.1", 1 },
    { "127.99.100.101", 1 },
    { "128.99.100.101", 0 },
    { "8.8.8.8", 0 },
    { "0.0.0.0", 0 },
    { "::2", 0 },
    { "::", 0 },
    { "::1.0.0.0", 0 },
    { NULL, 0 }
  };

  int i;
  tor_addr_t addr;
  (void)data;

  for (i=0; loopback_items[i].name; ++i) {
    tt_int_op(tor_addr_parse(&addr, loopback_items[i].name), OP_GE, 0);
    tt_int_op(tor_addr_is_loopback(&addr), OP_EQ,
              loopback_items[i].is_loopback);
  }

  tor_addr_make_unspec(&addr);
  tt_int_op(tor_addr_is_loopback(&addr), OP_EQ, 0);

 done:
  ;
}
Example #4
0
/** Launch a new cpuworker. Return 0 if we're happy, -1 if we failed.
 */
static int
spawn_cpuworker(void)
{
  tor_socket_t *fdarray;
  tor_socket_t fd;
  connection_t *conn;
  int err;

  fdarray = tor_malloc(sizeof(tor_socket_t)*2);
  if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) {
    log_warn(LD_NET, "Couldn't construct socketpair for cpuworker: %s",
             tor_socket_strerror(-err));
    tor_free(fdarray);
    return -1;
  }

  tor_assert(SOCKET_OK(fdarray[0]));
  tor_assert(SOCKET_OK(fdarray[1]));

  fd = fdarray[0];
  if (spawn_func(cpuworker_main, (void*)fdarray) < 0) {
    tor_close_socket(fdarray[0]);
    tor_close_socket(fdarray[1]);
    tor_free(fdarray);
    return -1;
  }
  log_debug(LD_OR,"just spawned a cpu worker.");
#ifndef TOR_IS_MULTITHREADED
  tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */
  tor_free(fdarray);
#endif

  conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);

  /* set up conn so it's got all the data we need to remember */
  conn->s = fd;
  conn->address = tor_strdup("localhost");
  tor_addr_make_unspec(&conn->addr);

  if (set_socket_nonblocking(fd) == -1) {
    connection_free(conn); /* this closes fd */
    return -1;
  }

  if (connection_add(conn) < 0) { /* no space, forget it */
    log_warn(LD_NET,"connection_add for cpuworker failed. Giving up.");
    connection_free(conn); /* this closes fd */
    return -1;
  }

  conn->state = CPUWORKER_STATE_IDLE;
  connection_start_reading(conn);

  return 0; /* success */
}
Example #5
0
/** Set the tor_addr_t in <b>a</b> to contain the socket address contained in
 * <b>sa</b>. */
int
tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
                       uint16_t *port_out)
{
  tor_assert(a);
  tor_assert(sa);
  if (sa->sa_family == AF_INET) {
    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
    tor_addr_from_ipv4n(a, sin->sin_addr.s_addr);
    if (port_out)
      *port_out = ntohs(sin->sin_port);
  } else if (sa->sa_family == AF_INET6) {
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
    tor_addr_from_in6(a, &sin6->sin6_addr);
    if (port_out)
      *port_out = ntohs(sin6->sin6_port);
  } else {
    tor_addr_make_unspec(a);
    return -1;
  }
  return 0;
}
Example #6
0
File: onion.c Project: BwRy/Astoria
/** Parse an EXTEND or EXTEND2 cell (according to <b>command</b>) from the
 * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
 * 0 on success, -1 on failure. */
int
extend_cell_parse(extend_cell_t *cell_out, const uint8_t command,
                  const uint8_t *payload, size_t payload_length)
{
  const uint8_t *eop;

  memset(cell_out, 0, sizeof(*cell_out));
  if (payload_length > RELAY_PAYLOAD_SIZE)
    return -1;
  eop = payload + payload_length;

  switch (command) {
  case RELAY_COMMAND_EXTEND:
    {
      if (payload_length != 6 + TAP_ONIONSKIN_CHALLENGE_LEN + DIGEST_LEN)
        return -1;

      cell_out->cell_type = RELAY_COMMAND_EXTEND;
      tor_addr_from_ipv4n(&cell_out->orport_ipv4.addr, get_uint32(payload));
      cell_out->orport_ipv4.port = ntohs(get_uint16(payload+4));
      tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
      if (tor_memeq(payload + 6, NTOR_CREATE_MAGIC, 16)) {
        cell_out->create_cell.cell_type = CELL_CREATE2;
        cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_NTOR;
        cell_out->create_cell.handshake_len = NTOR_ONIONSKIN_LEN;
        memcpy(cell_out->create_cell.onionskin, payload + 22,
               NTOR_ONIONSKIN_LEN);
      } else {
        cell_out->create_cell.cell_type = CELL_CREATE;
        cell_out->create_cell.handshake_type = ONION_HANDSHAKE_TYPE_TAP;
        cell_out->create_cell.handshake_len = TAP_ONIONSKIN_CHALLENGE_LEN;
        memcpy(cell_out->create_cell.onionskin, payload + 6,
               TAP_ONIONSKIN_CHALLENGE_LEN);
      }
      memcpy(cell_out->node_id, payload + 6 + TAP_ONIONSKIN_CHALLENGE_LEN,
             DIGEST_LEN);
      break;
    }
  case RELAY_COMMAND_EXTEND2:
    {
      uint8_t n_specs, spectype, speclen;
      int i;
      int found_ipv4 = 0, found_ipv6 = 0, found_id = 0;
      tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
      tor_addr_make_unspec(&cell_out->orport_ipv6.addr);

      if (payload_length == 0)
        return -1;

      cell_out->cell_type = RELAY_COMMAND_EXTEND2;
      n_specs = *payload++;
      /* Parse the specifiers. We'll only take the first IPv4 and first IPv6
       * address, and the node ID, and ignore everything else */
      for (i = 0; i < n_specs; ++i) {
        if (eop - payload < 2)
          return -1;
        spectype = payload[0];
        speclen = payload[1];
        payload += 2;
        if (eop - payload < speclen)
          return -1;
        switch (spectype) {
        case SPECTYPE_IPV4:
          if (speclen != 6)
            return -1;
          if (!found_ipv4) {
            tor_addr_from_ipv4n(&cell_out->orport_ipv4.addr,
                                get_uint32(payload));
            cell_out->orport_ipv4.port = ntohs(get_uint16(payload+4));
            found_ipv4 = 1;
          }
          break;
        case SPECTYPE_IPV6:
          if (speclen != 18)
            return -1;
          if (!found_ipv6) {
            tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
                                     (const char*)payload);
            cell_out->orport_ipv6.port = ntohs(get_uint16(payload+16));
            found_ipv6 = 1;
          }
          break;
        case SPECTYPE_LEGACY_ID:
          if (speclen != 20)
            return -1;
          if (found_id)
            return -1;
          memcpy(cell_out->node_id, payload, 20);
          found_id = 1;
          break;
        }
        payload += speclen;
      }
      if (!found_id || !found_ipv4)
        return -1;
      if (parse_create2_payload(&cell_out->create_cell,payload,eop-payload)<0)
        return -1;
      break;
    }
  default:
    return -1;
  }

  return check_extend_cell(cell_out);
}
Example #7
0
/** Send a resolve request for <b>hostname</b> to the Tor listening on
 * <b>sockshost</b>:<b>socksport</b>.  Store the resulting IPv4
 * address (in host order) into *<b>result_addr</b>.
 */
static int
do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
           int reverse, int version,
           tor_addr_t *result_addr, char **result_hostname)
{
  int s = -1;
  struct sockaddr_in socksaddr;
  char *req = NULL;
  ssize_t len = 0;

  tor_assert(hostname);
  tor_assert(result_addr);
  tor_assert(version == 4 || version == 5);

  tor_addr_make_unspec(result_addr);
  *result_hostname = NULL;

  s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  if (s<0) {
    log_sock_error("creating_socket", -1);
    return -1;
  }

  memset(&socksaddr, 0, sizeof(socksaddr));
  socksaddr.sin_family = AF_INET;
  socksaddr.sin_port = htons(socksport);
  socksaddr.sin_addr.s_addr = htonl(sockshost);
  if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
    log_sock_error("connecting to SOCKS host", s);
    goto err;
  }

  if (version == 5) {
    char method_buf[2];
    if (write_all(s, "\x05\x01\x00", 3, 1) != 3) {
      log_err(LD_NET, "Error sending SOCKS5 method list.");
      goto err;
    }
    if (read_all(s, method_buf, 2, 1) != 2) {
      log_err(LD_NET, "Error reading SOCKS5 methods.");
      goto err;
    }
    if (method_buf[0] != '\x05') {
      log_err(LD_NET, "Unrecognized socks version: %u",
              (unsigned)method_buf[0]);
      goto err;
    }
    if (method_buf[1] != '\x00') {
      log_err(LD_NET, "Unrecognized socks authentication method: %u",
              (unsigned)method_buf[1]);
      goto err;
    }
  }

  if ((len = build_socks_resolve_request(&req, "", hostname, reverse,
                                         version))<0) {
    log_err(LD_BUG,"Error generating SOCKS request");
    tor_assert(!req);
    goto err;
  }
  if (write_all(s, req, len, 1) != len) {
    log_sock_error("sending SOCKS request", s);
    tor_free(req);
    goto err;
  }
  tor_free(req);

  if (version == 4) {
    char reply_buf[RESPONSE_LEN_4];
    if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) {
      log_err(LD_NET, "Error reading SOCKS4 response.");
      goto err;
    }
    if (parse_socks4a_resolve_response(hostname,
                                       reply_buf, RESPONSE_LEN_4,
                                       result_addr)<0) {
      goto err;
    }
  } else {
    char reply_buf[16];
    if (read_all(s, reply_buf, 4, 1) != 4) {
      log_err(LD_NET, "Error reading SOCKS5 response.");
      goto err;
    }
    if (reply_buf[0] != 5) {
      log_err(LD_NET, "Bad SOCKS5 reply version.");
      goto err;
    }
    /* Give a user some useful feedback about SOCKS5 errors */
    if (reply_buf[1] != 0) {
      log_warn(LD_NET,"Got SOCKS5 status response '%u': %s",
               (unsigned)reply_buf[1],
               socks5_reason_to_string(reply_buf[1]));
      if (reply_buf[1] == 4 && !strcasecmpend(hostname, ".onion")) {
        onion_warning(hostname);
      }
      goto err;
    }
    if (reply_buf[3] == 1) {
      /* IPv4 address */
      if (read_all(s, reply_buf, 4, 1) != 4) {
        log_err(LD_NET, "Error reading address in socks5 response.");
        goto err;
      }
      tor_addr_from_ipv4n(result_addr, get_uint32(reply_buf));
    } else if (reply_buf[3] == 4) {
      /* IPv6 address */
      if (read_all(s, reply_buf, 16, 1) != 16) {
        log_err(LD_NET, "Error reading address in socks5 response.");
        goto err;
      }
      tor_addr_from_ipv6_bytes(result_addr, reply_buf);
    } else if (reply_buf[3] == 3) {
      /* Domain name */
      size_t result_len;
      if (read_all(s, reply_buf, 1, 1) != 1) {
        log_err(LD_NET, "Error reading address_length in socks5 response.");
        goto err;
      }
      result_len = *(uint8_t*)(reply_buf);
      *result_hostname = tor_malloc(result_len+1);
      if (read_all(s, *result_hostname, result_len, 1) != (int) result_len) {
        log_err(LD_NET, "Error reading hostname in socks5 response.");
        goto err;
      }
      (*result_hostname)[result_len] = '\0';
    }
  }

  tor_close_socket(s);
  return 0;
 err:
  tor_close_socket(s);
  return -1;
}
Example #8
0
/** Run unit tests for generating summary lines of exit policies */
static void
test_policies_general(void *arg)
{
  int i;
  smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL,
              *policy4 = NULL, *policy5 = NULL, *policy6 = NULL,
              *policy7 = NULL;
  addr_policy_t *p;
  tor_addr_t tar;
  config_line_t line;
  smartlist_t *sm = NULL;
  char *policy_str = NULL;
  short_policy_t *short_parsed = NULL;
  (void)arg;

  policy = smartlist_new();

  p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
  test_assert(p != NULL);
  test_eq(ADDR_POLICY_REJECT, p->policy_type);
  tor_addr_from_ipv4h(&tar, 0xc0a80000u);
  test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT));
  test_eq(16, p->maskbits);
  test_eq(1, p->prt_min);
  test_eq(65535, p->prt_max);

  smartlist_add(policy, p);

  tor_addr_from_ipv4h(&tar, 0x01020304u);
  test_assert(ADDR_POLICY_ACCEPTED ==
          compare_tor_addr_to_addr_policy(&tar, 2, policy));
  tor_addr_make_unspec(&tar);
  test_assert(ADDR_POLICY_PROBABLY_ACCEPTED ==
          compare_tor_addr_to_addr_policy(&tar, 2, policy));
  tor_addr_from_ipv4h(&tar, 0xc0a80102);
  test_assert(ADDR_POLICY_REJECTED ==
          compare_tor_addr_to_addr_policy(&tar, 2, policy));

  test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, 0, 1));
  test_assert(policy2);

  policy3 = smartlist_new();
  p = router_parse_addr_policy_item_from_string("reject *:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy3, p);
  p = router_parse_addr_policy_item_from_string("accept *:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy3, p);

  policy4 = smartlist_new();
  p = router_parse_addr_policy_item_from_string("accept *:443",-1);
  test_assert(p != NULL);
  smartlist_add(policy4, p);
  p = router_parse_addr_policy_item_from_string("accept *:443",-1);
  test_assert(p != NULL);
  smartlist_add(policy4, p);

  policy5 = smartlist_new();
  p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("reject *:65535",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);
  p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1);
  test_assert(p != NULL);
  smartlist_add(policy5, p);

  policy6 = smartlist_new();
  p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy6, p);

  policy7 = smartlist_new();
  p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1);
  test_assert(p != NULL);
  smartlist_add(policy7, p);

  test_assert(!exit_policy_is_general_exit(policy));
  test_assert(exit_policy_is_general_exit(policy2));
  test_assert(!exit_policy_is_general_exit(NULL));
  test_assert(!exit_policy_is_general_exit(policy3));
  test_assert(!exit_policy_is_general_exit(policy4));
  test_assert(!exit_policy_is_general_exit(policy5));
  test_assert(!exit_policy_is_general_exit(policy6));
  test_assert(!exit_policy_is_general_exit(policy7));

  test_assert(cmp_addr_policies(policy, policy2));
  test_assert(cmp_addr_policies(policy, NULL));
  test_assert(!cmp_addr_policies(policy2, policy2));
  test_assert(!cmp_addr_policies(NULL, NULL));

  test_assert(!policy_is_reject_star(policy2, AF_INET));
  test_assert(policy_is_reject_star(policy, AF_INET));
  test_assert(policy_is_reject_star(NULL, AF_INET));

  addr_policy_list_free(policy);
  policy = NULL;

  /* make sure compacting logic works. */
  policy = NULL;
  line.key = (char*)"foo";
  line.value = (char*)"accept *:80,reject private:*,reject *:*";
  line.next = NULL;
  test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1));
  test_assert(policy);
  //test_streq(policy->string, "accept *:80");
  //test_streq(policy->next->string, "reject *:*");
  test_eq(smartlist_len(policy), 4);

  /* test policy summaries */
  /* check if we properly ignore private IP addresses */
  test_policy_summary_helper("reject 192.168.0.0/16:*,"
                             "reject 0.0.0.0/8:*,"
                             "reject 10.0.0.0/8:*,"
                             "accept *:10-30,"
                             "accept *:90,"
                             "reject *:*",
                             "accept 10-30,90");
  /* check all accept policies, and proper counting of rejects */
  test_policy_summary_helper("reject 11.0.0.0/9:80,"
                             "reject 12.0.0.0/9:80,"
                             "reject 13.0.0.0/9:80,"
                             "reject 14.0.0.0/9:80,"
                             "accept *:*", "accept 1-65535");
  test_policy_summary_helper("reject 11.0.0.0/9:80,"
                             "reject 12.0.0.0/9:80,"
                             "reject 13.0.0.0/9:80,"
                             "reject 14.0.0.0/9:80,"
                             "reject 15.0.0.0:81,"
                             "accept *:*", "accept 1-65535");
  test_policy_summary_helper("reject 11.0.0.0/9:80,"
                             "reject 12.0.0.0/9:80,"
                             "reject 13.0.0.0/9:80,"
                             "reject 14.0.0.0/9:80,"
                             "reject 15.0.0.0:80,"
                             "accept *:*",
                             "reject 80");
  /* no exits */
  test_policy_summary_helper("accept 11.0.0.0/9:80,"
                             "reject *:*",
                             "reject 1-65535");
  /* port merging */
  test_policy_summary_helper("accept *:80,"
                             "accept *:81,"
                             "accept *:100-110,"
                             "accept *:111,"
                             "reject *:*",
                             "accept 80-81,100-111");
  /* border ports */
  test_policy_summary_helper("accept *:1,"
                             "accept *:3,"
                             "accept *:65535,"
                             "reject *:*",
                             "accept 1,3,65535");
  /* holes */
  test_policy_summary_helper("accept *:1,"
                             "accept *:3,"
                             "accept *:5,"
                             "accept *:7,"
                             "reject *:*",
                             "accept 1,3,5,7");
  test_policy_summary_helper("reject *:1,"
                             "reject *:3,"
                             "reject *:5,"
                             "reject *:7,"
                             "accept *:*",
                             "reject 1,3,5,7");

  /* Short policies with unrecognized formats should get accepted. */
  test_short_policy_parse("accept fred,2,3-5", "accept 2,3-5");
  test_short_policy_parse("accept 2,fred,3", "accept 2,3");
  test_short_policy_parse("accept 2,fred,3,bob", "accept 2,3");
  test_short_policy_parse("accept 2,-3,500-600", "accept 2,500-600");
  /* Short policies with nil entries are accepted too. */
  test_short_policy_parse("accept 1,,3", "accept 1,3");
  test_short_policy_parse("accept 100-200,,", "accept 100-200");
  test_short_policy_parse("reject ,1-10,,,,30-40", "reject 1-10,30-40");

  /* Try parsing various broken short policies */
#define TT_BAD_SHORT_POLICY(s)                                          \
  do {                                                                  \
    tt_ptr_op(NULL, ==, (short_parsed = parse_short_policy((s))));      \
  } while (0)
  TT_BAD_SHORT_POLICY("accept 200-199");
  TT_BAD_SHORT_POLICY("");
  TT_BAD_SHORT_POLICY("rejekt 1,2,3");
  TT_BAD_SHORT_POLICY("reject ");
  TT_BAD_SHORT_POLICY("reject");
  TT_BAD_SHORT_POLICY("rej");
  TT_BAD_SHORT_POLICY("accept 2,3,100000");
  TT_BAD_SHORT_POLICY("accept 2,3x,4");
  TT_BAD_SHORT_POLICY("accept 2,3x,4");
  TT_BAD_SHORT_POLICY("accept 2-");
  TT_BAD_SHORT_POLICY("accept 2-x");
  TT_BAD_SHORT_POLICY("accept 1-,3");
  TT_BAD_SHORT_POLICY("accept 1-,3");

  /* Test a too-long policy. */
  {
    int i;
    char *policy = NULL;
    smartlist_t *chunks = smartlist_new();
    smartlist_add(chunks, tor_strdup("accept "));
    for (i=1; i<10000; ++i)
      smartlist_add_asprintf(chunks, "%d,", i);
    smartlist_add(chunks, tor_strdup("20000"));
    policy = smartlist_join_strings(chunks, "", 0, NULL);
    SMARTLIST_FOREACH(chunks, char *, ch, tor_free(ch));
    smartlist_free(chunks);
    short_parsed = parse_short_policy(policy);/* shouldn't be accepted */
    tor_free(policy);
    tt_ptr_op(NULL, ==, short_parsed);
  }

  /* truncation ports */
  sm = smartlist_new();
  for (i=1; i<2000; i+=2) {
    char buf[POLICY_BUF_LEN];
    tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
    smartlist_add(sm, tor_strdup(buf));
  }
  smartlist_add(sm, tor_strdup("accept *:*"));
  policy_str = smartlist_join_strings(sm, ",", 0, NULL);
  test_policy_summary_helper( policy_str,
    "accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
    "46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,"
    "92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,"
    "130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,"
    "166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,"
    "202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,"
    "238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,"
    "274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,"
    "310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,"
    "346,348,350,352,354,356,358,360,362,364,366,368,370,372,374,376,378,380,"
    "382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,"
    "418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,"
    "454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,"
    "490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522");

 done:
  addr_policy_list_free(policy);
  addr_policy_list_free(policy2);
  addr_policy_list_free(policy3);
  addr_policy_list_free(policy4);
  addr_policy_list_free(policy5);
  addr_policy_list_free(policy6);
  addr_policy_list_free(policy7);
  tor_free(policy_str);
  if (sm) {
    SMARTLIST_FOREACH(sm, char *, s, tor_free(s));
    smartlist_free(sm);
  }
  short_policy_free(short_parsed);
}
Example #9
0
hs_desc_intro_point_t *
hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
                            const char *addr, int legacy)
{
  int ret;
  ed25519_keypair_t auth_kp;
  hs_desc_intro_point_t *intro_point = NULL;
  hs_desc_intro_point_t *ip = hs_desc_intro_point_new();

  /* For a usable intro point we need at least two link specifiers: One legacy
   * keyid and one ipv4 */
  {
    tor_addr_t a;
    tor_addr_make_unspec(&a);
    link_specifier_t *ls_legacy = link_specifier_new();
    link_specifier_t *ls_ip = link_specifier_new();
    link_specifier_set_ls_type(ls_legacy, LS_LEGACY_ID);
    memset(link_specifier_getarray_un_legacy_id(ls_legacy), 'C',
           link_specifier_getlen_un_legacy_id(ls_legacy));
    int family = tor_addr_parse(&a, addr);
    switch (family) {
    case AF_INET:
          link_specifier_set_ls_type(ls_ip, LS_IPV4);
          link_specifier_set_un_ipv4_addr(ls_ip, tor_addr_to_ipv4h(&a));
          link_specifier_set_un_ipv4_port(ls_ip, 9001);
          break;
        case AF_INET6:
          link_specifier_set_ls_type(ls_ip, LS_IPV6);
          memcpy(link_specifier_getarray_un_ipv6_addr(ls_ip),
                 tor_addr_to_in6_addr8(&a),
                 link_specifier_getlen_un_ipv6_addr(ls_ip));
          link_specifier_set_un_ipv6_port(ls_ip, 9001);
          break;
        default:
          /* Stop the test, not supposed to have an error.
           * Compare with -1 to show the actual family.
           */
          tt_int_op(family, OP_EQ, -1);
    }
    smartlist_add(ip->link_specifiers, ls_legacy);
    smartlist_add(ip->link_specifiers, ls_ip);
  }

  ret = ed25519_keypair_generate(&auth_kp, 0);
  tt_int_op(ret, ==, 0);
  ip->auth_key_cert = tor_cert_create(signing_kp, CERT_TYPE_AUTH_HS_IP_KEY,
                                      &auth_kp.pubkey, now,
                                      HS_DESC_CERT_LIFETIME,
                                      CERT_FLAG_INCLUDE_SIGNING_KEY);
  tt_assert(ip->auth_key_cert);

  if (legacy) {
    ip->legacy.key = crypto_pk_new();
    tt_assert(ip->legacy.key);
    ret = crypto_pk_generate_key(ip->legacy.key);
    tt_int_op(ret, ==, 0);
    ssize_t cert_len = tor_make_rsa_ed25519_crosscert(
                                    &signing_kp->pubkey, ip->legacy.key,
                                    now + HS_DESC_CERT_LIFETIME,
                                    &ip->legacy.cert.encoded);
    tt_assert(ip->legacy.cert.encoded);
    tt_u64_op(cert_len, OP_GT, 0);
    ip->legacy.cert.len = cert_len;
  }

  /* Encryption key. */
  {
    int signbit;
    curve25519_keypair_t curve25519_kp;
    ed25519_keypair_t ed25519_kp;
    tor_cert_t *cross_cert;

    ret = curve25519_keypair_generate(&curve25519_kp, 0);
    tt_int_op(ret, ==, 0);
    ed25519_keypair_from_curve25519_keypair(&ed25519_kp, &signbit,
                                            &curve25519_kp);
    cross_cert = tor_cert_create(signing_kp, CERT_TYPE_CROSS_HS_IP_KEYS,
                                 &ed25519_kp.pubkey, time(NULL),
                                 HS_DESC_CERT_LIFETIME,
                                 CERT_FLAG_INCLUDE_SIGNING_KEY);
    tt_assert(cross_cert);
    ip->enc_key_cert = cross_cert;
  }

  intro_point = ip;
 done:
  if (intro_point == NULL)
    tor_free(ip);

  return intro_point;
}
Example #10
0
static void
test_cfmt_connected_cells(void *arg)
{
  relay_header_t rh;
  cell_t cell;
  tor_addr_t addr;
  int ttl, r;
  char *mem_op_hex_tmp = NULL;
  (void)arg;

  /* Let's try an oldschool one with nothing in it. */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "", 0);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_UNSPEC);
  tt_int_op(ttl, ==, -1);

  /* A slightly less oldschool one: only an IPv4 address */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x20\x30\x40\x50", 4);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  tt_str_op(fmt_addr(&addr), ==, "32.48.64.80");
  tt_int_op(ttl, ==, -1);

  /* Bogus but understandable: truncated TTL */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED, "\x11\x12\x13\x14\x15", 5);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  tt_str_op(fmt_addr(&addr), ==, "17.18.19.20");
  tt_int_op(ttl, ==, -1);

  /* Regular IPv4 one: address and TTL */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x02\x03\x04\x05\x00\x00\x0e\x10", 8);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  tt_str_op(fmt_addr(&addr), ==, "2.3.4.5");
  tt_int_op(ttl, ==, 3600);

  /* IPv4 with too-big TTL */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x02\x03\x04\x05\xf0\x00\x00\x00", 8);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  tt_str_op(fmt_addr(&addr), ==, "2.3.4.5");
  tt_int_op(ttl, ==, -1);

  /* IPv6 (ttl is mandatory) */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x00\x00\x00\x00\x06"
                  "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
                  "\x00\x00\x00\x00\x00\x00\x00\x68"
                  "\x00\x00\x02\x58", 25);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68");
  tt_int_op(ttl, ==, 600);

  /* IPv6 (ttl too big) */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x00\x00\x00\x00\x06"
                  "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
                  "\x00\x00\x00\x00\x00\x00\x00\x68"
                  "\x90\x00\x02\x58", 25);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  tt_str_op(fmt_addr(&addr), ==, "2607:f8b0:400c:c02::68");
  tt_int_op(ttl, ==, -1);

  /* Bogus size: 3. */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x00\x01\x02", 3);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, -1);

  /* Bogus family: 7. */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x00\x00\x00\x00\x07"
                  "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
                  "\x00\x00\x00\x00\x00\x00\x00\x68"
                  "\x90\x00\x02\x58", 25);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, -1);

  /* Truncated IPv6. */
  make_relay_cell(&cell, RELAY_COMMAND_CONNECTED,
                  "\x00\x00\x00\x00\x06"
                  "\x26\x07\xf8\xb0\x40\x0c\x0c\x02"
                  "\x00\x00\x00\x00\x00\x00\x00\x68"
                  "\x00\x00\x02", 24);
  relay_header_unpack(&rh, cell.payload);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, -1);

  /* Now make sure we can generate connected cells correctly. */
  /* Try an IPv4 address */
  memset(&rh, 0, sizeof(rh));
  memset(&cell, 0, sizeof(cell));
  tor_addr_parse(&addr, "30.40.50.60");
  rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
                                            &addr, 128);
  tt_int_op(rh.length, ==, 8);
  test_memeq_hex(cell.payload+RELAY_HEADER_SIZE, "1e28323c" "00000080");

  /* Try parsing it. */
  tor_addr_make_unspec(&addr);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET);
  tt_str_op(fmt_addr(&addr), ==, "30.40.50.60");
  tt_int_op(ttl, ==, 128);

  /* Try an IPv6 address */
  memset(&rh, 0, sizeof(rh));
  memset(&cell, 0, sizeof(cell));
  tor_addr_parse(&addr, "2620::6b0:b:1a1a:0:26e5:480e");
  rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
                                            &addr, 3600);
  tt_int_op(rh.length, ==, 25);
  test_memeq_hex(cell.payload + RELAY_HEADER_SIZE,
                 "00000000" "06"
                 "2620000006b0000b1a1a000026e5480e" "00000e10");

  /* Try parsing it. */
  tor_addr_make_unspec(&addr);
  r = connected_cell_parse(&rh, &cell, &addr, &ttl);
  tt_int_op(r, ==, 0);
  tt_int_op(tor_addr_family(&addr), ==, AF_INET6);
  tt_str_op(fmt_addr(&addr), ==, "2620:0:6b0:b:1a1a:0:26e5:480e");
  tt_int_op(ttl, ==, 3600);

 done:
  tor_free(mem_op_hex_tmp);
}