aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/ndpi_typedefs.h10
-rw-r--r--src/lib/ndpi_main.c7
-rw-r--r--src/lib/ndpi_utils.c12
-rw-r--r--src/lib/protocols/quic.c6
-rw-r--r--src/lib/protocols/tls.c43
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");
}