|
|
|
|
@ -16,7 +16,8 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
use std;
|
|
|
|
|
use std::ffi::CString;
|
|
|
|
|
use std::ptr;
|
|
|
|
|
use std::ffi::{CStr, CString};
|
|
|
|
|
use std::os::raw::{c_char, c_int, c_void};
|
|
|
|
|
|
|
|
|
|
use crate::conf::{conf_get, get_memval};
|
|
|
|
|
@ -24,6 +25,11 @@ use crate::core::*;
|
|
|
|
|
use crate::ftp::constant::*;
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct DetectFtpModeData {
|
|
|
|
|
pub active: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// cbindgen:ignore
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct FtpCommand {
|
|
|
|
|
@ -218,6 +224,36 @@ pub unsafe extern "C" fn SCFTPGetConfigValues(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub unsafe extern "C" fn SCFTPParseMode(c_str: *const c_char) -> *mut DetectFtpModeData {
|
|
|
|
|
if c_str.is_null() {
|
|
|
|
|
return ptr::null_mut();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert C string to Rust string slice
|
|
|
|
|
let Ok(input_str) = CStr::from_ptr(c_str).to_str() else {
|
|
|
|
|
return ptr::null_mut();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Check for case-insensitive match
|
|
|
|
|
let is_active = match input_str.trim().to_ascii_lowercase().as_str() {
|
|
|
|
|
"active" => true,
|
|
|
|
|
"passive" => false,
|
|
|
|
|
_ => return ptr::null_mut(), // invalid input
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Return a pointer to a heap-allocated struct
|
|
|
|
|
let boxed = Box::new(DetectFtpModeData { active: is_active });
|
|
|
|
|
Box::into_raw(boxed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub unsafe extern "C" fn SCFTPFreeModeData(ptr: *mut DetectFtpModeData) {
|
|
|
|
|
if !ptr.is_null() {
|
|
|
|
|
drop(Box::from_raw(ptr));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns *mut FtpTransferCmd
|
|
|
|
|
#[no_mangle]
|
|
|
|
|
pub unsafe extern "C" fn SCFTPTransferCmdNew() -> *mut FtpTransferCmd {
|
|
|
|
|
|