From: Shivani Bhardwaj Date: Tue, 18 May 2021 11:48:00 +0000 (+0530) Subject: dcerpc: Add rust registration function X-Git-Tag: suricata-7.0.0-beta1~1616 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bac69af7e4082d4829cd9aad5bdfd0b0d35070b9;p=thirdparty%2Fsuricata.git dcerpc: Add rust registration function Get rid of the C glue code and move registration completely to Rust. --- diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 78155f892c..d2389d38d5 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -23,6 +23,7 @@ use nom::error::ErrorKind; use nom::number::Endianness; use nom; use std::cmp; +use std::ffi::CString; // Constant DCERPC UDP Header length pub const DCERPC_HDR_LEN: u16 = 16; @@ -108,6 +109,8 @@ pub const DCERPC_TYPE_ORPHANED: u8 = 19; pub const DCERPC_TYPE_RTS: u8 = 20; pub const DCERPC_TYPE_UNKNOWN: u8 = 99; +pub static mut ALPROTO_DCERPC: AppProto = ALPROTO_UNKNOWN; + pub fn dcerpc_type_string(t: u8) -> String { match t { DCERPC_TYPE_REQUEST => "REQUEST", @@ -1365,7 +1368,6 @@ fn probe(input: &[u8]) -> (bool, bool) { } } -#[no_mangle] pub extern "C" fn rs_dcerpc_probe_tcp(_f: *const core::Flow, direction: u8, input: *const u8, len: u32, rdir: *mut u8) -> AppProto { @@ -1387,9 +1389,93 @@ pub extern "C" fn rs_dcerpc_probe_tcp(_f: *const core::Flow, direction: u8, inpu if direction & (core::STREAM_TOSERVER|core::STREAM_TOCLIENT) != dir { unsafe { *rdir = dir }; } - return 1; + return unsafe { ALPROTO_DCERPC }; + } + return unsafe { core::ALPROTO_FAILED }; +} + +fn register_pattern_probe() -> i8 { + unsafe { + if AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP as u8, ALPROTO_DCERPC, + b"|05 00|\0".as_ptr() as *const std::os::raw::c_char, 2, 0, + core::STREAM_TOSERVER, rs_dcerpc_probe_tcp, 0, 0) < 0 { + SCLogDebug!("TOSERVER => AppLayerProtoDetectPMRegisterPatternCSwPP FAILED"); + return -1; + } + if AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP as u8, ALPROTO_DCERPC, + b"|05 00|\0".as_ptr() as *const std::os::raw::c_char, 2, 0, + core::STREAM_TOCLIENT, rs_dcerpc_probe_tcp, 0, 0) < 0 { + SCLogDebug!("TOCLIENT => AppLayerProtoDetectPMRegisterPatternCSwPP FAILED"); + return -1; + } + } + + 0 +} + + +// Parser name as a C style string. +pub const PARSER_NAME: &'static [u8] = b"dcerpc\0"; + +#[no_mangle] +pub unsafe extern "C" fn rs_dcerpc_register_parser() { + let default_port = CString::new("[0:65355]").unwrap(); + let parser = RustParser { + name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, + default_port: default_port.as_ptr(), + ipproto: IPPROTO_TCP, + probe_ts: None, + probe_tc: None, + min_depth: 0, + max_depth: 16, + state_new: rs_dcerpc_state_new, + state_free: rs_dcerpc_state_free, + tx_free: rs_dcerpc_state_transaction_free, + parse_ts: rs_dcerpc_parse_request, + parse_tc: rs_dcerpc_parse_response, + get_tx_count: rs_dcerpc_get_tx_cnt, + get_tx: rs_dcerpc_get_tx, + tx_comp_st_ts: 1, + tx_comp_st_tc: 1, + tx_get_progress: rs_dcerpc_get_alstate_progress, + get_de_state: rs_dcerpc_get_tx_detect_state, + set_de_state: rs_dcerpc_set_tx_detect_state, + get_events: None, + get_eventinfo: None, + get_eventinfo_byid : None, + localstorage_new: None, + localstorage_free: None, + get_files: None, + get_tx_iterator: None, + get_tx_data: rs_dcerpc_get_tx_data, + apply_tx_config: None, + flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS, + truncate: None, + }; + + let ip_proto_str = CString::new("tcp").unwrap(); + + if AppLayerProtoDetectConfProtoDetectionEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let alproto = AppLayerRegisterProtocolDetection(&parser, 1); + ALPROTO_DCERPC = alproto; + if register_pattern_probe() < 0 { + return; + } + if AppLayerParserConfParserEnabled( + ip_proto_str.as_ptr(), + parser.name, + ) != 0 + { + let _ = AppLayerRegisterParser(&parser, alproto); + } + SCLogDebug!("Rust DCERPC parser registered."); + } else { + SCLogDebug!("Protocol detector and parser disabled for DCERPC."); } - return 0; } #[cfg(test)] diff --git a/src/Makefile.am b/src/Makefile.am index 151b2f7c37..8cb00e04ba 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,6 @@ noinst_HEADERS = \ alert-prelude.h \ alert-syslog.h \ app-layer-dcerpc-common.h \ - app-layer-dcerpc.h \ app-layer-dcerpc-udp.h \ app-layer-detect-proto.h \ app-layer-dnp3.h \ @@ -600,7 +599,6 @@ libsuricata_c_a_SOURCES = \ alert-prelude.c \ alert-syslog.c \ app-layer.c \ - app-layer-dcerpc.c \ app-layer-dcerpc-udp.c \ app-layer-detect-proto.c \ app-layer-dnp3.c \ diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c deleted file mode 100644 index 85a85bd0e3..0000000000 --- a/src/app-layer-dcerpc.c +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "flow-util.h" - -#include "detect-engine-state.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer.h" - -#include "util-spm.h" -#include "util-unittest.h" - -#include "app-layer-dcerpc-common.h" -#include "app-layer-dcerpc.h" - -static AppLayerResult DCERPCParseRequest(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - const uint8_t *input, uint32_t input_len, - void *local_data, const uint8_t flags) -{ - if (input == NULL && input_len > 0) { - AppLayerResult res = rs_parse_dcerpc_request_gap(dcerpc_state, input_len); - SCLogDebug("DCERPC request GAP of %u bytes, retval %d", input_len, res.status); - SCReturnStruct(res); - } else { - AppLayerResult res = rs_dcerpc_parse_request( - f, dcerpc_state, pstate, input, input_len, local_data, flags); - SCLogDebug("DCERPC request%s of %u bytes, retval %d", - (input == NULL && input_len > 0) ? " is GAP" : "", input_len, res.status); - SCReturnStruct(res); - } -} - -static AppLayerResult DCERPCParseResponse(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - const uint8_t *input, uint32_t input_len, - void *local_data, const uint8_t flags) -{ - if (input == NULL && input_len > 0) { - AppLayerResult res = rs_parse_dcerpc_response_gap(dcerpc_state, input_len); - SCLogDebug("DCERPC response GAP of %u bytes, retval %d", input_len, res.status); - SCReturnStruct(res); - } else { - AppLayerResult res = rs_dcerpc_parse_response( - f, dcerpc_state, pstate, input, input_len, local_data, flags); - SCLogDebug("DCERPC response%s of %u bytes, retval %d", - (input == NULL && input_len > 0) ? " is GAP" : "", input_len, res.status); - SCReturnStruct(res); - } -} - -static void *RustDCERPCStateNew(void *state_orig, AppProto proto_orig) -{ - return rs_dcerpc_state_new(state_orig, proto_orig); -} - -static void DCERPCStateFree(void *s) -{ - return rs_dcerpc_state_free(s); -} - -static int DCERPCSetTxDetectState(void *vtx, DetectEngineState *de_state) -{ - return rs_dcerpc_set_tx_detect_state(vtx, de_state); -} - -static DetectEngineState *DCERPCGetTxDetectState(void *vtx) -{ - return rs_dcerpc_get_tx_detect_state(vtx); -} - -static void DCERPCStateTransactionFree(void *state, uint64_t tx_id) -{ - return rs_dcerpc_state_transaction_free(state, tx_id); -} - -static void *DCERPCGetTx(void *state, uint64_t tx_id) -{ - return rs_dcerpc_get_tx(state, tx_id); -} - -static uint64_t DCERPCGetTxCnt(void *state) -{ - return rs_dcerpc_get_tx_cnt(state); -} - -static int DCERPCGetAlstateProgress(void *tx, uint8_t direction) -{ - return rs_dcerpc_get_alstate_progress(tx, direction); -} - -static uint16_t DCERPCTCPProbe( - Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir) -{ - SCLogDebug("DCERPCTCPProbe"); - - const int r = rs_dcerpc_probe_tcp(f, direction, input, len, rdir); - switch (r) { - case 1: - return ALPROTO_DCERPC; - case 0: - return ALPROTO_UNKNOWN; - case -1: - default: - return ALPROTO_FAILED; - } -} - -static int DCERPCRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0, - STREAM_TOSERVER, DCERPCTCPProbe, 0, 0) < 0) { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0, - STREAM_TOCLIENT, DCERPCTCPProbe, 0, 0) < 0) { - return -1; - } - - return 0; -} - -void RegisterDCERPCParsers(void) -{ - const char *proto_name = "dcerpc"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DCERPC, proto_name); - if (DCERPCRegisterPatternsForProtocolDetection() < 0) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOSERVER, - DCERPCParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOCLIENT, - DCERPCParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DCERPC, RustDCERPCStateNew, - DCERPCStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOSERVER); - - - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCStateTransactionFree); - - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DCERPC, - DCERPCGetTxDetectState, DCERPCSetTxDetectState); - - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetTx); - AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_DCERPC, rs_dcerpc_get_tx_data); - - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetTxCnt); - - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCGetAlstateProgress); - - AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_DCERPC, 1, 1); - - /* This parser accepts gaps. */ - AppLayerParserRegisterOptionFlags(IPPROTO_TCP, ALPROTO_DCERPC, APP_LAYER_PARSER_OPT_ACCEPT_GAPS); - - AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_DCERPC, rs_dcerpc_state_trunc); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - return; -} diff --git a/src/app-layer-dcerpc.h b/src/app-layer-dcerpc.h deleted file mode 100644 index c1c440a9fd..0000000000 --- a/src/app-layer-dcerpc.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (C) 2020 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __APP_LAYER_DCERPC_RUST_H__ -#define __APP_LAYER_DCERPC_RUST_H__ - -void RegisterDCERPCParsers(void); - -#endif /* __APP_LAYER_DCERPC_H__ */ - diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 19497543cc..fcd213e7e6 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -46,7 +46,6 @@ #include "app-layer.h" #include "app-layer-protos.h" #include "app-layer-parser.h" -#include "app-layer-dcerpc.h" #include "app-layer-dcerpc-udp.h" #include "app-layer-smb.h" #include "app-layer-htp.h" @@ -1581,7 +1580,7 @@ void AppLayerParserRegisterProtocolParsers(void) RegisterHTPParsers(); RegisterSSLParsers(); - RegisterDCERPCParsers(); + rs_dcerpc_register_parser(); RegisterDCERPCUDPParsers(); RegisterSMBParsers(); RegisterFTPParsers(); diff --git a/src/detect-dce-iface.c b/src/detect-dce-iface.c index 34d41226ba..aec537410d 100644 --- a/src/detect-dce-iface.c +++ b/src/detect-dce-iface.c @@ -38,7 +38,6 @@ #include "flow-util.h" #include "app-layer.h" -#include "app-layer-dcerpc.h" #include "queue.h" #include "stream-tcp-reassemble.h" diff --git a/src/detect-dce-opnum.c b/src/detect-dce-opnum.c index b3217db9ee..553264ea63 100644 --- a/src/detect-dce-opnum.c +++ b/src/detect-dce-opnum.c @@ -37,7 +37,6 @@ #include "flow-util.h" #include "app-layer.h" -#include "app-layer-dcerpc.h" #include "queue.h" #include "stream-tcp-reassemble.h" #include "detect-dce-opnum.h" diff --git a/src/detect-dce-stub-data.c b/src/detect-dce-stub-data.c index e13d01e074..ababb7926b 100644 --- a/src/detect-dce-stub-data.c +++ b/src/detect-dce-stub-data.c @@ -40,7 +40,6 @@ #include "flow-util.h" #include "app-layer.h" -#include "app-layer-dcerpc.h" #include "queue.h" #include "stream-tcp-reassemble.h" diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 309efb37a4..00d2db5dea 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -49,8 +49,6 @@ #include "detect-dataset.h" #include "detect-datarep.h" -#include "app-layer-dcerpc.h" - #include "util-spm.h" #include "util-debug.h" #include "util-print.h" diff --git a/src/detect-engine-dcepayload.c b/src/detect-engine-dcepayload.c index 27c0d248cf..a4dd805eda 100644 --- a/src/detect-engine-dcepayload.c +++ b/src/detect-engine-dcepayload.c @@ -41,7 +41,6 @@ #include "stream-tcp.h" #include "app-layer.h" -#include "app-layer-dcerpc.h" #include "flow-util.h" #include "util-debug.h" diff --git a/src/detect-engine-file.c b/src/detect-engine-file.c index d9e31e0847..87034c6475 100644 --- a/src/detect-engine-file.c +++ b/src/detect-engine-file.c @@ -43,7 +43,6 @@ #include "app-layer-protos.h" #include "app-layer-htp.h" #include "app-layer-dcerpc-common.h" -#include "app-layer-dcerpc.h" #include "app-layer-smtp.h" #include "util-unittest.h" diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 0291e62627..a5cf9696bc 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -57,7 +57,6 @@ #include "app-layer-protos.h" #include "app-layer-htp.h" #include "app-layer-dcerpc-common.h" -#include "app-layer-dcerpc.h" #include "util-unittest.h" #include "util-unittest-helper.h" diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index b13a6dd8b1..40d1b6b74f 100644 --- a/src/runmode-unittests.c +++ b/src/runmode-unittests.c @@ -56,7 +56,6 @@ #include "app-layer-detect-proto.h" #include "app-layer-parser.h" #include "app-layer.h" -#include "app-layer-dcerpc.h" #include "app-layer-dcerpc-udp.h" #include "app-layer-htp.h" #include "app-layer-ftp.h" diff --git a/src/suricata.c b/src/suricata.c index d6830a45b7..97e7e0546a 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -122,7 +122,6 @@ #include "app-layer-enip.h" #include "app-layer-dnp3.h" #include "app-layer-smb.h" -#include "app-layer-dcerpc.h" #include "output-filestore.h"