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

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: Updated tls_socket_unittest for a mocked method signature change. (2) 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
49 SocketAsyncApiFunction::SocketAsyncApiFunction() {} 54 SocketAsyncApiFunction::SocketAsyncApiFunction() {}
50 55
51 SocketAsyncApiFunction::~SocketAsyncApiFunction() {} 56 SocketAsyncApiFunction::~SocketAsyncApiFunction() {}
52 57
53 bool SocketAsyncApiFunction::PrePrepare() { 58 bool SocketAsyncApiFunction::PrePrepare() {
54 manager_ = CreateSocketResourceManager(); 59 manager_ = CreateSocketResourceManager();
55 return manager_->SetBrowserContext(browser_context()); 60 return manager_->SetBrowserContext(browser_context());
56 } 61 }
57 62
58 bool SocketAsyncApiFunction::Respond() { return error_.empty(); } 63 bool SocketAsyncApiFunction::Respond() { return error_.empty(); }
59 64
60 scoped_ptr<SocketResourceManagerInterface> 65 scoped_ptr<SocketResourceManagerInterface>
61 SocketAsyncApiFunction::CreateSocketResourceManager() { 66 SocketAsyncApiFunction::CreateSocketResourceManager() {
62 return scoped_ptr<SocketResourceManagerInterface>( 67 return scoped_ptr<SocketResourceManagerInterface>(
63 new SocketResourceManager<Socket>()).Pass(); 68 new SocketResourceManager<Socket>()).Pass();
64 } 69 }
65 70
66 int SocketAsyncApiFunction::AddSocket(Socket* socket) { 71 int SocketAsyncApiFunction::AddSocket(Socket* socket) {
67 return manager_->Add(socket); 72 return manager_->Add(socket);
68 } 73 }
69 74
70 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) { 75 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) {
71 return manager_->Get(extension_->id(), api_resource_id); 76 return manager_->Get(extension_->id(), api_resource_id);
72 } 77 }
73 78
79 void SocketAsyncApiFunction::ReplaceSocket(int api_resource_id,
80 Socket* socket) {
81 manager_->Replace(extension_->id(), api_resource_id, socket);
82 }
83
74 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() { 84 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() {
75 return manager_->GetResourceIds(extension_->id()); 85 return manager_->GetResourceIds(extension_->id());
76 } 86 }
77 87
78 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) { 88 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) {
79 manager_->Remove(extension_->id(), api_resource_id); 89 manager_->Remove(extension_->id(), api_resource_id);
80 } 90 }
81 91
82 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction() 92 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction()
83 : resource_context_(NULL), 93 : resource_context_(NULL),
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 198
189 void SocketConnectFunction::AsyncWorkStart() { 199 void SocketConnectFunction::AsyncWorkStart() {
190 socket_ = GetSocket(socket_id_); 200 socket_ = GetSocket(socket_id_);
191 if (!socket_) { 201 if (!socket_) {
192 error_ = kSocketNotFoundError; 202 error_ = kSocketNotFoundError;
193 SetResult(new base::FundamentalValue(-1)); 203 SetResult(new base::FundamentalValue(-1));
194 AsyncWorkCompleted(); 204 AsyncWorkCompleted();
195 return; 205 return;
196 } 206 }
197 207
208 socket_->set_hostname(hostname_);
209
198 SocketPermissionRequest::OperationType operation_type; 210 SocketPermissionRequest::OperationType operation_type;
199 switch (socket_->GetSocketType()) { 211 switch (socket_->GetSocketType()) {
200 case Socket::TYPE_TCP: 212 case Socket::TYPE_TCP:
201 operation_type = SocketPermissionRequest::TCP_CONNECT; 213 operation_type = SocketPermissionRequest::TCP_CONNECT;
202 break; 214 break;
203 case Socket::TYPE_UDP: 215 case Socket::TYPE_UDP:
204 operation_type = SocketPermissionRequest::UDP_SEND_TO; 216 operation_type = SocketPermissionRequest::UDP_SEND_TO;
205 break; 217 break;
206 default: 218 default:
207 NOTREACHED() << "Unknown socket type."; 219 NOTREACHED() << "Unknown socket type.";
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 SetResult(new base::FundamentalValue(result)); 893 SetResult(new base::FundamentalValue(result));
882 return; 894 return;
883 } 895 }
884 896
885 base::ListValue* values = new base::ListValue(); 897 base::ListValue* values = new base::ListValue();
886 values->AppendStrings((std::vector<std::string>&)static_cast<UDPSocket*>( 898 values->AppendStrings((std::vector<std::string>&)static_cast<UDPSocket*>(
887 socket)->GetJoinedGroups()); 899 socket)->GetJoinedGroups());
888 SetResult(values); 900 SetResult(values);
889 } 901 }
890 902
903 SocketSecureFunction::SocketSecureFunction() {
904 }
905
906 SocketSecureFunction::~SocketSecureFunction() {
907 }
908
909 bool SocketSecureFunction::Prepare() {
910 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
911 params_ = core_api::socket::Secure::Params::Create(*args_);
912 EXTENSION_FUNCTION_VALIDATE(params_.get());
913 url_request_getter_ = browser_context()->GetRequestContext();
914 return true;
915 }
916
917 // Override the regular implementation, which would call AsyncWorkCompleted
918 // immediately after Work().
919 void SocketSecureFunction::AsyncWorkStart() {
920 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
921
922 Socket* socket = GetSocket(params_->socket_id);
923 if (!socket) {
924 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
925 error_ = kSocketNotFoundError;
926 AsyncWorkCompleted();
927 return;
928 }
929
930 // Make sure that the socket is a TCP client socket.
931 if (socket->GetSocketType() != Socket::TYPE_TCP ||
932 static_cast<TCPSocket*>(socket)->ClientStream() == NULL) {
933 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
934 error_ = kSecureSocketTypeError;
935 AsyncWorkCompleted();
936 return;
937 }
938
939 if (!socket->IsConnected()) {
940 SetResult(new base::FundamentalValue(net::ERR_INVALID_ARGUMENT));
941 error_ = kSocketNotConnectedError;
942 AsyncWorkCompleted();
943 return;
944 }
945
946 net::URLRequestContext* url_request_context =
947 url_request_getter_->GetURLRequestContext();
948
949 TLSSocket::UpgradeSocketToTLS(
950 socket,
951 url_request_context->ssl_config_service(),
952 url_request_context->cert_verifier(),
953 url_request_context->transport_security_state(),
954 extension_id(),
955 params_->options.get(),
956 base::Bind(&SocketSecureFunction::TlsConnectDone, this));
957 }
958
959 void SocketSecureFunction::TlsConnectDone(scoped_ptr<TLSSocket> socket,
960 int result) {
961 // if an error occurred, socket MUST be NULL.
962 DCHECK(result == net::OK || socket == NULL);
963
964 if (socket && result == net::OK) {
965 ReplaceSocket(params_->socket_id, socket.release());
966 } else {
967 RemoveSocket(params_->socket_id);
968 error_ = net::ErrorToString(result);
969 }
970
971 results_ = core_api::socket::Secure::Results::Create(result);
972 AsyncWorkCompleted();
973 }
974
891 } // namespace extensions 975 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698