Skip to content

Commit

Permalink
Add: Initial rust NASL interpreter (#1234)
Browse files Browse the repository at this point in the history
* Prepare interpreter module

* rust nasl interpreter add primitive error handling

* rust nasl interpreter basic framework to interprete built-in functions

* rust nasl interpreter add some builtin-in description functions

* rust update Cargo.lock

* Refactor: move string resolver into StringCategory

Creates a trait called Resolver<T> with a resolve methods and implements
it for StringCategory instead of a method in the Interpreter.

This makes it easier to resolve it since it is just relevant for
Category::String that contains a StringCategory.

Implements From<Token> for Range instead of a range method to be more
standardized.

* Refactor: implement Resolver for NumberBase

Instead of implementing a function within interpreter the Resolver trait
is implemented for NumberBase

* Refactor implement From<NASLValue> for bool

Instead of providing a to_bool method the From trait is implement for
bool to make it a bit easier to handle.

* Refactor create context crate to contain the context implementations

For easier navigation the context definitions are moved to a context
crate.

* Change: context handling

Instead of having a trait to deal with context it is now implemented as
a struct and is stored within a register.

The idea here is that on each new context the register is called to a
create a context and after a context is finished it must be dropped.

* Rudimentary integration test within tests/description

Added a couple of new description methods, add a small integration test
for the description block, renamed description function from nasl_script
  to script_ to be easier to match against a identifier input.

* Redfine function creation in description

Instead of calling two macros it is defined as one:
`make_storage_function`
with a small DSL to create specific storage functions for the
description block.

The small DSL is defined as

```
make_storage_function! {
  script_timeout => [timeout :1],
  script_category => [category :1],
  script_name => [name :1],
  script_version => [version :1],
  script_copyright => [copyright :1],
  script_family => [family :1],
  script_oid => [oid :1],
  script_dependencies => [dependencies :0],
  script_mandatory_keys => [mandatory_keys: 0],
  script_require_ports => [required_ports: 2],
  script_tag => (name: value)
}
```

The first parameter is the function name followed by an `=>` the
optional positional argument handling is defined within `[]` the first
parameter within this block is the key name for the positional arguments
followed by an `:` to define the expected positional arguments or 0 if
there is no limit.

The named parameter are defined within an `()` the first argument is the
name of the key value followed by an `:` and the name of the value
argument.

* Doc: improve documentation of generated description functions

* Add ACT_* categories as Keywords

Since ACT will control the scan execution flow it is set to a Keyword so
it is easier to handle within the interpreter.

* Add script_xref

* Add script_exclude_keys

* Add script_require_udp_ports

* Add script_cve_id

* Add script_require_keys

* fix typos

* remove unused includes

* Add ACT_* categories as Keywords

Since ACT will control the scan execution flow it is set to a Keyword so
it is easier to handle within the interpreter.

* update readme

Co-authored-by: Philipp Eder <philipp.eder@greenbone.net>
  • Loading branch information
Kraemii and nichtsfrei authored Dec 8, 2022
1 parent 407d6a4 commit d5e9f10
Show file tree
Hide file tree
Showing 24 changed files with 1,122 additions and 123 deletions.
148 changes: 142 additions & 6 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["nasl-syntax", "nasl-cli", "nvtcache"]
members = ["nasl-syntax", "nasl-interpreter", "nasl-cli", "nvtcache",]
1 change: 1 addition & 0 deletions rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

This multi cargo workspace contains
- nasl-syntax - to parse nasl for further processing
- nasl-interpreter - to interpret nasl statements
9 changes: 9 additions & 0 deletions rust/nasl-interpreter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "nasl-interpreter"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nasl-syntax = {path = "../nasl-syntax"}
5 changes: 5 additions & 0 deletions rust/nasl-interpreter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# nasl-built-in

`nasl-interpreter` is a library to run NASL.

TBD
113 changes: 113 additions & 0 deletions rust/nasl-interpreter/src/built_in_functions/description.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use crate::{
context::{ContextType, NaslContext, Register},
error::FunctionError,
interpreter::{NaslValue, Storage},
NaslFunction,
};

/// Makes a storage function base on a very small DSL.
///
/// The DSL is defined as
/// function_name => [positional_key: expected_amount_pos_args] (key_named_parameter:value_named_parameter)
/// although the positional block as well as the named_parameter block are optional wen both are omitted a warning
/// that the storage is unused will pop up informing the developer that this created method is useless.
macro_rules! make_storage_function {
($($name:ident=> $([$key:ident : $len:expr])? $(($nkey:ident:$value:ident)),* ),+) => {
$(
$(
/// Stores
/// positional values
#[doc = concat!("(", stringify!($len), ")")]
/// as
#[doc = concat!("`", stringify!($key), "`.")]
)?
$(
/// Stores value defined in named_parameter
#[doc = concat!("`", stringify!($value), "`")]
/// as key defined in
#[doc = concat!("`", stringify!($nkey), "`.")]
)*
///
/// Returns NaslValue::Null on success.
pub fn $name(
storage: &mut dyn Storage,
registrat: &mut Register,
) -> Result<NaslValue, FunctionError> {
let ctx = registrat.last();
$(
let positional = ctx.positional(registrat);
if $len > 0 && positional.len() != $len{
return Err(FunctionError::new(
format!("expected {} positional arguments but {} were given.", $len, positional.len()),
));
}
for p in positional {
match p {
ContextType::Value(value) => {
storage.write(stringify!($key), &value.to_string());
},
_ => {
return Err(FunctionError::new(
"argument is a function, string was expected".to_string(),
))
}
}
}
)?
$(
let key = get_named_parameter(registrat, ctx, stringify!($nkey))?;
let value = get_named_parameter(registrat, ctx, stringify!($value))?;

storage.write(key, value);
)*
Ok(NaslValue::Null)
}
)*
/// Returns found function for key or None when not found
pub fn lookup(key: &str) -> Option<NaslFunction> {
match key {
$(
stringify!($name) => Some($name),
)*
_ => None,
}
}
};
}

fn get_named_parameter<'a>(
registrat: &'a Register,
ctx: &'a NaslContext,
key: &'a str,
) -> Result<&'a str, FunctionError> {
match ctx.named(registrat, key) {
None => Err(FunctionError::new(format!("expected {} to be set.", key))),
Some(ct) => match ct {
ContextType::Value(NaslValue::String(value)) => Ok(value),
_ => Err(FunctionError::new(format!(
"expected {} to be a string.",
key
))),
},
}
}

// creates the actual description functions
make_storage_function! {
script_timeout => [timeout :1],
script_category => [category :1],
script_name => [name :1],
script_version => [version :1],
script_copyright => [copyright :1],
script_family => [family :1],
script_oid => [oid :1],
script_dependencies => [dependencies :0],
script_exclude_keys => [exclude_keys :0],
script_mandatory_keys => [mandatory_keys: 0],
script_require_ports => [required_ports: 2],
script_tag => (name: value),
script_require_udp_ports => [require_udp_ports: 0],
script_require_keys => [require_keys: 0],
script_cve_id => [cve_ids: 0],
script_xref => (name: value)
}
2 changes: 2 additions & 0 deletions rust/nasl-interpreter/src/built_in_functions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod description;

Loading

0 comments on commit d5e9f10

Please sign in to comment.