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_
|