Make probes work even in the face of arbitrary data

This commit is contained in:
Ondřej Kuzník 2013-09-23 23:30:31 +01:00 committed by Yves Rutschle
parent ce170814f5
commit 708c3b0177
1 changed files with 37 additions and 23 deletions

60
probe.c
View File

@ -125,7 +125,7 @@ void hexdump(const char *mem, unsigned int len)
/* Is the buffer the beginning of an SSH connection? */
static int is_ssh_protocol(const char *p, int len, struct proto *proto)
{
if (!strncmp(p, "SSH-", 4)) {
if (len >= 4 && !strncmp(p, "SSH-", 4)) {
return 1;
}
return 0;
@ -143,8 +143,12 @@ static int is_ssh_protocol(const char *p, int len, struct proto *proto)
*/
static int is_openvpn_protocol (const char*p,int len, struct proto *proto)
{
int packet_len = ntohs(*(uint16_t*)p);
int packet_len;
if (len < 2)
return 0;
packet_len = ntohs(*(uint16_t*)p);
return packet_len == len - 2;
}
@ -153,6 +157,9 @@ static int is_openvpn_protocol (const char*p,int len, struct proto *proto)
* */
static int is_tinc_protocol( const char *p, int len, struct proto *proto)
{
if (len < 2)
return 0;
return !strncmp(p, "0 ", 2);
}
@ -162,37 +169,47 @@ static int is_tinc_protocol( const char *p, int len, struct proto *proto)
* */
static int is_xmpp_protocol( const char *p, int len, struct proto *proto)
{
return strstr(p, "jabber") ? 1 : 0;
return memmem(p, len, "jabber", 6) ? 1 : 0;
}
static int probe_http_method(const char *p, const char *opt)
static int probe_http_method(const char *p, int len, const char *opt)
{
return !strcmp(p, opt);
if (len < strlen(opt))
return 0;
return !strncmp(p, opt, len);
}
/* Is the buffer the beginning of an HTTP connection? */
static int is_http_protocol(const char *p, int len, struct proto *proto)
{
/* If it's got HTTP in the request (HTTP/1.1) then it's HTTP */
if (strstr(p, "HTTP"))
if (memmem(p, len, "HTTP", 4))
return 1;
#define PROBE_HTTP_METHOD(opt) if (probe_http_method(p, len, opt)) return 1
/* Otherwise it could be HTTP/1.0 without version: check if it's got an
* HTTP method (RFC2616 5.1.1) */
probe_http_method(p, "OPTIONS");
probe_http_method(p, "GET");
probe_http_method(p, "HEAD");
probe_http_method(p, "POST");
probe_http_method(p, "PUT");
probe_http_method(p, "DELETE");
probe_http_method(p, "TRACE");
probe_http_method(p, "CONNECT");
PROBE_HTTP_METHOD("OPTIONS");
PROBE_HTTP_METHOD("GET");
PROBE_HTTP_METHOD("HEAD");
PROBE_HTTP_METHOD("POST");
PROBE_HTTP_METHOD("PUT");
PROBE_HTTP_METHOD("DELETE");
PROBE_HTTP_METHOD("TRACE");
PROBE_HTTP_METHOD("CONNECT");
#undef PROBE_HTTP_METHOD
return 0;
}
static int is_tls_protocol(const char *p, int len, struct proto *proto)
{
if (len < 3)
return 0;
/* TLS packet starts with a record "Hello" (0x16), followed by version
* (0x03 0x00-0x03) (RFC6101 A.1)
* This means we reject SSLv2 and lower, which is actually a good thing (RFC6176)
@ -202,16 +219,13 @@ static int is_tls_protocol(const char *p, int len, struct proto *proto)
static int regex_probe(const char *p, int len, struct proto *proto)
{
regex_t** probe_list = (regex_t**)(proto->data);
int i=0;
regex_t **probe = proto->data;
regmatch_t pos = { 0, len };
while (probe_list[i]) {
if (!regexec(probe_list[i], p, 0, NULL, 0)) {
return 1;
}
i++;
}
return 0;
for (; *probe && regexec(*probe, p, 0, &pos, REG_STARTEND); probe++)
/* try them all */;
return (probe != NULL);
}
/*