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

Side by Side Diff: chrome/browser/extensions/api/socket/socket_api.cc

Issue 10692160: Support socket endpoint permissions for AppsV2 Socket API. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix review issues Created 8 years, 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/socket/socket_api.h" 5 #include "chrome/browser/extensions/api/socket/socket_api.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/common/extensions/permissions/socket_permission.h"
8 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h" 10 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h"
10 #include "chrome/browser/extensions/api/socket/socket.h" 11 #include "chrome/browser/extensions/api/socket/socket.h"
11 #include "chrome/browser/extensions/api/socket/tcp_socket.h" 12 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
12 #include "chrome/browser/extensions/api/socket/udp_socket.h" 13 #include "chrome/browser/extensions/api/socket/udp_socket.h"
13 #include "chrome/browser/extensions/extension_system.h" 14 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/io_thread.h" 15 #include "chrome/browser/io_thread.h"
15 #include "net/base/host_port_pair.h" 16 #include "net/base/host_port_pair.h"
16 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
17 #include "net/base/ip_endpoint.h" 18 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/base/net_log.h" 20 #include "net/base/net_log.h"
20 21
21 namespace extensions { 22 namespace extensions {
22 23
23 const char kAddressKey[] = "address"; 24 const char kAddressKey[] = "address";
24 const char kPortKey[] = "port"; 25 const char kPortKey[] = "port";
25 const char kBytesWrittenKey[] = "bytesWritten"; 26 const char kBytesWrittenKey[] = "bytesWritten";
26 const char kDataKey[] = "data"; 27 const char kDataKey[] = "data";
27 const char kResultCodeKey[] = "resultCode"; 28 const char kResultCodeKey[] = "resultCode";
28 const char kSocketIdKey[] = "socketId"; 29 const char kSocketIdKey[] = "socketId";
29 const char kTCPOption[] = "tcp"; 30 const char kTCPOption[] = "tcp";
30 const char kUDPOption[] = "udp"; 31 const char kUDPOption[] = "udp";
32 const char kUnknown[] = "unknown";
31 33
32 const char kSocketNotFoundError[] = "Socket not found"; 34 const char kSocketNotFoundError[] = "Socket not found";
33 const char kSocketTypeInvalidError[] = "Socket type is not supported"; 35 const char kSocketTypeInvalidError[] = "Socket type is not supported";
34 const char kDnsLookupFailedError[] = "DNS resolution failed"; 36 const char kDnsLookupFailedError[] = "DNS resolution failed";
37 const char kPermissionError[] = "Caller does not have permission";
35 38
36 SocketAsyncApiFunction::SocketAsyncApiFunction() 39 SocketAsyncApiFunction::SocketAsyncApiFunction()
37 : manager_(NULL) { 40 : manager_(NULL) {
38 } 41 }
39 42
40 SocketAsyncApiFunction::~SocketAsyncApiFunction() { 43 SocketAsyncApiFunction::~SocketAsyncApiFunction() {
41 } 44 }
42 45
43 bool SocketAsyncApiFunction::PrePrepare() { 46 bool SocketAsyncApiFunction::PrePrepare() {
44 manager_ = ExtensionSystem::Get(profile())->socket_manager(); 47 manager_ = ExtensionSystem::Get(profile())->socket_manager();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 159 }
157 160
158 bool SocketConnectFunction::Prepare() { 161 bool SocketConnectFunction::Prepare() {
159 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 162 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
160 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_)); 163 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_));
161 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 164 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
162 return true; 165 return true;
163 } 166 }
164 167
165 void SocketConnectFunction::AsyncWorkStart() { 168 void SocketConnectFunction::AsyncWorkStart() {
169 socket_ = manager_->Get(socket_id_);
170 if (!socket_) {
171 error_ = kSocketNotFoundError;
172 SetResult(Value::CreateIntegerValue(-1));
173 AsyncWorkCompleted();
174 return;
175 }
176
177 SocketPermissionData::OperationType operation_type;
178 switch (socket_->socket_type()) {
179 case Socket::TYPE_TCP:
180 operation_type = SocketPermissionData::TCP_CONNECT;
181 break;
182 case Socket::TYPE_UDP:
183 operation_type = SocketPermissionData::UDP_SEND_TO;
184 break;
185 default:
186 NOTREACHED() << "Unknown socket type.";
187 operation_type = SocketPermissionData::NONE;
188 break;
189 }
190
191 SocketPermission::CheckParam param(operation_type, hostname_, port_);
192 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
193 &param)) {
194 error_ = kPermissionError;
195 SetResult(Value::CreateIntegerValue(-1));
196 AsyncWorkCompleted();
197 return;
198 }
199
166 StartDnsLookup(hostname_); 200 StartDnsLookup(hostname_);
167 } 201 }
168 202
169 void SocketConnectFunction::AfterDnsLookup(int lookup_result) { 203 void SocketConnectFunction::AfterDnsLookup(int lookup_result) {
170 if (lookup_result == net::OK) { 204 if (lookup_result == net::OK) {
171 StartConnect(); 205 StartConnect();
172 } else { 206 } else {
173 SetResult(Value::CreateIntegerValue(lookup_result)); 207 SetResult(Value::CreateIntegerValue(lookup_result));
174 AsyncWorkCompleted(); 208 AsyncWorkCompleted();
175 } 209 }
176 } 210 }
177 211
178 void SocketConnectFunction::StartConnect() { 212 void SocketConnectFunction::StartConnect() {
179 Socket* socket = manager_->Get(socket_id_); 213 socket_->Connect(resolved_address_, port_,
180 if (!socket) { 214 base::Bind(&SocketConnectFunction::OnConnect, this));
181 error_ = kSocketNotFoundError;
182 OnConnect(-1);
183 return;
184 }
185
186 socket->Connect(resolved_address_, port_,
187 base::Bind(&SocketConnectFunction::OnConnect, this));
188 } 215 }
189 216
190 void SocketConnectFunction::OnConnect(int result) { 217 void SocketConnectFunction::OnConnect(int result) {
191 SetResult(Value::CreateIntegerValue(result)); 218 SetResult(Value::CreateIntegerValue(result));
192 AsyncWorkCompleted(); 219 AsyncWorkCompleted();
193 } 220 }
194 221
195 bool SocketDisconnectFunction::Prepare() { 222 bool SocketDisconnectFunction::Prepare() {
196 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 223 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
197 return true; 224 return true;
(...skipping 11 matching lines...) Expand all
209 bool SocketBindFunction::Prepare() { 236 bool SocketBindFunction::Prepare() {
210 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 237 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
211 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 238 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
212 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 239 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
213 return true; 240 return true;
214 } 241 }
215 242
216 void SocketBindFunction::Work() { 243 void SocketBindFunction::Work() {
217 int result = -1; 244 int result = -1;
218 Socket* socket = manager_->Get(socket_id_); 245 Socket* socket = manager_->Get(socket_id_);
219 if (socket) 246
220 result = socket->Bind(address_, port_); 247 if (!socket) {
221 else
222 error_ = kSocketNotFoundError; 248 error_ = kSocketNotFoundError;
249 SetResult(Value::CreateIntegerValue(result));
250 return;
251 }
223 252
253 if (socket->socket_type() == Socket::TYPE_UDP) {
254 SocketPermission::CheckParam param(
255 SocketPermissionData::UDP_BIND, address_, port_);
256 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
257 &param)) {
258 error_ = kPermissionError;
259 SetResult(Value::CreateIntegerValue(result));
260 return;
261 }
262 }
263
264 result = socket->Bind(address_, port_);
224 SetResult(Value::CreateIntegerValue(result)); 265 SetResult(Value::CreateIntegerValue(result));
225 } 266 }
226 267
227 SocketReadFunction::SocketReadFunction() 268 SocketReadFunction::SocketReadFunction()
228 : params_(NULL) { 269 : params_(NULL) {
229 } 270 }
230 271
231 SocketReadFunction::~SocketReadFunction() {} 272 SocketReadFunction::~SocketReadFunction() {}
232 273
233 bool SocketReadFunction::Prepare() { 274 bool SocketReadFunction::Prepare() {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); 407 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data));
367 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_)); 408 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_));
368 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); 409 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_));
369 410
370 io_buffer_size_ = data->GetSize(); 411 io_buffer_size_ = data->GetSize();
371 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 412 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer());
372 return true; 413 return true;
373 } 414 }
374 415
375 void SocketSendToFunction::AsyncWorkStart() { 416 void SocketSendToFunction::AsyncWorkStart() {
417 socket_ = manager_->Get(socket_id_);
418 if (!socket_) {
419 error_ = kSocketNotFoundError;
420 SetResult(Value::CreateIntegerValue(-1));
421 AsyncWorkCompleted();
422 return;
423 }
424
425 if (socket_->socket_type() == Socket::TYPE_UDP) {
426 SocketPermission::CheckParam param(SocketPermissionData::UDP_SEND_TO,
427 hostname_, port_);
428 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
429 &param)) {
430 error_ = kPermissionError;
431 SetResult(Value::CreateIntegerValue(-1));
432 AsyncWorkCompleted();
433 return;
434 }
435 }
436
376 StartDnsLookup(hostname_); 437 StartDnsLookup(hostname_);
377 } 438 }
378 439
379 void SocketSendToFunction::AfterDnsLookup(int lookup_result) { 440 void SocketSendToFunction::AfterDnsLookup(int lookup_result) {
380 if (lookup_result == net::OK) { 441 if (lookup_result == net::OK) {
381 StartSendTo(); 442 StartSendTo();
382 } else { 443 } else {
383 SetResult(Value::CreateIntegerValue(lookup_result)); 444 SetResult(Value::CreateIntegerValue(lookup_result));
384 AsyncWorkCompleted(); 445 AsyncWorkCompleted();
385 } 446 }
386 } 447 }
387 448
388 void SocketSendToFunction::StartSendTo() { 449 void SocketSendToFunction::StartSendTo() {
389 Socket* socket = manager_->Get(socket_id_); 450 socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
390 if (!socket) { 451 base::Bind(&SocketSendToFunction::OnCompleted, this));
391 error_ = kSocketNotFoundError;
392 OnCompleted(-1);
393 return;
394 }
395
396 socket->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
397 base::Bind(&SocketSendToFunction::OnCompleted, this));
398 } 452 }
399 453
400 void SocketSendToFunction::OnCompleted(int bytes_written) { 454 void SocketSendToFunction::OnCompleted(int bytes_written) {
401 DictionaryValue* result = new DictionaryValue(); 455 DictionaryValue* result = new DictionaryValue();
402 result->SetInteger(kBytesWrittenKey, bytes_written); 456 result->SetInteger(kBytesWrittenKey, bytes_written);
403 SetResult(result); 457 SetResult(result);
404 458
405 AsyncWorkCompleted(); 459 AsyncWorkCompleted();
406 } 460 }
407 461
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 EXTENSION_FUNCTION_VALIDATE(params_.get()); 517 EXTENSION_FUNCTION_VALIDATE(params_.get());
464 return true; 518 return true;
465 } 519 }
466 520
467 void SocketGetInfoFunction::Work() { 521 void SocketGetInfoFunction::Work() {
468 api::socket::SocketInfo info; 522 api::socket::SocketInfo info;
469 Socket* socket = manager_->Get(params_->socket_id); 523 Socket* socket = manager_->Get(params_->socket_id);
470 if (socket) { 524 if (socket) {
471 // This represents what we know about the socket, and does not call through 525 // This represents what we know about the socket, and does not call through
472 // to the system. 526 // to the system.
473 info.socket_type = (socket->IsTCPSocket() ? kTCPOption : kUDPOption); 527 switch (socket->socket_type()) {
528 case Socket::TYPE_TCP:
529 info.socket_type = kTCPOption;
530 break;
531 case Socket::TYPE_UDP:
532 info.socket_type = kUDPOption;
533 break;
534 default:
535 NOTREACHED() << "Unknown socket type.";
536 info.socket_type = kUnknown;
537 break;
538 }
474 info.connected = socket->IsConnected(); 539 info.connected = socket->IsConnected();
475 540
476 // Grab the peer address as known by the OS. This and the call below will 541 // Grab the peer address as known by the OS. This and the call below will
477 // always succeed while the socket is connected, even if the socket has 542 // always succeed while the socket is connected, even if the socket has
478 // been remotely closed by the peer; only reading the socket will reveal 543 // been remotely closed by the peer; only reading the socket will reveal
479 // that it should be closed locally. 544 // that it should be closed locally.
480 net::IPEndPoint peerAddress; 545 net::IPEndPoint peerAddress;
481 if (socket->GetPeerAddress(&peerAddress)) { 546 if (socket->GetPeerAddress(&peerAddress)) {
482 info.peer_address.reset( 547 info.peer_address.reset(
483 new std::string(peerAddress.ToStringWithoutPort())); 548 new std::string(peerAddress.ToStringWithoutPort()));
484 info.peer_port.reset(new int(peerAddress.port())); 549 info.peer_port.reset(new int(peerAddress.port()));
485 } 550 }
486 551
487 // Grab the local address as known by the OS. 552 // Grab the local address as known by the OS.
488 net::IPEndPoint localAddress; 553 net::IPEndPoint localAddress;
489 if (socket->GetLocalAddress(&localAddress)) { 554 if (socket->GetLocalAddress(&localAddress)) {
490 info.local_address.reset( 555 info.local_address.reset(
491 new std::string(localAddress.ToStringWithoutPort())); 556 new std::string(localAddress.ToStringWithoutPort()));
492 info.local_port.reset(new int(localAddress.port())); 557 info.local_port.reset(new int(localAddress.port()));
493 } 558 }
494 } else { 559 } else {
495 error_ = kSocketNotFoundError; 560 error_ = kSocketNotFoundError;
496 } 561 }
497 SetResult(info.ToValue().release()); 562 SetResult(info.ToValue().release());
498 } 563 }
499 564
500 } // namespace extensions 565 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698