feat: add USB protected classes handler (#38263)
* feat: add USB protected classes handler * chore: apply review suggestions Co-authored-by: Charles Kerr <charles@charleskerr.com> * chore: update docs * chore: apply review suggestions * update doc per suggestion --------- Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
parent
71fb19ea14
commit
b4ec363b3d
9 changed files with 176 additions and 31 deletions
|
@ -74,6 +74,7 @@
|
|||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/media_converter.h"
|
||||
#include "shell/common/gin_converters/net_converter.h"
|
||||
#include "shell/common/gin_converters/usb_protected_classes_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
|
@ -699,6 +700,18 @@ void Session::SetDevicePermissionHandler(v8::Local<v8::Value> val,
|
|||
permission_manager->SetDevicePermissionHandler(handler);
|
||||
}
|
||||
|
||||
void Session::SetUSBProtectedClassesHandler(v8::Local<v8::Value> val,
|
||||
gin::Arguments* args) {
|
||||
ElectronPermissionManager::ProtectedUSBHandler handler;
|
||||
if (!(val->IsNull() || gin::ConvertFromV8(args->isolate(), val, &handler))) {
|
||||
args->ThrowTypeError("Must pass null or function");
|
||||
return;
|
||||
}
|
||||
auto* permission_manager = static_cast<ElectronPermissionManager*>(
|
||||
browser_context()->GetPermissionControllerDelegate());
|
||||
permission_manager->SetProtectedUSBHandler(handler);
|
||||
}
|
||||
|
||||
void Session::SetBluetoothPairingHandler(v8::Local<v8::Value> val,
|
||||
gin::Arguments* args) {
|
||||
ElectronPermissionManager::BluetoothPairingHandler handler;
|
||||
|
@ -1294,6 +1307,8 @@ void Session::FillObjectTemplate(v8::Isolate* isolate,
|
|||
&Session::SetDisplayMediaRequestHandler)
|
||||
.SetMethod("setDevicePermissionHandler",
|
||||
&Session::SetDevicePermissionHandler)
|
||||
.SetMethod("setUSBProtectedClassesHandler",
|
||||
&Session::SetUSBProtectedClassesHandler)
|
||||
.SetMethod("setBluetoothPairingHandler",
|
||||
&Session::SetBluetoothPairingHandler)
|
||||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
|
|
|
@ -118,6 +118,8 @@ class Session : public gin::Wrappable<Session>,
|
|||
gin::Arguments* args);
|
||||
void SetDevicePermissionHandler(v8::Local<v8::Value> val,
|
||||
gin::Arguments* args);
|
||||
void SetUSBProtectedClassesHandler(v8::Local<v8::Value> val,
|
||||
gin::Arguments* args);
|
||||
void SetBluetoothPairingHandler(v8::Local<v8::Value> val,
|
||||
gin::Arguments* args);
|
||||
v8::Local<v8::Promise> ClearHostResolverCache(gin::Arguments* args);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/common/gin_converters/content_converter.h"
|
||||
#include "shell/common/gin_converters/frame_converter.h"
|
||||
#include "shell/common/gin_converters/usb_protected_classes_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "third_party/blink/public/common/permissions/permission_utils.h"
|
||||
|
@ -130,6 +131,11 @@ void ElectronPermissionManager::SetDevicePermissionHandler(
|
|||
device_permission_handler_ = handler;
|
||||
}
|
||||
|
||||
void ElectronPermissionManager::SetProtectedUSBHandler(
|
||||
const ProtectedUSBHandler& handler) {
|
||||
protected_usb_handler_ = handler;
|
||||
}
|
||||
|
||||
void ElectronPermissionManager::SetBluetoothPairingHandler(
|
||||
const BluetoothPairingHandler& handler) {
|
||||
bluetooth_pairing_handler_ = handler;
|
||||
|
@ -362,6 +368,21 @@ void ElectronPermissionManager::RevokeDevicePermission(
|
|||
browser_context->RevokeDevicePermission(origin, device, permission);
|
||||
}
|
||||
|
||||
ElectronPermissionManager::USBProtectedClasses
|
||||
ElectronPermissionManager::CheckProtectedUSBClasses(
|
||||
const USBProtectedClasses& classes) const {
|
||||
if (protected_usb_handler_.is_null()) {
|
||||
return classes;
|
||||
} else {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Object> details = gin::DataObjectBuilder(isolate)
|
||||
.Set("protectedClasses", classes)
|
||||
.Build();
|
||||
return protected_usb_handler_.Run(details);
|
||||
}
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
ElectronPermissionManager::GetPermissionStatusForCurrentDocument(
|
||||
blink::PermissionType permission,
|
||||
|
|
|
@ -35,6 +35,8 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||
ElectronPermissionManager& operator=(const ElectronPermissionManager&) =
|
||||
delete;
|
||||
|
||||
using USBProtectedClasses = std::vector<uint8_t>;
|
||||
|
||||
using StatusCallback =
|
||||
base::OnceCallback<void(blink::mojom::PermissionStatus)>;
|
||||
using StatusesCallback = base::OnceCallback<void(
|
||||
|
@ -52,6 +54,10 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||
|
||||
using DeviceCheckHandler =
|
||||
base::RepeatingCallback<bool(const v8::Local<v8::Object>&)>;
|
||||
|
||||
using ProtectedUSBHandler = base::RepeatingCallback<USBProtectedClasses(
|
||||
const v8::Local<v8::Object>&)>;
|
||||
|
||||
using BluetoothPairingHandler =
|
||||
base::RepeatingCallback<void(gin_helper::Dictionary, PairCallback)>;
|
||||
|
||||
|
@ -59,6 +65,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||
void SetPermissionRequestHandler(const RequestHandler& handler);
|
||||
void SetPermissionCheckHandler(const CheckHandler& handler);
|
||||
void SetDevicePermissionHandler(const DeviceCheckHandler& handler);
|
||||
void SetProtectedUSBHandler(const ProtectedUSBHandler& handler);
|
||||
void SetBluetoothPairingHandler(const BluetoothPairingHandler& handler);
|
||||
|
||||
// content::PermissionControllerDelegate:
|
||||
|
@ -109,6 +116,9 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||
const base::Value& object,
|
||||
ElectronBrowserContext* browser_context) const;
|
||||
|
||||
USBProtectedClasses CheckProtectedUSBClasses(
|
||||
const USBProtectedClasses& classes) const;
|
||||
|
||||
protected:
|
||||
void OnPermissionResponse(int request_id,
|
||||
int permission_id,
|
||||
|
@ -159,6 +169,7 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||
RequestHandler request_handler_;
|
||||
CheckHandler check_handler_;
|
||||
DeviceCheckHandler device_permission_handler_;
|
||||
ProtectedUSBHandler protected_usb_handler_;
|
||||
BluetoothPairingHandler bluetooth_pairing_handler_;
|
||||
|
||||
PendingRequestsMap pending_requests_;
|
||||
|
|
|
@ -152,37 +152,9 @@ void ElectronUsbDelegate::AdjustProtectedInterfaceClasses(
|
|||
const url::Origin& origin,
|
||||
content::RenderFrameHost* frame,
|
||||
std::vector<uint8_t>& classes) {
|
||||
// Isolated Apps have unrestricted access to any USB interface class.
|
||||
if (frame &&
|
||||
frame->GetWebExposedIsolationLevel() >=
|
||||
content::WebExposedIsolationLevel::kMaybeIsolatedApplication) {
|
||||
// TODO(https://crbug.com/1236706): Should the list of interface classes the
|
||||
// app expects to claim be encoded in the Web App Manifest?
|
||||
classes.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
// Don't enforce protected interface classes for Chrome Apps since the
|
||||
// chrome.usb API has no such restriction.
|
||||
if (origin.scheme() == extensions::kExtensionScheme) {
|
||||
auto* extension_registry =
|
||||
extensions::ExtensionRegistry::Get(browser_context);
|
||||
if (extension_registry) {
|
||||
const extensions::Extension* extension =
|
||||
extension_registry->enabled_extensions().GetByID(origin.host());
|
||||
if (extension && extension->is_platform_app()) {
|
||||
classes.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (origin.scheme() == extensions::kExtensionScheme &&
|
||||
base::Contains(kSmartCardPrivilegedExtensionIds, origin.host())) {
|
||||
base::Erase(classes, device::mojom::kUsbSmartCardClass);
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
|
||||
auto* permission_manager = static_cast<ElectronPermissionManager*>(
|
||||
browser_context->GetPermissionControllerDelegate());
|
||||
classes = permission_manager->CheckProtectedUSBClasses(classes);
|
||||
}
|
||||
|
||||
std::unique_ptr<UsbChooser> ElectronUsbDelegate::RunChooser(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue