diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-03-28 07:50:47 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-03-28 07:50:47 -0400 |
commit | 6317aa2cc03a3b7a6f9fd4a4bdd99447f7914493 (patch) | |
tree | 9be2e06a8f24eca26924fcfaa33edfc474782332 /src/common/util.c | |
parent | fa6eaab83e05a11b60735f7bf4064b05e7085230 (diff) | |
parent | d416e208e4e94c2b4ccd4e11013151c72180faff (diff) | |
download | tor-6317aa2cc03a3b7a6f9fd4a4bdd99447f7914493.tar.gz tor-6317aa2cc03a3b7a6f9fd4a4bdd99447f7914493.zip |
Merge branch 'maint-0.3.3'
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/src/common/util.c b/src/common/util.c index 83a35e3c06..f63b121672 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1071,6 +1071,36 @@ string_is_valid_ipv6_address(const char *string) 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. * @@ -1078,37 +1108,51 @@ string_is_valid_ipv6_address(const char *string) * with misconfigured zones that have been encountered in the wild. */ int -string_is_valid_hostname(const char *string) +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; } - /* Allow a single terminating '.' used rarely to indicate domains - * are FQDNs rather than relative. */ - if ((c_sl_idx > 0) && (c_sl_idx + 1 == c_sl_len) && !*c) { - continue; - } - do { - if ((*c >= 'a' && *c <= 'z') || - (*c >= 'A' && *c <= 'Z') || - (*c >= '0' && *c <= '9') || - (*c == '-') || (*c == '_')) - c++; - else - result = 0; + result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_')); + c++; } while (result && *c); + if (result == 0) { + break; + } } SMARTLIST_FOREACH_END(c); SMARTLIST_FOREACH_BEGIN(components, char *, c) { |