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

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

Issue 76403004: An implementation of chrome.socket.secure(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Stop using Profile and move completely to URLRequestContext. Created 6 years, 5 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/socket/socket_api.h" 5 #include "extensions/browser/api/socket/socket_api.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
11 #include "content/public/browser/browser_context.h" 11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/resource_context.h" 12 #include "content/public/browser/resource_context.h"
13 #include "extensions/browser/api/dns/host_resolver_wrapper.h" 13 #include "extensions/browser/api/dns/host_resolver_wrapper.h"
14 #include "extensions/browser/api/socket/socket.h" 14 #include "extensions/browser/api/socket/socket.h"
15 #include "extensions/browser/api/socket/tcp_socket.h" 15 #include "extensions/browser/api/socket/tcp_socket.h"
16 #include "extensions/browser/api/socket/tls_socket.h"
16 #include "extensions/browser/api/socket/udp_socket.h" 17 #include "extensions/browser/api/socket/udp_socket.h"
17 #include "extensions/browser/extension_system.h" 18 #include "extensions/browser/extension_system.h"
18 #include "extensions/common/extension.h" 19 #include "extensions/common/extension.h"
19 #include "extensions/common/permissions/permissions_data.h" 20 #include "extensions/common/permissions/permissions_data.h"
20 #include "extensions/common/permissions/socket_permission.h" 21 #include "extensions/common/permissions/socket_permission.h"
21 #include "net/base/host_port_pair.h" 22 #include "net/base/host_port_pair.h"
22 #include "net/base/io_buffer.h" 23 #include "net/base/io_buffer.h"
23 #include "net/base/ip_endpoint.h" 24 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h" 25 #include "net/base/net_errors.h"
25 #include "net/base/net_log.h" 26 #include "net/base/net_log.h"
26 #include "net/base/net_util.h" 27 #include "net/base/net_util.h"
28 #include "net/url_request/url_request_context.h"
29 #include "net/url_request/url_request_context_getter.h"
27 30
28 namespace extensions { 31 namespace extensions {
29 32
30 using content::SocketPermissionRequest; 33 using content::SocketPermissionRequest;
31 34
32 const char kAddressKey[] = "address"; 35 const char kAddressKey[] = "address";
33 const char kPortKey[] = "port"; 36 const char kPortKey[] = "port";
34 const char kBytesWrittenKey[] = "bytesWritten"; 37 const char kBytesWrittenKey[] = "bytesWritten";
35 const char kDataKey[] = "data"; 38 const char kDataKey[] = "data";
36 const char kResultCodeKey[] = "resultCode"; 39 const char kResultCodeKey[] = "resultCode";
37 const char kSocketIdKey[] = "socketId"; 40 const char kSocketIdKey[] = "socketId";
38 41
39 const char kSocketNotFoundError[] = "Socket not found"; 42 const char kSocketNotFoundError[] = "Socket not found";
40 const char kDnsLookupFailedError[] = "DNS resolution failed"; 43 const char kDnsLookupFailedError[] = "DNS resolution failed";
41 const char kPermissionError[] = "App does not have permission"; 44 const char kPermissionError[] = "App does not have permission";
42 const char kNetworkListError[] = "Network lookup failed or unsupported"; 45 const char kNetworkListError[] = "Network lookup failed or unsupported";
43 const char kTCPSocketBindError[] = 46 const char kTCPSocketBindError[] =
44 "TCP socket does not support bind. For TCP server please use listen."; 47 "TCP socket does not support bind. For TCP server please use listen.";
45 const char kMulticastSocketTypeError[] = "Only UDP socket supports multicast."; 48 const char kMulticastSocketTypeError[] = "Only UDP socket supports multicast.";
49 const char kSecureSocketTypeError[] = "Only TCP sockets are supported for TLS.";
50 const char kSocketNotConnectedError[] = "Socket not connected";
46 const char kWildcardAddress[] = "*"; 51 const char kWildcardAddress[] = "*";
47 const int kWildcardPort = 0; 52 const int kWildcardPort = 0;
48 53
54 namespace {
55 // Returns the SSL protocol version (as a uint16) represented by a string.
56 // Returns 0 if the string is invalid.
57 uint16 SSLProtocolVersionFromString(const std::string& version_str) {
58 uint16 version = 0; // Invalid.
59 if (version_str == "ssl3") {
60 version = net::SSL_PROTOCOL_VERSION_SSL3;
61 } else if (version_str == "tls1") {
62 version = net::SSL_PROTOCOL_VERSION_TLS1;
63 } else if (version_str == "tls1.1") {
64 version = net::SSL_PROTOCOL_VERSION_TLS1_1;
65 } else if (version_str == "tls1.2") {
66 version = net::SSL_PROTOCOL_VERSION_TLS1_2;
67 }
68 return version;
69 }
70 } // namespace
71
49 SocketAsyncApiFunction::SocketAsyncApiFunction() {} 72 SocketAsyncApiFunction::SocketAsyncApiFunction() {}
50 73
51 SocketAsyncApiFunction::~SocketAsyncApiFunction() {} 74 SocketAsyncApiFunction::~SocketAsyncApiFunction() {}
52 75
53 bool SocketAsyncApiFunction::PrePrepare() { 76 bool SocketAsyncApiFunction::PrePrepare() {
54 manager_ = CreateSocketResourceManager(); 77 manager_ = CreateSocketResourceManager();
55 return manager_->SetBrowserContext(browser_context()); 78 return manager_->SetBrowserContext(browser_context());
56 } 79 }
57 80
58 bool SocketAsyncApiFunction::Respond() { return error_.empty(); } 81 bool SocketAsyncApiFunction::Respond() { return error_.empty(); }
59 82
60 scoped_ptr<SocketResourceManagerInterface> 83 scoped_ptr<SocketResourceManagerInterface>
61 SocketAsyncApiFunction::CreateSocketResourceManager() { 84 SocketAsyncApiFunction::CreateSocketResourceManager() {
62 return scoped_ptr<SocketResourceManagerInterface>( 85 return scoped_ptr<SocketResourceManagerInterface>(
63 new SocketResourceManager<Socket>()).Pass(); 86 new SocketResourceManager<Socket>()).Pass();
64 } 87 }
65 88
66 int SocketAsyncApiFunction::AddSocket(Socket* socket) { 89 int SocketAsyncApiFunction::AddSocket(Socket* socket) {
67 return manager_->Add(socket); 90 return manager_->Add(socket);
68 } 91 }
69 92
70 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) { 93 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) {
71 return manager_->Get(extension_->id(), api_resource_id); 94 return manager_->Get(extension_->id(), api_resource_id);
72 } 95 }
73 96
97 void SocketAsyncApiFunction::ReplaceSocket(int api_resource_id,
98 Socket* socket) {
99 manager_->Replace(extension_->id(), api_resource_id, socket);
100 }
101
74 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() { 102 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() {
75 return manager_->GetResourceIds(extension_->id()); 103 return manager_->GetResourceIds(extension_->id());
76 } 104 }
77 105
78 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) { 106 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) {
79 manager_->Remove(extension_->id(), api_resource_id); 107 manager_->Remove(extension_->id(), api_resource_id);
80 } 108 }
81 109
82 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction() 110 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction()
83 : resource_context_(NULL), 111 : resource_context_(NULL),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 216
189 void SocketConnectFunction::AsyncWorkStart() { 217 void SocketConnectFunction::AsyncWorkStart() {
190 socket_ = GetSocket(socket_id_); 218 socket_ = GetSocket(socket_id_);
191 if (!socket_) { 219 if (!socket_) {
192 error_ = kSocketNotFoundError; 220 error_ = kSocketNotFoundError;
193 SetResult(new base::FundamentalValue(-1)); 221 SetResult(new base::FundamentalValue(-1));
194 AsyncWorkCompleted(); 222 AsyncWorkCompleted();
195 return; 223 return;
196 } 224 }
197 225
226 socket_->set_hostname(hostname_);
227
198 SocketPermissionRequest::OperationType operation_type; 228 SocketPermissionRequest::OperationType operation_type;
199 switch (socket_->GetSocketType()) { 229 switch (socket_->GetSocketType()) {
200 case Socket::TYPE_TCP: 230 case Socket::TYPE_TCP:
201 operation_type = SocketPermissionRequest::TCP_CONNECT; 231 operation_type = SocketPermissionRequest::TCP_CONNECT;
202 break; 232 break;
203 case Socket::TYPE_UDP: 233 case Socket::TYPE_UDP:
204 operation_type = SocketPermissionRequest::UDP_SEND_TO; 234 operation_type = SocketPermissionRequest::UDP_SEND_TO;
205 break; 235 break;
206 default: 236 default:
207 NOTREACHED() << "Unknown socket type."; 237 NOTREACHED() << "Unknown socket type.";
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 SetResult(new base::FundamentalValue(result)); 911 SetResult(new base::FundamentalValue(result));
882 return; 912 return;
883 } 913 }
884 914
885 base::ListValue* values = new base::ListValue(); 915 base::ListValue* values = new base::ListValue();
886 values->AppendStrings((std::vector<std::string>&)static_cast<UDPSocket*>( 916 values->AppendStrings((std::vector<std::string>&)static_cast<UDPSocket*>(
887 socket)->GetJoinedGroups()); 917 socket)->GetJoinedGroups());
888 SetResult(values); 918 SetResult(values);
889 } 919 }
890 920
921 SocketSecureFunction::SocketSecureFunction() {
922 }
923
924 SocketSecureFunction::~SocketSecureFunction() {
925 }
926
927 bool SocketSecureFunction::Prepare() {
928 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
929 params_ = core_api::socket::Secure::Params::Create(*args_);
930 EXTENSION_FUNCTION_VALIDATE(params_.get());
931 url_request_getter_ = browser_context()->GetRequestContext();
932 return true;
933 }
934
935 // Override the regular implementation, which would call AsyncWorkCompleted
936 // immediately after Work().
937 void SocketSecureFunction::AsyncWorkStart() {
938 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
939
940 Socket* socket = GetSocket(params_->socket_id);
941 if (!socket) {
942 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
943 error_ = kSocketNotFoundError;
944 AsyncWorkCompleted();
945 return;
946 }
947
948 // Make sure that the socket is a TCP client socket.
949 if (socket->GetSocketType() != Socket::TYPE_TCP ||
950 static_cast<TCPSocket*>(socket)->ClientStream() == NULL) {
951 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
952 error_ = kSecureSocketTypeError;
953 AsyncWorkCompleted();
954 return;
955 }
956
957 if (!socket->IsConnected()) {
958 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
959 error_ = kSocketNotConnectedError;
960 AsyncWorkCompleted();
961 return;
962 }
963
964 net::URLRequestContext* url_request_context =
965 url_request_getter_->GetURLRequestContext();
966
967 TLSSocket::UpgradeSocketToTLS(
968 socket,
969 url_request_context->ssl_config_service(),
970 url_request_context->cert_verifier(),
971 url_request_context->transport_security_state(),
972 extension_id(),
973 params_->options.get(),
974 base::Bind(&SocketSecureFunction::TlsConnectDone, this));
975 }
976
977 void SocketSecureFunction::TlsConnectDone(scoped_ptr<TLSSocket> socket,
978 int result) {
979 // |socket| can only be non-null if |result| == net::OK.
980 DCHECK(result == net::OK || socket == NULL);
Ryan Sleevi 2014/07/15 00:18:45 This comment documents the inversion of the condit
lally 2014/07/16 16:19:44 I changed the comment as suggested. Thanks. On 2
981
982 if (socket && result == net::OK) {
983 ReplaceSocket(params_->socket_id, socket.release());
984 } else {
985 RemoveSocket(params_->socket_id);
986 error_ = net::ErrorToString(result);
987 }
988
989 results_ = core_api::socket::Secure::Results::Create(result);
990 AsyncWorkCompleted();
991 }
992
891 } // namespace extensions 993 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698