diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c69a9ce93..e6f407c07 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -19,11 +19,17 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + [[package]] name = "clap" -version = "4.0.24" +version = "4.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60494cedb60cb47462c0ff7be53de32c0e42a6fc2c772184554fa12bd9489c03" +checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" dependencies = [ "atty", "bitflags", @@ -56,6 +62,25 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + [[package]] name = "heck" version = "0.4.0" @@ -71,12 +96,34 @@ dependencies = [ "libc", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + [[package]] name = "libc" version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "nasl-cli" version = "0.1.0" @@ -90,6 +137,13 @@ dependencies = [ name = "nasl-syntax" version = "0.1.0" +[[package]] +name = "nvtcache" +version = "0.1.0" +dependencies = [ + "redis", +] + [[package]] name = "once_cell" version = "1.16.0" @@ -98,9 +152,15 @@ checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "os_str_bytes" -version = "6.4.0" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "percent-encoding" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5bf27447411e9ee3ff51186bf7a08e16c341efdde93f4d823e8844429bed7e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "proc-macro-error" @@ -144,6 +204,26 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redis" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513b3649f1a111c17954296e4a3b9eecb108b766c803e2b99f179ebe27005985" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "url", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + [[package]] name = "same-file" version = "1.0.6" @@ -153,6 +233,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "strsim" version = "0.10.0" @@ -179,12 +265,53 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + [[package]] name = "unicode-ident" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "version_check" version = "0.9.4" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 9fc48dd17..87ab0b154 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["nasl-syntax", "nasl-cli"] +members = ["nasl-syntax", "nasl-cli", "nvtcache"] diff --git a/rust/nvtcache/Cargo.lock b/rust/nvtcache/Cargo.lock new file mode 100644 index 000000000..53e87fe8d --- /dev/null +++ b/rust/nvtcache/Cargo.lock @@ -0,0 +1,130 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nvtcache" +version = "0.1.0" +dependencies = [ + "redis", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "redis" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513b3649f1a111c17954296e4a3b9eecb108b766c803e2b99f179ebe27005985" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "url", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] diff --git a/rust/nvtcache/Cargo.toml b/rust/nvtcache/Cargo.toml new file mode 100644 index 000000000..db6651c0d --- /dev/null +++ b/rust/nvtcache/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "nvtcache" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +redis = "0.22.1" diff --git a/rust/nvtcache/README.md b/rust/nvtcache/README.md new file mode 100644 index 000000000..d9839d1a7 --- /dev/null +++ b/rust/nvtcache/README.md @@ -0,0 +1,3 @@ +# NVTCache + +Libary for initializing and loading up the NVT Cache for OpenVAS Scanner written in rust. diff --git a/rust/nvtcache/src/dberror.rs b/rust/nvtcache/src/dberror.rs new file mode 100644 index 000000000..f3062ad57 --- /dev/null +++ b/rust/nvtcache/src/dberror.rs @@ -0,0 +1,39 @@ +use redis::*; +use std::error; +use std::fmt; + +pub mod dberror { + use super::*; + + pub type Result = std::result::Result; + + #[derive(Debug)] + pub enum DbError { + RedisErr(RedisError), + CustomErr(String), + } + + impl fmt::Display for DbError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &*self { + DbError::RedisErr(..) => write!(f, "Redis Error"), + DbError::CustomErr(e) => write!(f, "Error: String Message {}", e), + } + } + } + + impl error::Error for DbError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match *self { + DbError::RedisErr(ref e) => Some(e), + DbError::CustomErr(_) => None, + } + } + } + + impl From for DbError { + fn from(err: RedisError) -> DbError { + DbError::RedisErr(err) + } + } +} diff --git a/rust/nvtcache/src/lib.rs b/rust/nvtcache/src/lib.rs new file mode 100644 index 000000000..c13a3f2a0 --- /dev/null +++ b/rust/nvtcache/src/lib.rs @@ -0,0 +1,3 @@ +pub mod dberror; +pub mod nvtcache; +pub mod redisconnector; diff --git a/rust/nvtcache/src/nvtcache.rs b/rust/nvtcache/src/nvtcache.rs new file mode 100644 index 000000000..798c26e9b --- /dev/null +++ b/rust/nvtcache/src/nvtcache.rs @@ -0,0 +1,28 @@ +pub mod nvtcache { + + // use super::*; + use crate::dberror::dberror::Result; + use crate::redisconnector::redisconnector::*; + + pub struct NvtCache { + pub cache: RedisCtx, + pub init: bool, + } + + /// NvtCache implementation. + impl NvtCache { + /// initialize the NVT Cache. + pub fn init() -> Result { + let mut rctx = RedisCtx::new()?; + let kbi = rctx.select_database()?; + Ok(NvtCache { + cache: rctx, + init: true, + }) + } + + pub fn is_init(&mut self) -> bool { + self.init == true + } + } +} diff --git a/rust/nvtcache/src/redisconnector.rs b/rust/nvtcache/src/redisconnector.rs new file mode 100644 index 000000000..7c815e82c --- /dev/null +++ b/rust/nvtcache/src/redisconnector.rs @@ -0,0 +1,132 @@ +use redis::*; + +const GLOBAL_DBINDEX_NAME: &str = "GVM.__GlobalDBIndex"; +const REDIS_DEFAULT_PATH: &str = "unix:///run/redis/redis-server.sock"; +const NVTCACHE: &str = "nvticache"; + +pub mod redisconnector { + use super::*; + use crate::dberror::dberror::DbError; + use crate::dberror::dberror::Result; + + pub struct RedisCtx { + pub kb: Connection, //a redis connection + db: u32, // the name space + maxdb: u32, // max db index + } + + impl RedisCtx { + pub fn new() -> Result { + let client = redis::Client::open(REDIS_DEFAULT_PATH)?; + let kb = client.get_connection()?; + Ok(RedisCtx { + kb, + db: 0, + maxdb: 0, + }) + } + + pub fn max_db_index(&mut self) -> Result { + if self.maxdb > 0 { + return Ok(self.maxdb); + } + + let maxdb = Cmd::new() + .arg("CONFIG") + .arg("GET") + .arg("databases") + .query(&mut self.kb); + + match maxdb { + Ok(mdb) => { + let res: Vec = mdb; + self.maxdb = max_db_index_to_uint(res); + return Ok(self.maxdb); + } + Err(_) => { + return Err(DbError::CustomErr(String::from( + "Not possible to select a free database.", + ))) + } + } + + fn max_db_index_to_uint(res: Vec) -> u32 { + if res.len() == 2 { + match res[1].to_string().parse::() { + Ok(m) => return m, + Err(e) => { + println!("{}", e); + return 0 as u32; + } + } + } + return 0 as u32; + } + } + + pub fn get_namespace(&mut self) -> Result { + let db: u32 = self.db; + Ok(db) + } + pub fn set_namespace(&mut self, db_index: u32) -> Result { + let s = Cmd::new() + .arg("SELECT") + .arg(db_index.to_string()) + .query(&mut self.kb); + + match s { + Ok(ok) => { + self.db = db_index; + return Ok(ok); + } + Err(_) => { + return Err(DbError::CustomErr(String::from( + "Not possible to set a namespace.", + ))) + } + } + } + + pub fn try_database(&mut self, dbi: u32) -> Result { + return Ok(1); + } + + pub fn select_database(&mut self) -> Result { + let maxdb: u32 = self.max_db_index()?; + + if self.db == 0 { + for i in 1..maxdb { + match self.try_database(i) { + Ok(selected_db) => { + self.db = selected_db; + match self.set_namespace(i) { + Ok(_) => (), + Err(e) => { + println!("Error: {}", e); + break; + } + } + return Ok(self.db); + } + Err(_) => continue, + } + } + } + return Err(DbError::CustomErr(String::from( + "Not possible to select a free database.", + ))); + } + + pub fn redis_set_key_int(&mut self, key: &str, val: i32) -> Result<()> { + let _: () = self.kb.set(key, val)?; + Ok(()) + } + + pub fn redis_get_int(&mut self, key: &str) -> String { + match self.kb.get(key) { + Ok(x) => return x, + Err(e) => e.to_string(), + } + } + } +} diff --git a/rust/nvtcache/tests/nvtcache_tests.rs b/rust/nvtcache/tests/nvtcache_tests.rs new file mode 100644 index 000000000..11c3fd0db --- /dev/null +++ b/rust/nvtcache/tests/nvtcache_tests.rs @@ -0,0 +1,50 @@ +use nvtcache::nvtcache; +use std::error::Error; + +//test +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_nvtcache() { + let mut nvtcache: nvtcache::nvtcache::NvtCache; + let n = nvtcache::nvtcache::NvtCache::init(); + match n { + Ok(nc) => nvtcache = nc, + Err(e) => { + println!("{}", e); + if let Some(source) = e.source() { + println!("{}", source); + } + + panic!("Error") + } + } + match nvtcache.cache.max_db_index() { + Ok(n) => println!("MAX: {}", n), + Err(e) => println!("Error:{}", e), + } + + if nvtcache.is_init() { + println!("Is initialized"); + } + + match nvtcache.cache.set_namespace(1) { + Ok(ok) => println!("Select 1 {}", ok), + Err(e) => println!("Error:{}", e), + } + match nvtcache.cache.get_namespace() { + Ok(ok) => println!("The namespace: {}", ok), + Err(e) => println!("Error:{}", e), + } + + let key = "key"; + let val = 42; + match nvtcache.cache.redis_set_key_int(key, 42) { + Ok(_) => println!("Key {} set with {}", key, val), + Err(e) => println!("Error:{}", e), + } + println!("{}", nvtcache.cache.redis_get_int(key)) + } +}