diff --git a/probe.c b/probe.c index fa34f96..d2b3477 100644 --- a/probe.c +++ b/probe.c @@ -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); } /*