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

Side by Side Diff: extensions/browser/api/sockets_tcp/sockets_tcp_api.cc

Issue 76403004: An implementation of chrome.socket.secure(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed, @rsleevi's comments, added a new TLS test, further separated TLS and TCP tests, and reba… Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/api/sockets_tcp/sockets_tcp_api.h" 5 #include "extensions/browser/api/sockets_tcp/sockets_tcp_api.h"
6 6
7 #include "chrome/browser/profiles/profile.h"
7 #include "chrome/common/extensions/api/sockets/sockets_manifest_data.h" 8 #include "chrome/common/extensions/api/sockets/sockets_manifest_data.h"
8 #include "content/public/common/socket_permission_request.h" 9 #include "content/public/common/socket_permission_request.h"
9 #include "extensions/browser/api/socket/tcp_socket.h" 10 #include "extensions/browser/api/socket/tcp_socket.h"
11 #include "extensions/browser/api/socket/tls_socket.h"
10 #include "extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.h" 12 #include "extensions/browser/api/sockets_tcp/tcp_socket_event_dispatcher.h"
11 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
14 #include "net/url_request/url_request_context_getter.h"
12 15
13 using extensions::ResumableTCPSocket; 16 using extensions::ResumableTCPSocket;
14 using extensions::core_api::sockets_tcp::SocketInfo; 17 using extensions::core_api::sockets_tcp::SocketInfo;
15 using extensions::core_api::sockets_tcp::SocketProperties; 18 using extensions::core_api::sockets_tcp::SocketProperties;
16 19
17 namespace { 20 namespace {
18 21
19 const char kSocketNotFoundError[] = "Socket not found"; 22 const char kSocketNotFoundError[] = "Socket not found";
20 const char kPermissionError[] = "Does not have permission"; 23 const char kPermissionError[] = "Does not have permission";
24 const char kInvalidSocketStateError[] =
25 "Socket must be a connected client TCP socket.";
26 const char kSocketNotConnectedError[] = "Socket not connected";
21 27
22 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id, 28 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
23 ResumableTCPSocket* socket) { 29 ResumableTCPSocket* socket) {
24 linked_ptr<SocketInfo> socket_info(new SocketInfo()); 30 linked_ptr<SocketInfo> socket_info(new SocketInfo());
25 // This represents what we know about the socket, and does not call through 31 // This represents what we know about the socket, and does not call through
26 // to the system. 32 // to the system.
27 socket_info->socket_id = socket_id; 33 socket_info->socket_id = socket_id;
28 if (!socket->name().empty()) { 34 if (!socket->name().empty()) {
29 socket_info->name.reset(new std::string(socket->name())); 35 socket_info->name.reset(new std::string(socket->name()));
30 } 36 }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 } 260 }
255 261
256 void SocketsTcpConnectFunction::AsyncWorkStart() { 262 void SocketsTcpConnectFunction::AsyncWorkStart() {
257 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id); 263 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
258 if (!socket) { 264 if (!socket) {
259 error_ = kSocketNotFoundError; 265 error_ = kSocketNotFoundError;
260 AsyncWorkCompleted(); 266 AsyncWorkCompleted();
261 return; 267 return;
262 } 268 }
263 269
264 content::SocketPermissionRequest param(SocketPermissionRequest::TCP_CONNECT, 270 socket->set_hostname(params_->peer_address);
265 params_->peer_address, 271
266 params_->peer_port); 272 content::SocketPermissionRequest param(
273 SocketPermissionRequest::TCP_CONNECT,
274 params_->peer_address,
275 params_->peer_port);
276
267 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) { 277 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
268 error_ = kPermissionError; 278 error_ = kPermissionError;
269 AsyncWorkCompleted(); 279 AsyncWorkCompleted();
270 return; 280 return;
271 } 281 }
272 282
273 StartDnsLookup(params_->peer_address); 283 StartDnsLookup(params_->peer_address);
274 } 284 }
275 285
276 void SocketsTcpConnectFunction::AfterDnsLookup(int lookup_result) { 286 void SocketsTcpConnectFunction::AfterDnsLookup(int lookup_result) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 int socket_id = *it; 444 int socket_id = *it;
435 ResumableTCPSocket* socket = GetTcpSocket(socket_id); 445 ResumableTCPSocket* socket = GetTcpSocket(socket_id);
436 if (socket) { 446 if (socket) {
437 socket_infos.push_back(CreateSocketInfo(socket_id, socket)); 447 socket_infos.push_back(CreateSocketInfo(socket_id, socket));
438 } 448 }
439 } 449 }
440 } 450 }
441 results_ = sockets_tcp::GetSockets::Results::Create(socket_infos); 451 results_ = sockets_tcp::GetSockets::Results::Create(socket_infos);
442 } 452 }
443 453
444 } // namespace core_api 454 SocketsTcpSecureFunction::SocketsTcpSecureFunction() {}
455 SocketsTcpSecureFunction::~SocketsTcpSecureFunction() {}
456
457 bool SocketsTcpSecureFunction::Prepare() {
458 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
459 params_ = core_api::sockets_tcp::Secure::Params::Create(*args_);
460 EXTENSION_FUNCTION_VALIDATE(params_.get());
461 url_request_getter_ = browser_context()->GetRequestContext();
462 return true;
463 }
464
465 // Override the regular implementation, which would call AsyncWorkCompleted
466 // immediately after Work().
467 void SocketsTcpSecureFunction::AsyncWorkStart() {
468 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
469
470 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
471 if (!socket) {
472 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
473 error_ = kSocketNotFoundError;
474 AsyncWorkCompleted();
475 return;
476 }
477
478 paused_ = socket->paused();
479 persistent_ = socket->persistent();
480
481 // Make sure it's a connected TCP client socket. Error out if it's already
482 // secure()'d.
483 if (socket->GetSocketType() != Socket::TYPE_TCP ||
484 socket->ClientStream() == NULL) {
485 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
486 error_ = kInvalidSocketStateError;
487 AsyncWorkCompleted();
488 return;
489 }
490
491 if (!socket->IsConnected()) {
492 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
493 error_ = kSocketNotConnectedError;
494 AsyncWorkCompleted();
495 return;
496 }
497
498 Profile* profile = Profile::FromBrowserContext(browser_context());
499 DCHECK(profile);
500
501 scoped_refptr<net::SSLConfigService> config_service(
502 profile->GetSSLConfigService());
503
504 // UpgradeSocketToTLS() uses the older API's SecureOptions. Copy the only
505 // values inside -- the TLSVersionConstraints's |min| and |max|, over.
506 core_api::socket::SecureOptions legacy_params;
507 if (params_->options.get() && params_->options->tls_version.get()) {
508 legacy_params.tls_version.reset(
509 new core_api::socket::TLSVersionConstraints);
510 if (params_->options->tls_version->min.get()) {
511 legacy_params.tls_version->min.reset(
512 new std::string(*params_->options->tls_version->min.get()));
513 }
514 if (params_->options->tls_version->max.get()) {
515 legacy_params.tls_version->max.reset(
516 new std::string(*params_->options->tls_version->max.get()));
517 }
518 }
519
520 TLSSocket::UpgradeSocketToTLS(
521 socket,
522 config_service,
523 url_request_getter_,
524 extension_id(),
525 &legacy_params,
526 base::Bind(&SocketsTcpSecureFunction::TlsConnectDone, this));
527 }
528
529 void SocketsTcpSecureFunction::TlsConnectDone(scoped_ptr<TLSSocket> socket,
530 int result) {
531 // |socket| can only be non-null if |result| == net::OK.
532 DCHECK(result == net::OK || socket == NULL);
533
534 if (socket && result == net::OK) {
535 socket->set_persistent(persistent_);
536 socket->set_paused(paused_);
537 ReplaceSocket(params_->socket_id, socket.release());
538 } else {
539 RemoveSocket(params_->socket_id);
540 error_ = net::ErrorToString(result);
541 }
542
543 results_ = core_api::sockets_tcp::Secure::Results::Create(result);
544 AsyncWorkCompleted();
545 }
546
547 } // namespace api
445 } // namespace extensions 548 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698