aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca <deri@ntop.org>2020-02-10 15:04:37 +0100
committerLuca <deri@ntop.org>2020-02-10 15:04:37 +0100
commitaf6c86de2838a556997451ffd8e5c761b8b634f2 (patch)
tree89aeda8b4e775cbb0fa136a50985068d373357b0 /src
parent452ba1f339ae112492b75b0c53f5c2dd98ab92d2 (diff)
parent34984f1aec0eebdbee47408480c4f4cdb57cf0b3 (diff)
Merge branch 'dev' of https://github.com/ntop/nDPI into dev
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_typedefs.h3
-rw-r--r--src/lib/ndpi_main.c14
-rw-r--r--src/lib/protocols/telnet.c2
-rw-r--r--src/lib/protocols/tls.c192
4 files changed, 143 insertions, 68 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h
index c20352e90..98b8ccf8e 100644
--- a/src/include/ndpi_typedefs.h
+++ b/src/include/ndpi_typedefs.h
@@ -1232,7 +1232,8 @@ struct ndpi_flow_struct {
struct {
struct {
u_int16_t ssl_version, server_names_len;
- char client_requested_server_name[64], *server_names, server_organization[64];
+ char client_requested_server_name[64], *server_names, server_organization[64],
+ *alpn, *tls_supported_versions;
u_int32_t notBefore, notAfter;
char ja3_client[33], ja3_server[33];
u_int16_t server_cipher;
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index 01552a744..3b5d8e251 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -3846,7 +3846,11 @@ static int ndpi_init_packet_header(struct ndpi_detection_module_struct *ndpi_str
if(flow->http.url) { ndpi_free(flow->http.url); flow->http.url = NULL; }
if(flow->http.content_type) { ndpi_free(flow->http.content_type); flow->http.content_type = NULL; }
if(flow->http.user_agent) { ndpi_free(flow->http.user_agent); flow->http.user_agent = NULL; }
- if(flow->l4.tcp.tls.message.buffer) { ndpi_free(flow->l4.tcp.tls.message.buffer); flow->l4.tcp.tls.message.buffer = NULL; }
+ if(flow->l4.tcp.tls.message.buffer) {
+ ndpi_free(flow->l4.tcp.tls.message.buffer);
+ flow->l4.tcp.tls.message.buffer = NULL;
+ flow->l4.tcp.tls.message.buffer_len = flow->l4.tcp.tls.message.buffer_used = 0;
+ }
backup = flow->num_processed_pkts;
backup1 = flow->guessed_protocol_id;
@@ -6427,7 +6431,7 @@ int ndpi_match_bigram(struct ndpi_detection_module_struct *ndpi_str,
void ndpi_free_flow(struct ndpi_flow_struct *flow) {
if(flow) {
- if(flow->http.url) ndpi_free(flow->http.url);
+ if(flow->http.url) ndpi_free(flow->http.url);
if(flow->http.content_type) ndpi_free(flow->http.content_type);
if(flow->http.user_agent) ndpi_free(flow->http.user_agent);
if(flow->kerberos_buf.pktbuf) ndpi_free(flow->kerberos_buf.pktbuf);
@@ -6436,6 +6440,12 @@ void ndpi_free_flow(struct ndpi_flow_struct *flow) {
if(flow->protos.stun_ssl.ssl.server_names)
ndpi_free(flow->protos.stun_ssl.ssl.server_names);
+ if(flow->protos.stun_ssl.ssl.alpn)
+ ndpi_free(flow->protos.stun_ssl.ssl.alpn);
+
+ if(flow->protos.stun_ssl.ssl.tls_supported_versions)
+ ndpi_free(flow->protos.stun_ssl.ssl.tls_supported_versions);
+
if(flow->l4.tcp.tls.srv_cert_fingerprint_ctx)
ndpi_free(flow->l4.tcp.tls.srv_cert_fingerprint_ctx);
}
diff --git a/src/lib/protocols/telnet.c b/src/lib/protocols/telnet.c
index 0848ef467..dfccd904e 100644
--- a/src/lib/protocols/telnet.c
+++ b/src/lib/protocols/telnet.c
@@ -41,6 +41,8 @@ static int search_telnet_again(struct ndpi_detection_module_struct *ndpi_struct,
printf("==> %s() [%s][direction: %u]\n", __FUNCTION__, packet->payload, packet->packet_direction);
#endif
+ if (packet->payload == NULL)
+ return(1);
if(packet->payload[0] == 0xFF)
return(1);
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index e5f46c05c..b70538949 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -34,10 +34,8 @@ extern char *strptime(const char *s, const char *format, struct tm *tm);
extern int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
-#if 0
-#define DEBUG_TLS_MEMORY 1
-#define DEBUG_TLS 1
-#endif
+// #define DEBUG_TLS_MEMORY 1
+// #define DEBUG_TLS 1
// #define DEBUG_CERTIFICATE_HASH
@@ -175,7 +173,7 @@ void ndpi_search_tls_tcp_memory(struct ndpi_detection_module_struct *ndpi_struct
static void cleanupServerName(char *buffer, int buffer_len) {
u_int i;
-
+
/* Now all lowecase */
for(i=0; i<buffer_len; i++)
buffer[i] = tolower(buffer[i]);
@@ -190,7 +188,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
struct ndpi_packet_struct *packet = &flow->packet;
u_int num_found = 0, i, j;
char buffer[64] = { '\0' };
-
+
#ifdef DEBUG_TLS
printf("[TLS] %s() [offset: %u][certificate_len: %u]\n", __FUNCTION__, p_offset, certificate_len);
#endif
@@ -320,7 +318,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
if((len > sizeof(dNSName)-1) || (len == 0 /* Looks something went wrong */))
break; /* String too long */
-
+
strncpy(dNSName, (const char*)&packet->payload[i], len);
dNSName[len] = '\0';
@@ -352,8 +350,8 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi
if(!flow->l4.tcp.tls.subprotocol_detected)
if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len))
flow->l4.tcp.tls.subprotocol_detected = 1;
-
- i += len;
+
+ i += len;
} else {
#if DEBUG_TLS
printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i);
@@ -377,7 +375,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t certificates_length, length = (packet->payload[1] << 16) + (packet->payload[2] << 8) + packet->payload[3];
u_int16_t certificates_offset = 7;
u_int8_t num_certificates_found = 0;
-
+
#ifdef DEBUG_TLS
printf("[TLS] %s() [payload_packet_len=%u][direction: %u][%02X %02X %02X %02X %02X %02X...]\n",
__FUNCTION__, packet->payload_packet_len,
@@ -390,10 +388,10 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
return(-1); /* Invalid length */
certificates_length = (packet->payload[4] << 16) + (packet->payload[5] << 8) + packet->payload[6];
-
+
if((packet->payload[4] != 0x0) || ((certificates_length+3) != length))
return(-2); /* Invalid length */
-
+
if((flow->l4.tcp.tls.srv_cert_fingerprint_ctx = (void*)ndpi_malloc(sizeof(SHA1_CTX))) == NULL)
return(-3); /* Not enough memory */
@@ -413,7 +411,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
#endif
break;
}
-
+
certificates_offset += 3;
#ifdef DEBUG_TLS
printf("[TLS] Processing %u bytes certificate [%02X %02X %02X]\n",
@@ -425,32 +423,32 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
if(num_certificates_found++ == 0) /* Dissect only the first certificate that is the one we care */ {
/* For SHA-1 we take into account only the first certificate and not all of them */
-
+
SHA1Init(flow->l4.tcp.tls.srv_cert_fingerprint_ctx);
-
+
#ifdef DEBUG_CERTIFICATE_HASH
{
int i;
-
+
for(i=0;i<certificate_len;i++)
printf("%02X ", packet->payload[certificates_offset+i]);
-
+
printf("\n");
}
#endif
-
+
SHA1Update(flow->l4.tcp.tls.srv_cert_fingerprint_ctx,
&packet->payload[certificates_offset],
certificate_len);
-
+
SHA1Final(flow->l4.tcp.tls.sha1_certificate_fingerprint, flow->l4.tcp.tls.srv_cert_fingerprint_ctx);
flow->l4.tcp.tls.fingerprint_set = 1;
-
+
#ifdef DEBUG_TLS
{
int i;
-
+
printf("[TLS] SHA-1: ");
for(i=0;i<20;i++)
printf("%s%02X", (i > 0) ? ":" : "", flow->l4.tcp.tls.sha1_certificate_fingerprint[i]);
@@ -460,10 +458,10 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
processCertificateElements(ndpi_struct, flow, certificates_offset, certificate_len);
}
-
+
certificates_offset += certificate_len;
}
-
+
flow->extra_packets_func = NULL; /* We're good now */
return(1);
}
@@ -473,7 +471,7 @@ int processCertificate(struct ndpi_detection_module_struct *ndpi_struct,
static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
-
+
switch(packet->payload[0] /* block type */) {
case 0x01: /* Client Hello */
case 0x02: /* Server Hello */
@@ -481,7 +479,7 @@ static int processTLSBlock(struct ndpi_detection_module_struct *ndpi_struct,
flow->l4.tcp.tls.hello_processed = 1;
ndpi_int_tls_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TLS);
break;
-
+
case 0x0b: /* Certificate */
processCertificate(ndpi_struct, flow);
flow->l4.tcp.tls.certificate_processed = 1;
@@ -500,7 +498,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
u_int8_t something_went_wrong = 0;
-
+
#ifdef DEBUG_TLS_MEMORY
printf("[TLS Mem] ndpi_search_tls_tcp() [payload_packet_len: %u]\n",
packet->payload_packet_len);
@@ -537,7 +535,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
something_went_wrong = 1;
break;
}
-
+
#ifdef DEBUG_TLS_MEMORY
printf("[TLS Mem] Processing %u bytes message\n", len);
#endif
@@ -547,7 +545,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
/* Split the element in blocks */
u_int16_t processed = 5;
-
+
while((processed+4) < len) {
const u_int8_t *block = (const u_int8_t *)&flow->l4.tcp.tls.message.buffer[processed];
u_int32_t block_len = (block[1] << 16) + (block[2] << 8) + block[3];
@@ -556,14 +554,14 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
something_went_wrong = 1;
break;
}
-
+
packet->payload = block, packet->payload_packet_len = block_len+4;
if((processed+packet->payload_packet_len) > len) {
something_went_wrong = 1;
break;
}
-
+
#ifdef DEBUG_TLS_MEMORY
printf("*** [TLS Mem] Processing %u bytes block [%02X %02X %02X %02X %02X]\n",
packet->payload_packet_len,
@@ -574,7 +572,7 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
processTLSBlock(ndpi_struct, flow);
processed += packet->payload_packet_len;
}
-
+
packet->payload = p, packet->payload_packet_len = p_len; /* Restore */
flow->l4.tcp.tls.message.buffer_used -= len;
@@ -584,16 +582,12 @@ static int ndpi_search_tls_tcp(struct ndpi_detection_module_struct *ndpi_struct,
flow->l4.tcp.tls.message.buffer_used);
else
break;
-
+
#ifdef DEBUG_TLS_MEMORY
printf("[TLS Mem] Left memory buffer %u bytes\n", flow->l4.tcp.tls.message.buffer_used);
#endif
}
-#ifdef DEBUG_TLS_MEMORY
- printf("[TLS Mem] Returning %u\n", rc);
-#endif
-
if(something_went_wrong) {
flow->check_extra_packets = 0, flow->extra_packets_func = NULL;
return(0); /* That's all */
@@ -610,11 +604,11 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t handshake_len;
u_int16_t p_len;
const u_int8_t *p;
-
+
#ifdef DEBUG_TLS
printf("[TLS] %s()\n", __FUNCTION__);
#endif
-
+
/* Consider only specific SSL packets (handshake) */
if((packet->payload_packet_len < 17)
|| (packet->payload[0] != 0x16)
@@ -623,11 +617,11 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct,
|| ((ntohs(*((u_int16_t*)&packet->payload[11]))+13) != packet->payload_packet_len)
) {
no_dtls:
-
+
#ifdef DEBUG_TLS
printf("[TLS] No DTLS found\n");
#endif
-
+
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return(0); /* Giveup */
}
@@ -637,17 +631,17 @@ static int ndpi_search_tls_udp(struct ndpi_detection_module_struct *ndpi_struct,
if((handshake_len+25) != packet->payload_packet_len)
goto no_dtls;
-
+
/* Overwriting packet payload */
- p = packet->payload, p_len = packet->payload_packet_len; /* Backup */
+ p = packet->payload, p_len = packet->payload_packet_len; /* Backup */
packet->payload = &packet->payload[13], packet->payload_packet_len -= 13;
processTLSBlock(ndpi_struct, flow);
-
+
packet->payload = p, packet->payload_packet_len = p_len; /* Restore */
-
+
ndpi_int_tls_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TLS);
-
+
return(1); /* Keep working */
}
@@ -675,7 +669,7 @@ static void ndpi_int_tls_add_connection(struct ndpi_detection_module_struct *ndp
tlsInitExtraPacketProcessing(flow);
return;
}
-
+
if(protocol != NDPI_PROTOCOL_TLS)
;
else
@@ -715,7 +709,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t total_len;
u_int8_t handshake_type;
char buffer[64] = { '\0' };
-
+
#ifdef DEBUG_TLS
printf("SSL %s() called\n", __FUNCTION__);
#endif
@@ -724,29 +718,29 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
handshake_type = packet->payload[0];
total_len = (packet->payload[1] << 16) + (packet->payload[2] << 8) + packet->payload[3];
-
+
if((total_len > packet->payload_packet_len) || (packet->payload[1] != 0x0))
return(0); /* Not found */
total_len = packet->payload_packet_len;
-
+
/* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */
if(total_len > 4) {
u_int16_t base_offset = packet->tcp ? 38 : 46;
u_int16_t version_offset = packet->tcp ? 4 : 12;
u_int16_t offset = 38, extension_len, j;
u_int8_t session_id_len = packet->tcp ? packet->payload[offset] : packet->payload[46];
-
+
#ifdef DEBUG_TLS
printf("SSL [len: %u][handshake_type: %02X]\n", packet->payload_packet_len, handshake_type);
#endif
tls_version = ntohs(*((u_int16_t*)&packet->payload[version_offset]));
flow->protos.stun_ssl.ssl.ssl_version = ja3.tls_handshake_version = tls_version;
-
+
if(handshake_type == 0x02 /* Server Hello */) {
int i, rc;
-
+
#ifdef DEBUG_TLS
printf("SSL Server Hello [version: 0x%04X]\n", tls_version);
#endif
@@ -855,7 +849,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef DEBUG_TLS
printf("[JA3] Server: %s \n", flow->protos.stun_ssl.ssl.ja3_server);
-#endif
+#endif
} else if(handshake_type == 0x01 /* Client Hello */) {
u_int16_t cipher_len, cipher_offset;
@@ -869,7 +863,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
cipher_len = ntohs(*((u_int16_t*)&packet->payload[base_offset+2]));
cipher_offset = base_offset+4;
}
-
+
#ifdef DEBUG_TLS
printf("Client SSL [client cipher_len: %u][tls_version: 0x%04X]\n", cipher_len, tls_version);
#endif
@@ -1055,22 +1049,90 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
printf("Client SSL Invalid len %u vs %u\n", s_offset+extension_len, total_len);
#endif
}
- } else if(extension_id == 43 /* supported versions */) {
- u_int8_t version_len = packet->payload[offset+4];
+ } else if(extension_id == 16 /* application_layer_protocol_negotiation */) {
+ u_int16_t s_offset = offset+extension_offset;
+ u_int16_t tot_alpn_len = ntohs(*((u_int16_t*)&packet->payload[s_offset]));
+ char alpn_str[256];
+ u_int8_t alpn_str_len = 0;
- if(version_len == (extension_len-1)) {
#ifdef DEBUG_TLS
+ printf("Client SSL [ALPN: block_len=%u/len=%u]\n", extension_len, tot_alpn_len);
+#endif
+ s_offset += 2;
+ tot_alpn_len += s_offset;
+
+ while(s_offset < tot_alpn_len) {
+ u_int8_t alpn_i, alpn_len = packet->payload[s_offset++];
+
+ if((s_offset + alpn_len) <= tot_alpn_len) {
+#ifdef DEBUG_TLS
+ printf("Client SSL [ALPN: %u]\n", alpn_len);
+#endif
+
+ if((alpn_str_len+alpn_len+1) < sizeof(alpn_str)) {
+ if(alpn_str_len > 0) {
+ alpn_str[alpn_str_len] = ',';
+ alpn_str_len++;
+ }
+
+ for(alpn_i=0; alpn_i<alpn_len; alpn_i++)
+ alpn_str[alpn_str_len+alpn_i] = packet->payload[s_offset+alpn_i];
+
+ s_offset += alpn_len, alpn_str_len += alpn_len;;
+ } else
+ break;
+ } else
+ break;
+ } /* while */
+
+ alpn_str[alpn_str_len] = '\0';
+
+#ifdef DEBUG_TLS
+ printf("Client SSL [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len);
+#endif
+ if(flow->protos.stun_ssl.ssl.alpn == NULL)
+ flow->protos.stun_ssl.ssl.alpn = ndpi_strdup(alpn_str);
+ } else if(extension_id == 43 /* supported versions */) {
+ u_int16_t s_offset = offset+extension_offset;
+ u_int8_t version_len = packet->payload[s_offset];
+ char version_str[256];
+ u_int8_t version_str_len = 0;
+
+#ifdef DEBUG_TLS
+ printf("Client SSL [TLS version len: %u]\n", version_len);
+#endif
+
+ if(version_len == (extension_len-1)) {
u_int8_t j;
+ s_offset++;
+
for(j=0; j<version_len; j += 2) {
- u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[offset+5+j]));
+ u_int16_t tls_version = ntohs(*((u_int16_t*)&packet->payload[s_offset+j]));
+ u_int8_t unknown_tls_version;
+
+#ifdef DEBUG_TLS
+ printf("Client SSL [TLS version: %s/0x%04X]\n",
+ ndpi_ssl_version2str(tls_version, &unknown_tls_version), tls_version);
+#endif
- printf("Client SSL [TLS version: 0x%04X]\n", tls_version);
+ if((version_str_len+8) < sizeof(version_str)) {
+ int rc = snprintf(&version_str[version_str_len],
+ sizeof(version_str) - version_str_len, "%s%s",
+ (version_str_len > 0) ? "," : "",
+ ndpi_ssl_version2str(tls_version, &unknown_tls_version));
+ if(rc <= 0)
+ break;
+ else
+ version_str_len += rc;
+ }
}
-#endif
}
- }
+ if(flow->protos.stun_ssl.ssl.tls_supported_versions == NULL)
+ flow->protos.stun_ssl.ssl.tls_supported_versions = ndpi_strdup(version_str);
+ }
+
extension_offset += extension_len;
#ifdef DEBUG_TLS
@@ -1158,7 +1220,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
}
}
}
-
+
return(0); /* Not found */
}
@@ -1167,7 +1229,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
struct ndpi_packet_struct *packet = &flow->packet;
-
+
#ifdef DEBUG_TLS
printf("==>> %s() %u [len: %u][version: %u]\n",
__FUNCTION__,
@@ -1175,7 +1237,7 @@ static void ndpi_search_tls_wrapper(struct ndpi_detection_module_struct *ndpi_st
packet->payload_packet_len,
flow->protos.stun_ssl.ssl.ssl_version);
#endif
-
+
if(packet->udp != NULL)
ndpi_search_tls_udp(ndpi_struct, flow);
else
@@ -1203,6 +1265,6 @@ void init_tls_dissector(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
SAVE_DETECTION_BITMASK_AS_UNKNOWN,
ADD_TO_DETECTION_BITMASK);
-
+
*id += 1;
}