-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathport_tracker.h
147 lines (122 loc) · 5.23 KB
/
port_tracker.h
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
// Copyright 2015 The Chromium OS 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 PERMISSION_BROKER_PORT_TRACKER_H_
#define PERMISSION_BROKER_PORT_TRACKER_H_
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/macros.h>
#include <base/sequenced_task_runner.h>
#include <patchpanel/proto_bindings/patchpanel_service.pb.h>
namespace permission_broker {
using patchpanel::ModifyPortRuleRequest;
using Operation = patchpanel::ModifyPortRuleRequest::Operation;
using Protocol = patchpanel::ModifyPortRuleRequest::Protocol;
using RuleType = patchpanel::ModifyPortRuleRequest::RuleType;
class PortTracker {
public:
struct PortRuleKey {
Protocol proto;
uint16_t input_dst_port;
std::string input_ifname;
bool operator==(const PortRuleKey& other) const {
return proto == other.proto && input_dst_port == other.input_dst_port &&
input_ifname == other.input_ifname;
}
};
// Helper for using PortRuleKey as key entries in std::unordered_maps.
struct PortRuleKeyHasher {
std::size_t operator()(const PortRuleKey& k) const {
return ((std::hash<int>()(k.proto) ^
(std::hash<uint16_t>()(k.input_dst_port) << 1)) >>
1) ^
(std::hash<std::string>()(k.input_ifname) << 1);
}
};
// The different types of port rules supported.
enum PortRuleType : uint8_t {
// Forces default PortRuleType zero values to be different from any valid
// port rule type.
kUnknownRule = 0,
// Rule for opening ingress traffic on a destination port.
kAccessRule = 1,
// Rule for closing a destination port to locally originated traffic.
kLockdownRule = 2,
// Rule for forwarding ingress traffic on a destination port.
kForwardingRule = 3,
// Guard value used by FuzzedDataProvider. The name must remain unchanged.
kMaxValue = kForwardingRule
};
struct PortRule {
int lifeline_fd;
PortRuleType type;
Protocol proto;
std::string input_dst_ip;
uint16_t input_dst_port;
std::string input_ifname;
std::string dst_ip;
uint16_t dst_port;
};
PortTracker();
virtual ~PortTracker();
bool AllowTcpPortAccess(uint16_t port, const std::string& iface, int dbus_fd);
bool AllowUdpPortAccess(uint16_t port, const std::string& iface, int dbus_fd);
bool RevokeTcpPortAccess(uint16_t port, const std::string& iface);
bool RevokeUdpPortAccess(uint16_t port, const std::string& iface);
bool LockDownLoopbackTcpPort(uint16_t port, int dbus_fd);
bool ReleaseLoopbackTcpPort(uint16_t port);
bool StartTcpPortForwarding(uint16_t input_dst_port,
const std::string& input_ifname,
const std::string& dst_ip,
uint16_t dst_port,
int dbus_fd);
bool StartUdpPortForwarding(uint16_t input_dst_port,
const std::string& input_ifname,
const std::string& dst_ip,
uint16_t dst_port,
int dbus_fd);
bool StopTcpPortForwarding(uint16_t input_dst_port,
const std::string& input_ifname);
bool StopUdpPortForwarding(uint16_t input_dst_port,
const std::string& input_ifname);
bool HasActiveRules();
// Close all outstanding firewall holes, revoke all forwarding rules, and
// unblock all loopback ports.
void RevokeAllPortRules();
protected:
explicit PortTracker(scoped_refptr<base::SequencedTaskRunner> task_runner);
PortTracker(const PortTracker&) = delete;
PortTracker& operator=(const PortTracker&) = delete;
private:
// Call patchpanel's DBus API to create or remove firewall rule.
virtual bool ModifyPortRule(Operation op, const PortRule& rule);
// Callback to call when a lifeline file descriptor is triggered.
virtual void OnFileDescriptorReadable(int fd);
// Helper functions for process lifetime tracking.
virtual int AddLifelineFd(int dbus_fd);
virtual bool DeleteLifelineFd(int fd);
bool AddPortRule(const PortRule& rule, int dbus_fd);
bool ValidatePortRule(const PortRule& rule);
// Revoke port rule keyed by |key|. Create a copy of |key| to prevent
// accidentally deleting |key| through |lifeline_fds_| or |port_rules_|.
bool RevokePortRule(const PortRuleKey key);
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// For each port rule (protocol, port, interface), keep track of which fd
// requested it. We need this for Release{Tcp|Udp}Port(), to avoid
// traversing |lifeline_fds_| each time.
std::unordered_map<PortRuleKey, PortRule, PortRuleKeyHasher> port_rules_;
// For each fd (process), keep track of which rule (protocol, port, interface)
// it requested.
std::map<int, PortRuleKey> lifeline_fds_;
// For each fd (process), keep track of the FileDescriptorWatcher::Controller
// object associated with it.
std::map<int, std::unique_ptr<base::FileDescriptorWatcher::Controller>>
lifeline_fd_controllers_;
};
} // namespace permission_broker
#endif // PERMISSION_BROKER_PORT_TRACKER_H_