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.

Ticket OISF#7176
  • Loading branch information
glongo committed Aug 6, 2024
1 parent 6462420 commit 3867808
Showing 1 changed file with 56 additions and 2 deletions.
58 changes: 56 additions & 2 deletions rust/src/ldap/ldap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,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 @@ -111,6 +113,8 @@ impl LdapState {
tx_index_completed: 0,
request_frame: None,
response_frame: None,
request_gap: false,
response_gap: false,
}
}

Expand Down Expand Up @@ -178,6 +182,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 @@ -223,6 +243,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 @@ -397,6 +433,13 @@ impl LdapState {
frame.set_tx(flow, tx_id);
self.response_frame = None;
}

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

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

Expand Down Expand Up @@ -490,7 +533,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 @@ -506,7 +555,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 {
return state.parse_response(flow, stream_slice);
}
AppLayerResult::ok()
}

#[no_mangle]
Expand Down

0 comments on commit 3867808

Please sign in to comment.