]> git.ipfire.org Git - thirdparty/suricata-verify.git/commitdiff
add MQTT tests 205/head
authorSascha Steinbiss <satta@debian.org>
Sun, 22 Mar 2020 19:19:19 +0000 (20:19 +0100)
committerSascha Steinbiss <satta@debian.org>
Thu, 30 Jul 2020 17:56:51 +0000 (19:56 +0200)
118 files changed:
tests/mqtt-binary-message/mqtt5_pub_jpeg.pcap [new file with mode: 0644]
tests/mqtt-binary-message/suricata.yaml [new file with mode: 0644]
tests/mqtt-binary-message/test.rules [new file with mode: 0644]
tests/mqtt-binary-message/test.yaml [new file with mode: 0644]
tests/mqtt-events-invalid-qos/input.pcap [new file with mode: 0644]
tests/mqtt-events-invalid-qos/test.rules [new file with mode: 0644]
tests/mqtt-events-invalid-qos/test.yaml [new file with mode: 0644]
tests/mqtt-events-missing-connect/input.pcap [new file with mode: 0644]
tests/mqtt-events-missing-connect/test.rules [new file with mode: 0644]
tests/mqtt-events-missing-connect/test.yaml [new file with mode: 0644]
tests/mqtt-events-unassigned-msgtype/input.pcap [new file with mode: 0644]
tests/mqtt-events-unassigned-msgtype/test.rules [new file with mode: 0644]
tests/mqtt-events-unassigned-msgtype/test.yaml [new file with mode: 0644]
tests/mqtt-events-unintroduced/input.pcap [new file with mode: 0644]
tests/mqtt-events-unintroduced/test.rules [new file with mode: 0644]
tests/mqtt-events-unintroduced/test.yaml [new file with mode: 0644]
tests/mqtt-limit-1/input.pcap [new file with mode: 0644]
tests/mqtt-limit-1/suricata.yaml [new file with mode: 0644]
tests/mqtt-limit-1/test.yaml [new file with mode: 0644]
tests/mqtt-limit-2/input.pcap [new file with mode: 0644]
tests/mqtt-limit-2/suricata.yaml [new file with mode: 0644]
tests/mqtt-limit-2/test.yaml [new file with mode: 0644]
tests/mqtt-limit-3/input.pcap [new file with mode: 0644]
tests/mqtt-limit-3/suricata.yaml [new file with mode: 0644]
tests/mqtt-limit-3/test.yaml [new file with mode: 0644]
tests/mqtt-pub-rules/mqtt5_pub_jpeg.pcap [new file with mode: 0644]
tests/mqtt-pub-rules/suricata.yaml [new file with mode: 0644]
tests/mqtt-pub-rules/test.rules [new file with mode: 0644]
tests/mqtt-pub-rules/test.yaml [new file with mode: 0644]
tests/mqtt-sub-rules/mqtt5_sub_userpass.pcap [new file with mode: 0644]
tests/mqtt-sub-rules/suricata.yaml [new file with mode: 0644]
tests/mqtt-sub-rules/test.rules [new file with mode: 0644]
tests/mqtt-sub-rules/test.yaml [new file with mode: 0644]
tests/mqtt-unsub-rules/mqtt5_unsub_userpass.pcap [new file with mode: 0644]
tests/mqtt-unsub-rules/suricata.yaml [new file with mode: 0644]
tests/mqtt-unsub-rules/test.rules [new file with mode: 0644]
tests/mqtt-unsub-rules/test.yaml [new file with mode: 0644]
tests/mqtt31-pub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt31-pub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt31-pub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt31-pub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt31-pub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt31-pub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt31-pub-userpass-auto-clientid/input.pcap [new file with mode: 0644]
tests/mqtt31-pub-userpass-auto-clientid/suricata.yaml [new file with mode: 0644]
tests/mqtt31-pub-userpass-auto-clientid/test.yaml [new file with mode: 0644]
tests/mqtt31-pub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt31-pub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt31-pub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt31-sub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt31-sub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt31-sub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt31-unsub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt31-unsub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt31-unsub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt31-unsub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt31-unsub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt31-unsub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt31-unsub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt31-unsub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt31-unsub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt311-pub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt311-pub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt311-pub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt311-pub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt311-pub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt311-pub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt311-pub-userpass-auto-clientid/input.pcap [new file with mode: 0644]
tests/mqtt311-pub-userpass-auto-clientid/suricata.yaml [new file with mode: 0644]
tests/mqtt311-pub-userpass-auto-clientid/test.yaml [new file with mode: 0644]
tests/mqtt311-pub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt311-pub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt311-pub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt311-sub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt311-sub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt311-sub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt311-unsub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt311-unsub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt311-unsub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt311-unsub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt311-unsub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt311-unsub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt311-unsub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt311-unsub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt311-unsub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt5-pub-mosquittoprops/input.pcap [new file with mode: 0644]
tests/mqtt5-pub-mosquittoprops/suricata.yaml [new file with mode: 0644]
tests/mqtt5-pub-mosquittoprops/test.yaml [new file with mode: 0644]
tests/mqtt5-pub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt5-pub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt5-pub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt5-pub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt5-pub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt5-pub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt5-pub-userpass-auto-clientid/input.pcap [new file with mode: 0644]
tests/mqtt5-pub-userpass-auto-clientid/suricata.yaml [new file with mode: 0644]
tests/mqtt5-pub-userpass-auto-clientid/test.yaml [new file with mode: 0644]
tests/mqtt5-pub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt5-pub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt5-pub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt5-sub-customauth/input.pcap [new file with mode: 0644]
tests/mqtt5-sub-customauth/suricata.yaml [new file with mode: 0644]
tests/mqtt5-sub-customauth/test.yaml [new file with mode: 0644]
tests/mqtt5-sub-mosquittoprops/input.pcap [new file with mode: 0644]
tests/mqtt5-sub-mosquittoprops/suricata.yaml [new file with mode: 0644]
tests/mqtt5-sub-mosquittoprops/test.yaml [new file with mode: 0644]
tests/mqtt5-sub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt5-sub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt5-sub-userpass/test.yaml [new file with mode: 0644]
tests/mqtt5-unsub-qos1/input.pcap [new file with mode: 0644]
tests/mqtt5-unsub-qos1/suricata.yaml [new file with mode: 0644]
tests/mqtt5-unsub-qos1/test.yaml [new file with mode: 0644]
tests/mqtt5-unsub-qos2/input.pcap [new file with mode: 0644]
tests/mqtt5-unsub-qos2/suricata.yaml [new file with mode: 0644]
tests/mqtt5-unsub-qos2/test.yaml [new file with mode: 0644]
tests/mqtt5-unsub-userpass/input.pcap [new file with mode: 0644]
tests/mqtt5-unsub-userpass/suricata.yaml [new file with mode: 0644]
tests/mqtt5-unsub-userpass/test.yaml [new file with mode: 0644]

diff --git a/tests/mqtt-binary-message/mqtt5_pub_jpeg.pcap b/tests/mqtt-binary-message/mqtt5_pub_jpeg.pcap
new file mode 100644 (file)
index 0000000..fd6e905
Binary files /dev/null and b/tests/mqtt-binary-message/mqtt5_pub_jpeg.pcap differ
diff --git a/tests/mqtt-binary-message/suricata.yaml b/tests/mqtt-binary-message/suricata.yaml
new file mode 100644 (file)
index 0000000..6fb68aa
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+        - alert
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt-binary-message/test.rules b/tests/mqtt-binary-message/test.rules
new file mode 100644 (file)
index 0000000..e271d2b
--- /dev/null
@@ -0,0 +1 @@
+alert mqtt any any -> any any (msg:"MQTT PUBLISH JPEG message"; mqtt.type:PUBLISH; mqtt.publish.message; content:"|FF D8 FF E0|"; startswith; fast_pattern;)
\ No newline at end of file
diff --git a/tests/mqtt-binary-message/test.yaml b/tests/mqtt-binary-message/test.yaml
new file mode 100644 (file)
index 0000000..6ff46a0
--- /dev/null
@@ -0,0 +1,64 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: ""
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT PUBLISH JPEG message
diff --git a/tests/mqtt-events-invalid-qos/input.pcap b/tests/mqtt-events-invalid-qos/input.pcap
new file mode 100644 (file)
index 0000000..e76de75
Binary files /dev/null and b/tests/mqtt-events-invalid-qos/input.pcap differ
diff --git a/tests/mqtt-events-invalid-qos/test.rules b/tests/mqtt-events-invalid-qos/test.rules
new file mode 100644 (file)
index 0000000..45017bf
--- /dev/null
@@ -0,0 +1,14 @@
+# MQTT app-layer event rules.
+#
+# This SIDs fall in the 2226000+ range. See:
+#    http://doc.emergingthreats.net/bin/view/Main/SidAllocation
+
+alert mqtt any any -> any any (msg:"SURICATA MQTT CONNECT not seen before CONNACK"; app-layer-event:mqtt.missing_connect; classtype:protocol-command-decode; sid:2226000; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT PUBLISH not seen before PUBACK/PUBREL/PUBREC/PUBCOMP"; app-layer-event:mqtt.missing_publish; classtype:protocol-command-decode; sid:2226001; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT SUBSCRIBE not seen before SUBACK"; app-layer-event:mqtt.missing_subscribe; classtype:protocol-command-decode; sid:2226002; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT UNSUBSCRIBE not seen before UNSUBACK"; app-layer-event:mqtt.missing_unsubscribe; classtype:protocol-command-decode; sid:2226003; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT duplicate CONNECT"; app-layer-event:mqtt.double_connect; classtype:protocol-command-decode; sid:2226004; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT message seen before CONNECT/CONNACK completion"; app-layer-event:mqtt.unintroduced_message; classtype:protocol-command-decode; sid:2226005; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT invalid QOS level"; app-layer-event:mqtt.invalid_qos_level; classtype:protocol-command-decode; sid:2226006; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT missing message ID"; app-layer-event:mqtt.missing_msg_id; classtype:protocol-command-decode; sid:2226007; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT unassigned message type (0 or >15)"; app-layer-event:mqtt.unassigned_msg_type; classtype:protocol-command-decode; sid:2226008; rev:1;)
\ No newline at end of file
diff --git a/tests/mqtt-events-invalid-qos/test.yaml b/tests/mqtt-events-invalid-qos/test.yaml
new file mode 100644 (file)
index 0000000..44b3eac
--- /dev/null
@@ -0,0 +1,22 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 2
+      match:
+        event_type: alert
+        alert.signature_id: 2226006
+
+  - filter:
+      count: 1
+      match:
+        event_type: anomaly
+        anomaly.event: invalid_qos_level
diff --git a/tests/mqtt-events-missing-connect/input.pcap b/tests/mqtt-events-missing-connect/input.pcap
new file mode 100644 (file)
index 0000000..404abce
Binary files /dev/null and b/tests/mqtt-events-missing-connect/input.pcap differ
diff --git a/tests/mqtt-events-missing-connect/test.rules b/tests/mqtt-events-missing-connect/test.rules
new file mode 100644 (file)
index 0000000..45017bf
--- /dev/null
@@ -0,0 +1,14 @@
+# MQTT app-layer event rules.
+#
+# This SIDs fall in the 2226000+ range. See:
+#    http://doc.emergingthreats.net/bin/view/Main/SidAllocation
+
+alert mqtt any any -> any any (msg:"SURICATA MQTT CONNECT not seen before CONNACK"; app-layer-event:mqtt.missing_connect; classtype:protocol-command-decode; sid:2226000; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT PUBLISH not seen before PUBACK/PUBREL/PUBREC/PUBCOMP"; app-layer-event:mqtt.missing_publish; classtype:protocol-command-decode; sid:2226001; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT SUBSCRIBE not seen before SUBACK"; app-layer-event:mqtt.missing_subscribe; classtype:protocol-command-decode; sid:2226002; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT UNSUBSCRIBE not seen before UNSUBACK"; app-layer-event:mqtt.missing_unsubscribe; classtype:protocol-command-decode; sid:2226003; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT duplicate CONNECT"; app-layer-event:mqtt.double_connect; classtype:protocol-command-decode; sid:2226004; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT message seen before CONNECT/CONNACK completion"; app-layer-event:mqtt.unintroduced_message; classtype:protocol-command-decode; sid:2226005; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT invalid QOS level"; app-layer-event:mqtt.invalid_qos_level; classtype:protocol-command-decode; sid:2226006; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT missing message ID"; app-layer-event:mqtt.missing_msg_id; classtype:protocol-command-decode; sid:2226007; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT unassigned message type (0 or >15)"; app-layer-event:mqtt.unassigned_msg_type; classtype:protocol-command-decode; sid:2226008; rev:1;)
\ No newline at end of file
diff --git a/tests/mqtt-events-missing-connect/test.yaml b/tests/mqtt-events-missing-connect/test.yaml
new file mode 100644 (file)
index 0000000..97bdb0e
--- /dev/null
@@ -0,0 +1,22 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 2
+      match:
+        event_type: alert
+        alert.signature_id: 2226000
+
+  - filter:
+      count: 1
+      match:
+        event_type: anomaly
+        anomaly.event: missing_connect
diff --git a/tests/mqtt-events-unassigned-msgtype/input.pcap b/tests/mqtt-events-unassigned-msgtype/input.pcap
new file mode 100644 (file)
index 0000000..49c1ebe
Binary files /dev/null and b/tests/mqtt-events-unassigned-msgtype/input.pcap differ
diff --git a/tests/mqtt-events-unassigned-msgtype/test.rules b/tests/mqtt-events-unassigned-msgtype/test.rules
new file mode 100644 (file)
index 0000000..45017bf
--- /dev/null
@@ -0,0 +1,14 @@
+# MQTT app-layer event rules.
+#
+# This SIDs fall in the 2226000+ range. See:
+#    http://doc.emergingthreats.net/bin/view/Main/SidAllocation
+
+alert mqtt any any -> any any (msg:"SURICATA MQTT CONNECT not seen before CONNACK"; app-layer-event:mqtt.missing_connect; classtype:protocol-command-decode; sid:2226000; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT PUBLISH not seen before PUBACK/PUBREL/PUBREC/PUBCOMP"; app-layer-event:mqtt.missing_publish; classtype:protocol-command-decode; sid:2226001; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT SUBSCRIBE not seen before SUBACK"; app-layer-event:mqtt.missing_subscribe; classtype:protocol-command-decode; sid:2226002; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT UNSUBSCRIBE not seen before UNSUBACK"; app-layer-event:mqtt.missing_unsubscribe; classtype:protocol-command-decode; sid:2226003; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT duplicate CONNECT"; app-layer-event:mqtt.double_connect; classtype:protocol-command-decode; sid:2226004; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT message seen before CONNECT/CONNACK completion"; app-layer-event:mqtt.unintroduced_message; classtype:protocol-command-decode; sid:2226005; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT invalid QOS level"; app-layer-event:mqtt.invalid_qos_level; classtype:protocol-command-decode; sid:2226006; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT missing message ID"; app-layer-event:mqtt.missing_msg_id; classtype:protocol-command-decode; sid:2226007; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT unassigned message type (0 or >15)"; app-layer-event:mqtt.unassigned_msg_type; classtype:protocol-command-decode; sid:2226008; rev:1;)
\ No newline at end of file
diff --git a/tests/mqtt-events-unassigned-msgtype/test.yaml b/tests/mqtt-events-unassigned-msgtype/test.yaml
new file mode 100644 (file)
index 0000000..d874141
--- /dev/null
@@ -0,0 +1,22 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 2
+      match:
+        event_type: alert
+        alert.signature_id: 2226008
+
+  - filter:
+      count: 1
+      match:
+        event_type: anomaly
+        anomaly.event: unassigned_msg_type
diff --git a/tests/mqtt-events-unintroduced/input.pcap b/tests/mqtt-events-unintroduced/input.pcap
new file mode 100644 (file)
index 0000000..01147de
Binary files /dev/null and b/tests/mqtt-events-unintroduced/input.pcap differ
diff --git a/tests/mqtt-events-unintroduced/test.rules b/tests/mqtt-events-unintroduced/test.rules
new file mode 100644 (file)
index 0000000..45017bf
--- /dev/null
@@ -0,0 +1,14 @@
+# MQTT app-layer event rules.
+#
+# This SIDs fall in the 2226000+ range. See:
+#    http://doc.emergingthreats.net/bin/view/Main/SidAllocation
+
+alert mqtt any any -> any any (msg:"SURICATA MQTT CONNECT not seen before CONNACK"; app-layer-event:mqtt.missing_connect; classtype:protocol-command-decode; sid:2226000; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT PUBLISH not seen before PUBACK/PUBREL/PUBREC/PUBCOMP"; app-layer-event:mqtt.missing_publish; classtype:protocol-command-decode; sid:2226001; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT SUBSCRIBE not seen before SUBACK"; app-layer-event:mqtt.missing_subscribe; classtype:protocol-command-decode; sid:2226002; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT UNSUBSCRIBE not seen before UNSUBACK"; app-layer-event:mqtt.missing_unsubscribe; classtype:protocol-command-decode; sid:2226003; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT duplicate CONNECT"; app-layer-event:mqtt.double_connect; classtype:protocol-command-decode; sid:2226004; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT message seen before CONNECT/CONNACK completion"; app-layer-event:mqtt.unintroduced_message; classtype:protocol-command-decode; sid:2226005; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT invalid QOS level"; app-layer-event:mqtt.invalid_qos_level; classtype:protocol-command-decode; sid:2226006; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT missing message ID"; app-layer-event:mqtt.missing_msg_id; classtype:protocol-command-decode; sid:2226007; rev:1;)
+alert mqtt any any -> any any (msg:"SURICATA MQTT unassigned message type (0 or >15)"; app-layer-event:mqtt.unassigned_msg_type; classtype:protocol-command-decode; sid:2226008; rev:1;)
\ No newline at end of file
diff --git a/tests/mqtt-events-unintroduced/test.yaml b/tests/mqtt-events-unintroduced/test.yaml
new file mode 100644 (file)
index 0000000..c5ed38a
--- /dev/null
@@ -0,0 +1,22 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 2
+      match:
+        event_type: alert
+        alert.signature_id: 2226005
+
+  - filter:
+      count: 1
+      match:
+        event_type: anomaly
+        anomaly.event: unintroduced_message
diff --git a/tests/mqtt-limit-1/input.pcap b/tests/mqtt-limit-1/input.pcap
new file mode 100644 (file)
index 0000000..cf8fe04
Binary files /dev/null and b/tests/mqtt-limit-1/input.pcap differ
diff --git a/tests/mqtt-limit-1/suricata.yaml b/tests/mqtt-limit-1/suricata.yaml
new file mode 100644 (file)
index 0000000..b5dd03f
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
+      max-msg-length: 50000
\ No newline at end of file
diff --git a/tests/mqtt-limit-1/test.yaml b/tests/mqtt-limit-1/test.yaml
new file mode 100644 (file)
index 0000000..36fe424
--- /dev/null
@@ -0,0 +1,129 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: false
+        mqtt.connect.flags.password: false
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "P1"
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100011
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100009
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.message: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
+        mqtt.puback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.message: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
+        mqtt.puback.message_id: 4
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 4
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt-limit-2/input.pcap b/tests/mqtt-limit-2/input.pcap
new file mode 100644 (file)
index 0000000..cf8fe04
Binary files /dev/null and b/tests/mqtt-limit-2/input.pcap differ
diff --git a/tests/mqtt-limit-2/suricata.yaml b/tests/mqtt-limit-2/suricata.yaml
new file mode 100644 (file)
index 0000000..a3ba85e
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
+      max-msg-length: 500
\ No newline at end of file
diff --git a/tests/mqtt-limit-2/test.yaml b/tests/mqtt-limit-2/test.yaml
new file mode 100644 (file)
index 0000000..3b95859
--- /dev/null
@@ -0,0 +1,129 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: false
+        mqtt.connect.flags.password: false
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "P1"
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100011
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100009
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 1010
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.message: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
+        mqtt.puback.message_id: 4
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 4
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt-limit-3/input.pcap b/tests/mqtt-limit-3/input.pcap
new file mode 100644 (file)
index 0000000..cf8fe04
Binary files /dev/null and b/tests/mqtt-limit-3/input.pcap differ
diff --git a/tests/mqtt-limit-3/suricata.yaml b/tests/mqtt-limit-3/suricata.yaml
new file mode 100644 (file)
index 0000000..7fd2338
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
+      max-msg-length: 50
\ No newline at end of file
diff --git a/tests/mqtt-limit-3/test.yaml b/tests/mqtt-limit-3/test.yaml
new file mode 100644 (file)
index 0000000..1434209
--- /dev/null
@@ -0,0 +1,129 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: false
+        mqtt.connect.flags.password: false
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "P1"
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100011
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 100009
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.truncated: true
+        mqtt.publish.skipped_length: 1010
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.skipped_length: 109
+        mqtt.publish.truncated: true
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 4
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt-pub-rules/mqtt5_pub_jpeg.pcap b/tests/mqtt-pub-rules/mqtt5_pub_jpeg.pcap
new file mode 100644 (file)
index 0000000..fd6e905
Binary files /dev/null and b/tests/mqtt-pub-rules/mqtt5_pub_jpeg.pcap differ
diff --git a/tests/mqtt-pub-rules/suricata.yaml b/tests/mqtt-pub-rules/suricata.yaml
new file mode 100644 (file)
index 0000000..6fb68aa
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+        - alert
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt-pub-rules/test.rules b/tests/mqtt-pub-rules/test.rules
new file mode 100644 (file)
index 0000000..4ae61c6
--- /dev/null
@@ -0,0 +1,10 @@
+alert mqtt any any -> any any (msg:"MQTT Test CONNACK"; mqtt.type:CONNACK; sid:1;)
+alert mqtt any any -> any any (msg:"MQTT Test DISCONNECT"; mqtt.type:DISCONNECT; sid:3;)
+alert mqtt any any -> any any (msg:"MQTT Test flags"; mqtt.flags: !retain,!dup; sid:4;)
+alert mqtt any any -> any any (msg:"MQTT QOS 0 (val0)"; mqtt.qos:0; sid:6;)
+alert mqtt any any -> any any (msg:"MQTT proto version 5 CONNECT"; mqtt.protocol_version:5; mqtt.type:CONNECT; sid:12;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT flags"; mqtt.connect.flags:username,password,clean_session; sid:13;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT username"; mqtt.connect.username; content:"user"; sid:19;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT password"; mqtt.connect.password; content:"pass"; sid:20;)
+alert mqtt any any -> any any (msg:"MQTT PUBLISH topicX"; mqtt.type:PUBLISH; mqtt.publish.topic; content:"topicX"; sid:16;)
+alert mqtt any any -> any any (msg:"MQTT PUBLISH JPEG message"; mqtt.type:PUBLISH; mqtt.publish.message; content:"|FF D8 FF E0|"; startswith; fast_pattern; sid:18;)
diff --git a/tests/mqtt-pub-rules/test.yaml b/tests/mqtt-pub-rules/test.yaml
new file mode 100644 (file)
index 0000000..ec7a923
--- /dev/null
@@ -0,0 +1,107 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: ""
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT PUBLISH JPEG message
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test CONNACK
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test DISCONNECT
+
+  - filter:
+      count: 3
+      match:
+        event_type: alert
+        alert.signature: MQTT Test flags
+
+  - filter:
+      count: 3
+      match:
+        event_type: alert
+        alert.signature: "MQTT QOS 0 (val0)"
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT proto version 5 CONNECT
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT flags
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT username
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT password
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT PUBLISH topicX
diff --git a/tests/mqtt-sub-rules/mqtt5_sub_userpass.pcap b/tests/mqtt-sub-rules/mqtt5_sub_userpass.pcap
new file mode 100644 (file)
index 0000000..52ed40e
Binary files /dev/null and b/tests/mqtt-sub-rules/mqtt5_sub_userpass.pcap differ
diff --git a/tests/mqtt-sub-rules/suricata.yaml b/tests/mqtt-sub-rules/suricata.yaml
new file mode 100644 (file)
index 0000000..6fb68aa
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+        - alert
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt-sub-rules/test.rules b/tests/mqtt-sub-rules/test.rules
new file mode 100644 (file)
index 0000000..7639ec7
--- /dev/null
@@ -0,0 +1,10 @@
+alert mqtt any any -> any any (msg:"MQTT Test CONNACK"; mqtt.type:CONNACK; sid:1;)
+alert mqtt any any -> any any (msg:"MQTT Test DISCONNECT"; mqtt.type:DISCONNECT; sid:3;)
+alert mqtt any any -> any any (msg:"MQTT Test flags"; mqtt.flags: !retain,!dup; sid:4;)
+alert mqtt any any -> any any (msg:"MQTT QOS 1 (val0)"; mqtt.qos:0; sid:6;)
+alert mqtt any any -> any any (msg:"MQTT proto version 5 CONNECT"; mqtt.protocol_version:5; mqtt.type:CONNECT; sid:12;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT flags"; mqtt.connect.flags:username,password,clean_session; sid:13;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT username"; mqtt.connect.username; content:"user"; sid:19;)
+alert mqtt any any -> any any (msg:"MQTT CONNECT password"; mqtt.connect.password; content:"pass"; sid:20;)
+alert mqtt any any -> any any (msg:"MQTT SUBSCRIBE topicY"; mqtt.type:SUBSCRIBE; mqtt.subscribe.topic; content:"topicY"; sid:15;)
+alert mqtt any any -> any any (msg:"MQTT SUBSCRIBE topicY"; mqtt.type:SUBACK; mqtt.reason_code:0; sid:16;)
diff --git a/tests/mqtt-sub-rules/test.yaml b/tests/mqtt-sub-rules/test.yaml
new file mode 100644 (file)
index 0000000..117752b
--- /dev/null
@@ -0,0 +1,109 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "myvoiceismypassport"
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [{topic: topicX, qos: 0}, {topic: topicY, qos: 0} ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test CONNACK
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test DISCONNECT
+
+  - filter:
+      count: 3
+      match:
+        event_type: alert
+        alert.signature: MQTT Test flags
+
+  - filter:
+      count: 3
+      match:
+        event_type: alert
+        alert.signature: "MQTT QOS 1 (val0)"
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT proto version 5 CONNECT
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT flags
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT username
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT password
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT SUBSCRIBE topicY
diff --git a/tests/mqtt-unsub-rules/mqtt5_unsub_userpass.pcap b/tests/mqtt-unsub-rules/mqtt5_unsub_userpass.pcap
new file mode 100644 (file)
index 0000000..3c4d235
Binary files /dev/null and b/tests/mqtt-unsub-rules/mqtt5_unsub_userpass.pcap differ
diff --git a/tests/mqtt-unsub-rules/suricata.yaml b/tests/mqtt-unsub-rules/suricata.yaml
new file mode 100644 (file)
index 0000000..6fb68aa
--- /dev/null
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+        - alert
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt-unsub-rules/test.rules b/tests/mqtt-unsub-rules/test.rules
new file mode 100644 (file)
index 0000000..5c550a5
--- /dev/null
@@ -0,0 +1,24 @@
+#1
+alert mqtt any any -> any any (msg:"MQTT Test CONNACK"; mqtt.type:CONNACK; sid:1;)
+#1
+alert mqtt any any -> any any (msg:"MQTT Test DISCONNECT"; mqtt.type:DISCONNECT; sid:3;)
+#4
+alert mqtt any any -> any any (msg:"MQTT Test flags"; mqtt.flags: !retain,!dup; sid:4;)
+#4
+alert mqtt any any -> any any (msg:"MQTT QOS 1 (val0)"; mqtt.qos:0; sid:6;)
+#1
+alert mqtt any any -> any any (msg:"MQTT proto version 5 CONNECT"; mqtt.protocol_version:5; mqtt.type:CONNECT; sid:12;)
+#1
+alert mqtt any any -> any any (msg:"MQTT CONNECT flags"; mqtt.connect.flags:username,password,clean_session; sid:13;)
+#1
+alert mqtt any any -> any any (msg:"MQTT CONNECT username"; mqtt.connect.username; content:"user"; sid:19;)
+#1
+alert mqtt any any -> any any (msg:"MQTT CONNECT password"; mqtt.connect.password; content:"pass"; sid:20;)
+#1
+alert mqtt any any -> any any (msg:"MQTT UNSUBSCRIBE topicX"; mqtt.type:UNSUBSCRIBE; mqtt.unsubscribe.topic; content:"topicX"; sid:16;)
+#1
+alert mqtt any any -> any any (msg:"MQTT UNSUBSCRIBE topicY"; mqtt.type:UNSUBSCRIBE; mqtt.unsubscribe.topic; content:"topicY"; sid:17;)
+#1
+alert mqtt any any -> any any (msg:"MQTT UNSUBACK reason 17"; mqtt.type:UNSUBACK; mqtt.reason_code:17; sid:18;)
+#1
+alert mqtt any any -> any any (msg:"MQTT UNSUBACK reason 0"; mqtt.type:UNSUBACK; mqtt.reason_code:0; sid:21;)
\ No newline at end of file
diff --git a/tests/mqtt-unsub-rules/test.yaml b/tests/mqtt-unsub-rules/test.yaml
new file mode 100644 (file)
index 0000000..573f0f8
--- /dev/null
@@ -0,0 +1,115 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "myvoiceismypassport"
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test CONNACK
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT Test DISCONNECT
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT proto version 5 CONNECT
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT flags
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT username
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT CONNECT password
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT UNSUBSCRIBE topicX
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT UNSUBSCRIBE topicY
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT UNSUBACK reason 17
+        mqtt.unsuback.message_id: 3
+        mqtt.unsuback.reason_codes: [ 17 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: alert
+        alert.signature: MQTT UNSUBACK reason 0
+        mqtt.unsuback.message_id: 2
+        mqtt.unsuback.reason_codes: [ 0 ]
diff --git a/tests/mqtt31-pub-qos1/input.pcap b/tests/mqtt31-pub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..c35e969
Binary files /dev/null and b/tests/mqtt31-pub-qos1/input.pcap differ
diff --git a/tests/mqtt31-pub-qos1/suricata.yaml b/tests/mqtt31-pub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-pub-qos1/test.yaml b/tests/mqtt31-pub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..1e12c54
--- /dev/null
@@ -0,0 +1,71 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-pub-qos2/input.pcap b/tests/mqtt31-pub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..ba491cc
Binary files /dev/null and b/tests/mqtt31-pub-qos2/input.pcap differ
diff --git a/tests/mqtt31-pub-qos2/suricata.yaml b/tests/mqtt31-pub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-pub-qos2/test.yaml b/tests/mqtt31-pub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..70e7d0e
--- /dev/null
@@ -0,0 +1,89 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 2
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrec.qos: 0
+        mqtt.pubrec.retain: false
+        mqtt.pubrec.dup: false
+        mqtt.pubrec.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrel.qos: 1
+        mqtt.pubrel.retain: false
+        mqtt.pubrel.dup: false
+        mqtt.pubrel.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubcomp.qos: 0
+        mqtt.pubcomp.retain: false
+        mqtt.pubcomp.dup: false
+        mqtt.pubcomp.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-pub-userpass-auto-clientid/input.pcap b/tests/mqtt31-pub-userpass-auto-clientid/input.pcap
new file mode 100644 (file)
index 0000000..3cdc5b2
Binary files /dev/null and b/tests/mqtt31-pub-userpass-auto-clientid/input.pcap differ
diff --git a/tests/mqtt31-pub-userpass-auto-clientid/suricata.yaml b/tests/mqtt31-pub-userpass-auto-clientid/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-pub-userpass-auto-clientid/test.yaml b/tests/mqtt31-pub-userpass-auto-clientid/test.yaml
new file mode 100644 (file)
index 0000000..462b0c3
--- /dev/null
@@ -0,0 +1,61 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "mosq-dRkAMvJQvimi16jz72"
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-pub-userpass/input.pcap b/tests/mqtt31-pub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..146727d
Binary files /dev/null and b/tests/mqtt31-pub-userpass/input.pcap differ
diff --git a/tests/mqtt31-pub-userpass/suricata.yaml b/tests/mqtt31-pub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-pub-userpass/test.yaml b/tests/mqtt31-pub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..63d6018
--- /dev/null
@@ -0,0 +1,61 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-sub-userpass/input.pcap b/tests/mqtt31-sub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..3f57170
Binary files /dev/null and b/tests/mqtt31-sub-userpass/input.pcap differ
diff --git a/tests/mqtt31-sub-userpass/suricata.yaml b/tests/mqtt31-sub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-sub-userpass/test.yaml b/tests/mqtt31-sub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..c784b12
--- /dev/null
@@ -0,0 +1,71 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0}, {topic: topicY, qos: 0}]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [0, 0]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-unsub-qos1/input.pcap b/tests/mqtt31-unsub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..926c7b2
Binary files /dev/null and b/tests/mqtt31-unsub-qos1/input.pcap differ
diff --git a/tests/mqtt31-unsub-qos1/suricata.yaml b/tests/mqtt31-unsub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-unsub-qos1/test.yaml b/tests/mqtt31-unsub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..ed0858b
--- /dev/null
@@ -0,0 +1,109 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 1} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 1 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-unsub-qos2/input.pcap b/tests/mqtt31-unsub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..a0163f1
Binary files /dev/null and b/tests/mqtt31-unsub-qos2/input.pcap differ
diff --git a/tests/mqtt31-unsub-qos2/suricata.yaml b/tests/mqtt31-unsub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-unsub-qos2/test.yaml b/tests/mqtt31-unsub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..7a16605
--- /dev/null
@@ -0,0 +1,109 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 2} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 2 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt31-unsub-userpass/input.pcap b/tests/mqtt31-unsub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..5b2ac3d
Binary files /dev/null and b/tests/mqtt31-unsub-userpass/input.pcap differ
diff --git a/tests/mqtt31-unsub-userpass/suricata.yaml b/tests/mqtt31-unsub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt31-unsub-userpass/test.yaml b/tests/mqtt31-unsub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..14b6ed6
--- /dev/null
@@ -0,0 +1,110 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQIsdp
+        mqtt.connect.protocol_version: 3
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 0 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-pub-qos1/input.pcap b/tests/mqtt311-pub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..26525a0
Binary files /dev/null and b/tests/mqtt311-pub-qos1/input.pcap differ
diff --git a/tests/mqtt311-pub-qos1/suricata.yaml b/tests/mqtt311-pub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-pub-qos1/test.yaml b/tests/mqtt311-pub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..f742dbe
--- /dev/null
@@ -0,0 +1,71 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-pub-qos2/input.pcap b/tests/mqtt311-pub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..ad2b308
Binary files /dev/null and b/tests/mqtt311-pub-qos2/input.pcap differ
diff --git a/tests/mqtt311-pub-qos2/suricata.yaml b/tests/mqtt311-pub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-pub-qos2/test.yaml b/tests/mqtt311-pub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..b48d1aa
--- /dev/null
@@ -0,0 +1,89 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 2
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrec.qos: 0
+        mqtt.pubrec.retain: false
+        mqtt.pubrec.dup: false
+        mqtt.pubrec.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrel.qos: 1
+        mqtt.pubrel.retain: false
+        mqtt.pubrel.dup: false
+        mqtt.pubrel.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubcomp.qos: 0
+        mqtt.pubcomp.retain: false
+        mqtt.pubcomp.dup: false
+        mqtt.pubcomp.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-pub-userpass-auto-clientid/input.pcap b/tests/mqtt311-pub-userpass-auto-clientid/input.pcap
new file mode 100644 (file)
index 0000000..35834b9
Binary files /dev/null and b/tests/mqtt311-pub-userpass-auto-clientid/input.pcap differ
diff --git a/tests/mqtt311-pub-userpass-auto-clientid/suricata.yaml b/tests/mqtt311-pub-userpass-auto-clientid/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-pub-userpass-auto-clientid/test.yaml b/tests/mqtt311-pub-userpass-auto-clientid/test.yaml
new file mode 100644 (file)
index 0000000..3bd0e80
--- /dev/null
@@ -0,0 +1,61 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "mosq-aGMiV6nelbCb00tvAY"
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-pub-userpass/input.pcap b/tests/mqtt311-pub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..31f7dbf
Binary files /dev/null and b/tests/mqtt311-pub-userpass/input.pcap differ
diff --git a/tests/mqtt311-pub-userpass/suricata.yaml b/tests/mqtt311-pub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-pub-userpass/test.yaml b/tests/mqtt311-pub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..23f5ff9
--- /dev/null
@@ -0,0 +1,61 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-sub-userpass/input.pcap b/tests/mqtt311-sub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..80d3709
Binary files /dev/null and b/tests/mqtt311-sub-userpass/input.pcap differ
diff --git a/tests/mqtt311-sub-userpass/suricata.yaml b/tests/mqtt311-sub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-sub-userpass/test.yaml b/tests/mqtt311-sub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..2aec4ac
--- /dev/null
@@ -0,0 +1,71 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0}, {topic: topicY, qos: 0}]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [0, 0]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-unsub-qos1/input.pcap b/tests/mqtt311-unsub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..2f58467
Binary files /dev/null and b/tests/mqtt311-unsub-qos1/input.pcap differ
diff --git a/tests/mqtt311-unsub-qos1/suricata.yaml b/tests/mqtt311-unsub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-unsub-qos1/test.yaml b/tests/mqtt311-unsub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..3d79118
--- /dev/null
@@ -0,0 +1,109 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 1} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 1 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-unsub-qos2/input.pcap b/tests/mqtt311-unsub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..00fc7d6
Binary files /dev/null and b/tests/mqtt311-unsub-qos2/input.pcap differ
diff --git a/tests/mqtt311-unsub-qos2/suricata.yaml b/tests/mqtt311-unsub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-unsub-qos2/test.yaml b/tests/mqtt311-unsub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..077bca9
--- /dev/null
@@ -0,0 +1,109 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 2} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 2 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt311-unsub-userpass/input.pcap b/tests/mqtt311-unsub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..da0d281
Binary files /dev/null and b/tests/mqtt311-unsub-userpass/input.pcap differ
diff --git a/tests/mqtt311-unsub-userpass/suricata.yaml b/tests/mqtt311-unsub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt311-unsub-userpass/test.yaml b/tests/mqtt311-unsub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..644eaae
--- /dev/null
@@ -0,0 +1,110 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 4
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 0 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
diff --git a/tests/mqtt5-pub-mosquittoprops/input.pcap b/tests/mqtt5-pub-mosquittoprops/input.pcap
new file mode 100644 (file)
index 0000000..f2c8d76
Binary files /dev/null and b/tests/mqtt5-pub-mosquittoprops/input.pcap differ
diff --git a/tests/mqtt5-pub-mosquittoprops/suricata.yaml b/tests/mqtt5-pub-mosquittoprops/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-pub-mosquittoprops/test.yaml b/tests/mqtt5-pub-mosquittoprops/test.yaml
new file mode 100644 (file)
index 0000000..f59e83e
--- /dev/null
@@ -0,0 +1,98 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: true
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.will.topic: willtopic
+        mqtt.connect.will.message: willmessage
+        mqtt.connect.will.properties.content_type: mywilltype
+        mqtt.connect.will.properties.correlation_data: "1234567"
+        mqtt.connect.will.properties.message_expiry_interval: 133
+        mqtt.connect.will.properties.payload_format_indicator: 144
+        mqtt.connect.will.properties.response_topic: response_topic1
+        mqtt.connect.will.properties.userprop5: userval5
+        mqtt.connect.will.properties.will_delay_interval: 200
+        mqtt.connect.properties.maximum_packet_size: 11111
+        mqtt.connect.properties.receive_maximum: 222
+        mqtt.connect.properties.session_expiry_interval: 555
+        mqtt.connect.properties.topic_alias_maximum: 666
+        mqtt.connect.properties.userprop1: userval1
+        mqtt.connect.properties.userprop2: userval2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+        mqtt.publish.properties.content_type: mytype
+        mqtt.publish.properties.correlation_data: "12345"
+        mqtt.publish.properties.message_expiry_interval: 77
+        mqtt.publish.properties.payload_format_indicator: 88
+        mqtt.publish.properties.response_topic: response_topic1
+        mqtt.publish.properties.topic_alias: 5
+        mqtt.publish.properties.userprop3: userval3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 1
+        mqtt.puback.reason_code: 16
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
+        mqtt.disconnect.properties.session_expiry_interval: 122
+        mqtt.disconnect.properties.userprop4: userval4
diff --git a/tests/mqtt5-pub-qos1/input.pcap b/tests/mqtt5-pub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..141d4c5
Binary files /dev/null and b/tests/mqtt5-pub-qos1/input.pcap differ
diff --git a/tests/mqtt5-pub-qos1/suricata.yaml b/tests/mqtt5-pub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-pub-qos1/test.yaml b/tests/mqtt5-pub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..a185de2
--- /dev/null
@@ -0,0 +1,76 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 1
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.puback.qos: 0
+        mqtt.puback.retain: false
+        mqtt.puback.dup: false
+        mqtt.puback.message_id: 1
+        # "no subscriber"
+        mqtt.puback.reason_code: 16
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-pub-qos2/input.pcap b/tests/mqtt5-pub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..c651078
Binary files /dev/null and b/tests/mqtt5-pub-qos2/input.pcap differ
diff --git a/tests/mqtt5-pub-qos2/suricata.yaml b/tests/mqtt5-pub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-pub-qos2/test.yaml b/tests/mqtt5-pub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..75d1d7b
--- /dev/null
@@ -0,0 +1,95 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 2
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+        mqtt.publish.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrel.qos: 1
+        mqtt.pubrel.retain: false
+        mqtt.pubrel.dup: false
+        mqtt.pubrel.message_id: 1
+        mqtt.pubrel.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubrec.qos: 0
+        mqtt.pubrec.retain: false
+        mqtt.pubrec.dup: false
+        mqtt.pubrec.message_id: 1
+        mqtt.pubrec.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.pubcomp.qos: 0
+        mqtt.pubcomp.retain: false
+        mqtt.pubcomp.dup: false
+        mqtt.pubcomp.message_id: 1
+        mqtt.pubcomp.reason_code: 0
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-pub-userpass-auto-clientid/input.pcap b/tests/mqtt5-pub-userpass-auto-clientid/input.pcap
new file mode 100644 (file)
index 0000000..90b9801
Binary files /dev/null and b/tests/mqtt5-pub-userpass-auto-clientid/input.pcap differ
diff --git a/tests/mqtt5-pub-userpass-auto-clientid/suricata.yaml b/tests/mqtt5-pub-userpass-auto-clientid/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-pub-userpass-auto-clientid/test.yaml b/tests/mqtt5-pub-userpass-auto-clientid/test.yaml
new file mode 100644 (file)
index 0000000..0edf0b4
--- /dev/null
@@ -0,0 +1,65 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: ""
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+        mqtt.connack.properties.assigned_client_identifier: auto-6F78CADB-9176-19F4-B5F5-101745377C35
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-pub-userpass/input.pcap b/tests/mqtt5-pub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..9b4ec51
Binary files /dev/null and b/tests/mqtt5-pub-userpass/input.pcap differ
diff --git a/tests/mqtt5-pub-userpass/suricata.yaml b/tests/mqtt5-pub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-pub-userpass/test.yaml b/tests/mqtt5-pub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..a366a0c
--- /dev/null
@@ -0,0 +1,64 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.publish.qos: 0
+        mqtt.publish.retain: false
+        mqtt.publish.dup: false
+        mqtt.publish.topic: topicX
+        mqtt.publish.message: baabaablacksheep
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-sub-customauth/input.pcap b/tests/mqtt5-sub-customauth/input.pcap
new file mode 100644 (file)
index 0000000..90b7072
Binary files /dev/null and b/tests/mqtt5-sub-customauth/input.pcap differ
diff --git a/tests/mqtt5-sub-customauth/suricata.yaml b/tests/mqtt5-sub-customauth/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-sub-customauth/test.yaml b/tests/mqtt5-sub-customauth/test.yaml
new file mode 100644 (file)
index 0000000..a13179b
--- /dev/null
@@ -0,0 +1,44 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 1
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: false
+        mqtt.connect.flags.password: false
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: "myvoiceismypassport"
+        mqtt.connect.properties.receive_maximum: 20
+        mqtt.connect.properties.authentication_method: foo
+        mqtt.connect.properties.authentication_data: "1234"
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 140
diff --git a/tests/mqtt5-sub-mosquittoprops/input.pcap b/tests/mqtt5-sub-mosquittoprops/input.pcap
new file mode 100644 (file)
index 0000000..9d79a50
Binary files /dev/null and b/tests/mqtt5-sub-mosquittoprops/input.pcap differ
diff --git a/tests/mqtt5-sub-mosquittoprops/suricata.yaml b/tests/mqtt5-sub-mosquittoprops/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-sub-mosquittoprops/test.yaml b/tests/mqtt5-sub-mosquittoprops/test.yaml
new file mode 100644 (file)
index 0000000..d2a4f87
--- /dev/null
@@ -0,0 +1,91 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: true
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.will.topic: willtopic
+        mqtt.connect.will.message: willmessage
+        mqtt.connect.will.properties.content_type: mywilltype
+        mqtt.connect.will.properties.correlation_data: "1234567"
+        mqtt.connect.will.properties.message_expiry_interval: 133
+        mqtt.connect.will.properties.payload_format_indicator: 144
+        mqtt.connect.will.properties.response_topic: response_topic1
+        mqtt.connect.will.properties.userprop5: userval5
+        mqtt.connect.will.properties.will_delay_interval: 200
+        mqtt.connect.properties.maximum_packet_size: 11111
+        mqtt.connect.properties.receive_maximum: 222
+        mqtt.connect.properties.session_expiry_interval: 555
+        mqtt.connect.properties.topic_alias_maximum: 666
+        mqtt.connect.properties.userprop1: userval1
+        mqtt.connect.properties.userprop2: userval2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0}, {topic: topicY, qos: 0}]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [0, 0]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        # "Disconnect with Will Message"
+        mqtt.disconnect.reason_code: 4
+        mqtt.disconnect.properties.session_expiry_interval: 122
+        mqtt.disconnect.properties.userprop4: userval4
diff --git a/tests/mqtt5-sub-userpass/input.pcap b/tests/mqtt5-sub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..52ed40e
Binary files /dev/null and b/tests/mqtt5-sub-userpass/input.pcap differ
diff --git a/tests/mqtt5-sub-userpass/suricata.yaml b/tests/mqtt5-sub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-sub-userpass/test.yaml b/tests/mqtt5-sub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..b9784a2
--- /dev/null
@@ -0,0 +1,74 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 3
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0}, {topic: topicY, qos: 0}]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [0, 0]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-unsub-qos1/input.pcap b/tests/mqtt5-unsub-qos1/input.pcap
new file mode 100644 (file)
index 0000000..13819a6
Binary files /dev/null and b/tests/mqtt5-unsub-qos1/input.pcap differ
diff --git a/tests/mqtt5-unsub-qos1/suricata.yaml b/tests/mqtt5-unsub-qos1/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-unsub-qos1/test.yaml b/tests/mqtt5-unsub-qos1/test.yaml
new file mode 100644 (file)
index 0000000..a9b24dc
--- /dev/null
@@ -0,0 +1,117 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 1} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 1 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+        mqtt.unsuback.reason_codes: [ 0 ]
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+        # "No subscription"
+        mqtt.unsuback.reason_codes: [ 17 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-unsub-qos2/input.pcap b/tests/mqtt5-unsub-qos2/input.pcap
new file mode 100644 (file)
index 0000000..50ee5d9
Binary files /dev/null and b/tests/mqtt5-unsub-qos2/input.pcap differ
diff --git a/tests/mqtt5-unsub-qos2/suricata.yaml b/tests/mqtt5-unsub-qos2/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-unsub-qos2/test.yaml b/tests/mqtt5-unsub-qos2/test.yaml
new file mode 100644 (file)
index 0000000..d8725ee
--- /dev/null
@@ -0,0 +1,117 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 2} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 2 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+        mqtt.unsuback.reason_codes: [ 0 ]
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+        # "No subscription"
+        mqtt.unsuback.reason_codes: [ 17 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0
diff --git a/tests/mqtt5-unsub-userpass/input.pcap b/tests/mqtt5-unsub-userpass/input.pcap
new file mode 100644 (file)
index 0000000..3c4d235
Binary files /dev/null and b/tests/mqtt5-unsub-userpass/input.pcap differ
diff --git a/tests/mqtt5-unsub-userpass/suricata.yaml b/tests/mqtt5-unsub-userpass/suricata.yaml
new file mode 100644 (file)
index 0000000..14f5a71
--- /dev/null
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+
+outputs:
+  - eve-log:
+      enabled: yes
+      filetype: regular
+      filename: eve.json
+      types:
+        - mqtt
+
+app-layer:
+  protocols:
+    mqtt:
+      enabled: yes
\ No newline at end of file
diff --git a/tests/mqtt5-unsub-userpass/test.yaml b/tests/mqtt5-unsub-userpass/test.yaml
new file mode 100644 (file)
index 0000000..8ba181a
--- /dev/null
@@ -0,0 +1,117 @@
+requires:
+  features:
+    - HAVE_LIBJANSSON
+  files:
+    - rust/src/mqtt/parser.rs
+
+args:
+  - -k none
+
+checks:
+
+  - filter:
+      count: 5
+      match:
+        dest_port: 1883
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connect.qos: 0
+        mqtt.connect.retain: false
+        mqtt.connect.dup: false
+        mqtt.connect.protocol_string: MQTT
+        mqtt.connect.protocol_version: 5
+        mqtt.connect.flags.username: true
+        mqtt.connect.flags.password: true
+        mqtt.connect.flags.will: false
+        mqtt.connect.flags.will_retain: false
+        mqtt.connect.flags.clean_session: true
+        mqtt.connect.client_id: myvoiceismypassport
+        mqtt.connect.username: user
+        mqtt.connect.password: pass
+        mqtt.connect.properties.receive_maximum: 20
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.connack.qos: 0
+        mqtt.connack.retain: false
+        mqtt.connack.dup: false
+        mqtt.connack.session_present: false
+        mqtt.connack.return_code: 0
+        mqtt.connack.properties.topic_alias_maximum: 10
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.subscribe.qos: 1
+        mqtt.subscribe.retain: false
+        mqtt.subscribe.dup: false
+        mqtt.subscribe.topics: [ {topic: topicX, qos: 0} ]
+        mqtt.subscribe.message_id: 1
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.suback.qos: 0
+        mqtt.suback.retain: false
+        mqtt.suback.dup: false
+        mqtt.suback.message_id: 1
+        mqtt.suback.qos_granted: [ 0 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicX ]
+        mqtt.unsubscribe.message_id: 2
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsubscribe.qos: 1
+        mqtt.unsubscribe.retain: false
+        mqtt.unsubscribe.dup: false
+        mqtt.unsubscribe.topics: [ topicY ]
+        mqtt.unsubscribe.message_id: 3
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 2
+        mqtt.unsuback.reason_codes: [ 0 ]
+
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.unsuback.qos: 0
+        mqtt.unsuback.retain: false
+        mqtt.unsuback.dup: false
+        mqtt.unsuback.message_id: 3
+        # "No subscription"
+        mqtt.unsuback.reason_codes: [ 17 ]
+
+  - filter:
+      count: 1
+      match:
+        event_type: mqtt
+        mqtt.disconnect.qos: 0
+        mqtt.disconnect.retain: false
+        mqtt.disconnect.dup: false
+        mqtt.disconnect.reason_code: 0