File: usbguard_client.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (160 lines) | stat: -rw-r--r-- 4,753 bytes parent folder | download | duplicates (7)
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
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/dbus/usb/usbguard_client.h"

#include <map>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "chromeos/ash/components/dbus/usb/fake_usbguard_client.h"
#include "chromeos/ash/components/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 ash {

namespace {
UsbguardClient* g_instance = nullptr;
}  // namespace

class UsbguardClientImpl : public UsbguardClient {
 public:
  UsbguardClientImpl() = default;

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

  ~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::BindRepeating(&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;
  }

  raw_ptr<dbus::Bus> bus_ = nullptr;
  raw_ptr<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};
};

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 ash