Commit 80365b98 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Allow multiple exit policy lines; mostly add support for AP policies


svn:r1905
parent 80be19d9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -16,9 +16,9 @@ For 0.0.7:
        o the keep-trying-to-build-intropoints-always bug.
        - *bindaddress
          o include the port
          - allow multiple of them
          o allow multiple of them
          - have an allow/deny series for them
        - break exitpolicy into multiple config lines
        o break exitpolicy into multiple config lines
        - have the OP forget routers it hasn't heard about in 24 hours
        - rename/rearrange functions for what file they're in
        - try to break apart the main clump of functions better.
+65 −11
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
    config_compare(list, "DebugLogFile",   CONFIG_TYPE_STRING, &options->DebugLogFile) ||
    config_compare(list, "DataDirectory",  CONFIG_TYPE_STRING, &options->DataDirectory) ||
    config_compare(list, "DirPort",        CONFIG_TYPE_INT, &options->DirPort) ||
    config_compare(list, "DirBindAddress", CONFIG_TYPE_STRING, &options->DirBindAddress) ||
    config_compare(list, "DirBindAddress", CONFIG_TYPE_LINELIST, &options->DirBindAddress) ||
    config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_INT, &options->DirFetchPostPeriod) ||

    config_compare(list, "ExitNodes",      CONFIG_TYPE_STRING, &options->ExitNodes) ||
@@ -221,7 +221,7 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
    config_compare(list, "NumCpus",        CONFIG_TYPE_INT, &options->NumCpus) ||

    config_compare(list, "ORPort",         CONFIG_TYPE_INT, &options->ORPort) ||
    config_compare(list, "ORBindAddress",  CONFIG_TYPE_STRING, &options->ORBindAddress) ||
    config_compare(list, "ORBindAddress",  CONFIG_TYPE_LINELIST, &options->ORBindAddress) ||

    config_compare(list, "PidFile",        CONFIG_TYPE_STRING, &options->PidFile) ||
    config_compare(list, "PathlenCoinWeight",CONFIG_TYPE_DOUBLE, &options->PathlenCoinWeight) ||
@@ -233,7 +233,8 @@ static int config_assign(or_options_t *options, struct config_line_t *list) {
    config_compare(list, "RendExcludeNodes",CONFIG_TYPE_STRING, &options->RendExcludeNodes) ||

    config_compare(list, "SocksPort",      CONFIG_TYPE_INT, &options->SocksPort) ||
    config_compare(list, "SocksBindAddress",CONFIG_TYPE_STRING,&options->SocksBindAddress) ||
    config_compare(list, "SocksBindAddress",CONFIG_TYPE_LINELIST,&options->SocksBindAddress) ||
    config_compare(list, "SocksPolicy",     CONFIG_TYPE_LINELIST,&options->SocksPolicy) ||

    config_compare(list, "TrafficShaping", CONFIG_TYPE_BOOL, &options->TrafficShaping) ||

@@ -477,14 +478,15 @@ static void free_options(or_options_t *options) {
  tor_free(options->ExcludeNodes);
  tor_free(options->RendNodes);
  tor_free(options->RendExcludeNodes);
  tor_free(options->ExitPolicy);
  tor_free(options->SocksBindAddress);
  tor_free(options->ORBindAddress);
  tor_free(options->DirBindAddress);
  tor_free(options->RecommendedVersions);
  tor_free(options->User);
  tor_free(options->Group);
  config_free_lines(options->RendConfigLines);
  config_free_lines(options->SocksBindAddress);
  config_free_lines(options->ORBindAddress);
  config_free_lines(options->DirBindAddress);
  config_free_lines(options->ExitPolicy);
  config_free_lines(options->SocksPolicy);
}

/** Set <b>options</b> to hold reasonable defaults for most options. */
@@ -497,10 +499,11 @@ static void init_options(or_options_t *options) {
  options->ExcludeNodes = tor_strdup("");
  options->RendNodes = tor_strdup("");
  options->RendExcludeNodes = tor_strdup("");
  options->ExitPolicy = tor_strdup("");
  options->SocksBindAddress = tor_strdup("127.0.0.1");
  options->ORBindAddress = tor_strdup("0.0.0.0");
  options->DirBindAddress = tor_strdup("0.0.0.0");
  options->ExitPolicy = NULL;
  options->SocksPolicy = NULL;
  options->SocksBindAddress = NULL;
  options->ORBindAddress = NULL;
  options->DirBindAddress = NULL;
  options->RecommendedVersions = NULL;
  options->PidFile = NULL; // tor_strdup("tor.pid");
  options->DataDirectory = NULL;
@@ -808,6 +811,57 @@ void config_init_logs(or_options_t *options)
  }
}

void
config_parse_exit_policy(struct config_line_t *cfg,
                         struct exit_policy_t **dest)
{
  struct exit_policy_t **nextp;
  char *e, *s;
  int last=0;
  char line[1024];

  if (!cfg)
    return;
  nextp = dest;
  while (*nextp)
    nextp = &((*nextp)->next);

  for (; cfg; cfg = cfg->next) {
    s = cfg->value;
    for (;;) {
      e = strchr(s,',');
      if(!e) {
        last = 1;
        strncpy(line,s,1023);
      } else {
        memcpy(line,s, ((e-s)<1023)?(e-s):1023);
      line[e-s] = 0;
      }
      line[1023]=0;
      log_fn(LOG_DEBUG,"Adding new entry '%s'",line);
      *nextp = router_parse_exit_policy_from_string(line);
      if(*nextp) {
        nextp = &((*nextp)->next);
      } else {
        log_fn(LOG_WARN,"Malformed exit policy %s; skipping.", line);
      }
      if (last)
        break;
      s = e+1;
    }
  }
}

void exit_policy_free(struct exit_policy_t *p) {
  struct exit_policy_t *e;
  while (p) {
    e = p;
    p = p->next;
    tor_free(e->string);
    tor_free(e);
  }
}

/*
  Local Variables:
  mode:c
+43 −31
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ char *conn_state_to_string[][_CONN_TYPE_MAX+1] = {

/********* END VARIABLES ************/

static int connection_create_listener(const char *bindaddress,
                                      uint16_t bindport, int type);
static int connection_init_accepted_conn(connection_t *conn);
static int connection_handle_listener_read(connection_t *conn, int new_type);
static int connection_receiver_bucket_should_increase(connection_t *conn);
@@ -307,7 +309,7 @@ void connection_expire_held_open(void)
 * If <b>bindaddress</b> includes a port, we bind on that port; otherwise, we
 * use bindport.
 */
int connection_create_listener(char *bindaddress, uint16_t bindport, int type) {
static int connection_create_listener(const char *bindaddress, uint16_t bindport, int type) {
  struct sockaddr_in bindaddr; /* where to bind */
  connection_t *conn;
  char *hostname, *cp;
@@ -488,54 +490,64 @@ int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_
  return 1;
}

/** If there exists a listener of type <b>type</b> in the connection
 * array, mark it for close.
/** If there exist any listeners of type <b>type</b> in the connection
 * array, mark them for close.
 */
static void listener_close_if_present(int type) {
  connection_t *conn;
  connection_t **carray;
  int i,n;
  tor_assert(type == CONN_TYPE_OR_LISTENER ||
             type == CONN_TYPE_AP_LISTENER ||
             type == CONN_TYPE_DIR_LISTENER);
  conn = connection_get_by_type(type);
  if (conn) {
  get_connection_array(&carray,&n);
  for(i=0;i<n;i++) {
    conn = carray[i];
    if (conn->type == type && !conn->marked_for_close) {
      connection_close_immediate(conn);
      connection_mark_for_close(conn);
    }
  }
}

static int retry_listeners(int type, struct config_line_t *cfg,
                           int port_option, const char *default_addr)
{
  listener_close_if_present(type);
  if (port_option) {
    if (!cfg) {
      if (connection_create_listener(default_addr, (uint16_t) port_option,
                                     type)<0)
        return -1;
    } else {
      for ( ; cfg; cfg = cfg->next) {
        if (connection_create_listener(cfg->value, (uint16_t) port_option,
                                       type)<0)
          return -1;
      }
    }
  }
  return 0;
}

/** Start all connections that should be up but aren't.
 *  - Connect to all ORs if you're an OR.
 *  - Relaunch listeners for each port you have open.
 */
int retry_all_connections(void) {

  if(options.ORPort) {
    router_retry_connections();
  }

  if(options.ORPort) {
    listener_close_if_present(CONN_TYPE_OR_LISTENER);
    if(connection_create_listener(options.ORBindAddress,
                                  (uint16_t) options.ORPort,
                                  CONN_TYPE_OR_LISTENER) < 0)
  if (retry_listeners(CONN_TYPE_OR_LISTENER, options.ORBindAddress,
                      options.ORPort, "0.0.0.0")<0)
    return -1;
  }

  if(options.DirPort) {
    listener_close_if_present(CONN_TYPE_DIR_LISTENER);
    if(connection_create_listener(options.DirBindAddress,
                                  (uint16_t) options.DirPort,
                                  CONN_TYPE_DIR_LISTENER) < 0)
  if (retry_listeners(CONN_TYPE_DIR_LISTENER, options.DirBindAddress,
                      options.DirPort, "0.0.0.0")<0)
    return -1;
  }

  if(options.SocksPort) {
    listener_close_if_present(CONN_TYPE_AP_LISTENER);
    if(connection_create_listener(options.SocksBindAddress,
                                  (uint16_t) options.SocksPort,
                                  CONN_TYPE_AP_LISTENER) < 0)
  if (retry_listeners(CONN_TYPE_AP_LISTENER, options.SocksBindAddress,
                      options.SocksPort, "127.0.0.1")<0)
    return -1;
  }

  return 0;
}
+36 −0
Original line number Diff line number Diff line
@@ -13,7 +13,11 @@
extern or_options_t options; /* command-line and config-file options */
extern char *conn_state_to_string[][_CONN_TYPE_MAX+1]; /* from connection.c */

static struct exit_policy_t *socks_policy = NULL;

static int connection_ap_handshake_process_socks(connection_t *conn);
static void parse_socks_policy(void);
static int socks_policy_permits_address(uint32_t addr);

/** Handle new bytes on conn->inbuf, or notification of eof.
 *
@@ -781,6 +785,38 @@ int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit)
           conn->socks_request->port, exit->exit_policy);
}

static void parse_socks_policy(void)
{
  struct exit_policy_t *n;
  if (socks_policy) {
    exit_policy_free(socks_policy);
    socks_policy = NULL;
  }
  config_parse_exit_policy(options.SocksPolicy, &socks_policy);
  /* ports aren't used. */
  for (n=socks_policy; n; n = n->next) {
    n->prt_min = 1;
    n->prt_max = 65535;
  }
}

int socks_policy_permits_address(uint32_t addr)
{
  int a;
  if (options.SocksPolicy && !socks_policy)
    parse_socks_policy();

  a = router_compare_addr_to_exit_policy(addr, 1, socks_policy);
  if (a==-1)
    return 0;
  else if (a==0)
    return 1;
  else if (a==1) {
    log_fn(LOG_WARN, "Got unexpected 'maybe' answer from socks policy");
    return 1;
  }
}

/* ***** Client DNS code ***** */

/* XXX Perhaps this should get merged with the dns.c code somehow. */
+12 −9
Original line number Diff line number Diff line
@@ -777,13 +777,14 @@ typedef struct {
  char *RendExcludeNodes; /**< Comma-separated list of nicknames not to use
                           * as introduction points. */

  char *ExitPolicy; /**< Comma-separated list of exit policy components. */
  char *SocksBindAddress; /**< Address to bind for listening for SOCKS
                           * connections. */
  char *ORBindAddress; /**< Address to bind for listening for OR
                        * connections. */
  char *DirBindAddress; /**< Address to bind for listening for directory
                         * connections. */
  struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */
  struct config_line_t *SocksPolicy; /**< Lists of socks policy components */
  struct config_line_t *SocksBindAddress;
  /**< Addresses to bind for listening for SOCKS connections. */
  struct config_line_t *ORBindAddress;
  /**< Addresses to bind for listening for OR connections. */
  struct config_line_t *DirBindAddress;
  /**< Addresses to bind for listening for directory connections. */
  char *RecommendedVersions; /**< Directory server only: which versions of
                              * Tor should we tell users to run? */
  char *User; /**< Name of user to run Tor as. */
@@ -953,6 +954,9 @@ struct config_line_t {
int config_assign_default_dirservers(void);
int getconfig(int argc, char **argv, or_options_t *options);
void config_init_logs(or_options_t *options);
void config_parse_exit_policy(struct config_line_t *cfg,
                              struct exit_policy_t **dest);
void exit_policy_free(struct exit_policy_t *p);

/********************************* connection.c ***************************/

@@ -982,8 +986,6 @@ int _connection_mark_for_close(connection_t *conn);

void connection_expire_held_open(void);

int connection_create_listener(char *bindaddress, uint16_t bindport, int type);

int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port);
int retry_all_connections(void);

@@ -1318,6 +1320,7 @@ int router_parse_routerlist_from_directory(const char *s,
                                           crypto_pk_env_t *pkey);
routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
struct exit_policy_t *router_parse_exit_policy_from_string(const char *s);

#endif

Loading