From f9f6b43ca01562c2d2a9a14e8a5d43e4c926779a Mon Sep 17 00:00:00 2001 From: XOR-op <17672363+XOR-op@users.noreply.github.com> Date: Sat, 6 Apr 2024 21:21:41 -0400 Subject: [PATCH] config: allow disabling TLS parrot --- boltconn/src/config/config.rs | 4 ++-- boltconn/src/config/inbound.rs | 5 +---- boltconn/src/config/interception.rs | 5 +++++ boltconn/src/config/mod.rs | 4 ++++ boltconn/src/intercept/https_intercept.rs | 10 ++++++++-- boltconn/src/intercept/intercept_manager.rs | 9 +++++++++ boltconn/src/proxy/dispatcher.rs | 8 +++++++- 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/boltconn/src/config/config.rs b/boltconn/src/config/config.rs index 7a3a6d3..2b487fd 100644 --- a/boltconn/src/config/config.rs +++ b/boltconn/src/config/config.rs @@ -149,11 +149,11 @@ pub enum RawProxyLocalCfg { } // Used for serde -fn default_true() -> bool { +pub(super) fn default_true() -> bool { true } -fn default_false() -> bool { +pub(super) fn default_false() -> bool { false } diff --git a/boltconn/src/config/inbound.rs b/boltconn/src/config/inbound.rs index 37e2bec..4b5fa5f 100644 --- a/boltconn/src/config/inbound.rs +++ b/boltconn/src/config/inbound.rs @@ -1,3 +1,4 @@ +use super::config::default_true; use crate::config::SingleOrVec; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -20,10 +21,6 @@ pub struct RawInboundConfig { pub socks5: Option>, } -fn default_true() -> bool { - true -} - #[test] fn test_inbound() { let nothing = "\ diff --git a/boltconn/src/config/interception.rs b/boltconn/src/config/interception.rs index 9683e81..e24a70d 100644 --- a/boltconn/src/config/interception.rs +++ b/boltconn/src/config/interception.rs @@ -1,9 +1,14 @@ +use super::config::{default_false, default_true}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct InterceptionConfig { pub name: Option, + #[serde(default = "default_true")] + pub enabled: bool, + #[serde(alias = "parrot-fingerprint", default = "default_false")] + pub parrot_fingerprint: bool, pub filters: Vec, pub actions: Vec, } diff --git a/boltconn/src/config/mod.rs b/boltconn/src/config/mod.rs index 30a4984..e7d4f5f 100644 --- a/boltconn/src/config/mod.rs +++ b/boltconn/src/config/mod.rs @@ -176,3 +176,7 @@ where } } } + +pub(in crate::config) fn default_true() -> bool { + true +} diff --git a/boltconn/src/intercept/https_intercept.rs b/boltconn/src/intercept/https_intercept.rs index eea109c..5d897db 100644 --- a/boltconn/src/intercept/https_intercept.rs +++ b/boltconn/src/intercept/https_intercept.rs @@ -27,6 +27,7 @@ pub struct HttpsIntercept { modifier: Arc, creator: Arc, conn_info: Arc, + parrot_fingerprint: bool, } impl HttpsIntercept { @@ -37,6 +38,7 @@ impl HttpsIntercept { modifier: Arc, creator: Box, conn_info: Arc, + parrot_fingerprint: bool, ) -> anyhow::Result { let (cert, priv_key) = sign_site_cert(server_name.as_str(), ca_cert)?; Ok(Self { @@ -47,6 +49,7 @@ impl HttpsIntercept { modifier, creator: Arc::from(creator), conn_info, + parrot_fingerprint, }) } @@ -101,8 +104,11 @@ impl HttpsIntercept { let acceptor = TlsAcceptor::from(Arc::new(tls_config)); // tls client - let client_tls = create_tls_connector(Some(get_overrider())); - // let client_tls = create_tls_connector(None); + let client_tls = create_tls_connector(if self.parrot_fingerprint { + Some(get_overrider()) + } else { + None + }); let server_name = ServerName::try_from(self.server_name.as_str()) .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))? .to_owned(); diff --git a/boltconn/src/intercept/intercept_manager.rs b/boltconn/src/intercept/intercept_manager.rs index 534ae30..5d9cc9c 100644 --- a/boltconn/src/intercept/intercept_manager.rs +++ b/boltconn/src/intercept/intercept_manager.rs @@ -70,6 +70,7 @@ impl InterceptionPayload { struct InterceptionEntry { filters: Dispatching, + parrot_fingerprint: bool, payload: Arc, } @@ -84,6 +85,7 @@ impl InterceptionEntry { pub struct InterceptionResult { pub payloads: Vec>, + pub parrot_fingerprint: bool, pub capture_request: bool, pub capture_response: bool, pub contains_script: bool, @@ -108,11 +110,15 @@ impl InterceptionManager { ) -> anyhow::Result { let mut res = vec![]; for i in entries.iter() { + if !i.enabled { + continue; + } let filters = DispatchingBuilder::empty(dns.clone(), mmdb.clone()) .build_filter(i.filters.as_slice(), rulesets)?; let payload = InterceptionPayload::parse_actions(i.actions.as_slice())?; res.push(InterceptionEntry { filters, + parrot_fingerprint: i.parrot_fingerprint, payload: Arc::new(payload), }) } @@ -121,6 +127,7 @@ impl InterceptionManager { pub async fn matches(&self, conn_info: &mut ConnInfo) -> InterceptionResult { let mut result = vec![]; + let mut parrot_fingerprint = false; let mut capture_request = false; let mut capture_response = false; let mut contains_script = false; @@ -128,6 +135,7 @@ impl InterceptionManager { if let Some(payload) = i.matches(conn_info).await { capture_request |= payload.capture_request; capture_response |= payload.capture_response; + parrot_fingerprint |= i.parrot_fingerprint; contains_script |= payload .payloads .iter() @@ -137,6 +145,7 @@ impl InterceptionManager { } InterceptionResult { payloads: result, + parrot_fingerprint, capture_request, capture_response, contains_script, diff --git a/boltconn/src/proxy/dispatcher.rs b/boltconn/src/proxy/dispatcher.rs index ca40a40..8eb0ec0 100644 --- a/boltconn/src/proxy/dispatcher.rs +++ b/boltconn/src/proxy/dispatcher.rs @@ -290,6 +290,7 @@ impl Dispatcher { if port == 80 || port == 443 { let result = self.intercept_mgr.load().matches(&mut conn_info).await; if result.should_intercept() { + let parrot_fingerprint = result.parrot_fingerprint; let modifier = (self.modifier.load())(result, process_info); match port { 80 => { @@ -314,7 +315,11 @@ impl Dispatcher { return Ok(()); } 443 => { - tracing::debug!("HTTPS intercept for {}", domain_name); + tracing::debug!( + "HTTPS intercept for {}; parrot_fingerprint={}", + domain_name, + parrot_fingerprint + ); { let info = info.clone(); let mocker = match HttpsIntercept::new( @@ -324,6 +329,7 @@ impl Dispatcher { modifier, outbounding, info, + parrot_fingerprint, ) { Ok(v) => v, Err(err) => {