]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ldap: factorize code and remove duplicated structs, use ldap_parser where relevant
authorPierre Chifflier <chifflier@wzdftpd.net>
Wed, 4 Jun 2025 12:36:46 +0000 (14:36 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 11 Jun 2025 18:49:15 +0000 (20:49 +0200)
rust/src/ldap/detect.rs
rust/src/ldap/filters.rs [deleted file]
rust/src/ldap/ldap.rs
rust/src/ldap/logger.rs
rust/src/ldap/mod.rs
rust/src/ldap/types.rs

index 8942e573f247179e988c635fef3909f02eb73741..cd3d4087330ac5d199855e88e654d94183aede9c 100644 (file)
@@ -22,7 +22,8 @@ use crate::detect::uint::{
     SCDetectU8Free,
 };
 use crate::detect::{helper_keyword_register_sticky_buffer, SigTableElmtStickyBuffer};
-use crate::ldap::types::{LdapMessage, LdapResultCode, ProtocolOp, ProtocolOpCode};
+use crate::ldap::types::*;
+use ldap_parser::ldap::{LdapMessage, ProtocolOp};
 use suricata_sys::sys::{
     DetectEngineCtx, DetectEngineThreadCtx, Flow, SCDetectBufferSetActiveList,
     SCDetectHelperBufferMpmRegister, SCDetectHelperBufferRegister, SCDetectHelperKeywordRegister,
@@ -120,7 +121,7 @@ unsafe extern "C" fn ldap_detect_request_operation_match(
     let tx = cast_pointer!(tx, LdapTransaction);
     let ctx = cast_pointer!(ctx, DetectUintData<u8>);
     if let Some(request) = &tx.request {
-        let option = request.protocol_op.to_u8();
+        let option = request.protocol_op.tag().0 as u8;
         return detect_match_uint(ctx, option) as c_int;
     }
     return 0;
@@ -251,7 +252,7 @@ unsafe extern "C" fn ldap_detect_responses_operation_match(
     return match_at_index::<LdapMessage, u8>(
         &tx.responses,
         &ctx.du8,
-        |response| Some(response.protocol_op.to_u8()),
+        |response| Some(response.protocol_op.tag().0 as u8),
         |code, ctx_value| detect_match_uint(ctx_value, code) as c_int,
         &ctx.index,
     );
@@ -326,13 +327,13 @@ unsafe extern "C" fn ldap_detect_request_dn_get_data(
 
     if let Some(request) = &tx.request {
         let str_buffer: &str = match &request.protocol_op {
-            ProtocolOp::BindRequest(req) => req.name.0.as_str(),
-            ProtocolOp::AddRequest(req) => req.entry.0.as_str(),
-            ProtocolOp::SearchRequest(req) => req.base_object.0.as_str(),
-            ProtocolOp::ModifyRequest(req) => req.object.0.as_str(),
-            ProtocolOp::DelRequest(req) => req.0.as_str(),
-            ProtocolOp::ModDnRequest(req) => req.entry.0.as_str(),
-            ProtocolOp::CompareRequest(req) => req.entry.0.as_str(),
+            ProtocolOp::BindRequest(req) => req.name.0.as_ref(),
+            ProtocolOp::AddRequest(req) => req.entry.0.as_ref(),
+            ProtocolOp::SearchRequest(req) => req.base_object.0.as_ref(),
+            ProtocolOp::ModifyRequest(req) => req.object.0.as_ref(),
+            ProtocolOp::DelRequest(req) => req.0.as_ref(),
+            ProtocolOp::ModDnRequest(req) => req.entry.0.as_ref(),
+            ProtocolOp::CompareRequest(req) => req.entry.0.as_ref(),
             _ => return false,
         };
         *buffer = str_buffer.as_ptr();
@@ -369,15 +370,15 @@ unsafe extern "C" fn ldap_tx_get_responses_dn(
     let response = &tx.responses[local_id as usize];
     // We expect every response in one tx to be the same protocol_op
     let str_buffer: &str = match &response.protocol_op {
-        ProtocolOp::SearchResultEntry(resp) => resp.object_name.0.as_str(),
-        ProtocolOp::BindResponse(resp) => resp.result.matched_dn.0.as_str(),
-        ProtocolOp::SearchResultDone(resp) => resp.matched_dn.0.as_str(),
-        ProtocolOp::ModifyResponse(resp) => resp.result.matched_dn.0.as_str(),
-        ProtocolOp::AddResponse(resp) => resp.matched_dn.0.as_str(),
-        ProtocolOp::DelResponse(resp) => resp.matched_dn.0.as_str(),
-        ProtocolOp::ModDnResponse(resp) => resp.matched_dn.0.as_str(),
-        ProtocolOp::CompareResponse(resp) => resp.matched_dn.0.as_str(),
-        ProtocolOp::ExtendedResponse(resp) => resp.result.matched_dn.0.as_str(),
+        ProtocolOp::SearchResultEntry(resp) => resp.object_name.0.as_ref(),
+        ProtocolOp::BindResponse(resp) => resp.result.matched_dn.0.as_ref(),
+        ProtocolOp::SearchResultDone(resp) => resp.matched_dn.0.as_ref(),
+        ProtocolOp::ModifyResponse(resp) => resp.result.matched_dn.0.as_ref(),
+        ProtocolOp::AddResponse(resp) => resp.matched_dn.0.as_ref(),
+        ProtocolOp::DelResponse(resp) => resp.matched_dn.0.as_ref(),
+        ProtocolOp::ModDnResponse(resp) => resp.matched_dn.0.as_ref(),
+        ProtocolOp::CompareResponse(resp) => resp.matched_dn.0.as_ref(),
+        ProtocolOp::ExtendedResponse(resp) => resp.result.matched_dn.0.as_ref(),
         _ => "",
         // This ensures that the iteration continues,
         // allowing other responses in the transaction to be processed correctly
@@ -503,14 +504,14 @@ unsafe extern "C" fn ldap_tx_get_responses_msg(
     let response = &tx.responses[local_id as usize];
     // We expect every response in one tx to be the same protocol_op
     let str_buffer: &str = match &response.protocol_op {
-        ProtocolOp::BindResponse(resp) => resp.result.diagnostic_message.0.as_str(),
-        ProtocolOp::SearchResultDone(resp) => resp.diagnostic_message.0.as_str(),
-        ProtocolOp::ModifyResponse(resp) => resp.result.diagnostic_message.0.as_str(),
-        ProtocolOp::AddResponse(resp) => resp.diagnostic_message.0.as_str(),
-        ProtocolOp::DelResponse(resp) => resp.diagnostic_message.0.as_str(),
-        ProtocolOp::ModDnResponse(resp) => resp.diagnostic_message.0.as_str(),
-        ProtocolOp::CompareResponse(resp) => resp.diagnostic_message.0.as_str(),
-        ProtocolOp::ExtendedResponse(resp) => resp.result.diagnostic_message.0.as_str(),
+        ProtocolOp::BindResponse(resp) => resp.result.diagnostic_message.0.as_ref(),
+        ProtocolOp::SearchResultDone(resp) => resp.diagnostic_message.0.as_ref(),
+        ProtocolOp::ModifyResponse(resp) => resp.result.diagnostic_message.0.as_ref(),
+        ProtocolOp::AddResponse(resp) => resp.diagnostic_message.0.as_ref(),
+        ProtocolOp::DelResponse(resp) => resp.diagnostic_message.0.as_ref(),
+        ProtocolOp::ModDnResponse(resp) => resp.diagnostic_message.0.as_ref(),
+        ProtocolOp::CompareResponse(resp) => resp.diagnostic_message.0.as_ref(),
+        ProtocolOp::ExtendedResponse(resp) => resp.result.diagnostic_message.0.as_ref(),
         _ => "",
         // This ensures that the iteration continues,
         // allowing other responses in the transaction to be processed correctly
@@ -547,7 +548,7 @@ unsafe extern "C" fn ldap_tx_get_req_attribute_type(
                 if local_id as usize >= req.attributes.len() {
                     return false;
                 }
-                req.attributes[local_id as usize].0.as_str()
+                req.attributes[local_id as usize].0.as_ref()
             }
             ProtocolOp::ModifyRequest(req) => {
                 if local_id as usize >= req.changes.len() {
@@ -557,19 +558,19 @@ unsafe extern "C" fn ldap_tx_get_req_attribute_type(
                     .modification
                     .attr_type
                     .0
-                    .as_str()
+                    .as_ref()
             }
             ProtocolOp::AddRequest(req) => {
                 if local_id as usize >= req.attributes.len() {
                     return false;
                 }
-                req.attributes[local_id as usize].attr_type.0.as_str()
+                req.attributes[local_id as usize].attr_type.0.as_ref()
             }
             ProtocolOp::CompareRequest(req) => {
                 if local_id > 0 {
                     return false;
                 }
-                req.ava.attribute_desc.0.as_str()
+                req.ava.attribute_desc.0.as_ref()
             }
             _ => return false,
         };
diff --git a/rust/src/ldap/filters.rs b/rust/src/ldap/filters.rs
deleted file mode 100644 (file)
index caa8467..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (C) 2024 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-// written by Giuseppe Longo <giuseppe@glongo.it>
-
-use crate::ldap::types::LdapString;
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum Filter {
-    And(Vec<Filter>),
-    Or(Vec<Filter>),
-    Not(Box<Filter>),
-    EqualityMatch(AttributeValueAssertion),
-    Substrings(SubstringFilter),
-    GreaterOrEqual(AttributeValueAssertion),
-    LessOrEqual(AttributeValueAssertion),
-    Present(LdapString),
-    ApproxMatch(AttributeValueAssertion),
-    ExtensibleMatch(MatchingRuleAssertion),
-}
-
-impl From<ldap_parser::filter::Filter<'_>> for Filter {
-    fn from(f: ldap_parser::filter::Filter) -> Self {
-        match f {
-            ldap_parser::filter::Filter::And(val) => {
-                let mut vec = Vec::new();
-                for filter in val {
-                    vec.push(filter.into());
-                }
-                Filter::And(vec)
-            }
-            ldap_parser::filter::Filter::Or(val) => {
-                let mut vec = Vec::new();
-                for filter in val {
-                    vec.push(filter.into());
-                }
-                Filter::Or(vec)
-            }
-            ldap_parser::filter::Filter::Not(val) => {
-                let f = *val;
-                let f2: Filter = f.into();
-                Filter::Not(Box::from(f2))
-            }
-            ldap_parser::filter::Filter::EqualityMatch(val) => {
-                Filter::EqualityMatch(AttributeValueAssertion {
-                    attribute_desc: LdapString(val.attribute_desc.0.to_string()),
-                    assertion_value: val.assertion_value.to_vec(),
-                })
-            }
-            ldap_parser::filter::Filter::Substrings(val) => {
-                let filter_type = LdapString(val.filter_type.0.to_string());
-                let mut substrings: Vec<Substring> = Vec::new();
-                for s in val.substrings {
-                    substrings.push(s.into());
-                }
-                Filter::Substrings(SubstringFilter {
-                    filter_type,
-                    substrings,
-                })
-            }
-            ldap_parser::filter::Filter::GreaterOrEqual(val) => {
-                Filter::GreaterOrEqual(AttributeValueAssertion {
-                    attribute_desc: LdapString(val.attribute_desc.0.to_string()),
-                    assertion_value: val.assertion_value.to_vec(),
-                })
-            }
-            ldap_parser::filter::Filter::LessOrEqual(val) => {
-                Filter::LessOrEqual(AttributeValueAssertion {
-                    attribute_desc: LdapString(val.attribute_desc.0.to_string()),
-                    assertion_value: val.assertion_value.to_vec(),
-                })
-            }
-            ldap_parser::filter::Filter::Present(val) => {
-                Filter::Present(LdapString(val.0.to_string()))
-            }
-            ldap_parser::filter::Filter::ApproxMatch(val) => {
-                Filter::ApproxMatch(AttributeValueAssertion {
-                    attribute_desc: LdapString(val.attribute_desc.0.to_string()),
-                    assertion_value: val.assertion_value.to_vec(),
-                })
-            }
-            ldap_parser::filter::Filter::ExtensibleMatch(val) => {
-                let matching_rule = if let Some(mr) = val.matching_rule {
-                    Some(LdapString(mr.0.to_string()))
-                } else {
-                    None
-                };
-                let rule_type = if let Some(rt) = val.rule_type {
-                    Some(AttributeDescription(rt.0.to_string()))
-                } else {
-                    None
-                };
-                let assertion_value = AssertionValue(val.assertion_value.0.to_vec());
-                let dn_attributes = val.dn_attributes;
-                Filter::ExtensibleMatch(MatchingRuleAssertion {
-                    matching_rule,
-                    rule_type,
-                    assertion_value,
-                    dn_attributes,
-                })
-            }
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct PartialAttribute {
-    pub attr_type: LdapString,
-    pub attr_vals: Vec<AttributeValue>,
-}
-
-impl From<&ldap_parser::filter::PartialAttribute<'_>> for PartialAttribute {
-    fn from(value: &ldap_parser::filter::PartialAttribute) -> Self {
-        let attr_type = LdapString(value.attr_type.0.to_string());
-        let attr_vals: Vec<AttributeValue> = value
-            .attr_vals
-            .iter()
-            .map(|a| AttributeValue(a.0.to_vec()))
-            .collect();
-
-        Self {
-            attr_type,
-            attr_vals,
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Attribute {
-    pub attr_type: LdapString,
-    pub attr_vals: Vec<AttributeValue>,
-}
-
-impl From<&ldap_parser::filter::Attribute<'_>> for Attribute {
-    fn from(value: &ldap_parser::filter::Attribute) -> Self {
-        let attr_type = LdapString(value.attr_type.0.to_string());
-        let attr_vals: Vec<AttributeValue> = value
-            .attr_vals
-            .iter()
-            .map(|a| AttributeValue(a.0.to_vec()))
-            .collect();
-
-        Self {
-            attr_type,
-            attr_vals,
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AttributeValueAssertion {
-    pub attribute_desc: LdapString,
-    pub assertion_value: Vec<u8>,
-}
-impl From<&ldap_parser::filter::AttributeValueAssertion<'_>> for AttributeValueAssertion {
-    fn from(value: &ldap_parser::filter::AttributeValueAssertion) -> Self {
-        let attribute_desc = LdapString(value.attribute_desc.0.to_string());
-        let assertion_value = value.assertion_value.to_vec();
-        Self {
-            attribute_desc,
-            assertion_value,
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AttributeDescription(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct MatchingRuleAssertion {
-    pub matching_rule: Option<LdapString>,
-    pub rule_type: Option<AttributeDescription>,
-    pub assertion_value: AssertionValue,
-    pub dn_attributes: Option<bool>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct MatchingRuleId(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct SubstringFilter {
-    pub filter_type: LdapString,
-    pub substrings: Vec<Substring>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum Substring {
-    Initial(AssertionValue),
-    Any(AssertionValue),
-    Final(AssertionValue),
-}
-impl From<ldap_parser::filter::Substring<'_>> for Substring {
-    fn from(value: ldap_parser::filter::Substring) -> Self {
-        match value {
-            ldap_parser::filter::Substring::Initial(val) => {
-                Substring::Initial(AssertionValue(val.0.to_vec()))
-            }
-            ldap_parser::filter::Substring::Any(val) => {
-                Substring::Any(AssertionValue(val.0.to_vec()))
-            }
-            ldap_parser::filter::Substring::Final(val) => {
-                Substring::Final(AssertionValue(val.0.to_vec()))
-            }
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AssertionValue(pub Vec<u8>);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AttributeValue(pub Vec<u8>);
index 0b7e078343098414552385787bc8683dd4f08a6b..e59e36cefd12d55af9706f773d65b698a6a56556 100644 (file)
@@ -15,7 +15,8 @@
  * 02110-1301, USA.
  */
 
-// written by Giuseppe Longo <giuseppe@glongo.it>
+// Author: Giuseppe Longo <giuseppe@glongo.it>
+// Author: Pierre Chifflier <chifflier@wzdftpd.net>
 
 use crate::applayer::{self, *};
 use crate::conf::conf_get;
@@ -23,6 +24,7 @@ use crate::core::*;
 use crate::direction::Direction;
 use crate::flow::Flow;
 use crate::frames::*;
+use ldap_parser::asn1_rs::ToStatic;
 use nom7 as nom;
 use std;
 use std::collections::VecDeque;
@@ -34,7 +36,8 @@ use suricata_sys::sys::{
     SCAppLayerProtoDetectConfProtoDetectionEnabled, SCAppLayerRequestProtocolTLSUpgrade,
 };
 
-use crate::ldap::types::*;
+use super::types::*;
+use ldap_parser::ldap::*;
 
 static LDAP_MAX_TX_DEFAULT: usize = 256;
 
@@ -60,8 +63,8 @@ enum LdapEvent {
 #[derive(Debug)]
 pub struct LdapTransaction {
     pub tx_id: u64,
-    pub request: Option<LdapMessage>,
-    pub responses: VecDeque<LdapMessage>,
+    pub request: Option<LdapMessage<'static>>,
+    pub responses: VecDeque<LdapMessage<'static>>,
     complete: bool,
 
     tx_data: AppLayerTxData,
@@ -239,7 +242,7 @@ impl LdapState {
                         }
                     }
                     tx.complete |= tx_is_complete(&request.protocol_op, Direction::ToServer);
-                    tx.request = Some(request);
+                    tx.request = Some(request.to_static());
                     self.transactions.push_back(tx);
                     sc_app_layer_parser_trigger_raw_stream_inspection(
                         flow,
@@ -311,7 +314,7 @@ impl LdapState {
                         tx.complete |= tx_is_complete(&response.protocol_op, Direction::ToClient);
                         let tx_id = tx.id();
                         tx.tx_data.updated_tc = true;
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         sc_app_layer_parser_trigger_raw_stream_inspection(
                             flow,
                             Direction::ToClient as i32,
@@ -328,7 +331,7 @@ impl LdapState {
                         let mut tx = tx.unwrap();
                         let tx_id = tx.id();
                         tx.complete = true;
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         self.transactions.push_back(tx);
                         sc_app_layer_parser_trigger_raw_stream_inspection(
                             flow,
@@ -344,7 +347,7 @@ impl LdapState {
                         let mut tx = tx.unwrap();
                         tx.complete = true;
                         let tx_id = tx.id();
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         self.transactions.push_back(tx);
                         sc_app_layer_parser_trigger_raw_stream_inspection(
                             flow,
@@ -394,7 +397,7 @@ impl LdapState {
                 let mut tx = tx.unwrap();
                 let request = LdapMessage::from(msg);
                 tx.complete |= tx_is_complete(&request.protocol_op, Direction::ToServer);
-                tx.request = Some(request);
+                tx.request = Some(request.to_static());
                 self.transactions.push_back(tx);
             }
             Err(nom::Err::Incomplete(_)) => {
@@ -437,7 +440,7 @@ impl LdapState {
                     if let Some(tx) = self.find_request(response.message_id) {
                         tx.complete |= tx_is_complete(&response.protocol_op, Direction::ToClient);
                         let tx_id = tx.id();
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         let consumed = start.len() - rem.len();
                         self.set_frame_tc(flow, tx_id, consumed as i64);
                     } else if let ProtocolOp::ExtendedResponse(_) = response.protocol_op {
@@ -450,7 +453,7 @@ impl LdapState {
                         let mut tx = tx.unwrap();
                         tx.complete = true;
                         let tx_id = tx.id();
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         self.transactions.push_back(tx);
                         let consumed = start.len() - rem.len();
                         self.set_frame_tc(flow, tx_id, consumed as i64);
@@ -462,7 +465,7 @@ impl LdapState {
                         let mut tx = tx.unwrap();
                         tx.complete = true;
                         let tx_id = tx.id();
-                        tx.responses.push_back(response);
+                        tx.responses.push_back(response.to_static());
                         self.transactions.push_back(tx);
                         self.set_event(LdapEvent::RequestNotFound);
                         let consumed = start.len() - rem.len();
@@ -533,12 +536,12 @@ fn probe(input: &[u8], direction: Direction, rdir: *mut u8) -> AppProto {
     match ldap_parse_msg(input) {
         Ok((_, msg)) => {
             let ldap_msg = LdapMessage::from(msg);
-            if direction == Direction::ToServer && !ldap_msg.is_request() {
+            if direction == Direction::ToServer && !ldap_is_request(&ldap_msg) {
                 unsafe {
                     *rdir = Direction::ToClient.into();
                 }
             }
-            if direction == Direction::ToClient && !ldap_msg.is_response() {
+            if direction == Direction::ToClient && !ldap_is_response(&ldap_msg) {
                 unsafe {
                     *rdir = Direction::ToServer.into();
                 }
index 57557f3a40ef3bbbeb8cf67ee6461c3401abd768..227cb4c262cdb7e80aa28344b98df991c27107dd 100644 (file)
 
 use crate::detect::EnumString;
 use crate::jsonbuilder::{JsonBuilder, JsonError};
-use crate::ldap::filters::*;
 use crate::ldap::ldap::LdapTransaction;
 use crate::ldap::types::*;
+use ldap_parser::filter::*;
+use ldap_parser::ldap::*;
 
 fn log_ldap(tx: &LdapTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
     js.open_object("ldap")?;
 
     if let Some(req) = &tx.request {
-        let protocol_op_str = req.protocol_op.to_string();
+        let protocol_op_str = ldap_protocol_op_as_str(&req.protocol_op);
         js.open_object("request")?;
         js.set_uint("message_id", req.message_id.0)?;
-        js.set_string("operation", &protocol_op_str)?;
+        js.set_string("operation", protocol_op_str)?;
 
         match &req.protocol_op {
             ProtocolOp::SearchRequest(msg) => log_search_request(msg, js)?,
@@ -56,8 +57,8 @@ fn log_ldap(tx: &LdapTransaction, js: &mut JsonBuilder) -> Result<(), JsonError>
         for response in &tx.responses {
             js.start_object()?;
 
-            let protocol_op_str = response.protocol_op.to_string();
-            js.set_string("operation", &protocol_op_str)?;
+            let protocol_op_str = ldap_protocol_op_as_str(&response.protocol_op);
+            js.set_string("operation", protocol_op_str)?;
 
             if tx.request.is_none() {
                 js.set_uint("message_id", response.message_id.0)?;
@@ -97,7 +98,7 @@ fn log_search_request(msg: &SearchRequest, js: &mut JsonBuilder) -> Result<(), J
     if let Filter::Present(val) = &msg.filter {
         js.open_object("filter")?;
         js.set_string("type", "present")?;
-        js.set_string("value", &val.0.to_string())?;
+        js.set_string("value", &val.0)?;
         js.close()?;
     }
     if !msg.attributes.is_empty() {
@@ -135,7 +136,10 @@ fn log_modify_request(msg: &ModifyRequest, js: &mut JsonBuilder) -> Result<(), J
         js.open_array("changes")?;
         for change in &msg.changes {
             js.start_object()?;
-            js.set_string("operation", &change.operation.to_string())?;
+            js.set_string(
+                "operation",
+                ldap_operation_to_string(&change.operation).as_str(),
+            )?;
             js.open_object("modification")?;
             js.set_string("attribute_type", &change.modification.attr_type.0)?;
             if !change.modification.attr_vals.is_empty() {
index 723d7e87fb3116f4e651564c4bf9a484ab4f132f..366c8b6c680663f306ea127d7f1f9e56831be5d5 100644 (file)
@@ -18,7 +18,6 @@
 // written by Giuseppe Longo <giuseppe@glongo.it>
 
 pub mod detect;
-pub mod filters;
 pub mod ldap;
 pub mod logger;
 pub mod types;
index 8ee2ccfa0f283da61bc8ca6a4a80192292dd423b..08a94667afc65a35f5c2c5d111e16a6501c9a1af 100644 (file)
  * 02110-1301, USA.
  */
 
-// written by Giuseppe Longo <giuseppe@glongo.it>
-
-use std::convert::From;
-use std::fmt;
-use std::fmt::{Display, Formatter};
+// Author: Giuseppe Longo <giuseppe@glongo.it>
+// Author: Pierre Chifflier <chifflier@wzdftpd.net>
 
 use ldap_parser::asn1_rs::{FromBer, ParseResult};
 use ldap_parser::error::LdapError;
-
-use crate::ldap::filters::*;
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct Operation(pub u32);
-
-impl Display for Operation {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self.0 {
-            0 => write!(f, "add"),
-            1 => write!(f, "delete"),
-            2 => write!(f, "replace"),
-            _ => write!(f, "{}", self.0),
-        }
-    }
-}
-
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
-pub struct ResultCode(pub u32);
-
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
-pub struct MessageID(pub u32);
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct SearchScope(pub u32);
-
-impl Display for SearchScope {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self.0 {
-            0 => write!(f, "base_object"),
-            1 => write!(f, "single_level"),
-            2 => write!(f, "whole_subtree"),
-            _ => write!(f, "{}", self.0),
-        }
-    }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub struct DerefAliases(pub u32);
-
-impl Display for DerefAliases {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self.0 {
-            0 => write!(f, "never_deref_aliases"),
-            1 => write!(f, "deref_in_searching"),
-            2 => write!(f, "deref_finding_base_obj"),
-            3 => write!(f, "deref_always"),
-            _ => write!(f, "{}", self.0),
-        }
-    }
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct LdapString(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct LdapDN(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct RelativeLdapDN(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct LdapOID(pub String);
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct LdapResult {
-    pub result_code: ResultCode,
-    pub matched_dn: LdapDN,
-    pub diagnostic_message: LdapString,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct BindRequest {
-    pub version: u8,
-    pub name: LdapDN,
-    pub authentication: AuthenticationChoice,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct SaslCredentials {
-    pub mechanism: LdapString,
-    pub credentials: Option<Vec<u8>>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum AuthenticationChoice {
-    Simple(Vec<u8>),
-    Sasl(SaslCredentials),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct BindResponse {
-    pub result: LdapResult,
-    pub server_sasl_creds: Option<Vec<u8>>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct SearchRequest {
-    pub base_object: LdapDN,
-    pub scope: SearchScope,
-    pub deref_aliases: DerefAliases,
-    pub size_limit: u32,
-    pub time_limit: u32,
-    pub types_only: bool,
-    pub filter: Filter,
-    pub attributes: Vec<LdapString>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct SearchResultEntry {
-    pub object_name: LdapDN,
-    pub attributes: Vec<PartialAttribute>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ModifyRequest {
-    pub object: LdapDN,
-    pub changes: Vec<Change>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ModifyResponse {
-    pub result: LdapResult,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Change {
-    pub operation: Operation,
-    pub modification: PartialAttribute,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AddRequest {
-    pub entry: LdapDN,
-    pub attributes: Vec<Attribute>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ModDnRequest {
-    pub entry: LdapDN,
-    pub newrdn: RelativeLdapDN,
-    pub deleteoldrdn: bool,
-    pub newsuperior: Option<LdapDN>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct CompareRequest {
-    pub entry: LdapDN,
-    pub ava: AttributeValueAssertion,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct AbandonRequest {
-    pub message_id: u32,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ExtendedRequest {
-    pub request_name: LdapOID,
-    pub request_value: Option<Vec<u8>>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ExtendedResponse {
-    pub result: LdapResult,
-    pub response_name: Option<LdapOID>,
-    pub response_value: Option<Vec<u8>>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct IntermediateResponse {
-    pub response_name: Option<LdapOID>,
-    pub response_value: Option<Vec<u8>>,
-}
+use ldap_parser::ldap::{LdapMessage, Operation, ProtocolOp};
 
 #[derive(Clone, Debug, EnumStringU32)]
 #[repr(u32)]
@@ -277,31 +101,6 @@ pub enum LdapResultCode {
     NoOperation = 16654,
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum ProtocolOp {
-    BindRequest(BindRequest),
-    BindResponse(BindResponse),
-    UnbindRequest,
-    SearchRequest(SearchRequest),
-    SearchResultEntry(SearchResultEntry),
-    SearchResultDone(LdapResult),
-    SearchResultReference(Vec<LdapString>),
-    ModifyRequest(ModifyRequest),
-    ModifyResponse(ModifyResponse),
-    AddRequest(AddRequest),
-    AddResponse(LdapResult),
-    DelRequest(LdapDN),
-    DelResponse(LdapResult),
-    ModDnRequest(ModDnRequest),
-    ModDnResponse(LdapResult),
-    CompareRequest(CompareRequest),
-    CompareResponse(LdapResult),
-    ExtendedRequest(ExtendedRequest),
-    ExtendedResponse(ExtendedResponse),
-    IntermediateResponse(IntermediateResponse),
-    AbandonRequest(AbandonRequest),
-}
-
 #[derive(Clone, Debug, Default, EnumStringU8)]
 #[repr(u8)]
 pub enum ProtocolOpCode {
@@ -329,357 +128,66 @@ pub enum ProtocolOpCode {
     IntermediateResponse = 25,
 }
 
-impl ProtocolOp {
-    pub fn to_u8(&self) -> u8 {
-        match self {
-            ProtocolOp::BindRequest(_) => 0,
-            ProtocolOp::BindResponse(_) => 1,
-            ProtocolOp::UnbindRequest => 2,
-            ProtocolOp::SearchRequest(_) => 3,
-            ProtocolOp::SearchResultEntry(_) => 4,
-            ProtocolOp::SearchResultDone(_) => 5,
-            ProtocolOp::SearchResultReference(_) => 19,
-            ProtocolOp::ModifyRequest(_) => 6,
-            ProtocolOp::ModifyResponse(_) => 7,
-            ProtocolOp::AddRequest(_) => 8,
-            ProtocolOp::AddResponse(_) => 9,
-            ProtocolOp::DelRequest(_) => 10,
-            ProtocolOp::DelResponse(_) => 11,
-            ProtocolOp::ModDnRequest(_) => 12,
-            ProtocolOp::ModDnResponse(_) => 13,
-            ProtocolOp::CompareRequest(_) => 14,
-            ProtocolOp::CompareResponse(_) => 15,
-            ProtocolOp::AbandonRequest(_) => 16,
-            ProtocolOp::ExtendedRequest(_) => 23,
-            ProtocolOp::ExtendedResponse(_) => 24,
-            ProtocolOp::IntermediateResponse(_) => 25,
+pub fn ldap_operation_to_string(op: &Operation) -> String {
+    match op.0 {
+        0 => "add".to_string(),
+        1 => "delete".to_string(),
+        2 => "replace".to_string(),
+        _ => op.0.to_string(),
+    }
+}
+
+pub fn ldap_protocol_op_as_str(op: &ProtocolOp) -> &'static str {
+    match op {
+        ProtocolOp::BindRequest(_) => "bind_request",
+        ProtocolOp::BindResponse(_) => "bind_response",
+        ProtocolOp::UnbindRequest => "unbind_request",
+        ProtocolOp::SearchRequest(_) => "search_request",
+        ProtocolOp::SearchResultEntry(_) => "search_result_entry",
+        ProtocolOp::SearchResultDone(_) => "search_result_done",
+        ProtocolOp::SearchResultReference(_) => "search_result_reference",
+        ProtocolOp::ModifyRequest(_) => "modify_request",
+        ProtocolOp::ModifyResponse(_) => "modify_response",
+        ProtocolOp::AddRequest(_) => "add_request",
+        ProtocolOp::AddResponse(_) => "add_response",
+        ProtocolOp::DelRequest(_) => "del_request",
+        ProtocolOp::DelResponse(_) => "del_response",
+        ProtocolOp::ModDnRequest(_) => "mod_dn_request",
+        ProtocolOp::ModDnResponse(_) => "mod_dn_response",
+        ProtocolOp::CompareRequest(_) => "compare_request",
+        ProtocolOp::CompareResponse(_) => "compare_response",
+        ProtocolOp::AbandonRequest(_) => "abandon_request",
+        ProtocolOp::ExtendedRequest(_) => "extended_request",
+        ProtocolOp::ExtendedResponse(_) => "extended_response",
+        ProtocolOp::IntermediateResponse(_) => "intermediate_response",
+    }
+}
+
+pub fn ldap_is_request(message: &LdapMessage) -> bool {
+    match message.protocol_op {
+        ProtocolOp::BindRequest(_)
+        | ProtocolOp::UnbindRequest
+        | ProtocolOp::SearchRequest(_)
+        | ProtocolOp::ModifyRequest(_)
+        | ProtocolOp::AddRequest(_)
+        | ProtocolOp::DelRequest(_)
+        | ProtocolOp::ModDnRequest(_)
+        | ProtocolOp::CompareRequest(_)
+        | ProtocolOp::AbandonRequest(_)
+        | ProtocolOp::ExtendedRequest(_) => {
+            return true;
         }
-    }
-}
-
-impl Display for ProtocolOp {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        match self {
-            ProtocolOp::BindRequest(_) => write!(f, "bind_request"),
-            ProtocolOp::BindResponse(_) => write!(f, "bind_response"),
-            ProtocolOp::UnbindRequest => write!(f, "unbind_request"),
-            ProtocolOp::SearchRequest(_) => write!(f, "search_request"),
-            ProtocolOp::SearchResultEntry(_) => write!(f, "search_result_entry"),
-            ProtocolOp::SearchResultDone(_) => write!(f, "search_result_done"),
-            ProtocolOp::SearchResultReference(_) => write!(f, "search_result_reference"),
-            ProtocolOp::ModifyRequest(_) => write!(f, "modify_request"),
-            ProtocolOp::ModifyResponse(_) => write!(f, "modify_response"),
-            ProtocolOp::AddRequest(_) => write!(f, "add_request"),
-            ProtocolOp::AddResponse(_) => write!(f, "add_response"),
-            ProtocolOp::DelRequest(_) => write!(f, "del_request"),
-            ProtocolOp::DelResponse(_) => write!(f, "del_response"),
-            ProtocolOp::ModDnRequest(_) => write!(f, "mod_dn_request"),
-            ProtocolOp::ModDnResponse(_) => write!(f, "mod_dn_response"),
-            ProtocolOp::CompareRequest(_) => write!(f, "compare_request"),
-            ProtocolOp::CompareResponse(_) => write!(f, "compare_response"),
-            ProtocolOp::AbandonRequest(_) => write!(f, "abandon_request"),
-            ProtocolOp::ExtendedRequest(_) => write!(f, "extended_request"),
-            ProtocolOp::ExtendedResponse(_) => write!(f, "extended_response"),
-            ProtocolOp::IntermediateResponse(_) => write!(f, "intermediate_response"),
+        _ => {
+            return false;
         }
     }
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct LdapMessage {
-    pub message_id: MessageID,
-    pub protocol_op: ProtocolOp,
-    pub controls: Option<Vec<Control>>,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Control {
-    pub control_type: LdapOID,
-    pub criticality: bool,
-    pub control_value: Option<Vec<u8>>,
-}
-
-impl From<ldap_parser::ldap::LdapMessage<'_>> for LdapMessage {
-    fn from(ldap_msg: ldap_parser::ldap::LdapMessage) -> Self {
-        let message_id = MessageID(ldap_msg.message_id.0);
-        let protocol_op = match ldap_msg.protocol_op {
-            ldap_parser::ldap::ProtocolOp::BindRequest(msg) => Self::from_bind_request(msg),
-            ldap_parser::ldap::ProtocolOp::BindResponse(msg) => Self::from_bind_response(msg),
-            ldap_parser::ldap::ProtocolOp::UnbindRequest => ProtocolOp::UnbindRequest,
-            ldap_parser::ldap::ProtocolOp::SearchRequest(msg) => Self::from_search_request(msg),
-            ldap_parser::ldap::ProtocolOp::SearchResultEntry(msg) => {
-                Self::from_search_result_entry(msg)
-            }
-            ldap_parser::ldap::ProtocolOp::SearchResultDone(msg) => {
-                Self::from_search_result_done(msg)
-            }
-            ldap_parser::ldap::ProtocolOp::SearchResultReference(msg) => {
-                Self::from_search_result_reference(msg)
-            }
-            ldap_parser::ldap::ProtocolOp::ModifyRequest(msg) => Self::from_modify_request(msg),
-            ldap_parser::ldap::ProtocolOp::ModifyResponse(msg) => Self::from_modify_response(msg),
-            ldap_parser::ldap::ProtocolOp::AddRequest(msg) => Self::from_add_request(msg),
-            ldap_parser::ldap::ProtocolOp::AddResponse(msg) => Self::from_add_response(msg),
-            ldap_parser::ldap::ProtocolOp::DelRequest(msg) => Self::from_del_request(msg),
-            ldap_parser::ldap::ProtocolOp::DelResponse(msg) => Self::from_del_response(msg),
-            ldap_parser::ldap::ProtocolOp::ModDnRequest(msg) => Self::from_mod_dn_request(msg),
-            ldap_parser::ldap::ProtocolOp::ModDnResponse(msg) => Self::from_mod_dn_response(msg),
-            ldap_parser::ldap::ProtocolOp::CompareRequest(msg) => Self::from_compare_request(msg),
-            ldap_parser::ldap::ProtocolOp::CompareResponse(msg) => Self::from_compare_response(msg),
-            ldap_parser::ldap::ProtocolOp::ExtendedRequest(msg) => Self::from_extended_request(msg),
-            ldap_parser::ldap::ProtocolOp::ExtendedResponse(msg) => {
-                Self::from_extended_response(msg)
-            }
-            ldap_parser::ldap::ProtocolOp::IntermediateResponse(msg) => {
-                Self::from_intermediate_response(msg)
-            }
-            ldap_parser::ldap::ProtocolOp::AbandonRequest(msg) => Self::from_abandon_request(msg),
-        };
-        let controls = ldap_msg.controls.map(|ctls| {
-            ctls.iter()
-                .map(|ctl| Control {
-                    control_type: LdapOID(ctl.control_type.0.to_string()),
-                    criticality: ctl.criticality,
-                    control_value: ctl.control_value.as_ref().map(|val| val.to_vec()),
-                })
-                .collect()
-        });
-
-        Self {
-            message_id,
-            protocol_op,
-            controls,
-        }
-    }
-}
-
-impl LdapMessage {
-    pub fn is_request(&self) -> bool {
-        match self.protocol_op {
-            ProtocolOp::BindRequest(_)
-            | ProtocolOp::UnbindRequest
-            | ProtocolOp::SearchRequest(_)
-            | ProtocolOp::ModifyRequest(_)
-            | ProtocolOp::AddRequest(_)
-            | ProtocolOp::DelRequest(_)
-            | ProtocolOp::ModDnRequest(_)
-            | ProtocolOp::CompareRequest(_)
-            | ProtocolOp::AbandonRequest(_)
-            | ProtocolOp::ExtendedRequest(_) => {
-                return true;
-            }
-            _ => {
-                return false;
-            }
-        }
-    }
-
-    pub fn is_response(&self) -> bool {
-        // it is either a response or a request
-        return !self.is_request();
-    }
-
-    fn from_bind_request(msg: ldap_parser::ldap::BindRequest) -> ProtocolOp {
-        let authentication = match msg.authentication {
-            ldap_parser::ldap::AuthenticationChoice::Simple(val) => {
-                AuthenticationChoice::Simple(val.to_vec())
-            }
-            ldap_parser::ldap::AuthenticationChoice::Sasl(val) => {
-                AuthenticationChoice::Sasl(SaslCredentials {
-                    mechanism: LdapString(val.mechanism.0.to_string()),
-                    credentials: val.credentials.map(|creds| creds.to_vec()),
-                })
-            }
-        };
-        ProtocolOp::BindRequest(BindRequest {
-            version: msg.version,
-            name: LdapDN(msg.name.0.to_string()),
-            authentication,
-        })
-    }
-
-    fn from_bind_response(msg: ldap_parser::ldap::BindResponse) -> ProtocolOp {
-        ProtocolOp::BindResponse(BindResponse {
-            result: LdapResult {
-                result_code: ResultCode(msg.result.result_code.0),
-                matched_dn: LdapDN(msg.result.matched_dn.0.to_string()),
-                diagnostic_message: LdapString(msg.result.diagnostic_message.0.to_string()),
-            },
-            server_sasl_creds: msg
-                .server_sasl_creds
-                .map(|server_sasl_creds| server_sasl_creds.to_vec()),
-        })
-    }
-
-    fn from_search_request(msg: ldap_parser::ldap::SearchRequest) -> ProtocolOp {
-        let attributes = msg
-            .attributes
-            .iter()
-            .map(|s| LdapString(s.0.to_string()))
-            .collect();
-        ProtocolOp::SearchRequest(SearchRequest {
-            base_object: LdapDN(msg.base_object.0.to_string()),
-            scope: SearchScope(msg.scope.0),
-            deref_aliases: DerefAliases(msg.deref_aliases.0),
-            size_limit: msg.size_limit,
-            time_limit: msg.time_limit,
-            types_only: msg.types_only,
-            filter: Filter::from(msg.filter),
-            attributes,
-        })
-    }
-
-    fn from_search_result_entry(msg: ldap_parser::ldap::SearchResultEntry) -> ProtocolOp {
-        let attributes = msg.attributes.iter().map(PartialAttribute::from).collect();
-        ProtocolOp::SearchResultEntry(SearchResultEntry {
-            object_name: LdapDN(msg.object_name.0.to_string()),
-            attributes,
-        })
-    }
-
-    fn from_search_result_done(msg: ldap_parser::ldap::LdapResult) -> ProtocolOp {
-        ProtocolOp::SearchResultDone(LdapResult {
-            result_code: ResultCode(msg.result_code.0),
-            matched_dn: LdapDN(msg.matched_dn.0.to_string()),
-            diagnostic_message: LdapString(msg.diagnostic_message.0.to_string()),
-        })
-    }
-
-    fn from_search_result_reference(msg: Vec<ldap_parser::ldap::LdapString<'_>>) -> ProtocolOp {
-        let strs = msg.iter().map(|s| LdapString(s.0.to_string())).collect();
-        ProtocolOp::SearchResultReference(strs)
-    }
-
-    fn from_modify_request(msg: ldap_parser::ldap::ModifyRequest) -> ProtocolOp {
-        let changes = msg
-            .changes
-            .iter()
-            .map(|c| Change {
-                operation: Operation(c.operation.0),
-                modification: PartialAttribute::from(&c.modification),
-            })
-            .collect();
-        ProtocolOp::ModifyRequest(ModifyRequest {
-            object: LdapDN(msg.object.0.to_string()),
-            changes,
-        })
-    }
-
-    fn from_modify_response(msg: ldap_parser::ldap::ModifyResponse) -> ProtocolOp {
-        ProtocolOp::ModifyResponse(ModifyResponse {
-            result: LdapResult {
-                result_code: ResultCode(msg.result.result_code.0),
-                matched_dn: LdapDN(msg.result.matched_dn.0.to_string()),
-                diagnostic_message: LdapString(msg.result.diagnostic_message.0.to_string()),
-            },
-        })
-    }
-
-    fn from_add_request(msg: ldap_parser::ldap::AddRequest) -> ProtocolOp {
-        let attributes = msg.attributes.iter().map(Attribute::from).collect();
-        ProtocolOp::AddRequest(AddRequest {
-            entry: LdapDN(msg.entry.0.to_string()),
-            attributes,
-        })
-    }
-
-    fn from_add_response(msg: ldap_parser::ldap::LdapResult) -> ProtocolOp {
-        ProtocolOp::AddResponse(LdapResult {
-            result_code: ResultCode(msg.result_code.0),
-            matched_dn: LdapDN(msg.matched_dn.0.to_string()),
-            diagnostic_message: LdapString(msg.diagnostic_message.0.to_string()),
-        })
-    }
-
-    fn from_del_request(msg: ldap_parser::ldap::LdapDN<'_>) -> ProtocolOp {
-        ProtocolOp::DelRequest(LdapDN(msg.0.to_string()))
-    }
-
-    fn from_del_response(msg: ldap_parser::ldap::LdapResult) -> ProtocolOp {
-        ProtocolOp::DelResponse(LdapResult {
-            result_code: ResultCode(msg.result_code.0),
-            matched_dn: LdapDN(msg.matched_dn.0.to_string()),
-            diagnostic_message: LdapString(msg.diagnostic_message.0.to_string()),
-        })
-    }
-
-    fn from_mod_dn_request(msg: ldap_parser::ldap::ModDnRequest) -> ProtocolOp {
-        ProtocolOp::ModDnRequest(ModDnRequest {
-            entry: LdapDN(msg.entry.0.to_string()),
-            newrdn: RelativeLdapDN(msg.newrdn.0.to_string()),
-            deleteoldrdn: msg.deleteoldrdn,
-            newsuperior: if let Some(newsuperior) = msg.newsuperior {
-                Some(LdapDN(newsuperior.0.to_string()))
-            } else {
-                None
-            },
-        })
-    }
-
-    fn from_mod_dn_response(msg: ldap_parser::ldap::LdapResult) -> ProtocolOp {
-        ProtocolOp::ModDnResponse(LdapResult {
-            result_code: ResultCode(msg.result_code.0),
-            matched_dn: LdapDN(msg.matched_dn.0.to_string()),
-            diagnostic_message: LdapString(msg.diagnostic_message.0.to_string()),
-        })
-    }
-
-    fn from_compare_request(msg: ldap_parser::ldap::CompareRequest) -> ProtocolOp {
-        ProtocolOp::CompareRequest(CompareRequest {
-            entry: LdapDN(msg.entry.0.to_string()),
-            ava: AttributeValueAssertion::from(&msg.ava),
-        })
-    }
-
-    fn from_compare_response(msg: ldap_parser::ldap::LdapResult) -> ProtocolOp {
-        ProtocolOp::CompareResponse(LdapResult {
-            result_code: ResultCode(msg.result_code.0),
-            matched_dn: LdapDN(msg.matched_dn.0.to_string()),
-            diagnostic_message: LdapString(msg.diagnostic_message.0.to_string()),
-        })
-    }
-
-    fn from_abandon_request(msg: ldap_parser::ldap::MessageID) -> ProtocolOp {
-        ProtocolOp::AbandonRequest(AbandonRequest { message_id: msg.0 })
-    }
-
-    fn from_extended_request(msg: ldap_parser::ldap::ExtendedRequest) -> ProtocolOp {
-        ProtocolOp::ExtendedRequest(ExtendedRequest {
-            request_name: LdapOID(msg.request_name.0.to_string()),
-            request_value: msg
-                .request_value
-                .map(|request_value| request_value.to_vec()),
-        })
-    }
-
-    fn from_extended_response(msg: ldap_parser::ldap::ExtendedResponse) -> ProtocolOp {
-        ProtocolOp::ExtendedResponse(ExtendedResponse {
-            result: LdapResult {
-                result_code: ResultCode(msg.result.result_code.0),
-                matched_dn: LdapDN(msg.result.matched_dn.0.to_string()),
-                diagnostic_message: LdapString(msg.result.diagnostic_message.0.to_string()),
-            },
-            response_name: msg
-                .response_name
-                .map(|response_name| LdapOID(response_name.0.to_string())),
-            response_value: msg
-                .response_value
-                .map(|response_value| response_value.to_vec()),
-        })
-    }
-
-    fn from_intermediate_response(msg: ldap_parser::ldap::IntermediateResponse) -> ProtocolOp {
-        ProtocolOp::IntermediateResponse(IntermediateResponse {
-            response_name: msg
-                .response_name
-                .map(|response_name| LdapOID(response_name.0.to_string())),
-            response_value: msg
-                .response_value
-                .map(|response_value| response_value.to_vec()),
-        })
-    }
+pub fn ldap_is_response(message: &LdapMessage) -> bool {
+    // it is either a response or a request
+    return !ldap_is_request(message);
 }
 
-pub fn ldap_parse_msg(input: &[u8]) -> ParseResult<'_, ldap_parser::ldap::LdapMessage<'_>, LdapError> {
-    ldap_parser::ldap::LdapMessage::from_ber(input)
+pub fn ldap_parse_msg(input: &[u8]) -> ParseResult<LdapMessage, LdapError> {
+    LdapMessage::from_ber(input)
 }