summaryrefslogtreecommitdiffstats
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rust/derive/Cargo.toml2
-rw-r--r--rust/dist/rust-bindings.h2
-rw-r--r--rust/src/applayertemplate/template.rs20
-rw-r--r--rust/src/dhcp/logger.rs4
-rw-r--r--rust/src/dns/log.rs2
-rw-r--r--rust/src/ike/ikev1.rs2
-rw-r--r--rust/src/jsonbuilder.rs16
-rw-r--r--rust/src/mqtt/mqtt.rs8
-rw-r--r--rust/src/nfs/nfs.rs2
-rw-r--r--rust/src/smb/log.rs4
-rw-r--r--rust/src/ssh/logger.rs10
-rw-r--r--rust/src/ssh/ssh.rs6
12 files changed, 58 insertions, 20 deletions
diff --git a/rust/derive/Cargo.toml b/rust/derive/Cargo.toml
index 4aa81b4..c697f68 100644
--- a/rust/derive/Cargo.toml
+++ b/rust/derive/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "suricata-derive"
-version = "7.0.3"
+version = "7.0.4"
edition = "2021"
[lib]
diff --git a/rust/dist/rust-bindings.h b/rust/dist/rust-bindings.h
index 77afc3b..56f350c 100644
--- a/rust/dist/rust-bindings.h
+++ b/rust/dist/rust-bindings.h
@@ -4424,6 +4424,8 @@
#define RS_MIME_MAX_TOKEN_LEN 255
+#define SSH_MAX_BANNER_LEN 256
+
#define HTTP2_DECOMPRESSION_CHUNK_SIZE 4096
#define HTTP2_STATIC_HEADERS_NUMBER 61
diff --git a/rust/src/applayertemplate/template.rs b/rust/src/applayertemplate/template.rs
index acc6c26..dbbc784 100644
--- a/rust/src/applayertemplate/template.rs
+++ b/rust/src/applayertemplate/template.rs
@@ -17,6 +17,7 @@
use super::parser;
use crate::applayer::{self, *};
+use crate::conf::conf_get;
use crate::core::{AppProto, Flow, ALPROTO_UNKNOWN, IPPROTO_TCP};
use nom7 as nom;
use std;
@@ -24,10 +25,14 @@ use std::collections::VecDeque;
use std::ffi::CString;
use std::os::raw::{c_char, c_int, c_void};
+static mut TEMPLATE_MAX_TX: usize = 256;
+
static mut ALPROTO_TEMPLATE: AppProto = ALPROTO_UNKNOWN;
#[derive(AppLayerEvent)]
-enum TemplateEvent {}
+enum TemplateEvent {
+ TooManyTransactions,
+}
pub struct TemplateTransaction {
tx_id: u64,
@@ -145,7 +150,13 @@ impl TemplateState {
SCLogNotice!("Request: {}", request);
let mut tx = self.new_tx();
tx.request = Some(request);
+ if self.transactions.len() >= unsafe {TEMPLATE_MAX_TX} {
+ tx.tx_data.set_event(TemplateEvent::TooManyTransactions as u8);
+ }
self.transactions.push_back(tx);
+ if self.transactions.len() >= unsafe {TEMPLATE_MAX_TX} {
+ return AppLayerResult::err();
+ }
}
Err(nom::Err::Incomplete(_)) => {
// Not enough data. This parser doesn't give us a good indication
@@ -429,6 +440,13 @@ pub unsafe extern "C" fn rs_template_register_parser() {
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let _ = AppLayerRegisterParser(&parser, alproto);
}
+ if let Some(val) = conf_get("app-layer.protocols.template.max-tx") {
+ if let Ok(v) = val.parse::<usize>() {
+ TEMPLATE_MAX_TX = v;
+ } else {
+ SCLogError!("Invalid value for template.max-tx");
+ }
+ }
SCLogNotice!("Rust template parser registered.");
} else {
SCLogNotice!("Protocol detector and parser disabled for TEMPLATE.");
diff --git a/rust/src/dhcp/logger.rs b/rust/src/dhcp/logger.rs
index b29e215..3c86b1b 100644
--- a/rust/src/dhcp/logger.rs
+++ b/rust/src/dhcp/logger.rs
@@ -229,7 +229,7 @@ impl DHCPLogger {
fn log_opt_dns_server(&self, js: &mut JsonBuilder, option: &DHCPOptGeneric) -> Result<(), JsonError> {
js.open_array("dns_servers")?;
for i in 0..(option.data.len() / 4) {
- let val = dns_print_addr(&option.data[(i * 4)..(i * 4) + 4].to_vec());
+ let val = dns_print_addr(&option.data[(i * 4)..(i * 4) + 4]);
js.append_string(&val)?;
}
js.close()?;
@@ -239,7 +239,7 @@ impl DHCPLogger {
fn log_opt_routers(&self, js: &mut JsonBuilder, option: &DHCPOptGeneric) -> Result<(), JsonError> {
js.open_array("routers")?;
for i in 0..(option.data.len() / 4) {
- let val = dns_print_addr(&option.data[(i * 4)..(i * 4) + 4].to_vec());
+ let val = dns_print_addr(&option.data[(i * 4)..(i * 4) + 4]);
js.append_string(&val)?;
}
js.close()?;
diff --git a/rust/src/dns/log.rs b/rust/src/dns/log.rs
index 5212b1a..86325d5 100644
--- a/rust/src/dns/log.rs
+++ b/rust/src/dns/log.rs
@@ -368,7 +368,7 @@ pub fn dns_rcode_string(flags: u16) -> String {
}
/// Format bytes as an IP address string.
-pub fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
+pub fn dns_print_addr(addr: &[u8]) -> std::string::String {
if addr.len() == 4 {
return format!("{}.{}.{}.{}", addr[0], addr[1], addr[2], addr[3]);
} else if addr.len() == 16 {
diff --git a/rust/src/ike/ikev1.rs b/rust/src/ike/ikev1.rs
index 1e79c29..6f598f9 100644
--- a/rust/src/ike/ikev1.rs
+++ b/rust/src/ike/ikev1.rs
@@ -53,7 +53,7 @@ impl Ikev1ParticipantData {
}
pub fn update(
- &mut self, key_exchange: &str, nonce: &str, transforms: &Vec<Vec<SaAttribute>>,
+ &mut self, key_exchange: &str, nonce: &str, transforms: &[Vec<SaAttribute>],
) {
self.key_exchange = key_exchange.to_string();
self.nonce = nonce.to_string();
diff --git a/rust/src/jsonbuilder.rs b/rust/src/jsonbuilder.rs
index 9ff6234..7264be5 100644
--- a/rust/src/jsonbuilder.rs
+++ b/rust/src/jsonbuilder.rs
@@ -527,6 +527,22 @@ impl JsonBuilder {
}
}
+ /// Set a key and a string value (from bytes) on an object, with a limited size
+ pub fn set_string_from_bytes_limited(&mut self, key: &str, val: &[u8], limit: usize) -> Result<&mut Self, JsonError> {
+ let mut valtrunc = Vec::new();
+ let val = if val.len() > limit {
+ valtrunc.extend_from_slice(&val[..limit]);
+ valtrunc.extend_from_slice(b"[truncated]");
+ &valtrunc
+ } else {
+ val
+ };
+ match std::str::from_utf8(val) {
+ Ok(s) => self.set_string(key, s),
+ Err(_) => self.set_string(key, &try_string_from_bytes(val)?),
+ }
+ }
+
/// Set a key and a string field as the base64 encoded string of the value.
pub fn set_base64(&mut self, key: &str, val: &[u8]) -> Result<&mut Self, JsonError> {
match self.current_state() {
diff --git a/rust/src/mqtt/mqtt.rs b/rust/src/mqtt/mqtt.rs
index 3f110df..8260251 100644
--- a/rust/src/mqtt/mqtt.rs
+++ b/rust/src/mqtt/mqtt.rs
@@ -433,8 +433,8 @@ impl MQTTState {
let _pdu = Frame::new(
flow,
&stream_slice,
- input,
- current.len() as i64,
+ current,
+ (current.len() - rem.len()) as i64,
MQTTFrameType::Pdu as u8,
);
SCLogDebug!("request msg {:?}", msg);
@@ -518,8 +518,8 @@ impl MQTTState {
let _pdu = Frame::new(
flow,
&stream_slice,
- input,
- input.len() as i64,
+ current,
+ (current.len() - rem.len()) as i64,
MQTTFrameType::Pdu as u8,
);
diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs
index dfb5e0e..4a1c362 100644
--- a/rust/src/nfs/nfs.rs
+++ b/rust/src/nfs/nfs.rs
@@ -497,7 +497,7 @@ impl NFSState {
}
// TODO maybe not enough users to justify a func
- pub fn mark_response_tx_done(&mut self, xid: u32, rpc_status: u32, nfs_status: u32, resp_handle: &Vec<u8>)
+ pub fn mark_response_tx_done(&mut self, xid: u32, rpc_status: u32, nfs_status: u32, resp_handle: &[u8])
{
if let Some(mytx) = self.get_tx_by_xid(xid) {
mytx.response_done = true;
diff --git a/rust/src/smb/log.rs b/rust/src/smb/log.rs
index 8496574..e242d02 100644
--- a/rust/src/smb/log.rs
+++ b/rust/src/smb/log.rs
@@ -38,7 +38,7 @@ fn debug_add_progress(jsb: &mut JsonBuilder, tx: &SMBTransaction) -> Result<(),
/// take in a file GUID (16 bytes) or FID (2 bytes). Also deal
/// with our frankenFID (2 bytes + 4 user_id)
-fn fuid_to_string(fuid: &Vec<u8>) -> String {
+fn fuid_to_string(fuid: &[u8]) -> String {
let fuid_len = fuid.len();
if fuid_len == 16 {
guid_to_string(fuid)
@@ -52,7 +52,7 @@ fn fuid_to_string(fuid: &Vec<u8>) -> String {
}
}
-fn guid_to_string(guid: &Vec<u8>) -> String {
+fn guid_to_string(guid: &[u8]) -> String {
if guid.len() == 16 {
let output = format!("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
guid[3], guid[2], guid[1], guid[0],
diff --git a/rust/src/ssh/logger.rs b/rust/src/ssh/logger.rs
index 9bc7d7c..e83d288 100644
--- a/rust/src/ssh/logger.rs
+++ b/rust/src/ssh/logger.rs
@@ -15,7 +15,7 @@
* 02110-1301, USA.
*/
-use super::ssh::SSHTransaction;
+use super::ssh::{SSHTransaction, SSH_MAX_BANNER_LEN};
use crate::jsonbuilder::{JsonBuilder, JsonError};
fn log_ssh(tx: &SSHTransaction, js: &mut JsonBuilder) -> Result<bool, JsonError> {
@@ -24,9 +24,9 @@ fn log_ssh(tx: &SSHTransaction, js: &mut JsonBuilder) -> Result<bool, JsonError>
}
if !tx.cli_hdr.protover.is_empty() {
js.open_object("client")?;
- js.set_string_from_bytes("proto_version", &tx.cli_hdr.protover)?;
+ js.set_string_from_bytes_limited("proto_version", &tx.cli_hdr.protover, SSH_MAX_BANNER_LEN)?;
if !tx.cli_hdr.swver.is_empty() {
- js.set_string_from_bytes("software_version", &tx.cli_hdr.swver)?;
+ js.set_string_from_bytes_limited("software_version", &tx.cli_hdr.swver, SSH_MAX_BANNER_LEN)?;
}
if !tx.cli_hdr.hassh.is_empty() || !tx.cli_hdr.hassh_string.is_empty() {
js.open_object("hassh")?;
@@ -42,9 +42,9 @@ fn log_ssh(tx: &SSHTransaction, js: &mut JsonBuilder) -> Result<bool, JsonError>
}
if !tx.srv_hdr.protover.is_empty() {
js.open_object("server")?;
- js.set_string_from_bytes("proto_version", &tx.srv_hdr.protover)?;
+ js.set_string_from_bytes_limited("proto_version", &tx.srv_hdr.protover, SSH_MAX_BANNER_LEN)?;
if !tx.srv_hdr.swver.is_empty() {
- js.set_string_from_bytes("software_version", &tx.srv_hdr.swver)?;
+ js.set_string_from_bytes_limited("software_version", &tx.srv_hdr.swver, SSH_MAX_BANNER_LEN)?;
}
if !tx.srv_hdr.hassh.is_empty() || !tx.srv_hdr.hassh_string.is_empty() {
js.open_object("hassh")?;
diff --git a/rust/src/ssh/ssh.rs b/rust/src/ssh/ssh.rs
index 6280e0b..a058689 100644
--- a/rust/src/ssh/ssh.rs
+++ b/rust/src/ssh/ssh.rs
@@ -46,7 +46,7 @@ pub enum SSHConnectionState {
SshStateFinished = 3,
}
-const SSH_MAX_BANNER_LEN: usize = 256;
+pub const SSH_MAX_BANNER_LEN: usize = 256;
const SSH_RECORD_HEADER_LEN: usize = 6;
const SSH_MAX_REASSEMBLED_RECORD_LEN: usize = 65535;
@@ -256,7 +256,9 @@ impl SSHState {
return r;
}
Err(Err::Incomplete(_)) => {
- return AppLayerResult::incomplete(0_u32, (input.len() + 1) as u32);
+ // we do not need to retain these bytes
+ // we parsed them, we skip them
+ return AppLayerResult::ok();
}
Err(_e) => {
SCLogDebug!("SSH invalid banner {}", _e);