diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2021-11-15 16:20:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-15 16:20:57 +0100 |
commit | afc2b641eb9cf5035b5147e78030bafe0b40dd87 (patch) | |
tree | 99cf853d219ae6004819d2564f4cabd29c487cf6 /src/lib/ndpi_utils.c | |
parent | da47357762746c7fc5c537b575b5b56f252320a5 (diff) |
Fix writes to `flow->protos` union fields (#1354)
We can write to `flow->protos` only after a proper classification.
This issue has been found in Kerberos, DHCP, HTTP, STUN, IMO, FTP,
SMTP, IMAP and POP code.
There are two kinds of fixes:
* write to `flow->protos` only if a final protocol has been detected
* move protocol state out of `flow->protos`
The hard part is to find, for each protocol, the right tradeoff between
memory usage and code complexity.
Handle Kerberos like DNS: if we find a request, we set the protocol
and an extra callback to further parsing the reply.
For all the other protocols, move the state out of `flow->protos`. This
is an issue only for the FTP/MAIL stuff.
Add DHCP Class Identification value to the output of ndpiReader and to
the Jason serialization.
Extend code coverage of fuzz tests.
Close #1343
Close #1342
Diffstat (limited to 'src/lib/ndpi_utils.c')
-rw-r--r-- | src/lib/ndpi_utils.c | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index a9361f7c5..626f5ade3 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -865,9 +865,9 @@ static const char* ndpi_get_flow_info_by_proto_id(struct ndpi_flow_struct const return (char const *)flow->host_server_name; case NDPI_PROTOCOL_QUIC: case NDPI_PROTOCOL_TLS: - if (flow->protos.tls_quic_stun.tls_quic.hello_processed != 0) + if (flow->protos.tls_quic.hello_processed != 0) { - return flow->protos.tls_quic_stun.tls_quic.client_requested_server_name; + return flow->protos.tls_quic.client_requested_server_name; } break; } @@ -930,10 +930,10 @@ char* ndpi_ssl_version2str(struct ndpi_flow_struct *flow, *unknown_tls_version = 1; if(flow != NULL) { - snprintf(flow->protos.tls_quic_stun.tls_quic.ssl_version_str, - sizeof(flow->protos.tls_quic_stun.tls_quic.ssl_version_str), "TLS (%04X)", version); + snprintf(flow->protos.tls_quic.ssl_version_str, + sizeof(flow->protos.tls_quic.ssl_version_str), "TLS (%04X)", version); - return(flow->protos.tls_quic_stun.tls_quic.ssl_version_str); + return(flow->protos.tls_quic.ssl_version_str); } else return(""); } @@ -1150,7 +1150,9 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, switch(l7_protocol.master_protocol ? l7_protocol.master_protocol : l7_protocol.app_protocol) { case NDPI_PROTOCOL_DHCP: ndpi_serialize_start_of_block(serializer, "dhcp"); + ndpi_serialize_string_string(serializer, "hostname", (const char*)flow->host_server_name); ndpi_serialize_string_string(serializer, "fingerprint", flow->protos.dhcp.fingerprint); + ndpi_serialize_string_string(serializer, "class_ident", flow->protos.dhcp.class_ident); ndpi_serialize_end_of_block(serializer); break; @@ -1238,54 +1240,54 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, case NDPI_PROTOCOL_QUIC: ndpi_serialize_start_of_block(serializer, "quic"); - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') + if(flow->protos.tls_quic.client_requested_server_name[0] != '\0') ndpi_serialize_string_string(serializer, "client_requested_server_name", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); - if(flow->protos.tls_quic_stun.tls_quic.server_names) - ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic_stun.tls_quic.server_names); + flow->protos.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.server_names) + ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic.server_names); if(flow->http.user_agent) ndpi_serialize_string_string(serializer, "user_agent", flow->http.user_agent); - if(flow->protos.tls_quic_stun.tls_quic.ssl_version) { + if(flow->protos.tls_quic.ssl_version) { u_int8_t unknown_tls_version; - char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic_stun.tls_quic.ssl_version, &unknown_tls_version); + char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic.ssl_version, &unknown_tls_version); if(!unknown_tls_version) ndpi_serialize_string_string(serializer, "version", version); - if(flow->protos.tls_quic_stun.tls_quic.alpn) - ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic_stun.tls_quic.alpn); - ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic_stun.tls_quic.ja3_client); - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions) - ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic_stun.tls_quic.tls_supported_versions); + if(flow->protos.tls_quic.alpn) + ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic.alpn); + ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic.ja3_client); + if(flow->protos.tls_quic.tls_supported_versions) + ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic.tls_supported_versions); } ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_IMAP: ndpi_serialize_start_of_block(serializer, "imap"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_POP: ndpi_serialize_start_of_block(serializer, "pop"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_MAIL_SMTP: ndpi_serialize_start_of_block(serializer, "smtp"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); ndpi_serialize_end_of_block(serializer); break; case NDPI_PROTOCOL_FTP_CONTROL: ndpi_serialize_start_of_block(serializer, "ftp"); - ndpi_serialize_string_string(serializer, "user", flow->protos.ftp_imap_pop_smtp.username); - ndpi_serialize_string_string(serializer, "password", flow->protos.ftp_imap_pop_smtp.password); - ndpi_serialize_string_uint32(serializer, "auth_failed", flow->protos.ftp_imap_pop_smtp.auth_failed); + ndpi_serialize_string_string(serializer, "user", flow->ftp_imap_pop_smtp.username); + ndpi_serialize_string_string(serializer, "password", flow->ftp_imap_pop_smtp.password); + ndpi_serialize_string_uint32(serializer, "auth_failed", flow->ftp_imap_pop_smtp.auth_failed); ndpi_serialize_end_of_block(serializer); break; @@ -1300,25 +1302,25 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, case NDPI_PROTOCOL_TLS: case NDPI_PROTOCOL_DTLS: - if(flow->protos.tls_quic_stun.tls_quic.ssl_version) { + if(flow->protos.tls_quic.ssl_version) { char notBefore[32], notAfter[32]; struct tm a, b, *before = NULL, *after = NULL; u_int i, off; u_int8_t unknown_tls_version; - char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic_stun.tls_quic.ssl_version, &unknown_tls_version); + char *version = ndpi_ssl_version2str(flow, flow->protos.tls_quic.ssl_version, &unknown_tls_version); - if(flow->protos.tls_quic_stun.tls_quic.notBefore) - before = gmtime_r((const time_t *)&flow->protos.tls_quic_stun.tls_quic.notBefore, &a); - if(flow->protos.tls_quic_stun.tls_quic.notAfter) - after = gmtime_r((const time_t *)&flow->protos.tls_quic_stun.tls_quic.notAfter, &b); + if(flow->protos.tls_quic.notBefore) + before = gmtime_r((const time_t *)&flow->protos.tls_quic.notBefore, &a); + if(flow->protos.tls_quic.notAfter) + after = gmtime_r((const time_t *)&flow->protos.tls_quic.notAfter, &b); if(!unknown_tls_version) { ndpi_serialize_start_of_block(serializer, "tls"); ndpi_serialize_string_string(serializer, "version", version); ndpi_serialize_string_string(serializer, "client_requested_server_name", - flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); - if(flow->protos.tls_quic_stun.tls_quic.server_names) - ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic_stun.tls_quic.server_names); + flow->protos.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.server_names) + ndpi_serialize_string_string(serializer, "server_names", flow->protos.tls_quic.server_names); if(before) { strftime(notBefore, sizeof(notBefore), "%Y-%m-%d %H:%M:%S", before); @@ -1329,27 +1331,27 @@ int ndpi_dpi2json(struct ndpi_detection_module_struct *ndpi_struct, strftime(notAfter, sizeof(notAfter), "%Y-%m-%d %H:%M:%S", after); ndpi_serialize_string_string(serializer, "notafter", notAfter); } - ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic_stun.tls_quic.ja3_client); - ndpi_serialize_string_string(serializer, "ja3s", flow->protos.tls_quic_stun.tls_quic.ja3_server); - ndpi_serialize_string_uint32(serializer, "unsafe_cipher", flow->protos.tls_quic_stun.tls_quic.server_unsafe_cipher); - ndpi_serialize_string_string(serializer, "cipher", ndpi_cipher2str(flow->protos.tls_quic_stun.tls_quic.server_cipher)); + ndpi_serialize_string_string(serializer, "ja3", flow->protos.tls_quic.ja3_client); + ndpi_serialize_string_string(serializer, "ja3s", flow->protos.tls_quic.ja3_server); + ndpi_serialize_string_uint32(serializer, "unsafe_cipher", flow->protos.tls_quic.server_unsafe_cipher); + ndpi_serialize_string_string(serializer, "cipher", ndpi_cipher2str(flow->protos.tls_quic.server_cipher)); - if(flow->protos.tls_quic_stun.tls_quic.issuerDN) - ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.tls_quic_stun.tls_quic.issuerDN); + if(flow->protos.tls_quic.issuerDN) + ndpi_serialize_string_string(serializer, "issuerDN", flow->protos.tls_quic.issuerDN); - if(flow->protos.tls_quic_stun.tls_quic.subjectDN) - ndpi_serialize_string_string(serializer, "subjectDN", flow->protos.tls_quic_stun.tls_quic.subjectDN); + if(flow->protos.tls_quic.subjectDN) + ndpi_serialize_string_string(serializer, "subjectDN", flow->protos.tls_quic.subjectDN); - if(flow->protos.tls_quic_stun.tls_quic.alpn) - ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic_stun.tls_quic.alpn); + if(flow->protos.tls_quic.alpn) + ndpi_serialize_string_string(serializer, "alpn", flow->protos.tls_quic.alpn); - if(flow->protos.tls_quic_stun.tls_quic.tls_supported_versions) - ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic_stun.tls_quic.tls_supported_versions); + if(flow->protos.tls_quic.tls_supported_versions) + ndpi_serialize_string_string(serializer, "tls_supported_versions", flow->protos.tls_quic.tls_supported_versions); - if(flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint[0] != '\0') { + if(flow->protos.tls_quic.sha1_certificate_fingerprint[0] != '\0') { for(i=0, off=0; i<20; i++) { int rc = snprintf(&buf[off], sizeof(buf)-off,"%s%02X", (i > 0) ? ":" : "", - flow->protos.tls_quic_stun.tls_quic.sha1_certificate_fingerprint[i] & 0xFF); + flow->protos.tls_quic.sha1_certificate_fingerprint[i] & 0xFF); if(rc <= 0) break; else off += rc; } @@ -2197,8 +2199,8 @@ char* ndpi_get_flow_name(struct ndpi_flow_struct *flow) { if(flow->host_server_name[0] != '\0') return((char*)flow->host_server_name); - if(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] != '\0') - return(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name); + if(flow->protos.tls_quic.client_requested_server_name[0] != '\0') + return(flow->protos.tls_quic.client_requested_server_name); no_flow_info: return((char*)""); |