| Index: chrome/browser/extensions/api/socket/socket_api.cc
|
| diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc
|
| index 951f60005d772158d1fd1507a95b2453c27103ae..4e75c267417389324e9a10687a23d59c89cc0749 100644
|
| --- a/chrome/browser/extensions/api/socket/socket_api.cc
|
| +++ b/chrome/browser/extensions/api/socket/socket_api.cc
|
| @@ -5,6 +5,7 @@
|
| #include "chrome/browser/extensions/api/socket/socket_api.h"
|
|
|
| #include "base/bind.h"
|
| +#include "chrome/common/extensions/permissions/socket_permission.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h"
|
| #include "chrome/browser/extensions/api/socket/socket.h"
|
| @@ -28,10 +29,12 @@ const char kResultCodeKey[] = "resultCode";
|
| const char kSocketIdKey[] = "socketId";
|
| const char kTCPOption[] = "tcp";
|
| const char kUDPOption[] = "udp";
|
| +const char kUnknown[] = "unknown";
|
|
|
| const char kSocketNotFoundError[] = "Socket not found";
|
| const char kSocketTypeInvalidError[] = "Socket type is not supported";
|
| const char kDnsLookupFailedError[] = "DNS resolution failed";
|
| +const char kPermissionError[] = "Caller does not have permission";
|
|
|
| SocketAsyncApiFunction::SocketAsyncApiFunction()
|
| : manager_(NULL) {
|
| @@ -163,6 +166,37 @@ bool SocketConnectFunction::Prepare() {
|
| }
|
|
|
| void SocketConnectFunction::AsyncWorkStart() {
|
| + socket_ = manager_->Get(socket_id_);
|
| + if (!socket_) {
|
| + error_ = kSocketNotFoundError;
|
| + SetResult(Value::CreateIntegerValue(-1));
|
| + AsyncWorkCompleted();
|
| + return;
|
| + }
|
| +
|
| + SocketPermissionData::OperationType operation_type;
|
| + switch (socket_->GetSocketType()) {
|
| + case Socket::TYPE_TCP:
|
| + operation_type = SocketPermissionData::TCP_CONNECT;
|
| + break;
|
| + case Socket::TYPE_UDP:
|
| + operation_type = SocketPermissionData::UDP_SEND_TO;
|
| + break;
|
| + default:
|
| + NOTREACHED() << "Unknown socket type.";
|
| + operation_type = SocketPermissionData::NONE;
|
| + break;
|
| + }
|
| +
|
| + SocketPermission::CheckParam param(operation_type, hostname_, port_);
|
| + if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
|
| + ¶m)) {
|
| + error_ = kPermissionError;
|
| + SetResult(Value::CreateIntegerValue(-1));
|
| + AsyncWorkCompleted();
|
| + return;
|
| + }
|
| +
|
| StartDnsLookup(hostname_);
|
| }
|
|
|
| @@ -176,15 +210,8 @@ void SocketConnectFunction::AfterDnsLookup(int lookup_result) {
|
| }
|
|
|
| void SocketConnectFunction::StartConnect() {
|
| - Socket* socket = manager_->Get(socket_id_);
|
| - if (!socket) {
|
| - error_ = kSocketNotFoundError;
|
| - OnConnect(-1);
|
| - return;
|
| - }
|
| -
|
| - socket->Connect(resolved_address_, port_,
|
| - base::Bind(&SocketConnectFunction::OnConnect, this));
|
| + socket_->Connect(resolved_address_, port_,
|
| + base::Bind(&SocketConnectFunction::OnConnect, this));
|
| }
|
|
|
| void SocketConnectFunction::OnConnect(int result) {
|
| @@ -216,11 +243,25 @@ bool SocketBindFunction::Prepare() {
|
| void SocketBindFunction::Work() {
|
| int result = -1;
|
| Socket* socket = manager_->Get(socket_id_);
|
| - if (socket)
|
| - result = socket->Bind(address_, port_);
|
| - else
|
| +
|
| + if (!socket) {
|
| error_ = kSocketNotFoundError;
|
| + SetResult(Value::CreateIntegerValue(result));
|
| + return;
|
| + }
|
| +
|
| + if (socket->GetSocketType() == Socket::TYPE_UDP) {
|
| + SocketPermission::CheckParam param(
|
| + SocketPermissionData::UDP_BIND, address_, port_);
|
| + if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
|
| + ¶m)) {
|
| + error_ = kPermissionError;
|
| + SetResult(Value::CreateIntegerValue(result));
|
| + return;
|
| + }
|
| + }
|
|
|
| + result = socket->Bind(address_, port_);
|
| SetResult(Value::CreateIntegerValue(result));
|
| }
|
|
|
| @@ -373,6 +414,26 @@ bool SocketSendToFunction::Prepare() {
|
| }
|
|
|
| void SocketSendToFunction::AsyncWorkStart() {
|
| + socket_ = manager_->Get(socket_id_);
|
| + if (!socket_) {
|
| + error_ = kSocketNotFoundError;
|
| + SetResult(Value::CreateIntegerValue(-1));
|
| + AsyncWorkCompleted();
|
| + return;
|
| + }
|
| +
|
| + if (socket_->GetSocketType() == Socket::TYPE_UDP) {
|
| + SocketPermission::CheckParam param(SocketPermissionData::UDP_SEND_TO,
|
| + hostname_, port_);
|
| + if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket,
|
| + ¶m)) {
|
| + error_ = kPermissionError;
|
| + SetResult(Value::CreateIntegerValue(-1));
|
| + AsyncWorkCompleted();
|
| + return;
|
| + }
|
| + }
|
| +
|
| StartDnsLookup(hostname_);
|
| }
|
|
|
| @@ -386,15 +447,8 @@ void SocketSendToFunction::AfterDnsLookup(int lookup_result) {
|
| }
|
|
|
| void SocketSendToFunction::StartSendTo() {
|
| - Socket* socket = manager_->Get(socket_id_);
|
| - if (!socket) {
|
| - error_ = kSocketNotFoundError;
|
| - OnCompleted(-1);
|
| - return;
|
| - }
|
| -
|
| - socket->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
|
| - base::Bind(&SocketSendToFunction::OnCompleted, this));
|
| + socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
|
| + base::Bind(&SocketSendToFunction::OnCompleted, this));
|
| }
|
|
|
| void SocketSendToFunction::OnCompleted(int bytes_written) {
|
| @@ -470,7 +524,18 @@ void SocketGetInfoFunction::Work() {
|
| if (socket) {
|
| // This represents what we know about the socket, and does not call through
|
| // to the system.
|
| - info.socket_type = (socket->IsTCPSocket() ? kTCPOption : kUDPOption);
|
| + switch (socket->GetSocketType()) {
|
| + case Socket::TYPE_TCP:
|
| + info.socket_type = kTCPOption;
|
| + break;
|
| + case Socket::TYPE_UDP:
|
| + info.socket_type = kUDPOption;
|
| + break;
|
| + default:
|
| + NOTREACHED() << "Unknown socket type.";
|
| + info.socket_type = kUnknown;
|
| + break;
|
| + }
|
| info.connected = socket->IsConnected();
|
|
|
| // Grab the peer address as known by the OS. This and the call below will
|
|
|