Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: extensions/common/permissions/usb_device_permission_data.cc

Issue 2418353002: Allow interfaceClass USB device permissions (Closed)
Patch Set: . Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/common/permissions/usb_device_permission_data.cc
diff --git a/extensions/common/permissions/usb_device_permission_data.cc b/extensions/common/permissions/usb_device_permission_data.cc
index c23b0b21c81b3968d3853977cd3a91c0e7484140..982b9e4e1f29a70e6271969ad7b5935d919aab4e 100644
--- a/extensions/common/permissions/usb_device_permission_data.cc
+++ b/extensions/common/permissions/usb_device_permission_data.cc
@@ -4,6 +4,8 @@
#include "extensions/common/permissions/usb_device_permission_data.h"
+#include <stdint.h>
+
#include <limits>
#include <memory>
#include <string>
@@ -16,26 +18,44 @@
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/usb_device_permission.h"
+namespace extensions {
+
namespace {
const char kProductIdKey[] = "productId";
const char kVendorIdKey[] = "vendorId";
const char kInterfaceIdKey[] = "interfaceId";
+const char kInterfaceClassKey[] = "interfaceClass";
-} // namespace
+bool ExtractFromDict(const std::string& key,
+ const base::DictionaryValue* dict_value,
+ int max,
+ int* value) {
+ int temp;
+ if (!dict_value->GetInteger(key, &temp)) {
+ *value = UsbDevicePermissionData::SPECIAL_VALUE_ANY;
+ return true;
+ }
-namespace extensions {
+ if (temp < UsbDevicePermissionData::SPECIAL_VALUE_ANY || temp > max)
+ return false;
-UsbDevicePermissionData::UsbDevicePermissionData()
- : vendor_id_(0), product_id_(0), interface_id_(ANY_INTERFACE) {
+ *value = temp;
+ return true;
}
-UsbDevicePermissionData::UsbDevicePermissionData(uint16_t vendor_id,
- uint16_t product_id,
- int interface_id)
+} // namespace
+
+UsbDevicePermissionData::UsbDevicePermissionData() {}
+
+UsbDevicePermissionData::UsbDevicePermissionData(int vendor_id,
+ int product_id,
+ int interface_id,
+ int interface_class)
: vendor_id_(vendor_id),
product_id_(product_id),
- interface_id_(interface_id) {}
+ interface_id_(interface_id),
+ interface_class_(interface_class) {}
bool UsbDevicePermissionData::Check(
const APIPermission::CheckParam* param) const {
@@ -43,10 +63,25 @@ bool UsbDevicePermissionData::Check(
return false;
const UsbDevicePermission::CheckParam& specific_param =
*static_cast<const UsbDevicePermission::CheckParam*>(param);
- return vendor_id_ == specific_param.vendor_id &&
- product_id_ == specific_param.product_id &&
- (specific_param.interface_id == UNSPECIFIED_INTERFACE ||
- interface_id_ == specific_param.interface_id);
+
+ // The permission should be ignored if it filters by interface class when
+ // filtering by interface class is not allowed.
+ if (!specific_param.interface_class_allowed &&
+ interface_class_ != SPECIAL_VALUE_ANY) {
+ return false;
+ }
+ DCHECK(specific_param.interface_class_allowed ||
+ (vendor_id_ != SPECIAL_VALUE_ANY && product_id_ != SPECIAL_VALUE_ANY));
+
+ return (vendor_id_ == SPECIAL_VALUE_ANY ||
+ vendor_id_ == specific_param.vendor_id) &&
+ (product_id_ == SPECIAL_VALUE_ANY ||
+ product_id_ == specific_param.product_id) &&
+ (specific_param.interface_id == SPECIAL_VALUE_UNSPECIFIED ||
+ interface_id_ == specific_param.interface_id) &&
+ (!specific_param.interface_classes ||
+ interface_class_ == SPECIAL_VALUE_ANY ||
+ specific_param.interface_classes->count(interface_class_) > 0);
}
std::unique_ptr<base::Value> UsbDevicePermissionData::ToValue() const {
@@ -54,6 +89,7 @@ std::unique_ptr<base::Value> UsbDevicePermissionData::ToValue() const {
result->SetInteger(kVendorIdKey, vendor_id_);
result->SetInteger(kProductIdKey, product_id_);
result->SetInteger(kInterfaceIdKey, interface_id_);
+ result->SetInteger(kInterfaceClassKey, interface_class_);
return std::unique_ptr<base::Value>(result);
}
@@ -65,40 +101,61 @@ bool UsbDevicePermissionData::FromValue(const base::Value* value) {
if (!value->GetAsDictionary(&dict_value))
return false;
- int temp;
- if (!dict_value->GetInteger(kVendorIdKey, &temp))
+ const int kMaxId = std::numeric_limits<uint16_t>::max();
+ if (!ExtractFromDict(kVendorIdKey, dict_value, kMaxId, &vendor_id_))
+ return false;
+
+ if (!ExtractFromDict(kProductIdKey, dict_value, kMaxId, &product_id_))
return false;
- if (temp < 0 || temp > std::numeric_limits<uint16_t>::max())
+ // If product ID is specified, so should be vendor ID.
+ if (product_id_ != SPECIAL_VALUE_ANY && vendor_id_ == SPECIAL_VALUE_ANY)
return false;
- vendor_id_ = temp;
- if (!dict_value->GetInteger(kProductIdKey, &temp))
+ const int kMaxInterfaceData = std::numeric_limits<uint8_t>::max();
+ if (!ExtractFromDict(kInterfaceIdKey, dict_value, kMaxInterfaceData,
+ &interface_id_)) {
+ return false;
+ }
+ // If interface ID is specified, so should be vendor ID and product ID (note
+ // that product ID being set implies that vendor ID is set).
+ if (interface_id_ != SPECIAL_VALUE_ANY && product_id_ == SPECIAL_VALUE_ANY)
return false;
- if (temp < 0 || temp > std::numeric_limits<uint16_t>::max())
+
+ if (!ExtractFromDict(kInterfaceClassKey, dict_value, kMaxInterfaceData,
+ &interface_class_)) {
+ return false;
+ }
+
+ // Reject the permission if neither interface class nor vendor ID, product ID
+ // pair is specified in the permission.
+ // Note that set product ID implies that vendor ID is set as well, so only
+ // product ID has to be checked.
+ if (interface_class_ == SPECIAL_VALUE_ANY && product_id_ == SPECIAL_VALUE_ANY)
return false;
- product_id_ = temp;
- if (!dict_value->GetInteger(kInterfaceIdKey, &temp))
- interface_id_ = ANY_INTERFACE;
- else if (temp < ANY_INTERFACE || temp > std::numeric_limits<uint8_t>::max())
+ // Interface ID is ignored, but kept for backward compatibility - don't allow
+ // it's usage with interface class, as interface class property was introduced
+ // after interface ID support was dropped.
+ if (interface_class_ != SPECIAL_VALUE_ANY &&
+ interface_id_ != SPECIAL_VALUE_ANY) {
return false;
- else
- interface_id_ = temp;
+ }
return true;
}
bool UsbDevicePermissionData::operator<(
const UsbDevicePermissionData& rhs) const {
- return std::tie(vendor_id_, product_id_, interface_id_) <
- std::tie(rhs.vendor_id_, rhs.product_id_, rhs.interface_id_);
+ return std::tie(vendor_id_, product_id_, interface_id_, interface_class_) <
+ std::tie(rhs.vendor_id_, rhs.product_id_, rhs.interface_id_,
+ rhs.interface_class_);
}
bool UsbDevicePermissionData::operator==(
const UsbDevicePermissionData& rhs) const {
- return vendor_id_ == rhs.vendor_id_ &&
- product_id_ == rhs.product_id_ &&
- interface_id_ == rhs.interface_id_;
+ return vendor_id_ == rhs.vendor_id_ && product_id_ == rhs.product_id_ &&
+ interface_id_ == rhs.interface_id_ &&
+ interface_class_ == rhs.interface_class_;
}
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698