commit 3cff3e825a1478fc3350bbca16f091b8f635f921 Author: Nick Mathewson nickm@torproject.org Date: Wed Jun 27 15:45:53 2018 -0400
Move several address-string-testing functions to address.c --- src/common/util.c | 115 -------------------------------------------------- src/common/util.h | 4 -- src/lib/net/address.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/net/address.h | 5 +++ 4 files changed, 120 insertions(+), 119 deletions(-)
diff --git a/src/common/util.c b/src/common/util.c index 64efbc81e..497f54972 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -273,121 +273,6 @@ string_is_key_value(int severity, const char *string) return 1; }
-/** Return true if <b>string</b> represents a valid IPv4 adddress in - * 'a.b.c.d' form. - */ -int -string_is_valid_ipv4_address(const char *string) -{ - struct in_addr addr; - - return (tor_inet_pton(AF_INET,string,&addr) == 1); -} - -/** Return true if <b>string</b> represents a valid IPv6 address in - * a form that inet_pton() can parse. - */ -int -string_is_valid_ipv6_address(const char *string) -{ - struct in6_addr addr; - - return (tor_inet_pton(AF_INET6,string,&addr) == 1); -} - -/** Return true iff <b>string</b> is a valid destination address, - * i.e. either a DNS hostname or IPv4/IPv6 address string. - */ -int -string_is_valid_dest(const char *string) -{ - char *tmp = NULL; - int retval; - size_t len; - - if (string == NULL) - return 0; - - len = strlen(string); - - if (len == 0) - return 0; - - if (string[0] == '[' && string[len - 1] == ']') - string = tmp = tor_strndup(string + 1, len - 2); - - retval = string_is_valid_ipv4_address(string) || - string_is_valid_ipv6_address(string) || - string_is_valid_nonrfc_hostname(string); - - tor_free(tmp); - - return retval; -} - -/** Return true iff <b>string</b> matches a pattern of DNS names - * that we allow Tor clients to connect to. - * - * Note: This allows certain technically invalid characters ('_') to cope - * with misconfigured zones that have been encountered in the wild. - */ -int -string_is_valid_nonrfc_hostname(const char *string) -{ - int result = 1; - int has_trailing_dot; - char *last_label; - smartlist_t *components; - - if (!string || strlen(string) == 0) - return 0; - - if (string_is_valid_ipv4_address(string)) - return 0; - - components = smartlist_new(); - - smartlist_split_string(components,string,".",0,0); - - if (BUG(smartlist_len(components) == 0)) - return 0; // LCOV_EXCL_LINE should be impossible given the earlier checks. - - /* Allow a single terminating '.' used rarely to indicate domains - * are FQDNs rather than relative. */ - last_label = (char *)smartlist_get(components, - smartlist_len(components) - 1); - has_trailing_dot = (last_label[0] == '\0'); - if (has_trailing_dot) { - smartlist_pop_last(components); - tor_free(last_label); - last_label = NULL; - } - - SMARTLIST_FOREACH_BEGIN(components, char *, c) { - if ((c[0] == '-') || (*c == '_')) { - result = 0; - break; - } - - do { - result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_')); - c++; - } while (result && *c); - - if (result == 0) { - break; - } - } SMARTLIST_FOREACH_END(c); - - SMARTLIST_FOREACH_BEGIN(components, char *, c) { - tor_free(c); - } SMARTLIST_FOREACH_END(c); - - smartlist_free(components); - - return result; -} - /** Return a newly allocated string equal to <b>string</b>, except that every * character in <b>chars_to_escape</b> is preceded by a backslash. */ char * diff --git a/src/common/util.h b/src/common/util.h index f16a1fa98..fa7886d0f 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -73,10 +73,6 @@ int64_t clamp_double_to_int64(double number); const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
int string_is_key_value(int severity, const char *string); -int string_is_valid_dest(const char *string); -int string_is_valid_nonrfc_hostname(const char *string); -int string_is_valid_ipv4_address(const char *string); -int string_is_valid_ipv6_address(const char *string);
char *tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape); diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 69abb98a1..10e38871e 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -2139,3 +2139,118 @@ tor_addr_port_eq(const tor_addr_port_t *a, { return tor_addr_eq(&a->addr, &b->addr) && a->port == b->port; } + +/** Return true if <b>string</b> represents a valid IPv4 adddress in + * 'a.b.c.d' form. + */ +int +string_is_valid_ipv4_address(const char *string) +{ + struct in_addr addr; + + return (tor_inet_pton(AF_INET,string,&addr) == 1); +} + +/** Return true if <b>string</b> represents a valid IPv6 address in + * a form that inet_pton() can parse. + */ +int +string_is_valid_ipv6_address(const char *string) +{ + struct in6_addr addr; + + return (tor_inet_pton(AF_INET6,string,&addr) == 1); +} + +/** Return true iff <b>string</b> is a valid destination address, + * i.e. either a DNS hostname or IPv4/IPv6 address string. + */ +int +string_is_valid_dest(const char *string) +{ + char *tmp = NULL; + int retval; + size_t len; + + if (string == NULL) + return 0; + + len = strlen(string); + + if (len == 0) + return 0; + + if (string[0] == '[' && string[len - 1] == ']') + string = tmp = tor_strndup(string + 1, len - 2); + + retval = string_is_valid_ipv4_address(string) || + string_is_valid_ipv6_address(string) || + string_is_valid_nonrfc_hostname(string); + + tor_free(tmp); + + return retval; +} + +/** Return true iff <b>string</b> matches a pattern of DNS names + * that we allow Tor clients to connect to. + * + * Note: This allows certain technically invalid characters ('_') to cope + * with misconfigured zones that have been encountered in the wild. + */ +int +string_is_valid_nonrfc_hostname(const char *string) +{ + int result = 1; + int has_trailing_dot; + char *last_label; + smartlist_t *components; + + if (!string || strlen(string) == 0) + return 0; + + if (string_is_valid_ipv4_address(string)) + return 0; + + components = smartlist_new(); + + smartlist_split_string(components,string,".",0,0); + + if (BUG(smartlist_len(components) == 0)) + return 0; // LCOV_EXCL_LINE should be impossible given the earlier checks. + + /* Allow a single terminating '.' used rarely to indicate domains + * are FQDNs rather than relative. */ + last_label = (char *)smartlist_get(components, + smartlist_len(components) - 1); + has_trailing_dot = (last_label[0] == '\0'); + if (has_trailing_dot) { + smartlist_pop_last(components); + tor_free(last_label); + last_label = NULL; + } + + SMARTLIST_FOREACH_BEGIN(components, char *, c) { + if ((c[0] == '-') || (*c == '_')) { + result = 0; + break; + } + + do { + result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_')); + c++; + } while (result && *c); + + if (result == 0) { + break; + } + } SMARTLIST_FOREACH_END(c); + + SMARTLIST_FOREACH_BEGIN(components, char *, c) { + tor_free(c); + } SMARTLIST_FOREACH_END(c); + + smartlist_free(components); + + return result; +} diff --git a/src/lib/net/address.h b/src/lib/net/address.h index 78b798755..f8ea573c3 100644 --- a/src/lib/net/address.h +++ b/src/lib/net/address.h @@ -357,6 +357,11 @@ tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port); int tor_addr_port_eq(const tor_addr_port_t *a, const tor_addr_port_t *b);
+int string_is_valid_dest(const char *string); +int string_is_valid_nonrfc_hostname(const char *string); +int string_is_valid_ipv4_address(const char *string); +int string_is_valid_ipv6_address(const char *string); + #ifdef ADDRESS_PRIVATE MOCK_DECL(struct smartlist_t *,get_interface_addresses_raw,(int severity, sa_family_t family));