Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/userguide/configuration/suricata-yaml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,7 @@ address, you should enter 'any'.
SHELLCODE_PORTS: "!80"
ORACLE_PORTS: 1521
SSH_PORTS: 22
SIP_PORTS: "[5060, 5061]"

.. _host-os-policy:

Expand Down
15 changes: 12 additions & 3 deletions etc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3800,7 +3800,10 @@
"rfb": {
"$ref": "#/$defs/stats_applayer_error"
},
"sip": {
"sip_udp": {
"$ref": "#/$defs/stats_applayer_error"
},
"sip_tcp": {
"$ref": "#/$defs/stats_applayer_error"
},
"smb": {
Expand Down Expand Up @@ -3917,7 +3920,10 @@
"rfb": {
"type": "integer"
},
"sip": {
"sip_udp": {
"type": "integer"
},
"sip_tcp": {
"type": "integer"
},
"smb": {
Expand Down Expand Up @@ -4028,7 +4034,10 @@
"rfb": {
"type": "integer"
},
"sip": {
"sip_udp": {
"type": "integer"
},
"sip_tcp": {
"type": "integer"
},
"smb": {
Expand Down
29 changes: 7 additions & 22 deletions rust/src/sip/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ use std::ptr;

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_method(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.request {
let m = &r.method;
Expand All @@ -44,9 +42,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_method(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_uri(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.request {
let p = &r.path;
Expand All @@ -65,10 +61,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_uri(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_protocol(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
direction: u8,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32, direction: u8,
) -> u8 {
match direction.into() {
Direction::ToServer => {
Expand Down Expand Up @@ -101,9 +94,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_protocol(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_stat_code(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.response {
let c = &r.code;
Expand All @@ -122,9 +113,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_stat_code(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_stat_msg(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.response {
let re = &r.reason;
Expand All @@ -143,9 +132,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_stat_msg(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_request_line(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.request_line {
if !r.is_empty() {
Expand All @@ -163,9 +150,7 @@ pub unsafe extern "C" fn rs_sip_tx_get_request_line(

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_response_line(
tx: &mut SIPTransaction,
buffer: *mut *const u8,
buffer_len: *mut u32,
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
if let Some(ref r) = tx.response_line {
if !r.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion rust/src/sip/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ fn log(tx: &SIPTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
#[no_mangle]
pub extern "C" fn rs_sip_log_json(tx: &mut SIPTransaction, js: &mut JsonBuilder) -> bool {
log(tx, js).is_ok()
}
}
55 changes: 45 additions & 10 deletions rust/src/sip/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
* 02110-1301, USA.
*/

// written by Giuseppe Longo <giuseppe@glono.it>
// written by Giuseppe Longo <giuseppe@glongo.it>

use nom7::bytes::streaming::{take, take_while, take_while1};
use nom7::bytes::streaming::{take, take_while, take_while1, tag};
use nom7::character::streaming::{char, crlf};
use nom7::character::{is_alphabetic, is_alphanumeric, is_space};
use nom7::character::{is_alphabetic, is_alphanumeric, is_space, is_digit};
use nom7::combinator::map_res;
use nom7::sequence::delimited;
use nom7::{Err, IResult, Needed};
Expand Down Expand Up @@ -57,9 +57,13 @@ pub struct Response {
pub body_len: u16,
}

/**
* Valid tokens and chars are defined in RFC3261:
* https://www.rfc-editor.org/rfc/rfc3261#section-25.1
*/
#[inline]
fn is_token_char(b: u8) -> bool {
is_alphanumeric(b) || b"!%'*+-._`".contains(&b)
is_alphanumeric(b) || b"!%'*+-._`~".contains(&b)
}

#[inline]
Expand All @@ -69,12 +73,12 @@ fn is_method_char(b: u8) -> bool {

#[inline]
fn is_request_uri_char(b: u8) -> bool {
is_alphanumeric(b) || is_token_char(b) || b"~#@:".contains(&b)
is_alphanumeric(b) || is_token_char(b) || b"~#@:;=?+&$,/".contains(&b)
}

#[inline]
fn is_version_char(b: u8) -> bool {
is_alphanumeric(b) || b"./".contains(&b)
is_digit(b) || b".".contains(&b)
}

#[inline]
Expand Down Expand Up @@ -107,7 +111,7 @@ pub fn sip_parse_request(oi: &[u8]) -> IResult<&[u8], Request> {
Request {
method: method.into(),
path: path.into(),
version: version.into(),
version,
headers,

request_line_len: request_line_len as u16,
Expand All @@ -133,7 +137,7 @@ pub fn sip_parse_response(oi: &[u8]) -> IResult<&[u8], Response> {
Ok((
bi,
Response {
version: version.into(),
version,
code: code.into(),
reason: reason.into(),

Expand All @@ -156,8 +160,10 @@ fn parse_request_uri(i: &[u8]) -> IResult<&[u8], &str> {
}

#[inline]
fn parse_version(i: &[u8]) -> IResult<&[u8], &str> {
map_res(take_while1(is_version_char), std::str::from_utf8)(i)
fn parse_version(i: &[u8]) -> IResult<&[u8], String> {
let (i, prefix) = map_res(tag("SIP/"), std::str::from_utf8)(i)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the utf8 here ?

let (i, version) = map_res(take_while1(is_version_char), std::str::from_utf8)(i)?;
Ok((i, format!("{}{}", prefix, version)))
}

#[inline]
Expand Down Expand Up @@ -322,4 +328,33 @@ mod tests {
}
}
}

#[test]
fn test_parse_invalid_version() {
let buf: &[u8] = "HTTP/1.1\r\n".as_bytes();

// This test must fail if 'HTTP/1.1' is accepted
match parse_version(buf) {
Ok((_, _)) => {
assert!(false);
}
Err(_) => {
assert!(true);
}
}
}

#[test]
fn test_parse_valid_version() {
let buf: &[u8] = "SIP/2.0\r\n".as_bytes();

match parse_version(buf) {
Ok((_, version)) => {
assert_eq!(version, "SIP/2.0");
}
Err(_) => {
assert!(false);
}
}
}
}
Loading