Add option to allow wildcard as start of topdomain

This commit is contained in:
Erik Ekman 2021-08-24 23:32:57 +02:00
parent f09dadb1ed
commit 589027568b
5 changed files with 71 additions and 25 deletions

View file

@ -332,7 +332,7 @@ read_password(char *buf, size_t len)
} }
int int
check_topdomain(char *str, char **errormsg) check_topdomain(char *str, int allow_wildcard, char **errormsg)
{ {
int i; int i;
int dots = 0; int dots = 0;
@ -370,6 +370,18 @@ check_topdomain(char *str, char **errormsg)
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') ||
isdigit(str[i]) || str[i] == '-' || str[i] == '.') { isdigit(str[i]) || str[i] == '-' || str[i] == '.') {
continue; continue;
} else if (allow_wildcard && str[i] == '*') {
/* First char allowed to be wildcard, if followed by dot */
if (i == 0) {
if (str[i+1] == '.') {
continue;
}
if (errormsg) *errormsg = "Wildcard (*) must be followed by dot";
return 1;
} else {
if (errormsg) *errormsg = "Wildcard (*) only allowed as first char";
return 1;
}
} else { } else {
if (errormsg) *errormsg = "Contains illegal character (allowed: [a-zA-Z0-9-.])"; if (errormsg) *errormsg = "Contains illegal character (allowed: [a-zA-Z0-9-.])";
return 1; return 1;

View file

@ -126,7 +126,7 @@ void do_pidfile(char *);
void read_password(char*, size_t); void read_password(char*, size_t);
int check_topdomain(char *, char **); int check_topdomain(char *, int, char **);
#if defined(WINDOWS32) || defined(ANDROID) #if defined(WINDOWS32) || defined(ANDROID)
#ifndef ANDROID #ifndef ANDROID

View file

@ -317,7 +317,7 @@ int main(int argc, char **argv)
/* NOTREACHED */ /* NOTREACHED */
} }
if (check_topdomain(topdomain, &errormsg)) { if (check_topdomain(topdomain, 0, &errormsg)) {
warnx("Invalid topdomain: %s", errormsg); warnx("Invalid topdomain: %s", errormsg);
usage(); usage();
/* NOTREACHED */ /* NOTREACHED */

View file

@ -2543,7 +2543,7 @@ main(int argc, char **argv)
} }
topdomain = strdup(argv[1]); topdomain = strdup(argv[1]);
if (check_topdomain(topdomain, &errormsg)) { if (check_topdomain(topdomain, 0, &errormsg)) {
warnx("Invalid topdomain: %s", errormsg); warnx("Invalid topdomain: %s", errormsg);
usage(); usage();
/* NOTREACHED */ /* NOTREACHED */

View file

@ -25,15 +25,18 @@ START_TEST(test_topdomain_ok)
{ {
char *error = NULL; char *error = NULL;
ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error) == 0); ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error) == 0);
ck_assert(error == NULL);
/* Allowing wildcard */
ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 1, &error) == 0);
ck_assert(error == NULL); ck_assert(error == NULL);
/* Not allowed to start with dot */ /* Not allowed to start with dot */
ck_assert(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error)); ck_assert(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error));
ck_assert_str_eq("Starts with a dot", error); ck_assert_str_eq("Starts with a dot", error);
/* Test missing error msg ptr */ /* Test missing error msg ptr */
ck_assert(check_topdomain(".foo", NULL)); ck_assert(check_topdomain(".foo", 0, NULL));
} }
END_TEST END_TEST
@ -42,33 +45,33 @@ START_TEST(test_topdomain_length)
char *error; char *error;
/* Test empty and too short */ /* Test empty and too short */
ck_assert(check_topdomain("", &error)); ck_assert(check_topdomain("", 0, &error));
ck_assert_str_eq("Too short (< 3)", error); ck_assert_str_eq("Too short (< 3)", error);
error = NULL; error = NULL;
ck_assert(check_topdomain("a", &error)); ck_assert(check_topdomain("a", 0, &error));
ck_assert_str_eq("Too short (< 3)", error); ck_assert_str_eq("Too short (< 3)", error);
error = NULL; error = NULL;
ck_assert(check_topdomain(".a", &error)); ck_assert(check_topdomain(".a", 0, &error));
ck_assert_str_eq("Too short (< 3)", error); ck_assert_str_eq("Too short (< 3)", error);
error = NULL; error = NULL;
ck_assert(check_topdomain("a.", &error)); ck_assert(check_topdomain("a.", 0, &error));
ck_assert_str_eq("Too short (< 3)", error); ck_assert_str_eq("Too short (< 3)", error);
error = NULL; error = NULL;
ck_assert(check_topdomain("ab", &error)); ck_assert(check_topdomain("ab", 0, &error));
ck_assert_str_eq("Too short (< 3)", error); ck_assert_str_eq("Too short (< 3)", error);
error = NULL; error = NULL;
ck_assert(check_topdomain("a.b", &error) == 0); ck_assert(check_topdomain("a.b", 0, &error) == 0);
/* Test too long (over 128, need rest of space for data) */ /* Test too long (over 128, need rest of space for data) */
ck_assert(check_topdomain( ck_assert(check_topdomain(
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.foo129xxx", &error)); "abcd12345.abcd12345.foo129xxx", 0, &error));
ck_assert_str_eq("Too long (> 128)", error); ck_assert_str_eq("Too long (> 128)", error);
ck_assert(check_topdomain( ck_assert(check_topdomain(
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.foo128xx", &error) == 0); "abcd12345.abcd12345.foo128xx", 0, &error) == 0);
} }
END_TEST END_TEST
@ -77,39 +80,69 @@ START_TEST(test_topdomain_chunks)
char *error; char *error;
/* Must have at least one dot */ /* Must have at least one dot */
ck_assert(check_topdomain("abcde.gh", &error) == 0); ck_assert(check_topdomain("abcde.gh", 0, &error) == 0);
ck_assert(check_topdomain("abcdefgh", &error)); ck_assert(check_topdomain("abcdefgh", 0, &error));
ck_assert_str_eq("No dots", error); ck_assert_str_eq("No dots", error);
/* Not two consecutive dots */ /* Not two consecutive dots */
ck_assert(check_topdomain("abc..defgh", &error)); ck_assert(check_topdomain("abc..defgh", 0, &error));
ck_assert_str_eq("Consecutive dots", error); ck_assert_str_eq("Consecutive dots", error);
/* Not end with a dots */ /* Not end with a dots */
ck_assert(check_topdomain("abc.defgh.", &error)); ck_assert(check_topdomain("abc.defgh.", 0, &error));
ck_assert_str_eq("Ends with a dot", error); ck_assert_str_eq("Ends with a dot", error);
/* No chunk longer than 63 chars */ /* No chunk longer than 63 chars */
ck_assert(check_topdomain("123456789012345678901234567890" ck_assert(check_topdomain("123456789012345678901234567890"
"123456789012345678901234567890333.com", &error) == 0); "123456789012345678901234567890333.com", 0, &error) == 0);
ck_assert(check_topdomain("123456789012345678901234567890" ck_assert(check_topdomain("123456789012345678901234567890"
"1234567890123456789012345678904444.com", &error)); "1234567890123456789012345678904444.com", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error); ck_assert_str_eq("Too long domain part (> 63)", error);
ck_assert(check_topdomain("abc.123456789012345678901234567890" ck_assert(check_topdomain("abc.123456789012345678901234567890"
"123456789012345678901234567890333.com", &error) == 0); "123456789012345678901234567890333.com", 0, &error) == 0);
ck_assert(check_topdomain("abc.123456789012345678901234567890" ck_assert(check_topdomain("abc.123456789012345678901234567890"
"1234567890123456789012345678904444.com", &error)); "1234567890123456789012345678904444.com", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error); ck_assert_str_eq("Too long domain part (> 63)", error);
ck_assert(check_topdomain("abc.123456789012345678901234567890" ck_assert(check_topdomain("abc.123456789012345678901234567890"
"123456789012345678901234567890333", &error) == 0); "123456789012345678901234567890333", 0, &error) == 0);
ck_assert(check_topdomain("abc.123456789012345678901234567890" ck_assert(check_topdomain("abc.123456789012345678901234567890"
"1234567890123456789012345678904444", &error)); "1234567890123456789012345678904444", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error); ck_assert_str_eq("Too long domain part (> 63)", error);
} }
END_TEST END_TEST
START_TEST(test_topdomain_wild)
{
char *error = NULL;
ck_assert(check_topdomain("*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*.a", 1, &error) == 0);
ck_assert(error == NULL);
ck_assert(check_topdomain("b*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("b*.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
ck_assert(check_topdomain("*b.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*b.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) must be followed by dot", error);
ck_assert(check_topdomain("*.*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*.*.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
}
END_TEST
START_TEST(test_parse_format_ipv4) START_TEST(test_parse_format_ipv4)
{ {
char *host = "192.168.2.10"; char *host = "192.168.2.10";
@ -211,6 +244,7 @@ test_common_create_tests()
tcase_add_test(tc, test_topdomain_ok); tcase_add_test(tc, test_topdomain_ok);
tcase_add_test(tc, test_topdomain_length); tcase_add_test(tc, test_topdomain_length);
tcase_add_test(tc, test_topdomain_chunks); tcase_add_test(tc, test_topdomain_chunks);
tcase_add_test(tc, test_topdomain_wild);
tcase_add_test(tc, test_parse_format_ipv4); tcase_add_test(tc, test_parse_format_ipv4);
tcase_add_test(tc, test_parse_format_ipv4_listen_all); tcase_add_test(tc, test_parse_format_ipv4_listen_all);