summaryrefslogtreecommitdiff
path: root/src/domain.c
diff options
context:
space:
mode:
authorElias Norberg <xyzzy@kudzu.se>2013-01-28 11:46:49 +0100
committerElias Norberg <xyzzy@kudzu.se>2013-01-28 11:46:49 +0100
commit5f0b49d6f61f2825b0f45c750e13a22637746796 (patch)
tree25aa43d649b70a7d33c5cd7a143aea494479e5b4 /src/domain.c
parent56877826f0806bb2618d15f698bf7d665cca0b5e (diff)
downloaddwb-5f0b49d6f61f2825b0f45c750e13a22637746796.zip
New function 'domain_get_tld()'
This function can identify attemtps to have domains above the allowed TLD - which can then be used to identify supercookies et.al.
Diffstat (limited to 'src/domain.c')
-rw-r--r--src/domain.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/src/domain.c b/src/domain.c
index 432396e1..9aa6f156 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2010-2013 Stefan Bolte <portix@gmx.net>
+ * Copyright (c) 2013 Elias Norberg <xyzzy@kudzu.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -124,8 +125,22 @@ domain_match(char **domains, const char *host, const char *base_domain)
return false;
}/*}}}*/
+int
+count_char(const char *str, char ch)
+{
+ int count = 0;
+
+ if (str == NULL)
+ return 0;
+
+ for (; *str != '\0'; str++)
+ if (*str == ch)
+ count ++;
+ return count;
+}
+
const char *
-domain_get_base_for_host(const char *host)
+domain_get_tld(const char *host)
{
if (host == NULL)
return NULL;
@@ -138,6 +153,17 @@ domain_get_base_for_host(const char *host)
char *nextdot = strchr(cur_domain, '.');
char *entry = NULL;
+ /* check if hostname is valid
+ * - cannot start with .
+ * - must only contain A-Za-z0-9.-_
+ */
+ if (nextdot == cur_domain ||
+ strspn(cur_domain, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrustuvwxyz"
+ "0123456789._-") != strlen(cur_domain)) {
+ return NULL;
+ }
+
while (1)
{
entry = g_hash_table_lookup(s_tld_table, cur_domain);
@@ -145,15 +171,23 @@ domain_get_base_for_host(const char *host)
{
if (*entry == '*')
{
- ret = pprev_domain;
+ /* check that we have enough to build
+ * a domain that satisfies the rule
+ */
+ if (count_char(pprev_domain, '.') >=
+ count_char(entry, '.') + 1) {
+ ret = pprev_domain;
+ }
break;
}
- else if (*entry == '!' && nextdot)
+ else if (*entry == '!')
{
- ret = nextdot + 1;
+ ret = cur_domain;
break;
}
- else
+ else if(strcmp(entry, prev_domain) == 0)
+ break;
+ else if(strcmp(entry, prev_domain) != 0)
{
ret = prev_domain;
break;
@@ -170,10 +204,20 @@ domain_get_base_for_host(const char *host)
nextdot = strchr(cur_domain, '.');
}
- if (ret == NULL)
- ret = host;
return ret;
}
+
+
+const char *
+domain_get_base_for_host(const char *host)
+{
+ const char *base;
+ base = domain_get_tld(host);
+ if (base == NULL)
+ return host;
+ return base;
+}
+
void
domain_end()
{