summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-03-28 07:50:47 -0400
committerNick Mathewson <nickm@torproject.org>2018-03-28 07:50:47 -0400
commit6317aa2cc03a3b7a6f9fd4a4bdd99447f7914493 (patch)
tree9be2e06a8f24eca26924fcfaa33edfc474782332 /src/common/util.c
parentfa6eaab83e05a11b60735f7bf4064b05e7085230 (diff)
parentd416e208e4e94c2b4ccd4e11013151c72180faff (diff)
downloadtor-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.c72
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) {