File: device_permissions_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (229 lines) | stat: -rw-r--r-- 8,159 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_
#define EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "extensions/common/extension_id.h"
#include "services/device/public/mojom/hid.mojom.h"
#include "services/device/public/mojom/usb_device.mojom.h"

namespace base {
template <typename T>
struct DefaultSingletonTraits;
}

namespace content {
class BrowserContext;
}

namespace device {
class UsbDevice;
}

namespace extensions {

// Stores information about a device saved with access granted.
class DevicePermissionEntry : public base::RefCounted<DevicePermissionEntry> {
 public:
  enum class Type {
    USB,
    HID,
  };

  explicit DevicePermissionEntry(const device::mojom::UsbDeviceInfo& device);

  explicit DevicePermissionEntry(const device::mojom::HidDeviceInfo& device);
  DevicePermissionEntry(Type type,
                        uint16_t vendor_id,
                        uint16_t product_id,
                        const std::u16string& serial_number,
                        const std::u16string& manufacturer_string,
                        const std::u16string& product_string,
                        const base::Time& last_used);

  // A persistent device is one that can be recognized when it is reconnected
  // and can therefore be remembered persistently by writing information about
  // it to ExtensionPrefs. Currently this means it has a serial number string.
  bool IsPersistent() const;

  // Convert the device to a serializable value, returns an is_none() value
  // if the entry is not persistent.
  base::Value::Dict ToValue() const;

  std::u16string GetPermissionMessageString() const;

  Type type() const { return type_; }
  uint16_t vendor_id() const { return vendor_id_; }
  uint16_t product_id() const { return product_id_; }
  const std::u16string& serial_number() const { return serial_number_; }
  const base::Time& last_used() const { return last_used_; }

  std::u16string GetManufacturer() const;
  std::u16string GetProduct() const;

 private:
  friend class base::RefCounted<DevicePermissionEntry>;
  friend class DevicePermissionsManager;

  ~DevicePermissionEntry();

  void set_last_used(const base::Time& last_used) { last_used_ = last_used; }

  // The device guid of a hid/USB device tracked by this entry.
  std::string device_guid_;
  // The type of device this entry represents.
  Type type_;
  // The vendor ID of this device.
  uint16_t vendor_id_;
  // The product ID of this device.
  uint16_t product_id_;
  // The serial number (possibly alphanumeric) of this device.
  std::u16string serial_number_;
  // The manufacturer string read from the device (optional).
  std::u16string manufacturer_string_;
  // The product string read from the device (optional).
  std::u16string product_string_;
  // The last time this device was used by the extension.
  base::Time last_used_;
};

// Stores device permissions associated with a particular extension.
class DevicePermissions {
 public:
  DevicePermissions(const DevicePermissions&) = delete;
  DevicePermissions& operator=(const DevicePermissions&) = delete;

  virtual ~DevicePermissions();

  // Attempts to find a permission entry matching the given device.
  scoped_refptr<DevicePermissionEntry> FindUsbDeviceEntry(
      scoped_refptr<device::UsbDevice> device) const;
  scoped_refptr<DevicePermissionEntry> FindUsbDeviceEntry(
      const device::mojom::UsbDeviceInfo& device) const;
  scoped_refptr<DevicePermissionEntry> FindHidDeviceEntry(
      const device::mojom::HidDeviceInfo& device) const;

  const std::set<scoped_refptr<DevicePermissionEntry>>& entries() const {
    return entries_;
  }

 private:
  friend class DevicePermissionsManager;

  // Reads permissions out of ExtensionPrefs.
  DevicePermissions(content::BrowserContext* context,
                    const ExtensionId& extension_id);

  std::set<scoped_refptr<DevicePermissionEntry>> entries_;
  std::map<std::string, scoped_refptr<DevicePermissionEntry>>
      ephemeral_usb_devices_;
  std::map<std::string, scoped_refptr<DevicePermissionEntry>>
      ephemeral_hid_devices_;
};

// Manages saved device permissions for all extensions.
class DevicePermissionsManager : public KeyedService {
 public:
  explicit DevicePermissionsManager(content::BrowserContext* context);
  ~DevicePermissionsManager() override;

  DevicePermissionsManager(const DevicePermissionsManager&) = delete;
  DevicePermissionsManager& operator=(const DevicePermissionsManager&) = delete;

  static DevicePermissionsManager* Get(content::BrowserContext* context);

  static std::u16string GetPermissionMessage(
      uint16_t vendor_id,
      uint16_t product_id,
      const std::u16string& manufacturer_string,
      const std::u16string& product_string,
      const std::u16string& serial_number,
      bool always_include_manufacturer);

  // The DevicePermissions object for a given extension.
  DevicePermissions* GetForExtension(const ExtensionId& extension_id);

  // Equivalent to calling GetForExtension and extracting the permission string
  // for each entry.
  std::vector<std::u16string> GetPermissionMessageStrings(
      const ExtensionId& extension_id) const;

  void AllowUsbDevice(const ExtensionId& extension_id,
                      const device::mojom::UsbDeviceInfo& device_info);
  void AllowHidDevice(const ExtensionId& extension_id,
                      const device::mojom::HidDeviceInfo& device);

  // Updates the "last used" timestamp on the given device entry and writes it
  // out to ExtensionPrefs.
  void UpdateLastUsed(const ExtensionId& extension_id,
                      scoped_refptr<DevicePermissionEntry> entry);

  // Revokes permission for the extension to access the given device.
  void RemoveEntry(const ExtensionId& extension_id,
                   scoped_refptr<DevicePermissionEntry> entry);

  // Revokes permission for an ephemeral hid/USB device by its guid.
  void RemoveEntryByDeviceGUID(DevicePermissionEntry::Type type,
                               const std::string& guid);

  // Revokes permission for the extension to access all allowed devices.
  void Clear(const ExtensionId& extension_id);

 private:
  friend class DevicePermissionsManagerFactory;
  FRIEND_TEST_ALL_PREFIXES(DevicePermissionsManagerTest, SuspendExtension);

  DevicePermissions* GetInternal(const ExtensionId& extension_id) const;

  base::ThreadChecker thread_checker_;
  raw_ptr<content::BrowserContext> context_;
  std::map<std::string, raw_ptr<DevicePermissions, CtnExperimental>>
      extension_id_to_device_permissions_;
};

class DevicePermissionsManagerFactory
    : public BrowserContextKeyedServiceFactory {
 public:
  DevicePermissionsManagerFactory(const DevicePermissionsManagerFactory&) =
      delete;
  DevicePermissionsManagerFactory& operator=(
      const DevicePermissionsManagerFactory&) = delete;

  static DevicePermissionsManager* GetForBrowserContext(
      content::BrowserContext* context);
  static DevicePermissionsManagerFactory* GetInstance();

 private:
  friend struct base::DefaultSingletonTraits<DevicePermissionsManagerFactory>;

  DevicePermissionsManagerFactory();
  ~DevicePermissionsManagerFactory() override;

  // BrowserContextKeyedServiceFactory implementation
  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
      content::BrowserContext* context) const override;
  content::BrowserContext* GetBrowserContextToUse(
      content::BrowserContext* context) const override;
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_API_DEVICE_PERMISSIONS_MANAGER_H_