aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorfokinv <fokinv@inf.u-szeged.hu>2016-05-20 13:19:58 +0200
committerAttila Dusnoki <dati91@gmail.com>2016-05-31 17:05:45 +0200
commita920e6d54e4e75e06ac8ac5029f9aa69fdf31ae8 (patch)
tree473b5d5892ace996d2afccdcbc7fbfe61f7ef13a /components
parentb11648903bb07a31ec93f3030058ed41b3472b17 (diff)
downloadservo-a920e6d54e4e75e06ac8ac5029f9aa69fdf31ae8.tar.gz
servo-a920e6d54e4e75e06ac8ac5029f9aa69fdf31ae8.zip
Add WebBluetooth Blacklist support
Diffstat (limited to 'components')
-rw-r--r--components/script/bluetooth_blacklist.rs124
-rw-r--r--components/script/dom/bluetooth.rs15
-rw-r--r--components/script/dom/bluetoothremotegattcharacteristic.rs19
-rw-r--r--components/script/dom/bluetoothremotegattdescriptor.rs9
-rw-r--r--components/script/dom/bluetoothremotegattserver.rs13
-rw-r--r--components/script/dom/bluetoothremotegattservice.rs13
-rw-r--r--components/script/lib.rs1
7 files changed, 184 insertions, 10 deletions
diff --git a/components/script/bluetooth_blacklist.rs b/components/script/bluetooth_blacklist.rs
new file mode 100644
index 00000000000..f9d1c564692
--- /dev/null
+++ b/components/script/bluetooth_blacklist.rs
@@ -0,0 +1,124 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use regex::Regex;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::io::BufRead;
+use std::string::String;
+use util::resource_files::read_resource_file;
+
+const BLACKLIST_FILE: &'static str = "gatt_blacklist.txt";
+const BLACKLIST_FILE_NOT_FOUND: &'static str = "Could not find gatt_blacklist.txt file";
+const EXCLUDE_READS: &'static str = "exclude-reads";
+const EXCLUDE_WRITES: &'static str = "exclude-writes";
+const VALID_UUID_REGEX: &'static str = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
+
+thread_local!(pub static BLUETOOTH_BLACKLIST: RefCell<BluetoothBlacklist> =
+ RefCell::new(BluetoothBlacklist(parse_blacklist())));
+
+pub fn uuid_is_blacklisted(uuid: &str, exclude_type: Blacklist) -> bool {
+ BLUETOOTH_BLACKLIST.with(|blist| {
+ match exclude_type {
+ Blacklist::All => {
+ blist.borrow().is_blacklisted(uuid)
+ },
+ Blacklist::Reads => {
+ blist.borrow().is_blacklisted_for_reads(uuid)
+ }
+ Blacklist::Writes => {
+ blist.borrow().is_blacklisted_for_writes(uuid)
+ }
+ }
+ })
+}
+
+pub struct BluetoothBlacklist(Option<HashMap<String, Blacklist>>);
+
+#[derive(Eq, PartialEq)]
+pub enum Blacklist {
+ All, // Read and Write
+ Reads,
+ Writes,
+}
+
+impl BluetoothBlacklist {
+ // https://webbluetoothcg.github.io/web-bluetooth/#blacklisted
+ pub fn is_blacklisted(&self, uuid: &str) -> bool {
+ match self.0 {
+ Some(ref map) => map.get(uuid).map_or(false, |et| et.eq(&Blacklist::All)),
+ None => false,
+ }
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#blacklisted-for-reads
+ pub fn is_blacklisted_for_reads(&self, uuid: &str) -> bool {
+ match self.0 {
+ Some(ref map) => map.get(uuid).map_or(false, |et| et.eq(&Blacklist::All) ||
+ et.eq(&Blacklist::Reads)),
+ None => false,
+ }
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#blacklisted-for-writes
+ pub fn is_blacklisted_for_writes(&self, uuid: &str) -> bool {
+ match self.0 {
+ Some(ref map) => map.get(uuid).map_or(false, |et| et.eq(&Blacklist::All) ||
+ et.eq(&Blacklist::Writes)),
+ None => false,
+ }
+ }
+}
+
+// https://webbluetoothcg.github.io/web-bluetooth/#parsing-the-blacklist
+fn parse_blacklist() -> Option<HashMap<String, Blacklist>> {
+ // Step 1 missing, currently we parse ./resources/gatt_blacklist.txt.
+ let valid_uuid_regex = Regex::new(VALID_UUID_REGEX).unwrap();
+ let content = read_resource_file(BLACKLIST_FILE).expect(BLACKLIST_FILE_NOT_FOUND);
+ // Step 3
+ let mut result = HashMap::new();
+ // Step 2 and 4
+ for line in content.lines() {
+ let line = match line {
+ Ok(l) => l,
+ Err(_) => return None,
+ };
+ // Step 4.1
+ if line.is_empty() || line.starts_with('#') {
+ continue;
+ }
+ let mut exclude_type = Blacklist::All;
+ let mut words = line.split_whitespace();
+ let uuid = match words.next() {
+ Some(uuid) => uuid,
+ None => continue,
+ };
+ if !valid_uuid_regex.is_match(uuid) {
+ return None;
+ }
+ match words.next() {
+ // Step 4.2 We already have an initialized exclude_type variable with Blacklist::All.
+ None => {},
+ // Step 4.3
+ Some(EXCLUDE_READS) => {
+ exclude_type = Blacklist::Reads;
+ },
+ Some(EXCLUDE_WRITES) => {
+ exclude_type = Blacklist::Writes;
+ },
+ // Step 4.4
+ _ => {
+ return None;
+ },
+ }
+ // Step 4.5
+ if result.contains_key(uuid) {
+ return None;
+ }
+ // Step 4.6
+ result.insert(uuid.to_string(), exclude_type);
+ }
+ // Step 5
+ return Some(result);
+}
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 9617dad4485..e00fb33cf59 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -2,11 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use core::clone::Clone;
use dom::bindings::codegen::Bindings::BluetoothBinding;
use dom::bindings::codegen::Bindings::BluetoothBinding::RequestDeviceOptions;
use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothScanFilter, BluetoothMethods};
-use dom::bindings::error::Error::Type;
+use dom::bindings::error::Error::{Security, Type};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::Root;
@@ -71,7 +72,11 @@ fn canonicalize_filter(filter: &BluetoothScanFilter, global: GlobalRef) -> Falli
return Err(Type(SERVICE_ERROR.to_owned()));
}
for service in services {
- services_vec.push(try!(BluetoothUUID::GetService(global, service.clone())).to_string());
+ let uuid = try!(BluetoothUUID::GetService(global, service.clone())).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ services_vec.push(uuid);
}
}
@@ -119,7 +124,11 @@ fn convert_request_device_options(options: &RequestDeviceOptions,
let mut optional_services = vec!();
if let Some(ref opt_services) = options.optionalServices {
for opt_service in opt_services {
- optional_services.push(try!(BluetoothUUID::GetService(global, opt_service.clone())).to_string());
+ let uuid = try!(BluetoothUUID::GetService(global, opt_service.clone())).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ optional_services.push(uuid);
}
}
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index cb1585b559f..2b3443f8a40 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding;
@@ -9,7 +10,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
BluetoothRemoteGATTCharacteristicMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::{Network, Type};
+use dom::bindings::error::Error::{Network, Security, Type};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -93,6 +94,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Fallible<Root<BluetoothRemoteGATTDescriptor>> {
let uuid = try!(BluetoothUUID::GetDescriptor(self.global().r(), descriptor)).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap();
@@ -116,7 +120,12 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
-> Fallible<Vec<Root<BluetoothRemoteGATTDescriptor>>> {
let mut uuid: Option<String> = None;
if let Some(d) = descriptor {
- uuid = Some(try!(BluetoothUUID::GetDescriptor(self.global().r(), d)).to_string())
+ uuid = Some(try!(BluetoothUUID::GetDescriptor(self.global().r(), d)).to_string());
+ if let Some(ref uuid) = uuid {
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ }
};
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
@@ -144,6 +153,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
fn ReadValue(&self) -> Fallible<ByteString> {
+ if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Reads) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
if !self.Service().Device().Gatt().Connected() {
return Err(Network)
@@ -165,6 +177,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
fn WriteValue(&self, value: Vec<u8>) -> ErrorResult {
+ if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Writes) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::WriteValue(self.get_instance_id(), value, sender)).unwrap();
diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs
index 03de0a52dd6..d2c1de65cb3 100644
--- a/components/script/dom/bluetoothremotegattdescriptor.rs
+++ b/components/script/dom/bluetoothremotegattdescriptor.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding::
@@ -10,7 +11,7 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::BluetoothRemoteGATTDescriptorMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::{Type, Network};
+use dom::bindings::error::Error::{Network, Security, Type};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -85,6 +86,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
fn ReadValue(&self) -> Fallible<ByteString> {
+ if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Reads) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
if !self.Characteristic().Service().Device().Gatt().Connected() {
return Err(Network)
@@ -106,6 +110,9 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
fn WriteValue(&self, value: Vec<u8>) -> ErrorResult {
+ if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Writes) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::WriteValue(self.get_instance_id(), value, sender)).unwrap();
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs
index 4813aa77183..56aad1b8bf6 100644
--- a/components/script/dom/bluetoothremotegattserver.rs
+++ b/components/script/dom/bluetoothremotegattserver.rs
@@ -2,10 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
-use dom::bindings::error::Error::Type;
+use dom::bindings::error::Error::{Security, Type};
use dom::bindings::error::{Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -96,6 +97,9 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Fallible<Root<BluetoothRemoteGATTService>> {
let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap();
@@ -120,7 +124,12 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
-> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
let mut uuid: Option<String> = None;
if let Some(s) = service {
- uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string())
+ uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string());
+ if let Some(ref uuid) = uuid {
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ }
};
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs
index 78427f7f6de..48cf9be6361 100644
--- a/components/script/dom/bluetoothremotegattservice.rs
+++ b/components/script/dom/bluetoothremotegattservice.rs
@@ -2,9 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding;
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods;
-use dom::bindings::error::Error::Type;
+use dom::bindings::error::Error::{Security, Type};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
@@ -88,6 +89,9 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
characteristic: BluetoothCharacteristicUUID)
-> Fallible<Root<BluetoothRemoteGATTCharacteristic>> {
let uuid = try!(BluetoothUUID::GetCharacteristic(self.global().r(), characteristic)).to_string();
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GetCharacteristic(self.get_instance_id(), uuid, sender)).unwrap();
@@ -122,7 +126,12 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
-> Fallible<Vec<Root<BluetoothRemoteGATTCharacteristic>>> {
let mut uuid: Option<String> = None;
if let Some(c) = characteristic {
- uuid = Some(try!(BluetoothUUID::GetCharacteristic(self.global().r(), c)).to_string())
+ uuid = Some(try!(BluetoothUUID::GetCharacteristic(self.global().r(), c)).to_string());
+ if let Some(ref uuid) = uuid {
+ if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
+ return Err(Security)
+ }
+ }
};
let mut characteristics = vec!();
let (sender, receiver) = ipc::channel().unwrap();
diff --git a/components/script/lib.rs b/components/script/lib.rs
index af6d3b2a9c0..6e978eb01c1 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -87,6 +87,7 @@ extern crate webrender_traits;
extern crate websocket;
extern crate xml5ever;
+pub mod bluetooth_blacklist;
pub mod clipboard_provider;
pub mod cors;
mod devtools;