Skip to content

Commit

Permalink
suricata-eve-sqlite-output: cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
aiooss-anssi committed Nov 11, 2024
1 parent cfaed57 commit c2f276d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 179 deletions.
49 changes: 29 additions & 20 deletions suricata/suricata-eve-sqlite-output/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions suricata/suricata-eve-sqlite-output/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ name = "eve_sqlite_output"

[dependencies]
env_logger = { version = "0.11.5", default-features = false }
lazy_static = "1.4.0"
lazy_static = "1.5.0"
log = "0.4.22"
regex = "1.10.6"
regex = "1.11"
rusqlite = { version = "0.32.1", features = ["bundled"] }
1 change: 1 addition & 0 deletions suricata/suricata-eve-sqlite-output/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ impl Database {

/// Database thread entry
pub fn run(&mut self) {
log::debug!("Database thread started");
if let Err(err) = self.batch_write_events() {
log::error!("Failed to write batch of events: {err:?}");
}
Expand Down
124 changes: 15 additions & 109 deletions suricata/suricata-eve-sqlite-output/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,125 +1,31 @@
// Copyright (c) 2021 Open Information Security Foundation
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Copyright (C) 2024 ANSSI
// SPDX-License-Identifier: GPL-2.0-or-later

/// Helper module for this plugin to provide better interfaces to the C API.
/// This will become part of the Suricata dependency crate at some point.
use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_int, c_void};

// Rust representation of a C plugin.
/// Rust representation of a C plugin.
#[repr(C)]
#[allow(non_snake_case)]
pub struct SCPlugin {
name: *const c_char,
license: *const c_char,
author: *const c_char,
init: unsafe extern "C" fn(),
}

impl SCPlugin {
pub fn new(
name: &str,
license: &str,
author: &str,
init_fn: unsafe extern "C" fn(),
) -> *const Self {
let name = CString::new(name).unwrap();
let license = CString::new(license).unwrap();
let author = CString::new(author).unwrap();
let plugin = SCPlugin {
name: name.into_raw(),
license: license.into_raw(),
author: author.into_raw(),
init: init_fn,
};
Box::into_raw(Box::new(plugin))
}
pub name: *const c_char,
pub license: *const c_char,
pub author: *const c_char,
pub Init: extern "C" fn(),
}

pub type InitFn =
unsafe extern "C" fn(conf: *const c_void, threaded: bool, init_data: *mut *mut c_void) -> c_int;
pub type DeinitFn = unsafe extern "C" fn(init_data: *const c_void);
pub type WriteFn = unsafe extern "C" fn(
buffer: *const c_char,
buffer_len: c_int,
init_data: *const c_void,
thread_data: *const c_void,
) -> c_int;
pub type ThreadInitFn = unsafe extern "C" fn(
init_data: *const c_void,
thread_id: std::os::raw::c_int,
thread_data: *mut *mut c_void,
) -> c_int;
pub type ThreadDeinitFn = unsafe extern "C" fn(init_data: *const c_void, thread_data: *mut c_void);

/// Rust representation of a Eve FileType
#[repr(C)]
#[allow(non_snake_case)]
pub struct SCEveFileType {
pub name: *const c_char,
pub open: InitFn,
pub write: WriteFn,
pub close: DeinitFn,
pub thread_init: ThreadInitFn,
pub thread_deinit: ThreadDeinitFn,
pad: [usize; 2],
}

impl SCEveFileType {
pub fn new(
name: &str,
open: InitFn,
close: DeinitFn,
write: WriteFn,
thread_init: ThreadInitFn,
thread_deinit: ThreadDeinitFn,
) -> *const Self {
// Convert the name to C and forget.
let name = CString::new(name).unwrap().into_raw();
let file_type = SCEveFileType {
name,
open,
close,
write,
thread_init,
thread_deinit,
pad: [0, 0],
};
Box::into_raw(Box::new(file_type))
}
pub Init: extern "C" fn(*const c_void, bool, *mut *mut c_void) -> c_int,
pub Write: extern "C" fn(*const c_char, c_int, *const c_void, *const c_void) -> c_int,
pub Deinit: extern "C" fn(*const c_void),
pub ThreadInit: extern "C" fn(*const c_void, std::os::raw::c_int, *mut *mut c_void) -> c_int,
pub ThreadDeinit: extern "C" fn(*const c_void, thread_data: *mut c_void),
pub pad: [usize; 2], // Suricata internal list management pointers.
}

extern "C" {
pub fn SCRegisterEveFileType(filetype: *const SCEveFileType) -> bool;
}

// Convert a C string with a provided length to a Rust &str.
//
// This is an alternative to CStr::from_ptr when the length is already known to avoid the
// scan of the string to find the length (strlen).
pub fn str_from_c_parts<'a>(buffer: *const c_char, buffer_len: c_int) -> &'a CStr {
unsafe {
CStr::from_bytes_with_nul_unchecked(std::slice::from_raw_parts(
buffer as *const u8,
buffer_len as usize + 1,
))
}
}
Loading

0 comments on commit c2f276d

Please sign in to comment.