permission_broker_client.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chromeos/dbus/permission_broker/permission_broker_client.h"
  5. #include <stdint.h>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/logging.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "chromeos/dbus/permission_broker/fake_permission_broker_client.h"
  12. #include "dbus/bus.h"
  13. #include "dbus/message.h"
  14. #include "dbus/object_proxy.h"
  15. #include "third_party/cros_system_api/dbus/service_constants.h"
  16. using permission_broker::kCheckPathAccess;
  17. using permission_broker::kClaimDevicePath;
  18. using permission_broker::kDetachInterface;
  19. using permission_broker::kOpenPath;
  20. using permission_broker::kOpenPathAndRegisterClient;
  21. using permission_broker::kPermissionBrokerInterface;
  22. using permission_broker::kPermissionBrokerServiceName;
  23. using permission_broker::kPermissionBrokerServicePath;
  24. using permission_broker::kReattachInterface;
  25. using permission_broker::kReleaseTcpPort;
  26. using permission_broker::kReleaseTcpPortForward;
  27. using permission_broker::kReleaseUdpPort;
  28. using permission_broker::kReleaseUdpPortForward;
  29. using permission_broker::kRequestTcpPortAccess;
  30. using permission_broker::kRequestTcpPortForward;
  31. using permission_broker::kRequestUdpPortAccess;
  32. using permission_broker::kRequestUdpPortForward;
  33. namespace chromeos {
  34. namespace {
  35. const char kNoResponseError[] = "org.chromium.Error.NoResponse";
  36. PermissionBrokerClient* g_instance = nullptr;
  37. } // namespace
  38. class PermissionBrokerClientImpl : public PermissionBrokerClient {
  39. public:
  40. PermissionBrokerClientImpl() = default;
  41. PermissionBrokerClientImpl(const PermissionBrokerClientImpl&) = delete;
  42. PermissionBrokerClientImpl& operator=(const PermissionBrokerClientImpl&) =
  43. delete;
  44. ~PermissionBrokerClientImpl() override = default;
  45. void CheckPathAccess(const std::string& path,
  46. ResultCallback callback) override {
  47. dbus::MethodCall method_call(kPermissionBrokerInterface, kCheckPathAccess);
  48. dbus::MessageWriter writer(&method_call);
  49. writer.AppendString(path);
  50. proxy_->CallMethod(
  51. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  52. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  53. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  54. }
  55. void OpenPath(const std::string& path,
  56. OpenPathCallback callback,
  57. ErrorCallback error_callback) override {
  58. dbus::MethodCall method_call(kPermissionBrokerInterface, kOpenPath);
  59. dbus::MessageWriter writer(&method_call);
  60. writer.AppendString(path);
  61. proxy_->CallMethodWithErrorCallback(
  62. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  63. base::BindOnce(&PermissionBrokerClientImpl::OnOpenPathResponse,
  64. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  65. base::BindOnce(&PermissionBrokerClientImpl::OnError,
  66. weak_ptr_factory_.GetWeakPtr(),
  67. std::move(error_callback)));
  68. }
  69. void ClaimDevicePath(const std::string& path,
  70. uint32_t allowed_interfaces_mask,
  71. int lifeline_fd,
  72. OpenPathCallback callback,
  73. ErrorCallback error_callback) override {
  74. dbus::MethodCall method_call(kPermissionBrokerInterface, kClaimDevicePath);
  75. dbus::MessageWriter writer(&method_call);
  76. writer.AppendString(path);
  77. writer.AppendUint32(allowed_interfaces_mask);
  78. writer.AppendFileDescriptor(lifeline_fd);
  79. proxy_->CallMethodWithErrorCallback(
  80. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  81. base::BindOnce(&PermissionBrokerClientImpl::OnOpenPathResponse,
  82. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  83. base::BindOnce(&PermissionBrokerClientImpl::OnError,
  84. weak_ptr_factory_.GetWeakPtr(),
  85. std::move(error_callback)));
  86. }
  87. void OpenPathAndRegisterClient(const std::string& path,
  88. uint32_t allowed_interfaces_mask,
  89. int lifeline_fd,
  90. OpenPathAndRegisterClientCallback callback,
  91. ErrorCallback error_callback) override {
  92. dbus::MethodCall method_call(kPermissionBrokerInterface,
  93. kOpenPathAndRegisterClient);
  94. dbus::MessageWriter writer(&method_call);
  95. writer.AppendString(path);
  96. writer.AppendUint32(allowed_interfaces_mask);
  97. writer.AppendFileDescriptor(lifeline_fd);
  98. proxy_->CallMethodWithErrorCallback(
  99. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  100. base::BindOnce(
  101. &PermissionBrokerClientImpl::OpenPathAndRegisterClientResponse,
  102. weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
  103. base::BindOnce(&PermissionBrokerClientImpl::OnError,
  104. weak_ptr_factory_.GetWeakPtr(),
  105. std::move(error_callback)));
  106. }
  107. void DetachInterface(const std::string& client_id,
  108. uint8_t iface_num,
  109. ResultCallback callback) override {
  110. dbus::MethodCall method_call(kPermissionBrokerInterface, kDetachInterface);
  111. dbus::MessageWriter writer(&method_call);
  112. writer.AppendString(client_id);
  113. writer.AppendByte(iface_num);
  114. proxy_->CallMethod(
  115. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  116. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  117. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  118. }
  119. void ReattachInterface(const std::string& client_id,
  120. uint8_t iface_num,
  121. ResultCallback callback) override {
  122. dbus::MethodCall method_call(kPermissionBrokerInterface,
  123. kReattachInterface);
  124. dbus::MessageWriter writer(&method_call);
  125. writer.AppendString(client_id);
  126. writer.AppendByte(iface_num);
  127. proxy_->CallMethod(
  128. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  129. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  130. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  131. }
  132. void RequestTcpPortAccess(uint16_t port,
  133. const std::string& interface,
  134. int lifeline_fd,
  135. ResultCallback callback) override {
  136. dbus::MethodCall method_call(kPermissionBrokerInterface,
  137. kRequestTcpPortAccess);
  138. dbus::MessageWriter writer(&method_call);
  139. writer.AppendUint16(port);
  140. writer.AppendString(interface);
  141. writer.AppendFileDescriptor(lifeline_fd);
  142. proxy_->CallMethod(
  143. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  144. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  145. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  146. }
  147. void RequestUdpPortAccess(uint16_t port,
  148. const std::string& interface,
  149. int lifeline_fd,
  150. ResultCallback callback) override {
  151. dbus::MethodCall method_call(kPermissionBrokerInterface,
  152. kRequestUdpPortAccess);
  153. dbus::MessageWriter writer(&method_call);
  154. writer.AppendUint16(port);
  155. writer.AppendString(interface);
  156. writer.AppendFileDescriptor(lifeline_fd);
  157. proxy_->CallMethod(
  158. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  159. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  160. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  161. }
  162. void ReleaseTcpPort(uint16_t port,
  163. const std::string& interface,
  164. ResultCallback callback) override {
  165. dbus::MethodCall method_call(kPermissionBrokerInterface, kReleaseTcpPort);
  166. dbus::MessageWriter writer(&method_call);
  167. writer.AppendUint16(port);
  168. writer.AppendString(interface);
  169. proxy_->CallMethod(
  170. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  171. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  172. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  173. }
  174. void ReleaseUdpPort(uint16_t port,
  175. const std::string& interface,
  176. ResultCallback callback) override {
  177. dbus::MethodCall method_call(kPermissionBrokerInterface, kReleaseUdpPort);
  178. dbus::MessageWriter writer(&method_call);
  179. writer.AppendUint16(port);
  180. writer.AppendString(interface);
  181. proxy_->CallMethod(
  182. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  183. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  184. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  185. }
  186. void RequestTcpPortForward(uint16_t in_port,
  187. const std::string& in_interface,
  188. const std::string& dst_ip,
  189. uint16_t dst_port,
  190. int lifeline_fd,
  191. ResultCallback callback) override {
  192. dbus::MethodCall method_call(kPermissionBrokerInterface,
  193. kRequestTcpPortForward);
  194. dbus::MessageWriter writer(&method_call);
  195. writer.AppendUint16(in_port);
  196. writer.AppendString(in_interface);
  197. writer.AppendString(dst_ip);
  198. writer.AppendUint16(dst_port);
  199. writer.AppendFileDescriptor(lifeline_fd);
  200. proxy_->CallMethod(
  201. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  202. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  203. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  204. }
  205. void RequestUdpPortForward(uint16_t in_port,
  206. const std::string& in_interface,
  207. const std::string& dst_ip,
  208. uint16_t dst_port,
  209. int lifeline_fd,
  210. ResultCallback callback) override {
  211. dbus::MethodCall method_call(kPermissionBrokerInterface,
  212. kRequestUdpPortForward);
  213. dbus::MessageWriter writer(&method_call);
  214. writer.AppendUint16(in_port);
  215. writer.AppendString(in_interface);
  216. writer.AppendString(dst_ip);
  217. writer.AppendUint16(dst_port);
  218. writer.AppendFileDescriptor(lifeline_fd);
  219. proxy_->CallMethod(
  220. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  221. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  222. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  223. }
  224. void ReleaseTcpPortForward(uint16_t in_port,
  225. const std::string& in_interface,
  226. ResultCallback callback) override {
  227. dbus::MethodCall method_call(kPermissionBrokerInterface,
  228. kReleaseTcpPortForward);
  229. dbus::MessageWriter writer(&method_call);
  230. writer.AppendUint16(in_port);
  231. writer.AppendString(in_interface);
  232. proxy_->CallMethod(
  233. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  234. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  235. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  236. }
  237. void ReleaseUdpPortForward(uint16_t in_port,
  238. const std::string& in_interface,
  239. ResultCallback callback) override {
  240. dbus::MethodCall method_call(kPermissionBrokerInterface,
  241. kReleaseUdpPortForward);
  242. dbus::MessageWriter writer(&method_call);
  243. writer.AppendUint16(in_port);
  244. writer.AppendString(in_interface);
  245. proxy_->CallMethod(
  246. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  247. base::BindOnce(&PermissionBrokerClientImpl::OnResponse,
  248. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  249. }
  250. void Init(dbus::Bus* bus) {
  251. proxy_ =
  252. bus->GetObjectProxy(kPermissionBrokerServiceName,
  253. dbus::ObjectPath(kPermissionBrokerServicePath));
  254. }
  255. private:
  256. // Handle a DBus response from the permission broker, invoking the callback
  257. // that the method was originally called with with the success response.
  258. void OnResponse(ResultCallback callback, dbus::Response* response) {
  259. if (!response) {
  260. LOG(WARNING) << "Access request method call failed.";
  261. std::move(callback).Run(false);
  262. return;
  263. }
  264. bool result = false;
  265. dbus::MessageReader reader(response);
  266. if (!reader.PopBool(&result))
  267. LOG(WARNING) << "Could not parse response: " << response->ToString();
  268. std::move(callback).Run(result);
  269. }
  270. void OnOpenPathResponse(OpenPathCallback callback, dbus::Response* response) {
  271. base::ScopedFD fd;
  272. dbus::MessageReader reader(response);
  273. if (!reader.PopFileDescriptor(&fd))
  274. LOG(WARNING) << "Could not parse response: " << response->ToString();
  275. std::move(callback).Run(std::move(fd));
  276. }
  277. void OpenPathAndRegisterClientResponse(
  278. OpenPathAndRegisterClientCallback callback,
  279. dbus::Response* response) {
  280. base::ScopedFD fd;
  281. std::string client_id;
  282. dbus::MessageReader reader(response);
  283. if (!reader.PopFileDescriptor(&fd)) {
  284. LOG(WARNING) << "Could not parse response for fd: "
  285. << response->ToString();
  286. }
  287. if (!reader.PopString(&client_id)) {
  288. LOG(WARNING) << "Could not parse response for client_id: "
  289. << response->ToString();
  290. }
  291. std::move(callback).Run(client_id, std::move(fd));
  292. }
  293. void OnError(ErrorCallback callback, dbus::ErrorResponse* response) {
  294. std::string error_name;
  295. std::string error_message;
  296. if (response) {
  297. dbus::MessageReader reader(response);
  298. error_name = response->GetErrorName();
  299. reader.PopString(&error_message);
  300. } else {
  301. error_name = kNoResponseError;
  302. }
  303. std::move(callback).Run(error_name, error_message);
  304. }
  305. raw_ptr<dbus::ObjectProxy> proxy_ = nullptr;
  306. // Note: This should remain the last member so that it will be destroyed
  307. // first, invalidating its weak pointers, before the other members are
  308. // destroyed.
  309. base::WeakPtrFactory<PermissionBrokerClientImpl> weak_ptr_factory_{this};
  310. };
  311. PermissionBrokerClient::PermissionBrokerClient() {
  312. DCHECK(!g_instance);
  313. g_instance = this;
  314. }
  315. PermissionBrokerClient::~PermissionBrokerClient() {
  316. DCHECK_EQ(this, g_instance);
  317. g_instance = nullptr;
  318. }
  319. // static
  320. void PermissionBrokerClient::Initialize(dbus::Bus* bus) {
  321. DCHECK(bus);
  322. (new PermissionBrokerClientImpl())->Init(bus);
  323. }
  324. // static
  325. void PermissionBrokerClient::InitializeFake() {
  326. new FakePermissionBrokerClient();
  327. }
  328. // static
  329. void PermissionBrokerClient::Shutdown() {
  330. DCHECK(g_instance);
  331. delete g_instance;
  332. }
  333. // static
  334. PermissionBrokerClient* PermissionBrokerClient::Get() {
  335. return g_instance;
  336. }
  337. } // namespace chromeos