diff --git a/etc/schema.json b/etc/schema.json index 4924f5982bea..6988a14da796 100644 --- a/etc/schema.json +++ b/etc/schema.json @@ -1171,6 +1171,13 @@ "type": "string" } }, + "NS": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, "NULL": { "type": "array", "minItems": 1, @@ -3778,6 +3785,9 @@ "description": "Errors encountered parsing DNS/UDP protocol", "$ref": "#/$defs/stats_applayer_error" }, + "doh2": { + "$ref": "#/$defs/stats_applayer_error" + }, "enip_tcp": { "description": "Errors encounterd parsing ENIP/TCP", "$ref": "#/$defs/stats_applayer_error" @@ -3928,6 +3938,9 @@ "description": "Number of flows for DNS/UDP protocol", "type": "integer" }, + "doh2": { + "type": "integer" + }, "enip_tcp": { "description": "Number of flows for ENIP/TCP", "type": "integer" @@ -4079,6 +4092,9 @@ "dns_udp": { "type": "integer" }, + "doh2": { + "type": "integer" + }, "enip_tcp": { "type": "integer" }, diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 97db321e2249..8dc5a1051c22 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -449,6 +449,7 @@ pub unsafe fn AppLayerRegisterParser(parser: *const RustParser, alproto: AppProt // Defined in app-layer-detect-proto.h extern { + pub fn AppLayerForceProtocolChange(f: *const Flow, new_proto: AppProto); pub fn AppLayerProtoDetectPPRegister(ipproto: u8, portstr: *const c_char, alproto: AppProto, min_depth: u16, max_depth: u16, dir: u8, pparser1: ProbeFn, pparser2: ProbeFn); @@ -487,6 +488,7 @@ extern { pub fn AppLayerParserStateIssetFlag(state: *mut c_void, flag: u16) -> u16; pub fn AppLayerParserSetStreamDepth(ipproto: u8, alproto: AppProto, stream_depth: u32); pub fn AppLayerParserConfParserEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; + pub fn AppLayerParserRegisterLogger(pproto: u8, alproto: AppProto); } #[repr(C)] diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs index dbbc7841fad5..e8cdc27dfe91 100644 --- a/rust/src/applayertemplate/template.rs +++ b/rust/src/applayertemplate/template.rs @@ -447,6 +447,7 @@ pub unsafe extern "C" fn rs_template_register_parser() { SCLogError!("Invalid value for template.max-tx"); } } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TEMPLATE); SCLogNotice!("Rust template parser registered."); } else { SCLogNotice!("Protocol detector and parser disabled for TEMPLATE."); diff --git a/rust/src/bittorrent_dht/bittorrent_dht.rs b/rust/src/bittorrent_dht/bittorrent_dht.rs index 8c6857dc5d92..61eefb9e29af 100644 --- a/rust/src/bittorrent_dht/bittorrent_dht.rs +++ b/rust/src/bittorrent_dht/bittorrent_dht.rs @@ -318,6 +318,7 @@ pub unsafe extern "C" fn rs_bittorrent_dht_udp_register_parser() { { SCLogDebug!("Failed to register protocol detection pattern for direction TOCLIENT"); } + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_BITTORRENT_DHT); SCLogDebug!("Parser registered for bittorrent-dht."); } else { diff --git a/rust/src/core.rs b/rust/src/core.rs index abb27ea578fe..bca228131124 100644 --- a/rust/src/core.rs +++ b/rust/src/core.rs @@ -61,6 +61,13 @@ impl Direction { pub fn is_to_client(&self) -> bool { matches!(self, Self::ToClient) } + + pub fn index(&self) -> usize { + match self { + Self::ToClient => 0, + _ => 1, + } + } } impl Default for Direction { diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index d4f71d268273..2735c7e1e391 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -271,6 +271,11 @@ impl DNSTransaction { } return 0; } + + /// Set an event. The event is set on the most recent transaction. + pub fn set_event(&mut self, event: DNSEvent) { + self.tx_data.set_event(event as u8); + } } struct ConfigTracker { @@ -328,6 +333,111 @@ impl State for DNSState { } } +fn dns_validate_header(input: &[u8]) -> Option<(&[u8], DNSHeader)> { + if let Ok((body, header)) = parser::dns_parse_header(input) { + if probe_header_validity(&header, input.len()).0 { + return Some((body, header)); + } + } + None +} + +#[derive(Debug, PartialEq, Eq)] +pub enum DNSParseError { + HeaderValidation, + NotRequest, + Incomplete, + OtherError, +} + +pub(crate) fn dns_parse_request(input: &[u8]) -> Result { + let (body, header) = if let Some((body, header)) = dns_validate_header(input) { + (body, header) + } else { + return Err(DNSParseError::HeaderValidation); + }; + + match parser::dns_parse_body(body, input, header) { + Ok((_, request)) => { + if request.header.flags & 0x8000 != 0 { + SCLogDebug!("DNS message is not a request"); + return Err(DNSParseError::NotRequest); + } + + let z_flag = request.header.flags & 0x0040 != 0; + let opcode = ((request.header.flags >> 11) & 0xf) as u8; + + let mut tx = DNSTransaction::new(Direction::ToServer); + tx.request = Some(request); + + if z_flag { + SCLogDebug!("Z-flag set on DNS request"); + tx.set_event(DNSEvent::ZFlagSet); + } + if opcode >= 7 { + tx.set_event(DNSEvent::InvalidOpcode); + } + + return Ok(tx); + } + Err(Err::Incomplete(_)) => { + // Insufficient data. + SCLogDebug!("Insufficient data while parsing DNS request"); + return Err(DNSParseError::Incomplete); + } + Err(_) => { + // Error, probably malformed data. + SCLogDebug!("An error occurred while parsing DNS request"); + return Err(DNSParseError::OtherError); + } + } +} + +pub(crate) fn dns_parse_response(input: &[u8]) -> Result { + let (body, header) = if let Some((body, header)) = dns_validate_header(input) { + (body, header) + } else { + return Err(DNSParseError::HeaderValidation); + }; + + match parser::dns_parse_body(body, input, header) { + Ok((_, response)) => { + SCLogDebug!("Response header flags: {}", response.header.flags); + let z_flag = response.header.flags & 0x0040 != 0; + let opcode = ((response.header.flags >> 11) & 0xf) as u8; + let flags = response.header.flags; + + let mut tx = DNSTransaction::new(Direction::ToClient); + tx.response = Some(response); + + if flags & 0x8000 == 0 { + SCLogDebug!("DNS message is not a response"); + tx.set_event(DNSEvent::NotResponse); + } + + if z_flag { + SCLogDebug!("Z-flag set on DNS response"); + tx.set_event(DNSEvent::ZFlagSet); + } + if opcode >= 7 { + tx.set_event(DNSEvent::InvalidOpcode); + } + + return Ok(tx); + } + Err(Err::Incomplete(_)) => { + // Insufficient data. + SCLogDebug!("Insufficient data while parsing DNS request"); + return Err(DNSParseError::Incomplete); + } + Err(_) => { + // Error, probably malformed data. + SCLogDebug!("An error occurred while parsing DNS request"); + return Err(DNSParseError::OtherError); + } + } +} + impl DNSState { pub fn new() -> Self { Default::default() @@ -372,60 +482,31 @@ impl DNSState { tx.tx_data.set_event(event as u8); } - fn validate_header<'a>(&self, input: &'a [u8]) -> Option<(&'a [u8], DNSHeader)> { - if let Ok((body, header)) = parser::dns_parse_header(input) { - if probe_header_validity(&header, input.len()).0 { - return Some((body, header)); - } - } - None - } - fn parse_request(&mut self, input: &[u8], is_tcp: bool) -> bool { - let (body, header) = if let Some((body, header)) = self.validate_header(input) { - (body, header) - } else { - return !is_tcp; - }; - - match parser::dns_parse_body(body, input, header) { - Ok((_, request)) => { - if request.header.flags & 0x8000 != 0 { - SCLogDebug!("DNS message is not a request"); + match dns_parse_request(input) { + Ok(mut tx) => { + self.tx_id += 1; + tx.id = self.tx_id; + self.transactions.push_back(tx); + return true; + } + Err(e) => match e { + DNSParseError::HeaderValidation => { + return !is_tcp; + } + DNSParseError::NotRequest => { self.set_event(DNSEvent::NotRequest); return false; } - - let z_flag = request.header.flags & 0x0040 != 0; - let opcode = ((request.header.flags >> 11) & 0xf) as u8; - - let mut tx = self.new_tx(Direction::ToServer); - tx.request = Some(request); - self.transactions.push_back(tx); - - if z_flag { - SCLogDebug!("Z-flag set on DNS response"); - self.set_event(DNSEvent::ZFlagSet); + DNSParseError::Incomplete => { + self.set_event(DNSEvent::MalformedData); + return false; } - - if opcode >= 7 { - self.set_event(DNSEvent::InvalidOpcode); + DNSParseError::OtherError => { + self.set_event(DNSEvent::MalformedData); + return false; } - - return true; - } - Err(Err::Incomplete(_)) => { - // Insufficient data. - SCLogDebug!("Insufficient data while parsing DNS request"); - self.set_event(DNSEvent::MalformedData); - return false; - } - Err(_) => { - // Error, probably malformed data. - SCLogDebug!("An error occurred while parsing DNS request"); - self.set_event(DNSEvent::MalformedData); - return false; - } + }, } } @@ -454,56 +535,29 @@ impl DNSState { } pub fn parse_response(&mut self, input: &[u8], is_tcp: bool) -> bool { - let (body, header) = if let Some((body, header)) = self.validate_header(input) { - (body, header) - } else { - return !is_tcp; - }; - - match parser::dns_parse_body(body, input, header) { - Ok((_, response)) => { - SCLogDebug!("Response header flags: {}", response.header.flags); - - if response.header.flags & 0x8000 == 0 { - SCLogDebug!("DNS message is not a response"); - self.set_event(DNSEvent::NotResponse); - } - - let z_flag = response.header.flags & 0x0040 != 0; - let opcode = ((response.header.flags >> 11) & 0xf) as u8; - - let mut tx = self.new_tx(Direction::ToClient); + match dns_parse_response(input) { + Ok(mut tx) => { + self.tx_id += 1; + tx.id = self.tx_id; if let Some(ref mut config) = &mut self.config { - if let Some(config) = config.remove(&response.header.tx_id) { - tx.tx_data.config = config; + if let Some(response) = &tx.response { + if let Some(config) = config.remove(&response.header.tx_id) { + tx.tx_data.config = config; + } } } - tx.response = Some(response); self.transactions.push_back(tx); - - if z_flag { - SCLogDebug!("Z-flag set on DNS response"); - self.set_event(DNSEvent::ZFlagSet); - } - - if opcode >= 7 { - self.set_event(DNSEvent::InvalidOpcode); - } - return true; } - Err(Err::Incomplete(_)) => { - // Insufficient data. - SCLogDebug!("Insufficient data while parsing DNS response"); - self.set_event(DNSEvent::MalformedData); - return false; - } - Err(_) => { - // Error, probably malformed data. - SCLogDebug!("An error occurred while parsing DNS response"); - self.set_event(DNSEvent::MalformedData); - return false; - } + Err(e) => match e { + DNSParseError::HeaderValidation => { + return !is_tcp; + } + _ => { + self.set_event(DNSEvent::MalformedData); + return false; + } + }, } } diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs index b2bf72ba1e46..745f4a16936f 100644 --- a/rust/src/dns/log.rs +++ b/rust/src/dns/log.rs @@ -610,7 +610,7 @@ fn dns_log_json_answer( } fn dns_log_query( - tx: &mut DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder, + tx: &DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder, ) -> Result { let index = i as usize; if let Some(request) = &tx.request { @@ -637,7 +637,7 @@ fn dns_log_query( #[no_mangle] pub extern "C" fn rs_dns_log_json_query( - tx: &mut DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder, + tx: &DNSTransaction, i: u16, flags: u64, jb: &mut JsonBuilder, ) -> bool { match dns_log_query(tx, i, flags, jb) { Ok(false) | Err(_) => { @@ -651,7 +651,7 @@ pub extern "C" fn rs_dns_log_json_query( #[no_mangle] pub extern "C" fn rs_dns_log_json_answer( - tx: &mut DNSTransaction, flags: u64, js: &mut JsonBuilder, + tx: &DNSTransaction, flags: u64, js: &mut JsonBuilder, ) -> bool { if let Some(response) = &tx.response { for query in &response.queries { @@ -664,7 +664,7 @@ pub extern "C" fn rs_dns_log_json_answer( } #[no_mangle] -pub extern "C" fn rs_dns_do_log_answer(tx: &mut DNSTransaction, flags: u64) -> bool { +pub extern "C" fn rs_dns_do_log_answer(tx: &DNSTransaction, flags: u64) -> bool { if let Some(response) = &tx.response { for query in &response.queries { if dns_log_rrtype_enabled(query.rrtype, flags) { diff --git a/rust/src/http2/decompression.rs b/rust/src/http2/decompression.rs index 99f8af39032c..31e8547a8134 100644 --- a/rust/src/http2/decompression.rs +++ b/rust/src/http2/decompression.rs @@ -178,10 +178,12 @@ impl HTTP2DecoderHalf { if self.encoding == HTTP2ContentEncoding::Unknown { if input == b"gzip" { self.encoding = HTTP2ContentEncoding::Gzip; - self.decoder = HTTP2Decompresser::Gzip(Box::new(GzDecoder::new(HTTP2cursor::new()))); + self.decoder = + HTTP2Decompresser::Gzip(Box::new(GzDecoder::new(HTTP2cursor::new()))); } else if input == b"deflate" { self.encoding = HTTP2ContentEncoding::Deflate; - self.decoder = HTTP2Decompresser::Deflate(Box::new(DeflateDecoder::new(HTTP2cursor::new()))); + self.decoder = + HTTP2Decompresser::Deflate(Box::new(DeflateDecoder::new(HTTP2cursor::new()))); } else if input == b"br" { self.encoding = HTTP2ContentEncoding::Br; self.decoder = HTTP2Decompresser::Brotli(Box::new(brotli::Decompressor::new( diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 52b41190555b..d2be3fe94241 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -537,7 +537,7 @@ fn http2_tx_get_resp_line(tx: &mut HTTP2Transaction) { return; } let empty = Vec::new(); - let mut resp_line : Vec = Vec::new(); + let mut resp_line: Vec = Vec::new(); let status = if let Ok(value) = http2_frames_get_header_firstvalue(tx, Direction::ToClient, ":status") { @@ -616,7 +616,7 @@ fn http2_lower(value: &[u8]) -> Option> { fn http2_normalize_host(value: &[u8]) -> &[u8] { match value.iter().position(|&x| x == b'@') { Some(i) => { - let value = &value[i+1..]; + let value = &value[i + 1..]; match value.iter().position(|&x| x == b':') { Some(i) => { return &value[..i]; @@ -626,16 +626,14 @@ fn http2_normalize_host(value: &[u8]) -> &[u8] { } } } - None => { - match value.iter().position(|&x| x == b':') { - Some(i) => { - return &value[..i]; - } - None => { - return value; - } + None => match value.iter().position(|&x| x == b':') { + Some(i) => { + return &value[..i]; } - } + None => { + return value; + } + }, } } diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index b62ccb985034..e283861a005e 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -25,6 +25,9 @@ use crate::conf::conf_get; use crate::core::*; use crate::filecontainer::*; use crate::filetracker::*; + +use crate::dns::dns::{dns_parse_request, dns_parse_response, DNSTransaction}; + use nom7::Err; use std; use std::collections::VecDeque; @@ -33,6 +36,7 @@ use std::fmt; use std::io; static mut ALPROTO_HTTP2: AppProto = ALPROTO_UNKNOWN; +static mut ALPROTO_DOH2: AppProto = ALPROTO_UNKNOWN; const HTTP2_DEFAULT_MAX_FRAME_SIZE: u32 = 16384; const HTTP2_MAX_HANDLED_FRAME_SIZE: usize = 65536; @@ -61,7 +65,7 @@ const HTTP2_FRAME_RSTSTREAM_LEN: usize = 4; const HTTP2_FRAME_PRIORITY_LEN: usize = 5; const HTTP2_FRAME_WINDOWUPDATE_LEN: usize = 4; pub static mut HTTP2_MAX_TABLESIZE: u32 = 65536; // 0x10000 -// maximum size of reassembly for header + continuation + // maximum size of reassembly for header + continuation static mut HTTP2_MAX_REASS: usize = 102400; static mut HTTP2_MAX_STREAMS: usize = 4096; // 0x1000 @@ -146,6 +150,12 @@ pub struct HTTP2Transaction { pub escaped: Vec>, pub req_line: Vec, pub resp_line: Vec, + + is_doh_data: [bool; 2], + // dns response buffer + pub doh_data_buf: [Vec; 2], + pub dns_request_tx: Option, + pub dns_response_tx: Option, } impl Transaction for HTTP2Transaction { @@ -177,6 +187,10 @@ impl HTTP2Transaction { escaped: Vec::with_capacity(16), req_line: Vec::new(), resp_line: Vec::new(), + is_doh_data: [false; 2], + doh_data_buf: Default::default(), + dns_request_tx: None, + dns_response_tx: None, } } @@ -186,13 +200,13 @@ impl HTTP2Transaction { if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { //TODO get a file container instead of NULL (c.HTPFileCloseHandleRange)( - sfcm.files_sbcfg, - std::ptr::null_mut(), - 0, - self.file_range, - std::ptr::null_mut(), - 0, - ); + sfcm.files_sbcfg, + std::ptr::null_mut(), + 0, + self.file_range, + std::ptr::null_mut(), + 0, + ); (c.HttpRangeFreeBlock)(self.file_range); self.file_range = std::ptr::null_mut(); } @@ -204,12 +218,27 @@ impl HTTP2Transaction { self.tx_data.set_event(event as u8); } - fn handle_headers(&mut self, blocks: &[parser::HTTP2FrameHeaderBlock], dir: Direction) { + fn handle_headers( + &mut self, blocks: &[parser::HTTP2FrameHeaderBlock], dir: Direction, + ) -> Option> { let mut authority = None; + let mut path = None; + let mut doh = false; let mut host = None; for block in blocks { if block.name == b"content-encoding" { self.decoder.http2_encoding_fromvec(&block.value, dir); + } else if block.name == b"accept" { + //TODO? faster pattern matching + if block.value == b"application/dns-message" { + doh = true; + } + } else if block.name == b"content-type" { + if block.value == b"application/dns-message" { + self.is_doh_data[dir.index()] = true; + } + } else if block.name == b":path" { + path = Some(&block.value); } else if block.name.eq_ignore_ascii_case(b":authority") { authority = Some(&block.value); if block.value.iter().any(|&x| x == b'@') { @@ -231,6 +260,14 @@ impl HTTP2Transaction { } } } + if doh && unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN { + if let Some(p) = path { + if let Ok((_, dns_req)) = parser::doh_extract_request(p) { + return Some(dns_req); + } + } + } + return None; } pub fn update_file_flags(&mut self, flow_file_flags: u16) { @@ -239,10 +276,10 @@ impl HTTP2Transaction { } fn decompress<'a>( - &'a mut self, input: &'a [u8], dir: Direction, sfcm: &'static SuricataFileContext, over: bool, flow: *const Flow, + &'a mut self, input: &'a [u8], output: &'a mut Vec, dir: Direction, + sfcm: &'static SuricataFileContext, over: bool, flow: *const Flow, ) -> io::Result<()> { - let mut output = Vec::with_capacity(decompression::HTTP2_DECOMPRESSION_CHUNK_SIZE); - let decompressed = self.decoder.decompress(input, &mut output, dir)?; + let decompressed = self.decoder.decompress(input, output, dir)?; let xid: u32 = self.tx_id as u32; if dir == Direction::ToClient { self.ft_tc.tx_id = self.tx_id - 1; @@ -258,7 +295,14 @@ impl HTTP2Transaction { ) { match range::http2_parse_check_content_range(&value) { Ok((_, v)) => { - range::http2_range_open(self, &v, flow, sfcm, Direction::ToClient, decompressed); + range::http2_range_open( + self, + &v, + flow, + sfcm, + Direction::ToClient, + decompressed, + ); if over && !self.file_range.is_null() { range::http2_range_close(self, Direction::ToClient, &[]) } @@ -301,13 +345,21 @@ impl HTTP2Transaction { &xid, ); }; + if unsafe { ALPROTO_DOH2 } != ALPROTO_UNKNOWN { + // we store DNS response, and process it when complete + if self.is_doh_data[dir.index()] && self.doh_data_buf[dir.index()].len() < 0xFFFF { + // a DNS message is U16_MAX + self.doh_data_buf[dir.index()].extend_from_slice(decompressed); + } + } return Ok(()); } fn handle_frame( &mut self, header: &parser::HTTP2FrameHeader, data: &HTTP2FrameTypeData, dir: Direction, - ) { + ) -> Option> { //handle child_stream_id changes + let mut r = None; match data { HTTP2FrameTypeData::PUSHPROMISE(hs) => { if dir == Direction::ToClient { @@ -317,7 +369,7 @@ impl HTTP2Transaction { } self.state = HTTP2TransactionState::HTTP2StateReserved; } - self.handle_headers(&hs.blocks, dir); + r = self.handle_headers(&hs.blocks, dir); } HTTP2FrameTypeData::CONTINUATION(hs) => { if dir == Direction::ToClient @@ -325,13 +377,13 @@ impl HTTP2Transaction { { self.child_stream_id = 0; } - self.handle_headers(&hs.blocks, dir); + r = self.handle_headers(&hs.blocks, dir); } HTTP2FrameTypeData::HEADERS(hs) => { if dir == Direction::ToClient { self.child_stream_id = 0; } - self.handle_headers(&hs.blocks, dir); + r = self.handle_headers(&hs.blocks, dir); } HTTP2FrameTypeData::RSTSTREAM(_) => { self.child_stream_id = 0; @@ -378,6 +430,27 @@ impl HTTP2Transaction { } _ => {} } + return r; + } + + fn handle_dns_data(&mut self, over: bool, dir: Direction, flow: *const Flow) { + if !self.doh_data_buf[dir.index()].is_empty() && over { + if dir.is_to_client() { + if let Ok(mut dtx) = dns_parse_response(&self.doh_data_buf[dir.index()]) { + dtx.id = 1; + self.dns_response_tx = Some(dtx); + unsafe { + AppLayerForceProtocolChange(flow, ALPROTO_DOH2); + } + } + } else if let Ok(mut dtx) = dns_parse_request(&self.doh_data_buf[dir.index()]) { + dtx.id = 1; + self.dns_request_tx = Some(dtx); + unsafe { + AppLayerForceProtocolChange(flow, ALPROTO_DOH2); + } + } + } } } @@ -603,7 +676,7 @@ impl HTTP2State { tx.state = HTTP2TransactionState::HTTP2StateGlobal; tx.tx_data.update_file_flags(self.state_data.file_flags); // TODO can this tx hold files? - tx.tx_data.file_tx = STREAM_TOSERVER|STREAM_TOCLIENT; // might hold files in both directions + tx.tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT; // might hold files in both directions tx.update_file_flags(tx.tx_data.file_flags); self.transactions.push_back(tx); return self.transactions.back_mut().unwrap(); @@ -677,7 +750,7 @@ impl HTTP2State { tx.state = HTTP2TransactionState::HTTP2StateOpen; tx.tx_data.update_file_flags(self.state_data.file_flags); tx.update_file_flags(tx.tx_data.file_flags); - tx.tx_data.file_tx = STREAM_TOSERVER|STREAM_TOCLIENT; // might hold files in both directions + tx.tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT; // might hold files in both directions self.transactions.push_back(tx); return Some(self.transactions.back_mut().unwrap()); } @@ -688,9 +761,7 @@ impl HTTP2State { for block in blocks { if block.error >= parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeError { self.set_event(HTTP2Event::InvalidHeader); - } else if block.error - == parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSizeUpdate - { + } else if block.error == parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSizeUpdate { update = true; if block.sizeupdate > sizeup { sizeup = block.sizeupdate; @@ -891,13 +962,15 @@ impl HTTP2State { *reass_limit_reached = true; } if head.flags & parser::HTTP2_FLAG_HEADER_END_HEADERS == 0 { - let hs = parser::HTTP2FrameContinuation { - blocks: Vec::new(), - }; + let hs = parser::HTTP2FrameContinuation { blocks: Vec::new() }; return HTTP2FrameTypeData::CONTINUATION(hs); } } // else try to parse anyways - let input_reass = if head.stream_id == buf.stream_id { &buf.data } else { input }; + let input_reass = if head.stream_id == buf.stream_id { + &buf.data + } else { + input + }; let dyn_headers = if dir == Direction::ToClient { &mut self.dynamic_headers_tc @@ -1055,8 +1128,18 @@ impl HTTP2State { return AppLayerResult::err(); } let tx = tx.unwrap(); + if let Some(doh_req_buf) = tx.handle_frame(&head, &txdata, dir) { + if let Ok(mut dtx) = dns_parse_request(&doh_req_buf) { + dtx.id = 1; + tx.dns_request_tx = Some(dtx); + unsafe { + AppLayerForceProtocolChange(flow, ALPROTO_DOH2); + } + } + } if reass_limit_reached { - tx.tx_data.set_event(HTTP2Event::ReassemblyLimitReached as u8); + tx.tx_data + .set_event(HTTP2Event::ReassemblyLimitReached as u8); } tx.handle_frame(&head, &txdata, dir); let over = head.flags & parser::HTTP2_FLAG_HEADER_EOS != 0; @@ -1087,16 +1170,26 @@ impl HTTP2State { tx_same.ft_ts.tx_id = tx_same.tx_id - 1; }; let mut dinput = &rem[..hlsafe]; - if padded && !rem.is_empty() && usize::from(rem[0]) < hlsafe{ + if padded && !rem.is_empty() && usize::from(rem[0]) < hlsafe { dinput = &rem[1..hlsafe - usize::from(rem[0])]; } - if tx_same.decompress( + let mut output = Vec::with_capacity( + decompression::HTTP2_DECOMPRESSION_CHUNK_SIZE, + ); + match tx_same.decompress( dinput, + &mut output, dir, sfcm, over, - flow).is_err() { - self.set_event(HTTP2Event::FailedDecompression); + flow, + ) { + Ok(_) => { + tx_same.handle_dns_data(over, dir, flow); + } + _ => { + self.set_event(HTTP2Event::FailedDecompression); + } } } } @@ -1191,6 +1284,22 @@ impl HTTP2State { // C exports. +#[no_mangle] +pub unsafe extern "C" fn SCDoH2GetDnsTx( + tx: &HTTP2Transaction, flags: u8, +) -> *mut std::os::raw::c_void { + if flags & Direction::ToServer as u8 != 0 { + if let Some(ref dtx) = &tx.dns_request_tx { + return dtx as *const _ as *mut _; + } + } else if flags & Direction::ToClient as u8 != 0 { + if let Some(ref dtx) = &tx.dns_response_tx { + return dtx as *const _ as *mut _; + } + } + std::ptr::null_mut() +} + export_tx_data_get!(rs_http2_get_tx_data, HTTP2Transaction); export_state_data_get!(rs_http2_get_state_data, HTTP2State); @@ -1319,15 +1428,20 @@ pub unsafe extern "C" fn rs_http2_tx_get_alstate_progress( #[no_mangle] pub unsafe extern "C" fn rs_http2_getfiles( - _state: *mut std::os::raw::c_void, - tx: *mut std::os::raw::c_void, direction: u8, + _state: *mut std::os::raw::c_void, tx: *mut std::os::raw::c_void, direction: u8, ) -> AppLayerGetFileState { let tx = cast_pointer!(tx, HTTP2Transaction); if let Some(sfcm) = { SURICATA_HTTP2_FILE_CONFIG } { if direction & STREAM_TOSERVER != 0 { - return AppLayerGetFileState { fc: &mut tx.ft_ts.file, cfg: sfcm.files_sbcfg } + return AppLayerGetFileState { + fc: &mut tx.ft_ts.file, + cfg: sfcm.files_sbcfg, + }; } else { - return AppLayerGetFileState { fc: &mut tx.ft_tc.file, cfg: sfcm.files_sbcfg } + return AppLayerGetFileState { + fc: &mut tx.ft_tc.file, + cfg: sfcm.files_sbcfg, + }; } } AppLayerGetFileState::err() @@ -1339,7 +1453,7 @@ const PARSER_NAME: &[u8] = b"http2\0"; #[no_mangle] pub unsafe extern "C" fn rs_http2_register_parser() { let default_port = CString::new("[80]").unwrap(); - let parser = RustParser { + let mut parser = RustParser { name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char, default_port: default_port.as_ptr(), ipproto: IPPROTO_TCP, @@ -1401,8 +1515,27 @@ pub unsafe extern "C" fn rs_http2_register_parser() { SCLogError!("Invalid value for http2.max-reassembly-size"); } } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP2); SCLogDebug!("Rust http2 parser registered."); } else { SCLogNotice!("Protocol detector and parser disabled for HTTP2."); } + + // doh2 is just http2 wrapped in another name + parser.name = b"doh2\0".as_ptr() as *const std::os::raw::c_char; + parser.probe_tc = None; + parser.default_port = std::ptr::null(); + if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { + let alproto = AppLayerRegisterProtocolDetection(&parser, 1); + ALPROTO_DOH2 = alproto; + if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { + let _ = AppLayerRegisterParser(&parser, alproto); + } else { + SCLogWarning!("DOH2 is not meant to be detection-only."); + } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DOH2); + SCLogDebug!("Rust doh2 parser registered."); + } else { + SCLogNotice!("Protocol detector and parser disabled for DOH2."); + } } diff --git a/rust/src/http2/logger.rs b/rust/src/http2/logger.rs index 099112b1aeb4..38a5ee4d178a 100644 --- a/rust/src/http2/logger.rs +++ b/rust/src/http2/logger.rs @@ -17,6 +17,7 @@ use super::http2::{HTTP2Frame, HTTP2FrameTypeData, HTTP2Transaction}; use super::parser; +use crate::dns::log::{rs_dns_do_log_answer, rs_dns_log_json_answer, rs_dns_log_json_query}; use crate::jsonbuilder::{JsonBuilder, JsonError}; use std; use std::collections::HashMap; @@ -112,7 +113,10 @@ fn log_http2_frames(frames: &[HTTP2Frame], js: &mut JsonBuilder) -> Result Result( while dyn_headers.current_size > dyn_headers.max_size && toremove < dyn_headers.table.len() { - dyn_headers.current_size -= - 32 + dyn_headers.table[toremove].name.len() + dyn_headers.table[toremove].value.len(); + dyn_headers.current_size -= 32 + + dyn_headers.table[toremove].name.len() + + dyn_headers.table[toremove].value.len(); toremove += 1; } dyn_headers.table.drain(0..toremove); @@ -751,6 +753,19 @@ pub fn http2_parse_frame_settings(i: &[u8]) -> IResult<&[u8], Vec IResult<&[u8], Vec> { + let (i, _) = tag("/dns-query?dns=")(i)?; + match base64::decode(i) { + Ok(dec) => { + // i is unused + return Ok((i, dec)); + } + _ => { + return Err(Err::Error(make_error(i, ErrorKind::MapOpt))); + } + } +} + #[cfg(test)] mod tests { diff --git a/rust/src/http2/range.rs b/rust/src/http2/range.rs index 9c96899443a1..71c22a7b5d01 100644 --- a/rust/src/http2/range.rs +++ b/rust/src/http2/range.rs @@ -131,7 +131,11 @@ pub fn http2_range_open( // whole file in one range return; } - let flags = if dir == Direction::ToServer { tx.ft_ts.file_flags } else { tx.ft_tc.file_flags }; + let flags = if dir == Direction::ToServer { + tx.ft_ts.file_flags + } else { + tx.ft_tc.file_flags + }; if let Ok((key, index)) = http2_range_key_get(tx) { let name = &key[index..]; tx.file_range = unsafe { @@ -151,15 +155,15 @@ pub fn http2_range_open( } } -pub fn http2_range_append(cfg: &'static SuricataFileContext, fr: *mut HttpRangeContainerBlock, data: &[u8]) { +pub fn http2_range_append( + cfg: &'static SuricataFileContext, fr: *mut HttpRangeContainerBlock, data: &[u8], +) { unsafe { HttpRangeAppendData(cfg.files_sbcfg, fr, data.as_ptr(), data.len() as u32); } } -pub fn http2_range_close( - tx: &mut HTTP2Transaction, dir: Direction, data: &[u8], -) { +pub fn http2_range_close(tx: &mut HTTP2Transaction, dir: Direction, data: &[u8]) { let added = if let Some(c) = unsafe { SC } { if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } { let (files, flags) = if dir == Direction::ToServer { @@ -168,13 +172,13 @@ pub fn http2_range_close( (&mut tx.ft_tc.file, tx.ft_tc.file_flags) }; let added = (c.HTPFileCloseHandleRange)( - sfcm.files_sbcfg, - files, - flags, - tx.file_range, - data.as_ptr(), - data.len() as u32, - ); + sfcm.files_sbcfg, + files, + flags, + tx.file_range, + data.as_ptr(), + data.len() as u32, + ); (c.HttpRangeFreeBlock)(tx.file_range); added } else { @@ -197,7 +201,8 @@ extern "C" { data: *const c_uchar, data_len: u32, ) -> *mut HttpRangeContainerBlock; pub fn HttpRangeAppendData( - cfg: *const StreamingBufferConfig, c: *mut HttpRangeContainerBlock, data: *const c_uchar, data_len: u32, + cfg: *const StreamingBufferConfig, c: *mut HttpRangeContainerBlock, data: *const c_uchar, + data_len: u32, ) -> std::os::raw::c_int; } diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 3f9ea23634c4..ddcca94b291c 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -28,7 +28,7 @@ use kerberos_parser::krb5::{EncryptionType,ErrorCode,MessageType,PrincipalName,R use asn1_rs::FromDer; use crate::applayer::{self, *}; use crate::core; -use crate::core::{AppProto,Flow,ALPROTO_FAILED,ALPROTO_UNKNOWN,Direction}; +use crate::core::{AppProto,Flow,ALPROTO_FAILED,ALPROTO_UNKNOWN,Direction, IPPROTO_TCP, IPPROTO_UDP}; #[derive(AppLayerEvent)] pub enum KRB5Event { @@ -616,6 +616,7 @@ pub unsafe extern "C" fn rs_register_krb5_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_KRB5); } else { SCLogDebug!("Protocol detector and parser disabled for KRB5/UDP."); } @@ -633,6 +634,7 @@ pub unsafe extern "C" fn rs_register_krb5_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_KRB5); } else { SCLogDebug!("Protocol detector and parser disabled for KRB5/TCP."); } diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 246e9cae6d6c..1c0ecc884dd5 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -416,6 +416,7 @@ pub unsafe extern "C" fn rs_modbus_register_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_MODBUS); } } diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 8e3ea6f35a21..8fb4c9a2f583 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -496,6 +496,7 @@ pub unsafe extern "C" fn rs_quic_register_parser() { let _ = AppLayerRegisterParser(&parser, alproto); } SCLogDebug!("Rust quic parser registered."); + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_QUIC); } else { SCLogDebug!("Protocol detector and parser disabled for quic."); } diff --git a/rust/src/rdp/rdp.rs b/rust/src/rdp/rdp.rs index f08026a82db8..2899f99c1824 100644 --- a/rust/src/rdp/rdp.rs +++ b/rust/src/rdp/rdp.rs @@ -506,6 +506,7 @@ pub unsafe extern "C" fn rs_rdp_register_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_RDP); } } diff --git a/rust/src/rfb/rfb.rs b/rust/src/rfb/rfb.rs index 8c3381345012..058ec53f6695 100644 --- a/rust/src/rfb/rfb.rs +++ b/rust/src/rfb/rfb.rs @@ -864,6 +864,7 @@ pub unsafe extern "C" fn rs_rfb_register_parser() { let _ = AppLayerRegisterParser(&parser, alproto); } SCLogDebug!("Rust rfb parser registered."); + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_RFB); } else { SCLogDebug!("Protocol detector and parser disabled for RFB."); } diff --git a/rust/src/sip/sip.rs b/rust/src/sip/sip.rs index 75982216f2e0..e34783fe742a 100755 --- a/rust/src/sip/sip.rs +++ b/rust/src/sip/sip.rs @@ -19,7 +19,7 @@ use crate::applayer::{self, *}; use crate::core; -use crate::core::{AppProto, ALPROTO_UNKNOWN}; +use crate::core::{AppProto, ALPROTO_UNKNOWN, IPPROTO_TCP, IPPROTO_UDP}; use crate::frames::*; use crate::sip::parser::*; use nom7::Err; @@ -569,6 +569,7 @@ pub unsafe extern "C" fn rs_sip_register_parser() { if register_pattern_probe(core::IPPROTO_UDP) < 0 { return; } + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SIP); } else { SCLogDebug!("Protocol detection and parsing disabled for UDP SIP."); } @@ -590,6 +591,7 @@ pub unsafe extern "C" fn rs_sip_register_parser() { if register_pattern_probe(core::IPPROTO_TCP) < 0 { return; } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SIP); } else { SCLogDebug!("Protocol detection and parsing disabled for TCP SIP."); } diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index a4481f4bc191..3b78b47f7a1d 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -423,6 +423,7 @@ pub unsafe extern "C" fn rs_register_snmp_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SNMP); } else { SCLogDebug!("Protocol detector and parser disabled for SNMP."); } diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs index a0586894f9fb..c1f08a904c4d 100644 --- a/rust/src/ssh/ssh.rs +++ b/rust/src/ssh/ssh.rs @@ -477,6 +477,7 @@ pub unsafe extern "C" fn rs_ssh_register_parser() { if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 { let _ = AppLayerRegisterParser(&parser, alproto); } + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SSH); SCLogDebug!("Rust ssh parser registered."); } else { SCLogNotice!("Protocol detector and parser disabled for SSH."); diff --git a/scripts/setup-app-layer.py b/scripts/setup-app-layer.py index d8426634bca8..26d9892b87f7 100755 --- a/scripts/setup-app-layer.py +++ b/scripts/setup-app-layer.py @@ -200,15 +200,21 @@ def logger_patch_output_c(proto): output = io.StringIO() inlines = open(filename).readlines() for i, line in enumerate(inlines): - if line.find("ALPROTO_TEMPLATE") > -1: - new_line = line.replace("TEMPLATE", proto.upper()).replace( - "template", proto.lower()) - output.write(new_line) - if line.find("output-json-template.h") > -1: - output.write(line.replace("template", proto.lower())) if line.find("/* Template JSON logger.") > -1: output.write(inlines[i].replace("Template", proto)) output.write(inlines[i+1].replace("Template", proto)) + output.write(inlines[i+2].replace("TEMPLATE", proto.upper()).replace( + "template", proto.lower()).replace("Template", proto)) + output.write(inlines[i+3]) + if line.find("rs_template_logger_log") > -1: + output.write(inlines[i].replace("TEMPLATE", proto.upper()).replace( + "template", proto.lower())) + if line.find("OutputTemplateLogInitSub(") > -1: + output.write(inlines[i].replace("Template", proto)) + output.write(inlines[i+1]) + output.write(inlines[i+2].replace("TEMPLATE", proto.upper())) + output.write(inlines[i+3]) + output.write(inlines[i+4]) output.write(line) open(filename, "w").write(output.getvalue()) @@ -216,27 +222,12 @@ def logger_copy_templates(proto): lower = proto.lower() pairs = ( - ("src/output-json-template.h", - "src/output-json-%s.h" % (lower)), - ("src/output-json-template.c", - "src/output-json-%s.c" % (lower)), ("rust/src/applayertemplate/logger.rs", "rust/src/applayer%s/logger.rs" % (lower)), ) common_copy_templates(proto, pairs) -def logger_patch_makefile_am(protoname): - filename = "src/Makefile.am" - print("Patching %s." % (filename)) - output = io.StringIO() - with open(filename) as infile: - for line in infile: - if line.lstrip().startswith("output-json-template."): - output.write(line.replace("template", protoname.lower())) - output.write(line) - open(filename, "w").write(output.getvalue()) - def detect_copy_templates(proto, buffername): lower = proto.lower() @@ -398,7 +389,6 @@ def main(): raise SetupError("no app-layer parser exists for %s" % (proto)) logger_copy_templates(proto) patch_rust_applayer_mod_rs(proto) - logger_patch_makefile_am(proto) logger_patch_output_c(proto) logger_patch_suricata_yaml_in(proto) diff --git a/src/Makefile.am b/src/Makefile.am index df37a5e9dc08..0bad1fcab774 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -403,7 +403,6 @@ noinst_HEADERS = \ output.h \ output-json-alert.h \ output-json-anomaly.h \ - output-json-bittorrent-dht.h \ output-json-dcerpc.h \ output-json-dhcp.h \ output-json-dnp3.h \ @@ -416,27 +415,16 @@ noinst_HEADERS = \ output-json-frame.h \ output-json-ftp.h \ output-json.h \ - output-json-http2.h \ output-json-http.h \ output-json-ike.h \ - output-json-krb5.h \ output-json-metadata.h \ - output-json-modbus.h \ - output-json-quic.h \ output-json-mqtt.h \ output-json-netflow.h \ output-json-nfs.h \ output-json-pgsql.h \ - output-json-rdp.h \ - output-json-rfb.h \ - output-json-sip.h \ output-json-smb.h \ output-json-smtp.h \ - output-json-snmp.h \ - output-json-ssh.h \ output-json-stats.h \ - output-json-template.h \ - output-json-tftp.h \ output-json-tls.h \ output-eve-syslog.h \ output-lua.h \ @@ -1023,7 +1011,6 @@ libsuricata_c_a_SOURCES = \ output-flow.c \ output-json-alert.c \ output-json-anomaly.c \ - output-json-bittorrent-dht.c \ output-json.c \ output-json-common.c \ output-json-dcerpc.c \ @@ -1037,27 +1024,16 @@ libsuricata_c_a_SOURCES = \ output-json-flow.c \ output-json-frame.c \ output-json-ftp.c \ - output-json-http2.c \ output-json-http.c \ output-json-ike.c \ - output-json-krb5.c \ output-json-metadata.c \ - output-json-modbus.c \ - output-json-quic.c \ output-json-mqtt.c \ output-json-netflow.c \ output-json-nfs.c \ output-json-pgsql.c \ - output-json-rdp.c \ - output-json-rfb.c \ - output-json-sip.c \ output-json-smb.c \ output-json-smtp.c \ - output-json-snmp.c \ - output-json-ssh.c \ output-json-stats.c \ - output-json-template.c \ - output-json-tftp.c \ output-json-tls.c \ output-eve.c \ output-eve-syslog.c \ diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 690950d34e72..c3f44cf1da64 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -1866,6 +1866,16 @@ bool AppLayerRequestProtocolTLSUpgrade(Flow *f) return AppLayerRequestProtocolChange(f, 443, ALPROTO_TLS); } +void AppLayerForceProtocolChange(Flow *f, AppProto new_proto) +{ + if (new_proto != f->alproto) { + f->alproto_orig = f->alproto; + f->alproto = new_proto; + f->alproto_ts = f->alproto; + f->alproto_tc = f->alproto; + } +} + void AppLayerProtoDetectReset(Flow *f) { FLOW_RESET_PM_DONE(f, STREAM_TOSERVER); @@ -2047,6 +2057,9 @@ void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos) if (alproto == ALPROTO_HTTP) { AppLayerProtoDetectSupportedIpprotos(ALPROTO_HTTP1, ipprotos); AppLayerProtoDetectSupportedIpprotos(ALPROTO_HTTP2, ipprotos); + } else if (alproto == ALPROTO_DOH2) { + // DOH2 is not detected, just HTTP2 + AppLayerProtoDetectSupportedIpprotos(ALPROTO_HTTP2, ipprotos); } else { AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos); AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos); diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index 158ad234dd49..adc458ed93f2 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -121,6 +121,8 @@ void AppLayerProtoDetectReset(Flow *); bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto); bool AppLayerRequestProtocolTLSUpgrade(Flow *f); +void AppLayerForceProtocolChange(Flow *f, AppProto new_proto); + /** * \brief Cleans up the app layer protocol detection phase. */ diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index 8925d6dd6a13..7347f1a37a94 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -1348,6 +1348,9 @@ void RegisterFTPParsers(void) AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_FTP, ftp_get_event_info); AppLayerParserRegisterGetEventInfoById(IPPROTO_TCP, ALPROTO_FTP, ftp_get_event_info_by_id); + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_FTP); + AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_FTPDATA); + sbcfg.buf_size = 4096; sbcfg.Calloc = FTPCalloc; sbcfg.Realloc = FTPRealloc; diff --git a/src/app-layer-protos.c b/src/app-layer-protos.c index 368efacd88d7..c08b1db4adb6 100644 --- a/src/app-layer-protos.c +++ b/src/app-layer-protos.c @@ -60,6 +60,7 @@ const AppProtoStringTuple AppProtoStrings[ALPROTO_MAX] = { { ALPROTO_MQTT, "mqtt" }, { ALPROTO_PGSQL, "pgsql" }, { ALPROTO_TELNET, "telnet" }, + { ALPROTO_DOH2, "doh2" }, { ALPROTO_TEMPLATE, "template" }, { ALPROTO_RDP, "rdp" }, { ALPROTO_HTTP2, "http2" }, diff --git a/src/app-layer-protos.h b/src/app-layer-protos.h index dc17ddca1ea3..ed60e52d6777 100644 --- a/src/app-layer-protos.h +++ b/src/app-layer-protos.h @@ -56,6 +56,7 @@ enum AppProtoEnum { ALPROTO_MQTT, ALPROTO_PGSQL, ALPROTO_TELNET, + ALPROTO_DOH2, ALPROTO_TEMPLATE, ALPROTO_RDP, ALPROTO_HTTP2, @@ -84,6 +85,16 @@ static inline bool AppProtoIsValid(AppProto a) return ((a > ALPROTO_UNKNOWN && a < ALPROTO_FAILED)); } +// whether an engine proto works on a flow proto +static inline bool AppProtoCompatible(AppProto eng_proto, AppProto alproto) +{ + switch (alproto) { + case ALPROTO_DOH2: + return (eng_proto == ALPROTO_HTTP2) || (eng_proto == ALPROTO_DNS); + } + return (eng_proto == alproto); +} + // whether a signature AppProto matches a flow (or signature) AppProto static inline bool AppProtoEquals(AppProto sigproto, AppProto alproto) { @@ -91,6 +102,13 @@ static inline bool AppProtoEquals(AppProto sigproto, AppProto alproto) return true; } switch (sigproto) { + case ALPROTO_DNS: + return (alproto == ALPROTO_DOH2) || (alproto == ALPROTO_DNS); + case ALPROTO_HTTP2: + return (alproto == ALPROTO_DOH2) || (alproto == ALPROTO_HTTP2); + case ALPROTO_DOH2: + return (alproto == ALPROTO_DOH2) || (alproto == ALPROTO_HTTP2) || + (alproto == ALPROTO_DNS) || (alproto == ALPROTO_HTTP); case ALPROTO_HTTP: return (alproto == ALPROTO_HTTP1) || (alproto == ALPROTO_HTTP2); case ALPROTO_DCERPC: @@ -99,6 +117,48 @@ static inline bool AppProtoEquals(AppProto sigproto, AppProto alproto) return false; } +// whether a signature AppProto matches a flow (or signature) AppProto +static inline AppProto AppProtoCommon(AppProto sigproto, AppProto alproto) +{ + switch (sigproto) { + case ALPROTO_SMB: + if (alproto == ALPROTO_DCERPC) { + // ok to have dcerpc keywords in smb sig + return ALPROTO_SMB; + } + break; + case ALPROTO_HTTP: + // we had a generic http sig, now version specific + if (alproto == ALPROTO_HTTP1) { + return ALPROTO_HTTP1; + } else if (alproto == ALPROTO_HTTP2) { + return ALPROTO_HTTP2; + } + break; + case ALPROTO_HTTP1: + // version-specific sig with a generic keyword + if (alproto == ALPROTO_HTTP) { + return ALPROTO_HTTP1; + } + break; + case ALPROTO_HTTP2: + if (alproto == ALPROTO_HTTP) { + return ALPROTO_HTTP2; + } + break; + case ALPROTO_DOH2: + // DOH2 accepts different protocol keywords + if (alproto == ALPROTO_HTTP || alproto == ALPROTO_HTTP2 || alproto == ALPROTO_DNS) { + return ALPROTO_DOH2; + } + break; + } + if (sigproto != alproto) { + return ALPROTO_FAILED; + } + return alproto; +} + /** * \brief Maps the ALPROTO_*, to its string equivalent. * diff --git a/src/app-layer-tftp.c b/src/app-layer-tftp.c index 73dc52a59eac..0c08c6d58979 100644 --- a/src/app-layer-tftp.c +++ b/src/app-layer-tftp.c @@ -190,6 +190,7 @@ void RegisterTFTPParsers(void) TFTPProbingParser); } } + AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_TFTP); } else { SCLogDebug("Protocol detector and parser disabled for TFTP."); return; diff --git a/src/app-layer.c b/src/app-layer.c index e159b932afc3..a16a4f5bfa3c 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -505,7 +505,7 @@ static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, PACKET_PROFILING_APP_START(app_tctx, f->alproto); int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, f->alproto); + PACKET_PROFILING_APP_END(app_tctx); p->app_update_direction = (uint8_t)dir; if (r != 1) { StreamTcpUpdateAppLayerProgress(ssn, direction, data_len); @@ -593,7 +593,7 @@ static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, f->alproto); + PACKET_PROFILING_APP_END(app_tctx); p->app_update_direction = (uint8_t)dir; if (r != 1) { StreamTcpUpdateAppLayerProgress(ssn, direction, data_len); @@ -701,7 +701,7 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Packet PACKET_PROFILING_APP_START(app_tctx, f->alproto); r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, f->alproto); + PACKET_PROFILING_APP_END(app_tctx); p->app_update_direction = (uint8_t)dir; /* ignore parser result for gap */ StreamTcpUpdateAppLayerProgress(ssn, direction, data_len); @@ -786,7 +786,7 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Packet PACKET_PROFILING_APP_START(app_tctx, f->alproto); r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, f->alproto); + PACKET_PROFILING_APP_END(app_tctx); p->app_update_direction = (uint8_t)dir; if (r != 1) { StreamTcpUpdateAppLayerProgress(ssn, direction, data_len); @@ -911,7 +911,7 @@ int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow * PACKET_PROFILING_APP_START(tctx, f->alproto); r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto, flags, p->payload, p->payload_len); - PACKET_PROFILING_APP_END(tctx, f->alproto); + PACKET_PROFILING_APP_END(tctx); p->app_update_direction = (uint8_t)UPDATE_DIR_PACKET; } PACKET_PROFILING_APP_STORE(tctx, p); @@ -927,7 +927,7 @@ int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow * PACKET_PROFILING_APP_START(tctx, f->alproto); r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto, flags, p->payload, p->payload_len); - PACKET_PROFILING_APP_END(tctx, f->alproto); + PACKET_PROFILING_APP_END(tctx); PACKET_PROFILING_APP_STORE(tctx, p); p->app_update_direction = (uint8_t)UPDATE_DIR_PACKET; } diff --git a/src/detect-dns-answer-name.c b/src/detect-dns-answer-name.c index bc64f55fbf49..3e46b4e82420 100644 --- a/src/detect-dns-answer-name.c +++ b/src/detect-dns-answer-name.c @@ -83,6 +83,12 @@ static uint8_t DetectEngineInspectCb(DetectEngineCtx *de_ctx, DetectEngineThread transforms = engine->v2.transforms; } + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + } for (uint32_t i = 0;; i++) { InspectionBuffer *buffer = GetBuffer(det_ctx, flags, transforms, txv, i, engine->sm_list); if (buffer == NULL || buffer->inspect == NULL) { @@ -108,6 +114,12 @@ static void PrefilterTx(DetectEngineThreadCtx *det_ctx, const void *pectx, Packe const MpmCtx *mpm_ctx = ctx->mpm_ctx; const int list_id = ctx->list_id; + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return; + } + } for (uint32_t i = 0;; i++) { InspectionBuffer *buffer = GetBuffer(det_ctx, flags, ctx->transforms, txv, i, list_id); if (buffer == NULL) { diff --git a/src/detect-dns-opcode.c b/src/detect-dns-opcode.c index f5dcab700f27..493098b016de 100644 --- a/src/detect-dns-opcode.c +++ b/src/detect-dns-opcode.c @@ -67,6 +67,12 @@ static int DetectDnsOpcodeMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, void *txv, const Signature *s, const SigMatchCtx *ctx) { + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return 0; + } + } return rs_dns_opcode_match(txv, (void *)ctx, flags); } diff --git a/src/detect-dns-query-name.c b/src/detect-dns-query-name.c index a3983bf575cd..572ef3d31dc6 100644 --- a/src/detect-dns-query-name.c +++ b/src/detect-dns-query-name.c @@ -83,6 +83,12 @@ static uint8_t DetectEngineInspectCb(DetectEngineCtx *de_ctx, DetectEngineThread transforms = engine->v2.transforms; } + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + } for (uint32_t i = 0;; i++) { InspectionBuffer *buffer = GetBuffer(det_ctx, flags, transforms, txv, i, engine->sm_list); if (buffer == NULL || buffer->inspect == NULL) { @@ -108,6 +114,12 @@ static void PrefilterTx(DetectEngineThreadCtx *det_ctx, const void *pectx, Packe const MpmCtx *mpm_ctx = ctx->mpm_ctx; const int list_id = ctx->list_id; + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return; + } + } for (uint32_t i = 0;; i++) { InspectionBuffer *buffer = GetBuffer(det_ctx, flags, ctx->transforms, txv, i, list_id); if (buffer == NULL) { diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index 3225f126f2df..c29c9451ae74 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -108,6 +108,12 @@ static uint8_t DetectEngineInspectDnsQuery(DetectEngineCtx *de_ctx, DetectEngine transforms = engine->v2.transforms; } + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + } + } while(1) { struct DnsQueryGetDataArgs cbdata = { local_id, txv, }; InspectionBuffer *buffer = @@ -149,6 +155,12 @@ static void PrefilterTxDnsQuery(DetectEngineThreadCtx *det_ctx, const void *pect const int list_id = ctx->list_id; uint32_t local_id = 0; + if (f->alproto == ALPROTO_DOH2) { + txv = SCDoH2GetDnsTx(txv, flags); + if (txv == NULL) { + return; + } + } while(1) { // loop until we get a NULL diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index e7122e90caa9..7a6e746cdb52 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -107,6 +107,11 @@ void DetectAppLayerMpmRegister(const char *name, int direction, int priority, FatalError("MPM engine registration for %s failed", name); } + // every HTTP2 can be accessed from DOH2 + if (alproto == ALPROTO_HTTP2 || alproto == ALPROTO_DNS) { + DetectAppLayerMpmRegister(name, direction, priority, PrefilterRegister, GetData, + ALPROTO_DOH2, tx_min_progress); + } DetectBufferMpmRegistry *am = SCCalloc(1, sizeof(*am)); BUG_ON(am == NULL); am->name = name; diff --git a/src/detect-engine-prefilter.c b/src/detect-engine-prefilter.c index e40a5175dafb..9611ba335f0d 100644 --- a/src/detect-engine-prefilter.c +++ b/src/detect-engine-prefilter.c @@ -107,7 +107,7 @@ void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx, PrefilterEngine *engine = sgh->tx_engines; do { - if (engine->alproto != alproto) + if (!AppProtoCompatible(engine->alproto, alproto)) goto next; if (engine->ctx.tx_min_progress > tx->tx_progress) break; diff --git a/src/detect-engine.c b/src/detect-engine.c index 13e09be71889..9fdd45783f53 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -242,6 +242,10 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin } else { direction = 1; } + // every DNS or HTTP2 can be accessed from DOH2 + if (alproto == ALPROTO_HTTP2 || alproto == ALPROTO_DNS) { + DetectAppLayerInspectEngineRegister(name, ALPROTO_DOH2, dir, progress, Callback, GetData); + } DetectEngineAppInspectionEngine *new_engine = SCCalloc(1, sizeof(DetectEngineAppInspectionEngine)); diff --git a/src/detect-parse.c b/src/detect-parse.c index 243dbf9befa3..c23b823d9f1b 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1758,20 +1758,9 @@ int DetectSignatureSetAppProto(Signature *s, AppProto alproto) return -1; } - /* since AppProtoEquals is quite permissive wrt dcerpc and smb, make sure - * we refuse `alert dcerpc ... smb.share; content...` explicitly. */ - if (alproto == ALPROTO_SMB && s->alproto == ALPROTO_DCERPC) { - SCLogError("can't set rule app proto to %s: already set to %s", AppProtoToString(alproto), - AppProtoToString(s->alproto)); - return -1; - } - - if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, alproto)) { - if (AppProtoEquals(alproto, s->alproto)) { - // happens if alproto = HTTP_ANY and s->alproto = HTTP1 - // in this case, we must keep the most restrictive HTTP1 - alproto = s->alproto; - } else { + if (s->alproto != ALPROTO_UNKNOWN) { + alproto = AppProtoCommon(s->alproto, alproto); + if (alproto == ALPROTO_FAILED) { SCLogError("can't set rule app proto to %s: already set to %s", AppProtoToString(alproto), AppProtoToString(s->alproto)); return -1; diff --git a/src/detect.c b/src/detect.c index 4cc428eb999e..fc1e23446e15 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1099,7 +1099,9 @@ static bool DetectRunTxInspectRule(ThreadVars *tv, if (!(inspect_flags & BIT_U32(engine->id)) && direction == engine->dir) { - const bool skip_engine = (engine->alproto != 0 && engine->alproto != f->alproto); + const bool skip_engine = + (engine->alproto != 0 && !AppProtoCompatible(engine->alproto, f->alproto)); + /* special case: file_data on 'alert tcp' will have engines * in the list that are not for us. */ if (unlikely(skip_engine)) { diff --git a/src/output-json-alert.c b/src/output-json-alert.c index 18a14a0fc505..8465e2a566c9 100644 --- a/src/output-json-alert.c +++ b/src/output-json-alert.c @@ -61,13 +61,9 @@ #include "output-json-nfs.h" #include "output-json-smb.h" #include "output-json-flow.h" -#include "output-json-sip.h" -#include "output-json-rfb.h" #include "output-json-mqtt.h" #include "output-json-ike.h" -#include "output-json-modbus.h" #include "output-json-frame.h" -#include "output-json-quic.h" #include "util-print.h" #include "util-optimize.h" diff --git a/src/output-json-bittorrent-dht.c b/src/output-json-bittorrent-dht.c deleted file mode 100644 index 066df78f61fb..000000000000 --- a/src/output-json-bittorrent-dht.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (C) 2021 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. - */ - -/** - * \file - * - * Implement JSON/eve logging app-layer BitTorrent DHT. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "output-json-bittorrent-dht.h" -#include "rust.h" - -typedef struct LogBitTorrentDHTFileCtx_ { - uint32_t flags; - OutputJsonCtx *eve_ctx; -} LogBitTorrentDHTFileCtx; - -typedef struct LogBitTorrentDHTLogThread_ { - LogBitTorrentDHTFileCtx *bittorrent_dht_log_ctx; - OutputJsonThreadCtx *ctx; -} LogBitTorrentDHTLogThread; - -static int JsonBitTorrentDHTLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, - void *state, void *tx, uint64_t tx_id) -{ - LogBitTorrentDHTLogThread *thread = thread_data; - - JsonBuilder *js = CreateEveHeader( - p, LOG_DIR_PACKET, "bittorrent_dht", NULL, thread->bittorrent_dht_log_ctx->eve_ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_FAILED; - } - - if (!rs_bittorrent_dht_logger_log(tx, js)) { - goto error; - } - - OutputJsonBuilderBuffer(js, thread->ctx); - jb_free(js); - - return TM_ECODE_OK; - -error: - jb_free(js); - return TM_ECODE_FAILED; -} - -static void OutputBitTorrentDHTLogDeInitCtxSub(OutputCtx *output_ctx) -{ - LogBitTorrentDHTFileCtx *bittorrent_dht_log_ctx = (LogBitTorrentDHTFileCtx *)output_ctx->data; - SCFree(bittorrent_dht_log_ctx); - SCFree(output_ctx); -} - -static OutputInitResult OutputBitTorrentDHTLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputInitResult result = { NULL, false }; - OutputJsonCtx *ajt = parent_ctx->data; - - LogBitTorrentDHTFileCtx *bittorrent_dht_log_ctx = SCCalloc(1, sizeof(*bittorrent_dht_log_ctx)); - if (unlikely(bittorrent_dht_log_ctx == NULL)) { - return result; - } - bittorrent_dht_log_ctx->eve_ctx = ajt; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx)); - if (unlikely(output_ctx == NULL)) { - SCFree(bittorrent_dht_log_ctx); - return result; - } - output_ctx->data = bittorrent_dht_log_ctx; - output_ctx->DeInit = OutputBitTorrentDHTLogDeInitCtxSub; - - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_BITTORRENT_DHT); - - result.ctx = output_ctx; - result.ok = true; - return result; -} - -static TmEcode JsonBitTorrentDHTLogThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - LogBitTorrentDHTLogThread *thread = SCCalloc(1, sizeof(*thread)); - if (unlikely(thread == NULL)) { - return TM_ECODE_FAILED; - } - - if (initdata == NULL) { - SCLogDebug("Error getting context for EveLogBitTorrentDHT. \"initdata\" is NULL."); - goto error_exit; - } - - thread->bittorrent_dht_log_ctx = ((OutputCtx *)initdata)->data; - thread->ctx = CreateEveThreadCtx(t, thread->bittorrent_dht_log_ctx->eve_ctx); - if (!thread->ctx) { - goto error_exit; - } - *data = (void *)thread; - - return TM_ECODE_OK; - -error_exit: - SCFree(thread); - return TM_ECODE_FAILED; -} - -static TmEcode JsonBitTorrentDHTLogThreadDeinit(ThreadVars *t, void *data) -{ - LogBitTorrentDHTLogThread *thread = (LogBitTorrentDHTLogThread *)data; - if (thread == NULL) { - return TM_ECODE_OK; - } - FreeEveThreadCtx(thread->ctx); - SCFree(thread); - return TM_ECODE_OK; -} - -void JsonBitTorrentDHTLogRegister(void) -{ - if (ConfGetNode("app-layer.protocols.bittorrent-dht") == NULL) { - return; - } - - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonBitTorrentDHTLog", - "eve-log.bittorrent-dht", OutputBitTorrentDHTLogInitSub, ALPROTO_BITTORRENT_DHT, - JsonBitTorrentDHTLogger, JsonBitTorrentDHTLogThreadInit, - JsonBitTorrentDHTLogThreadDeinit, NULL); -} diff --git a/src/output-json-bittorrent-dht.h b/src/output-json-bittorrent-dht.h deleted file mode 100644 index 9396f5a5e8bb..000000000000 --- a/src/output-json-bittorrent-dht.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2021 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. - */ - -/** - * \file - */ - -#ifndef SURICATA_OUTPUT_JSON_BITTORRENT_DHT_H -#define SURICATA_OUTPUT_JSON_BITTORRENT_DHT_H - -void JsonBitTorrentDHTLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_BITTORRENT_DHT_H */ diff --git a/src/output-json-dnp3.c b/src/output-json-dnp3.c index 4336e04e070c..1387d6213632 100644 --- a/src/output-json-dnp3.c +++ b/src/output-json-dnp3.c @@ -140,7 +140,7 @@ static void JsonDNP3LogObjects(JsonBuilder *js, DNP3ObjectList *objects) } } -void JsonDNP3LogRequest(JsonBuilder *js, DNP3Transaction *dnp3tx) +static void JsonDNP3LogRequest(JsonBuilder *js, DNP3Transaction *dnp3tx) { JB_SET_STRING(js, "type", "request"); @@ -171,7 +171,7 @@ void JsonDNP3LogRequest(JsonBuilder *js, DNP3Transaction *dnp3tx) jb_close(js); } -void JsonDNP3LogResponse(JsonBuilder *js, DNP3Transaction *dnp3tx) +static void JsonDNP3LogResponse(JsonBuilder *js, DNP3Transaction *dnp3tx) { if (dnp3tx->ah.function_code == DNP3_APP_FC_UNSOLICITED_RESP) { JB_SET_STRING(js, "type", "unsolicited_response"); diff --git a/src/output-json-dnp3.h b/src/output-json-dnp3.h index 064421a0b1d1..5abc2774b46e 100644 --- a/src/output-json-dnp3.h +++ b/src/output-json-dnp3.h @@ -20,9 +20,6 @@ #include "app-layer-dnp3.h" -void JsonDNP3LogRequest(JsonBuilder *js, DNP3Transaction *); -void JsonDNP3LogResponse(JsonBuilder *js, DNP3Transaction *); - void JsonDNP3LogRegister(void); bool AlertJsonDnp3(void *vtx, JsonBuilder *js); diff --git a/src/output-json-dns.c b/src/output-json-dns.c index 3c7009b501ca..9cab2bde55c2 100644 --- a/src/output-json-dns.c +++ b/src/output-json-dns.c @@ -293,19 +293,22 @@ static JsonBuilder *JsonDNSLogAnswer(void *txptr) bool AlertJsonDns(void *txptr, JsonBuilder *js) { + bool r = false; jb_open_object(js, "dns"); JsonBuilder *qjs = JsonDNSLogQuery(txptr); if (qjs != NULL) { jb_set_object(js, "query", qjs); jb_free(qjs); + r = true; } JsonBuilder *ajs = JsonDNSLogAnswer(txptr); if (ajs != NULL) { jb_set_object(js, "answer", ajs); jb_free(ajs); + r = true; } jb_close(js); - return true; + return r; } static int JsonDnsLoggerToServer(ThreadVars *tv, void *thread_data, diff --git a/src/output-json-file.c b/src/output-json-file.c index 1018be06ee80..ae8400a18d53 100644 --- a/src/output-json-file.c +++ b/src/output-json-file.c @@ -61,7 +61,6 @@ #include "output-json-email-common.h" #include "output-json-nfs.h" #include "output-json-smb.h" -#include "output-json-http2.h" #include "app-layer-htp.h" #include "app-layer-htp-xff.h" diff --git a/src/output-json-ftp.c b/src/output-json-ftp.c index 34422f72f4af..14232bdfe393 100644 --- a/src/output-json-ftp.c +++ b/src/output-json-ftp.c @@ -154,60 +154,3 @@ bool EveFTPLogCommand(void *vtx, JsonBuilder *jb) jb_close(jb); return true; } - - -static int JsonFTPLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *vtx, uint64_t tx_id) -{ - SCEnter(); - OutputJsonThreadCtx *thread = thread_data; - - const char *event_type; - if (f->alproto == ALPROTO_FTPDATA) { - event_type = "ftp_data"; - } else { - event_type = "ftp"; - } - - JsonBuilder *jb = - CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, event_type, NULL, tx_id, thread->ctx); - if (likely(jb)) { - if (f->alproto == ALPROTO_FTPDATA) { - if (!EveFTPDataAddMetadata(vtx, jb)) { - goto fail; - } - } else { - EveFTPLogCommand(vtx, jb); - } - - OutputJsonBuilderBuffer(jb, thread); - - jb_free(jb); - } - return TM_ECODE_OK; - -fail: - jb_free(jb); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputFTPLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_FTP); - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_FTPDATA); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonFTPLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonFTPLog", "eve-log.ftp", - OutputFTPLogInitSub, ALPROTO_FTP, JsonFTPLogger, JsonLogThreadInit, JsonLogThreadDeinit, - NULL); - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonFTPLog", "eve-log.ftp", - OutputFTPLogInitSub, ALPROTO_FTPDATA, JsonFTPLogger, JsonLogThreadInit, - JsonLogThreadDeinit, NULL); - - SCLogDebug("FTP JSON logger registered."); -} diff --git a/src/output-json-ftp.h b/src/output-json-ftp.h index b87eebe2cc3f..57c35e9b66cb 100644 --- a/src/output-json-ftp.h +++ b/src/output-json-ftp.h @@ -24,7 +24,6 @@ #ifndef SURICATA_OUTPUT_JSON_FTP_H #define SURICATA_OUTPUT_JSON_FTP_H -void JsonFTPLogRegister(void); bool EveFTPLogCommand(void *vtx, JsonBuilder *js); #endif /* SURICATA_OUTPUT_JSON_FTP_H */ diff --git a/src/output-json-http2.c b/src/output-json-http2.c deleted file mode 100644 index cb096f37a043..000000000000 --- a/src/output-json-http2.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright (C) 2020-2021 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. - */ - -/** - * \file - * - * \author Philippe Antoine - * - * Implements HTTP2 JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-http2.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" - -#include "output-json.h" -#include "output-json-http2.h" -#include "rust.h" - -#define MODULE_NAME "LogHttp2Log" - -typedef struct OutputHttp2Ctx_ { - OutputJsonCtx *eve_ctx; -} OutputHttp2Ctx; - - -typedef struct JsonHttp2LogThread_ { - OutputHttp2Ctx *http2log_ctx; - OutputJsonThreadCtx *ctx; -} JsonHttp2LogThread; - -static int JsonHttp2Logger(ThreadVars *tv, void *thread_data, const Packet *p, - Flow *f, void *state, void *txptr, uint64_t tx_id) -{ - JsonHttp2LogThread *aft = (JsonHttp2LogThread *)thread_data; - - if (unlikely(state == NULL)) { - return 0; - } - - JsonBuilder *js = CreateEveHeaderWithTxId( - p, LOG_DIR_FLOW, "http", NULL, tx_id, aft->http2log_ctx->eve_ctx); - if (unlikely(js == NULL)) - return 0; - - if (!rs_http2_log_json(txptr, js)) { - goto end; - } - OutputJsonBuilderBuffer(js, aft->ctx); -end: - jb_free(js); - return 0; -} - -static TmEcode JsonHttp2LogThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - JsonHttp2LogThread *aft = SCCalloc(1, sizeof(JsonHttp2LogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - - if(initdata == NULL) - { - SCLogDebug("Error getting context for EveLogHTTP2. \"initdata\" argument NULL"); - goto error_exit; - } - - /* Use the Output Context (file pointer and mutex) */ - aft->http2log_ctx = ((OutputCtx *)initdata)->data; - aft->ctx = CreateEveThreadCtx(t, aft->http2log_ctx->eve_ctx); - if (!aft->ctx) { - goto error_exit; - } - - *data = (void *)aft; - return TM_ECODE_OK; - -error_exit: - SCFree(aft); - return TM_ECODE_FAILED; -} - -static TmEcode JsonHttp2LogThreadDeinit(ThreadVars *t, void *data) -{ - JsonHttp2LogThread *aft = (JsonHttp2LogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - FreeEveThreadCtx(aft->ctx); - /* clear memory */ - memset(aft, 0, sizeof(JsonHttp2LogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void OutputHttp2LogDeinitSub(OutputCtx *output_ctx) -{ - OutputHttp2Ctx *http2_ctx = output_ctx->data; - SCFree(http2_ctx); - SCFree(output_ctx); -} - -static OutputInitResult OutputHttp2LogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputInitResult result = { NULL, false }; - OutputJsonCtx *ojc = parent_ctx->data; - - OutputHttp2Ctx *http2_ctx = SCCalloc(1, sizeof(OutputHttp2Ctx)); - if (unlikely(http2_ctx == NULL)) - return result; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(http2_ctx); - return result; - } - - http2_ctx->eve_ctx = ojc; - - output_ctx->data = http2_ctx; - output_ctx->DeInit = OutputHttp2LogDeinitSub; - - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP2); - - result.ctx = output_ctx; - result.ok = true; - return result; -} - -void JsonHttp2LogRegister (void) -{ - /* also register as child of eve-log */ - OutputRegisterTxSubModuleWithProgress(LOGGER_JSON_TX, "eve-log", MODULE_NAME, "eve-log.http2", - OutputHttp2LogInitSub, ALPROTO_HTTP2, JsonHttp2Logger, HTTP2StateClosed, - HTTP2StateClosed, JsonHttp2LogThreadInit, JsonHttp2LogThreadDeinit, NULL); -} diff --git a/src/output-json-http2.h b/src/output-json-http2.h deleted file mode 100644 index 2b30fd7901f8..000000000000 --- a/src/output-json-http2.h +++ /dev/null @@ -1,29 +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. - */ - -/** - * \file - * - * \author Philippe Antoine - */ - -#ifndef SURICATA_OUTPUT_JSON_HTTP2_H -#define SURICATA_OUTPUT_JSON_HTTP2_H - -void JsonHttp2LogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_HTTP2_H */ diff --git a/src/output-json-krb5.c b/src/output-json-krb5.c deleted file mode 100644 index 9fc45c5d3c53..000000000000 --- a/src/output-json-krb5.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (C) 2018-2021 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * Implement JSON/eve logging app-layer KRB5. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-krb5.h" -#include "output-json-krb5.h" - -#include "rust.h" - -static int JsonKRB5Logger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - KRB5Transaction *krb5tx = tx; - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_PACKET, "krb5", NULL, thread->ctx); - if (unlikely(jb == NULL)) { - return TM_ECODE_FAILED; - } - - if (!rs_krb5_log_json_response(krb5tx, jb)) { - goto error; - } - - OutputJsonBuilderBuffer(jb, thread); - - jb_free(jb); - return TM_ECODE_OK; - -error: - jb_free(jb); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputKRB5LogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_KRB5); - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_KRB5); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonKRB5LogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonKRB5Log", "eve-log.krb5", - OutputKRB5LogInitSub, ALPROTO_KRB5, JsonKRB5Logger, JsonLogThreadInit, - JsonLogThreadDeinit, NULL); - - SCLogDebug("KRB5 JSON logger registered."); -} diff --git a/src/output-json-krb5.h b/src/output-json-krb5.h deleted file mode 100644 index 33c7f956773b..000000000000 --- a/src/output-json-krb5.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_OUTPUT_JSON_KRB5_H -#define SURICATA_OUTPUT_JSON_KRB5_H - -void JsonKRB5LogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_KRB5_H */ diff --git a/src/output-json-modbus.c b/src/output-json-modbus.c deleted file mode 100644 index 9e508ead9acc..000000000000 --- a/src/output-json-modbus.c +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (C) 2019-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. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" -#include "output.h" -#include "output-json.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "output-json-modbus.h" -#include "rust.h" - -typedef struct LogModbusFileCtx_ { - LogFileCtx *file_ctx; - OutputJsonCtx *eve_ctx; -} LogModbusFileCtx; - -typedef struct JsonModbusLogThread_ { - LogModbusFileCtx *modbuslog_ctx; - OutputJsonThreadCtx *ctx; -} JsonModbusLogThread; - -static int JsonModbusLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, - void *state, void *tx, uint64_t tx_id) -{ - JsonModbusLogThread *thread = thread_data; - - JsonBuilder *js = - CreateEveHeader(p, LOG_DIR_FLOW, "modbus", NULL, thread->modbuslog_ctx->eve_ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_OK; - } - if (!rs_modbus_to_json(tx, js)) { - jb_free(js); - return TM_ECODE_FAILED; - } - OutputJsonBuilderBuffer(js, thread->ctx); - - jb_free(js); - return TM_ECODE_OK; -} - -static void OutputModbusLogDeInitCtxSub(OutputCtx *output_ctx) -{ - LogModbusFileCtx *modbuslog_ctx = (LogModbusFileCtx *)output_ctx->data; - SCFree(modbuslog_ctx); - SCFree(output_ctx); -} - -static OutputInitResult OutputModbusLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputInitResult result = { NULL, false }; - OutputJsonCtx *ajt = parent_ctx->data; - - LogModbusFileCtx *modbuslog_ctx = SCCalloc(1, sizeof(*modbuslog_ctx)); - if (unlikely(modbuslog_ctx == NULL)) { - return result; - } - modbuslog_ctx->file_ctx = ajt->file_ctx; - modbuslog_ctx->eve_ctx = ajt; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx)); - if (unlikely(output_ctx == NULL)) { - SCFree(modbuslog_ctx); - return result; - } - output_ctx->data = modbuslog_ctx; - output_ctx->DeInit = OutputModbusLogDeInitCtxSub; - - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_MODBUS); - - SCLogDebug("modbus log sub-module initialized."); - - result.ctx = output_ctx; - result.ok = true; - return result; -} - -static TmEcode JsonModbusLogThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - if (initdata == NULL) { - SCLogDebug("Error getting context for EveLogModbus. \"initdata\" is NULL."); - return TM_ECODE_FAILED; - } - - JsonModbusLogThread *thread = SCCalloc(1, sizeof(*thread)); - if (unlikely(thread == NULL)) { - return TM_ECODE_FAILED; - } - - thread->modbuslog_ctx = ((OutputCtx *)initdata)->data; - thread->ctx = CreateEveThreadCtx(t, thread->modbuslog_ctx->eve_ctx); - if (thread->ctx == NULL) { - goto error_exit; - } - - *data = (void *)thread; - return TM_ECODE_OK; - -error_exit: - SCFree(thread); - return TM_ECODE_FAILED; -} - -static TmEcode JsonModbusLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonModbusLogThread *thread = (JsonModbusLogThread *)data; - if (thread == NULL) { - return TM_ECODE_OK; - } - FreeEveThreadCtx(thread->ctx); - SCFree(thread); - return TM_ECODE_OK; -} - -void JsonModbusLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonModbusLog", "eve-log.modbus", - OutputModbusLogInitSub, ALPROTO_MODBUS, JsonModbusLogger, JsonModbusLogThreadInit, - JsonModbusLogThreadDeinit, NULL); - - SCLogDebug("modbus json logger registered."); -} diff --git a/src/output-json-modbus.h b/src/output-json-modbus.h deleted file mode 100644 index 4c104964a285..000000000000 --- a/src/output-json-modbus.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2019 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 SURICATA_OUTPUT_JSON_MODBUS_H -#define SURICATA_OUTPUT_JSON_MODBUS_H - -void JsonModbusLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_MODBUS_H */ diff --git a/src/output-json-quic.c b/src/output-json-quic.c deleted file mode 100644 index 830ac78fdfbb..000000000000 --- a/src/output-json-quic.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 2021 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. - */ - -/** - * \file - * - * Implements JSON/eve logging for Quic app-layer. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" -#include "output.h" -#include "output-json.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "output-json-quic.h" -#include "rust.h" - -typedef struct LogQuicFileCtx_ { - LogFileCtx *file_ctx; - OutputJsonCtx *eve_ctx; -} LogQuicFileCtx; - -typedef struct JsonQuicLogThread_ { - LogQuicFileCtx *quiclog_ctx; - OutputJsonThreadCtx *ctx; -} JsonQuicLogThread; - -static int JsonQuicLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, - void *tx, uint64_t tx_id) -{ - JsonQuicLogThread *thread = thread_data; - - JsonBuilder *js = - CreateEveHeader(p, LOG_DIR_PACKET, "quic", NULL, thread->quiclog_ctx->eve_ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_OK; - } - if (!rs_quic_to_json(tx, js)) { - jb_free(js); - return TM_ECODE_FAILED; - } - OutputJsonBuilderBuffer(js, thread->ctx); - - jb_free(js); - return TM_ECODE_OK; -} - -static void OutputQuicLogDeInitCtxSub(OutputCtx *output_ctx) -{ - LogQuicFileCtx *quiclog_ctx = (LogQuicFileCtx *)output_ctx->data; - SCFree(quiclog_ctx); - SCFree(output_ctx); -} - -static OutputInitResult OutputQuicLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputInitResult result = { NULL, false }; - OutputJsonCtx *ajt = parent_ctx->data; - - LogQuicFileCtx *quiclog_ctx = SCCalloc(1, sizeof(*quiclog_ctx)); - if (unlikely(quiclog_ctx == NULL)) { - return result; - } - quiclog_ctx->file_ctx = ajt->file_ctx; - quiclog_ctx->eve_ctx = ajt; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx)); - if (unlikely(output_ctx == NULL)) { - SCFree(quiclog_ctx); - return result; - } - output_ctx->data = quiclog_ctx; - output_ctx->DeInit = OutputQuicLogDeInitCtxSub; - - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_QUIC); - - result.ctx = output_ctx; - result.ok = true; - return result; -} - -static TmEcode JsonQuicLogThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - if (initdata == NULL) { - SCLogDebug("Error getting context for EveLogQuic. \"initdata\" is NULL."); - return TM_ECODE_FAILED; - } - - JsonQuicLogThread *thread = SCCalloc(1, sizeof(*thread)); - if (unlikely(thread == NULL)) { - return TM_ECODE_FAILED; - } - - thread->quiclog_ctx = ((OutputCtx *)initdata)->data; - thread->ctx = CreateEveThreadCtx(t, thread->quiclog_ctx->eve_ctx); - if (thread->ctx == NULL) { - goto error_exit; - } - - *data = (void *)thread; - return TM_ECODE_OK; - -error_exit: - SCFree(thread); - return TM_ECODE_FAILED; -} - -static TmEcode JsonQuicLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonQuicLogThread *thread = (JsonQuicLogThread *)data; - if (thread == NULL) { - return TM_ECODE_OK; - } - FreeEveThreadCtx(thread->ctx); - SCFree(thread); - return TM_ECODE_OK; -} - -void JsonQuicLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonQuicLog", "eve-log.quic", - OutputQuicLogInitSub, ALPROTO_QUIC, JsonQuicLogger, JsonQuicLogThreadInit, - JsonQuicLogThreadDeinit, NULL); - - SCLogDebug("quic json logger registered."); -} diff --git a/src/output-json-quic.h b/src/output-json-quic.h deleted file mode 100644 index a93a4dff029f..000000000000 --- a/src/output-json-quic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2021 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. - */ - -/** - * \file - */ - -#ifndef SURICATA_OUTPUT_JSON_QUIC_H -#define SURICATA_OUTPUT_JSON_QUIC_H - -void JsonQuicLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_QUIC_H */ diff --git a/src/output-json-rdp.c b/src/output-json-rdp.c deleted file mode 100644 index bc5d9ae9df89..000000000000 --- a/src/output-json-rdp.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2019-2021 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. - */ - -/** - * \file - * - * \author Zach Kelly - * - * Application layer logger for RDP - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" -#include "output.h" -#include "output-json.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-rdp.h" -#include "output-json-rdp.h" -#include "rust.h" - -static int JsonRdpLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *js = CreateEveHeader(p, LOG_DIR_PACKET, "rdp", NULL, thread->ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_OK; - } - if (!rs_rdp_to_json(tx, js)) { - jb_free(js); - return TM_ECODE_FAILED; - } - OutputJsonBuilderBuffer(js, thread); - - jb_free(js); - return TM_ECODE_OK; -} - -static OutputInitResult OutputRdpLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_RDP); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonRdpLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonRdpLog", "eve-log.rdp", - OutputRdpLogInitSub, ALPROTO_RDP, JsonRdpLogger, JsonLogThreadInit, JsonLogThreadDeinit, - NULL); - - SCLogDebug("rdp json logger registered."); -} diff --git a/src/output-json-rdp.h b/src/output-json-rdp.h deleted file mode 100644 index 9a400c9a2d03..000000000000 --- a/src/output-json-rdp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2019 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. - */ - -/** - * \file - * - * \author Zach Kelly - */ - -#ifndef SURICATA_OUTPUT_JSON_RDP_H -#define SURICATA_OUTPUT_JSON_RDP_H - -void JsonRdpLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_RDP_H */ diff --git a/src/output-json-rfb.c b/src/output-json-rfb.c deleted file mode 100644 index e2b832bece13..000000000000 --- a/src/output-json-rfb.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (C) 2020-2021 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. - */ - -/** - * \file - * - * \author Frank Honza - * - * Implement JSON/eve logging app-layer RFB. - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-rfb.h" -#include "output-json-rfb.h" - -#include "rust-bindings.h" - -static int JsonRFBLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *js = CreateEveHeader(p, LOG_DIR_FLOW, "rfb", NULL, thread->ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_FAILED; - } - - if (!rs_rfb_logger_log(tx, js)) { - goto error; - } - - OutputJsonBuilderBuffer(js, thread); - jb_free(js); - - return TM_ECODE_OK; - -error: - jb_free(js); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputRFBLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_RFB); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonRFBLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonRFBLog", "eve-log.rfb", - OutputRFBLogInitSub, ALPROTO_RFB, JsonRFBLogger, JsonLogThreadInit, JsonLogThreadDeinit, - NULL); -} diff --git a/src/output-json-rfb.h b/src/output-json-rfb.h deleted file mode 100644 index 4411963b9bed..000000000000 --- a/src/output-json-rfb.h +++ /dev/null @@ -1,29 +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. - */ - -/** - * \file - * - * \author Frank Honza - */ - -#ifndef SURICATA_OUTPUT_JSON_RFB_H -#define SURICATA_OUTPUT_JSON_RFB_H - -void JsonRFBLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_RFB_H */ diff --git a/src/output-json-sip.c b/src/output-json-sip.c deleted file mode 100644 index f147a755e28d..000000000000 --- a/src/output-json-sip.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (C) 2018-2021 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. - */ - -/** - * \file - * - * \author Giuseppe Longo - * - * Implement JSON/eve logging app-layer SIP. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-sip.h" -#include "output-json-sip.h" - -#include "rust.h" - -static int JsonSIPLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - SIPTransaction *siptx = tx; - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *js = CreateEveHeader((Packet *)p, LOG_DIR_PACKET, "sip", NULL, thread->ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_OK; - } - - if (!rs_sip_log_json(siptx, js)) { - goto error; - } - - OutputJsonBuilderBuffer(js, thread); - jb_free(js); - - return TM_ECODE_OK; - -error: - jb_free(js); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputSIPLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SIP); - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SIP); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonSIPLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSIPLog", "eve-log.sip", - OutputSIPLogInitSub, ALPROTO_SIP, JsonSIPLogger, JsonLogThreadInit, JsonLogThreadDeinit, - NULL); - - SCLogDebug("SIP JSON logger registered."); -} diff --git a/src/output-json-sip.h b/src/output-json-sip.h deleted file mode 100644 index 1d47e5ada223..000000000000 --- a/src/output-json-sip.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015 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. - */ - -/** - * \file - * - * \author Giuseppe Longo - */ - -#ifndef SURICATA_OUTPUT_JSON_SIP_H -#define SURICATA_OUTPUT_JSON_SIP_H - -void JsonSIPLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_SIP_H */ diff --git a/src/output-json-snmp.c b/src/output-json-snmp.c deleted file mode 100644 index cbf0a7c992e4..000000000000 --- a/src/output-json-snmp.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (C) 2018-2021 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * Implement JSON/eve logging app-layer SNMP. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-snmp.h" -#include "output-json-snmp.h" - -#include "rust.h" - -static int JsonSNMPLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - SNMPTransaction *snmptx = tx; - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_PACKET, "snmp", NULL, thread->ctx); - if (unlikely(jb == NULL)) { - return TM_ECODE_FAILED; - } - - if (!rs_snmp_log_json_response(snmptx, jb)) { - goto error; - } - - OutputJsonBuilderBuffer(jb, thread); - - jb_free(jb); - return TM_ECODE_OK; - -error: - jb_free(jb); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputSNMPLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SNMP); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonSNMPLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSNMPLog", "eve-log.snmp", - OutputSNMPLogInitSub, ALPROTO_SNMP, JsonSNMPLogger, JsonLogThreadInit, - JsonLogThreadDeinit, NULL); - - SCLogDebug("SNMP JSON logger registered."); -} diff --git a/src/output-json-snmp.h b/src/output-json-snmp.h deleted file mode 100644 index fa40b0c2f0d3..000000000000 --- a/src/output-json-snmp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015-2019 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. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef SURICATA_OUTPUT_JSON_SNMP_H -#define SURICATA_OUTPUT_JSON_SNMP_H - -void JsonSNMPLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_SNMP_H */ diff --git a/src/output-json-ssh.c b/src/output-json-ssh.c deleted file mode 100644 index 45a8d8eab333..000000000000 --- a/src/output-json-ssh.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 2014-2021 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. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements SSH JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-ssh.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" - -#include "output-json.h" -#include "output-json-ssh.h" -#include "rust.h" - -#define MODULE_NAME "LogSshLog" - -static int JsonSshLogger(ThreadVars *tv, void *thread_data, const Packet *p, - Flow *f, void *state, void *txptr, uint64_t tx_id) -{ - OutputJsonThreadCtx *thread = thread_data; - - if (unlikely(state == NULL)) { - return 0; - } - - JsonBuilder *js = CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, "ssh", NULL, tx_id, thread->ctx); - if (unlikely(js == NULL)) - return 0; - - if (!rs_ssh_log_json(txptr, js)) { - goto end; - } - OutputJsonBuilderBuffer(js, thread); - -end: - jb_free(js); - return 0; -} - -static OutputInitResult OutputSshLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SSH); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonSshLogRegister (void) -{ - /* register as child of eve-log */ - OutputRegisterTxSubModuleWithCondition(LOGGER_JSON_TX, "eve-log", "JsonSshLog", "eve-log.ssh", - OutputSshLogInitSub, ALPROTO_SSH, JsonSshLogger, SSHTxLogCondition, JsonLogThreadInit, - JsonLogThreadDeinit, NULL); -} diff --git a/src/output-json-ssh.h b/src/output-json-ssh.h deleted file mode 100644 index 74f24b053bd6..000000000000 --- a/src/output-json-ssh.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 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. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef SURICATA_OUTPUT_JSON_SSH_H -#define SURICATA_OUTPUT_JSON_SSH_H - -void JsonSshLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_SSH_H */ diff --git a/src/output-json-template.c b/src/output-json-template.c deleted file mode 100644 index 2ca48b7ae373..000000000000 --- a/src/output-json-template.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (C) 2018-2022 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: Update \author in this file and in output-json-template.h. - * TODO: Remove SCLogNotice statements, or convert to debug. - * TODO: Implement your app-layers logging. - */ - -/** - * \file - * - * \author FirstName LastName - * - * Implement JSON/eve logging app-layer Template. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "output-json-template.h" -#include "rust.h" - -typedef struct LogTemplateFileCtx_ { - uint32_t flags; - OutputJsonCtx *eve_ctx; -} LogTemplateFileCtx; - -typedef struct LogTemplateLogThread_ { - LogTemplateFileCtx *templatelog_ctx; - OutputJsonThreadCtx *ctx; -} LogTemplateLogThread; - -static int JsonTemplateLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, - void *state, void *tx, uint64_t tx_id) -{ - SCLogNotice("JsonTemplateLogger"); - LogTemplateLogThread *thread = thread_data; - - JsonBuilder *js = - CreateEveHeader(p, LOG_DIR_PACKET, "template", NULL, thread->templatelog_ctx->eve_ctx); - if (unlikely(js == NULL)) { - return TM_ECODE_FAILED; - } - - if (!rs_template_logger_log(tx, js)) { - goto error; - } - - OutputJsonBuilderBuffer(js, thread->ctx); - jb_free(js); - - return TM_ECODE_OK; - -error: - jb_free(js); - return TM_ECODE_FAILED; -} - -static void OutputTemplateLogDeInitCtxSub(OutputCtx *output_ctx) -{ - LogTemplateFileCtx *templatelog_ctx = (LogTemplateFileCtx *)output_ctx->data; - SCFree(templatelog_ctx); - SCFree(output_ctx); -} - -static OutputInitResult OutputTemplateLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputInitResult result = { NULL, false }; - OutputJsonCtx *ajt = parent_ctx->data; - - LogTemplateFileCtx *templatelog_ctx = SCCalloc(1, sizeof(*templatelog_ctx)); - if (unlikely(templatelog_ctx == NULL)) { - return result; - } - templatelog_ctx->eve_ctx = ajt; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx)); - if (unlikely(output_ctx == NULL)) { - SCFree(templatelog_ctx); - return result; - } - output_ctx->data = templatelog_ctx; - output_ctx->DeInit = OutputTemplateLogDeInitCtxSub; - - SCLogNotice("Template log sub-module initialized."); - - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TEMPLATE); - - result.ctx = output_ctx; - result.ok = true; - return result; -} - -static TmEcode JsonTemplateLogThreadInit(ThreadVars *t, const void *initdata, void **data) -{ - LogTemplateLogThread *thread = SCCalloc(1, sizeof(*thread)); - if (unlikely(thread == NULL)) { - return TM_ECODE_FAILED; - } - - if (initdata == NULL) { - SCLogDebug("Error getting context for EveLogTemplate. \"initdata\" is NULL."); - goto error_exit; - } - - thread->templatelog_ctx = ((OutputCtx *)initdata)->data; - thread->ctx = CreateEveThreadCtx(t, thread->templatelog_ctx->eve_ctx); - if (!thread->ctx) { - goto error_exit; - } - *data = (void *)thread; - - return TM_ECODE_OK; - -error_exit: - SCFree(thread); - return TM_ECODE_FAILED; -} - -static TmEcode JsonTemplateLogThreadDeinit(ThreadVars *t, void *data) -{ - LogTemplateLogThread *thread = (LogTemplateLogThread *)data; - if (thread == NULL) { - return TM_ECODE_OK; - } - FreeEveThreadCtx(thread->ctx); - SCFree(thread); - return TM_ECODE_OK; -} - -void JsonTemplateLogRegister(void) -{ - /* TEMPLATE_START_REMOVE */ - if (ConfGetNode("app-layer.protocols.template") == NULL) { - return; - } - /* TEMPLATE_END_REMOVE */ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTemplateLog", "eve-log.template", - OutputTemplateLogInitSub, ALPROTO_TEMPLATE, JsonTemplateLogger, - JsonTemplateLogThreadInit, JsonTemplateLogThreadDeinit, NULL); - - SCLogNotice("Template JSON logger registered."); -} diff --git a/src/output-json-template.h b/src/output-json-template.h deleted file mode 100644 index 5a91af5932e1..000000000000 --- a/src/output-json-template.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2018 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. - */ - -/** - * \file - * - * \author FirstName LastName - */ - -#ifndef SURICATA_OUTPUT_JSON_TEMPLATE_RUST_H -#define SURICATA_OUTPUT_JSON_TEMPLATE_RUST_H - -void JsonTemplateLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_TEMPLATE_RUST_H */ diff --git a/src/output-json-tftp.c b/src/output-json-tftp.c deleted file mode 100644 index a0bc9ee1809e..000000000000 --- a/src/output-json-tftp.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (C) 2020-2021 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. - */ - -/** - * \file - * - * \author Clément Galland - * - * Implement JSON/eve logging app-layer TFTP. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-tftp.h" -#include "output-json-tftp.h" - -#include "rust.h" - -static int JsonTFTPLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - OutputJsonThreadCtx *thread = thread_data; - - JsonBuilder *jb = CreateEveHeader(p, LOG_DIR_PACKET, "tftp", NULL, thread->ctx); - if (unlikely(jb == NULL)) { - return TM_ECODE_FAILED; - } - - if (unlikely(!rs_tftp_log_json_request(tx, jb))) { - goto error; - } - - OutputJsonBuilderBuffer(jb, thread); - - jb_free(jb); - return TM_ECODE_OK; - -error: - jb_free(jb); - return TM_ECODE_FAILED; -} - -static OutputInitResult OutputTFTPLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_TFTP); - return OutputJsonLogInitSub(conf, parent_ctx); -} - -void JsonTFTPLogRegister(void) -{ - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTFTPLog", "eve-log.tftp", - OutputTFTPLogInitSub, ALPROTO_TFTP, JsonTFTPLogger, JsonLogThreadInit, - JsonLogThreadDeinit, NULL); - - SCLogDebug("TFTP JSON logger registered."); -} diff --git a/src/output-json-tftp.h b/src/output-json-tftp.h deleted file mode 100644 index 40bbf7c4d474..000000000000 --- a/src/output-json-tftp.h +++ /dev/null @@ -1,29 +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. - */ - -/** - * \file - * - * \author Clément Galland - */ - -#ifndef SURICATA_OUTPUT_JSON_TFTP_H -#define SURICATA_OUTPUT_JSON_TFTP_H - -void JsonTFTPLogRegister(void); - -#endif /* SURICATA_OUTPUT_JSON_TFTP_H */ diff --git a/src/output.c b/src/output.c index 149dda58c284..78b9704d369f 100644 --- a/src/output.c +++ b/src/output.c @@ -54,12 +54,12 @@ #include "log-httplog.h" #include "output-json-http.h" #include "output-json-dns.h" -#include "output-json-modbus.h" #include "log-tlslog.h" #include "log-tlsstore.h" #include "output-json-tls.h" -#include "output-json-ssh.h" #include "log-pcap.h" +// for SSHTxLogCondition +#include "app-layer-ssh.h" #include "output-json-file.h" #include "output-json-smtp.h" #include "output-json-stats.h" @@ -69,26 +69,17 @@ #include "output-json-ftp.h" // for misplaced EveFTPDataAddMetadata #include "app-layer-ftp.h" -#include "output-json-tftp.h" #include "output-json-smb.h" #include "output-json-ike.h" -#include "output-json-krb5.h" -#include "output-json-quic.h" #include "output-json-dhcp.h" -#include "output-json-snmp.h" -#include "output-json-sip.h" -#include "output-json-rfb.h" #include "output-json-mqtt.h" #include "output-json-pgsql.h" -#include "output-json-template.h" -#include "output-json-rdp.h" -#include "output-json-http2.h" #include "output-lua.h" #include "output-json-dnp3.h" #include "output-json-metadata.h" #include "output-json-dcerpc.h" #include "output-json-frame.h" -#include "output-json-bittorrent-dht.h" +#include "app-layer-parser.h" #include "output-filestore.h" typedef struct RootLogger_ { @@ -1034,6 +1025,63 @@ void OutputRegisterRootLoggers(void) OutputStreamingLoggerRegister(); } +static int JsonGenericLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, + void *state, void *tx, uint64_t tx_id, int dir) +{ + OutputJsonThreadCtx *thread = thread_data; + EveJsonSimpleAppLayerLogger *al = SCEveJsonSimpleGetLogger(f->alproto); + if (al == NULL) { + return TM_ECODE_FAILED; + } + + const char *name; + switch (al->proto) { + case ALPROTO_HTTP2: + // special case + name = "http"; + break; + case ALPROTO_FTPDATA: + // underscore instead of dash + name = "ftp_data"; + break; + case ALPROTO_BITTORRENT_DHT: + // underscore instead of dash + name = "bittorrent_dht"; + break; + default: + name = AppProtoToString(al->proto); + } + JsonBuilder *js = CreateEveHeader(p, dir, name, NULL, thread->ctx); + if (unlikely(js == NULL)) { + return TM_ECODE_FAILED; + } + + if (!al->LogTx(tx, js)) { + goto error; + } + + OutputJsonBuilderBuffer(js, thread); + jb_free(js); + + return TM_ECODE_OK; + +error: + jb_free(js); + return TM_ECODE_FAILED; +} + +static int JsonGenericDirPacketLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, + void *state, void *tx, uint64_t tx_id) +{ + return JsonGenericLogger(tv, thread_data, p, f, state, tx, tx_id, LOG_DIR_PACKET); +} + +static int JsonGenericDirFlowLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, + void *state, void *tx, uint64_t tx_id) +{ + return JsonGenericLogger(tv, thread_data, p, f, state, tx, tx_id, LOG_DIR_FLOW); +} + /** * \brief Register all non-root logging modules. */ @@ -1058,13 +1106,17 @@ void OutputRegisterLoggers(void) /* http log */ LogHttpLogRegister(); JsonHttpLogRegister(); - JsonHttp2LogRegister(); + OutputRegisterTxSubModuleWithProgress(LOGGER_JSON_TX, "eve-log", "LogHttp2Log", "eve-log.http2", + OutputJsonLogInitSub, ALPROTO_HTTP2, JsonGenericDirFlowLogger, HTTP2StateClosed, + HTTP2StateClosed, JsonLogThreadInit, JsonLogThreadDeinit, NULL); /* tls log */ LogTlsLogRegister(); JsonTlsLogRegister(); LogTlsStoreRegister(); /* ssh */ - JsonSshLogRegister(); + OutputRegisterTxSubModuleWithCondition(LOGGER_JSON_TX, "eve-log", "JsonSshLog", "eve-log.ssh", + OutputJsonLogInitSub, ALPROTO_SSH, JsonGenericDirFlowLogger, SSHTxLogCondition, + JsonLogThreadInit, JsonLogThreadDeinit, NULL); /* pcap log */ PcapLogRegister(); /* file log */ @@ -1073,7 +1125,11 @@ void OutputRegisterLoggers(void) /* dns */ JsonDnsLogRegister(); /* modbus */ - JsonModbusLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonModbusLog", "eve-log.modbus", + OutputJsonLogInitSub, ALPROTO_MODBUS, JsonGenericDirFlowLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("modbus json logger registered."); /* tcp streaming data */ LogTcpDataLogRegister(); /* log stats */ @@ -1094,39 +1150,82 @@ void OutputRegisterLoggers(void) /* NFS JSON logger. */ JsonNFSLogRegister(); /* TFTP JSON logger. */ - JsonTFTPLogRegister(); - /* FTP JSON logger. */ - JsonFTPLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTFTPLog", "eve-log.tftp", + OutputJsonLogInitSub, ALPROTO_TFTP, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("TFTP JSON logger registered."); + /* FTP and FTP-DATA JSON loggers. */ + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonFTPLog", "eve-log.ftp", + OutputJsonLogInitSub, ALPROTO_FTP, JsonGenericDirFlowLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonFTPLog", "eve-log.ftp", + OutputJsonLogInitSub, ALPROTO_FTPDATA, JsonGenericDirFlowLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + SCLogDebug("FTP JSON logger registered."); + /* SMB JSON logger. */ JsonSMBLogRegister(); /* IKE JSON logger. */ JsonIKELogRegister(); /* KRB5 JSON logger. */ - JsonKRB5LogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonKRB5Log", "eve-log.krb5", + OutputJsonLogInitSub, ALPROTO_KRB5, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("KRB5 JSON logger registered."); /* QUIC JSON logger. */ - JsonQuicLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonQuicLog", "eve-log.quic", + OutputJsonLogInitSub, ALPROTO_QUIC, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("quic json logger registered."); /* DHCP JSON logger. */ JsonDHCPLogRegister(); /* SNMP JSON logger. */ - JsonSNMPLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSNMPLog", "eve-log.snmp", + OutputJsonLogInitSub, ALPROTO_SNMP, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("SNMP JSON logger registered."); /* SIP JSON logger. */ - JsonSIPLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonSIPLog", "eve-log.sip", + OutputJsonLogInitSub, ALPROTO_SIP, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + + SCLogDebug("SIP JSON logger registered."); /* RFB JSON logger. */ - JsonRFBLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonRFBLog", "eve-log.rfb", + OutputJsonLogInitSub, ALPROTO_RFB, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); /* MQTT JSON logger. */ JsonMQTTLogRegister(); /* Pgsql JSON logger. */ JsonPgsqlLogRegister(); + /* DoH2 JSON logger. */ + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonDoH2Log", "eve-log.doh2", + OutputJsonLogInitSub, ALPROTO_DOH2, JsonGenericDirFlowLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); /* Template JSON logger. */ - JsonTemplateLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonTemplateLog", "eve-log.template", + OutputJsonLogInitSub, ALPROTO_TEMPLATE, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); /* RDP JSON logger. */ - JsonRdpLogRegister(); + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonRdpLog", "eve-log.rdp", + OutputJsonLogInitSub, ALPROTO_RDP, JsonGenericDirPacketLogger, JsonLogThreadInit, + JsonLogThreadDeinit, NULL); + SCLogDebug("rdp json logger registered."); /* DCERPC JSON logger. */ JsonDCERPCLogRegister(); /* app layer frames */ JsonFrameLogRegister(); /* BitTorrent DHT JSON logger */ - JsonBitTorrentDHTLogRegister(); + if (ConfGetNode("app-layer.protocols.bittorrent-dht") != NULL) { + /* Register as an eve sub-module. */ + OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonBitTorrentDHTLog", + "eve-log.bittorrent-dht", OutputJsonLogInitSub, ALPROTO_BITTORRENT_DHT, + JsonGenericDirPacketLogger, JsonLogThreadInit, JsonLogThreadDeinit, NULL); + } } static EveJsonSimpleAppLayerLogger simple_json_applayer_loggers[ALPROTO_MAX] = { @@ -1157,8 +1256,9 @@ static EveJsonSimpleAppLayerLogger simple_json_applayer_loggers[ALPROTO_MAX] = { { ALPROTO_SIP, (EveJsonSimpleTxLogFunc)rs_sip_log_json }, { ALPROTO_RFB, rs_rfb_logger_log }, { ALPROTO_MQTT, JsonMQTTAddMetadata }, - { ALPROTO_PGSQL, NULL }, // TODO missing - { ALPROTO_TELNET, NULL }, // no logging + { ALPROTO_PGSQL, NULL }, // TODO missing + { ALPROTO_TELNET, NULL }, // no logging + { ALPROTO_DOH2, rs_http2_log_json }, // http2 logger knows how to log dns { ALPROTO_TEMPLATE, rs_template_logger_log }, { ALPROTO_RDP, (EveJsonSimpleTxLogFunc)rs_rdp_to_json }, { ALPROTO_HTTP2, rs_http2_log_json }, diff --git a/src/util-profiling.h b/src/util-profiling.h index 564f62b5c78f..094c6de6d209 100644 --- a/src/util-profiling.h +++ b/src/util-profiling.h @@ -170,13 +170,12 @@ PktProfiling *SCProfilePacketStart(void); (dp)->alproto = (id); \ } -#define PACKET_PROFILING_APP_END(dp, id) \ - if (profiling_packets_enabled) { \ - BUG_ON((id) != (dp)->alproto); \ - (dp)->ticks_end = UtilCpuGetTicks(); \ - if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \ - (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \ - } \ +#define PACKET_PROFILING_APP_END(dp) \ + if (profiling_packets_enabled) { \ + (dp)->ticks_end = UtilCpuGetTicks(); \ + if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \ + (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \ + } \ } #define PACKET_PROFILING_APP_PD_START(dp) \ @@ -340,7 +339,7 @@ void SCProfilingDump(void); #define PACKET_PROFILING_RESET(p) #define PACKET_PROFILING_APP_START(dp, id) -#define PACKET_PROFILING_APP_END(dp, id) +#define PACKET_PROFILING_APP_END(d) #define PACKET_PROFILING_APP_RESET(dp) #define PACKET_PROFILING_APP_STORE(dp, p) diff --git a/suricata.yaml.in b/suricata.yaml.in index 38f5152f5dad..730eb6b5dac6 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -305,6 +305,8 @@ outputs: - mqtt: # passwords: yes # enable output of passwords - http2 + # dns over http2 + - doh2 - pgsql: enabled: no # passwords: yes # enable output of passwords. Disabled by default @@ -925,6 +927,8 @@ app-layer: ssh: enabled: yes #hassh: yes + doh2: + enabled: yes http2: enabled: yes # Maximum number of live HTTP2 streams in a flow