[sslh] [PATCH 01/10] Make probes work even in the face of arbitrary data
ondra+sslh at mistotebe.net
ondra+sslh at mistotebe.net
Tue Sep 24 00:30:31 CEST 2013
From: Ondřej Kuzník <ondra at mistotebe.net>
---
probe.c | 60 +++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 37 insertions(+), 23 deletions(-)
diff --git a/probe.c b/probe.c
index d693797..25a1f27 100644
--- a/probe.c
+++ b/probe.c
@@ -124,7 +124,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;
@@ -142,8 +142,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;
}
@@ -152,6 +156,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);
}
@@ -161,37 +168,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)
@@ -201,16 +218,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);
}
/*
--
1.8.4.rc3
More information about the sslh
mailing list