diff options
author | rl1987 <rl1987@sdf.lonestar.org> | 2018-02-17 21:49:02 +0100 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-03-28 07:39:03 -0400 |
commit | dbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3 (patch) | |
tree | 1b990be96b52e6e7f5a38685a35a2ca60d68e460 /src | |
parent | 4413e52f9e2e3898f870df481aea93b1ea5fd836 (diff) | |
download | tor-dbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3.tar.gz tor-dbb7c8e6fd757db51226a47a2e14f4fd1aaf60c3.zip |
Validate hostnames with punycode TLDs correctly
Diffstat (limited to 'src')
-rw-r--r-- | src/common/util.c | 17 | ||||
-rw-r--r-- | src/test/test_util.c | 4 |
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; } |