]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ike: set event for multiple server proposals
authorfrank honza <frank.honza@dcso.de>
Fri, 16 Apr 2021 08:21:22 +0000 (10:21 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 4 May 2021 08:36:54 +0000 (10:36 +0200)
doc/userguide/output/eve/eve-json-format.rst
doc/userguide/rules/ike-keywords.rst
rules/ipsec-events.rules
rust/src/ike/detect.rs
rust/src/ike/ike.rs
rust/src/ike/ikev1.rs
rust/src/ike/logger.rs

index 88545f7debdaa26087a1bc33db55b2d6928a591d..512cd6f6c72ec1ef373091f02c9c2748fc6bb932 100644 (file)
@@ -1838,6 +1838,7 @@ Fields
 * "ikev1.server.nonce_payload_length", "ikev1.client.nonce_payload_length": Length of the nonce payload.
 * "ikev1.client.client_proposals": List of the security associations proposed to the server.
 * "ikev1.vendor_ids": List of the vendor IDs observed in the communication.
+* "server_proposals": List of server proposals with parameters, if there are more than one. This is a non-standard case; this field is only present if such a situation was observed in the inspected traffic.
 
 
 
index b8ee70277e72606df20e1347fc40ee27d8cbace7..1d12ce329e663e62fd1330fd393b41ae563eda1b 100644 (file)
@@ -47,6 +47,8 @@ Match on an attribute value of the chosen Security Association (SA) by the Respo
 ``sa_field_size``.
 IKEv2 supports ``alg_enc``, ``alg_auth``, ``alg_prf`` and ``alg_dh``.
 
+If there is more than one chosen SA the event ``MultipleServerProposal`` is set. The attributes of the first SA are used for this keyword.
+
 
 Examples::
 
index 1ae6edffe6e90ef744113cd5f7474922396e4731..ccfd65145c57317ca318dd1e588a968b8732378a 100644 (file)
@@ -17,3 +17,4 @@ alert ike any any -> any any (msg:"SURICATA IKE invalid proposal"; flow:to_serve
 alert ike any any -> any any (msg:"SURICATA IKE invalid proposal selected"; flow:to_client; app-layer-event:ike.invalid_proposal; classtype:protocol-command-decode; sid:2224010; rev:2;)
 alert ike any any -> any any (msg:"SURICATA IKE unknown proposal"; flow:to_server; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224011; rev:2;)
 alert ike any any -> any any (msg:"SURICATA IKE unknown proposal selected"; flow:to_client; app-layer-event:ike.unknown_proposal; classtype:protocol-command-decode; sid:2224012; rev:2;)
+alert ike any any -> any any (msg:"SURICATA IKE multiple server proposal"; flow:to_client; app-layer-event:ike.multiple_server_proposal; classtype:protocol-command-decode; sid:2224013; rev:1;)
index 787032bde4ca55d634a066ee9c8d3c630fbd63ce..78f60c8d6720bd6791a9b14046b51891cf5c3e31 100644 (file)
@@ -151,17 +151,16 @@ pub extern "C" fn rs_ike_state_get_sa_attribute(
 
     if let Ok(sa) = sa_type_s {
         if tx.ike_version == 1 {
-            'outer1: for (i, server_transform) in tx.hdr.ikev1_transforms.iter().enumerate() {
-                if i >= 1 {
-                    debug_validate_bug_on!(true);
-                    break;
-                }
-                for attr in server_transform {
-                    if attr.attribute_type.to_string() == sa {
-                        if let Some(numeric_value) = attr.numeric_value {
-                            ret_val = numeric_value;
-                            ret_code = 1;
-                            break 'outer1;
+            if tx.hdr.ikev1_transforms.len() >= 1 {
+                // there should be only one chosen server_transform, check event
+                if let Some(server_transform) = tx.hdr.ikev1_transforms.first() {
+                    for attr in server_transform {
+                        if attr.attribute_type.to_string() == sa {
+                            if let Some(numeric_value) = attr.numeric_value {
+                                ret_val = numeric_value;
+                                ret_code = 1;
+                                break
+                            }
                         }
                     }
                 }
index 8c87f1ab7802f12788665b5f89a550eed39f67c5..bcd6ffcec6d6819f05556f668aad820091c69883 100644 (file)
@@ -47,6 +47,7 @@ pub enum IkeEvent {
     InvalidProposal,
     UnknownProposal,
     PayloadExtraData,
+    MultipleServerProposal,
 }
 
 impl IkeEvent {
@@ -63,6 +64,7 @@ impl IkeEvent {
             8 => Some(IkeEvent::InvalidProposal),
             9 => Some(IkeEvent::UnknownProposal),
             10 => Some(IkeEvent::PayloadExtraData),
+            11 => Some(IkeEvent::MultipleServerProposal),
             _ => None,
         }
     }
@@ -456,6 +458,7 @@ pub extern "C" fn rs_ike_state_get_event_info_by_id(
             IkeEvent::InvalidProposal => "invalid_proposal\0",
             IkeEvent::UnknownProposal => "unknown_proposal\0",
             IkeEvent::PayloadExtraData => "payload_extra_data\0",
+            IkeEvent::MultipleServerProposal => "multiple_server_proposal\0",
         };
         unsafe {
             *event_name = estr.as_ptr() as *const std::os::raw::c_char;
@@ -490,6 +493,7 @@ pub extern "C" fn rs_ike_state_get_event_info(
                 "invalid_proposal" => IkeEvent::InvalidProposal as i32,
                 "unknown_proposal" => IkeEvent::UnknownProposal as i32,
                 "payload_extra_data" => IkeEvent::PayloadExtraData as i32,
+                "multiple_server_proposal" => IkeEvent::MultipleServerProposal as i32,
                 _ => -1, // unknown event
             }
         }
index 043f2496f8d3e705fb98df29577bc23feb8b5c3a..c7f85945e746d04292c00af02917a912f170c35c 100644 (file)
@@ -130,6 +130,15 @@ pub fn handle_ikev1(
                         &tx.hdr.ikev1_transforms,
                     );
                 } else {
+                    if state.ikev1_container.server.transforms.len() <= 1
+                        && state.ikev1_container.server.transforms.len()
+                            + tx.hdr.ikev1_transforms.len()
+                            > 1
+                    {
+                        SCLogDebug!("More than one chosen server proposal");
+                        state.set_event(IkeEvent::MultipleServerProposal);
+                    }
+
                     state.ikev1_container.server.update(
                         &to_hex(tx.hdr.ikev1_header.key_exchange.as_ref()),
                         &to_hex(tx.hdr.ikev1_header.nonce.as_ref()),
index 3a022a1f99513a07dd89fc33c8475d236835f825..390231229e3f2b8383710daa12951426ab8e090b 100644 (file)
@@ -73,14 +73,19 @@ fn log_ike(
     }
 
     if tx.ike_version == 1 {
-        let mut index = 0;
-        for server_transform in &state.ikev1_container.server.transforms {
-            if index >= 1 {
-                debug_validate_bug_on!(true);
-                break;
+        if state.ikev1_container.server.transforms.len() > 0 {
+            // log the first transform as the chosen one
+            add_attributes(&state.ikev1_container.server.transforms[0], jb)?;
+        }
+        if state.ikev1_container.server.transforms.len() > 1 {
+            // in case we have multiple server transforms log them in a list
+            jb.open_array("server_proposals")?;
+            for server_transform in &state.ikev1_container.server.transforms {
+                jb.start_object()?;
+                add_attributes(server_transform, jb)?;
+                jb.close()?;
             }
-            add_attributes(server_transform, jb)?;
-            index += 1;
+            jb.close()?;
         }
     } else if tx.ike_version == 2 {
         if tx.hdr.flags & IKEV2_FLAG_INITIATOR != 0 {