diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 1e3c6e6..0864aaf 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/aarch64/tpws b/binaries/aarch64/tpws index 6d2dc91..beff5c3 100755 Binary files a/binaries/aarch64/tpws and b/binaries/aarch64/tpws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index e1bf395..f0f354d 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/arm/tpws b/binaries/arm/tpws index 420ed4b..3fd2b18 100755 Binary files a/binaries/arm/tpws and b/binaries/arm/tpws differ diff --git a/binaries/freebsd-x64/dvtws b/binaries/freebsd-x64/dvtws index 648df7c..d326f5e 100755 Binary files a/binaries/freebsd-x64/dvtws and b/binaries/freebsd-x64/dvtws differ diff --git a/binaries/freebsd-x64/tpws b/binaries/freebsd-x64/tpws index 4e766bd..42374b5 100755 Binary files a/binaries/freebsd-x64/tpws and b/binaries/freebsd-x64/tpws differ diff --git a/binaries/mac64/tpws b/binaries/mac64/tpws index f67517f..5dd4b75 100755 Binary files a/binaries/mac64/tpws and b/binaries/mac64/tpws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index e8e5e6a..a00f04c 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-lsb/tpws b/binaries/mips32r1-lsb/tpws index ebdc634..4303ac7 100755 Binary files a/binaries/mips32r1-lsb/tpws and b/binaries/mips32r1-lsb/tpws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index 8b81069..60a5e33 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips32r1-msb/tpws b/binaries/mips32r1-msb/tpws index 67b71fd..a3c301e 100755 Binary files a/binaries/mips32r1-msb/tpws and b/binaries/mips32r1-msb/tpws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index 9a9ce1e..d0ada4c 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/mips64r2-msb/tpws b/binaries/mips64r2-msb/tpws index 7116841..12a403b 100755 Binary files a/binaries/mips64r2-msb/tpws and b/binaries/mips64r2-msb/tpws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 7bfb0ec..689093b 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/ppc/tpws b/binaries/ppc/tpws index 85bf322..76bdf7e 100755 Binary files a/binaries/ppc/tpws and b/binaries/ppc/tpws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 044e71a..880ad15 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86/tpws b/binaries/x86/tpws index 4fd773c..0870049 100755 Binary files a/binaries/x86/tpws and b/binaries/x86/tpws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 381a8c7..ad0522d 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/binaries/x86_64/tpws b/binaries/x86_64/tpws index 90a2479..ec51376 100755 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/binaries/x86_64/tpws_wsl.tgz b/binaries/x86_64/tpws_wsl.tgz index 943689f..dc19751 100644 Binary files a/binaries/x86_64/tpws_wsl.tgz and b/binaries/x86_64/tpws_wsl.tgz differ diff --git a/nfq/desync.c b/nfq/desync.c index 5d1a533..a580647 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -323,7 +323,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (bHaveHost) { DLOG("hostname: %s\n",host) - if (params.hostlist && !SearchHostList(params.hostlist,host,params.debug)) + if ((params.hostlist || params.hostlist_exclude) && !HostlistCheck(params.hostlist, params.hostlist_exclude, host)) { DLOG("not applying tampering to this request\n") return res; @@ -738,7 +738,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, if (bHaveHost) { DLOG("hostname: %s\n",host) - if (params.hostlist && !SearchHostList(params.hostlist,host,params.debug)) + if ((params.hostlist || params.hostlist_exclude) && !HostlistCheck(params.hostlist, params.hostlist_exclude, host)) { DLOG("not applying tampering to this request\n") return res; diff --git a/nfq/hostlist.c b/nfq/hostlist.c index 797e363..e942d3a 100644 --- a/nfq/hostlist.c +++ b/nfq/hostlist.c @@ -1,6 +1,7 @@ #include #include "hostlist.h" #include "gzip.h" +#include "params.h" static bool addpool(strpool **hostlist, char **s, const char *end) @@ -22,20 +23,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end) } -bool LoadHostList(strpool **hostlist, char *filename) +bool AppendHostList(strpool **hostlist, char *filename) { char *p, *e, s[256], *zbuf; size_t zsize; int ct = 0; FILE *F; int r; - - if (*hostlist) - { - StrPoolDestroy(hostlist); - *hostlist = NULL; - } - + + printf("Loading hostlist %s\n",filename); + if (!(F = fopen(filename, "rb"))) { fprintf(stderr, "Could not open %s\n", filename); @@ -92,8 +89,25 @@ bool LoadHostList(strpool **hostlist, char *filename) return true; } +bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list) +{ + struct str_list *file; -bool SearchHostList(strpool *hostlist, const char *host, bool debug) + if (*hostlist) + { + StrPoolDestroy(hostlist); + *hostlist = NULL; + } + + LIST_FOREACH(file, file_list, next) + { + if (!AppendHostList(hostlist, file->str)) return false; + } + return true; +} + + +bool SearchHostList(strpool *hostlist, const char *host) { if (hostlist) { @@ -102,7 +116,7 @@ bool SearchHostList(strpool *hostlist, const char *host, bool debug) while (p) { bInHostList = StrPoolCheckStr(hostlist, p); - if (debug) printf("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); + if (params.debug) printf("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); if (bInHostList) return true; p = strchr(p, '.'); if (p) p++; @@ -110,3 +124,19 @@ bool SearchHostList(strpool *hostlist, const char *host, bool debug) } return false; } + +// return : true = apply fooling, false = do not apply +bool HostlistCheck(strpool *hostlist, strpool *hostlist_exclude, const char *host) +{ + if (hostlist_exclude) + { + if (params.debug) printf("Checking exclude hostlist\n"); + if (SearchHostList(hostlist_exclude, host)) return false; + } + if (hostlist) + { + if (params.debug) printf("Checking include hostlist\n"); + return SearchHostList(hostlist, host); + } + return true; +} diff --git a/nfq/hostlist.h b/nfq/hostlist.h index 0402beb..91bce82 100644 --- a/nfq/hostlist.h +++ b/nfq/hostlist.h @@ -3,5 +3,8 @@ #include #include "strpool.h" -bool LoadHostList(strpool **hostlist, char *filename); -bool SearchHostList(strpool *hostlist, const char *host,bool debug); +bool AppendHostList(strpool **hostlist, char *filename); +bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list); +bool SearchHostList(strpool *hostlist, const char *host); +// return : true = apply fooling, false = do not apply +bool HostlistCheck(strpool *hostlist, strpool *hostlist_exclude, const char *host); diff --git a/nfq/nfqws.c b/nfq/nfqws.c index a6a5ff3..9e155d9 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -48,7 +48,7 @@ static bool bHup = false; static void onhup(int sig) { printf("HUP received !\n"); - if (params.hostlist) + if (params.hostlist || params.hostlist_exclude) printf("Will reload hostlist on next request\n"); bHup = true; } @@ -57,13 +57,11 @@ static void dohup() { if (bHup) { - if (params.hostlist) + if (!LoadHostLists(¶ms.hostlist, ¶ms.hostlist_files) || + !LoadHostLists(¶ms.hostlist_exclude, ¶ms.hostlist_exclude_files)) { - if (!LoadHostList(¶ms.hostlist, params.hostfile)) - { - // what will we do without hostlist ?? sure, gonna die - exit(1); - } + // what will we do without hostlist ?? sure, gonna die + exit(1); } bHup = false; } @@ -549,7 +547,8 @@ static void exithelp() " --dpi-desync-fake-unknown-udp= ; file containing unknown udp protocol fake payload\n" " --dpi-desync-udplen-increment=\t; increase udp packet length by N bytes (default %u)\n" " --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n" - " --hostlist=\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply)\n", + " --hostlist=\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" + " --hostlist-exclude=\t\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n", CTRACK_T_SYN, CTRACK_T_EST, CTRACK_T_FIN, CTRACK_T_UDP, #if defined(__linux__) || defined(SO_USER_COOKIE) DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT, @@ -565,12 +564,20 @@ static void exithelp() static void cleanup_params() { + ConntrackPoolDestroy(¶ms.conntrack); + + strlist_destroy(¶ms.hostlist_files); + strlist_destroy(¶ms.hostlist_exclude_files); + if (params.hostlist_exclude) + { + StrPoolDestroy(¶ms.hostlist_exclude); + params.hostlist_exclude = NULL; + } if (params.hostlist) { StrPoolDestroy(¶ms.hostlist); params.hostlist = NULL; } - ConntrackPoolDestroy(¶ms.conntrack); } static void exithelp_clean() { @@ -649,6 +656,9 @@ int main(int argc, char **argv) params.wssize_cutoff_mode = params.desync_cutoff_mode = 'n'; // packet number by default params.udplen_increment = UDPLEN_INCREMENT_DEFAULT; + LIST_INIT(¶ms.hostlist_files); + LIST_INIT(¶ms.hostlist_exclude_files); + if (can_drop_root()) // are we root ? { params.uid = params.gid = 0x7FFFFFFF; // default uid:gid @@ -704,9 +714,10 @@ int main(int argc, char **argv) {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=33 {"dpi-desync-cutoff",required_argument,0,0},// optidx=34 {"hostlist",required_argument,0,0}, // optidx=35 + {"hostlist-exclude",required_argument,0,0}, // optidx=36 #ifdef __linux__ - {"bind-fix4",no_argument,0,0}, // optidx=36 - {"bind-fix6",no_argument,0,0}, // optidx=37 + {"bind-fix4",no_argument,0,0}, // optidx=37 + {"bind-fix6",no_argument,0,0}, // optidx=38 #endif {NULL,0,NULL,0} }; @@ -1003,16 +1014,24 @@ int main(int argc, char **argv) } break; case 35: /* hostlist */ - if (!LoadHostList(¶ms.hostlist, optarg)) + if (!strlist_add(¶ms.hostlist_files, optarg)) + { + fprintf(stderr, "strlist_add failed\n"); exit_clean(1); - strncpy(params.hostfile,optarg,sizeof(params.hostfile)); - params.hostfile[sizeof(params.hostfile)-1]='\0'; + } + break; + case 36: /* hostlist-exclude */ + if (!strlist_add(¶ms.hostlist_exclude_files, optarg)) + { + fprintf(stderr, "strlist_add failed\n"); + exit_clean(1); + } break; #ifdef __linux__ - case 36: /* bind-fix4 */ + case 37: /* bind-fix4 */ params.bind_fix4 = true; break; - case 37: /* bind-fix6 */ + case 38: /* bind-fix6 */ params.bind_fix6 = true; break; #endif @@ -1028,6 +1047,17 @@ int main(int argc, char **argv) } #endif + if (!LoadHostLists(¶ms.hostlist, ¶ms.hostlist_files)) + { + fprintf(stderr, "Include hostlist load failed\n"); + exit_clean(1); + } + if (!LoadHostLists(¶ms.hostlist_exclude, ¶ms.hostlist_exclude_files)) + { + fprintf(stderr, "Exclude hostlist load failed\n"); + exit_clean(1); + } + if (daemon) daemonize(); if (*pidfile && !writepid(pidfile)) diff --git a/nfq/params.h b/nfq/params.h index f577662..c9ecc95 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -50,8 +50,6 @@ struct params_s uint8_t desync_fooling_mode; uint32_t desync_fwmark; // unused in BSD uint32_t desync_badseq_increment, desync_badseq_ack_increment; - char hostfile[256]; - strpool *hostlist; uint8_t fake_http[1432],fake_tls[1432],fake_unknown[1432],fake_unknown_udp[1472],fake_quic[1472]; size_t fake_http_size,fake_tls_size,fake_unknown_size,fake_unknown_udp_size,fake_quic_size; uint16_t udplen_increment; @@ -59,6 +57,9 @@ struct params_s uid_t uid; gid_t gid; + strpool *hostlist, *hostlist_exclude; + struct str_list_head hostlist_files, hostlist_exclude_files; + unsigned int ctrack_t_syn, ctrack_t_est, ctrack_t_fin, ctrack_t_udp; t_conntrack conntrack; }; diff --git a/nfq/strpool.c b/nfq/strpool.c index 6649763..6a219e0 100644 --- a/nfq/strpool.c +++ b/nfq/strpool.c @@ -74,3 +74,34 @@ void StrPoolDestroy(strpool **p) } *p = NULL; } + + + + +bool strlist_add(struct str_list_head *head, const char *filename) +{ + struct str_list *entry = malloc(sizeof(struct str_list)); + if (!entry) return false; + entry->str = strdup(filename); + if (!entry->str) + { + free(entry); + return false; + } + LIST_INSERT_HEAD(head, entry, next); + return true; +} +static void strlist_entry_destroy(struct str_list *entry) +{ + if (entry->str) free(entry->str); + free(entry); +} +void strlist_destroy(struct str_list_head *head) +{ + struct str_list *entry; + while (entry = LIST_FIRST(head)) + { + LIST_REMOVE(entry, next); + strlist_entry_destroy(entry); + } +} diff --git a/nfq/strpool.h b/nfq/strpool.h index 2653cb4..36d484e 100644 --- a/nfq/strpool.h +++ b/nfq/strpool.h @@ -2,10 +2,10 @@ #include #include +#include //#define HASH_BLOOM 20 #define HASH_NONFATAL_OOM 1 -#undef HASH_FUNCTION #define HASH_FUNCTION HASH_BER #include "uthash.h" @@ -18,3 +18,12 @@ void StrPoolDestroy(strpool **p); bool StrPoolAddStr(strpool **pp,const char *s); bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); bool StrPoolCheckStr(strpool *p,const char *s); + +struct str_list { + char *str; + LIST_ENTRY(str_list) next; +}; +LIST_HEAD(str_list_head, str_list); + +bool strlist_add(struct str_list_head *head, const char *filename); +void strlist_destroy(struct str_list_head *head); diff --git a/tpws/hostlist.c b/tpws/hostlist.c index 9768379..e942d3a 100644 --- a/tpws/hostlist.c +++ b/tpws/hostlist.c @@ -3,6 +3,7 @@ #include "gzip.h" #include "params.h" + static bool addpool(strpool **hostlist, char **s, const char *end) { char *p; @@ -22,20 +23,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end) } -bool LoadHostList(strpool **hostlist, char *filename) +bool AppendHostList(strpool **hostlist, char *filename) { char *p, *e, s[256], *zbuf; size_t zsize; int ct = 0; FILE *F; int r; - - if (*hostlist) - { - StrPoolDestroy(hostlist); - *hostlist = NULL; - } - + + printf("Loading hostlist %s\n",filename); + if (!(F = fopen(filename, "rb"))) { fprintf(stderr, "Could not open %s\n", filename); @@ -92,8 +89,25 @@ bool LoadHostList(strpool **hostlist, char *filename) return true; } +bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list) +{ + struct str_list *file; -bool SearchHostList(strpool *hostlist, const char *host, bool debug) + if (*hostlist) + { + StrPoolDestroy(hostlist); + *hostlist = NULL; + } + + LIST_FOREACH(file, file_list, next) + { + if (!AppendHostList(hostlist, file->str)) return false; + } + return true; +} + + +bool SearchHostList(strpool *hostlist, const char *host) { if (hostlist) { @@ -102,7 +116,7 @@ bool SearchHostList(strpool *hostlist, const char *host, bool debug) while (p) { bInHostList = StrPoolCheckStr(hostlist, p); - if (debug) VPRINT("Hostlist check for %s : %s", p, bInHostList ? "positive" : "negative") + if (params.debug) printf("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); if (bInHostList) return true; p = strchr(p, '.'); if (p) p++; @@ -110,3 +124,19 @@ bool SearchHostList(strpool *hostlist, const char *host, bool debug) } return false; } + +// return : true = apply fooling, false = do not apply +bool HostlistCheck(strpool *hostlist, strpool *hostlist_exclude, const char *host) +{ + if (hostlist_exclude) + { + if (params.debug) printf("Checking exclude hostlist\n"); + if (SearchHostList(hostlist_exclude, host)) return false; + } + if (hostlist) + { + if (params.debug) printf("Checking include hostlist\n"); + return SearchHostList(hostlist, host); + } + return true; +} diff --git a/tpws/hostlist.h b/tpws/hostlist.h index dfe3bdf..91bce82 100644 --- a/tpws/hostlist.h +++ b/tpws/hostlist.h @@ -3,5 +3,8 @@ #include #include "strpool.h" -bool LoadHostList(strpool **hostlist, char *filename); -bool SearchHostList(strpool *hostlist, const char *host, bool debug); +bool AppendHostList(strpool **hostlist, char *filename); +bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list); +bool SearchHostList(strpool *hostlist, const char *host); +// return : true = apply fooling, false = do not apply +bool HostlistCheck(strpool *hostlist, strpool *hostlist_exclude, const char *host); diff --git a/tpws/params.h b/tpws/params.h index a5122f3..e377fad 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "strpool.h" enum splithttpreq { split_none = 0, split_method, split_host }; @@ -42,9 +43,11 @@ struct params_s enum splithttpreq split_http_req; bool split_any_protocol; int split_pos; - char hostfile[256]; + char pidfile[256]; - strpool *hostlist; + + strpool *hostlist, *hostlist_exclude; + struct str_list_head hostlist_files, hostlist_exclude_files; int debug; diff --git a/tpws/strpool.c b/tpws/strpool.c index 41e62a9..6a219e0 100644 --- a/tpws/strpool.c +++ b/tpws/strpool.c @@ -6,71 +6,102 @@ #undef uthash_nonfatal_oom #define uthash_nonfatal_oom(elt) ut_oom_recover(elt) -static bool oom=false; +static bool oom = false; static void ut_oom_recover(strpool *elem) { - oom=true; + oom = true; } // for zero terminated strings -bool StrPoolAddStr(strpool **pp,const char *s) +bool StrPoolAddStr(strpool **pp, const char *s) { - strpool *elem; - if (!(elem = (strpool*)malloc(sizeof(strpool)))) - return false; - if (!(elem->str = strdup(s))) - { - free(elem); - return false; - } - oom = false; - HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem ); - if (oom) - { - free(elem->str); - free(elem); - return false; - } - return true; + strpool *elem; + if (!(elem = (strpool*)malloc(sizeof(strpool)))) + return false; + if (!(elem->str = strdup(s))) + { + free(elem); + return false; + } + oom = false; + HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem); + if (oom) + { + free(elem->str); + free(elem); + return false; + } + return true; } // for not zero terminated strings -bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen) +bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) { - strpool *elem; - if (!(elem = (strpool*)malloc(sizeof(strpool)))) - return false; - if (!(elem->str = malloc(slen+1))) - { - free(elem); - return false; - } - memcpy(elem->str,s,slen); - elem->str[slen]=0; - oom = false; - HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem ); - if (oom) - { - free(elem->str); - free(elem); - return false; - } - return true; + strpool *elem; + if (!(elem = (strpool*)malloc(sizeof(strpool)))) + return false; + if (!(elem->str = malloc(slen + 1))) + { + free(elem); + return false; + } + memcpy(elem->str, s, slen); + elem->str[slen] = 0; + oom = false; + HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem); + if (oom) + { + free(elem->str); + free(elem); + return false; + } + return true; } -bool StrPoolCheckStr(strpool *p,const char *s) +bool StrPoolCheckStr(strpool *p, const char *s) { - strpool *elem; - HASH_FIND_STR( p, s, elem); - return elem!=NULL; + strpool *elem; + HASH_FIND_STR(p, s, elem); + return elem != NULL; } void StrPoolDestroy(strpool **p) { - strpool *elem,*tmp; - HASH_ITER(hh, *p, elem, tmp) { - free(elem->str); - HASH_DEL(*p, elem); - free(elem); - } - *p = NULL; + strpool *elem, *tmp; + HASH_ITER(hh, *p, elem, tmp) { + free(elem->str); + HASH_DEL(*p, elem); + free(elem); + } + *p = NULL; +} + + + + +bool strlist_add(struct str_list_head *head, const char *filename) +{ + struct str_list *entry = malloc(sizeof(struct str_list)); + if (!entry) return false; + entry->str = strdup(filename); + if (!entry->str) + { + free(entry); + return false; + } + LIST_INSERT_HEAD(head, entry, next); + return true; +} +static void strlist_entry_destroy(struct str_list *entry) +{ + if (entry->str) free(entry->str); + free(entry); +} +void strlist_destroy(struct str_list_head *head) +{ + struct str_list *entry; + while (entry = LIST_FIRST(head)) + { + LIST_REMOVE(entry, next); + strlist_entry_destroy(entry); + } } diff --git a/tpws/strpool.h b/tpws/strpool.h index 5932ba3..36d484e 100644 --- a/tpws/strpool.h +++ b/tpws/strpool.h @@ -2,6 +2,7 @@ #include #include +#include //#define HASH_BLOOM 20 #define HASH_NONFATAL_OOM 1 @@ -17,3 +18,12 @@ void StrPoolDestroy(strpool **p); bool StrPoolAddStr(strpool **pp,const char *s); bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); bool StrPoolCheckStr(strpool *p,const char *s); + +struct str_list { + char *str; + LIST_ENTRY(str_list) next; +}; +LIST_HEAD(str_list_head, str_list); + +bool strlist_add(struct str_list_head *head, const char *filename); +void strlist_destroy(struct str_list_head *head); diff --git a/tpws/tamper.c b/tpws/tamper.c index 45f7ef1..9c22666 100644 --- a/tpws/tamper.c +++ b/tpws/tamper.c @@ -48,7 +48,7 @@ void modify_tcp_segment(char *segment,size_t segment_buffer_size,size_t *size,si { VPRINT("Data block looks like http request start : %s", *method) // cpu saving : we search host only if and when required. we do not research host every time we need its position - if (params.hostlist && find_host(&pHost,segment,*size)) + if ((params.hostlist || params.hostlist_exclude) && find_host(&pHost,segment,*size)) { p = pHost + 5; while (p < (segment + *size) && (*p == ' ' || *p == '\t')) p++; @@ -58,7 +58,7 @@ void modify_tcp_segment(char *segment,size_t segment_buffer_size,size_t *size,si Host[pp - p] = '\0'; VPRINT("Requested Host is : %s", Host) for(p = Host; *p; p++) *p=tolower(*p); - bBypass = !SearchHostList(params.hostlist,Host,!!params.debug); + bBypass = !HostlistCheck(params.hostlist, params.hostlist_exclude, Host); } if (!bBypass) { @@ -218,10 +218,10 @@ void modify_tcp_segment(char *segment,size_t segment_buffer_size,size_t *size,si VPRINT("packet contains TLS ClientHello") // we need host only if hostlist is present - if (params.hostlist && TLSHelloExtractHost((uint8_t*)segment,*size,host,sizeof(host))) + if ((params.hostlist || params.hostlist_exclude) && TLSHelloExtractHost((uint8_t*)segment,*size,host,sizeof(host))) { VPRINT("hostname: %s",host) - if (!SearchHostList(params.hostlist,host,!!params.debug)) + if (!HostlistCheck(params.hostlist, params.hostlist_exclude, host)) { VPRINT("Not acting on this request") return; diff --git a/tpws/tpws.c b/tpws/tpws.c index ae81595..551eb83 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -43,8 +43,8 @@ bool bHup = false; static void onhup(int sig) { printf("HUP received !\n"); - if (params.hostlist) - printf("Will reload hostlist on next request\n"); + if (params.hostlist || params.hostlist_exclude) + printf("Will reload hostlists on next request\n"); bHup = true; } // should be called in normal execution @@ -52,13 +52,11 @@ void dohup() { if (bHup) { - if (params.hostlist) + if (!LoadHostLists(¶ms.hostlist, ¶ms.hostlist_files) || + !LoadHostLists(¶ms.hostlist_exclude, ¶ms.hostlist_exclude_files)) { - if (!LoadHostList(¶ms.hostlist, params.hostfile)) - { - // what will we do without hostlist ?? sure, gonna die - exit(1); - } + // what will we do without hostlist ?? sure, gonna die + exit(1); } bHup = false; } @@ -144,8 +142,9 @@ static void exithelp() #endif " --debug=0|1|2\t\t\t; 0(default)=silent 1=verbose 2=debug\n" "\nTAMPERING:\n" - " --hostlist=\t\t; only act on host in the list (one host per line, subdomains auto apply)\n" - " --split-http-req=method|host\n" + " --hostlist=\t\t; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" + " --hostlist-exclude=\t; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" + " --split-http-req=method|host\t; split at specified logical part of plain http request\n" " --split-pos=\t; split at specified pos. split-http-req takes precedence for http.\n" " --split-any-protocol\t\t; split not only http and https\n" " --hostcase\t\t\t; change Host: => host:\n" @@ -163,6 +162,13 @@ static void exithelp() } static void cleanup_params() { + strlist_destroy(¶ms.hostlist_files); + strlist_destroy(¶ms.hostlist_exclude_files); + if (params.hostlist_exclude) + { + StrPoolDestroy(¶ms.hostlist_exclude); + params.hostlist_exclude = NULL; + } if (params.hostlist) { StrPoolDestroy(¶ms.hostlist); @@ -208,6 +214,9 @@ void parse_params(int argc, char *argv[]) params.maxconn = DEFAULT_MAX_CONN; params.max_orphan_time = DEFAULT_MAX_ORPHAN_TIME; params.binds_last = -1; + LIST_INIT(¶ms.hostlist_files); + LIST_INIT(¶ms.hostlist_exclude_files); + #if defined(__OpenBSD__) || defined(__APPLE__) params.pf_enable = true; // OpenBSD and MacOS have no other choice #endif @@ -249,17 +258,18 @@ void parse_params(int argc, char *argv[]) { "hosttab",no_argument,0,0 },// optidx=28 { "unixeol",no_argument,0,0 },// optidx=29 { "hostlist",required_argument,0,0 },// optidx=30 - { "pidfile",required_argument,0,0 },// optidx=31 - { "debug",optional_argument,0,0 },// optidx=32 - { "local-rcvbuf",required_argument,0,0 },// optidx=33 - { "local-sndbuf",required_argument,0,0 },// optidx=34 - { "remote-rcvbuf",required_argument,0,0 },// optidx=35 - { "remote-sndbuf",required_argument,0,0 },// optidx=36 - { "socks",no_argument,0,0 },// optidx=37 - { "no-resolve",no_argument,0,0 },// optidx=38 - { "skip-nodelay",no_argument,0,0 },// optidx=39 + { "hostlist-exclude",required_argument,0,0 },// optidx=31 + { "pidfile",required_argument,0,0 },// optidx=32 + { "debug",optional_argument,0,0 },// optidx=33 + { "local-rcvbuf",required_argument,0,0 },// optidx=34 + { "local-sndbuf",required_argument,0,0 },// optidx=35 + { "remote-rcvbuf",required_argument,0,0 },// optidx=36 + { "remote-sndbuf",required_argument,0,0 },// optidx=37 + { "socks",no_argument,0,0 },// optidx=38 + { "no-resolve",no_argument,0,0 },// optidx=39 + { "skip-nodelay",no_argument,0,0 },// optidx=40 #if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) - { "enable-pf",no_argument,0,0 },// optidx=40 + { "enable-pf",no_argument,0,0 },// optidx=41 #endif { NULL,0,NULL,0 } }; @@ -460,42 +470,51 @@ void parse_params(int argc, char *argv[]) params.tamper = true; break; case 30: /* hostlist */ - if (!LoadHostList(¶ms.hostlist, optarg)) + if (!strlist_add(¶ms.hostlist_files, optarg)) + { + fprintf(stderr, "strlist_add failed\n"); exit_clean(1); - strncpy(params.hostfile,optarg,sizeof(params.hostfile)); - params.hostfile[sizeof(params.hostfile)-1]='\0'; + } params.tamper = true; break; - case 31: /* pidfile */ + case 31: /* hostlist-exclude */ + if (!strlist_add(¶ms.hostlist_exclude_files, optarg)) + { + fprintf(stderr, "strlist_add failed\n"); + exit_clean(1); + } + params.tamper = true; + break; + case 32: /* pidfile */ strncpy(params.pidfile,optarg,sizeof(params.pidfile)); params.pidfile[sizeof(params.pidfile)-1]='\0'; break; - case 32: + case 33: params.debug = optarg ? atoi(optarg) : 1; break; - case 33: /* local-rcvbuf */ + case 34: /* local-rcvbuf */ params.local_rcvbuf = atoi(optarg)/2; break; - case 34: /* local-sndbuf */ + case 35: /* local-sndbuf */ params.local_sndbuf = atoi(optarg)/2; break; - case 35: /* remote-rcvbuf */ + case 36: /* remote-rcvbuf */ params.remote_rcvbuf = atoi(optarg)/2; break; - case 36: /* remote-sndbuf */ + case 37: /* remote-sndbuf */ params.remote_sndbuf = atoi(optarg)/2; break; - case 37: /* socks */ + case 38: /* socks */ params.proxy_type = CONN_TYPE_SOCKS; break; - case 38: /* no-resolve */ + case 39: /* no-resolve */ params.no_resolve = true; break; - case 39: /* skip-nodelay */ + case 40: /* skip-nodelay */ params.skip_nodelay = true; break; #if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) - case 40: /* enable-pf */ + case 41: /* enable-pf */ params.pf_enable = true; break; #endif @@ -515,6 +534,17 @@ void parse_params(int argc, char *argv[]) fprintf(stderr, "Cannot split with --skip-nodelay\n"); exit_clean(1); } + + if (!LoadHostLists(¶ms.hostlist, ¶ms.hostlist_files)) + { + fprintf(stderr, "Include hostlist load failed\n"); + exit_clean(1); + } + if (!LoadHostLists(¶ms.hostlist_exclude, ¶ms.hostlist_exclude_files)) + { + fprintf(stderr, "Exclude hostlist load failed\n"); + exit_clean(1); + } }