소스 검색

Introducing helper function to validate DNS name strings.

rl1987 9 년 전
부모
커밋
1ea9a6fd72
3개의 변경된 파일68개의 추가작업 그리고 0개의 파일을 삭제
  1. 36 0
      src/common/util.c
  2. 1 0
      src/common/util.h
  3. 31 0
      src/test/test_util.c

+ 36 - 0
src/common/util.c

@@ -957,6 +957,42 @@ string_is_key_value(int severity, const char *string)
   return 1;
 }
 
+/** Return true iff <b>string</b> is valid DNS name, as defined in
+ * RFC 1035 Section 2.3.1.
+ */
+int
+string_is_valid_hostname(const char *string)
+{
+   int result = 1;
+   smartlist_t *components;
+
+   components = smartlist_new();
+
+   smartlist_split_string(components,string,".",0,0);
+
+   SMARTLIST_FOREACH_BEGIN(components, char *, c) {
+     if (c[0] == '-') {
+       result = 0;
+       break;
+     }
+
+     do {
+       if ((*c >= 'a' && *c <= 'z') ||
+           (*c >= 'A' && *c <= 'Z') ||
+           (*c >= '0' && *c <= '9') ||
+           (*c == '-'))
+         c++;
+       else
+         result = 0;
+     } while (result && *c);
+
+   } SMARTLIST_FOREACH_END(c);
+
+   smartlist_free(components);
+
+   return result;
+}
+
 /** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
 int
 tor_digest256_is_zero(const char *digest)

+ 1 - 0
src/common/util.h

@@ -227,6 +227,7 @@ const char *find_str_at_start_of_line(const char *haystack,
                                       const char *needle);
 int string_is_C_identifier(const char *string);
 int string_is_key_value(int severity, const char *string);
+int string_is_valid_hostname(const char *string);
 
 int tor_mem_is_zero(const char *mem, size_t len);
 int tor_digest_is_zero(const char *digest);

+ 31 - 0
src/test/test_util.c

@@ -4122,6 +4122,36 @@ test_util_max_mem(void *arg)
   ;
 }
 
+static void
+test_util_hostname_validation(void *arg)
+{
+  (void)arg;
+
+  // Lets try valid hostnames first.
+  tt_assert(string_is_valid_hostname("torproject.org"));
+  tt_assert(string_is_valid_hostname("ocw.mit.edu"));
+  tt_assert(string_is_valid_hostname("i.4cdn.org"));
+  tt_assert(string_is_valid_hostname("stanford.edu"));
+  tt_assert(string_is_valid_hostname("multiple-words-with-hypens.jp"));
+
+  // Subdomain name cannot start with '-'.
+  tt_assert(!string_is_valid_hostname("-torproject.org"));
+  tt_assert(!string_is_valid_hostname("subdomain.-domain.org"));
+  tt_assert(!string_is_valid_hostname("-subdomain.domain.org"));
+  
+  // Hostnames cannot contain non-alphanumeric characters.
+  tt_assert(!string_is_valid_hostname("%%domain.\\org."));  
+  tt_assert(!string_is_valid_hostname("***x.net"));
+  tt_assert(!string_is_valid_hostname("___abc.org"));
+  tt_assert(!string_is_valid_hostname("\xff\xffxyz.org"));
+  tt_assert(!string_is_valid_hostname("word1 word2.net"));
+
+  // XXX: do we allow single-label DNS names?
+
+  done:
+  return;
+}
+
 struct testcase_t util_tests[] = {
   UTIL_LEGACY(time),
   UTIL_TEST(parse_http_time, 0),
@@ -4194,6 +4224,7 @@ struct testcase_t util_tests[] = {
   { "socketpair_ersatz", test_util_socketpair, TT_FORK,
     &socketpair_setup, (void*)"1" },
   UTIL_TEST(max_mem, 0),
+  UTIL_TEST(hostname_validation, 0),
   END_OF_TESTCASES
 };