Update goodbyedpi.c
This commit is contained in:
parent
110ba354d8
commit
cda71e0c61
254
src/goodbyedpi.c
254
src/goodbyedpi.c
|
|
@ -393,46 +393,42 @@ static int find_header_and_get_info(const char *pktdata, unsigned int pktlen,
|
||||||
static int extract_sni(const char *pktdata, unsigned int pktlen,
|
static int extract_sni(const char *pktdata, unsigned int pktlen,
|
||||||
char **hostnameaddr, unsigned int *hostnamelen) {
|
char **hostnameaddr, unsigned int *hostnamelen) {
|
||||||
unsigned int ptr = 0;
|
unsigned int ptr = 0;
|
||||||
unsigned const char *d = (unsigned const char *)pktdata;
|
const unsigned char *d = (const unsigned char *)pktdata;
|
||||||
unsigned const char *hnaddr = 0;
|
const unsigned char *hnaddr = NULL;
|
||||||
int hnlen = 0;
|
int hnlen = 0;
|
||||||
|
|
||||||
while (ptr + 8 < pktlen) {
|
while (ptr + 8 < pktlen) {
|
||||||
/* Search for specific Extensions sequence */
|
|
||||||
if (d[ptr] == '\0' && d[ptr+1] == '\0' && d[ptr+2] == '\0' &&
|
if (d[ptr] == '\0' && d[ptr+1] == '\0' && d[ptr+2] == '\0' &&
|
||||||
d[ptr+4] == '\0' && d[ptr+6] == '\0' && d[ptr+7] == '\0' &&
|
d[ptr+4] == '\0' && d[ptr+6] == '\0' && d[ptr+7] == '\0' &&
|
||||||
/* Check Extension length, Server Name list length
|
|
||||||
* and Server Name length relations
|
|
||||||
*/
|
|
||||||
d[ptr+3] - d[ptr+5] == 2 && d[ptr+5] - d[ptr+8] == 3)
|
d[ptr+3] - d[ptr+5] == 2 && d[ptr+5] - d[ptr+8] == 3)
|
||||||
{
|
{
|
||||||
if (ptr + 8 + d[ptr+8] > pktlen) {
|
hnaddr = &d[ptr+9];
|
||||||
return FALSE;
|
hnlen = d[ptr+8];
|
||||||
}
|
|
||||||
hnaddr = &d[ptr+9];
|
if (ptr + 8 + hnlen > pktlen || hnlen < 3 || hnlen > HOST_MAXLEN) {
|
||||||
hnlen = d[ptr+8];
|
return FALSE;
|
||||||
/* Limit hostname size up to 253 bytes */
|
|
||||||
if (hnlen < 3 || hnlen > HOST_MAXLEN) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Validate that hostname has only ascii lowercase characters */
|
|
||||||
for (int i=0; i<hnlen; i++) {
|
|
||||||
if (!( (hnaddr[i] >= '0' && hnaddr[i] <= '9') ||
|
|
||||||
(hnaddr[i] >= 'a' && hnaddr[i] <= 'z') ||
|
|
||||||
hnaddr[i] == '.' || hnaddr[i] == '-'))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*hostnameaddr = (char*)hnaddr;
|
|
||||||
*hostnamelen = (unsigned int)hnlen;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < hnlen; i++) {
|
||||||
|
if (!((hnaddr[i] >= '0' && hnaddr[i] <= '9') ||
|
||||||
|
(hnaddr[i] >= 'a' && hnaddr[i] <= 'z') ||
|
||||||
|
hnaddr[i] == '.' || hnaddr[i] == '-'))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*hostnameaddr = (char*)hnaddr;
|
||||||
|
*hostnamelen = (unsigned int)hnlen;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned int size) {
|
static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned int size) {
|
||||||
if (size >= 1 && size <= 0xFFFFu) {
|
if (size >= 1 && size <= 0xFFFFu) {
|
||||||
ppTcpHdr->Window = htons((u_short)size);
|
ppTcpHdr->Window = htons((u_short)size);
|
||||||
|
|
@ -441,118 +437,107 @@ static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned
|
||||||
|
|
||||||
/* HTTP method end without trailing space */
|
/* HTTP method end without trailing space */
|
||||||
static const char *find_http_method_end(const char *pkt, unsigned int http_frag, int *is_fragmented) {
|
static const char *find_http_method_end(const char *pkt, unsigned int http_frag, int *is_fragmented) {
|
||||||
|
const char *method_end = NULL;
|
||||||
|
int fragmented = 0;
|
||||||
|
|
||||||
switch (*pkt) {
|
switch (*pkt) {
|
||||||
case 'G':
|
case 'G':
|
||||||
if (strncmp(pkt, "GET", 3) == 0) {
|
if (strncmp(pkt, "GET", 3) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 3;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 3;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if (strncmp(pkt, "POST", 4) == 0) {
|
if (strncmp(pkt, "POST", 4) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 4;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 4;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
if (strncmp(pkt, "HEAD", 4) == 0) {
|
if (strncmp(pkt, "HEAD", 4) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 4;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 4;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
if (strncmp(pkt, "OPTIONS", 7) == 0) {
|
if (strncmp(pkt, "OPTIONS", 7) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 7;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 7;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
if (strncmp(pkt, "DELETE", 6) == 0) {
|
if (strncmp(pkt, "DELETE", 6) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 6;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 6;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
if (strncmp(pkt, "TRACE", 5) == 0) {
|
if (strncmp(pkt, "TRACE", 5) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 5;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 5;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (strncmp(pkt, "CONNECT", 7) == 0) {
|
if (strncmp(pkt, "CONNECT", 7) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + 7;
|
||||||
*is_fragmented = 0;
|
|
||||||
return pkt + 7;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Try to find HTTP method in a second part of fragmented packet */
|
break;
|
||||||
if ((http_frag == 1 || http_frag == 2)) {
|
}
|
||||||
switch (*pkt) {
|
|
||||||
case 'E':
|
if (method_end == NULL && (http_frag == 1 || http_frag == 2)) {
|
||||||
if (strncmp(pkt, "ET", http_frag) == 0) {
|
switch (*pkt) {
|
||||||
if (is_fragmented)
|
case 'E':
|
||||||
*is_fragmented = 1;
|
if (strncmp(pkt, "ET", http_frag) == 0) {
|
||||||
return pkt + http_frag - 1;
|
method_end = pkt + http_frag - 1;
|
||||||
}
|
fragmented = 1;
|
||||||
break;
|
}
|
||||||
case 'S':
|
break;
|
||||||
if (strncmp(pkt, "ST", http_frag) == 0) {
|
case 'S':
|
||||||
if (is_fragmented)
|
if (strncmp(pkt, "ST", http_frag) == 0) {
|
||||||
*is_fragmented = 1;
|
method_end = pkt + http_frag - 1;
|
||||||
return pkt + http_frag - 1;
|
fragmented = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
if (strncmp(pkt, "AD", http_frag) == 0) {
|
if (strncmp(pkt, "AD", http_frag) == 0) {
|
||||||
if (is_fragmented)
|
method_end = pkt + http_frag - 1;
|
||||||
*is_fragmented = 1;
|
fragmented = 1;
|
||||||
return pkt + http_frag - 1;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case 'N':
|
||||||
case 'N':
|
if (strncmp(pkt, "NS", http_frag) == 0) {
|
||||||
if (strncmp(pkt, "NS", http_frag) == 0) {
|
method_end = pkt + http_frag - 1;
|
||||||
if (is_fragmented)
|
fragmented = 1;
|
||||||
*is_fragmented = 1;
|
}
|
||||||
return pkt + http_frag - 1;
|
break;
|
||||||
}
|
case 'L':
|
||||||
break;
|
if (strncmp(pkt, "LE", http_frag) == 0) {
|
||||||
case 'L':
|
method_end = pkt + http_frag - 1;
|
||||||
if (strncmp(pkt, "LE", http_frag) == 0) {
|
fragmented = 1;
|
||||||
if (is_fragmented)
|
}
|
||||||
*is_fragmented = 1;
|
break;
|
||||||
return pkt + http_frag - 1;
|
case 'R':
|
||||||
}
|
if (strncmp(pkt, "RACE", http_frag + 1) == 0) {
|
||||||
break;
|
method_end = pkt + http_frag - 1;
|
||||||
case 'R':
|
fragmented = 1;
|
||||||
if (strncmp(pkt, "RACE", http_frag + 1) == 0) {
|
}
|
||||||
if (is_fragmented)
|
break;
|
||||||
*is_fragmented = 1;
|
case 'O':
|
||||||
return pkt + http_frag - 1;
|
if (strncmp(pkt, "ONNECT", http_frag + 1) == 0) {
|
||||||
}
|
method_end = pkt + http_frag - 1;
|
||||||
break;
|
fragmented = 1;
|
||||||
case 'O':
|
}
|
||||||
if (strncmp(pkt, "ONNECT", http_frag + 1) == 0) {
|
break;
|
||||||
if (is_fragmented)
|
default:
|
||||||
*is_fragmented = 1;
|
break;
|
||||||
return pkt + http_frag - 1;
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
if (method_end != NULL && is_fragmented != NULL) {
|
||||||
return NULL;
|
*is_fragmented = fragmented;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
return method_end;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Fragment and send the packet.
|
/** Fragment and send the packet.
|
||||||
*
|
*
|
||||||
* This function cuts off the end of the packet (step=0) or
|
* This function cuts off the end of the packet (step=0) or
|
||||||
|
|
@ -575,36 +560,33 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(step) {
|
if (step == 0) {
|
||||||
case 0:
|
if (packet_v4)
|
||||||
if (packet_v4)
|
ppIpHdr->Length = htons(
|
||||||
ppIpHdr->Length = htons(
|
ntohs(ppIpHdr->Length) -
|
||||||
ntohs(ppIpHdr->Length) -
|
packet_dataLen + fragment_size
|
||||||
packet_dataLen + fragment_size
|
);
|
||||||
);
|
else if (packet_v6)
|
||||||
else if (packet_v6)
|
ppIpV6Hdr->Length = htons(
|
||||||
ppIpV6Hdr->Length = htons(
|
ntohs(ppIpV6Hdr->Length) -
|
||||||
ntohs(ppIpV6Hdr->Length) -
|
packet_dataLen + fragment_size
|
||||||
packet_dataLen + fragment_size
|
);
|
||||||
);
|
packetLen = packetLen - packet_dataLen + fragment_size;
|
||||||
packetLen = packetLen - packet_dataLen + fragment_size;
|
} else if (step == 1) {
|
||||||
break;
|
if (packet_v4)
|
||||||
case 1:
|
ppIpHdr->Length = htons(
|
||||||
if (packet_v4)
|
ntohs(ppIpHdr->Length) - fragment_size
|
||||||
ppIpHdr->Length = htons(
|
);
|
||||||
ntohs(ppIpHdr->Length) - fragment_size
|
else if (packet_v6)
|
||||||
);
|
ppIpV6Hdr->Length = htons(
|
||||||
else if (packet_v6)
|
ntohs(ppIpV6Hdr->Length) - fragment_size
|
||||||
ppIpV6Hdr->Length = htons(
|
);
|
||||||
ntohs(ppIpV6Hdr->Length) - fragment_size
|
memmove(packet_data,
|
||||||
);
|
(char*)packet_data + fragment_size,
|
||||||
memmove(packet_data,
|
packet_dataLen - fragment_size);
|
||||||
(char*)packet_data + fragment_size,
|
packetLen -= fragment_size;
|
||||||
packet_dataLen - fragment_size);
|
|
||||||
packetLen -= fragment_size;
|
|
||||||
|
|
||||||
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size);
|
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr.IPChecksum = 0;
|
addr.IPChecksum = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue