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

Side by Side Diff: extensions/common/permissions/usb_device_permission_data.cc

Issue 2418353002: Allow interfaceClass USB device permissions (Closed)
Patch Set: . Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/common/permissions/usb_device_permission_data.h" 5 #include "extensions/common/permissions/usb_device_permission_data.h"
6 6
7 #include <stdint.h>
8
7 #include <limits> 9 #include <limits>
8 #include <memory> 10 #include <memory>
9 #include <string> 11 #include <string>
10 #include <tuple> 12 #include <tuple>
11 #include <vector> 13 #include <vector>
12 14
13 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h" 16 #include "base/strings/string_split.h"
15 #include "base/values.h" 17 #include "base/values.h"
16 #include "extensions/common/permissions/api_permission.h" 18 #include "extensions/common/permissions/api_permission.h"
17 #include "extensions/common/permissions/usb_device_permission.h" 19 #include "extensions/common/permissions/usb_device_permission.h"
18 20
21 namespace extensions {
22
19 namespace { 23 namespace {
20 24
21 const char kProductIdKey[] = "productId"; 25 const char kProductIdKey[] = "productId";
22 const char kVendorIdKey[] = "vendorId"; 26 const char kVendorIdKey[] = "vendorId";
23 const char kInterfaceIdKey[] = "interfaceId"; 27 const char kInterfaceIdKey[] = "interfaceId";
28 const char kInterfaceClassKey[] = "interfaceClass";
29
30 bool ExtractFromDict(const std::string& key,
31 const base::DictionaryValue* dict_value,
32 int max,
33 int* value) {
34 int temp;
35 if (!dict_value->GetInteger(key, &temp)) {
36 *value = UsbDevicePermissionData::SPECIAL_VALUE_ANY;
37 return true;
38 }
39
40 if (temp < UsbDevicePermissionData::SPECIAL_VALUE_ANY || temp > max)
41 return false;
42
43 *value = temp;
44 return true;
45 }
24 46
25 } // namespace 47 } // namespace
26 48
27 namespace extensions { 49 UsbDevicePermissionData::UsbDevicePermissionData() {}
28 50
29 UsbDevicePermissionData::UsbDevicePermissionData() 51 UsbDevicePermissionData::UsbDevicePermissionData(int vendor_id,
30 : vendor_id_(0), product_id_(0), interface_id_(ANY_INTERFACE) { 52 int product_id,
31 } 53 int interface_id,
32 54 int interface_class)
33 UsbDevicePermissionData::UsbDevicePermissionData(uint16_t vendor_id,
34 uint16_t product_id,
35 int interface_id)
36 : vendor_id_(vendor_id), 55 : vendor_id_(vendor_id),
37 product_id_(product_id), 56 product_id_(product_id),
38 interface_id_(interface_id) {} 57 interface_id_(interface_id),
58 interface_class_(interface_class) {}
39 59
40 bool UsbDevicePermissionData::Check( 60 bool UsbDevicePermissionData::Check(
41 const APIPermission::CheckParam* param) const { 61 const APIPermission::CheckParam* param) const {
42 if (!param) 62 if (!param)
43 return false; 63 return false;
44 const UsbDevicePermission::CheckParam& specific_param = 64 const UsbDevicePermission::CheckParam& specific_param =
45 *static_cast<const UsbDevicePermission::CheckParam*>(param); 65 *static_cast<const UsbDevicePermission::CheckParam*>(param);
46 return vendor_id_ == specific_param.vendor_id && 66
47 product_id_ == specific_param.product_id && 67 // The permission should be ignored if it filters by interface class when
48 (specific_param.interface_id == UNSPECIFIED_INTERFACE || 68 // filtering by interface class is not allowed.
49 interface_id_ == specific_param.interface_id); 69 if (!specific_param.interface_class_allowed &&
70 interface_class_ != SPECIAL_VALUE_ANY) {
71 return false;
72 }
73 DCHECK(specific_param.interface_class_allowed ||
74 (vendor_id_ != SPECIAL_VALUE_ANY && product_id_ != SPECIAL_VALUE_ANY));
75
76 return (vendor_id_ == SPECIAL_VALUE_ANY ||
77 vendor_id_ == specific_param.vendor_id) &&
78 (product_id_ == SPECIAL_VALUE_ANY ||
79 product_id_ == specific_param.product_id) &&
80 (specific_param.interface_id == SPECIAL_VALUE_UNSPECIFIED ||
81 interface_id_ == specific_param.interface_id) &&
82 (!specific_param.interface_classes ||
83 interface_class_ == SPECIAL_VALUE_ANY ||
84 specific_param.interface_classes->count(interface_class_) > 0);
50 } 85 }
51 86
52 std::unique_ptr<base::Value> UsbDevicePermissionData::ToValue() const { 87 std::unique_ptr<base::Value> UsbDevicePermissionData::ToValue() const {
53 base::DictionaryValue* result = new base::DictionaryValue(); 88 base::DictionaryValue* result = new base::DictionaryValue();
54 result->SetInteger(kVendorIdKey, vendor_id_); 89 result->SetInteger(kVendorIdKey, vendor_id_);
55 result->SetInteger(kProductIdKey, product_id_); 90 result->SetInteger(kProductIdKey, product_id_);
56 result->SetInteger(kInterfaceIdKey, interface_id_); 91 result->SetInteger(kInterfaceIdKey, interface_id_);
92 result->SetInteger(kInterfaceClassKey, interface_class_);
57 return std::unique_ptr<base::Value>(result); 93 return std::unique_ptr<base::Value>(result);
58 } 94 }
59 95
60 bool UsbDevicePermissionData::FromValue(const base::Value* value) { 96 bool UsbDevicePermissionData::FromValue(const base::Value* value) {
61 if (!value) 97 if (!value)
62 return false; 98 return false;
63 99
64 const base::DictionaryValue* dict_value; 100 const base::DictionaryValue* dict_value;
65 if (!value->GetAsDictionary(&dict_value)) 101 if (!value->GetAsDictionary(&dict_value))
66 return false; 102 return false;
67 103
68 int temp; 104 const int kMaxId = std::numeric_limits<uint16_t>::max();
69 if (!dict_value->GetInteger(kVendorIdKey, &temp)) 105 if (!ExtractFromDict(kVendorIdKey, dict_value, kMaxId, &vendor_id_))
70 return false; 106 return false;
71 if (temp < 0 || temp > std::numeric_limits<uint16_t>::max()) 107
108 if (!ExtractFromDict(kProductIdKey, dict_value, kMaxId, &product_id_))
72 return false; 109 return false;
73 vendor_id_ = temp; 110 // If product ID is specified, so should be vendor ID.
111 if (product_id_ != SPECIAL_VALUE_ANY && vendor_id_ == SPECIAL_VALUE_ANY)
112 return false;
74 113
75 if (!dict_value->GetInteger(kProductIdKey, &temp)) 114 const int kMaxInterfaceData = std::numeric_limits<uint8_t>::max();
115 if (!ExtractFromDict(kInterfaceIdKey, dict_value, kMaxInterfaceData,
116 &interface_id_)) {
76 return false; 117 return false;
77 if (temp < 0 || temp > std::numeric_limits<uint16_t>::max()) 118 }
119 // If interface ID is specified, so should be vendor ID and product ID (note
120 // that product ID being set implies that vendor ID is set).
121 if (interface_id_ != SPECIAL_VALUE_ANY && product_id_ == SPECIAL_VALUE_ANY)
78 return false; 122 return false;
79 product_id_ = temp;
80 123
81 if (!dict_value->GetInteger(kInterfaceIdKey, &temp)) 124 if (!ExtractFromDict(kInterfaceClassKey, dict_value, kMaxInterfaceData,
82 interface_id_ = ANY_INTERFACE; 125 &interface_class_)) {
83 else if (temp < ANY_INTERFACE || temp > std::numeric_limits<uint8_t>::max())
84 return false; 126 return false;
85 else 127 }
86 interface_id_ = temp; 128
129 // Reject the permission if neither interface class nor vendor ID, product ID
130 // pair is specified in the permission.
131 // Note that set product ID implies that vendor ID is set as well, so only
132 // product ID has to be checked.
133 if (interface_class_ == SPECIAL_VALUE_ANY && product_id_ == SPECIAL_VALUE_ANY)
134 return false;
135
136 // Interface ID is ignored, but kept for backward compatibility - don't allow
137 // it's usage with interface class, as interface class property was introduced
138 // after interface ID support was dropped.
139 if (interface_class_ != SPECIAL_VALUE_ANY &&
140 interface_id_ != SPECIAL_VALUE_ANY) {
141 return false;
142 }
87 143
88 return true; 144 return true;
89 } 145 }
90 146
91 bool UsbDevicePermissionData::operator<( 147 bool UsbDevicePermissionData::operator<(
92 const UsbDevicePermissionData& rhs) const { 148 const UsbDevicePermissionData& rhs) const {
93 return std::tie(vendor_id_, product_id_, interface_id_) < 149 return std::tie(vendor_id_, product_id_, interface_id_, interface_class_) <
94 std::tie(rhs.vendor_id_, rhs.product_id_, rhs.interface_id_); 150 std::tie(rhs.vendor_id_, rhs.product_id_, rhs.interface_id_,
151 rhs.interface_class_);
95 } 152 }
96 153
97 bool UsbDevicePermissionData::operator==( 154 bool UsbDevicePermissionData::operator==(
98 const UsbDevicePermissionData& rhs) const { 155 const UsbDevicePermissionData& rhs) const {
99 return vendor_id_ == rhs.vendor_id_ && 156 return vendor_id_ == rhs.vendor_id_ && product_id_ == rhs.product_id_ &&
100 product_id_ == rhs.product_id_ && 157 interface_id_ == rhs.interface_id_ &&
101 interface_id_ == rhs.interface_id_; 158 interface_class_ == rhs.interface_class_;
102 } 159 }
103 160
104 } // namespace extensions 161 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698