Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(475)

Side by Side Diff: chromeos/network/firewall_hole.cc

Issue 965613002: Open a firewall hole when a TCP server or UDP socket is bound. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address the rest of pneubeck@'s comments. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/network/firewall_hole.h ('k') | extensions/browser/api/socket/socket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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
5 #include "chromeos/network/firewall_hole.h"
6
7 #include <fcntl.h>
8 #include <unistd.h>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/sys_info.h"
13 #include "base/threading/worker_pool.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/permission_broker_client.h"
16 #include "dbus/file_descriptor.h"
17
18 namespace chromeos {
19
20 namespace {
21
22 // Creates a pair of file descriptors that form a "lifeline" between Chrome and
23 // firewalld. If this pipe is closed unexpectedly (i.e. Chrome crashes) then
24 // firewalld will notice and close the hole in the firewall.
25 void CreateValidLifeline(dbus::FileDescriptor* lifeline_local,
26 dbus::FileDescriptor* lifeline_remote) {
27 int lifeline[2] = {-1, -1};
28 if (pipe2(lifeline, O_CLOEXEC) < 0) {
29 PLOG(ERROR) << "Failed to create a lifeline pipe";
30 return;
31 }
32
33 lifeline_local->PutValue(lifeline[0]);
34 lifeline_local->CheckValidity();
35
36 lifeline_remote->PutValue(lifeline[1]);
37 lifeline_remote->CheckValidity();
38 }
39
40 const char* PortTypeToString(FirewallHole::PortType type) {
41 switch (type) {
42 case FirewallHole::PortType::TCP:
43 return "TCP";
44 case FirewallHole::PortType::UDP:
45 return "UDP";
46 default:
pneubeck (no reviews) 2015/03/08 03:35:01 could you just add a 'return' after the switch ins
Reilly Grant (use Gerrit) 2015/03/09 19:57:06 Done.
47 NOTREACHED();
48 return nullptr;
49 }
50 }
51
52 void PortReleased(FirewallHole::PortType type,
53 uint16_t port,
54 const std::string& interface,
55 FirewallHole::ScopedFileDescriptor lifeline_fd,
56 bool success) {
57 if (!success) {
58 LOG(WARNING) << "Failed to release firewall hole for "
59 << PortTypeToString(type) << " port " << port << " on "
60 << interface << ".";
61 }
62 }
63
64 } // namespace
65
66 void CHROMEOS_EXPORT FirewallHole::FileDescriptorDeleter::operator()(
67 dbus::FileDescriptor* fd) {
68 base::WorkerPool::PostTask(
69 FROM_HERE, base::Bind(&base::DeletePointer<dbus::FileDescriptor>, fd),
70 false);
71 }
72
73 // static
74 void FirewallHole::Open(PortType type,
75 uint16_t port,
76 const std::string& interface,
77 const OpenCallback& callback) {
78 ScopedFileDescriptor lifeline_local(new dbus::FileDescriptor());
79 ScopedFileDescriptor lifeline_remote(new dbus::FileDescriptor());
80
81 // This closure shares pointers with the one below. PostTaskAndReply
82 // guarantees that it will always be deleted first.
83 base::Closure create_lifeline_closure = base::Bind(
84 &CreateValidLifeline, lifeline_local.get(), lifeline_remote.get());
85
86 base::WorkerPool::PostTaskAndReply(
87 FROM_HERE, create_lifeline_closure,
88 base::Bind(&RequestPortAccess, type, port, interface,
89 base::Passed(&lifeline_local), base::Passed(&lifeline_remote),
90 callback),
91 false);
92 }
93
94 FirewallHole::~FirewallHole() {
95 base::Callback<void(bool)> port_released_closure = base::Bind(
96 &PortReleased, type_, port_, interface_, base::Passed(&lifeline_fd_));
97
98 if (base::SysInfo::IsRunningOnChromeOS()) {
99 PermissionBrokerClient* client =
pneubeck (no reviews) 2015/03/08 03:35:01 will you be even able to test this code path in br
Reilly Grant (use Gerrit) 2015/03/09 19:57:06 The goal is to make it so that Chromium built for
pneubeck (no reviews) 2015/03/09 20:03:46 But you're also disabling this code paths from tes
100 DBusThreadManager::Get()->GetPermissionBrokerClient();
101 DCHECK(client) << "Could not get permission broker client.";
102 if (client) {
103 switch (type_) {
104 case PortType::TCP:
105 client->ReleaseTcpPort(port_, interface_, port_released_closure);
106 break;
107 case PortType::UDP:
108 client->ReleaseUdpPort(port_, interface_, port_released_closure);
109 break;
110 }
111
112 // Return now. Otherwise, the closure is run immediately to clean up.
113 return;
114 }
115 }
116
117 port_released_closure.Run(true);
118 }
119
120 void FirewallHole::RequestPortAccess(PortType type,
121 uint16_t port,
122 const std::string& interface,
123 ScopedFileDescriptor lifeline_local,
124 ScopedFileDescriptor lifeline_remote,
125 const OpenCallback& callback) {
126 if (!lifeline_local->is_valid() || !lifeline_remote->is_valid()) {
127 callback.Run(nullptr);
128 return;
129 }
130
131 base::Callback<void(bool)> access_granted_closure =
132 base::Bind(&PortAccessGranted, type, port, interface,
133 base::Passed(&lifeline_local), callback);
134
135 if (base::SysInfo::IsRunningOnChromeOS()) {
pneubeck (no reviews) 2015/03/08 03:35:01 same comment as above.
136 PermissionBrokerClient* client =
137 DBusThreadManager::Get()->GetPermissionBrokerClient();
138 DCHECK(client) << "Could not get permission broker client.";
139 if (!client) {
140 callback.Run(nullptr);
141 return;
142 }
143
144 switch (type) {
145 case PortType::TCP:
146 client->RequestTcpPortAccess(port, interface, *lifeline_remote,
147 access_granted_closure);
148 break;
149 case PortType::UDP:
150 client->RequestUdpPortAccess(port, interface, *lifeline_remote,
151 access_granted_closure);
152 break;
153 default:
154 NOTREACHED();
155 callback.Run(nullptr);
156 }
157 } else {
158 access_granted_closure.Run(true);
159 }
160 }
161
162 void FirewallHole::PortAccessGranted(PortType type,
163 uint16_t port,
164 const std::string& interface,
165 ScopedFileDescriptor lifeline_fd,
166 const FirewallHole::OpenCallback& callback,
167 bool success) {
168 if (success) {
169 callback.Run(make_scoped_ptr(
170 new FirewallHole(type, port, interface, lifeline_fd.Pass())));
171 } else {
172 callback.Run(nullptr);
173 }
174 }
175
176 FirewallHole::FirewallHole(PortType type,
177 uint16_t port,
178 const std::string& interface,
179 ScopedFileDescriptor lifeline_fd)
180 : type_(type),
181 port_(port),
182 interface_(interface),
183 lifeline_fd_(lifeline_fd.Pass()) {
184 }
185
186 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/network/firewall_hole.h ('k') | extensions/browser/api/socket/socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698