OLD | NEW |
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 Loading... |
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 ¶m)) { |
| 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 Loading... |
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 ¶m)) { |
| 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 Loading... |
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 ¶m)) { |
| 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 Loading... |
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 |
OLD | NEW |