summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrl1987 <rl1987@sdf.lonestar.org>2018-02-17 21:49:02 +0100
committerNick Mathewson <nickm@torproject.org>2018-03-28 07:39:03 -0400
commitdbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3 (patch)
tree1b990be96b52e6e7f5a38685a35a2ca60d68e460
parent4413e52f9e2e3898f870df481aea93b1ea5fd836 (diff)
downloadtor-dbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3.tar.gz
tor-dbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3.zip
Validate hostnames with punycode TLDs correctly
-rw-r--r--src/common/util.c17
-rw-r--r--src/test/test_util.c4
2 files changed, 17 insertions, 4 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 096188cfcf..a55f7a3cd5 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1119,7 +1119,8 @@ string_is_valid_hostname(const char *string)
/* Allow a single terminating '.' used rarely to indicate domains
* are FQDNs rather than relative. */
- last_label = (char *)smartlist_get(components, smartlist_len(components) - 1);
+ 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);
@@ -1133,12 +1134,20 @@ string_is_valid_hostname(const char *string)
break;
}
- if (c_sl_idx == c_sl_len - 1) {
+ if (c_sl_idx == c_sl_len - 1) { // TLD validation.
+ int is_punycode = (strlen(c) > 4 &&
+ (c[0] == 'X' || c[0] == 'x') &&
+ (c[1] == 'N' || c[1] == 'n') &&
+ c[2] == '-' && c[3] == '-');
+
+ if (is_punycode)
+ c += 4;
+
do {
- result = TOR_ISALPHA(*c);
+ result = is_punycode ? TOR_ISALNUM(*c) : TOR_ISALPHA(*c);
c++;
} while (result && *c);
- } else {
+ } else { // Regular hostname label validation.
do {
result = (TOR_ISALNUM(*c) || (*c == '-') || (*c == '_'));
c++;
diff --git a/src/test/test_util.c b/src/test/test_util.c
index db2ea1a348..ef1f420fe3 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -5595,6 +5595,10 @@ test_util_hostname_validation(void *arg)
tt_assert(!string_is_valid_hostname("luck.y13"));
tt_assert(!string_is_valid_hostname("luck.y13."));
+ // We allow punycode TLDs. For examples, see
+ // http://data.iana.org/TLD/tlds-alpha-by-domain.txt
+ tt_assert(string_is_valid_hostname("example.xn--l1acc"));
+
done:
return;
}