use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::sync::Mutex;
use sdkt_audit::plugin_abi::{
abi_version_pack, SdktAuditFindingC, SdktAuditReportC, MAX_FINDINGS, SEVERITY_INFO,
};
use sdkt_audit::{AuditReport, AuditRule};
use crate::ExampleRule;
static SOURCE: Mutex<Option<String>> = Mutex::new(None);
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_abi_version() -> u32 {
abi_version_pack()
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_id() -> *const c_char {
static ID: &[u8] = b"EXAMPLE-001\0";
ID.as_ptr() as *const c_char
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_severity() -> u32 {
SEVERITY_INFO
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_description() -> *const c_char {
static DESC: &[u8] = b"Example rule: detects functions named sdkt_example_trigger\0";
DESC.as_ptr() as *const c_char
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_init(src: *const c_char) -> i32 {
if src.is_null() {
return 1;
}
match CStr::from_ptr(src).to_str() {
Ok(s) => {
if let Ok(mut lock) = SOURCE.lock() {
*lock = Some(s.to_string());
0
} else {
1
}
}
Err(_) => 1,
}
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_check(report: *mut SdktAuditReportC) -> i32 {
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
if report.is_null() {
return 1;
}
let src = {
let lock = match SOURCE.lock() {
Ok(l) => l,
Err(_) => return 2, };
match &*lock {
Some(s) => s.clone(),
None => return 2,
}
};
let scans = match sdkt_audit::scan_all_functions_str(&src) {
Some(s) => s,
None => return 3,
};
let ctx = sdkt_audit::AuditContext { spec: None };
let mut local = AuditReport::default();
ExampleRule.check(&scans, &ctx, &mut local);
let out = unsafe { &mut *report };
out.count = 0;
for f in local.findings {
if out.count >= MAX_FINDINGS {
break;
}
let rule_id = match CString::new(f.rule_id) {
Ok(c) => c,
Err(_) => continue,
};
let message = match CString::new(f.message) {
Ok(c) => c,
Err(_) => continue,
};
let location = f
.location
.as_ref()
.and_then(|l| CString::new(l.clone()).ok());
let slot: &mut SdktAuditFindingC = &mut out.findings[out.count];
slot.rule_id = rule_id.into_raw() as *const c_char;
slot.severity = match f.severity {
sdkt_audit::Severity::Critical => 0,
sdkt_audit::Severity::Info => 2,
sdkt_audit::Severity::Warning => 1,
};
slot.message = message.into_raw() as *const c_char;
slot.location = location
.map(|c| c.into_raw() as *const c_char)
.unwrap_or(std::ptr::null());
out.count += 1;
}
0
}));
res.unwrap_or(4)
}
#[no_mangle]
pub unsafe extern "C" fn sdkt_plugin_free() {}