microsandbox_network/tls/
bypass.rs1pub struct BypassMatcher {
14 entries: Vec<BypassEntry>,
15}
16
17enum BypassEntry {
19 Exact(String),
21
22 Suffix(String),
25}
26
27impl BypassMatcher {
32 pub fn new(patterns: &[String]) -> Self {
37 let entries = patterns
38 .iter()
39 .map(|p| {
40 if let Some(suffix) = p.strip_prefix("*.") {
41 BypassEntry::Suffix(suffix.to_ascii_lowercase())
42 } else {
43 BypassEntry::Exact(p.to_ascii_lowercase())
44 }
45 })
46 .collect();
47
48 Self { entries }
49 }
50
51 pub fn is_bypassed(&self, sni: &str) -> bool {
53 let lower = sni.to_ascii_lowercase();
54 self.entries.iter().any(|entry| match entry {
55 BypassEntry::Exact(domain) => lower == *domain,
56 BypassEntry::Suffix(suffix) => {
57 lower.ends_with(suffix) && lower.len() > suffix.len() && {
58 let prefix_len = lower.len() - suffix.len();
60 lower.as_bytes()[prefix_len - 1] == b'.'
61 }
62 }
63 })
64 }
65}
66
67#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_exact_match() {
77 let matcher = BypassMatcher::new(&["example.com".to_string()]);
78 assert!(matcher.is_bypassed("example.com"));
79 assert!(matcher.is_bypassed("EXAMPLE.COM"));
80 assert!(!matcher.is_bypassed("foo.example.com"));
81 assert!(!matcher.is_bypassed("notexample.com"));
82 }
83
84 #[test]
85 fn test_suffix_match() {
86 let matcher = BypassMatcher::new(&["*.pinned.com".to_string()]);
87 assert!(matcher.is_bypassed("foo.pinned.com"));
88 assert!(matcher.is_bypassed("bar.baz.pinned.com"));
89 assert!(matcher.is_bypassed("FOO.PINNED.COM"));
90 assert!(!matcher.is_bypassed("pinned.com"));
91 assert!(!matcher.is_bypassed("notpinned.com"));
92 }
93
94 #[test]
95 fn test_no_match() {
96 let matcher = BypassMatcher::new(&["example.com".to_string(), "*.pinned.com".to_string()]);
97 assert!(!matcher.is_bypassed("other.com"));
98 assert!(!matcher.is_bypassed("evil.net"));
99 }
100
101 #[test]
102 fn test_empty_list() {
103 let matcher = BypassMatcher::new(&[]);
104 assert!(!matcher.is_bypassed("anything.com"));
105 }
106
107 #[test]
108 fn test_multiple_patterns() {
109 let matcher = BypassMatcher::new(&[
110 "exact.com".to_string(),
111 "*.wildcard.org".to_string(),
112 "another.net".to_string(),
113 ]);
114 assert!(matcher.is_bypassed("exact.com"));
115 assert!(matcher.is_bypassed("sub.wildcard.org"));
116 assert!(matcher.is_bypassed("another.net"));
117 assert!(!matcher.is_bypassed("wildcard.org"));
118 }
119}