This repository has been archived by the owner on Aug 6, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from rye/dump
Implement Dump parsing (first pass)
- Loading branch information
Showing
11 changed files
with
259 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
use std::collections::HashSet; | ||
|
||
mod detection; | ||
mod host; | ||
mod plugin; | ||
mod record; | ||
|
||
use detection::*; | ||
use host::*; | ||
use plugin::*; | ||
use record::*; | ||
|
||
#[derive(Debug, Clone)] | ||
#[allow(dead_code)] | ||
pub struct Dump { | ||
pub filename: String, | ||
pub detections: Vec<Detection>, | ||
} | ||
|
||
impl Dump { | ||
pub fn read<R: std::io::Read>(rdr: R) -> Dump { | ||
let mut reader = csv::Reader::from_reader(rdr); | ||
|
||
let mut plugins: HashSet<Plugin> = HashSet::new(); | ||
let mut hosts: HashSet<Host> = HashSet::new(); | ||
let mut detections: HashSet<Detection> = HashSet::new(); | ||
|
||
// TODO refactor for efficiency and conciseness | ||
reader | ||
.deserialize() | ||
.filter_map(|result| -> Option<Record> { result.ok() }) | ||
.for_each(|record| { | ||
let record_plugin = Plugin { | ||
id: record.plugin_id, | ||
cve: vec![record.cve], | ||
cvss: record.cvss, | ||
risk: record.risk, | ||
name: record.name, | ||
synopsis: record.synopsis, | ||
description: record.description, | ||
solution: record.solution, | ||
see_also: record.see_also, | ||
}; | ||
|
||
let record_host = Host { | ||
hostname: record.host.clone(), | ||
addr: record.host.parse().unwrap(), | ||
}; | ||
|
||
if let Some(plugin) = plugins.get(&record_plugin) { | ||
if !plugin.cve.contains(record_plugin.cve.first().unwrap()) { | ||
plugins.replace(Plugin { | ||
cve: [plugin.cve.as_slice(), record_plugin.cve.as_slice()].concat(), | ||
..(plugin.clone()) | ||
}); | ||
} | ||
} else { | ||
assert_eq!(plugins.insert(record_plugin.clone()), true); | ||
} | ||
|
||
let host = hosts.get(&record_host); | ||
|
||
if host.is_none() { | ||
assert_eq!(hosts.insert(record_host.clone()), true); | ||
} | ||
|
||
let plugin: Plugin = plugins.get(&record_plugin).unwrap().clone(); | ||
let host: Host = hosts.get(&record_host).unwrap().clone(); | ||
|
||
let record_detection = Detection { | ||
host, | ||
plugin, | ||
plugin_output: record.plugin_output, | ||
port: record.port, | ||
protocol: record.protocol, | ||
}; | ||
|
||
detections.insert(record_detection); | ||
}); | ||
|
||
Dump { | ||
filename: "test".to_string(), | ||
detections: detections.iter().cloned().collect(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use super::host::*; | ||
use super::plugin::*; | ||
|
||
#[derive(Clone, Debug, Hash, Eq, PartialEq)] | ||
pub struct Detection { | ||
pub host: Host, | ||
pub port: u32, | ||
pub protocol: String, | ||
pub plugin: Plugin, | ||
pub plugin_output: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
use std::net::IpAddr; | ||
|
||
#[derive(Clone, Debug, Hash, Eq, PartialEq)] | ||
pub struct Host { | ||
pub hostname: String, | ||
pub addr: IpAddr, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use std::collections::hash_map::DefaultHasher; | ||
use std::hash::{Hash, Hasher}; | ||
|
||
#[derive(Clone, Debug, Eq)] | ||
pub struct Plugin { | ||
pub id: i32, | ||
pub cve: Vec<String>, | ||
pub cvss: String, | ||
pub risk: String, | ||
pub name: String, | ||
pub synopsis: String, | ||
pub description: String, | ||
pub solution: String, | ||
pub see_also: String, | ||
} | ||
|
||
impl PartialEq for Plugin { | ||
fn eq(&self, other: &Plugin) -> bool { | ||
let mut s = DefaultHasher::new(); | ||
let mut o = DefaultHasher::new(); | ||
self.hash(&mut s); | ||
other.hash(&mut o); | ||
s.finish() == o.finish() | ||
} | ||
} | ||
|
||
impl Hash for Plugin { | ||
fn hash<H: Hasher>(&self, state: &mut H) { | ||
self.id.hash(state); | ||
self.cvss.hash(state); | ||
self.risk.hash(state); | ||
self.name.hash(state); | ||
self.synopsis.hash(state); | ||
self.description.hash(state); | ||
self.solution.hash(state); | ||
self.see_also.hash(state); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// {Host, Protocol, Port} => Host | ||
// {Plugin ID, CVE, CVSS, Name, Synopsis, Description, Solution, See Also} => Plugin | ||
// {Plugin Output} => Detection (&Host, &Plugin) also | ||
|
||
#[derive(Debug, Deserialize)] | ||
pub struct Record { | ||
#[serde(rename = "Plugin ID")] | ||
pub plugin_id: i32, | ||
#[serde(rename = "CVE")] | ||
pub cve: String, | ||
#[serde(rename = "CVSS")] | ||
pub cvss: String, | ||
#[serde(rename = "Risk")] | ||
pub risk: String, | ||
#[serde(rename = "Host")] | ||
pub host: String, | ||
#[serde(rename = "Protocol")] | ||
pub protocol: String, | ||
#[serde(rename = "Port")] | ||
pub port: u32, | ||
#[serde(rename = "Name")] | ||
pub name: String, | ||
#[serde(rename = "Synopsis")] | ||
pub synopsis: String, | ||
#[serde(rename = "Description")] | ||
pub description: String, | ||
#[serde(rename = "Solution")] | ||
pub solution: String, | ||
#[serde(rename = "See Also")] | ||
pub see_also: String, | ||
#[serde(rename = "Plugin Output")] | ||
pub plugin_output: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
extern crate csv; | ||
|
||
extern crate serde; | ||
|
||
#[macro_use] | ||
extern crate serde_derive; | ||
|
||
pub mod dump; | ||
pub use dump::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
use nessify::dump::*; | ||
|
||
#[test] | ||
fn parses_no_records_if_schema_is_bad() { | ||
let data = "invalid,csv | ||
what are you,doing"; | ||
|
||
let dump: Dump = Dump::read(data.as_bytes()); | ||
|
||
dbg!(dump.clone()); | ||
|
||
assert_eq!(dump.clone().filename, "test"); | ||
assert_eq!(dump.clone().detections.len(), 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mod dump; |