aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/protocols')
-rw-r--r--src/lib/protocols/amazon_video.c43
-rw-r--r--src/lib/protocols/dns.c4
-rw-r--r--src/lib/protocols/ftp_control.c426
-rw-r--r--src/lib/protocols/http.c163
-rw-r--r--src/lib/protocols/iec60870-5-104.c18
-rw-r--r--src/lib/protocols/irc.c3
-rw-r--r--src/lib/protocols/kerberos.c283
-rw-r--r--src/lib/protocols/mail_smtp.c84
-rw-r--r--src/lib/protocols/ntp.c2
-rw-r--r--src/lib/protocols/smpp.c2
-rw-r--r--src/lib/protocols/ssh.c2
-rw-r--r--src/lib/protocols/telnet.c33
-rw-r--r--src/lib/protocols/tls.c21
13 files changed, 461 insertions, 623 deletions
diff --git a/src/lib/protocols/amazon_video.c b/src/lib/protocols/amazon_video.c
index 41356d9ad..e92c87ad5 100644
--- a/src/lib/protocols/amazon_video.c
+++ b/src/lib/protocols/amazon_video.c
@@ -1,7 +1,7 @@
/*
* amazon_video.c
*
- * Copyright (C) 2018 by ntop.org
+ * Copyright (C) 2018-19 by ntop.org
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -28,37 +28,36 @@
#include "ndpi_api.h"
static void ndpi_check_amazon_video(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow) {
-
+ struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
NDPI_LOG_DBG(ndpi_struct, "search Amazon Prime\n");
- if((packet->tcp != NULL) &&
- (packet->payload[0] == 0xFE &&
- packet->payload[1] == 0xED &&
- packet->payload[2] == 0xFA &&
- packet->payload[3] == 0xCE))
- {
+ if(packet->payload_packet_len > 4) {
+ if((packet->tcp != NULL) &&
+ (packet->payload[0] == 0xFE &&
+ packet->payload[1] == 0xED &&
+ packet->payload[2] == 0xFA &&
+ packet->payload[3] == 0xCE)) {
NDPI_LOG_INFO(ndpi_struct, "found Amazon Video on TCP\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AMAZON_VIDEO, NDPI_PROTOCOL_UNKNOWN);
return;
- }
- else if((packet->udp != NULL) &&
- (packet->payload[0] == 0xDE &&
- packet->payload[1] == 0xAD &&
- packet->payload[2] == 0xBE &&
- packet->payload[3] == 0xEF))
- {
+ } else if((packet->udp != NULL) &&
+ (packet->payload[0] == 0xDE &&
+ packet->payload[1] == 0xAD &&
+ packet->payload[2] == 0xBE &&
+ packet->payload[3] == 0xEF)) {
NDPI_LOG_INFO(ndpi_struct, "found Amazon Video on UDP\n");
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_AMAZON_VIDEO, NDPI_PROTOCOL_UNKNOWN);
- } else {
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
+ }
}
+
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
-void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
-{
+void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
NDPI_LOG_DBG(ndpi_struct, "search amazon_video\n");
@@ -69,8 +68,8 @@ void ndpi_search_amazon_video(struct ndpi_detection_module_struct *ndpi_struct,
}
-void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
-{
+void init_amazon_video_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
ndpi_set_bitmask_protocol_detection("AMAZON_VIDEO", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_AMAZON_VIDEO,
ndpi_search_amazon_video,
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index 7051b2227..3fbb39915 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -47,7 +47,9 @@ static u_int16_t get16(int *i, const u_int8_t *payload) {
/* *********************************************** */
static u_int getNameLength(u_int i, const u_int8_t *payload, u_int payloadLen) {
- if(payload[i] == 0x00)
+ if(i >= payloadLen)
+ return(0);
+ else if(payload[i] == 0x00)
return(1);
else if(payload[i] == 0xC0)
return(2);
diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c
index 135096743..2fbbece28 100644
--- a/src/lib/protocols/ftp_control.c
+++ b/src/lib/protocols/ftp_control.c
@@ -553,411 +553,21 @@ static int ndpi_ftp_control_check_response(struct ndpi_flow_struct *flow,
printf("%s() [%s]\n", __FUNCTION__, payload);
#endif
- if(ndpi_match_strprefix(payload, payload_len, "110-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "120-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "125-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "150-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "202-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "211-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "212-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "213-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "214-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "215-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "220-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "221-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "225-")) {
- return 1;
- }
+ if(payload_len == 0) return(1);
- if(ndpi_match_strprefix(payload, payload_len, "226-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "227-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "228-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "229-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "230-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "231-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "232-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "250-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "257-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "331-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "332-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "350-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "421-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "425-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "426-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "430-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "434-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "450-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "451-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "452-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "501-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "502-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "503-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "504-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "530-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "532-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "550-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "551-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "552-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "553-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "631-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "632-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "633-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10054-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10060-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10061-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10066-")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10068-")) {
- return 1;
- }
+ switch(payload[0]) {
+ case '1':
+ case '2':
+ case '3':
+ case '6':
+ return(1);
+ break;
- if(ndpi_match_strprefix(payload, payload_len, "110 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "120 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "125 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "150 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "202 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "211 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "212 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "213 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "214 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "215 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "220 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "221 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "225 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "226 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "227 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "228 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "229 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "230 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "231 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "232 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "250 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "257 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "331 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "332 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "350 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "421 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "425 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "426 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "430 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "434 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "450 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "451 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "452 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "501 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "502 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "503 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "504 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "530 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "532 ")) {
- return 1;
- }
- if(ndpi_match_strprefix(payload, payload_len, "550 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "551 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "552 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "553 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "631 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "632 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "633 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10054 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10060 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10061 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10066 ")) {
- return 1;
- }
-
- if(ndpi_match_strprefix(payload, payload_len, "10068 ")) {
- return 1;
+ case '4':
+ case '5':
+ flow->protos.ftp_imap_pop_smtp.auth_failed = 1;
+ return(1);
+ break;
}
return 0;
@@ -972,8 +582,10 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
/* Check connection over TCP */
if(packet->tcp) {
+ u_int16_t twentyfive = htons(25);
+
/* Exclude SMTP, which uses similar commands. */
- if(packet->tcp->dest == htons(25) || packet->tcp->source == htons(25)) {
+ if(packet->tcp->dest == twentyfive || packet->tcp->source == twentyfive) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
}
@@ -988,8 +600,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
if(flow->ftp_control_stage == 0) {
NDPI_LOG_DBG2(ndpi_struct, "FTP_CONTROL stage 0: \n");
- if((payload_len > 0)
- && ndpi_ftp_control_check_request(flow, packet->payload, payload_len)) {
+ if((payload_len > 0) && ndpi_ftp_control_check_request(flow, packet->payload, payload_len)) {
NDPI_LOG_DBG2(ndpi_struct,
"Possible FTP_CONTROL request detected, we will look further for the response..\n");
@@ -1011,8 +622,7 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
}
/* This is a packet in another direction. Check if we find the proper response. */
- if((payload_len > 0)
- && ndpi_ftp_control_check_response(flow, packet->payload, payload_len)) {
+ if((payload_len > 0) && ndpi_ftp_control_check_response(flow, packet->payload, payload_len)) {
NDPI_LOG_INFO(ndpi_struct, "found FTP_CONTROL\n");
#ifdef FTP_DEBUG
diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c
index 2525cfbd7..70ca0c389 100644
--- a/src/lib/protocols/http.c
+++ b/src/lib/protocols/http.c
@@ -33,7 +33,8 @@ static void ndpi_search_http_tcp(struct ndpi_detection_module_struct *ndpi_struc
/* *********************************************** */
-static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
ndpi_search_http_tcp(ndpi_struct, flow);
#ifdef HTTP_DEBUG
@@ -52,9 +53,46 @@ static int ndpi_search_http_tcp_again(struct ndpi_detection_module_struct *ndpi_
/* *********************************************** */
+/* https://www.freeformatter.com/mime-types-list.html */
+static ndpi_protocol_category_t ndpi_http_check_content(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
+ struct ndpi_packet_struct *packet = &flow->packet;
+
+ if(packet->content_line.len > 0) {
+ u_int app_len = sizeof("application");
+
+ if(packet->content_line.len > app_len) {
+ if(ndpi_strncasestr((const char *)&packet->content_line.ptr[app_len], "mpeg",
+ packet->content_line.len-app_len) != NULL) {
+ flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_STREAMING;
+ return(flow->category);
+ }
+ }
+
+ switch(packet->content_line.ptr[0]) {
+ case 'a':
+ if(strncasecmp((const char *)packet->content_line.ptr, "audio",
+ ndpi_min(packet->content_line.len, 5)) == 0)
+ flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA;
+ break;
+
+ case 'v':
+ if(strncasecmp((const char *)packet->content_line.ptr, "video",
+ ndpi_min(packet->content_line.len, 5)) == 0)
+ flow->guessed_category = flow->category = NDPI_PROTOCOL_CATEGORY_MEDIA;
+ break;
+ }
+ }
+
+ return(flow->category);
+}
+
+/* *********************************************** */
+
static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- u_int16_t category) {
+ u_int16_t http_protocol,
+ ndpi_protocol_category_t category) {
#ifdef HTTP_DEBUG
printf("=> %s()\n", __FUNCTION__);
#endif
@@ -66,30 +104,36 @@ static void ndpi_int_http_add_connection(struct ndpi_detection_module_struct *nd
ndpi_search_tcp_or_udp(ndpi_struct, flow);
/* If no custom protocol has been detected */
- if(flow->guessed_host_protocol_id != NDPI_PROTOCOL_UNKNOWN) {
- ndpi_int_reset_protocol(flow);
- ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP);
- } else
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN);
+ if((flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN) || (http_protocol != NDPI_PROTOCOL_HTTP))
+ flow->guessed_host_protocol_id = http_protocol;
+
+ category = ndpi_http_check_content(ndpi_struct, flow);
+ ndpi_int_reset_protocol(flow);
+ ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_host_protocol_id, NDPI_PROTOCOL_HTTP);
/* This is necessary to inform the core to call this dissector again */
flow->check_extra_packets = 1;
flow->max_extra_packets_to_check = 5;
flow->extra_packets_func = ndpi_search_http_tcp_again;
- flow->http_detected = 1, flow->guessed_category = category;
+ flow->http_detected = 1, flow->guessed_category = flow->category = category;
}
+/* ************************************************************* */
+
static void rtsp_parse_packet_acceptline(struct ndpi_detection_module_struct
*ndpi_struct, struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct *packet = &flow->packet;
- if(packet->accept_line.len >= 28 && memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0) {
+ if((packet->accept_line.len >= 28)
+ && (memcmp(packet->accept_line.ptr, "application/x-rtsp-tunnelled", 28) == 0)) {
NDPI_LOG_INFO(ndpi_struct, "found RTSP accept line\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_RTSP, NDPI_PROTOCOL_CATEGORY_MEDIA);
}
}
+/* ************************************************************* */
+
static void setHttpUserAgent(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, char *ua) {
if ( !strcmp(ua, "Windows NT 5.0")) ua = "Windows 2000";
@@ -110,7 +154,10 @@ static void setHttpUserAgent(struct ndpi_detection_module_struct *ndpi_struct,
}
}
-static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
+/* ************************************************************* */
+
+static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
if((flow->l4.tcp.http_stage == 0) || (flow->http.url && flow->http_detected)) {
char *double_col = strchr((char*)flow->host_server_name, ':');
ndpi_protocol_match_result ret_match;
@@ -124,13 +171,14 @@ static void parseHttpSubprotocol(struct ndpi_detection_module_struct *ndpi_struc
}
}
+/* ************************************************************* */
+
/**
NOTE
ndpi_parse_packet_line_info is in ndpi_main.c
*/
static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
-
struct ndpi_packet_struct *packet = &flow->packet;
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_UNKNOWN);
@@ -142,13 +190,12 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
/* PPStream */
if(flow->l4.tcp.ppstream_stage > 0 && flow->iqiyi_counter == 0) {
NDPI_LOG_INFO(ndpi_struct, "found PPStream\n");
- /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM); */
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM, NDPI_PROTOCOL_HTTP);
- }
- else if(flow->iqiyi_counter > 0) {
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_PPSTREAM,
+ NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_STREAMING);
+ } else if(flow->iqiyi_counter > 0) {
NDPI_LOG_INFO(ndpi_struct, "found iQiyi\n");
- /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI); */
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI, NDPI_PROTOCOL_HTTP);
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IQIYI,
+ NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_STREAMING);
}
#endif
@@ -156,8 +203,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
/* 1KXUN */
if(flow->kxun_counter > 0) {
NDPI_LOG_INFO(ndpi_struct, "found 1kxun\n");
- /* ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN); */
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN, NDPI_PROTOCOL_HTTP);
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_1KXUN, NDPI_PROTOCOL_CATEGORY_STREAMING);
}
#endif
@@ -257,10 +303,9 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
setHttpUserAgent(ndpi_struct, flow, token);
}
}
- }
- else if(memcmp(ua, "netflix-ios-app", 15) == 0) {
+ } else if(memcmp(ua, "netflix-ios-app", 15) == 0) {
NDPI_LOG_INFO(ndpi_struct, "found netflix\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLIX);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_NETFLIX, NDPI_PROTOCOL_CATEGORY_STREAMING);
return;
}
}
@@ -287,17 +332,6 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
NDPI_LOG_DBG2(ndpi_struct, "HOST line found %.*s\n",
packet->host_line.len, packet->host_line.ptr);
- /* call ndpi_match_host_subprotocol to see if there is a match with known-host HTTP subprotocol */
- if(flow->http_detected) {
- ndpi_protocol_match_result ret_match;
-
- ndpi_match_host_subprotocol(ndpi_struct, flow,
- (char*)packet->host_line.ptr,
- packet->host_line.len,
- &ret_match,
- NDPI_PROTOCOL_HTTP);
- }
-
/* Copy result for nDPI apps */
if(!ndpi_struct->disable_metadata_export) {
len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1);
@@ -316,7 +350,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
}
}
- parseHttpSubprotocol(ndpi_struct, flow);
+ ndpi_http_parse_subprotocol(ndpi_struct, flow);
/**
check result of host subprotocol detection
@@ -355,7 +389,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) {
NDPI_LOG_INFO(ndpi_struct, "found HTTP/%s\n",
ndpi_get_proto_name(ndpi_struct, packet->detected_protocol_stack[0]));
- ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]);
+ ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0], NDPI_PROTOCOL_CATEGORY_WEB);
return; /* We have identified a sub-protocol so we're done */
}
}
@@ -363,7 +397,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
#if 0
if(flow->http_detected)
- parseHttpSubprotocol(ndpi_struct, flow);
+ ndpi_http_parse_subprotocol(ndpi_struct, flow);
#endif
if(flow->guessed_protocol_id == NDPI_PROTOCOL_UNKNOWN)
@@ -385,7 +419,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
if((flow->http.content_type == NULL) && (packet->content_line.len > 0)) {
int len = packet->content_line.len + 1;
-
+
flow->http.content_type = ndpi_malloc(len);
if(flow->http.content_type) {
strncpy(flow->http.content_type, (char*)packet->content_line.ptr,
@@ -393,7 +427,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
flow->http.content_type[packet->content_line.len] = '\0';
}
}
-
+
if(flow->http_detected) {
ndpi_protocol_match_result ret_match;
@@ -403,13 +437,17 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_
}
}
- ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]);
+ ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0], NDPI_PROTOCOL_CATEGORY_WEB);
}
+/* ************************************************************* */
+
static void check_http_payload(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
/* Add here your paylod code check */
}
+/* ************************************************************* */
+
/**
* Functions to check whether the packet begins with a valid http request
* @param ndpi_struct
@@ -446,7 +484,7 @@ static u_int16_t http_request_url_offset(struct ndpi_detection_module_struct *nd
packet->payload_packet_len);
/* Check first char */
- if(!strchr(http_fs,packet->payload[0])) return 0;
+ if(!packet->payload_packet_len || !strchr(http_fs,packet->payload[0])) return 0;
/**
FIRST PAYLOAD PACKET FROM CLIENT
**/
@@ -540,7 +578,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
</cross-domain-policy>
*/
ookla_found:
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_UNKNOWN);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_OOKLA, NDPI_PROTOCOL_CATEGORY_WEB);
if(ndpi_struct->ookla_cache == NULL)
ndpi_struct->ookla_cache = ndpi_lru_cache_init(1024);
@@ -604,34 +642,12 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
goto ookla_found;
}
-#if OBSOLETE
- /* Check for additional field introduced by Steam */
- int x = 1;
- if(packet->line[x].len >= 11 && (memcmp(packet->line[x].ptr, "x-steam-sid", 11)) == 0) {
- NDPI_LOG_INFO(ndpi_struct, "found STEAM\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_STEAM);
- check_content_type_and_change_protocol(ndpi_struct, flow);
- return;
- }
-
- /* Check for additional field introduced by Facebook */
- x = 1;
- while(packet->line[x].len != 0) {
- if(packet->line[x].len >= 12 && (memcmp(packet->line[x].ptr, "X-FB-SIM-HNI", 12)) == 0) {
- NDPI_LOG_INFO(ndpi_struct, "found FACEBOOK\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_FACEBOOK);
- check_content_type_and_change_protocol(ndpi_struct, flow);
- return;
- }
- x++;
- }
-#endif
-
#if defined(NDPI_PROTOCOL_1KXUN) || defined(NDPI_PROTOCOL_IQIYI)
/* check PPStream protocol or iQiyi service
(iqiyi is delivered by ppstream) */
// substring in url
- if(ndpi_strnstr((const char*) &packet->payload[filename_start], "iqiyi.com", (packet->payload_packet_len - filename_start)) != NULL) {
+ if(ndpi_strnstr((const char*) &packet->payload[filename_start], "iqiyi.com",
+ (packet->payload_packet_len - filename_start)) != NULL) {
if(flow->kxun_counter == 0) {
flow->l4.tcp.ppstream_stage++;
flow->iqiyi_counter++;
@@ -673,14 +689,14 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
if((packet->http_url_name.len > 7)
&& (!strncmp((const char*) packet->http_url_name.ptr, "http://", 7))) {
NDPI_LOG_INFO(ndpi_struct, "found HTTP_PROXY\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_PROXY, NDPI_PROTOCOL_CATEGORY_WEB);
check_content_type_and_change_protocol(ndpi_struct, flow);
}
if(filename_start == 8 && (memcmp(packet->payload, "CONNECT ", 8) == 0)) {
/* nathan@getoffmalawn.com */
NDPI_LOG_INFO(ndpi_struct, "found HTTP_CONNECT\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP_CONNECT, NDPI_PROTOCOL_CATEGORY_WEB);
check_content_type_and_change_protocol(ndpi_struct, flow);
}
@@ -695,7 +711,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
in 99.99% of the cases is like that.
*/
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB);
flow->http_detected = 1;
NDPI_LOG_DBG2(ndpi_struct,
"HTTP START Found, we will look further for the response...\n");
@@ -723,7 +739,8 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_OOKLA);
/**
- At first check, if this is for sure a response packet (in another direction. If not, if HTTP is detected do nothing now and return,
+ At first check, if this is for sure a response packet
+ (in another direction. If not, if HTTP is detected do nothing now and return,
otherwise check the second packet for the HTTP request
*/
if((flow->l4.tcp.http_stage - packet->packet_direction) == 1) { /* Expected a response package */
@@ -757,7 +774,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
&& memcmp(&packet->line[0].ptr[packet->line[0].len - 9], " HTTP/1.", 8) == 0) {
NDPI_LOG_INFO(ndpi_struct, "found HTTP\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB);
check_content_type_and_change_protocol(ndpi_struct, flow);
NDPI_LOG_DBG2(ndpi_struct,
@@ -779,7 +796,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
if((packet->parsed_lines == 1) && (packet->packet_direction == 1 /* server -> client */)) {
/* In Apache if you do "GET /\n\n" the response comes without any header */
NDPI_LOG_INFO(ndpi_struct, "found HTTP. (apache)\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB);
check_content_type_and_change_protocol(ndpi_struct, flow);
return;
}
@@ -787,7 +804,7 @@ static void ndpi_check_http_tcp(struct ndpi_detection_module_struct *ndpi_struct
/* If we already detected the HTTP request, we can add the connection and then check for the sub-protocol */
if(flow->http_detected) {
NDPI_LOG_INFO(ndpi_struct, "found HTTP\n");
- ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP);
+ ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_HTTP, NDPI_PROTOCOL_CATEGORY_WEB);
}
/* Parse packet line and we look for the subprotocols */
diff --git a/src/lib/protocols/iec60870-5-104.c b/src/lib/protocols/iec60870-5-104.c
index e34ca3d63..040a1842a 100644
--- a/src/lib/protocols/iec60870-5-104.c
+++ b/src/lib/protocols/iec60870-5-104.c
@@ -27,16 +27,16 @@
#include "ndpi_protocol_ids.h"
#include "ndpi_api.h"
-#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_104
+#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_IEC60870
-void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct,
+void ndpi_search_iec60870_tcp(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
- NDPI_LOG_DBG(ndpi_struct, "search 104\n");
- u_int16_t iec104_port = htons(2404); // port used by 104
+ u_int16_t iec104_port = htons(2404); // port used by IEC60870
/* Check connection over TCP */
-
+ NDPI_LOG_DBG(ndpi_struct, "search IEC60870\n");
+
if(packet->tcp) {
/* The start byte of 104 is 0x68
* The usual port: 2404
@@ -44,7 +44,7 @@ void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct,
if((packet->payload[0] == 0x68) &&
((packet->tcp->dest == iec104_port) || (packet->tcp->source == iec104_port)) ){
NDPI_LOG_INFO(ndpi_struct, "found 104\n");
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_104, NDPI_PROTOCOL_UNKNOWN);
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_IEC60870, NDPI_PROTOCOL_UNKNOWN);
return;
}
}
@@ -56,9 +56,9 @@ void ndpi_search_104_tcp(struct ndpi_detection_module_struct *ndpi_struct,
void init_104_dissector(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {
- ndpi_set_bitmask_protocol_detection("104", ndpi_struct, detection_bitmask, *id,
- NDPI_PROTOCOL_104,
- ndpi_search_104_tcp,
+ ndpi_set_bitmask_protocol_detection("IEC60870", ndpi_struct, detection_bitmask, *id,
+ NDPI_PROTOCOL_IEC60870,
+ ndpi_search_iec60870_tcp,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);
diff --git a/src/lib/protocols/irc.c b/src/lib/protocols/irc.c
index ec22ee38b..37cfbe1ed 100644
--- a/src/lib/protocols/irc.c
+++ b/src/lib/protocols/irc.c
@@ -492,9 +492,10 @@ void ndpi_search_irc_tcp(struct ndpi_detection_module_struct *ndpi_struct, struc
ndpi_parse_packet_line_info(ndpi_struct, flow);
} else {
flow->l4.tcp.irc_3a_counter++;
+ packet->parsed_lines = 0;
}
for (i = 0; i < packet->parsed_lines; i++) {
- if (packet->line[i].ptr[0] == ':') {
+ if ((packet->line[i].len > 0) && packet->line[i].ptr[0] == ':') {
flow->l4.tcp.irc_3a_counter++;
if (flow->l4.tcp.irc_3a_counter == 7) { /* ':' == 0x3a */
NDPI_LOG_INFO(ndpi_struct, "found irc. 0x3a. seven times.");
diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c
index 533995604..1eb006108 100644
--- a/src/lib/protocols/kerberos.c
+++ b/src/lib/protocols/kerberos.c
@@ -28,7 +28,9 @@
#include "ndpi_api.h"
-/* #define KERBEROS_DEBUG 1 */
+//#define KERBEROS_DEBUG 1
+
+#define KERBEROS_PORT 88
static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
@@ -41,62 +43,198 @@ static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct
void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
+ u_int16_t sport = packet->tcp ? ntohs(packet->tcp->source) : ntohs(packet->udp->source);
+ u_int16_t dport = packet->tcp ? ntohs(packet->tcp->dest) : ntohs(packet->udp->dest);
+ if((sport != KERBEROS_PORT) && (dport != KERBEROS_PORT)) {
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ return;
+ }
+
NDPI_LOG_DBG(ndpi_struct, "search KERBEROS\n");
+#ifdef KERBEROS_DEBUG
+ printf("\n[Kerberos] Process packet [len: %u]\n", packet->payload_packet_len);
+#endif
+
+ if(flow->kerberos_buf.pktbuf != NULL) {
+ u_int missing = flow->kerberos_buf.pktbuf_maxlen - flow->kerberos_buf.pktbuf_currlen;
+
+ if(packet->payload_packet_len <= missing) {
+ memcpy(&flow->kerberos_buf.pktbuf[flow->kerberos_buf.pktbuf_currlen], packet->payload, packet->payload_packet_len);
+ flow->kerberos_buf.pktbuf_currlen += packet->payload_packet_len;
+
+ if(flow->kerberos_buf.pktbuf_currlen == flow->kerberos_buf.pktbuf_maxlen) {
+ packet->payload = (u_int8_t *)flow->kerberos_buf.pktbuf;
+ packet->payload_packet_len = flow->kerberos_buf.pktbuf_currlen;
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Packet is now full: processing\n");
+#endif
+ } else {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Missing %u bytes: skipping\n",
+ flow->kerberos_buf.pktbuf_maxlen - flow->kerberos_buf.pktbuf_currlen);
+#endif
+
+ return;
+ }
+ }
+ }
+
/* I have observed 0a,0c,0d,0e at packet->payload[19/21], maybe there are other possibilities */
if(packet->payload_packet_len >= 4) {
- u_int32_t kerberos_len = ntohl(get_u_int32_t(packet->payload, 0));
- u_int32_t expected_len = packet->payload_packet_len - 4;
+ u_int32_t kerberos_len, expected_len;
+ u_int16_t base_offset = 0;
+
+ if(packet->tcp) {
+ kerberos_len = ntohl(get_u_int32_t(packet->payload, 0)),
+ expected_len = packet->payload_packet_len - 4;
+ base_offset = 4;
+ } else
+ base_offset = 0, kerberos_len = expected_len = packet->payload_packet_len;
- if(kerberos_len < 1514) {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] [Kerberos len: %u][expected_len: %u]\n", kerberos_len, expected_len);
+#endif
+
+ if(kerberos_len < 12000) {
/*
Kerberos packets might be too long for a TCP packet
so it could be split across two packets. Instead of
rebuilding the stream we use a heuristic approach
*/
- if(kerberos_len >= expected_len) {
+ if(kerberos_len > expected_len) {
+ if(packet->tcp) {
+ flow->kerberos_buf.pktbuf = (char*)ndpi_malloc(kerberos_len+4);
+ if(flow->kerberos_buf.pktbuf != NULL) {
+ flow->kerberos_buf.pktbuf_maxlen = kerberos_len+4;
+ memcpy(flow->kerberos_buf.pktbuf, packet->payload, packet->payload_packet_len);
+ flow->kerberos_buf.pktbuf_currlen = packet->payload_packet_len;
+ }
+ }
+
+ return;
+ } else if(kerberos_len == expected_len) {
if(packet->payload_packet_len > 128) {
- u_int16_t koffset;
+ u_int16_t koffset, i;
- if(packet->payload[14] == 0x05) /* PVNO */
- koffset = 19;
- else
- koffset = 21;
+ for(i=8; i<16; i++)
+ if((packet->payload[base_offset+i] == 0x03)
+ && (packet->payload[base_offset+i+1] == 0x02)
+ && (packet->payload[base_offset+i+2] == 0x01)
+ && (packet->payload[base_offset+i+3] != 0x05)
+ )
+ break;
+
+ koffset = base_offset + i + 3;
- if((packet->payload[koffset] == 0x0a || packet->payload[koffset] == 0x0c || packet->payload[koffset] == 0x0d || packet->payload[koffset] == 0x0e)) {
#ifdef KERBEROS_DEBUG
- printf("[Kerberos] Packet found\n");
+ printf("[Kerberos] [msg-type: 0x%02X/%u][koffset: %u]\n",
+ packet->payload[koffset], packet->payload[koffset], koffset);
+#endif
+
+ if(((packet->payload[koffset] == 0x0A)
+ || (packet->payload[koffset] == 0x0C)
+ || (packet->payload[koffset] == 0x0D)
+ || (packet->payload[koffset] == 0x0E))) {
+ u_int16_t koffsetp, body_offset, pad_len;
+ u_int8_t msg_type = packet->payload[koffset];
+
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Packet found 0x%02X/%u\n", msg_type, msg_type);
+#endif
+ if(msg_type != 0x0d) /* TGS-REP */ {
+ /* Process only on requests */
+ if(packet->payload[koffset+1] == 0xA3) {
+ if(packet->payload[koffset+3] == 0x30)
+ pad_len = packet->payload[koffset+4];
+ else {
+ /* Long pad */
+ pad_len = packet->payload[koffset+2];
+ for(i=3; i<10; i++) if(packet->payload[koffset+i] == pad_len) break;
+
+ pad_len = (packet->payload[koffset+i+1] << 8) + packet->payload[koffset+i+2];
+ koffset += i-2;
+ }
+ } else
+ pad_len = 0;
+
+#ifdef KERBEROS_DEBUG
+ printf("pad_len=0x%02X/%u\n", pad_len, pad_len);
+#endif
+
+ if(pad_len > 0) {
+ koffsetp = koffset + 2;
+ for(i=0; i<4; i++) if(packet->payload[koffsetp] != 0x30) koffsetp++; /* ASN.1 */
+#ifdef KERBEROS_DEBUG
+ printf("koffsetp=%u [%02X %02X] [byte 0 must be 0x30]\n", koffsetp, packet->payload[koffsetp], packet->payload[koffsetp+1]);
+#endif
+ } else
+ koffsetp = koffset;
+
+ body_offset = koffsetp + 1 + pad_len;
+
+ for(i=0; i<10; i++) if(packet->payload[body_offset] != 0x05) body_offset++; /* ASN.1 */
+#ifdef KERBEROS_DEBUG
+ printf("body_offset=%u [%02X %02X] [byte 0 must be 0x05]\n", body_offset, packet->payload[body_offset], packet->payload[body_offset+1]);
+#endif
+ }
+
+ if(msg_type == 0x0A) /* AS-REQ */ {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Processing AS-REQ\n");
#endif
- if(packet->payload[koffset] == 0x0a) /* AS-REQ */ {
- u_int16_t koffsetp, pad_data_len, body_offset;
-
- koffsetp = koffset + 4;
- pad_data_len = packet->payload[koffsetp];
- body_offset = pad_data_len + koffsetp;
if(body_offset < packet->payload_packet_len) {
- u_int name_offset = body_offset + 30;
+ u_int16_t name_offset;
+
+ name_offset = body_offset + 13;
+ for(i=0; i<10; i++) if(packet->payload[name_offset] != 0x1b) name_offset++; /* ASN.1 */
+
+#ifdef KERBEROS_DEBUG
+ printf("name_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", name_offset, packet->payload[name_offset], packet->payload[name_offset+1]);
+#endif
if(name_offset < packet->payload_packet_len) {
- u_int cname_len = packet->payload[name_offset];
+ u_int cname_len;
+
+ name_offset += 1;
+ if(packet->payload[name_offset+1] < ' ') /* Isn't printable ? */
+ name_offset++;
+
+ if(packet->payload[name_offset+1] == 0x1b)
+ name_offset += 2;
+
+ cname_len = packet->payload[name_offset];
if((cname_len+name_offset) < packet->payload_packet_len) {
- u_int realm_len, realm_offset = cname_len + name_offset + 4, i;
- char cname_str[24];
+ u_int realm_len, realm_offset, i;
+ char cname_str[48];
+ u_int8_t num_cname = 0;
- if(cname_len > sizeof(cname_str)-1)
- cname_len = sizeof(cname_str)-1;
+ while(++num_cname <= 2) {
+ if(cname_len > sizeof(cname_str)-1)
+ cname_len = sizeof(cname_str)-1;
- strncpy(cname_str, (char*)&packet->payload[name_offset+1], cname_len);
- cname_str[cname_len] = '\0';
- for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]);
+ strncpy(cname_str, (char*)&packet->payload[name_offset+1], cname_len);
+ cname_str[cname_len] = '\0';
+ for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]);
#ifdef KERBEROS_DEBUG
- printf("[Kerberos Cname][len: %u][%s]\n", cname_len, cname_str);
+ printf("[AS-REQ][s/dport: %u/%u][Kerberos Cname][len: %u][%s]\n",
+ sport, dport, cname_len, cname_str);
#endif
+ if(((strcmp(cname_str, "host") == 0) || (strcmp(cname_str, "ldap") == 0)) && (packet->payload[name_offset+1+cname_len] == 0x1b)) {
+ name_offset += cname_len + 2;
+ cname_len = packet->payload[name_offset];
+ } else
+ break;
+ }
+
+ realm_offset = cname_len + name_offset + 3;
+
/* if cname does not end with a $ then it's a username */
if(cname_len && cname_str[cname_len-1] == '$') {
cname_str[cname_len-1] = '\0';
@@ -104,62 +242,97 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
} else
snprintf(flow->protos.kerberos.username, sizeof(flow->protos.kerberos.username), "%s", cname_str);
+ for(i=0; i<10; i++) if(packet->payload[realm_offset] != 0x1b) name_offset++; /* ASN.1 */
+#ifdef KERBEROS_DEBUG
+ printf("realm_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", realm_offset, packet->payload[realm_offset], packet->payload[realm_offset+1]);
+#endif
+ realm_offset += 1;
+ //if(num_cname == 2) realm_offset++;
realm_len = packet->payload[realm_offset];
if((realm_offset+realm_len) < packet->payload_packet_len) {
- char realm_str[24];
+ char realm_str[48];
if(realm_len > sizeof(realm_str)-1)
realm_len = sizeof(realm_str);
- strncpy(realm_str, (char*)&packet->payload[realm_offset+1], realm_len);
+ realm_offset += 1;
+
+ strncpy(realm_str, (char*)&packet->payload[realm_offset], realm_len);
realm_str[realm_len] = '\0';
for(i=0; i<realm_len; i++) realm_str[i] = tolower(realm_str[i]);
#ifdef KERBEROS_DEBUG
- printf("[Kerberos Realm][len: %u][%s]\n", realm_len, realm_str);
+ printf("[AS-REQ][Kerberos Realm][len: %u][%s]\n", realm_len, realm_str);
#endif
snprintf(flow->protos.kerberos.domain, sizeof(flow->protos.kerberos.domain), "%s", realm_str);
}
}
}
- }
- } else if(packet->payload[koffset] == 0x0c) /* TGS-REQ */ {
- u_int16_t koffsetp, pad_data_len, body_offset;
-
- koffsetp = koffset + 3;
- pad_data_len = ntohs(*((u_int16_t*)&packet->payload[koffsetp]));
- body_offset = pad_data_len + koffsetp + 4;
+ }
+ } else if(msg_type == 0x0c) /* TGS-REQ */ {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Processing TGS-REQ\n");
+#endif
if(body_offset < packet->payload_packet_len) {
- u_int name_offset = body_offset + 14;
+ u_int name_offset, padding_offset = body_offset + 4;
+
+ name_offset = padding_offset;
+ for(i=0; i<10; i++) if(packet->payload[name_offset] != 0x1b) name_offset++; /* ASN.1 */
+
+#ifdef KERBEROS_DEBUG
+ printf("name_offset=%u [%02X %02X] [byte 0 must be 0x1b]\n", name_offset, packet->payload[name_offset], packet->payload[name_offset+1]);
+#endif
if(name_offset < packet->payload_packet_len) {
- u_int realm_len = packet->payload[name_offset];
+ u_int realm_len;
+
+ name_offset++;
+ realm_len = packet->payload[name_offset];
if((realm_len+name_offset) < packet->payload_packet_len) {
u_int i;
- char realm_str[24];
+ char realm_str[48];
if(realm_len > sizeof(realm_str)-1)
realm_len = sizeof(realm_str)-1;
- strncpy(realm_str, (char*)&packet->payload[name_offset+1], realm_len);
+ name_offset += 1;
+
+ strncpy(realm_str, (char*)&packet->payload[name_offset], realm_len);
realm_str[realm_len] = '\0';
for(i=0; i<realm_len; i++) realm_str[i] = tolower(realm_str[i]);
#ifdef KERBEROS_DEBUG
- printf("[Kerberos Realm][len: %u][%s]\n", realm_len, realm_str);
+ printf("[TGS-REQ][s/dport: %u/%u][Kerberos Realm][len: %u][%s]\n", sport, dport, realm_len, realm_str);
#endif
snprintf(flow->protos.kerberos.domain, sizeof(flow->protos.kerberos.domain), "%s", realm_str);
+
+ /* If necessary we can decode sname */
+
+ if(flow->kerberos_buf.pktbuf) ndpi_free(flow->kerberos_buf.pktbuf);
+ flow->kerberos_buf.pktbuf = NULL;
}
}
}
+ if(packet->udp)
+ ndpi_int_kerberos_add_connection(ndpi_struct, flow);
+
/* We set the protocol in the response */
+ if(flow->kerberos_buf.pktbuf != NULL) {
+ free(flow->kerberos_buf.pktbuf);
+ flow->kerberos_buf.pktbuf = NULL;
+ }
+
return;
- } else if(packet->payload[koffset] == 0x0d) /* TGS-RES */ {
+ } else if(msg_type == 0x0d) /* TGS-REP */ {
u_int16_t koffsetp, pad_data_len, cname_offset;
+
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Processing TGS-REP\n");
+#endif
koffsetp = koffset + 4;
pad_data_len = packet->payload[koffsetp];
@@ -170,20 +343,21 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
u_int8_t cname_len = packet->payload[cname_offset];
if((cname_offset+cname_offset) < packet->payload_packet_len) {
- char cname_str[24];
+ char cname_str[48];
u_int i;
-
+
if(cname_len > sizeof(cname_str)-1)
cname_len = sizeof(cname_str)-1;
-
+
strncpy(cname_str, (char*)&packet->payload[cname_offset+1], cname_len);
cname_str[cname_len] = '\0';
for(i=0; i<cname_len; i++) cname_str[i] = tolower(cname_str[i]);
-
+
#ifdef KERBEROS_DEBUG
- printf("[Kerberos Cname][len: %u][%s]\n", cname_len, cname_str);
+ printf("[TGS-REP][s/dport: %u/%u][Kerberos Cname][len: %u][%s]\n",
+ sport, dport, cname_len, cname_str);
#endif
-
+
if(cname_len && cname_str[cname_len-1] == '$') {
cname_str[cname_len-1] = '\0';
snprintf(flow->protos.kerberos.hostname, sizeof(flow->protos.kerberos.hostname), "%s", cname_str);
@@ -194,7 +368,7 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
}
}
}
-
+
return;
}
@@ -208,6 +382,11 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
}
}
} else {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos][s/dport: %u/%u] Skipping packet: too long [kerberos_len: %u]\n",
+ sport, dport, kerberos_len);
+#endif
+
if(flow->protos.kerberos.domain[0] != '\0')
return;
}
@@ -222,7 +401,7 @@ void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_set_bitmask_protocol_detection("Kerberos", ndpi_struct, detection_bitmask, *id,
NDPI_PROTOCOL_KERBEROS,
ndpi_search_kerberos,
- NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);
diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c
index 2cd4657c9..86ff79486 100644
--- a/src/lib/protocols/mail_smtp.c
+++ b/src/lib/protocols/mail_smtp.c
@@ -70,9 +70,9 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_LOG_DBG(ndpi_struct, "search mail_smtp\n");
if((packet->payload_packet_len > 2)
- && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET)
- && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
- ) {
+ && (packet->parsed_lines < NDPI_MAX_PARSE_LINES_PER_PACKET)
+ && (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a)
+ ) {
u_int8_t a;
u_int8_t bit_count = 0;
@@ -97,33 +97,33 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
// expected client requests
if(packet->line[a].len >= 5) {
if((((packet->line[a].ptr[0] == 'H' || packet->line[a].ptr[0] == 'h')
- && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e'))
- || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e')
- && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h')))
- && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l')
- && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o')
- && packet->line[a].ptr[4] == ' ') {
+ && (packet->line[a].ptr[1] == 'E' || packet->line[a].ptr[1] == 'e'))
+ || ((packet->line[a].ptr[0] == 'E' || packet->line[a].ptr[0] == 'e')
+ && (packet->line[a].ptr[1] == 'H' || packet->line[a].ptr[1] == 'h')))
+ && (packet->line[a].ptr[2] == 'L' || packet->line[a].ptr[2] == 'l')
+ && (packet->line[a].ptr[3] == 'O' || packet->line[a].ptr[3] == 'o')
+ && packet->line[a].ptr[4] == ' ') {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_HELO_EHLO;
flow->protos.ftp_imap_pop_smtp.auth_found = 0;
} else if((packet->line[a].ptr[0] == 'M' || packet->line[a].ptr[0] == 'm')
- && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
- && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i')
- && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l')
- && packet->line[a].ptr[4] == ' ') {
+ && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
+ && (packet->line[a].ptr[2] == 'I' || packet->line[a].ptr[2] == 'i')
+ && (packet->line[a].ptr[3] == 'L' || packet->line[a].ptr[3] == 'l')
+ && packet->line[a].ptr[4] == ' ') {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_MAIL;
flow->protos.ftp_imap_pop_smtp.auth_found = 0;
} else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r')
- && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c')
- && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p')
- && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')
- && packet->line[a].ptr[4] == ' ') {
+ && (packet->line[a].ptr[1] == 'C' || packet->line[a].ptr[1] == 'c')
+ && (packet->line[a].ptr[2] == 'P' || packet->line[a].ptr[2] == 'p')
+ && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')
+ && packet->line[a].ptr[4] == ' ') {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RCPT;
flow->protos.ftp_imap_pop_smtp.auth_found = 0;
} else if((packet->line[a].ptr[0] == 'A' || packet->line[a].ptr[0] == 'a')
- && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u')
- && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
- && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h')
- && packet->line[a].ptr[4] == ' ') {
+ && (packet->line[a].ptr[1] == 'U' || packet->line[a].ptr[1] == 'u')
+ && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
+ && (packet->line[a].ptr[3] == 'H' || packet->line[a].ptr[3] == 'h')
+ && packet->line[a].ptr[4] == ' ') {
#ifdef SMTP_DEBUG
printf("%s() AUTH [%s]\n", __FUNCTION__, packet->line[a].ptr);
#endif
@@ -143,7 +143,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
u_char *out;
size_t out_len;
- ndpi_user_pwd_payload_copy(buf, sizeof(buf), 0,
+ ndpi_user_pwd_payload_copy(buf, sizeof(buf)-1, 0,
packet->line[a].ptr, packet->line[a].len);
#ifdef SMTP_DEBUG
@@ -191,32 +191,32 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
if(packet->line[a].len >= 8) {
if((packet->line[a].ptr[0] == 'S' || packet->line[a].ptr[0] == 's')
- && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't')
- && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a')
- && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r')
- && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[4] == 't')
- && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't')
- && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l')
- && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) {
+ && (packet->line[a].ptr[1] == 'T' || packet->line[a].ptr[1] == 't')
+ && (packet->line[a].ptr[2] == 'A' || packet->line[a].ptr[2] == 'a')
+ && (packet->line[a].ptr[3] == 'R' || packet->line[a].ptr[3] == 'r')
+ && (packet->line[a].ptr[4] == 'T' || packet->line[a].ptr[4] == 't')
+ && (packet->line[a].ptr[5] == 'T' || packet->line[a].ptr[5] == 't')
+ && (packet->line[a].ptr[6] == 'L' || packet->line[a].ptr[6] == 'l')
+ && (packet->line[a].ptr[7] == 'S' || packet->line[a].ptr[7] == 's')) {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_STARTTLS;
}
}
if(packet->line[a].len >= 4) {
if((packet->line[a].ptr[0] == 'D' || packet->line[a].ptr[0] == 'd')
- && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
- && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
- && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) {
+ && (packet->line[a].ptr[1] == 'A' || packet->line[a].ptr[1] == 'a')
+ && (packet->line[a].ptr[2] == 'T' || packet->line[a].ptr[2] == 't')
+ && (packet->line[a].ptr[3] == 'A' || packet->line[a].ptr[3] == 'a')) {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_DATA;
} else if((packet->line[a].ptr[0] == 'N' || packet->line[a].ptr[0] == 'n')
- && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o')
- && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o')
- && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) {
+ && (packet->line[a].ptr[1] == 'O' || packet->line[a].ptr[1] == 'o')
+ && (packet->line[a].ptr[2] == 'O' || packet->line[a].ptr[2] == 'o')
+ && (packet->line[a].ptr[3] == 'P' || packet->line[a].ptr[3] == 'p')) {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_NOOP;
} else if((packet->line[a].ptr[0] == 'R' || packet->line[a].ptr[0] == 'r')
- && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's')
- && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e')
- && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) {
+ && (packet->line[a].ptr[1] == 'S' || packet->line[a].ptr[1] == 's')
+ && (packet->line[a].ptr[2] == 'E' || packet->line[a].ptr[2] == 'e')
+ && (packet->line[a].ptr[3] == 'T' || packet->line[a].ptr[3] == 't')) {
flow->l4.tcp.smtp_command_bitmask |= SMTP_BIT_RSET;
}
}
@@ -229,7 +229,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
}
}
NDPI_LOG_DBG2(ndpi_struct, "seen smtp commands and responses: %u\n",
- bit_count);
+ bit_count);
if(bit_count >= 3) {
NDPI_LOG_INFO(ndpi_struct, "mail smtp identified\n");
@@ -251,9 +251,9 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
/* when the first or second packets are split into two packets, those packets are ignored. */
if(flow->packet_counter <= 4 &&
- packet->payload_packet_len >= 4 &&
- (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a
- || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) {
+ packet->payload_packet_len >= 4 &&
+ (ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a
+ || memcmp(packet->payload, "220", 3) == 0 || memcmp(packet->payload, "EHLO", 4) == 0)) {
NDPI_LOG_DBG2(ndpi_struct, "maybe SMTP, need next packet\n");
return;
}
diff --git a/src/lib/protocols/ntp.c b/src/lib/protocols/ntp.c
index a03ed3b43..126dadc4c 100644
--- a/src/lib/protocols/ntp.c
+++ b/src/lib/protocols/ntp.c
@@ -58,8 +58,8 @@ void ndpi_search_ntp_udp(struct ndpi_detection_module_struct *ndpi_struct, struc
return;
}
}
- NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
diff --git a/src/lib/protocols/smpp.c b/src/lib/protocols/smpp.c
index c188bd91f..e0521ae12 100644
--- a/src/lib/protocols/smpp.c
+++ b/src/lib/protocols/smpp.c
@@ -68,7 +68,7 @@ void ndpi_search_smpp_tcp(struct ndpi_detection_module_struct* ndpi_struct,
u_int32_t tmp_pdu_l = 0;
u_int16_t pdu_c = 1;
// loop PDUs (check if lengths are valid)
- while(total_pdu_l < packet->payload_packet_len) {
+ while(total_pdu_l < (packet->payload_packet_len-4)) {
// get next PDU length
tmp_pdu_l = ntohl(get_u_int32_t(packet->payload, total_pdu_l));
// if zero or overflowing , return, will try the next TCP segment
diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c
index 5bdf78959..068d2c345 100644
--- a/src/lib/protocols/ssh.c
+++ b/src/lib/protocols/ssh.c
@@ -296,7 +296,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct
flow->l4.tcp.ssh_stage = 3;
return;
}
- } else {
+ } else if(packet->payload_packet_len > 5) {
u_int8_t msgcode = *(packet->payload + 5);
ndpi_MD5_CTX ctx;
diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c
index 0fd00e6d4..35693bf62 100644
--- a/src/lib/protocols/telnet.c
+++ b/src/lib/protocols/telnet.c
@@ -1,8 +1,8 @@
/*
* telnet.c
*
- * Copyright (C) 2009-2011 by ipoque GmbH
* Copyright (C) 2011-19 - ntop.org
+ * Copyright (C) 2009-2011 by ipoque GmbH
*
* This file is part of nDPI, an open source deep packet inspection
* library based on the OpenDPI and PACE technology by ipoque GmbH
@@ -47,6 +47,34 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct,
if(packet->payload_packet_len > 0) {
int i;
+ if(flow->protos.telnet.username_detected) {
+ if((!flow->protos.telnet.password_found)
+ && (packet->payload_packet_len > 6)) {
+
+ if(strncasecmp((char*)packet->payload, "password:", 9) == 0) {
+ flow->protos.telnet.password_found = 1;
+ }
+
+ return(1);
+ }
+
+ if(packet->payload[0] == '\r') {
+ if(!flow->protos.telnet.password_found)
+ return(1);
+
+ flow->protos.telnet.password_detected = 1;
+ flow->protos.telnet.password[flow->protos.telnet.character_id] = '\0';
+ return(0);
+ }
+
+ for(i=0; i<packet->payload_packet_len; i++) {
+ if(flow->protos.telnet.character_id < (sizeof(flow->protos.telnet.password)-1))
+ flow->protos.telnet.password[flow->protos.telnet.character_id++] = packet->payload[i];
+ }
+
+ return(1);
+ }
+
if((!flow->protos.telnet.username_found)
&& (packet->payload_packet_len > 6)) {
@@ -60,7 +88,8 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct,
if(packet->payload[0] == '\r') {
flow->protos.telnet.username_detected = 1;
flow->protos.telnet.username[flow->protos.telnet.character_id] = '\0';
- return(0);
+ flow->protos.telnet.character_id = 0;
+ return(1);
}
for(i=0; i<packet->payload_packet_len; i++) {
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 9d22a66db..ed92814d9 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -308,7 +308,11 @@ int getTLScertificate(struct ndpi_detection_module_struct *ndpi_struct,
#endif
offset += 2 + 1;
- extension_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
+
+ if((offset + 1) < packet->payload_packet_len) /* +1 because we are goint to read 2 bytes */
+ extension_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
+ else
+ extension_len = 0;
#ifdef DEBUG_TLS
printf("TLS [server][extension_len: %u]\n", extension_len);
@@ -870,7 +874,7 @@ int getSSCertificateFingerprint(struct ndpi_detection_module_struct *ndpi_struct
return(0); /* That's all */
} else if(flow->l4.tcp.tls_seen_certificate)
return(0); /* That's all */
- else if(packet->payload_packet_len > flow->l4.tcp.tls_record_offset+7) {
+ else if(packet->payload_packet_len > flow->l4.tcp.tls_record_offset+7+1/* +1 because we are going to read 2 bytes */) {
/* This is a handshake but not a certificate record */
u_int16_t len = ntohs(*(u_int16_t*)&packet->payload[flow->l4.tcp.tls_record_offset+7]);
@@ -1400,19 +1404,16 @@ void ndpi_search_tls_tcp_udp(struct ndpi_detection_module_struct *ndpi_struct,
u_int8_t ret, skip_cert_processing = 0;
#ifdef DEBUG_TLS
- printf("%s()\n", __FUNCTION__);
+ printf("==>> %u [len: %u][version: %u]\n",
+ flow->guessed_host_protocol_id,
+ packet->payload_packet_len,
+ flow->protos.stun_ssl.ssl.ssl_version);
#endif
if(packet->udp != NULL) {
/* DTLS dissector */
int rc = sslTryAndRetrieveServerCertificate(ndpi_struct, flow);
-
-#ifdef DEBUG_TLS
- printf("==>> %u [rc: %d][len: %u][%s][version: %u]\n",
- flow->guessed_host_protocol_id, rc, packet->payload_packet_len, flow->protos.stun_ssl.ssl.ja3_server,
- flow->protos.stun_ssl.ssl.ssl_version);
-#endif
-
+
if((rc == 0) && (flow->protos.stun_ssl.ssl.ssl_version != 0)) {
flow->guessed_protocol_id = NDPI_PROTOCOL_TLS;