Back to index

tor  0.2.3.19-rc
Defines | Functions
policies.h File Reference

Header file for policies.c. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define POLICY_BUF_LEN   52

Functions

int firewall_is_fascist_or (void)
 Return true iff the firewall options might block any address:port combination.
int fascist_firewall_allows_address_or (const tor_addr_t *addr, uint16_t port)
 Return true iff we think our firewall will let us make an OR connection to addr:port.
int fascist_firewall_allows_or (const routerinfo_t *ri)
 Return true iff we think our firewall will let us make an OR connection to ri.
int fascist_firewall_allows_node (const node_t *node)
 Return true iff we think our firewall will let us make an OR connection to node.
int fascist_firewall_allows_address_dir (const tor_addr_t *addr, uint16_t port)
 Return true iff we think our firewall will let us make a directory connection to addr:port.
int dir_policy_permits_address (const tor_addr_t *addr)
 Return 1 if addr is permitted to connect to our dir port, based on dir_policy.
int socks_policy_permits_address (const tor_addr_t *addr)
 Return 1 if addr is permitted to connect to our socks port, based on socks_policy.
int authdir_policy_permits_address (uint32_t addr, uint16_t port)
 Return 1 if addr:port is permitted to publish to our directory, based on authdir_reject_policy.
int authdir_policy_valid_address (uint32_t addr, uint16_t port)
 Return 1 if addr:port is considered valid in our directory, based on authdir_invalid_policy.
int authdir_policy_baddir_address (uint32_t addr, uint16_t port)
 Return 1 if addr:port should be marked as a bad dir, based on authdir_baddir_policy.
int authdir_policy_badexit_address (uint32_t addr, uint16_t port)
 Return 1 if addr:port should be marked as a bad exit, based on authdir_badexit_policy.
int validate_addr_policies (const or_options_t *options, char **msg)
 Config helper: If there's any problem with the policy configuration options in options, return -1 and set msg to a newly allocated description of the error.
void policy_expand_private (smartlist_t **policy)
 Replace all "private" entries in *policy with their expanded equivalents.
int policies_parse_from_options (const or_options_t *options)
 Set all policies based on options, which should have been validated first by validate_addr_policies.
addr_policy_taddr_policy_get_canonical_entry (addr_policy_t *ent)
int cmp_addr_policies (smartlist_t *a, smartlist_t *b)
 Like cmp_single_addr_policy() above, but looks at the whole set of policies in each case.
addr_policy_result_t compare_tor_addr_to_addr_policy (const tor_addr_t *addr, uint16_t port, const smartlist_t *policy)
 Decide whether a given addr:port is definitely accepted, definitely rejected, probably accepted, or probably rejected by a given policy.
addr_policy_result_t compare_tor_addr_to_node_policy (const tor_addr_t *addr, uint16_t port, const node_t *node)
 Decides whether addr:port is probably or definitely accepted or rejcted by node.
int policies_parse_exit_policy (config_line_t *cfg, smartlist_t **dest, int rejectprivate, const char *local_address, int add_default_policy)
 Parse the exit policy cfg into the linked list *dest.
void policies_exit_policy_append_reject_star (smartlist_t **dest)
 Add "reject *:*" to the end of the policy in *dest, allocating *dest as needed.
void policies_set_node_exitpolicy_to_reject_all (node_t *exitrouter)
 Replace the exit policy of node with reject *:*.
int exit_policy_is_general_exit (smartlist_t *policy)
 Return true iff ri is "useful as an exit node", meaning it allows exit to at least one /8 address space for at least two of ports 80, 443, and 6667.
int policy_is_reject_star (const smartlist_t *policy)
 Return false if policy might permit access to some addr:port; otherwise if we are certain it rejects everything, return true.
int getinfo_helper_policies (control_connection_t *conn, const char *question, char **answer, const char **errmsg)
 Implementation for GETINFO control command: knows the answer for questions about "exit-policy/...".
int policy_write_item (char *buf, size_t buflen, addr_policy_t *item, int format_for_desc)
 Write a single address policy to the buf_len byte buffer at buf.
void addr_policy_list_free (smartlist_t *p)
 Release all storage held by p.
void addr_policy_free (addr_policy_t *p)
 Release all storage held by p.
void policies_free_all (void)
 Release all storage held by policy variables.
char * policy_summarize (smartlist_t *policy)
 Create a string representing a summary for an exit policy.
short_policy_tparse_short_policy (const char *summary)
 Convert a summarized policy string into a short_policy_t.
void short_policy_free (short_policy_t *policy)
 Release all storage held in policy.
int short_policy_is_reject_star (const short_policy_t *policy)
 Return true iff policy seems reject all ports.
addr_policy_result_t compare_tor_addr_to_short_policy (const tor_addr_t *addr, uint16_t port, const short_policy_t *policy)
 See whether the addr:port address is likely to be accepted or rejected by the summarized policy policy.

Detailed Description

Header file for policies.c.

Definition in file policies.h.


Define Documentation

#define POLICY_BUF_LEN   52

Definition at line 18 of file policies.h.


Function Documentation

Release all storage held by p.

Definition at line 1537 of file policies.c.

{
  if (!p)
    return;

  if (--p->refcnt <= 0) {
    if (p->is_canonical) {
      policy_map_ent_t search, *found;
      search.policy = p;
      found = HT_REMOVE(policy_map, &policy_root, &search);
      if (found) {
        tor_assert(p == found->policy);
        tor_free(found);
      }
    }
    tor_free(p);
  }
}

Here is the caller graph for this function:

Here is the caller graph for this function:

Release all storage held by p.

Definition at line 1527 of file policies.c.

{
  if (!lst)
    return;
  SMARTLIST_FOREACH(lst, addr_policy_t *, policy, addr_policy_free(policy));
  smartlist_free(lst);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int authdir_policy_baddir_address ( uint32_t  addr,
uint16_t  port 
)

Return 1 if addr:port should be marked as a bad dir, based on authdir_baddir_policy.

Else return 0.

Definition at line 357 of file policies.c.

{
  if (! addr_policy_permits_address(addr, port, authdir_baddir_policy))
    return 1;
  return addr_is_in_cc_list(addr, get_options()->AuthDirBadDirCCs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int authdir_policy_badexit_address ( uint32_t  addr,
uint16_t  port 
)

Return 1 if addr:port should be marked as a bad exit, based on authdir_badexit_policy.

Else return 0.

Definition at line 368 of file policies.c.

{
  if (! addr_policy_permits_address(addr, port, authdir_badexit_policy))
    return 1;
  return addr_is_in_cc_list(addr, get_options()->AuthDirBadExitCCs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int authdir_policy_permits_address ( uint32_t  addr,
uint16_t  port 
)

Return 1 if addr:port is permitted to publish to our directory, based on authdir_reject_policy.

Else return 0.

Definition at line 335 of file policies.c.

{
  if (! addr_policy_permits_address(addr, port, authdir_reject_policy))
    return 0;
  return !addr_is_in_cc_list(addr, get_options()->AuthDirRejectCCs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int authdir_policy_valid_address ( uint32_t  addr,
uint16_t  port 
)

Return 1 if addr:port is considered valid in our directory, based on authdir_invalid_policy.

Else return 0.

Definition at line 346 of file policies.c.

{
  if (! addr_policy_permits_address(addr, port, authdir_invalid_policy))
    return 0;
  return !addr_is_in_cc_list(addr, get_options()->AuthDirInvalidCCs);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int cmp_addr_policies ( smartlist_t a,
smartlist_t b 
)

Like cmp_single_addr_policy() above, but looks at the whole set of policies in each case.

Definition at line 514 of file policies.c.

{
  int r, i;
  int len_a = a ? smartlist_len(a) : 0;
  int len_b = b ? smartlist_len(b) : 0;

  for (i = 0; i < len_a && i < len_b; ++i) {
    if ((r = cmp_single_addr_policy(smartlist_get(a, i), smartlist_get(b, i))))
      return r;
  }
  if (i == len_a && i == len_b)
    return 0;
  if (i < len_a)
    return -1;
  else
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

addr_policy_result_t compare_tor_addr_to_addr_policy ( const tor_addr_t addr,
uint16_t  port,
const smartlist_t policy 
)

Decide whether a given addr:port is definitely accepted, definitely rejected, probably accepted, or probably rejected by a given policy.

If addr is 0, we don't know the IP of the target address. If port is 0, we don't know the port of the target address. (At least one of addr and port must be provided. If you want to know whether a policy would definitely reject an unknown address:port, use policy_is_reject_star().)

We could do better by assuming that some ranges never match typical addresses (127.0.0.1, and so on). But we'll try this for now.

Definition at line 710 of file policies.c.

{
  if (!policy) {
    /* no policy? accept all. */
    return ADDR_POLICY_ACCEPTED;
  } else if (addr == NULL || tor_addr_is_null(addr)) {
    tor_assert(port != 0);
    return compare_unknown_tor_addr_to_addr_policy(port, policy);
  } else if (port == 0) {
    return compare_known_tor_addr_to_addr_policy_noport(addr, policy);
  } else {
    return compare_known_tor_addr_to_addr_policy(addr, port, policy);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

addr_policy_result_t compare_tor_addr_to_node_policy ( const tor_addr_t addr,
uint16_t  port,
const node_t node 
)

Decides whether addr:port is probably or definitely accepted or rejcted by node.

See compare_tor_addr_to_addr_policy for details on addr/port interpretation.

Definition at line 1492 of file policies.c.

{
  if (node->rejects_all)
    return ADDR_POLICY_REJECTED;

  if (node->ri)
    return compare_tor_addr_to_addr_policy(addr, port, node->ri->exit_policy);
  else if (node->md) {
    if (node->md->exit_policy == NULL)
      return ADDR_POLICY_REJECTED;
    else
      return compare_tor_addr_to_short_policy(addr, port,
                                              node->md->exit_policy);
  } else
    return ADDR_POLICY_PROBABLY_REJECTED;
}

Here is the call graph for this function:

Here is the caller graph for this function:

addr_policy_result_t compare_tor_addr_to_short_policy ( const tor_addr_t addr,
uint16_t  port,
const short_policy_t policy 
)

See whether the addr:port address is likely to be accepted or rejected by the summarized policy policy.

Return values are as for compare_tor_addr_to_addr_policy. Unlike the regular addr_policy functions, requires the port be specified.

Definition at line 1426 of file policies.c.

{
  int i;
  int found_match = 0;
  int accept;
  (void)addr;

  tor_assert(port != 0);

  if (addr && tor_addr_is_null(addr))
    addr = NULL; /* Unspec means 'no address at all,' in this context. */

  if (addr && (tor_addr_is_internal(addr, 0) ||
               tor_addr_is_loopback(addr)))
    return ADDR_POLICY_REJECTED;

  for (i=0; i < policy->n_entries; ++i) {
    const short_policy_entry_t *e = &policy->entries[i];
    if (e->min_port <= port && port <= e->max_port) {
      found_match = 1;
      break;
    }
  }

  if (found_match)
    accept = policy->is_accept;
  else
    accept = ! policy->is_accept;

  /* ???? are these right? -NM */
  /* We should be sure not to return ADDR_POLICY_ACCEPTED in the accept
   * case here, because it would cause clients to believe that the node
   * allows exit enclaving. Trying it anyway would open up a cool attack
   * where the node refuses due to exitpolicy, the client reacts in
   * surprise by rewriting the node's exitpolicy to reject *:*, and then
   * a bad guy targets users by causing them to attempt such connections
   * to 98% of the exits.
   *
   * Once microdescriptors can handle addresses in special cases (e.g. if
   * we ever solve ticket 1774), we can provide certainty here. -RD */
  if (accept)
    return ADDR_POLICY_PROBABLY_ACCEPTED;
  else
    return ADDR_POLICY_REJECTED;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int dir_policy_permits_address ( const tor_addr_t addr)

Return 1 if addr is permitted to connect to our dir port, based on dir_policy.

Else return 0.

Definition at line 303 of file policies.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Return true iff ri is "useful as an exit node", meaning it allows exit to at least one /8 address space for at least two of ports 80, 443, and 6667.

Definition at line 954 of file policies.c.

{
  static const int ports[] = { 80, 443, 6667 };
  int n_allowed = 0;
  int i;
  if (!policy) /*XXXX disallow NULL policies? */
    return 0;

  for (i = 0; i < 3; ++i) {
    n_allowed += exit_policy_is_general_exit_helper(policy, ports[i]);
  }
  return n_allowed >= 2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int fascist_firewall_allows_address_dir ( const tor_addr_t addr,
uint16_t  port 
)

Return true iff we think our firewall will let us make a directory connection to addr:port.

Definition at line 293 of file policies.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int fascist_firewall_allows_address_or ( const tor_addr_t addr,
uint16_t  port 
)

Return true iff we think our firewall will let us make an OR connection to addr:port.

Definition at line 257 of file policies.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int fascist_firewall_allows_node ( const node_t node)

Return true iff we think our firewall will let us make an OR connection to node.

Definition at line 277 of file policies.c.

{
  if (node->ri) {
    return fascist_firewall_allows_or(node->ri);
  } else if (node->rs) {
    tor_addr_t addr;
    tor_addr_from_ipv4h(&addr, node->rs->addr);
    return fascist_firewall_allows_address_or(&addr, node->rs->or_port);
  } else {
    return 1;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Return true iff we think our firewall will let us make an OR connection to ri.

Definition at line 266 of file policies.c.

{
  /* XXXX proposal 118 */
  tor_addr_t addr;
  tor_addr_from_ipv4h(&addr, ri->addr);
  return fascist_firewall_allows_address_or(&addr, ri->or_port);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int firewall_is_fascist_or ( void  )

Return true iff the firewall options might block any address:port combination.

Definition at line 214 of file policies.c.

{
  return reachable_or_addr_policy != NULL;
}

Here is the caller graph for this function:

int getinfo_helper_policies ( control_connection_t conn,
const char *  question,
char **  answer,
const char **  errmsg 
)

Implementation for GETINFO control command: knows the answer for questions about "exit-policy/...".

Definition at line 1513 of file policies.c.

{
  (void) conn;
  (void) errmsg;
  if (!strcmp(question, "exit-policy/default")) {
    *answer = tor_strdup(DEFAULT_EXIT_POLICY);
  }
  return 0;
}
short_policy_t* parse_short_policy ( const char *  summary)

Convert a summarized policy string into a short_policy_t.

Return NULL if the string is not well-formed.

Definition at line 1323 of file policies.c.

{
  const char *orig_summary = summary;
  short_policy_t *result;
  int is_accept;
  int n_entries;
  short_policy_entry_t entries[MAX_EXITPOLICY_SUMMARY_LEN]; /* overkill */
  const char *next;

  if (!strcmpstart(summary, "accept ")) {
    is_accept = 1;
    summary += strlen("accept ");
  } else if (!strcmpstart(summary, "reject ")) {
    is_accept = 0;
    summary += strlen("reject ");
  } else {
    log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Unrecognized policy summary keyword");
    return NULL;
  }

  n_entries = 0;
  for ( ; *summary; summary = next) {
    const char *comma = strchr(summary, ',');
    unsigned low, high;
    char dummy;
    char ent_buf[32];

    next = comma ? comma+1 : strchr(summary, '\0');

    if (n_entries == MAX_EXITPOLICY_SUMMARY_LEN) {
      log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Impossibly long policy summary %s",
             escaped(orig_summary));
      return NULL;
    }

    if (! TOR_ISDIGIT(*summary) || next-summary > (int)(sizeof(ent_buf)-1)) {
      /* unrecognized entry format. skip it. */
      continue;
    }
    if (next-summary < 2) {
      /* empty; skip it. */
      continue;
    }

    memcpy(ent_buf, summary, next-summary-1);
    ent_buf[next-summary-1] = '\0';

    if (tor_sscanf(ent_buf, "%u-%u%c", &low, &high, &dummy) == 2) {
      if (low<1 || low>65535 || high<1 || high>65535) {
        log_fn(LOG_PROTOCOL_WARN, LD_DIR,
               "Found bad entry in policy summary %s", escaped(orig_summary));
        return NULL;
      }
    } else if (tor_sscanf(ent_buf, "%u%c", &low, &dummy) == 1) {
      if (low<1 || low>65535) {
        log_fn(LOG_PROTOCOL_WARN, LD_DIR,
               "Found bad entry in policy summary %s", escaped(orig_summary));
        return NULL;
      }
      high = low;
    } else {
      log_fn(LOG_PROTOCOL_WARN, LD_DIR,"Found bad entry in policy summary %s",
             escaped(orig_summary));
      return NULL;
    }

    entries[n_entries].min_port = low;
    entries[n_entries].max_port = high;
    n_entries++;
  }

  if (n_entries == 0) {
    log_fn(LOG_PROTOCOL_WARN, LD_DIR,
           "Found no port-range entries in summary %s", escaped(orig_summary));
    return NULL;
  }

  {
    size_t size = STRUCT_OFFSET(short_policy_t, entries) +
      sizeof(short_policy_entry_t)*(n_entries);
    result = tor_malloc_zero(size);

    tor_assert( (char*)&result->entries[n_entries-1] < ((char*)result)+size);
  }

  result->is_accept = is_accept;
  result->n_entries = n_entries;
  memcpy(result->entries, entries, sizeof(short_policy_entry_t)*n_entries);
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Add "reject *:*" to the end of the policy in *dest, allocating *dest as needed.

Definition at line 893 of file policies.c.

{
  append_exit_policy_string(dest, "reject *:*");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void policies_free_all ( void  )

Release all storage held by policy variables.

Definition at line 1558 of file policies.c.

{
  addr_policy_list_free(reachable_or_addr_policy);
  reachable_or_addr_policy = NULL;
  addr_policy_list_free(reachable_dir_addr_policy);
  reachable_dir_addr_policy = NULL;
  addr_policy_list_free(socks_policy);
  socks_policy = NULL;
  addr_policy_list_free(dir_policy);
  dir_policy = NULL;
  addr_policy_list_free(authdir_reject_policy);
  authdir_reject_policy = NULL;
  addr_policy_list_free(authdir_invalid_policy);
  authdir_invalid_policy = NULL;
  addr_policy_list_free(authdir_baddir_policy);
  authdir_baddir_policy = NULL;
  addr_policy_list_free(authdir_badexit_policy);
  authdir_badexit_policy = NULL;

  if (!HT_EMPTY(&policy_root)) {
    policy_map_ent_t **ent;
    int n = 0;
    char buf[POLICY_BUF_LEN];

    log_warn(LD_MM, "Still had %d address policies cached at shutdown.",
             (int)HT_SIZE(&policy_root));

    /* Note the first 10 cached policies to try to figure out where they
     * might be coming from. */
    HT_FOREACH(ent, policy_map, &policy_root) {
      if (++n > 10)
        break;
      if (policy_write_item(buf, sizeof(buf), (*ent)->policy, 0) >= 0)
        log_warn(LD_MM,"  %d [%d]: %s", n, (*ent)->policy->refcnt, buf);
    }
  }
  HT_CLEAR(policy_map, &policy_root);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int policies_parse_exit_policy ( config_line_t cfg,
smartlist_t **  dest,
int  rejectprivate,
const char *  local_address,
int  add_default_policy 
)

Parse the exit policy cfg into the linked list *dest.

If cfg doesn't end in an absolute accept or reject and if add_default_policy is true, add the default exit policy afterwards. If rejectprivate is true, prepend "reject private:*" to the policy. Return -1 if we can't parse cfg, else return 0.

Definition at line 867 of file policies.c.

{
  if (rejectprivate) {
    append_exit_policy_string(dest, "reject private:*");
    if (local_address) {
      char buf[POLICY_BUF_LEN];
      tor_snprintf(buf, sizeof(buf), "reject %s:*", local_address);
      append_exit_policy_string(dest, buf);
    }
  }
  if (parse_addr_policy(cfg, dest, -1))
    return -1;
  if (add_default_policy)
    append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
  else
    append_exit_policy_string(dest, "reject *:*");
  exit_policy_remove_redundancies(*dest);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int policies_parse_from_options ( const or_options_t options)

Set all policies based on options, which should have been validated first by validate_addr_policies.

Definition at line 466 of file policies.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Replace the exit policy of node with reject *:*.

Definition at line 900 of file policies.c.

{
  node->rejects_all = 1;
}

Here is the caller graph for this function:

void policy_expand_private ( smartlist_t **  policy)

Replace all "private" entries in *policy with their expanded equivalents.

Definition at line 68 of file policies.c.

{
  uint16_t port_min, port_max;

  int i;
  smartlist_t *tmp;

  if (!*policy) /*XXXX disallow NULL policies? */
    return;

  tmp = smartlist_new();

  SMARTLIST_FOREACH(*policy, addr_policy_t *, p,
  {
     if (! p->is_private) {
       smartlist_add(tmp, p);
       continue;
     }
     for (i = 0; private_nets[i]; ++i) {
       addr_policy_t newpolicy;
       memcpy(&newpolicy, p, sizeof(addr_policy_t));
       newpolicy.is_private = 0;
       newpolicy.is_canonical = 0;
       if (tor_addr_parse_mask_ports(private_nets[i], &newpolicy.addr,
                               &newpolicy.maskbits, &port_min, &port_max)<0) {
         tor_assert(0);
       }
       smartlist_add(tmp, addr_policy_get_canonical_entry(&newpolicy));
     }
     addr_policy_free(p);
  });

  smartlist_free(*policy);
  *policy = tmp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int policy_is_reject_star ( const smartlist_t policy)

Return false if policy might permit access to some addr:port; otherwise if we are certain it rejects everything, return true.

Definition at line 971 of file policies.c.

{
  if (!policy) /*XXXX disallow NULL policies? */
    return 1;
  SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
    if (p->policy_type == ADDR_POLICY_ACCEPT)
      return 0;
    else if (p->policy_type == ADDR_POLICY_REJECT &&
             p->prt_min <= 1 && p->prt_max == 65535 &&
             p->maskbits == 0)
      return 1;
  });
  return 1;
}

Here is the caller graph for this function:

char* policy_summarize ( smartlist_t policy)

Create a string representing a summary for an exit policy.

The summary will either be an "accept" plus a comma-separated list of port ranges or a "reject" plus port-ranges, depending on which is shorter.

If no exits are allowed at all then NULL is returned, if no ports are blocked instead of "reject " we return "accept 1-65535" (this is an exception to the shorter-representation-wins rule).

Definition at line 1217 of file policies.c.

{
  smartlist_t *summary = policy_summary_create();
  smartlist_t *accepts, *rejects;
  int i, last, start_prt;
  size_t accepts_len, rejects_len;
  char *accepts_str = NULL, *rejects_str = NULL, *shorter_str, *result;
  const char *prefix;

  tor_assert(policy);

  /* Create the summary list */
  SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
    policy_summary_add_item(summary, p);
  });

  /* Now create two lists of strings, one for accepted and one
   * for rejected ports.  We take care to merge ranges so that
   * we avoid getting stuff like "1-4,5-9,10", instead we want
   * "1-10"
   */
  i = 0;
  start_prt = 1;
  accepts = smartlist_new();
  rejects = smartlist_new();
  while (1) {
    last = i == smartlist_len(summary)-1;
    if (last ||
        AT(i)->accepted != AT(i+1)->accepted) {
      char buf[POLICY_BUF_LEN];

      if (start_prt == AT(i)->prt_max)
        tor_snprintf(buf, sizeof(buf), "%d", start_prt);
      else
        tor_snprintf(buf, sizeof(buf), "%d-%d", start_prt, AT(i)->prt_max);

      if (AT(i)->accepted)
        smartlist_add(accepts, tor_strdup(buf));
      else
        smartlist_add(rejects, tor_strdup(buf));

      if (last)
        break;

      start_prt = AT(i+1)->prt_min;
    };
    i++;
  };

  /* Figure out which of the two stringlists will be shorter and use
   * that to build the result
   */
  if (smartlist_len(accepts) == 0) { /* no exits at all */
    result = tor_strdup("reject 1-65535");
    goto cleanup;
  }
  if (smartlist_len(rejects) == 0) { /* no rejects at all */
    result = tor_strdup("accept 1-65535");
    goto cleanup;
  }

  accepts_str = smartlist_join_strings(accepts, ",", 0, &accepts_len);
  rejects_str = smartlist_join_strings(rejects, ",", 0, &rejects_len);

  if (rejects_len > MAX_EXITPOLICY_SUMMARY_LEN-strlen("reject")-1 &&
      accepts_len > MAX_EXITPOLICY_SUMMARY_LEN-strlen("accept")-1) {
    char *c;
    shorter_str = accepts_str;
    prefix = "accept";

    c = shorter_str + (MAX_EXITPOLICY_SUMMARY_LEN-strlen(prefix)-1);
    while (*c != ',' && c >= shorter_str)
      c--;
    tor_assert(c >= shorter_str);
    tor_assert(*c == ',');
    *c = '\0';

  } else if (rejects_len < accepts_len) {
    shorter_str = rejects_str;
    prefix = "reject";
  } else {
    shorter_str = accepts_str;
    prefix = "accept";
  }

  tor_asprintf(&result, "%s %s", prefix, shorter_str);

 cleanup:
  /* cleanup */
  SMARTLIST_FOREACH(summary, policy_summary_item_t *, s, tor_free(s));
  smartlist_free(summary);

  tor_free(accepts_str);
  SMARTLIST_FOREACH(accepts, char *, s, tor_free(s));
  smartlist_free(accepts);

  tor_free(rejects_str);
  SMARTLIST_FOREACH(rejects, char *, s, tor_free(s));
  smartlist_free(rejects);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int policy_write_item ( char *  buf,
size_t  buflen,
addr_policy_t policy,
int  format_for_desc 
)

Write a single address policy to the buf_len byte buffer at buf.

Return the number of characters written, or -1 on failure.

Definition at line 989 of file policies.c.

{
  size_t written = 0;
  char addrbuf[TOR_ADDR_BUF_LEN];
  const char *addrpart;
  int result;
  const int is_accept = policy->policy_type == ADDR_POLICY_ACCEPT;
  const int is_ip6 = tor_addr_family(&policy->addr) == AF_INET6;

  tor_addr_to_str(addrbuf, &policy->addr, sizeof(addrbuf), 1);

  /* write accept/reject 1.2.3.4 */
  if (policy->is_private)
    addrpart = "private";
  else if (policy->maskbits == 0)
    addrpart = "*";
  else
    addrpart = addrbuf;

  result = tor_snprintf(buf, buflen, "%s%s%s %s",
                        (is_ip6&&format_for_desc)?"opt ":"",
                        is_accept ? "accept" : "reject",
                        (is_ip6&&format_for_desc)?"6":"",
                        addrpart);
  if (result < 0)
    return -1;
  written += strlen(buf);
  /* If the maskbits is 32 we don't need to give it.  If the mask is 0,
   * we already wrote "*". */
  if (policy->maskbits < 32 && policy->maskbits > 0) {
    if (tor_snprintf(buf+written, buflen-written, "/%d", policy->maskbits)<0)
      return -1;
    written += strlen(buf+written);
  }
  if (policy->prt_min <= 1 && policy->prt_max == 65535) {
    /* There is no port set; write ":*" */
    if (written+4 > buflen)
      return -1;
    strlcat(buf+written, ":*", buflen-written);
    written += 2;
  } else if (policy->prt_min == policy->prt_max) {
    /* There is only one port; write ":80". */
    result = tor_snprintf(buf+written, buflen-written, ":%d", policy->prt_min);
    if (result<0)
      return -1;
    written += result;
  } else {
    /* There is a range of ports; write ":79-80". */
    result = tor_snprintf(buf+written, buflen-written, ":%d-%d",
                          policy->prt_min, policy->prt_max);
    if (result<0)
      return -1;
    written += result;
  }
  if (written < buflen)
    buf[written] = '\0';
  else
    return -1;

  return (int)written;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void short_policy_free ( short_policy_t policy)

Release all storage held in policy.

Definition at line 1416 of file policies.c.

{
  tor_free(policy);
}

Here is the caller graph for this function:

Return true iff policy seems reject all ports.

Definition at line 1475 of file policies.c.

{
  /* This doesn't need to be as much on the lookout as policy_is_reject_star,
   * since policy summaries are from the consensus or from consensus
   * microdescs.
   */
  tor_assert(policy);
  /* Check for an exact match of "reject 1-65535". */
  return (policy->is_accept == 0 && policy->n_entries == 1 &&
          policy->entries[0].min_port == 1 &&
          policy->entries[0].max_port == 65535);
}

Here is the caller graph for this function:

Return 1 if addr is permitted to connect to our socks port, based on socks_policy.

Else return 0.

Definition at line 312 of file policies.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int validate_addr_policies ( const or_options_t options,
char **  msg 
)

Config helper: If there's any problem with the policy configuration options in options, return -1 and set msg to a newly allocated description of the error.

Else return 0.

Definition at line 382 of file policies.c.

{
  /* XXXX Maybe merge this into parse_policies_from_options, to make sure
   * that the two can't go out of sync. */

  smartlist_t *addr_policy=NULL;
  *msg = NULL;

  if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
                                 options->ExitPolicyRejectPrivate, NULL,
                                 !options->BridgeRelay))
    REJECT("Error in ExitPolicy entry.");

  /* The rest of these calls *append* to addr_policy. So don't actually
   * use the results for anything other than checking if they parse! */
  if (parse_addr_policy(options->DirPolicy, &addr_policy, -1))
    REJECT("Error in DirPolicy entry.");
  if (parse_addr_policy(options->SocksPolicy, &addr_policy, -1))
    REJECT("Error in SocksPolicy entry.");
  if (parse_addr_policy(options->AuthDirReject, &addr_policy,
                        ADDR_POLICY_REJECT))
    REJECT("Error in AuthDirReject entry.");
  if (parse_addr_policy(options->AuthDirInvalid, &addr_policy,
                        ADDR_POLICY_REJECT))
    REJECT("Error in AuthDirInvalid entry.");
  if (parse_addr_policy(options->AuthDirBadDir, &addr_policy,
                        ADDR_POLICY_REJECT))
    REJECT("Error in AuthDirBadDir entry.");
  if (parse_addr_policy(options->AuthDirBadExit, &addr_policy,
                        ADDR_POLICY_REJECT))
    REJECT("Error in AuthDirBadExit entry.");

  if (parse_addr_policy(options->ReachableAddresses, &addr_policy,
                        ADDR_POLICY_ACCEPT))
    REJECT("Error in ReachableAddresses entry.");
  if (parse_addr_policy(options->ReachableORAddresses, &addr_policy,
                        ADDR_POLICY_ACCEPT))
    REJECT("Error in ReachableORAddresses entry.");
  if (parse_addr_policy(options->ReachableDirAddresses, &addr_policy,
                        ADDR_POLICY_ACCEPT))
    REJECT("Error in ReachableDirAddresses entry.");

 err:
  addr_policy_list_free(addr_policy);
  return *msg ? -1 : 0;
#undef REJECT
}

Here is the call graph for this function: