Skip to content
132 changes: 132 additions & 0 deletions doc/userguide/rules/sip-keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ sip.stat_code Response
sip.stat_msg Response
sip.response_line Response
sip.protocol Both
sip.from Both
sip.to Both
sip.via Both
sip.user_agent Both
sip.content_type Both
sip.content_length Both
============================== ==================

sip.method
Expand Down Expand Up @@ -177,3 +183,129 @@ Example
::

sip.protocol; content:"SIP/2.0"

sip.from
--------

This keyword matches on the From field that can be present in SIP headers.
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if there are multiple From headers ?

Should it be a multi buffer ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it should.


Syntax
~~~~~~

::

sip.from; content:<from>

Where <from> is the value of the From header.
Copy link
Contributor

Choose a reason for hiding this comment

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

@jufajardini we should precise this is a sticky buffer, right ?


Example
~~~~~~~

::

sip.from; content:"user"

sip.to
------

This keyword matches on the To field that can be present in SIP headers.

Syntax
~~~~~~

::

sip.to; content:<to>

Where <to> is the value of the To header.

Example
~~~~~~~

::

sip.to; content:"user"

sip.via
--------

This keyword matches on the Via field that can be present in SIP headers.

Syntax
~~~~~~

::

sip.via; content:<via>

Where <via> is the value of the Via header.

Example
~~~~~~~

::

sip.via; content:"SIP/2.0/UDP"

sip.user_agent
--------------

This keyword matches on the User-Agent field that can be present in SIP headers.

Syntax
~~~~~~

::

sip.user_agent; content:<user_agent>

Where <user_agent> is the value of the User-Agent header.

Example
~~~~~~~

::

sip.user_agent; content:"Asterisk"

sip.content_type
----------------

This keyword matches on the Content-Type field that can be present in SIP headers.

Syntax
~~~~~~

::

sip.content_type; content:<content_type>

Where <content_type> is the value of the Content-Type header.

Example
~~~~~~~

::

sip.content_type; content:"application/sdp"

sip.content_length
------------------

This keyword matches on the Content-Length field that can be present in SIP headers.

Syntax
~~~~~~

::

sip.content_length; content:<content_length>

Where <content_length> is the value of the Content-Length header.

Example
~~~~~~~

::

sip.content_length; content:"200"
8 changes: 8 additions & 0 deletions doc/userguide/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ Major changes
- SDP parser and logger have been introduced.
Due to SDP being encapsulated within other protocols, such as SIP, they cannot be directly enabled or disabled.
Instead, both the SDP parser and logger depend on being invoked by another parser (or logger).
- The following sticky buffers for matching SIP headers have been implemented:
- sip.via
- sip.from
- sip.to
- sip.content_type
- sip.content_length

Note: Headers expressed in compact form will still be matched.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the Note line is too much details for this file


Upgrading 6.0 to 7.0
--------------------
Expand Down
53 changes: 52 additions & 1 deletion rust/src/sip/detect.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2019 Open Information Security Foundation
/* Copyright (C) 2024 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
Expand All @@ -19,8 +19,26 @@

use crate::core::Direction;
use crate::sip::sip::SIPTransaction;
use std::ffi::CStr;
use std::ptr;

fn header_compact_name(h: &str) -> Option<String> {
let compact = match h {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you add a comment to the RFC specifying these ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, would not it be simpler the other way, to associate i to Call-Id?

"Call-ID" => "i",
"Contact" => "m",
"Content-Encoding" => "e",
"Content-Length" => "l",
"Content-Type" => "c",
"From" => "f",
"Subject" => "s",
"Supported" => "k",
"To" => "t",
"Via" => "v",
_ => return None,
};
Some(compact.to_string())
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need the allocation ?

}

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_method(
tx: &mut SIPTransaction, buffer: *mut *const u8, buffer_len: *mut u32,
Expand Down Expand Up @@ -165,3 +183,36 @@ pub unsafe extern "C" fn rs_sip_tx_get_response_line(

return 0;
}

#[no_mangle]
pub unsafe extern "C" fn rs_sip_tx_get_header_value(
tx: &mut SIPTransaction, direction: u8, strname: *const std::os::raw::c_char,
buffer: *mut *const u8, buffer_len: *mut u32,
) -> u8 {
let hname: &CStr = CStr::from_ptr(strname);
if let Ok(s) = hname.to_str() {
let s2 = header_compact_name(s);
let headers = match direction.into() {
Direction::ToServer => tx.request.as_ref().map(|r| &r.headers),
Direction::ToClient => tx.response.as_ref().map(|r| &r.headers),
};
if let Some(headers) = headers {
let header_value = headers
.get(s)
.or_else(|| s2.as_ref().and_then(|s2| headers.get(s2)));
Copy link
Contributor

Choose a reason for hiding this comment

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

That means if I have the header in long and short form, I only get the long form, right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, right.


if let Some(value) = header_value {
if !value.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

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

*buffer = value.as_ptr();
*buffer_len = value.len() as u32;
return 1;
}
}
};
}

*buffer = ptr::null();
*buffer_len = 0;

return 0;
}
4 changes: 3 additions & 1 deletion rust/src/sip/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub struct Response {
pub version: String,
pub code: String,
pub reason: String,
pub headers: HashMap<String, String>,

pub response_line_len: u16,
pub headers_len: u16,
Expand Down Expand Up @@ -135,7 +136,7 @@ pub fn sip_parse_response(oi: &[u8]) -> IResult<&[u8], Response> {
let (i, reason) = parse_reason(i)?;
let (hi, _) = crlf(i)?;
let response_line_len = oi.len() - hi.len();
let (phi, _headers) = parse_headers(hi)?;
let (phi, headers) = parse_headers(hi)?;
let headers_len = hi.len() - phi.len();
let (bi, _) = crlf(phi)?;
let body_offset = oi.len() - bi.len();
Expand All @@ -146,6 +147,7 @@ pub fn sip_parse_response(oi: &[u8]) -> IResult<&[u8], Response> {
version,
code: code.into(),
reason: reason.into(),
headers,

response_line_len: response_line_len as u16,
headers_len: headers_len as u16,
Expand Down
15 changes: 15 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,21 @@ noinst_HEADERS = \
detect-rpc.h \
detect-sameip.h \
detect-sid.h \
detect-sip-content-length.h \
detect-sip-content-type.h \
detect-sip-headers.h \
detect-sip-headers-stub.h \
detect-sip-from.h \
detect-sip-method.h \
detect-sip-protocol.h \
detect-sip-request-line.h \
detect-sip-response-line.h \
detect-sip-stat-code.h \
detect-sip-stat-msg.h \
detect-sip-to.h \
detect-sip-ua.h \
detect-sip-uri.h \
detect-sip-via.h \
detect-smb-ntlmssp.h \
detect-smb-share.h \
detect-smb-version.h \
Expand Down Expand Up @@ -891,13 +899,20 @@ libsuricata_c_a_SOURCES = \
detect-rpc.c \
detect-sameip.c \
detect-sid.c \
detect-sip-content-length.c \
detect-sip-content-type.c \
detect-sip-headers.c \
detect-sip-from.c \
detect-sip-method.c \
detect-sip-protocol.c \
detect-sip-request-line.c \
detect-sip-response-line.c \
detect-sip-stat-code.c \
detect-sip-stat-msg.c \
detect-sip-to.c \
detect-sip-ua.c \
detect-sip-uri.c \
detect-sip-via.c \
detect-smb-ntlmssp.c \
detect-smb-share.c \
detect-smb-version.c \
Expand Down
2 changes: 2 additions & 0 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
#include "detect-sip-stat-msg.h"
#include "detect-sip-request-line.h"
#include "detect-sip-response-line.h"
#include "detect-sip-headers.h"
#include "detect-rfb-secresult.h"
#include "detect-rfb-sectype.h"
#include "detect-rfb-name.h"
Expand Down Expand Up @@ -675,6 +676,7 @@ void SigTableSetup(void)
DetectSipStatMsgRegister();
DetectSipRequestLineRegister();
DetectSipResponseLineRegister();
DetectSipHeadersRegister();
DetectRfbSecresultRegister();
DetectRfbSectypeRegister();
DetectRfbNameRegister();
Expand Down
6 changes: 6 additions & 0 deletions src/detect-engine-register.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ enum DetectKeywordId {
DETECT_AL_SIP_STAT_MSG,
DETECT_AL_SIP_REQUEST_LINE,
DETECT_AL_SIP_RESPONSE_LINE,
DETECT_AL_SIP_HEADER_FROM,
DETECT_AL_SIP_HEADER_TO,
DETECT_AL_SIP_HEADER_VIA,
DETECT_AL_SIP_HEADER_UA,
DETECT_AL_SIP_HEADER_CONTENT_TYPE,
DETECT_AL_SIP_HEADER_CONTENT_LENGTH,
DETECT_AL_RFB_SECRESULT,
DETECT_AL_RFB_SECTYPE,
DETECT_AL_RFB_NAME,
Expand Down
41 changes: 41 additions & 0 deletions src/detect-sip-content-length.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Copyright (C) 2024 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 <giuseppe@glongo.it>
*
* Implements the sip.content_length sticky buffer
*/

#define KEYWORD_NAME "sip.content_length"
#define KEYWORD_DOC "sip-keywords.html#sip-content-length"
#define BUFFER_NAME "sip.content_length"
#define BUFFER_DESC "sip content-length header"
#define HEADER_NAME "Content-Length"
#define KEYWORD_ID DETECT_AL_SIP_HEADER_CONTENT_LENGTH
#define KEYWORD_TOSERVER 1
#define KEYWORD_TOCLIENT 1

#include "detect-sip-headers-stub.h"
#include "detect-sip-content-length.h"

void RegisterSipHeadersContentLength(void)
{
DetectSipHeadersRegisterStub();
}
23 changes: 23 additions & 0 deletions src/detect-sip-content-length.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* Copyright (C) 2024 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 __DETECT_SIP_CONTENT_LENGTH_H__
Copy link
Contributor

Choose a reason for hiding this comment

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

Old guard style

#define __DETECT_SIP_CONTENT_LENGTH_H__

void RegisterSipHeadersContentLength(void);

#endif /* __DETECT_SIP_CONTENT_LENGTH_H__ */
Loading