Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Global regex module #111

Merged
merged 5 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/cli/input/load_scripts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::lua::runtime::{
encode_ext::EncodeEXT, http_ext::HTTPEXT, payloads_ext::PayloadsEXT, utils_ext::UtilsEXT,
use crate::lua::{
model::LuaRunTime,
runtime::{
encode_ext::EncodeEXT, http_ext::HTTPEXT, payloads_ext::PayloadsEXT, utils_ext::UtilsEXT,
},
};
use crate::{filename_to_string, show_msg, CliErrors, LuaRunTime, MessageLevel};
use crate::{filename_to_string, show_msg, CliErrors, MessageLevel};
use glob::glob;
use log::error;
use mlua::Lua;
Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use cli::{
input::load_scripts::{get_scripts, valid_scripts},
};
use lua::{
loader::{LuaOptions, LuaRunTime},
parsing::files::filename_to_string,
run::LuaLoader,
model::LuaOptions, parsing::files::filename_to_string, run::LuaLoader,
threads::runner::iter_futures,
};
use reqwest::header::HeaderMap;
Expand Down
2 changes: 1 addition & 1 deletion src/lua/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod loader;
pub mod model;
pub mod network;
pub mod output;
pub mod parsing;
Expand Down
19 changes: 0 additions & 19 deletions src/lua/loader.rs → src/lua/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

use crate::cli::errors::CliErrors;
use crate::ScanTypes;
use log::error;
use mlua::Lua;

/// Setup The Lua Runtime
Expand All @@ -30,20 +28,3 @@ pub struct LuaOptions<'a> {
pub script_dir: &'a str,
pub env_vars: serde_json::Value,
}

/// check if the regex pattern is matching with this string or not without get the matched parts
pub fn is_match(pattern: String, resp: String) -> Result<bool, CliErrors> {
let re = fancy_regex::Regex::new(&pattern);
if let Ok(..) = re {
let matched = re.unwrap().is_match(&resp);
if matched.is_err() {
error!("Cannot match with resp value: {}", resp);
Err(CliErrors::RegexError)
} else {
Ok(matched.unwrap())
}
} else {
error!("Regex Pattern ERROR {:?}", pattern);
Err(CliErrors::RegexPatternError)
}
}
163 changes: 146 additions & 17 deletions src/lua/parsing/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

use crate::cli::errors::CliErrors;
use mlua::ExternalError;
use mlua::UserData;
use regex::RegexBuilder;
use tealr::TypeName;
Expand All @@ -27,71 +29,198 @@ pub struct ResponseMatcher {
}

impl ResponseMatcher {
pub fn match_and_body(&self, body: &str, text: Vec<String>, is_regex: Option<bool>) -> bool {
pub fn is_match(&self, pattern: String, resp: String) -> Result<bool, CliErrors> {
match RegexBuilder::new(&pattern)
.multi_line(self.multi_line)
.case_insensitive(self.case_insensitive)
.unicode(self.unicode)
.octal(self.octal)
.dot_matches_new_line(self.dot_matches_new_line)
.build()
{
Ok(re) => Ok(re.is_match(&resp)),
Err(_) => {
log::error!("Regex Pattern ERROR {:?}", pattern);
Err(CliErrors::RegexPatternError)
}
}
}

pub fn extract_data(
&self,
regex_pattern: &str,
response: &str,
) -> Result<Vec<String>, CliErrors> {
match RegexBuilder::new(&regex_pattern)
.multi_line(self.multi_line)
.case_insensitive(self.case_insensitive)
.unicode(self.unicode)
.octal(self.octal)
.dot_matches_new_line(self.dot_matches_new_line)
.build()
{
Ok(re) => {
let match_iter = re
.find_iter(response)
.map(|m| m.as_str().to_owned())
.collect();
Ok(match_iter)
}
Err(_) => {
log::error!("Regex Pattern ERROR {:?}", regex_pattern);
Err(CliErrors::RegexPatternError)
}
}
}
pub fn replace_txt(
&self,
regex_pattern: &str,
replacement: &str,
response: &str,
) -> Result<String, CliErrors> {
match RegexBuilder::new(&regex_pattern)
.multi_line(self.multi_line)
.case_insensitive(self.case_insensitive)
.unicode(self.unicode)
.octal(self.octal)
.dot_matches_new_line(self.dot_matches_new_line)
.build()
{
Ok(re) => {
let replace_output = re.replacen(response, 2, replacement).to_string();
Ok(replace_output)
}
Err(_) => {
log::error!("Regex Pattern ERROR {:?}", regex_pattern);
Err(CliErrors::RegexPatternError)
}
}
}
pub fn match_and_body(
&self,
body: &str,
text: Vec<String>,
is_regex: Option<bool>,
) -> Result<bool, CliErrors> {
let mut counter = 0;
for x in text.iter() {
if is_regex.unwrap_or(false) {
if let Ok(re_pattern) = RegexBuilder::new(x)
for search_pattern in text.iter() {
match is_regex.unwrap_or(false) {
true => match RegexBuilder::new(&search_pattern)
.multi_line(self.multi_line)
.case_insensitive(self.case_insensitive)
.unicode(self.unicode)
.octal(self.octal)
.dot_matches_new_line(self.dot_matches_new_line)
.build()
{
if re_pattern.is_match(body) {
Ok(re_pattern) => {
if re_pattern.is_match(body) {
counter += 1;
}
}
Err(_) => {
log::error!("Invalid regex pattern: {:?}", search_pattern);
return Err(CliErrors::RegexPatternError);
}
},
false => {
if body.contains(search_pattern) {
counter += 1;
}
}
} else if body.contains(x) {
counter += 1;
}
}
counter == text.len()
Ok(counter == text.len())
}

pub fn match_once_body(
&self,
body: String,
text: Vec<String>,
is_regex: Option<bool>,
) -> Vec<String> {
) -> Result<Vec<String>, CliErrors> {
let mut matched_data = Vec::new();
for pattern in text {
if is_regex.unwrap_or(false) {
if let Ok(re) = RegexBuilder::new(&pattern)
match is_regex.unwrap_or(false) {
true => match RegexBuilder::new(&pattern)
.multi_line(self.multi_line)
.case_insensitive(self.case_insensitive)
.unicode(self.unicode)
.octal(self.octal)
.dot_matches_new_line(self.dot_matches_new_line)
.build()
{
if re.is_match(&body) {
Ok(re) => {
if re.is_match(&body) {
matched_data.push(pattern);
}
}
Err(_) => {
log::error!("Invalid regex pattern: {:?}", pattern);
return Err(CliErrors::RegexPatternError);
}
},
false => {
if body.contains(&pattern) {
matched_data.push(pattern);
}
}
} else if body.contains(&pattern) {
matched_data.push(pattern);
}
}
matched_data
Ok(matched_data)
}
}

impl UserData for ResponseMatcher {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_method(
"is_match",
|_, this, (regex_pattern, response): (String, String)| {
let is_match = this.is_match(regex_pattern, response);
match is_match {
Ok(matched) => Ok(matched),
Err(err) => Err(err.to_lua_err()),
}
},
);
methods.add_method(
"match_body",
|_, this, (response, text_list, is_regex): (String, Vec<String>, Option<bool>)| {
Ok(this.match_and_body(&response, text_list, is_regex))
let body_match = this.match_and_body(&response, text_list, is_regex);
match body_match {
Ok(matched) => Ok(matched),
Err(err) => Err(err.to_lua_err()),
}
},
);
methods.add_method(
"match_body_once",
|_, this, (response, text_list, is_regex): (String, Vec<String>, Option<bool>)| {
let is_match = this.match_once_body(response, text_list, is_regex);
Ok(is_match)
match is_match {
Ok(matched) => Ok(matched),
Err(err) => Err(err.to_lua_err()),
}
},
);
methods.add_method(
"replace",
|_, this, (response, regex_pattern, replacement): (String, String, String)| {
let replace_output = this.replace_txt(&regex_pattern, &replacement, &response);
match replace_output {
Ok(replaced) => Ok(replaced),
Err(err) => Err(err.to_lua_err()),
}
},
);
methods.add_method(
"extract",
|_, this, (regex_pattern, response): (String, String)| {
let extract_data = this.extract_data(&regex_pattern, &response);
match extract_data {
Ok(data) => Ok(data),
Err(err) => Err(err.to_lua_err()),
}
},
);
methods.add_method_mut("options", |_, this, opts: mlua::Table| {
Expand Down
2 changes: 1 addition & 1 deletion src/lua/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::lua::runtime::{
use crate::{
cli::bar::BAR,
lua::{
loader::{LuaOptions, LuaRunTime},
model::{LuaOptions, LuaRunTime},
network::http::Sender,
output::report::AllReports,
},
Expand Down
2 changes: 1 addition & 1 deletion src/lua/runtime/encode_ext.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::LuaRunTime;
use crate::lua::model::LuaRunTime;

pub trait EncodeEXT {
fn add_encode_function(&self);
Expand Down
3 changes: 2 additions & 1 deletion src/lua/runtime/http_ext.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{
lua::{
model::LuaRunTime,
output::report::AllReports,
parsing::{files::filename_to_string, url::HttpMessage},
},
CliErrors, LuaRunTime,
CliErrors,
};
use log::{debug, error, info, warn};
use mlua::ExternalError;
Expand Down
2 changes: 1 addition & 1 deletion src/lua/runtime/payloads_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::lua::model::LuaRunTime;
use crate::lua::parsing::html::Location;
use crate::lua::payloads;
use crate::LuaRunTime;

pub trait PayloadsEXT {
fn add_payloadsfuncs(&self);
Expand Down
21 changes: 2 additions & 19 deletions src/lua/runtime/utils_ext.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use crate::{
lua::{
loader::is_match,
model::LuaRunTime,
parsing::{
html::{css_selector, html_parse, html_search},
text::ResponseMatcher,
},
threads::{LuaThreader, ParamScan},
},
LuaRunTime, BAR,
BAR,
};
use mlua::ExternalError;
use std::sync::{Arc, Mutex};

pub trait UtilsEXT {
Expand All @@ -36,22 +35,6 @@ impl UtilsEXT for LuaRunTime<'_> {
.unwrap();
}
fn add_matchingfunc(&self) {
self.lua
.globals()
.set(
"is_match",
self.lua
.create_function(|_, (pattern, text): (String, String)| {
let try_match = is_match(pattern, text);
if try_match.is_err() {
Err(try_match.unwrap_err().to_lua_err())
} else {
Ok(try_match.unwrap())
}
})
.unwrap(),
)
.unwrap();
self.lua
.globals()
.set(
Expand Down