113 lines
2.8 KiB
Rust
113 lines
2.8 KiB
Rust
use std::collections::HashMap;
|
||
|
||
use cvrf_xmlparser::{SaInfo, CVE};
|
||
use serde::{Deserialize, Serialize};
|
||
use updateinfo_xmlparser::{UpdateInfoDb, RpmInfo};
|
||
|
||
// PackageDb 从 updateinfo 中获取
|
||
// 以包名为键,值为一个 Vector ,里面包含更新的不同版本的 rpm 包信息
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct PackgeDb {
|
||
db: HashMap<String, Vec<RpmInfo>>,
|
||
}
|
||
|
||
impl PackgeDb {
|
||
pub fn new() -> Self {
|
||
PackgeDb {
|
||
db: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 从已有的 updateinfo 仓库文件中,获取所有与安全更新相关的软件包
|
||
pub fn load_from_updateinfodb(&mut self, updateinfodb: &UpdateInfoDb) {
|
||
for updateinfo in &updateinfodb.db {
|
||
for pkg in &updateinfo.pkglist {
|
||
if let Some(rpms) = self.db.get_mut(pkg.name()) {
|
||
rpms.push(pkg.clone());
|
||
} else {
|
||
let rpms = vec![pkg.clone()];
|
||
self.db.insert(pkg.name().to_string(), rpms);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
pub fn db(&self) -> &HashMap<String, Vec<RpmInfo>> {
|
||
&self.db
|
||
}
|
||
}
|
||
|
||
// SaDb 为精简版的安全公告集
|
||
// 一般从安全公告相关的 xml 文件解析、转换而来
|
||
// 目前支持 cvrf 格式
|
||
// 其键为 SA id,值为详情
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct SaDb {
|
||
db: HashMap<String, SaInfo>,
|
||
}
|
||
|
||
impl SaDb {
|
||
pub fn new() -> Self {
|
||
SaDb {
|
||
db: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 一般来自对 cvrf 文件解析并转换为 SaInfo 的文本数据文件
|
||
pub fn load_from_file(&mut self, file: &str) -> crate::Result<()> {
|
||
let data = std::fs::read_to_string(file)?;
|
||
self.db = toml::from_str(&data)?;
|
||
Ok(())
|
||
}
|
||
|
||
/// 从 SaInfo 中提取出所有的 CVE 源
|
||
pub fn get_cvedb(&self) -> CveDb {
|
||
let mut cvedb = CveDb::new();
|
||
|
||
self.db.iter().for_each(|(_, sainfo)| {
|
||
sainfo.cves.iter().for_each(|cve| {
|
||
cvedb.db.insert(cve.id.clone(), cve.clone());
|
||
})
|
||
});
|
||
|
||
cvedb
|
||
}
|
||
}
|
||
|
||
// CveDb 中的 CVE,以 cve_id -> cve_info 形式存储
|
||
// 目前的来源为 cvrf 文件,SaDb
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct CveDb {
|
||
db: HashMap<String, CVE>,
|
||
}
|
||
|
||
impl CveDb {
|
||
#[allow(dead_code)]
|
||
pub fn new() -> Self {
|
||
CveDb {
|
||
db: HashMap::new(),
|
||
}
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod test {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn pkgdb_works() {
|
||
assert!(true);
|
||
|
||
let updatexml = "test/updateinfo.xml";
|
||
let mut updatedb = UpdateInfoDb::new();
|
||
updatedb.load_xml(&updatexml).unwrap();
|
||
|
||
let mut pkgdb = PackgeDb::new();
|
||
pkgdb.load_from_updateinfodb(&updatedb);
|
||
|
||
let bash_pkgs = pkgdb.db.get("bash").unwrap();
|
||
|
||
assert_eq!(bash_pkgs.len(), 2);
|
||
}
|
||
}
|