Skip to content

Commit

Permalink
Add: proper error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Kraemii committed Nov 9, 2023
1 parent 7f64bd0 commit dcf07bc
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 95 deletions.
2 changes: 1 addition & 1 deletion rust/models/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub struct VulnerablePackage {
pub fixed_version: FixedVersion,
}

#[cfg_attr(feature = "serde_support", derive(serde::Serialize))]
#[cfg_attr(feature = "serde_support", derive(serde::Serialize), serde(untagged))]
#[derive(Debug)]
pub enum FixedVersion {
Single {
Expand Down
87 changes: 87 additions & 0 deletions rust/notus/data/debian_10_advisory_parse_err.notus
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"version": "1.3",
"package_type": "deb",
"advisories": [
{
"oid": "1.3.6.1.4.1.25623.1.1.7.2.2023.10089729899100",
"fixed_packages": [
{
"name": "gitlab-ce",
"range": {
"start": "?",
"end": "="
}
},
{
"name": "gitlab-ce",
"range": {
"start": "16.0.0",
"end": "16.0.7"
}
},
{
"name": "gitlab-ce",
"range": {
"start": "16.1.0",
"end": "16.1.2"
}
}
]
},
{
"oid": "1.3.6.1.4.1.25623.1.1.7.2.2023.0988598199100",
"fixed_packages": [
{
"name": "grafana",
"full_version": "8.5.24",
"specifier": ">="
},
{
"name": "grafana",
"range": {
"start": "9.0.0",
"end": "9.2.17"
}
},
{
"name": "grafana",
"range": {
"start": "9.3.0",
"end": "9.3.13"
}
},
{
"name": "grafana",
"range": {
"start": "9.4.0",
"end": "9.4.9"
}
},
{
"name": "grafana8",
"full_version": "8.5.24",
"specifier": ">="
},
{
"name": "grafana9",
"full_version": "9.2.17",
"specifier": ">="
},
{
"name": "grafana9",
"range": {
"start": "9.3.0",
"end": "9.3.13"
}
},
{
"name": "grafana9",
"range": {
"start": "9.4.0",
"end": "9.4.9"
}
}
]
}
]
}
87 changes: 87 additions & 0 deletions rust/notus/data/debian_10_json_parse_err.notus
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"version": "1.3",
"package_type": "deb",
"advisories": [
{
"oid": "1.3.6.1.4.1.25623.1.1.7.2.2023.10089729899100",
"fixed_packages": [
{
"name": "gitlab-ce",
"range": {
"start": "15.11.0",
"en": "15.11.11"
}
},
{
"name": "gitlab-ce",
"range": {
"start": "16.0.0",
"end": "16.0.7"
}
},
{
"name": "gitlab-ce",
"range": {
"start": "16.1.0",
"end": "16.1.2"
}
}
]
},
{
"oid": "1.3.6.1.4.1.25623.1.1.7.2.2023.0988598199100",
"fixed_packages": [
{
"name": "grafana",
"full_version": "8.5.24",
"specifier": ">="
},
{
"name": "grafana",
"range": {
"start": "9.0.0",
"end": "9.2.17"
}
},
{
"name": "grafana",
"range": {
"start": "9.3.0",
"end": "9.3.13"
}
},
{
"name": "grafana",
"range": {
"start": "9.4.0",
"end": "9.4.9"
}
},
{
"name": "grafana8",
"full_version": "8.5.24",
"specifier": ">="
},
{
"name": "grafana9",
"full_version": "9.2.17",
"specifier": ">="
},
{
"name": "grafana9",
"range": {
"start": "9.3.0",
"end": "9.3.13"
}
},
{
"name": "grafana9",
"range": {
"start": "9.4.0",
"end": "9.4.9"
}
}
]
}
]
}
32 changes: 19 additions & 13 deletions rust/notus/src/advisory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::collections::HashMap;

use models::{FixedPackage, FixedVersion, Specifier};

use crate::packages::{deb::Deb, ebuild::EBuild, rpm::Rpm, slack::Slack, Package};
use crate::{
error::Error,
packages::{deb::Deb, ebuild::EBuild, rpm::Rpm, slack::Slack, Package},
};

pub type Advisories<P> = HashMap<String, Vec<Advisory<P>>>;

Expand All @@ -17,7 +20,7 @@ impl PackageAdvisories {
fn fill_advisory_map<P: Package>(
advisory_map: &mut Advisories<P>,
advisories: Vec<models::Advisory>,
) {
) -> Result<(), Error> {
// Iterate through advisories of parse file
for advisory in advisories {
// Iterate through fixed_packages of single advisories
Expand All @@ -26,7 +29,7 @@ impl PackageAdvisories {
let (pkg_name, adv) = match Advisory::create(advisory.oid.clone(), &fixed_package) {
Some(adv) => adv,
// Notus data on system are wrong!
None => continue, // TODO: Some handling, at least logging
None => return Err(Error::AdvisoryParseError("".to_string(), fixed_package)),
};
// Add advisory to map
match advisory_map.get_mut(&pkg_name) {
Expand All @@ -39,34 +42,37 @@ impl PackageAdvisories {
};
}
}
Ok(())
}
}

impl From<models::Advisories> for PackageAdvisories {
fn from(value: models::Advisories) -> Self {
impl TryFrom<models::Advisories> for PackageAdvisories {
fn try_from(value: models::Advisories) -> Result<Self, Self::Error> {
match value.package_type {
models::PackageType::DEB => {
let mut advisory_map: Advisories<Deb> = HashMap::new();
Self::fill_advisory_map(&mut advisory_map, value.advisories);
Self::Deb(advisory_map)
Self::fill_advisory_map(&mut advisory_map, value.advisories)?;
Ok(Self::Deb(advisory_map))
}
models::PackageType::EBUILD => {
let mut advisory_map: Advisories<EBuild> = HashMap::new();
Self::fill_advisory_map(&mut advisory_map, value.advisories);
Self::EBuild(advisory_map)
Self::fill_advisory_map(&mut advisory_map, value.advisories)?;
Ok(Self::EBuild(advisory_map))
}
models::PackageType::RPM => {
let mut advisory_map: Advisories<Rpm> = HashMap::new();
Self::fill_advisory_map(&mut advisory_map, value.advisories);
Self::Rpm(advisory_map)
Self::fill_advisory_map(&mut advisory_map, value.advisories)?;
Ok(Self::Rpm(advisory_map))
}
models::PackageType::SLACK => {
let mut advisory_map: Advisories<Slack> = HashMap::new();
Self::fill_advisory_map(&mut advisory_map, value.advisories);
Self::Slack(advisory_map)
Self::fill_advisory_map(&mut advisory_map, value.advisories)?;
Ok(Self::Slack(advisory_map))
}
}
}

type Error = Error;
}

pub struct Advisory<P>
Expand Down
44 changes: 31 additions & 13 deletions rust/notus/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
use std::fmt::Display;
use std::{fmt::Display, io};

#[derive(PartialEq, PartialOrd, Debug)]
pub enum NotusError {
InvalidOS,
JSONParseError,
UnsupportedVersion(String),
NoLoader,
use models::FixedPackage;

#[derive(Debug)]
pub enum Error {
// The directory containing the notus advisories does not exist
MissingAdvisoryDir(String),
// The given notus advisory directory is a file
AdvisoryDirIsFile(String),
// There are no corresponding notus files for the given Operating System
UnknownOs(String),
// General error while loading notus advisories
LoadAdvisoryError(String, io::Error),
// Unable to parse notus advisory file due to a JSON error
JSONParseError(String, serde_json::Error),
// The version of the notus advisory file is not supported
UnsupportedVersion(String, String, String),
// Unable to parse a given package
PackageParseError(String),
// Unable to parse a package in the notus advisory file
AdvisoryParseError(String, FixedPackage),
}

impl Display for NotusError {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NotusError::InvalidOS => todo!(),
NotusError::JSONParseError => todo!(),
NotusError::UnsupportedVersion(_) => todo!(),
NotusError::NoLoader => todo!(),
Error::UnknownOs(path) => write!(f, "the File {path} was not found, that is either due to a typo or missing notus advisories for the corresponding OS"),
Error::JSONParseError(path, json_err) => write!(f, "unable to parse Notus file {path}. The corresponding parse error was: {json_err}"),
Error::UnsupportedVersion(path, version1, version2) => write!(f, "the version of the parsed advisory file {path} is {version1}. This version is currently not supported, the version {version2} is required"),
Error::MissingAdvisoryDir(path) => write!(f, "The directory {path}, which should contain the notus advisories does not exist"),
Error::AdvisoryDirIsFile(path) => write!(f, "The given notus advisory directory {path} is a file"),
Error::LoadAdvisoryError(path, err) => write!(f, "Unable to load advisories from {path}: {err}"),
Error::PackageParseError(pkg) => write!(f, "Unable to parse the given package {pkg}"),
Error::AdvisoryParseError(path, pkg) => write!(f, "Unable to parse fixed package information {:?} in the advisories {path}", pkg),
}
}
}
1 change: 1 addition & 0 deletions rust/notus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pub mod loader;
pub mod packages;

pub mod advisory;
pub mod error;
pub mod notus;
Loading

0 comments on commit dcf07bc

Please sign in to comment.