Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error handling for builtin functions #1752

Merged
merged 38 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fb3f3e1
Rename FunctionErrorKind -> NaslError
Tehforsch Nov 4, 2024
640d863
Add new variants to `NaslError`.
Tehforsch Nov 4, 2024
250ffc1
Move TrailingPositionalArguments to new variant
Tehforsch Nov 4, 2024
c306601
Improve check_err_matches! ergonomics.
Tehforsch Nov 4, 2024
d213320
Move MissingArguments to ArgumentError
Tehforsch Nov 4, 2024
e96399f
Move UnexpectedArgument to ArgumentError
Tehforsch Nov 4, 2024
a5f603b
Move WrongArgument into Argument variant
Tehforsch Nov 4, 2024
a5d8d59
Move FmtError into StringError
Tehforsch Nov 4, 2024
d2252c7
Remove IOError from NaslError
Tehforsch Nov 4, 2024
f205ce0
Move 'authentication' to cryptographic error
Tehforsch Nov 4, 2024
4ff1469
Move GeneralErrorType to InternalError::Storage
Tehforsch Nov 4, 2024
09e445e
Remove GeneralErrorType
Tehforsch Nov 5, 2024
670ac1e
Move SshError into BuiltinError
Tehforsch Nov 5, 2024
aa1d579
Remove Dirty in favor of custom errors
Tehforsch Nov 5, 2024
963634d
Remove Eq derive on errors
Tehforsch Nov 5, 2024
09f31c0
Remove PartialEq on Error
Tehforsch Nov 5, 2024
0078e67
Rename back to FunctionErrorKind for the draft PR
Tehforsch Nov 5, 2024
fe796f3
Add return_value to builtin errors
Tehforsch Nov 6, 2024
c30d44a
Remove diagnostic variant
Tehforsch Nov 6, 2024
c4e85c8
Remove (&str, &NaslValue) -> FunctionErrorKind impl
Tehforsch Nov 7, 2024
259a3f1
Remove From<&str, &str, ContextType> impl
Tehforsch Nov 7, 2024
e7b9023
Remove From<(&str, &str, &NaslValue)> impl
Tehforsch Nov 7, 2024
9db2909
Move AttachErrorInfo to utils/error
Tehforsch Nov 7, 2024
0cc2bfd
Move FEK (temp)
Tehforsch Nov 7, 2024
a846cd8
Rename FunctionErrorKind -> FnError.
Tehforsch Nov 7, 2024
c0aeea3
Remove StorageError/IOError from InterpreterError
Tehforsch Nov 8, 2024
2d3cc61
Improve scannerctl error message on Fn errors.
Tehforsch Nov 8, 2024
93286d5
Implement retry logic
Tehforsch Nov 8, 2024
de6617e
Add basic test for retry functionality
Tehforsch Nov 8, 2024
eaad6bb
Remove clone derive on errors
Tehforsch Nov 11, 2024
35820f1
Move PacketForgeryError into RawIpError
Tehforsch Nov 11, 2024
babafc4
Make BuiltinError return Null by default
Tehforsch Nov 11, 2024
54fe4f1
Re-use WithErrorInfo
Tehforsch Nov 11, 2024
199b265
Change Option<NaslValue> to ReturnBehavior
Tehforsch Nov 11, 2024
2eaa0fc
Merge branch 'rust-only-ssh' into enum-error-handling2
Tehforsch Nov 26, 2024
0f63731
Fix clippy lints
Tehforsch Nov 27, 2024
f9526b8
Merge branch 'main' into enum-error-handling
Tehforsch Dec 5, 2024
e1d20c6
Add documentation on new error handling
Tehforsch Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rust/src/feed/transpile/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::nasl::syntax::{LoadError, Statement};
use super::verify;
use super::Replace;

#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[derive(Debug, Clone, PartialEq, Error)]
/// Error during transpiling
pub enum TranspileError {
/// Loader is unable to handle operation
Expand All @@ -19,7 +19,7 @@ pub enum TranspileError {
Replace(#[from] ReplaceError),
}

#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[derive(Debug, Clone, PartialEq, Error)]
/// Error cases on a replace operation
pub enum ReplaceError {
/// The replace operation is invalid on statement
Expand Down
4 changes: 2 additions & 2 deletions rust/src/feed/update/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use thiserror::Error;

use crate::feed::{verify, VerifyError};

#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[derive(Debug, Error)]
/// Errors within feed handling
pub enum ErrorKind {
/// An InterpretError occurred while interpreting
Expand All @@ -32,7 +32,7 @@ pub enum ErrorKind {
VerifyError(#[from] verify::Error),
}

#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[derive(Debug, Error)]
#[error("Error with key '{key}': {kind}")]
/// ErrorKind and key of error
pub struct Error {
Expand Down
2 changes: 1 addition & 1 deletion rust/src/feed/verify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use sequoia_ipc::keybox::{Keybox, KeyboxRecord};
use sequoia_openpgp as openpgp;
use thiserror::Error;

#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[derive(Debug, Clone, PartialEq, Error)]
/// Defines error cases that can happen while verifying
pub enum Error {
#[error("Incorrect feed.")]
Expand Down
56 changes: 25 additions & 31 deletions rust/src/nasl/builtin/cert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@ use std::collections::HashMap;
use std::sync::RwLock;

use nasl_function_proc_macro::nasl_function;
use thiserror::Error;
use x509_certificate::X509Certificate;
use x509_parser::prelude::GeneralName;

use crate::{
function_set,
nasl::{FunctionErrorKind, NaslValue},
};
use crate::nasl::prelude::*;

use super::string::encode_hex;

#[derive(Debug, Error)]
pub enum CertError {
#[error("Unable to calculate SHA256 fingerprint")]
UnableToCalculateSHA256Fingerprint,
#[error("Unable to calculate SHA1 fingerprint")]
UnableToCalculateSHA1Fingerprint,
#[error("Query parameter 'all' not implemented yet.")]
QueryParamAllNotImplemented,
}

fn sign_alg_oid_to_name(oid: &str) -> &str {
match oid {
"1.2.840.10040.4.1" => "id-dsa",
Expand Down Expand Up @@ -118,7 +126,7 @@ pub enum CertCommands {
}

impl TryFrom<&str> for CertCommands {
type Error = FunctionErrorKind;
type Error = FnError;

fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
Expand All @@ -138,9 +146,9 @@ impl TryFrom<&str> for CertCommands {
"modulus" => Ok(Self::Modulus),
"exponent" => Ok(Self::Exponent),
"key-size" => Ok(Self::KeySize),
_ => Err(FunctionErrorKind::WrongArgument(
"The given query is not valid.".to_string(),
)),
_ => Err(
ArgumentError::WrongArgument("The given query is not valid.".to_string()).into(),
),
}
}
}
Expand Down Expand Up @@ -176,7 +184,7 @@ impl NaslCerts {
/// On success the function returns a cert identifier that can be used
/// for further operations.
#[nasl_function]
fn cert_open(&self, cert: &[u8]) -> Result<usize, FunctionErrorKind> {
fn cert_open(&self, cert: &[u8]) -> Result<usize, FnError> {
if let Ok(cert) = X509Certificate::from_der(cert) {
return Ok(self.insert(cert));
}
Expand All @@ -187,10 +195,11 @@ impl NaslCerts {
return Ok(self.insert(cert));
}

Err(FunctionErrorKind::WrongArgument(
Err(ArgumentError::WrongArgument(
"The given string is not a valid DER, BER or PEM encoded X.509 certificate."
.to_string(),
))
)
.into())
}

/// Release a certificate object.
Expand Down Expand Up @@ -358,12 +367,12 @@ impl NaslCerts {
cert_handle: usize,
query: &str,
idx: Option<usize>,
) -> Result<NaslValue, FunctionErrorKind> {
) -> Result<NaslValue, FnError> {
let idx = idx.unwrap_or(0);
let handle = self.0.read().unwrap();

let cert = handle.certs.get(&cert_handle).ok_or_else(|| {
FunctionErrorKind::WrongArgument("The given file descriptor is not valid.".to_string())
ArgumentError::WrongArgument("The given file descriptor is not valid.".to_string())
})?;
let result = match CertCommands::try_from(query)? {
CertCommands::Serial => {
Expand All @@ -387,27 +396,12 @@ impl NaslCerts {
CertCommands::FprSha256 => cert
.sha256_fingerprint()
.map(|fpr| NaslValue::String(encode_hex(fpr.as_ref())))
.map_err(|_| {
FunctionErrorKind::Diagnostic(
"Unable to calculate SHA256 fingerprint".to_string(),
None,
)
})?,
.map_err(|_| CertError::UnableToCalculateSHA256Fingerprint)?,
CertCommands::FprSha1 => cert
.sha1_fingerprint()
.map(|fpr| NaslValue::String(encode_hex(fpr.as_ref())))
.map_err(|_| {
FunctionErrorKind::Diagnostic(
"Unable to calculate SHA1 fingerprint".to_string(),
None,
)
})?,
CertCommands::All => {
return Err(FunctionErrorKind::Diagnostic(
"Query parameter 'all' is not implemented yet".to_string(),
None,
))
}
.map_err(|_| CertError::UnableToCalculateSHA1Fingerprint)?,
CertCommands::All => return Err(CertError::QueryParamAllNotImplemented.into()),
CertCommands::Hostnames => NaslValue::Array(
Self::hostnames(cert)
.into_iter()
Expand Down
30 changes: 14 additions & 16 deletions rust/src/nasl/builtin/cryptographic/aes_cbc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ use aes::{
};
use cbc::{Decryptor, Encryptor};

use crate::function_set;
use crate::nasl::syntax::NaslValue;
use crate::nasl::utils::error::FunctionErrorKind;
use crate::nasl::utils::{Context, Register};
use crate::nasl::prelude::*;

use super::{get_data, get_iv, get_key, get_len, Crypt};

/// Base function for en- and decrypting Cipher Block Chaining (CBC) mode
fn cbc<D>(register: &Register, crypt: Crypt) -> Result<NaslValue, FunctionErrorKind>
fn cbc<D>(register: &Register, crypt: Crypt) -> Result<NaslValue, FnError>
where
D: BlockCipher + BlockEncrypt + BlockDecrypt + KeyInit,
{
Expand All @@ -35,7 +32,7 @@ where
let res = Encryptor::<D>::new_from_slices(key, iv);
match res {
Ok(encryptor) => Ok(encryptor.encrypt_padded_vec_mut::<ZeroPadding>(data).into()),
Err(e) => Err(FunctionErrorKind::WrongArgument(e.to_string())),
Err(e) => Err(ArgumentError::WrongArgument(e.to_string()).into()),
}
}
Crypt::Decrypt => {
Expand All @@ -47,20 +44,21 @@ where

// len should not be more than the length of the data
if len > data.len() {
return Err(FunctionErrorKind::wrong_argument(
return Err(ArgumentError::wrong_argument(
"len",
format!("<={:?}", data.len()).as_str(),
len.to_string().as_str(),
));
)
.into());
}
let res = Decryptor::<D>::new_from_slices(key, iv);
match res {
Ok(decryptor) => Ok(decryptor
.decrypt_padded_vec_mut::<NoPadding>(data)
.map_err(|e| FunctionErrorKind::WrongArgument(e.to_string()))?[..len]
.map_err(|e| ArgumentError::WrongArgument(e.to_string()))?[..len]
.to_vec()
.into()),
Err(e) => Err(FunctionErrorKind::WrongArgument(e.to_string())),
Err(e) => Err(ArgumentError::WrongArgument(e.to_string()).into()),
}
}
}
Expand All @@ -73,7 +71,7 @@ where
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes128>(register, Crypt::Encrypt)
}

Expand All @@ -85,7 +83,7 @@ fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, Fun
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes128>(register, Crypt::Decrypt)
}

Expand All @@ -96,7 +94,7 @@ fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, Fun
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes192>(register, Crypt::Encrypt)
}

Expand All @@ -108,7 +106,7 @@ fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, Fun
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes192>(register, Crypt::Decrypt)
}

Expand All @@ -119,7 +117,7 @@ fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, Fun
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes256>(register, Crypt::Encrypt)
}

Expand All @@ -131,7 +129,7 @@ fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result<NaslValue, Fun
/// Currently the data is filled with zeroes. Therefore the length of the encrypted data must be
/// known for decryption. If no length is given, the last block is decrypted as a whole.
/// - The iv must have a length of 16 bytes
fn aes256_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FunctionErrorKind> {
fn aes256_cbc_decrypt(register: &Register, _: &Context) -> Result<NaslValue, FnError> {
cbc::<Aes256>(register, Crypt::Decrypt)
}

Expand Down
Loading
Loading