feat: Implement LDAP bind/whoami
This commit is contained in:
parent
bdb5008914
commit
b4330b37fa
19 changed files with 664 additions and 37 deletions
69
vendor/dn_escape/src/lib.rs
vendored
Normal file
69
vendor/dn_escape/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// CODE DEVELOPED BY THE LDAP3 PROJECT, UNDER MIT LICENSE.
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Escape an attribute value in a relative distinguished name (RDN).
|
||||
///
|
||||
/// When a literal string is used to represent an attribute value in an RDN,
|
||||
/// some of its characters might need to be escaped according to the rules
|
||||
/// of [RFC 4514](https://tools.ietf.org/html/rfc4514).
|
||||
///
|
||||
/// The function is named `dn_escape()` instead of `rdn_escape()` because of
|
||||
/// a long-standing association of its intended use with the handling of DNs.
|
||||
///
|
||||
/// The argument, `val`, can be owned or borrowed. The function doesn't
|
||||
/// allocate the return value unless there's need to escape the input.
|
||||
pub fn dn_escape<'a, S: Into<Cow<'a, str>>>(val: S) -> Cow<'a, str> {
|
||||
#[inline]
|
||||
fn always_escape(c: u8) -> bool {
|
||||
c == b'"'
|
||||
|| c == b'+'
|
||||
|| c == b','
|
||||
|| c == b';'
|
||||
|| c == b'<'
|
||||
|| c == b'='
|
||||
|| c == b'>'
|
||||
|| c == b'\\'
|
||||
|| c == 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn escape_leading(c: u8) -> bool {
|
||||
c == b' ' || c == b'#'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn escape_trailing(c: u8) -> bool {
|
||||
c == b' '
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn xdigit(c: u8) -> u8 {
|
||||
c + if c < 10 { b'0' } else { b'a' - 10 }
|
||||
}
|
||||
|
||||
let val = val.into();
|
||||
let mut output = None;
|
||||
for (i, &c) in val.as_bytes().iter().enumerate() {
|
||||
if always_escape(c)
|
||||
|| i == 0 && escape_leading(c)
|
||||
|| i + 1 == val.len() && escape_trailing(c)
|
||||
{
|
||||
if output.is_none() {
|
||||
output = Some(Vec::with_capacity(val.len() + 12)); // guess: up to 4 escaped chars
|
||||
output.as_mut().unwrap().extend(val[..i].as_bytes());
|
||||
}
|
||||
let output = output.as_mut().unwrap();
|
||||
output.push(b'\\');
|
||||
output.push(xdigit(c >> 4));
|
||||
output.push(xdigit(c & 0xF));
|
||||
} else if let Some(ref mut output) = output {
|
||||
output.push(c);
|
||||
}
|
||||
}
|
||||
if let Some(output) = output {
|
||||
Cow::Owned(String::from_utf8(output).expect("dn escaped"))
|
||||
} else {
|
||||
val
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue