release v0.1.0

Signed-off-by: Jia Chao <jiac13@chinaunicom.cn>
This commit is contained in:
Jia Chao 2024-07-24 10:04:20 +08:00
parent 62f8f5c669
commit d667ef7fda
3 changed files with 7736 additions and 4 deletions

View File

@ -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" }

View File

@ -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 &note.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);
}
}
} }
} }

File diff suppressed because one or more lines are too long