policy_parse.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file policy_parse.c
  8. * \brief Code to parse address policies.
  9. **/
  10. #define EXPOSE_ROUTERDESC_TOKEN_TABLE
  11. #include "core/or/or.h"
  12. #include "core/or/policies.h"
  13. #include "feature/dirparse/parsecommon.h"
  14. #include "feature/dirparse/policy_parse.h"
  15. #include "feature/dirparse/routerparse.h"
  16. #include "feature/dirparse/unparseable.h"
  17. #include "lib/memarea/memarea.h"
  18. #include "core/or/addr_policy_st.h"
  19. static addr_policy_t *router_parse_addr_policy_private(directory_token_t *tok);
  20. /** Parse the addr policy in the string <b>s</b> and return it. If
  21. * assume_action is nonnegative, then insert its action (ADDR_POLICY_ACCEPT or
  22. * ADDR_POLICY_REJECT) for items that specify no action.
  23. *
  24. * Returns NULL on policy errors.
  25. *
  26. * Set *<b>malformed_list</b> to true if the entire policy list should be
  27. * discarded. Otherwise, set it to false, and only this item should be ignored
  28. * on error - the rest of the policy list can continue to be processed and
  29. * used.
  30. *
  31. * The addr_policy_t returned by this function can have its address set to
  32. * AF_UNSPEC for '*'. Use policy_expand_unspec() to turn this into a pair
  33. * of AF_INET and AF_INET6 items.
  34. */
  35. MOCK_IMPL(addr_policy_t *,
  36. router_parse_addr_policy_item_from_string,(const char *s, int assume_action,
  37. int *malformed_list))
  38. {
  39. directory_token_t *tok = NULL;
  40. const char *cp, *eos;
  41. /* Longest possible policy is
  42. * "accept6 [ffff:ffff:..255]/128:10000-65535",
  43. * which contains a max-length IPv6 address, plus 26 characters.
  44. * But note that there can be an arbitrary amount of space between the
  45. * accept and the address:mask/port element.
  46. * We don't need to multiply TOR_ADDR_BUF_LEN by 2, as there is only one
  47. * IPv6 address. But making the buffer shorter might cause valid long lines,
  48. * which parsed in previous versions, to fail to parse in new versions.
  49. * (These lines would have to have excessive amounts of whitespace.) */
  50. char line[TOR_ADDR_BUF_LEN*2 + 32];
  51. addr_policy_t *r;
  52. memarea_t *area = NULL;
  53. tor_assert(malformed_list);
  54. *malformed_list = 0;
  55. s = eat_whitespace(s);
  56. /* We can only do assume_action on []-quoted IPv6, as "a" (accept)
  57. * and ":" (port separator) are ambiguous */
  58. if ((*s == '*' || *s == '[' || TOR_ISDIGIT(*s)) && assume_action >= 0) {
  59. if (tor_snprintf(line, sizeof(line), "%s %s",
  60. assume_action == ADDR_POLICY_ACCEPT?"accept":"reject", s)<0) {
  61. log_warn(LD_DIR, "Policy %s is too long.", escaped(s));
  62. return NULL;
  63. }
  64. cp = line;
  65. tor_strlower(line);
  66. } else { /* assume an already well-formed address policy line */
  67. cp = s;
  68. }
  69. eos = cp + strlen(cp);
  70. area = memarea_new();
  71. tok = get_next_token(area, &cp, eos, routerdesc_token_table);
  72. if (tok->tp == ERR_) {
  73. log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
  74. goto err;
  75. }
  76. if (tok->tp != K_ACCEPT && tok->tp != K_ACCEPT6 &&
  77. tok->tp != K_REJECT && tok->tp != K_REJECT6) {
  78. log_warn(LD_DIR, "Expected 'accept' or 'reject'.");
  79. goto err;
  80. }
  81. /* Use the extended interpretation of accept/reject *,
  82. * expanding it into an IPv4 wildcard and an IPv6 wildcard.
  83. * Also permit *4 and *6 for IPv4 and IPv6 only wildcards. */
  84. r = router_parse_addr_policy(tok, TAPMP_EXTENDED_STAR);
  85. if (!r) {
  86. goto err;
  87. }
  88. /* Ensure that accept6/reject6 fields are followed by IPv6 addresses.
  89. * AF_UNSPEC addresses are only permitted on the accept/reject field type.
  90. * Unlike descriptors, torrcs exit policy accept/reject can be followed by
  91. * either an IPv4 or IPv6 address. */
  92. if ((tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) &&
  93. tor_addr_family(&r->addr) != AF_INET6) {
  94. /* This is a non-fatal error, just ignore this one entry. */
  95. *malformed_list = 0;
  96. log_warn(LD_DIR, "IPv4 address '%s' with accept6/reject6 field type in "
  97. "exit policy. Ignoring, but continuing to parse rules. (Use "
  98. "accept/reject with IPv4 addresses.)",
  99. tok->n_args == 1 ? tok->args[0] : "");
  100. addr_policy_free(r);
  101. r = NULL;
  102. goto done;
  103. }
  104. goto done;
  105. err:
  106. *malformed_list = 1;
  107. r = NULL;
  108. done:
  109. token_clear(tok);
  110. if (area) {
  111. DUMP_AREA(area, "policy item");
  112. memarea_drop_all(area);
  113. }
  114. return r;
  115. }
  116. /** Given a K_ACCEPT[6] or K_REJECT[6] token and a router, create and return
  117. * a new exit_policy_t corresponding to the token. If TAPMP_EXTENDED_STAR
  118. * is set in fmt_flags, K_ACCEPT6 and K_REJECT6 tokens followed by *
  119. * expand to IPv6-only policies, otherwise they expand to IPv4 and IPv6
  120. * policies */
  121. addr_policy_t *
  122. router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags)
  123. {
  124. addr_policy_t newe;
  125. char *arg;
  126. tor_assert(tok->tp == K_REJECT || tok->tp == K_REJECT6 ||
  127. tok->tp == K_ACCEPT || tok->tp == K_ACCEPT6);
  128. if (tok->n_args != 1)
  129. return NULL;
  130. arg = tok->args[0];
  131. if (!strcmpstart(arg,"private"))
  132. return router_parse_addr_policy_private(tok);
  133. memset(&newe, 0, sizeof(newe));
  134. if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
  135. newe.policy_type = ADDR_POLICY_REJECT;
  136. else
  137. newe.policy_type = ADDR_POLICY_ACCEPT;
  138. /* accept6/reject6 * produces an IPv6 wildcard address only.
  139. * (accept/reject * produces rules for IPv4 and IPv6 wildcard addresses.) */
  140. if ((fmt_flags & TAPMP_EXTENDED_STAR)
  141. && (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6)) {
  142. fmt_flags |= TAPMP_STAR_IPV6_ONLY;
  143. }
  144. if (tor_addr_parse_mask_ports(arg, fmt_flags, &newe.addr, &newe.maskbits,
  145. &newe.prt_min, &newe.prt_max) < 0) {
  146. log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
  147. return NULL;
  148. }
  149. addr_policy_t *result = addr_policy_get_canonical_entry(&newe);
  150. /* It would be a nasty error to return 'newe', and sometimes
  151. * addr_policy_get_canonical_entry() can return its argument. But in this
  152. * case, it won't, since newe is *not* canonical. We assert here to make
  153. * sure that the compiler knows it too.
  154. */
  155. tor_assert(result != &newe);
  156. return result;
  157. }
  158. /** Parse an exit policy line of the format "accept[6]/reject[6] private:...".
  159. * This didn't exist until Tor 0.1.1.15, so nobody should generate it in
  160. * router descriptors until earlier versions are obsolete.
  161. *
  162. * accept/reject and accept6/reject6 private all produce rules for both
  163. * IPv4 and IPv6 addresses.
  164. */
  165. static addr_policy_t *
  166. router_parse_addr_policy_private(directory_token_t *tok)
  167. {
  168. const char *arg;
  169. uint16_t port_min, port_max;
  170. addr_policy_t result;
  171. arg = tok->args[0];
  172. if (strcmpstart(arg, "private"))
  173. return NULL;
  174. arg += strlen("private");
  175. arg = (char*) eat_whitespace(arg);
  176. if (!arg || *arg != ':')
  177. return NULL;
  178. if (parse_port_range(arg+1, &port_min, &port_max)<0)
  179. return NULL;
  180. memset(&result, 0, sizeof(result));
  181. if (tok->tp == K_REJECT || tok->tp == K_REJECT6)
  182. result.policy_type = ADDR_POLICY_REJECT;
  183. else
  184. result.policy_type = ADDR_POLICY_ACCEPT;
  185. result.is_private = 1;
  186. result.prt_min = port_min;
  187. result.prt_max = port_max;
  188. if (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) {
  189. log_warn(LD_GENERAL,
  190. "'%s' expands into rules which apply to all private IPv4 and "
  191. "IPv6 addresses. (Use accept/reject private:* for IPv4 and "
  192. "IPv6.)", tok->n_args == 1 ? tok->args[0] : "");
  193. }
  194. return addr_policy_get_canonical_entry(&result);
  195. }