Skip to main content

ldap_client_ber/
codec.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use bytes::BytesMut;
4use tokio_util::codec::{Decoder, Encoder};
5
6use crate::BerError;
7use crate::length::decode_length;
8
9/// BER-aware message framing codec for LDAP.
10///
11/// Reads the tag + length to determine message boundaries, then yields
12/// the complete TLV as a frame.
13///
14/// Note that LDAP does not use length-prefix framing.
15pub struct LdapCodec {
16    max_message_size: u32,
17}
18
19impl LdapCodec {
20    pub fn new() -> Self {
21        Self {
22            max_message_size: 10 * 1024 * 1024,
23        }
24    }
25
26    pub fn with_max_message_size(mut self, max: u32) -> Self {
27        self.max_message_size = max;
28        self
29    }
30}
31
32impl Default for LdapCodec {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl Decoder for LdapCodec {
39    type Item = BytesMut;
40    type Error = BerError;
41
42    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
43        if src.is_empty() {
44            return Ok(None);
45        }
46
47        // Every LDAP message is a SEQUENCE (0x30).
48        if src[0] != 0x30 {
49            return Err(BerError::InvalidTag(src[0]));
50        }
51
52        // Try to read the length field (starts at byte 1).
53        if src.len() < 2 {
54            return Ok(None);
55        }
56
57        match decode_length(&src[1..])? {
58            None => Ok(None),
59            Some((length_field_size, value_length)) => {
60                if value_length as u64 > self.max_message_size as u64 {
61                    return Err(BerError::ElementTooLarge {
62                        size: value_length as u64,
63                        max: self.max_message_size,
64                    });
65                }
66
67                let total = 1usize
68                    .saturating_add(length_field_size)
69                    .saturating_add(value_length);
70                if src.len() < total {
71                    src.reserve(total - src.len());
72                    return Ok(None);
73                }
74
75                Ok(Some(src.split_to(total)))
76            }
77        }
78    }
79}
80
81impl Encoder<Vec<u8>> for LdapCodec {
82    type Error = BerError;
83
84    fn encode(&mut self, item: Vec<u8>, dst: &mut BytesMut) -> Result<(), Self::Error> {
85        dst.extend_from_slice(&item);
86        Ok(())
87    }
88}
89
90impl Encoder<&[u8]> for LdapCodec {
91    type Error = BerError;
92
93    fn encode(&mut self, item: &[u8], dst: &mut BytesMut) -> Result<(), Self::Error> {
94        dst.extend_from_slice(item);
95        Ok(())
96    }
97}