//! RDP application layer
use crate::applayer::{self, *};
-use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP};
+use crate::core::{ALPROTO_UNKNOWN, IPPROTO_TCP, sc_app_layer_parser_trigger_raw_stream_inspection};
use crate::flow::Flow;
use crate::rdp::parser::*;
+use crate::direction::Direction;
use nom7::Err;
use suricata_sys::sys::AppProto;
use std;
}
/// parse buffer captures from client to server
- fn parse_ts(&mut self, input: &[u8]) -> AppLayerResult {
+ fn parse_ts(&mut self, flow: *const Flow, input: &[u8]) -> AppLayerResult {
// no need to process input buffer
if self.bypass_parsing {
return AppLayerResult::ok();
let tx =
self.new_tx(RdpTransactionItem::X224ConnectionRequest(x224));
self.transactions.push_back(tx);
+ if !flow.is_null() {
+ sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
+ }
}
// X.223 data packet, evaluate what it encapsulates
let tx =
self.new_tx(RdpTransactionItem::McsConnectRequest(mcs));
self.transactions.push_back(tx);
+ if !flow.is_null() {
+ sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToServer as i32);
+ }
}
// unknown message in X.223, skip
_ => (),
Err(Err::Failure(_)) | Err(Err::Error(_)) => {
if probe_tls_handshake(available) {
self.tls_parsing = true;
- let r = self.parse_ts(available);
+ let r = self.parse_ts(flow, available);
if r.status == 1 {
//adds bytes already consumed to incomplete result
let consumed = (input.len() - available.len()) as u32;
}
/// parse buffer captures from server to client
- fn parse_tc(&mut self, input: &[u8]) -> AppLayerResult {
+ fn parse_tc(&mut self, flow: *const Flow, input: &[u8]) -> AppLayerResult {
// no need to process input buffer
if self.bypass_parsing {
return AppLayerResult::ok();
let tx =
self.new_tx(RdpTransactionItem::TlsCertificateChain(chain));
self.transactions.push_back(tx);
+ if !flow.is_null() {
+ sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToClient as i32);
+ }
self.bypass_parsing = true;
}
_ => {}
let tx =
self.new_tx(RdpTransactionItem::X224ConnectionConfirm(x224));
self.transactions.push_back(tx);
+ if !flow.is_null() {
+ sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToClient as i32);
+ }
}
// X.223 data packet, evaluate what it encapsulates
let tx = self
.new_tx(RdpTransactionItem::McsConnectResponse(mcs));
self.transactions.push_back(tx);
+ if !flow.is_null() {
+ sc_app_layer_parser_trigger_raw_stream_inspection(flow, Direction::ToClient as i32);
+ }
self.bypass_parsing = true;
return AppLayerResult::ok();
}
Err(Err::Failure(_)) | Err(Err::Error(_)) => {
if probe_tls_handshake(available) {
self.tls_parsing = true;
- let r = self.parse_tc(available);
+ let r = self.parse_tc(flow, available);
if r.status == 1 {
//adds bytes already consumed to incomplete result
let consumed = (input.len() - available.len()) as u32;
//
unsafe extern "C" fn rdp_parse_ts(
- _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+ flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void
) -> AppLayerResult {
let state = cast_pointer!(state, RdpState);
let buf = stream_slice.as_slice();
// attempt to parse bytes as `rdp` protocol
- return state.parse_ts(buf);
+ return state.parse_ts(flow, buf);
}
unsafe extern "C" fn rdp_parse_tc(
- _flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
+ flow: *const Flow, state: *mut std::os::raw::c_void, _pstate: *mut std::os::raw::c_void,
stream_slice: StreamSlice,
_data: *const std::os::raw::c_void
) -> AppLayerResult {
let state = cast_pointer!(state, RdpState);
let buf = stream_slice.as_slice();
// attempt to parse bytes as `rdp` protocol
- return state.parse_tc(buf);
+ return state.parse_tc(flow, buf);
}
export_tx_data_get!(rdp_get_tx_data, RdpTransaction);
];
let mut state = RdpState::new();
// will consume 0, request length + 1
- assert_eq!(AppLayerResult::incomplete(0, 9), state.parse_ts(buf_1));
+ assert_eq!(AppLayerResult::incomplete(0, 9), state.parse_ts(std::ptr::null(), buf_1));
assert_eq!(0, state.transactions.len());
// exactly aligns with transaction
- assert_eq!(AppLayerResult::ok(), state.parse_ts(buf_2));
+ assert_eq!(AppLayerResult::ok(), state.parse_ts(std::ptr::null(), buf_2));
assert_eq!(1, state.transactions.len());
let item = RdpTransactionItem::X224ConnectionRequest(X224ConnectionRequest {
cdt: 0,
fn test_parse_ts_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
let mut state = RdpState::new();
- assert_eq!(AppLayerResult::err(), state.parse_ts(buf));
+ assert_eq!(AppLayerResult::err(), state.parse_ts(std::ptr::null(), buf));
}
#[test]
let buf_2: &[u8] = &[0x03, 0x00, 0x00, 0x09, 0x02, 0xf0, 0x80, 0x7f, 0x66];
let mut state = RdpState::new();
// will consume 0, request length + 1
- assert_eq!(AppLayerResult::incomplete(0, 6), state.parse_tc(buf_1));
+ assert_eq!(AppLayerResult::incomplete(0, 6), state.parse_tc(std::ptr::null(), buf_1));
assert_eq!(0, state.transactions.len());
// exactly aligns with transaction
- assert_eq!(AppLayerResult::ok(), state.parse_tc(buf_2));
+ assert_eq!(AppLayerResult::ok(), state.parse_tc(std::ptr::null(), buf_2));
assert_eq!(1, state.transactions.len());
let item = RdpTransactionItem::McsConnectResponse(McsConnectResponse {});
assert_eq!(item, state.transactions[0].item);
fn test_parse_tc_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
let mut state = RdpState::new();
- assert_eq!(AppLayerResult::err(), state.parse_tc(buf));
+ assert_eq!(AppLayerResult::err(), state.parse_tc(std::ptr::null(), buf));
}
#[test]