Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add whitelist option #305

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Usage: goodbyedpi.exe [OPTION...]
--blacklist <txtfile> perform circumvention tricks only to host names and subdomains from
supplied text file (HTTP Host/TLS SNI).
This option can be supplied multiple times.
--whitelist <txtfile> does not perform circumvention tricks to host names and subdomains from
supplied text file.
This option can be supplied multiple times.
--allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.
--set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
Expand Down
43 changes: 30 additions & 13 deletions src/blackwhitelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ typedef struct blackwhitelist_record {
UT_hash_handle hh; /* makes this structure hashable */
} blackwhitelist_record_t;

static blackwhitelist_record_t *blackwhitelist = NULL;
static blackwhitelist_record_t *blacklist = NULL;
static blackwhitelist_record_t *whitelist = NULL;

static int check_get_hostname(const char *host) {
static int check_get_hostname(const char *host, blackwhitelist_record_t **list) {
blackwhitelist_record_t *tmp_record = NULL;
if (!blackwhitelist) return FALSE;
if (!*list) return FALSE;

HASH_FIND_STR(blackwhitelist, host, tmp_record);
HASH_FIND_STR(*list, host, tmp_record);
if (tmp_record) {
debug("check_get_hostname found host\n");
return TRUE;
Expand All @@ -31,17 +32,17 @@ static int check_get_hostname(const char *host) {
return FALSE;
}

static int add_hostname(const char *host) {
static int add_hostname(const char *host, blackwhitelist_record_t **list) {
if (!host)
return FALSE;

blackwhitelist_record_t *tmp_record = malloc(sizeof(blackwhitelist_record_t));
char *host_c = NULL;

if (!check_get_hostname(host)) {
if (!check_get_hostname(host, list)) {
host_c = strdup(host);
tmp_record->host = host_c;
HASH_ADD_KEYPTR(hh, blackwhitelist, tmp_record->host,
HASH_ADD_KEYPTR(hh, *list, tmp_record->host,
strlen(tmp_record->host), tmp_record);
debug("Added host %s\n", host_c);
return TRUE;
Expand All @@ -53,7 +54,7 @@ static int add_hostname(const char *host) {
return FALSE;
}

int blackwhitelist_load_list(const char *filename) {
static int blackwhitelist_load_list(const char *filename, blackwhitelist_record_t **list) {
char *line = malloc(HOST_MAXLEN + 1);
size_t linelen = HOST_MAXLEN + 1;
int cnt = 0;
Expand All @@ -74,17 +75,25 @@ int blackwhitelist_load_list(const char *filename) {
printf("WARNING: host %s is less than 3 bytes, skipping\n", line);
continue;
}
if (add_hostname(line))
if (add_hostname(line, list))
cnt++;
}
free(line);
if (!blackwhitelist) return FALSE;
if (!*list) return FALSE;
printf("Loaded %d hosts from file %s\n", cnt, filename);
fclose(fp);
return TRUE;
}

int blackwhitelist_check_hostname(const char *host_addr, size_t host_len) {
int blackwhitelist_load_blacklist(const char *filename) {
return blackwhitelist_load_list(filename, &blacklist);
}

int blackwhitelist_load_whitelist(const char *filename) {
return blackwhitelist_load_list(filename, &whitelist);
}

static int blackwhitelist_check_hostname(const char *host_addr, size_t host_len, blackwhitelist_record_t **list) {
char current_host[HOST_MAXLEN + 1];
char *tokenized_host = NULL;

Expand All @@ -94,17 +103,25 @@ int blackwhitelist_check_hostname(const char *host_addr, size_t host_len) {
current_host[host_len] = '\0';
}

if (check_get_hostname(current_host))
if (check_get_hostname(current_host, list))
return TRUE;

tokenized_host = strchr(current_host, '.');
while (tokenized_host != NULL && tokenized_host < (current_host + HOST_MAXLEN)) {
/* Search hostname only if there is next token */
if (strchr(tokenized_host + 1, '.') && check_get_hostname(tokenized_host + 1))
if (strchr(tokenized_host + 1, '.') && check_get_hostname(tokenized_host + 1, list))
return TRUE;
tokenized_host = strchr(tokenized_host + 1, '.');
}

debug("____blackwhitelist_check_hostname FALSE: host %s\n", current_host);
return FALSE;
}

int blackwhitelist_check_hostname_blacklist(const char *host_addr, size_t host_len) {
return blackwhitelist_check_hostname(host_addr, host_len, &blacklist);
}

int blackwhitelist_check_hostname_whitelist(const char *host_addr, size_t host_len) {
return blackwhitelist_check_hostname(host_addr, host_len, &whitelist);
}
6 changes: 4 additions & 2 deletions src/blackwhitelist.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
int blackwhitelist_load_list(const char *filename);
int blackwhitelist_check_hostname(const char *host_addr, size_t host_len);
int blackwhitelist_load_blacklist(const char *filename);
int blackwhitelist_load_whitelist(const char *filename);
int blackwhitelist_check_hostname_blacklist(const char *host_addr, size_t host_len);
int blackwhitelist_check_hostname_whitelist(const char *host_addr, size_t host_len);
28 changes: 21 additions & 7 deletions src/goodbyedpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static struct option long_options[] = {
{"dnsv6-port", required_argument, 0, '@' },
{"dns-verb", no_argument, 0, 'v' },
{"blacklist", required_argument, 0, 'b' },
{"whitelist", required_argument, 0, 't' },
{"allow-no-sni",no_argument, 0, ']' },
{"ip-id", required_argument, 0, 'i' },
{"set-ttl", required_argument, 0, '$' },
Expand Down Expand Up @@ -566,7 +567,8 @@ int main(int argc, char *argv[]) {
do_http_allports = 0,
do_host_mixedcase = 0,
do_dnsv4_redirect = 0, do_dnsv6_redirect = 0,
do_dns_verb = 0, do_tcp_verb = 0, do_blacklist = 0,
do_dns_verb = 0, do_tcp_verb = 0,
do_blacklist = 0, do_whitelist = 0,
do_allow_no_sni = 0,
do_fake_packet = 0,
do_auto_ttl = 0,
Expand Down Expand Up @@ -798,11 +800,18 @@ int main(int argc, char *argv[]) {
break;
case 'b': // --blacklist
do_blacklist = 1;
if (!blackwhitelist_load_list(optarg)) {
if (!blackwhitelist_load_blacklist(optarg)) {
printf("Can't load blacklist from file!\n");
exit(EXIT_FAILURE);
}
break;
case 't': // --whitelist
do_whitelist = 1;
if (!blackwhitelist_load_whitelist(optarg)) {
printf("Can't load whitelist from file!\n");
exit(EXIT_FAILURE);
}
break;
case ']': // --allow-no-sni
do_allow_no_sni = 1;
break;
Expand Down Expand Up @@ -898,6 +907,9 @@ int main(int argc, char *argv[]) {
" --blacklist <txtfile> perform circumvention tricks only to host names and subdomains from\n"
" supplied text file (HTTP Host/TLS SNI).\n"
" This option can be supplied multiple times.\n"
" --whitelist <txtfile> does not perform circumvention tricks to host names and subdomains from\n"
" supplied text file.\n"
" This option can be supplied multiple times.\n"
" --allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.\n"
" --set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.\n"
" DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).\n"
Expand Down Expand Up @@ -1131,16 +1143,17 @@ int main(int argc, char *argv[]) {
if ((packet_dataLen == 2 && memcmp(packet_data, "\x16\x03", 2) == 0) ||
(packet_dataLen >= 3 && memcmp(packet_data, "\x16\x03\x01", 3) == 0))
{
if (do_blacklist) {
if (do_blacklist || do_whitelist) {
sni_ok = extract_sni(packet_data, packet_dataLen,
&host_addr, &host_len);
}
if (
(do_blacklist && sni_ok &&
blackwhitelist_check_hostname(host_addr, host_len)
((do_blacklist && sni_ok &&
blackwhitelist_check_hostname_blacklist(host_addr, host_len)
) ||
(do_blacklist && !sni_ok && do_allow_no_sni) ||
(!do_blacklist)
(!do_blacklist)) &&
(do_whitelist ? !blackwhitelist_check_hostname_whitelist(host_addr, host_len) : 1)
)
{
#ifdef DEBUG
Expand Down Expand Up @@ -1176,7 +1189,8 @@ int main(int argc, char *argv[]) {
if (find_header_and_get_info(packet_data, packet_dataLen,
http_host_find, &hdr_name_addr, &hdr_value_addr, &hdr_value_len) &&
hdr_value_len > 0 && hdr_value_len <= HOST_MAXLEN &&
(do_blacklist ? blackwhitelist_check_hostname(hdr_value_addr, hdr_value_len) : 1))
(do_blacklist ? blackwhitelist_check_hostname_blacklist(hdr_value_addr, hdr_value_len) : 1) &&
(do_whitelist ? !blackwhitelist_check_hostname_whitelist(hdr_value_addr, hdr_value_len) : 1))
{
host_addr = hdr_value_addr;
host_len = hdr_value_len;
Expand Down