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

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 compile issues.wq 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 type;
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 Can you call this variable operation_type? Otherwi
Peng 2012/08/13 16:26:10 Done.
178 switch (socket_->socket_type()) {
179 case Socket::TYPE_TCP:
180 type = SocketPermissionData::TCP_CONNECT;
181 break;
182 case Socket::TYPE_UDP:
183 type = SocketPermissionData::UDP_SEND_TO;
184 break;
185 default:
186 type = SocketPermissionData::NONE;
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 NOTREACHED() may be more appropriate here (I think
Peng 2012/08/13 16:26:10 Done.
187 break;
188 }
189
190 SocketPermission::CheckParam param(type, hostname_, port_);
191 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
192 &param)) {
193 error_ = kPermissionError;
194 SetResult(Value::CreateIntegerValue(-1));
195 AsyncWorkCompleted();
196 return;
197 }
198
166 StartDnsLookup(hostname_); 199 StartDnsLookup(hostname_);
167 } 200 }
168 201
169 void SocketConnectFunction::AfterDnsLookup(int lookup_result) { 202 void SocketConnectFunction::AfterDnsLookup(int lookup_result) {
170 if (lookup_result == net::OK) { 203 if (lookup_result == net::OK) {
171 StartConnect(); 204 StartConnect();
172 } else { 205 } else {
173 SetResult(Value::CreateIntegerValue(lookup_result)); 206 SetResult(Value::CreateIntegerValue(lookup_result));
174 AsyncWorkCompleted(); 207 AsyncWorkCompleted();
175 } 208 }
176 } 209 }
177 210
178 void SocketConnectFunction::StartConnect() { 211 void SocketConnectFunction::StartConnect() {
179 Socket* socket = manager_->Get(socket_id_); 212 socket_->Connect(resolved_address_, port_,
180 if (!socket) { 213 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 } 214 }
189 215
190 void SocketConnectFunction::OnConnect(int result) { 216 void SocketConnectFunction::OnConnect(int result) {
191 SetResult(Value::CreateIntegerValue(result)); 217 SetResult(Value::CreateIntegerValue(result));
192 AsyncWorkCompleted(); 218 AsyncWorkCompleted();
193 } 219 }
194 220
195 bool SocketDisconnectFunction::Prepare() { 221 bool SocketDisconnectFunction::Prepare() {
196 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 222 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
197 return true; 223 return true;
(...skipping 11 matching lines...) Expand all
209 bool SocketBindFunction::Prepare() { 235 bool SocketBindFunction::Prepare() {
210 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 236 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
211 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 237 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
212 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 238 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
213 return true; 239 return true;
214 } 240 }
215 241
216 void SocketBindFunction::Work() { 242 void SocketBindFunction::Work() {
217 int result = -1; 243 int result = -1;
218 Socket* socket = manager_->Get(socket_id_); 244 Socket* socket = manager_->Get(socket_id_);
219 if (socket) 245 SocketPermission::CheckParam param(
220 result = socket->Bind(address_, port_); 246 SocketPermissionData::UDP_BIND, address_, port_);
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 TCP sockets also implement the Bind method. Can yo
Peng 2012/08/13 16:26:10 Done.
221 else 247 if (socket) {
248 if (GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
249 &param))
250 result = socket->Bind(address_, port_);
251 else
252 error_ = kPermissionError;
253 } else {
222 error_ = kSocketNotFoundError; 254 error_ = kSocketNotFoundError;
255 }
223 256
224 SetResult(Value::CreateIntegerValue(result)); 257 SetResult(Value::CreateIntegerValue(result));
225 } 258 }
226 259
227 SocketReadFunction::SocketReadFunction() 260 SocketReadFunction::SocketReadFunction()
228 : params_(NULL) { 261 : params_(NULL) {
229 } 262 }
230 263
231 SocketReadFunction::~SocketReadFunction() {} 264 SocketReadFunction::~SocketReadFunction() {}
232 265
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); 399 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data));
367 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_)); 400 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_));
368 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); 401 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_));
369 402
370 io_buffer_size_ = data->GetSize(); 403 io_buffer_size_ = data->GetSize();
371 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); 404 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer());
372 return true; 405 return true;
373 } 406 }
374 407
375 void SocketSendToFunction::AsyncWorkStart() { 408 void SocketSendToFunction::AsyncWorkStart() {
376 StartDnsLookup(hostname_); 409 do {
410 socket_ = manager_->Get(socket_id_);
411 if (!socket_) {
412 error_ = kSocketNotFoundError;
413 break;
414 }
415
416 SocketPermission::CheckParam param(SocketPermissionData::UDP_SEND_TO,
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 Same thing here.
Peng 2012/08/13 16:26:10 Done.
417 hostname_, port_);
418 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
419 &param)) {
420 error_ = kPermissionError;
421 break;
422 }
423
424 StartDnsLookup(hostname_);
425 return;
426 } while (false);
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 I found the break/while(false) pattern hard to rea
Peng 2012/08/13 16:26:10 Done.
Peng 2012/08/13 16:26:10 Done.
427 SetResult(Value::CreateIntegerValue(-1));
428 AsyncWorkCompleted();
377 } 429 }
378 430
379 void SocketSendToFunction::AfterDnsLookup(int lookup_result) { 431 void SocketSendToFunction::AfterDnsLookup(int lookup_result) {
380 if (lookup_result == net::OK) { 432 if (lookup_result == net::OK) {
381 StartSendTo(); 433 StartSendTo();
382 } else { 434 } else {
383 SetResult(Value::CreateIntegerValue(lookup_result)); 435 SetResult(Value::CreateIntegerValue(lookup_result));
384 AsyncWorkCompleted(); 436 AsyncWorkCompleted();
385 } 437 }
386 } 438 }
387 439
388 void SocketSendToFunction::StartSendTo() { 440 void SocketSendToFunction::StartSendTo() {
389 Socket* socket = manager_->Get(socket_id_); 441 socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
390 if (!socket) { 442 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 } 443 }
399 444
400 void SocketSendToFunction::OnCompleted(int bytes_written) { 445 void SocketSendToFunction::OnCompleted(int bytes_written) {
401 DictionaryValue* result = new DictionaryValue(); 446 DictionaryValue* result = new DictionaryValue();
402 result->SetInteger(kBytesWrittenKey, bytes_written); 447 result->SetInteger(kBytesWrittenKey, bytes_written);
403 SetResult(result); 448 SetResult(result);
404 449
405 AsyncWorkCompleted(); 450 AsyncWorkCompleted();
406 } 451 }
407 452
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 EXTENSION_FUNCTION_VALIDATE(params_.get()); 508 EXTENSION_FUNCTION_VALIDATE(params_.get());
464 return true; 509 return true;
465 } 510 }
466 511
467 void SocketGetInfoFunction::Work() { 512 void SocketGetInfoFunction::Work() {
468 api::socket::SocketInfo info; 513 api::socket::SocketInfo info;
469 Socket* socket = manager_->Get(params_->socket_id); 514 Socket* socket = manager_->Get(params_->socket_id);
470 if (socket) { 515 if (socket) {
471 // This represents what we know about the socket, and does not call through 516 // This represents what we know about the socket, and does not call through
472 // to the system. 517 // to the system.
473 info.socket_type = (socket->IsTCPSocket() ? kTCPOption : kUDPOption); 518 switch (socket->socket_type()) {
519 case Socket::TYPE_TCP:
520 info.socket_type = kTCPOption;
521 break;
522 case Socket::TYPE_UDP:
523 info.socket_type = kUDPOption;
524 break;
525 default:
526 info.socket_type = kUnknown;
Mihai Parparita -not on Chrome 2012/08/10 00:16:16 Also use NOTREACHED here.
Peng 2012/08/13 16:26:10 Done.
527 break;
528 }
474 info.connected = socket->IsConnected(); 529 info.connected = socket->IsConnected();
475 530
476 // Grab the peer address as known by the OS. This and the call below will 531 // 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 532 // 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 533 // been remotely closed by the peer; only reading the socket will reveal
479 // that it should be closed locally. 534 // that it should be closed locally.
480 net::IPEndPoint peerAddress; 535 net::IPEndPoint peerAddress;
481 if (socket->GetPeerAddress(&peerAddress)) { 536 if (socket->GetPeerAddress(&peerAddress)) {
482 info.peer_address.reset( 537 info.peer_address.reset(
483 new std::string(peerAddress.ToStringWithoutPort())); 538 new std::string(peerAddress.ToStringWithoutPort()));
484 info.peer_port.reset(new int(peerAddress.port())); 539 info.peer_port.reset(new int(peerAddress.port()));
485 } 540 }
486 541
487 // Grab the local address as known by the OS. 542 // Grab the local address as known by the OS.
488 net::IPEndPoint localAddress; 543 net::IPEndPoint localAddress;
489 if (socket->GetLocalAddress(&localAddress)) { 544 if (socket->GetLocalAddress(&localAddress)) {
490 info.local_address.reset( 545 info.local_address.reset(
491 new std::string(localAddress.ToStringWithoutPort())); 546 new std::string(localAddress.ToStringWithoutPort()));
492 info.local_port.reset(new int(localAddress.port())); 547 info.local_port.reset(new int(localAddress.port()));
493 } 548 }
494 } else { 549 } else {
495 error_ = kSocketNotFoundError; 550 error_ = kSocketNotFoundError;
496 } 551 }
497 SetResult(info.ToValue().release()); 552 SetResult(info.ToValue().release());
498 } 553 }
499 554
500 } // namespace extensions 555 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698