Skip to content

Commit

Permalink
rust/ldap: handle GAPs
Browse files Browse the repository at this point in the history
Following the same logic as for PGSQL, if there is a gap in an LDAP request or
response, the parser tries to sync up again by checking if the message can be
parsed and effectively parses it on the next call.
  • Loading branch information
glongo committed Jul 30, 2024
1 parent 3b31654 commit ec637e6
Showing 1 changed file with 57 additions and 2 deletions.
59 changes: 57 additions & 2 deletions rust/src/ldap/ldap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub struct LdapState {
tx_index_completed: usize,
request_frame: Option<Frame>,
response_frame: Option<Frame>,
request_gap: bool,
response_gap: bool,
}

impl State<LdapTransaction> for LdapState {
Expand All @@ -110,6 +112,8 @@ impl LdapState {
tx_index_completed: 0,
request_frame: None,
response_frame: None,
request_gap: false,
response_gap: false,
}
}

Expand Down Expand Up @@ -177,6 +181,22 @@ impl LdapState {
return AppLayerResult::ok();
}

if self.request_gap {
match ldap_parse_msg(input) {
Ok((_, msg)) => {
let ldap_msg = LdapMessage::from(msg);
if ldap_msg.is_unknown() {
return AppLayerResult::err();
}
AppLayerResult::ok();
}
Err(_e) => {
return AppLayerResult::err();
}
}
self.request_gap = false;
}

let mut start = input;
while !start.is_empty() {
if self.request_frame.is_none() {
Expand Down Expand Up @@ -230,6 +250,22 @@ impl LdapState {
return AppLayerResult::ok();
}

if self.response_gap {
match ldap_parse_msg(input) {
Ok((_, msg)) => {
let ldap_msg = LdapMessage::from(msg);
if ldap_msg.is_unknown() {
return AppLayerResult::err();
}
AppLayerResult::ok();
}
Err(_e) => {
return AppLayerResult::err();
}
}
self.response_gap = false;
}

let mut start = input;
while !start.is_empty() {
if self.response_frame.is_none() {
Expand Down Expand Up @@ -310,6 +346,14 @@ impl LdapState {

return AppLayerResult::ok();
}

fn on_request_gap(&mut self, _size: u32) {
self.request_gap = true;
}

fn on_response_gap(&mut self, _size: u32) {
self.response_gap = true;
}
}

fn probe(input: &[u8], direction: Direction, rdir: *mut u8) -> AppProto {
Expand Down Expand Up @@ -382,7 +426,13 @@ unsafe extern "C" fn SCLdapParseRequest(
}
}
let state = cast_pointer!(state, LdapState);
state.parse_request(flow, stream_slice)

if stream_slice.is_gap() {
state.on_request_gap(stream_slice.gap_size());
} else {
return state.parse_request(flow, stream_slice);
}
AppLayerResult::ok()
}

#[no_mangle]
Expand All @@ -398,7 +448,12 @@ unsafe extern "C" fn SCLdapParseResponse(
}
}
let state = cast_pointer!(state, LdapState);
state.parse_response(flow, stream_slice)
if stream_slice.is_gap() {
state.on_response_gap(stream_slice.gap_size());
} else {
state.parse_response(flow, stream_slice);
}
AppLayerResult::ok()
}

#[no_mangle]
Expand Down

0 comments on commit ec637e6

Please sign in to comment.