aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/reader_util.c1
-rw-r--r--src/include/ndpi_api.h.in5
-rw-r--r--src/include/ndpi_protocol_ids.h1
-rw-r--r--src/include/ndpi_typedefs.h7
-rw-r--r--src/lib/ndpi_main.c71
-rw-r--r--src/lib/protocols/ftp_control.c18
-rw-r--r--src/lib/protocols/mail_imap.c27
-rw-r--r--src/lib/protocols/mail_pop.c24
-rw-r--r--src/lib/protocols/mail_smtp.c55
-rw-r--r--src/lib/protocols/tls.c41
-rw-r--r--tests/pcap/pop3_stls.pcapbin0 -> 12061 bytes
-rw-r--r--tests/pcap/smtp-starttls.pcapbin9003 -> 15960 bytes
-rw-r--r--tests/pcap/tls_multiple_synack_different_seq.pcapngbin0 -> 6984 bytes
-rw-r--r--tests/result/ftp-start-tls.pcap.out17
-rw-r--r--tests/result/imap-starttls.pcap.out17
-rw-r--r--tests/result/pop3_stls.pcap.out29
-rw-r--r--tests/result/smtp-starttls.pcap.out19
-rw-r--r--tests/result/synscan.pcap.out4
-rw-r--r--tests/result/tls_multiple_synack_different_seq.pcapng.out29
19 files changed, 286 insertions, 79 deletions
diff --git a/example/reader_util.c b/example/reader_util.c
index ce639b09a..37e5bf4b4 100644
--- a/example/reader_util.c
+++ b/example/reader_util.c
@@ -1214,6 +1214,7 @@ void process_ndpi_collected_info(struct ndpi_workflow * workflow, struct ndpi_fl
|| is_ndpi_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS)
|| is_ndpi_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)
|| is_ndpi_proto(flow, NDPI_PROTOCOL_MAIL_POPS)
+ || is_ndpi_proto(flow, NDPI_PROTOCOL_FTPS)
|| ((is_quic = is_ndpi_proto(flow, NDPI_PROTOCOL_QUIC)))
) {
flow->ssh_tls.ssl_version = flow->ndpi_flow->protos.tls_quic.ssl_version;
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in
index 3a81cceb3..0fd177557 100644
--- a/src/include/ndpi_api.h.in
+++ b/src/include/ndpi_api.h.in
@@ -1010,6 +1010,11 @@ extern "C" {
lru_cache_type cache_type,
struct ndpi_lru_cache_stats *stats);
+ int ndpi_set_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, int value);
+ int ndpi_get_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto);
+
/**
* Find a protocol id associated with a string automata
*
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h
index b0ab19ebb..405cc4155 100644
--- a/src/include/ndpi_protocol_ids.h
+++ b/src/include/ndpi_protocol_ids.h
@@ -339,6 +339,7 @@ typedef enum {
NDPI_PROTOCOL_TIVOCONNECT = 308,
NDPI_PROTOCOL_KISMET = 309,
NDPI_PROTOCOL_FASTCGI = 310,
+ NDPI_PROTOCOL_FTPS = 311,
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_protocol_ids.h"
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index 80834005b..b86e66aeb 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1208,6 +1208,11 @@ struct ndpi_detection_module_struct {
/* *** If you add a new LRU cache, please update lru_cache_type above! *** */
+ int opportunistic_tls_smtp_enabled;
+ int opportunistic_tls_imap_enabled;
+ int opportunistic_tls_pop_enabled;
+ int opportunistic_tls_ftp_enabled;
+
ndpi_proto_defaults_t proto_defaults[NDPI_MAX_SUPPORTED_PROTOCOLS+NDPI_MAX_NUM_CUSTOM_PROTOCOLS];
u_int8_t direction_detect_disable:1, /* disable internal detection of packet direction */ _pad:7;
@@ -1395,7 +1400,7 @@ struct ndpi_flow_struct {
char *esni;
} encrypted_sni;
ndpi_cipher_weakness server_unsafe_cipher;
- } tls_quic; /* Used also by DTLS and POPS/IMAPS/SMTPS */
+ } tls_quic; /* Used also by DTLS and POPS/IMAPS/SMTPS/FTPS */
struct {
char client_signature[48], server_signature[48];
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 58931d567..4d6523856 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -1974,6 +1974,10 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
"FastCGI", NDPI_PROTOCOL_CATEGORY_NETWORK,
ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
+ ndpi_set_proto_defaults(ndpi_str, 0 /* encrypted */, 0 /* nw proto */, NDPI_PROTOCOL_UNSAFE, NDPI_PROTOCOL_FTPS,
+ "FTPS", NDPI_PROTOCOL_CATEGORY_DOWNLOAD_FT,
+ ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
+ ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main.c"
@@ -2759,6 +2763,11 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
return(NULL);
}
+ ndpi_str->opportunistic_tls_smtp_enabled = 1;
+ ndpi_str->opportunistic_tls_imap_enabled = 1;
+ ndpi_str->opportunistic_tls_pop_enabled = 1;
+ ndpi_str->opportunistic_tls_ftp_enabled = 1;
+
ndpi_init_protocol_defaults(ndpi_str);
if(ndpi_callback_init(ndpi_str)) {
@@ -4924,7 +4933,8 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
flow_is_proto(flow, NDPI_PROTOCOL_DTLS) ||
flow_is_proto(flow, NDPI_PROTOCOL_MAIL_SMTPS) ||
flow_is_proto(flow, NDPI_PROTOCOL_MAIL_POPS) ||
- flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS)) {
+ flow_is_proto(flow, NDPI_PROTOCOL_MAIL_IMAPS) ||
+ flow_is_proto(flow, NDPI_PROTOCOL_FTPS)) {
if(flow->protos.tls_quic.server_names)
ndpi_free(flow->protos.tls_quic.server_names);
@@ -5193,8 +5203,8 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
}
}
- if((flow->next_tcp_seq_nr[0] == 0 && flow->next_tcp_seq_nr[1] == 0) ||
- (flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0)) {
+ if(flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0 ||
+ (tcph->syn && flow->packet_counter == 0)) {
/* initialize tcp sequence counters */
/* the ack flag needs to be set to get valid sequence numbers from the other
* direction. Usually it will catch the second packet syn+ack but it works
@@ -5202,6 +5212,8 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
*
* if the syn flag is set add one to the sequence number,
* otherwise use the payload length.
+ *
+ * If we receive multiple syn-ack (before any real data), keep the last one
*/
if(tcph->ack != 0) {
flow->next_tcp_seq_nr[packet->packet_direction] =
@@ -6246,9 +6258,8 @@ ndpi_protocol ndpi_detection_process_packet(struct ndpi_detection_module_struct
u_int32_t num_calls = 0;
ndpi_protocol ret = { flow->detected_protocol_stack[1], flow->detected_protocol_stack[0], flow->category, NULL };
- if(ndpi_str->ndpi_log_level >= NDPI_LOG_TRACE)
- NDPI_LOG(flow ? flow->detected_protocol_stack[0] : NDPI_PROTOCOL_UNKNOWN, ndpi_str, NDPI_LOG_TRACE,
- "START packet processing\n");
+ NDPI_LOG_DBG(ndpi_str, "[%d/%d] START packet processing\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
if(flow == NULL)
return(ret);
@@ -8889,3 +8900,51 @@ int ndpi_seen_flow_beginning(const struct ndpi_flow_struct *flow)
return 0;
return 1;
}
+
+/* ******************************************************************** */
+
+int ndpi_set_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto, int value)
+{
+ if(!ndpi_struct || (value != 0 && value != 1))
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_MAIL_SMTP:
+ ndpi_struct->opportunistic_tls_smtp_enabled = value;
+ return 0;
+ case NDPI_PROTOCOL_MAIL_IMAP:
+ ndpi_struct->opportunistic_tls_imap_enabled = value;
+ return 0;
+ case NDPI_PROTOCOL_MAIL_POP:
+ ndpi_struct->opportunistic_tls_pop_enabled = value;
+ return 0;
+ case NDPI_PROTOCOL_FTP_CONTROL:
+ ndpi_struct->opportunistic_tls_ftp_enabled = value;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+/* ******************************************************************** */
+
+int ndpi_get_opportunistic_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int16_t proto)
+{
+ if(!ndpi_struct)
+ return -1;
+
+ switch(proto) {
+ case NDPI_PROTOCOL_MAIL_SMTP:
+ return ndpi_struct->opportunistic_tls_smtp_enabled;
+ case NDPI_PROTOCOL_MAIL_IMAP:
+ return ndpi_struct->opportunistic_tls_imap_enabled;
+ case NDPI_PROTOCOL_MAIL_POP:
+ return ndpi_struct->opportunistic_tls_pop_enabled;
+ case NDPI_PROTOCOL_FTP_CONTROL:
+ return ndpi_struct->opportunistic_tls_ftp_enabled;
+ default:
+ return -1;
+ }
+}
diff --git a/src/lib/protocols/ftp_control.c b/src/lib/protocols/ftp_control.c
index a0bec3864..44911b2d2 100644
--- a/src/lib/protocols/ftp_control.c
+++ b/src/lib/protocols/ftp_control.c
@@ -29,6 +29,9 @@
// #define FTP_DEBUG
+extern void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
/* *************************************************************** */
static void ndpi_int_ftp_control_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
@@ -643,10 +646,21 @@ static void ndpi_check_ftp_control(struct ndpi_detection_module_struct *ndpi_str
if(flow->l4.tcp.ftp_imap_pop_smtp.password[0] == '\0' &&
flow->l4.tcp.ftp_imap_pop_smtp.auth_done == 0 &&
- flow->l4.tcp.ftp_imap_pop_smtp.auth_tls == 0) /* TODO: any values on dissecting TLS handshake? */
+ flow->l4.tcp.ftp_imap_pop_smtp.auth_tls == 0) {
flow->ftp_control_stage = 0;
- else
+ } else if (flow->l4.tcp.ftp_imap_pop_smtp.auth_tls == 1 &&
+ ndpi_struct->opportunistic_tls_ftp_enabled) {
+ flow->host_server_name[0] = '\0'; /* Remove any data set by other dissectors (eg. SMTP) */
+ /* Switch classification to FTPS */
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ NDPI_PROTOCOL_FTPS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+ NDPI_LOG_DBG(ndpi_struct, "Switching to [%d/%d]\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ /* We are done (in FTP dissector): delegating TLS... */
+ switch_extra_dissection_to_tls(ndpi_struct, flow);
+ } else {
ndpi_int_ftp_control_add_connection(ndpi_struct, flow);
+ }
} else {
NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to FTP_CONTROL, "
"resetting the stage to 0\n");
diff --git a/src/lib/protocols/mail_imap.c b/src/lib/protocols/mail_imap.c
index a6809b454..2ae04f24b 100644
--- a/src/lib/protocols/mail_imap.c
+++ b/src/lib/protocols/mail_imap.c
@@ -30,6 +30,9 @@
/* #define IMAP_DEBUG 1*/
+extern void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
static void ndpi_int_mail_imap_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow,
u_int16_t protocol) {
flow->guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN; /* Avoid IMAPS to be used s sub-protocol */
@@ -51,13 +54,6 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
printf("%s() [%.*s]\n", __FUNCTION__, packet->payload_packet_len, packet->payload);
#endif
- if(flow->l4.tcp.mail_imap_starttls == 2) {
- NDPI_LOG_DBG2(ndpi_struct, "starttls detected\n");
- NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_MAIL_IMAP);
- NDPI_DEL_PROTOCOL_FROM_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_TLS);
- return;
- }
-
if(packet->payload_packet_len >= 4 && ntohs(get_u_int16_t(packet->payload, packet->payload_packet_len - 2)) == 0x0d0a) {
// the DONE command appears without a tag
if(packet->payload_packet_len == 6 && ((packet->payload[0] == 'D' || packet->payload[0] == 'd')
@@ -113,8 +109,17 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
&& (packet->payload[command_start + 1] == 'K' || packet->payload[command_start + 1] == 'k')
&& packet->payload[command_start + 2] == ' ') {
flow->l4.tcp.mail_imap_stage += 1;
- if(flow->l4.tcp.mail_imap_starttls == 1)
- flow->l4.tcp.mail_imap_starttls = 2;
+ if(flow->l4.tcp.mail_imap_starttls == 1) {
+ NDPI_LOG_DBG2(ndpi_struct, "starttls detected\n");
+ ndpi_int_mail_imap_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAPS);
+ if(ndpi_struct->opportunistic_tls_imap_enabled) {
+ NDPI_LOG_DBG(ndpi_struct, "Switching to [%d/%d]\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ /* We are done (in IMAP dissector): delegating TLS... */
+ switch_extra_dissection_to_tls(ndpi_struct, flow);
+ return;
+ }
+ }
saw_command = 1;
} else if((packet->payload[command_start] == 'U' || packet->payload[command_start] == 'u')
&& (packet->payload[command_start + 1] == 'I' || packet->payload[command_start + 1] == 'i')
@@ -126,7 +131,7 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
&& packet->payload[command_start + 2] == ' ') {
flow->l4.tcp.mail_imap_stage += 1;
if(flow->l4.tcp.mail_imap_starttls == 1)
- flow->l4.tcp.mail_imap_starttls = 2;
+ flow->l4.tcp.mail_imap_starttls = 0;
saw_command = 1;
}
}
@@ -156,7 +161,6 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
&& (packet->payload[command_start + 7] == 'S' || packet->payload[command_start + 7] == 's')) {
flow->l4.tcp.mail_imap_stage += 1;
flow->l4.tcp.mail_imap_starttls = 1;
- ndpi_int_mail_imap_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAPS);
saw_command = 1;
}
}
@@ -242,7 +246,6 @@ void ndpi_search_mail_imap_tcp(struct ndpi_detection_module_struct *ndpi_struct,
flow->l4.tcp.mail_imap_stage += 1;
/* Authenticate phase may have multiple messages. Ignore them since they are
somehow encrypted anyway. */
- flow->l4.tcp.mail_imap_starttls = 2;
ndpi_int_mail_imap_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_IMAPS);
saw_command = 1;
}
diff --git a/src/lib/protocols/mail_pop.c b/src/lib/protocols/mail_pop.c
index f0a1731b3..1474af1be 100644
--- a/src/lib/protocols/mail_pop.c
+++ b/src/lib/protocols/mail_pop.c
@@ -43,12 +43,16 @@
#define POP_BIT_STLS 0x0400
+extern void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
static void ndpi_int_mail_pop_add_connection(struct ndpi_detection_module_struct
- *ndpi_struct, struct ndpi_flow_struct *flow) {
+ *ndpi_struct, struct ndpi_flow_struct *flow,
+ u_int16_t protocol) {
NDPI_LOG_INFO(ndpi_struct, "mail_pop identified\n");
flow->guessed_protocol_id = NDPI_PROTOCOL_UNKNOWN; /* Avoid POP3S to be used s sub-protocol */
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POP, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+ ndpi_set_detected_protocol(ndpi_struct, flow, protocol, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
}
/* **************************************** */
@@ -142,6 +146,7 @@ static int ndpi_int_mail_pop_check_for_client_commands(struct ndpi_detection_mod
&& (packet->payload[2] == 'L' || packet->payload[2] == 'l')
&& (packet->payload[3] == 'S' || packet->payload[3] == 's')) {
flow->l4.tcp.pop_command_bitmask |= POP_BIT_STLS;
+ flow->l4.tcp.mail_imap_starttls = 1;
return 1;
}
}
@@ -168,6 +173,19 @@ void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct
&& (packet->payload[3] == 'R' || packet->payload[3] == 'r')))) {
// +OK or -ERR seen
flow->l4.tcp.mail_pop_stage += 1;
+ if(packet->payload[0] == '+' && flow->l4.tcp.mail_imap_starttls == 1) {
+ NDPI_LOG_DBG2(ndpi_struct, "starttls detected\n");
+ ndpi_int_mail_pop_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POPS);
+ if(ndpi_struct->opportunistic_tls_pop_enabled) {
+ NDPI_LOG_DBG(ndpi_struct, "Switching to [%d/%d]\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ /* We are done (in POP dissector): delegating TLS... */
+ switch_extra_dissection_to_tls(ndpi_struct, flow);
+ return;
+ }
+ }
+ if(packet->payload[0] == '-' && flow->l4.tcp.mail_imap_starttls == 1)
+ flow->l4.tcp.mail_imap_starttls = 0;
} else if(!ndpi_int_mail_pop_check_for_client_commands(ndpi_struct, flow)) {
goto maybe_split_pop;
}
@@ -189,7 +207,7 @@ void ndpi_search_mail_pop_tcp(struct ndpi_detection_module_struct
if((flow->l4.tcp.ftp_imap_pop_smtp.password[0] != '\0')
|| (flow->l4.tcp.mail_pop_stage > 3)) {
- ndpi_int_mail_pop_add_connection(ndpi_struct, flow);
+ ndpi_int_mail_pop_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_POP);
if(flow->l4.tcp.ftp_imap_pop_smtp.password[0] == '\0')
popInitExtraPacketProcessing(flow);
}
diff --git a/src/lib/protocols/mail_smtp.c b/src/lib/protocols/mail_smtp.c
index 31f07c1c0..f6b0af060 100644
--- a/src/lib/protocols/mail_smtp.c
+++ b/src/lib/protocols/mail_smtp.c
@@ -48,8 +48,8 @@
/* #define SMTP_DEBUG 1 */
-extern int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow);
+extern void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
static void ndpi_int_mail_smtp_add_connection(struct ndpi_detection_module_struct
*ndpi_struct, struct ndpi_flow_struct *flow) {
@@ -153,6 +153,7 @@ void ndpi_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_struct,
len = i-4;
/* Copy result for nDPI apps */
ndpi_hostname_sni_set(flow, &packet->line[a].ptr[4], len);
+ NDPI_LOG_DBG(ndpi_struct, "SMTP: hostname [%s]\n", flow->host_server_name);
if (ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MAIL_SMTP,
flow->host_server_name,
@@ -406,38 +407,40 @@ int ndpi_extra_search_mail_smtp_tcp(struct ndpi_detection_module_struct *ndpi_st
struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct * const packet = &ndpi_struct->packet;
- int rc = 0;
+ int rc;
- if (flow->l4.tcp.smtp_command_bitmask & SMTP_BIT_STARTTLS &&
- packet->payload_packet_len > 5)
- {
- uint8_t const * const block = &packet->payload[5];
- uint8_t const * const p = &packet->payload[0];
- uint16_t const block_len = packet->payload_packet_len - 5;
- uint16_t const l = packet->payload_packet_len;
+ if(flow->l4.tcp.smtp_command_bitmask & SMTP_BIT_STARTTLS) {
- packet->payload = block;
- packet->payload_packet_len = block_len;
+ /* RFC 3207:
+ "After the client gives the STARTTLS command, the server responds with
+ one of the following reply codes:
+ 220 Ready to start TLS
+ 501 Syntax error (no parameters allowed)
+ 454 TLS not available due to temporary reason"
+ */
- if (processTLSBlock(ndpi_struct, flow) != 0) {
+ if(ndpi_struct->opportunistic_tls_smtp_enabled &&
+ packet->payload_packet_len > 3 && memcmp(packet->payload, "220", 3) == 0) {
rc = 1;
- }
-
- packet->payload = p;
- packet->payload_packet_len = l;
-
- /* STARTTLS may be followed by a 220 - Service ready */
- if (rc == 0 && memcmp(packet->payload, "220", 3) != 0)
- {
- flow->l4.tcp.ftp_imap_pop_smtp.auth_done = 1;
- if (flow->guessed_host_protocol_id == NDPI_PROTOCOL_UNKNOWN) {
- ndpi_set_detected_protocol(ndpi_struct, flow,
- NDPI_PROTOCOL_MAIL_SMTPS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+ /* Switch classification to SMTPS, keeping the hostname sub-classification (if any) */
+ if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN &&
+ flow->detected_protocol_stack[0] != NDPI_PROTOCOL_MAIL_SMTP) {
+ ndpi_set_detected_protocol(ndpi_struct, flow,
+ flow->detected_protocol_stack[0], NDPI_PROTOCOL_MAIL_SMTPS, NDPI_CONFIDENCE_DPI);
+ /* Now it is safe to write to `flow->protos.tls_quic` union */
+ flow->protos.tls_quic.subprotocol_detected = 1;
} else {
ndpi_set_detected_protocol(ndpi_struct, flow,
- flow->guessed_host_protocol_id, NDPI_PROTOCOL_MAIL_SMTPS, NDPI_CONFIDENCE_DPI);
+ NDPI_PROTOCOL_MAIL_SMTPS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
}
+ NDPI_LOG_DBG(ndpi_struct, "Switching to [%d/%d]\n",
+ flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
+ /* We are done (in SMTP dissector): delegating TLS... */
+ switch_extra_dissection_to_tls(ndpi_struct, flow);
+ } else {
+ rc = 0; /* Something went wrong. Stop extra dissection */
}
+
} else {
ndpi_search_mail_smtp_tcp(ndpi_struct, flow);
rc = ((flow->l4.tcp.ftp_imap_pop_smtp.password[0] == '\0') &&
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 53245a21e..98a8d8208 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -28,8 +28,6 @@
#include "ndpi_encryption.h"
extern char *strptime(const char *s, const char *format, struct tm *tm);
-extern int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow);
extern int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, uint32_t quic_version);
extern int http_process_user_agent(struct ndpi_detection_module_struct *ndpi_struct,
@@ -221,7 +219,7 @@ void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct
message->buffer_len,
packet->packet_direction,
ntohl(packet->tcp->seq),
- ntohl(packet->tcp->seq)+packet->payload_packet_len);
+ message->next_seq);
#endif
}
}
@@ -852,8 +850,8 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
/* **************************************** */
-int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
- struct ndpi_flow_struct *flow) {
+static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
int ret;
@@ -924,8 +922,17 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
packet->payload_packet_len);
#endif
- if(packet->payload_packet_len == 0)
- return(1); /* Keep working */
+ /* This function is also called by "extra dissection" data path. Unfortunately,
+ generic "extra function" code doesn't honour protocol bitmask.
+ TODO: handle that in ndpi_main.c for all the protocols */
+ if(packet->payload_packet_len == 0 ||
+ packet->tcp_retransmission) {
+#ifdef DEBUG_TLS_MEMORY
+ printf("[TLS Mem] Ack or retransmission %d/%d. Skip\n",
+ packet->payload_packet_len, packet->tcp_retransmission);
+#endif
+ return 1; /* Keep working */
+ }
ndpi_search_tls_tcp_memory(ndpi_struct, flow);
message = &flow->l4.tcp.tls.message[packet->packet_direction];
@@ -1224,6 +1231,26 @@ static void tlsInitExtraPacketProcessing(struct ndpi_detection_module_struct *nd
/* **************************************** */
+void switch_extra_dissection_to_tls(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+#ifdef DEBUG_TLS
+ printf("Switching to TLS extra dissection\n");
+#endif
+
+ /* Reset reassemblers */
+ if(flow->l4.tcp.tls.message[0].buffer)
+ ndpi_free(flow->l4.tcp.tls.message[0].buffer);
+ memset(&flow->l4.tcp.tls.message[0], '\0', sizeof(flow->l4.tcp.tls.message[0]));
+ if(flow->l4.tcp.tls.message[1].buffer)
+ ndpi_free(flow->l4.tcp.tls.message[1].buffer);
+ memset(&flow->l4.tcp.tls.message[1], '\0', sizeof(flow->l4.tcp.tls.message[1]));
+
+ tlsInitExtraPacketProcessing(ndpi_struct, flow);
+}
+
+/* **************************************** */
+
static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
char * alpn_start = flow->protos.tls_quic.alpn;
diff --git a/tests/pcap/pop3_stls.pcap b/tests/pcap/pop3_stls.pcap
new file mode 100644
index 000000000..b56dffac6
--- /dev/null
+++ b/tests/pcap/pop3_stls.pcap
Binary files differ
diff --git a/tests/pcap/smtp-starttls.pcap b/tests/pcap/smtp-starttls.pcap
index 493751539..4a37ecc51 100644
--- a/tests/pcap/smtp-starttls.pcap
+++ b/tests/pcap/smtp-starttls.pcap
Binary files differ
diff --git a/tests/pcap/tls_multiple_synack_different_seq.pcapng b/tests/pcap/tls_multiple_synack_different_seq.pcapng
new file mode 100644
index 000000000..3b9b621e4
--- /dev/null
+++ b/tests/pcap/tls_multiple_synack_different_seq.pcapng
Binary files differ
diff --git a/tests/result/ftp-start-tls.pcap.out b/tests/result/ftp-start-tls.pcap.out
index f671a123d..63b2c093e 100644
--- a/tests/result/ftp-start-tls.pcap.out
+++ b/tests/result/ftp-start-tls.pcap.out
@@ -1,6 +1,6 @@
Guessed flow protos: 0
-DPI Packets (TCP): 10 (10.00 pkts/flow)
+DPI Packets (TCP): 17 (17.00 pkts/flow)
Confidence DPI : 1 (flows)
Num dissector calls: 154 (154.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
@@ -10,15 +10,20 @@ LRU cache stun: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
-Automa host: 1/0 (search/found)
-Automa domain: 1/0 (search/found)
-Automa tls cert: 0/0 (search/found)
+Automa host: 2/0 (search/found)
+Automa domain: 2/0 (search/found)
+Automa tls cert: 1/0 (search/found)
Automa risk mask: 0/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 2/0 (search/found)
Patricia risk: 0/0 (search/found)
Patricia protocols: 6/0 (search/found)
-FTP_CONTROL 51 7510 1
+FTPS 51 7510 1
- 1 TCP 10.238.26.36:62092 <-> 10.220.50.76:21 [proto: 1/FTP_CONTROL][ClearText][Confidence: DPI][cat: Download/7][16 pkts/1744 bytes <-> 35 pkts/5766 bytes][Goodput ratio: 49/66][0.33 sec][bytes ratio: -0.536 (Download)][IAT c2s/s2c min/avg/max/stddev: 1/0 13/4 34/34 13/8][Pkt Len c2s/s2c min/avg/max/stddev: 60/60 109/165 384/566 80/152][Risk: ** Unsafe Protocol **][Risk Score: 10][PLAIN TEXT (Authorized users only. All acti)][Plen Bins: 22,25,32,0,2,0,5,0,0,0,2,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 10.238.26.36 1
+
+
+ 1 TCP 10.238.26.36:62092 <-> 10.220.50.76:21 [proto: 311/FTPS][Encrypted][Confidence: DPI][cat: Download/7][16 pkts/1744 bytes <-> 35 pkts/5766 bytes][Goodput ratio: 49/66][0.33 sec][bytes ratio: -0.536 (Download)][IAT c2s/s2c min/avg/max/stddev: 1/0 13/4 34/34 13/8][Pkt Len c2s/s2c min/avg/max/stddev: 60/60 109/165 384/566 80/152][Risk: ** Weak TLS Cipher **** TLS (probably) Not Carrying HTTPS **** Unsafe Protocol **** Missing SNI TLS Extn **][Risk Score: 170][Risk Info: No ALPN / Cipher TLS_RSA_WITH_3DES_EDE_CBC_SHA][TLSv1.2][JA3C: 398076b7fcad56308a762b3c79fe1f44][ServerNames: oss.huawei.com][JA3S: 5cd6efb8d804faf03e1462073b729151 (WEAK)][Issuer: C=CN, O=Huawei, OU=Wireless Network Product Line, CN=Huawei Wireless Network Product CA][Subject: C=CN, O=Huawei, OU=Huawei Network Product Line, CN=OSS Certificate][Certificate SHA-1: 0A:14:3A:AB:E1:3A:5B:1C:A7:BD:C7:82:45:8C:FA:37:D7:87:29:D2][Validity: 2012-03-12 08:54:33 - 2027-03-09 08:54:33][Cipher: TLS_RSA_WITH_3DES_EDE_CBC_SHA][PLAIN TEXT (Authorized users only. All acti)][Plen Bins: 22,25,32,0,2,0,5,0,0,0,2,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/result/imap-starttls.pcap.out b/tests/result/imap-starttls.pcap.out
index b1897c7eb..3122ddbe6 100644
--- a/tests/result/imap-starttls.pcap.out
+++ b/tests/result/imap-starttls.pcap.out
@@ -1,8 +1,8 @@
Guessed flow protos: 0
-DPI Packets (TCP): 10 (10.00 pkts/flow)
+DPI Packets (TCP): 19 (19.00 pkts/flow)
Confidence DPI : 1 (flows)
-Num dissector calls: 181 (181.00 diss/flow)
+Num dissector calls: 204 (204.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
@@ -10,9 +10,9 @@ LRU cache stun: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
-Automa host: 0/0 (search/found)
-Automa domain: 0/0 (search/found)
-Automa tls cert: 0/0 (search/found)
+Automa host: 2/0 (search/found)
+Automa domain: 2/0 (search/found)
+Automa tls cert: 1/0 (search/found)
Automa risk mask: 0/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 2/0 (search/found)
@@ -21,4 +21,9 @@ Patricia protocols: 6/0 (search/found)
IMAPS 32 7975 1
- 1 TCP 192.168.17.53:49640 <-> 212.227.17.186:143 [proto: 51/IMAPS][Encrypted][Confidence: DPI][cat: Email/3][18 pkts/1536 bytes <-> 14 pkts/6439 bytes][Goodput ratio: 35/88][3.02 sec][bytes ratio: -0.615 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 188/251 1486/1677 371/512][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 85/460 372/1514 76/571][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][Risk Info: Expected on port 993][PLAIN TEXT (CAPABILITY IMAP)][Plen Bins: 25,18,6,6,0,0,0,6,6,6,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0]
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 192.168.17.53 1
+
+
+ 1 TCP 192.168.17.53:49640 <-> 212.227.17.186:143 [proto: 51/IMAPS][Encrypted][Confidence: DPI][cat: Email/3][18 pkts/1536 bytes <-> 14 pkts/6439 bytes][Goodput ratio: 35/88][3.02 sec][bytes ratio: -0.615 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 188/251 1486/1677 371/512][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 85/460 372/1514 76/571][Risk: ** Known Proto on Non Std Port **** TLS (probably) Not Carrying HTTPS **** Missing SNI TLS Extn **][Risk Score: 110][Risk Info: Expected on port 993 / No ALPN][TLSv1.2][JA3C: c369db2c355ad05c76f5660af3179b01][ServerNames: imap.gmx.net,imap.gmx.de][JA3S: 0debd3853f330c574b05e0b6d882dc27][Issuer: C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=NRW, L=Netphen, CN=TeleSec ServerPass DE-1][Subject: C=DE, O=1&1 Mail & Media GmbH, ST=Rhineland-Palatinate, L=Montabaur, CN=imap.gmx.net][Certificate SHA-1: 0F:E8:EA:E2:48:87:DF:8E:FE:F2:84:59:FE:D0:FC:1C:46:24:85:F5][Firefox][Validity: 2013-11-12 10:17:31 - 2016-11-17 23:59:59][Cipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384][PLAIN TEXT (CAPABILITY IMAP)][Plen Bins: 25,18,6,6,0,0,0,6,6,6,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0]
diff --git a/tests/result/pop3_stls.pcap.out b/tests/result/pop3_stls.pcap.out
new file mode 100644
index 000000000..4009a9757
--- /dev/null
+++ b/tests/result/pop3_stls.pcap.out
@@ -0,0 +1,29 @@
+Guessed flow protos: 0
+
+DPI Packets (TCP): 18 (18.00 pkts/flow)
+Confidence DPI : 1 (flows)
+Num dissector calls: 232 (232.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache zoom: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+Automa host: 4/0 (search/found)
+Automa domain: 3/0 (search/found)
+Automa tls cert: 1/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 0/0 (search/found)
+Patricia risk mask: 2/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia protocols: 4/0 (search/found)
+
+POPS 53 11189 1
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 192.168.20.18 1
+
+
+ 1 TCP 192.168.20.18:50583 <-> 72.249.41.52:110 [proto: 23/POPS][Encrypted][Confidence: DPI][cat: Email/3][23 pkts/2059 bytes <-> 30 pkts/9130 bytes][Goodput ratio: 39/82][5.43 sec][Hostname/SNI: pop.lavabit.com][bytes ratio: -0.632 (Download)][IAT c2s/s2c min/avg/max/stddev: 6/0 273/202 2072/2002 508/432][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 90/304 368/1514 69/480][Risk: ** Known Proto on Non Std Port **** Obsolete TLS (v1.1 or older) **][Risk Score: 150][Risk Info: Expected on port 995 / TLSv1][TLSv1][JA3C: 207409c2b30e670ca50e1eac016a4831][ServerNames: *.lavabit.com,lavabit.com][JA3S: 6b96cf9c27b0223177b0e9f135fe4899 (INSECURE)][Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certificates.godaddy.com/repository, CN=Go Daddy Secure Certification Authority][Subject: O=*.lavabit.com, OU=Domain Control Validated, CN=*.lavabit.com][Certificate SHA-1: 1D:14:60:3D:5E:0F:A2:EB:61:C5:27:F8:A4:26:80:B3:E5:BB:A2:B2][Validity: 2012-02-17 04:07:46 - 2017-02-17 04:07:46][Cipher: TLS_RSA_WITH_RC4_128_SHA][PLAIN TEXT (ERR Unrecognized command.)][Plen Bins: 34,37,2,2,2,5,0,2,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0]
diff --git a/tests/result/smtp-starttls.pcap.out b/tests/result/smtp-starttls.pcap.out
index 4cacda8e0..b5f55902c 100644
--- a/tests/result/smtp-starttls.pcap.out
+++ b/tests/result/smtp-starttls.pcap.out
@@ -1,8 +1,8 @@
Guessed flow protos: 0
-DPI Packets (TCP): 11 (11.00 pkts/flow)
-Confidence DPI : 1 (flows)
-Num dissector calls: 1 (1.00 diss/flow)
+DPI Packets (TCP): 26 (13.00 pkts/flow)
+Confidence DPI : 2 (flows)
+Num dissector calls: 152 (76.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
@@ -10,20 +10,23 @@ LRU cache stun: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
-Automa host: 1/1 (search/found)
-Automa domain: 1/0 (search/found)
-Automa tls cert: 0/0 (search/found)
-Automa risk mask: 1/0 (search/found)
+Automa host: 4/1 (search/found)
+Automa domain: 3/0 (search/found)
+Automa tls cert: 1/0 (search/found)
+Automa risk mask: 2/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 2/0 (search/found)
Patricia risk: 0/0 (search/found)
Patricia protocols: 2/2 (search/found)
+SMTPS 33 6429 1
Google 36 8403 1
JA3 Host Stats:
IP Address # JA3C
1 10.0.0.1 1
+ 2 2003:de:2016:125:fc36:8317:4e86:cb72 1
- 1 TCP 10.0.0.1:57406 <-> 173.194.68.26:25 [proto: 29.126/SMTPS.Google][Encrypted][Confidence: DPI][cat: Email/3][17 pkts/2514 bytes <-> 19 pkts/5889 bytes][Goodput ratio: 55/79][0.48 sec][Hostname/SNI: mx.google.com][bytes ratio: -0.402 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 30/24 156/103 42/26][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 148/310 752/1484 168/444][Risk: ** Obsolete TLS (v1.1 or older) **][Risk Score: 100][Risk Info: TLSv1][TLSv1][JA3C: fab507fe132c544e8a0eb7c394affeae][PLAIN TEXT (x.google.com ESMTP s4)][Plen Bins: 23,18,13,9,4,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0]
+ 1 TCP 10.0.0.1:57406 <-> 173.194.68.26:25 [proto: 29.126/SMTPS.Google][Encrypted][Confidence: DPI][cat: Email/3][17 pkts/2514 bytes <-> 19 pkts/5889 bytes][Goodput ratio: 55/79][0.48 sec][Hostname/SNI: mx.google.com][bytes ratio: -0.402 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/0 30/24 156/103 42/26][Pkt Len c2s/s2c min/avg/max/stddev: 66/66 148/310 752/1484 168/444][Risk: ** Obsolete TLS (v1.1 or older) **][Risk Score: 100][Risk Info: TLSv1][TLSv1][JA3C: fab507fe132c544e8a0eb7c394affeae][ServerNames: aspmx.l.google.com,alt1.aspmx.l.google.com,alt2.aspmx.l.google.com,alt3.aspmx.l.google.com,alt4.aspmx.l.google.com,gmail-smtp-in.l.google.com,alt1.gmail-smtp-in.l.google.com,alt2.gmail-smtp-in.l.google.com,alt3.gmail-smtp-in.l.google.com,alt4.gmail-smtp-in.l.google.com,gmr-smtp-in.l.google.com,alt1.gmr-smtp-in.l.google.com,alt2.gmr-smtp-in.l.google.com,alt3.gmr-smtp-in.l.google.com,alt4.gmr-smtp-in.l.google.com,mx.google.com,aspmx2.googlemail.com,aspmx3.googlemail.com,aspmx4.googlemail.com,aspmx5.googlemail.com][JA3S: 6b96cf9c27b0223177b0e9f135fe4899 (INSECURE)][Issuer: C=US, O=Google Inc, CN=Google Internet Authority G2][Subject: C=US, ST=California, L=Mountain View, O=Google Inc, CN=mx.google.com][Certificate SHA-1: 45:15:6A:E7:49:63:40:94:F9:AB:09:1E:F5:A7:33:6D:F3:7B:28:FC][Validity: 2013-09-09 11:32:35 - 2014-09-09 11:32:35][Cipher: TLS_RSA_WITH_RC4_128_SHA][PLAIN TEXT (x.google.com ESMTP s4)][Plen Bins: 23,18,13,9,4,4,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0]
+ 2 TCP [2003:de:2016:125:fc36:8317:4e86:cb72]:7562 <-> [2003:de:2016:120::a08:53]:25 [VLAN: 125][proto: 29/SMTPS][Encrypted][Confidence: DPI][cat: Email/3][16 pkts/2994 bytes <-> 17 pkts/3435 bytes][Goodput ratio: 58/61][0.30 sec][Hostname/SNI: dovecot.weberlab.de][bytes ratio: -0.069 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 22/23 202/202 55/54][Pkt Len c2s/s2c min/avg/max/stddev: 78/78 187/202 1112/1218 244/263][Risk: ** Self-signed Cert **** TLS (probably) Not Carrying HTTPS **** TLS Suspicious Extn **][Risk Score: 210][Risk Info: Extn id 65283 / No ALPN / CN=jw-vm08-int-dns][TLSv1.2][JA3C: 7b38238e17474b8f6d113523bb5a8dd9][JA3S: ccc514751b175866924439bdbb5bba34][Issuer: CN=jw-vm08-int-dns][Subject: CN=jw-vm08-int-dns][Certificate SHA-1: AD:1B:57:6C:AC:BE:46:54:65:F6:1D:6D:85:2A:38:16:07:7D:31:17][Firefox][Validity: 2016-08-16 09:33:19 - 2026-08-14 09:33:19][Cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256][PLAIN TEXT (dns.webernetz.net ESMTP Postfix)][Plen Bins: 17,35,17,4,4,8,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/result/synscan.pcap.out b/tests/result/synscan.pcap.out
index 832c90858..917778735 100644
--- a/tests/result/synscan.pcap.out
+++ b/tests/result/synscan.pcap.out
@@ -121,7 +121,7 @@ iSCSI 2 116 2
44 TCP 172.16.0.8:36050 -> 64.13.134.52:2605 [proto: 13/BGP][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
45 TCP 172.16.0.8:36050 -> 64.13.134.52:3000 [proto: 26/ntop][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
46 TCP 172.16.0.8:36050 -> 64.13.134.52:3128 [proto: 131/HTTP_Proxy][ClearText][Confidence: Match by port][cat: Web/5][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 47 TCP 172.16.0.8:36050 -> 64.13.134.52:3260 [proto: 311/iSCSI][ClearText][Confidence: Match by port][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 47 TCP 172.16.0.8:36050 -> 64.13.134.52:3260 [proto: 312/iSCSI][ClearText][Confidence: Match by port][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
48 TCP 172.16.0.8:36050 -> 64.13.134.52:3306 [proto: 20/MySQL][ClearText][Confidence: Match by port][cat: Database/11][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
49 TCP 172.16.0.8:36050 -> 64.13.134.52:3389 [proto: 88/RDP][ClearText][Confidence: Match by port][cat: RemoteAccess/12][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Desktop/File Sharing **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Found RDP][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
50 TCP 172.16.0.8:36050 -> 64.13.134.52:4343 [proto: 170/Whois-DAS][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
@@ -183,7 +183,7 @@ iSCSI 2 116 2
106 TCP 172.16.0.8:36051 -> 64.13.134.52:2605 [proto: 13/BGP][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
107 TCP 172.16.0.8:36051 -> 64.13.134.52:3000 [proto: 26/ntop][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
108 TCP 172.16.0.8:36051 -> 64.13.134.52:3128 [proto: 131/HTTP_Proxy][ClearText][Confidence: Match by port][cat: Web/5][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
- 109 TCP 172.16.0.8:36051 -> 64.13.134.52:3260 [proto: 311/iSCSI][ClearText][Confidence: Match by port][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 109 TCP 172.16.0.8:36051 -> 64.13.134.52:3260 [proto: 312/iSCSI][ClearText][Confidence: Match by port][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
110 TCP 172.16.0.8:36051 -> 64.13.134.52:3306 [proto: 20/MySQL][ClearText][Confidence: Match by port][cat: Database/11][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
111 TCP 172.16.0.8:36051 -> 64.13.134.52:3389 [proto: 88/RDP][ClearText][Confidence: Match by port][cat: RemoteAccess/12][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Desktop/File Sharing **** Unidirectional Traffic **][Risk Score: 20][Risk Info: No server to client traffic / Found RDP][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
112 TCP 172.16.0.8:36051 -> 64.13.134.52:4343 [proto: 170/Whois-DAS][ClearText][Confidence: Match by port][cat: Network/14][1 pkts/58 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
diff --git a/tests/result/tls_multiple_synack_different_seq.pcapng.out b/tests/result/tls_multiple_synack_different_seq.pcapng.out
new file mode 100644
index 000000000..a1c3dea4e
--- /dev/null
+++ b/tests/result/tls_multiple_synack_different_seq.pcapng.out
@@ -0,0 +1,29 @@
+Guessed flow protos: 0
+
+DPI Packets (TCP): 10 (10.00 pkts/flow)
+Confidence DPI : 1 (flows)
+Num dissector calls: 1 (1.00 diss/flow)
+LRU cache ookla: 0/0/0 (insert/search/found)
+LRU cache bittorrent: 0/0/0 (insert/search/found)
+LRU cache zoom: 0/0/0 (insert/search/found)
+LRU cache stun: 0/0/0 (insert/search/found)
+LRU cache tls_cert: 0/0/0 (insert/search/found)
+LRU cache mining: 0/0/0 (insert/search/found)
+LRU cache msteams: 0/0/0 (insert/search/found)
+Automa host: 1/1 (search/found)
+Automa domain: 1/0 (search/found)
+Automa tls cert: 0/0 (search/found)
+Automa risk mask: 0/0 (search/found)
+Automa common alpns: 0/0 (search/found)
+Patricia risk mask: 2/0 (search/found)
+Patricia risk: 0/0 (search/found)
+Patricia protocols: 4/0 (search/found)
+
+AmazonAWS 10 6532 1
+
+JA3 Host Stats:
+ IP Address # JA3C
+ 1 10.10.10.1 1
+
+
+ 1 TCP 10.10.10.1:443 <-> 192.168.0.1:59927 [proto: 91.265/TLS.AmazonAWS][Encrypted][Confidence: DPI][cat: Cloud/13][9 pkts/5961 bytes <-> 1 pkts/571 bytes][Goodput ratio: 91/90][29.38 sec][Hostname/SNI: bolt-prod-s3-eu-west-1.s3.eu-west-1.amazonaws.com][ALPN: h2;http/1.1][TLS Supported Versions: GREASE;TLSv1.3;TLSv1.2;TLSv1.1;TLSv1][bytes ratio: 0.825 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 3672/0 15063/0 5728/0][Pkt Len c2s/s2c min/avg/max/stddev: 66/571 662/571 1414/571 649/0][TLSv1.2][JA3C: b32309a26951912be7dba376398abc3b][ServerNames: s3-eu-west-1.amazonaws.com,*.s3-eu-west-1.amazonaws.com,s3.eu-west-1.amazonaws.com,*.s3.eu-west-1.amazonaws.com,s3.dualstack.eu-west-1.amazonaws.com,*.s3.dualstack.eu-west-1.amazonaws.com,*.s3.amazonaws.com,*.s3-control.eu-west-1.amazonaws.com,s3-control.eu-west-1.amazonaws.com,*.s3-control.dualstack.eu-west-1.amazonaws.com,s3-control.dualstack.eu-west-1.amazonaws.com,*.s3-accesspoint.eu-west-1.amazonaws.com,*.s3-accesspoint.dualstack.eu-west-1.amazonaws.com,*.s3.eu-west-1.vpce.amazonaws.com][JA3S: 704239182a9091e4453fdbfe0fd17586][Issuer: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon][Subject: CN=*.s3-eu-west-1.amazonaws.com][Certificate SHA-1: 5A:47:18:0A:2F:90:02:C9:30:5C:B1:BE:D6:0D:5A:42:24:C8:81:76][Chrome][Validity: 2021-03-26 00:00:00 - 2022-03-08 23:59:59][Cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256][PLAIN TEXT (Starfield Technologies)][Plen Bins: 0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,51,0,0,0,0,0]