Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 1 | // Copyright 2019 The Chromium OS 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 | |
Jason Jeremy Iman | adffbcb | 2020-08-31 13:21:36 +0900 | [diff] [blame] | 5 | #ifndef PATCHPANEL_DBUS_CLIENT_H_ |
| 6 | #define PATCHPANEL_DBUS_CLIENT_H_ |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 7 | |
| 8 | #include <memory> |
Jason Jeremy Iman | adffbcb | 2020-08-31 13:21:36 +0900 | [diff] [blame] | 9 | #include <set> |
Jason Jeremy Iman | 6f1f3e7 | 2020-07-06 13:04:03 +0900 | [diff] [blame] | 10 | #include <string> |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 11 | #include <utility> |
| 12 | #include <vector> |
| 13 | |
Hugo Benichi | cc6850f | 2020-01-17 13:26:06 +0900 | [diff] [blame] | 14 | #include "base/files/scoped_file.h" |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 15 | #include <brillo/brillo_export.h> |
| 16 | #include <dbus/bus.h> |
| 17 | #include <dbus/object_proxy.h> |
Hugo Benichi | 8135e56 | 2019-12-12 15:56:36 +0900 | [diff] [blame] | 18 | #include <patchpanel/proto_bindings/patchpanel_service.pb.h> |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 19 | |
| 20 | namespace patchpanel { |
| 21 | |
Hugo Benichi | 51ff71b | 2020-08-19 00:55:15 +0900 | [diff] [blame] | 22 | // Simple wrapper around patchpanel DBus API. All public functions are blocking |
Jie Jiang | 0a70acf | 2020-10-02 11:57:32 +0900 | [diff] [blame] | 23 | // DBus calls to patchpaneld (asynchronous calls are mentioned explicitly). The |
| 24 | // method names and protobuf schema used by patchpanel DBus API are defined in |
| 25 | // platform2/system_api/dbus/patchpanel. Access control for clients is defined |
| 26 | // in platform2/patchpanel/dbus. |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 27 | class BRILLO_EXPORT Client { |
| 28 | public: |
Jie Jiang | 0a70acf | 2020-10-02 11:57:32 +0900 | [diff] [blame] | 29 | using GetTrafficCountersCallback = |
| 30 | base::OnceCallback<void(const std::vector<TrafficCounter>&)>; |
Jie Jiang | 25c1b97 | 2020-11-12 15:42:53 +0900 | [diff] [blame] | 31 | using NeighborReachabilityEventHandler = |
| 32 | base::RepeatingCallback<void(const NeighborReachabilityEventSignal&)>; |
Garrick Evans | f04f044 | 2020-12-01 12:36:44 +0900 | [diff] [blame] | 33 | using NetworkDeviceChangedSignalHandler = |
| 34 | base::RepeatingCallback<void(const NetworkDeviceChangedSignal&)>; |
Jie Jiang | 0a70acf | 2020-10-02 11:57:32 +0900 | [diff] [blame] | 35 | |
Woody Chow | dee3c8b | 2020-12-04 20:03:54 +0900 | [diff] [blame] | 36 | // This variation creates a dbus object internally |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 37 | static std::unique_ptr<Client> New(); |
Woody Chow | dee3c8b | 2020-12-04 20:03:54 +0900 | [diff] [blame] | 38 | static std::unique_ptr<Client> New(const scoped_refptr<dbus::Bus>& bus); |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 39 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 40 | // Only used in tests. |
| 41 | static std::unique_ptr<Client> New(const scoped_refptr<dbus::Bus>& bus, |
| 42 | dbus::ObjectProxy* proxy); |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 43 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 44 | virtual ~Client() = default; |
Garrick Evans | 27b7403 | 2019-11-19 13:33:47 +0900 | [diff] [blame] | 45 | |
Garrick Evans | d0a646e | 2020-11-25 21:08:32 +0900 | [diff] [blame] | 46 | virtual void RegisterOnAvailableCallback( |
| 47 | base::RepeatingCallback<void(bool)> callback) = 0; |
| 48 | |
Garrick Evans | 6a06201 | 2021-02-15 09:25:44 +0900 | [diff] [blame] | 49 | // |callback| will be invoked if patchpanel exits and/or the DBus service |
| 50 | // owner changes. The parameter will be false if the process is gone (no |
| 51 | // owner) or true otherwise. |
| 52 | virtual void RegisterProcessChangedCallback( |
| 53 | base::RepeatingCallback<void(bool)> callback) = 0; |
| 54 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 55 | virtual bool NotifyArcStartup(pid_t pid) = 0; |
| 56 | virtual bool NotifyArcShutdown() = 0; |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 57 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 58 | virtual std::vector<NetworkDevice> NotifyArcVmStartup(uint32_t cid) = 0; |
| 59 | virtual bool NotifyArcVmShutdown(uint32_t cid) = 0; |
Garrick Evans | 27b7403 | 2019-11-19 13:33:47 +0900 | [diff] [blame] | 60 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 61 | virtual bool NotifyTerminaVmStartup(uint32_t cid, |
| 62 | NetworkDevice* device, |
| 63 | IPv4Subnet* container_subnet) = 0; |
| 64 | virtual bool NotifyTerminaVmShutdown(uint32_t cid) = 0; |
| 65 | |
| 66 | virtual bool NotifyPluginVmStartup(uint64_t vm_id, |
| 67 | int subnet_index, |
| 68 | NetworkDevice* device) = 0; |
| 69 | virtual bool NotifyPluginVmShutdown(uint64_t vm_id) = 0; |
Garrick Evans | 376f067 | 2020-01-07 15:31:50 +0900 | [diff] [blame] | 70 | |
Hugo Benichi | 7d9d8db | 2020-03-30 15:56:56 +0900 | [diff] [blame] | 71 | // Reset the VPN routing intent mark on a socket to the default policy for |
| 72 | // the current uid. This is in general incorrect to call this method for |
| 73 | // a socket that is already connected. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 74 | virtual bool DefaultVpnRouting(int socket) = 0; |
Hugo Benichi | 7d9d8db | 2020-03-30 15:56:56 +0900 | [diff] [blame] | 75 | |
| 76 | // Mark a socket to be always routed through a VPN if there is one. |
| 77 | // Must be called before the socket is connected. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 78 | virtual bool RouteOnVpn(int socket) = 0; |
Hugo Benichi | 7d9d8db | 2020-03-30 15:56:56 +0900 | [diff] [blame] | 79 | |
| 80 | // Mark a socket to be always routed through the physical network. |
| 81 | // Must be called before the socket is connected. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 82 | virtual bool BypassVpn(int socket) = 0; |
Hugo Benichi | 7d9d8db | 2020-03-30 15:56:56 +0900 | [diff] [blame] | 83 | |
Hugo Benichi | cc6850f | 2020-01-17 13:26:06 +0900 | [diff] [blame] | 84 | // Sends a ConnectNamespaceRequest for the given namespace pid. Returns a |
| 85 | // pair with a valid ScopedFD and the ConnectNamespaceResponse proto message |
| 86 | // received if the request succeeded. Closing the ScopedFD will teardown the |
| 87 | // veth and routing setup and free the allocated IPv4 subnet. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 88 | virtual std::pair<base::ScopedFD, patchpanel::ConnectNamespaceResponse> |
Hugo Benichi | cc6850f | 2020-01-17 13:26:06 +0900 | [diff] [blame] | 89 | ConnectNamespace(pid_t pid, |
| 90 | const std::string& outbound_ifname, |
Garrick Evans | 5869702 | 2020-12-03 12:41:13 +0900 | [diff] [blame] | 91 | bool forward_user_traffic, |
| 92 | bool route_on_vpn, |
| 93 | TrafficCounter::Source traffic_source) = 0; |
Hugo Benichi | cc6850f | 2020-01-17 13:26:06 +0900 | [diff] [blame] | 94 | |
Jie Jiang | 0a70acf | 2020-10-02 11:57:32 +0900 | [diff] [blame] | 95 | // Gets the traffic counters kept by patchpanel asynchronously, |callback| |
| 96 | // will be called with the counters once they are ready, or with an empty |
| 97 | // vector when an error happen. |devices| is the set of interfaces (shill |
| 98 | // devices) for which counters should be returned, any unknown interfaces will |
| 99 | // be ignored. If |devices| is empty, counters for all known interfaces will |
| 100 | // be returned. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 101 | virtual void GetTrafficCounters(const std::set<std::string>& devices, |
| 102 | GetTrafficCountersCallback callback) = 0; |
Jie Jiang | e02d120 | 2020-07-27 16:57:04 +0900 | [diff] [blame] | 103 | |
Jason Jeremy Iman | 6f1f3e7 | 2020-07-06 13:04:03 +0900 | [diff] [blame] | 104 | // Sends a ModifyPortRuleRequest to modify iptables ingress rules. |
| 105 | // This should only be called by permission_broker's 'devbroker'. |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 106 | virtual bool ModifyPortRule(patchpanel::ModifyPortRuleRequest::Operation op, |
| 107 | patchpanel::ModifyPortRuleRequest::RuleType type, |
| 108 | patchpanel::ModifyPortRuleRequest::Protocol proto, |
| 109 | const std::string& input_ifname, |
| 110 | const std::string& input_dst_ip, |
| 111 | uint32_t input_dst_port, |
| 112 | const std::string& dst_ip, |
| 113 | uint32_t dst_port) = 0; |
Jason Jeremy Iman | 6f1f3e7 | 2020-07-06 13:04:03 +0900 | [diff] [blame] | 114 | |
Hugo Benichi | 007abcc | 2021-05-14 10:44:45 +0900 | [diff] [blame] | 115 | // Start or stop VPN lockdown. When VPN lockdown is enabled and no VPN |
| 116 | // connection exists, any non-ARC traffic that would be routed to a VPN |
| 117 | // connection is instead rejected. ARC traffic is ignored because Android |
| 118 | // already implements VPN lockdown. |
| 119 | virtual bool SetVpnLockdown(bool enable) = 0; |
| 120 | |
Garrick Evans | 9e63798 | 2020-11-30 11:59:27 +0900 | [diff] [blame] | 121 | // Obtains a list of NetworkDevices currently managed by patchpanel. |
| 122 | virtual std::vector<NetworkDevice> GetDevices() = 0; |
| 123 | |
Garrick Evans | f04f044 | 2020-12-01 12:36:44 +0900 | [diff] [blame] | 124 | // Registers a handler that will be called upon receiving a signal indicating |
| 125 | // that a network device managed by patchpanel was added or removed. |
| 126 | virtual void RegisterNetworkDeviceChangedSignalHandler( |
| 127 | NetworkDeviceChangedSignalHandler handler) = 0; |
| 128 | |
Jie Jiang | 25c1b97 | 2020-11-12 15:42:53 +0900 | [diff] [blame] | 129 | // Registers a handler that will be called on receiving a neighbor |
| 130 | // reachability event. Currently these events are generated only for WiFi |
Jie Jiang | e2e4c0b | 2020-09-16 18:48:43 +0900 | [diff] [blame] | 131 | // devices. The handler is registered for as long as this patchpanel::Client |
| 132 | // instance is alive. |
Jie Jiang | 25c1b97 | 2020-11-12 15:42:53 +0900 | [diff] [blame] | 133 | virtual void RegisterNeighborReachabilityEventHandler( |
| 134 | NeighborReachabilityEventHandler handler) = 0; |
Jie Jiang | e2e4c0b | 2020-09-16 18:48:43 +0900 | [diff] [blame] | 135 | |
Jie Jiang | 81c84db | 2020-09-29 17:40:16 +0900 | [diff] [blame] | 136 | protected: |
| 137 | Client() = default; |
Garrick Evans | 0884393 | 2019-09-17 14:41:08 +0900 | [diff] [blame] | 138 | }; |
| 139 | |
| 140 | } // namespace patchpanel |
| 141 | |
Jason Jeremy Iman | adffbcb | 2020-08-31 13:21:36 +0900 | [diff] [blame] | 142 | #endif // PATCHPANEL_DBUS_CLIENT_H_ |