mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-14 08:07:14 +03:00
Make probes work even in the face of arbitrary data
This commit is contained in:
parent
ce170814f5
commit
708c3b0177
60
probe.c
60
probe.c
@ -125,7 +125,7 @@ void hexdump(const char *mem, unsigned int len)
|
|||||||
/* Is the buffer the beginning of an SSH connection? */
|
/* Is the buffer the beginning of an SSH connection? */
|
||||||
static int is_ssh_protocol(const char *p, int len, struct proto *proto)
|
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 1;
|
||||||
}
|
}
|
||||||
return 0;
|
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)
|
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;
|
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)
|
static int is_tinc_protocol( const char *p, int len, struct proto *proto)
|
||||||
{
|
{
|
||||||
|
if (len < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return !strncmp(p, "0 ", 2);
|
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)
|
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? */
|
/* Is the buffer the beginning of an HTTP connection? */
|
||||||
static int is_http_protocol(const char *p, int len, struct proto *proto)
|
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 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;
|
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
|
/* Otherwise it could be HTTP/1.0 without version: check if it's got an
|
||||||
* HTTP method (RFC2616 5.1.1) */
|
* HTTP method (RFC2616 5.1.1) */
|
||||||
probe_http_method(p, "OPTIONS");
|
PROBE_HTTP_METHOD("OPTIONS");
|
||||||
probe_http_method(p, "GET");
|
PROBE_HTTP_METHOD("GET");
|
||||||
probe_http_method(p, "HEAD");
|
PROBE_HTTP_METHOD("HEAD");
|
||||||
probe_http_method(p, "POST");
|
PROBE_HTTP_METHOD("POST");
|
||||||
probe_http_method(p, "PUT");
|
PROBE_HTTP_METHOD("PUT");
|
||||||
probe_http_method(p, "DELETE");
|
PROBE_HTTP_METHOD("DELETE");
|
||||||
probe_http_method(p, "TRACE");
|
PROBE_HTTP_METHOD("TRACE");
|
||||||
probe_http_method(p, "CONNECT");
|
PROBE_HTTP_METHOD("CONNECT");
|
||||||
|
|
||||||
|
#undef PROBE_HTTP_METHOD
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_tls_protocol(const char *p, int len, struct proto *proto)
|
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
|
/* TLS packet starts with a record "Hello" (0x16), followed by version
|
||||||
* (0x03 0x00-0x03) (RFC6101 A.1)
|
* (0x03 0x00-0x03) (RFC6101 A.1)
|
||||||
* This means we reject SSLv2 and lower, which is actually a good thing (RFC6176)
|
* 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)
|
static int regex_probe(const char *p, int len, struct proto *proto)
|
||||||
{
|
{
|
||||||
regex_t** probe_list = (regex_t**)(proto->data);
|
regex_t **probe = proto->data;
|
||||||
int i=0;
|
regmatch_t pos = { 0, len };
|
||||||
|
|
||||||
while (probe_list[i]) {
|
for (; *probe && regexec(*probe, p, 0, &pos, REG_STARTEND); probe++)
|
||||||
if (!regexec(probe_list[i], p, 0, NULL, 0)) {
|
/* try them all */;
|
||||||
return 1;
|
|
||||||
}
|
return (probe != NULL);
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user