summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-03-05 05:27:59 +0000
committerNick Mathewson <nickm@torproject.org>2006-03-05 05:27:59 +0000
commit6a4e304d9e613b613e208bb0f11ec44c3fc30150 (patch)
tree9bad163e3aeb3bb299223924cee4e69ae773e276
parentae628a3aee48c0fcd76f747fc44adfbfc94c910c (diff)
downloadtor-6a4e304d9e613b613e208bb0f11ec44c3fc30150.tar.gz
tor-6a4e304d9e613b613e208bb0f11ec44c3fc30150.zip
Allow private:* in routerdescs; not generated yet (because older Tors do not understand it); needs testing.
svn:r6086
-rw-r--r--src/common/util.c78
-rw-r--r--src/common/util.h2
-rw-r--r--src/or/config.c4
-rw-r--r--src/or/routerparse.c55
4 files changed, 107 insertions, 32 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 1f94345fc0..7e4f0a1457 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1440,8 +1440,52 @@ addr_mask_get_bits(uint32_t mask)
return -1;
}
+/** Parse a string <b>s</b> in the format of (*|port(-maxport)?)?, setting the
+ * various *out pointers as appropriate. Return 0 on success, -1 on failure.
+ */
+int
+parse_port_range(const char *port, uint16_t *port_min_out,
+ uint16_t *port_max_out)
+{
+ tor_assert(port_min_out);
+ tor_assert(port_max_out);
+
+ if (!port || *port == '\0' || strcmp(port, "*") == 0) {
+ *port_min_out = 1;
+ *port_max_out = 65535;
+ } else {
+ char *endptr = NULL;
+ *port_min_out = (uint16_t) tor_parse_long(port, 10, 1, 65535,
+ NULL, &endptr);
+ if (*endptr == '-') {
+ port = endptr+1;
+ endptr = NULL;
+ *port_max_out = (uint16_t) tor_parse_long(port, 10, 1, 65535, NULL,
+ &endptr);
+ if (*endptr || !*port_max_out) {
+ log_warn(LD_GENERAL,
+ "Malformed port \"%s\" on address range rejecting.",
+ port);
+ }
+ } else if (*endptr || !*port_min_out) {
+ log_warn(LD_GENERAL,
+ "Malformed port \"%s\" on address range; rejecting.",
+ port);
+ return -1;
+ } else {
+ *port_max_out = *port_min_out;
+ }
+ if (*port_min_out > *port_max_out) {
+ log_warn(LD_GENERAL, "Insane port range on address policy; rejecting.");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/** Parse a string <b>s</b> in the format of
- * (IP(/mask|/mask-bits)?|*):(*|port(-maxport)?), setting the various
+ * (IP(/mask|/mask-bits)?|*)(:*|port(-maxport)?)?, setting the various
* *out pointers as appropriate. Return 0 on success, -1 on failure.
*/
int
@@ -1510,36 +1554,8 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out,
}
}
- if (!port || strcmp(port, "*") == 0) {
- *port_min_out = 1;
- *port_max_out = 65535;
- } else {
- endptr = NULL;
- *port_min_out = (uint16_t) tor_parse_long(port, 10, 1, 65535,
- NULL, &endptr);
- if (*endptr == '-') {
- port = endptr+1;
- endptr = NULL;
- *port_max_out = (uint16_t) tor_parse_long(port, 10, 1, 65535, NULL,
- &endptr);
- if (*endptr || !*port_max_out) {
- log_warn(LD_GENERAL,
- "Malformed port \"%s\" on address range rejecting.",
- port);
- }
- } else if (*endptr || !*port_min_out) {
- log_warn(LD_GENERAL,
- "Malformed port \"%s\" on address range; rejecting.",
- port);
- goto err;
- } else {
- *port_max_out = *port_min_out;
- }
- if (*port_min_out > *port_max_out) {
- log_warn(LD_GENERAL, "Insane port range on address policy; rejecting.");
- goto err;
- }
- }
+ if (parse_port_range(port, port_min_out, port_max_out)<0)
+ goto err;
tor_free(address);
return 0;
diff --git a/src/common/util.h b/src/common/util.h
index 36c02164eb..64aca2392c 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -165,6 +165,8 @@ int is_internal_IP(uint32_t ip, int for_listening);
int is_local_IP(uint32_t ip);
int parse_addr_port(const char *addrport, char **address, uint32_t *addr,
uint16_t *port);
+int parse_port_range(const char *port, uint16_t *port_min_out,
+ uint16_t *port_max_out);
int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
uint32_t *mask_out, uint16_t *port_min_out,
uint16_t *port_max_out);
diff --git a/src/or/config.c b/src/or/config.c
index 08a17814a1..b97c07fb85 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -3299,7 +3299,9 @@ config_parse_addr_policy(config_line_t *cfg,
log_warn(LD_CONFIG, "Address policy element '%s' can't be expressed "
"as a bit prefix.", ent);
}
- nextp = &((*nextp)->next);
+ /* Advance nextp to the end of the policy. */
+ while (*nextp)
+ nextp = &((*nextp)->next);
} else {
log_warn(LD_CONFIG,"Malformed policy '%s'.", ent);
r = -1;
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 4bdd1ce06a..c5df489f35 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -151,6 +151,8 @@ static struct {
/* static function prototypes */
static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
static addr_policy_t *router_parse_addr_policy(directory_token_t *tok);
+static addr_policy_t *router_parse_private_addr_policy_private(
+ directory_token_t *tok);
static int router_get_hash_impl(const char *s, char *digest,
const char *start_str, const char *end_str);
static void token_free(directory_token_t *tok);
@@ -1338,6 +1340,9 @@ router_parse_addr_policy(directory_token_t *tok)
return NULL;
arg = tok->args[0];
+ if (!strcmpstart(arg,"private"))
+ return router_parse_private_addr_policy_private(tok);
+
newe = tor_malloc_zero(sizeof(addr_policy_t));
newe->string = tor_malloc(8+strlen(arg));
@@ -1370,6 +1375,56 @@ policy_read_failed:
return NULL;
}
+/** Parse an exit policy line of the format "accept/reject private:...".
+ * This didn't exist until Tor 0.1.1.15, so nobody should generate it in
+ * router descriptors until earlier versions are obsolete.
+ */
+static addr_policy_t *
+router_parse_private_addr_policy_private(directory_token_t *tok)
+{
+ /* XXXX duplicated from config.c */
+ static const char *private_nets[] = {
+ "0.0.0.0/8", "169.254.0.0/16",
+ "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",NULL };
+ char *arg;
+ addr_policy_t *result, **nextp;
+ int net;
+ uint16_t port_min, port_max;
+
+ arg = tok->args[0];
+ if (strcmpstart(arg, "private"))
+ return NULL;
+ arg += strlen("private");
+ arg = (char*) eat_whitespace(arg);
+ if (!arg || *arg != ':')
+ return NULL;
+
+ if (parse_port_range(arg+1, &port_min, &port_max)<0)
+ return NULL;
+
+ nextp = &result;
+ for (net = 0; private_nets[net]; ++net) {
+ size_t len;
+ *nextp = tor_malloc_zero(sizeof(addr_policy_t));
+ (*nextp)->policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
+ : ADDR_POLICY_ACCEPT;
+ len = strlen(arg)+strlen(private_nets[net])+16;
+ (*nextp)->string = tor_malloc(len+1);
+ tor_snprintf((*nextp)->string, len, "%s %s%s",
+ tok->tp == K_REJECT ? "reject" : "accept",
+ private_nets[net], arg);
+ if (parse_addr_and_port_range((*nextp)->string + 7,
+ &(*nextp)->addr, &(*nextp)->msk,
+ &(*nextp)->prt_min, &(*nextp)->prt_max)) {
+ log_warn(LD_BUG, "Couldn't parse an address range we generated!");
+ return NULL;
+ }
+ nextp = &(*nextp)->next;
+ }
+
+ return result;
+}
+
/** Log and exit if <b>t</b> is malformed */
void
assert_addr_policy_ok(addr_policy_t *t)