Skip to content

Commit

Permalink
template: move detect keywords to pure rust
Browse files Browse the repository at this point in the history
Ticket: 3195

Also remove unused src/tests/detect-template-buffer.c

Completes commit 4a7567b
to remove references to template-rust
  • Loading branch information
catenacyber authored and victorjulien committed Oct 12, 2024
1 parent 87e6e93 commit 96c8470
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 420 deletions.
111 changes: 111 additions & 0 deletions rust/src/applayertemplate/detect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* 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.
*/

use super::template::{TemplateTransaction, ALPROTO_TEMPLATE};
/* TEMPLATE_START_REMOVE */
use crate::conf::conf_get_node;
/* TEMPLATE_END_REMOVE */
use crate::core::Direction;
use crate::detect::{
DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperGetData,
DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt,
SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT,
};
use std::os::raw::{c_int, c_void};

static mut G_TEMPLATE_BUFFER_BUFFER_ID: c_int = 0;

unsafe extern "C" fn template_buffer_setup(
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char,
) -> c_int {
if DetectSignatureSetAppProto(s, ALPROTO_TEMPLATE) != 0 {
return -1;
}
if DetectBufferSetActiveList(de, s, G_TEMPLATE_BUFFER_BUFFER_ID) < 0 {
return -1;
}
return 0;
}

/// Get the request/response buffer for a transaction from C.
unsafe extern "C" fn template_buffer_get_data(
tx: *const c_void, flags: u8, buf: *mut *const u8, len: *mut u32,
) -> bool {
let tx = cast_pointer!(tx, TemplateTransaction);
if flags & Direction::ToClient as u8 != 0 {
if let Some(ref response) = tx.response {
if !response.is_empty() {
*len = response.len() as u32;
*buf = response.as_ptr();
return true;
}
}
} else if let Some(ref request) = tx.request {
if !request.is_empty() {
*len = request.len() as u32;
*buf = request.as_ptr();
return true;
}
}
return false;
}

unsafe extern "C" fn template_buffer_get(
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8,
tx: *const c_void, list_id: c_int,
) -> *mut c_void {
return DetectHelperGetData(
de,
transforms,
flow,
flow_flags,
tx,
list_id,
template_buffer_get_data,
);
}

#[no_mangle]
pub unsafe extern "C" fn ScDetectTemplateRegister() {
/* TEMPLATE_START_REMOVE */
if conf_get_node("app-layer.protocols.template").is_none() {
return;
}
/* TEMPLATE_END_REMOVE */
// TODO create a suricata-verify test
// Setup a keyword structure and register it
let kw = SCSigTableElmt {
name: b"template.buffer\0".as_ptr() as *const libc::c_char,
desc: b"Template content modifier to match on the template buffer\0".as_ptr()
as *const libc::c_char,
// TODO use the right anchor for url and write doc
url: b"/rules/template-keywords.html#buffer\0".as_ptr() as *const libc::c_char,
Setup: template_buffer_setup,
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER,
AppLayerTxMatch: None,
Free: None,
};
let _g_template_buffer_kw_id = DetectHelperKeywordRegister(&kw);
G_TEMPLATE_BUFFER_BUFFER_ID = DetectHelperBufferMpmRegister(
b"template.buffer\0".as_ptr() as *const libc::c_char,
b"template.buffer intern description\0".as_ptr() as *const libc::c_char,
ALPROTO_TEMPLATE,
true, //toclient
true, //toserver
template_buffer_get,
);
}
1 change: 1 addition & 0 deletions rust/src/applayertemplate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ mod parser;
pub mod template;
/* TEMPLATE_START_REMOVE */
pub mod logger;
pub mod detect;
/* TEMPLATE_END_REMOVE */
37 changes: 1 addition & 36 deletions rust/src/applayertemplate/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::os::raw::{c_char, c_int, c_void};

static mut TEMPLATE_MAX_TX: usize = 256;

static mut ALPROTO_TEMPLATE: AppProto = ALPROTO_UNKNOWN;
pub(super) static mut ALPROTO_TEMPLATE: AppProto = ALPROTO_UNKNOWN;

#[derive(AppLayerEvent)]
enum TemplateEvent {
Expand Down Expand Up @@ -347,41 +347,6 @@ unsafe extern "C" fn rs_template_tx_get_alstate_progress(tx: *mut c_void, _direc
return 0;
}

/// Get the request buffer for a transaction from C.
///
/// No required for parsing, but an example function for retrieving a
/// pointer to the request buffer from C for detection.
#[no_mangle]
pub unsafe extern "C" fn rs_template_get_request_buffer(
tx: *mut c_void, buf: *mut *const u8, len: *mut u32,
) -> u8 {
let tx = cast_pointer!(tx, TemplateTransaction);
if let Some(ref request) = tx.request {
if !request.is_empty() {
*len = request.len() as u32;
*buf = request.as_ptr();
return 1;
}
}
return 0;
}

/// Get the response buffer for a transaction from C.
#[no_mangle]
pub unsafe extern "C" fn rs_template_get_response_buffer(
tx: *mut c_void, buf: *mut *const u8, len: *mut u32,
) -> u8 {
let tx = cast_pointer!(tx, TemplateTransaction);
if let Some(ref response) = tx.response {
if !response.is_empty() {
*len = response.len() as u32;
*buf = response.as_ptr();
return 1;
}
}
return 0;
}

export_tx_data_get!(rs_template_get_tx_data, TemplateTransaction);
export_state_data_get!(rs_template_get_state_data, TemplateState);

Expand Down
70 changes: 17 additions & 53 deletions scripts/setup-app-layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ def patch_rust_lib_rs(protoname):
output.write(line)
open(filename, "w").write(output.getvalue())

def patch_rust_applayer_mod_rs(protoname):
# arg is the name of the new module to add
def patch_rust_applayer_mod_rs(protoname, arg):
lower = protoname.lower()
filename = "rust/src/applayer%s/mod.rs" % (lower)
print("Patching %s." % (filename))
Expand All @@ -110,7 +111,7 @@ def patch_rust_applayer_mod_rs(protoname):
with open(filename) as infile:
for line in infile:
if not done and line.find("mod parser") > -1:
output.write("pub mod logger;\n")
output.write("pub mod %s;\n" % arg)
done = True
output.write(line)
open(filename, "w").write(output.getvalue())
Expand Down Expand Up @@ -234,68 +235,32 @@ def detect_copy_templates(proto, buffername):
buffername_lower = buffername.lower()

pairs = (
("src/detect-template-rust-buffer.h",
"src/detect-%s-%s.h" % (lower, buffername_lower)),
("src/detect-template-rust-buffer.c",
"src/detect-%s-%s.c" % (lower, buffername_lower)),
("rust/src/applayertemplate/detect.rs",
"rust/src/applayer%s/detect.rs" % (lower)),
)
replacements = (
("TEMPLATE_RUST_BUFFER", "%s_%s" % (
("TEMPLATE_BUFFER", "%s_%s" % (
proto.upper(), buffername.upper())),
("template-rust-buffer", "%s-%s" % (
("template.buffer", "%s.%s" % (
proto.lower(), buffername.lower())),
("template_rust_buffer", "%s_%s" % (
("template_buffer", "%s_%s" % (
proto.lower(), buffername.lower())),
("TemplateRustBuffer", "%s%s" % (proto, buffername)),
)

common_copy_templates(proto, pairs, replacements)

def detect_patch_makefile_am(protoname, buffername):
filename = "src/Makefile.am"
print("Patching %s." % (filename))
output = io.StringIO()
with open(filename) as infile:
for line in infile:
if line.lstrip().startswith("detect-template-buffer."):
new = line.replace("template-buffer", "%s-%s" % (
protoname.lower(), buffername.lower()))
output.write(new)
output.write(line)
open(filename, "w").write(output.getvalue())

def detect_patch_detect_engine_register_c(protoname, buffername):
def detect_patch_detect_engine_register_c(protoname):
filename = "src/detect-engine-register.c"
print("Patching %s." % (filename))
output = io.StringIO()
with open(filename) as infile:
for line in infile:

if line.find("detect-template-buffer.h") > -1:
new = line.replace("template-buffer", "%s-%s" % (
protoname.lower(), buffername.lower()))
output.write(new)

if line.find("DetectTemplateBufferRegister") > -1:
new = line.replace("TemplateBuffer", "%s%s" % (
protoname, buffername))
output.write(new)

output.write(line)
open(filename, "w").write(output.getvalue())

def detect_patch_detect_engine_register_h(protoname, buffername):
filename = "src/detect-engine-register.h"
print("Patching %s." % (filename))
output = io.StringIO()
with open(filename) as infile:
for line in infile:

if line.find("DETECT_AL_TEMPLATE_BUFFER") > -1:
new = line.replace("TEMPLATE_BUFFER", "%s_%s" % (
protoname.upper(), buffername.upper()))
if line.find("ScDetect%sRegister" % protoname) > -1:
# patch already applied
return
if line.find("ScDetectTemplateRegister") > -1:
new = line.replace("Template", "%s" % protoname)
output.write(new)

output.write(line)
open(filename, "w").write(output.getvalue())

Expand Down Expand Up @@ -388,17 +353,16 @@ def main():
if not proto_exists(proto):
raise SetupError("no app-layer parser exists for %s" % (proto))
logger_copy_templates(proto)
patch_rust_applayer_mod_rs(proto)
patch_rust_applayer_mod_rs(proto, "logger")
logger_patch_output_c(proto)
logger_patch_suricata_yaml_in(proto)

if detect:
if not proto_exists(proto):
raise SetupError("no app-layer parser exists for %s" % (proto))
detect_copy_templates(proto, args.buffer)
detect_patch_makefile_am(proto, args.buffer)
detect_patch_detect_engine_register_c(proto, args.buffer)
detect_patch_detect_engine_register_h(proto, args.buffer)
detect_patch_detect_engine_register_c(proto)
patch_rust_applayer_mod_rs(proto, "detect")

if parser:
print("""
Expand Down
3 changes: 0 additions & 3 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ noinst_HEADERS = \
detect-tcp-window.h \
detect-template2.h \
detect-template.h \
detect-template-rust-buffer.h \
detect-threshold.h \
detect-tls-alpn.h \
detect-tls-cert-fingerprint.h \
Expand Down Expand Up @@ -857,7 +856,6 @@ libsuricata_c_a_SOURCES = \
detect-tcp-window.c \
detect-template2.c \
detect-template.c \
detect-template-rust-buffer.c \
detect-threshold.c \
detect-tls.c \
detect-tls-alpn.c \
Expand Down Expand Up @@ -1176,7 +1174,6 @@ EXTRA_DIST = \
tests/detect-http-user-agent.c \
tests/detect-ssl-state.c \
tests/detect-ssl-version.c \
tests/detect-template-buffer.c \
tests/detect-tls-cert-fingerprint.c \
tests/detect-tls-cert-issuer.c \
tests/detect-tls-cert-serial.c \
Expand Down
3 changes: 1 addition & 2 deletions src/detect-engine-register.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@
#include "detect-sip-method.h"
#include "detect-sip-uri.h"
#include "detect-target.h"
#include "detect-template-rust-buffer.h"
#include "detect-quic-sni.h"
#include "detect-quic-ua.h"
#include "detect-quic-version.h"
Expand Down Expand Up @@ -660,7 +659,6 @@ void SigTableSetup(void)
DetectSipMethodRegister();
DetectSipUriRegister();
DetectTargetRegister();
DetectTemplateRustBufferRegister();
DetectQuicSniRegister();
DetectQuicUaRegister();
DetectQuicVersionRegister();
Expand Down Expand Up @@ -695,6 +693,7 @@ void SigTableSetup(void)
ScDetectMqttRegister();
ScDetectRfbRegister();
ScDetectSipRegister();
ScDetectTemplateRegister();

/* close keyword registration */
DetectBufferTypeCloseRegistration();
Expand Down
1 change: 0 additions & 1 deletion src/detect-engine-register.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ enum DetectKeywordId {
DETECT_TCPMSS,
DETECT_FTPDATA,
DETECT_TARGET,
DETECT_AL_TEMPLATE_BUFFER,
DETECT_AL_QUIC_VERSION,
DETECT_AL_QUIC_SNI,
DETECT_AL_QUIC_UA,
Expand Down
Loading

0 comments on commit 96c8470

Please sign in to comment.