aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/kerberos.c
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2021-11-15 16:20:57 +0100
committerGitHub <noreply@github.com>2021-11-15 16:20:57 +0100
commitafc2b641eb9cf5035b5147e78030bafe0b40dd87 (patch)
tree99cf853d219ae6004819d2564f4cabd29c487cf6 /src/lib/protocols/kerberos.c
parentda47357762746c7fc5c537b575b5b56f252320a5 (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/protocols/kerberos.c')
-rw-r--r--src/lib/protocols/kerberos.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c
index 1f242ac46..7702a8e07 100644
--- a/src/lib/protocols/kerberos.c
+++ b/src/lib/protocols/kerberos.c
@@ -32,6 +32,10 @@
#define KERBEROS_PORT 88
+static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow);
+
+
static void ndpi_int_kerberos_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow) {
ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_KERBEROS, NDPI_PROTOCOL_UNKNOWN);
@@ -158,6 +162,9 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef KERBEROS_DEBUG
printf("[Kerberos] Packet found 0x%02X/%u\n", msg_type, msg_type);
#endif
+
+ ndpi_int_kerberos_add_connection(ndpi_struct, flow);
+
if(msg_type != 0x0d) /* TGS-REP */ {
/* Process only on requests */
if(packet->payload[koffset+1] == 0xA3) {
@@ -309,6 +316,19 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
}
}
}
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Setting extra func from AS-REQ\n");
+#endif
+ flow->check_extra_packets = 1;
+ flow->max_extra_packets_to_check = 5; /* Reply may be split into multiple segments */
+ flow->extra_packets_func = ndpi_search_kerberos_extra;
+ } else if(msg_type == 0x0e) /* AS-REQ */ {
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Processing AS-REQ\n");
+#endif
+ /* Nothing specific to do; stop dissecting this flow */
+ flow->extra_packets_func = NULL;
+
} else if(msg_type == 0x0c) /* TGS-REQ */ {
#ifdef KERBEROS_DEBUG
printf("[Kerberos] Processing TGS-REQ\n");
@@ -357,18 +377,22 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
}
}
}
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Setting extra func from TGS-REQ\n");
+#endif
+ if(!packet->udp) {
+ flow->check_extra_packets = 1;
+ flow->max_extra_packets_to_check = 5; /* Reply may be split into multiple segments */
+ flow->extra_packets_func = ndpi_search_kerberos_extra;
+ }
- if(packet->udp)
- ndpi_int_kerberos_add_connection(ndpi_struct, flow);
-
- /* We set the protocol in the response */
if(flow->kerberos_buf.pktbuf != NULL) {
ndpi_free(flow->kerberos_buf.pktbuf);
packet->payload = original_packet_payload;
packet->payload_packet_len = original_payload_packet_len;
flow->kerberos_buf.pktbuf = NULL;
}
-
+
return;
} else if(msg_type == 0x0d) /* TGS-REP */ {
u_int16_t pad_data_len, cname_offset;
@@ -403,24 +427,20 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
if(cname_len && cname_str[cname_len-1] == '$') {
cname_str[cname_len-1] = '\0';
snprintf(flow->protos.kerberos.hostname, sizeof(flow->protos.kerberos.hostname), "%s", cname_str);
- } else
+ } else {
snprintf(flow->protos.kerberos.username, sizeof(flow->protos.kerberos.username), "%s", cname_str);
+ }
- ndpi_int_kerberos_add_connection(ndpi_struct, flow);
+#ifdef KERBEROS_DEBUG
+ printf("[TGS-REP] Found everything. disabling extra func\n");
+#endif
+ flow->extra_packets_func = NULL;
}
}
}
return;
}
-
- if(packet->payload_packet_len > 21 &&
- packet->payload[16] == 0x05 &&
- (packet->payload[21] == 0x0a ||
- packet->payload[21] == 0x0c || packet->payload[21] == 0x0d || packet->payload[21] == 0x0e)) {
- ndpi_int_kerberos_add_connection(ndpi_struct, flow);
- return;
- }
}
}
} else {
@@ -437,6 +457,27 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct,
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}
+static int ndpi_search_kerberos_extra(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ struct ndpi_packet_struct *packet = &ndpi_struct->packet;
+
+#ifdef KERBEROS_DEBUG
+ printf("[Kerberos] Extra function\n");
+#endif
+
+ /* 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)
+ return 1;
+
+ /* Possibly dissect the reply */
+ ndpi_search_kerberos(ndpi_struct, flow);
+
+ /* Possibly more processing */
+ return 1;
+}
void init_kerberos_dissector(struct ndpi_detection_module_struct *ndpi_struct,
u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) {