1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 extern crate url; 6 use address::{Address, ExplicitlyTypedAddress}; 7 use std::collections::HashMap; 8 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; 9 use std::num::Wrapping; 10 11 pub trait AnonymizingClone { masked_clone(&self, anon: &mut StatefulSdpAnonymizer) -> Self12 fn masked_clone(&self, anon: &mut StatefulSdpAnonymizer) -> Self; 13 } 14 15 pub trait ToBytesVec { to_byte_vec(&self) -> Vec<u8>16 fn to_byte_vec(&self) -> Vec<u8>; 17 } 18 19 impl ToBytesVec for u64 { to_byte_vec(&self) -> Vec<u8>20 fn to_byte_vec(&self) -> Vec<u8> { 21 let mut bytes = Vec::new(); 22 let mut val = *self; 23 for _ in 0..8 { 24 bytes.push(val as u8); 25 val <<= 8; 26 } 27 bytes.reverse(); 28 bytes 29 } 30 } 31 32 /* 33 * Anonymizes SDP in a stateful fashion, such that a pre-anonymized value will 34 * always be transformed into the same anonymized value within the context of 35 * the anonymizer. 36 * Stores the opaque state necessary for intelligent anonymization of SDP. This 37 * state can be stored and reused during the offer-answer period, and it 38 * will maintain a stable set of masked values. 39 */ 40 pub struct StatefulSdpAnonymizer { 41 ips: HashMap<IpAddr, IpAddr>, 42 ip_v4_inc: Wrapping<u32>, 43 ip_v6_inc: Wrapping<u128>, 44 host_names: AnonymizationStrMap, 45 ports: HashMap<u32, u32>, 46 port_inc: Wrapping<u32>, 47 origin_users: AnonymizationStrMap, 48 ice_passwords: AnonymizationStrMap, 49 ice_users: AnonymizationStrMap, 50 cert_finger_prints: HashMap<Vec<u8>, Vec<u8>>, 51 cert_finger_print_inc: Wrapping<u64>, 52 cnames: AnonymizationStrMap, 53 } 54 55 impl Default for StatefulSdpAnonymizer { default() -> Self56 fn default() -> Self { 57 Self::new() 58 } 59 } 60 61 impl StatefulSdpAnonymizer { new() -> Self62 pub fn new() -> Self { 63 StatefulSdpAnonymizer { 64 ips: HashMap::new(), 65 ip_v4_inc: Wrapping(0), 66 ip_v6_inc: Wrapping(0), 67 host_names: AnonymizationStrMap::new("fqdn-", 8), 68 ports: HashMap::new(), 69 port_inc: Wrapping(0), 70 origin_users: AnonymizationStrMap::new("origin-user-", 8), 71 ice_passwords: AnonymizationStrMap::new("ice-password-", 8), 72 ice_users: AnonymizationStrMap::new("ice-user-", 8), 73 cert_finger_prints: HashMap::new(), 74 cert_finger_print_inc: Wrapping(0), 75 cnames: AnonymizationStrMap::new("cname-", 8), 76 } 77 } 78 mask_host(&mut self, host: &str) -> String79 pub fn mask_host(&mut self, host: &str) -> String { 80 self.host_names.mask(host) 81 } 82 mask_ip(&mut self, addr: &IpAddr) -> IpAddr83 pub fn mask_ip(&mut self, addr: &IpAddr) -> IpAddr { 84 if let Some(address) = self.ips.get(addr) { 85 return *address; 86 } 87 let mapped = match addr { 88 IpAddr::V4(_) => { 89 self.ip_v4_inc += Wrapping(1); 90 IpAddr::V4(Ipv4Addr::from(self.ip_v4_inc.0)) 91 } 92 IpAddr::V6(_) => { 93 self.ip_v6_inc += Wrapping(1); 94 IpAddr::V6(Ipv6Addr::from(self.ip_v6_inc.0)) 95 } 96 }; 97 self.ips.insert(*addr, mapped); 98 mapped 99 } 100 mask_address(&mut self, address: &Address) -> Address101 pub fn mask_address(&mut self, address: &Address) -> Address { 102 match address { 103 Address::Fqdn(host) => Address::Fqdn(self.mask_host(host)), 104 Address::Ip(ip) => Address::Ip(self.mask_ip(ip)), 105 } 106 } 107 mask_typed_address( &mut self, address: &ExplicitlyTypedAddress, ) -> ExplicitlyTypedAddress108 pub fn mask_typed_address( 109 &mut self, 110 address: &ExplicitlyTypedAddress, 111 ) -> ExplicitlyTypedAddress { 112 match address { 113 ExplicitlyTypedAddress::Fqdn { 114 address_type, 115 domain, 116 } => ExplicitlyTypedAddress::Fqdn { 117 address_type: *address_type, 118 domain: self.mask_host(domain), 119 }, 120 ExplicitlyTypedAddress::Ip(ip) => ExplicitlyTypedAddress::Ip(self.mask_ip(ip)), 121 } 122 } 123 mask_port(&mut self, port: u32) -> u32124 pub fn mask_port(&mut self, port: u32) -> u32 { 125 if let Some(stored) = self.ports.get(&port) { 126 return *stored; 127 } 128 self.port_inc += Wrapping(1); 129 self.ports.insert(port, self.port_inc.0); 130 self.port_inc.0 131 } 132 mask_origin_user(&mut self, user: &str) -> String133 pub fn mask_origin_user(&mut self, user: &str) -> String { 134 self.origin_users.mask(user) 135 } 136 mask_ice_password(&mut self, password: &str) -> String137 pub fn mask_ice_password(&mut self, password: &str) -> String { 138 self.ice_passwords.mask(password) 139 } 140 mask_ice_user(&mut self, user: &str) -> String141 pub fn mask_ice_user(&mut self, user: &str) -> String { 142 self.ice_users.mask(user) 143 } 144 mask_cert_finger_print(&mut self, finger_print: &[u8]) -> Vec<u8>145 pub fn mask_cert_finger_print(&mut self, finger_print: &[u8]) -> Vec<u8> { 146 if let Some(stored) = self.cert_finger_prints.get(finger_print) { 147 return stored.clone(); 148 } 149 self.cert_finger_print_inc += Wrapping(1); 150 self.cert_finger_prints.insert( 151 finger_print.to_vec(), 152 self.cert_finger_print_inc.0.to_byte_vec(), 153 ); 154 self.cert_finger_print_inc.0.to_byte_vec() 155 } 156 mask_cname(&mut self, cname: &str) -> String157 pub fn mask_cname(&mut self, cname: &str) -> String { 158 self.cnames.mask(cname) 159 } 160 } 161 162 struct AnonymizationStrMap { 163 map: HashMap<String, String>, 164 counter: Wrapping<u64>, 165 prefix: &'static str, 166 padding: usize, 167 } 168 169 impl AnonymizationStrMap { new(prefix: &'static str, padding: usize) -> Self170 pub fn new(prefix: &'static str, padding: usize) -> Self { 171 Self { 172 map: HashMap::new(), 173 counter: Wrapping(0), 174 prefix, 175 padding, 176 } 177 } 178 mask(&mut self, value: &str) -> String179 pub fn mask(&mut self, value: &str) -> String { 180 let key = value.to_owned(); 181 if let Some(stored) = self.map.get(&key) { 182 return stored.clone(); 183 } 184 self.counter += Wrapping(1); 185 let store = format!( 186 "{}{:0padding$}", 187 self.prefix, 188 self.counter.0, 189 padding = self.padding 190 ); 191 self.map.insert(key, store.clone()); 192 store 193 } 194 } 195 196 #[cfg(test)] 197 mod tests { 198 use super::*; 199 200 #[test] test_mask_ip()201 fn test_mask_ip() { 202 let mut anon = StatefulSdpAnonymizer::default(); 203 let v4 = [ 204 Ipv4Addr::new(127, 0, 0, 1), 205 Ipv4Addr::new(10, 0, 0, 1), 206 Ipv4Addr::new(1, 1, 1, 1), 207 ]; 208 let v4_masked = [ 209 Ipv4Addr::new(0, 0, 0, 1), 210 Ipv4Addr::new(0, 0, 0, 2), 211 Ipv4Addr::new(0, 0, 0, 3), 212 ]; 213 let v6 = [ 214 Ipv6Addr::from(0), 215 Ipv6Addr::from(528_189_235), 216 Ipv6Addr::from(1_623_734_988_148_990), 217 ]; 218 let v6_masked = [Ipv6Addr::from(1), Ipv6Addr::from(2), Ipv6Addr::from(3)]; 219 for _ in 0..2 { 220 assert_eq!(anon.mask_ip(&IpAddr::V4(v4[0])), v4_masked[0]); 221 assert_eq!(anon.mask_ip(&IpAddr::V6(v6[0])), v6_masked[0]); 222 223 assert_eq!(anon.mask_ip(&IpAddr::V4(v4[1])), v4_masked[1]); 224 assert_eq!(anon.mask_ip(&IpAddr::V6(v6[1])), v6_masked[1]); 225 226 assert_eq!(anon.mask_ip(&IpAddr::V4(v4[2])), v4_masked[2]); 227 assert_eq!(anon.mask_ip(&IpAddr::V6(v6[2])), v6_masked[2]); 228 } 229 } 230 231 #[test] test_mask_port()232 fn test_mask_port() { 233 let mut anon = StatefulSdpAnonymizer::default(); 234 let ports = [0, 125, 12346]; 235 let masked_ports = [1, 2, 3]; 236 for _ in 0..2 { 237 assert_eq!(anon.mask_port(ports[0]), masked_ports[0]); 238 assert_eq!(anon.mask_port(ports[1]), masked_ports[1]); 239 assert_eq!(anon.mask_port(ports[2]), masked_ports[2]); 240 } 241 } 242 243 #[test] test_mask_ice_password()244 fn test_mask_ice_password() { 245 let mut anon = StatefulSdpAnonymizer::default(); 246 let passwords = ["vasdfioqwenl14082`14", "0", "ncp HY878hp(poh"]; 247 let masked_passwords = [ 248 "ice-password-00000001", 249 "ice-password-00000002", 250 "ice-password-00000003", 251 ]; 252 for _ in 0..2 { 253 assert_eq!(anon.mask_ice_password(passwords[0]), masked_passwords[0]); 254 assert_eq!(anon.mask_ice_password(passwords[1]), masked_passwords[1]); 255 assert_eq!(anon.mask_ice_password(passwords[2]), masked_passwords[2]); 256 } 257 } 258 259 #[test] test_mask_ice_user()260 fn test_mask_ice_user() { 261 let mut anon = StatefulSdpAnonymizer::default(); 262 let users = ["user1", "user2", "8109q2asdf"]; 263 let masked_users = [ 264 "ice-user-00000001", 265 "ice-user-00000002", 266 "ice-user-00000003", 267 ]; 268 for _ in 0..2 { 269 assert_eq!(anon.mask_ice_user(users[0]), masked_users[0]); 270 assert_eq!(anon.mask_ice_user(users[1]), masked_users[1]); 271 assert_eq!(anon.mask_ice_user(users[2]), masked_users[2]); 272 } 273 } 274 275 #[test] test_mask_cert_fingerprint()276 fn test_mask_cert_fingerprint() { 277 let mut anon = StatefulSdpAnonymizer::default(); 278 let prints: [Vec<u8>; 3] = [ 279 vec![ 280 0x59u8, 0x4A, 0x8B, 0x73, 0xA7, 0x73, 0x53, 0x71, 0x88, 0xD7, 0x4D, 0x58, 0x28, 281 0x0C, 0x79, 0x72, 0x31, 0x29, 0x9B, 0x05, 0x37, 0xDD, 0x58, 0x43, 0xC2, 0xD4, 0x85, 282 0xA2, 0xB3, 0x66, 0x38, 0x7A, 283 ], 284 vec![ 285 0x30u8, 0xFF, 0x8E, 0x2B, 0xAC, 0x9D, 0xED, 0x70, 0x18, 0x10, 0x67, 0xC8, 0xAE, 286 0x9E, 0x68, 0xF3, 0x86, 0x53, 0x51, 0xB0, 0xAC, 0x31, 0xB7, 0xBE, 0x6D, 0xCF, 0xA4, 287 0x2E, 0xD3, 0x6E, 0xB4, 0x28, 288 ], 289 vec![ 290 0xDFu8, 0x2E, 0xAC, 0x8A, 0xFD, 0x0A, 0x8E, 0x99, 0xBF, 0x5D, 0xE8, 0x3C, 0xE7, 291 0xFA, 0xFB, 0x08, 0x3B, 0x3C, 0x54, 0x1D, 0xD7, 0xD4, 0x05, 0x77, 0xA0, 0x72, 0x9B, 292 0x14, 0x08, 0x6D, 0x0F, 0x4C, 293 ], 294 ]; 295 296 let masked_prints = [1u64.to_byte_vec(), 2u64.to_byte_vec(), 3u64.to_byte_vec()]; 297 for _ in 0..2 { 298 assert_eq!(anon.mask_cert_finger_print(&prints[0]), masked_prints[0]); 299 assert_eq!(anon.mask_cert_finger_print(&prints[1]), masked_prints[1]); 300 assert_eq!(anon.mask_cert_finger_print(&prints[2]), masked_prints[2]); 301 } 302 } 303 304 #[test] test_mask_cname()305 fn test_mask_cname() { 306 let mut anon = StatefulSdpAnonymizer::default(); 307 let cnames = ["mailto:foo@bar", "JohnDoe", "Jane Doe"]; 308 let masked_cnames = ["cname-00000001", "cname-00000002", "cname-00000003"]; 309 for _ in 0..2 { 310 assert_eq!(anon.mask_cname(cnames[0]), masked_cnames[0]); 311 assert_eq!(anon.mask_cname(cnames[1]), masked_cnames[1]); 312 assert_eq!(anon.mask_cname(cnames[2]), masked_cnames[2]); 313 } 314 } 315 } 316