diff --git a/src/challenge.rs b/src/challenge.rs index 4317ecd..333b33a 100644 --- a/src/challenge.rs +++ b/src/challenge.rs @@ -50,11 +50,11 @@ pub fn verify_challenge_cookie( challenge_timeout: u64, ) -> bool { let Ok(cookie_bytes) = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(cookie) else { - dbg!("invalid base64"); + // invalid base64 return false; }; if cookie_bytes.len() != SALT_LEN + 8 + MAC_LEN { - dbg!("invalid len"); + // bad length return false; } let timestamp: [u8; 8] = cookie_bytes[SALT_LEN..SALT_LEN + 8].try_into().unwrap(); @@ -65,7 +65,7 @@ pub fn verify_challenge_cookie( .unwrap() .as_secs() { - dbg!("invalid time"); + // challenge timeout return false; } let salt: [u8; SALT_LEN] = cookie_bytes[0..SALT_LEN].try_into().unwrap(); diff --git a/src/cli.rs b/src/cli.rs index eac5198..66b820a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,5 @@ /// PoW anti-crawler middle-proxy -/// +/// /// https://git.txmn.tk/tuxmain/mesozoa/ /// Distributed under license GNU AGPL v3 without any warranty. #[derive(argp::FromArgs)] diff --git a/src/main.rs b/src/main.rs index 968758e..52bc769 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use policy::CompiledPolicies; use rand::Rng; use realm_syscall::socket2::TcpKeepalive; use regex::bytes::Regex; -use std::{io::Write, net::SocketAddr, time::Duration}; +use std::{net::SocketAddr, time::Duration}; use tokio::{ io::{AsyncWriteExt, ReadBuf}, net::{TcpSocket, TcpStream}, @@ -100,25 +100,19 @@ async fn main() { .await .is_err() { - println!("peek timeout"); + // Peek timeout return; } - let mut stdout = std::io::stdout(); - stdout.write_all(&buf).unwrap(); - stdout.flush().unwrap(); - println!(); - let mut header_line_iter = HeaderLineIterator::new(&buf); let Some(first_line) = header_line_iter.next() else { - println!("Not HTTP, or too long line"); + // Not HTTP, or too long line return; }; let mut action = config.default_action; for policy_group in policy_groups.iter() { if let Some(policy) = policy_group.evaluate(first_line) { - println!("Applying policy {}", policy.name); action = policy.action; break; } @@ -160,12 +154,8 @@ async fn main() { req_ip, config.challenge_timeout, ); - allow = dbg!(valid_challenge) - && dbg!(challenge::check_challenge( - req_challenge, - req_proof, - TARGET_ZEROS - )); + allow = valid_challenge + && challenge::check_challenge(req_challenge, req_proof, TARGET_ZEROS); } if allow { diff --git a/src/policy.bak.rs b/src/policy.bak.rs deleted file mode 100644 index bdecc1d..0000000 --- a/src/policy.bak.rs +++ /dev/null @@ -1,198 +0,0 @@ -use regex::bytes::{Regex, RegexSet, SetMatches}; - -#[derive(Clone, Debug)] -pub enum Action { - Allow, - Challenge, - Drop, -} - -#[derive(Clone, Debug)] -pub enum Filter { - Bool(bool), - FirstLineMatch(String), - HeaderLineMatch(String), - And(Vec), - Or(Vec), - Not(Box), -} - -impl Filter { - fn compile<'a>( - &'a self, - first_line_regexes: &mut Vec<&'a str>, - header_line_regexes: &mut Vec<&'a str>, - ) -> CompiledFilter { - match self { - Filter::Bool(v) => CompiledFilter::Bool(*v), - Filter::And(filters) => CompiledFilter::And( - filters - .iter() - .map(|filter| filter.compile(first_line_regexes, header_line_regexes)) - .collect(), - ), - Filter::Or(filters) => CompiledFilter::Or( - filters - .iter() - .map(|filter| filter.compile(first_line_regexes, header_line_regexes)) - .collect(), - ), - Filter::Not(filter) => CompiledFilter::Not(Box::new( - filter.compile(first_line_regexes, header_line_regexes), - )), - Filter::FirstLineMatch(regex) => { - let filter = CompiledFilter::FirstLineMatch(first_line_regexes.len()); - first_line_regexes.push(regex); - filter - } - Filter::HeaderLineMatch(regex) => { - let filter = CompiledFilter::HeaderLineMatch(header_line_regexes.len()); - header_line_regexes.push(regex); - filter - } - } - } -} - -#[derive(Clone, Debug)] -pub struct Policy { - pub name: String, - pub filter: Filter, - pub action: Action, - pub priority: i32, -} - -pub enum CompiledFilter { - Bool(bool), - FirstLineMatch(usize), - HeaderLineMatch(usize), - And(Vec), - Or(Vec), - Not(Box), -} - -/*impl CompiledFilter { - fn evaluate(&self, matches: &SetMatches) -> bool { - match self { - Self::And(filters) => filters.iter().all(Self::evaluate), - Self::Or(filters) => filters.iter().any(Self::evaluate), - Self::Bool(b) => *b, - Self::Not(filter) => !filter.evaluate(matches), - Self::FirstLineMatch(regex_id) => matches.matched(regex_id), - Self::HeaderLineMatch(regex_id) => matches.matched(regex_id), - } - } -}*/ - -pub struct CompiledPolicy { - pub name: String, - pub filter: CompiledFilter, - pub priority: i32, - pub action: Action, -} - -pub struct CompiledPolicies { - pub first_line_regex_set: Option, - pub header_line_regex_set: Option, - pub policies: Vec, -} - -pub enum RegexOrRegexSet { - Many(RegexSet), - One(Regex), - None, -} - -impl TryInto for Vec<&str> { - type Error = regex::Error; - fn try_into(self) -> Result { - Ok(match self.len() { - 0 => RegexOrRegexSet::None, - 1 => RegexOrRegexSet::One(Regex::new(self[0])?), - _ => RegexOrRegexSet::Many(RegexSet::new(self)?) - }) - } -} - -impl CompiledPolicies { - pub fn new<'a>(policies: impl IntoIterator) -> Self { - let mut first_line_regexes = Vec::new(); - let mut header_line_regexes = Vec::new(); - let mut compiled_policies = Vec::new(); - - for policy in policies { - let compiled_policy = CompiledPolicy { - name: policy.name.clone(), - filter: policy - .filter - .compile(&mut first_line_regexes, &mut header_line_regexes), - priority: policy.priority, - action: policy.action.clone(), - }; - compiled_policies.push(compiled_policy); - } - - CompiledPolicies { - first_line_regex_set: if first_line_regexes.is_empty() { - None - } else { - Some(RegexSet::new(&first_line_regexes).unwrap()) - }, - header_line_regex_set: if header_line_regexes.is_empty() { - None - } else { - Some(RegexSet::new(&header_line_regexes).unwrap()) - }, - policies: compiled_policies, - } - } - - /*pub fn evaluate<'a>( - &self, - mut header_lines: impl Iterator, - ) -> Result, PolicyEvaluationError> { - let mut best_policy: Option<&CompiledPolicy> = None; - - let first_line = header_lines - .next() - .ok_or(PolicyEvaluationError::NoFirstLine)?; - - if let Some(first_line_regex_set) = &self.first_line_regex_set { - let matches = first_line_regex_set.matches(first_line); - for policy in self.policies.iter() { - - } - let policy = &self.policies[matched]; - if let Some(best_policy) = &mut best_policy { - if policy.priority < best_policy.priority { - *best_policy = policy; - } - } else { - best_policy = Some(policy); - } - } - - if let Some(header_line_regex_set) = &self.header_line_regex_set { - for header_line in header_lines { - for matched in header_line_regex_set.matches(header_line) { - let policy = &self.policies[matched]; - if let Some(best_policy) = &mut best_policy { - if policy.priority < best_policy.priority { - *best_policy = policy; - } - } else { - best_policy = Some(policy); - } - } - } - } - - Ok(best_policy) - }*/ -} - -#[derive(Debug)] -pub enum PolicyEvaluationError { - /// First HTTP line is too long or absent - NoFirstLine, -} diff --git a/src/policy.rs b/src/policy.rs index 1c796e0..cec93dd 100644 --- a/src/policy.rs +++ b/src/policy.rs @@ -21,6 +21,8 @@ impl std::str::FromStr for Action { #[derive(Clone, Debug)] pub struct Policy { + // Will be used when we add log + #[allow(unused)] pub name: String, pub first_line_regex: String, pub action: Action,