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

Side by Side Diff: chrome/common/extensions/api/sockets/sockets_manifest_permission.cc

Issue 51433002: Enable permission warnings from ManifestHandlers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address code review feedback. Created 7 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2013 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 "chrome/common/extensions/api/sockets/sockets_manifest_permission.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/api/manifest_types.h"
11 #include "chrome/common/extensions/api/sockets/sockets_manifest_data.h"
12 #include "chrome/common/extensions/extension_messages.h"
13 #include "extensions/common/error_utils.h"
14 #include "extensions/common/manifest_constants.h"
15 #include "grit/generated_resources.h"
16 #include "ipc/ipc_message.h"
17 #include "ui/base/l10n/l10n_util.h"
18
19 namespace extensions {
20
21 namespace sockets_errors {
22 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'";
23 }
24
25 namespace errors = sockets_errors;
26 using api::manifest_types::Sockets;
27 using content::SocketPermissionRequest;
28
29 SocketsManifestPermission::SocketsManifestPermission()
30 : kinds_(kNone) {
31 }
32
33 SocketsManifestPermission::~SocketsManifestPermission() {}
34
35 // static
36 scoped_ptr<SocketsManifestPermission> SocketsManifestPermission::FromValue(
37 const base::Value& value,
38 std::vector<InstallWarning>* install_warnings,
Yoyo Zhou 2013/11/14 00:26:55 You don't use this at all.
39 string16* error) {
40 scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error);
41 if (!sockets)
42 return scoped_ptr<SocketsManifestPermission>();
43
44 scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
45 if (sockets->udp) {
46 result->kinds_ |= kUdpPermission;
47 if (!ParseHostPattern(result.get(),
48 SocketPermissionRequest::UDP_BIND,
49 sockets->udp->bind,
50 error)) {
51 return scoped_ptr<SocketsManifestPermission>();
52 }
53 if (!ParseHostPattern(result.get(),
54 SocketPermissionRequest::UDP_SEND_TO,
55 sockets->udp->send,
56 error)) {
57 return scoped_ptr<SocketsManifestPermission>();
58 }
59 if (!ParseHostPattern(result.get(),
60 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
61 sockets->udp->multicast_membership,
62 error)) {
63 return scoped_ptr<SocketsManifestPermission>();
64 }
65 }
66 if (sockets->tcp) {
67 result->kinds_ |= kTcpPermission;
68 if (!ParseHostPattern(result.get(),
69 SocketPermissionRequest::TCP_CONNECT,
70 sockets->tcp->connect,
71 error)) {
72 return scoped_ptr<SocketsManifestPermission>();
73 }
74 }
75 if (sockets->tcp_server) {
76 result->kinds_ |= kTcpServerPermission;
77 if (!ParseHostPattern(result.get(),
78 SocketPermissionRequest::TCP_LISTEN,
79 sockets->tcp_server->listen,
80 error)) {
81 return scoped_ptr<SocketsManifestPermission>();
82 }
83 }
84 return result.Pass();
85 }
86
87 bool SocketsManifestPermission::CheckRequest(
88 const Extension* extension,
89 const SocketPermissionRequest& request) const {
90 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
91 it != permissions_.end(); ++it) {
92 if (it->Check(request))
93 return true;
94 }
95 return false;
96 }
97
98 std::string SocketsManifestPermission::name() const {
99 return manifest_keys::kSockets;
100 }
101
102 std::string SocketsManifestPermission::id() const {
103 return name();
104 }
105
106 bool SocketsManifestPermission::HasMessages() const {
107 bool is_empty = permissions_.empty() && (kinds_ == kNone);
108 return !is_empty;
109 }
110
111 PermissionMessages SocketsManifestPermission::GetMessages() const {
112 // TODO(rpaquay): This function and callees is (almost) a copy/paste
113 // from |extensions::SocketPermission|.
Yoyo Zhou 2013/11/14 00:26:55 nit: no |
114 PermissionMessages result;
115 if (!AddAnyHostMessage(result)) {
116 AddSpecificHostMessage(result);
117 AddSubdomainHostMessage(result);
118 }
119 AddNetworkListMessage(result);
120 return result;
121 }
122
123 bool SocketsManifestPermission::FromValue(const base::Value* value) {
124 if (!value)
125 return false;
126
127 std::vector<InstallWarning> warnings;
128 string16 error;
129 scoped_ptr<SocketsManifestPermission> data(
130 SocketsManifestPermission::FromValue(*value, &warnings, &error));
131
132 if (!data)
133 return false;
134
135 permissions_ = data->permissions_;
136 kinds_ = data->kinds_;
137 return true;
138 }
139
140 scoped_ptr<base::Value> SocketsManifestPermission::ToValue() const {
141 Sockets sockets;
142 if (has_udp()) {
143 sockets.udp.reset(new Sockets::Udp());
144 sockets.udp->bind = CreateHostPattern(SocketPermissionRequest::UDP_BIND);
145 sockets.udp->send = CreateHostPattern(SocketPermissionRequest::UDP_SEND_TO);
146 sockets.udp->multicast_membership =
147 CreateHostPattern(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP);
148 }
149 if (has_tcp()) {
150 sockets.tcp.reset(new Sockets::Tcp());
151 sockets.tcp->connect =
152 CreateHostPattern(SocketPermissionRequest::TCP_CONNECT);
153 }
154 if (has_tcp_server()) {
155 sockets.tcp_server.reset(new Sockets::TcpServer());
156 sockets.tcp_server->listen =
157 CreateHostPattern(SocketPermissionRequest::TCP_LISTEN);
158 }
159
160 return sockets.ToValue().Pass();
161 }
162
163 ManifestPermission* SocketsManifestPermission::Clone() const {
164 scoped_ptr<SocketsManifestPermission> result(new SocketsManifestPermission());
165 result->permissions_ = permissions_;
166 result->kinds_ = kinds_;
167 return result.release();
168 }
169
170 ManifestPermission* SocketsManifestPermission::Diff(
171 const ManifestPermission* rhs) const {
172 const SocketsManifestPermission* other =
173 static_cast<const SocketsManifestPermission*>(rhs);
174
175 scoped_ptr<SocketsManifestPermission> data(new SocketsManifestPermission());
176 std::set_difference(
177 permissions_.begin(), permissions_.end(),
178 other->permissions_.begin(), other->permissions_.end(),
179 std::inserter<SocketPermissionEntrySet>(
180 data->permissions_, data->permissions_.begin()));
181
182 data->kinds_ = (kinds_ & (~other->kinds_));
183 return data.release();
184 }
185
186 ManifestPermission* SocketsManifestPermission::Union(
187 const ManifestPermission* rhs) const {
188 const SocketsManifestPermission* other =
189 static_cast<const SocketsManifestPermission*>(rhs);
190
191 scoped_ptr<SocketsManifestPermission> data(new SocketsManifestPermission());
192 std::set_union(
193 permissions_.begin(), permissions_.end(),
194 other->permissions_.begin(), other->permissions_.end(),
195 std::inserter<SocketPermissionEntrySet>(
196 data->permissions_, data->permissions_.begin()));
197
198 data->kinds_ = (kinds_ | other->kinds_);
199 return data.release();
200 }
201
202 ManifestPermission* SocketsManifestPermission::Intersect(
203 const ManifestPermission* rhs) const {
204 const SocketsManifestPermission* other =
205 static_cast<const SocketsManifestPermission*>(rhs);
206
207 scoped_ptr<SocketsManifestPermission> data(new SocketsManifestPermission());
208 std::set_intersection(
209 permissions_.begin(), permissions_.end(),
210 other->permissions_.begin(), other->permissions_.end(),
211 std::inserter<SocketPermissionEntrySet>(
212 data->permissions_, data->permissions_.begin()));
213
214 data->kinds_ = (kinds_ & other->kinds_);
215 return data.release();
216 }
217
218 bool SocketsManifestPermission::Contains(const ManifestPermission* rhs) const {
219 const SocketsManifestPermission* other =
220 static_cast<const SocketsManifestPermission*>(rhs);
221
222 return std::includes(
223 permissions_.begin(), permissions_.end(),
224 other->permissions_.begin(), other->permissions_.end()) &&
225 ((kinds_ | other->kinds_) == kinds_);
226 }
227
228 bool SocketsManifestPermission::Equal(const ManifestPermission* rhs) const {
229 const SocketsManifestPermission* other =
230 static_cast<const SocketsManifestPermission*>(rhs);
231
232 return (permissions_ == other->permissions_) &&
233 (kinds_ == other->kinds_);
234 }
235
236 void SocketsManifestPermission::Write(IPC::Message* m) const {
237 IPC::WriteParam(m, permissions_);
238 IPC::WriteParam(m, kinds_);
239 }
240
241 bool SocketsManifestPermission::Read(const IPC::Message* m,
242 PickleIterator* iter) {
243 return IPC::ReadParam(m, iter, &permissions_) &&
244 IPC::ReadParam(m, iter, &kinds_);
245 }
246
247 void SocketsManifestPermission::Log(std::string* log) const {
248 IPC::LogParam(permissions_, log);
249 IPC::LogParam(kinds_, log);
250 }
251
252 // static
253 bool SocketsManifestPermission::ParseHostPattern(
254 SocketsManifestPermission* manifest_data,
255 SocketPermissionRequest::OperationType operation_type,
256 const scoped_ptr<std::string>& value,
257 string16* error) {
258 if (value) {
259 SocketPermissionEntry entry;
260 if (!SocketPermissionEntry::ParseHostPattern(
261 operation_type, *value, &entry)) {
262 *error = ErrorUtils::FormatErrorMessageUTF16(
263 errors::kErrorInvalidHostPattern, *value);
264 return false;
265 }
266 manifest_data->AddPermission(entry);
267 }
268 return true;
269 }
270
271 scoped_ptr<std::string> SocketsManifestPermission::CreateHostPattern(
272 SocketPermissionRequest::OperationType operation_type) const {
273 scoped_ptr<std::string> result;
274 for (SocketPermissionEntrySet::const_iterator it =
275 entries().begin(); it != entries().end() ; ++it) {
276 if (it->pattern().type == operation_type) {
277 result.reset(new std::string(it->GetHostPatternAsString()));
278 break;
279 }
280 }
281 return result.Pass();
282 }
283
284 void SocketsManifestPermission::AddPermission(
285 const SocketPermissionEntry& entry) {
286 permissions_.insert(entry);
287 }
288
289 bool SocketsManifestPermission::AddAnyHostMessage(
290 PermissionMessages& messages) const {
291 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
292 it != permissions_.end(); ++it) {
293 if (it->IsAddressBoundType() &&
294 it->GetHostType() == SocketPermissionEntry::ANY_HOST) {
295 messages.push_back(PermissionMessage(
296 PermissionMessage::kSocketAnyHost,
297 l10n_util::GetStringUTF16(
298 IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST)));
299 return true;
300 }
301 }
302 return false;
303 }
304
305 void SocketsManifestPermission::AddSubdomainHostMessage(
306 PermissionMessages& messages) const {
307 std::set<string16> domains;
308 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
309 it != permissions_.end(); ++it) {
310 if (it->GetHostType() == SocketPermissionEntry::HOSTS_IN_DOMAINS)
311 domains.insert(UTF8ToUTF16(it->pattern().host));
312 }
313 if (!domains.empty()) {
314 int id = (domains.size() == 1) ?
315 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN :
316 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS;
317 messages.push_back(PermissionMessage(
318 PermissionMessage::kSocketDomainHosts,
319 l10n_util::GetStringFUTF16(
320 id,
321 JoinString(
322 std::vector<string16>(
323 domains.begin(), domains.end()), ' '))));
324 }
325 }
326
327 void SocketsManifestPermission::AddSpecificHostMessage(
328 PermissionMessages& messages) const {
329 std::set<string16> hostnames;
330 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
331 it != permissions_.end(); ++it) {
332 if (it->GetHostType() == SocketPermissionEntry::SPECIFIC_HOSTS)
333 hostnames.insert(UTF8ToUTF16(it->pattern().host));
334 }
335 if (!hostnames.empty()) {
336 int id = (hostnames.size() == 1) ?
337 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST :
338 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS;
339 messages.push_back(PermissionMessage(
340 PermissionMessage::kSocketSpecificHosts,
341 l10n_util::GetStringFUTF16(
342 id,
343 JoinString(
344 std::vector<string16>(
345 hostnames.begin(), hostnames.end()), ' '))));
346 }
347 }
348
349 void SocketsManifestPermission::AddNetworkListMessage(
350 PermissionMessages& messages) const {
351 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin();
352 it != permissions_.end(); ++it) {
353 if (it->pattern().type == SocketPermissionRequest::NETWORK_STATE) {
354 messages.push_back(PermissionMessage(
355 PermissionMessage::kNetworkState,
356 l10n_util::GetStringUTF16(
357 IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE)));
358 }
359 }
360 }
361
362 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698