From: Shivani Bhardwaj Date: Wed, 19 May 2021 05:59:04 +0000 (+0530) Subject: dcerpc/udp: Add rust registration function X-Git-Tag: suricata-7.0.0-beta1~1614 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=581cb6223d315a0b2d66d44462e048e6cf7825f0;p=thirdparty%2Fsuricata.git dcerpc/udp: Add rust registration function Get rid of the C glue code and move registration completely to Rust. --- diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 60dc99c878..5e6c3ca4a2 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -17,11 +17,14 @@ use std::mem::transmute; -use crate::applayer::{AppLayerResult, AppLayerTxData}; +use crate::applayer::*; use crate::core; use crate::dcerpc::dcerpc::{ DCERPCTransaction, DCERPC_TYPE_REQUEST, DCERPC_TYPE_RESPONSE, PFCL1_FRAG, PFCL1_LASTFRAG, + rs_dcerpc_get_alstate_progress, ALPROTO_DCERPC, PARSER_NAME, }; +use std; +use std::ffi::CString; use crate::dcerpc::parser; // Constant DCERPC UDP Header length @@ -305,8 +308,7 @@ fn probe(input: &[u8]) -> (bool, bool) { } } -#[no_mangle] -pub extern "C" fn rs_dcerpc_probe_udp(direction: u8, input: *const u8, +pub extern "C" fn rs_dcerpc_probe_udp(_f: *const core::Flow, direction: u8, input: *const u8, len: u32, rdir: *mut u8) -> core::AppProto { SCLogDebug!("Probing the packet for DCERPC/UDP"); @@ -327,9 +329,72 @@ pub extern "C" fn rs_dcerpc_probe_udp(direction: u8, input: *const u8, 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(core::IPPROTO_UDP as u8, ALPROTO_DCERPC, + b"|04 00|\0".as_ptr() as *const std::os::raw::c_char, 2, 0, + core::STREAM_TOSERVER, rs_dcerpc_probe_udp, 0, 0) < 0 { + SCLogDebug!("TOSERVER => AppLayerProtoDetectPMRegisterPatternCSwPP FAILED"); + return -1; + } + } + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn rs_dcerpc_udp_register_parser() { + let default_port = CString::new("[0:65535]").unwrap(); + let parser = RustParser { + name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, + default_port: default_port.as_ptr(), + ipproto: core::IPPROTO_UDP, + probe_ts: None, + probe_tc: None, + min_depth: 0, + max_depth: 16, + state_new: rs_dcerpc_udp_state_new, + state_free: rs_dcerpc_udp_state_free, + tx_free: rs_dcerpc_udp_state_transaction_free, + parse_ts: rs_dcerpc_udp_parse, + parse_tc: rs_dcerpc_udp_parse, + get_tx_count: rs_dcerpc_udp_get_tx_cnt, + get_tx: rs_dcerpc_udp_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_udp_get_tx_detect_state, + set_de_state: rs_dcerpc_udp_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_udp_get_tx_data, + apply_tx_config: None, + flags: APP_LAYER_PARSER_OPT_UNIDIR_TXS, + truncate: None, + }; + + let ip_proto_str = CString::new("udp").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); + } + } else { + SCLogDebug!("Protocol detecter and parser disabled for DCERPC/UDP."); } - return 0; } diff --git a/src/Makefile.am b/src/Makefile.am index 8cb00e04ba..fb0da712ae 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-udp.h \ app-layer-detect-proto.h \ app-layer-dnp3.h \ app-layer-dnp3-objects.h \ @@ -599,7 +598,6 @@ libsuricata_c_a_SOURCES = \ alert-prelude.c \ alert-syslog.c \ app-layer.c \ - app-layer-dcerpc-udp.c \ app-layer-detect-proto.c \ app-layer-dnp3.c \ app-layer-dnp3-objects.c \ diff --git a/src/app-layer-dcerpc-udp.c b/src/app-layer-dcerpc-udp.c deleted file mode 100644 index d47fa4dda5..0000000000 --- a/src/app-layer-dcerpc-udp.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009, 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. - */ -/* - * \todo Updated by AS: Inspect the possibilities of sending junk start at the - * start of udp session to avoid alproto detection. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "decode.h" - -#include "flow-util.h" - -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.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-udp.h" - -static AppLayerResult RustDCERPCUDPParse(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, const uint8_t *input, uint32_t input_len, - void *local_data, const uint8_t flags) -{ - return rs_dcerpc_udp_parse(f, dcerpc_state, pstate, input, input_len, - local_data, flags); -} - -static void *RustDCERPCUDPStateNew(void *state_orig, AppProto proto_orig) -{ - return rs_dcerpc_udp_state_new(state_orig, proto_orig); -} - -static void RustDCERPCUDPStateFree(void *s) -{ - return rs_dcerpc_udp_state_free(s); -} - -static int RustDCERPCUDPSetTxDetectState(void *vtx, DetectEngineState *de_state) -{ - return rs_dcerpc_udp_set_tx_detect_state(vtx, de_state); -} - -static DetectEngineState *RustDCERPCUDPGetTxDetectState(void *vtx) -{ - return rs_dcerpc_udp_get_tx_detect_state(vtx); -} - -static void RustDCERPCUDPStateTransactionFree(void *state, uint64_t tx_id) -{ - return rs_dcerpc_udp_state_transaction_free(state, tx_id); -} - -static void *RustDCERPCUDPGetTx(void *state, uint64_t tx_id) -{ - return rs_dcerpc_udp_get_tx(state, tx_id); -} - -static uint64_t RustDCERPCUDPGetTxCnt(void *state) -{ - return rs_dcerpc_udp_get_tx_cnt(state); -} - -static int RustDCERPCUDPGetAlstateProgress(void *tx, uint8_t direction) -{ - return rs_dcerpc_get_alstate_progress(tx, direction); -} - -static uint16_t DCERPCUDPProbe( - Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir) -{ - SCLogDebug("DCERPCUDPProbe"); - - const int r = rs_dcerpc_probe_udp(direction, input, len, rdir); - switch (r) { - case 1: - return ALPROTO_DCERPC; - case 0: - return ALPROTO_UNKNOWN; - case -1: - default: - return ALPROTO_FAILED; - } -} - -static int DCERPCUDPRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCSwPP(IPPROTO_UDP, ALPROTO_DCERPC, "|04 00|", 2, 0, - STREAM_TOSERVER, DCERPCUDPProbe, 0, 0) < 0) { - return -1; - } - - return 0; -} - -void RegisterDCERPCUDPParsers(void) -{ - const char *proto_name = "dcerpc"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DCERPC, proto_name); - if (DCERPCUDPRegisterPatternsForProtocolDetection() < 0) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - "dcerpc"); - return; - } - - if (AppLayerParserConfParserEnabled("udp", "dcerpc")) { - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER, - RustDCERPCUDPParse); - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOCLIENT, - RustDCERPCUDPParse); - AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DCERPC, RustDCERPCUDPStateNew, - RustDCERPCUDPStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER); - - AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_DCERPC, RustDCERPCUDPStateTransactionFree); - - AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_DCERPC, - RustDCERPCUDPGetTxDetectState, RustDCERPCUDPSetTxDetectState); - - AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_DCERPC, RustDCERPCUDPGetTx); - AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_DCERPC, rs_dcerpc_udp_get_tx_data); - - AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_DCERPC, RustDCERPCUDPGetTxCnt); - - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_DCERPC, RustDCERPCUDPGetAlstateProgress); - - AppLayerParserRegisterStateProgressCompletionStatus(ALPROTO_DCERPC, 1, 1); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", "dcerpc"); - } - - return; -} diff --git a/src/app-layer-dcerpc-udp.h b/src/app-layer-dcerpc-udp.h deleted file mode 100644 index d60bc1667c..0000000000 --- a/src/app-layer-dcerpc-udp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2017 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_UDP_RUST_H__ -#define __APP_LAYER_DCERPC_UDP_RUST_H__ - -void RegisterDCERPCUDPParsers(void); - -#endif /* !__APP_LAYER_DCERPC_UDP_RUST_H__ */ diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index fcd213e7e6..8eba36bbaa 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-udp.h" #include "app-layer-smb.h" #include "app-layer-htp.h" #include "app-layer-ftp.h" @@ -1581,7 +1580,7 @@ void AppLayerParserRegisterProtocolParsers(void) RegisterHTPParsers(); RegisterSSLParsers(); rs_dcerpc_register_parser(); - RegisterDCERPCUDPParsers(); + rs_dcerpc_udp_register_parser(); RegisterSMBParsers(); RegisterFTPParsers(); RegisterSSHParsers(); diff --git a/src/output-json-dcerpc.c b/src/output-json-dcerpc.c index 6b27d7dbbd..f3f28859f3 100644 --- a/src/output-json-dcerpc.c +++ b/src/output-json-dcerpc.c @@ -34,7 +34,6 @@ #include "app-layer.h" #include "app-layer-parser.h" -#include "app-layer-dcerpc-udp.h" #include "app-layer-dcerpc-common.h" #include "output-json-dcerpc.h" diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index 40d1b6b74f..79be365f5d 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-udp.h" #include "app-layer-htp.h" #include "app-layer-ftp.h" #include "app-layer-ssl.h"