From 7b390ba2a3ec96585b181cf3b5782797c9492cd4 Mon Sep 17 00:00:00 2001 From: SashaXser <24498484+SashaXser@users.noreply.github.com> Date: Fri, 17 Nov 2023 12:50:31 +0400 Subject: [PATCH] Update blackwhitelist.c --- src/blackwhitelist.c | 139 +++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 78 deletions(-) diff --git a/src/blackwhitelist.c b/src/blackwhitelist.c index 4a2151f..e59b59d 100644 --- a/src/blackwhitelist.c +++ b/src/blackwhitelist.c @@ -2,8 +2,8 @@ * Blacklist for GoodbyeDPI HTTP DPI circumvention tricks * * This is a simple domain hash table. - * Domain records are added from a file, where every - * domain is separated by a new line. + * Domain records are added from a text file, where every + * domain is separated with a new line. */ #include #include @@ -11,117 +11,100 @@ #include "utils/uthash.h" #include "utils/getline.h" -/* Define the minimum length of a host name */ -#define HOST_MINLEN 3 +typedef struct blackwhitelist_record { + const char *host; + UT_hash_handle hh; /* makes this structure hashable */ +} blackwhitelist_record_t; -/* Define the structure of a blacklist record */ -typedef struct blacklist_record { - const char *host; /* The host name of the blacklisted domain */ - UT_hash_handle hh; /* The hash handle for the hash table */ -} blacklist_record_t; +static blackwhitelist_record_t *blackwhitelist = NULL; -/* Check if a host name is in the blacklist hash table */ -static int blacklist_check_hostname(const char *host, blacklist_record_t *blacklist) { - blacklist_record_t *tmp_record = NULL; - if (!blacklist) return FALSE; /* Return false if the hash table is empty */ +static int check_get_hostname(const char *host) { + blackwhitelist_record_t *tmp_record = NULL; + if (!blackwhitelist) return FALSE; - HASH_FIND_STR(blacklist, host, tmp_record); /* Find the host name in the hash table */ + HASH_FIND_STR(blackwhitelist, host, tmp_record); if (tmp_record) { - debug("blacklist_check_hostname found host\n"); - return TRUE; /* Return true if the host name is found */ + debug("check_get_hostname found host\n"); + return TRUE; } - debug("blacklist_check_hostname host not found\n"); - return FALSE; /* Return false if the host name is not found */ + debug("check_get_hostname host not found\n"); + return FALSE; } -/* Add a host name to the blacklist hash table */ -static int blacklist_add_hostname(const char *host, blacklist_record_t **blacklist) { - if (!host || !blacklist) - return FALSE; /* Return false if the host name or the hash table pointer is null */ +static int add_hostname(const char *host) { + if (!host) + return FALSE; - blacklist_record_t *tmp_record = NULL; + blackwhitelist_record_t *tmp_record = malloc(sizeof(blackwhitelist_record_t)); char *host_c = NULL; - if (!blacklist_check_hostname(host, *blacklist)) { /* Check if the host name is already in the hash table */ - tmp_record = malloc(sizeof(blacklist_record_t)); /* Allocate memory for a new record */ - if (!tmp_record) return FALSE; /* Return false if the allocation fails */ - host_c = strdup(host); /* Duplicate the host name */ - if (!host_c) { /* Return false if the duplication fails */ - free(tmp_record); /* Free the allocated memory for the record */ - return FALSE; - } - tmp_record->host = host_c; /* Set the host name field of the record */ - HASH_ADD_KEYPTR(hh, *blacklist, tmp_record->host, - strlen(tmp_record->host), tmp_record); /* Add the record to the hash table */ + if (!check_get_hostname(host)) { + host_c = strdup(host); + tmp_record->host = host_c; + HASH_ADD_KEYPTR(hh, blackwhitelist, tmp_record->host, + strlen(tmp_record->host), tmp_record); debug("Added host %s\n", host_c); - return TRUE; /* Return true if the host name is added successfully */ + return TRUE; } debug("Not added host %s\n", host); - return FALSE; /* Return false if the host name is already in the hash table */ + free(tmp_record); + if (host_c) + free(host_c); + return FALSE; } -/* Load the blacklist from a file and store it in a hash table */ -int blacklist_load_list(const char *filename, blacklist_record_t **blacklist) { - char *line = NULL; - size_t linelen = 0; +int blackwhitelist_load_list(const char *filename) { + char *line = malloc(HOST_MAXLEN + 1); + size_t linelen = HOST_MAXLEN + 1; int cnt = 0; ssize_t read; - FILE *fp = fopen(filename, "r"); /* Open the file for reading */ - if (!fp) return FALSE; /* Return false if the file does not exist or cannot be opened */ + FILE *fp = fopen(filename, "r"); + if (!fp) return FALSE; - while ((read = getline(&line, &linelen, fp)) != -1) { /* Read a line from the file */ - /* Remove the trailing newline or carriage return characters */ + while ((read = getline(&line, &linelen, fp)) != -1) { + /* works with both \n and \r\n */ line[strcspn(line, "\r\n")] = '\0'; - if (strlen(line) < HOST_MINLEN) { /* Skip the line if the host name is too short */ - printf("WARNING: host %s is less than %d bytes, skipping\n", line, HOST_MINLEN); + if (strlen(line) > HOST_MAXLEN) { + printf("WARNING: host %s exceeds maximum host length and has not been added\n", + line); + continue; + } + if (strlen(line) < 3) { + printf("WARNING: host %s is less than 3 bytes, skipping\n", line); continue; } - if (blacklist_add_hostname(line, blacklist)) /* Add the host name to the hash table */ - cnt++; /* Increment the counter of added host names */ + if (add_hostname(line)) + cnt++; } - free(line); /* Free the allocated memory for the line buffer */ - if (!*blacklist) return FALSE; /* Return false if the hash table is empty */ + free(line); + if (!blackwhitelist) return FALSE; printf("Loaded %d hosts from file %s\n", cnt, filename); - fclose(fp); /* Close the file */ - return TRUE; /* Return true if the hash table is loaded successfully */ -} - -/* Free the memory allocated for the blacklist hash table and its records */ -void blacklist_free_list(blacklist_record_t **blacklist) { - blacklist_record_t *tmp_record = NULL, *tmp = NULL; - if (!blacklist || !*blacklist) return; /* Return if the hash table pointer is null or the hash table is empty */ - - HASH_ITER(hh, *blacklist, tmp_record, tmp) { /* Iterate over the hash table records */ - HASH_DEL(*blacklist, tmp_record); /* Delete the record from the hash table */ - free(tmp_record->host); /* Free the memory allocated for the host name */ - free(tmp_record); /* Free the memory allocated for the record */ - } - *blacklist = NULL; /* Set the hash table pointer to null */ + fclose(fp); + return TRUE; } -/* Check if a host name matches any of the blacklisted domains */ -int blacklist_match_hostname(const char *host_addr, size_t host_len, blacklist_record_t *blacklist) { +int blackwhitelist_check_hostname(const char *host_addr, size_t host_len) { char current_host[HOST_MAXLEN + 1]; char *tokenized_host = NULL; - if (host_len > HOST_MAXLEN) return FALSE; /* Return false if the host name is too long */ + if (host_len > HOST_MAXLEN) return FALSE; if (host_addr && host_len) { - memcpy(current_host, host_addr, host_len); /* Copy the host name to a local buffer */ - current_host[host_len] = '\0'; /* Add a null terminator */ + memcpy(current_host, host_addr, host_len); + current_host[host_len] = '\0'; } - if (blacklist_check_hostname(current_host, blacklist)) /* Check if the host name is in the hash table */ - return TRUE; /* Return true if the host name is found */ + if (check_get_hostname(current_host)) + return TRUE; - tokenized_host = strchr(current_host, '.'); /* Find the first dot in the host name */ + 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, '.') && blacklist_check_hostname(tokenized_host + 1, blacklist)) - return TRUE; /* Return true if the host name is found */ - tokenized_host = strchr(tokenized_host + 1, '.'); /* Find the next dot in the host name */ + if (strchr(tokenized_host + 1, '.') && check_get_hostname(tokenized_host + 1)) + return TRUE; + tokenized_host = strchr(tokenized_host + 1, '.'); } - debug("____blacklist_match_hostname FALSE: host %s\n", current_host); - return FALSE; /* Return false if the host name is not found */ + debug("____blackwhitelist_check_hostname FALSE: host %s\n", current_host); + return FALSE; }