rust/ldap: handle GAPs

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 #7176
pull/11616/head
Giuseppe Longo 7 months ago committed by Victor Julien
parent 6a606ff21e
commit 564a6c9a20

@ -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 {
@ -111,6 +113,8 @@ impl LdapState {
tx_index_completed: 0,
request_frame: None,
response_frame: None,
request_gap: false,
response_gap: false,
}
}
@ -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() {
@ -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() {
@ -398,6 +434,14 @@ impl LdapState {
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;
}
}
fn tx_is_complete(op: &ProtocolOp, dir: Direction) -> bool {
@ -490,7 +534,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]
@ -506,7 +556,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]

Loading…
Cancel
Save