feat(rust): split core library into activate/license/heartbeat modules with build.rs and C ABI tests

This commit is contained in:
2026-04-28 18:46:20 +08:00
parent 6b3f1bdab5
commit 6a92f46447
14 changed files with 769 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
// CraftLabs 授权核心库 — Rust 实现
// 导出 C ABI 接口,与 native/include/craftlabs_auth.h 一致
// 对齐 docs/平台架构思路.md §3.1
use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr;
mod activate;
mod heartbeat;
mod license;
mod security;
pub struct CraftContext {
dummy: i32,
}
#[repr(C)]
pub struct CraftResult {
pub success: i32,
pub message: *const c_char,
}
#[repr(C)]
pub struct LicenseInfo {
pub is_licensed: i32,
pub expiration_date: i64,
pub feature_names: *const *const c_char,
pub feature_values: *const i32,
pub feature_count: i32,
}
unsafe fn c_str_to_string(ptr: *const c_char) -> String {
if ptr.is_null() {
String::new()
} else {
CStr::from_ptr(ptr).to_string_lossy().into_owned()
}
}
static OK_MSG: &[u8] = b"ok\0";
static FAIL_MSG: &[u8] = b"failure\0";
fn ok_result() -> CraftResult {
CraftResult {
success: 1,
message: OK_MSG.as_ptr() as *const c_char,
}
}
fn fail_result() -> CraftResult {
CraftResult {
success: 0,
message: FAIL_MSG.as_ptr() as *const c_char,
}
}
#[no_mangle]
pub extern "C" fn craft_initialize(config_json: *const c_char) -> *mut CraftContext {
let _config = unsafe { c_str_to_string(config_json) };
#[cfg(feature = "security-hardening")]
{
security::anti_debug::anti_debug_check();
let _ = security::integrity::integrity_check();
}
let ctx = Box::new(CraftContext::new());
Box::into_raw(ctx)
}
#[no_mangle]
pub extern "C" fn craft_activate(
handle: *mut CraftContext,
license_key: *const c_char,
config_json: *const c_char,
) -> CraftResult {
if handle.is_null() {
return fail_result();
}
let key = unsafe { c_str_to_string(license_key) };
let config = unsafe { c_str_to_string(config_json) };
activate::core_activate(&key, &config)
}
#[no_mangle]
pub extern "C" fn craft_check_license(handle: *mut CraftContext) -> CraftResult {
if handle.is_null() {
return fail_result();
}
license::check_license(unsafe { &*handle })
}
#[no_mangle]
pub extern "C" fn craft_get_license_info(handle: *mut CraftContext) -> *mut LicenseInfo {
if handle.is_null() {
return ptr::null_mut();
}
license::get_license_info(unsafe { &*handle })
}
#[no_mangle]
pub extern "C" fn craft_free_license_info(info: *mut LicenseInfo) {
if !info.is_null() {
unsafe {
drop(Box::from_raw(info));
}
}
}
#[no_mangle]
pub extern "C" fn craft_has_feature(
handle: *mut CraftContext,
feature_name: *const c_char,
) -> i32 {
if handle.is_null() {
return 0;
}
let name = unsafe { c_str_to_string(feature_name) };
if license::has_feature(unsafe { &*handle }, &name) {
1
} else {
0
}
}
#[no_mangle]
pub extern "C" fn craft_release(handle: *mut CraftContext) -> CraftResult {
if handle.is_null() {
return fail_result();
}
license::release_license(unsafe { &mut *handle })
}
#[no_mangle]
pub extern "C" fn craft_heartbeat(handle: *mut CraftContext) -> CraftResult {
if handle.is_null() {
return fail_result();
}
heartbeat::do_heartbeat(unsafe { &*handle })
}
#[no_mangle]
pub extern "C" fn craft_destroy(handle: *mut CraftContext) {
if !handle.is_null() {
unsafe {
drop(Box::from_raw(handle));
}
}
}