release v0.1.0
Signed-off-by: Jia Chao <jiac13@chinaunicom.cn>
This commit is contained in:
parent
62f8f5c669
commit
d667ef7fda
|
@ -4,3 +4,8 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ccutils = { git = "https://git.zhgsun.com:8089/jiachao2130/ccutils.git", version = "0.1.0" }
|
||||||
|
cusa = { git = "https://git.zhgsun.com:8089/jiachao2130/cusa.git", version = "0.1.0" }
|
||||||
|
serde = { version = "1", features = ["serde_derive"] }
|
||||||
|
serde_json = { version = "1.0" }
|
||||||
|
tracing = { version = "0.1" }
|
||||||
|
|
307
src/lib.rs
307
src/lib.rs
|
@ -1,5 +1,299 @@
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
use serde::{Deserialize, Serialize};
|
||||||
left + right
|
pub use cusa::{CUSA, CVE, Severity};
|
||||||
|
|
||||||
|
/// 顶级 CSAT 结构体,包含文档、产品树和漏洞信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct CSAF {
|
||||||
|
pub document: Document,
|
||||||
|
pub product_tree: ProductTree,
|
||||||
|
pub vulnerabilities: Vec<Vulnerability>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CSAF {
|
||||||
|
/// 从给定路径加载 CSAT 文件并解析为 CSAF 结构体
|
||||||
|
pub fn from(path: &str) -> ccutils::Result<Self> {
|
||||||
|
let data = std::fs::read_to_string(path)?;
|
||||||
|
Ok(serde_json::from_str::<Self>(&data)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CSAF {
|
||||||
|
/// 获取 SA 编号
|
||||||
|
pub fn id(&self) -> &str {
|
||||||
|
&self.document.tracking.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 安全公告的标题
|
||||||
|
pub fn title(&self) -> &str {
|
||||||
|
&self.document.title
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 此安全公告的危害级别
|
||||||
|
pub fn severity(&self) -> Severity {
|
||||||
|
let mut severity = Severity::None;
|
||||||
|
|
||||||
|
for v in &self.vulnerabilities {
|
||||||
|
for t in &v.threats {
|
||||||
|
if t.details > severity {
|
||||||
|
severity = t.details.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
severity
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 详细的公告描述信息
|
||||||
|
pub fn description(&self) -> &str {
|
||||||
|
for note in &self.document.notes {
|
||||||
|
if note.title == "Description" {
|
||||||
|
return ¬e.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 安全公告所涉及的所有 CVE 的列表
|
||||||
|
pub fn cves(&self) -> Vec<CVE> {
|
||||||
|
let mut cves = vec![];
|
||||||
|
for v in &self.vulnerabilities {
|
||||||
|
cves.push(CVE {
|
||||||
|
id: v.cve.clone(),
|
||||||
|
url: format!("https://nvd.nist.gov/vuln/detail/{}", v.cve),
|
||||||
|
severity: v.threats[0].details.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cves
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 将之转换成为 `CUSA` 格式
|
||||||
|
pub fn sainfo(&self) -> CUSA {
|
||||||
|
let id = self.id().to_string();
|
||||||
|
let url = format!("https://www.openeuler.org/zh/security/security-bulletins/detail/?id={id}");
|
||||||
|
let title = self.title().to_string();
|
||||||
|
let severity = self.severity();
|
||||||
|
let description = self.description().to_string();
|
||||||
|
let cves = self.cves();
|
||||||
|
|
||||||
|
CUSA { id, url, title, severity, description, cves }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 文档结构体,包含各种文档相关的信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Document {
|
||||||
|
pub aggregate_severity: AggregateSeverity,
|
||||||
|
pub category: String,
|
||||||
|
pub csaf_version: String,
|
||||||
|
pub distribution: Distribution,
|
||||||
|
pub lang: String,
|
||||||
|
pub notes: Vec<Note>,
|
||||||
|
pub publisher: Publisher,
|
||||||
|
pub references: Vec<Reference>,
|
||||||
|
pub title: String,
|
||||||
|
pub tracking: Tracking,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 聚合严重性结构体,包含名称空间和文本信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct AggregateSeverity {
|
||||||
|
namespace: String,
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分发结构体,包含 TLP 信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Distribution {
|
||||||
|
tlp: Tlp,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TLP 结构体,包含标签和 URL
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Tlp {
|
||||||
|
pub label: String,
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 注释结构体,包含文本、类别和标题
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Note {
|
||||||
|
text: String,
|
||||||
|
category: String,
|
||||||
|
title: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 发布者结构体,包含发布者相关信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Publisher {
|
||||||
|
issuing_authority: String,
|
||||||
|
name: String,
|
||||||
|
namespace: String,
|
||||||
|
contact_details: String,
|
||||||
|
category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 参考结构体,包含摘要、类别和 URL
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Reference {
|
||||||
|
summary: String,
|
||||||
|
category: String,
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 跟踪结构体,包含跟踪相关信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Tracking {
|
||||||
|
initial_release_date: String,
|
||||||
|
revision_history: Vec<Revision>,
|
||||||
|
generator: Generator,
|
||||||
|
current_release_date: String,
|
||||||
|
id: String,
|
||||||
|
version: String,
|
||||||
|
status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 修订结构体,包含日期、摘要和编号
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Revision {
|
||||||
|
date: String,
|
||||||
|
summary: String,
|
||||||
|
number: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 生成器结构体,包含日期和引擎信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Generator {
|
||||||
|
pub date: String,
|
||||||
|
pub engine: Engine,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 引擎结构体,包含引擎名称
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Engine {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品树结构体,包含分支和关系
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ProductTree {
|
||||||
|
branches: Vec<ProductTreeBranch>,
|
||||||
|
relationships: Vec<RelationShip>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品树分支结构体,包含名称、类别和子分支
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ProductTreeBranch {
|
||||||
|
pub name: String,
|
||||||
|
pub category: String,
|
||||||
|
pub branches: Vec<Branch>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分支结构体,包含名称和子分支
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Branch {
|
||||||
|
pub name: String,
|
||||||
|
pub branches: Vec<SubBranch>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 子分支结构体,包含名称、类别和产品
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SubBranch {
|
||||||
|
pub name: String,
|
||||||
|
pub category: String,
|
||||||
|
pub product: Product,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品结构体,包含名称、产品 ID 和产品识别帮助信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Product {
|
||||||
|
pub name: String,
|
||||||
|
pub product_id: String,
|
||||||
|
pub product_identification_helper: ProductIdentificationHelper,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品识别帮助结构体,包含 CPE
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ProductIdentificationHelper {
|
||||||
|
pub cpe: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 关系结构体,包含与产品的关系信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct RelationShip {
|
||||||
|
pub relates_to_product_reference: String,
|
||||||
|
pub product_reference: String,
|
||||||
|
pub full_product_name: ProductName,
|
||||||
|
pub category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品名称结构体,包含名称和产品 ID
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ProductName {
|
||||||
|
pub name: String,
|
||||||
|
pub product_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 漏洞结构体,包含漏洞相关信息
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Vulnerability {
|
||||||
|
pub cve: String,
|
||||||
|
pub title: String,
|
||||||
|
pub notes: Vec<Note>,
|
||||||
|
pub product_status: ProductStatus,
|
||||||
|
pub remediations: Vec<Remediation>,
|
||||||
|
pub scores: Vec<Score>,
|
||||||
|
pub threats: Vec<Threat>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 产品状态结构体,包含已修复的产品 ID 列表
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ProductStatus {
|
||||||
|
pub fixed: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 修复结构体,包含产品 ID、详细信息、类别和 URL
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Remediation {
|
||||||
|
pub product_ids: Vec<String>,
|
||||||
|
pub details: String,
|
||||||
|
pub category: String,
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 分数结构体,包含 CVSS 和产品列表
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Score {
|
||||||
|
pub cvss_v3: CVSS,
|
||||||
|
pub products: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// CVSS 结构体,包含基本严重性、基本分数、向量字符串和版本
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct CVSS {
|
||||||
|
pub baseSeverity: BaseSeverity,
|
||||||
|
pub baseScore: f32,
|
||||||
|
pub vectorString: String,
|
||||||
|
pub version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 威胁结构体,包含严重性和类别
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Threat {
|
||||||
|
pub details: Severity,
|
||||||
|
pub category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 严重性枚举,表示不同的严重性级别
|
||||||
|
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub enum BaseSeverity {
|
||||||
|
NONE,
|
||||||
|
LOW,
|
||||||
|
MEDIUM,
|
||||||
|
HIGH,
|
||||||
|
CRITICAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -8,7 +302,12 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_works() {
|
||||||
let result = add(2, 2);
|
match CSAF::from("tests/csaf-openEuler-SA-2024-1836.json") {
|
||||||
assert_eq!(result, 4);
|
Ok(_) => assert!(true),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{:#?}", e);
|
||||||
|
assert!(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7428
tests/csaf-openEuler-SA-2024-1836.json
Normal file
7428
tests/csaf-openEuler-SA-2024-1836.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user