mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 10:00:30 +08:00
build(native): rename lib to craftlabs_auth_core, add crypto deps
feat(rust): extend error codes for selfhosted licensing (crypto/license state variants)
This commit is contained in:
@@ -6,13 +6,20 @@ description = "CraftLabs 授权核心库 — Rust 实现,导出 craft_* C ABI
|
|||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "staticlib"]
|
crate-type = ["cdylib", "staticlib"]
|
||||||
name = "craftlabs_auth_bitanswer"
|
name = "craftlabs_auth_core"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
obfstr = "0.4"
|
obfstr = "0.4"
|
||||||
sha2 = "0.10"
|
sha2 = "0.10"
|
||||||
libloading = "0.8"
|
libloading = "0.8"
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
|
rsa = { version = "0.9", features = ["sha2"] }
|
||||||
|
aes-gcm = "0.10"
|
||||||
|
hkdf = "0.12"
|
||||||
|
base64 = "0.22"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
windows-sys = { version = "0.52", features = ["Win32_System_Diagnostics_Debug"], optional = true }
|
windows-sys = { version = "0.52", features = ["Win32_System_Diagnostics_Debug"], optional = true }
|
||||||
|
|||||||
@@ -1,82 +1,91 @@
|
|||||||
|
// Error codes for selfhosted + BitAnswer licensing
|
||||||
use crate::CraftResult;
|
use crate::CraftResult;
|
||||||
|
|
||||||
/// BitAnswer BIT_STATUS 错误码到结构化错误的精简映射。
|
|
||||||
/// 完整 200+ 码请参考 bitanswer.h,此处映射文档中明确列出的高频码。
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum LicenseError {
|
pub enum LicenseError {
|
||||||
|
// ── 通用 ──
|
||||||
Success,
|
Success,
|
||||||
NetworkError,
|
ConfigMissing(&'static str),
|
||||||
WrongHandle,
|
Network(String),
|
||||||
InvalidParameter,
|
NotInitialized,
|
||||||
ApplicationDataError,
|
|
||||||
LicenseExpired,
|
// ── 签名 / 加密 ──
|
||||||
LicenseNotFound,
|
InvalidFormat(&'static str),
|
||||||
LicenseDisabled,
|
InvalidSignature,
|
||||||
FeatureNotFound(u32),
|
SignatureMismatch,
|
||||||
FeatureExpired(u32),
|
CryptoError,
|
||||||
FeatureTypeNotMatch(u32),
|
DecryptionFailed,
|
||||||
SnInvalid,
|
CorruptedPayload,
|
||||||
SnNotFound,
|
LicenseIdMismatch,
|
||||||
SnDisabled,
|
|
||||||
SnRevoked,
|
// ── 许可状态 ──
|
||||||
SnExpired,
|
NotYetValid,
|
||||||
CapacityExhausted,
|
Expired,
|
||||||
ServerBusy,
|
NoCachedLicense,
|
||||||
ServerDown,
|
OfflineGraceExceeded { days_offline: u32, max_days: u32 },
|
||||||
Timeout,
|
InvalidLicense,
|
||||||
Unknown(u32),
|
LicenseRevoked,
|
||||||
|
DeviceLimitReached,
|
||||||
|
ConcurrentUserLimitReached,
|
||||||
|
ActivationLimitReached,
|
||||||
|
|
||||||
|
// ── 兼容比特 ──
|
||||||
|
BitAnswerStatus(u32),
|
||||||
|
|
||||||
|
// ── 未知 ──
|
||||||
|
UnknownStatus(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LicenseError {
|
impl LicenseError {
|
||||||
/// 将 BitAnswer BIT_STATUS (u32) 映射为 LicenseError
|
/// Map BitAnswer BIT_STATUS (u32) → LicenseError (双线共存保留)
|
||||||
pub fn from_bit_status(status: u32) -> Self {
|
pub fn from_bit_status(status: u32) -> Self {
|
||||||
match status {
|
match status {
|
||||||
0x0000 => LicenseError::Success,
|
0x0000 => LicenseError::Success,
|
||||||
0x0101 => LicenseError::NetworkError,
|
0x0101 => LicenseError::Network("bitanswer network error".into()),
|
||||||
0x0102 => LicenseError::WrongHandle,
|
0x0102 => LicenseError::ConfigMissing("bitanswer wrong handle"),
|
||||||
0x0103 => LicenseError::InvalidParameter,
|
0x0103 => LicenseError::ConfigMissing("bitanswer invalid parameter"),
|
||||||
0x0105 => LicenseError::ApplicationDataError,
|
0x0105 => LicenseError::ConfigMissing("bitanswer application data error"),
|
||||||
0x0701 => LicenseError::LicenseExpired,
|
0x0114 => LicenseError::InvalidLicense,
|
||||||
0x0114 => LicenseError::LicenseNotFound,
|
0x011C => LicenseError::InvalidLicense,
|
||||||
0x0705 => LicenseError::LicenseDisabled,
|
0x0701 => LicenseError::Expired,
|
||||||
0x0503 => LicenseError::FeatureNotFound(0),
|
0x0705 => LicenseError::LicenseRevoked,
|
||||||
0x0509 => LicenseError::FeatureExpired(0),
|
0x0706 => LicenseError::InvalidLicense,
|
||||||
0x0504 => LicenseError::FeatureTypeNotMatch(0),
|
0x0712 => LicenseError::DeviceLimitReached,
|
||||||
0x011C => LicenseError::SnInvalid,
|
0x0123 => LicenseError::LicenseRevoked,
|
||||||
0x0706 => LicenseError::SnNotFound,
|
0x0503 => LicenseError::InvalidLicense,
|
||||||
// 继续保留对相关码的映射
|
0x0504 => LicenseError::InvalidLicense,
|
||||||
0x0123 => LicenseError::SnRevoked,
|
0x0509 => LicenseError::Expired,
|
||||||
0x0107 => LicenseError::ServerBusy,
|
0x0107 => LicenseError::Network("bitanswer server busy".into()),
|
||||||
0x0108 => LicenseError::ServerDown,
|
0x0108 => LicenseError::Network("bitanswer server down".into()),
|
||||||
0x0141 => LicenseError::Timeout,
|
0x0141 => LicenseError::Network("bitanswer timeout".into()),
|
||||||
0x0712 => LicenseError::CapacityExhausted,
|
_ => LicenseError::BitAnswerStatus(status),
|
||||||
_ => LicenseError::Unknown(status),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> &'static str {
|
pub fn message(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
LicenseError::Success => "ok",
|
LicenseError::Success => "ok",
|
||||||
LicenseError::NetworkError => "network error",
|
LicenseError::ConfigMissing(_) => "config missing",
|
||||||
LicenseError::WrongHandle => "wrong handle",
|
LicenseError::Network(_) => "network error",
|
||||||
LicenseError::InvalidParameter => "invalid parameter",
|
LicenseError::NotInitialized => "not initialized",
|
||||||
LicenseError::ApplicationDataError => "application data error",
|
LicenseError::InvalidFormat(_) => "invalid format",
|
||||||
LicenseError::LicenseExpired => "license expired",
|
LicenseError::InvalidSignature => "invalid signature",
|
||||||
LicenseError::LicenseNotFound => "license not found",
|
LicenseError::SignatureMismatch => "signature verification failed",
|
||||||
LicenseError::LicenseDisabled => "license disabled",
|
LicenseError::CryptoError => "crypto error",
|
||||||
LicenseError::FeatureNotFound(_) => "feature not found",
|
LicenseError::DecryptionFailed => "decryption failed",
|
||||||
LicenseError::FeatureExpired(_) => "feature expired",
|
LicenseError::CorruptedPayload => "corrupted payload",
|
||||||
LicenseError::FeatureTypeNotMatch(_) => "feature type not match",
|
LicenseError::LicenseIdMismatch => "license id mismatch",
|
||||||
LicenseError::SnInvalid => "sn invalid",
|
LicenseError::NotYetValid => "license not yet valid",
|
||||||
LicenseError::SnNotFound => "sn not found",
|
LicenseError::Expired => "license expired",
|
||||||
LicenseError::SnDisabled => "sn disabled",
|
LicenseError::NoCachedLicense => "no cached license",
|
||||||
LicenseError::SnRevoked => "sn revoked",
|
LicenseError::OfflineGraceExceeded { .. } => "offline grace period exceeded",
|
||||||
LicenseError::SnExpired => "sn expired",
|
LicenseError::InvalidLicense => "invalid license",
|
||||||
LicenseError::CapacityExhausted => "capacity exhausted",
|
LicenseError::LicenseRevoked => "license revoked",
|
||||||
LicenseError::ServerBusy => "server busy",
|
LicenseError::DeviceLimitReached => "device limit reached",
|
||||||
LicenseError::ServerDown => "server down",
|
LicenseError::ConcurrentUserLimitReached => "concurrent user limit reached",
|
||||||
LicenseError::Timeout => "timeout",
|
LicenseError::ActivationLimitReached => "activation limit reached",
|
||||||
LicenseError::Unknown(_) => "unknown error",
|
LicenseError::BitAnswerStatus(_) => "bitanswer error",
|
||||||
|
LicenseError::UnknownStatus(_) => "unknown error",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,19 +94,14 @@ impl LicenseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 将 LicenseError 转为 C ABI 兼容的 CraftResult
|
/// Convert LicenseError to C ABI CraftResult
|
||||||
pub fn to_craft_result(error: LicenseError) -> CraftResult {
|
pub fn to_craft_result(error: LicenseError) -> CraftResult {
|
||||||
if error.is_success() {
|
if error.is_success() {
|
||||||
// 对于成功场景,返回一个最小的 CraftResult(message 指针为 NULL,调用方通过成功状态判断)
|
|
||||||
CraftResult { success: 1, message: std::ptr::null() }
|
CraftResult { success: 1, message: std::ptr::null() }
|
||||||
} else {
|
} else {
|
||||||
// 使用堆分配的消息指针(调用方通过 craft_free_license_info 类似方式释放)
|
|
||||||
let msg = format!("{}\0", error.message());
|
let msg = format!("{}\0", error.message());
|
||||||
let msg_ptr = msg.as_ptr() as *const std::os::raw::c_char;
|
let msg_ptr = msg.as_ptr() as *const std::os::raw::c_char;
|
||||||
std::mem::forget(msg); // 内存由调用方管理
|
std::mem::forget(msg);
|
||||||
CraftResult {
|
CraftResult { success: 0, message: msg_ptr }
|
||||||
success: 0,
|
|
||||||
message: msg_ptr,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user