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,
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;
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,
);
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();
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
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
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() {
.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,
};
+++ /dev/null
-/* 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>);
* 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)]
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 {
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)
}