Commit d1a8e23a authored by Allen Webb's avatar Allen Webb Committed by Commit Bot

ash: Add D-Bus client for usbguard's DevicePolicyChanged.

In order to show notifications about blocked USB devices when
appropriate, ash needs to be aware of these events. This CL adds the
logic necessary to observe the appropriate D-Bus signal.

Bug: 987351
Change-Id: I3eacbc3c401ba2f7d6dc0272a0b56c689ac8cd5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1772369Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarJorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Allen Webb <allenwebb@google.com>
Cr-Commit-Position: refs/heads/master@{#698936}
parent 5b5211e5
...@@ -66,6 +66,7 @@ include_rules = [ ...@@ -66,6 +66,7 @@ include_rules = [
# TODO(https://crbug.com/644355): Eliminate this. # TODO(https://crbug.com/644355): Eliminate this.
"+chromeos/dbus/shill", "+chromeos/dbus/shill",
"+chromeos/dbus/system_clock", "+chromeos/dbus/system_clock",
"+chromeos/dbus/usb",
# TODO(https://crbug.com/644355): Eliminate this. # TODO(https://crbug.com/644355): Eliminate this.
"+chromeos/network", "+chromeos/network",
"+chromeos/services/assistant/public" , "+chromeos/services/assistant/public" ,
......
...@@ -163,6 +163,7 @@ ...@@ -163,6 +163,7 @@
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "chromeos/dbus/initialize_dbus_client.h" #include "chromeos/dbus/initialize_dbus_client.h"
#include "chromeos/dbus/power/power_policy_controller.h" #include "chromeos/dbus/power/power_policy_controller.h"
#include "chromeos/dbus/usb/usbguard_client.h"
#include "chromeos/system/devicemode.h" #include "chromeos/system/devicemode.h"
#include "components/exo/file_helper.h" #include "components/exo/file_helper.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
...@@ -835,6 +836,8 @@ Shell::~Shell() { ...@@ -835,6 +836,8 @@ Shell::~Shell() {
shell_delegate_.reset(); shell_delegate_.reset();
chromeos::UsbguardClient::Shutdown();
// Must be shut down after detachable_base_handler_. // Must be shut down after detachable_base_handler_.
chromeos::HammerdClient::Shutdown(); chromeos::HammerdClient::Shutdown();
...@@ -854,6 +857,8 @@ void Shell::Init( ...@@ -854,6 +857,8 @@ void Shell::Init(
// Required by DetachableBaseHandler. // Required by DetachableBaseHandler.
chromeos::InitializeDBusClient<chromeos::HammerdClient>(dbus_bus.get()); chromeos::InitializeDBusClient<chromeos::HammerdClient>(dbus_bus.get());
chromeos::InitializeDBusClient<chromeos::UsbguardClient>(dbus_bus.get());
local_state_ = local_state; local_state_ = local_state;
// This creates the MessageCenter object which is used by some other objects // This creates the MessageCenter object which is used by some other objects
......
...@@ -137,6 +137,11 @@ component("dbus") { ...@@ -137,6 +137,11 @@ component("dbus") {
"smb_provider_client.h", "smb_provider_client.h",
"update_engine_client.cc", "update_engine_client.cc",
"update_engine_client.h", "update_engine_client.h",
"usb/fake_usbguard_client.cc",
"usb/fake_usbguard_client.h",
"usb/usbguard_client.cc",
"usb/usbguard_client.h",
"usb/usbguard_observer.h",
"util/version_loader.cc", "util/version_loader.cc",
"util/version_loader.h", "util/version_loader.h",
"virtual_file_provider_client.cc", "virtual_file_provider_client.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/dbus/usb/fake_usbguard_client.h"
namespace chromeos {
namespace {
FakeUsbguardClient* g_instance = nullptr;
} // namespace
FakeUsbguardClient::FakeUsbguardClient() {
DCHECK(!g_instance);
g_instance = this;
}
FakeUsbguardClient::~FakeUsbguardClient() {
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}
// static
FakeUsbguardClient* FakeUsbguardClient::Get() {
DCHECK(g_instance);
return g_instance;
}
void FakeUsbguardClient::AddObserver(UsbguardObserver* observer) {
observers_.AddObserver(observer);
}
void FakeUsbguardClient::RemoveObserver(UsbguardObserver* observer) {
observers_.RemoveObserver(observer);
}
bool FakeUsbguardClient::HasObserver(const UsbguardObserver* observer) const {
return observers_.HasObserver(observer);
}
void FakeUsbguardClient::SendDevicePolicyChanged(
uint32_t id,
UsbguardObserver::Target target_old,
UsbguardObserver::Target target_new,
const std::string& device_rule,
uint32_t rule_id,
const std::map<std::string, std::string>& attributes) {
for (auto& observer : observers_) {
observer.DevicePolicyChanged(id, target_old, target_new, device_rule,
rule_id, attributes);
}
}
} // namespace chromeos
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_USB_FAKE_USBGUARD_CLIENT_H_
#define CHROMEOS_DBUS_USB_FAKE_USBGUARD_CLIENT_H_
#include <map>
#include "base/component_export.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/dbus/usb/usbguard_client.h"
#include "chromeos/dbus/usb/usbguard_observer.h"
namespace chromeos {
class COMPONENT_EXPORT(CHROMEOS_DBUS) FakeUsbguardClient
: public UsbguardClient {
public:
FakeUsbguardClient();
~FakeUsbguardClient() override;
// Returns the global instance if initialized. May return null.
static FakeUsbguardClient* Get();
// UsbguardClient:
void AddObserver(UsbguardObserver* observer) override;
void RemoveObserver(UsbguardObserver* observer) override;
bool HasObserver(const UsbguardObserver* observer) const override;
// Simulates receiving a DevicePolicyChanged signal with the given parameters.
void SendDevicePolicyChanged(
uint32_t id,
UsbguardObserver::Target target_old,
UsbguardObserver::Target target_new,
const std::string& device_rule,
uint32_t rule_id,
const std::map<std::string, std::string>& attributes);
private:
base::ObserverList<UsbguardObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(FakeUsbguardClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_USB_FAKE_USBGUARD_CLIENT_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/dbus/usb/usbguard_client.h"
#include <map>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/observer_list.h"
#include "chromeos/dbus/usb/fake_usbguard_client.h"
#include "chromeos/dbus/usb/usbguard_observer.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/usbguard/dbus-constants.h"
namespace chromeos {
namespace {
UsbguardClient* g_instance = nullptr;
} // namespace
class UsbguardClientImpl : public UsbguardClient {
public:
UsbguardClientImpl() = default;
~UsbguardClientImpl() override = default;
// UsbguardClient:
void AddObserver(UsbguardObserver* observer) override {
observers_.AddObserver(observer);
}
// UsbguardClient:
void RemoveObserver(UsbguardObserver* observer) override {
observers_.RemoveObserver(observer);
}
// UsbguardClient:
bool HasObserver(const UsbguardObserver* observer) const override {
return observers_.HasObserver(observer);
}
void Init(dbus::Bus* bus) {
bus_ = bus;
usbguard_proxy_ = bus_->GetObjectProxy(
usbguard::kUsbguardServiceName,
dbus::ObjectPath(usbguard::kUsbguardDevicesInterfacePath));
usbguard_proxy_->ConnectToSignal(
usbguard::kUsbguardDevicesInterface,
usbguard::kDevicePolicyChangedSignalName,
base::Bind(&UsbguardClientImpl::DevicePolicyChanged,
weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&UsbguardClientImpl::OnSignalConnected,
weak_ptr_factory_.GetWeakPtr()));
}
private:
// Dispatches the DevicePolicyChanged signal with signature: uuusua{ss}
void DevicePolicyChanged(dbus::Signal* signal) {
dbus::MessageReader signal_reader(signal);
dbus::MessageReader array_reader(nullptr);
uint32_t id;
uint32_t target_old;
uint32_t target_new;
std::string device_rule;
uint32_t rule_id;
if (!signal_reader.PopUint32(&id) ||
!signal_reader.PopUint32(&target_old) ||
!signal_reader.PopUint32(&target_new) ||
!signal_reader.PopString(&device_rule) ||
!signal_reader.PopUint32(&rule_id) ||
!signal_reader.PopArray(&array_reader)) {
LOG(ERROR) << "Error reading signal from usbguard: "
<< signal->ToString();
return;
}
std::map<std::string, std::string> attributes;
while (array_reader.HasMoreData()) {
dbus::MessageReader dict_entry(nullptr);
std::string key;
std::string value;
if (!array_reader.PopDictEntry(&dict_entry) ||
!dict_entry.PopString(&key) || !dict_entry.PopString(&value)) {
LOG(ERROR) << "Error reading array from signal from usbguard: "
<< signal->ToString();
return;
}
attributes[key] = value;
}
for (auto& observer : observers_) {
observer.DevicePolicyChanged(
id, static_cast<UsbguardObserver::Target>(target_old),
static_cast<UsbguardObserver::Target>(target_new), device_rule,
rule_id, attributes);
}
}
// Called when the biometrics signal is initially connected.
void OnSignalConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
LOG_IF(ERROR, !success)
<< "Failed to connect to usbguard signal: " << signal_name;
}
dbus::Bus* bus_ = nullptr;
dbus::ObjectProxy* usbguard_proxy_ = nullptr;
base::ObserverList<UsbguardObserver> observers_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<UsbguardClientImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(UsbguardClientImpl);
};
UsbguardClient::UsbguardClient() {
DCHECK(!g_instance);
g_instance = this;
}
UsbguardClient::~UsbguardClient() {
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}
// static
void UsbguardClient::Initialize(dbus::Bus* bus) {
DCHECK(bus);
(new UsbguardClientImpl())->Init(bus);
}
// static
void UsbguardClient::InitializeFake() {
new FakeUsbguardClient();
}
// static
void UsbguardClient::Shutdown() {
DCHECK(g_instance);
delete g_instance;
}
// static
UsbguardClient* UsbguardClient::Get() {
return g_instance;
}
} // namespace chromeos
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_USB_USBGUARD_CLIENT_H_
#define CHROMEOS_DBUS_USB_USBGUARD_CLIENT_H_
#include "base/component_export.h"
#include "base/macros.h"
#include "chromeos/dbus/usb/usbguard_observer.h"
namespace dbus {
class Bus;
}
namespace chromeos {
class COMPONENT_EXPORT(CHROMEOS_DBUS) UsbguardClient {
public:
virtual ~UsbguardClient();
// Creates and initializes the global instance. |bus| must not be null.
static void Initialize(dbus::Bus* bus);
// Creates and initializes a fake global instance if not already created.
static void InitializeFake();
// Destroys the global instance which must have been initialized.
static void Shutdown();
// Returns the global instance if initialized. May return null.
static UsbguardClient* Get();
// Adds the given observer.
virtual void AddObserver(UsbguardObserver* observer) = 0;
// Removes the given observer if this object has the observer.
virtual void RemoveObserver(UsbguardObserver* observer) = 0;
// Returns true if this object has the given observer.
virtual bool HasObserver(const UsbguardObserver* observer) const = 0;
protected:
// Initialize/Shutdown should be used instead.
UsbguardClient();
private:
DISALLOW_COPY_AND_ASSIGN(UsbguardClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_USB_USBGUARD_CLIENT_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_DBUS_USB_USBGUARD_OBSERVER_H_
#define CHROMEOS_DBUS_USB_USBGUARD_OBSERVER_H_
#include <unistd.h>
#include <map>
#include <string>
#include "base/component_export.h"
#include "base/observer_list_types.h"
namespace chromeos {
class COMPONENT_EXPORT(CHROMEOS_DBUS) UsbguardObserver
: public base::CheckedObserver {
public:
// Based on usbguard src/Library/public/usbguard/Rule.hpp "enum class Target".
// We should only see either kAllow or kBlock.
enum class Target {
kAllow = 0,
kBlock = 1,
kReject = 2,
kMatch = 3,
kUnknown = 4,
kDevice = 5,
kEmpty = 6,
kInvalid = 7,
};
// A signal fired by usbguard-daemon whenever a USB device has been connected
// after the resulting policy has been determined.
//
// Parameters
// |target_old| represents the state of the device before applying the policy
// rules. Typically, this is kBlock except for signals emitted as part of
// the usbguard-daemon service starting up.
// |target_new| represents the state of the device after applying policy
// rules.
// |device_rule| is a string representation of the usbguard rule that matches
// the device.
// |attributes| has key-value pairs with information about the device. Keys
// that can be expected include:
// "hash" - A hash of the USB device descriptors for example
// "9hMkYEMPjuNegGmzLIKwUp2MPctSL0tCWk7ruWGuOzc="
// "id" - The VID:PID for example "0781:5588"
// "name" - The text name of the device such as "USB Extreme Pro"
// "parent-hash" a hash the parent device's USB descriptors
// "serial" a serial number string that is often blank and doesn't have a
// reliable pattern.
// "via-port" the port number the device is connected to such as "2-1.1.3"
// "with-interface" a list of USB interfaces. Each interface includes the
// class, subclass, and protocol numbers used to bind an interface to a
// driver for example "08:06:50".
virtual void DevicePolicyChanged(
uint32_t id,
Target target_old,
Target target_new,
const std::string& device_rule,
uint32_t rule_id,
const std::map<std::string, std::string>& attributes) = 0;
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_USB_USBGUARD_OBSERVER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment