diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 10 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 7 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 12 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 6 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 43 |
5 files changed, 48 insertions, 30 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 5b8a9c52b..33ccd93ec 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1404,7 +1404,7 @@ struct ndpi_flow_struct { } softether; struct { - char *server_names, *alpn, *tls_supported_versions, *issuerDN, *subjectDN; + char *server_names, *advertised_alpns, *negotiated_alpn, *tls_supported_versions, *issuerDN, *subjectDN; u_int32_t notBefore, notAfter; char ja3_client[33], ja3_server[33]; u_int16_t server_cipher; @@ -1578,11 +1578,11 @@ struct ndpi_flow_struct { #if !defined(NDPI_CFFI_PREPROCESSING) && defined(__linux__) #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -_Static_assert(sizeof(((struct ndpi_flow_struct *)0)->protos) <= 200, - "Size of the struct member protocols increased to more than 200 bytes, " +_Static_assert(sizeof(((struct ndpi_flow_struct *)0)->protos) <= 208, + "Size of the struct member protocols increased to more than 208 bytes, " "please check if this change is necessary."); -_Static_assert(sizeof(struct ndpi_flow_struct) <= 920, - "Size of the flow struct increased to more than 920 bytes, " +_Static_assert(sizeof(struct ndpi_flow_struct) <= 928, + "Size of the flow struct increased to more than 928 bytes, " "please check if this change is necessary."); #endif #endif diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 2c4116745..285f43d2a 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -5070,8 +5070,11 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) { if(flow->protos.tls_quic.server_names) ndpi_free(flow->protos.tls_quic.server_names); - if(flow->protos.tls_quic.alpn) - ndpi_free(flow->protos.tls_quic.alpn); + if(flow->protos.tls_quic.advertised_alpns) + ndpi_free(flow->protos.tls_quic.advertised_alpns); + + if(flow->protos.tls_quic.negotiated_alpn) + ndpi_free(flow->protos.tls_quic.negotiated_alpn); if(flow->protos.tls_quic.tls_supported_versions) ndpi_free(flow->protos.tls_quic.tls_supported_versions); diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 255a1fa8e..b7c687033 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1202,9 +1202,13 @@ static void ndpi_tls2json(ndpi_serializer *serializer, struct ndpi_flow_struct * { ndpi_serialize_string_string(serializer, "subjectDN", flow->protos.tls_quic.subjectDN); } - if(flow->protos.tls_quic.alpn) + if(flow->protos.tls_quic.advertised_alpns) { - ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic.alpn); + ndpi_serialize_string_string(serializer, "advertised_alpns", flow->protos.tls_quic.advertised_alpns); + } + if(flow->protos.tls_quic.negotiated_alpn) + { + ndpi_serialize_string_string(serializer, "negotiated_alpn", flow->protos.tls_quic.negotiated_alpn); } if(flow->protos.tls_quic.tls_supported_versions) { @@ -2559,8 +2563,8 @@ void load_common_alpns(struct ndpi_detection_module_struct *ndpi_str) { /* QUIC ALPNs */ "h3-T051", "h3-T050", - "h3-32", "h3-30", "h3-29", "h3-28", "h3-27", "h3-24", "h3-22", - "hq-30", "hq-29", "hq-28", "hq-27", + "h3-34", "h3-33", "h3-32", "h3-31", "h3-30", "h3-29", "h3-28", "h3-27", "h3-24", "h3-22", + "hq-34", "hq-33", "hq-32", "hq-31", "hq-30", "hq-29", "hq-28", "hq-27", "hq-interop", "h3-fb-05", "h1q-fb", "doq-i00", diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index cbfaa9fd1..433bc0261 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1335,9 +1335,9 @@ static void process_tls(struct ndpi_detection_module_struct *ndpi_struct, flow->protos.tls_quic.ssl_version = 0x0304; /* DNS-over-QUIC: ALPN is "doq" or "doq-XXX" (for drafts versions) */ - if(flow->protos.tls_quic.alpn && - strncmp(flow->protos.tls_quic.alpn, "doq", 3) == 0) { - NDPI_LOG_DBG(ndpi_struct, "Found DOQ (ALPN: [%s])\n", flow->protos.tls_quic.alpn); + if(flow->protos.tls_quic.advertised_alpns && + strncmp(flow->protos.tls_quic.advertised_alpns, "doq", 3) == 0) { + NDPI_LOG_DBG(ndpi_struct, "Found DOQ (ALPN: [%s])\n", flow->protos.tls_quic.advertised_alpns); ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DOH_DOT, NDPI_PROTOCOL_QUIC, NDPI_CONFIDENCE_DPI); } } diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 869fe504b..fa40070f6 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -1261,11 +1261,11 @@ static void tls_subclassify_by_alpn(struct ndpi_detection_module_struct *ndpi_st struct ndpi_flow_struct *flow) { /* Right now we have only one rule so we can keep it trivial */ - if (!flow->protos.tls_quic.alpn) + if (!flow->protos.tls_quic.advertised_alpns) return; - if(strlen(flow->protos.tls_quic.alpn) > NDPI_STATICSTRING_LEN("anydesk/") && - strncmp(flow->protos.tls_quic.alpn, "anydesk/", NDPI_STATICSTRING_LEN("anydesk/")) == 0) { + if(strlen(flow->protos.tls_quic.advertised_alpns) > NDPI_STATICSTRING_LEN("anydesk/") && + strncmp(flow->protos.tls_quic.advertised_alpns, "anydesk/", NDPI_STATICSTRING_LEN("anydesk/")) == 0) { #ifdef DEBUG_TLS printf("Matching ANYDESK via alpn\n"); #endif @@ -1278,9 +1278,10 @@ static void tls_subclassify_by_alpn(struct ndpi_detection_module_struct *ndpi_st /* **************************************** */ static void tlsCheckUncommonALPN(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow) { - char * alpn_start = flow->protos.tls_quic.alpn; + struct ndpi_flow_struct *flow, + char *alpn_start) { char * comma_or_nul = alpn_start; + do { size_t alpn_len; @@ -1555,7 +1556,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, u_int16_t s_offset = offset+4; 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, i; + u_int16_t alpn_str_len = 0, i; #ifdef DEBUG_TLS printf("Server TLS [ALPN: block_len=%u/len=%u]\n", extension_len, tot_alpn_len); @@ -1605,13 +1606,18 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, if(ndpi_normalize_printable_string(alpn_str, alpn_str_len) == 0) ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, alpn_str); - if(flow->protos.tls_quic.alpn == NULL) - flow->protos.tls_quic.alpn = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic.negotiated_alpn == NULL) + flow->protos.tls_quic.negotiated_alpn = ndpi_strdup(alpn_str); - if(flow->protos.tls_quic.alpn != NULL) - tlsCheckUncommonALPN(ndpi_struct, flow); + /* Check ALPN only if not already checked (client-side) */ + if(flow->protos.tls_quic.negotiated_alpn != NULL && + flow->protos.tls_quic.advertised_alpns == NULL) + tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.negotiated_alpn); - ndpi_snprintf(ja3.server.alpn, sizeof(ja3.server.alpn), "%s", alpn_str); + alpn_str_len = ndpi_min(sizeof(ja3.server.alpn), (size_t)alpn_str_len); + memcpy(ja3.server.alpn, alpn_str, alpn_str_len); + if(alpn_str_len > 0) + ja3.server.alpn[alpn_str_len - 1] = '\0'; /* Replace , with - as in JA3 */ for(i=0; ja3.server.alpn[i] != '\0'; i++) @@ -2164,7 +2170,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, 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, i; + u_int16_t alpn_str_len = 0, i; #ifdef DEBUG_TLS printf("Client TLS [ALPN: block_len=%u/len=%u]\n", extension_len, tot_alpn_len); @@ -2202,8 +2208,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, #ifdef DEBUG_TLS printf("Client TLS [ALPN: %s][len: %u]\n", alpn_str, alpn_str_len); #endif - if(flow->protos.tls_quic.alpn == NULL) { - flow->protos.tls_quic.alpn = ndpi_strdup(alpn_str); + if(flow->protos.tls_quic.advertised_alpns == NULL) { + flow->protos.tls_quic.advertised_alpns = ndpi_strdup(alpn_str); + + tlsCheckUncommonALPN(ndpi_struct, flow, flow->protos.tls_quic.advertised_alpns); /* Without SNI matching we can try to sub-classify the flow via ALPN. Note that this happens only on very rare cases, not the common ones @@ -2212,7 +2220,10 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, tls_subclassify_by_alpn(ndpi_struct, flow); } - ndpi_snprintf(ja3.client.alpn, sizeof(ja3.client.alpn), "%s", alpn_str); + alpn_str_len = ndpi_min(sizeof(ja3.client.alpn), (size_t)alpn_str_len); + memcpy(ja3.client.alpn, alpn_str, alpn_str_len); + if(alpn_str_len > 0) + ja3.client.alpn[alpn_str_len - 1] = '\0'; /* Replace , with - as in JA3 */ for(i=0; ja3.client.alpn[i] != '\0'; i++) @@ -2473,7 +2484,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, /* Before returning to the caller we need to make a final check */ if((flow->protos.tls_quic.ssl_version >= 0x0303) /* >= TLSv1.2 */ - && (flow->protos.tls_quic.alpn == NULL) /* No ALPN */) { + && (flow->protos.tls_quic.advertised_alpns == NULL) /* No ALPN */) { ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_NOT_CARRYING_HTTPS, "No ALPN"); } |