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

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

Powered by Google App Engine
This is Rietveld 408576698