]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/ikev2: fix events not being raised in first message
authorPierre Chifflier <chifflier@wzdftpd.net>
Mon, 4 Mar 2019 17:47:07 +0000 (18:47 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 5 Mar 2019 12:30:02 +0000 (13:30 +0100)
The `set_event` function requires that the transaction is already
inserted, or the event set is silently lost.
When parsing first IKEv2 message, first insert transaction, prepare
values, and borrow back inserted transaction to update it.

rust/src/ikev2/ikev2.rs

index 417e28f9180c3abd3cf5c55102b97f0f2b68df58..dfff4f10b5aaf93fa4dc499238c90765f7a29ac4 100644 (file)
@@ -149,10 +149,14 @@ impl IKEV2State {
                 // use init_spi as transaction identifier
                 tx.xid = hdr.init_spi;
                 tx.hdr = (*hdr).clone();
+                self.transactions.push(tx);
+                let mut payload_types = Vec::new();
+                let mut errors = 0;
+                let mut notify_types = Vec::new();
                 match parse_ikev2_payload_list(rem,hdr.next_payload) {
                     Ok((_,Ok(ref p))) => {
                         for payload in p {
-                            tx.payload_types.push(payload.hdr.next_payload_type);
+                            payload_types.push(payload.hdr.next_payload_type);
                             match payload.content {
                                 IkeV2PayloadContent::Dummy => (),
                                 IkeV2PayloadContent::SA(ref prop) => {
@@ -172,9 +176,9 @@ impl IKEV2State {
                                 IkeV2PayloadContent::Notify(ref n) => {
                                     SCLogDebug!("Notify: {:?}", n);
                                     if n.notify_type.is_error() {
-                                        tx.errors += 1;
+                                        errors += 1;
                                     }
-                                    tx.notify_types.push(n.notify_type);
+                                    notify_types.push(n.notify_type);
                                 },
                                 // XXX CertificateRequest
                                 // XXX Certificate
@@ -187,11 +191,16 @@ impl IKEV2State {
                                 },
                             }
                             self.connection_state = self.connection_state.advance(payload);
+                            if let Some(tx) = self.transactions.last_mut() {
+                                // borrow back tx to update it
+                                tx.payload_types.append(&mut payload_types);
+                                tx.errors = errors;
+                                tx.notify_types.append(&mut notify_types);
+                            }
                         };
                     },
                     e => { SCLogDebug!("parse_ikev2_payload_with_type: {:?}",e); () },
                 }
-                self.transactions.push(tx);
                 1
             },
             Err(nom::Err::Incomplete(_)) => {
@@ -235,6 +244,8 @@ impl IKEV2State {
         if let Some(tx) = self.transactions.last_mut() {
             let ev = event as u8;
             core::sc_app_layer_decoder_events_set_event_raw(&mut tx.events, ev);
+        } else {
+            SCLogDebug!("IKEv2: trying to set event {} on non-existing transaction", event as u32);
         }
     }