From fb3f3e14ef14dc3679f3a5fe540ca6a947198b46 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 09:31:02 +0100 Subject: [PATCH 01/36] Rename FunctionErrorKind -> NaslError --- .../src/nasl/builtin/cryptographic/aes_cbc.rs | 24 +- .../src/nasl/builtin/cryptographic/aes_ccm.rs | 58 +-- .../nasl/builtin/cryptographic/aes_cmac.rs | 4 +- .../src/nasl/builtin/cryptographic/aes_ctr.rs | 14 +- .../src/nasl/builtin/cryptographic/aes_gcm.rs | 50 +-- .../nasl/builtin/cryptographic/aes_gmac.rs | 4 +- rust/src/nasl/builtin/cryptographic/des.rs | 20 +- rust/src/nasl/builtin/cryptographic/hash.rs | 18 +- rust/src/nasl/builtin/cryptographic/hmac.rs | 18 +- rust/src/nasl/builtin/cryptographic/mod.rs | 27 +- .../builtin/cryptographic/tests/aes_gcm.rs | 2 +- rust/src/nasl/builtin/description/mod.rs | 12 +- rust/src/nasl/builtin/host/mod.rs | 17 +- rust/src/nasl/builtin/http/mod.rs | 87 ++-- rust/src/nasl/builtin/isotime/mod.rs | 12 +- rust/src/nasl/builtin/isotime/tests.rs | 27 +- rust/src/nasl/builtin/knowledge_base/mod.rs | 16 +- rust/src/nasl/builtin/knowledge_base/tests.rs | 6 +- rust/src/nasl/builtin/misc/mod.rs | 14 +- rust/src/nasl/builtin/misc/tests.rs | 2 +- rust/src/nasl/builtin/network/mod.rs | 8 +- rust/src/nasl/builtin/network/network.rs | 16 +- .../src/nasl/builtin/network/network_utils.rs | 21 +- rust/src/nasl/builtin/network/socket.rs | 103 +++-- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 53 ++- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 377 +++++++----------- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 25 +- .../builtin/raw_ip/tests/packet_forgery.rs | 12 +- rust/src/nasl/builtin/regex/mod.rs | 12 +- rust/src/nasl/builtin/report_functions/mod.rs | 12 +- rust/src/nasl/builtin/ssh/error.rs | 6 +- rust/src/nasl/builtin/ssh/mod.rs | 4 +- rust/src/nasl/builtin/ssh/tests/mod.rs | 6 +- rust/src/nasl/builtin/ssh/utils.rs | 18 +- rust/src/nasl/builtin/string/mod.rs | 26 +- rust/src/nasl/builtin/string/tests.rs | 2 +- rust/src/nasl/interpreter/error.rs | 14 +- rust/src/nasl/mod.rs | 2 +- rust/src/nasl/test_utils.rs | 6 +- rust/src/nasl/utils/error.rs | 24 +- .../nasl/utils/function/from_nasl_value.rs | 48 +-- rust/src/nasl/utils/function/maybe.rs | 4 +- rust/src/nasl/utils/function/positionals.rs | 10 +- .../src/nasl/utils/function/to_nasl_result.rs | 12 +- rust/src/nasl/utils/function/types.rs | 4 +- rust/src/nasl/utils/function/utils.rs | 28 +- rust/src/nasl/utils/mod.rs | 10 +- rust/src/scannerctl/interpret/mod.rs | 2 +- 48 files changed, 537 insertions(+), 760 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs index db69748ac..db60514be 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs @@ -14,13 +14,13 @@ use cbc::{Decryptor, Encryptor}; use crate::function_set; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::NaslError; use crate::nasl::utils::{Context, Register}; use super::{get_data, get_iv, get_key, get_len, Crypt}; /// Base function for en- and decrypting Cipher Block Chaining (CBC) mode -fn cbc(register: &Register, crypt: Crypt) -> Result +fn cbc(register: &Register, crypt: Crypt) -> Result where D: BlockCipher + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -35,7 +35,7 @@ where let res = Encryptor::::new_from_slices(key, iv); match res { Ok(encryptor) => Ok(encryptor.encrypt_padded_vec_mut::(data).into()), - Err(e) => Err(FunctionErrorKind::WrongArgument(e.to_string())), + Err(e) => Err(NaslError::WrongArgument(e.to_string())), } } Crypt::Decrypt => { @@ -47,7 +47,7 @@ where // len should not be more than the length of the data if len > data.len() { - return Err(FunctionErrorKind::wrong_argument( + return Err(NaslError::wrong_argument( "len", format!("<={:?}", data.len()).as_str(), len.to_string().as_str(), @@ -57,10 +57,10 @@ where match res { Ok(decryptor) => Ok(decryptor .decrypt_padded_vec_mut::(data) - .map_err(|e| FunctionErrorKind::WrongArgument(e.to_string()))?[..len] + .map_err(|e| NaslError::WrongArgument(e.to_string()))?[..len] .to_vec() .into()), - Err(e) => Err(FunctionErrorKind::WrongArgument(e.to_string())), + Err(e) => Err(NaslError::WrongArgument(e.to_string())), } } } @@ -73,7 +73,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 { +fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -85,7 +85,7 @@ fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -96,7 +96,7 @@ fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -108,7 +108,7 @@ fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -119,7 +119,7 @@ fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -131,7 +131,7 @@ fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs index 9eaa248d3..1eb6fc718 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::nasl::utils::error::{FunctionErrorKind, GeneralErrorType}; +use crate::nasl::utils::error::{GeneralErrorType, NaslError}; use aes::cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ @@ -41,7 +41,7 @@ where } /// Base function for ccm en- and decryption. Sets the tag length to 16. -fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -60,9 +60,9 @@ where // Error handling match res { Ok(x) => Ok(NaslValue::Data(x)), - Err(_) => Err(FunctionErrorKind::GeneralError( - GeneralErrorType::UnexpectedData("unable to en-/decrypt data".to_string()), - )), + Err(_) => Err(NaslError::GeneralError(GeneralErrorType::UnexpectedData( + "unable to en-/decrypt data".to_string(), + ))), } } @@ -73,7 +73,7 @@ where /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -84,10 +84,7 @@ fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -98,7 +95,7 @@ fn aes128_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -109,10 +106,7 @@ fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -123,7 +117,7 @@ fn aes128_ccm_decrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -134,10 +128,7 @@ fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -148,7 +139,7 @@ fn aes192_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -159,10 +150,7 @@ fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -173,7 +161,7 @@ fn aes192_ccm_decrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -184,10 +172,7 @@ fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -198,7 +183,7 @@ fn aes256_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -209,16 +194,13 @@ fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } macro_rules! ccm_call_typed { ($(($t1s: expr, $t1: ty) => $(($t2s: expr, $t2: ty)),*);*) => { - fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, FunctionErrorKind> + fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, NaslError> where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit { match tag_size { @@ -230,11 +212,11 @@ macro_rules! ccm_call_typed { Ok(ccm_crypt::(crypt, key, nonce, data, aad)) } ),* - other => Err(FunctionErrorKind::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) + other => Err(NaslError::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) } } ),* - other => Err(FunctionErrorKind::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) + other => Err(NaslError::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) } } } diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 927719248..9a1e4c61e 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -4,7 +4,7 @@ use crate::nasl::syntax::NaslValue; use crate::nasl::utils::error::GeneralErrorType; -use crate::nasl::utils::{Context, FunctionErrorKind, Register}; +use crate::nasl::utils::{Context, NaslError, Register}; use aes::Aes128; use cmac::{Cmac, Mac}; @@ -17,7 +17,7 @@ use super::{get_data, get_key}; /// This function expects 2 named arguments key and data either in a string or data type. /// It is important to notice, that internally the CMAC algorithm is used and not, as the name /// suggests, CBC-MAC. -fn aes_cmac(register: &Register, _: &Context) -> Result { +fn aes_cmac(register: &Register, _: &Context) -> Result { let key = get_key(register)?; let data = get_data(register)?; diff --git a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs index 7d46c7495..ff8b335f7 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs @@ -15,7 +15,7 @@ use crate::nasl::prelude::*; use super::{get_data, get_iv, get_key, get_len, Crypt}; -fn ctr(register: &Register, crypt: Crypt) -> Result +fn ctr(register: &Register, crypt: Crypt) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -56,7 +56,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. It is used as the initial counter. -fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -68,7 +68,7 @@ fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -79,7 +79,7 @@ fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -91,7 +91,7 @@ fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -102,7 +102,7 @@ fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -114,7 +114,7 @@ fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs index 71868f4a5..c856cefb2 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// FunctionErrorKind::GeneralError +// NaslError::GeneralError use crate::nasl::syntax::NaslValue; use crate::{ function_set, - nasl::utils::{Context, FunctionErrorKind, Register}, + nasl::utils::{Context, NaslError, Register}, }; use aes::{ cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit}, @@ -20,7 +20,7 @@ use digest::typenum::{U12, U16}; use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt}; -fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -67,7 +67,7 @@ where }, Crypt::Encrypt => Ok(x.into()), }, - Err(_) => Err(FunctionErrorKind::Authentication), + Err(_) => Err(NaslError::Authentication), } } @@ -80,7 +80,7 @@ where /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -93,10 +93,7 @@ fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -109,7 +106,7 @@ fn aes128_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -122,10 +119,7 @@ fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -138,7 +132,7 @@ fn aes128_gcm_decrypt_auth( /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -151,10 +145,7 @@ fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -167,7 +158,7 @@ fn aes192_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -180,10 +171,7 @@ fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -196,7 +184,7 @@ fn aes192_gcm_decrypt_auth( /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -209,10 +197,7 @@ fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -225,7 +210,7 @@ fn aes256_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -238,10 +223,7 @@ fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs index 15cb71d3c..71d5022e3 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs @@ -11,7 +11,7 @@ use crate::function_set; fn aes_gmac( register: &crate::nasl::utils::Register, _: &crate::nasl::utils::Context, -) -> Result { +) -> Result { use super::{get_data, get_iv, get_key}; use nasl_c_lib::cryptographic::mac::aes_gmac; @@ -21,7 +21,7 @@ fn aes_gmac( match aes_gmac(data, key, iv) { Ok(val) => Ok(val.into()), - Err(code) => Err(crate::nasl::utils::FunctionErrorKind::GeneralError( + Err(code) => Err(crate::nasl::utils::NaslError::GeneralError( crate::nasl::utils::error::GeneralErrorType::UnexpectedData(format!( "Error code {}", code diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index 23ce75016..db91cca18 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -4,7 +4,7 @@ use crate::{ function_set, - nasl::utils::{Context, FunctionErrorKind, Register}, + nasl::utils::{Context, NaslError, Register}, }; use aes::cipher::BlockEncrypt; use ccm::KeyInit; @@ -13,34 +13,26 @@ use des::cipher::generic_array::GenericArray; fn encrypt_des( register: &Register, _: &Context, -) -> Result { +) -> Result { let positional = register.positional(); if positional.len() != 2 { - return Err(FunctionErrorKind::MissingPositionalArguments { + return Err(NaslError::MissingPositionalArguments { expected: 2, got: positional.len(), }); } let key = match &positional[1] { crate::nasl::syntax::NaslValue::Data(x) => x, - _ => { - return Err(FunctionErrorKind::WrongArgument( - "expected Data.".to_string(), - )) - } + _ => return Err(NaslError::WrongArgument("expected Data.".to_string())), }; if key.len() != 8 { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "16, 32 or 48 bytes length key".to_string(), )); } let mut data = GenericArray::clone_from_slice(match &positional[0] { crate::nasl::syntax::NaslValue::Data(x) => x, - _ => { - return Err(FunctionErrorKind::WrongArgument( - "expected Data.".to_string(), - )) - } + _ => return Err(NaslError::WrongArgument("expected Data.".to_string())), }); let des_cipher = des::Des::new(&GenericArray::clone_from_slice(key)); des_cipher.encrypt_block(&mut data); diff --git a/rust/src/nasl/builtin/cryptographic/hash.rs b/rust/src/nasl/builtin/cryptographic/hash.rs index 5289e0033..4d9d59340 100644 --- a/rust/src/nasl/builtin/cryptographic/hash.rs +++ b/rust/src/nasl/builtin/cryptographic/hash.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::function_set; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::NaslError; use digest::Digest; use md2::Md2; use md4::Md4; @@ -15,7 +15,7 @@ use sha2::{Sha256, Sha512}; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{Context, Register}; -fn nasl_hash(register: &Register) -> Result +fn nasl_hash(register: &Register) -> Result where D::OutputSize: std::ops::Add, ::Output: digest::generic_array::ArrayLength, @@ -37,37 +37,37 @@ where } /// NASL function to get MD2 hash -pub fn hash_md2(register: &Register, _: &Context) -> Result { +pub fn hash_md2(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get MD4 hash -pub fn hash_md4(register: &Register, _: &Context) -> Result { +pub fn hash_md4(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get MD5 hash -pub fn hash_md5(register: &Register, _: &Context) -> Result { +pub fn hash_md5(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA1 hash -pub fn hash_sha1(register: &Register, _: &Context) -> Result { +pub fn hash_sha1(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA256 hash -pub fn hash_sha256(register: &Register, _: &Context) -> Result { +pub fn hash_sha256(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA512 hash -pub fn hash_sha512(register: &Register, _: &Context) -> Result { +pub fn hash_sha512(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get RIPemd160 hash -pub fn hash_ripemd160(register: &Register, _: &Context) -> Result { +pub fn hash_ripemd160(register: &Register, _: &Context) -> Result { nasl_hash::(register) } diff --git a/rust/src/nasl/builtin/cryptographic/hmac.rs b/rust/src/nasl/builtin/cryptographic/hmac.rs index 4aa78f744..95d3a973f 100644 --- a/rust/src/nasl/builtin/cryptographic/hmac.rs +++ b/rust/src/nasl/builtin/cryptographic/hmac.rs @@ -19,7 +19,7 @@ use sha2::{Sha256, Sha384, Sha512}; use crate::nasl::prelude::*; -fn hmac(register: &Register) -> Result +fn hmac(register: &Register) -> Result where D: CoreProxy, D::Core: HashMarker @@ -44,7 +44,7 @@ where let mut hmac = match Hmac::::new_from_slice(key.as_bytes()) { Ok(x) => x, Err(InvalidLength) => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "valid size key", "invalid size key", )) @@ -57,37 +57,37 @@ where } /// NASL function to get HMAC MD2 string -pub fn hmac_md2(register: &Register, _: &Context) -> Result { +pub fn hmac_md2(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC MD5 string -pub fn hmac_md5(register: &Register, _: &Context) -> Result { +pub fn hmac_md5(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC RIPEMD160 string -pub fn hmac_ripemd160(register: &Register, _: &Context) -> Result { +pub fn hmac_ripemd160(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA1 string -pub fn hmac_sha1(register: &Register, _: &Context) -> Result { +pub fn hmac_sha1(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA256 string -pub fn hmac_sha256(register: &Register, _: &Context) -> Result { +pub fn hmac_sha256(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA384 string -pub fn hmac_sha384(register: &Register, _: &Context) -> Result { +pub fn hmac_sha384(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA512 string -pub fn hmac_sha512(register: &Register, _: &Context) -> Result { +pub fn hmac_sha512(register: &Register, _: &Context) -> Result { hmac::(register) } diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 06cfad2aa..73e83e47f 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception // use crate::nasl::utils::combine_function_sets; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::NaslError; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{ContextType, IntoFunctionSet, Register, StoredFunctionSet}; @@ -36,16 +36,16 @@ enum Crypt { fn get_required_named_data<'a>( register: &'a Register, key: &'a str, -) -> Result<&'a [u8], FunctionErrorKind> { +) -> Result<&'a [u8], NaslError> { match register.named(key) { Some(ContextType::Value(NaslValue::Data(x))) => Ok(x.as_slice()), Some(ContextType::Value(NaslValue::String(x))) => Ok(x.as_bytes()), - Some(x) => Err(FunctionErrorKind::wrong_argument( + Some(x) => Err(NaslError::wrong_argument( key, "a String or Data Value", format!("{:?}", x).as_str(), )), - _ => Err(FunctionErrorKind::missing_argument(key)), + _ => Err(NaslError::missing_argument(key)), } } @@ -53,13 +53,10 @@ fn get_required_named_data<'a>( /// In case the argument is required, the returned value is either an Error or the Option is always /// set to Some value. If it is false, no error will be returned but the Option can be either Some /// or None. -fn get_optional_named_number( - register: &Register, - key: &str, -) -> Result, FunctionErrorKind> { +fn get_optional_named_number(register: &Register, key: &str) -> Result, NaslError> { match register.named(key) { Some(ContextType::Value(NaslValue::Number(x))) => Ok(Some(*x)), - Some(x) => Err(FunctionErrorKind::wrong_argument( + Some(x) => Err(NaslError::wrong_argument( key, "a Number Value", format!("{:?}", x).as_str(), @@ -69,33 +66,33 @@ fn get_optional_named_number( } /// Get the required key argument or error. -fn get_key(register: &Register) -> Result<&[u8], FunctionErrorKind> { +fn get_key(register: &Register) -> Result<&[u8], NaslError> { get_required_named_data(register, "key") } /// Get the required data argument or error. -fn get_data(register: &Register) -> Result<&[u8], FunctionErrorKind> { +fn get_data(register: &Register) -> Result<&[u8], NaslError> { get_required_named_data(register, "data") } /// Get the required iv argument or error. -fn get_iv(register: &Register) -> Result<&[u8], FunctionErrorKind> { +fn get_iv(register: &Register) -> Result<&[u8], NaslError> { get_required_named_data(register, "iv") } /// Get the required iv argument or error. -fn get_aad(register: &Register) -> Result<&[u8], FunctionErrorKind> { +fn get_aad(register: &Register) -> Result<&[u8], NaslError> { get_required_named_data(register, "aad") } /// Get the optional len argument with proper error handling. -fn get_len(register: &Register) -> Result, FunctionErrorKind> { +fn get_len(register: &Register) -> Result, NaslError> { let buf = get_optional_named_number(register, "len")?; match buf { None => Ok(None), Some(x) => match x.try_into() { Ok(y) => Ok(Some(y)), - Err(_) => Err(FunctionErrorKind::WrongArgument(format!( + Err(_) => Err(NaslError::WrongArgument(format!( "System only supports numbers between {:?} and {:?} but was {:?}", usize::MIN, usize::MAX, diff --git a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs index 1708da468..c7637c71e 100644 --- a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// FunctionErrorKind::GeneralError +// NaslError::GeneralError use super::helper::decode_hex; use crate::nasl::test_prelude::*; diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index 91b4734bc..326d9eb22 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -25,7 +25,7 @@ use crate::nasl::utils::get_named_parameter; ///} /// ```` /// The first parameter is the name of the function as well as the &str lookup key. -/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. +/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. /// /// Parameter are separated from the definition by a `=>`. /// @@ -59,13 +59,13 @@ macro_rules! make_storage_function { pub fn $name( registrat: &Register, ctxconfigs: &Context, - ) -> Result { + ) -> Result { let mut variables = vec![]; $( let positional = registrat.positional(); if $len > 0 && positional.len() != $len{ return Err( - FunctionErrorKind::MissingPositionalArguments { expected: $len, got: positional.len() } + NaslError::MissingPositionalArguments { expected: $len, got: positional.len() } ); } for p in positional { @@ -106,7 +106,7 @@ macro_rules! make_storage_function { }; } -type Transform = Result, FunctionErrorKind>; +type Transform = Result, NaslError>; fn as_timeout_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { Ok(vec![NVTField::Preference(NvtPreference { @@ -200,7 +200,7 @@ fn as_tag_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_xref_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { if arguments.len() != 2 { - return Err(FunctionErrorKind::MissingArguments(vec![ + return Err(NaslError::MissingArguments(vec![ "name".to_owned(), "csv".to_owned(), ])); @@ -213,7 +213,7 @@ fn as_xref_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_preference(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { if arguments.len() < 3 { - return Err(FunctionErrorKind::MissingArguments(vec![ + return Err(NaslError::MissingArguments(vec![ "type".to_owned(), "value".to_owned(), ])); diff --git a/rust/src/nasl/builtin/host/mod.rs b/rust/src/nasl/builtin/host/mod.rs index 8a941ea79..f61a77a8b 100644 --- a/rust/src/nasl/builtin/host/mod.rs +++ b/rust/src/nasl/builtin/host/mod.rs @@ -8,7 +8,7 @@ mod tests; use std::{net::IpAddr, str::FromStr}; use crate::function_set; -use crate::nasl::utils::{error::FunctionErrorKind, lookup_keys::TARGET}; +use crate::nasl::utils::{error::NaslError, lookup_keys::TARGET}; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{Context, ContextType, Register}; @@ -17,7 +17,7 @@ use crate::nasl::utils::{Context, ContextType, Register}; /// /// It does lookup TARGET and when not found falls back to 127.0.0.1 to resolve. /// If the TARGET is not a IP address than we assume that it already is a fqdn or a hostname and will return that instead. -fn resolve_hostname(register: &Register) -> Result { +fn resolve_hostname(register: &Register) -> Result { use std::net::ToSocketAddrs; let default_ip = "127.0.0.1"; @@ -41,7 +41,7 @@ fn resolve_hostname(register: &Register) -> Result { /// /// As of now (2023-01-20) there is no vhost handling. /// Therefore this function does load the registered TARGET and if it is an IP Address resolves it via DNS instead. -fn get_host_names(register: &Register, _: &Context) -> Result { +fn get_host_names(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(|x| NaslValue::Array(vec![NaslValue::String(x)])) } @@ -49,12 +49,12 @@ fn get_host_names(register: &Register, _: &Context) -> Result Result { +fn get_host_name(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(NaslValue::String) } /// Return the target's IP address as IpAddr. -pub fn get_host_ip(context: &Context) -> Result { +pub fn get_host_ip(context: &Context) -> Result { let default_ip = "127.0.0.1"; let r_sock_addr = match context.target() { x if !x.is_empty() => IpAddr::from_str(x), @@ -63,7 +63,7 @@ pub fn get_host_ip(context: &Context) -> Result { match r_sock_addr { Ok(x) => Ok(x), - Err(e) => Err(FunctionErrorKind::wrong_unnamed_argument( + Err(e) => Err(NaslError::wrong_unnamed_argument( "IP address", e.to_string().as_str(), )), @@ -71,10 +71,7 @@ pub fn get_host_ip(context: &Context) -> Result { } /// Return the target's IP address or 127.0.0.1 if not set. -fn nasl_get_host_ip( - _register: &Register, - context: &Context, -) -> Result { +fn nasl_get_host_ip(_register: &Register, context: &Context) -> Result { let ip = get_host_ip(context)?; Ok(NaslValue::String(ip.to_string())) } diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index af134ffda..f0513e29c 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -35,9 +35,9 @@ pub struct NaslHttp { async fn lock_handles( handles: &Arc>>, -) -> Result>, FunctionErrorKind> { +) -> Result>, NaslError> { // we actually need to panic as a lock error is fatal - // alternatively we need to add a poison error on FunctionErrorKind + // alternatively we need to add a poison error on NaslError Ok(Arc::as_ref(handles).lock().await) } @@ -131,7 +131,7 @@ impl NaslHttp { data: String, method: Method, handle: &mut Handle, - ) -> Result<(Parts, String), FunctionErrorKind> { + ) -> Result<(Parts, String), NaslError> { // Establish TCP connection to the server. let mut config = ClientConfig::builder() @@ -148,31 +148,20 @@ impl NaslHttp { let stream = match TcpStream::connect(format!("{}:{}", ip_str, port)).await { Ok(a) => a, Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )); + return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))); } }; let stream = match connector.connect(server_name, stream).await { Ok(a) => a, Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )); + return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))); } }; let (h2, connection) = match client::handshake(stream).await { Ok((x, y)) => (x, y), - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } + Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), }; tokio::spawn(async move { @@ -181,12 +170,7 @@ impl NaslHttp { let mut h2 = match h2.ready().await { Ok(x) => x, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } + Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), }; // Prepare the HTTP request to send to the server. @@ -216,12 +200,7 @@ impl NaslHttp { while let Some(chunk) = body.data().await { let chunk = match chunk { Ok(byte_chunk) => byte_chunk, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } + Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), }; resp.push_str(&String::from_utf8_lossy(&chunk)); @@ -238,14 +217,10 @@ impl NaslHttp { register: &Register, ctx: &Context<'a>, method: Method, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => { - return Err(FunctionErrorKind::WrongArgument( - ("Invalid handle ID").to_string(), - )) - } + _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), }; let mut handles = lock_handles(&self.handles).await?; @@ -256,7 +231,7 @@ impl NaslHttp { { Some((_i, handle)) => handle, _ => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )) @@ -266,7 +241,7 @@ impl NaslHttp { let item: String = match register.named("item") { Some(x) => x.to_string(), _ => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( "Missing item".to_string(), Some(NaslValue::Null), )) @@ -334,7 +309,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::GET).await } @@ -343,7 +318,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::POST).await } @@ -352,7 +327,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::PUT).await } @@ -361,7 +336,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::HEAD).await } @@ -370,7 +345,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::DELETE).await } @@ -381,7 +356,7 @@ impl NaslHttp { /// On success the function returns a and integer with the handle /// identifier. Null on error. #[nasl_function] - async fn handle(&self) -> Result { + async fn handle(&self) -> Result { let mut handles = lock_handles(&self.handles).await?; let handle_id = next_handle_id(&handles); let h = Handle { @@ -401,7 +376,7 @@ impl NaslHttp { /// The function returns an integer. /// O on success, -1 on error. #[nasl_function(named(handle))] - async fn close_handle(&self, handle: i32) -> Result { + async fn close_handle(&self, handle: i32) -> Result { let mut handles = lock_handles(&self.handles).await?; match handles .iter_mut() @@ -412,7 +387,7 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(FunctionErrorKind::Diagnostic( + _ => Err(NaslError::Diagnostic( format!("Handle ID {} not found", handle), Some(NaslValue::Number(-1)), )), @@ -429,14 +404,10 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => { - return Err(FunctionErrorKind::WrongArgument( - ("Invalid handle ID").to_string(), - )) - } + _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), }; let mut handles = lock_handles(&self.handles).await?; @@ -446,7 +417,7 @@ impl NaslHttp { .find(|(_i, h)| h.handle_id == handle_id) { Some((_i, handle)) => Ok(NaslValue::Number(handle.http_code as i64)), - _ => Err(FunctionErrorKind::Diagnostic( + _ => Err(NaslError::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )), @@ -463,21 +434,17 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let header_item = match register.named("header_item") { Some(ContextType::Value(NaslValue::String(x))) => x, - _ => return Err(FunctionErrorKind::missing_argument("No command passed")), + _ => return Err(NaslError::missing_argument("No command passed")), }; let (key, val) = header_item.split_once(": ").expect("Missing header_item"); let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => { - return Err(FunctionErrorKind::WrongArgument( - ("Invalid handle ID").to_string(), - )) - } + _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), }; let mut handles = lock_handles(&self.handles).await?; @@ -490,7 +457,7 @@ impl NaslHttp { h.header_items.push((key.to_string(), val.to_string())); Ok(NaslValue::Number(0)) } - _ => Err(FunctionErrorKind::Diagnostic( + _ => Err(NaslError::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )), diff --git a/rust/src/nasl/builtin/isotime/mod.rs b/rust/src/nasl/builtin/isotime/mod.rs index 5f9543fd0..a5e75ebbc 100644 --- a/rust/src/nasl/builtin/isotime/mod.rs +++ b/rust/src/nasl/builtin/isotime/mod.rs @@ -41,14 +41,14 @@ fn parse_readable_time(time: &str) -> Option { None } -fn parse_time(time: &str) -> Result { +fn parse_time(time: &str) -> Result { if let Some(time) = parse_isotime(time) { return Ok(time); } if let Some(time) = parse_readable_time(time) { return Ok(time); } - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( format!( "The given time is not in the correct isotime ({}) or readable time format ({}): {}", ISOFORMAT, READABLEFORMAT, time @@ -63,7 +63,7 @@ fn isotime_add( years: Option, days: Option, seconds: Option, -) -> Result { +) -> Result { let mut time = parse_time(time)?; if let Some(years) = years { @@ -83,7 +83,7 @@ fn isotime_add( } if time.year() < 0 || time.year() > 9999 { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!( "The resulting year is out of range (0000-9999): {}.", time.year() @@ -106,12 +106,12 @@ fn isotime_now() -> String { } #[nasl_function] -fn isotime_print(time: &str) -> Result { +fn isotime_print(time: &str) -> Result { Ok(parse_time(time)?.format("%Y-%m-%d %H:%M:%S").to_string()) } #[nasl_function] -fn isotime_scan(time: &str) -> Result { +fn isotime_scan(time: &str) -> Result { let time = parse_time(time)?; Ok(time.format("%Y%m%dT%H%M%S").to_string()) diff --git a/rust/src/nasl/builtin/isotime/tests.rs b/rust/src/nasl/builtin/isotime/tests.rs index eaf6d86a3..cc5fc21f6 100644 --- a/rust/src/nasl/builtin/isotime/tests.rs +++ b/rust/src/nasl/builtin/isotime/tests.rs @@ -21,22 +21,22 @@ mod tests { #[test] fn isotime_scan() { - check_err_matches!("isotime_scan(\"\");", FunctionErrorKind::Diagnostic { .. }); + check_err_matches!("isotime_scan(\"\");", NaslError::Diagnostic { .. }); check_err_matches!( "isotime_scan(\"a8691002T123456\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"18691002T1234\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"18691002T1234512\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"1869-10-02T12:34:56\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_code_result("isotime_scan(\"18691002T123456\");", "18691002T123456"); @@ -47,18 +47,18 @@ mod tests { #[test] fn isotime_print() { - check_err_matches!("isotime_print(\"\");", FunctionErrorKind::Diagnostic { .. }); + check_err_matches!("isotime_print(\"\");", NaslError::Diagnostic { .. }); check_err_matches!( "isotime_print(\"a8691002T123456\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_print(\"18691002T1234\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_print(\"1869-10-02T12:34:56\");", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_code_result("isotime_print(\"18691002T123456\");", "1869-10-02 12:34:56"); @@ -76,17 +76,14 @@ mod tests { #[test] fn isotime_add() { - check_err_matches!( - "isotime_add(\"\", years: 0);", - FunctionErrorKind::Diagnostic { .. } - ); + check_err_matches!("isotime_add(\"\", years: 0);", NaslError::Diagnostic { .. }); check_err_matches!( "isotime_add(\"50001002T120000\", years: 5000);", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_err_matches!( "isotime_add(\"50001002T120000\", years: -5001);", - FunctionErrorKind::Diagnostic { .. } + NaslError::Diagnostic { .. } ); check_code_result( diff --git a/rust/src/nasl/builtin/knowledge_base/mod.rs b/rust/src/nasl/builtin/knowledge_base/mod.rs index 296fd6a83..7ab8c66d2 100644 --- a/rust/src/nasl/builtin/knowledge_base/mod.rs +++ b/rust/src/nasl/builtin/knowledge_base/mod.rs @@ -9,7 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::function_set; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::NaslError; use crate::nasl::utils::Context; use crate::storage::{Field, Kb, Retrieve}; use nasl_function_proc_macro::nasl_function; @@ -22,13 +22,13 @@ fn set_kb_item( name: NaslValue, value: NaslValue, expires: Option, -) -> Result { +) -> Result { let expires = match expires { Some(NaslValue::Number(x)) => Some(x), Some(NaslValue::Exit(0)) => None, None => None, Some(x) => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!("expected expires to be a number but is {x}."), None, )) @@ -56,7 +56,7 @@ fn set_kb_item( /// NASL function to get a knowledge base #[nasl_function] -fn get_kb_item(c: &Context, key: &str) -> Result { +fn get_kb_item(c: &Context, key: &str) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { @@ -73,11 +73,7 @@ fn get_kb_item(c: &Context, key: &str) -> Result { /// NASL function to replace a kb list #[nasl_function(named(name, value))] -fn replace_kb_item( - c: &Context, - name: NaslValue, - value: NaslValue, -) -> Result { +fn replace_kb_item(c: &Context, name: NaslValue, value: NaslValue) -> Result { c.dispatcher() .dispatch_replace( c.key(), @@ -93,7 +89,7 @@ fn replace_kb_item( /// NASL function to retrieve an item in a KB. #[nasl_function] -fn get_kb_list(c: &Context, key: NaslValue) -> Result { +fn get_kb_list(c: &Context, key: NaslValue) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { diff --git a/rust/src/nasl/builtin/knowledge_base/tests.rs b/rust/src/nasl/builtin/knowledge_base/tests.rs index c27e0a817..9750f8508 100644 --- a/rust/src/nasl/builtin/knowledge_base/tests.rs +++ b/rust/src/nasl/builtin/knowledge_base/tests.rs @@ -5,7 +5,7 @@ #[cfg(test)] mod tests { use crate::nasl::test_prelude::*; - use FunctionErrorKind::*; + use NaslError::*; #[test] fn set_kb_item() { @@ -22,12 +22,12 @@ mod tests { check_err_matches!( t, r#"get_kb_item("test", 1);"#, - FunctionErrorKind::TrailingPositionalArguments { .. } + NaslError::TrailingPositionalArguments { .. } ); check_err_matches!( t, r#"get_kb_item();"#, - FunctionErrorKind::MissingPositionalArguments { .. } + NaslError::MissingPositionalArguments { .. } ); } diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index b392176e8..3dd280c95 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -28,7 +28,7 @@ use flate2::{ #[inline] #[cfg(unix)] /// Reads 8 bytes from /dev/urandom and parses it to an i64 -pub fn random_impl() -> Result { +pub fn random_impl() -> Result { let mut rng = File::open("/dev/urandom")?; let mut buffer = [0u8; 8]; rng.read_exact(&mut buffer) @@ -38,7 +38,7 @@ pub fn random_impl() -> Result { /// NASL function to get random number #[nasl_function] -fn rand() -> Result { +fn rand() -> Result { random_impl() } @@ -91,13 +91,11 @@ fn isnull(val: NaslValue) -> bool { /// Returns the seconds counted from 1st January 1970 as an integer. #[nasl_function] -fn unixtime() -> Result { +fn unixtime() -> Result { std::time::SystemTime::now() .duration_since(UNIX_EPOCH) .map(|t| t.as_secs()) - .map_err(|_| { - FunctionErrorKind::Dirty("System time set to time before 1st January 1960".into()) - }) + .map_err(|_| NaslError::Dirty("System time set to time before 1st January 1960".into())) } /// Compress given data with gzip, when headformat is set to 'gzip' it uses gzipheader. @@ -226,13 +224,13 @@ fn defined_func(ctx: &Context, register: &Register, fn_name: Option> /// /// For example: “1067352015.030757” means 1067352015 seconds and 30757 microseconds. #[nasl_function] -fn gettimeofday() -> Result { +fn gettimeofday() -> Result { match time::SystemTime::now().duration_since(time::SystemTime::UNIX_EPOCH) { Ok(time) => { let time = time.as_micros(); Ok(format!("{}.{:06}", time / 1000000, time % 1000000)) } - Err(e) => Err(FunctionErrorKind::Dirty(format!("{e}"))), + Err(e) => Err(NaslError::Dirty(format!("{e}"))), } } diff --git a/rust/src/nasl/builtin/misc/tests.rs b/rust/src/nasl/builtin/misc/tests.rs index 99936771d..8d12057e4 100644 --- a/rust/src/nasl/builtin/misc/tests.rs +++ b/rust/src/nasl/builtin/misc/tests.rs @@ -38,7 +38,7 @@ mod tests { check_err_matches!( t, r#"typeof(23,76);"#, - FunctionErrorKind::TrailingPositionalArguments { .. } + NaslError::TrailingPositionalArguments { .. } ); t.ok("d['test'] = 2;", 2); t.ok("typeof(d);", "array"); diff --git a/rust/src/nasl/builtin/network/mod.rs b/rust/src/nasl/builtin/network/mod.rs index 30a169def..f5537df3d 100644 --- a/rust/src/nasl/builtin/network/mod.rs +++ b/rust/src/nasl/builtin/network/mod.rs @@ -5,7 +5,7 @@ use std::{fmt::Display, net::IpAddr}; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{Context, FunctionErrorKind}; +use crate::nasl::utils::{Context, NaslError}; use crate::storage::{Field, Retrieve}; #[allow(clippy::module_inception)] @@ -75,7 +75,7 @@ impl Display for OpenvasEncaps { } } -pub fn get_kb_item(context: &Context, name: &str) -> Result, FunctionErrorKind> { +pub fn get_kb_item(context: &Context, name: &str) -> Result, NaslError> { context .retriever() .retrieve(context.key(), Retrieve::KB(name.to_string())) @@ -89,9 +89,9 @@ pub fn get_kb_item(context: &Context, name: &str) -> Result, F .map_err(|e| e.into()) } -pub fn verify_port(port: i64) -> Result { +pub fn verify_port(port: i64) -> Result { if !(0..=65535).contains(&port) { - return Err(FunctionErrorKind::WrongArgument(format!( + return Err(NaslError::WrongArgument(format!( "{} is not a valid port number", port ))); diff --git a/rust/src/nasl/builtin/network/network.rs b/rust/src/nasl/builtin/network/network.rs index b0e92dd30..725805093 100644 --- a/rust/src/nasl/builtin/network/network.rs +++ b/rust/src/nasl/builtin/network/network.rs @@ -10,7 +10,7 @@ use super::{ verify_port, DEFAULT_PORT, }; use crate::function_set; -use crate::nasl::utils::{Context, FunctionErrorKind}; +use crate::nasl::utils::{Context, NaslError}; use crate::storage::{types::Primitive, Field, Kb}; use nasl_function_proc_macro::nasl_function; @@ -22,7 +22,7 @@ fn get_host_ip(context: &Context) -> String { /// Get the IP address of the current (attacking) machine depending on which network device is used #[nasl_function] -fn this_host(context: &Context) -> Result { +fn this_host(context: &Context) -> Result { let dst = ipstr2ipaddr(context.target())?; let port: u16 = DEFAULT_PORT; @@ -42,21 +42,21 @@ fn this_host_name() -> String { /// get the maximum transition unit for the scanned host #[nasl_function] -fn get_mtu(context: &Context) -> Result { +fn get_mtu(context: &Context) -> Result { let target = ipstr2ipaddr(context.target())?; Ok(mtu(target) as i64) } /// check if the currently scanned host is the localhost #[nasl_function] -fn nasl_islocalhost(context: &Context) -> Result { +fn nasl_islocalhost(context: &Context) -> Result { let host_ip = ipstr2ipaddr(context.target())?; Ok(islocalhost(host_ip)) } /// Check if the target host is on the same network as the attacking host #[nasl_function] -fn islocalnet(context: &Context) -> Result { +fn islocalnet(context: &Context) -> Result { let dst = ipstr2ipaddr(context.target())?; let src = get_source_ip(dst, DEFAULT_PORT)?; let netmask = match get_netmask_by_local_ip(src)? { @@ -131,11 +131,7 @@ fn islocalnet(context: &Context) -> Result { /// Declares an open port on the target host #[nasl_function(named(port, proto))] -fn scanner_add_port( - context: &Context, - port: i64, - proto: Option<&str>, -) -> Result<(), FunctionErrorKind> { +fn scanner_add_port(context: &Context, port: i64, proto: Option<&str>) -> Result<(), NaslError> { let port = verify_port(port)?; let protocol = proto.unwrap_or("tcp"); diff --git a/rust/src/nasl/builtin/network/network_utils.rs b/rust/src/nasl/builtin/network/network_utils.rs index 1ecfcd5da..15efee7ad 100644 --- a/rust/src/nasl/builtin/network/network_utils.rs +++ b/rust/src/nasl/builtin/network/network_utils.rs @@ -12,10 +12,10 @@ use std::{ use crate::nasl::prelude::*; /// Convert a string in a IpAddr -pub fn ipstr2ipaddr(ip_addr: &str) -> Result { +pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(NaslError::Diagnostic( format!("Invalid IP address ({})", ip_addr), Some(NaslValue::Null), )), @@ -23,11 +23,8 @@ pub fn ipstr2ipaddr(ip_addr: &str) -> Result { } /// Bind a local UDP socket to a V4 or V6 address depending on the given destination address -pub fn bind_local_socket(dst: &SocketAddr) -> Result { - let fe = Err(FunctionErrorKind::Diagnostic( - "Error binding".to_string(), - None, - )); +pub fn bind_local_socket(dst: &SocketAddr) -> Result { + let fe = Err(NaslError::Diagnostic("Error binding".to_string(), None)); match dst { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0").or(fe), SocketAddr::V6(_) => UdpSocket::bind("[::]:0").or(fe), @@ -35,7 +32,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result Result { +pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { let socket = SocketAddr::new(dst, port); let sd = format!("{}:{}", dst, port); let local_socket = bind_local_socket(&socket)?; @@ -44,7 +41,7 @@ pub fn get_source_ip(dst: IpAddr, port: u16) -> Result bool { } /// Get the interface from the local ip -pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, FunctionErrorKind> { +pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, NaslError> { let mut interfaces: *mut libc::ifaddrs = ptr::null_mut(); let ret = unsafe { libc::getifaddrs(&mut interfaces) }; if ret < 0 { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( "Error getting interfaces".to_string(), None, )); @@ -126,7 +123,7 @@ pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, unsafe { libc::freeifaddrs(interfaces); } - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( "No route to destination".to_string(), None, )) diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index 0ec4a474d..c7ec81497 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -14,7 +14,7 @@ use std::{ use crate::function_set; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{error::FunctionErrorKind, Context}; +use crate::nasl::utils::{error::NaslError, Context}; use dns_lookup::lookup_host; use nasl_function_proc_macro::nasl_function; use pkcs8::der::Decode; @@ -65,12 +65,7 @@ impl TCPConnection { /// Send data on a TCP connection using the libc send function. /// To ensure safety of the function, the caller must ensure, that the given length does not /// exceed the length of the given data data. - unsafe fn send( - &self, - mut data: &[u8], - len: usize, - flags: i32, - ) -> Result { + unsafe fn send(&self, mut data: &[u8], len: usize, flags: i32) -> Result { let fd = self.socket.as_raw_fd(); let mut ret = 0; while !data.is_empty() { @@ -95,12 +90,7 @@ impl UDPConnection { /// Send data on a UDP connection using the libc send function. /// To ensure safety of the function, the caller must ensure, that the given length does not /// exceed the length of the given data data. - unsafe fn send( - &mut self, - data: &[u8], - len: usize, - flags: i32, - ) -> Result { + unsafe fn send(&mut self, data: &[u8], len: usize, flags: i32) -> Result { let fd = self.socket.as_raw_fd(); let ip = self.socket.peer_addr()?.ip(); @@ -108,7 +98,7 @@ impl UDPConnection { let mtu = mtu(ip); if len > mtu { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!( "udp data of size {} exceeds the maximum length of {}", len, mtu @@ -145,11 +135,11 @@ pub struct NaslSockets { } impl NaslSockets { - fn resolve_socket_addr(addr: IpAddr, port: u16) -> Result { + fn resolve_socket_addr(addr: IpAddr, port: u16) -> Result { (addr, port) .to_socket_addrs()? .next() - .ok_or(FunctionErrorKind::Diagnostic( + .ok_or(NaslError::Diagnostic( format!( "the given address and port do not correspond to a valid address: {addr}:{port}" ), @@ -157,7 +147,7 @@ impl NaslSockets { )) } - fn open_udp(addr: IpAddr, port: u16) -> Result { + fn open_udp(addr: IpAddr, port: u16) -> Result { let sock_addr = Self::resolve_socket_addr(addr, port)?; let socket = bind_local_socket(&sock_addr)?; socket.connect(sock_addr)?; @@ -174,7 +164,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, tls_config: Option<&TLSConfig>, - ) -> Result { + ) -> Result { // Resolve Address and Port to SocketAddr let sock_addr = Self::resolve_socket_addr(addr, port)?; // Create Vec depending of buffer size @@ -203,7 +193,7 @@ impl NaslSockets { Some(config) => Some( ClientConnection::new(Arc::new(config.config.clone()), config.server.clone()) .map_err(|e| { - FunctionErrorKind::Diagnostic( + NaslError::Diagnostic( format!("Unable to establish TLS connection: {e}"), None, ) @@ -235,11 +225,11 @@ impl NaslSockets { /// Close a given file descriptor taken as an unnamed argument. #[nasl_function] - fn close(&self, socket_fd: usize) -> Result { + fn close(&self, socket_fd: usize) -> Result { let mut handles = self.handles.write().unwrap(); match handles.handles.get_mut(socket_fd) { Some(NaslSocket::Close) => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( "the given socket FD is already closed".to_string(), None, )) @@ -249,7 +239,7 @@ impl NaslSockets { handles.closed_fd.push(socket_fd); } None => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( "the given socket FD does not exist".to_string(), None, )) @@ -280,7 +270,7 @@ impl NaslSockets { data: &[u8], flags: Option, len: Option, - ) -> Result { + ) -> Result { let len = if let Some(len) = len { if len < 1 || len > data.len() { data.len() @@ -299,7 +289,7 @@ impl NaslSockets { .unwrap() .handles .get_mut(socket) - .ok_or(FunctionErrorKind::WrongArgument(format!( + .ok_or(NaslError::WrongArgument(format!( "the given socket FD {socket} does not exist" )))? { NaslSocket::Tcp(conn) => { @@ -321,7 +311,7 @@ impl NaslSockets { } } NaslSocket::Udp(conn) => unsafe { conn.send(data, len, flags.unwrap_or(0) as i32) }, - NaslSocket::Close => Err(FunctionErrorKind::WrongArgument( + NaslSocket::Close => Err(NaslError::WrongArgument( "the given socket FD is already closed".to_string(), )), } @@ -332,7 +322,7 @@ impl NaslSockets { data: &mut [u8], len: usize, min: usize, - ) -> Result<(), FunctionErrorKind> { + ) -> Result<(), NaslError> { let mut ret = 0; while ret < len && ret < min { let n = socket.read(&mut data[ret..]).or_else(|e| match e.kind() { @@ -361,7 +351,7 @@ impl NaslSockets { len: usize, min: Option, timeout: Option, - ) -> Result { + ) -> Result { let min = min .map(|min| if min < 0 { len } else { min as usize }) .unwrap_or(len); @@ -375,7 +365,7 @@ impl NaslSockets { .unwrap() .handles .get_mut(socket) - .ok_or(FunctionErrorKind::WrongArgument(format!( + .ok_or(NaslError::WrongArgument(format!( "the given socket FD {socket} does not exist" )))? { NaslSocket::Tcp(conn) => { @@ -422,7 +412,7 @@ impl NaslSockets { conn.socket.send(&conn.buffer)?; } kind => { - ret = Err(FunctionErrorKind::IOError(kind)); + ret = Err(NaslError::IOError(kind)); break; } }, @@ -435,7 +425,7 @@ impl NaslSockets { } ret } - NaslSocket::Close => Err(FunctionErrorKind::WrongArgument( + NaslSocket::Close => Err(NaslError::WrongArgument( "the given socket FD is already closed".to_string(), )), } @@ -446,10 +436,10 @@ impl NaslSockets { /// - Secret/kdc_port /// - Secret/kdc_use_tcp #[nasl_function] - fn open_sock_kdc(&self, context: &Context) -> Result { + fn open_sock_kdc(&self, context: &Context) -> Result { let hostname = match get_kb_item(context, "Secret/kdc_hostname")? { Some(x) => Ok(x.to_string()), - None => Err(FunctionErrorKind::Diagnostic( + None => Err(NaslError::Diagnostic( "KB key 'Secret/kdc_hostname' is not set".to_string(), None, )), @@ -457,11 +447,11 @@ impl NaslSockets { let ip = lookup_host(&hostname) .map_err(|_| { - FunctionErrorKind::Diagnostic(format!("unable to lookup hostname {hostname}"), None) + NaslError::Diagnostic(format!("unable to lookup hostname {hostname}"), None) })? .into_iter() .next() - .ok_or(FunctionErrorKind::Diagnostic( + .ok_or(NaslError::Diagnostic( format!("No IP found for hostname {hostname}"), None, ))?; @@ -471,7 +461,7 @@ impl NaslSockets { let port = match port { Some(NaslValue::Number(x)) => { if x <= 0 || x > 65535 { - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( "KB key 'Secret/kdc_port' out of range".to_string(), port, )) @@ -479,11 +469,11 @@ impl NaslSockets { Ok(x as u16) } } - Some(_) => Err(FunctionErrorKind::Diagnostic( + Some(_) => Err(NaslError::Diagnostic( "KB key 'Secret/kdc_port' has wrong type".to_string(), port, )), - None => Err(FunctionErrorKind::Diagnostic( + None => Err(NaslError::Diagnostic( "KB key 'Secret/kdc_port' is not set".to_string(), None, )), @@ -529,14 +519,14 @@ impl NaslSockets { bufsz: Option, // TODO: Extract information from custom priority string // priority: Option<&str>, - ) -> Result { + ) -> Result { // Get port let port = verify_port(port)?; let transport = transport.unwrap_or(-1); let addr = context.target(); if addr.is_empty() { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "A target must be specified to open a socket".to_string(), )); } @@ -591,7 +581,7 @@ impl NaslSockets { } // Unsupported transport layer None | Some(OpenvasEncaps::Max) => { - return Err(FunctionErrorKind::WrongArgument(format!( + return Err(NaslError::WrongArgument(format!( "unsupported transport layer: {transport}(unknown)" ))) } @@ -603,7 +593,7 @@ impl NaslSockets { fds.push(self.add(fd)) } _ => { - return Err(FunctionErrorKind::WrongArgument(format!( + return Err(NaslError::WrongArgument(format!( "unsupported transport layer: {transport}{tls_version}" ))) } @@ -626,7 +616,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, tls_config: Option, - ) -> Result { + ) -> Result { let addr = ipstr2ipaddr(addr)?; let mut retry = super::get_kb_item(context, "timeout_retry")? .map(|val| match val { @@ -640,7 +630,7 @@ impl NaslSockets { match Self::open_tcp(addr, port, bufsz, timeout, tls_config.as_ref()) { Ok(socket) => return Ok(socket), Err(err) => { - if !matches!(err, FunctionErrorKind::IOError(io::ErrorKind::TimedOut)) { + if !matches!(err, NaslError::IOError(io::ErrorKind::TimedOut)) { return Err(err); } retry -= 1; @@ -652,10 +642,10 @@ impl NaslSockets { // 2. Log too many timeouts // 3. Create result of type error with: // ERRMSG|||||||||/tcp||| ||| Too many timeouts. The port was set to closed - Err(FunctionErrorKind::IOError(io::ErrorKind::TimedOut)) + Err(NaslError::IOError(io::ErrorKind::TimedOut)) } - fn load_private_key(filename: &str) -> Result, FunctionErrorKind> { + fn load_private_key(filename: &str) -> Result, NaslError> { let keyfile = fs::File::open(filename)?; let mut reader = BufReader::new(keyfile); @@ -669,7 +659,7 @@ impl NaslSockets { } } - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( format!( "no keys found in {:?} (encrypted keys not supported)", filename @@ -686,15 +676,15 @@ impl NaslSockets { bufsz: Option, timeout: Duration, hostname: &str, - ) -> Result { + ) -> Result { let cert_path = get_kb_item(context, "SSL/cert")? - .ok_or(FunctionErrorKind::Diagnostic( + .ok_or(NaslError::Diagnostic( "unable to open TLS connection: kes 'SSL/cert' is missing".to_string(), None, ))? .to_string(); let key_path = get_kb_item(context, "SSL/key")? - .ok_or(FunctionErrorKind::Diagnostic( + .ok_or(NaslError::Diagnostic( "unable to open TLS connection: kes 'SSL/key' is missing".to_string(), None, ))? @@ -703,16 +693,15 @@ impl NaslSockets { .unwrap_or(NaslValue::Null) .to_string(); let cafile_path = get_kb_item(context, "SSL/CA")? - .ok_or(FunctionErrorKind::Diagnostic( + .ok_or(NaslError::Diagnostic( "unable to open TLS connection: kes 'SSL/CA' is missing".to_string(), None, ))? .to_string(); // TODO: From vhost name - let server = ServerName::try_from(hostname.to_owned()).map_err(|_| { - FunctionErrorKind::Dirty(format!("Given vHost Name {hostname} is not valid")) - })?; + let server = ServerName::try_from(hostname.to_owned()) + .map_err(|_| NaslError::Dirty(format!("Given vHost Name {hostname} is not valid")))?; let mut root_store = RootCertStore::empty(); let ca_file = fs::File::open(cafile_path)?; @@ -732,13 +721,13 @@ impl NaslSockets { if !password.is_empty() { let encrypted_key = pkcs8::EncryptedPrivateKeyInfo::from_der(key.secret_der()) .map_err(|_| { - FunctionErrorKind::Diagnostic( + NaslError::Diagnostic( format!("Unable to decrypt private key {key_path} with given password"), None, ) })?; let decrypted_key = encrypted_key.decrypt(password).map_err(|_| { - FunctionErrorKind::Diagnostic( + NaslError::Diagnostic( format!("Unable to decrypt private key {key_path} with given password"), None, ) @@ -751,7 +740,7 @@ impl NaslSockets { let config = ClientConfig::builder() .with_root_certificates(root_store) .with_client_auth_cert(cert, key) - .map_err(|_| FunctionErrorKind::WrongArgument("Invalid Key".to_string()))?; + .map_err(|_| NaslError::WrongArgument("Invalid Key".to_string()))?; self.open_sock_tcp_ip( context, @@ -765,7 +754,7 @@ impl NaslSockets { /// Open a UDP socket to the target host #[nasl_function] - fn open_sock_udp(&self, context: &Context, port: i64) -> Result { + fn open_sock_udp(&self, context: &Context, port: i64) -> Result { let port = verify_port(port)?; let addr = ipstr2ipaddr(context.target())?; diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 44f2aa9ba..fc5773ddc 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -105,11 +105,11 @@ impl From<&Frame> for Vec { } impl TryFrom<&[u8]> for Frame { - type Error = FunctionErrorKind; + type Error = NaslError; fn try_from(f: &[u8]) -> Result { if f.len() < 14 { - Err(FunctionErrorKind::missing_argument("valid ip address")) + Err(NaslError::missing_argument("valid ip address")) } else { let mut frame = Frame::new(); frame.set_dsthaddr(MacAddr(f[0], f[1], f[2], f[3], f[4], f[5])); @@ -272,15 +272,13 @@ fn convert_vec_into_mac_address(v: &[u8]) -> Option { } } -fn validate_mac_address(v: Option<&ContextType>) -> Result { +fn validate_mac_address(v: Option<&ContextType>) -> Result { let mac_addr = match v { Some(ContextType::Value(NaslValue::String(x))) => MacAddr::from_str(x).ok(), Some(ContextType::Value(NaslValue::Data(x))) => convert_vec_into_mac_address(x), _ => None, }; - mac_addr.ok_or_else(|| { - FunctionErrorKind::wrong_unnamed_argument("mac address", "invalid mac address") - }) + mac_addr.ok_or_else(|| NaslError::wrong_unnamed_argument("mac address", "invalid mac address")) } /// Return the MAC address, given the interface name @@ -293,7 +291,7 @@ fn get_local_mac_address(name: &str) -> Option { /// Return a frame given a capture device and a filter. It returns an empty frame in case /// there was no response or anything was filtered. -fn recv_frame(cap: &mut Capture, filter: &str) -> Result { +fn recv_frame(cap: &mut Capture, filter: &str) -> Result { let f = Frame::new(); let p = match cap.filter(filter, true) { @@ -313,7 +311,7 @@ fn send_frame( pcap_active: &bool, filter: Option<&String>, timeout: i32, -) -> Result, FunctionErrorKind> { +) -> Result, NaslError> { let mut capture_dev = match Capture::from_device(iface.clone()) { Ok(c) => match c.promisc(true).timeout(timeout).open() { Ok(mut capture) => match capture.sendpacket(frame) { @@ -346,15 +344,12 @@ fn send_frame( /// /// It takes the following argument: /// - cap_timeout: time to wait for answer in seconds, 5 by default -fn nasl_send_arp_request( - register: &Register, - context: &Context, -) -> Result { +fn nasl_send_arp_request(register: &Register, context: &Context) -> Result { let timeout = match register.named("pcap_timeout") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -364,7 +359,7 @@ fn nasl_send_arp_request( let target_ip = get_host_ip(context)?; if target_ip.is_ipv6() { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "IPv4", "IPv6 does not support ARP protocol.", )); @@ -374,7 +369,7 @@ fn nasl_send_arp_request( let local_mac_address = match get_local_mac_address(&iface.name) { Some(x) => x, _ => { - return Err(FunctionErrorKind::missing_argument( + return Err(NaslError::missing_argument( "Not possible to get a src mac address.", )) } @@ -383,7 +378,7 @@ fn nasl_send_arp_request( let src_ip = match Ipv4Addr::from_str(&local_ip.to_string()) { Ok(x) => x, Err(_) => { - return Err(FunctionErrorKind::missing_argument( + return Err(NaslError::missing_argument( "Not possible to parse the src IP address.", )) } @@ -392,7 +387,7 @@ fn nasl_send_arp_request( let dst_ip = match Ipv4Addr::from_str(&target_ip.to_string()) { Ok(x) => x, Err(_) => { - return Err(FunctionErrorKind::missing_argument( + return Err(NaslError::missing_argument( "Not possible to parse the dst IP address.", )) } @@ -412,10 +407,10 @@ fn nasl_send_arp_request( fn nasl_get_local_mac_address_from_ip( register: &Register, _: &Context, -) -> Result { +) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::MissingPositionalArguments { + return Err(NaslError::MissingPositionalArguments { expected: 1, got: 0, }); @@ -427,13 +422,13 @@ fn nasl_get_local_mac_address_from_ip( let iface = get_interface_by_local_ip(ip)?; match get_local_mac_address(&iface.name) { Some(mac) => Ok(NaslValue::String(mac.to_string())), - _ => Err(FunctionErrorKind::Diagnostic( + _ => Err(NaslError::Diagnostic( "Not possible to get the local mac address".to_string(), Some(NaslValue::Null), )), } } - _ => Err(FunctionErrorKind::WrongArgument( + _ => Err(NaslError::WrongArgument( "Expected String containing a valid IP address.".to_string(), )), } @@ -445,7 +440,7 @@ fn nasl_get_local_mac_address_from_ip( /// - ether_proto: is an int containing the ethernet type (normally given as hexadecimal). /// It is optional and its default value is 0x0800. A list of Types can be e.g. looked up here. /// - payload: is any data, which is then attached as payload to the frame. -fn nasl_forge_frame(register: &Register, _: &Context) -> Result { +fn nasl_forge_frame(register: &Register, _: &Context) -> Result { let src_haddr = validate_mac_address(register.named("src_haddr"))?; let dst_haddr = validate_mac_address(register.named("dst_haddr"))?; let ether_proto = match register.named("ether_proto") { @@ -473,11 +468,11 @@ fn nasl_forge_frame(register: &Register, _: &Context) -> Result Result { +fn nasl_send_frame(register: &Register, context: &Context) -> Result { let frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => x, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Data", "Invalid data type", )) @@ -488,7 +483,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result x, None => &true, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -499,7 +494,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Some(x), None => None, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -510,7 +505,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -532,11 +527,11 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Result { +fn nasl_dump_frame(register: &Register, _: &Context) -> Result { let frame: Frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => (x as &[u8]).try_into()?, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Data", "Invalid data type", )) diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 3a477f2ff..7872ec381 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -36,7 +36,7 @@ use tracing::debug; macro_rules! custom_error { ($a:expr, $b:expr) => { - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( format!($a, $b), Some(NaslValue::Null), )) @@ -88,7 +88,7 @@ fn safe_copy_from_slice( o_buf: &[u8], o_init: usize, o_fin: usize, -) -> Result<(), FunctionErrorKind> { +) -> Result<(), NaslError> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -97,7 +97,7 @@ fn safe_copy_from_slice( || d_buf.len() < d_fin || o_buf.len() < o_fin { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "Error copying from slice. Index out of range".to_string(), )); } @@ -121,11 +121,11 @@ fn safe_copy_from_slice( /// - ip_v is: the IP version. 4 by default. /// /// Returns the IP datagram or NULL on error. -fn forge_ip_packet(register: &Register, configs: &Context) -> Result { +fn forge_ip_packet(register: &Register, configs: &Context) -> Result { let dst_addr = get_host_ip(configs)?; if dst_addr.is_ipv6() { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "forge_ip_packet: No valid dst_addr could be determined via call to get_host_ip()" .to_string(), )); @@ -141,7 +141,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result { - return Err(FunctionErrorKind::WrongArgument(format!( - "Invalid ip_src: {}", - e - ))); + return Err(NaslError::WrongArgument(format!("Invalid ip_src: {}", e))); } }; x.to_string() @@ -220,10 +217,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result { - return Err(FunctionErrorKind::WrongArgument(format!( - "Invalid ip_dst: {}", - e - ))); + return Err(NaslError::WrongArgument(format!("Invalid ip_dst: {}", e))); } }; x.to_string() @@ -234,10 +228,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result { - return Err(FunctionErrorKind::WrongArgument(format!( - "Invalid ip: {}", - e - ))); + return Err(NaslError::WrongArgument(format!("Invalid ip: {}", e))); } }; dst_addr.to_string() @@ -268,19 +259,16 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result { +fn set_ip_elements(register: &Register, _configs: &Context) -> Result { let mut buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(NaslError::missing_argument("ip")); } }; let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Diagnostic( + NaslError::Diagnostic( "No possible to create a packet from buffer".to_string(), None, ) @@ -334,10 +322,7 @@ fn set_ip_elements( pkt.set_source(ip); } Err(e) => { - return Err(FunctionErrorKind::WrongArgument(format!( - "Invalid ip_src: {}", - e - ))); + return Err(NaslError::WrongArgument(format!("Invalid ip_src: {}", e))); } }; }; @@ -367,16 +352,16 @@ fn set_ip_elements( /// - ip_sum /// - ip_src /// - ip_dst -fn get_ip_element(register: &Register, _configs: &Context) -> Result { +fn get_ip_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(NaslError::missing_argument("ip")); } }; let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("element") { @@ -392,19 +377,17 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Number(pkt.get_checksum() as i64)), "ip_src" => Ok(NaslValue::String(pkt.get_source().to_string())), "ip_dst" => Ok(NaslValue::String(pkt.get_destination().to_string())), - _ => Err(FunctionErrorKind::WrongArgument( - "Invalid element".to_string(), - )), + _ => Err(NaslError::WrongArgument("Invalid element".to_string())), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(NaslError::missing_argument("element")), } } /// Receive a list of IP packets and print them in a readable format in the screen. -fn dump_ip_packet(register: &Register, _: &Context) -> Result { +fn dump_ip_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::MissingPositionalArguments { + return Err(NaslError::MissingPositionalArguments { expected: 1, got: 0, }); @@ -414,9 +397,7 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { let pkt = packet::ipv4::Ipv4Packet::new(data).ok_or_else(|| { - FunctionErrorKind::Dirty( - "No possible to create a packet from buffer".to_string(), - ) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; println!("\tip_hl={}", pkt.get_header_length()); @@ -433,9 +414,7 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { - return Err(FunctionErrorKind::WrongArgument( - "Invalid ip packet".to_string(), - )); + return Err(NaslError::WrongArgument("Invalid ip packet".to_string())); } } } @@ -460,34 +439,31 @@ fn dump_protocol(pkt: &Ipv4Packet) -> String { /// - code: is the identifier of the option to add /// - length: is the length of the option data /// - value: is the option data -fn insert_ip_options( - register: &Register, - _configs: &Context, -) -> Result { +fn insert_ip_options(register: &Register, _configs: &Context) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(NaslError::missing_argument("ip")); } }; let code = match register.named("code") { Some(ContextType::Value(NaslValue::Number(x))) => *x, _ => { - return Err(FunctionErrorKind::missing_argument("code")); + return Err(NaslError::missing_argument("code")); } }; let length = match register.named("length") { Some(ContextType::Value(NaslValue::Number(x))) => *x as usize, _ => { - return Err(FunctionErrorKind::missing_argument("length")); + return Err(NaslError::missing_argument("length")); } }; let value = match register.named("value") { Some(ContextType::Value(NaslValue::String(x))) => x.as_bytes(), Some(ContextType::Value(NaslValue::Data(x))) => x, _ => { - return Err(FunctionErrorKind::missing_argument("value")); + return Err(NaslError::missing_argument("value")); } }; @@ -532,7 +508,7 @@ fn insert_ip_options( )?; let mut new_pkt = MutableIpv4Packet::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let checksum = checksum(&new_pkt.to_immutable()); new_pkt.set_checksum(checksum); @@ -557,15 +533,12 @@ fn insert_ip_options( /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. /// /// The modified IP datagram or NULL on error. -fn forge_tcp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_tcp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { // Missingarguments - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(NaslError::missing_argument("ip")); } }; let original_ip_len = ip_buf.len(); @@ -581,7 +554,7 @@ fn forge_tcp_packet( let total_length = 20 + data.len(); let mut buf = vec![0; total_length]; let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; if !data.is_empty() { @@ -630,24 +603,24 @@ fn forge_tcp_packet( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let tcp_aux = TcpPacket::new(tcp_seg.packet()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; tcp_seg.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { @@ -680,22 +653,19 @@ fn forge_tcp_packet( /// - data /// /// Returns an TCP element from a IP datagram. -fn get_tcp_element( - register: &Register, - _configs: &Context, -) -> Result { +fn get_tcp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(NaslError::missing_argument("tcp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let tcp = packet::tcp::TcpPacket::new(ip.payload()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("element") { @@ -711,9 +681,9 @@ fn get_tcp_element( "th_sum" => Ok(NaslValue::Number(tcp.get_checksum() as i64)), "th_urp" => Ok(NaslValue::Number(tcp.get_urgent_ptr() as i64)), "th_data" => Ok(NaslValue::Data(tcp.payload().to_vec())), - _ => Err(FunctionErrorKind::WrongArgument("element".to_string())), + _ => Err(NaslError::WrongArgument("element".to_string())), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(NaslError::missing_argument("element")), } } @@ -728,19 +698,19 @@ fn get_tcp_element( /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. /// /// The returned option depends on the given *option* parameter. It is either an int for option 2, 3 and 4 or an array containing the two values for option 8. -fn get_tcp_option(register: &Register, _configs: &Context) -> Result { +fn get_tcp_option(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(NaslError::missing_argument("tcp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let tcp = packet::tcp::TcpPacket::new(ip.payload()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let mut max_seg: i64 = 0; @@ -783,11 +753,9 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Number(window)), 4 => Ok(NaslValue::Number(sack_permitted)), 8 => Ok(NaslValue::Array(timestamps)), - _ => Err(FunctionErrorKind::WrongArgument( - "Invalid option".to_string(), - )), + _ => Err(NaslError::WrongArgument("Invalid option".to_string())), }, - _ => Err(FunctionErrorKind::missing_argument("option")), + _ => Err(NaslError::missing_argument("option")), } } @@ -806,19 +774,16 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Result { +fn set_tcp_elements(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(NaslError::missing_argument("tcp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let iph_len = ip.get_header_length() as usize * 4; // the header length is given in 32-bits words @@ -841,7 +806,7 @@ fn set_tcp_elements( //new_buf[..20].copy_from_slice(&ori_tcp_buf[..20]); safe_copy_from_slice(&mut new_buf[..], 0, 20, &ori_tcp_buf, 0, 20)?; ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; ori_tcp.set_payload(&data); } else { @@ -858,7 +823,7 @@ fn set_tcp_elements( ori_tcp_buf.len(), )?; ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; } @@ -896,10 +861,10 @@ fn set_tcp_elements( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } @@ -920,7 +885,7 @@ fn set_tcp_elements( let l = new_ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut new_ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; // pnet will panic if the total length set in the ip datagram field does not much with the total length. @@ -951,21 +916,18 @@ fn set_tcp_elements( /// - 3: TCPOPT_WINDOW, with values between 0 and 14 /// - 4: TCPOPT_SACK_PERMITTED, no value required. /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. -fn insert_tcp_options( - register: &Register, - _configs: &Context, -) -> Result { +fn insert_tcp_options(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "insert_tcp_options: missing field".to_string(), )); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let iph_len = ip.get_header_length() as usize * 4; // the header length is given in 32-bits words let ori_tcp_buf = <&[u8]>::clone(&ip.payload()).to_owned(); @@ -978,7 +940,7 @@ fn insert_tcp_options( Some(ContextType::Value(NaslValue::Number(d))) => d.to_be_bytes().to_vec(), _ => { let tcp = TcpPacket::new(&ori_tcp_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; tcp.payload().to_vec() } @@ -987,7 +949,7 @@ fn insert_tcp_options( // Forge the options field let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "Missing optional arguments. At least one optional porsitional argument followed by its value must be given".to_string() )); } @@ -1003,7 +965,7 @@ fn insert_tcp_options( opts.push(TcpOption::mss(v)); opts_len += 4; } else { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "Invalid value for tcp option TCPOPT_MAXSEG".to_string(), )); } @@ -1014,7 +976,7 @@ fn insert_tcp_options( opts.push(TcpOption::wscale(v)); opts_len += 3; } else { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "Invalid value for tcp option TCPOPT_WINDOW".to_string(), )); } @@ -1032,19 +994,19 @@ fn insert_tcp_options( opts.push(TcpOption::timestamp(v1, v2)); opts_len += 10; } else { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "Invalid value for tcp option TCPOPT_TIMESTAMP".to_string(), )); } } else { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "Invalid value for tcp option TCPOPT_TIMESTAMP".to_string(), )); } } None => break, _ => { - return Err(FunctionErrorKind::WrongArgument( + return Err(NaslError::WrongArgument( "insert_tcp_options: invalid tcp option".to_string(), )); } @@ -1072,7 +1034,7 @@ fn insert_tcp_options( safe_copy_from_slice(&mut new_buf[..], 0, 20, &ori_tcp_buf, 0, 20)?; ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; // At this point, opts len is a 4bytes multiple and the offset is expressed in 32bits words @@ -1089,10 +1051,10 @@ fn insert_tcp_options( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } @@ -1112,7 +1074,7 @@ fn insert_tcp_options( let l = new_ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut new_ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; // pnet will panic if the total length set in the ip datagram field does not much with the total length. @@ -1136,10 +1098,10 @@ fn insert_tcp_options( } /// Receive a list of IPv4 datagrams and print their TCP part in a readable format in the screen. -fn dump_tcp_packet(register: &Register, _: &Context) -> Result { +fn dump_tcp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "Missing arguments. It needs at least one tcp packet".to_string(), )); } @@ -1150,9 +1112,7 @@ fn dump_tcp_packet(register: &Register, _: &Context) -> Result ip, None => { - return Err(FunctionErrorKind::WrongArgument( - "Invalid TCP packet".to_string(), - )); + return Err(NaslError::WrongArgument("Invalid TCP packet".to_string())); } }; @@ -1174,16 +1134,12 @@ fn dump_tcp_packet(register: &Register, _: &Context) -> Result { - return Err(FunctionErrorKind::WrongArgument( - "Invalid TCP packet".to_string(), - )); + return Err(NaslError::WrongArgument("Invalid TCP packet".to_string())); } } } _ => { - return Err(FunctionErrorKind::WrongArgument( - "Invalid ip packet".to_string(), - )); + return Err(NaslError::WrongArgument("Invalid ip packet".to_string())); } } } @@ -1240,13 +1196,10 @@ fn format_flags(pkt: &TcpPacket) -> String { /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. /// /// Returns the modified IP datagram or NULL on error. -fn forge_udp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_udp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), - _ => return Err(FunctionErrorKind::missing_argument("ip")), + _ => return Err(NaslError::missing_argument("ip")), }; let original_ip_len = ip_buf.len(); @@ -1261,7 +1214,7 @@ fn forge_udp_packet( let total_length = 8 + data.len(); let mut buf = vec![0; total_length]; let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; if !data.is_empty() { @@ -1286,24 +1239,24 @@ fn forge_udp_packet( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let udp_aux = UdpPacket::new(udp_datagram.packet()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::udp::ipv4_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } }; let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; udp_datagram.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { @@ -1326,19 +1279,16 @@ fn forge_udp_packet( /// - uh_sport: is the source port. NASL will convert it into network order if necessary. 0 by default. /// - uh_sum: is the UDP checksum. Although it is not compulsory, the right value is computed by default. /// - uh_ulen: is the data length. By default it is set to the length the data argument plus the size of the UDP header. -fn set_udp_elements( - register: &Register, - _configs: &Context, -) -> Result { +fn set_udp_elements(register: &Register, _configs: &Context) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("udp")); + return Err(NaslError::missing_argument("udp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let iph_len = ip.get_header_length() as usize * 4; // the header length is given in 32-bits words @@ -1362,7 +1312,7 @@ fn set_udp_elements( safe_copy_from_slice(&mut new_buf[..], 0, 8, &ori_udp_buf, 0, 8)?; ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; ori_udp.set_payload(&data); } else { @@ -1379,7 +1329,7 @@ fn set_udp_elements( ori_udp_buf.len(), )?; ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; } @@ -1399,10 +1349,10 @@ fn set_udp_elements( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let udp_aux = UdpPacket::new(ori_udp.packet()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::udp::ipv4_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } @@ -1422,7 +1372,7 @@ fn set_udp_elements( let l = new_ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut new_ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pkt.set_total_length(l as u16); @@ -1436,18 +1386,15 @@ fn set_udp_elements( } /// Receive a list of IPv4 datagrams and print their UDP part in a readable format in the screen. -fn dump_udp_packet(register: &Register, _: &Context) -> Result { +fn dump_udp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( "Missing arguments. It needs at least one UDP packet".to_string(), )); } - let invalid_udp_packet_error = || { - Err(FunctionErrorKind::WrongArgument( - "Invalid UDP packet".to_string(), - )) - }; + let invalid_udp_packet_error = + || Err(NaslError::WrongArgument("Invalid UDP packet".to_string())); for udp_datagram in positional.iter() { match udp_datagram { @@ -1491,22 +1438,19 @@ fn dump_udp_packet(register: &Register, _: &Context) -> Result Result { +fn get_udp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("udp")); + return Err(NaslError::missing_argument("udp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let udp = packet::udp::UdpPacket::new(ip.payload()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("element") { @@ -1516,9 +1460,9 @@ fn get_udp_element( "uh_len" => Ok(NaslValue::Number(udp.get_length() as i64)), "uh_sum" => Ok(NaslValue::Number(udp.get_checksum() as i64)), "data" => Ok(NaslValue::Data(udp.payload().to_vec())), - _ => Err(FunctionErrorKind::WrongArgument("element".to_string())), + _ => Err(NaslError::WrongArgument("element".to_string())), }, - _ => Err(FunctionErrorKind::WrongArgument("element".to_string())), + _ => Err(NaslError::WrongArgument("element".to_string())), } } @@ -1531,14 +1475,11 @@ fn get_udp_element( /// - *icmp_seq*: ICMP sequence number. /// - *icmp_type*: ICMP type. 0 by default. /// - *update_ip_len*: If this flag is set, NASL will recompute the size field of the IP datagram. Default: True. -fn forge_icmp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(NaslError::missing_argument("icmp")); } }; let original_ip_len = ip_buf.len(); @@ -1553,7 +1494,7 @@ fn forge_icmp_packet( let total_length = 8 + data.len(); let mut buf = vec![0; total_length]; let mut icmp_pkt = packet::icmp::MutableIcmpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("icmp_type") { @@ -1589,21 +1530,21 @@ fn forge_icmp_packet( Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { let icmp_aux = IcmpPacket::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pnet::packet::icmp::checksum(&icmp_aux) } }; let mut icmp_pkt = packet::icmp::MutableIcmpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { @@ -1629,22 +1570,19 @@ fn forge_icmp_packet( /// - icmp_seq /// - icmp_chsum /// - icmp_data -fn get_icmp_element( - register: &Register, - _configs: &Context, -) -> Result { +fn get_icmp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("icmp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(NaslError::missing_argument("icmp")); } }; let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let icmp = packet::icmp::IcmpPacket::new(ip.payload()).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("element") { @@ -1685,15 +1623,15 @@ fn get_icmp_element( } _ => Ok(NaslValue::Null), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(NaslError::missing_argument("element")), } } /// Receive a list of IPv4 ICMP packets and print them in a readable format in the screen. -fn dump_icmp_packet(register: &Register, _: &Context) -> Result { +fn dump_icmp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(NaslError::missing_argument("icmp")); } for icmp_pkt in positional.iter() { @@ -1705,10 +1643,10 @@ fn dump_icmp_packet(register: &Register, _: &Context) -> Result Result { +fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("igmp")); + return Err(NaslError::missing_argument("igmp")); } }; let original_ip_len = ip_buf.len(); @@ -1840,7 +1775,7 @@ fn forge_igmp_packet( let total_length = 8 + data.len(); let mut buf = vec![0; total_length]; let mut igmp_pkt = igmp::MutableIgmpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; match register.named("type") { @@ -1863,10 +1798,7 @@ fn forge_igmp_packet( igmp_pkt.set_group_address(ip); } Err(e) => { - return Err(FunctionErrorKind::Dirty(format!( - "Invalid address group: {}", - e - ))); + return Err(NaslError::Dirty(format!("Invalid address group: {}", e))); } }; } @@ -1878,19 +1810,19 @@ fn forge_igmp_packet( } let igmp_aux = igmp::IgmpPacket::new(&buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; let cksum = igmp::checksum(&igmp_aux); let mut icmp_pkt = packet::icmp::MutableIcmpPacket::new(&mut buf).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_checksum(cksum); ip_buf.append(&mut buf); let l = ip_buf.len(); let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - FunctionErrorKind::Diagnostic( + NaslError::Diagnostic( "No possible to create a packet from buffer".to_string(), Some(NaslValue::Null), ) @@ -1908,14 +1840,14 @@ fn forge_igmp_packet( Ok(NaslValue::Data(ip_buf)) } -fn new_raw_socket() -> Result { +fn new_raw_socket() -> Result { match Socket::new_raw( Domain::IPV4, socket2::Type::RAW, Some(Protocol::from(IPPROTO_RAW)), ) { Ok(s) => Ok(s), - Err(e) => Err(FunctionErrorKind::Dirty(format!( + Err(e) => Err(NaslError::Dirty(format!( "Not possible to create a raw socket: {}", e ))), @@ -1926,7 +1858,7 @@ fn new_raw_socket() -> Result { /// /// Its argument is: /// - port: port for the ping -fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { +fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { let rnd_tcp_port = || -> u16 { (random_impl().unwrap_or(0) % 65535 + 1024) as u16 }; let sports_ori: Vec = vec![ @@ -1948,7 +1880,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result *x, None => 0, //TODO: implement plug_get_host_open_port() _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -1985,7 +1917,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result Result Result { - return Err(FunctionErrorKind::Dirty(format!("send_packet: {}", e))); + return Err(NaslError::Dirty(format!("send_packet: {}", e))); } } @@ -2067,15 +1999,12 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_packet(register: &Register, configs: &Context) -> Result { let use_pcap = match register.named("pcap_active") { Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => true, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -2086,7 +2015,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -2097,7 +2026,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -2108,7 +2037,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => false, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Boolean", "Invalid allow_broadcast value", )) @@ -2123,7 +2052,7 @@ fn nasl_send_packet( let soc = new_raw_socket()?; if let Err(e) = soc.set_header_included(true) { - return Err(FunctionErrorKind::Dirty(format!( + return Err(NaslError::Dirty(format!( "Not possible to create a raw socket: {}", e ))); @@ -2133,7 +2062,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Number(x))) => *x, None => 0, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -2156,15 +2085,10 @@ fn nasl_send_packet( for pkt in positional.iter() { let packet_raw = match pkt { NaslValue::Data(data) => data as &[u8], - _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( - "Data", - "Invalid packet", - )) - } + _ => return Err(NaslError::wrong_unnamed_argument("Data", "Invalid packet")), }; let packet = packet::ipv4::Ipv4Packet::new(packet_raw).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; if allow_broadcast { @@ -2178,7 +2102,7 @@ fn nasl_send_packet( // No broadcast destination and dst ip address inside the IP packet // differs from target IP, is consider a malicious or buggy script. if packet.get_destination() != target_ip && !allow_broadcast { - return Err(FunctionErrorKind::Dirty( + return Err(NaslError::Dirty( format!("send_packet: malicious or buggy script is trying to send packet to {} instead of designated target {}", packet.get_destination(), target_ip) )); @@ -2188,7 +2112,7 @@ fn nasl_send_packet( let sockaddr = match SocketAddr::from_str(&sock_str) { Ok(addr) => socket2::SockAddr::from(addr), Err(e) => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!("send_packet: {}", e), Some(NaslValue::Null), )); @@ -2200,7 +2124,7 @@ fn nasl_send_packet( debug!("Sent {} bytes", b); } Err(e) => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!("send_packet: {}", e), Some(NaslValue::Null), )); @@ -2227,7 +2151,7 @@ fn nasl_send_packet( /// - interface: network interface name, by default NASL will try to find the best one /// - pcap_filter: BPF filter, by default it listens to everything /// - timeout: timeout in seconds, 5 by default -fn nasl_pcap_next(register: &Register, configs: &Context) -> Result { +fn nasl_pcap_next(register: &Register, configs: &Context) -> Result { nasl_send_capture(register, configs) } @@ -2236,15 +2160,12 @@ fn nasl_pcap_next(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_capture(register: &Register, configs: &Context) -> Result { let interface = match register.named("interface") { Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "String", "Invalid interface value", )) @@ -2255,7 +2176,7 @@ fn nasl_send_capture( Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -2266,7 +2187,7 @@ fn nasl_send_capture( Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(NaslError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -2298,7 +2219,7 @@ fn nasl_send_capture( Ok(packet) => { // Remove all from lower layer let frame = EthernetPacket::new(packet.data).ok_or_else(|| { - FunctionErrorKind::Dirty("No possible to create a packet from buffer".to_string()) + NaslError::Dirty("No possible to create a packet from buffer".to_string()) })?; return Ok(NaslValue::Data(frame.payload().to_vec())); } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index ae1794023..c59ef6fa1 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -8,14 +8,14 @@ use std::{ }; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::FunctionErrorKind; +use crate::nasl::utils::NaslError; use pcap::{Address, Device}; /// Convert a string in a IpAddr -pub fn ipstr2ipaddr(ip_addr: &str) -> Result { +pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(NaslError::Diagnostic( "Invalid IP address".to_string(), Some(NaslValue::Null), )), @@ -39,7 +39,7 @@ pub fn islocalhost(addr: IpAddr) -> bool { } /// Get the interface from the local ip -pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { +pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { // This fake IP is used for matching (and return false) // during the search of the interface in case an interface // doesn't have an associated address. @@ -70,18 +70,15 @@ pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result Ok(dev), - _ => Err(FunctionErrorKind::Diagnostic( + _ => Err(NaslError::Diagnostic( "Invalid ip address".to_string(), None, )), } } -pub fn bind_local_socket(dst: &SocketAddr) -> Result { - let fe = Err(FunctionErrorKind::Diagnostic( - "Error binding".to_string(), - None, - )); +pub fn bind_local_socket(dst: &SocketAddr) -> Result { + let fe = Err(NaslError::Diagnostic("Error binding".to_string(), None)); match dst { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0").or(fe), SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0").or(fe), @@ -89,7 +86,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result Result { +pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { let socket = SocketAddr::new(dst, port); let sd = format!("{}:{}", dst, port); let local_socket = bind_local_socket(&socket)?; @@ -97,17 +94,17 @@ pub fn get_source_ip(dst: IpAddr, port: u16) -> Result match local_socket.local_addr() { Ok(l_addr) => match IpAddr::from_str(&l_addr.ip().to_string()) { Ok(x) => Ok(x), - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(NaslError::Diagnostic( "No route to destination".to_string(), None, )), }, - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(NaslError::Diagnostic( "No route to destination".to_string(), None, )), }, - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(NaslError::Diagnostic( "No route to destination".to_string(), None, )), diff --git a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs index fb446c261..0d9a10fcb 100644 --- a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs @@ -8,7 +8,7 @@ mod tests { use nasl_builtin_raw_ip::RawIp; use nasl_builtin_std::ContextFactory; - use crate::nasl::utils::{error::FunctionErrorKind, Executor}; + use crate::nasl::utils::{error::NaslError, Executor}; use crate::nasl::interpreter::test_utils::TestBuilder; use crate::nasl::syntax::NaslValue; @@ -20,7 +20,7 @@ mod tests { o_buf: &[u8], o_init: usize, o_fin: usize, - ) -> Result<(), FunctionErrorKind> { + ) -> Result<(), NaslError> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -29,7 +29,7 @@ mod tests { || d_buf.len() < d_fin || o_buf.len() < o_fin { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null), )); @@ -270,7 +270,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, 2, &b, 0, b.len()), - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -279,7 +279,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, alen, &b, 0, 2), - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -288,7 +288,7 @@ mod tests { // out of index in the destination range assert_eq!( safe_copy_from_slice(&mut a, 1, alen + 1, &b, 0, b.len()), - Err(FunctionErrorKind::Diagnostic( + Err(NaslError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index c615d3d72..ad52d8000 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -19,14 +19,14 @@ fn parse_search_string(mut s: &str, rnul: bool, multiline: bool) -> &str { s } -fn make_regex(pattern: &str, icase: bool, multiline: bool) -> Result { +fn make_regex(pattern: &str, icase: bool, multiline: bool) -> Result { match RegexBuilder::new(pattern.to_string().as_str()) .case_insensitive(icase) .multi_line(multiline) .build() { Ok(re) => Ok(re), - Err(e) => Err(FunctionErrorKind::Dirty(format!( + Err(e) => Err(NaslError::Dirty(format!( " Error building regular expression pattern: {}", e ))), @@ -48,7 +48,7 @@ fn ereg( icase: Option, rnul: Option, multiline: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let multiline = multiline.unwrap_or(false); @@ -75,7 +75,7 @@ fn ereg_replace( replace: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -103,7 +103,7 @@ fn egrep( pattern: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -137,7 +137,7 @@ fn eregmatch( find_all: Option, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let find_all = find_all.unwrap_or(false); diff --git a/rust/src/nasl/builtin/report_functions/mod.rs b/rust/src/nasl/builtin/report_functions/mod.rs index 652d1fcd9..dc7ccae92 100644 --- a/rust/src/nasl/builtin/report_functions/mod.rs +++ b/rust/src/nasl/builtin/report_functions/mod.rs @@ -26,7 +26,7 @@ impl Reporting { typus: ResultType, register: &Register, context: &Context, - ) -> Result { + ) -> Result { let data = register.named("data").map(|x| x.to_string()); let port = register .named("port") @@ -70,11 +70,7 @@ impl Reporting { /// - port, optional TCP or UDP port number of the service /// - proto is the protocol ("tcp" by default; "udp" is the other value). /// - uri specifies the location of a found product - fn log_message( - &self, - register: &Register, - context: &Context, - ) -> Result { + fn log_message(&self, register: &Register, context: &Context) -> Result { self.store_result(ResultType::Log, register, context) } @@ -89,7 +85,7 @@ impl Reporting { &self, register: &Register, context: &Context, - ) -> Result { + ) -> Result { self.store_result(ResultType::Alarm, register, context) } @@ -104,7 +100,7 @@ impl Reporting { &self, register: &Register, context: &Context, - ) -> Result { + ) -> Result { self.store_result(ResultType::Error, register, context) } } diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index 115e83b13..d9e8b15a0 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -2,7 +2,7 @@ use std::fmt; use thiserror::Error; -use crate::nasl::FunctionErrorKind; +use crate::nasl::NaslError; use super::SessionId; @@ -170,8 +170,8 @@ impl SshError { } } -impl From for FunctionErrorKind { +impl From for NaslError { fn from(e: SshError) -> Self { - FunctionErrorKind::Ssh(e) + NaslError::Ssh(e) } } diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 60cc74dc0..61aefa442 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -42,7 +42,7 @@ mod libssh_uses { #[cfg(feature = "nasl-builtin-libssh")] pub use libssh_uses::*; -type Result = std::result::Result; +type Result = std::result::Result; const DEFAULT_SSH_PORT: u16 = 22; @@ -533,7 +533,7 @@ impl Ssh { } AuthStatus::Success => break, status => { - return Err(FunctionErrorKind::Diagnostic( + return Err(NaslError::Diagnostic( format!( "Unexpected authentication status for session_id {}: {:?}", session_id, status diff --git a/rust/src/nasl/builtin/ssh/tests/mod.rs b/rust/src/nasl/builtin/ssh/tests/mod.rs index 1ed70972d..5176d2e29 100644 --- a/rust/src/nasl/builtin/ssh/tests/mod.rs +++ b/rust/src/nasl/builtin/ssh/tests/mod.rs @@ -83,13 +83,13 @@ async fn ssh_connect() { check_err_matches!( t, format!(r#"id = ssh_connect(port:{}, keytype: "foo");"#, PORT), - FunctionErrorKind::WrongArgument(_) + NaslError::WrongArgument(_) ); // Without a matching key algorithm, we should not be able to connect check_err_matches!( t, format!(r#"id = ssh_connect(port:{}, keytype: "ssh-rsa");"#, PORT), - FunctionErrorKind::Ssh(SshError { + NaslError::Ssh(SshError { kind: SshErrorKind::Connect, .. }) @@ -121,7 +121,7 @@ async fn ssh_userauth() { check_err_matches!( t, r#"ssh_userauth(session_id);"#, - FunctionErrorKind::Ssh(SshError { + NaslError::Ssh(SshError { kind: SshErrorKind::NoAuthenticationGiven, .. }), diff --git a/rust/src/nasl/builtin/ssh/utils.rs b/rust/src/nasl/builtin/ssh/utils.rs index be283db84..e35c7e25c 100644 --- a/rust/src/nasl/builtin/ssh/utils.rs +++ b/rust/src/nasl/builtin/ssh/utils.rs @@ -12,7 +12,7 @@ impl<'a, T> FromNaslValue<'a> for CommaSeparated where T: for<'b> FromNaslValue<'b>, { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = StringOrData::from_nasl_value(value)?; Ok(Self( s.0.split(",") @@ -21,31 +21,25 @@ where let nasl_val = NaslValue::String(substr.to_string()); T::from_nasl_value(&nasl_val) }) - .collect::, FunctionErrorKind>>()?, + .collect::, NaslError>>()?, )) } } impl<'a> FromNaslValue<'a> for key::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; key::Name::try_from(&*s).map_err(|_| { - FunctionErrorKind::WrongArgument(format!( - "Expected a valid SSH key type, found '{}'", - s - )) + NaslError::WrongArgument(format!("Expected a valid SSH key type, found '{}'", s)) }) } } impl<'a> FromNaslValue<'a> for cipher::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; cipher::Name::try_from(&*s).map_err(|_| { - FunctionErrorKind::WrongArgument(format!( - "Expected a valid SSH cipher type, found '{}'", - s - )) + NaslError::WrongArgument(format!("Expected a valid SSH cipher type, found '{}'", s)) }) } } diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 31ad2188b..25bcd3cc9 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -9,7 +9,7 @@ mod tests; use crate::nasl::utils::{ function::{bytes_to_str, CheckedPositionals, Maybe, StringOrData}, - Context, FunctionErrorKind, Register, + Context, NaslError, Register, }; use core::fmt::Write; use glob::{MatchOptions, Pattern}; @@ -74,7 +74,7 @@ fn raw_string(positional: CheckedPositionals<&NaslValue>) -> Vec { data } -fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), FunctionErrorKind> { +fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), NaslError> { match value { NaslValue::String(x) => write!(s, "{x}"), NaslValue::Data(x) => { @@ -108,7 +108,7 @@ fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), FunctionEr /// NASL function to parse values into string representations #[nasl_function] -fn string(positional: CheckedPositionals<&NaslValue>) -> Result { +fn string(positional: CheckedPositionals<&NaslValue>) -> Result { let mut s = String::with_capacity(2 * positional.len()); for p in positional { write_nasl_string_value(&mut s, p)?; @@ -116,7 +116,7 @@ fn string(positional: CheckedPositionals<&NaslValue>) -> Result Result<(), FunctionErrorKind> { +fn write_nasl_string_value(s: &mut String, value: &NaslValue) -> Result<(), NaslError> { match value { NaslValue::Array(x) => { for p in x { @@ -219,11 +219,11 @@ fn hex(s: i64) -> String { /// /// The first positional argument must be a string, all other arguments are ignored. If either the no argument was given or the first positional is not a string, a error is returned. #[nasl_function] -fn hexstr_to_data(s: NaslValue) -> Result, FunctionErrorKind> { +fn hexstr_to_data(s: NaslValue) -> Result, NaslError> { let s = s.to_string(); let s = s.as_str(); decode_hex(s).map_err(|_| { - FunctionErrorKind::WrongArgument(format!( + NaslError::WrongArgument(format!( "Expected an even-length string containing only 0-9a-fA-F, found '{}'", s )) @@ -282,7 +282,7 @@ fn stridx(haystack: NaslValue, needle: NaslValue, offset: Option) -> i64 /// NASL function to display any number of NASL values /// /// Internally the string function is used to concatenate the given parameters -fn display(register: &Register, configs: &Context) -> Result { +fn display(register: &Register, configs: &Context) -> Result { println!("{}", &string(register, configs)?); Ok(NaslValue::Null) } @@ -331,7 +331,7 @@ fn insstr( to_insert: NaslValue, start: usize, end: Option, -) -> Result { +) -> Result { let mut s = s.to_string(); let insb = to_insert.to_string(); @@ -339,7 +339,7 @@ fn insstr( let end = end.unwrap_or(s.len()).min(s.len()); if start > end { - return Err(FunctionErrorKind::WrongArgument(format!( + return Err(NaslError::WrongArgument(format!( "start index ({}) larger than end ({}).", start, end ))); @@ -360,11 +360,7 @@ fn insstr( /// `pattern` contains the pattern to search for. /// The optional argument `icase` toggles case sensitivity. Default: false (case sensitive). If true, search is case insensitive. #[nasl_function(named(string, pattern, icase))] -fn match_( - string: NaslValue, - pattern: NaslValue, - icase: Option, -) -> Result { +fn match_(string: NaslValue, pattern: NaslValue, icase: Option) -> Result { let options = MatchOptions { case_sensitive: !icase.unwrap_or(false), require_literal_separator: false, @@ -377,7 +373,7 @@ fn match_( Ok(Pattern::new(pattern) .map_err(|err| { - FunctionErrorKind::WrongArgument(format!( + NaslError::WrongArgument(format!( "Argument 'pattern' to 'match' is not a valid pattern: {}. {}", pattern, err )) diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index 1f6e95dc7..2db293e5f 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -4,7 +4,7 @@ #[cfg(test)] mod tests { use crate::nasl::test_prelude::*; - use FunctionErrorKind::*; + use NaslError::*; use NaslValue::*; #[test] diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 60d04b56f..679c92f61 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -6,7 +6,7 @@ use std::io; use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::NaslError; use crate::storage::StorageError; use thiserror::Error; @@ -18,12 +18,12 @@ pub struct FunctionError { pub function: String, /// Kind of error #[source] - pub kind: FunctionErrorKind, + pub kind: NaslError, } impl FunctionError { /// Creates a new FunctionError - pub fn new(function: &str, kind: FunctionErrorKind) -> Self { + pub fn new(function: &str, kind: NaslError) -> Self { Self { function: function.to_owned(), kind, @@ -230,11 +230,9 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { match fe.kind { - FunctionErrorKind::FMTError(fe) => fe.into(), - FunctionErrorKind::IOError(ie) => ie.into(), - FunctionErrorKind::GeneralError(e) => { - Self::new(InterpretErrorKind::StorageError(e), None) - } + NaslError::FMTError(fe) => fe.into(), + NaslError::IOError(ie) => ie.into(), + NaslError::GeneralError(e) => Self::new(InterpretErrorKind::StorageError(e), None), _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), } } diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index a399cbcb9..01c871bfe 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -18,7 +18,7 @@ pub mod prelude { pub use super::utils::function::ToNaslResult; pub use super::utils::Context; pub use super::utils::ContextType; - pub use super::utils::FunctionErrorKind; + pub use super::utils::NaslError; pub use super::utils::NaslResult; pub use super::utils::Register; pub use crate::function_set; diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index 92b1f8c63..1ed0a4d86 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -294,7 +294,7 @@ where fn check_result( &self, - result: &Result, + result: &Result, reference: &TracedTestResult, line_count: usize, ) { @@ -305,7 +305,7 @@ where "Mismatch at {}.\nIn code \"{}\":\nExpected: {:?}\nFound: {:?}", reference.location, self.lines[line_count], - Ok::<_, FunctionErrorKind>(reference_result), + Ok::<_, NaslError>(reference_result), result, ); } @@ -326,7 +326,7 @@ where fn compare_result( &self, - result: &Result, + result: &Result, reference: &TestResult, ) -> bool { match reference { diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 16cc74641..d4a54f089 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -18,7 +18,7 @@ pub type GeneralErrorType = StorageError; #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function -pub enum FunctionErrorKind { +pub enum NaslError { /// Function called with insufficient arguments #[error("Expected {expected} but got {got}")] MissingPositionalArguments { @@ -72,13 +72,13 @@ pub enum FunctionErrorKind { // thiserror, but io::Error does not impl `PartialEq`, // `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which // does not impl `Error` which is why this `From` impl exists. -impl From for FunctionErrorKind { +impl From for NaslError { fn from(e: io::Error) -> Self { Self::IOError(e.kind()) } } -impl FunctionErrorKind { +impl NaslError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and /// the actual value. @@ -100,39 +100,39 @@ impl FunctionErrorKind { } } -impl From<(&str, &str, &NaslValue)> for FunctionErrorKind { +impl From<(&str, &str, &NaslValue)> for NaslError { fn from(value: (&str, &str, &NaslValue)) -> Self { let (key, expected, got) = value; let got: &str = &got.to_string(); - FunctionErrorKind::wrong_argument(key, expected, got) + NaslError::wrong_argument(key, expected, got) } } -impl From<(&str, &str, Option<&NaslValue>)> for FunctionErrorKind { +impl From<(&str, &str, Option<&NaslValue>)> for NaslError { fn from(value: (&str, &str, Option<&NaslValue>)) -> Self { match value { (key, expected, Some(x)) => (key, expected, x).into(), - (key, expected, None) => FunctionErrorKind::wrong_argument(key, expected, "NULL"), + (key, expected, None) => NaslError::wrong_argument(key, expected, "NULL"), } } } -impl From<(&str, &str, Option<&ContextType>)> for FunctionErrorKind { +impl From<(&str, &str, Option<&ContextType>)> for NaslError { fn from(value: (&str, &str, Option<&ContextType>)) -> Self { match value { (key, expected, Some(ContextType::Value(x))) => (key, expected, x).into(), (key, expected, Some(ContextType::Function(_, _))) => { - FunctionErrorKind::wrong_argument(key, expected, "function") + NaslError::wrong_argument(key, expected, "function") } - (key, expected, None) => FunctionErrorKind::wrong_argument(key, expected, "NULL"), + (key, expected, None) => NaslError::wrong_argument(key, expected, "NULL"), } } } -impl From<(&str, &NaslValue)> for FunctionErrorKind { +impl From<(&str, &NaslValue)> for NaslError { fn from(value: (&str, &NaslValue)) -> Self { let (expected, got) = value; let got: &str = &got.to_string(); - FunctionErrorKind::wrong_unnamed_argument(expected, got) + NaslError::wrong_unnamed_argument(expected, got) } } diff --git a/rust/src/nasl/utils/function/from_nasl_value.rs b/rust/src/nasl/utils/function/from_nasl_value.rs index d876dc1be..8f59ef21d 100644 --- a/rust/src/nasl/utils/function/from_nasl_value.rs +++ b/rust/src/nasl/utils/function/from_nasl_value.rs @@ -6,76 +6,68 @@ use crate::nasl::prelude::*; /// The conversion may fail. pub trait FromNaslValue<'a>: Sized { /// Perform the conversion - fn from_nasl_value(value: &'a NaslValue) -> Result; + fn from_nasl_value(value: &'a NaslValue) -> Result; } impl<'a> FromNaslValue<'a> for NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value.clone()) } } impl<'a> FromNaslValue<'a> for &'a NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value) } } impl<'a> FromNaslValue<'a> for String { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string.to_string()), - _ => Err(FunctionErrorKind::WrongArgument( - "Expected string.".to_string(), - )), + _ => Err(NaslError::WrongArgument("Expected string.".to_string())), } } } impl<'a> FromNaslValue<'a> for &'a str { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string), - _ => Err(FunctionErrorKind::WrongArgument( - "Expected string.".to_string(), - )), + _ => Err(NaslError::WrongArgument("Expected string.".to_string())), } } } impl<'a> FromNaslValue<'a> for &'a [u8] { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Data(bytes) => Ok(bytes), - _ => Err(FunctionErrorKind::WrongArgument( - "Expected byte data.".to_string(), - )), + _ => Err(NaslError::WrongArgument("Expected byte data.".to_string())), } } } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Vec { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Array(vals) => Ok(vals .iter() .map(T::from_nasl_value) - .collect::, FunctionErrorKind>>()?), - _ => Err(FunctionErrorKind::WrongArgument( - "Expected an array..".to_string(), - )), + .collect::, NaslError>>()?), + _ => Err(NaslError::WrongArgument("Expected an array..".to_string())), } } } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Dict(map) => Ok(map .iter() .map(|(k, v)| T::from_nasl_value(v).map(|v| (k.clone(), v))) .collect::, _>>()?), - _ => Err(FunctionErrorKind::WrongArgument( + _ => Err(NaslError::WrongArgument( "Expected a dictionary.".to_string(), )), } @@ -83,13 +75,11 @@ impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { } impl<'a> FromNaslValue<'a> for bool { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Boolean(b) => Ok(*b), NaslValue::Number(n) => Ok(*n != 0), - _ => Err(FunctionErrorKind::WrongArgument( - "Expected bool.".to_string(), - )), + _ => Err(NaslError::WrongArgument("Expected bool.".to_string())), } } } @@ -97,12 +87,12 @@ impl<'a> FromNaslValue<'a> for bool { macro_rules! impl_from_nasl_value_for_numeric_type { ($ty: ty) => { impl<'a> FromNaslValue<'a> for $ty { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::Number(num) => Ok(<$ty>::try_from(*num).map_err(|_| { - FunctionErrorKind::WrongArgument("Expected positive number.".into()) + NaslError::WrongArgument("Expected positive number.".into()) })?), - e => Err(FunctionErrorKind::WrongArgument(format!( + e => Err(NaslError::WrongArgument(format!( "Expected a number, found '{}'.", e ))), diff --git a/rust/src/nasl/utils/function/maybe.rs b/rust/src/nasl/utils/function/maybe.rs index 28085e718..04a8cc049 100644 --- a/rust/src/nasl/utils/function/maybe.rs +++ b/rust/src/nasl/utils/function/maybe.rs @@ -1,6 +1,6 @@ use crate::nasl::syntax::NaslValue; -use crate::nasl::FunctionErrorKind; +use crate::nasl::NaslError; use super::FromNaslValue; @@ -12,7 +12,7 @@ use super::FromNaslValue; pub struct Maybe(Option); impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Maybe { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(Self(T::from_nasl_value(value).ok())) } } diff --git a/rust/src/nasl/utils/function/positionals.rs b/rust/src/nasl/utils/function/positionals.rs index bd29d26f5..fc26a3128 100644 --- a/rust/src/nasl/utils/function/positionals.rs +++ b/rust/src/nasl/utils/function/positionals.rs @@ -1,6 +1,6 @@ use std::{marker::PhantomData, ops::Index}; -use crate::nasl::{FunctionErrorKind, Register}; +use crate::nasl::{NaslError, Register}; use super::FromNaslValue; @@ -22,9 +22,9 @@ impl<'a, T: FromNaslValue<'a>> Positionals<'a, T> { } /// Returns an iterator over the positional arguments. - /// The item type is Result, since + /// The item type is Result, since /// the conversion to T can still fail. - pub fn iter(&self) -> impl Iterator> + 'a { + pub fn iter(&self) -> impl Iterator> + 'a { self.register .positional() .iter() @@ -45,12 +45,12 @@ pub struct CheckedPositionals { impl<'a, T: FromNaslValue<'a>> CheckedPositionals { /// Create a new `CheckedPositionals` from the register. - pub fn new(register: &'a Register) -> Result { + pub fn new(register: &'a Register) -> Result { let data = register .positional() .iter() .map(T::from_nasl_value) - .collect::, FunctionErrorKind>>()?; + .collect::, NaslError>>()?; Ok(Self { data, _marker: PhantomData, diff --git a/rust/src/nasl/utils/function/to_nasl_result.rs b/rust/src/nasl/utils/function/to_nasl_result.rs index ab48aa7eb..5afff332a 100644 --- a/rust/src/nasl/utils/function/to_nasl_result.rs +++ b/rust/src/nasl/utils/function/to_nasl_result.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::nasl::syntax::NaslValue; -use crate::nasl::{FunctionErrorKind, NaslResult}; +use crate::nasl::{NaslError, NaslResult}; /// A type that can be converted to a NaslResult. /// The conversion is fallible to make it possible to convert from other Result @@ -26,7 +26,7 @@ impl ToNaslResult for Option { } } -impl> ToNaslResult for Result { +impl> ToNaslResult for Result { fn to_nasl_result(self) -> NaslResult { self.map_err(|e| e.into()).and_then(|x| x.to_nasl_result()) } @@ -67,7 +67,7 @@ impl ToNaslResult for Vec<&str> { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, FunctionErrorKind>>()?, + .collect::, NaslError>>()?, )) } } @@ -77,7 +77,7 @@ impl ToNaslResult for Vec { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, FunctionErrorKind>>()?, + .collect::, NaslError>>()?, )) } } @@ -93,7 +93,7 @@ impl ToNaslResult for HashMap { Ok(NaslValue::Dict( self.into_iter() .map(|(key, s)| s.to_nasl_result().map(|res| (key, res))) - .collect::, FunctionErrorKind>>()?, + .collect::, NaslError>>()?, )) } } @@ -116,7 +116,7 @@ macro_rules! impl_to_nasl_result_for_numeric_type { impl_to_nasl_result_for_numeric_type!($ty, skip_vec_impl); impl ToNaslResult for Vec<$ty> { fn to_nasl_result(self) -> NaslResult { - let collected: Result, FunctionErrorKind> = + let collected: Result, NaslError> = self.into_iter().map(|x| x.to_nasl_result()).collect(); Ok(NaslValue::Array(collected?)) } diff --git a/rust/src/nasl/utils/function/types.rs b/rust/src/nasl/utils/function/types.rs index 5da814b36..c6cb6b361 100644 --- a/rust/src/nasl/utils/function/types.rs +++ b/rust/src/nasl/utils/function/types.rs @@ -5,11 +5,11 @@ use crate::nasl::prelude::*; pub struct StringOrData(pub String); impl<'a> FromNaslValue<'a> for StringOrData { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(Self(string.clone())), NaslValue::Data(buffer) => Ok(Self(bytes_to_str(buffer))), - _ => Err(FunctionErrorKind::WrongArgument( + _ => Err(NaslError::WrongArgument( "Expected string or byte buffer.".to_string(), )), } diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 0fbbc7990..6f36f68aa 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::*; pub fn get_optional_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, -) -> Result, FunctionErrorKind> { +) -> Result, NaslError> { register .positional() .get(position) @@ -23,11 +23,11 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, num_required_positional_args: usize, -) -> Result { +) -> Result { let positional = register.positional(); let arg = positional.get(position).ok_or_else(|| { let num_given = positional.len(); - FunctionErrorKind::MissingPositionalArguments { + NaslError::MissingPositionalArguments { expected: num_required_positional_args, got: num_given, } @@ -38,9 +38,9 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( fn context_type_as_nasl_value<'a>( context_type: &'a ContextType, arg_name: &str, -) -> Result<&'a NaslValue, FunctionErrorKind> { +) -> Result<&'a NaslValue, NaslError> { match context_type { - ContextType::Function(_, _) => Err(FunctionErrorKind::WrongArgument(format!( + ContextType::Function(_, _) => Err(NaslError::WrongArgument(format!( "Wrong argument for {}, expected a value, found a function.", arg_name ))), @@ -53,7 +53,7 @@ fn context_type_as_nasl_value<'a>( pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result, FunctionErrorKind> { +) -> Result, NaslError> { register .named(name) .map(|arg| context_type_as_nasl_value(arg, name)) @@ -67,10 +67,10 @@ pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( pub fn get_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result { +) -> Result { let arg = register .named(name) - .ok_or_else(|| FunctionErrorKind::MissingArguments(vec![name.to_string()]))?; + .ok_or_else(|| NaslError::MissingArguments(vec![name.to_string()]))?; ::from_nasl_value(context_type_as_nasl_value(arg, name)?) } @@ -80,7 +80,7 @@ pub fn get_optional_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result, FunctionErrorKind> { +) -> Result, NaslError> { let via_position = get_optional_positional_arg::(register, position)?; if let Some(via_position) = via_position { Ok(Some(via_position)) @@ -95,7 +95,7 @@ pub fn get_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result { +) -> Result { let via_position = get_optional_positional_arg(register, position)?; if let Some(via_position) = via_position { Ok(via_position) @@ -114,7 +114,7 @@ fn check_named_args( _nasl_fn_name: &str, named: &[&str], maybe_named: &[&str], -) -> Result { +) -> Result { let mut num_maybe_named = 0; for arg_name in register.iter_named_args().unwrap() { if arg_name == FC_ANON_ARGS || named.contains(&arg_name) { @@ -123,7 +123,7 @@ fn check_named_args( num_maybe_named += 1; } else { #[cfg(feature = "enforce-no-trailing-arguments")] - return Err(FunctionErrorKind::UnexpectedArgument(arg_name.into())); + return Err(NaslError::UnexpectedArgument(arg_name.into())); #[cfg(not(feature = "enforce-no-trailing-arguments"))] tracing::debug!( "Unexpected named argument '{arg_name}' in NASL function {_nasl_fn_name}." @@ -142,14 +142,14 @@ pub fn check_args( named: &[&str], maybe_named: &[&str], max_num_expected_positional: Option, -) -> Result<(), FunctionErrorKind> { +) -> Result<(), NaslError> { let num_maybe_named_given = check_named_args(register, _nasl_fn_name, named, maybe_named)?; let num_positional_given = register.positional().len(); if let Some(max_num_expected_positional) = max_num_expected_positional { let num_positional_expected = max_num_expected_positional - num_maybe_named_given; if num_positional_given > num_positional_expected { #[cfg(feature = "enforce-no-trailing-arguments")] - return Err(FunctionErrorKind::TrailingPositionalArguments { + return Err(NaslError::TrailingPositionalArguments { expected: num_positional_expected, got: num_positional_given, }); diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index 701ce7fcd..044e54a9a 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -12,12 +12,12 @@ pub mod lookup_keys; use std::collections::HashMap; pub use context::{Context, ContextType, Register}; -pub use error::FunctionErrorKind; +pub use error::NaslError; pub use executor::{Executor, IntoFunctionSet, StoredFunctionSet}; /// The result of a function call. -pub type NaslResult = Result; +pub type NaslResult = Result; /// Resolves positional arguments from the register. pub fn resolve_positional_arguments(register: &Register) -> Vec { @@ -46,11 +46,11 @@ pub fn get_named_parameter<'a>( registrat: &'a Register, key: &'a str, required: bool, -) -> Result<&'a crate::nasl::syntax::NaslValue, FunctionErrorKind> { +) -> Result<&'a crate::nasl::syntax::NaslValue, NaslError> { match registrat.named(key) { None => { if required { - Err(FunctionErrorKind::MissingArguments(vec![key.to_owned()])) + Err(NaslError::MissingArguments(vec![key.to_owned()])) } else { // we use exit because a named value can be intentionally set to null and may be // treated differently when it is not set compared to set but null. @@ -59,7 +59,7 @@ pub fn get_named_parameter<'a>( } Some(ct) => match ct { ContextType::Value(value) => Ok(value), - _ => Err(FunctionErrorKind::wrong_argument(key, "value", "function")), + _ => Err(NaslError::wrong_argument(key, "value", "function")), }, } } diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 89caa58b3..771d5affc 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -141,7 +141,7 @@ where Err(e) => match &e.kind { InterpretErrorKind::FunctionCallError(FunctionError { function: _, - kind: FunctionErrorKind::Diagnostic(_, x), + kind: NaslError::Diagnostic(_, x), }) => { tracing::warn!(error=?e, "function call error"); x.clone().unwrap_or_default() From 640d8637fb53de9ab2686b600fe64b90a01caa12 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 10:00:36 +0100 Subject: [PATCH 02/36] Add new variants to `NaslError`. --- rust/src/nasl/builtin/cryptographic/des.rs | 9 ++--- rust/src/nasl/builtin/description/mod.rs | 2 +- rust/src/nasl/builtin/error.rs | 11 ++++++ rust/src/nasl/builtin/knowledge_base/tests.rs | 2 +- rust/src/nasl/builtin/mod.rs | 2 + rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 4 +- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 4 +- rust/src/nasl/builtin/ssh/tests/mod.rs | 2 +- rust/src/nasl/builtin/string/tests.rs | 29 ++++++++++---- rust/src/nasl/mod.rs | 2 + rust/src/nasl/utils/error.rs | 38 ++++++++++++++----- rust/src/nasl/utils/function/utils.rs | 2 +- rust/src/nasl/utils/mod.rs | 2 + 13 files changed, 79 insertions(+), 30 deletions(-) create mode 100644 rust/src/nasl/builtin/error.rs diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index db91cca18..52d7ad146 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -2,10 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later -use crate::{ - function_set, - nasl::utils::{Context, NaslError, Register}, -}; +use crate::nasl::prelude::*; use aes::cipher::BlockEncrypt; use ccm::KeyInit; use des::cipher::generic_array::GenericArray; @@ -16,10 +13,10 @@ fn encrypt_des( ) -> Result { let positional = register.positional(); if positional.len() != 2 { - return Err(NaslError::MissingPositionalArguments { + return Err(NaslError::Argument(ArgumentError::MissingPositionals { expected: 2, got: positional.len(), - }); + })); } let key = match &positional[1] { crate::nasl::syntax::NaslValue::Data(x) => x, diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index 326d9eb22..fedce7fcd 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -65,7 +65,7 @@ macro_rules! make_storage_function { let positional = registrat.positional(); if $len > 0 && positional.len() != $len{ return Err( - NaslError::MissingPositionalArguments { expected: $len, got: positional.len() } + NaslError::Argument(ArgumentError::MissingPositionals { expected: $len, got: positional.len() }) ); } for p in positional { diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs new file mode 100644 index 000000000..210454457 --- /dev/null +++ b/rust/src/nasl/builtin/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +use super::ssh::SshError; + +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum BuiltinError { + #[error("Authentication error.")] + Authentication, + #[error("{0}")] + Ssh(SshError), +} diff --git a/rust/src/nasl/builtin/knowledge_base/tests.rs b/rust/src/nasl/builtin/knowledge_base/tests.rs index 9750f8508..0c19f5e3f 100644 --- a/rust/src/nasl/builtin/knowledge_base/tests.rs +++ b/rust/src/nasl/builtin/knowledge_base/tests.rs @@ -27,7 +27,7 @@ mod tests { check_err_matches!( t, r#"get_kb_item();"#, - NaslError::MissingPositionalArguments { .. } + Argument(ArgumentError::MissingPositionals { .. }) ); } diff --git a/rust/src/nasl/builtin/mod.rs b/rust/src/nasl/builtin/mod.rs index 238d385c0..4da926511 100644 --- a/rust/src/nasl/builtin/mod.rs +++ b/rust/src/nasl/builtin/mod.rs @@ -7,6 +7,7 @@ mod array; mod cryptographic; mod description; +mod error; mod host; mod http; mod isotime; @@ -23,6 +24,7 @@ mod string; #[cfg(test)] mod tests; +pub use error::BuiltinError; pub use ssh::SshError; use crate::nasl::syntax::{Loader, NoOpLoader}; diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index fc5773ddc..2509da03f 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -410,10 +410,10 @@ fn nasl_get_local_mac_address_from_ip( ) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::MissingPositionalArguments { + return Err(NaslError::Argument(ArgumentError::MissingPositionals { expected: 1, got: 0, - }); + })); } match &positional[0] { diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 7872ec381..a50f24aac 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -387,10 +387,10 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::MissingPositionalArguments { + return Err(NaslError::Argument(ArgumentError::MissingPositionals { expected: 1, got: 0, - }); + })); } for ip in positional.iter() { diff --git a/rust/src/nasl/builtin/ssh/tests/mod.rs b/rust/src/nasl/builtin/ssh/tests/mod.rs index 5176d2e29..4d869d810 100644 --- a/rust/src/nasl/builtin/ssh/tests/mod.rs +++ b/rust/src/nasl/builtin/ssh/tests/mod.rs @@ -13,7 +13,7 @@ use server::TestServer; use crate::check_err_matches; use crate::nasl::builtin::ssh::error::SshErrorKind; use crate::nasl::builtin::ssh::sessions::MIN_SESSION_ID; -use crate::nasl::builtin::SshError; +use crate::nasl::builtin::ssh::SshError; use crate::nasl::test_prelude::*; use crate::nasl::NoOpLoader; use crate::storage::DefaultDispatcher; diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index 2db293e5f..a4c874c34 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception #[cfg(test)] mod tests { - use crate::nasl::test_prelude::*; + use crate::nasl::{test_prelude::*, utils::error::ArgumentError}; use NaslError::*; use NaslValue::*; @@ -82,7 +82,10 @@ mod tests { check_code_result("chomp('abc\n');", "abc"); check_code_result("chomp('abc ');", "abc"); check_code_result("chomp('abc\n\t\r ');", "abc"); - check_err_matches!("chomp();", MissingPositionalArguments { .. }); + check_err_matches!( + "chomp();", + Argument(ArgumentError::MissingPositionals { .. }) + ); } #[test] @@ -123,7 +126,7 @@ mod tests { check_code_result(r#"ord("c");"#, 99); check_code_result(r#"ord("");"#, Null); check_code_result("ord(1);", 49); - check_err_matches!("ord();", MissingPositionalArguments { .. }); + check_err_matches!("ord();", Argument(ArgumentError::MissingPositionals { .. })); } #[test] @@ -153,7 +156,10 @@ mod tests { check_code_result(r#"hex(256);"#, "0x00"); check_code_result(r#"hex(257);"#, "0x01"); check_code_result(r#"hex(-2);"#, "0xfe"); - check_err_matches!(r#"hex();"#, MissingPositionalArguments { .. }); + check_err_matches!( + r#"hex();"#, + Argument(ArgumentError::MissingPositionals { .. }) + ); } #[test] @@ -210,7 +216,10 @@ mod tests { r#"split("a;b;c", sep: ";");"#, vec!["a;".to_string(), "b;".to_string(), "c".to_string()], ); - check_err_matches!(r#"split();"#, MissingPositionalArguments { .. }); + check_err_matches!( + r#"split();"#, + Argument(ArgumentError::MissingPositionals { .. }) + ); } #[test] @@ -236,7 +245,13 @@ mod tests { check_code_result(r#"strstr("abc", "b");"#, "bc"); check_code_result(r#"strstr("abcbd", "b");"#, "bcbd"); check_code_result(r#"strstr('a\rbcbd', '\rb');"#, "\rbcbd"); - check_err_matches!(r#"strstr();"#, MissingPositionalArguments { .. }); - check_err_matches!(r#"strstr("a");"#, MissingPositionalArguments { .. }); + check_err_matches!( + r#"strstr();"#, + Argument(ArgumentError::MissingPositionals { .. }) + ); + check_err_matches!( + r#"strstr("a");"#, + Argument(ArgumentError::MissingPositionals { .. }) + ); } } diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index 01c871bfe..648e75edb 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -16,8 +16,10 @@ pub mod prelude { pub use super::utils::function::FromNaslValue; pub use super::utils::function::Positionals; pub use super::utils::function::ToNaslResult; + pub use super::utils::ArgumentError; pub use super::utils::Context; pub use super::utils::ContextType; + pub use super::utils::InternalError; pub use super::utils::NaslError; pub use super::utils::NaslResult; pub use super::utils::Register; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index d4a54f089..b44fb9cf5 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -6,27 +6,41 @@ use std::io; use thiserror::Error; +use crate::nasl::builtin::{BuiltinError, SshError}; use crate::nasl::prelude::NaslValue; use crate::storage::StorageError; -use super::super::builtin::SshError; use super::ContextType; /// Reuses the StorageError definitions as they should fit most cases. pub type GeneralErrorType = StorageError; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum ArgumentError { + #[error("Expected {expected} but got {got}")] + MissingPositionals { expected: usize, got: usize }, + #[error("Expected {expected} but got {got}")] + TrailingPositionals { expected: usize, got: usize }, + #[error("Missing arguments: {}", .0.join(", "))] + MissingNamed(Vec), + #[error("Unknown named argument given to function: {}", .0)] + Unexpected(String), + #[error("Function was called with wrong arguments: {0}")] + Wrong(String), +} + +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum InternalError { + #[error("{0}")] + GeneralError(#[from] GeneralErrorType), + #[error("{0}")] + Dirty(String), +} + #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Function called with insufficient arguments - #[error("Expected {expected} but got {got}")] - MissingPositionalArguments { - /// Expected amount of arguments - expected: usize, - /// Actual amount of arguments - got: usize, - }, /// Function called with trailing positional arguments #[error("Expected {expected} but got {got}")] TrailingPositionalArguments { @@ -66,6 +80,12 @@ pub enum NaslError { /// An Error originating from an SSH-specific NASL function #[error("SSH error: {0}")] Ssh(SshError), + #[error("{0}")] + Argument(#[from] ArgumentError), + #[error("{0}")] + Builtin(#[from] BuiltinError), + #[error("{0}")] + Internal(#[from] InternalError), } // It would be nicer to derive this using #[from] from diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 6f36f68aa..4a3099ce0 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -27,7 +27,7 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( let positional = register.positional(); let arg = positional.get(position).ok_or_else(|| { let num_given = positional.len(); - NaslError::MissingPositionalArguments { + ArgumentError::MissingPositionals { expected: num_required_positional_args, got: num_given, } diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index 044e54a9a..e5bb8d2ab 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -12,6 +12,8 @@ pub mod lookup_keys; use std::collections::HashMap; pub use context::{Context, ContextType, Register}; +pub use error::ArgumentError; +pub use error::InternalError; pub use error::NaslError; pub use executor::{Executor, IntoFunctionSet, StoredFunctionSet}; From 250ffc13f890e6da3258997de7fd82d1064dea76 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 10:07:32 +0100 Subject: [PATCH 03/36] Move TrailingPositionalArguments to new variant --- rust/src/nasl/builtin/knowledge_base/tests.rs | 2 +- rust/src/nasl/builtin/misc/tests.rs | 2 +- rust/src/nasl/builtin/string/tests.rs | 2 +- rust/src/nasl/utils/error.rs | 8 -------- rust/src/nasl/utils/function/utils.rs | 5 +++-- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/rust/src/nasl/builtin/knowledge_base/tests.rs b/rust/src/nasl/builtin/knowledge_base/tests.rs index 0c19f5e3f..131480d97 100644 --- a/rust/src/nasl/builtin/knowledge_base/tests.rs +++ b/rust/src/nasl/builtin/knowledge_base/tests.rs @@ -22,7 +22,7 @@ mod tests { check_err_matches!( t, r#"get_kb_item("test", 1);"#, - NaslError::TrailingPositionalArguments { .. } + Argument(ArgumentError::TrailingPositionals { .. }), ); check_err_matches!( t, diff --git a/rust/src/nasl/builtin/misc/tests.rs b/rust/src/nasl/builtin/misc/tests.rs index 8d12057e4..acaec7901 100644 --- a/rust/src/nasl/builtin/misc/tests.rs +++ b/rust/src/nasl/builtin/misc/tests.rs @@ -38,7 +38,7 @@ mod tests { check_err_matches!( t, r#"typeof(23,76);"#, - NaslError::TrailingPositionalArguments { .. } + NaslError::Argument(ArgumentError::TrailingPositionals { .. }) ); t.ok("d['test'] = 2;", 2); t.ok("typeof(d);", "array"); diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index a4c874c34..437e9439d 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -12,7 +12,7 @@ mod tests { check_code_result("hexstr('foo');", "666f6f"); check_err_matches!( "hexstr('foo', 'I will be ignored');", - TrailingPositionalArguments { .. }, + Argument(ArgumentError::TrailingPositionals { .. }), ); check_code_result("hexstr(6);", Null); check_code_result("hexstr();", Null); diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index b44fb9cf5..aa36f0884 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -41,14 +41,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Function called with trailing positional arguments - #[error("Expected {expected} but got {got}")] - TrailingPositionalArguments { - /// Expected amount of arguments - expected: usize, - /// Actual amount of arguments - got: usize, - }, /// Function called without required named arguments #[error("Missing arguments: {}", .0.join(", "))] MissingArguments(Vec), diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 4a3099ce0..41057f5a9 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -149,10 +149,11 @@ pub fn check_args( let num_positional_expected = max_num_expected_positional - num_maybe_named_given; if num_positional_given > num_positional_expected { #[cfg(feature = "enforce-no-trailing-arguments")] - return Err(NaslError::TrailingPositionalArguments { + return Err(ArgumentError::TrailingPositionals { expected: num_positional_expected, got: num_positional_given, - }); + } + .into()); #[cfg(not(feature = "enforce-no-trailing-arguments"))] tracing::debug!( "Trailing positional arguments in NASL function {_nasl_fn_name}. Expected {num_positional_expected}, found {num_positional_given}" From c306601bb52b3930ac3a952380606cfd00bd23f5 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 10:33:41 +0100 Subject: [PATCH 04/36] Improve check_err_matches! ergonomics. More specifically, allow autoconversion into the type of the match pattern, so that one does not need to specify the fully qualified error variant every time. --- rust/src/nasl/builtin/cryptographic/des.rs | 5 +-- rust/src/nasl/builtin/description/mod.rs | 2 +- rust/src/nasl/builtin/knowledge_base/tests.rs | 13 ++------ rust/src/nasl/builtin/misc/tests.rs | 2 +- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 5 +-- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 5 +-- rust/src/nasl/builtin/string/tests.rs | 30 +++++------------ rust/src/nasl/test_utils.rs | 25 ++++++++++++-- rust/src/nasl/utils/error.rs | 33 +++++++++++++++++++ 9 files changed, 78 insertions(+), 42 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index 52d7ad146..324364c22 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -13,10 +13,11 @@ fn encrypt_des( ) -> Result { let positional = register.positional(); if positional.len() != 2 { - return Err(NaslError::Argument(ArgumentError::MissingPositionals { + return Err(ArgumentError::MissingPositionals { expected: 2, got: positional.len(), - })); + } + .into()); } let key = match &positional[1] { crate::nasl::syntax::NaslValue::Data(x) => x, diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index fedce7fcd..57fcf787d 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -65,7 +65,7 @@ macro_rules! make_storage_function { let positional = registrat.positional(); if $len > 0 && positional.len() != $len{ return Err( - NaslError::Argument(ArgumentError::MissingPositionals { expected: $len, got: positional.len() }) + ArgumentError::MissingPositionals { expected: $len, got: positional.len() }.into() ); } for p in positional { diff --git a/rust/src/nasl/builtin/knowledge_base/tests.rs b/rust/src/nasl/builtin/knowledge_base/tests.rs index 131480d97..69f081e5f 100644 --- a/rust/src/nasl/builtin/knowledge_base/tests.rs +++ b/rust/src/nasl/builtin/knowledge_base/tests.rs @@ -5,6 +5,7 @@ #[cfg(test)] mod tests { use crate::nasl::test_prelude::*; + use ArgumentError::*; use NaslError::*; #[test] @@ -19,16 +20,8 @@ mod tests { let mut t = TestBuilder::default(); t.ok(r#"set_kb_item(name: "test", value: 1);"#, NaslValue::Null); t.ok(r#"get_kb_item("test");"#, 1); - check_err_matches!( - t, - r#"get_kb_item("test", 1);"#, - Argument(ArgumentError::TrailingPositionals { .. }), - ); - check_err_matches!( - t, - r#"get_kb_item();"#, - Argument(ArgumentError::MissingPositionals { .. }) - ); + check_err_matches!(t, r#"get_kb_item("test", 1);"#, TrailingPositionals { .. },); + check_err_matches!(t, r#"get_kb_item();"#, MissingPositionals { .. }); } #[test] diff --git a/rust/src/nasl/builtin/misc/tests.rs b/rust/src/nasl/builtin/misc/tests.rs index acaec7901..2e1e1281e 100644 --- a/rust/src/nasl/builtin/misc/tests.rs +++ b/rust/src/nasl/builtin/misc/tests.rs @@ -38,7 +38,7 @@ mod tests { check_err_matches!( t, r#"typeof(23,76);"#, - NaslError::Argument(ArgumentError::TrailingPositionals { .. }) + ArgumentError::TrailingPositionals { .. } ); t.ok("d['test'] = 2;", 2); t.ok("typeof(d);", "array"); diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 2509da03f..24c9a3c4f 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -410,10 +410,11 @@ fn nasl_get_local_mac_address_from_ip( ) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::Argument(ArgumentError::MissingPositionals { + return Err(ArgumentError::MissingPositionals { expected: 1, got: 0, - })); + } + .into()); } match &positional[0] { diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index a50f24aac..d9cb3381d 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -387,10 +387,11 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::Argument(ArgumentError::MissingPositionals { + return Err(ArgumentError::MissingPositionals { expected: 1, got: 0, - })); + } + .into()); } for ip in positional.iter() { diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index 437e9439d..d1b6b5760 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -4,6 +4,7 @@ #[cfg(test)] mod tests { use crate::nasl::{test_prelude::*, utils::error::ArgumentError}; + use ArgumentError::*; use NaslError::*; use NaslValue::*; @@ -12,7 +13,7 @@ mod tests { check_code_result("hexstr('foo');", "666f6f"); check_err_matches!( "hexstr('foo', 'I will be ignored');", - Argument(ArgumentError::TrailingPositionals { .. }), + TrailingPositionals { .. }, ); check_code_result("hexstr(6);", Null); check_code_result("hexstr();", Null); @@ -82,10 +83,7 @@ mod tests { check_code_result("chomp('abc\n');", "abc"); check_code_result("chomp('abc ');", "abc"); check_code_result("chomp('abc\n\t\r ');", "abc"); - check_err_matches!( - "chomp();", - Argument(ArgumentError::MissingPositionals { .. }) - ); + check_err_matches!("chomp();", MissingPositionals { .. }); } #[test] @@ -126,7 +124,7 @@ mod tests { check_code_result(r#"ord("c");"#, 99); check_code_result(r#"ord("");"#, Null); check_code_result("ord(1);", 49); - check_err_matches!("ord();", Argument(ArgumentError::MissingPositionals { .. })); + check_err_matches!("ord();", MissingPositionals { .. }); } #[test] @@ -156,10 +154,7 @@ mod tests { check_code_result(r#"hex(256);"#, "0x00"); check_code_result(r#"hex(257);"#, "0x01"); check_code_result(r#"hex(-2);"#, "0xfe"); - check_err_matches!( - r#"hex();"#, - Argument(ArgumentError::MissingPositionals { .. }) - ); + check_err_matches!(r#"hex();"#, MissingPositionals { .. }); } #[test] @@ -216,10 +211,7 @@ mod tests { r#"split("a;b;c", sep: ";");"#, vec!["a;".to_string(), "b;".to_string(), "c".to_string()], ); - check_err_matches!( - r#"split();"#, - Argument(ArgumentError::MissingPositionals { .. }) - ); + check_err_matches!(r#"split();"#, MissingPositionals { .. }); } #[test] @@ -245,13 +237,7 @@ mod tests { check_code_result(r#"strstr("abc", "b");"#, "bc"); check_code_result(r#"strstr("abcbd", "b");"#, "bcbd"); check_code_result(r#"strstr('a\rbcbd', '\rb');"#, "\rbcbd"); - check_err_matches!( - r#"strstr();"#, - Argument(ArgumentError::MissingPositionals { .. }) - ); - check_err_matches!( - r#"strstr("a");"#, - Argument(ArgumentError::MissingPositionals { .. }) - ); + check_err_matches!(r#"strstr();"#, MissingPositionals { .. }); + check_err_matches!(r#"strstr("a");"#, MissingPositionals { .. }); } } diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index 1ed0a4d86..ee1606cff 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -398,11 +398,32 @@ pub fn check_code_result(code: &str, expected: impl ToNaslResult) { #[macro_export] macro_rules! check_err_matches { ($t: ident, $code: expr, $pat: pat $(,)?) => { - $t.check($code, |e| matches!(e, Err($pat)), Some(stringify!($pat))); + $t.check( + $code, + |e| { + if let Err(e) = e { + // Convert with try_into to allow using + // the variants of `NaslError` directly without + // having to wrap them in the outer enum. + let converted = e.try_into(); + // This is only irrefutable for the + // NaslError -> NaslError conversion but not for others. + #[allow(irrefutable_let_patterns)] + if let Ok(e) = converted { + matches!(e, $pat) + } else { + false + } + } else { + false + } + }, + Some(stringify!($pat)), + ); }; ($code: expr, $pat: pat $(,)?) => { let mut t = $crate::nasl::test_utils::TestBuilder::default(); - t.check($code, |e| matches!(e, Err($pat)), Some(stringify!($pat))); + check_err_matches!(t, $code, $pat); }; } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index aa36f0884..6b11bfe27 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -80,6 +80,39 @@ pub enum NaslError { Internal(#[from] InternalError), } +impl TryFrom for ArgumentError { + type Error = (); + + fn try_from(value: NaslError) -> Result { + match value { + NaslError::Argument(e) => Ok(e), + _ => Err(()), + } + } +} + +impl TryFrom for InternalError { + type Error = (); + + fn try_from(value: NaslError) -> Result { + match value { + NaslError::Internal(e) => Ok(e), + _ => Err(()), + } + } +} + +impl TryFrom for BuiltinError { + type Error = (); + + fn try_from(value: NaslError) -> Result { + match value { + NaslError::Builtin(e) => Ok(e), + _ => Err(()), + } + } +} + // It would be nicer to derive this using #[from] from // thiserror, but io::Error does not impl `PartialEq`, // `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which From d213320c4656434b124b7a1cfd26184b45f0f64b Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 10:41:50 +0100 Subject: [PATCH 05/36] Move MissingArguments to ArgumentError --- rust/src/nasl/builtin/description/mod.rs | 12 ++++-------- rust/src/nasl/builtin/knowledge_base/tests.rs | 5 ++--- rust/src/nasl/builtin/string/tests.rs | 8 ++++---- rust/src/nasl/utils/error.rs | 5 +---- rust/src/nasl/utils/function/utils.rs | 2 +- rust/src/nasl/utils/mod.rs | 2 +- 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index 57fcf787d..4a6066d7e 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -200,10 +200,7 @@ fn as_tag_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_xref_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { if arguments.len() != 2 { - return Err(NaslError::MissingArguments(vec![ - "name".to_owned(), - "csv".to_owned(), - ])); + return Err(ArgumentError::MissingNamed(vec!["name".to_owned(), "csv".to_owned()]).into()); } Ok(vec![NVTField::Reference(vec![NvtRef { class: arguments[1].to_string(), @@ -213,10 +210,9 @@ fn as_xref_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_preference(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { if arguments.len() < 3 { - return Err(NaslError::MissingArguments(vec![ - "type".to_owned(), - "value".to_owned(), - ])); + return Err( + ArgumentError::MissingNamed(vec!["type".to_owned(), "value".to_owned()]).into(), + ); } let name = arguments[0].to_string(); let class = arguments[1].to_string(); diff --git a/rust/src/nasl/builtin/knowledge_base/tests.rs b/rust/src/nasl/builtin/knowledge_base/tests.rs index 69f081e5f..9cccfacb3 100644 --- a/rust/src/nasl/builtin/knowledge_base/tests.rs +++ b/rust/src/nasl/builtin/knowledge_base/tests.rs @@ -6,13 +6,12 @@ mod tests { use crate::nasl::test_prelude::*; use ArgumentError::*; - use NaslError::*; #[test] fn set_kb_item() { check_code_result(r#"set_kb_item(name: "test", value: 1);"#, NaslValue::Null); - check_err_matches!(r#"set_kb_item(name: "test");"#, MissingArguments { .. }); - check_err_matches!(r#"set_kb_item(value: 1);"#, MissingArguments { .. }); + check_err_matches!(r#"set_kb_item(name: "test");"#, MissingNamed { .. }); + check_err_matches!(r#"set_kb_item(value: 1);"#, MissingNamed { .. }); } #[test] diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index d1b6b5760..332c0c046 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -142,8 +142,8 @@ mod tests { // g_pattern_spec allows globs to match slashes, make sure we do too check_code_result(r#"match(string: "a///", pattern: "a*");"#, true); check_code_result(r#"match(string: "///a", pattern: "*a");"#, true); - check_err_matches!(r#"match(string: "abcd");"#, MissingArguments { .. }); - check_err_matches!(r#"match(pattern: "ab");"#, MissingArguments { .. }); + check_err_matches!(r#"match(string: "abcd");"#, MissingNamed { .. }); + check_err_matches!(r#"match(pattern: "ab");"#, MissingNamed { .. }); } #[test] @@ -220,8 +220,8 @@ mod tests { r#"str_replace(string: "abc", find: "b", replace: "foo");"#, "afooc", ); - check_err_matches!(r#"str_replace();"#, MissingArguments { .. }); - check_err_matches!(r#"str_replace(string: "abc");"#, MissingArguments { .. }); + check_err_matches!(r#"str_replace();"#, MissingNamed { .. }); + check_err_matches!(r#"str_replace(string: "abc");"#, MissingNamed { .. }); check_code_result(r#"str_replace(string: "abc", find: "b");"#, "ac"); check_code_result( r#"str_replace(string: "abcbd", find: "b", count: 1);"#, diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 6b11bfe27..a13793ea1 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -41,9 +41,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Function called without required named arguments - #[error("Missing arguments: {}", .0.join(", "))] - MissingArguments(Vec), /// Function called with additional, unexpected named arguments #[error("Unknown named argument given to function: {}", .0)] UnexpectedArgument(String), @@ -141,7 +138,7 @@ impl NaslError { /// Helper function to quickly construct a `MissingArguments` variant /// for a single missing argument. pub fn missing_argument(val: &str) -> Self { - Self::MissingArguments(vec![val.to_string()]) + Self::Argument(ArgumentError::MissingNamed(vec![val.to_string()])) } } diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 41057f5a9..525f38be8 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -70,7 +70,7 @@ pub fn get_named_arg<'a, T: FromNaslValue<'a>>( ) -> Result { let arg = register .named(name) - .ok_or_else(|| NaslError::MissingArguments(vec![name.to_string()]))?; + .ok_or_else(|| ArgumentError::MissingNamed(vec![name.to_string()]))?; ::from_nasl_value(context_type_as_nasl_value(arg, name)?) } diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index e5bb8d2ab..2bf65ed71 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -52,7 +52,7 @@ pub fn get_named_parameter<'a>( match registrat.named(key) { None => { if required { - Err(NaslError::MissingArguments(vec![key.to_owned()])) + Err(ArgumentError::MissingNamed(vec![key.to_owned()]).into()) } else { // we use exit because a named value can be intentionally set to null and may be // treated differently when it is not set compared to set but null. From e96399ffb2724ad5165fb1a3d2094c5ae1b8632f Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 10:43:44 +0100 Subject: [PATCH 06/36] Move UnexpectedArgument to ArgumentError --- rust/src/nasl/utils/error.rs | 5 +---- rust/src/nasl/utils/function/utils.rs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index a13793ea1..74f690c3c 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -25,7 +25,7 @@ pub enum ArgumentError { #[error("Missing arguments: {}", .0.join(", "))] MissingNamed(Vec), #[error("Unknown named argument given to function: {}", .0)] - Unexpected(String), + UnexpectedArgument(String), #[error("Function was called with wrong arguments: {0}")] Wrong(String), } @@ -41,9 +41,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Function called with additional, unexpected named arguments - #[error("Unknown named argument given to function: {}", .0)] - UnexpectedArgument(String), /// Wraps formatting error #[error("Formatting error: {0}")] FMTError(#[from] std::fmt::Error), diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 525f38be8..7ecdb463d 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -123,7 +123,7 @@ fn check_named_args( num_maybe_named += 1; } else { #[cfg(feature = "enforce-no-trailing-arguments")] - return Err(NaslError::UnexpectedArgument(arg_name.into())); + return Err(ArgumentError::UnexpectedArgument(arg_name.into()).into()); #[cfg(not(feature = "enforce-no-trailing-arguments"))] tracing::debug!( "Unexpected named argument '{arg_name}' in NASL function {_nasl_fn_name}." From a5f603b299e50305eb8ac98188de7314ebe36bb2 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 11:15:52 +0100 Subject: [PATCH 07/36] Move WrongArgument into Argument variant --- .../src/nasl/builtin/cryptographic/aes_cbc.rs | 16 ++--- rust/src/nasl/builtin/cryptographic/des.rs | 19 +++-- rust/src/nasl/builtin/cryptographic/mod.rs | 25 ++++--- rust/src/nasl/builtin/http/mod.rs | 12 +++- rust/src/nasl/builtin/network/mod.rs | 7 +- rust/src/nasl/builtin/network/socket.rs | 29 ++++---- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 5 +- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 70 +++++++++++-------- rust/src/nasl/builtin/ssh/tests/mod.rs | 2 +- rust/src/nasl/builtin/ssh/utils.rs | 6 +- rust/src/nasl/builtin/string/mod.rs | 23 +++--- rust/src/nasl/builtin/string/tests.rs | 1 - rust/src/nasl/utils/error.rs | 23 +++--- .../nasl/utils/function/from_nasl_value.rs | 21 +++--- rust/src/nasl/utils/function/types.rs | 6 +- rust/src/nasl/utils/function/utils.rs | 4 +- rust/src/nasl/utils/mod.rs | 4 +- 17 files changed, 146 insertions(+), 127 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs index db60514be..4da1c2374 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs @@ -12,10 +12,7 @@ use aes::{ }; use cbc::{Decryptor, Encryptor}; -use crate::function_set; -use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::NaslError; -use crate::nasl::utils::{Context, Register}; +use crate::nasl::prelude::*; use super::{get_data, get_iv, get_key, get_len, Crypt}; @@ -35,7 +32,7 @@ where let res = Encryptor::::new_from_slices(key, iv); match res { Ok(encryptor) => Ok(encryptor.encrypt_padded_vec_mut::(data).into()), - Err(e) => Err(NaslError::WrongArgument(e.to_string())), + Err(e) => Err(ArgumentError::WrongArgument(e.to_string()).into()), } } Crypt::Decrypt => { @@ -47,20 +44,21 @@ where // len should not be more than the length of the data if len > data.len() { - return Err(NaslError::wrong_argument( + return Err(ArgumentError::wrong_argument( "len", format!("<={:?}", data.len()).as_str(), len.to_string().as_str(), - )); + ) + .into()); } let res = Decryptor::::new_from_slices(key, iv); match res { Ok(decryptor) => Ok(decryptor .decrypt_padded_vec_mut::(data) - .map_err(|e| NaslError::WrongArgument(e.to_string()))?[..len] + .map_err(|e| ArgumentError::WrongArgument(e.to_string()))?[..len] .to_vec() .into()), - Err(e) => Err(NaslError::WrongArgument(e.to_string())), + Err(e) => Err(ArgumentError::WrongArgument(e.to_string()).into()), } } } diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index 324364c22..20944a225 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -7,10 +7,7 @@ use aes::cipher::BlockEncrypt; use ccm::KeyInit; use des::cipher::generic_array::GenericArray; -fn encrypt_des( - register: &Register, - _: &Context, -) -> Result { +fn encrypt_des(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.len() != 2 { return Err(ArgumentError::MissingPositionals { @@ -20,17 +17,17 @@ fn encrypt_des( .into()); } let key = match &positional[1] { - crate::nasl::syntax::NaslValue::Data(x) => x, - _ => return Err(NaslError::WrongArgument("expected Data.".to_string())), + NaslValue::Data(x) => x, + _ => return Err(ArgumentError::WrongArgument("expected Data.".to_string()).into()), }; if key.len() != 8 { - return Err(NaslError::WrongArgument( - "16, 32 or 48 bytes length key".to_string(), - )); + return Err( + ArgumentError::WrongArgument("16, 32 or 48 bytes length key".to_string()).into(), + ); } let mut data = GenericArray::clone_from_slice(match &positional[0] { - crate::nasl::syntax::NaslValue::Data(x) => x, - _ => return Err(NaslError::WrongArgument("expected Data.".to_string())), + NaslValue::Data(x) => x, + _ => return Err(ArgumentError::WrongArgument("expected Data.".to_string()).into()), }); let des_cipher = des::Des::new(&GenericArray::clone_from_slice(key)); des_cipher.encrypt_block(&mut data); diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 73e83e47f..5e748b2ba 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -3,9 +3,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception // use crate::nasl::utils::combine_function_sets; -use crate::nasl::utils::error::NaslError; +use crate::nasl::prelude::*; -use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{ContextType, IntoFunctionSet, Register, StoredFunctionSet}; pub mod aes_cbc; @@ -36,16 +35,16 @@ enum Crypt { fn get_required_named_data<'a>( register: &'a Register, key: &'a str, -) -> Result<&'a [u8], NaslError> { +) -> Result<&'a [u8], ArgumentError> { match register.named(key) { Some(ContextType::Value(NaslValue::Data(x))) => Ok(x.as_slice()), Some(ContextType::Value(NaslValue::String(x))) => Ok(x.as_bytes()), - Some(x) => Err(NaslError::wrong_argument( + Some(x) => Err(ArgumentError::wrong_argument( key, "a String or Data Value", format!("{:?}", x).as_str(), )), - _ => Err(NaslError::missing_argument(key)), + _ => Err(ArgumentError::MissingNamed(vec![key.into()]).into()), } } @@ -53,10 +52,10 @@ fn get_required_named_data<'a>( /// In case the argument is required, the returned value is either an Error or the Option is always /// set to Some value. If it is false, no error will be returned but the Option can be either Some /// or None. -fn get_optional_named_number(register: &Register, key: &str) -> Result, NaslError> { +fn get_optional_named_number(register: &Register, key: &str) -> Result, ArgumentError> { match register.named(key) { Some(ContextType::Value(NaslValue::Number(x))) => Ok(Some(*x)), - Some(x) => Err(NaslError::wrong_argument( + Some(x) => Err(ArgumentError::wrong_argument( key, "a Number Value", format!("{:?}", x).as_str(), @@ -66,33 +65,33 @@ fn get_optional_named_number(register: &Register, key: &str) -> Result Result<&[u8], NaslError> { +fn get_key(register: &Register) -> Result<&[u8], ArgumentError> { get_required_named_data(register, "key") } /// Get the required data argument or error. -fn get_data(register: &Register) -> Result<&[u8], NaslError> { +fn get_data(register: &Register) -> Result<&[u8], ArgumentError> { get_required_named_data(register, "data") } /// Get the required iv argument or error. -fn get_iv(register: &Register) -> Result<&[u8], NaslError> { +fn get_iv(register: &Register) -> Result<&[u8], ArgumentError> { get_required_named_data(register, "iv") } /// Get the required iv argument or error. -fn get_aad(register: &Register) -> Result<&[u8], NaslError> { +fn get_aad(register: &Register) -> Result<&[u8], ArgumentError> { get_required_named_data(register, "aad") } /// Get the optional len argument with proper error handling. -fn get_len(register: &Register) -> Result, NaslError> { +fn get_len(register: &Register) -> Result, ArgumentError> { let buf = get_optional_named_number(register, "len")?; match buf { None => Ok(None), Some(x) => match x.try_into() { Ok(y) => Ok(Some(y)), - Err(_) => Err(NaslError::WrongArgument(format!( + Err(_) => Err(ArgumentError::WrongArgument(format!( "System only supports numbers between {:?} and {:?} but was {:?}", usize::MIN, usize::MAX, diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index f0513e29c..585c06ee6 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -220,7 +220,9 @@ impl NaslHttp { ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), + _ => { + return Err(ArgumentError::WrongArgument(("Invalid handle ID").to_string()).into()) + } }; let mut handles = lock_handles(&self.handles).await?; @@ -407,7 +409,9 @@ impl NaslHttp { ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), + _ => { + return Err(ArgumentError::WrongArgument(("Invalid handle ID").to_string()).into()) + } }; let mut handles = lock_handles(&self.handles).await?; @@ -444,7 +448,9 @@ impl NaslHttp { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => return Err(NaslError::WrongArgument(("Invalid handle ID").to_string())), + _ => { + return Err(ArgumentError::WrongArgument(("Invalid handle ID").to_string()).into()) + } }; let mut handles = lock_handles(&self.handles).await?; diff --git a/rust/src/nasl/builtin/network/mod.rs b/rust/src/nasl/builtin/network/mod.rs index f5537df3d..eeaedebcc 100644 --- a/rust/src/nasl/builtin/network/mod.rs +++ b/rust/src/nasl/builtin/network/mod.rs @@ -4,8 +4,7 @@ use std::{fmt::Display, net::IpAddr}; -use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{Context, NaslError}; +use crate::nasl::prelude::*; use crate::storage::{Field, Retrieve}; #[allow(clippy::module_inception)] @@ -89,9 +88,9 @@ pub fn get_kb_item(context: &Context, name: &str) -> Result, N .map_err(|e| e.into()) } -pub fn verify_port(port: i64) -> Result { +pub fn verify_port(port: i64) -> Result { if !(0..=65535).contains(&port) { - return Err(NaslError::WrongArgument(format!( + return Err(ArgumentError::WrongArgument(format!( "{} is not a valid port number", port ))); diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index c7ec81497..e3c2e0447 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -13,8 +13,7 @@ use std::{ }; use crate::function_set; -use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{error::NaslError, Context}; +use crate::nasl::prelude::*; use dns_lookup::lookup_host; use nasl_function_proc_macro::nasl_function; use pkcs8::der::Decode; @@ -289,7 +288,7 @@ impl NaslSockets { .unwrap() .handles .get_mut(socket) - .ok_or(NaslError::WrongArgument(format!( + .ok_or(ArgumentError::WrongArgument(format!( "the given socket FD {socket} does not exist" )))? { NaslSocket::Tcp(conn) => { @@ -311,9 +310,10 @@ impl NaslSockets { } } NaslSocket::Udp(conn) => unsafe { conn.send(data, len, flags.unwrap_or(0) as i32) }, - NaslSocket::Close => Err(NaslError::WrongArgument( + NaslSocket::Close => Err(ArgumentError::WrongArgument( "the given socket FD is already closed".to_string(), - )), + ) + .into()), } } @@ -365,7 +365,7 @@ impl NaslSockets { .unwrap() .handles .get_mut(socket) - .ok_or(NaslError::WrongArgument(format!( + .ok_or(ArgumentError::WrongArgument(format!( "the given socket FD {socket} does not exist" )))? { NaslSocket::Tcp(conn) => { @@ -425,9 +425,10 @@ impl NaslSockets { } ret } - NaslSocket::Close => Err(NaslError::WrongArgument( + NaslSocket::Close => Err(ArgumentError::WrongArgument( "the given socket FD is already closed".to_string(), - )), + ) + .into()), } } @@ -581,9 +582,10 @@ impl NaslSockets { } // Unsupported transport layer None | Some(OpenvasEncaps::Max) => { - return Err(NaslError::WrongArgument(format!( + return Err(ArgumentError::WrongArgument(format!( "unsupported transport layer: {transport}(unknown)" - ))) + )) + .into()) } // TLS/SSL Some(tls_version) => match tls_version { @@ -593,9 +595,10 @@ impl NaslSockets { fds.push(self.add(fd)) } _ => { - return Err(NaslError::WrongArgument(format!( + return Err(ArgumentError::WrongArgument(format!( "unsupported transport layer: {transport}{tls_version}" - ))) + )) + .into()) } }, } @@ -740,7 +743,7 @@ impl NaslSockets { let config = ClientConfig::builder() .with_root_certificates(root_store) .with_client_auth_cert(cert, key) - .map_err(|_| NaslError::WrongArgument("Invalid Key".to_string()))?; + .map_err(|_| ArgumentError::WrongArgument("Invalid Key".to_string()))?; self.open_sock_tcp_ip( context, diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 24c9a3c4f..6656cec9f 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -429,9 +429,10 @@ fn nasl_get_local_mac_address_from_ip( )), } } - _ => Err(NaslError::WrongArgument( + _ => Err(ArgumentError::WrongArgument( "Expected String containing a valid IP address.".to_string(), - )), + ) + .into()), } } diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index d9cb3381d..04f32d4af 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -125,10 +125,11 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result { - return Err(NaslError::WrongArgument(format!("Invalid ip_src: {}", e))); + return Err( + ArgumentError::WrongArgument(format!("Invalid ip_src: {}", e)).into(), + ); } }; x.to_string() @@ -217,7 +220,9 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result { - return Err(NaslError::WrongArgument(format!("Invalid ip_dst: {}", e))); + return Err( + ArgumentError::WrongArgument(format!("Invalid ip_dst: {}", e)).into(), + ); } }; x.to_string() @@ -228,7 +233,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result { - return Err(NaslError::WrongArgument(format!("Invalid ip: {}", e))); + return Err(ArgumentError::WrongArgument(format!("Invalid ip: {}", e)).into()); } }; dst_addr.to_string() @@ -322,7 +327,7 @@ fn set_ip_elements(register: &Register, _configs: &Context) -> Result { - return Err(NaslError::WrongArgument(format!("Invalid ip_src: {}", e))); + return Err(ArgumentError::WrongArgument(format!("Invalid ip_src: {}", e)).into()); } }; }; @@ -377,7 +382,7 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Number(pkt.get_checksum() as i64)), "ip_src" => Ok(NaslValue::String(pkt.get_source().to_string())), "ip_dst" => Ok(NaslValue::String(pkt.get_destination().to_string())), - _ => Err(NaslError::WrongArgument("Invalid element".to_string())), + _ => Err(ArgumentError::WrongArgument("Invalid element".to_string()).into()), }, _ => Err(NaslError::missing_argument("element")), } @@ -415,7 +420,7 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { - return Err(NaslError::WrongArgument("Invalid ip packet".to_string())); + return Err(ArgumentError::WrongArgument("Invalid ip packet".to_string()).into()); } } } @@ -682,7 +687,7 @@ fn get_tcp_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Number(tcp.get_checksum() as i64)), "th_urp" => Ok(NaslValue::Number(tcp.get_urgent_ptr() as i64)), "th_data" => Ok(NaslValue::Data(tcp.payload().to_vec())), - _ => Err(NaslError::WrongArgument("element".to_string())), + _ => Err(ArgumentError::WrongArgument("element".to_string()).into()), }, _ => Err(NaslError::missing_argument("element")), } @@ -754,7 +759,7 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Number(window)), 4 => Ok(NaslValue::Number(sack_permitted)), 8 => Ok(NaslValue::Array(timestamps)), - _ => Err(NaslError::WrongArgument("Invalid option".to_string())), + _ => Err(ArgumentError::WrongArgument("Invalid option".to_string()).into()), }, _ => Err(NaslError::missing_argument("option")), } @@ -966,9 +971,10 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result { @@ -977,9 +983,10 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result Result break, _ => { - return Err(NaslError::WrongArgument( + return Err(ArgumentError::WrongArgument( "insert_tcp_options: invalid tcp option".to_string(), - )); + ) + .into()); } } } @@ -1113,7 +1123,9 @@ fn dump_tcp_packet(register: &Register, _: &Context) -> Result ip, None => { - return Err(NaslError::WrongArgument("Invalid TCP packet".to_string())); + return Err( + ArgumentError::WrongArgument("Invalid TCP packet".to_string()).into(), + ); } }; @@ -1135,12 +1147,14 @@ fn dump_tcp_packet(register: &Register, _: &Context) -> Result { - return Err(NaslError::WrongArgument("Invalid TCP packet".to_string())); + return Err( + ArgumentError::WrongArgument("Invalid TCP packet".to_string()).into(), + ); } } } _ => { - return Err(NaslError::WrongArgument("Invalid ip packet".to_string())); + return Err(ArgumentError::WrongArgument("Invalid ip packet".to_string()).into()); } } } @@ -1395,7 +1409,7 @@ fn dump_udp_packet(register: &Register, _: &Context) -> Result Result Ok(NaslValue::Number(udp.get_length() as i64)), "uh_sum" => Ok(NaslValue::Number(udp.get_checksum() as i64)), "data" => Ok(NaslValue::Data(udp.payload().to_vec())), - _ => Err(NaslError::WrongArgument("element".to_string())), + _ => Err(ArgumentError::WrongArgument("element".to_string()).into()), }, - _ => Err(NaslError::WrongArgument("element".to_string())), + _ => Err(ArgumentError::WrongArgument("element".to_string()).into()), } } @@ -1929,10 +1943,10 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result FromNaslValue<'a> for key::Name { fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; key::Name::try_from(&*s).map_err(|_| { - NaslError::WrongArgument(format!("Expected a valid SSH key type, found '{}'", s)) + ArgumentError::WrongArgument(format!("Expected a valid SSH key type, found '{}'", s)) + .into() }) } } @@ -39,7 +40,8 @@ impl<'a> FromNaslValue<'a> for cipher::Name { fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; cipher::Name::try_from(&*s).map_err(|_| { - NaslError::WrongArgument(format!("Expected a valid SSH cipher type, found '{}'", s)) + ArgumentError::WrongArgument(format!("Expected a valid SSH cipher type, found '{}'", s)) + .into() }) } } diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 25bcd3cc9..b8b2048f1 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -7,17 +7,18 @@ #[cfg(test)] mod tests; -use crate::nasl::utils::{ - function::{bytes_to_str, CheckedPositionals, Maybe, StringOrData}, - Context, NaslError, Register, +use crate::nasl::{ + utils::{ + function::{bytes_to_str, CheckedPositionals, Maybe, StringOrData}, + NaslError, + }, + ArgumentError, }; use core::fmt::Write; use glob::{MatchOptions, Pattern}; -use nasl_function_proc_macro::nasl_function; use std::num::ParseIntError; -use crate::function_set; -use crate::nasl::syntax::NaslValue; +use crate::nasl::prelude::*; /// Decodes given string as hex and returns the result as a byte array pub fn decode_hex(s: &str) -> Result, ParseIntError> { @@ -219,11 +220,11 @@ fn hex(s: i64) -> String { /// /// The first positional argument must be a string, all other arguments are ignored. If either the no argument was given or the first positional is not a string, a error is returned. #[nasl_function] -fn hexstr_to_data(s: NaslValue) -> Result, NaslError> { +fn hexstr_to_data(s: NaslValue) -> Result, ArgumentError> { let s = s.to_string(); let s = s.as_str(); decode_hex(s).map_err(|_| { - NaslError::WrongArgument(format!( + ArgumentError::WrongArgument(format!( "Expected an even-length string containing only 0-9a-fA-F, found '{}'", s )) @@ -331,7 +332,7 @@ fn insstr( to_insert: NaslValue, start: usize, end: Option, -) -> Result { +) -> Result { let mut s = s.to_string(); let insb = to_insert.to_string(); @@ -339,7 +340,7 @@ fn insstr( let end = end.unwrap_or(s.len()).min(s.len()); if start > end { - return Err(NaslError::WrongArgument(format!( + return Err(ArgumentError::WrongArgument(format!( "start index ({}) larger than end ({}).", start, end ))); @@ -373,7 +374,7 @@ fn match_(string: NaslValue, pattern: NaslValue, icase: Option) -> Result< Ok(Pattern::new(pattern) .map_err(|err| { - NaslError::WrongArgument(format!( + ArgumentError::WrongArgument(format!( "Argument 'pattern' to 'match' is not a valid pattern: {}. {}", pattern, err )) diff --git a/rust/src/nasl/builtin/string/tests.rs b/rust/src/nasl/builtin/string/tests.rs index 332c0c046..65a796617 100644 --- a/rust/src/nasl/builtin/string/tests.rs +++ b/rust/src/nasl/builtin/string/tests.rs @@ -5,7 +5,6 @@ mod tests { use crate::nasl::{test_prelude::*, utils::error::ArgumentError}; use ArgumentError::*; - use NaslError::*; use NaslValue::*; #[test] diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 74f690c3c..35a45ac1a 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -27,7 +27,7 @@ pub enum ArgumentError { #[error("Unknown named argument given to function: {}", .0)] UnexpectedArgument(String), #[error("Function was called with wrong arguments: {0}")] - Wrong(String), + WrongArgument(String), } #[derive(Debug, Clone, PartialEq, Eq, Error)] @@ -47,9 +47,6 @@ pub enum NaslError { /// Wraps io::Error #[error("IOError: {0}")] IOError(io::ErrorKind), - /// Function was called with wrong arguments - #[error("Function was called with wrong arguments: {0}")] - WrongArgument(String), /// Authentication failed #[error("Authentication failed.")] Authentication, @@ -117,19 +114,23 @@ impl From for NaslError { } } -impl NaslError { +impl ArgumentError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and /// the actual value. pub fn wrong_argument(key: &str, expected: &str, got: &str) -> Self { - Self::WrongArgument(format!("Expected {key} to be {expected} but it is {got}")) + ArgumentError::WrongArgument(format!("Expected {key} to be {expected} but it is {got}")) } +} +impl NaslError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and /// the actual value. pub fn wrong_unnamed_argument(expected: &str, got: &str) -> Self { - Self::WrongArgument(format!("Expected {expected} but {got}")) + Self::Argument(ArgumentError::WrongArgument(format!( + "Expected {expected} but {got}" + ))) } /// Helper function to quickly construct a `MissingArguments` variant @@ -143,7 +144,7 @@ impl From<(&str, &str, &NaslValue)> for NaslError { fn from(value: (&str, &str, &NaslValue)) -> Self { let (key, expected, got) = value; let got: &str = &got.to_string(); - NaslError::wrong_argument(key, expected, got) + ArgumentError::wrong_argument(key, expected, got).into() } } @@ -151,7 +152,7 @@ impl From<(&str, &str, Option<&NaslValue>)> for NaslError { fn from(value: (&str, &str, Option<&NaslValue>)) -> Self { match value { (key, expected, Some(x)) => (key, expected, x).into(), - (key, expected, None) => NaslError::wrong_argument(key, expected, "NULL"), + (key, expected, None) => ArgumentError::wrong_argument(key, expected, "NULL").into(), } } } @@ -161,9 +162,9 @@ impl From<(&str, &str, Option<&ContextType>)> for NaslError { match value { (key, expected, Some(ContextType::Value(x))) => (key, expected, x).into(), (key, expected, Some(ContextType::Function(_, _))) => { - NaslError::wrong_argument(key, expected, "function") + ArgumentError::wrong_argument(key, expected, "function").into() } - (key, expected, None) => NaslError::wrong_argument(key, expected, "NULL"), + (key, expected, None) => ArgumentError::wrong_argument(key, expected, "NULL").into(), } } } diff --git a/rust/src/nasl/utils/function/from_nasl_value.rs b/rust/src/nasl/utils/function/from_nasl_value.rs index 8f59ef21d..106d89742 100644 --- a/rust/src/nasl/utils/function/from_nasl_value.rs +++ b/rust/src/nasl/utils/function/from_nasl_value.rs @@ -25,7 +25,7 @@ impl<'a> FromNaslValue<'a> for String { fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string.to_string()), - _ => Err(NaslError::WrongArgument("Expected string.".to_string())), + _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), } } } @@ -34,7 +34,7 @@ impl<'a> FromNaslValue<'a> for &'a str { fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string), - _ => Err(NaslError::WrongArgument("Expected string.".to_string())), + _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), } } } @@ -43,7 +43,7 @@ impl<'a> FromNaslValue<'a> for &'a [u8] { fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Data(bytes) => Ok(bytes), - _ => Err(NaslError::WrongArgument("Expected byte data.".to_string())), + _ => Err(ArgumentError::WrongArgument("Expected byte data.".to_string()).into()), } } } @@ -55,7 +55,7 @@ impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Vec { .iter() .map(T::from_nasl_value) .collect::, NaslError>>()?), - _ => Err(NaslError::WrongArgument("Expected an array..".to_string())), + _ => Err(ArgumentError::WrongArgument("Expected an array..".to_string()).into()), } } } @@ -67,9 +67,7 @@ impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { .iter() .map(|(k, v)| T::from_nasl_value(v).map(|v| (k.clone(), v))) .collect::, _>>()?), - _ => Err(NaslError::WrongArgument( - "Expected a dictionary.".to_string(), - )), + _ => Err(ArgumentError::WrongArgument("Expected a dictionary.".to_string()).into()), } } } @@ -79,7 +77,7 @@ impl<'a> FromNaslValue<'a> for bool { match value { NaslValue::Boolean(b) => Ok(*b), NaslValue::Number(n) => Ok(*n != 0), - _ => Err(NaslError::WrongArgument("Expected bool.".to_string())), + _ => Err(ArgumentError::WrongArgument("Expected bool.".to_string()).into()), } } } @@ -90,12 +88,13 @@ macro_rules! impl_from_nasl_value_for_numeric_type { fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::Number(num) => Ok(<$ty>::try_from(*num).map_err(|_| { - NaslError::WrongArgument("Expected positive number.".into()) + ArgumentError::WrongArgument("Expected positive number.".into()) })?), - e => Err(NaslError::WrongArgument(format!( + e => Err(ArgumentError::WrongArgument(format!( "Expected a number, found '{}'.", e - ))), + )) + .into()), } } } diff --git a/rust/src/nasl/utils/function/types.rs b/rust/src/nasl/utils/function/types.rs index c6cb6b361..ff1920f45 100644 --- a/rust/src/nasl/utils/function/types.rs +++ b/rust/src/nasl/utils/function/types.rs @@ -9,9 +9,9 @@ impl<'a> FromNaslValue<'a> for StringOrData { match value { NaslValue::String(string) => Ok(Self(string.clone())), NaslValue::Data(buffer) => Ok(Self(bytes_to_str(buffer))), - _ => Err(NaslError::WrongArgument( - "Expected string or byte buffer.".to_string(), - )), + _ => Err( + ArgumentError::WrongArgument("Expected string or byte buffer.".to_string()).into(), + ), } } } diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 7ecdb463d..b3d33f3a6 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -38,9 +38,9 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( fn context_type_as_nasl_value<'a>( context_type: &'a ContextType, arg_name: &str, -) -> Result<&'a NaslValue, NaslError> { +) -> Result<&'a NaslValue, ArgumentError> { match context_type { - ContextType::Function(_, _) => Err(NaslError::WrongArgument(format!( + ContextType::Function(_, _) => Err(ArgumentError::WrongArgument(format!( "Wrong argument for {}, expected a value, found a function.", arg_name ))), diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index 2bf65ed71..6b0333122 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -48,7 +48,7 @@ pub fn get_named_parameter<'a>( registrat: &'a Register, key: &'a str, required: bool, -) -> Result<&'a crate::nasl::syntax::NaslValue, NaslError> { +) -> Result<&'a crate::nasl::syntax::NaslValue, ArgumentError> { match registrat.named(key) { None => { if required { @@ -61,7 +61,7 @@ pub fn get_named_parameter<'a>( } Some(ct) => match ct { ContextType::Value(value) => Ok(value), - _ => Err(NaslError::wrong_argument(key, "value", "function")), + _ => Err(ArgumentError::wrong_argument(key, "value", "function")), }, } } From a5d8d59196408707f6ed7cfaf13a5dfa08c9ed4d Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 11:23:14 +0100 Subject: [PATCH 08/36] Move FmtError into StringError --- rust/src/nasl/builtin/error.rs | 4 +++- rust/src/nasl/builtin/string/mod.rs | 19 ++++++++++++++++--- rust/src/nasl/interpreter/error.rs | 1 - rust/src/nasl/utils/error.rs | 3 --- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 210454457..2729569da 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use super::ssh::SshError; +use super::{ssh::SshError, string::StringError}; #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum BuiltinError { @@ -8,4 +8,6 @@ pub enum BuiltinError { Authentication, #[error("{0}")] Ssh(SshError), + #[error("{0}")] + String(StringError), } diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index b8b2048f1..9c3067d0c 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -17,9 +17,22 @@ use crate::nasl::{ use core::fmt::Write; use glob::{MatchOptions, Pattern}; use std::num::ParseIntError; +use thiserror::Error; use crate::nasl::prelude::*; +use super::BuiltinError; + +#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[error("{0}")] +pub struct StringError(#[from] std::fmt::Error); + +impl From for BuiltinError { + fn from(value: StringError) -> Self { + BuiltinError::String(value) + } +} + /// Decodes given string as hex and returns the result as a byte array pub fn decode_hex(s: &str) -> Result, ParseIntError> { (0..s.len()) @@ -75,7 +88,7 @@ fn raw_string(positional: CheckedPositionals<&NaslValue>) -> Vec { data } -fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), NaslError> { +fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), StringError> { match value { NaslValue::String(x) => write!(s, "{x}"), NaslValue::Data(x) => { @@ -109,7 +122,7 @@ fn write_nasl_string(s: &mut String, value: &NaslValue) -> Result<(), NaslError> /// NASL function to parse values into string representations #[nasl_function] -fn string(positional: CheckedPositionals<&NaslValue>) -> Result { +fn string(positional: CheckedPositionals<&NaslValue>) -> Result { let mut s = String::with_capacity(2 * positional.len()); for p in positional { write_nasl_string_value(&mut s, p)?; @@ -117,7 +130,7 @@ fn string(positional: CheckedPositionals<&NaslValue>) -> Result Result<(), NaslError> { +fn write_nasl_string_value(s: &mut String, value: &NaslValue) -> Result<(), StringError> { match value { NaslValue::Array(x) => { for p in x { diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 679c92f61..e783ceb18 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -230,7 +230,6 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { match fe.kind { - NaslError::FMTError(fe) => fe.into(), NaslError::IOError(ie) => ie.into(), NaslError::GeneralError(e) => Self::new(InterpretErrorKind::StorageError(e), None), _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 35a45ac1a..1b2a80bf4 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -41,9 +41,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Wraps formatting error - #[error("Formatting error: {0}")] - FMTError(#[from] std::fmt::Error), /// Wraps io::Error #[error("IOError: {0}")] IOError(io::ErrorKind), From d2252c7a64c8e5a3ebaae2059dbb11af44519081 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 12:25:45 +0100 Subject: [PATCH 09/36] Remove IOError from NaslError Move all use cases into custom errors from those builtin modules. --- rust/src/nasl/builtin/error.rs | 27 +++- rust/src/nasl/builtin/misc/mod.rs | 21 ++- rust/src/nasl/builtin/network/network.rs | 9 +- .../src/nasl/builtin/network/network_utils.rs | 20 +-- rust/src/nasl/builtin/network/socket.rs | 131 ++++++++++++------ rust/src/nasl/builtin/string/mod.rs | 6 - rust/src/nasl/interpreter/error.rs | 1 - rust/src/nasl/mod.rs | 1 + rust/src/nasl/utils/error.rs | 14 -- 9 files changed, 146 insertions(+), 84 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 2729569da..894700e23 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,6 +1,7 @@ use thiserror::Error; -use super::{ssh::SshError, string::StringError}; +use super::super::prelude::NaslError; +use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum BuiltinError { @@ -10,4 +11,28 @@ pub enum BuiltinError { Ssh(SshError), #[error("{0}")] String(StringError), + #[error("{0}")] + Misc(MiscError), + #[error("{0}")] + Socket(SocketError), } + +macro_rules! builtin_error_variant ( + ($ty: ty, $variant: ident) => { + impl From<$ty> for BuiltinError { + fn from(value: $ty) -> Self { + BuiltinError::$variant(value) + } + } + + impl From<$ty> for NaslError { + fn from(value: $ty) -> Self { + NaslError::Builtin(BuiltinError::$variant(value)) + } + } + } +); + +builtin_error_variant!(StringError, String); +builtin_error_variant!(MiscError, Misc); +builtin_error_variant!(SocketError, Socket); diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index 3dd280c95..f2e7693a8 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -10,7 +10,7 @@ mod tests; use std::{ collections::HashMap, fs::File, - io::{Read, Write}, + io::{self, Read, Write}, thread, time::{self, Duration, UNIX_EPOCH}, }; @@ -19,16 +19,31 @@ use chrono::{ self, DateTime, Datelike, FixedOffset, Local, LocalResult, Offset, TimeZone, Timelike, Utc, }; use nasl_function_proc_macro::nasl_function; +use thiserror::Error; use crate::nasl::{prelude::*, utils::function::Maybe}; use flate2::{ read::GzDecoder, read::ZlibDecoder, write::GzEncoder, write::ZlibEncoder, Compression, }; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[error("{0}")] +// It would be nicer to derive this using #[from] from +// thiserror, but io::Error does not impl `PartialEq`, +// `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which +// does not impl `Error` which is why this `From` impl exists. +pub struct MiscError(io::ErrorKind); + +impl From for MiscError { + fn from(value: io::Error) -> Self { + Self(value.kind()) + } +} + #[inline] #[cfg(unix)] /// Reads 8 bytes from /dev/urandom and parses it to an i64 -pub fn random_impl() -> Result { +pub fn random_impl() -> Result { let mut rng = File::open("/dev/urandom")?; let mut buffer = [0u8; 8]; rng.read_exact(&mut buffer) @@ -38,7 +53,7 @@ pub fn random_impl() -> Result { /// NASL function to get random number #[nasl_function] -fn rand() -> Result { +fn rand() -> Result { random_impl() } diff --git a/rust/src/nasl/builtin/network/network.rs b/rust/src/nasl/builtin/network/network.rs index 725805093..003692176 100644 --- a/rust/src/nasl/builtin/network/network.rs +++ b/rust/src/nasl/builtin/network/network.rs @@ -5,6 +5,7 @@ use std::{net::IpAddr, process::Command}; use super::mtu; +use super::socket::SocketError; use super::{ network_utils::{get_netmask_by_local_ip, get_source_ip, ipstr2ipaddr, islocalhost}, verify_port, DEFAULT_PORT, @@ -22,7 +23,7 @@ fn get_host_ip(context: &Context) -> String { /// Get the IP address of the current (attacking) machine depending on which network device is used #[nasl_function] -fn this_host(context: &Context) -> Result { +fn this_host(context: &Context) -> Result { let dst = ipstr2ipaddr(context.target())?; let port: u16 = DEFAULT_PORT; @@ -42,21 +43,21 @@ fn this_host_name() -> String { /// get the maximum transition unit for the scanned host #[nasl_function] -fn get_mtu(context: &Context) -> Result { +fn get_mtu(context: &Context) -> Result { let target = ipstr2ipaddr(context.target())?; Ok(mtu(target) as i64) } /// check if the currently scanned host is the localhost #[nasl_function] -fn nasl_islocalhost(context: &Context) -> Result { +fn nasl_islocalhost(context: &Context) -> Result { let host_ip = ipstr2ipaddr(context.target())?; Ok(islocalhost(host_ip)) } /// Check if the target host is on the same network as the attacking host #[nasl_function] -fn islocalnet(context: &Context) -> Result { +fn islocalnet(context: &Context) -> Result { let dst = ipstr2ipaddr(context.target())?; let src = get_source_ip(dst, DEFAULT_PORT)?; let netmask = match get_netmask_by_local_ip(src)? { diff --git a/rust/src/nasl/builtin/network/network_utils.rs b/rust/src/nasl/builtin/network/network_utils.rs index 15efee7ad..5c33b3c7e 100644 --- a/rust/src/nasl/builtin/network/network_utils.rs +++ b/rust/src/nasl/builtin/network/network_utils.rs @@ -11,11 +11,13 @@ use std::{ use crate::nasl::prelude::*; +use super::socket::SocketError; + /// Convert a string in a IpAddr -pub fn ipstr2ipaddr(ip_addr: &str) -> Result { +pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(NaslError::Diagnostic( + Err(_) => Err(SocketError::Diagnostic( format!("Invalid IP address ({})", ip_addr), Some(NaslValue::Null), )), @@ -23,8 +25,8 @@ pub fn ipstr2ipaddr(ip_addr: &str) -> Result { } /// Bind a local UDP socket to a V4 or V6 address depending on the given destination address -pub fn bind_local_socket(dst: &SocketAddr) -> Result { - let fe = Err(NaslError::Diagnostic("Error binding".to_string(), None)); +pub fn bind_local_socket(dst: &SocketAddr) -> Result { + let fe = Err(SocketError::Diagnostic("Error binding".to_string(), None)); match dst { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0").or(fe), SocketAddr::V6(_) => UdpSocket::bind("[::]:0").or(fe), @@ -32,7 +34,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result { } /// Return the source IP address given the destination IP address -pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { +pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { let socket = SocketAddr::new(dst, port); let sd = format!("{}:{}", dst, port); let local_socket = bind_local_socket(&socket)?; @@ -41,7 +43,7 @@ pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { .ok() .and_then(|_| local_socket.local_addr().ok()) .and_then(|l_addr| IpAddr::from_str(&l_addr.ip().to_string()).ok()) - .ok_or_else(|| NaslError::Diagnostic("No route to destination".to_string(), None)) + .ok_or_else(|| SocketError::Diagnostic("No route to destination".to_string(), None)) } /// Tests whether a packet sent to IP is LIKELY to route through the @@ -57,13 +59,13 @@ pub fn islocalhost(addr: IpAddr) -> bool { } /// Get the interface from the local ip -pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, NaslError> { +pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, SocketError> { let mut interfaces: *mut libc::ifaddrs = ptr::null_mut(); let ret = unsafe { libc::getifaddrs(&mut interfaces) }; if ret < 0 { - return Err(NaslError::Diagnostic( + return Err(SocketError::Diagnostic( "Error getting interfaces".to_string(), None, )); @@ -123,7 +125,7 @@ pub fn get_netmask_by_local_ip(local_address: IpAddr) -> Result, unsafe { libc::freeifaddrs(interfaces); } - Err(NaslError::Diagnostic( + Err(SocketError::Diagnostic( "No route to destination".to_string(), None, )) diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index e3c2e0447..077d74cbf 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -21,6 +21,7 @@ use rustls::{ pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer, ServerName}, ClientConfig, ClientConnection, RootCertStore, Stream, }; +use thiserror::Error; use super::{ get_kb_item, mtu, @@ -31,6 +32,23 @@ use super::{ // Number of times to resend a UDP packet, when no response is received const NUM_TIMES_TO_RESEND: usize = 5; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[error("{0}")] +// It would be nicer to derive this using #[from] from +// thiserror, but io::Error does not impl `PartialEq`, +// `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which +// does not impl `Error` which is why this `From` impl exists. +pub enum SocketError { + IO(std::io::ErrorKind), + Diagnostic(String, Option), +} + +impl From for SocketError { + fn from(value: io::Error) -> Self { + Self::IO(value.kind()) + } +} + pub struct Interval { interval: Duration, last_tick: SystemTime, @@ -64,14 +82,19 @@ impl TCPConnection { /// Send data on a TCP connection using the libc send function. /// To ensure safety of the function, the caller must ensure, that the given length does not /// exceed the length of the given data data. - unsafe fn send(&self, mut data: &[u8], len: usize, flags: i32) -> Result { + unsafe fn send( + &self, + mut data: &[u8], + len: usize, + flags: i32, + ) -> Result { let fd = self.socket.as_raw_fd(); let mut ret = 0; while !data.is_empty() { let n = unsafe { libc::send(fd, data.as_ptr() as *const libc::c_void, len - ret, flags) }; if n < 0 { - return Err(io::Error::last_os_error().into()); + return Err(SocketError::from(io::Error::last_os_error()).into()); } ret += n as usize; data = &data[n as usize..]; @@ -89,7 +112,12 @@ impl UDPConnection { /// Send data on a UDP connection using the libc send function. /// To ensure safety of the function, the caller must ensure, that the given length does not /// exceed the length of the given data data. - unsafe fn send(&mut self, data: &[u8], len: usize, flags: i32) -> Result { + unsafe fn send( + &mut self, + data: &[u8], + len: usize, + flags: i32, + ) -> Result { let fd = self.socket.as_raw_fd(); let ip = self.socket.peer_addr()?.ip(); @@ -97,7 +125,7 @@ impl UDPConnection { let mtu = mtu(ip); if len > mtu { - return Err(NaslError::Diagnostic( + return Err(SocketError::Diagnostic( format!( "udp data of size {} exceeds the maximum length of {}", len, mtu @@ -134,11 +162,11 @@ pub struct NaslSockets { } impl NaslSockets { - fn resolve_socket_addr(addr: IpAddr, port: u16) -> Result { + fn resolve_socket_addr(addr: IpAddr, port: u16) -> Result { (addr, port) .to_socket_addrs()? .next() - .ok_or(NaslError::Diagnostic( + .ok_or(SocketError::Diagnostic( format!( "the given address and port do not correspond to a valid address: {addr}:{port}" ), @@ -146,7 +174,7 @@ impl NaslSockets { )) } - fn open_udp(addr: IpAddr, port: u16) -> Result { + fn open_udp(addr: IpAddr, port: u16) -> Result { let sock_addr = Self::resolve_socket_addr(addr, port)?; let socket = bind_local_socket(&sock_addr)?; socket.connect(sock_addr)?; @@ -163,7 +191,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, tls_config: Option<&TLSConfig>, - ) -> Result { + ) -> Result { // Resolve Address and Port to SocketAddr let sock_addr = Self::resolve_socket_addr(addr, port)?; // Create Vec depending of buffer size @@ -192,7 +220,7 @@ impl NaslSockets { Some(config) => Some( ClientConnection::new(Arc::new(config.config.clone()), config.server.clone()) .map_err(|e| { - NaslError::Diagnostic( + SocketError::Diagnostic( format!("Unable to establish TLS connection: {e}"), None, ) @@ -224,11 +252,11 @@ impl NaslSockets { /// Close a given file descriptor taken as an unnamed argument. #[nasl_function] - fn close(&self, socket_fd: usize) -> Result { + fn close(&self, socket_fd: usize) -> Result { let mut handles = self.handles.write().unwrap(); match handles.handles.get_mut(socket_fd) { Some(NaslSocket::Close) => { - return Err(NaslError::Diagnostic( + return Err(SocketError::Diagnostic( "the given socket FD is already closed".to_string(), None, )) @@ -238,7 +266,7 @@ impl NaslSockets { handles.closed_fd.push(socket_fd); } None => { - return Err(NaslError::Diagnostic( + return Err(SocketError::Diagnostic( "the given socket FD does not exist".to_string(), None, )) @@ -300,16 +328,18 @@ impl NaslSockets { let mut stream = Stream::new(tls, &mut conn.socket); let mut ret = 0; while !data.is_empty() { - let n = stream.write(data)?; + let n = stream.write(data).map_err(SocketError::from)?; ret += n; data = &data[n..]; } Ok(NaslValue::Number(ret as i64)) } else { - unsafe { conn.send(data, len, flags.unwrap_or(0) as i32) } + unsafe { Ok(conn.send(data, len, flags.unwrap_or(0) as i32)?) } } } - NaslSocket::Udp(conn) => unsafe { conn.send(data, len, flags.unwrap_or(0) as i32) }, + NaslSocket::Udp(conn) => unsafe { + Ok(conn.send(data, len, flags.unwrap_or(0) as i32)?) + }, NaslSocket::Close => Err(ArgumentError::WrongArgument( "the given socket FD is already closed".to_string(), ) @@ -322,7 +352,7 @@ impl NaslSockets { data: &mut [u8], len: usize, min: usize, - ) -> Result<(), NaslError> { + ) -> Result<(), SocketError> { let mut ret = 0; while ret < len && ret < min { let n = socket.read(&mut data[ret..]).or_else(|e| match e.kind() { @@ -373,7 +403,8 @@ impl NaslSockets { if let Some(timeout) = timeout { old = conn.socket.read_timeout().unwrap(); conn.socket - .set_read_timeout(Some(Duration::from_secs(timeout as u64)))?; + .set_read_timeout(Some(Duration::from_secs(timeout as u64))) + .map_err(SocketError::from)?; } if let Some(tls) = conn.tls_connection.as_mut() { let mut socket = Stream::new(tls, &mut conn.socket); @@ -383,7 +414,9 @@ impl NaslSockets { } if let Some(timeout) = old { - conn.socket.set_read_timeout(Some(timeout))?; + conn.socket + .set_read_timeout(Some(timeout)) + .map_err(SocketError::from)?; } Ok(NaslValue::Data(data)) @@ -393,7 +426,8 @@ impl NaslSockets { if let Some(timeout) = timeout { old = conn.socket.read_timeout().unwrap(); conn.socket - .set_read_timeout(Some(Duration::from_secs(timeout as u64)))?; + .set_read_timeout(Some(Duration::from_secs(timeout as u64))) + .map_err(SocketError::from)?; } let mut result = conn.socket.recv_from(data.as_mut_slice()); @@ -401,7 +435,7 @@ impl NaslSockets { for _ in 0..NUM_TIMES_TO_RESEND { match result { Ok((size, origin)) => { - if conn.socket.peer_addr()? == origin { + if conn.socket.peer_addr().map_err(SocketError::from)? == origin { data.truncate(size); ret = Ok(NaslValue::Data(data)); break; @@ -409,10 +443,10 @@ impl NaslSockets { } Err(e) => match e.kind() { io::ErrorKind::TimedOut => { - conn.socket.send(&conn.buffer)?; + conn.socket.send(&conn.buffer).map_err(SocketError::from)?; } kind => { - ret = Err(NaslError::IOError(kind)); + ret = Err(SocketError::IO(kind)); break; } }, @@ -421,9 +455,11 @@ impl NaslSockets { result = conn.socket.recv_from(data.as_mut_slice()); } if let Some(timeout) = old { - conn.socket.set_read_timeout(Some(timeout))?; + conn.socket + .set_read_timeout(Some(timeout)) + .map_err(SocketError::from)?; } - ret + Ok(ret?) } NaslSocket::Close => Err(ArgumentError::WrongArgument( "the given socket FD is already closed".to_string(), @@ -440,7 +476,7 @@ impl NaslSockets { fn open_sock_kdc(&self, context: &Context) -> Result { let hostname = match get_kb_item(context, "Secret/kdc_hostname")? { Some(x) => Ok(x.to_string()), - None => Err(NaslError::Diagnostic( + None => Err(SocketError::Diagnostic( "KB key 'Secret/kdc_hostname' is not set".to_string(), None, )), @@ -448,11 +484,11 @@ impl NaslSockets { let ip = lookup_host(&hostname) .map_err(|_| { - NaslError::Diagnostic(format!("unable to lookup hostname {hostname}"), None) + SocketError::Diagnostic(format!("unable to lookup hostname {hostname}"), None) })? .into_iter() .next() - .ok_or(NaslError::Diagnostic( + .ok_or(SocketError::Diagnostic( format!("No IP found for hostname {hostname}"), None, ))?; @@ -462,7 +498,7 @@ impl NaslSockets { let port = match port { Some(NaslValue::Number(x)) => { if x <= 0 || x > 65535 { - Err(NaslError::Diagnostic( + Err(SocketError::Diagnostic( "KB key 'Secret/kdc_port' out of range".to_string(), port, )) @@ -470,11 +506,11 @@ impl NaslSockets { Ok(x as u16) } } - Some(_) => Err(NaslError::Diagnostic( + Some(_) => Err(SocketError::Diagnostic( "KB key 'Secret/kdc_port' has wrong type".to_string(), port, )), - None => Err(NaslError::Diagnostic( + None => Err(SocketError::Diagnostic( "KB key 'Secret/kdc_port' is not set".to_string(), None, )), @@ -527,9 +563,11 @@ impl NaslSockets { let addr = context.target(); if addr.is_empty() { - return Err(NaslError::Dirty( + return Err(SocketError::Diagnostic( "A target must be specified to open a socket".to_string(), - )); + None, + ) + .into()); } self.wait_before_next_probe(); @@ -633,8 +671,8 @@ impl NaslSockets { match Self::open_tcp(addr, port, bufsz, timeout, tls_config.as_ref()) { Ok(socket) => return Ok(socket), Err(err) => { - if !matches!(err, NaslError::IOError(io::ErrorKind::TimedOut)) { - return Err(err); + if !matches!(err, SocketError::IO(io::ErrorKind::TimedOut)) { + return Err(err.into()); } retry -= 1; } @@ -645,10 +683,10 @@ impl NaslSockets { // 2. Log too many timeouts // 3. Create result of type error with: // ERRMSG|||||||||/tcp||| ||| Too many timeouts. The port was set to closed - Err(NaslError::IOError(io::ErrorKind::TimedOut)) + Err(SocketError::IO(io::ErrorKind::TimedOut).into()) } - fn load_private_key(filename: &str) -> Result, NaslError> { + fn load_private_key(filename: &str) -> Result, SocketError> { let keyfile = fs::File::open(filename)?; let mut reader = BufReader::new(keyfile); @@ -662,7 +700,7 @@ impl NaslSockets { } } - Err(NaslError::Diagnostic( + Err(SocketError::Diagnostic( format!( "no keys found in {:?} (encrypted keys not supported)", filename @@ -681,13 +719,13 @@ impl NaslSockets { hostname: &str, ) -> Result { let cert_path = get_kb_item(context, "SSL/cert")? - .ok_or(NaslError::Diagnostic( + .ok_or(SocketError::Diagnostic( "unable to open TLS connection: kes 'SSL/cert' is missing".to_string(), None, ))? .to_string(); let key_path = get_kb_item(context, "SSL/key")? - .ok_or(NaslError::Diagnostic( + .ok_or(SocketError::Diagnostic( "unable to open TLS connection: kes 'SSL/key' is missing".to_string(), None, ))? @@ -696,24 +734,25 @@ impl NaslSockets { .unwrap_or(NaslValue::Null) .to_string(); let cafile_path = get_kb_item(context, "SSL/CA")? - .ok_or(NaslError::Diagnostic( + .ok_or(SocketError::Diagnostic( "unable to open TLS connection: kes 'SSL/CA' is missing".to_string(), None, ))? .to_string(); // TODO: From vhost name - let server = ServerName::try_from(hostname.to_owned()) - .map_err(|_| NaslError::Dirty(format!("Given vHost Name {hostname} is not valid")))?; + let server = ServerName::try_from(hostname.to_owned()).map_err(|_| { + SocketError::Diagnostic(format!("Given vHost Name {hostname} is not valid"), None) + })?; let mut root_store = RootCertStore::empty(); - let ca_file = fs::File::open(cafile_path)?; + let ca_file = fs::File::open(cafile_path).map_err(SocketError::from)?; let mut reader = BufReader::new(ca_file); root_store.add_parsable_certificates( rustls_pemfile::certs(&mut reader).map(|result| result.unwrap()), ); - let cert_file = fs::File::open(cert_path)?; + let cert_file = fs::File::open(cert_path).map_err(SocketError::from)?; let mut reader = BufReader::new(cert_file); let cert = rustls_pemfile::certs(&mut reader) .map(|result| result.unwrap()) @@ -724,13 +763,13 @@ impl NaslSockets { if !password.is_empty() { let encrypted_key = pkcs8::EncryptedPrivateKeyInfo::from_der(key.secret_der()) .map_err(|_| { - NaslError::Diagnostic( + SocketError::Diagnostic( format!("Unable to decrypt private key {key_path} with given password"), None, ) })?; let decrypted_key = encrypted_key.decrypt(password).map_err(|_| { - NaslError::Diagnostic( + SocketError::Diagnostic( format!("Unable to decrypt private key {key_path} with given password"), None, ) diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 9c3067d0c..5a06ee1eb 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -27,12 +27,6 @@ use super::BuiltinError; #[error("{0}")] pub struct StringError(#[from] std::fmt::Error); -impl From for BuiltinError { - fn from(value: StringError) -> Self { - BuiltinError::String(value) - } -} - /// Decodes given string as hex and returns the result as a byte array pub fn decode_hex(s: &str) -> Result, ParseIntError> { (0..s.len()) diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index e783ceb18..f3dbec932 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -230,7 +230,6 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { match fe.kind { - NaslError::IOError(ie) => ie.into(), NaslError::GeneralError(e) => Self::new(InterpretErrorKind::StorageError(e), None), _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), } diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index 648e75edb..701611cb4 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -7,6 +7,7 @@ pub mod utils; pub mod test_utils; pub mod prelude { + pub use super::builtin::BuiltinError; pub use super::builtin::ContextFactory; pub use super::builtin::RegisterBuilder; pub use super::syntax::FSPluginLoader; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 1b2a80bf4..dd1929894 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -3,7 +3,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception //! Defines function error kinds -use std::io; use thiserror::Error; use crate::nasl::builtin::{BuiltinError, SshError}; @@ -41,9 +40,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Wraps io::Error - #[error("IOError: {0}")] - IOError(io::ErrorKind), /// Authentication failed #[error("Authentication failed.")] Authentication, @@ -101,16 +97,6 @@ impl TryFrom for BuiltinError { } } -// It would be nicer to derive this using #[from] from -// thiserror, but io::Error does not impl `PartialEq`, -// `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which -// does not impl `Error` which is why this `From` impl exists. -impl From for NaslError { - fn from(e: io::Error) -> Self { - Self::IOError(e.kind()) - } -} - impl ArgumentError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and From f205ce01426246ff2a39c85b6e93304f2469a83f Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 12:32:25 +0100 Subject: [PATCH 10/36] Move 'authentication' to cryptographic error --- rust/src/nasl/builtin/cryptographic/aes_gcm.rs | 10 +++------- rust/src/nasl/builtin/cryptographic/mod.rs | 8 ++++++++ rust/src/nasl/builtin/error.rs | 6 ++++-- rust/src/nasl/utils/error.rs | 3 --- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs index c856cefb2..af2b1682e 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs @@ -3,11 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception // NaslError::GeneralError -use crate::nasl::syntax::NaslValue; -use crate::{ - function_set, - nasl::utils::{Context, NaslError, Register}, -}; +use crate::nasl::prelude::*; use aes::{ cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit}, Aes128, Aes192, Aes256, @@ -18,7 +14,7 @@ use aes_gcm::{ }; use digest::typenum::{U12, U16}; -use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt}; +use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt, CryptographicError}; fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result where @@ -67,7 +63,7 @@ where }, Crypt::Encrypt => Ok(x.into()), }, - Err(_) => Err(NaslError::Authentication), + Err(_) => Err(CryptographicError::InsufficientBufferSize.into()), } } diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 5e748b2ba..c8a19a186 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception +use thiserror::Error; + // use crate::nasl::utils::combine_function_sets; use crate::nasl::prelude::*; @@ -23,6 +25,12 @@ pub mod rsa; #[cfg(test)] mod tests; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum CryptographicError { + #[error("Error in AesGcm: insufficient buffer size.")] + InsufficientBufferSize, +} + enum Crypt { Encrypt, Decrypt, diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 894700e23..f78dd1371 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,12 +1,11 @@ use thiserror::Error; use super::super::prelude::NaslError; +use super::cryptographic::CryptographicError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum BuiltinError { - #[error("Authentication error.")] - Authentication, #[error("{0}")] Ssh(SshError), #[error("{0}")] @@ -15,6 +14,8 @@ pub enum BuiltinError { Misc(MiscError), #[error("{0}")] Socket(SocketError), + #[error("{0}")] + Cryptographic(CryptographicError), } macro_rules! builtin_error_variant ( @@ -36,3 +37,4 @@ macro_rules! builtin_error_variant ( builtin_error_variant!(StringError, String); builtin_error_variant!(MiscError, Misc); builtin_error_variant!(SocketError, Socket); +builtin_error_variant!(CryptographicError, Cryptographic); diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index dd1929894..705fbf39f 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -40,9 +40,6 @@ pub enum InternalError { #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { - /// Authentication failed - #[error("Authentication failed.")] - Authentication, /// Diagnostic string is informational and the second arg is the return value for the user #[error("{0}")] Diagnostic(String, Option), From 4ff1469161962ee49be2558b2c67178f3eddf67b Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 4 Nov 2024 15:20:27 +0100 Subject: [PATCH 11/36] Move GeneralErrorType to InternalError::Storage --- rust/src/nasl/builtin/cryptographic/aes_ccm.rs | 8 +++----- rust/src/nasl/builtin/cryptographic/aes_gmac.rs | 16 +++++----------- rust/src/nasl/builtin/cryptographic/mod.rs | 4 ++++ rust/src/nasl/interpreter/error.rs | 5 ++++- rust/src/nasl/utils/error.rs | 11 +++++++---- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs index 1eb6fc718..846899ffd 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::nasl::utils::error::{GeneralErrorType, NaslError}; +use crate::nasl::utils::error::NaslError; use aes::cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ @@ -17,7 +17,7 @@ use crate::nasl::utils::{Context, Register}; use crate::function_set; -use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt}; +use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt, CryptographicError}; /// Core function to en- and decrypt data. Throws error in case of failure. fn ccm_crypt( @@ -60,9 +60,7 @@ where // Error handling match res { Ok(x) => Ok(NaslValue::Data(x)), - Err(_) => Err(NaslError::GeneralError(GeneralErrorType::UnexpectedData( - "unable to en-/decrypt data".to_string(), - ))), + Err(_) => Err(CryptographicError::AesCcmUnableToEncrypt.into()), } } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs index 71d5022e3..5d9a9a39c 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs @@ -3,16 +3,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::function_set; +#[cfg(feature = "nasl-c-lib")] +use crate::nasl::prelude::*; /// NASL function to calculate GMAC with AES128. /// /// This function expects 3 named arguments key, data and iv either in a string or data type. #[cfg(feature = "nasl-c-lib")] -fn aes_gmac( - register: &crate::nasl::utils::Register, - _: &crate::nasl::utils::Context, -) -> Result { - use super::{get_data, get_iv, get_key}; +fn aes_gmac(register: &Register, _: &Context) -> Result { + use super::{get_data, get_iv, get_key, CryptographicError}; use nasl_c_lib::cryptographic::mac::aes_gmac; let key = get_key(register)?; @@ -21,12 +20,7 @@ fn aes_gmac( match aes_gmac(data, key, iv) { Ok(val) => Ok(val.into()), - Err(code) => Err(crate::nasl::utils::NaslError::GeneralError( - crate::nasl::utils::error::GeneralErrorType::UnexpectedData(format!( - "Error code {}", - code - )), - )), + Err(msg) => Err(CryptographicError::AesGmacError(msg.into()).into()), } } diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index c8a19a186..2141cceff 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -29,6 +29,10 @@ mod tests; pub enum CryptographicError { #[error("Error in AesGcm: insufficient buffer size.")] InsufficientBufferSize, + #[error("Error in AesCcm: unable to encrypt.")] + AesCcmUnableToEncrypt, + #[error("Error in AesGmac: {0}.")] + AesGmacError(String), } enum Crypt { diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index f3dbec932..670aa22c8 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -7,6 +7,7 @@ use std::io; use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; use crate::nasl::utils::error::NaslError; +use crate::nasl::InternalError; use crate::storage::StorageError; use thiserror::Error; @@ -230,7 +231,9 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { match fe.kind { - NaslError::GeneralError(e) => Self::new(InterpretErrorKind::StorageError(e), None), + NaslError::Internal(InternalError::Storage(e)) => { + Self::new(InterpretErrorKind::StorageError(e), None) + } _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), } } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 705fbf39f..00350256e 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -32,20 +32,23 @@ pub enum ArgumentError { #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum InternalError { #[error("{0}")] - GeneralError(#[from] GeneralErrorType), + Storage(#[from] StorageError), #[error("{0}")] Dirty(String), } +impl From for NaslError { + fn from(value: StorageError) -> Self { + NaslError::Internal(InternalError::Storage(value)) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { /// Diagnostic string is informational and the second arg is the return value for the user #[error("{0}")] Diagnostic(String, Option), - /// Generic error - #[error("Generic error: {0}")] - GeneralError(#[from] GeneralErrorType), /// There is a deeper problem /// An example would be that there is no free memory left in the system #[error("{0}")] From 09e445eae3190e4f64ed8ad738526bd5a56afe6b Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 09:08:36 +0100 Subject: [PATCH 12/36] Remove GeneralErrorType --- .../nasl/builtin/cryptographic/aes_cmac.rs | 5 +-- rust/src/nasl/builtin/cryptographic/mod.rs | 2 + rust/src/nasl/utils/error.rs | 43 +++++++++---------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 9a1e4c61e..8671cb154 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -3,14 +3,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::GeneralErrorType; use crate::nasl::utils::{Context, NaslError, Register}; use aes::Aes128; use cmac::{Cmac, Mac}; use crate::function_set; -use super::{get_data, get_key}; +use super::{get_data, get_key, CryptographicError}; /// NASL function to calculate CMAC wit AES128. /// @@ -22,7 +21,7 @@ fn aes_cmac(register: &Register, _: &Context) -> Result { let data = get_data(register)?; let mut mac = Cmac::::new_from_slice(key) - .map_err(|e| GeneralErrorType::UnexpectedData(format!("CMAC: {}", e)))?; + .map_err(|e| CryptographicError::AesCmacError(format!("{}", e)))?; mac.update(data); Ok(mac.finalize().into_bytes().to_vec().into()) diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 2141cceff..3562da600 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -33,6 +33,8 @@ pub enum CryptographicError { AesCcmUnableToEncrypt, #[error("Error in AesGmac: {0}.")] AesGmacError(String), + #[error("Error in AesCmac: {0}.")] + AesCmacError(String), } enum Crypt { diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 00350256e..2a5b714c1 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -12,8 +12,26 @@ use crate::storage::StorageError; use super::ContextType; -/// Reuses the StorageError definitions as they should fit most cases. -pub type GeneralErrorType = StorageError; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +/// Descriptive kind of error that can occur while calling a function +pub enum NaslError { + /// Diagnostic string is informational and the second arg is the return value for the user + #[error("{0}")] + Diagnostic(String, Option), + /// There is a deeper problem + /// An example would be that there is no free memory left in the system + #[error("{0}")] + Dirty(String), + /// An Error originating from an SSH-specific NASL function + #[error("SSH error: {0}")] + Ssh(SshError), + #[error("{0}")] + Argument(#[from] ArgumentError), + #[error("{0}")] + Builtin(#[from] BuiltinError), + #[error("{0}")] + Internal(#[from] InternalError), +} #[derive(Debug, Clone, PartialEq, Eq, Error)] pub enum ArgumentError { @@ -43,27 +61,6 @@ impl From for NaslError { } } -#[derive(Debug, Clone, PartialEq, Eq, Error)] -/// Descriptive kind of error that can occur while calling a function -pub enum NaslError { - /// Diagnostic string is informational and the second arg is the return value for the user - #[error("{0}")] - Diagnostic(String, Option), - /// There is a deeper problem - /// An example would be that there is no free memory left in the system - #[error("{0}")] - Dirty(String), - /// An Error originating from an SSH-specific NASL function - #[error("SSH error: {0}")] - Ssh(SshError), - #[error("{0}")] - Argument(#[from] ArgumentError), - #[error("{0}")] - Builtin(#[from] BuiltinError), - #[error("{0}")] - Internal(#[from] InternalError), -} - impl TryFrom for ArgumentError { type Error = (); From 670ac1ee529a67d37a5a6523d6a65621cbd16d1a Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 09:13:40 +0100 Subject: [PATCH 13/36] Move SshError into BuiltinError --- rust/src/nasl/builtin/error.rs | 12 ++++++++++++ rust/src/nasl/builtin/mod.rs | 1 - rust/src/nasl/builtin/ssh/error.rs | 8 -------- rust/src/nasl/builtin/ssh/tests/mod.rs | 8 ++++---- rust/src/nasl/utils/error.rs | 5 +---- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index f78dd1371..21f7b64a5 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -31,6 +31,17 @@ macro_rules! builtin_error_variant ( NaslError::Builtin(BuiltinError::$variant(value)) } } + + impl TryFrom for $ty { + type Error = (); + + fn try_from(value: NaslError) -> Result { + match value { + NaslError::Builtin(BuiltinError::$variant(e)) => Ok(e), + _ => Err(()), + } + } + } } ); @@ -38,3 +49,4 @@ builtin_error_variant!(StringError, String); builtin_error_variant!(MiscError, Misc); builtin_error_variant!(SocketError, Socket); builtin_error_variant!(CryptographicError, Cryptographic); +builtin_error_variant!(SshError, Ssh); diff --git a/rust/src/nasl/builtin/mod.rs b/rust/src/nasl/builtin/mod.rs index 4da926511..ae15314eb 100644 --- a/rust/src/nasl/builtin/mod.rs +++ b/rust/src/nasl/builtin/mod.rs @@ -25,7 +25,6 @@ mod string; mod tests; pub use error::BuiltinError; -pub use ssh::SshError; use crate::nasl::syntax::{Loader, NoOpLoader}; use crate::nasl::utils::{Context, Executor, NaslVarRegister, NaslVarRegisterBuilder, Register}; diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index d9e8b15a0..717360ad7 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -2,8 +2,6 @@ use std::fmt; use thiserror::Error; -use crate::nasl::NaslError; - use super::SessionId; /// A cloneable representation of the Error type of the underlying SSH lib @@ -169,9 +167,3 @@ impl SshError { self.attach_error_info(m) } } - -impl From for NaslError { - fn from(e: SshError) -> Self { - NaslError::Ssh(e) - } -} diff --git a/rust/src/nasl/builtin/ssh/tests/mod.rs b/rust/src/nasl/builtin/ssh/tests/mod.rs index bc662ea3a..84a9183e0 100644 --- a/rust/src/nasl/builtin/ssh/tests/mod.rs +++ b/rust/src/nasl/builtin/ssh/tests/mod.rs @@ -89,10 +89,10 @@ async fn ssh_connect() { check_err_matches!( t, format!(r#"id = ssh_connect(port:{}, keytype: "ssh-rsa");"#, PORT), - NaslError::Ssh(SshError { + SshError { kind: SshErrorKind::Connect, .. - }) + } ); }, default_config(), @@ -121,10 +121,10 @@ async fn ssh_userauth() { check_err_matches!( t, r#"ssh_userauth(session_id);"#, - NaslError::Ssh(SshError { + SshError { kind: SshErrorKind::NoAuthenticationGiven, .. - }), + }, ); userauth(&mut t); }, diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 2a5b714c1..76283318d 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -5,7 +5,7 @@ //! Defines function error kinds use thiserror::Error; -use crate::nasl::builtin::{BuiltinError, SshError}; +use crate::nasl::builtin::BuiltinError; use crate::nasl::prelude::NaslValue; use crate::storage::StorageError; @@ -22,9 +22,6 @@ pub enum NaslError { /// An example would be that there is no free memory left in the system #[error("{0}")] Dirty(String), - /// An Error originating from an SSH-specific NASL function - #[error("SSH error: {0}")] - Ssh(SshError), #[error("{0}")] Argument(#[from] ArgumentError), #[error("{0}")] From aa1d579079727935b79f6632cdea173fc1f4c783 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 09:31:25 +0100 Subject: [PATCH 14/36] Remove Dirty in favor of custom errors --- rust/src/nasl/builtin/error.rs | 21 +- rust/src/nasl/builtin/misc/mod.rs | 18 +- rust/src/nasl/builtin/raw_ip/mod.rs | 1 + .../src/nasl/builtin/raw_ip/packet_forgery.rs | 301 ++++++++---------- rust/src/nasl/builtin/regex/mod.rs | 14 +- rust/src/nasl/utils/error.rs | 6 - 6 files changed, 161 insertions(+), 200 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 21f7b64a5..9e6ef08b3 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -2,6 +2,7 @@ use thiserror::Error; use super::super::prelude::NaslError; use super::cryptographic::CryptographicError; +use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; #[derive(Debug, Clone, PartialEq, Eq, Error)] @@ -16,23 +17,28 @@ pub enum BuiltinError { Socket(SocketError), #[error("{0}")] Cryptographic(CryptographicError), + #[error("{0}")] + Regex(RegexError), + #[cfg(feature = "nasl-builtin-raw-ip")] + #[error("{0}")] + PacketForgery(super::raw_ip::PacketForgeryError), } macro_rules! builtin_error_variant ( - ($ty: ty, $variant: ident) => { - impl From<$ty> for BuiltinError { - fn from(value: $ty) -> Self { + ($err: path, $variant: ident) => { + impl From<$err> for BuiltinError { + fn from(value: $err) -> Self { BuiltinError::$variant(value) } } - impl From<$ty> for NaslError { - fn from(value: $ty) -> Self { + impl From<$err> for NaslError { + fn from(value: $err) -> Self { NaslError::Builtin(BuiltinError::$variant(value)) } } - impl TryFrom for $ty { + impl TryFrom for $err { type Error = (); fn try_from(value: NaslError) -> Result { @@ -50,3 +56,6 @@ builtin_error_variant!(MiscError, Misc); builtin_error_variant!(SocketError, Socket); builtin_error_variant!(CryptographicError, Cryptographic); builtin_error_variant!(SshError, Ssh); +builtin_error_variant!(RegexError, Regex); +#[cfg(feature = "nasl-builtin-raw-ip")] +builtin_error_variant!(super::raw_ip::PacketForgeryError, PacketForgery); diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index f2e7693a8..3d7e56ce3 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -27,16 +27,20 @@ use flate2::{ }; #[derive(Debug, Clone, PartialEq, Eq, Error)] -#[error("{0}")] // It would be nicer to derive this using #[from] from // thiserror, but io::Error does not impl `PartialEq`, // `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which // does not impl `Error` which is why this `From` impl exists. -pub struct MiscError(io::ErrorKind); +pub enum MiscError { + #[error("IO Error: {0}")] + IO(io::ErrorKind), + #[error("Encountered time before 1970. {0}")] + TimeBefore1970(String), +} impl From for MiscError { fn from(value: io::Error) -> Self { - Self(value.kind()) + Self::IO(value.kind()) } } @@ -106,11 +110,11 @@ fn isnull(val: NaslValue) -> bool { /// Returns the seconds counted from 1st January 1970 as an integer. #[nasl_function] -fn unixtime() -> Result { +fn unixtime() -> Result { std::time::SystemTime::now() .duration_since(UNIX_EPOCH) .map(|t| t.as_secs()) - .map_err(|_| NaslError::Dirty("System time set to time before 1st January 1960".into())) + .map_err(|e| MiscError::TimeBefore1970(e.to_string())) } /// Compress given data with gzip, when headformat is set to 'gzip' it uses gzipheader. @@ -239,13 +243,13 @@ fn defined_func(ctx: &Context, register: &Register, fn_name: Option> /// /// For example: “1067352015.030757” means 1067352015 seconds and 30757 microseconds. #[nasl_function] -fn gettimeofday() -> Result { +fn gettimeofday() -> Result { match time::SystemTime::now().duration_since(time::SystemTime::UNIX_EPOCH) { Ok(time) => { let time = time.as_micros(); Ok(format!("{}.{:06}", time / 1000000, time % 1000000)) } - Err(e) => Err(NaslError::Dirty(format!("{e}"))), + Err(e) => Err(MiscError::TimeBefore1970(e.to_string())), } } diff --git a/rust/src/nasl/builtin/raw_ip/mod.rs b/rust/src/nasl/builtin/raw_ip/mod.rs index 2d87d2a91..952b2c71f 100644 --- a/rust/src/nasl/builtin/raw_ip/mod.rs +++ b/rust/src/nasl/builtin/raw_ip/mod.rs @@ -8,6 +8,7 @@ mod raw_ip_utils; use crate::nasl::utils::{IntoFunctionSet, NaslVars, StoredFunctionSet}; use frame_forgery::FrameForgery; use packet_forgery::PacketForgery; +pub use packet_forgery::PacketForgeryError; pub struct RawIp; diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 04f32d4af..5744cc251 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -32,8 +32,19 @@ use pnet::packet::{ use pnet_macros_support::types::u9be; use socket2::{Domain, Protocol, Socket}; +use thiserror::Error; use tracing::debug; +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum PacketForgeryError { + #[error("{0}")] + Custom(String), +} + +fn error(s: String) -> NaslError { + PacketForgeryError::Custom(s).into() +} + macro_rules! custom_error { ($a:expr, $b:expr) => { Err(NaslError::Diagnostic( @@ -97,7 +108,7 @@ fn safe_copy_from_slice( || d_buf.len() < d_fin || o_buf.len() < o_fin { - return Err(NaslError::Dirty( + return Err(error( "Error copying from slice. Index out of range".to_string(), )); } @@ -365,9 +376,8 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result match e.as_str() { @@ -403,7 +413,7 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { let pkt = packet::ipv4::Ipv4Packet::new(data).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) + error("No possible to create a packet from buffer".to_string()) })?; println!("\tip_hl={}", pkt.get_header_length()); @@ -513,9 +523,8 @@ fn insert_ip_options(register: &Register, _configs: &Context) -> Result Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(tcp_seg.packet()).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(tcp_seg.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; - let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; tcp_seg.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -667,12 +671,10 @@ fn get_tcp_element(register: &Register, _configs: &Context) -> Result match el.as_str() { @@ -712,12 +714,10 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Result Result Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(ori_tcp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -890,9 +885,8 @@ fn set_tcp_elements(register: &Register, _configs: &Context) -> Result Result d.clone(), _ => { - return Err(NaslError::Dirty( - "insert_tcp_options: missing field".to_string(), - )); + return Err(error("insert_tcp_options: missing field".to_string())); } }; - let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let iph_len = ip.get_header_length() as usize * 4; // the header length is given in 32-bits words let ori_tcp_buf = <&[u8]>::clone(&ip.payload()).to_owned(); let mut ori_tcp: packet::tcp::MutableTcpPacket; @@ -945,9 +936,8 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result d.as_bytes().to_vec(), Some(ContextType::Value(NaslValue::Number(d))) => d.to_be_bytes().to_vec(), _ => { - let tcp = TcpPacket::new(&ori_tcp_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let tcp = TcpPacket::new(&ori_tcp_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; tcp.payload().to_vec() } }; @@ -955,7 +945,7 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(ori_tcp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -1084,9 +1071,8 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result Result Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::Dirty( + return Err(error( "Missing arguments. It needs at least one tcp packet".to_string(), )); } @@ -1228,9 +1214,8 @@ fn forge_udp_packet(register: &Register, _configs: &Context) -> Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; - let udp_aux = UdpPacket::new(udp_datagram.packet()).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let udp_aux = UdpPacket::new(udp_datagram.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::udp::ipv4_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } }; - let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; udp_datagram.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -1302,9 +1283,8 @@ fn set_udp_elements(register: &Register, _configs: &Context) -> Result Result Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; - let udp_aux = UdpPacket::new(ori_udp.packet()).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let udp_aux = UdpPacket::new(ori_udp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::udp::ipv4_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -1386,9 +1362,8 @@ fn set_udp_elements(register: &Register, _configs: &Context) -> Result Result Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::Dirty( + return Err(error( "Missing arguments. It needs at least one UDP packet".to_string(), )); } @@ -1461,12 +1436,10 @@ fn get_udp_element(register: &Register, _configs: &Context) -> Result match el.as_str() { @@ -1508,9 +1481,8 @@ fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result { @@ -1544,23 +1516,20 @@ fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result (*x as u16).to_be(), _ => { - let icmp_aux = IcmpPacket::new(&buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let icmp_aux = IcmpPacket::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::icmp::checksum(&icmp_aux) } }; - let mut icmp_pkt = packet::icmp::MutableIcmpPacket::new(&mut buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut icmp_pkt = packet::icmp::MutableIcmpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; icmp_pkt.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -1593,12 +1562,10 @@ fn get_icmp_element(register: &Register, _configs: &Context) -> Result match el.as_str() { @@ -1657,12 +1624,10 @@ fn dump_icmp_packet(register: &Register, _: &Context) -> Result= 4 { @@ -1789,9 +1754,8 @@ fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { @@ -1813,7 +1777,7 @@ fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { - return Err(NaslError::Dirty(format!("Invalid address group: {}", e))); + return Err(error(format!("Invalid address group: {}", e))); } }; } @@ -1824,14 +1788,12 @@ fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result Result { Some(Protocol::from(IPPROTO_RAW)), ) { Ok(s) => Ok(s), - Err(e) => Err(NaslError::Dirty(format!( - "Not possible to create a raw socket: {}", - e - ))), + Err(e) => Err(error(format!("Not possible to create a raw socket: {}", e))), } } @@ -1895,10 +1854,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result Result Result { - return Err(NaslError::Dirty(format!("send_packet: {}", e))); + return Err(error(format!("send_packet: {}", e))); } } @@ -2067,10 +2021,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result Result data as &[u8], _ => return Err(NaslError::wrong_unnamed_argument("Data", "Invalid packet")), }; - let packet = packet::ipv4::Ipv4Packet::new(packet_raw).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let packet = packet::ipv4::Ipv4Packet::new(packet_raw) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; if allow_broadcast { if let Err(err) = soc.set_broadcast(true) { @@ -2117,7 +2067,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result Result { // Remove all from lower layer - let frame = EthernetPacket::new(packet.data).ok_or_else(|| { - NaslError::Dirty("No possible to create a packet from buffer".to_string()) - })?; + let frame = EthernetPacket::new(packet.data) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; return Ok(NaslValue::Data(frame.payload().to_vec())); } Err(_) => Ok(NaslValue::Null), diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index ad52d8000..1a18fc082 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -7,6 +7,13 @@ mod tests; use crate::nasl::prelude::*; use regex::{Regex, RegexBuilder}; +use thiserror::Error; + +#[derive(Debug, Clone, PartialEq, Eq, Error)] +pub enum RegexError { + #[error("Error building regular expression pattern: {0}")] + BuildingError(String), +} fn parse_search_string(mut s: &str, rnul: bool, multiline: bool) -> &str { if !rnul { @@ -19,17 +26,14 @@ fn parse_search_string(mut s: &str, rnul: bool, multiline: bool) -> &str { s } -fn make_regex(pattern: &str, icase: bool, multiline: bool) -> Result { +fn make_regex(pattern: &str, icase: bool, multiline: bool) -> Result { match RegexBuilder::new(pattern.to_string().as_str()) .case_insensitive(icase) .multi_line(multiline) .build() { Ok(re) => Ok(re), - Err(e) => Err(NaslError::Dirty(format!( - " Error building regular expression pattern: {}", - e - ))), + Err(e) => Err(RegexError::BuildingError(e.to_string())), } } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 76283318d..440429dc2 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -18,10 +18,6 @@ pub enum NaslError { /// Diagnostic string is informational and the second arg is the return value for the user #[error("{0}")] Diagnostic(String, Option), - /// There is a deeper problem - /// An example would be that there is no free memory left in the system - #[error("{0}")] - Dirty(String), #[error("{0}")] Argument(#[from] ArgumentError), #[error("{0}")] @@ -48,8 +44,6 @@ pub enum ArgumentError { pub enum InternalError { #[error("{0}")] Storage(#[from] StorageError), - #[error("{0}")] - Dirty(String), } impl From for NaslError { From 963634ddb26c3897d1d2940d6280b597ad851594 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 09:45:50 +0100 Subject: [PATCH 15/36] Remove Eq derive on errors --- rust/src/feed/transpile/error.rs | 4 ++-- rust/src/feed/update/error.rs | 4 ++-- rust/src/feed/verify/mod.rs | 2 +- rust/src/nasl/builtin/cryptographic/mod.rs | 2 +- rust/src/nasl/builtin/error.rs | 2 +- rust/src/nasl/builtin/misc/mod.rs | 2 +- rust/src/nasl/builtin/network/socket.rs | 2 +- rust/src/nasl/builtin/raw_ip/packet_forgery.rs | 2 +- rust/src/nasl/builtin/regex/mod.rs | 6 +++--- rust/src/nasl/builtin/ssh/error.rs | 4 ++-- rust/src/nasl/builtin/string/mod.rs | 2 +- rust/src/nasl/interpreter/error.rs | 6 +++--- rust/src/nasl/utils/error.rs | 6 +++--- rust/src/storage/mod.rs | 2 +- 14 files changed, 23 insertions(+), 23 deletions(-) diff --git a/rust/src/feed/transpile/error.rs b/rust/src/feed/transpile/error.rs index 2b70916fb..26c006eb7 100644 --- a/rust/src/feed/transpile/error.rs +++ b/rust/src/feed/transpile/error.rs @@ -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 @@ -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 diff --git a/rust/src/feed/update/error.rs b/rust/src/feed/update/error.rs index 9a59437ac..677a37afb 100644 --- a/rust/src/feed/update/error.rs +++ b/rust/src/feed/update/error.rs @@ -9,7 +9,7 @@ use thiserror::Error; use crate::feed::{verify, VerifyError}; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] /// Errors within feed handling pub enum ErrorKind { /// An InterpretError occurred while interpreting @@ -32,7 +32,7 @@ pub enum ErrorKind { VerifyError(#[from] verify::Error), } -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] #[error("Error with key '{key}': {kind}")] /// ErrorKind and key of error pub struct Error { diff --git a/rust/src/feed/verify/mod.rs b/rust/src/feed/verify/mod.rs index 2b32c6bd3..05959cd70 100644 --- a/rust/src/feed/verify/mod.rs +++ b/rust/src/feed/verify/mod.rs @@ -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.")] diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 3562da600..b4f69b9b9 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -25,7 +25,7 @@ pub mod rsa; #[cfg(test)] mod tests; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum CryptographicError { #[error("Error in AesGcm: insufficient buffer size.")] InsufficientBufferSize, diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 9e6ef08b3..003ecab87 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -5,7 +5,7 @@ use super::cryptographic::CryptographicError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum BuiltinError { #[error("{0}")] Ssh(SshError), diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index 3d7e56ce3..8108227c4 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -26,7 +26,7 @@ use flate2::{ read::GzDecoder, read::ZlibDecoder, write::GzEncoder, write::ZlibEncoder, Compression, }; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] // It would be nicer to derive this using #[from] from // thiserror, but io::Error does not impl `PartialEq`, // `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index 077d74cbf..b6c9575c5 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -32,7 +32,7 @@ use super::{ // Number of times to resend a UDP packet, when no response is received const NUM_TIMES_TO_RESEND: usize = 5; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] #[error("{0}")] // It would be nicer to derive this using #[from] from // thiserror, but io::Error does not impl `PartialEq`, diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 5744cc251..3d2147ded 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -35,7 +35,7 @@ use socket2::{Domain, Protocol, Socket}; use thiserror::Error; use tracing::debug; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum PacketForgeryError { #[error("{0}")] Custom(String), diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index 1a18fc082..450328a6a 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -9,10 +9,10 @@ use crate::nasl::prelude::*; use regex::{Regex, RegexBuilder}; use thiserror::Error; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum RegexError { #[error("Error building regular expression pattern: {0}")] - BuildingError(String), + BuildingError(regex::Error), } fn parse_search_string(mut s: &str, rnul: bool, multiline: bool) -> &str { @@ -33,7 +33,7 @@ fn make_regex(pattern: &str, icase: bool, multiline: bool) -> Result Ok(re), - Err(e) => Err(RegexError::BuildingError(e.to_string())), + Err(e) => Err(RegexError::BuildingError(e)), } } diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index 717360ad7..ccc9623c0 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -5,7 +5,7 @@ use thiserror::Error; use super::SessionId; /// A cloneable representation of the Error type of the underlying SSH lib -#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[derive(Clone, Debug, PartialEq, Error)] #[error("{0}")] pub struct LibError(String); @@ -23,7 +23,7 @@ impl From for LibError { } } -#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[derive(Clone, Debug, PartialEq, Error)] pub struct SshError { pub kind: SshErrorKind, id: Option, diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 5a06ee1eb..6dfe09f00 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -23,7 +23,7 @@ use crate::nasl::prelude::*; use super::BuiltinError; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] #[error("{0}")] pub struct StringError(#[from] std::fmt::Error); diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 670aa22c8..0f5fe686f 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -11,7 +11,7 @@ use crate::nasl::InternalError; use crate::storage::StorageError; use thiserror::Error; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] /// An error that occurred while calling a function #[error("Error while calling function '{function}': {kind}")] pub struct FunctionError { @@ -32,7 +32,7 @@ impl FunctionError { } } -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] /// Is used to represent an error while interpreting #[error("{}{kind}", self.origin.clone().map(|e| format!("{e}: ")).unwrap_or_default())] pub struct InterpretError { @@ -43,7 +43,7 @@ pub struct InterpretError { pub origin: Option, } -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] /// Is used to give hints to the user how to react on an error while interpreting pub enum InterpretErrorKind { /// When returned context is a function when a value is required. diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 440429dc2..ef82c5cc8 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -12,7 +12,7 @@ use crate::storage::StorageError; use super::ContextType; -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { /// Diagnostic string is informational and the second arg is the return value for the user @@ -26,7 +26,7 @@ pub enum NaslError { Internal(#[from] InternalError), } -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum ArgumentError { #[error("Expected {expected} but got {got}")] MissingPositionals { expected: usize, got: usize }, @@ -40,7 +40,7 @@ pub enum ArgumentError { WrongArgument(String), } -#[derive(Debug, Clone, PartialEq, Eq, Error)] +#[derive(Debug, Clone, PartialEq, Error)] pub enum InternalError { #[error("{0}")] Storage(#[from] StorageError), diff --git a/rust/src/storage/mod.rs b/rust/src/storage/mod.rs index 674901c1d..d9f80bbee 100644 --- a/rust/src/storage/mod.rs +++ b/rust/src/storage/mod.rs @@ -167,7 +167,7 @@ impl From for Field { } /// Defines abstract error cases -#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[derive(Clone, Debug, PartialEq, Error)] pub enum StorageError { /// Informs the caller to retry the call #[error("There was a temporary issue while reading: {0}")] From 09f31c0b45b3e6392a3a85b93fe410eab3fdc822 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 09:56:01 +0100 Subject: [PATCH 16/36] Remove PartialEq on Error --- rust/src/feed/update/error.rs | 4 ++-- .../nasl/builtin/cryptographic/aes_cmac.rs | 2 +- rust/src/nasl/builtin/cryptographic/mod.rs | 6 ++--- .../builtin/cryptographic/tests/aes_cbc.rs | 5 ++++- .../builtin/cryptographic/tests/aes_gcm.rs | 5 ++++- rust/src/nasl/builtin/error.rs | 2 +- rust/src/nasl/builtin/misc/mod.rs | 6 ++--- rust/src/nasl/builtin/misc/tests.rs | 22 +++++-------------- rust/src/nasl/builtin/network/socket.rs | 6 ++--- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 2 +- rust/src/nasl/builtin/regex/mod.rs | 2 +- rust/src/nasl/builtin/regex/tests.rs | 8 +++---- rust/src/nasl/builtin/ssh/error.rs | 6 ++--- rust/src/nasl/builtin/string/mod.rs | 2 +- rust/src/nasl/interpreter/error.rs | 6 ++--- rust/src/nasl/interpreter/include.rs | 15 ++++++++----- .../src/nasl/interpreter/tests/description.rs | 5 ++++- rust/src/nasl/interpreter/tests/local_var.rs | 5 ++++- rust/src/nasl/test_utils.rs | 2 +- rust/src/nasl/utils/error.rs | 2 +- 20 files changed, 59 insertions(+), 54 deletions(-) diff --git a/rust/src/feed/update/error.rs b/rust/src/feed/update/error.rs index 677a37afb..c84c9888c 100644 --- a/rust/src/feed/update/error.rs +++ b/rust/src/feed/update/error.rs @@ -9,7 +9,7 @@ use thiserror::Error; use crate::feed::{verify, VerifyError}; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] /// Errors within feed handling pub enum ErrorKind { /// An InterpretError occurred while interpreting @@ -32,7 +32,7 @@ pub enum ErrorKind { VerifyError(#[from] verify::Error), } -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] #[error("Error with key '{key}': {kind}")] /// ErrorKind and key of error pub struct Error { diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 8671cb154..987c8b5bf 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -21,7 +21,7 @@ fn aes_cmac(register: &Register, _: &Context) -> Result { let data = get_data(register)?; let mut mac = Cmac::::new_from_slice(key) - .map_err(|e| CryptographicError::AesCmacError(format!("{}", e)))?; + .map_err(|e| CryptographicError::AesCmacInvalidLength(e))?; mac.update(data); Ok(mac.finalize().into_bytes().to_vec().into()) diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index b4f69b9b9..e8c1a948a 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -25,7 +25,7 @@ pub mod rsa; #[cfg(test)] mod tests; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] pub enum CryptographicError { #[error("Error in AesGcm: insufficient buffer size.")] InsufficientBufferSize, @@ -33,8 +33,8 @@ pub enum CryptographicError { AesCcmUnableToEncrypt, #[error("Error in AesGmac: {0}.")] AesGmacError(String), - #[error("Error in AesCmac: {0}.")] - AesCmacError(String), + #[error("Invalid length of key in AesCmac {0}.")] + AesCmacInvalidLength(digest::InvalidLength), } enum Crypt { diff --git a/rust/src/nasl/builtin/cryptographic/tests/aes_cbc.rs b/rust/src/nasl/builtin/cryptographic/tests/aes_cbc.rs index bd0829f8b..560bb0b28 100644 --- a/rust/src/nasl/builtin/cryptographic/tests/aes_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/tests/aes_cbc.rs @@ -68,5 +68,8 @@ fn padding() { "#, ); let results = t.results(); - assert_eq!(results[results.len() - 2], results[results.len() - 1]); + assert_eq!( + results[results.len() - 2].as_ref().unwrap(), + results[results.len() - 1].as_ref().unwrap() + ); } diff --git a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs index c7637c71e..f928923e7 100644 --- a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs @@ -119,5 +119,8 @@ fn padding() { "#, ); let results = t.results(); - assert_eq!(results[results.len() - 2], results[results.len() - 1]); + assert_eq!( + results[results.len() - 2].as_ref().unwrap(), + results[results.len() - 1].as_ref().unwrap() + ); } diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 003ecab87..a95936984 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -5,7 +5,7 @@ use super::cryptographic::CryptographicError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] pub enum BuiltinError { #[error("{0}")] Ssh(SshError), diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index 8108227c4..01c09fc92 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -26,10 +26,10 @@ use flate2::{ read::GzDecoder, read::ZlibDecoder, write::GzEncoder, write::ZlibEncoder, Compression, }; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] // It would be nicer to derive this using #[from] from -// thiserror, but io::Error does not impl `PartialEq`, -// `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which +// thiserror, but io::Error does not impl `Clone`, +// so we wrap `io::ErrorKind` instead, which // does not impl `Error` which is why this `From` impl exists. pub enum MiscError { #[error("IO Error: {0}")] diff --git a/rust/src/nasl/builtin/misc/tests.rs b/rust/src/nasl/builtin/misc/tests.rs index 2e1e1281e..cb9977419 100644 --- a/rust/src/nasl/builtin/misc/tests.rs +++ b/rust/src/nasl/builtin/misc/tests.rs @@ -72,22 +72,12 @@ mod tests { #[test] fn gunzip() { let mut t = TestBuilder::default(); - t.run_all( - r#" - z = raw_string (0x78, 0x9c, 0xab, 0x02, 0x00, 0x00, 0x7b, 0x00, 0x7b); - gunzip(data: z); - # With Header Format and data is data - gz = gzip(data: 'gz', headformat: "gzip"); - gunzip(data: gz); - # Without Header format and data is a string - ngz = gzip(data: "ngz"); - gunzip(data: ngz); - "#, - ); - let results = t.results(); - assert_eq!(results[1], Ok(NaslValue::String("z".into()))); - assert_eq!(results[3], Ok(NaslValue::String("gz".into()))); - assert_eq!(results[5], Ok(NaslValue::String("ngz".into()))); + t.run(r#"z = raw_string (0x78, 0x9c, 0xab, 0x02, 0x00, 0x00, 0x7b, 0x00, 0x7b);"#); + t.ok(r#"gunzip(data: z);"#, "z"); + t.run(r#"gz = gzip(data: 'gz', headformat: "gzip");"#); + t.ok(r#"gunzip(data: gz);"#, "gz"); + t.run(r#"ngz = gzip(data: "ngz");"#); + t.ok(r#"gunzip(data: ngz);"#, "ngz"); } #[test] diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index b6c9575c5..8e22ec7c8 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -32,11 +32,11 @@ use super::{ // Number of times to resend a UDP packet, when no response is received const NUM_TIMES_TO_RESEND: usize = 5; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] #[error("{0}")] // It would be nicer to derive this using #[from] from -// thiserror, but io::Error does not impl `PartialEq`, -// `Eq` or `Clone`, so we wrap `io::ErrorKind` instead, which +// thiserror, but io::Error does not impl `Clone`, +// so we wrap `io::ErrorKind` instead, which // does not impl `Error` which is why this `From` impl exists. pub enum SocketError { IO(std::io::ErrorKind), diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 3d2147ded..f9efeba2d 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -35,7 +35,7 @@ use socket2::{Domain, Protocol, Socket}; use thiserror::Error; use tracing::debug; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] pub enum PacketForgeryError { #[error("{0}")] Custom(String), diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index 450328a6a..9cb3d5d52 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::*; use regex::{Regex, RegexBuilder}; use thiserror::Error; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] pub enum RegexError { #[error("Error building regular expression pattern: {0}")] BuildingError(regex::Error), diff --git a/rust/src/nasl/builtin/regex/tests.rs b/rust/src/nasl/builtin/regex/tests.rs index 03402f615..87eaa0772 100644 --- a/rust/src/nasl/builtin/regex/tests.rs +++ b/rust/src/nasl/builtin/regex/tests.rs @@ -107,8 +107,8 @@ mod tests { "#, ); assert_eq!( - t.results()[1], - Ok(NaslValue::String("Pair 0\n Pair 2\n".to_string())) + t.results()[1].as_ref().unwrap(), + &NaslValue::String("Pair 0\n Pair 2\n".to_string()) ); } @@ -124,8 +124,8 @@ mod tests { "#, ); assert_eq!( - t.results()[1], - Ok(NaslValue::String("Pair 0\n Pair 2\n".to_string())) + t.results()[1].as_ref().unwrap(), + &NaslValue::String("Pair 0\n Pair 2\n".to_string()) ); } diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index ccc9623c0..7aad2ad1c 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -5,7 +5,7 @@ use thiserror::Error; use super::SessionId; /// A cloneable representation of the Error type of the underlying SSH lib -#[derive(Clone, Debug, PartialEq, Error)] +#[derive(Clone, Debug, Error)] #[error("{0}")] pub struct LibError(String); @@ -23,7 +23,7 @@ impl From for LibError { } } -#[derive(Clone, Debug, PartialEq, Error)] +#[derive(Clone, Debug, Error)] pub struct SshError { pub kind: SshErrorKind, id: Option, @@ -46,7 +46,7 @@ impl fmt::Display for SshError { } } -#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[derive(Clone, Debug, Error)] pub enum SshErrorKind { #[error("Failed to open new SSH session.")] NewSession, diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 6dfe09f00..41828d5be 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -23,7 +23,7 @@ use crate::nasl::prelude::*; use super::BuiltinError; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] #[error("{0}")] pub struct StringError(#[from] std::fmt::Error); diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 0f5fe686f..1da72d046 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -11,7 +11,7 @@ use crate::nasl::InternalError; use crate::storage::StorageError; use thiserror::Error; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] /// An error that occurred while calling a function #[error("Error while calling function '{function}': {kind}")] pub struct FunctionError { @@ -32,7 +32,7 @@ impl FunctionError { } } -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] /// Is used to represent an error while interpreting #[error("{}{kind}", self.origin.clone().map(|e| format!("{e}: ")).unwrap_or_default())] pub struct InterpretError { @@ -43,7 +43,7 @@ pub struct InterpretError { pub origin: Option, } -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] /// Is used to give hints to the user how to react on an error while interpreting pub enum InterpretErrorKind { /// When returned context is a function when a value is required. diff --git a/rust/src/nasl/interpreter/include.rs b/rust/src/nasl/interpreter/include.rs index 232c6136d..b94a39101 100644 --- a/rust/src/nasl/interpreter/include.rs +++ b/rust/src/nasl/interpreter/include.rs @@ -54,16 +54,19 @@ mod tests { let ctx = context.build(Default::default()); let mut interpreter = CodeInterpreter::new(code, register, &ctx); assert_eq!( - interpreter.next_statement().await, - Some(Ok(NaslValue::Null)) + interpreter.next_statement().await.unwrap().unwrap(), + NaslValue::Null ); - assert_eq!(interpreter.next_statement().await, Some(Ok(12.into()))); assert_eq!( - interpreter.next_statement().await, - Some(Ok(NaslValue::Dict(HashMap::from([( + interpreter.next_statement().await.unwrap().unwrap(), + 12.into() + ); + assert_eq!( + interpreter.next_statement().await.unwrap().unwrap(), + NaslValue::Dict(HashMap::from([( "hello".to_owned(), NaslValue::Data("world".as_bytes().into()) - )])))) + )])) ); } } diff --git a/rust/src/nasl/interpreter/tests/description.rs b/rust/src/nasl/interpreter/tests/description.rs index acc601334..9d6db83e8 100644 --- a/rust/src/nasl/interpreter/tests/description.rs +++ b/rust/src/nasl/interpreter/tests/description.rs @@ -61,7 +61,10 @@ if(description) t.set_variable("description", NaslValue::Number(1)); t.run_all(code); let results = t.results(); - assert_eq!(*results.last().unwrap(), Ok(NaslValue::Exit(23))); + assert_eq!( + *results.last().unwrap().as_ref().unwrap(), + NaslValue::Exit(23) + ); let mut tag = BTreeMap::new(); tag.insert(TagKey::CreationDate, 1366091481.into()); diff --git a/rust/src/nasl/interpreter/tests/local_var.rs b/rust/src/nasl/interpreter/tests/local_var.rs index 8b39cdef4..65d61fee7 100644 --- a/rust/src/nasl/interpreter/tests/local_var.rs +++ b/rust/src/nasl/interpreter/tests/local_var.rs @@ -18,5 +18,8 @@ if (a) { a; "###, ); - assert_eq!(t.results().last().unwrap(), &Ok(NaslValue::Number(1))); + assert!(matches!( + t.results().last().unwrap(), + &Ok(NaslValue::Number(1)) + )); } diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index ee1606cff..ddf581dfd 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -330,7 +330,7 @@ where reference: &TestResult, ) -> bool { match reference { - TestResult::Ok(val) => result.as_ref() == Ok(val), + TestResult::Ok(val) => result.as_ref().unwrap() == val, TestResult::GenericCheck(f, _) => f(result.clone()), TestResult::None => true, } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index ef82c5cc8..d52802e64 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -12,7 +12,7 @@ use crate::storage::StorageError; use super::ContextType; -#[derive(Debug, Clone, PartialEq, Error)] +#[derive(Debug, Clone, Error)] /// Descriptive kind of error that can occur while calling a function pub enum NaslError { /// Diagnostic string is informational and the second arg is the return value for the user From 0078e67533c118785079094d66c2950ff220e140 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Tue, 5 Nov 2024 10:45:35 +0100 Subject: [PATCH 17/36] Rename back to FunctionErrorKind for the draft PR --- .../src/nasl/builtin/cryptographic/aes_cbc.rs | 14 +- .../src/nasl/builtin/cryptographic/aes_ccm.rs | 52 ++++-- .../nasl/builtin/cryptographic/aes_cmac.rs | 4 +- .../src/nasl/builtin/cryptographic/aes_ctr.rs | 14 +- .../src/nasl/builtin/cryptographic/aes_gcm.rs | 46 +++-- .../nasl/builtin/cryptographic/aes_gmac.rs | 2 +- rust/src/nasl/builtin/cryptographic/des.rs | 2 +- rust/src/nasl/builtin/cryptographic/hash.rs | 18 +- rust/src/nasl/builtin/cryptographic/hmac.rs | 18 +- .../builtin/cryptographic/tests/aes_gcm.rs | 2 +- rust/src/nasl/builtin/description/mod.rs | 6 +- rust/src/nasl/builtin/error.rs | 12 +- rust/src/nasl/builtin/host/mod.rs | 17 +- rust/src/nasl/builtin/http/mod.rs | 69 ++++--- rust/src/nasl/builtin/isotime/mod.rs | 12 +- rust/src/nasl/builtin/isotime/tests.rs | 27 +-- rust/src/nasl/builtin/knowledge_base/mod.rs | 16 +- rust/src/nasl/builtin/network/mod.rs | 2 +- rust/src/nasl/builtin/network/network.rs | 8 +- rust/src/nasl/builtin/network/socket.rs | 14 +- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 49 ++--- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 173 +++++++++++------- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 25 +-- .../builtin/raw_ip/tests/packet_forgery.rs | 12 +- rust/src/nasl/builtin/regex/mod.rs | 8 +- rust/src/nasl/builtin/report_functions/mod.rs | 12 +- rust/src/nasl/builtin/ssh/mod.rs | 4 +- rust/src/nasl/builtin/ssh/utils.rs | 8 +- rust/src/nasl/builtin/string/mod.rs | 10 +- rust/src/nasl/interpreter/error.rs | 8 +- rust/src/nasl/mod.rs | 2 +- rust/src/nasl/test_utils.rs | 10 +- rust/src/nasl/utils/error.rs | 36 ++-- .../nasl/utils/function/from_nasl_value.rs | 22 +-- rust/src/nasl/utils/function/maybe.rs | 4 +- rust/src/nasl/utils/function/positionals.rs | 10 +- .../src/nasl/utils/function/to_nasl_result.rs | 12 +- rust/src/nasl/utils/function/types.rs | 2 +- rust/src/nasl/utils/function/utils.rs | 16 +- rust/src/nasl/utils/mod.rs | 4 +- rust/src/scannerctl/interpret/mod.rs | 2 +- 41 files changed, 459 insertions(+), 325 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs index 4da1c2374..610dc08fe 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs @@ -17,7 +17,7 @@ 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(register: &Register, crypt: Crypt) -> Result +fn cbc(register: &Register, crypt: Crypt) -> Result where D: BlockCipher + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -71,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 { +fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -83,7 +83,7 @@ fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -94,7 +94,7 @@ fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -106,7 +106,7 @@ fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -117,7 +117,7 @@ fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -129,7 +129,7 @@ fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs index 846899ffd..9785ba1ed 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::nasl::utils::error::NaslError; +use crate::nasl::utils::error::FunctionErrorKind; use aes::cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ @@ -41,7 +41,7 @@ where } /// Base function for ccm en- and decryption. Sets the tag length to 16. -fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -71,7 +71,7 @@ where /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -82,7 +82,10 @@ fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -93,7 +96,7 @@ fn aes128_ccm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -104,7 +107,10 @@ fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -115,7 +121,7 @@ fn aes128_ccm_decrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -126,7 +132,10 @@ fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -137,7 +146,7 @@ fn aes192_ccm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -148,7 +157,10 @@ fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -159,7 +171,7 @@ fn aes192_ccm_decrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -170,7 +182,10 @@ fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -181,7 +196,7 @@ fn aes256_ccm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -192,13 +207,16 @@ fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { ccm::(register, Crypt::Decrypt, true) } macro_rules! ccm_call_typed { ($(($t1s: expr, $t1: ty) => $(($t2s: expr, $t2: ty)),*);*) => { - fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, NaslError> + fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, FunctionErrorKind> where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit { match tag_size { @@ -210,11 +228,11 @@ macro_rules! ccm_call_typed { Ok(ccm_crypt::(crypt, key, nonce, data, aad)) } ),* - other => Err(NaslError::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) + other => Err(FunctionErrorKind::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) } } ),* - other => Err(NaslError::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) + other => Err(FunctionErrorKind::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) } } } diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 987c8b5bf..9e01cd544 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{Context, NaslError, Register}; +use crate::nasl::utils::{Context, FunctionErrorKind, Register}; use aes::Aes128; use cmac::{Cmac, Mac}; @@ -16,7 +16,7 @@ use super::{get_data, get_key, CryptographicError}; /// This function expects 2 named arguments key and data either in a string or data type. /// It is important to notice, that internally the CMAC algorithm is used and not, as the name /// suggests, CBC-MAC. -fn aes_cmac(register: &Register, _: &Context) -> Result { +fn aes_cmac(register: &Register, _: &Context) -> Result { let key = get_key(register)?; let data = get_data(register)?; diff --git a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs index ff8b335f7..7d46c7495 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs @@ -15,7 +15,7 @@ use crate::nasl::prelude::*; use super::{get_data, get_iv, get_key, get_len, Crypt}; -fn ctr(register: &Register, crypt: Crypt) -> Result +fn ctr(register: &Register, crypt: Crypt) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -56,7 +56,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. It is used as the initial counter. -fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -68,7 +68,7 @@ fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -79,7 +79,7 @@ fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -91,7 +91,7 @@ fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -102,7 +102,7 @@ fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -114,7 +114,7 @@ fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs index af2b1682e..9d8fbf436 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// NaslError::GeneralError +// FunctionErrorKind::GeneralError use crate::nasl::prelude::*; use aes::{ cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit}, @@ -16,7 +16,7 @@ use digest::typenum::{U12, U16}; use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt, CryptographicError}; -fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -76,7 +76,7 @@ where /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -89,7 +89,10 @@ fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -102,7 +105,7 @@ fn aes128_gcm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -115,7 +118,10 @@ fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -128,7 +134,7 @@ fn aes128_gcm_decrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -141,7 +147,10 @@ fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -154,7 +163,7 @@ fn aes192_gcm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -167,7 +176,10 @@ fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -180,7 +192,7 @@ fn aes192_gcm_decrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -193,7 +205,10 @@ fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_encrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -206,7 +221,7 @@ fn aes256_gcm_encrypt_auth(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -219,7 +234,10 @@ fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_decrypt_auth( + register: &Register, + _: &Context, +) -> Result { gcm::(register, Crypt::Decrypt, true) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs index 5d9a9a39c..03147c1f8 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs @@ -10,7 +10,7 @@ use crate::nasl::prelude::*; /// /// This function expects 3 named arguments key, data and iv either in a string or data type. #[cfg(feature = "nasl-c-lib")] -fn aes_gmac(register: &Register, _: &Context) -> Result { +fn aes_gmac(register: &Register, _: &Context) -> Result { use super::{get_data, get_iv, get_key, CryptographicError}; use nasl_c_lib::cryptographic::mac::aes_gmac; diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index 20944a225..7e1f26020 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -7,7 +7,7 @@ use aes::cipher::BlockEncrypt; use ccm::KeyInit; use des::cipher::generic_array::GenericArray; -fn encrypt_des(register: &Register, _: &Context) -> Result { +fn encrypt_des(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.len() != 2 { return Err(ArgumentError::MissingPositionals { diff --git a/rust/src/nasl/builtin/cryptographic/hash.rs b/rust/src/nasl/builtin/cryptographic/hash.rs index 4d9d59340..5289e0033 100644 --- a/rust/src/nasl/builtin/cryptographic/hash.rs +++ b/rust/src/nasl/builtin/cryptographic/hash.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::function_set; -use crate::nasl::utils::error::NaslError; +use crate::nasl::utils::error::FunctionErrorKind; use digest::Digest; use md2::Md2; use md4::Md4; @@ -15,7 +15,7 @@ use sha2::{Sha256, Sha512}; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{Context, Register}; -fn nasl_hash(register: &Register) -> Result +fn nasl_hash(register: &Register) -> Result where D::OutputSize: std::ops::Add, ::Output: digest::generic_array::ArrayLength, @@ -37,37 +37,37 @@ where } /// NASL function to get MD2 hash -pub fn hash_md2(register: &Register, _: &Context) -> Result { +pub fn hash_md2(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get MD4 hash -pub fn hash_md4(register: &Register, _: &Context) -> Result { +pub fn hash_md4(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get MD5 hash -pub fn hash_md5(register: &Register, _: &Context) -> Result { +pub fn hash_md5(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA1 hash -pub fn hash_sha1(register: &Register, _: &Context) -> Result { +pub fn hash_sha1(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA256 hash -pub fn hash_sha256(register: &Register, _: &Context) -> Result { +pub fn hash_sha256(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get SHA512 hash -pub fn hash_sha512(register: &Register, _: &Context) -> Result { +pub fn hash_sha512(register: &Register, _: &Context) -> Result { nasl_hash::(register) } /// NASL function to get RIPemd160 hash -pub fn hash_ripemd160(register: &Register, _: &Context) -> Result { +pub fn hash_ripemd160(register: &Register, _: &Context) -> Result { nasl_hash::(register) } diff --git a/rust/src/nasl/builtin/cryptographic/hmac.rs b/rust/src/nasl/builtin/cryptographic/hmac.rs index 95d3a973f..4aa78f744 100644 --- a/rust/src/nasl/builtin/cryptographic/hmac.rs +++ b/rust/src/nasl/builtin/cryptographic/hmac.rs @@ -19,7 +19,7 @@ use sha2::{Sha256, Sha384, Sha512}; use crate::nasl::prelude::*; -fn hmac(register: &Register) -> Result +fn hmac(register: &Register) -> Result where D: CoreProxy, D::Core: HashMarker @@ -44,7 +44,7 @@ where let mut hmac = match Hmac::::new_from_slice(key.as_bytes()) { Ok(x) => x, Err(InvalidLength) => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "valid size key", "invalid size key", )) @@ -57,37 +57,37 @@ where } /// NASL function to get HMAC MD2 string -pub fn hmac_md2(register: &Register, _: &Context) -> Result { +pub fn hmac_md2(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC MD5 string -pub fn hmac_md5(register: &Register, _: &Context) -> Result { +pub fn hmac_md5(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC RIPEMD160 string -pub fn hmac_ripemd160(register: &Register, _: &Context) -> Result { +pub fn hmac_ripemd160(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA1 string -pub fn hmac_sha1(register: &Register, _: &Context) -> Result { +pub fn hmac_sha1(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA256 string -pub fn hmac_sha256(register: &Register, _: &Context) -> Result { +pub fn hmac_sha256(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA384 string -pub fn hmac_sha384(register: &Register, _: &Context) -> Result { +pub fn hmac_sha384(register: &Register, _: &Context) -> Result { hmac::(register) } /// NASL function to get HMAC SHA512 string -pub fn hmac_sha512(register: &Register, _: &Context) -> Result { +pub fn hmac_sha512(register: &Register, _: &Context) -> Result { hmac::(register) } diff --git a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs index f928923e7..28b663ef8 100644 --- a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// NaslError::GeneralError +// FunctionErrorKind::GeneralError use super::helper::decode_hex; use crate::nasl::test_prelude::*; diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index 4a6066d7e..f797089af 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -25,7 +25,7 @@ use crate::nasl::utils::get_named_parameter; ///} /// ```` /// The first parameter is the name of the function as well as the &str lookup key. -/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. +/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. /// /// Parameter are separated from the definition by a `=>`. /// @@ -59,7 +59,7 @@ macro_rules! make_storage_function { pub fn $name( registrat: &Register, ctxconfigs: &Context, - ) -> Result { + ) -> Result { let mut variables = vec![]; $( let positional = registrat.positional(); @@ -106,7 +106,7 @@ macro_rules! make_storage_function { }; } -type Transform = Result, NaslError>; +type Transform = Result, FunctionErrorKind>; fn as_timeout_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { Ok(vec![NVTField::Preference(NvtPreference { diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index a95936984..00bfa8484 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use super::super::prelude::NaslError; +use super::super::prelude::FunctionErrorKind; use super::cryptographic::CryptographicError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; @@ -32,18 +32,18 @@ macro_rules! builtin_error_variant ( } } - impl From<$err> for NaslError { + impl From<$err> for FunctionErrorKind { fn from(value: $err) -> Self { - NaslError::Builtin(BuiltinError::$variant(value)) + FunctionErrorKind::Builtin(BuiltinError::$variant(value)) } } - impl TryFrom for $err { + impl TryFrom for $err { type Error = (); - fn try_from(value: NaslError) -> Result { + fn try_from(value: FunctionErrorKind) -> Result { match value { - NaslError::Builtin(BuiltinError::$variant(e)) => Ok(e), + FunctionErrorKind::Builtin(BuiltinError::$variant(e)) => Ok(e), _ => Err(()), } } diff --git a/rust/src/nasl/builtin/host/mod.rs b/rust/src/nasl/builtin/host/mod.rs index f61a77a8b..8a941ea79 100644 --- a/rust/src/nasl/builtin/host/mod.rs +++ b/rust/src/nasl/builtin/host/mod.rs @@ -8,7 +8,7 @@ mod tests; use std::{net::IpAddr, str::FromStr}; use crate::function_set; -use crate::nasl::utils::{error::NaslError, lookup_keys::TARGET}; +use crate::nasl::utils::{error::FunctionErrorKind, lookup_keys::TARGET}; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{Context, ContextType, Register}; @@ -17,7 +17,7 @@ use crate::nasl::utils::{Context, ContextType, Register}; /// /// It does lookup TARGET and when not found falls back to 127.0.0.1 to resolve. /// If the TARGET is not a IP address than we assume that it already is a fqdn or a hostname and will return that instead. -fn resolve_hostname(register: &Register) -> Result { +fn resolve_hostname(register: &Register) -> Result { use std::net::ToSocketAddrs; let default_ip = "127.0.0.1"; @@ -41,7 +41,7 @@ fn resolve_hostname(register: &Register) -> Result { /// /// As of now (2023-01-20) there is no vhost handling. /// Therefore this function does load the registered TARGET and if it is an IP Address resolves it via DNS instead. -fn get_host_names(register: &Register, _: &Context) -> Result { +fn get_host_names(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(|x| NaslValue::Array(vec![NaslValue::String(x)])) } @@ -49,12 +49,12 @@ fn get_host_names(register: &Register, _: &Context) -> Result Result { +fn get_host_name(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(NaslValue::String) } /// Return the target's IP address as IpAddr. -pub fn get_host_ip(context: &Context) -> Result { +pub fn get_host_ip(context: &Context) -> Result { let default_ip = "127.0.0.1"; let r_sock_addr = match context.target() { x if !x.is_empty() => IpAddr::from_str(x), @@ -63,7 +63,7 @@ pub fn get_host_ip(context: &Context) -> Result { match r_sock_addr { Ok(x) => Ok(x), - Err(e) => Err(NaslError::wrong_unnamed_argument( + Err(e) => Err(FunctionErrorKind::wrong_unnamed_argument( "IP address", e.to_string().as_str(), )), @@ -71,7 +71,10 @@ pub fn get_host_ip(context: &Context) -> Result { } /// Return the target's IP address or 127.0.0.1 if not set. -fn nasl_get_host_ip(_register: &Register, context: &Context) -> Result { +fn nasl_get_host_ip( + _register: &Register, + context: &Context, +) -> Result { let ip = get_host_ip(context)?; Ok(NaslValue::String(ip.to_string())) } diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index 585c06ee6..98b59d758 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -35,9 +35,9 @@ pub struct NaslHttp { async fn lock_handles( handles: &Arc>>, -) -> Result>, NaslError> { +) -> Result>, FunctionErrorKind> { // we actually need to panic as a lock error is fatal - // alternatively we need to add a poison error on NaslError + // alternatively we need to add a poison error on FunctionErrorKind Ok(Arc::as_ref(handles).lock().await) } @@ -131,7 +131,7 @@ impl NaslHttp { data: String, method: Method, handle: &mut Handle, - ) -> Result<(Parts, String), NaslError> { + ) -> Result<(Parts, String), FunctionErrorKind> { // Establish TCP connection to the server. let mut config = ClientConfig::builder() @@ -148,20 +148,31 @@ impl NaslHttp { let stream = match TcpStream::connect(format!("{}:{}", ip_str, port)).await { Ok(a) => a, Err(e) => { - return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))); + return Err(FunctionErrorKind::Diagnostic( + e.to_string(), + Some(NaslValue::Null), + )); } }; let stream = match connector.connect(server_name, stream).await { Ok(a) => a, Err(e) => { - return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))); + return Err(FunctionErrorKind::Diagnostic( + e.to_string(), + Some(NaslValue::Null), + )); } }; let (h2, connection) = match client::handshake(stream).await { Ok((x, y)) => (x, y), - Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), + Err(e) => { + return Err(FunctionErrorKind::Diagnostic( + e.to_string(), + Some(NaslValue::Null), + )) + } }; tokio::spawn(async move { @@ -170,7 +181,12 @@ impl NaslHttp { let mut h2 = match h2.ready().await { Ok(x) => x, - Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), + Err(e) => { + return Err(FunctionErrorKind::Diagnostic( + e.to_string(), + Some(NaslValue::Null), + )) + } }; // Prepare the HTTP request to send to the server. @@ -200,7 +216,12 @@ impl NaslHttp { while let Some(chunk) = body.data().await { let chunk = match chunk { Ok(byte_chunk) => byte_chunk, - Err(e) => return Err(NaslError::Diagnostic(e.to_string(), Some(NaslValue::Null))), + Err(e) => { + return Err(FunctionErrorKind::Diagnostic( + e.to_string(), + Some(NaslValue::Null), + )) + } }; resp.push_str(&String::from_utf8_lossy(&chunk)); @@ -217,7 +238,7 @@ impl NaslHttp { register: &Register, ctx: &Context<'a>, method: Method, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, _ => { @@ -233,7 +254,7 @@ impl NaslHttp { { Some((_i, handle)) => handle, _ => { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )) @@ -243,7 +264,7 @@ impl NaslHttp { let item: String = match register.named("item") { Some(x) => x.to_string(), _ => { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( "Missing item".to_string(), Some(NaslValue::Null), )) @@ -311,7 +332,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::GET).await } @@ -320,7 +341,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::POST).await } @@ -329,7 +350,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::PUT).await } @@ -338,7 +359,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::HEAD).await } @@ -347,7 +368,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::DELETE).await } @@ -358,7 +379,7 @@ impl NaslHttp { /// On success the function returns a and integer with the handle /// identifier. Null on error. #[nasl_function] - async fn handle(&self) -> Result { + async fn handle(&self) -> Result { let mut handles = lock_handles(&self.handles).await?; let handle_id = next_handle_id(&handles); let h = Handle { @@ -378,7 +399,7 @@ impl NaslHttp { /// The function returns an integer. /// O on success, -1 on error. #[nasl_function(named(handle))] - async fn close_handle(&self, handle: i32) -> Result { + async fn close_handle(&self, handle: i32) -> Result { let mut handles = lock_handles(&self.handles).await?; match handles .iter_mut() @@ -389,7 +410,7 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(NaslError::Diagnostic( + _ => Err(FunctionErrorKind::Diagnostic( format!("Handle ID {} not found", handle), Some(NaslValue::Number(-1)), )), @@ -406,7 +427,7 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, _ => { @@ -421,7 +442,7 @@ impl NaslHttp { .find(|(_i, h)| h.handle_id == handle_id) { Some((_i, handle)) => Ok(NaslValue::Number(handle.http_code as i64)), - _ => Err(NaslError::Diagnostic( + _ => Err(FunctionErrorKind::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )), @@ -438,10 +459,10 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let header_item = match register.named("header_item") { Some(ContextType::Value(NaslValue::String(x))) => x, - _ => return Err(NaslError::missing_argument("No command passed")), + _ => return Err(FunctionErrorKind::missing_argument("No command passed")), }; let (key, val) = header_item.split_once(": ").expect("Missing header_item"); @@ -463,7 +484,7 @@ impl NaslHttp { h.header_items.push((key.to_string(), val.to_string())); Ok(NaslValue::Number(0)) } - _ => Err(NaslError::Diagnostic( + _ => Err(FunctionErrorKind::Diagnostic( format!("Handle ID {} not found", handle_id), Some(NaslValue::Null), )), diff --git a/rust/src/nasl/builtin/isotime/mod.rs b/rust/src/nasl/builtin/isotime/mod.rs index a5e75ebbc..5f9543fd0 100644 --- a/rust/src/nasl/builtin/isotime/mod.rs +++ b/rust/src/nasl/builtin/isotime/mod.rs @@ -41,14 +41,14 @@ fn parse_readable_time(time: &str) -> Option { None } -fn parse_time(time: &str) -> Result { +fn parse_time(time: &str) -> Result { if let Some(time) = parse_isotime(time) { return Ok(time); } if let Some(time) = parse_readable_time(time) { return Ok(time); } - Err(NaslError::Diagnostic( + Err(FunctionErrorKind::Diagnostic( format!( "The given time is not in the correct isotime ({}) or readable time format ({}): {}", ISOFORMAT, READABLEFORMAT, time @@ -63,7 +63,7 @@ fn isotime_add( years: Option, days: Option, seconds: Option, -) -> Result { +) -> Result { let mut time = parse_time(time)?; if let Some(years) = years { @@ -83,7 +83,7 @@ fn isotime_add( } if time.year() < 0 || time.year() > 9999 { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!( "The resulting year is out of range (0000-9999): {}.", time.year() @@ -106,12 +106,12 @@ fn isotime_now() -> String { } #[nasl_function] -fn isotime_print(time: &str) -> Result { +fn isotime_print(time: &str) -> Result { Ok(parse_time(time)?.format("%Y-%m-%d %H:%M:%S").to_string()) } #[nasl_function] -fn isotime_scan(time: &str) -> Result { +fn isotime_scan(time: &str) -> Result { let time = parse_time(time)?; Ok(time.format("%Y%m%dT%H%M%S").to_string()) diff --git a/rust/src/nasl/builtin/isotime/tests.rs b/rust/src/nasl/builtin/isotime/tests.rs index cc5fc21f6..eaf6d86a3 100644 --- a/rust/src/nasl/builtin/isotime/tests.rs +++ b/rust/src/nasl/builtin/isotime/tests.rs @@ -21,22 +21,22 @@ mod tests { #[test] fn isotime_scan() { - check_err_matches!("isotime_scan(\"\");", NaslError::Diagnostic { .. }); + check_err_matches!("isotime_scan(\"\");", FunctionErrorKind::Diagnostic { .. }); check_err_matches!( "isotime_scan(\"a8691002T123456\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"18691002T1234\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"18691002T1234512\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_scan(\"1869-10-02T12:34:56\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_code_result("isotime_scan(\"18691002T123456\");", "18691002T123456"); @@ -47,18 +47,18 @@ mod tests { #[test] fn isotime_print() { - check_err_matches!("isotime_print(\"\");", NaslError::Diagnostic { .. }); + check_err_matches!("isotime_print(\"\");", FunctionErrorKind::Diagnostic { .. }); check_err_matches!( "isotime_print(\"a8691002T123456\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_print(\"18691002T1234\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_print(\"1869-10-02T12:34:56\");", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_code_result("isotime_print(\"18691002T123456\");", "1869-10-02 12:34:56"); @@ -76,14 +76,17 @@ mod tests { #[test] fn isotime_add() { - check_err_matches!("isotime_add(\"\", years: 0);", NaslError::Diagnostic { .. }); + check_err_matches!( + "isotime_add(\"\", years: 0);", + FunctionErrorKind::Diagnostic { .. } + ); check_err_matches!( "isotime_add(\"50001002T120000\", years: 5000);", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_err_matches!( "isotime_add(\"50001002T120000\", years: -5001);", - NaslError::Diagnostic { .. } + FunctionErrorKind::Diagnostic { .. } ); check_code_result( diff --git a/rust/src/nasl/builtin/knowledge_base/mod.rs b/rust/src/nasl/builtin/knowledge_base/mod.rs index 7ab8c66d2..296fd6a83 100644 --- a/rust/src/nasl/builtin/knowledge_base/mod.rs +++ b/rust/src/nasl/builtin/knowledge_base/mod.rs @@ -9,7 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::function_set; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::NaslError; +use crate::nasl::utils::error::FunctionErrorKind; use crate::nasl::utils::Context; use crate::storage::{Field, Kb, Retrieve}; use nasl_function_proc_macro::nasl_function; @@ -22,13 +22,13 @@ fn set_kb_item( name: NaslValue, value: NaslValue, expires: Option, -) -> Result { +) -> Result { let expires = match expires { Some(NaslValue::Number(x)) => Some(x), Some(NaslValue::Exit(0)) => None, None => None, Some(x) => { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!("expected expires to be a number but is {x}."), None, )) @@ -56,7 +56,7 @@ fn set_kb_item( /// NASL function to get a knowledge base #[nasl_function] -fn get_kb_item(c: &Context, key: &str) -> Result { +fn get_kb_item(c: &Context, key: &str) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { @@ -73,7 +73,11 @@ fn get_kb_item(c: &Context, key: &str) -> Result { /// NASL function to replace a kb list #[nasl_function(named(name, value))] -fn replace_kb_item(c: &Context, name: NaslValue, value: NaslValue) -> Result { +fn replace_kb_item( + c: &Context, + name: NaslValue, + value: NaslValue, +) -> Result { c.dispatcher() .dispatch_replace( c.key(), @@ -89,7 +93,7 @@ fn replace_kb_item(c: &Context, name: NaslValue, value: NaslValue) -> Result Result { +fn get_kb_list(c: &Context, key: NaslValue) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { diff --git a/rust/src/nasl/builtin/network/mod.rs b/rust/src/nasl/builtin/network/mod.rs index eeaedebcc..3a09e6e42 100644 --- a/rust/src/nasl/builtin/network/mod.rs +++ b/rust/src/nasl/builtin/network/mod.rs @@ -74,7 +74,7 @@ impl Display for OpenvasEncaps { } } -pub fn get_kb_item(context: &Context, name: &str) -> Result, NaslError> { +pub fn get_kb_item(context: &Context, name: &str) -> Result, FunctionErrorKind> { context .retriever() .retrieve(context.key(), Retrieve::KB(name.to_string())) diff --git a/rust/src/nasl/builtin/network/network.rs b/rust/src/nasl/builtin/network/network.rs index 003692176..33f3915bf 100644 --- a/rust/src/nasl/builtin/network/network.rs +++ b/rust/src/nasl/builtin/network/network.rs @@ -11,7 +11,7 @@ use super::{ verify_port, DEFAULT_PORT, }; use crate::function_set; -use crate::nasl::utils::{Context, NaslError}; +use crate::nasl::utils::{Context, FunctionErrorKind}; use crate::storage::{types::Primitive, Field, Kb}; use nasl_function_proc_macro::nasl_function; @@ -132,7 +132,11 @@ fn islocalnet(context: &Context) -> Result { /// Declares an open port on the target host #[nasl_function(named(port, proto))] -fn scanner_add_port(context: &Context, port: i64, proto: Option<&str>) -> Result<(), NaslError> { +fn scanner_add_port( + context: &Context, + port: i64, + proto: Option<&str>, +) -> Result<(), FunctionErrorKind> { let port = verify_port(port)?; let protocol = proto.unwrap_or("tcp"); diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index 8e22ec7c8..cf81a770c 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -297,7 +297,7 @@ impl NaslSockets { data: &[u8], flags: Option, len: Option, - ) -> Result { + ) -> Result { let len = if let Some(len) = len { if len < 1 || len > data.len() { data.len() @@ -381,7 +381,7 @@ impl NaslSockets { len: usize, min: Option, timeout: Option, - ) -> Result { + ) -> Result { let min = min .map(|min| if min < 0 { len } else { min as usize }) .unwrap_or(len); @@ -473,7 +473,7 @@ impl NaslSockets { /// - Secret/kdc_port /// - Secret/kdc_use_tcp #[nasl_function] - fn open_sock_kdc(&self, context: &Context) -> Result { + fn open_sock_kdc(&self, context: &Context) -> Result { let hostname = match get_kb_item(context, "Secret/kdc_hostname")? { Some(x) => Ok(x.to_string()), None => Err(SocketError::Diagnostic( @@ -556,7 +556,7 @@ impl NaslSockets { bufsz: Option, // TODO: Extract information from custom priority string // priority: Option<&str>, - ) -> Result { + ) -> Result { // Get port let port = verify_port(port)?; let transport = transport.unwrap_or(-1); @@ -657,7 +657,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, tls_config: Option, - ) -> Result { + ) -> Result { let addr = ipstr2ipaddr(addr)?; let mut retry = super::get_kb_item(context, "timeout_retry")? .map(|val| match val { @@ -717,7 +717,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, hostname: &str, - ) -> Result { + ) -> Result { let cert_path = get_kb_item(context, "SSL/cert")? .ok_or(SocketError::Diagnostic( "unable to open TLS connection: kes 'SSL/cert' is missing".to_string(), @@ -796,7 +796,7 @@ impl NaslSockets { /// Open a UDP socket to the target host #[nasl_function] - fn open_sock_udp(&self, context: &Context, port: i64) -> Result { + fn open_sock_udp(&self, context: &Context, port: i64) -> Result { let port = verify_port(port)?; let addr = ipstr2ipaddr(context.target())?; diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 6656cec9f..2724ea750 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -105,11 +105,11 @@ impl From<&Frame> for Vec { } impl TryFrom<&[u8]> for Frame { - type Error = NaslError; + type Error = FunctionErrorKind; fn try_from(f: &[u8]) -> Result { if f.len() < 14 { - Err(NaslError::missing_argument("valid ip address")) + Err(FunctionErrorKind::missing_argument("valid ip address")) } else { let mut frame = Frame::new(); frame.set_dsthaddr(MacAddr(f[0], f[1], f[2], f[3], f[4], f[5])); @@ -272,13 +272,15 @@ fn convert_vec_into_mac_address(v: &[u8]) -> Option { } } -fn validate_mac_address(v: Option<&ContextType>) -> Result { +fn validate_mac_address(v: Option<&ContextType>) -> Result { let mac_addr = match v { Some(ContextType::Value(NaslValue::String(x))) => MacAddr::from_str(x).ok(), Some(ContextType::Value(NaslValue::Data(x))) => convert_vec_into_mac_address(x), _ => None, }; - mac_addr.ok_or_else(|| NaslError::wrong_unnamed_argument("mac address", "invalid mac address")) + mac_addr.ok_or_else(|| { + FunctionErrorKind::wrong_unnamed_argument("mac address", "invalid mac address") + }) } /// Return the MAC address, given the interface name @@ -291,7 +293,7 @@ fn get_local_mac_address(name: &str) -> Option { /// Return a frame given a capture device and a filter. It returns an empty frame in case /// there was no response or anything was filtered. -fn recv_frame(cap: &mut Capture, filter: &str) -> Result { +fn recv_frame(cap: &mut Capture, filter: &str) -> Result { let f = Frame::new(); let p = match cap.filter(filter, true) { @@ -311,7 +313,7 @@ fn send_frame( pcap_active: &bool, filter: Option<&String>, timeout: i32, -) -> Result, NaslError> { +) -> Result, FunctionErrorKind> { let mut capture_dev = match Capture::from_device(iface.clone()) { Ok(c) => match c.promisc(true).timeout(timeout).open() { Ok(mut capture) => match capture.sendpacket(frame) { @@ -344,12 +346,15 @@ fn send_frame( /// /// It takes the following argument: /// - cap_timeout: time to wait for answer in seconds, 5 by default -fn nasl_send_arp_request(register: &Register, context: &Context) -> Result { +fn nasl_send_arp_request( + register: &Register, + context: &Context, +) -> Result { let timeout = match register.named("pcap_timeout") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -359,7 +364,7 @@ fn nasl_send_arp_request(register: &Register, context: &Context) -> Result Result x, _ => { - return Err(NaslError::missing_argument( + return Err(FunctionErrorKind::missing_argument( "Not possible to get a src mac address.", )) } @@ -378,7 +383,7 @@ fn nasl_send_arp_request(register: &Register, context: &Context) -> Result x, Err(_) => { - return Err(NaslError::missing_argument( + return Err(FunctionErrorKind::missing_argument( "Not possible to parse the src IP address.", )) } @@ -387,7 +392,7 @@ fn nasl_send_arp_request(register: &Register, context: &Context) -> Result x, Err(_) => { - return Err(NaslError::missing_argument( + return Err(FunctionErrorKind::missing_argument( "Not possible to parse the dst IP address.", )) } @@ -407,7 +412,7 @@ fn nasl_send_arp_request(register: &Register, context: &Context) -> Result Result { +) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(ArgumentError::MissingPositionals { @@ -423,7 +428,7 @@ fn nasl_get_local_mac_address_from_ip( let iface = get_interface_by_local_ip(ip)?; match get_local_mac_address(&iface.name) { Some(mac) => Ok(NaslValue::String(mac.to_string())), - _ => Err(NaslError::Diagnostic( + _ => Err(FunctionErrorKind::Diagnostic( "Not possible to get the local mac address".to_string(), Some(NaslValue::Null), )), @@ -442,7 +447,7 @@ fn nasl_get_local_mac_address_from_ip( /// - ether_proto: is an int containing the ethernet type (normally given as hexadecimal). /// It is optional and its default value is 0x0800. A list of Types can be e.g. looked up here. /// - payload: is any data, which is then attached as payload to the frame. -fn nasl_forge_frame(register: &Register, _: &Context) -> Result { +fn nasl_forge_frame(register: &Register, _: &Context) -> Result { let src_haddr = validate_mac_address(register.named("src_haddr"))?; let dst_haddr = validate_mac_address(register.named("dst_haddr"))?; let ether_proto = match register.named("ether_proto") { @@ -470,11 +475,11 @@ fn nasl_forge_frame(register: &Register, _: &Context) -> Result Result { +fn nasl_send_frame(register: &Register, context: &Context) -> Result { let frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => x, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Data", "Invalid data type", )) @@ -485,7 +490,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result x, None => &true, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -496,7 +501,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Some(x), None => None, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -507,7 +512,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -529,11 +534,11 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Result { +fn nasl_dump_frame(register: &Register, _: &Context) -> Result { let frame: Frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => (x as &[u8]).try_into()?, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Data", "Invalid data type", )) diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index f9efeba2d..601363fdb 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -41,13 +41,13 @@ pub enum PacketForgeryError { Custom(String), } -fn error(s: String) -> NaslError { +fn error(s: String) -> FunctionErrorKind { PacketForgeryError::Custom(s).into() } macro_rules! custom_error { ($a:expr, $b:expr) => { - Err(NaslError::Diagnostic( + Err(FunctionErrorKind::Diagnostic( format!($a, $b), Some(NaslValue::Null), )) @@ -99,7 +99,7 @@ fn safe_copy_from_slice( o_buf: &[u8], o_init: usize, o_fin: usize, -) -> Result<(), NaslError> { +) -> Result<(), FunctionErrorKind> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -132,7 +132,7 @@ fn safe_copy_from_slice( /// - ip_v is: the IP version. 4 by default. /// /// Returns the IP datagram or NULL on error. -fn forge_ip_packet(register: &Register, configs: &Context) -> Result { +fn forge_ip_packet(register: &Register, configs: &Context) -> Result { let dst_addr = get_host_ip(configs)?; if dst_addr.is_ipv6() { @@ -153,7 +153,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result Result { +fn set_ip_elements( + register: &Register, + _configs: &Context, +) -> Result { let mut buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("ip")); + return Err(FunctionErrorKind::missing_argument("ip")); } }; let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut buf).ok_or_else(|| { - NaslError::Diagnostic( + FunctionErrorKind::Diagnostic( "No possible to create a packet from buffer".to_string(), None, ) @@ -368,11 +371,11 @@ fn set_ip_elements(register: &Register, _configs: &Context) -> Result Result { +fn get_ip_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("ip")); + return Err(FunctionErrorKind::missing_argument("ip")); } }; @@ -394,12 +397,12 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::String(pkt.get_destination().to_string())), _ => Err(ArgumentError::WrongArgument("Invalid element".to_string()).into()), }, - _ => Err(NaslError::missing_argument("element")), + _ => Err(FunctionErrorKind::missing_argument("element")), } } /// Receive a list of IP packets and print them in a readable format in the screen. -fn dump_ip_packet(register: &Register, _: &Context) -> Result { +fn dump_ip_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(ArgumentError::MissingPositionals { @@ -455,31 +458,34 @@ fn dump_protocol(pkt: &Ipv4Packet) -> String { /// - code: is the identifier of the option to add /// - length: is the length of the option data /// - value: is the option data -fn insert_ip_options(register: &Register, _configs: &Context) -> Result { +fn insert_ip_options( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("ip")); + return Err(FunctionErrorKind::missing_argument("ip")); } }; let code = match register.named("code") { Some(ContextType::Value(NaslValue::Number(x))) => *x, _ => { - return Err(NaslError::missing_argument("code")); + return Err(FunctionErrorKind::missing_argument("code")); } }; let length = match register.named("length") { Some(ContextType::Value(NaslValue::Number(x))) => *x as usize, _ => { - return Err(NaslError::missing_argument("length")); + return Err(FunctionErrorKind::missing_argument("length")); } }; let value = match register.named("value") { Some(ContextType::Value(NaslValue::String(x))) => x.as_bytes(), Some(ContextType::Value(NaslValue::Data(x))) => x, _ => { - return Err(NaslError::missing_argument("value")); + return Err(FunctionErrorKind::missing_argument("value")); } }; @@ -548,12 +554,15 @@ fn insert_ip_options(register: &Register, _configs: &Context) -> Result Result { +fn forge_tcp_packet( + register: &Register, + _configs: &Context, +) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { // Missingarguments - return Err(NaslError::missing_argument("ip")); + return Err(FunctionErrorKind::missing_argument("ip")); } }; let original_ip_len = ip_buf.len(); @@ -663,11 +672,14 @@ fn forge_tcp_packet(register: &Register, _configs: &Context) -> Result Result { +fn get_tcp_element( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("tcp")); + return Err(FunctionErrorKind::missing_argument("tcp")); } }; @@ -691,7 +703,7 @@ fn get_tcp_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Data(tcp.payload().to_vec())), _ => Err(ArgumentError::WrongArgument("element".to_string()).into()), }, - _ => Err(NaslError::missing_argument("element")), + _ => Err(FunctionErrorKind::missing_argument("element")), } } @@ -706,11 +718,11 @@ fn get_tcp_element(register: &Register, _configs: &Context) -> Result Result { +fn get_tcp_option(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("tcp")); + return Err(FunctionErrorKind::missing_argument("tcp")); } }; @@ -761,7 +773,7 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Array(timestamps)), _ => Err(ArgumentError::WrongArgument("Invalid option".to_string()).into()), }, - _ => Err(NaslError::missing_argument("option")), + _ => Err(FunctionErrorKind::missing_argument("option")), } } @@ -780,11 +792,14 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Result { +fn set_tcp_elements( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("tcp")); + return Err(FunctionErrorKind::missing_argument("tcp")); } }; @@ -916,7 +931,10 @@ fn set_tcp_elements(register: &Register, _configs: &Context) -> Result Result { +fn insert_tcp_options( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1095,7 +1113,7 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result Result { +fn dump_tcp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -1197,10 +1215,13 @@ fn format_flags(pkt: &TcpPacket) -> String { /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. /// /// Returns the modified IP datagram or NULL on error. -fn forge_udp_packet(register: &Register, _configs: &Context) -> Result { +fn forge_udp_packet( + register: &Register, + _configs: &Context, +) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), - _ => return Err(NaslError::missing_argument("ip")), + _ => return Err(FunctionErrorKind::missing_argument("ip")), }; let original_ip_len = ip_buf.len(); @@ -1275,11 +1296,14 @@ fn forge_udp_packet(register: &Register, _configs: &Context) -> Result Result { +fn set_udp_elements( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("udp")); + return Err(FunctionErrorKind::missing_argument("udp")); } }; @@ -1376,7 +1400,7 @@ fn set_udp_elements(register: &Register, _configs: &Context) -> Result Result { +fn dump_udp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -1428,11 +1452,14 @@ fn dump_udp_packet(register: &Register, _: &Context) -> Result Result { +fn get_udp_element( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("udp")); + return Err(FunctionErrorKind::missing_argument("udp")); } }; @@ -1463,11 +1490,14 @@ fn get_udp_element(register: &Register, _configs: &Context) -> Result Result { +fn forge_icmp_packet( + register: &Register, + _configs: &Context, +) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("icmp")); + return Err(FunctionErrorKind::missing_argument("icmp")); } }; let original_ip_len = ip_buf.len(); @@ -1554,11 +1584,14 @@ fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result Result { +fn get_icmp_element( + register: &Register, + _configs: &Context, +) -> Result { let buf = match register.named("icmp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("icmp")); + return Err(FunctionErrorKind::missing_argument("icmp")); } }; @@ -1605,15 +1638,15 @@ fn get_icmp_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Null), }, - _ => Err(NaslError::missing_argument("element")), + _ => Err(FunctionErrorKind::missing_argument("element")), } } /// Receive a list of IPv4 ICMP packets and print them in a readable format in the screen. -fn dump_icmp_packet(register: &Register, _: &Context) -> Result { +fn dump_icmp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(NaslError::missing_argument("icmp")); + return Err(FunctionErrorKind::missing_argument("icmp")); } for icmp_pkt in positional.iter() { @@ -1736,11 +1769,14 @@ pub mod igmp { /// - group: IGMP group /// - type: IGMP type. 0 by default. /// - update_ip_len: If this flag is set, NASL will recompute the size field of the IP datagram. Default: True. -fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { +fn forge_igmp_packet( + register: &Register, + _configs: &Context, +) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(NaslError::missing_argument("igmp")); + return Err(FunctionErrorKind::missing_argument("igmp")); } }; let original_ip_len = ip_buf.len(); @@ -1799,7 +1835,7 @@ fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result Result Result { +fn new_raw_socket() -> Result { match Socket::new_raw( Domain::IPV4, socket2::Type::RAW, @@ -1832,7 +1868,7 @@ fn new_raw_socket() -> Result { /// /// Its argument is: /// - port: port for the ping -fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { +fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { let rnd_tcp_port = || -> u16 { (random_impl().unwrap_or(0) % 65535 + 1024) as u16 }; let sports_ori: Vec = vec![ @@ -1866,7 +1902,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result *x, None => 0, //TODO: implement plug_get_host_open_port() _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -1968,12 +2004,15 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_packet( + register: &Register, + configs: &Context, +) -> Result { let use_pcap = match register.named("pcap_active") { Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => true, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -1984,7 +2023,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result x.to_string(), None => String::new(), _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -1995,7 +2034,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -2006,7 +2045,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result *x, None => false, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Boolean", "Invalid allow_broadcast value", )) @@ -2028,7 +2067,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result *x, None => 0, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -2051,7 +2090,12 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result data as &[u8], - _ => return Err(NaslError::wrong_unnamed_argument("Data", "Invalid packet")), + _ => { + return Err(FunctionErrorKind::wrong_unnamed_argument( + "Data", + "Invalid packet", + )) + } }; let packet = packet::ipv4::Ipv4Packet::new(packet_raw) .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; @@ -2077,7 +2121,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result socket2::SockAddr::from(addr), Err(e) => { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!("send_packet: {}", e), Some(NaslValue::Null), )); @@ -2089,7 +2133,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!("send_packet: {}", e), Some(NaslValue::Null), )); @@ -2116,7 +2160,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result Result { +fn nasl_pcap_next(register: &Register, configs: &Context) -> Result { nasl_send_capture(register, configs) } @@ -2125,12 +2169,15 @@ fn nasl_pcap_next(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_capture( + register: &Register, + configs: &Context, +) -> Result { let interface = match register.named("interface") { Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "String", "Invalid interface value", )) @@ -2141,7 +2188,7 @@ fn nasl_send_capture(register: &Register, configs: &Context) -> Result x.to_string(), None => String::new(), _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -2152,7 +2199,7 @@ fn nasl_send_capture(register: &Register, configs: &Context) -> Result *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(NaslError::wrong_unnamed_argument( + return Err(FunctionErrorKind::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index c59ef6fa1..ae1794023 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -8,14 +8,14 @@ use std::{ }; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::NaslError; +use crate::nasl::utils::FunctionErrorKind; use pcap::{Address, Device}; /// Convert a string in a IpAddr -pub fn ipstr2ipaddr(ip_addr: &str) -> Result { +pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(NaslError::Diagnostic( + Err(_) => Err(FunctionErrorKind::Diagnostic( "Invalid IP address".to_string(), Some(NaslValue::Null), )), @@ -39,7 +39,7 @@ pub fn islocalhost(addr: IpAddr) -> bool { } /// Get the interface from the local ip -pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { +pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { // This fake IP is used for matching (and return false) // during the search of the interface in case an interface // doesn't have an associated address. @@ -70,15 +70,18 @@ pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result Ok(dev), - _ => Err(NaslError::Diagnostic( + _ => Err(FunctionErrorKind::Diagnostic( "Invalid ip address".to_string(), None, )), } } -pub fn bind_local_socket(dst: &SocketAddr) -> Result { - let fe = Err(NaslError::Diagnostic("Error binding".to_string(), None)); +pub fn bind_local_socket(dst: &SocketAddr) -> Result { + let fe = Err(FunctionErrorKind::Diagnostic( + "Error binding".to_string(), + None, + )); match dst { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0").or(fe), SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0").or(fe), @@ -86,7 +89,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result { } /// Return the source IP address given the destination IP address -pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { +pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { let socket = SocketAddr::new(dst, port); let sd = format!("{}:{}", dst, port); let local_socket = bind_local_socket(&socket)?; @@ -94,17 +97,17 @@ pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { Ok(_) => match local_socket.local_addr() { Ok(l_addr) => match IpAddr::from_str(&l_addr.ip().to_string()) { Ok(x) => Ok(x), - Err(_) => Err(NaslError::Diagnostic( + Err(_) => Err(FunctionErrorKind::Diagnostic( "No route to destination".to_string(), None, )), }, - Err(_) => Err(NaslError::Diagnostic( + Err(_) => Err(FunctionErrorKind::Diagnostic( "No route to destination".to_string(), None, )), }, - Err(_) => Err(NaslError::Diagnostic( + Err(_) => Err(FunctionErrorKind::Diagnostic( "No route to destination".to_string(), None, )), diff --git a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs index 0d9a10fcb..fb446c261 100644 --- a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs @@ -8,7 +8,7 @@ mod tests { use nasl_builtin_raw_ip::RawIp; use nasl_builtin_std::ContextFactory; - use crate::nasl::utils::{error::NaslError, Executor}; + use crate::nasl::utils::{error::FunctionErrorKind, Executor}; use crate::nasl::interpreter::test_utils::TestBuilder; use crate::nasl::syntax::NaslValue; @@ -20,7 +20,7 @@ mod tests { o_buf: &[u8], o_init: usize, o_fin: usize, - ) -> Result<(), NaslError> { + ) -> Result<(), FunctionErrorKind> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -29,7 +29,7 @@ mod tests { || d_buf.len() < d_fin || o_buf.len() < o_fin { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null), )); @@ -270,7 +270,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, 2, &b, 0, b.len()), - Err(NaslError::Diagnostic( + Err(FunctionErrorKind::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -279,7 +279,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, alen, &b, 0, 2), - Err(NaslError::Diagnostic( + Err(FunctionErrorKind::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -288,7 +288,7 @@ mod tests { // out of index in the destination range assert_eq!( safe_copy_from_slice(&mut a, 1, alen + 1, &b, 0, b.len()), - Err(NaslError::Diagnostic( + Err(FunctionErrorKind::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index 9cb3d5d52..adb2e8af7 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -52,7 +52,7 @@ fn ereg( icase: Option, rnul: Option, multiline: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let multiline = multiline.unwrap_or(false); @@ -79,7 +79,7 @@ fn ereg_replace( replace: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -107,7 +107,7 @@ fn egrep( pattern: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -141,7 +141,7 @@ fn eregmatch( find_all: Option, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let find_all = find_all.unwrap_or(false); diff --git a/rust/src/nasl/builtin/report_functions/mod.rs b/rust/src/nasl/builtin/report_functions/mod.rs index dc7ccae92..652d1fcd9 100644 --- a/rust/src/nasl/builtin/report_functions/mod.rs +++ b/rust/src/nasl/builtin/report_functions/mod.rs @@ -26,7 +26,7 @@ impl Reporting { typus: ResultType, register: &Register, context: &Context, - ) -> Result { + ) -> Result { let data = register.named("data").map(|x| x.to_string()); let port = register .named("port") @@ -70,7 +70,11 @@ impl Reporting { /// - port, optional TCP or UDP port number of the service /// - proto is the protocol ("tcp" by default; "udp" is the other value). /// - uri specifies the location of a found product - fn log_message(&self, register: &Register, context: &Context) -> Result { + fn log_message( + &self, + register: &Register, + context: &Context, + ) -> Result { self.store_result(ResultType::Log, register, context) } @@ -85,7 +89,7 @@ impl Reporting { &self, register: &Register, context: &Context, - ) -> Result { + ) -> Result { self.store_result(ResultType::Alarm, register, context) } @@ -100,7 +104,7 @@ impl Reporting { &self, register: &Register, context: &Context, - ) -> Result { + ) -> Result { self.store_result(ResultType::Error, register, context) } } diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 61aefa442..60cc74dc0 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -42,7 +42,7 @@ mod libssh_uses { #[cfg(feature = "nasl-builtin-libssh")] pub use libssh_uses::*; -type Result = std::result::Result; +type Result = std::result::Result; const DEFAULT_SSH_PORT: u16 = 22; @@ -533,7 +533,7 @@ impl Ssh { } AuthStatus::Success => break, status => { - return Err(NaslError::Diagnostic( + return Err(FunctionErrorKind::Diagnostic( format!( "Unexpected authentication status for session_id {}: {:?}", session_id, status diff --git a/rust/src/nasl/builtin/ssh/utils.rs b/rust/src/nasl/builtin/ssh/utils.rs index 744ca3b38..3a0a89d4d 100644 --- a/rust/src/nasl/builtin/ssh/utils.rs +++ b/rust/src/nasl/builtin/ssh/utils.rs @@ -12,7 +12,7 @@ impl<'a, T> FromNaslValue<'a> for CommaSeparated where T: for<'b> FromNaslValue<'b>, { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = StringOrData::from_nasl_value(value)?; Ok(Self( s.0.split(",") @@ -21,13 +21,13 @@ where let nasl_val = NaslValue::String(substr.to_string()); T::from_nasl_value(&nasl_val) }) - .collect::, NaslError>>()?, + .collect::, FunctionErrorKind>>()?, )) } } impl<'a> FromNaslValue<'a> for key::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; key::Name::try_from(&*s).map_err(|_| { ArgumentError::WrongArgument(format!("Expected a valid SSH key type, found '{}'", s)) @@ -37,7 +37,7 @@ impl<'a> FromNaslValue<'a> for key::Name { } impl<'a> FromNaslValue<'a> for cipher::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; cipher::Name::try_from(&*s).map_err(|_| { ArgumentError::WrongArgument(format!("Expected a valid SSH cipher type, found '{}'", s)) diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 41828d5be..64b822030 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -10,7 +10,7 @@ mod tests; use crate::nasl::{ utils::{ function::{bytes_to_str, CheckedPositionals, Maybe, StringOrData}, - NaslError, + FunctionErrorKind, }, ArgumentError, }; @@ -290,7 +290,7 @@ fn stridx(haystack: NaslValue, needle: NaslValue, offset: Option) -> i64 /// NASL function to display any number of NASL values /// /// Internally the string function is used to concatenate the given parameters -fn display(register: &Register, configs: &Context) -> Result { +fn display(register: &Register, configs: &Context) -> Result { println!("{}", &string(register, configs)?); Ok(NaslValue::Null) } @@ -368,7 +368,11 @@ fn insstr( /// `pattern` contains the pattern to search for. /// The optional argument `icase` toggles case sensitivity. Default: false (case sensitive). If true, search is case insensitive. #[nasl_function(named(string, pattern, icase))] -fn match_(string: NaslValue, pattern: NaslValue, icase: Option) -> Result { +fn match_( + string: NaslValue, + pattern: NaslValue, + icase: Option, +) -> Result { let options = MatchOptions { case_sensitive: !icase.unwrap_or(false), require_literal_separator: false, diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 1da72d046..d108f0475 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -6,7 +6,7 @@ use std::io; use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; -use crate::nasl::utils::error::NaslError; +use crate::nasl::utils::error::FunctionErrorKind; use crate::nasl::InternalError; use crate::storage::StorageError; use thiserror::Error; @@ -19,12 +19,12 @@ pub struct FunctionError { pub function: String, /// Kind of error #[source] - pub kind: NaslError, + pub kind: FunctionErrorKind, } impl FunctionError { /// Creates a new FunctionError - pub fn new(function: &str, kind: NaslError) -> Self { + pub fn new(function: &str, kind: FunctionErrorKind) -> Self { Self { function: function.to_owned(), kind, @@ -231,7 +231,7 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { match fe.kind { - NaslError::Internal(InternalError::Storage(e)) => { + FunctionErrorKind::Internal(InternalError::Storage(e)) => { Self::new(InterpretErrorKind::StorageError(e), None) } _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index 701611cb4..8581544c3 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -20,8 +20,8 @@ pub mod prelude { pub use super::utils::ArgumentError; pub use super::utils::Context; pub use super::utils::ContextType; + pub use super::utils::FunctionErrorKind; pub use super::utils::InternalError; - pub use super::utils::NaslError; pub use super::utils::NaslResult; pub use super::utils::Register; pub use crate::function_set; diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index ddf581dfd..88dbaf50c 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -294,7 +294,7 @@ where fn check_result( &self, - result: &Result, + result: &Result, reference: &TracedTestResult, line_count: usize, ) { @@ -305,7 +305,7 @@ where "Mismatch at {}.\nIn code \"{}\":\nExpected: {:?}\nFound: {:?}", reference.location, self.lines[line_count], - Ok::<_, NaslError>(reference_result), + Ok::<_, FunctionErrorKind>(reference_result), result, ); } @@ -326,7 +326,7 @@ where fn compare_result( &self, - result: &Result, + result: &Result, reference: &TestResult, ) -> bool { match reference { @@ -403,11 +403,11 @@ macro_rules! check_err_matches { |e| { if let Err(e) = e { // Convert with try_into to allow using - // the variants of `NaslError` directly without + // the variants of `FunctionErrorKind` directly without // having to wrap them in the outer enum. let converted = e.try_into(); // This is only irrefutable for the - // NaslError -> NaslError conversion but not for others. + // FunctionErrorKind -> FunctionErrorKind conversion but not for others. #[allow(irrefutable_let_patterns)] if let Ok(e) = converted { matches!(e, $pat) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index d52802e64..bdf5d80fb 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -14,7 +14,7 @@ use super::ContextType; #[derive(Debug, Clone, Error)] /// Descriptive kind of error that can occur while calling a function -pub enum NaslError { +pub enum FunctionErrorKind { /// Diagnostic string is informational and the second arg is the return value for the user #[error("{0}")] Diagnostic(String, Option), @@ -46,40 +46,40 @@ pub enum InternalError { Storage(#[from] StorageError), } -impl From for NaslError { +impl From for FunctionErrorKind { fn from(value: StorageError) -> Self { - NaslError::Internal(InternalError::Storage(value)) + FunctionErrorKind::Internal(InternalError::Storage(value)) } } -impl TryFrom for ArgumentError { +impl TryFrom for ArgumentError { type Error = (); - fn try_from(value: NaslError) -> Result { + fn try_from(value: FunctionErrorKind) -> Result { match value { - NaslError::Argument(e) => Ok(e), + FunctionErrorKind::Argument(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for InternalError { +impl TryFrom for InternalError { type Error = (); - fn try_from(value: NaslError) -> Result { + fn try_from(value: FunctionErrorKind) -> Result { match value { - NaslError::Internal(e) => Ok(e), + FunctionErrorKind::Internal(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for BuiltinError { +impl TryFrom for BuiltinError { type Error = (); - fn try_from(value: NaslError) -> Result { + fn try_from(value: FunctionErrorKind) -> Result { match value { - NaslError::Builtin(e) => Ok(e), + FunctionErrorKind::Builtin(e) => Ok(e), _ => Err(()), } } @@ -94,7 +94,7 @@ impl ArgumentError { } } -impl NaslError { +impl FunctionErrorKind { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and /// the actual value. @@ -111,7 +111,7 @@ impl NaslError { } } -impl From<(&str, &str, &NaslValue)> for NaslError { +impl From<(&str, &str, &NaslValue)> for FunctionErrorKind { fn from(value: (&str, &str, &NaslValue)) -> Self { let (key, expected, got) = value; let got: &str = &got.to_string(); @@ -119,7 +119,7 @@ impl From<(&str, &str, &NaslValue)> for NaslError { } } -impl From<(&str, &str, Option<&NaslValue>)> for NaslError { +impl From<(&str, &str, Option<&NaslValue>)> for FunctionErrorKind { fn from(value: (&str, &str, Option<&NaslValue>)) -> Self { match value { (key, expected, Some(x)) => (key, expected, x).into(), @@ -128,7 +128,7 @@ impl From<(&str, &str, Option<&NaslValue>)> for NaslError { } } -impl From<(&str, &str, Option<&ContextType>)> for NaslError { +impl From<(&str, &str, Option<&ContextType>)> for FunctionErrorKind { fn from(value: (&str, &str, Option<&ContextType>)) -> Self { match value { (key, expected, Some(ContextType::Value(x))) => (key, expected, x).into(), @@ -140,10 +140,10 @@ impl From<(&str, &str, Option<&ContextType>)> for NaslError { } } -impl From<(&str, &NaslValue)> for NaslError { +impl From<(&str, &NaslValue)> for FunctionErrorKind { fn from(value: (&str, &NaslValue)) -> Self { let (expected, got) = value; let got: &str = &got.to_string(); - NaslError::wrong_unnamed_argument(expected, got) + FunctionErrorKind::wrong_unnamed_argument(expected, got) } } diff --git a/rust/src/nasl/utils/function/from_nasl_value.rs b/rust/src/nasl/utils/function/from_nasl_value.rs index 106d89742..eecf9b68c 100644 --- a/rust/src/nasl/utils/function/from_nasl_value.rs +++ b/rust/src/nasl/utils/function/from_nasl_value.rs @@ -6,23 +6,23 @@ use crate::nasl::prelude::*; /// The conversion may fail. pub trait FromNaslValue<'a>: Sized { /// Perform the conversion - fn from_nasl_value(value: &'a NaslValue) -> Result; + fn from_nasl_value(value: &'a NaslValue) -> Result; } impl<'a> FromNaslValue<'a> for NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value.clone()) } } impl<'a> FromNaslValue<'a> for &'a NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value) } } impl<'a> FromNaslValue<'a> for String { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string.to_string()), _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), @@ -31,7 +31,7 @@ impl<'a> FromNaslValue<'a> for String { } impl<'a> FromNaslValue<'a> for &'a str { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string), _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), @@ -40,7 +40,7 @@ impl<'a> FromNaslValue<'a> for &'a str { } impl<'a> FromNaslValue<'a> for &'a [u8] { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Data(bytes) => Ok(bytes), _ => Err(ArgumentError::WrongArgument("Expected byte data.".to_string()).into()), @@ -49,19 +49,19 @@ impl<'a> FromNaslValue<'a> for &'a [u8] { } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Vec { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Array(vals) => Ok(vals .iter() .map(T::from_nasl_value) - .collect::, NaslError>>()?), + .collect::, FunctionErrorKind>>()?), _ => Err(ArgumentError::WrongArgument("Expected an array..".to_string()).into()), } } } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Dict(map) => Ok(map .iter() @@ -73,7 +73,7 @@ impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { } impl<'a> FromNaslValue<'a> for bool { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Boolean(b) => Ok(*b), NaslValue::Number(n) => Ok(*n != 0), @@ -85,7 +85,7 @@ impl<'a> FromNaslValue<'a> for bool { macro_rules! impl_from_nasl_value_for_numeric_type { ($ty: ty) => { impl<'a> FromNaslValue<'a> for $ty { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::Number(num) => Ok(<$ty>::try_from(*num).map_err(|_| { ArgumentError::WrongArgument("Expected positive number.".into()) diff --git a/rust/src/nasl/utils/function/maybe.rs b/rust/src/nasl/utils/function/maybe.rs index 04a8cc049..28085e718 100644 --- a/rust/src/nasl/utils/function/maybe.rs +++ b/rust/src/nasl/utils/function/maybe.rs @@ -1,6 +1,6 @@ use crate::nasl::syntax::NaslValue; -use crate::nasl::NaslError; +use crate::nasl::FunctionErrorKind; use super::FromNaslValue; @@ -12,7 +12,7 @@ use super::FromNaslValue; pub struct Maybe(Option); impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Maybe { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(Self(T::from_nasl_value(value).ok())) } } diff --git a/rust/src/nasl/utils/function/positionals.rs b/rust/src/nasl/utils/function/positionals.rs index fc26a3128..bd29d26f5 100644 --- a/rust/src/nasl/utils/function/positionals.rs +++ b/rust/src/nasl/utils/function/positionals.rs @@ -1,6 +1,6 @@ use std::{marker::PhantomData, ops::Index}; -use crate::nasl::{NaslError, Register}; +use crate::nasl::{FunctionErrorKind, Register}; use super::FromNaslValue; @@ -22,9 +22,9 @@ impl<'a, T: FromNaslValue<'a>> Positionals<'a, T> { } /// Returns an iterator over the positional arguments. - /// The item type is Result, since + /// The item type is Result, since /// the conversion to T can still fail. - pub fn iter(&self) -> impl Iterator> + 'a { + pub fn iter(&self) -> impl Iterator> + 'a { self.register .positional() .iter() @@ -45,12 +45,12 @@ pub struct CheckedPositionals { impl<'a, T: FromNaslValue<'a>> CheckedPositionals { /// Create a new `CheckedPositionals` from the register. - pub fn new(register: &'a Register) -> Result { + pub fn new(register: &'a Register) -> Result { let data = register .positional() .iter() .map(T::from_nasl_value) - .collect::, NaslError>>()?; + .collect::, FunctionErrorKind>>()?; Ok(Self { data, _marker: PhantomData, diff --git a/rust/src/nasl/utils/function/to_nasl_result.rs b/rust/src/nasl/utils/function/to_nasl_result.rs index 5afff332a..ab48aa7eb 100644 --- a/rust/src/nasl/utils/function/to_nasl_result.rs +++ b/rust/src/nasl/utils/function/to_nasl_result.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::nasl::syntax::NaslValue; -use crate::nasl::{NaslError, NaslResult}; +use crate::nasl::{FunctionErrorKind, NaslResult}; /// A type that can be converted to a NaslResult. /// The conversion is fallible to make it possible to convert from other Result @@ -26,7 +26,7 @@ impl ToNaslResult for Option { } } -impl> ToNaslResult for Result { +impl> ToNaslResult for Result { fn to_nasl_result(self) -> NaslResult { self.map_err(|e| e.into()).and_then(|x| x.to_nasl_result()) } @@ -67,7 +67,7 @@ impl ToNaslResult for Vec<&str> { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, NaslError>>()?, + .collect::, FunctionErrorKind>>()?, )) } } @@ -77,7 +77,7 @@ impl ToNaslResult for Vec { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, NaslError>>()?, + .collect::, FunctionErrorKind>>()?, )) } } @@ -93,7 +93,7 @@ impl ToNaslResult for HashMap { Ok(NaslValue::Dict( self.into_iter() .map(|(key, s)| s.to_nasl_result().map(|res| (key, res))) - .collect::, NaslError>>()?, + .collect::, FunctionErrorKind>>()?, )) } } @@ -116,7 +116,7 @@ macro_rules! impl_to_nasl_result_for_numeric_type { impl_to_nasl_result_for_numeric_type!($ty, skip_vec_impl); impl ToNaslResult for Vec<$ty> { fn to_nasl_result(self) -> NaslResult { - let collected: Result, NaslError> = + let collected: Result, FunctionErrorKind> = self.into_iter().map(|x| x.to_nasl_result()).collect(); Ok(NaslValue::Array(collected?)) } diff --git a/rust/src/nasl/utils/function/types.rs b/rust/src/nasl/utils/function/types.rs index ff1920f45..38179334d 100644 --- a/rust/src/nasl/utils/function/types.rs +++ b/rust/src/nasl/utils/function/types.rs @@ -5,7 +5,7 @@ use crate::nasl::prelude::*; pub struct StringOrData(pub String); impl<'a> FromNaslValue<'a> for StringOrData { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(Self(string.clone())), NaslValue::Data(buffer) => Ok(Self(bytes_to_str(buffer))), diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index b3d33f3a6..14990eccc 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::*; pub fn get_optional_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, -) -> Result, NaslError> { +) -> Result, FunctionErrorKind> { register .positional() .get(position) @@ -23,7 +23,7 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, num_required_positional_args: usize, -) -> Result { +) -> Result { let positional = register.positional(); let arg = positional.get(position).ok_or_else(|| { let num_given = positional.len(); @@ -53,7 +53,7 @@ fn context_type_as_nasl_value<'a>( pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result, NaslError> { +) -> Result, FunctionErrorKind> { register .named(name) .map(|arg| context_type_as_nasl_value(arg, name)) @@ -67,7 +67,7 @@ pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( pub fn get_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result { +) -> Result { let arg = register .named(name) .ok_or_else(|| ArgumentError::MissingNamed(vec![name.to_string()]))?; @@ -80,7 +80,7 @@ pub fn get_optional_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result, NaslError> { +) -> Result, FunctionErrorKind> { let via_position = get_optional_positional_arg::(register, position)?; if let Some(via_position) = via_position { Ok(Some(via_position)) @@ -95,7 +95,7 @@ pub fn get_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result { +) -> Result { let via_position = get_optional_positional_arg(register, position)?; if let Some(via_position) = via_position { Ok(via_position) @@ -114,7 +114,7 @@ fn check_named_args( _nasl_fn_name: &str, named: &[&str], maybe_named: &[&str], -) -> Result { +) -> Result { let mut num_maybe_named = 0; for arg_name in register.iter_named_args().unwrap() { if arg_name == FC_ANON_ARGS || named.contains(&arg_name) { @@ -142,7 +142,7 @@ pub fn check_args( named: &[&str], maybe_named: &[&str], max_num_expected_positional: Option, -) -> Result<(), NaslError> { +) -> Result<(), FunctionErrorKind> { let num_maybe_named_given = check_named_args(register, _nasl_fn_name, named, maybe_named)?; let num_positional_given = register.positional().len(); if let Some(max_num_expected_positional) = max_num_expected_positional { diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index 6b0333122..cf8699b9e 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -13,13 +13,13 @@ use std::collections::HashMap; pub use context::{Context, ContextType, Register}; pub use error::ArgumentError; +pub use error::FunctionErrorKind; pub use error::InternalError; -pub use error::NaslError; pub use executor::{Executor, IntoFunctionSet, StoredFunctionSet}; /// The result of a function call. -pub type NaslResult = Result; +pub type NaslResult = Result; /// Resolves positional arguments from the register. pub fn resolve_positional_arguments(register: &Register) -> Vec { diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 771d5affc..89caa58b3 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -141,7 +141,7 @@ where Err(e) => match &e.kind { InterpretErrorKind::FunctionCallError(FunctionError { function: _, - kind: NaslError::Diagnostic(_, x), + kind: FunctionErrorKind::Diagnostic(_, x), }) => { tracing::warn!(error=?e, "function call error"); x.clone().unwrap_or_default() From fe796f331d8cc8bccba090fd60b20f5379260f54 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Wed, 6 Nov 2024 09:26:55 +0100 Subject: [PATCH 18/36] Add return_value to builtin errors --- rust/src/nasl/builtin/error.rs | 44 +++++++++++++++++++++++++--- rust/src/nasl/utils/error.rs | 25 ++++++++++++++++ rust/src/scannerctl/interpret/mod.rs | 20 ++++++------- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 00bfa8484..eccc2b2f7 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,12 +1,22 @@ use thiserror::Error; +use crate::nasl::utils::error::ReturnValue; +use crate::nasl::NaslValue; + use super::super::prelude::FunctionErrorKind; use super::cryptographic::CryptographicError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; #[derive(Debug, Clone, Error)] -pub enum BuiltinError { +#[error("{kind}")] +pub struct BuiltinError { + kind: BuiltinErrorKind, + return_value: Option, +} + +#[derive(Debug, Clone, Error)] +pub enum BuiltinErrorKind { #[error("{0}")] Ssh(SshError), #[error("{0}")] @@ -24,17 +34,39 @@ pub enum BuiltinError { PacketForgery(super::raw_ip::PacketForgeryError), } +impl ReturnValue for BuiltinError { + fn with_return_value(self, return_value: NaslValue) -> Self { + Self { + kind: self.kind, + return_value: Some(return_value), + } + } + + fn get_return_value(&self) -> Option<&NaslValue> { + self.return_value.as_ref() + } +} + +impl From for BuiltinError { + fn from(kind: BuiltinErrorKind) -> Self { + Self { + kind, + return_value: None, + } + } +} + macro_rules! builtin_error_variant ( ($err: path, $variant: ident) => { impl From<$err> for BuiltinError { fn from(value: $err) -> Self { - BuiltinError::$variant(value) + BuiltinErrorKind::$variant(value).into() } } impl From<$err> for FunctionErrorKind { fn from(value: $err) -> Self { - FunctionErrorKind::Builtin(BuiltinError::$variant(value)) + FunctionErrorKind::Builtin(BuiltinErrorKind::$variant(value).into()) } } @@ -43,7 +75,11 @@ macro_rules! builtin_error_variant ( fn try_from(value: FunctionErrorKind) -> Result { match value { - FunctionErrorKind::Builtin(BuiltinError::$variant(e)) => Ok(e), + FunctionErrorKind::Builtin( + BuiltinError { + kind: BuiltinErrorKind::$variant(e), .. + } + ) => Ok(e), _ => Err(()), } } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index bdf5d80fb..80855888f 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -46,6 +46,31 @@ pub enum InternalError { Storage(#[from] StorageError), } +pub trait ReturnValue { + fn with_return_value(self, val: NaslValue) -> Self; + fn get_return_value(&self) -> Option<&NaslValue>; +} + +impl ReturnValue for FunctionErrorKind { + fn with_return_value(self, return_value: NaslValue) -> Self { + match self { + Self::Diagnostic(_, _) => unimplemented!(), + Self::Argument(_) => self, + Self::Builtin(e) => Self::Builtin(e.with_return_value(return_value)), + Self::Internal(_) => self, + } + } + + fn get_return_value(&self) -> Option<&NaslValue> { + match self { + Self::Diagnostic(_, _) => unimplemented!(), + Self::Argument(_) => None, + Self::Builtin(e) => e.get_return_value(), + Self::Internal(_) => None, + } + } +} + impl From for FunctionErrorKind { fn from(value: StorageError) -> Self { FunctionErrorKind::Internal(InternalError::Storage(value)) diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 89caa58b3..2d48eb0e8 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -8,7 +8,7 @@ use std::{ }; use futures::StreamExt; -use scannerlib::nasl::interpreter::CodeInterpreter; +use scannerlib::nasl::{interpreter::CodeInterpreter, utils::error::ReturnValue}; use scannerlib::nasl::{ interpreter::{FunctionError, InterpretErrorKind}, prelude::*, @@ -138,16 +138,16 @@ where for result in results { let r = match result { Ok(x) => x, - Err(e) => match &e.kind { - InterpretErrorKind::FunctionCallError(FunctionError { - function: _, - kind: FunctionErrorKind::Diagnostic(_, x), - }) => { - tracing::warn!(error=?e, "function call error"); - x.clone().unwrap_or_default() + Err(e) => { + if let InterpretErrorKind::FunctionCallError(FunctionError { kind, .. }) = + e.kind + { + tracing::warn!(error=?kind, "function call error"); + kind.get_return_value().cloned().unwrap_or_default() + } else { + return Err(e.into()); } - _ => return Err(e.into()), - }, + } }; match r { NaslValue::Exit(rc) => std::process::exit(rc as i32), From c30d44aa670633288893bbf0a1d94d5a1a8f75c6 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Wed, 6 Nov 2024 11:47:59 +0100 Subject: [PATCH 19/36] Remove diagnostic variant --- rust/src/nasl/builtin/error.rs | 21 ++- rust/src/nasl/builtin/http/error.rs | 25 ++++ rust/src/nasl/builtin/http/mod.rs | 141 ++++++------------ rust/src/nasl/builtin/isotime/mod.rs | 31 ++-- rust/src/nasl/builtin/isotime/tests.rs | 44 ++---- rust/src/nasl/builtin/knowledge_base/mod.rs | 10 +- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 33 ++-- rust/src/nasl/builtin/raw_ip/mod.rs | 19 +++ .../src/nasl/builtin/raw_ip/packet_forgery.rs | 60 +++----- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 67 +++------ rust/src/nasl/builtin/ssh/error.rs | 2 + rust/src/nasl/builtin/ssh/mod.rs | 12 +- rust/src/nasl/mod.rs | 1 + rust/src/nasl/utils/error.rs | 9 +- 14 files changed, 205 insertions(+), 270 deletions(-) create mode 100644 rust/src/nasl/builtin/http/error.rs diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index eccc2b2f7..b7bef5bd5 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -5,6 +5,9 @@ use crate::nasl::NaslValue; use super::super::prelude::FunctionErrorKind; use super::cryptographic::CryptographicError; +use super::http::HttpError; +use super::isotime::IsotimeError; +use super::knowledge_base::KBError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; @@ -20,6 +23,8 @@ pub enum BuiltinErrorKind { #[error("{0}")] Ssh(SshError), #[error("{0}")] + Http(HttpError), + #[error("{0}")] String(StringError), #[error("{0}")] Misc(MiscError), @@ -29,16 +34,23 @@ pub enum BuiltinErrorKind { Cryptographic(CryptographicError), #[error("{0}")] Regex(RegexError), + #[error("{0}")] + Isotime(IsotimeError), + #[error("{0}")] + KB(KBError), #[cfg(feature = "nasl-builtin-raw-ip")] #[error("{0}")] PacketForgery(super::raw_ip::PacketForgeryError), + #[cfg(feature = "nasl-builtin-raw-ip")] + #[error("{0}")] + RawIp(super::raw_ip::RawIpError), } impl ReturnValue for BuiltinError { - fn with_return_value(self, return_value: NaslValue) -> Self { + fn with_return_value(self, return_value: impl Into) -> Self { Self { kind: self.kind, - return_value: Some(return_value), + return_value: Some(return_value.into()), } } @@ -92,6 +104,11 @@ builtin_error_variant!(MiscError, Misc); builtin_error_variant!(SocketError, Socket); builtin_error_variant!(CryptographicError, Cryptographic); builtin_error_variant!(SshError, Ssh); +builtin_error_variant!(HttpError, Http); +builtin_error_variant!(IsotimeError, Isotime); builtin_error_variant!(RegexError, Regex); +builtin_error_variant!(KBError, KB); #[cfg(feature = "nasl-builtin-raw-ip")] builtin_error_variant!(super::raw_ip::PacketForgeryError, PacketForgery); +#[cfg(feature = "nasl-builtin-raw-ip")] +builtin_error_variant!(super::raw_ip::RawIpError, RawIp); diff --git a/rust/src/nasl/builtin/http/error.rs b/rust/src/nasl/builtin/http/error.rs new file mode 100644 index 000000000..2dea5844c --- /dev/null +++ b/rust/src/nasl/builtin/http/error.rs @@ -0,0 +1,25 @@ +use std::io; + +use thiserror::Error; + +#[derive(Clone, Debug, Error)] +pub enum HttpError { + #[error("IO error during HTTP: {0}")] + IO(io::ErrorKind), + #[error("HTTP error: {0}")] + H2(String), + #[error("Handle ID {0} not found.")] + HandleIdNotFound(i32), +} + +impl From for HttpError { + fn from(value: io::Error) -> Self { + Self::IO(value.kind()) + } +} + +impl From for HttpError { + fn from(value: h2::Error) -> Self { + Self::H2(format!("{}", value)) + } +} diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index 98b59d758..b15f761cc 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -5,9 +5,12 @@ //! Defines NASL functions to perform HTTP/2 request. // TODO: implement http functions once socket handling is available -use crate::nasl::prelude::*; +mod error; + use crate::nasl::utils::ContextType; +use crate::nasl::{prelude::*, utils::error::ReturnValue}; +pub use error::HttpError; use h2::client; use core::convert::AsRef; @@ -131,7 +134,7 @@ impl NaslHttp { data: String, method: Method, handle: &mut Handle, - ) -> Result<(Parts, String), FunctionErrorKind> { + ) -> Result<(Parts, String), HttpError> { // Establish TCP connection to the server. let mut config = ClientConfig::builder() @@ -145,49 +148,20 @@ impl NaslHttp { let server_name = ip_str.clone().to_owned().try_into().unwrap(); let connector = TlsConnector::from(Arc::new(config)); - let stream = match TcpStream::connect(format!("{}:{}", ip_str, port)).await { - Ok(a) => a, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )); - } - }; - - let stream = match connector.connect(server_name, stream).await { - Ok(a) => a, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )); - } - }; - - let (h2, connection) = match client::handshake(stream).await { - Ok((x, y)) => (x, y), - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } - }; + let stream = TcpStream::connect(format!("{}:{}", ip_str, port)) + .await + .map_err(HttpError::from)?; + let stream = connector + .connect(server_name, stream) + .await + .map_err(HttpError::from)?; + let (h2, connection) = client::handshake(stream).await.map_err(HttpError::from)?; tokio::spawn(async move { connection.await.unwrap(); }); - let mut h2 = match h2.ready().await { - Ok(x) => x, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } - }; + let mut h2 = h2.ready().await.map_err(HttpError::from)?; // Prepare the HTTP request to send to the server. let mut request = Request::builder(); @@ -214,15 +188,7 @@ impl NaslHttp { let mut resp = String::new(); while let Some(chunk) = body.data().await { - let chunk = match chunk { - Ok(byte_chunk) => byte_chunk, - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - e.to_string(), - Some(NaslValue::Null), - )) - } - }; + let chunk = chunk.map_err(HttpError::from)?; resp.push_str(&String::from_utf8_lossy(&chunk)); // Let the server send more data. @@ -247,29 +213,16 @@ impl NaslHttp { }; let mut handles = lock_handles(&self.handles).await?; - let handle = match handles + let (_, handle) = handles .iter_mut() .enumerate() .find(|(_i, h)| h.handle_id == handle_id) - { - Some((_i, handle)) => handle, - _ => { - return Err(FunctionErrorKind::Diagnostic( - format!("Handle ID {} not found", handle_id), - Some(NaslValue::Null), - )) - } - }; + .ok_or(HttpError::HandleIdNotFound(handle_id))?; - let item: String = match register.named("item") { - Some(x) => x.to_string(), - _ => { - return Err(FunctionErrorKind::Diagnostic( - "Missing item".to_string(), - Some(NaslValue::Null), - )) - } - }; + let item: String = register + .named("item") + .map(|x| x.to_string()) + .ok_or(FunctionErrorKind::missing_argument("item"))?; let schema: String = match register.named("schema") { Some(x) => { @@ -306,25 +259,23 @@ impl NaslHttp { uri = format!("{}{}", uri, item); - match self.request(&ip_str, port, uri, data, method, handle).await { - Ok((head, body)) => { - handle.http_code = head.status.as_u16(); - let mut header_str = String::new(); - header_str.push_str(format!("{:?} ", head.version).as_str()); - header_str.push_str(format!("{:?}\n", head.status).as_str()); - for (k, v) in head.headers.iter() { - header_str.push_str(&format!( - "{}: {}\n", - k.as_str(), - String::from_utf8_lossy(v.as_bytes()) - )) - } - //let _ = head.headers.iter().map(|(k,v)| header_str.push_str(&format!("{}: {}\n", k.as_str(), String::from_utf8_lossy(v.as_bytes())))); - header_str.push_str(&body); - Ok(NaslValue::String(header_str)) - } - Err(e) => Err(e), + let (head, body) = self + .request(&ip_str, port, uri, data, method, handle) + .await?; + handle.http_code = head.status.as_u16(); + let mut header_str = String::new(); + header_str.push_str(format!("{:?} ", head.version).as_str()); + header_str.push_str(format!("{:?}\n", head.status).as_str()); + for (k, v) in head.headers.iter() { + header_str.push_str(&format!( + "{}: {}\n", + k.as_str(), + String::from_utf8_lossy(v.as_bytes()) + )) } + //let _ = head.headers.iter().map(|(k,v)| header_str.push_str(&format!("{}: {}\n", k.as_str(), String::from_utf8_lossy(v.as_bytes())))); + header_str.push_str(&body); + Ok(NaslValue::String(header_str)) } /// Wrapper function for GET request. See http2_req @@ -410,10 +361,10 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(FunctionErrorKind::Diagnostic( - format!("Handle ID {} not found", handle), - Some(NaslValue::Number(-1)), - )), + _ => { + Err(FunctionErrorKind::from(HttpError::HandleIdNotFound(handle)) + .with_return_value(-1)) + } } } @@ -442,10 +393,7 @@ impl NaslHttp { .find(|(_i, h)| h.handle_id == handle_id) { Some((_i, handle)) => Ok(NaslValue::Number(handle.http_code as i64)), - _ => Err(FunctionErrorKind::Diagnostic( - format!("Handle ID {} not found", handle_id), - Some(NaslValue::Null), - )), + _ => Err(HttpError::HandleIdNotFound(handle_id).into()), } } @@ -484,10 +432,7 @@ impl NaslHttp { h.header_items.push((key.to_string(), val.to_string())); Ok(NaslValue::Number(0)) } - _ => Err(FunctionErrorKind::Diagnostic( - format!("Handle ID {} not found", handle_id), - Some(NaslValue::Null), - )), + _ => Err(HttpError::HandleIdNotFound(handle_id).into()), } } } diff --git a/rust/src/nasl/builtin/isotime/mod.rs b/rust/src/nasl/builtin/isotime/mod.rs index 5f9543fd0..4b830423f 100644 --- a/rust/src/nasl/builtin/isotime/mod.rs +++ b/rust/src/nasl/builtin/isotime/mod.rs @@ -9,6 +9,11 @@ mod tests; use crate::nasl::prelude::*; use chrono::{Datelike, Months, NaiveDate, NaiveDateTime, TimeDelta}; +use thiserror::Error; + +#[derive(Clone, Debug, Error)] +#[error("{0}")] +pub struct IsotimeError(String); const ISOFORMAT: &str = "yyyymmddThhmmss"; const READABLEFORMAT: &str = "yyyy-mm-dd hh:mm:ss"; @@ -41,20 +46,17 @@ fn parse_readable_time(time: &str) -> Option { None } -fn parse_time(time: &str) -> Result { +fn parse_time(time: &str) -> Result { if let Some(time) = parse_isotime(time) { return Ok(time); } if let Some(time) = parse_readable_time(time) { return Ok(time); } - Err(FunctionErrorKind::Diagnostic( - format!( - "The given time is not in the correct isotime ({}) or readable time format ({}): {}", - ISOFORMAT, READABLEFORMAT, time - ), - None, - )) + Err(IsotimeError(format!( + "The given time is not in the correct isotime ({}) or readable time format ({}): {}", + ISOFORMAT, READABLEFORMAT, time + ))) } #[nasl_function(named(years, days, seconds))] @@ -63,7 +65,7 @@ fn isotime_add( years: Option, days: Option, seconds: Option, -) -> Result { +) -> Result { let mut time = parse_time(time)?; if let Some(years) = years { @@ -83,13 +85,10 @@ fn isotime_add( } if time.year() < 0 || time.year() > 9999 { - return Err(FunctionErrorKind::Diagnostic( - format!( - "The resulting year is out of range (0000-9999): {}.", - time.year() - ), - None, - )); + return Err(IsotimeError(format!( + "The resulting year is out of range (0000-9999): {}.", + time.year() + ))); } Ok(time.format("%Y%m%dT%H%M%S").to_string()) diff --git a/rust/src/nasl/builtin/isotime/tests.rs b/rust/src/nasl/builtin/isotime/tests.rs index eaf6d86a3..202bdca44 100644 --- a/rust/src/nasl/builtin/isotime/tests.rs +++ b/rust/src/nasl/builtin/isotime/tests.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception #[cfg(test)] mod tests { - use crate::nasl::test_prelude::*; + use crate::nasl::{builtin::isotime::IsotimeError, test_prelude::*}; #[test] fn isotime_is_valid() { @@ -21,22 +21,13 @@ mod tests { #[test] fn isotime_scan() { - check_err_matches!("isotime_scan(\"\");", FunctionErrorKind::Diagnostic { .. }); - check_err_matches!( - "isotime_scan(\"a8691002T123456\");", - FunctionErrorKind::Diagnostic { .. } - ); - check_err_matches!( - "isotime_scan(\"18691002T1234\");", - FunctionErrorKind::Diagnostic { .. } - ); - check_err_matches!( - "isotime_scan(\"18691002T1234512\");", - FunctionErrorKind::Diagnostic { .. } - ); + check_err_matches!("isotime_scan(\"\");", IsotimeError { .. }); + check_err_matches!("isotime_scan(\"a8691002T123456\");", IsotimeError { .. }); + check_err_matches!("isotime_scan(\"18691002T1234\");", IsotimeError { .. }); + check_err_matches!("isotime_scan(\"18691002T1234512\");", IsotimeError { .. }); check_err_matches!( "isotime_scan(\"1869-10-02T12:34:56\");", - FunctionErrorKind::Diagnostic { .. } + IsotimeError { .. } ); check_code_result("isotime_scan(\"18691002T123456\");", "18691002T123456"); @@ -47,18 +38,12 @@ mod tests { #[test] fn isotime_print() { - check_err_matches!("isotime_print(\"\");", FunctionErrorKind::Diagnostic { .. }); - check_err_matches!( - "isotime_print(\"a8691002T123456\");", - FunctionErrorKind::Diagnostic { .. } - ); - check_err_matches!( - "isotime_print(\"18691002T1234\");", - FunctionErrorKind::Diagnostic { .. } - ); + check_err_matches!("isotime_print(\"\");", IsotimeError { .. }); + check_err_matches!("isotime_print(\"a8691002T123456\");", IsotimeError { .. }); + check_err_matches!("isotime_print(\"18691002T1234\");", IsotimeError { .. }); check_err_matches!( "isotime_print(\"1869-10-02T12:34:56\");", - FunctionErrorKind::Diagnostic { .. } + IsotimeError { .. } ); check_code_result("isotime_print(\"18691002T123456\");", "1869-10-02 12:34:56"); @@ -76,17 +61,14 @@ mod tests { #[test] fn isotime_add() { - check_err_matches!( - "isotime_add(\"\", years: 0);", - FunctionErrorKind::Diagnostic { .. } - ); + check_err_matches!("isotime_add(\"\", years: 0);", IsotimeError { .. }); check_err_matches!( "isotime_add(\"50001002T120000\", years: 5000);", - FunctionErrorKind::Diagnostic { .. } + IsotimeError { .. } ); check_err_matches!( "isotime_add(\"50001002T120000\", years: -5001);", - FunctionErrorKind::Diagnostic { .. } + IsotimeError { .. } ); check_code_result( diff --git a/rust/src/nasl/builtin/knowledge_base/mod.rs b/rust/src/nasl/builtin/knowledge_base/mod.rs index 296fd6a83..a9ec656df 100644 --- a/rust/src/nasl/builtin/knowledge_base/mod.rs +++ b/rust/src/nasl/builtin/knowledge_base/mod.rs @@ -13,6 +13,11 @@ use crate::nasl::utils::error::FunctionErrorKind; use crate::nasl::utils::Context; use crate::storage::{Field, Kb, Retrieve}; use nasl_function_proc_macro::nasl_function; +use thiserror::Error; + +#[derive(Clone, Debug, Error)] +#[error("{0}")] +pub struct KBError(String); /// NASL function to set a value under name in a knowledge base /// Only pushes unique values for the given name. @@ -28,10 +33,7 @@ fn set_kb_item( Some(NaslValue::Exit(0)) => None, None => None, Some(x) => { - return Err(FunctionErrorKind::Diagnostic( - format!("expected expires to be a number but is {x}."), - None, - )) + return Err(KBError(format!("expected expires to be a number but is {x}.")).into()) } } .map(|seconds| { diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 2724ea750..0f27aff94 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -14,6 +14,7 @@ use pcap::{Capture, Device}; use super::super::host::get_host_ip; use super::raw_ip_utils::{get_interface_by_local_ip, get_source_ip, ipstr2ipaddr}; +use super::RawIpError; use tracing::info; @@ -284,11 +285,12 @@ fn validate_mac_address(v: Option<&ContextType>) -> Result Option { - match interfaces().into_iter().find(|x| x.name == *name) { - Some(dev) => dev.mac, - _ => None, - } +fn get_local_mac_address(name: &str) -> Result { + interfaces() + .into_iter() + .find(|x| x.name == *name) + .and_then(|dev| dev.mac) + .ok_or_else(|| RawIpError::FailedToGetLocalMacAddress.into()) } /// Return a frame given a capture device and a filter. It returns an empty frame in case @@ -371,14 +373,7 @@ fn nasl_send_arp_request( } let local_ip = get_source_ip(target_ip, 50000u16)?; let iface = get_interface_by_local_ip(local_ip)?; - let local_mac_address = match get_local_mac_address(&iface.name) { - Some(x) => x, - _ => { - return Err(FunctionErrorKind::missing_argument( - "Not possible to get a src mac address.", - )) - } - }; + let local_mac_address = get_local_mac_address(&iface.name)?; let src_ip = match Ipv4Addr::from_str(&local_ip.to_string()) { Ok(x) => x, @@ -426,13 +421,7 @@ fn nasl_get_local_mac_address_from_ip( NaslValue::String(x) => { let ip = ipstr2ipaddr(x)?; let iface = get_interface_by_local_ip(ip)?; - match get_local_mac_address(&iface.name) { - Some(mac) => Ok(NaslValue::String(mac.to_string())), - _ => Err(FunctionErrorKind::Diagnostic( - "Not possible to get the local mac address".to_string(), - Some(NaslValue::Null), - )), - } + get_local_mac_address(&iface.name).map(|mac| mac.to_string().into()) } _ => Err(ArgumentError::WrongArgument( "Expected String containing a valid IP address.".to_string(), @@ -615,9 +604,9 @@ mod tests { #[test] fn get_local_mac() { if cfg!(target_os = "macos") { - assert_eq!(get_local_mac_address("lo"), None); + assert!(matches!(get_local_mac_address("lo"), Err(_))); } else { - assert_eq!(get_local_mac_address("lo"), Some(MacAddr::zero())); + assert_eq!(get_local_mac_address("lo").unwrap(), MacAddr::zero()); } } } diff --git a/rust/src/nasl/builtin/raw_ip/mod.rs b/rust/src/nasl/builtin/raw_ip/mod.rs index 952b2c71f..a54deb4d2 100644 --- a/rust/src/nasl/builtin/raw_ip/mod.rs +++ b/rust/src/nasl/builtin/raw_ip/mod.rs @@ -5,10 +5,29 @@ mod frame_forgery; mod packet_forgery; mod raw_ip_utils; +use std::io; + use crate::nasl::utils::{IntoFunctionSet, NaslVars, StoredFunctionSet}; use frame_forgery::FrameForgery; use packet_forgery::PacketForgery; pub use packet_forgery::PacketForgeryError; +use thiserror::Error; + +#[derive(Clone, Debug, Error)] +pub enum RawIpError { + #[error("Failed to get local MAC address.")] + FailedToGetLocalMacAddress, + #[error("Failed to create packet from buffer.")] + FailedToCreatePacket, + #[error("Failed to get device list.")] + FailedToGetDeviceList, + #[error("Invalid IP address.")] + InvalidIpAddress, + #[error("Failed to bind.")] + FailedToBind(io::ErrorKind), + #[error("No route to destination.")] + NoRouteToDestination, +} pub struct RawIp; diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 601363fdb..496a28527 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -9,7 +9,10 @@ use std::{ str::FromStr, }; -use super::raw_ip_utils::{get_interface_by_local_ip, get_source_ip, islocalhost}; +use super::{ + raw_ip_utils::{get_interface_by_local_ip, get_source_ip, islocalhost}, + RawIpError, +}; use super::super::host::get_host_ip; use crate::nasl::builtin::misc::random_impl; @@ -39,6 +42,10 @@ use tracing::debug; pub enum PacketForgeryError { #[error("{0}")] Custom(String), + #[error("Failed to parse socket address. {0}")] + ParseSocketAddr(std::net::AddrParseError), + #[error("Failed to send packet. {0}")] + SendPacket(std::io::ErrorKind), } fn error(s: String) -> FunctionErrorKind { @@ -47,10 +54,7 @@ fn error(s: String) -> FunctionErrorKind { macro_rules! custom_error { ($a:expr, $b:expr) => { - Err(FunctionErrorKind::Diagnostic( - format!($a, $b), - Some(NaslValue::Null), - )) + Err(PacketForgeryError::Custom(format!($a, $b)).into()) }; } @@ -152,12 +156,8 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result *x as u8, @@ -415,9 +411,8 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { - let pkt = packet::ipv4::Ipv4Packet::new(data).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(data) + .ok_or_else(|| RawIpError::FailedToCreatePacket)?; println!("\tip_hl={}", pkt.get_header_length()); println!("\tip_v={}", pkt.get_version()); @@ -1834,12 +1829,8 @@ fn forge_igmp_packet( ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf).ok_or_else(|| { - FunctionErrorKind::Diagnostic( - "No possible to create a packet from buffer".to_string(), - Some(NaslValue::Null), - ) - })?; + let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut ip_buf) + .ok_or_else(|| RawIpError::FailedToCreatePacket)?; pkt.set_total_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -2118,25 +2109,16 @@ fn nasl_send_packet( } let sock_str = format!("{}:{}", &packet.get_destination().to_string().as_str(), 0); - let sockaddr = match SocketAddr::from_str(&sock_str) { - Ok(addr) => socket2::SockAddr::from(addr), - Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - format!("send_packet: {}", e), - Some(NaslValue::Null), - )); - } - }; + let sockaddr = + SocketAddr::from_str(&sock_str).map_err(|e| PacketForgeryError::ParseSocketAddr(e))?; + let sockaddr = socket2::SockAddr::from(sockaddr); match soc.send_to(packet_raw, &sockaddr) { Ok(b) => { debug!("Sent {} bytes", b); } Err(e) => { - return Err(FunctionErrorKind::Diagnostic( - format!("send_packet: {}", e), - Some(NaslValue::Null), - )); + return Err(PacketForgeryError::SendPacket(e.kind()).into()); } } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index ae1794023..5e325bbd0 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -7,18 +7,20 @@ use std::{ str::FromStr, }; -use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::FunctionErrorKind; +use crate::nasl::utils::{error::ReturnValue, FunctionErrorKind}; +use crate::nasl::{syntax::NaslValue, ArgumentError}; use pcap::{Address, Device}; +use super::RawIpError; + /// Convert a string in a IpAddr pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(FunctionErrorKind::Diagnostic( + Err(_) => Err(FunctionErrorKind::from(ArgumentError::WrongArgument( "Invalid IP address".to_string(), - Some(NaslValue::Null), - )), + )) + .with_return_value(NaslValue::Null)), } } @@ -58,34 +60,24 @@ pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result devices.into_iter().find(|x| { + let devices = Device::list().map_err(|_| RawIpError::FailedToGetDeviceList)?; + devices + .into_iter() + .find(|x| { local_address == (x.addresses.clone().into_iter().find(ip_match)) .unwrap_or_else(|| fake_addr.to_owned()) .addr - }), - Err(_) => None, - }; - - match dev { - Some(dev) => Ok(dev), - _ => Err(FunctionErrorKind::Diagnostic( - "Invalid ip address".to_string(), - None, - )), - } + }) + .ok_or(RawIpError::InvalidIpAddress.into()) } -pub fn bind_local_socket(dst: &SocketAddr) -> Result { - let fe = Err(FunctionErrorKind::Diagnostic( - "Error binding".to_string(), - None, - )); +pub fn bind_local_socket(dst: &SocketAddr) -> Result { match dst { - SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0").or(fe), - SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0").or(fe), + SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0"), + SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0"), } + .map_err(|e| RawIpError::FailedToBind(e.kind())) } /// Return the source IP address given the destination IP address @@ -93,23 +85,10 @@ pub fn get_source_ip(dst: IpAddr, port: u16) -> Result match local_socket.local_addr() { - Ok(l_addr) => match IpAddr::from_str(&l_addr.ip().to_string()) { - Ok(x) => Ok(x), - Err(_) => Err(FunctionErrorKind::Diagnostic( - "No route to destination".to_string(), - None, - )), - }, - Err(_) => Err(FunctionErrorKind::Diagnostic( - "No route to destination".to_string(), - None, - )), - }, - Err(_) => Err(FunctionErrorKind::Diagnostic( - "No route to destination".to_string(), - None, - )), - } + local_socket + .connect(sd) + .ok() + .and_then(|_| local_socket.local_addr().ok()) + .and_then(|l_addr| IpAddr::from_str(&l_addr.ip().to_string()).ok()) + .ok_or(RawIpError::NoRouteToDestination.into()) } diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index 7aad2ad1c..334cc86ff 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -110,6 +110,8 @@ pub enum SshErrorKind { ConvertPrivateKey, #[error("Not yet implemented.")] Unimplemented, + #[error("Unexpected authentication status")] + UnexpectedAuthenticationStatus(String), } pub trait AttachErrorInfo { diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 60cc74dc0..65afc05e3 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -533,13 +533,11 @@ impl Ssh { } AuthStatus::Success => break, status => { - return Err(FunctionErrorKind::Diagnostic( - format!( - "Unexpected authentication status for session_id {}: {:?}", - session_id, status - ), - Some(NaslValue::Number(-1)), - )); + return Err(FunctionErrorKind::from( + SshErrorKind::UnexpectedAuthenticationStatus(format!("{:?}", status)) + .with(session_id), + ) + .with_return_value(-1)); } } } diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index 8581544c3..d23343bce 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -13,6 +13,7 @@ pub mod prelude { pub use super::syntax::FSPluginLoader; pub use super::syntax::Loader; pub use super::syntax::NaslValue; + pub use super::utils::error::ReturnValue; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; pub use super::utils::function::Positionals; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 80855888f..ea19692ac 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -15,9 +15,6 @@ use super::ContextType; #[derive(Debug, Clone, Error)] /// Descriptive kind of error that can occur while calling a function pub enum FunctionErrorKind { - /// Diagnostic string is informational and the second arg is the return value for the user - #[error("{0}")] - Diagnostic(String, Option), #[error("{0}")] Argument(#[from] ArgumentError), #[error("{0}")] @@ -47,14 +44,13 @@ pub enum InternalError { } pub trait ReturnValue { - fn with_return_value(self, val: NaslValue) -> Self; + fn with_return_value(self, return_value: impl Into) -> Self; fn get_return_value(&self) -> Option<&NaslValue>; } impl ReturnValue for FunctionErrorKind { - fn with_return_value(self, return_value: NaslValue) -> Self { + fn with_return_value(self, return_value: impl Into) -> Self { match self { - Self::Diagnostic(_, _) => unimplemented!(), Self::Argument(_) => self, Self::Builtin(e) => Self::Builtin(e.with_return_value(return_value)), Self::Internal(_) => self, @@ -63,7 +59,6 @@ impl ReturnValue for FunctionErrorKind { fn get_return_value(&self) -> Option<&NaslValue> { match self { - Self::Diagnostic(_, _) => unimplemented!(), Self::Argument(_) => None, Self::Builtin(e) => e.get_return_value(), Self::Internal(_) => None, From c4e85c8c368c1965bec2723009ec793e5209b5f4 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 09:46:19 +0100 Subject: [PATCH 20/36] Remove (&str, &NaslValue) -> FunctionErrorKind impl --- rust/src/nasl/builtin/description/mod.rs | 5 ++++- rust/src/nasl/utils/error.rs | 8 -------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index f797089af..66f80cac3 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -120,7 +120,10 @@ fn as_timeout_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_category_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { match arguments[0] { NaslValue::AttackCategory(cat) => Ok(vec![NVTField::Category(*cat)]), - a => Err(("AttackCategory", a).into()), + a => Err(FunctionErrorKind::wrong_unnamed_argument( + "AttackCategory", + &a.to_string(), + )), } } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index ea19692ac..4a2a3c282 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -159,11 +159,3 @@ impl From<(&str, &str, Option<&ContextType>)> for FunctionErrorKind { } } } - -impl From<(&str, &NaslValue)> for FunctionErrorKind { - fn from(value: (&str, &NaslValue)) -> Self { - let (expected, got) = value; - let got: &str = &got.to_string(); - FunctionErrorKind::wrong_unnamed_argument(expected, got) - } -} From 259a3f1211b69a5cea4fb50de1bdcffb7fd982f9 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 09:58:56 +0100 Subject: [PATCH 21/36] Remove From<&str, &str, ContextType> impl --- rust/src/nasl/builtin/cryptographic/hmac.rs | 47 ++++++++++----------- rust/src/nasl/utils/error.rs | 14 ------ 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/hmac.rs b/rust/src/nasl/builtin/cryptographic/hmac.rs index 4aa78f744..aefbc05ec 100644 --- a/rust/src/nasl/builtin/cryptographic/hmac.rs +++ b/rust/src/nasl/builtin/cryptographic/hmac.rs @@ -19,7 +19,7 @@ use sha2::{Sha256, Sha384, Sha512}; use crate::nasl::prelude::*; -fn hmac(register: &Register) -> Result +fn hmac(key: &str, data: &str) -> Result where D: CoreProxy, D::Core: HashMarker @@ -31,16 +31,6 @@ where ::BlockSize: IsLess, Le<::BlockSize, U256>: NonZero, { - let key = match register.named("key") { - Some(ContextType::Value(NaslValue::String(x))) => x, - Some(ContextType::Value(NaslValue::Null)) => return Ok(NaslValue::Null), - x => return Err(("key", "string", x).into()), - }; - let data = match register.named("data") { - Some(ContextType::Value(NaslValue::String(x))) => x, - Some(ContextType::Value(NaslValue::Null)) => return Ok(NaslValue::Null), - x => return Err(("data", "string", x).into()), - }; let mut hmac = match Hmac::::new_from_slice(key.as_bytes()) { Ok(x) => x, Err(InvalidLength) => { @@ -57,38 +47,45 @@ where } /// NASL function to get HMAC MD2 string -pub fn hmac_md2(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_md2(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC MD5 string -pub fn hmac_md5(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_md5(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC RIPEMD160 string -pub fn hmac_ripemd160(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_ripemd160(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC SHA1 string -pub fn hmac_sha1(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_sha1(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC SHA256 string -pub fn hmac_sha256(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_sha256(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC SHA384 string -pub fn hmac_sha384(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_sha384(key: &str, data: &str) -> Result { + hmac::(key, data) } /// NASL function to get HMAC SHA512 string -pub fn hmac_sha512(register: &Register, _: &Context) -> Result { - hmac::(register) +#[nasl_function(named(key, data))] +pub fn hmac_sha512(key: &str, data: &str) -> Result { + hmac::(key, data) } pub struct HmacFns; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 4a2a3c282..d699ff002 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -10,8 +10,6 @@ use crate::nasl::prelude::NaslValue; use crate::storage::StorageError; -use super::ContextType; - #[derive(Debug, Clone, Error)] /// Descriptive kind of error that can occur while calling a function pub enum FunctionErrorKind { @@ -147,15 +145,3 @@ impl From<(&str, &str, Option<&NaslValue>)> for FunctionErrorKind { } } } - -impl From<(&str, &str, Option<&ContextType>)> for FunctionErrorKind { - fn from(value: (&str, &str, Option<&ContextType>)) -> Self { - match value { - (key, expected, Some(ContextType::Value(x))) => (key, expected, x).into(), - (key, expected, Some(ContextType::Function(_, _))) => { - ArgumentError::wrong_argument(key, expected, "function").into() - } - (key, expected, None) => ArgumentError::wrong_argument(key, expected, "NULL").into(), - } - } -} From e7b9023d3c484446d36f35afb77e900a4368a136 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 10:01:46 +0100 Subject: [PATCH 22/36] Remove From<(&str, &str, &NaslValue)> impl --- rust/src/nasl/builtin/cryptographic/hash.rs | 64 ++++++++++----------- rust/src/nasl/utils/error.rs | 17 ------ 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/hash.rs b/rust/src/nasl/builtin/cryptographic/hash.rs index 5289e0033..5be8a996a 100644 --- a/rust/src/nasl/builtin/cryptographic/hash.rs +++ b/rust/src/nasl/builtin/cryptographic/hash.rs @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::function_set; -use crate::nasl::utils::error::FunctionErrorKind; use digest::Digest; use md2::Md2; use md4::Md4; @@ -12,63 +10,63 @@ use ripemd::Ripemd160; use sha1::Sha1; use sha2::{Sha256, Sha512}; -use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{Context, Register}; +use crate::nasl::prelude::*; +use crate::nasl::utils::function::StringOrData; -fn nasl_hash(register: &Register) -> Result +fn nasl_hash(data: Option) -> Result where D::OutputSize: std::ops::Add, ::Output: digest::generic_array::ArrayLength, { - let positional = register.positional(); - if positional.is_empty() { - return Ok(NaslValue::Null); - }; - let data = match &positional[0] { - NaslValue::String(x) => x.as_bytes(), - NaslValue::Data(x) => x, - NaslValue::Null => return Ok(NaslValue::Null), - x => return Err(("data", "string", x).into()), - }; - - let mut hash = D::new(); - hash.update(data); - Ok(NaslValue::Data(hash.finalize().as_slice().to_vec())) + if let Some(data) = data { + let mut hash = D::new(); + hash.update(data.0.as_bytes()); + Ok(NaslValue::Data(hash.finalize().as_slice().to_vec())) + } else { + Ok(NaslValue::Null) + } } /// NASL function to get MD2 hash -pub fn hash_md2(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_md2(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get MD4 hash -pub fn hash_md4(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_md4(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get MD5 hash -pub fn hash_md5(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_md5(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get SHA1 hash -pub fn hash_sha1(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_sha1(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get SHA256 hash -pub fn hash_sha256(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_sha256(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get SHA512 hash -pub fn hash_sha512(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_sha512(data: Option) -> Result { + nasl_hash::(data) } /// NASL function to get RIPemd160 hash -pub fn hash_ripemd160(register: &Register, _: &Context) -> Result { - nasl_hash::(register) +#[nasl_function] +pub fn hash_ripemd160(data: Option) -> Result { + nasl_hash::(data) } pub struct Hash; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index d699ff002..13b4dce8d 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -128,20 +128,3 @@ impl FunctionErrorKind { Self::Argument(ArgumentError::MissingNamed(vec![val.to_string()])) } } - -impl From<(&str, &str, &NaslValue)> for FunctionErrorKind { - fn from(value: (&str, &str, &NaslValue)) -> Self { - let (key, expected, got) = value; - let got: &str = &got.to_string(); - ArgumentError::wrong_argument(key, expected, got).into() - } -} - -impl From<(&str, &str, Option<&NaslValue>)> for FunctionErrorKind { - fn from(value: (&str, &str, Option<&NaslValue>)) -> Self { - match value { - (key, expected, Some(x)) => (key, expected, x).into(), - (key, expected, None) => ArgumentError::wrong_argument(key, expected, "NULL").into(), - } - } -} From 9db2909ecf64cadda9d6eac31d4f9809dbbbbaf0 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 11:21:38 +0100 Subject: [PATCH 23/36] Move AttachErrorInfo to utils/error --- rust/src/nasl/builtin/ssh/error.rs | 31 +++++++-------------- rust/src/nasl/builtin/ssh/libssh/channel.rs | 1 + rust/src/nasl/builtin/ssh/libssh/session.rs | 1 + rust/src/nasl/builtin/ssh/russh/session.rs | 1 + rust/src/nasl/utils/error.rs | 4 +++ 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index 334cc86ff..b6efec0c9 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -2,6 +2,8 @@ use std::fmt; use thiserror::Error; +use crate::nasl::utils::error::WithErrorInfo; + use super::SessionId; /// A cloneable representation of the Error type of the underlying SSH lib @@ -114,28 +116,24 @@ pub enum SshErrorKind { UnexpectedAuthenticationStatus(String), } -pub trait AttachErrorInfo { - fn attach_error_info(self, e: Info) -> Self; -} - -impl AttachErrorInfo for SshError { - fn attach_error_info(mut self, id: SessionId) -> SshError { +impl WithErrorInfo for SshError { + fn with(mut self, id: SessionId) -> SshError { self.id = Some(id); self } } #[cfg(feature = "nasl-builtin-libssh")] -impl AttachErrorInfo for SshError { - fn attach_error_info(mut self, source: libssh_rs::Error) -> SshError { +impl WithErrorInfo for SshError { + fn with(mut self, source: libssh_rs::Error) -> SshError { self.source = Some(source.into()); self } } #[cfg(not(feature = "nasl-builtin-libssh"))] -impl AttachErrorInfo for SshError { - fn attach_error_info(mut self, source: russh::Error) -> SshError { +impl WithErrorInfo for SshError { + fn with(mut self, source: russh::Error) -> SshError { self.source = Some(source.into()); self } @@ -154,18 +152,9 @@ impl From for SshError { impl SshErrorKind { pub fn with(self, m: Info) -> SshError where - SshError: AttachErrorInfo, + SshError: WithErrorInfo, { let e: SshError = self.into(); - e.attach_error_info(m) - } -} - -impl SshError { - pub fn with(self, m: Info) -> SshError - where - SshError: AttachErrorInfo, - { - self.attach_error_info(m) + e.with(m) } } diff --git a/rust/src/nasl/builtin/ssh/libssh/channel.rs b/rust/src/nasl/builtin/ssh/libssh/channel.rs index c857ebd12..db6144e0d 100644 --- a/rust/src/nasl/builtin/ssh/libssh/channel.rs +++ b/rust/src/nasl/builtin/ssh/libssh/channel.rs @@ -1,6 +1,7 @@ use std::time::Duration; use crate::nasl::builtin::ssh::error::SshErrorKind; +use crate::nasl::utils::error::WithErrorInfo; use super::{super::error::Result, SessionId}; diff --git a/rust/src/nasl/builtin/ssh/libssh/session.rs b/rust/src/nasl/builtin/ssh/libssh/session.rs index cc1710767..fc178a2f1 100644 --- a/rust/src/nasl/builtin/ssh/libssh/session.rs +++ b/rust/src/nasl/builtin/ssh/libssh/session.rs @@ -7,6 +7,7 @@ use super::super::error::{Result, SshErrorKind}; use super::super::Output; use super::SessionId; use super::{channel::Channel, Socket}; +use crate::nasl::utils::error::WithErrorInfo; /// Structure to hold an SSH Session pub struct SshSession { diff --git a/rust/src/nasl/builtin/ssh/russh/session.rs b/rust/src/nasl/builtin/ssh/russh/session.rs index 99cb9dad5..d846b5df6 100644 --- a/rust/src/nasl/builtin/ssh/russh/session.rs +++ b/rust/src/nasl/builtin/ssh/russh/session.rs @@ -10,6 +10,7 @@ use tracing::{error, warn}; use crate::nasl::builtin::ssh::error::SshErrorKind; use crate::nasl::builtin::ssh::Output; +use crate::nasl::utils::error::WithErrorInfo; use crate::nasl::utils::function::bytes_to_str; use super::super::error::SshError; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 13b4dce8d..4f56fb9a4 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -41,6 +41,10 @@ pub enum InternalError { Storage(#[from] StorageError), } +pub trait WithErrorInfo { + fn with(self, e: Info) -> Self; +} + pub trait ReturnValue { fn with_return_value(self, return_value: impl Into) -> Self; fn get_return_value(&self) -> Option<&NaslValue>; From 0cc2bfdb47ea8634bbee8d0ed4fbf33242d4a628 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 11:44:39 +0100 Subject: [PATCH 24/36] Move FEK (temp) --- rust/src/nasl/builtin/error.rs | 48 ++------- rust/src/nasl/builtin/http/mod.rs | 6 +- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 5 +- rust/src/nasl/builtin/ssh/mod.rs | 2 +- rust/src/nasl/interpreter/error.rs | 6 +- rust/src/nasl/mod.rs | 2 + rust/src/nasl/utils/error.rs | 101 +++++++++++++------ rust/src/scannerctl/interpret/mod.rs | 4 +- 8 files changed, 89 insertions(+), 85 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index b7bef5bd5..3a607b353 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,9 +1,7 @@ use thiserror::Error; -use crate::nasl::utils::error::ReturnValue; -use crate::nasl::NaslValue; +use crate::nasl::prelude::*; -use super::super::prelude::FunctionErrorKind; use super::cryptographic::CryptographicError; use super::http::HttpError; use super::isotime::IsotimeError; @@ -12,14 +10,7 @@ use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; #[derive(Debug, Clone, Error)] -#[error("{kind}")] -pub struct BuiltinError { - kind: BuiltinErrorKind, - return_value: Option, -} - -#[derive(Debug, Clone, Error)] -pub enum BuiltinErrorKind { +pub enum BuiltinError { #[error("{0}")] Ssh(SshError), #[error("{0}")] @@ -46,39 +37,17 @@ pub enum BuiltinErrorKind { RawIp(super::raw_ip::RawIpError), } -impl ReturnValue for BuiltinError { - fn with_return_value(self, return_value: impl Into) -> Self { - Self { - kind: self.kind, - return_value: Some(return_value.into()), - } - } - - fn get_return_value(&self) -> Option<&NaslValue> { - self.return_value.as_ref() - } -} - -impl From for BuiltinError { - fn from(kind: BuiltinErrorKind) -> Self { - Self { - kind, - return_value: None, - } - } -} - macro_rules! builtin_error_variant ( ($err: path, $variant: ident) => { impl From<$err> for BuiltinError { fn from(value: $err) -> Self { - BuiltinErrorKind::$variant(value).into() + BuiltinError::$variant(value).into() } } impl From<$err> for FunctionErrorKind { fn from(value: $err) -> Self { - FunctionErrorKind::Builtin(BuiltinErrorKind::$variant(value).into()) + FEK::Builtin(BuiltinError::$variant(value).into()).into() } } @@ -86,11 +55,9 @@ macro_rules! builtin_error_variant ( type Error = (); fn try_from(value: FunctionErrorKind) -> Result { - match value { - FunctionErrorKind::Builtin( - BuiltinError { - kind: BuiltinErrorKind::$variant(e), .. - } + match value.kind { + FEK::Builtin( + BuiltinError::$variant(e) ) => Ok(e), _ => Err(()), } @@ -108,6 +75,7 @@ builtin_error_variant!(HttpError, Http); builtin_error_variant!(IsotimeError, Isotime); builtin_error_variant!(RegexError, Regex); builtin_error_variant!(KBError, KB); + #[cfg(feature = "nasl-builtin-raw-ip")] builtin_error_variant!(super::raw_ip::PacketForgeryError, PacketForgery); #[cfg(feature = "nasl-builtin-raw-ip")] diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index b15f761cc..1348938fd 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -207,9 +207,7 @@ impl NaslHttp { ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => { - return Err(ArgumentError::WrongArgument(("Invalid handle ID").to_string()).into()) - } + _ => return Err(ArgumentError::WrongArgument("Invalid handle ID".to_string()).into()), }; let mut handles = lock_handles(&self.handles).await?; @@ -363,7 +361,7 @@ impl NaslHttp { } _ => { Err(FunctionErrorKind::from(HttpError::HandleIdNotFound(handle)) - .with_return_value(-1)) + .with(ReturnValue(-1))) } } } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index 5e325bbd0..e3396b77a 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -7,8 +7,7 @@ use std::{ str::FromStr, }; -use crate::nasl::utils::{error::ReturnValue, FunctionErrorKind}; -use crate::nasl::{syntax::NaslValue, ArgumentError}; +use crate::nasl::prelude::*; use pcap::{Address, Device}; use super::RawIpError; @@ -20,7 +19,7 @@ pub fn ipstr2ipaddr(ip_addr: &str) -> Result { Err(_) => Err(FunctionErrorKind::from(ArgumentError::WrongArgument( "Invalid IP address".to_string(), )) - .with_return_value(NaslValue::Null)), + .with(ReturnValue(NaslValue::Null))), } } diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 65afc05e3..8a7ee76f6 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -537,7 +537,7 @@ impl Ssh { SshErrorKind::UnexpectedAuthenticationStatus(format!("{:?}", status)) .with(session_id), ) - .with_return_value(-1)); + .with(ReturnValue(-1))); } } } diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index d108f0475..7279f4fb4 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -7,7 +7,7 @@ use std::io; use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; use crate::nasl::utils::error::FunctionErrorKind; -use crate::nasl::InternalError; +use crate::nasl::{InternalError, FEK}; use crate::storage::StorageError; use thiserror::Error; @@ -230,8 +230,8 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionError) -> Self { - match fe.kind { - FunctionErrorKind::Internal(InternalError::Storage(e)) => { + match fe.kind.kind { + FEK::Internal(InternalError::Storage(e)) => { Self::new(InterpretErrorKind::StorageError(e), None) } _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index d23343bce..d5c229028 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -14,6 +14,8 @@ pub mod prelude { pub use super::syntax::Loader; pub use super::syntax::NaslValue; pub use super::utils::error::ReturnValue; + pub use super::utils::error::WithErrorInfo; + pub use super::utils::error::FEK; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; pub use super::utils::function::Positionals; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 4f56fb9a4..aeef08a51 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -10,15 +10,65 @@ use crate::nasl::prelude::NaslValue; use crate::storage::StorageError; +#[derive(Debug, Clone, Error)] +#[error("{kind}")] +pub struct FunctionErrorKind { + #[source] + pub kind: FEK, + return_value: Option, +} + +impl FunctionErrorKind { + pub fn return_value(&self) -> &Option { + &self.return_value + } +} + +impl From for FunctionErrorKind { + fn from(value: FEK) -> Self { + FunctionErrorKind { + kind: value, + return_value: None, + } + } +} + +impl From for FunctionErrorKind { + fn from(value: ArgumentError) -> Self { + FunctionErrorKind { + kind: FEK::Argument(value), + return_value: None, + } + } +} + +impl From for FunctionErrorKind { + fn from(value: BuiltinError) -> Self { + FunctionErrorKind { + kind: FEK::Builtin(value), + return_value: None, + } + } +} + +impl From for FunctionErrorKind { + fn from(value: InternalError) -> Self { + FunctionErrorKind { + kind: FEK::Internal(value), + return_value: None, + } + } +} + #[derive(Debug, Clone, Error)] /// Descriptive kind of error that can occur while calling a function -pub enum FunctionErrorKind { +pub enum FEK { #[error("{0}")] - Argument(#[from] ArgumentError), + Argument(ArgumentError), #[error("{0}")] - Builtin(#[from] BuiltinError), + Builtin(BuiltinError), #[error("{0}")] - Internal(#[from] InternalError), + Internal(InternalError), } #[derive(Debug, Clone, PartialEq, Error)] @@ -45,32 +95,18 @@ pub trait WithErrorInfo { fn with(self, e: Info) -> Self; } -pub trait ReturnValue { - fn with_return_value(self, return_value: impl Into) -> Self; - fn get_return_value(&self) -> Option<&NaslValue>; -} +pub struct ReturnValue(pub T); -impl ReturnValue for FunctionErrorKind { - fn with_return_value(self, return_value: impl Into) -> Self { - match self { - Self::Argument(_) => self, - Self::Builtin(e) => Self::Builtin(e.with_return_value(return_value)), - Self::Internal(_) => self, - } - } - - fn get_return_value(&self) -> Option<&NaslValue> { - match self { - Self::Argument(_) => None, - Self::Builtin(e) => e.get_return_value(), - Self::Internal(_) => None, - } +impl> WithErrorInfo> for FunctionErrorKind { + fn with(mut self, val: ReturnValue) -> Self { + self.return_value = Some(val.0.into()); + self } } impl From for FunctionErrorKind { fn from(value: StorageError) -> Self { - FunctionErrorKind::Internal(InternalError::Storage(value)) + FEK::Internal(InternalError::Storage(value)).into() } } @@ -78,8 +114,8 @@ impl TryFrom for ArgumentError { type Error = (); fn try_from(value: FunctionErrorKind) -> Result { - match value { - FunctionErrorKind::Argument(e) => Ok(e), + match value.kind { + FEK::Argument(e) => Ok(e), _ => Err(()), } } @@ -89,8 +125,8 @@ impl TryFrom for InternalError { type Error = (); fn try_from(value: FunctionErrorKind) -> Result { - match value { - FunctionErrorKind::Internal(e) => Ok(e), + match value.kind { + FEK::Internal(e) => Ok(e), _ => Err(()), } } @@ -100,8 +136,8 @@ impl TryFrom for BuiltinError { type Error = (); fn try_from(value: FunctionErrorKind) -> Result { - match value { - FunctionErrorKind::Builtin(e) => Ok(e), + match value.kind { + FEK::Builtin(e) => Ok(e), _ => Err(()), } } @@ -121,14 +157,15 @@ impl FunctionErrorKind { /// containing the name of the argument, the expected value and /// the actual value. pub fn wrong_unnamed_argument(expected: &str, got: &str) -> Self { - Self::Argument(ArgumentError::WrongArgument(format!( + FEK::Argument(ArgumentError::WrongArgument(format!( "Expected {expected} but {got}" ))) + .into() } /// Helper function to quickly construct a `MissingArguments` variant /// for a single missing argument. pub fn missing_argument(val: &str) -> Self { - Self::Argument(ArgumentError::MissingNamed(vec![val.to_string()])) + FEK::Argument(ArgumentError::MissingNamed(vec![val.to_string()])).into() } } diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 2d48eb0e8..fed0ed298 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -8,7 +8,7 @@ use std::{ }; use futures::StreamExt; -use scannerlib::nasl::{interpreter::CodeInterpreter, utils::error::ReturnValue}; +use scannerlib::nasl::interpreter::CodeInterpreter; use scannerlib::nasl::{ interpreter::{FunctionError, InterpretErrorKind}, prelude::*, @@ -143,7 +143,7 @@ where e.kind { tracing::warn!(error=?kind, "function call error"); - kind.get_return_value().cloned().unwrap_or_default() + kind.return_value().clone().unwrap_or_default() } else { return Err(e.into()); } From a846cd8c2e5a0e61a2465bca2bc83d448e5abdc5 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 7 Nov 2024 12:22:58 +0100 Subject: [PATCH 25/36] Rename FunctionErrorKind -> FnError. Also rename FunctionError within interpreter to FunctionCallError. --- .../src/nasl/builtin/cryptographic/aes_cbc.rs | 14 +- .../src/nasl/builtin/cryptographic/aes_ccm.rs | 52 ++---- .../nasl/builtin/cryptographic/aes_cmac.rs | 4 +- .../src/nasl/builtin/cryptographic/aes_ctr.rs | 14 +- .../src/nasl/builtin/cryptographic/aes_gcm.rs | 46 ++--- .../nasl/builtin/cryptographic/aes_gmac.rs | 2 +- rust/src/nasl/builtin/cryptographic/des.rs | 2 +- rust/src/nasl/builtin/cryptographic/hash.rs | 16 +- rust/src/nasl/builtin/cryptographic/hmac.rs | 18 +- .../builtin/cryptographic/tests/aes_gcm.rs | 2 +- rust/src/nasl/builtin/description/mod.rs | 8 +- rust/src/nasl/builtin/error.rs | 11 +- rust/src/nasl/builtin/host/mod.rs | 17 +- rust/src/nasl/builtin/http/mod.rs | 49 ++---- rust/src/nasl/builtin/isotime/mod.rs | 4 +- rust/src/nasl/builtin/knowledge_base/mod.rs | 14 +- rust/src/nasl/builtin/network/mod.rs | 2 +- rust/src/nasl/builtin/network/network.rs | 8 +- rust/src/nasl/builtin/network/socket.rs | 14 +- rust/src/nasl/builtin/raw_ip/frame_forgery.rs | 57 +++---- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 161 +++++++----------- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 8 +- .../builtin/raw_ip/tests/packet_forgery.rs | 12 +- rust/src/nasl/builtin/regex/mod.rs | 8 +- rust/src/nasl/builtin/report_functions/mod.rs | 16 +- rust/src/nasl/builtin/ssh/mod.rs | 4 +- rust/src/nasl/builtin/ssh/utils.rs | 8 +- rust/src/nasl/builtin/string/mod.rs | 10 +- rust/src/nasl/interpreter/call.rs | 4 +- rust/src/nasl/interpreter/error.rs | 20 +-- rust/src/nasl/interpreter/mod.rs | 2 +- rust/src/nasl/mod.rs | 3 +- rust/src/nasl/test_utils.rs | 14 +- rust/src/nasl/utils/error.rs | 64 ++++--- .../nasl/utils/function/from_nasl_value.rs | 22 +-- rust/src/nasl/utils/function/maybe.rs | 4 +- rust/src/nasl/utils/function/positionals.rs | 10 +- .../src/nasl/utils/function/to_nasl_result.rs | 12 +- rust/src/nasl/utils/function/types.rs | 2 +- rust/src/nasl/utils/function/utils.rs | 16 +- rust/src/nasl/utils/mod.rs | 4 +- rust/src/scannerctl/interpret/mod.rs | 7 +- 42 files changed, 310 insertions(+), 455 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs index 610dc08fe..17b71ce49 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cbc.rs @@ -17,7 +17,7 @@ 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(register: &Register, crypt: Crypt) -> Result +fn cbc(register: &Register, crypt: Crypt) -> Result where D: BlockCipher + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -71,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 { +fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -83,7 +83,7 @@ fn aes128_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -94,7 +94,7 @@ fn aes128_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -106,7 +106,7 @@ fn aes192_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } @@ -117,7 +117,7 @@ fn aes192_cbc_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -129,7 +129,7 @@ fn aes256_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs index 9785ba1ed..b52e6d0f5 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ccm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ccm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::FnError; use aes::cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser}; use aes::{Aes128, Aes192, Aes256}; use ccm::{ @@ -41,7 +41,7 @@ where } /// Base function for ccm en- and decryption. Sets the tag length to 16. -fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn ccm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -71,7 +71,7 @@ where /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -82,10 +82,7 @@ fn aes128_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -96,7 +93,7 @@ fn aes128_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -107,10 +104,7 @@ fn aes128_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -121,7 +115,7 @@ fn aes128_ccm_decrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -132,10 +126,7 @@ fn aes192_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -146,7 +137,7 @@ fn aes192_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -157,10 +148,7 @@ fn aes192_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } @@ -171,7 +159,7 @@ fn aes192_ccm_decrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result { +fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, false) } @@ -182,10 +170,7 @@ fn aes256_ccm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_encrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Encrypt, true) } @@ -196,7 +181,7 @@ fn aes256_ccm_encrypt_auth( /// - The length of the key should be 16 bytes long /// - The iv must have a length of 7-13 bytes /// - The tag_size default is 16, it can be set to either 4, 6, 8, 10, 12, 14 or 16 -fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result { +fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, false) } @@ -207,16 +192,13 @@ fn aes256_ccm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ccm_decrypt_auth(register: &Register, _: &Context) -> Result { ccm::(register, Crypt::Decrypt, true) } macro_rules! ccm_call_typed { ($(($t1s: expr, $t1: ty) => $(($t2s: expr, $t2: ty)),*);*) => { - fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, FunctionErrorKind> + fn ccm_typed(tag_size: usize, iv_size: usize, crypt: Crypt, key: &[u8], nonce: &[u8], data: &[u8], aad: &[u8]) -> Result, aError>, FnError> where D: BlockCipher + BlockSizeUser + BlockEncrypt + BlockDecrypt + KeyInit { match tag_size { @@ -228,11 +210,11 @@ macro_rules! ccm_call_typed { Ok(ccm_crypt::(crypt, key, nonce, data, aad)) } ),* - other => Err(FunctionErrorKind::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) + other => Err(FnError::wrong_unnamed_argument("iv must be between 7 and 13", other.to_string().as_str())) } } ),* - other => Err(FunctionErrorKind::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) + other => Err(FnError::wrong_unnamed_argument("tag_size must be 4, 6, 8, 10, 12, 14 or 16", other.to_string().as_str())) } } } diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 9e01cd544..7acab3e91 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::{Context, FunctionErrorKind, Register}; +use crate::nasl::utils::{Context, FnError, Register}; use aes::Aes128; use cmac::{Cmac, Mac}; @@ -16,7 +16,7 @@ use super::{get_data, get_key, CryptographicError}; /// This function expects 2 named arguments key and data either in a string or data type. /// It is important to notice, that internally the CMAC algorithm is used and not, as the name /// suggests, CBC-MAC. -fn aes_cmac(register: &Register, _: &Context) -> Result { +fn aes_cmac(register: &Register, _: &Context) -> Result { let key = get_key(register)?; let data = get_data(register)?; diff --git a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs index 7d46c7495..7e6d9ec08 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_ctr.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_ctr.rs @@ -15,7 +15,7 @@ use crate::nasl::prelude::*; use super::{get_data, get_iv, get_key, get_len, Crypt}; -fn ctr(register: &Register, crypt: Crypt) -> Result +fn ctr(register: &Register, crypt: Crypt) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -56,7 +56,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. It is used as the initial counter. -fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -68,7 +68,7 @@ fn aes128_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -79,7 +79,7 @@ fn aes128_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -91,7 +91,7 @@ fn aes192_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } @@ -102,7 +102,7 @@ fn aes192_ctr_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Encrypt) } @@ -114,7 +114,7 @@ fn aes256_ctr_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_ctr_decrypt(register: &Register, _: &Context) -> Result { ctr::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs index 9d8fbf436..55bab0129 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gcm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// FunctionErrorKind::GeneralError +// FnError::GeneralError use crate::nasl::prelude::*; use aes::{ cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit}, @@ -16,7 +16,7 @@ use digest::typenum::{U12, U16}; use super::{get_aad, get_data, get_iv, get_key, get_len, Crypt, CryptographicError}; -fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result +fn gcm(register: &Register, crypt: Crypt, auth: bool) -> Result where D: BlockSizeUser + aes::cipher::KeyInit @@ -76,7 +76,7 @@ where /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -89,10 +89,7 @@ fn aes128_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -105,7 +102,7 @@ fn aes128_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -118,10 +115,7 @@ fn aes128_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes128_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -134,7 +128,7 @@ fn aes128_gcm_decrypt_auth( /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -147,10 +141,7 @@ fn aes192_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -163,7 +154,7 @@ fn aes192_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -176,10 +167,7 @@ fn aes192_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes192_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } @@ -192,7 +180,7 @@ fn aes192_gcm_decrypt_auth( /// - The iv must have a length of 16 bytes. It is used as the initial counter. /// - The result contains the ciphertext and the calculated tag in a single data type. /// - The tag has a size of 16 Bytes. -fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result { +fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, false) } @@ -205,10 +193,7 @@ fn aes256_gcm_encrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_encrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Encrypt, true) } @@ -221,7 +206,7 @@ fn aes256_gcm_encrypt_auth( /// 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. It is used as the initial counter. /// - The tag is needed as a postfix in the given data in order to decrypt successfully. -fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result { +fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, false) } @@ -234,10 +219,7 @@ fn aes256_gcm_decrypt(register: &Register, _: &Context) -> Result Result { +fn aes256_gcm_decrypt_auth(register: &Register, _: &Context) -> Result { gcm::(register, Crypt::Decrypt, true) } diff --git a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs index 03147c1f8..195738c9e 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_gmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_gmac.rs @@ -10,7 +10,7 @@ use crate::nasl::prelude::*; /// /// This function expects 3 named arguments key, data and iv either in a string or data type. #[cfg(feature = "nasl-c-lib")] -fn aes_gmac(register: &Register, _: &Context) -> Result { +fn aes_gmac(register: &Register, _: &Context) -> Result { use super::{get_data, get_iv, get_key, CryptographicError}; use nasl_c_lib::cryptographic::mac::aes_gmac; diff --git a/rust/src/nasl/builtin/cryptographic/des.rs b/rust/src/nasl/builtin/cryptographic/des.rs index 7e1f26020..ddd8b2c37 100644 --- a/rust/src/nasl/builtin/cryptographic/des.rs +++ b/rust/src/nasl/builtin/cryptographic/des.rs @@ -7,7 +7,7 @@ use aes::cipher::BlockEncrypt; use ccm::KeyInit; use des::cipher::generic_array::GenericArray; -fn encrypt_des(register: &Register, _: &Context) -> Result { +fn encrypt_des(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.len() != 2 { return Err(ArgumentError::MissingPositionals { diff --git a/rust/src/nasl/builtin/cryptographic/hash.rs b/rust/src/nasl/builtin/cryptographic/hash.rs index 5be8a996a..be4ef0aa5 100644 --- a/rust/src/nasl/builtin/cryptographic/hash.rs +++ b/rust/src/nasl/builtin/cryptographic/hash.rs @@ -13,7 +13,7 @@ use sha2::{Sha256, Sha512}; use crate::nasl::prelude::*; use crate::nasl::utils::function::StringOrData; -fn nasl_hash(data: Option) -> Result +fn nasl_hash(data: Option) -> Result where D::OutputSize: std::ops::Add, ::Output: digest::generic_array::ArrayLength, @@ -29,43 +29,43 @@ where /// NASL function to get MD2 hash #[nasl_function] -pub fn hash_md2(data: Option) -> Result { +pub fn hash_md2(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get MD4 hash #[nasl_function] -pub fn hash_md4(data: Option) -> Result { +pub fn hash_md4(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get MD5 hash #[nasl_function] -pub fn hash_md5(data: Option) -> Result { +pub fn hash_md5(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get SHA1 hash #[nasl_function] -pub fn hash_sha1(data: Option) -> Result { +pub fn hash_sha1(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get SHA256 hash #[nasl_function] -pub fn hash_sha256(data: Option) -> Result { +pub fn hash_sha256(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get SHA512 hash #[nasl_function] -pub fn hash_sha512(data: Option) -> Result { +pub fn hash_sha512(data: Option) -> Result { nasl_hash::(data) } /// NASL function to get RIPemd160 hash #[nasl_function] -pub fn hash_ripemd160(data: Option) -> Result { +pub fn hash_ripemd160(data: Option) -> Result { nasl_hash::(data) } diff --git a/rust/src/nasl/builtin/cryptographic/hmac.rs b/rust/src/nasl/builtin/cryptographic/hmac.rs index aefbc05ec..556cc5899 100644 --- a/rust/src/nasl/builtin/cryptographic/hmac.rs +++ b/rust/src/nasl/builtin/cryptographic/hmac.rs @@ -19,7 +19,7 @@ use sha2::{Sha256, Sha384, Sha512}; use crate::nasl::prelude::*; -fn hmac(key: &str, data: &str) -> Result +fn hmac(key: &str, data: &str) -> Result where D: CoreProxy, D::Core: HashMarker @@ -34,7 +34,7 @@ where let mut hmac = match Hmac::::new_from_slice(key.as_bytes()) { Ok(x) => x, Err(InvalidLength) => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "valid size key", "invalid size key", )) @@ -48,43 +48,43 @@ where /// NASL function to get HMAC MD2 string #[nasl_function(named(key, data))] -pub fn hmac_md2(key: &str, data: &str) -> Result { +pub fn hmac_md2(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC MD5 string #[nasl_function(named(key, data))] -pub fn hmac_md5(key: &str, data: &str) -> Result { +pub fn hmac_md5(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC RIPEMD160 string #[nasl_function(named(key, data))] -pub fn hmac_ripemd160(key: &str, data: &str) -> Result { +pub fn hmac_ripemd160(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC SHA1 string #[nasl_function(named(key, data))] -pub fn hmac_sha1(key: &str, data: &str) -> Result { +pub fn hmac_sha1(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC SHA256 string #[nasl_function(named(key, data))] -pub fn hmac_sha256(key: &str, data: &str) -> Result { +pub fn hmac_sha256(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC SHA384 string #[nasl_function(named(key, data))] -pub fn hmac_sha384(key: &str, data: &str) -> Result { +pub fn hmac_sha384(key: &str, data: &str) -> Result { hmac::(key, data) } /// NASL function to get HMAC SHA512 string #[nasl_function(named(key, data))] -pub fn hmac_sha512(key: &str, data: &str) -> Result { +pub fn hmac_sha512(key: &str, data: &str) -> Result { hmac::(key, data) } diff --git a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs index 28b663ef8..5363ce454 100644 --- a/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs +++ b/rust/src/nasl/builtin/cryptographic/tests/aes_gcm.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -// FunctionErrorKind::GeneralError +// FnError::GeneralError use super::helper::decode_hex; use crate::nasl::test_prelude::*; diff --git a/rust/src/nasl/builtin/description/mod.rs b/rust/src/nasl/builtin/description/mod.rs index 66f80cac3..8aae68866 100644 --- a/rust/src/nasl/builtin/description/mod.rs +++ b/rust/src/nasl/builtin/description/mod.rs @@ -25,7 +25,7 @@ use crate::nasl::utils::get_named_parameter; ///} /// ```` /// The first parameter is the name of the function as well as the &str lookup key. -/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. +/// Afterwards a method that transform `&[&NaslValue]` to `Result` must be defined. /// /// Parameter are separated from the definition by a `=>`. /// @@ -59,7 +59,7 @@ macro_rules! make_storage_function { pub fn $name( registrat: &Register, ctxconfigs: &Context, - ) -> Result { + ) -> Result { let mut variables = vec![]; $( let positional = registrat.positional(); @@ -106,7 +106,7 @@ macro_rules! make_storage_function { }; } -type Transform = Result, FunctionErrorKind>; +type Transform = Result, FnError>; fn as_timeout_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { Ok(vec![NVTField::Preference(NvtPreference { @@ -120,7 +120,7 @@ fn as_timeout_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { fn as_category_field(_: &ContextKey, arguments: &[&NaslValue]) -> Transform { match arguments[0] { NaslValue::AttackCategory(cat) => Ok(vec![NVTField::Category(*cat)]), - a => Err(FunctionErrorKind::wrong_unnamed_argument( + a => Err(FnError::wrong_unnamed_argument( "AttackCategory", &a.to_string(), )), diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 3a607b353..d0250c645 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -1,6 +1,7 @@ use thiserror::Error; use crate::nasl::prelude::*; +use crate::nasl::utils::error::FnErrorKind; use super::cryptographic::CryptographicError; use super::http::HttpError; @@ -45,18 +46,18 @@ macro_rules! builtin_error_variant ( } } - impl From<$err> for FunctionErrorKind { + impl From<$err> for FnError { fn from(value: $err) -> Self { - FEK::Builtin(BuiltinError::$variant(value).into()).into() + FnErrorKind::Builtin(BuiltinError::$variant(value).into()).into() } } - impl TryFrom for $err { + impl TryFrom for $err { type Error = (); - fn try_from(value: FunctionErrorKind) -> Result { + fn try_from(value: FnError) -> Result { match value.kind { - FEK::Builtin( + FnErrorKind::Builtin( BuiltinError::$variant(e) ) => Ok(e), _ => Err(()), diff --git a/rust/src/nasl/builtin/host/mod.rs b/rust/src/nasl/builtin/host/mod.rs index 8a941ea79..92b4f4559 100644 --- a/rust/src/nasl/builtin/host/mod.rs +++ b/rust/src/nasl/builtin/host/mod.rs @@ -8,7 +8,7 @@ mod tests; use std::{net::IpAddr, str::FromStr}; use crate::function_set; -use crate::nasl::utils::{error::FunctionErrorKind, lookup_keys::TARGET}; +use crate::nasl::utils::{error::FnError, lookup_keys::TARGET}; use crate::nasl::syntax::NaslValue; use crate::nasl::utils::{Context, ContextType, Register}; @@ -17,7 +17,7 @@ use crate::nasl::utils::{Context, ContextType, Register}; /// /// It does lookup TARGET and when not found falls back to 127.0.0.1 to resolve. /// If the TARGET is not a IP address than we assume that it already is a fqdn or a hostname and will return that instead. -fn resolve_hostname(register: &Register) -> Result { +fn resolve_hostname(register: &Register) -> Result { use std::net::ToSocketAddrs; let default_ip = "127.0.0.1"; @@ -41,7 +41,7 @@ fn resolve_hostname(register: &Register) -> Result { /// /// As of now (2023-01-20) there is no vhost handling. /// Therefore this function does load the registered TARGET and if it is an IP Address resolves it via DNS instead. -fn get_host_names(register: &Register, _: &Context) -> Result { +fn get_host_names(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(|x| NaslValue::Array(vec![NaslValue::String(x)])) } @@ -49,12 +49,12 @@ fn get_host_names(register: &Register, _: &Context) -> Result Result { +fn get_host_name(register: &Register, _: &Context) -> Result { resolve_hostname(register).map(NaslValue::String) } /// Return the target's IP address as IpAddr. -pub fn get_host_ip(context: &Context) -> Result { +pub fn get_host_ip(context: &Context) -> Result { let default_ip = "127.0.0.1"; let r_sock_addr = match context.target() { x if !x.is_empty() => IpAddr::from_str(x), @@ -63,7 +63,7 @@ pub fn get_host_ip(context: &Context) -> Result { match r_sock_addr { Ok(x) => Ok(x), - Err(e) => Err(FunctionErrorKind::wrong_unnamed_argument( + Err(e) => Err(FnError::wrong_unnamed_argument( "IP address", e.to_string().as_str(), )), @@ -71,10 +71,7 @@ pub fn get_host_ip(context: &Context) -> Result { } /// Return the target's IP address or 127.0.0.1 if not set. -fn nasl_get_host_ip( - _register: &Register, - context: &Context, -) -> Result { +fn nasl_get_host_ip(_register: &Register, context: &Context) -> Result { let ip = get_host_ip(context)?; Ok(NaslValue::String(ip.to_string())) } diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index 1348938fd..856e95537 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -38,9 +38,9 @@ pub struct NaslHttp { async fn lock_handles( handles: &Arc>>, -) -> Result>, FunctionErrorKind> { +) -> Result>, FnError> { // we actually need to panic as a lock error is fatal - // alternatively we need to add a poison error on FunctionErrorKind + // alternatively we need to add a poison error on FnError Ok(Arc::as_ref(handles).lock().await) } @@ -204,7 +204,7 @@ impl NaslHttp { register: &Register, ctx: &Context<'a>, method: Method, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, _ => return Err(ArgumentError::WrongArgument("Invalid handle ID".to_string()).into()), @@ -220,7 +220,7 @@ impl NaslHttp { let item: String = register .named("item") .map(|x| x.to_string()) - .ok_or(FunctionErrorKind::missing_argument("item"))?; + .ok_or(FnError::missing_argument("item"))?; let schema: String = match register.named("schema") { Some(x) => { @@ -277,38 +277,22 @@ impl NaslHttp { } /// Wrapper function for GET request. See http2_req - async fn get<'a>( - &self, - register: &Register, - ctx: &Context<'a>, - ) -> Result { + async fn get<'a>(&self, register: &Register, ctx: &Context<'a>) -> Result { self.http2_req(register, ctx, Method::GET).await } /// Wrapper function for POST request. See http2_req - async fn post<'a>( - &self, - register: &Register, - ctx: &Context<'a>, - ) -> Result { + async fn post<'a>(&self, register: &Register, ctx: &Context<'a>) -> Result { self.http2_req(register, ctx, Method::POST).await } /// Wrapper function for PUT request. See http2_req - async fn put<'a>( - &self, - register: &Register, - ctx: &Context<'a>, - ) -> Result { + async fn put<'a>(&self, register: &Register, ctx: &Context<'a>) -> Result { self.http2_req(register, ctx, Method::PUT).await } /// Wrapper function for HEAD request. See http2_req - async fn head<'a>( - &self, - register: &Register, - ctx: &Context<'a>, - ) -> Result { + async fn head<'a>(&self, register: &Register, ctx: &Context<'a>) -> Result { self.http2_req(register, ctx, Method::HEAD).await } @@ -317,7 +301,7 @@ impl NaslHttp { &self, register: &Register, ctx: &Context<'a>, - ) -> Result { + ) -> Result { self.http2_req(register, ctx, Method::DELETE).await } @@ -328,7 +312,7 @@ impl NaslHttp { /// On success the function returns a and integer with the handle /// identifier. Null on error. #[nasl_function] - async fn handle(&self) -> Result { + async fn handle(&self) -> Result { let mut handles = lock_handles(&self.handles).await?; let handle_id = next_handle_id(&handles); let h = Handle { @@ -348,7 +332,7 @@ impl NaslHttp { /// The function returns an integer. /// O on success, -1 on error. #[nasl_function(named(handle))] - async fn close_handle(&self, handle: i32) -> Result { + async fn close_handle(&self, handle: i32) -> Result { let mut handles = lock_handles(&self.handles).await?; match handles .iter_mut() @@ -359,10 +343,7 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => { - Err(FunctionErrorKind::from(HttpError::HandleIdNotFound(handle)) - .with(ReturnValue(-1))) - } + _ => Err(FnError::from(HttpError::HandleIdNotFound(handle)).with(ReturnValue(-1))), } } @@ -376,7 +357,7 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let handle_id = match register.named("handle") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, _ => { @@ -405,10 +386,10 @@ impl NaslHttp { &self, register: &Register, _: &Context<'_>, - ) -> Result { + ) -> Result { let header_item = match register.named("header_item") { Some(ContextType::Value(NaslValue::String(x))) => x, - _ => return Err(FunctionErrorKind::missing_argument("No command passed")), + _ => return Err(FnError::missing_argument("No command passed")), }; let (key, val) = header_item.split_once(": ").expect("Missing header_item"); diff --git a/rust/src/nasl/builtin/isotime/mod.rs b/rust/src/nasl/builtin/isotime/mod.rs index 4b830423f..9cf644e2b 100644 --- a/rust/src/nasl/builtin/isotime/mod.rs +++ b/rust/src/nasl/builtin/isotime/mod.rs @@ -105,12 +105,12 @@ fn isotime_now() -> String { } #[nasl_function] -fn isotime_print(time: &str) -> Result { +fn isotime_print(time: &str) -> Result { Ok(parse_time(time)?.format("%Y-%m-%d %H:%M:%S").to_string()) } #[nasl_function] -fn isotime_scan(time: &str) -> Result { +fn isotime_scan(time: &str) -> Result { let time = parse_time(time)?; Ok(time.format("%Y%m%dT%H%M%S").to_string()) diff --git a/rust/src/nasl/builtin/knowledge_base/mod.rs b/rust/src/nasl/builtin/knowledge_base/mod.rs index a9ec656df..56c502ba9 100644 --- a/rust/src/nasl/builtin/knowledge_base/mod.rs +++ b/rust/src/nasl/builtin/knowledge_base/mod.rs @@ -9,7 +9,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::function_set; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::FunctionErrorKind; +use crate::nasl::utils::error::FnError; use crate::nasl::utils::Context; use crate::storage::{Field, Kb, Retrieve}; use nasl_function_proc_macro::nasl_function; @@ -27,7 +27,7 @@ fn set_kb_item( name: NaslValue, value: NaslValue, expires: Option, -) -> Result { +) -> Result { let expires = match expires { Some(NaslValue::Number(x)) => Some(x), Some(NaslValue::Exit(0)) => None, @@ -58,7 +58,7 @@ fn set_kb_item( /// NASL function to get a knowledge base #[nasl_function] -fn get_kb_item(c: &Context, key: &str) -> Result { +fn get_kb_item(c: &Context, key: &str) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { @@ -75,11 +75,7 @@ fn get_kb_item(c: &Context, key: &str) -> Result { /// NASL function to replace a kb list #[nasl_function(named(name, value))] -fn replace_kb_item( - c: &Context, - name: NaslValue, - value: NaslValue, -) -> Result { +fn replace_kb_item(c: &Context, name: NaslValue, value: NaslValue) -> Result { c.dispatcher() .dispatch_replace( c.key(), @@ -95,7 +91,7 @@ fn replace_kb_item( /// NASL function to retrieve an item in a KB. #[nasl_function] -fn get_kb_list(c: &Context, key: NaslValue) -> Result { +fn get_kb_list(c: &Context, key: NaslValue) -> Result { c.retriever() .retrieve(c.key(), Retrieve::KB(key.to_string())) .map(|r| { diff --git a/rust/src/nasl/builtin/network/mod.rs b/rust/src/nasl/builtin/network/mod.rs index 3a09e6e42..306290b7f 100644 --- a/rust/src/nasl/builtin/network/mod.rs +++ b/rust/src/nasl/builtin/network/mod.rs @@ -74,7 +74,7 @@ impl Display for OpenvasEncaps { } } -pub fn get_kb_item(context: &Context, name: &str) -> Result, FunctionErrorKind> { +pub fn get_kb_item(context: &Context, name: &str) -> Result, FnError> { context .retriever() .retrieve(context.key(), Retrieve::KB(name.to_string())) diff --git a/rust/src/nasl/builtin/network/network.rs b/rust/src/nasl/builtin/network/network.rs index 33f3915bf..9072967d0 100644 --- a/rust/src/nasl/builtin/network/network.rs +++ b/rust/src/nasl/builtin/network/network.rs @@ -11,7 +11,7 @@ use super::{ verify_port, DEFAULT_PORT, }; use crate::function_set; -use crate::nasl::utils::{Context, FunctionErrorKind}; +use crate::nasl::utils::{Context, FnError}; use crate::storage::{types::Primitive, Field, Kb}; use nasl_function_proc_macro::nasl_function; @@ -132,11 +132,7 @@ fn islocalnet(context: &Context) -> Result { /// Declares an open port on the target host #[nasl_function(named(port, proto))] -fn scanner_add_port( - context: &Context, - port: i64, - proto: Option<&str>, -) -> Result<(), FunctionErrorKind> { +fn scanner_add_port(context: &Context, port: i64, proto: Option<&str>) -> Result<(), FnError> { let port = verify_port(port)?; let protocol = proto.unwrap_or("tcp"); diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index cf81a770c..b02222c0d 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -297,7 +297,7 @@ impl NaslSockets { data: &[u8], flags: Option, len: Option, - ) -> Result { + ) -> Result { let len = if let Some(len) = len { if len < 1 || len > data.len() { data.len() @@ -381,7 +381,7 @@ impl NaslSockets { len: usize, min: Option, timeout: Option, - ) -> Result { + ) -> Result { let min = min .map(|min| if min < 0 { len } else { min as usize }) .unwrap_or(len); @@ -473,7 +473,7 @@ impl NaslSockets { /// - Secret/kdc_port /// - Secret/kdc_use_tcp #[nasl_function] - fn open_sock_kdc(&self, context: &Context) -> Result { + fn open_sock_kdc(&self, context: &Context) -> Result { let hostname = match get_kb_item(context, "Secret/kdc_hostname")? { Some(x) => Ok(x.to_string()), None => Err(SocketError::Diagnostic( @@ -556,7 +556,7 @@ impl NaslSockets { bufsz: Option, // TODO: Extract information from custom priority string // priority: Option<&str>, - ) -> Result { + ) -> Result { // Get port let port = verify_port(port)?; let transport = transport.unwrap_or(-1); @@ -657,7 +657,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, tls_config: Option, - ) -> Result { + ) -> Result { let addr = ipstr2ipaddr(addr)?; let mut retry = super::get_kb_item(context, "timeout_retry")? .map(|val| match val { @@ -717,7 +717,7 @@ impl NaslSockets { bufsz: Option, timeout: Duration, hostname: &str, - ) -> Result { + ) -> Result { let cert_path = get_kb_item(context, "SSL/cert")? .ok_or(SocketError::Diagnostic( "unable to open TLS connection: kes 'SSL/cert' is missing".to_string(), @@ -796,7 +796,7 @@ impl NaslSockets { /// Open a UDP socket to the target host #[nasl_function] - fn open_sock_udp(&self, context: &Context, port: i64) -> Result { + fn open_sock_udp(&self, context: &Context, port: i64) -> Result { let port = verify_port(port)?; let addr = ipstr2ipaddr(context.target())?; diff --git a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs index 0f27aff94..e45c73eb7 100644 --- a/rust/src/nasl/builtin/raw_ip/frame_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/frame_forgery.rs @@ -106,11 +106,11 @@ impl From<&Frame> for Vec { } impl TryFrom<&[u8]> for Frame { - type Error = FunctionErrorKind; + type Error = FnError; fn try_from(f: &[u8]) -> Result { if f.len() < 14 { - Err(FunctionErrorKind::missing_argument("valid ip address")) + Err(FnError::missing_argument("valid ip address")) } else { let mut frame = Frame::new(); frame.set_dsthaddr(MacAddr(f[0], f[1], f[2], f[3], f[4], f[5])); @@ -273,19 +273,17 @@ fn convert_vec_into_mac_address(v: &[u8]) -> Option { } } -fn validate_mac_address(v: Option<&ContextType>) -> Result { +fn validate_mac_address(v: Option<&ContextType>) -> Result { let mac_addr = match v { Some(ContextType::Value(NaslValue::String(x))) => MacAddr::from_str(x).ok(), Some(ContextType::Value(NaslValue::Data(x))) => convert_vec_into_mac_address(x), _ => None, }; - mac_addr.ok_or_else(|| { - FunctionErrorKind::wrong_unnamed_argument("mac address", "invalid mac address") - }) + mac_addr.ok_or_else(|| FnError::wrong_unnamed_argument("mac address", "invalid mac address")) } /// Return the MAC address, given the interface name -fn get_local_mac_address(name: &str) -> Result { +fn get_local_mac_address(name: &str) -> Result { interfaces() .into_iter() .find(|x| x.name == *name) @@ -295,7 +293,7 @@ fn get_local_mac_address(name: &str) -> Result { /// Return a frame given a capture device and a filter. It returns an empty frame in case /// there was no response or anything was filtered. -fn recv_frame(cap: &mut Capture, filter: &str) -> Result { +fn recv_frame(cap: &mut Capture, filter: &str) -> Result { let f = Frame::new(); let p = match cap.filter(filter, true) { @@ -315,7 +313,7 @@ fn send_frame( pcap_active: &bool, filter: Option<&String>, timeout: i32, -) -> Result, FunctionErrorKind> { +) -> Result, FnError> { let mut capture_dev = match Capture::from_device(iface.clone()) { Ok(c) => match c.promisc(true).timeout(timeout).open() { Ok(mut capture) => match capture.sendpacket(frame) { @@ -348,15 +346,12 @@ fn send_frame( /// /// It takes the following argument: /// - cap_timeout: time to wait for answer in seconds, 5 by default -fn nasl_send_arp_request( - register: &Register, - context: &Context, -) -> Result { +fn nasl_send_arp_request(register: &Register, context: &Context) -> Result { let timeout = match register.named("pcap_timeout") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -366,7 +361,7 @@ fn nasl_send_arp_request( let target_ip = get_host_ip(context)?; if target_ip.is_ipv6() { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "IPv4", "IPv6 does not support ARP protocol.", )); @@ -378,7 +373,7 @@ fn nasl_send_arp_request( let src_ip = match Ipv4Addr::from_str(&local_ip.to_string()) { Ok(x) => x, Err(_) => { - return Err(FunctionErrorKind::missing_argument( + return Err(FnError::missing_argument( "Not possible to parse the src IP address.", )) } @@ -387,7 +382,7 @@ fn nasl_send_arp_request( let dst_ip = match Ipv4Addr::from_str(&target_ip.to_string()) { Ok(x) => x, Err(_) => { - return Err(FunctionErrorKind::missing_argument( + return Err(FnError::missing_argument( "Not possible to parse the dst IP address.", )) } @@ -407,7 +402,7 @@ fn nasl_send_arp_request( fn nasl_get_local_mac_address_from_ip( register: &Register, _: &Context, -) -> Result { +) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(ArgumentError::MissingPositionals { @@ -436,7 +431,7 @@ fn nasl_get_local_mac_address_from_ip( /// - ether_proto: is an int containing the ethernet type (normally given as hexadecimal). /// It is optional and its default value is 0x0800. A list of Types can be e.g. looked up here. /// - payload: is any data, which is then attached as payload to the frame. -fn nasl_forge_frame(register: &Register, _: &Context) -> Result { +fn nasl_forge_frame(register: &Register, _: &Context) -> Result { let src_haddr = validate_mac_address(register.named("src_haddr"))?; let dst_haddr = validate_mac_address(register.named("dst_haddr"))?; let ether_proto = match register.named("ether_proto") { @@ -464,22 +459,17 @@ fn nasl_forge_frame(register: &Register, _: &Context) -> Result Result { +fn nasl_send_frame(register: &Register, context: &Context) -> Result { let frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => x, - _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( - "Data", - "Invalid data type", - )) - } + _ => return Err(FnError::wrong_unnamed_argument("Data", "Invalid data type")), }; let pcap_active = match register.named("pcap_active") { Some(ContextType::Value(NaslValue::Boolean(x))) => x, None => &true, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -490,7 +480,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Some(x), None => None, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -501,7 +491,7 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -523,15 +513,10 @@ fn nasl_send_frame(register: &Register, context: &Context) -> Result Result { +fn nasl_dump_frame(register: &Register, _: &Context) -> Result { let frame: Frame = match register.named("frame") { Some(ContextType::Value(NaslValue::Data(x))) => (x as &[u8]).try_into()?, - _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( - "Data", - "Invalid data type", - )) - } + _ => return Err(FnError::wrong_unnamed_argument("Data", "Invalid data type")), }; info!(frame=%frame); diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 496a28527..15f39ae2e 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -48,7 +48,7 @@ pub enum PacketForgeryError { SendPacket(std::io::ErrorKind), } -fn error(s: String) -> FunctionErrorKind { +fn error(s: String) -> FnError { PacketForgeryError::Custom(s).into() } @@ -103,7 +103,7 @@ fn safe_copy_from_slice( o_buf: &[u8], o_init: usize, o_fin: usize, -) -> Result<(), FunctionErrorKind> { +) -> Result<(), FnError> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -136,7 +136,7 @@ fn safe_copy_from_slice( /// - ip_v is: the IP version. 4 by default. /// /// Returns the IP datagram or NULL on error. -fn forge_ip_packet(register: &Register, configs: &Context) -> Result { +fn forge_ip_packet(register: &Register, configs: &Context) -> Result { let dst_addr = get_host_ip(configs)?; if dst_addr.is_ipv6() { @@ -275,14 +275,11 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result { +fn set_ip_elements(register: &Register, _configs: &Context) -> Result { let mut buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(FnError::missing_argument("ip")); } }; @@ -367,11 +364,11 @@ fn set_ip_elements( /// - ip_sum /// - ip_src /// - ip_dst -fn get_ip_element(register: &Register, _configs: &Context) -> Result { +fn get_ip_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(FnError::missing_argument("ip")); } }; @@ -393,12 +390,12 @@ fn get_ip_element(register: &Register, _configs: &Context) -> Result Ok(NaslValue::String(pkt.get_destination().to_string())), _ => Err(ArgumentError::WrongArgument("Invalid element".to_string()).into()), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(FnError::missing_argument("element")), } } /// Receive a list of IP packets and print them in a readable format in the screen. -fn dump_ip_packet(register: &Register, _: &Context) -> Result { +fn dump_ip_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(ArgumentError::MissingPositionals { @@ -453,34 +450,31 @@ fn dump_protocol(pkt: &Ipv4Packet) -> String { /// - code: is the identifier of the option to add /// - length: is the length of the option data /// - value: is the option data -fn insert_ip_options( - register: &Register, - _configs: &Context, -) -> Result { +fn insert_ip_options(register: &Register, _configs: &Context) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(FnError::missing_argument("ip")); } }; let code = match register.named("code") { Some(ContextType::Value(NaslValue::Number(x))) => *x, _ => { - return Err(FunctionErrorKind::missing_argument("code")); + return Err(FnError::missing_argument("code")); } }; let length = match register.named("length") { Some(ContextType::Value(NaslValue::Number(x))) => *x as usize, _ => { - return Err(FunctionErrorKind::missing_argument("length")); + return Err(FnError::missing_argument("length")); } }; let value = match register.named("value") { Some(ContextType::Value(NaslValue::String(x))) => x.as_bytes(), Some(ContextType::Value(NaslValue::Data(x))) => x, _ => { - return Err(FunctionErrorKind::missing_argument("value")); + return Err(FnError::missing_argument("value")); } }; @@ -549,15 +543,12 @@ fn insert_ip_options( /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. /// /// The modified IP datagram or NULL on error. -fn forge_tcp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_tcp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { // Missingarguments - return Err(FunctionErrorKind::missing_argument("ip")); + return Err(FnError::missing_argument("ip")); } }; let original_ip_len = ip_buf.len(); @@ -667,14 +658,11 @@ fn forge_tcp_packet( /// - data /// /// Returns an TCP element from a IP datagram. -fn get_tcp_element( - register: &Register, - _configs: &Context, -) -> Result { +fn get_tcp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(FnError::missing_argument("tcp")); } }; @@ -698,7 +686,7 @@ fn get_tcp_element( "th_data" => Ok(NaslValue::Data(tcp.payload().to_vec())), _ => Err(ArgumentError::WrongArgument("element".to_string()).into()), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(FnError::missing_argument("element")), } } @@ -713,11 +701,11 @@ fn get_tcp_element( /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. /// /// The returned option depends on the given *option* parameter. It is either an int for option 2, 3 and 4 or an array containing the two values for option 8. -fn get_tcp_option(register: &Register, _configs: &Context) -> Result { +fn get_tcp_option(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(FnError::missing_argument("tcp")); } }; @@ -768,7 +756,7 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Ok(NaslValue::Array(timestamps)), _ => Err(ArgumentError::WrongArgument("Invalid option".to_string()).into()), }, - _ => Err(FunctionErrorKind::missing_argument("option")), + _ => Err(FnError::missing_argument("option")), } } @@ -787,14 +775,11 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Result { +fn set_tcp_elements(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("tcp")); + return Err(FnError::missing_argument("tcp")); } }; @@ -926,10 +911,7 @@ fn set_tcp_elements( /// - 3: TCPOPT_WINDOW, with values between 0 and 14 /// - 4: TCPOPT_SACK_PERMITTED, no value required. /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. -fn insert_tcp_options( - register: &Register, - _configs: &Context, -) -> Result { +fn insert_tcp_options(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1108,7 +1090,7 @@ fn insert_tcp_options( } /// Receive a list of IPv4 datagrams and print their TCP part in a readable format in the screen. -fn dump_tcp_packet(register: &Register, _: &Context) -> Result { +fn dump_tcp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -1210,13 +1192,10 @@ fn format_flags(pkt: &TcpPacket) -> String { /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. /// /// Returns the modified IP datagram or NULL on error. -fn forge_udp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_udp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), - _ => return Err(FunctionErrorKind::missing_argument("ip")), + _ => return Err(FnError::missing_argument("ip")), }; let original_ip_len = ip_buf.len(); @@ -1291,14 +1270,11 @@ fn forge_udp_packet( /// - uh_sport: is the source port. NASL will convert it into network order if necessary. 0 by default. /// - uh_sum: is the UDP checksum. Although it is not compulsory, the right value is computed by default. /// - uh_ulen: is the data length. By default it is set to the length the data argument plus the size of the UDP header. -fn set_udp_elements( - register: &Register, - _configs: &Context, -) -> Result { +fn set_udp_elements(register: &Register, _configs: &Context) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("udp")); + return Err(FnError::missing_argument("udp")); } }; @@ -1395,7 +1371,7 @@ fn set_udp_elements( } /// Receive a list of IPv4 datagrams and print their UDP part in a readable format in the screen. -fn dump_udp_packet(register: &Register, _: &Context) -> Result { +fn dump_udp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -1447,14 +1423,11 @@ fn dump_udp_packet(register: &Register, _: &Context) -> Result Result { +fn get_udp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("udp")); + return Err(FnError::missing_argument("udp")); } }; @@ -1485,14 +1458,11 @@ fn get_udp_element( /// - *icmp_seq*: ICMP sequence number. /// - *icmp_type*: ICMP type. 0 by default. /// - *update_ip_len*: If this flag is set, NASL will recompute the size field of the IP datagram. Default: True. -fn forge_icmp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(FnError::missing_argument("icmp")); } }; let original_ip_len = ip_buf.len(); @@ -1579,14 +1549,11 @@ fn forge_icmp_packet( /// - icmp_seq /// - icmp_chsum /// - icmp_data -fn get_icmp_element( - register: &Register, - _configs: &Context, -) -> Result { +fn get_icmp_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("icmp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(FnError::missing_argument("icmp")); } }; @@ -1633,15 +1600,15 @@ fn get_icmp_element( } _ => Ok(NaslValue::Null), }, - _ => Err(FunctionErrorKind::missing_argument("element")), + _ => Err(FnError::missing_argument("element")), } } /// Receive a list of IPv4 ICMP packets and print them in a readable format in the screen. -fn dump_icmp_packet(register: &Register, _: &Context) -> Result { +fn dump_icmp_packet(register: &Register, _: &Context) -> Result { let positional = register.positional(); if positional.is_empty() { - return Err(FunctionErrorKind::missing_argument("icmp")); + return Err(FnError::missing_argument("icmp")); } for icmp_pkt in positional.iter() { @@ -1764,14 +1731,11 @@ pub mod igmp { /// - group: IGMP group /// - type: IGMP type. 0 by default. /// - update_ip_len: If this flag is set, NASL will recompute the size field of the IP datagram. Default: True. -fn forge_igmp_packet( - register: &Register, - _configs: &Context, -) -> Result { +fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FunctionErrorKind::missing_argument("igmp")); + return Err(FnError::missing_argument("igmp")); } }; let original_ip_len = ip_buf.len(); @@ -1844,7 +1808,7 @@ fn forge_igmp_packet( Ok(NaslValue::Data(ip_buf)) } -fn new_raw_socket() -> Result { +fn new_raw_socket() -> Result { match Socket::new_raw( Domain::IPV4, socket2::Type::RAW, @@ -1859,7 +1823,7 @@ fn new_raw_socket() -> Result { /// /// Its argument is: /// - port: port for the ping -fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { +fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result { let rnd_tcp_port = || -> u16 { (random_impl().unwrap_or(0) % 65535 + 1024) as u16 }; let sports_ori: Vec = vec![ @@ -1893,7 +1857,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result *x, None => 0, //TODO: implement plug_get_host_open_port() _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -1995,15 +1959,12 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_packet(register: &Register, configs: &Context) -> Result { let use_pcap = match register.named("pcap_active") { Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => true, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Boolean", "Invalid pcap_active value", )) @@ -2014,7 +1975,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -2025,7 +1986,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) @@ -2036,7 +1997,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => false, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Boolean", "Invalid allow_broadcast value", )) @@ -2058,7 +2019,7 @@ fn nasl_send_packet( Some(ContextType::Value(NaslValue::Number(x))) => *x, None => 0, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Number", "Invalid length value", )) @@ -2081,12 +2042,7 @@ fn nasl_send_packet( for pkt in positional.iter() { let packet_raw = match pkt { NaslValue::Data(data) => data as &[u8], - _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( - "Data", - "Invalid packet", - )) - } + _ => return Err(FnError::wrong_unnamed_argument("Data", "Invalid packet")), }; let packet = packet::ipv4::Ipv4Packet::new(packet_raw) .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; @@ -2142,7 +2098,7 @@ fn nasl_send_packet( /// - interface: network interface name, by default NASL will try to find the best one /// - pcap_filter: BPF filter, by default it listens to everything /// - timeout: timeout in seconds, 5 by default -fn nasl_pcap_next(register: &Register, configs: &Context) -> Result { +fn nasl_pcap_next(register: &Register, configs: &Context) -> Result { nasl_send_capture(register, configs) } @@ -2151,15 +2107,12 @@ fn nasl_pcap_next(register: &Register, configs: &Context) -> Result Result { +fn nasl_send_capture(register: &Register, configs: &Context) -> Result { let interface = match register.named("interface") { Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "String", "Invalid interface value", )) @@ -2170,7 +2123,7 @@ fn nasl_send_capture( Some(ContextType::Value(NaslValue::String(x))) => x.to_string(), None => String::new(), _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "String", "Invalid pcap_filter value", )) @@ -2181,7 +2134,7 @@ fn nasl_send_capture( Some(ContextType::Value(NaslValue::Number(x))) => *x as i32 * 1000i32, // to milliseconds None => DEFAULT_TIMEOUT, _ => { - return Err(FunctionErrorKind::wrong_unnamed_argument( + return Err(FnError::wrong_unnamed_argument( "Integer", "Invalid timeout value", )) diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index e3396b77a..8e25d9ed2 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -13,10 +13,10 @@ use pcap::{Address, Device}; use super::RawIpError; /// Convert a string in a IpAddr -pub fn ipstr2ipaddr(ip_addr: &str) -> Result { +pub fn ipstr2ipaddr(ip_addr: &str) -> Result { match IpAddr::from_str(ip_addr) { Ok(ip) => Ok(ip), - Err(_) => Err(FunctionErrorKind::from(ArgumentError::WrongArgument( + Err(_) => Err(FnError::from(ArgumentError::WrongArgument( "Invalid IP address".to_string(), )) .with(ReturnValue(NaslValue::Null))), @@ -40,7 +40,7 @@ pub fn islocalhost(addr: IpAddr) -> bool { } /// Get the interface from the local ip -pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { +pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result { // This fake IP is used for matching (and return false) // during the search of the interface in case an interface // doesn't have an associated address. @@ -80,7 +80,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result { } /// Return the source IP address given the destination IP address -pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { +pub fn get_source_ip(dst: IpAddr, port: u16) -> Result { let socket = SocketAddr::new(dst, port); let sd = format!("{}:{}", dst, port); let local_socket = bind_local_socket(&socket)?; diff --git a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs index fb446c261..cf3a20b53 100644 --- a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs @@ -8,7 +8,7 @@ mod tests { use nasl_builtin_raw_ip::RawIp; use nasl_builtin_std::ContextFactory; - use crate::nasl::utils::{error::FunctionErrorKind, Executor}; + use crate::nasl::utils::{error::FnError, Executor}; use crate::nasl::interpreter::test_utils::TestBuilder; use crate::nasl::syntax::NaslValue; @@ -20,7 +20,7 @@ mod tests { o_buf: &[u8], o_init: usize, o_fin: usize, - ) -> Result<(), FunctionErrorKind> { + ) -> Result<(), FnError> { let o_range = o_fin - o_init; let d_range = d_fin - d_init; if d_buf.len() < d_range @@ -29,7 +29,7 @@ mod tests { || d_buf.len() < d_fin || o_buf.len() < o_fin { - return Err(FunctionErrorKind::Diagnostic( + return Err(FnError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null), )); @@ -270,7 +270,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, 2, &b, 0, b.len()), - Err(FunctionErrorKind::Diagnostic( + Err(FnError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -279,7 +279,7 @@ mod tests { // different range size between origin and destination assert_eq!( safe_copy_from_slice(&mut a, 0, alen, &b, 0, 2), - Err(FunctionErrorKind::Diagnostic( + Err(FnError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) @@ -288,7 +288,7 @@ mod tests { // out of index in the destination range assert_eq!( safe_copy_from_slice(&mut a, 1, alen + 1, &b, 0, b.len()), - Err(FunctionErrorKind::Diagnostic( + Err(FnError::Diagnostic( "Error copying from slice. Index out of range".to_string(), Some(NaslValue::Null) )) diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index adb2e8af7..e2464c7a4 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -52,7 +52,7 @@ fn ereg( icase: Option, rnul: Option, multiline: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let multiline = multiline.unwrap_or(false); @@ -79,7 +79,7 @@ fn ereg_replace( replace: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -107,7 +107,7 @@ fn egrep( pattern: NaslValue, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); @@ -141,7 +141,7 @@ fn eregmatch( find_all: Option, icase: Option, rnul: Option, -) -> Result { +) -> Result { let icase = icase.unwrap_or(false); let rnul = rnul.unwrap_or(true); let find_all = find_all.unwrap_or(false); diff --git a/rust/src/nasl/builtin/report_functions/mod.rs b/rust/src/nasl/builtin/report_functions/mod.rs index 652d1fcd9..689e9ae26 100644 --- a/rust/src/nasl/builtin/report_functions/mod.rs +++ b/rust/src/nasl/builtin/report_functions/mod.rs @@ -26,7 +26,7 @@ impl Reporting { typus: ResultType, register: &Register, context: &Context, - ) -> Result { + ) -> Result { let data = register.named("data").map(|x| x.to_string()); let port = register .named("port") @@ -70,11 +70,7 @@ impl Reporting { /// - port, optional TCP or UDP port number of the service /// - proto is the protocol ("tcp" by default; "udp" is the other value). /// - uri specifies the location of a found product - fn log_message( - &self, - register: &Register, - context: &Context, - ) -> Result { + fn log_message(&self, register: &Register, context: &Context) -> Result { self.store_result(ResultType::Log, register, context) } @@ -89,7 +85,7 @@ impl Reporting { &self, register: &Register, context: &Context, - ) -> Result { + ) -> Result { self.store_result(ResultType::Alarm, register, context) } @@ -100,11 +96,7 @@ impl Reporting { /// - port, optional TCP or UDP port number of the service /// - proto is the protocol ("tcp" by default; "udp" is the other value). /// - uri specifies the location of a found product - fn error_message( - &self, - register: &Register, - context: &Context, - ) -> Result { + fn error_message(&self, register: &Register, context: &Context) -> Result { self.store_result(ResultType::Error, register, context) } } diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 8a7ee76f6..ab05d3a6c 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -42,7 +42,7 @@ mod libssh_uses { #[cfg(feature = "nasl-builtin-libssh")] pub use libssh_uses::*; -type Result = std::result::Result; +type Result = std::result::Result; const DEFAULT_SSH_PORT: u16 = 22; @@ -533,7 +533,7 @@ impl Ssh { } AuthStatus::Success => break, status => { - return Err(FunctionErrorKind::from( + return Err(FnError::from( SshErrorKind::UnexpectedAuthenticationStatus(format!("{:?}", status)) .with(session_id), ) diff --git a/rust/src/nasl/builtin/ssh/utils.rs b/rust/src/nasl/builtin/ssh/utils.rs index 3a0a89d4d..446c2501c 100644 --- a/rust/src/nasl/builtin/ssh/utils.rs +++ b/rust/src/nasl/builtin/ssh/utils.rs @@ -12,7 +12,7 @@ impl<'a, T> FromNaslValue<'a> for CommaSeparated where T: for<'b> FromNaslValue<'b>, { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = StringOrData::from_nasl_value(value)?; Ok(Self( s.0.split(",") @@ -21,13 +21,13 @@ where let nasl_val = NaslValue::String(substr.to_string()); T::from_nasl_value(&nasl_val) }) - .collect::, FunctionErrorKind>>()?, + .collect::, FnError>>()?, )) } } impl<'a> FromNaslValue<'a> for key::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; key::Name::try_from(&*s).map_err(|_| { ArgumentError::WrongArgument(format!("Expected a valid SSH key type, found '{}'", s)) @@ -37,7 +37,7 @@ impl<'a> FromNaslValue<'a> for key::Name { } impl<'a> FromNaslValue<'a> for cipher::Name { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { let s = String::from_nasl_value(value)?; cipher::Name::try_from(&*s).map_err(|_| { ArgumentError::WrongArgument(format!("Expected a valid SSH cipher type, found '{}'", s)) diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 64b822030..69458e976 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -10,7 +10,7 @@ mod tests; use crate::nasl::{ utils::{ function::{bytes_to_str, CheckedPositionals, Maybe, StringOrData}, - FunctionErrorKind, + FnError, }, ArgumentError, }; @@ -290,7 +290,7 @@ fn stridx(haystack: NaslValue, needle: NaslValue, offset: Option) -> i64 /// NASL function to display any number of NASL values /// /// Internally the string function is used to concatenate the given parameters -fn display(register: &Register, configs: &Context) -> Result { +fn display(register: &Register, configs: &Context) -> Result { println!("{}", &string(register, configs)?); Ok(NaslValue::Null) } @@ -368,11 +368,7 @@ fn insstr( /// `pattern` contains the pattern to search for. /// The optional argument `icase` toggles case sensitivity. Default: false (case sensitive). If true, search is case insensitive. #[nasl_function(named(string, pattern, icase))] -fn match_( - string: NaslValue, - pattern: NaslValue, - icase: Option, -) -> Result { +fn match_(string: NaslValue, pattern: NaslValue, icase: Option) -> Result { let options = MatchOptions { case_sensitive: !icase.unwrap_or(false), require_literal_separator: false, diff --git a/rust/src/nasl/interpreter/call.rs b/rust/src/nasl/interpreter/call.rs index f57a05ecf..515db23a8 100644 --- a/rust/src/nasl/interpreter/call.rs +++ b/rust/src/nasl/interpreter/call.rs @@ -6,7 +6,7 @@ use crate::nasl::syntax::{Statement, StatementKind::*, Token}; use crate::nasl::utils::lookup_keys::FC_ANON_ARGS; use crate::nasl::interpreter::{ - error::{FunctionError, InterpretError}, + error::{FunctionCallError, InterpretError}, interpreter::{InterpretResult, RunSpecific}, Interpreter, }; @@ -68,7 +68,7 @@ impl<'a> Interpreter<'a> { NaslValue::Null }) } else { - r.map_err(|x| FunctionError::new(name, x).into()) + r.map_err(|x| FunctionCallError::new(name, x).into()) } } None => { diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 7279f4fb4..b18900ab8 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -6,25 +6,25 @@ use std::io; use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; -use crate::nasl::utils::error::FunctionErrorKind; -use crate::nasl::{InternalError, FEK}; +use crate::nasl::utils::error::{FnError, FnErrorKind}; +use crate::nasl::InternalError; use crate::storage::StorageError; use thiserror::Error; #[derive(Debug, Clone, Error)] /// An error that occurred while calling a function #[error("Error while calling function '{function}': {kind}")] -pub struct FunctionError { +pub struct FunctionCallError { /// Name of the function pub function: String, /// Kind of error #[source] - pub kind: FunctionErrorKind, + pub kind: FnError, } -impl FunctionError { +impl FunctionCallError { /// Creates a new FunctionError - pub fn new(function: &str, kind: FunctionErrorKind) -> Self { + pub fn new(function: &str, kind: FnError) -> Self { Self { function: function.to_owned(), kind, @@ -90,7 +90,7 @@ pub enum InterpretErrorKind { IOError(io::ErrorKind), /// An error occurred while calling a built-in function. #[error("{0}")] - FunctionCallError(FunctionError), + FunctionCallError(FunctionCallError), } impl InterpretError { @@ -228,10 +228,10 @@ impl From for InterpretError { } } -impl From for InterpretError { - fn from(fe: FunctionError) -> Self { +impl From for InterpretError { + fn from(fe: FunctionCallError) -> Self { match fe.kind.kind { - FEK::Internal(InternalError::Storage(e)) => { + FnErrorKind::Internal(InternalError::Storage(e)) => { Self::new(InterpretErrorKind::StorageError(e), None) } _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), diff --git a/rust/src/nasl/interpreter/mod.rs b/rust/src/nasl/interpreter/mod.rs index 13c01efa4..bb2e2a585 100644 --- a/rust/src/nasl/interpreter/mod.rs +++ b/rust/src/nasl/interpreter/mod.rs @@ -20,7 +20,7 @@ mod operator; mod tests; pub use code_interpreter::*; -pub use error::FunctionError; +pub use error::FunctionCallError; pub use error::InterpretError; pub use error::InterpretErrorKind; pub use interpreter::Interpreter; diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index d5c229028..0f599398a 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -15,7 +15,6 @@ pub mod prelude { pub use super::syntax::NaslValue; pub use super::utils::error::ReturnValue; pub use super::utils::error::WithErrorInfo; - pub use super::utils::error::FEK; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; pub use super::utils::function::Positionals; @@ -23,7 +22,7 @@ pub mod prelude { pub use super::utils::ArgumentError; pub use super::utils::Context; pub use super::utils::ContextType; - pub use super::utils::FunctionErrorKind; + pub use super::utils::FnError; pub use super::utils::InternalError; pub use super::utils::NaslResult; pub use super::utils::Register; diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index 88dbaf50c..ef0094121 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -294,7 +294,7 @@ where fn check_result( &self, - result: &Result, + result: &Result, reference: &TracedTestResult, line_count: usize, ) { @@ -305,7 +305,7 @@ where "Mismatch at {}.\nIn code \"{}\":\nExpected: {:?}\nFound: {:?}", reference.location, self.lines[line_count], - Ok::<_, FunctionErrorKind>(reference_result), + Ok::<_, FnError>(reference_result), result, ); } @@ -324,11 +324,7 @@ where } } - fn compare_result( - &self, - result: &Result, - reference: &TestResult, - ) -> bool { + fn compare_result(&self, result: &Result, reference: &TestResult) -> bool { match reference { TestResult::Ok(val) => result.as_ref().unwrap() == val, TestResult::GenericCheck(f, _) => f(result.clone()), @@ -403,11 +399,11 @@ macro_rules! check_err_matches { |e| { if let Err(e) = e { // Convert with try_into to allow using - // the variants of `FunctionErrorKind` directly without + // the variants of `FnError` directly without // having to wrap them in the outer enum. let converted = e.try_into(); // This is only irrefutable for the - // FunctionErrorKind -> FunctionErrorKind conversion but not for others. + // FnError -> FnError conversion but not for others. #[allow(irrefutable_let_patterns)] if let Ok(e) = converted { matches!(e, $pat) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index aeef08a51..2873be289 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -//! Defines function error kinds use thiserror::Error; use crate::nasl::builtin::BuiltinError; @@ -12,57 +11,56 @@ use crate::storage::StorageError; #[derive(Debug, Clone, Error)] #[error("{kind}")] -pub struct FunctionErrorKind { +pub struct FnError { #[source] - pub kind: FEK, + pub kind: FnErrorKind, return_value: Option, } -impl FunctionErrorKind { +impl FnError { pub fn return_value(&self) -> &Option { &self.return_value } } -impl From for FunctionErrorKind { - fn from(value: FEK) -> Self { - FunctionErrorKind { +impl From for FnError { + fn from(value: FnErrorKind) -> Self { + FnError { kind: value, return_value: None, } } } -impl From for FunctionErrorKind { +impl From for FnError { fn from(value: ArgumentError) -> Self { - FunctionErrorKind { - kind: FEK::Argument(value), + FnError { + kind: FnErrorKind::Argument(value), return_value: None, } } } -impl From for FunctionErrorKind { +impl From for FnError { fn from(value: BuiltinError) -> Self { - FunctionErrorKind { - kind: FEK::Builtin(value), + FnError { + kind: FnErrorKind::Builtin(value), return_value: None, } } } -impl From for FunctionErrorKind { +impl From for FnError { fn from(value: InternalError) -> Self { - FunctionErrorKind { - kind: FEK::Internal(value), + FnError { + kind: FnErrorKind::Internal(value), return_value: None, } } } #[derive(Debug, Clone, Error)] -/// Descriptive kind of error that can occur while calling a function -pub enum FEK { +pub enum FnErrorKind { #[error("{0}")] Argument(ArgumentError), #[error("{0}")] @@ -97,47 +95,47 @@ pub trait WithErrorInfo { pub struct ReturnValue(pub T); -impl> WithErrorInfo> for FunctionErrorKind { +impl> WithErrorInfo> for FnError { fn with(mut self, val: ReturnValue) -> Self { self.return_value = Some(val.0.into()); self } } -impl From for FunctionErrorKind { +impl From for FnError { fn from(value: StorageError) -> Self { - FEK::Internal(InternalError::Storage(value)).into() + FnErrorKind::Internal(InternalError::Storage(value)).into() } } -impl TryFrom for ArgumentError { +impl TryFrom for ArgumentError { type Error = (); - fn try_from(value: FunctionErrorKind) -> Result { + fn try_from(value: FnError) -> Result { match value.kind { - FEK::Argument(e) => Ok(e), + FnErrorKind::Argument(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for InternalError { +impl TryFrom for InternalError { type Error = (); - fn try_from(value: FunctionErrorKind) -> Result { + fn try_from(value: FnError) -> Result { match value.kind { - FEK::Internal(e) => Ok(e), + FnErrorKind::Internal(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for BuiltinError { +impl TryFrom for BuiltinError { type Error = (); - fn try_from(value: FunctionErrorKind) -> Result { + fn try_from(value: FnError) -> Result { match value.kind { - FEK::Builtin(e) => Ok(e), + FnErrorKind::Builtin(e) => Ok(e), _ => Err(()), } } @@ -152,12 +150,12 @@ impl ArgumentError { } } -impl FunctionErrorKind { +impl FnError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and /// the actual value. pub fn wrong_unnamed_argument(expected: &str, got: &str) -> Self { - FEK::Argument(ArgumentError::WrongArgument(format!( + FnErrorKind::Argument(ArgumentError::WrongArgument(format!( "Expected {expected} but {got}" ))) .into() @@ -166,6 +164,6 @@ impl FunctionErrorKind { /// Helper function to quickly construct a `MissingArguments` variant /// for a single missing argument. pub fn missing_argument(val: &str) -> Self { - FEK::Argument(ArgumentError::MissingNamed(vec![val.to_string()])).into() + FnErrorKind::Argument(ArgumentError::MissingNamed(vec![val.to_string()])).into() } } diff --git a/rust/src/nasl/utils/function/from_nasl_value.rs b/rust/src/nasl/utils/function/from_nasl_value.rs index eecf9b68c..efb37312b 100644 --- a/rust/src/nasl/utils/function/from_nasl_value.rs +++ b/rust/src/nasl/utils/function/from_nasl_value.rs @@ -6,23 +6,23 @@ use crate::nasl::prelude::*; /// The conversion may fail. pub trait FromNaslValue<'a>: Sized { /// Perform the conversion - fn from_nasl_value(value: &'a NaslValue) -> Result; + fn from_nasl_value(value: &'a NaslValue) -> Result; } impl<'a> FromNaslValue<'a> for NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value.clone()) } } impl<'a> FromNaslValue<'a> for &'a NaslValue { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(value) } } impl<'a> FromNaslValue<'a> for String { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string.to_string()), _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), @@ -31,7 +31,7 @@ impl<'a> FromNaslValue<'a> for String { } impl<'a> FromNaslValue<'a> for &'a str { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(string), _ => Err(ArgumentError::WrongArgument("Expected string.".to_string()).into()), @@ -40,7 +40,7 @@ impl<'a> FromNaslValue<'a> for &'a str { } impl<'a> FromNaslValue<'a> for &'a [u8] { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Data(bytes) => Ok(bytes), _ => Err(ArgumentError::WrongArgument("Expected byte data.".to_string()).into()), @@ -49,19 +49,19 @@ impl<'a> FromNaslValue<'a> for &'a [u8] { } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Vec { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Array(vals) => Ok(vals .iter() .map(T::from_nasl_value) - .collect::, FunctionErrorKind>>()?), + .collect::, FnError>>()?), _ => Err(ArgumentError::WrongArgument("Expected an array..".to_string()).into()), } } } impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Dict(map) => Ok(map .iter() @@ -73,7 +73,7 @@ impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for HashMap { } impl<'a> FromNaslValue<'a> for bool { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::Boolean(b) => Ok(*b), NaslValue::Number(n) => Ok(*n != 0), @@ -85,7 +85,7 @@ impl<'a> FromNaslValue<'a> for bool { macro_rules! impl_from_nasl_value_for_numeric_type { ($ty: ty) => { impl<'a> FromNaslValue<'a> for $ty { - fn from_nasl_value(value: &NaslValue) -> Result { + fn from_nasl_value(value: &NaslValue) -> Result { match value { NaslValue::Number(num) => Ok(<$ty>::try_from(*num).map_err(|_| { ArgumentError::WrongArgument("Expected positive number.".into()) diff --git a/rust/src/nasl/utils/function/maybe.rs b/rust/src/nasl/utils/function/maybe.rs index 28085e718..f7e868892 100644 --- a/rust/src/nasl/utils/function/maybe.rs +++ b/rust/src/nasl/utils/function/maybe.rs @@ -1,6 +1,6 @@ use crate::nasl::syntax::NaslValue; -use crate::nasl::FunctionErrorKind; +use crate::nasl::FnError; use super::FromNaslValue; @@ -12,7 +12,7 @@ use super::FromNaslValue; pub struct Maybe(Option); impl<'a, T: FromNaslValue<'a>> FromNaslValue<'a> for Maybe { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { Ok(Self(T::from_nasl_value(value).ok())) } } diff --git a/rust/src/nasl/utils/function/positionals.rs b/rust/src/nasl/utils/function/positionals.rs index bd29d26f5..58cb1bef6 100644 --- a/rust/src/nasl/utils/function/positionals.rs +++ b/rust/src/nasl/utils/function/positionals.rs @@ -1,6 +1,6 @@ use std::{marker::PhantomData, ops::Index}; -use crate::nasl::{FunctionErrorKind, Register}; +use crate::nasl::{FnError, Register}; use super::FromNaslValue; @@ -22,9 +22,9 @@ impl<'a, T: FromNaslValue<'a>> Positionals<'a, T> { } /// Returns an iterator over the positional arguments. - /// The item type is Result, since + /// The item type is Result, since /// the conversion to T can still fail. - pub fn iter(&self) -> impl Iterator> + 'a { + pub fn iter(&self) -> impl Iterator> + 'a { self.register .positional() .iter() @@ -45,12 +45,12 @@ pub struct CheckedPositionals { impl<'a, T: FromNaslValue<'a>> CheckedPositionals { /// Create a new `CheckedPositionals` from the register. - pub fn new(register: &'a Register) -> Result { + pub fn new(register: &'a Register) -> Result { let data = register .positional() .iter() .map(T::from_nasl_value) - .collect::, FunctionErrorKind>>()?; + .collect::, FnError>>()?; Ok(Self { data, _marker: PhantomData, diff --git a/rust/src/nasl/utils/function/to_nasl_result.rs b/rust/src/nasl/utils/function/to_nasl_result.rs index ab48aa7eb..c96d004d9 100644 --- a/rust/src/nasl/utils/function/to_nasl_result.rs +++ b/rust/src/nasl/utils/function/to_nasl_result.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::nasl::syntax::NaslValue; -use crate::nasl::{FunctionErrorKind, NaslResult}; +use crate::nasl::{FnError, NaslResult}; /// A type that can be converted to a NaslResult. /// The conversion is fallible to make it possible to convert from other Result @@ -26,7 +26,7 @@ impl ToNaslResult for Option { } } -impl> ToNaslResult for Result { +impl> ToNaslResult for Result { fn to_nasl_result(self) -> NaslResult { self.map_err(|e| e.into()).and_then(|x| x.to_nasl_result()) } @@ -67,7 +67,7 @@ impl ToNaslResult for Vec<&str> { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, FunctionErrorKind>>()?, + .collect::, FnError>>()?, )) } } @@ -77,7 +77,7 @@ impl ToNaslResult for Vec { Ok(NaslValue::Array( self.into_iter() .map(|s| s.to_nasl_result()) - .collect::, FunctionErrorKind>>()?, + .collect::, FnError>>()?, )) } } @@ -93,7 +93,7 @@ impl ToNaslResult for HashMap { Ok(NaslValue::Dict( self.into_iter() .map(|(key, s)| s.to_nasl_result().map(|res| (key, res))) - .collect::, FunctionErrorKind>>()?, + .collect::, FnError>>()?, )) } } @@ -116,7 +116,7 @@ macro_rules! impl_to_nasl_result_for_numeric_type { impl_to_nasl_result_for_numeric_type!($ty, skip_vec_impl); impl ToNaslResult for Vec<$ty> { fn to_nasl_result(self) -> NaslResult { - let collected: Result, FunctionErrorKind> = + let collected: Result, FnError> = self.into_iter().map(|x| x.to_nasl_result()).collect(); Ok(NaslValue::Array(collected?)) } diff --git a/rust/src/nasl/utils/function/types.rs b/rust/src/nasl/utils/function/types.rs index 38179334d..b4d911775 100644 --- a/rust/src/nasl/utils/function/types.rs +++ b/rust/src/nasl/utils/function/types.rs @@ -5,7 +5,7 @@ use crate::nasl::prelude::*; pub struct StringOrData(pub String); impl<'a> FromNaslValue<'a> for StringOrData { - fn from_nasl_value(value: &'a NaslValue) -> Result { + fn from_nasl_value(value: &'a NaslValue) -> Result { match value { NaslValue::String(string) => Ok(Self(string.clone())), NaslValue::Data(buffer) => Ok(Self(bytes_to_str(buffer))), diff --git a/rust/src/nasl/utils/function/utils.rs b/rust/src/nasl/utils/function/utils.rs index 14990eccc..94802d668 100644 --- a/rust/src/nasl/utils/function/utils.rs +++ b/rust/src/nasl/utils/function/utils.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::*; pub fn get_optional_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, -) -> Result, FunctionErrorKind> { +) -> Result, FnError> { register .positional() .get(position) @@ -23,7 +23,7 @@ pub fn get_positional_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, position: usize, num_required_positional_args: usize, -) -> Result { +) -> Result { let positional = register.positional(); let arg = positional.get(position).ok_or_else(|| { let num_given = positional.len(); @@ -53,7 +53,7 @@ fn context_type_as_nasl_value<'a>( pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result, FunctionErrorKind> { +) -> Result, FnError> { register .named(name) .map(|arg| context_type_as_nasl_value(arg, name)) @@ -67,7 +67,7 @@ pub fn get_optional_named_arg<'a, T: FromNaslValue<'a>>( pub fn get_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, -) -> Result { +) -> Result { let arg = register .named(name) .ok_or_else(|| ArgumentError::MissingNamed(vec![name.to_string()]))?; @@ -80,7 +80,7 @@ pub fn get_optional_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result, FunctionErrorKind> { +) -> Result, FnError> { let via_position = get_optional_positional_arg::(register, position)?; if let Some(via_position) = via_position { Ok(Some(via_position)) @@ -95,7 +95,7 @@ pub fn get_maybe_named_arg<'a, T: FromNaslValue<'a>>( register: &'a Register, name: &'a str, position: usize, -) -> Result { +) -> Result { let via_position = get_optional_positional_arg(register, position)?; if let Some(via_position) = via_position { Ok(via_position) @@ -114,7 +114,7 @@ fn check_named_args( _nasl_fn_name: &str, named: &[&str], maybe_named: &[&str], -) -> Result { +) -> Result { let mut num_maybe_named = 0; for arg_name in register.iter_named_args().unwrap() { if arg_name == FC_ANON_ARGS || named.contains(&arg_name) { @@ -142,7 +142,7 @@ pub fn check_args( named: &[&str], maybe_named: &[&str], max_num_expected_positional: Option, -) -> Result<(), FunctionErrorKind> { +) -> Result<(), FnError> { let num_maybe_named_given = check_named_args(register, _nasl_fn_name, named, maybe_named)?; let num_positional_given = register.positional().len(); if let Some(max_num_expected_positional) = max_num_expected_positional { diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index cf8699b9e..f2e7bd39c 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -13,13 +13,13 @@ use std::collections::HashMap; pub use context::{Context, ContextType, Register}; pub use error::ArgumentError; -pub use error::FunctionErrorKind; +pub use error::FnError; pub use error::InternalError; pub use executor::{Executor, IntoFunctionSet, StoredFunctionSet}; /// The result of a function call. -pub type NaslResult = Result; +pub type NaslResult = Result; /// Resolves positional arguments from the register. pub fn resolve_positional_arguments(register: &Register) -> Vec { diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index fed0ed298..52b4203f4 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -10,7 +10,7 @@ use std::{ use futures::StreamExt; use scannerlib::nasl::interpreter::CodeInterpreter; use scannerlib::nasl::{ - interpreter::{FunctionError, InterpretErrorKind}, + interpreter::{FunctionCallError, InterpretErrorKind}, prelude::*, syntax::{load_non_utf8_path, LoadError}, Loader, NoOpLoader, @@ -139,8 +139,9 @@ where let r = match result { Ok(x) => x, Err(e) => { - if let InterpretErrorKind::FunctionCallError(FunctionError { kind, .. }) = - e.kind + if let InterpretErrorKind::FunctionCallError(FunctionCallError { + kind, .. + }) = e.kind { tracing::warn!(error=?kind, "function call error"); kind.return_value().clone().unwrap_or_default() From c0aeea3a1003ee0edeeeaaaa7e80c887e425bf91 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Fri, 8 Nov 2024 09:21:41 +0100 Subject: [PATCH 26/36] Remove StorageError/IOError from InterpreterError --- rust/src/nasl/interpreter/error.rs | 47 +----------------------- rust/src/nasl/interpreter/interpreter.rs | 16 +++----- 2 files changed, 8 insertions(+), 55 deletions(-) diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index b18900ab8..9efa2fe9a 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -2,13 +2,9 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use std::io; - use crate::nasl::syntax::LoadError; use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; -use crate::nasl::utils::error::{FnError, FnErrorKind}; -use crate::nasl::InternalError; -use crate::storage::StorageError; +use crate::nasl::utils::error::FnError; use thiserror::Error; #[derive(Debug, Clone, Error)] @@ -75,19 +71,9 @@ pub enum InterpretErrorKind { /// When the given key was not found in the context #[error("Key not found: {0}")] NotFound(String), - /// A StorageError occurred - // FIXME rename to general error - #[error("{0}")] - StorageError(StorageError), /// A LoadError occurred #[error("{0}")] LoadError(LoadError), - /// A Formatting error occurred - #[error("{0}")] - FMTError(std::fmt::Error), - /// An IOError occurred - #[error("{0}")] - IOError(io::ErrorKind), /// An error occurred while calling a built-in function. #[error("{0}")] FunctionCallError(FunctionCallError), @@ -198,30 +184,6 @@ impl From for InterpretError { } } -impl From for InterpretError { - fn from(se: StorageError) -> Self { - Self::new(InterpretErrorKind::StorageError(se), None) - } -} - -impl From for InterpretError { - fn from(ie: io::ErrorKind) -> Self { - Self::new(InterpretErrorKind::IOError(ie), None) - } -} - -impl From for InterpretError { - fn from(e: io::Error) -> Self { - e.kind().into() - } -} - -impl From for InterpretError { - fn from(fe: std::fmt::Error) -> Self { - Self::new(InterpretErrorKind::FMTError(fe), None) - } -} - impl From for InterpretError { fn from(le: LoadError) -> Self { Self::new(InterpretErrorKind::LoadError(le), None) @@ -230,11 +192,6 @@ impl From for InterpretError { impl From for InterpretError { fn from(fe: FunctionCallError) -> Self { - match fe.kind.kind { - FnErrorKind::Internal(InternalError::Storage(e)) => { - Self::new(InterpretErrorKind::StorageError(e), None) - } - _ => Self::new(InterpretErrorKind::FunctionCallError(fe), None), - } + Self::new(InterpretErrorKind::FunctionCallError(fe), None) } } diff --git a/rust/src/nasl/interpreter/interpreter.rs b/rust/src/nasl/interpreter/interpreter.rs index e0d14f01e..b7a54bdc3 100644 --- a/rust/src/nasl/interpreter/interpreter.rs +++ b/rust/src/nasl/interpreter/interpreter.rs @@ -2,18 +2,16 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use std::{collections::HashMap, io}; - -use crate::nasl::syntax::{ - IdentifierType, LoadError, NaslValue, Statement, StatementKind::*, SyntaxError, Token, - TokenCategory, -}; -use crate::storage::StorageError; +use std::collections::HashMap; use crate::nasl::interpreter::{ declare::{DeclareFunctionExtension, DeclareVariableExtension}, InterpretError, InterpretErrorKind, }; +use crate::nasl::syntax::{ + IdentifierType, LoadError, NaslValue, Statement, StatementKind::*, SyntaxError, Token, + TokenCategory, +}; use crate::nasl::utils::{Context, ContextType, Register}; @@ -192,9 +190,7 @@ impl<'a> Interpreter<'a> { Err(e) => { if max_attempts > 0 { match e.kind { - InterpretErrorKind::LoadError(LoadError::Retry(_)) - | InterpretErrorKind::IOError(io::ErrorKind::Interrupted) - | InterpretErrorKind::StorageError(StorageError::Retry(_)) => { + InterpretErrorKind::LoadError(LoadError::Retry(_)) => { Box::pin(self.retry_resolve_next(stmt, max_attempts - 1)).await } _ => Err(e), From 2d3cc613a74886b081c7f9bc9fe49c111e98a1cf Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Fri, 8 Nov 2024 10:02:27 +0100 Subject: [PATCH 27/36] Improve scannerctl error message on Fn errors. Add code location and origin statement to the message. --- rust/src/nasl/interpreter/call.rs | 18 +++++++++++++++--- rust/src/nasl/interpreter/error.rs | 14 +++++++++++++- rust/src/nasl/interpreter/interpreter.rs | 4 +--- rust/src/nasl/utils/error.rs | 10 +++++----- rust/src/scannerctl/interpret/mod.rs | 11 ++++------- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/rust/src/nasl/interpreter/call.rs b/rust/src/nasl/interpreter/call.rs index 515db23a8..fa14acc6e 100644 --- a/rust/src/nasl/interpreter/call.rs +++ b/rust/src/nasl/interpreter/call.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception -use crate::nasl::syntax::{Statement, StatementKind::*, Token}; +use crate::nasl::syntax::{Statement, StatementKind::*}; use crate::nasl::utils::lookup_keys::FC_ANON_ARGS; use crate::nasl::interpreter::{ @@ -15,8 +15,15 @@ use crate::nasl::syntax::NaslValue; use crate::nasl::utils::ContextType; use std::collections::HashMap; +use super::InterpretErrorKind; + impl<'a> Interpreter<'a> { - pub async fn call(&mut self, name: &Token, arguments: &[Statement]) -> InterpretResult { + pub async fn call( + &mut self, + statement: &Statement, + arguments: &[Statement], + ) -> InterpretResult { + let name = statement.as_token(); let name = &Self::identifier(name)?; // get the context let mut named = HashMap::new(); @@ -68,7 +75,12 @@ impl<'a> Interpreter<'a> { NaslValue::Null }) } else { - r.map_err(|x| FunctionCallError::new(name, x).into()) + r.map_err(|x| { + InterpretError::new( + InterpretErrorKind::FunctionCallError(FunctionCallError::new(name, x)), + Some(statement.clone()), + ) + }) } } None => { diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 9efa2fe9a..74346c550 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -30,7 +30,7 @@ impl FunctionCallError { #[derive(Debug, Clone, Error)] /// Is used to represent an error while interpreting -#[error("{}{kind}", self.origin.clone().map(|e| format!("{e}: ")).unwrap_or_default())] +#[error("{} {kind}", self.format_origin())] pub struct InterpretError { /// Defined the type of error that occurred. #[source] @@ -39,6 +39,18 @@ pub struct InterpretError { pub origin: Option, } +impl InterpretError { + fn format_origin(&self) -> String { + if let Some(ref origin) = self.origin { + let line = self.line(); + let col = self.column(); + format!("Error in statement '{origin}' at {}:{}.", line, col) + } else { + "".into() + } + } +} + #[derive(Debug, Clone, Error)] /// Is used to give hints to the user how to react on an error while interpreting pub enum InterpretErrorKind { diff --git a/rust/src/nasl/interpreter/interpreter.rs b/rust/src/nasl/interpreter/interpreter.rs index b7a54bdc3..cc079f6f4 100644 --- a/rust/src/nasl/interpreter/interpreter.rs +++ b/rust/src/nasl/interpreter/interpreter.rs @@ -247,9 +247,7 @@ impl<'a> Interpreter<'a> { } Primitive => self.resolve_primitive(statement), Variable => self.resolve_variable(statement), - Call(arguments) => { - Box::pin(self.call(statement.as_token(), arguments.children())).await - } + Call(arguments) => Box::pin(self.call(statement, arguments.children())).await, Declare(stmts) => self.declare_variable(statement.as_token(), stmts), Parameter(x) => self.resolve_parameter(x).await, Assign(cat, order, left, right) => { diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 2873be289..f12881768 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -71,15 +71,15 @@ pub enum FnErrorKind { #[derive(Debug, Clone, PartialEq, Error)] pub enum ArgumentError { - #[error("Expected {expected} but got {got}")] + #[error("Missing positional arguments. Expected {expected} but got {got}.")] MissingPositionals { expected: usize, got: usize }, - #[error("Expected {expected} but got {got}")] + #[error("Trailing positional arguments. Expected {expected} but got {got}.")] TrailingPositionals { expected: usize, got: usize }, - #[error("Missing arguments: {}", .0.join(", "))] + #[error("Missing named arguments: {}", .0.join(", "))] MissingNamed(Vec), - #[error("Unknown named argument given to function: {}", .0)] + #[error("Unknown named argument given: {}", .0)] UnexpectedArgument(String), - #[error("Function was called with wrong arguments: {0}")] + #[error("Wrong arguments given: {0}")] WrongArgument(String), } diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 52b4203f4..39e6bc9cb 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -10,7 +10,7 @@ use std::{ use futures::StreamExt; use scannerlib::nasl::interpreter::CodeInterpreter; use scannerlib::nasl::{ - interpreter::{FunctionCallError, InterpretErrorKind}, + interpreter::InterpretErrorKind, prelude::*, syntax::{load_non_utf8_path, LoadError}, Loader, NoOpLoader, @@ -139,12 +139,9 @@ where let r = match result { Ok(x) => x, Err(e) => { - if let InterpretErrorKind::FunctionCallError(FunctionCallError { - kind, .. - }) = e.kind - { - tracing::warn!(error=?kind, "function call error"); - kind.return_value().clone().unwrap_or_default() + if let InterpretErrorKind::FunctionCallError(ref fe) = e.kind { + tracing::warn!("{}", e.to_string()); + fe.kind.return_value().clone().unwrap_or_default() } else { return Err(e.into()); } From 93286d5be29c715747f53705a5f921077e023998 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Fri, 8 Nov 2024 10:10:32 +0100 Subject: [PATCH 28/36] Implement retry logic --- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 2 +- rust/src/nasl/interpreter/error.rs | 12 +++++ rust/src/nasl/interpreter/interpreter.rs | 14 +++-- rust/src/nasl/utils/error.rs | 54 +++++++++++++------- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index 8e25d9ed2..b9d19edcd 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -19,7 +19,7 @@ pub fn ipstr2ipaddr(ip_addr: &str) -> Result { Err(_) => Err(FnError::from(ArgumentError::WrongArgument( "Invalid IP address".to_string(), )) - .with(ReturnValue(NaslValue::Null))), + .with_return_value(NaslValue::Null)), } } diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 74346c550..66700acb6 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -26,6 +26,10 @@ impl FunctionCallError { kind, } } + + fn retryable(&self) -> bool { + self.kind.retryable() + } } #[derive(Debug, Clone, Error)] @@ -49,6 +53,14 @@ impl InterpretError { "".into() } } + + pub fn retryable(&self) -> bool { + match &self.kind { + InterpretErrorKind::LoadError(LoadError::Retry(_)) => true, + InterpretErrorKind::FunctionCallError(e) => e.retryable(), + _ => false, + } + } } #[derive(Debug, Clone, Error)] diff --git a/rust/src/nasl/interpreter/interpreter.rs b/rust/src/nasl/interpreter/interpreter.rs index cc079f6f4..d1309fa90 100644 --- a/rust/src/nasl/interpreter/interpreter.rs +++ b/rust/src/nasl/interpreter/interpreter.rs @@ -6,11 +6,10 @@ use std::collections::HashMap; use crate::nasl::interpreter::{ declare::{DeclareFunctionExtension, DeclareVariableExtension}, - InterpretError, InterpretErrorKind, + InterpretError, }; use crate::nasl::syntax::{ - IdentifierType, LoadError, NaslValue, Statement, StatementKind::*, SyntaxError, Token, - TokenCategory, + IdentifierType, NaslValue, Statement, StatementKind::*, SyntaxError, Token, TokenCategory, }; use crate::nasl::utils::{Context, ContextType, Register}; @@ -189,11 +188,10 @@ impl<'a> Interpreter<'a> { Ok(x) => Ok(x), Err(e) => { if max_attempts > 0 { - match e.kind { - InterpretErrorKind::LoadError(LoadError::Retry(_)) => { - Box::pin(self.retry_resolve_next(stmt, max_attempts - 1)).await - } - _ => Err(e), + if e.retryable() { + Box::pin(self.retry_resolve_next(stmt, max_attempts - 1)).await + } else { + Err(e) } } else { Err(e) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index f12881768..9c1854fb3 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -15,45 +15,51 @@ pub struct FnError { #[source] pub kind: FnErrorKind, return_value: Option, + retryable: bool, } impl FnError { pub fn return_value(&self) -> &Option { &self.return_value } -} -impl From for FnError { - fn from(value: FnErrorKind) -> Self { - FnError { - kind: value, + pub fn retryable(&self) -> bool { + self.retryable + } + + fn from_kind(kind: FnErrorKind) -> FnError { + Self { + kind, return_value: None, + retryable: false, } } } +impl From for FnError { + fn from(kind: FnErrorKind) -> Self { + FnError::from_kind(kind) + } +} + impl From for FnError { - fn from(value: ArgumentError) -> Self { - FnError { - kind: FnErrorKind::Argument(value), - return_value: None, - } + fn from(kind: ArgumentError) -> Self { + FnError::from_kind(FnErrorKind::Argument(kind)) } } impl From for FnError { - fn from(value: BuiltinError) -> Self { - FnError { - kind: FnErrorKind::Builtin(value), - return_value: None, - } + fn from(kind: BuiltinError) -> Self { + FnError::from_kind(FnErrorKind::Builtin(kind)) } } impl From for FnError { - fn from(value: InternalError) -> Self { - FnError { - kind: FnErrorKind::Internal(value), + fn from(kind: InternalError) -> Self { + let retryable = kind.retryable(); + Self { + kind: FnErrorKind::Internal(kind), + retryable, return_value: None, } } @@ -89,6 +95,18 @@ pub enum InternalError { Storage(#[from] StorageError), } +impl InternalError { + fn retryable(&self) -> bool { + // Keep this match exhaustive without a catchall + // to make sure we implement future internal errors + // properly. + match self { + InternalError::Storage(StorageError::Retry(_)) => true, + InternalError::Storage(_) => false, + } + } +} + pub trait WithErrorInfo { fn with(self, e: Info) -> Self; } From de6617e6e38419a79490cfa5135070589bb73823 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Fri, 8 Nov 2024 10:27:04 +0100 Subject: [PATCH 29/36] Add basic test for retry functionality --- rust/src/nasl/builtin/http/mod.rs | 4 +-- rust/src/nasl/builtin/ssh/mod.rs | 2 +- rust/src/nasl/interpreter/tests/mod.rs | 1 + rust/src/nasl/interpreter/tests/retry.rs | 46 ++++++++++++++++++++++++ rust/src/nasl/mod.rs | 1 - rust/src/nasl/utils/error.rs | 19 +++++----- 6 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 rust/src/nasl/interpreter/tests/retry.rs diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index 856e95537..af572134b 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -7,8 +7,8 @@ mod error; +use crate::nasl::prelude::*; use crate::nasl::utils::ContextType; -use crate::nasl::{prelude::*, utils::error::ReturnValue}; pub use error::HttpError; use h2::client; @@ -343,7 +343,7 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(FnError::from(HttpError::HandleIdNotFound(handle)).with(ReturnValue(-1))), + _ => Err(FnError::from(HttpError::HandleIdNotFound(handle)).with_return_value(-1)), } } diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index ab05d3a6c..17dcfb723 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -537,7 +537,7 @@ impl Ssh { SshErrorKind::UnexpectedAuthenticationStatus(format!("{:?}", status)) .with(session_id), ) - .with(ReturnValue(-1))); + .with_return_value(-1)); } } } diff --git a/rust/src/nasl/interpreter/tests/mod.rs b/rust/src/nasl/interpreter/tests/mod.rs index 46dc84ed4..6663b80cc 100644 --- a/rust/src/nasl/interpreter/tests/mod.rs +++ b/rust/src/nasl/interpreter/tests/mod.rs @@ -1,2 +1,3 @@ mod description; mod local_var; +mod retry; diff --git a/rust/src/nasl/interpreter/tests/retry.rs b/rust/src/nasl/interpreter/tests/retry.rs new file mode 100644 index 000000000..d987ff850 --- /dev/null +++ b/rust/src/nasl/interpreter/tests/retry.rs @@ -0,0 +1,46 @@ +//! Checks that errors that specify that they are solvable by +//! retrying are actually retried within the interpreter. + +use crate::nasl::{test_prelude::*, utils::Executor}; + +struct Counter { + count: usize, +} + +impl Counter { + fn check_and_increment(&mut self) -> Result { + self.count += 1; + if self.count < 5 { + // Return a dummy error, it doesnt matter what it is. + Err(FnError::from(ArgumentError::WrongArgument("test".into()))) + } else { + Ok(self.count) + } + } + + #[nasl_function] + fn check_counter_retry(&mut self) -> Result { + self.check_and_increment().map_err(|e| e.with_retryable()) + } + + #[nasl_function] + fn check_counter(&mut self) -> Result { + self.check_and_increment() + } +} + +function_set! { + Counter, + sync_stateful_mut, + ( + (Counter::check_counter_retry, "check_counter_retry"), + (Counter::check_counter, "check_counter"), + ) +} + +#[test] +fn retryable_error() { + let mut t = TestBuilder::default().with_executor(Executor::single(Counter { count: 0 })); + check_err_matches!(t, "check_counter();", ArgumentError::WrongArgument(_)); + t.ok("check_counter_retry();", 5); +} diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index 0f599398a..ca9a21a6d 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -13,7 +13,6 @@ pub mod prelude { pub use super::syntax::FSPluginLoader; pub use super::syntax::Loader; pub use super::syntax::NaslValue; - pub use super::utils::error::ReturnValue; pub use super::utils::error::WithErrorInfo; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 9c1854fb3..65a25ce62 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -27,6 +27,16 @@ impl FnError { self.retryable } + pub fn with_return_value(mut self, val: impl Into) -> Self { + self.return_value = Some(val.into()); + self + } + + pub fn with_retryable(mut self) -> Self { + self.retryable = true; + self + } + fn from_kind(kind: FnErrorKind) -> FnError { Self { kind, @@ -111,15 +121,6 @@ pub trait WithErrorInfo { fn with(self, e: Info) -> Self; } -pub struct ReturnValue(pub T); - -impl> WithErrorInfo> for FnError { - fn with(mut self, val: ReturnValue) -> Self { - self.return_value = Some(val.0.into()); - self - } -} - impl From for FnError { fn from(value: StorageError) -> Self { FnErrorKind::Internal(InternalError::Storage(value)).into() From eaad6bb73d0e3352c0f6c26f74903a261866ed23 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 11 Nov 2024 09:20:02 +0100 Subject: [PATCH 30/36] Remove clone derive on errors --- rust/src/feed/update/error.rs | 4 +- rust/src/nasl/builtin/cryptographic/bf_cbc.rs | 22 +++--- rust/src/nasl/builtin/cryptographic/mod.rs | 6 +- rust/src/nasl/builtin/cryptographic/rc4.rs | 58 ++++------------ rust/src/nasl/builtin/cryptographic/rsa.rs | 69 +++++++++---------- rust/src/nasl/builtin/error.rs | 8 +-- rust/src/nasl/builtin/http/error.rs | 2 +- rust/src/nasl/builtin/isotime/mod.rs | 2 +- rust/src/nasl/builtin/knowledge_base/mod.rs | 2 +- rust/src/nasl/builtin/misc/mod.rs | 14 +--- rust/src/nasl/builtin/network/socket.rs | 26 +++---- rust/src/nasl/builtin/raw_ip/mod.rs | 4 +- .../src/nasl/builtin/raw_ip/packet_forgery.rs | 6 +- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 2 +- rust/src/nasl/builtin/regex/mod.rs | 2 +- rust/src/nasl/builtin/ssh/error.rs | 2 +- rust/src/nasl/builtin/string/mod.rs | 2 +- rust/src/nasl/interpreter/error.rs | 6 +- rust/src/nasl/test_utils.rs | 12 ++-- rust/src/nasl/utils/error.rs | 22 +++--- rust/src/scanner/error.rs | 8 +-- rust/src/scanner/running_scan.rs | 2 +- rust/src/scanner/scan_runner.rs | 14 ++-- rust/src/scanner/vt_runner.rs | 2 +- rust/src/scannerctl/error.rs | 4 +- 25 files changed, 121 insertions(+), 180 deletions(-) diff --git a/rust/src/feed/update/error.rs b/rust/src/feed/update/error.rs index c84c9888c..04a77f49a 100644 --- a/rust/src/feed/update/error.rs +++ b/rust/src/feed/update/error.rs @@ -9,7 +9,7 @@ use thiserror::Error; use crate::feed::{verify, VerifyError}; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] /// Errors within feed handling pub enum ErrorKind { /// An InterpretError occurred while interpreting @@ -32,7 +32,7 @@ pub enum ErrorKind { VerifyError(#[from] verify::Error), } -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] #[error("Error with key '{key}': {kind}")] /// ErrorKind and key of error pub struct Error { diff --git a/rust/src/nasl/builtin/cryptographic/bf_cbc.rs b/rust/src/nasl/builtin/cryptographic/bf_cbc.rs index 8a6fe0ff5..34103a3ad 100644 --- a/rust/src/nasl/builtin/cryptographic/bf_cbc.rs +++ b/rust/src/nasl/builtin/cryptographic/bf_cbc.rs @@ -12,15 +12,12 @@ use blowfish::{ }; 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(register: &Register, crypt: Crypt) -> Result +fn cbc(register: &Register, crypt: Crypt) -> Result where D: BlockCipher + BlockEncrypt + BlockDecrypt + KeyInit, { @@ -35,7 +32,7 @@ where let res = Encryptor::::new_from_slices(key, iv); match res { Ok(encryptor) => Ok(encryptor.encrypt_padded_vec_mut::(data).into()), - Err(e) => Err(FunctionErrorKind::WrongArgument(e.to_string())), + Err(e) => Err(ArgumentError::WrongArgument(e.to_string()).into()), } } Crypt::Decrypt => { @@ -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::::new_from_slices(key, iv); match res { Ok(decryptor) => Ok(decryptor .decrypt_padded_vec_mut::(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()), } } } @@ -77,7 +75,7 @@ where /// a[1] the new initialization vector to use for the next part of the /// data. -fn bf_cbc_encrypt(register: &Register, _: &Context) -> Result { +fn bf_cbc_encrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Encrypt) } @@ -91,7 +89,7 @@ fn bf_cbc_encrypt(register: &Register, _: &Context) -> Result Result { +fn bf_cbc_decrypt(register: &Register, _: &Context) -> Result { cbc::(register, Crypt::Decrypt) } diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index e8c1a948a..27362e849 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -25,7 +25,7 @@ pub mod rsa; #[cfg(test)] mod tests; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum CryptographicError { #[error("Error in AesGcm: insufficient buffer size.")] InsufficientBufferSize, @@ -35,6 +35,10 @@ pub enum CryptographicError { AesGmacError(String), #[error("Invalid length of key in AesCmac {0}.")] AesCmacInvalidLength(digest::InvalidLength), + #[error("Error in RSA: {0}.")] + RSA(String), + #[error("Error in RC4: {0}.")] + RC4(String), } enum Crypt { diff --git a/rust/src/nasl/builtin/cryptographic/rc4.rs b/rust/src/nasl/builtin/cryptographic/rc4.rs index 03dcce2b8..c9874cf5e 100644 --- a/rust/src/nasl/builtin/cryptographic/rc4.rs +++ b/rust/src/nasl/builtin/cryptographic/rc4.rs @@ -8,10 +8,9 @@ use std::sync::{Arc, Mutex, MutexGuard}; use crate::nasl::prelude::*; use crate::nasl::syntax::NaslValue; -use crate::nasl::utils::error::FunctionErrorKind; use crate::nasl::utils::{Context, Register}; -use super::{get_data, get_key}; +use super::{get_data, get_key, CryptographicError}; /// Structure to hold a Cipher Handler pub struct CipherHandler { @@ -23,9 +22,9 @@ pub struct CipherHandler { fn lock_handlers( handlers: &Arc>>, -) -> Result>, FunctionErrorKind> { +) -> Result>, FnError> { // we actually need to panic as a lock error is fatal - // alternatively we need to add a poison error on FunctionErrorKind + // alternatively we need to add a poison error on FnError Ok(Arc::as_ref(handlers).lock().unwrap()) } @@ -63,15 +62,10 @@ impl CipherHandlers { &self, register: &Register, _: &Context, - ) -> Result { + ) -> Result { let hd = match register.named("hd") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => { - return Err(FunctionErrorKind::Diagnostic( - "Handler ID not found".to_string(), - Some(NaslValue::Null), - )) - } + _ => return Err(CryptographicError::RC4("Handler ID not found".to_string()).into()), }; let mut handlers = lock_handlers(&self.cipher_handlers)?; @@ -80,10 +74,7 @@ impl CipherHandlers { handlers.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(FunctionErrorKind::Diagnostic( - format!("Handler ID {} not found", hd), - Some(NaslValue::Null), - )), + _ => Err(CryptographicError::RC4(format!("Handler ID {} not found", hd)).into()), } } @@ -93,21 +84,12 @@ impl CipherHandlers { /// -key: the key used for encryption /// /// Returns the id of the encrypted data cipher handler on success. - pub fn open_rc4_cipher( - &self, - register: &Register, - _: &Context, - ) -> Result { + pub fn open_rc4_cipher(&self, register: &Register, _: &Context) -> Result { // Get Arguments let key = match get_key(register) { Ok(k) if !k.is_empty() => k.to_vec(), - _ => { - return Err(FunctionErrorKind::Diagnostic( - "Missing Key argument".to_string(), - Some(NaslValue::Null), - )) - } + _ => return Err(CryptographicError::RC4("Missing Key argument".to_string()).into()), }; let rc_handler = Rc4Key::build_handler_from_key(key.to_vec())?; @@ -131,19 +113,10 @@ impl CipherHandlers { /// -hd: the handler index. (mandatory if not key and iv is given) /// -iv: string Initialization vector (mandatory if no handler is given). /// -key: string key (mandatory if no handler is given). - pub fn rc4_encrypt( - &self, - register: &Register, - _: &Context, - ) -> Result { + pub fn rc4_encrypt(&self, register: &Register, _: &Context) -> Result { let data = match get_data(register) { Ok(d) if !d.is_empty() => d.to_vec(), - _ => { - return Err(FunctionErrorKind::Diagnostic( - "Missing data argument".to_string(), - Some(NaslValue::Null), - )) - } + _ => return Err(CryptographicError::RC4("Missing data argument".to_string()).into()), }; let hd = match register.named("hd") { @@ -162,12 +135,7 @@ impl CipherHandlers { let key = match get_key(register) { Ok(k) if !k.is_empty() => k.to_vec(), - _ => { - return Err(FunctionErrorKind::Diagnostic( - "Missing Key argument".to_string(), - Some(NaslValue::Null), - )) - } + _ => return Err(CryptographicError::RC4("Missing Key argument".to_string()).into()), }; let mut rc_handler = Rc4Key::build_handler_from_key(key.to_vec())?; @@ -185,10 +153,10 @@ macro_rules! build_rc4key_enum { } impl Rc4Key { - fn build_handler_from_key(bl: Vec) -> Result { + fn build_handler_from_key(bl: Vec) -> Result { match bl.len() { $($l => Ok(Self::$i(Rc4::new_from_slice(bl.as_slice()).unwrap())),)* - _ => {return Err(FunctionErrorKind::Diagnostic("RC4 Key size not supported".into(), Some(NaslValue::Null)))} + _ => {return Err(CryptographicError::RC4("RC4 Key size not supported".into()).into())} } } diff --git a/rust/src/nasl/builtin/cryptographic/rsa.rs b/rust/src/nasl/builtin/cryptographic/rsa.rs index 102a17961..4e518ff02 100644 --- a/rust/src/nasl/builtin/cryptographic/rsa.rs +++ b/rust/src/nasl/builtin/cryptographic/rsa.rs @@ -3,8 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later use crate::function_set; -use crate::nasl::FunctionErrorKind; -use crate::nasl::NaslValue; +use crate::nasl::prelude::*; use ccm::aead::OsRng; use nasl_function_proc_macro::nasl_function; use rsa::pkcs8::DecodePrivateKey; @@ -12,28 +11,30 @@ use rsa::signature::digest::Digest; use rsa::{BigUint, Pkcs1v15Encrypt, Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey}; use sha1::Sha1; +use super::CryptographicError; + #[nasl_function(named(data, n, e, pad))] fn rsa_public_encrypt( data: &[u8], n: &[u8], e: &[u8], pad: Option, -) -> Result { +) -> Result { let pad = pad.unwrap_or_default(); let mut rng = rand::thread_rng(); let pub_key = RsaPublicKey::new( rsa::BigUint::from_bytes_be(n), rsa::BigUint::from_bytes_be(e), ) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; + .map_err(|e| CryptographicError::RSA(e.to_string()))?; let biguint_data = BigUint::from_bytes_be(data); let enc_data = if pad { pub_key .encrypt(&mut rng, Pkcs1v15Encrypt, data) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? } else { rsa::hazmat::rsa_encrypt(&pub_key, &biguint_data) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? .to_bytes_be() }; Ok(enc_data.to_vec().into()) @@ -46,7 +47,7 @@ fn rsa_private_decrypt( e: &[u8], d: &[u8], pad: Option, -) -> Result { +) -> Result { let pad = pad.unwrap_or_default(); let priv_key = match RsaPrivateKey::from_components( rsa::BigUint::from_bytes_be(n), @@ -55,30 +56,31 @@ fn rsa_private_decrypt( vec![], ) { Ok(val) => Ok(val), - Err(code) => Err(crate::nasl::FunctionErrorKind::Diagnostic( - format!("Error code {}", code), - Some(NaslValue::Array(vec![ - NaslValue::Data(n.to_vec()), - NaslValue::Data(e.to_vec()), - NaslValue::Data(d.to_vec()), - ])), - )), + Err(code) => Err( + FnError::from(CryptographicError::RSA(format!("Error code {}", code))) + .with_return_value(NaslValue::Array(vec![ + NaslValue::Data(n.to_vec()), + NaslValue::Data(e.to_vec()), + NaslValue::Data(d.to_vec()), + ])), + ), } - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; + .map_err(|e| CryptographicError::RSA(e.to_string()))?; let mut rng = OsRng; let biguint_data = BigUint::from_bytes_be(data); let dec_data = if pad { match priv_key.decrypt(Pkcs1v15Encrypt, data) { Ok(val) => Ok(val), - Err(code) => Err(crate::nasl::FunctionErrorKind::Diagnostic( - format!("Error code {}", code), - Some(NaslValue::Data(data.to_vec())), - )), + Err(code) => Err(FnError::from(CryptographicError::RSA(format!( + "Error code {}", + code + ))) + .with_return_value(NaslValue::Data(data.to_vec()))), } - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? } else { rsa::hazmat::rsa_decrypt_and_check(&priv_key, Some(&mut rng), &biguint_data) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? .to_bytes_be() }; @@ -86,39 +88,34 @@ fn rsa_private_decrypt( } #[nasl_function(named(data, pem, passphrase))] -fn rsa_sign( - data: &[u8], - pem: &[u8], - passphrase: Option<&str>, -) -> Result { - let pem_str = - std::str::from_utf8(pem).map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; +fn rsa_sign(data: &[u8], pem: &[u8], passphrase: Option<&str>) -> Result { + let pem_str = std::str::from_utf8(pem).map_err(|e| CryptographicError::RSA(e.to_string()))?; let rsa: RsaPrivateKey = if passphrase.unwrap_or_default() != "" { pkcs8::DecodePrivateKey::from_pkcs8_encrypted_pem(pem_str, passphrase.unwrap_or_default()) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? } else { RsaPrivateKey::from_pkcs8_pem(pem_str) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))? + .map_err(|e| CryptographicError::RSA(e.to_string()))? }; let mut hasher = Sha1::new_with_prefix(data); hasher.update(data); let hashed_data = hasher.finalize(); let signature = rsa .sign(Pkcs1v15Sign::new_unprefixed(), &hashed_data) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; + .map_err(|e| CryptographicError::RSA(e.to_string()))?; Ok(signature.into()) } #[nasl_function(named(sign, n, e))] -fn rsa_public_decrypt(sign: &[u8], n: &[u8], e: &[u8]) -> Result { +fn rsa_public_decrypt(sign: &[u8], n: &[u8], e: &[u8]) -> Result { let e_b = rsa::BigUint::from_bytes_be(e); let n_b = rsa::BigUint::from_bytes_be(n); - let public_key = RsaPublicKey::new(n_b, e_b) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; + let public_key = + RsaPublicKey::new(n_b, e_b).map_err(|e| CryptographicError::RSA(e.to_string()))?; let mut rng = rand::thread_rng(); let enc_data = public_key .encrypt(&mut rng, Pkcs1v15Encrypt, sign) - .map_err(|e| FunctionErrorKind::Diagnostic(e.to_string(), None))?; + .map_err(|e| CryptographicError::RSA(e.to_string()))?; Ok(enc_data.to_vec().into()) } diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index d0250c645..9ce464fe7 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -10,7 +10,7 @@ use super::knowledge_base::KBError; use super::regex::RegexError; use super::{misc::MiscError, network::socket::SocketError, ssh::SshError, string::StringError}; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum BuiltinError { #[error("{0}")] Ssh(SshError), @@ -52,11 +52,11 @@ macro_rules! builtin_error_variant ( } } - impl TryFrom for $err { + impl<'a> TryFrom<&'a FnError> for &'a $err { type Error = (); - fn try_from(value: FnError) -> Result { - match value.kind { + fn try_from(value: &'a FnError) -> Result { + match &value.kind { FnErrorKind::Builtin( BuiltinError::$variant(e) ) => Ok(e), diff --git a/rust/src/nasl/builtin/http/error.rs b/rust/src/nasl/builtin/http/error.rs index 2dea5844c..7e28c6d1d 100644 --- a/rust/src/nasl/builtin/http/error.rs +++ b/rust/src/nasl/builtin/http/error.rs @@ -2,7 +2,7 @@ use std::io; use thiserror::Error; -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] pub enum HttpError { #[error("IO error during HTTP: {0}")] IO(io::ErrorKind), diff --git a/rust/src/nasl/builtin/isotime/mod.rs b/rust/src/nasl/builtin/isotime/mod.rs index 9cf644e2b..565e36149 100644 --- a/rust/src/nasl/builtin/isotime/mod.rs +++ b/rust/src/nasl/builtin/isotime/mod.rs @@ -11,7 +11,7 @@ use crate::nasl::prelude::*; use chrono::{Datelike, Months, NaiveDate, NaiveDateTime, TimeDelta}; use thiserror::Error; -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] #[error("{0}")] pub struct IsotimeError(String); diff --git a/rust/src/nasl/builtin/knowledge_base/mod.rs b/rust/src/nasl/builtin/knowledge_base/mod.rs index 56c502ba9..c821f9c2f 100644 --- a/rust/src/nasl/builtin/knowledge_base/mod.rs +++ b/rust/src/nasl/builtin/knowledge_base/mod.rs @@ -15,7 +15,7 @@ use crate::storage::{Field, Kb, Retrieve}; use nasl_function_proc_macro::nasl_function; use thiserror::Error; -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] #[error("{0}")] pub struct KBError(String); diff --git a/rust/src/nasl/builtin/misc/mod.rs b/rust/src/nasl/builtin/misc/mod.rs index 01c09fc92..92cc6a92e 100644 --- a/rust/src/nasl/builtin/misc/mod.rs +++ b/rust/src/nasl/builtin/misc/mod.rs @@ -26,24 +26,14 @@ use flate2::{ read::GzDecoder, read::ZlibDecoder, write::GzEncoder, write::ZlibEncoder, Compression, }; -#[derive(Debug, Clone, Error)] -// It would be nicer to derive this using #[from] from -// thiserror, but io::Error does not impl `Clone`, -// so we wrap `io::ErrorKind` instead, which -// does not impl `Error` which is why this `From` impl exists. +#[derive(Debug, Error)] pub enum MiscError { #[error("IO Error: {0}")] - IO(io::ErrorKind), + IO(#[from] io::Error), #[error("Encountered time before 1970. {0}")] TimeBefore1970(String), } -impl From for MiscError { - fn from(value: io::Error) -> Self { - Self::IO(value.kind()) - } -} - #[inline] #[cfg(unix)] /// Reads 8 bytes from /dev/urandom and parses it to an i64 diff --git a/rust/src/nasl/builtin/network/socket.rs b/rust/src/nasl/builtin/network/socket.rs index b02222c0d..e23dab6a9 100644 --- a/rust/src/nasl/builtin/network/socket.rs +++ b/rust/src/nasl/builtin/network/socket.rs @@ -32,23 +32,13 @@ use super::{ // Number of times to resend a UDP packet, when no response is received const NUM_TIMES_TO_RESEND: usize = 5; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] #[error("{0}")] -// It would be nicer to derive this using #[from] from -// thiserror, but io::Error does not impl `Clone`, -// so we wrap `io::ErrorKind` instead, which -// does not impl `Error` which is why this `From` impl exists. pub enum SocketError { - IO(std::io::ErrorKind), + IO(#[from] std::io::Error), Diagnostic(String, Option), } -impl From for SocketError { - fn from(value: io::Error) -> Self { - Self::IO(value.kind()) - } -} - pub struct Interval { interval: Duration, last_tick: SystemTime, @@ -445,8 +435,8 @@ impl NaslSockets { io::ErrorKind::TimedOut => { conn.socket.send(&conn.buffer).map_err(SocketError::from)?; } - kind => { - ret = Err(SocketError::IO(kind)); + _ => { + ret = Err(SocketError::IO(e)); break; } }, @@ -671,8 +661,10 @@ impl NaslSockets { match Self::open_tcp(addr, port, bufsz, timeout, tls_config.as_ref()) { Ok(socket) => return Ok(socket), Err(err) => { - if !matches!(err, SocketError::IO(io::ErrorKind::TimedOut)) { - return Err(err.into()); + if let SocketError::IO(ref io_err) = err { + if io_err.kind() == io::ErrorKind::TimedOut { + return Err(err.into()); + } } retry -= 1; } @@ -683,7 +675,7 @@ impl NaslSockets { // 2. Log too many timeouts // 3. Create result of type error with: // ERRMSG|||||||||/tcp||| ||| Too many timeouts. The port was set to closed - Err(SocketError::IO(io::ErrorKind::TimedOut).into()) + Err(SocketError::IO(io::ErrorKind::TimedOut.into()).into()) } fn load_private_key(filename: &str) -> Result, SocketError> { diff --git a/rust/src/nasl/builtin/raw_ip/mod.rs b/rust/src/nasl/builtin/raw_ip/mod.rs index a54deb4d2..afab04c48 100644 --- a/rust/src/nasl/builtin/raw_ip/mod.rs +++ b/rust/src/nasl/builtin/raw_ip/mod.rs @@ -13,7 +13,7 @@ use packet_forgery::PacketForgery; pub use packet_forgery::PacketForgeryError; use thiserror::Error; -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] pub enum RawIpError { #[error("Failed to get local MAC address.")] FailedToGetLocalMacAddress, @@ -24,7 +24,7 @@ pub enum RawIpError { #[error("Invalid IP address.")] InvalidIpAddress, #[error("Failed to bind.")] - FailedToBind(io::ErrorKind), + FailedToBind(io::Error), #[error("No route to destination.")] NoRouteToDestination, } diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 15f39ae2e..8d61eebfc 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -38,14 +38,14 @@ use socket2::{Domain, Protocol, Socket}; use thiserror::Error; use tracing::debug; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum PacketForgeryError { #[error("{0}")] Custom(String), #[error("Failed to parse socket address. {0}")] ParseSocketAddr(std::net::AddrParseError), #[error("Failed to send packet. {0}")] - SendPacket(std::io::ErrorKind), + SendPacket(std::io::Error), } fn error(s: String) -> FnError { @@ -2074,7 +2074,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result { - return Err(PacketForgeryError::SendPacket(e.kind()).into()); + return Err(PacketForgeryError::SendPacket(e).into()); } } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index b9d19edcd..506f1781e 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -76,7 +76,7 @@ pub fn bind_local_socket(dst: &SocketAddr) -> Result { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0"), SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0"), } - .map_err(|e| RawIpError::FailedToBind(e.kind())) + .map_err(|e| RawIpError::FailedToBind(e)) } /// Return the source IP address given the destination IP address diff --git a/rust/src/nasl/builtin/regex/mod.rs b/rust/src/nasl/builtin/regex/mod.rs index e2464c7a4..eda1fdfba 100644 --- a/rust/src/nasl/builtin/regex/mod.rs +++ b/rust/src/nasl/builtin/regex/mod.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::*; use regex::{Regex, RegexBuilder}; use thiserror::Error; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum RegexError { #[error("Error building regular expression pattern: {0}")] BuildingError(regex::Error), diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index b6efec0c9..60ec631ea 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -25,7 +25,7 @@ impl From for LibError { } } -#[derive(Clone, Debug, Error)] +#[derive(Debug, Error)] pub struct SshError { pub kind: SshErrorKind, id: Option, diff --git a/rust/src/nasl/builtin/string/mod.rs b/rust/src/nasl/builtin/string/mod.rs index 69458e976..957fc8e38 100644 --- a/rust/src/nasl/builtin/string/mod.rs +++ b/rust/src/nasl/builtin/string/mod.rs @@ -23,7 +23,7 @@ use crate::nasl::prelude::*; use super::BuiltinError; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] #[error("{0}")] pub struct StringError(#[from] std::fmt::Error); diff --git a/rust/src/nasl/interpreter/error.rs b/rust/src/nasl/interpreter/error.rs index 66700acb6..7602ca448 100644 --- a/rust/src/nasl/interpreter/error.rs +++ b/rust/src/nasl/interpreter/error.rs @@ -7,7 +7,7 @@ use crate::nasl::syntax::{Statement, SyntaxError, TokenCategory}; use crate::nasl::utils::error::FnError; use thiserror::Error; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] /// An error that occurred while calling a function #[error("Error while calling function '{function}': {kind}")] pub struct FunctionCallError { @@ -32,7 +32,7 @@ impl FunctionCallError { } } -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] /// Is used to represent an error while interpreting #[error("{} {kind}", self.format_origin())] pub struct InterpretError { @@ -63,7 +63,7 @@ impl InterpretError { } } -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] /// Is used to give hints to the user how to react on an error while interpreting pub enum InterpretErrorKind { /// When returned context is a function when a value is required. diff --git a/rust/src/nasl/test_utils.rs b/rust/src/nasl/test_utils.rs index ef0094121..e132c14d7 100644 --- a/rust/src/nasl/test_utils.rs +++ b/rust/src/nasl/test_utils.rs @@ -24,7 +24,7 @@ use super::{ // The following exists to trick the trait solver into // believing me that everything is fine. Doing this naively // runs into some compiler errors. -trait CloneableFn: Fn(NaslResult) -> bool + Sync + Send { +trait CloneableFn: Fn(&NaslResult) -> bool + Sync + Send { fn clone_box<'a>(&self) -> Box where Self: 'a; @@ -32,7 +32,7 @@ trait CloneableFn: Fn(NaslResult) -> bool + Sync + Send { impl CloneableFn for F where - F: Fn(NaslResult) -> bool + Clone + Sync + Send, + F: Fn(&NaslResult) -> bool + Clone + Sync + Send, { fn clone_box<'a>(&self) -> Box where @@ -184,7 +184,7 @@ where pub fn check( &mut self, line: impl Into, - f: impl Fn(NaslResult) -> bool + 'static + Clone + Sync + Send, + f: impl Fn(&NaslResult) -> bool + 'static + Clone + Sync + Send, expected: Option>, ) -> &mut Self { self.add_line( @@ -327,7 +327,7 @@ where fn compare_result(&self, result: &Result, reference: &TestResult) -> bool { match reference { TestResult::Ok(val) => result.as_ref().unwrap() == val, - TestResult::GenericCheck(f, _) => f(result.clone()), + TestResult::GenericCheck(f, _) => f(result), TestResult::None => true, } } @@ -399,14 +399,14 @@ macro_rules! check_err_matches { |e| { if let Err(e) = e { // Convert with try_into to allow using - // the variants of `FnError` directly without + // the variants of `FnErrorKind` directly without // having to wrap them in the outer enum. let converted = e.try_into(); // This is only irrefutable for the // FnError -> FnError conversion but not for others. #[allow(irrefutable_let_patterns)] if let Ok(e) = converted { - matches!(e, $pat) + matches!(e, &$pat) } else { false } diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 65a25ce62..07c6529e9 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -9,7 +9,7 @@ use crate::nasl::prelude::NaslValue; use crate::storage::StorageError; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] #[error("{kind}")] pub struct FnError { #[source] @@ -75,7 +75,7 @@ impl From for FnError { } } -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum FnErrorKind { #[error("{0}")] Argument(ArgumentError), @@ -127,33 +127,33 @@ impl From for FnError { } } -impl TryFrom for ArgumentError { +impl<'a> TryFrom<&'a FnError> for &'a ArgumentError { type Error = (); - fn try_from(value: FnError) -> Result { - match value.kind { + fn try_from(value: &'a FnError) -> Result { + match &value.kind { FnErrorKind::Argument(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for InternalError { +impl<'a> TryFrom<&'a FnError> for &'a InternalError { type Error = (); - fn try_from(value: FnError) -> Result { - match value.kind { + fn try_from(value: &'a FnError) -> Result { + match &value.kind { FnErrorKind::Internal(e) => Ok(e), _ => Err(()), } } } -impl TryFrom for BuiltinError { +impl<'a> TryFrom<&'a FnError> for &'a BuiltinError { type Error = (); - fn try_from(value: FnError) -> Result { - match value.kind { + fn try_from(value: &'a FnError) -> Result { + match &value.kind { FnErrorKind::Builtin(e) => Ok(e), _ => Err(()), } diff --git a/rust/src/scanner/error.rs b/rust/src/scanner/error.rs index 0054c59d3..545eedeec 100644 --- a/rust/src/scanner/error.rs +++ b/rust/src/scanner/error.rs @@ -24,7 +24,7 @@ pub enum ExecuteError { Parameter(crate::models::Parameter), } -#[derive(Debug, Clone)] +#[derive(Debug)] /// Contains the result of a executed script pub enum ScriptResultKind { /// Contains the code provided by exit call or 0 when script finished successful without exit @@ -46,7 +46,7 @@ pub enum ScriptResultKind { Error(InterpretError), } -#[derive(Debug, Clone)] +#[derive(Debug)] /// Contains meta data of the script and its result pub struct ScriptResult { /// Object identifier of the script @@ -66,10 +66,6 @@ impl ScriptResult { pub fn has_succeeded(&self) -> bool { matches!(&self.kind, ScriptResultKind::ReturnCode(0)) } - /// Returns true when the return code of the script not 0 - pub fn has_failed(&self) -> bool { - !self.has_succeeded() - } /// Returns true when the script didn't run pub fn has_not_run(&self) -> bool { diff --git a/rust/src/scanner/running_scan.rs b/rust/src/scanner/running_scan.rs index c357e4217..e2884fe3f 100644 --- a/rust/src/scanner/running_scan.rs +++ b/rust/src/scanner/running_scan.rs @@ -122,7 +122,7 @@ impl RunningScan { } debug!(result=?result, "script finished"); - if result.has_failed() { + if !result.has_succeeded() { end_phase = Phase::Failed; } } diff --git a/rust/src/scanner/scan_runner.rs b/rust/src/scanner/scan_runner.rs index b0b9081ff..f9120a1c0 100644 --- a/rust/src/scanner/scan_runner.rs +++ b/rust/src/scanner/scan_runner.rs @@ -394,18 +394,14 @@ exit({rc}); dispatcher: DefaultDispatcher, ) -> (Vec, Vec) { let result = run(vts.to_vec(), dispatcher).await.expect("success run"); - let success = result - .clone() + let (success, rest): (Vec<_>, Vec<_>) = result .into_iter() .filter_map(|x| x.ok()) - .filter(|x| x.has_succeeded()) - .collect::>(); - let failure = result + .partition(|x| x.has_succeeded()); + let failure = rest .into_iter() - .filter_map(|x| x.ok()) - .filter(|x| x.has_failed()) - .filter(|x| x.has_not_run()) - .collect::>(); + .filter(|x| !x.has_succeeded() && x.has_not_run()) + .collect(); (success, failure) } diff --git a/rust/src/scanner/vt_runner.rs b/rust/src/scanner/vt_runner.rs index eae697909..a7bc69292 100644 --- a/rust/src/scanner/vt_runner.rs +++ b/rust/src/scanner/vt_runner.rs @@ -206,7 +206,7 @@ impl<'a, Stack: ScannerStack> VTRunner<'a, Stack> { while let Some(r) = results.next().await { match r { Ok(NaslValue::Exit(x)) => return ScriptResultKind::ReturnCode(x), - Err(e) => return ScriptResultKind::Error(e.clone()), + Err(e) => return ScriptResultKind::Error(e), Ok(x) => { trace!(statement_result=?x); } diff --git a/rust/src/scannerctl/error.rs b/rust/src/scannerctl/error.rs index 7a4a40a88..18f3e1771 100644 --- a/rust/src/scannerctl/error.rs +++ b/rust/src/scannerctl/error.rs @@ -16,7 +16,7 @@ use scannerlib::{ scanner::ExecuteError, }; -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum CliErrorKind { WrongAction, @@ -52,7 +52,7 @@ impl CliErrorKind { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct CliError { pub filename: String, pub kind: CliErrorKind, From 35820f1593bf457a1dfe5e37703c894500e18116 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 11 Nov 2024 10:11:51 +0100 Subject: [PATCH 31/36] Move PacketForgeryError into RawIpError --- rust/src/nasl/builtin/error.rs | 5 ----- rust/src/nasl/builtin/raw_ip/mod.rs | 4 ++-- rust/src/nasl/builtin/raw_ip/packet_forgery.rs | 18 +++++++++++++----- rust/src/nasl/mod.rs | 1 + 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/rust/src/nasl/builtin/error.rs b/rust/src/nasl/builtin/error.rs index 9ce464fe7..9fd6c52c1 100644 --- a/rust/src/nasl/builtin/error.rs +++ b/rust/src/nasl/builtin/error.rs @@ -32,9 +32,6 @@ pub enum BuiltinError { KB(KBError), #[cfg(feature = "nasl-builtin-raw-ip")] #[error("{0}")] - PacketForgery(super::raw_ip::PacketForgeryError), - #[cfg(feature = "nasl-builtin-raw-ip")] - #[error("{0}")] RawIp(super::raw_ip::RawIpError), } @@ -77,7 +74,5 @@ builtin_error_variant!(IsotimeError, Isotime); builtin_error_variant!(RegexError, Regex); builtin_error_variant!(KBError, KB); -#[cfg(feature = "nasl-builtin-raw-ip")] -builtin_error_variant!(super::raw_ip::PacketForgeryError, PacketForgery); #[cfg(feature = "nasl-builtin-raw-ip")] builtin_error_variant!(super::raw_ip::RawIpError, RawIp); diff --git a/rust/src/nasl/builtin/raw_ip/mod.rs b/rust/src/nasl/builtin/raw_ip/mod.rs index afab04c48..25924f4d4 100644 --- a/rust/src/nasl/builtin/raw_ip/mod.rs +++ b/rust/src/nasl/builtin/raw_ip/mod.rs @@ -17,8 +17,6 @@ use thiserror::Error; pub enum RawIpError { #[error("Failed to get local MAC address.")] FailedToGetLocalMacAddress, - #[error("Failed to create packet from buffer.")] - FailedToCreatePacket, #[error("Failed to get device list.")] FailedToGetDeviceList, #[error("Invalid IP address.")] @@ -27,6 +25,8 @@ pub enum RawIpError { FailedToBind(io::Error), #[error("No route to destination.")] NoRouteToDestination, + #[error("{0}")] + PacketForgery(PacketForgeryError), } pub struct RawIp; diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 8d61eebfc..8e43b0cf0 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -46,6 +46,14 @@ pub enum PacketForgeryError { ParseSocketAddr(std::net::AddrParseError), #[error("Failed to send packet. {0}")] SendPacket(std::io::Error), + #[error("Failed to create packet from buffer.")] + CreatePacket, +} + +impl From for FnError { + fn from(e: PacketForgeryError) -> Self { + RawIpError::PacketForgery(e).into() + } } fn error(s: String) -> FnError { @@ -54,7 +62,7 @@ fn error(s: String) -> FnError { macro_rules! custom_error { ($a:expr, $b:expr) => { - Err(PacketForgeryError::Custom(format!($a, $b)).into()) + Err(RawIpError::PacketForgery(PacketForgeryError::Custom(format!($a, $b))).into()) }; } @@ -157,7 +165,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result *x as u8, @@ -409,7 +417,7 @@ fn dump_ip_packet(register: &Register, _: &Context) -> Result { let pkt = packet::ipv4::Ipv4Packet::new(data) - .ok_or_else(|| RawIpError::FailedToCreatePacket)?; + .ok_or_else(|| PacketForgeryError::CreatePacket)?; println!("\tip_hl={}", pkt.get_header_length()); println!("\tip_v={}", pkt.get_version()); @@ -1794,7 +1802,7 @@ fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index ca9a21a6d..c150e41c6 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -13,6 +13,7 @@ pub mod prelude { pub use super::syntax::FSPluginLoader; pub use super::syntax::Loader; pub use super::syntax::NaslValue; + pub use super::utils::error::FnErrorKind; pub use super::utils::error::WithErrorInfo; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; From babafc4e1f2e139978da01142d862c005ed2bac0 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 11 Nov 2024 10:18:45 +0100 Subject: [PATCH 32/36] Make BuiltinError return Null by default --- rust/src/nasl/utils/error.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 07c6529e9..855bcb0ca 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -60,7 +60,11 @@ impl From for FnError { impl From for FnError { fn from(kind: BuiltinError) -> Self { - FnError::from_kind(FnErrorKind::Builtin(kind)) + FnError { + kind: FnErrorKind::Builtin(kind), + retryable: false, + return_value: Some(NaslValue::Null), + } } } From 54fe4f10b5a31832e00c4d64e86326dcb82b1466 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 11 Nov 2024 14:24:16 +0100 Subject: [PATCH 33/36] Re-use WithErrorInfo --- rust/src/nasl/builtin/cryptographic/rsa.rs | 7 ++-- rust/src/nasl/builtin/http/mod.rs | 2 +- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 2 +- rust/src/nasl/builtin/ssh/error.rs | 8 +++- rust/src/nasl/builtin/ssh/mod.rs | 11 ++--- rust/src/nasl/interpreter/tests/retry.rs | 2 +- rust/src/nasl/mod.rs | 2 + rust/src/nasl/utils/error.rs | 44 +++++++++++++------- 8 files changed, 52 insertions(+), 26 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/rsa.rs b/rust/src/nasl/builtin/cryptographic/rsa.rs index 4e518ff02..214d5fa2a 100644 --- a/rust/src/nasl/builtin/cryptographic/rsa.rs +++ b/rust/src/nasl/builtin/cryptographic/rsa.rs @@ -57,12 +57,13 @@ fn rsa_private_decrypt( ) { Ok(val) => Ok(val), Err(code) => Err( - FnError::from(CryptographicError::RSA(format!("Error code {}", code))) - .with_return_value(NaslValue::Array(vec![ + FnError::from(CryptographicError::RSA(format!("Error code {}", code))).with( + ReturnValue(NaslValue::Array(vec![ NaslValue::Data(n.to_vec()), NaslValue::Data(e.to_vec()), NaslValue::Data(d.to_vec()), ])), + ), ), } .map_err(|e| CryptographicError::RSA(e.to_string()))?; @@ -75,7 +76,7 @@ fn rsa_private_decrypt( "Error code {}", code ))) - .with_return_value(NaslValue::Data(data.to_vec()))), + .with(ReturnValue(NaslValue::Data(data.to_vec())))), } .map_err(|e| CryptographicError::RSA(e.to_string()))? } else { diff --git a/rust/src/nasl/builtin/http/mod.rs b/rust/src/nasl/builtin/http/mod.rs index af572134b..9fd9274c3 100644 --- a/rust/src/nasl/builtin/http/mod.rs +++ b/rust/src/nasl/builtin/http/mod.rs @@ -343,7 +343,7 @@ impl NaslHttp { handles.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(FnError::from(HttpError::HandleIdNotFound(handle)).with_return_value(-1)), + _ => Err(HttpError::HandleIdNotFound(handle).with(ReturnValue(-1))), } } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index 506f1781e..7190e2152 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -19,7 +19,7 @@ pub fn ipstr2ipaddr(ip_addr: &str) -> Result { Err(_) => Err(FnError::from(ArgumentError::WrongArgument( "Invalid IP address".to_string(), )) - .with_return_value(NaslValue::Null)), + .with(ReturnValue(NaslValue::Null))), } } diff --git a/rust/src/nasl/builtin/ssh/error.rs b/rust/src/nasl/builtin/ssh/error.rs index 60ec631ea..396acd60d 100644 --- a/rust/src/nasl/builtin/ssh/error.rs +++ b/rust/src/nasl/builtin/ssh/error.rs @@ -117,6 +117,8 @@ pub enum SshErrorKind { } impl WithErrorInfo for SshError { + type Error = SshError; + fn with(mut self, id: SessionId) -> SshError { self.id = Some(id); self @@ -125,6 +127,8 @@ impl WithErrorInfo for SshError { #[cfg(feature = "nasl-builtin-libssh")] impl WithErrorInfo for SshError { + type Error = SshError; + fn with(mut self, source: libssh_rs::Error) -> SshError { self.source = Some(source.into()); self @@ -133,6 +137,8 @@ impl WithErrorInfo for SshError { #[cfg(not(feature = "nasl-builtin-libssh"))] impl WithErrorInfo for SshError { + type Error = SshError; + fn with(mut self, source: russh::Error) -> SshError { self.source = Some(source.into()); self @@ -150,7 +156,7 @@ impl From for SshError { } impl SshErrorKind { - pub fn with(self, m: Info) -> SshError + pub fn with(self, m: Info) -> >::Error where SshError: WithErrorInfo, { diff --git a/rust/src/nasl/builtin/ssh/mod.rs b/rust/src/nasl/builtin/ssh/mod.rs index 17dcfb723..53c65aeda 100644 --- a/rust/src/nasl/builtin/ssh/mod.rs +++ b/rust/src/nasl/builtin/ssh/mod.rs @@ -533,11 +533,12 @@ impl Ssh { } AuthStatus::Success => break, status => { - return Err(FnError::from( - SshErrorKind::UnexpectedAuthenticationStatus(format!("{:?}", status)) - .with(session_id), - ) - .with_return_value(-1)); + return Err(SshErrorKind::UnexpectedAuthenticationStatus(format!( + "{:?}", + status + )) + .with(session_id) + .with(ReturnValue(-1))); } } } diff --git a/rust/src/nasl/interpreter/tests/retry.rs b/rust/src/nasl/interpreter/tests/retry.rs index d987ff850..d850f03ff 100644 --- a/rust/src/nasl/interpreter/tests/retry.rs +++ b/rust/src/nasl/interpreter/tests/retry.rs @@ -20,7 +20,7 @@ impl Counter { #[nasl_function] fn check_counter_retry(&mut self) -> Result { - self.check_and_increment().map_err(|e| e.with_retryable()) + self.check_and_increment().map_err(|e| e.with(Retryable)) } #[nasl_function] diff --git a/rust/src/nasl/mod.rs b/rust/src/nasl/mod.rs index c150e41c6..4436e50bb 100644 --- a/rust/src/nasl/mod.rs +++ b/rust/src/nasl/mod.rs @@ -14,6 +14,8 @@ pub mod prelude { pub use super::syntax::Loader; pub use super::syntax::NaslValue; pub use super::utils::error::FnErrorKind; + pub use super::utils::error::Retryable; + pub use super::utils::error::ReturnValue; pub use super::utils::error::WithErrorInfo; pub use super::utils::function::CheckedPositionals; pub use super::utils::function::FromNaslValue; diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 855bcb0ca..7b753dd20 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -27,16 +27,6 @@ impl FnError { self.retryable } - pub fn with_return_value(mut self, val: impl Into) -> Self { - self.return_value = Some(val.into()); - self - } - - pub fn with_retryable(mut self) -> Self { - self.retryable = true; - self - } - fn from_kind(kind: FnErrorKind) -> FnError { Self { kind, @@ -121,10 +111,6 @@ impl InternalError { } } -pub trait WithErrorInfo { - fn with(self, e: Info) -> Self; -} - impl From for FnError { fn from(value: StorageError) -> Self { FnErrorKind::Internal(InternalError::Storage(value)).into() @@ -164,6 +150,36 @@ impl<'a> TryFrom<&'a FnError> for &'a BuiltinError { } } +pub trait WithErrorInfo { + type Error; + fn with(self, e: Info) -> Self::Error; +} + +pub struct Retryable; + +impl> WithErrorInfo for E { + type Error = FnError; + + fn with(self, _: Retryable) -> Self::Error { + let mut e = self.into(); + e.retryable = true; + e + } +} + +pub struct ReturnValue(pub T); + +impl, E: Into> WithErrorInfo> for E { + type Error = FnError; + + fn with(self, val: ReturnValue) -> Self::Error { + let mut e = self.into(); + let val = val.0.into(); + e.return_value = Some(val); + e + } +} + impl ArgumentError { /// Helper function to quickly construct a `WrongArgument` variant /// containing the name of the argument, the expected value and From 199b2651d492455e85d6ed09d96a7a03abff96ff Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Mon, 11 Nov 2024 16:42:15 +0100 Subject: [PATCH 34/36] Change Option to ReturnBehavior --- rust/src/nasl/utils/error.rs | 20 +++++++++++++------- rust/src/scannerctl/interpret/mod.rs | 11 ++++++++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/rust/src/nasl/utils/error.rs b/rust/src/nasl/utils/error.rs index 7b753dd20..409d0cf6d 100644 --- a/rust/src/nasl/utils/error.rs +++ b/rust/src/nasl/utils/error.rs @@ -14,13 +14,19 @@ use crate::storage::StorageError; pub struct FnError { #[source] pub kind: FnErrorKind, - return_value: Option, + return_behavior: ReturnBehavior, retryable: bool, } +#[derive(Debug)] +pub enum ReturnBehavior { + ExitScript, + ReturnValue(NaslValue), +} + impl FnError { - pub fn return_value(&self) -> &Option { - &self.return_value + pub fn return_behavior(&self) -> &ReturnBehavior { + &self.return_behavior } pub fn retryable(&self) -> bool { @@ -30,7 +36,7 @@ impl FnError { fn from_kind(kind: FnErrorKind) -> FnError { Self { kind, - return_value: None, + return_behavior: ReturnBehavior::ExitScript, retryable: false, } } @@ -53,7 +59,7 @@ impl From for FnError { FnError { kind: FnErrorKind::Builtin(kind), retryable: false, - return_value: Some(NaslValue::Null), + return_behavior: ReturnBehavior::ReturnValue(NaslValue::Null), } } } @@ -64,7 +70,7 @@ impl From for FnError { Self { kind: FnErrorKind::Internal(kind), retryable, - return_value: None, + return_behavior: ReturnBehavior::ExitScript, } } } @@ -175,7 +181,7 @@ impl, E: Into> WithErrorInfo> for E { fn with(self, val: ReturnValue) -> Self::Error { let mut e = self.into(); let val = val.0.into(); - e.return_value = Some(val); + e.return_behavior = ReturnBehavior::ReturnValue(val); e } } diff --git a/rust/src/scannerctl/interpret/mod.rs b/rust/src/scannerctl/interpret/mod.rs index 39e6bc9cb..1480fc0ec 100644 --- a/rust/src/scannerctl/interpret/mod.rs +++ b/rust/src/scannerctl/interpret/mod.rs @@ -8,7 +8,7 @@ use std::{ }; use futures::StreamExt; -use scannerlib::nasl::interpreter::CodeInterpreter; +use scannerlib::nasl::{interpreter::CodeInterpreter, utils::error::ReturnBehavior}; use scannerlib::nasl::{ interpreter::InterpretErrorKind, prelude::*, @@ -140,8 +140,13 @@ where Ok(x) => x, Err(e) => { if let InterpretErrorKind::FunctionCallError(ref fe) = e.kind { - tracing::warn!("{}", e.to_string()); - fe.kind.return_value().clone().unwrap_or_default() + match fe.kind.return_behavior() { + ReturnBehavior::ExitScript => return Err(e.into()), + ReturnBehavior::ReturnValue(val) => { + tracing::warn!("{}", e.to_string()); + val.clone() + } + } } else { return Err(e.into()); } From 0f63731d5ab662d538b14a728d9245fb52c415c3 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Wed, 27 Nov 2024 09:22:40 +0100 Subject: [PATCH 35/36] Fix clippy lints --- .../nasl/builtin/cryptographic/aes_cmac.rs | 4 +-- rust/src/nasl/builtin/cryptographic/mod.rs | 6 ++-- rust/src/nasl/builtin/cryptographic/rc4.rs | 12 ++++---- rust/src/nasl/builtin/cryptographic/rsa.rs | 28 +++++++++---------- rust/src/nasl/builtin/network/socket.rs | 17 +++++------ .../src/nasl/builtin/raw_ip/packet_forgery.rs | 2 +- rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs | 2 +- rust/src/nasl/utils/mod.rs | 2 +- 8 files changed, 35 insertions(+), 38 deletions(-) diff --git a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs index 7acab3e91..4e80eb718 100644 --- a/rust/src/nasl/builtin/cryptographic/aes_cmac.rs +++ b/rust/src/nasl/builtin/cryptographic/aes_cmac.rs @@ -20,8 +20,8 @@ fn aes_cmac(register: &Register, _: &Context) -> Result { let key = get_key(register)?; let data = get_data(register)?; - let mut mac = Cmac::::new_from_slice(key) - .map_err(|e| CryptographicError::AesCmacInvalidLength(e))?; + let mut mac = + Cmac::::new_from_slice(key).map_err(CryptographicError::AesCmacInvalidLength)?; mac.update(data); Ok(mac.finalize().into_bytes().to_vec().into()) diff --git a/rust/src/nasl/builtin/cryptographic/mod.rs b/rust/src/nasl/builtin/cryptographic/mod.rs index 27362e849..1702331aa 100644 --- a/rust/src/nasl/builtin/cryptographic/mod.rs +++ b/rust/src/nasl/builtin/cryptographic/mod.rs @@ -36,9 +36,9 @@ pub enum CryptographicError { #[error("Invalid length of key in AesCmac {0}.")] AesCmacInvalidLength(digest::InvalidLength), #[error("Error in RSA: {0}.")] - RSA(String), + Rsa(String), #[error("Error in RC4: {0}.")] - RC4(String), + Rc4(String), } enum Crypt { @@ -62,7 +62,7 @@ fn get_required_named_data<'a>( "a String or Data Value", format!("{:?}", x).as_str(), )), - _ => Err(ArgumentError::MissingNamed(vec![key.into()]).into()), + _ => Err(ArgumentError::MissingNamed(vec![key.into()])), } } diff --git a/rust/src/nasl/builtin/cryptographic/rc4.rs b/rust/src/nasl/builtin/cryptographic/rc4.rs index c9874cf5e..224e41027 100644 --- a/rust/src/nasl/builtin/cryptographic/rc4.rs +++ b/rust/src/nasl/builtin/cryptographic/rc4.rs @@ -65,7 +65,7 @@ impl CipherHandlers { ) -> Result { let hd = match register.named("hd") { Some(ContextType::Value(NaslValue::Number(x))) => *x as i32, - _ => return Err(CryptographicError::RC4("Handler ID not found".to_string()).into()), + _ => return Err(CryptographicError::Rc4("Handler ID not found".to_string()).into()), }; let mut handlers = lock_handlers(&self.cipher_handlers)?; @@ -74,7 +74,7 @@ impl CipherHandlers { handlers.remove(i); Ok(NaslValue::Number(0)) } - _ => Err(CryptographicError::RC4(format!("Handler ID {} not found", hd)).into()), + _ => Err(CryptographicError::Rc4(format!("Handler ID {} not found", hd)).into()), } } @@ -89,7 +89,7 @@ impl CipherHandlers { let key = match get_key(register) { Ok(k) if !k.is_empty() => k.to_vec(), - _ => return Err(CryptographicError::RC4("Missing Key argument".to_string()).into()), + _ => return Err(CryptographicError::Rc4("Missing Key argument".to_string()).into()), }; let rc_handler = Rc4Key::build_handler_from_key(key.to_vec())?; @@ -116,7 +116,7 @@ impl CipherHandlers { pub fn rc4_encrypt(&self, register: &Register, _: &Context) -> Result { let data = match get_data(register) { Ok(d) if !d.is_empty() => d.to_vec(), - _ => return Err(CryptographicError::RC4("Missing data argument".to_string()).into()), + _ => return Err(CryptographicError::Rc4("Missing data argument".to_string()).into()), }; let hd = match register.named("hd") { @@ -135,7 +135,7 @@ impl CipherHandlers { let key = match get_key(register) { Ok(k) if !k.is_empty() => k.to_vec(), - _ => return Err(CryptographicError::RC4("Missing Key argument".to_string()).into()), + _ => return Err(CryptographicError::Rc4("Missing Key argument".to_string()).into()), }; let mut rc_handler = Rc4Key::build_handler_from_key(key.to_vec())?; @@ -156,7 +156,7 @@ macro_rules! build_rc4key_enum { fn build_handler_from_key(bl: Vec) -> Result { match bl.len() { $($l => Ok(Self::$i(Rc4::new_from_slice(bl.as_slice()).unwrap())),)* - _ => {return Err(CryptographicError::RC4("RC4 Key size not supported".into()).into())} + _ => {return Err(CryptographicError::Rc4("RC4 Key size not supported".into()).into())} } } diff --git a/rust/src/nasl/builtin/cryptographic/rsa.rs b/rust/src/nasl/builtin/cryptographic/rsa.rs index 214d5fa2a..2ce383d8a 100644 --- a/rust/src/nasl/builtin/cryptographic/rsa.rs +++ b/rust/src/nasl/builtin/cryptographic/rsa.rs @@ -26,15 +26,15 @@ fn rsa_public_encrypt( rsa::BigUint::from_bytes_be(n), rsa::BigUint::from_bytes_be(e), ) - .map_err(|e| CryptographicError::RSA(e.to_string()))?; + .map_err(|e| CryptographicError::Rsa(e.to_string()))?; let biguint_data = BigUint::from_bytes_be(data); let enc_data = if pad { pub_key .encrypt(&mut rng, Pkcs1v15Encrypt, data) - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? } else { rsa::hazmat::rsa_encrypt(&pub_key, &biguint_data) - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? .to_bytes_be() }; Ok(enc_data.to_vec().into()) @@ -57,7 +57,7 @@ fn rsa_private_decrypt( ) { Ok(val) => Ok(val), Err(code) => Err( - FnError::from(CryptographicError::RSA(format!("Error code {}", code))).with( + FnError::from(CryptographicError::Rsa(format!("Error code {}", code))).with( ReturnValue(NaslValue::Array(vec![ NaslValue::Data(n.to_vec()), NaslValue::Data(e.to_vec()), @@ -66,22 +66,22 @@ fn rsa_private_decrypt( ), ), } - .map_err(|e| CryptographicError::RSA(e.to_string()))?; + .map_err(|e| CryptographicError::Rsa(e.to_string()))?; let mut rng = OsRng; let biguint_data = BigUint::from_bytes_be(data); let dec_data = if pad { match priv_key.decrypt(Pkcs1v15Encrypt, data) { Ok(val) => Ok(val), - Err(code) => Err(FnError::from(CryptographicError::RSA(format!( + Err(code) => Err(FnError::from(CryptographicError::Rsa(format!( "Error code {}", code ))) .with(ReturnValue(NaslValue::Data(data.to_vec())))), } - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? } else { rsa::hazmat::rsa_decrypt_and_check(&priv_key, Some(&mut rng), &biguint_data) - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? .to_bytes_be() }; @@ -90,20 +90,20 @@ fn rsa_private_decrypt( #[nasl_function(named(data, pem, passphrase))] fn rsa_sign(data: &[u8], pem: &[u8], passphrase: Option<&str>) -> Result { - let pem_str = std::str::from_utf8(pem).map_err(|e| CryptographicError::RSA(e.to_string()))?; + let pem_str = std::str::from_utf8(pem).map_err(|e| CryptographicError::Rsa(e.to_string()))?; let rsa: RsaPrivateKey = if passphrase.unwrap_or_default() != "" { pkcs8::DecodePrivateKey::from_pkcs8_encrypted_pem(pem_str, passphrase.unwrap_or_default()) - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? } else { RsaPrivateKey::from_pkcs8_pem(pem_str) - .map_err(|e| CryptographicError::RSA(e.to_string()))? + .map_err(|e| CryptographicError::Rsa(e.to_string()))? }; let mut hasher = Sha1::new_with_prefix(data); hasher.update(data); let hashed_data = hasher.finalize(); let signature = rsa .sign(Pkcs1v15Sign::new_unprefixed(), &hashed_data) - .map_err(|e| CryptographicError::RSA(e.to_string()))?; + .map_err(|e| CryptographicError::Rsa(e.to_string()))?; Ok(signature.into()) } @@ -112,11 +112,11 @@ fn rsa_public_decrypt(sign: &[u8], n: &[u8], e: &[u8]) -> Result i32::MAX as i64 { return Err(SocketError::WrongArgument( "the given flags value is out of range".to_string(), - ) - .into()); + )); } Ok(conn.send_with_flags(data, flags as i32)?) } else { @@ -245,7 +244,7 @@ impl NaslSockets { match conn.read_with_timeout(&mut data[pos..], timeout) { Ok(n) => pos += n, Err(e) if e.kind() == io::ErrorKind::TimedOut => break, - Err(e) => return Err(SocketError::from(e).into()), + Err(e) => return Err(SocketError::from(e)), } } Ok(NaslValue::Data(data[..pos].to_vec())) @@ -295,12 +294,10 @@ impl NaslSockets { } NaslSocket::Udp(_) => Err(SocketError::Diagnostic( "This function is only available for TCP connections".to_string(), - ) - .into()), + )), NaslSocket::Closed => Err(SocketError::WrongArgument( "the given socket FD is already closed".to_string(), - ) - .into()), + )), } } @@ -335,9 +332,9 @@ impl NaslSockets { Some(_) => Err(SocketError::Diagnostic( "KB key 'Secret/kdc_port' has wrong type".to_string(), )), - None => Err( - SocketError::Diagnostic("KB key 'Secret/kdc_port' is not set".to_string()).into(), - ), + None => Err(SocketError::Diagnostic( + "KB key 'Secret/kdc_port' is not set".to_string(), + )), }?; let use_tcp: bool = get_kb_item(context, "Secret/kdc_use_tcp")? diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 8e43b0cf0..2a58b31ec 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -2074,7 +2074,7 @@ fn nasl_send_packet(register: &Register, configs: &Context) -> Result Result { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0"), SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0"), } - .map_err(|e| RawIpError::FailedToBind(e)) + .map_err(RawIpError::FailedToBind) } /// Return the source IP address given the destination IP address diff --git a/rust/src/nasl/utils/mod.rs b/rust/src/nasl/utils/mod.rs index f2e7bd39c..77d690815 100644 --- a/rust/src/nasl/utils/mod.rs +++ b/rust/src/nasl/utils/mod.rs @@ -52,7 +52,7 @@ pub fn get_named_parameter<'a>( match registrat.named(key) { None => { if required { - Err(ArgumentError::MissingNamed(vec![key.to_owned()]).into()) + Err(ArgumentError::MissingNamed(vec![key.to_owned()])) } else { // we use exit because a named value can be intentionally set to null and may be // treated differently when it is not set compared to set but null. From e1d20c6a273a1c67c857c40309a3f3c57aa84437 Mon Sep 17 00:00:00 2001 From: Toni Peter Date: Thu, 5 Dec 2024 14:31:40 +0100 Subject: [PATCH 36/36] Add documentation on new error handling --- rust/src/nasl/utils/README.md | 116 +++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/rust/src/nasl/utils/README.md b/rust/src/nasl/utils/README.md index 71c0b9e50..772ba6d17 100644 --- a/rust/src/nasl/utils/README.md +++ b/rust/src/nasl/utils/README.md @@ -2,5 +2,117 @@ Contains the necessary traits and helper functions to create builtin functions. -To register your function you have to add it into the context of an interpreter. -Usually that is done by adding it to [nasl-builtin-std::nasl_std_functions] so that it is registered on an default interpreter run. +# Error handling +This section briefly describes how to handle errors that occur during builtin functions. Builtin functions return a result with an error type `FnError`. This is a type that contains metadata about the error as well as its kind, described by the `FnErrorKind` enum, which is structured as follows + + +```rust +pub enum FnErrorKind { + Argument(ArgumentError), + Internal(InternalError), + Builtin(BuiltinError), +} +``` + +The variants represent three different kinds of errors: `ArgumentError` refers to errors caused by calling a function with the wrong arguments which typically reflect an error in the usage of the function by the script authors. + +`InternalError` refers to any error caused by failure of an internal process of the scanner (such as the storage). This reflects a deeper problem and may mean we cannot simply proceed with execution of the scan. + +Finally, `BuiltinError` represents any (more or less expected) error that occurred within a builtin function. This may include timeouts, authentication failures, etc.. + +## Metadata +As stated above, the metadata (return value, retryable) on how to handle a specific error are stored in a `FnError`. This means that authors of builtin functions always have the option of explicitly overriding any defaults for any specific case. However, in practice, the defaults should reflect the behavior what we want most of the time. + +### Return behavior +The return behavior of a given error specifies how an error should be handled during execution. This is specified by the following type: +```rust +enum ReturnBehavior { + ExitScript, + ReturnValue(NaslValue), +} +``` +When the interpreter encounters an error with `ReturnBehavior::ExitScript` behavior, it will unsurprisingly exit the script. If it encounters an error with `ReturnBehavior::ReturnValue(val)`, it will return `val` and continue execution. + +In the corresponding `From` impls, the `Argument` and `Internal` variants of `FnError` are automatically constructed with `ReturnBehavior::ExitScript`, meaning that they abort execution of the script. The `Builtin` variant is constructed with `ReturnBehavior::ReturnValue(NaslValue::Null)` by default, but this value can easily be overwritten when the error is created, for example: +```rust +HttpError::HandleIdNotFound(handle).with(ReturnValue(-1)) +``` + +### Retry behavior +Certain errors can be flagged as being solvable by retrying the operation that caused them. This is represented by a `retryable` boolean on `FnError`, which is `false` by default for all variants except for a specific internal error in the storage. However, this default behavior can be overwritten at error creation if needed, for example +```rust +HttpError::ConnectionFailed(...).with(Retryable) +``` +I also added a small test to make sure that the interpreter does actually retry retryable errors. + +## How to add a new error type for a builtin module +1. Add a custom error type for the builtin module. These can be of arbitrary form but a typical error type might look like +```rust +#[derive(Debug, Error)] +enum FooError { + #[error("Bar occurred.")] + Bar, + #[error("Baz occurred. Here is some more data: {0}")] + Baz(SomeData), +} +``` +This helps with keeping the error messages all in one place to ensure a common form. + +2. Add this builtin error as a variant of the `BuiltinError` type described above. +```rust +enum BuiltinError { + ... + Foo(FooError), + ... +} +``` + +3. For convenience, some `From` impls and `TryFrom` impls can make the error type easier to use by enabling use of the question mark operator. I added a tiny macro that implements these traits (because the implementations are usually trivial), so this comes down to one line too: +``` +builtin_error_variant!(Foo, FooError); +``` + +This is all that is needed to make this error usable in NASL functions: +```rust +fn check(a: usize) -> Result<(), FooError> { + if a == 0 { + Err(FooError::Bar) + } + else { + Ok(()) + } +} + +#[nasl_function] +fn foo(a: usize) -> Result { + check(a)?; + Ok(a) +} +``` + +As a side note, NASL functions can also return any concrete `impl Into` directly, so for this case we can also write + +```rust +#[nasl_function] +fn foo(a: usize) -> Result { + if a == 0 { + Err(FooError::Bar) + } + else { + Ok(a) + } +} +``` + +Note that the above `From` impls that are automatically written by the `builtin_error_variant!` macro can also be manually implemented if one wants to specify defaults for a specific error variant. For example + +```rust +impl From for FnError { + fn from(e: FooError) -> FnError { + match e { + FooError::Foo => BuiltinError::Foo(e).with(ReturnValue(-1)), + _ => BuiltinError::Foo(e).into(), + } + } +} +```