OLD | NEW |
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/vpn_provider/vpn_service.h" | 5 #include "extensions/browser/api/vpn_provider/vpn_service.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/guid.h" | 13 #include "base/guid.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/memory/ptr_util.h" |
17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
21 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
22 #include "base/values.h" | 23 #include "base/values.h" |
23 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h" | 24 #include "chromeos/dbus/shill_third_party_vpn_driver_client.h" |
24 #include "chromeos/dbus/shill_third_party_vpn_observer.h" | 25 #include "chromeos/dbus/shill_third_party_vpn_observer.h" |
25 #include "chromeos/network/network_configuration_handler.h" | 26 #include "chromeos/network/network_configuration_handler.h" |
26 #include "chromeos/network/network_profile.h" | 27 #include "chromeos/network/network_profile.h" |
27 #include "chromeos/network/network_profile_handler.h" | 28 #include "chromeos/network/network_profile_handler.h" |
28 #include "chromeos/network/network_state.h" | 29 #include "chromeos/network/network_state.h" |
29 #include "chromeos/network/network_state_handler.h" | 30 #include "chromeos/network/network_state_handler.h" |
30 #include "chromeos/network/network_type_pattern.h" | 31 #include "chromeos/network/network_type_pattern.h" |
| 32 #include "content/public/browser/pepper_vpn_provider_resource_host_proxy.h" |
| 33 #include "content/public/browser/vpn_service_proxy.h" |
31 #include "crypto/sha2.h" | 34 #include "crypto/sha2.h" |
32 #include "extensions/browser/event_router.h" | 35 #include "extensions/browser/event_router.h" |
33 #include "extensions/browser/extension_registry.h" | 36 #include "extensions/browser/extension_registry.h" |
34 #include "third_party/cros_system_api/dbus/service_constants.h" | 37 #include "third_party/cros_system_api/dbus/service_constants.h" |
35 | 38 |
36 namespace chromeos { | 39 namespace chromeos { |
37 | 40 |
38 namespace { | 41 namespace { |
39 | 42 |
40 namespace api_vpn = extensions::api::vpn_provider; | 43 namespace api_vpn = extensions::api::vpn_provider; |
(...skipping 15 matching lines...) Expand all Loading... |
56 | 59 |
57 const std::string& extension_id() const { return extension_id_; } | 60 const std::string& extension_id() const { return extension_id_; } |
58 const std::string& configuration_name() const { return configuration_name_; } | 61 const std::string& configuration_name() const { return configuration_name_; } |
59 const std::string& key() const { return key_; } | 62 const std::string& key() const { return key_; } |
60 const std::string& service_path() const { return service_path_; } | 63 const std::string& service_path() const { return service_path_; } |
61 void set_service_path(const std::string& service_path) { | 64 void set_service_path(const std::string& service_path) { |
62 service_path_ = service_path; | 65 service_path_ = service_path; |
63 } | 66 } |
64 const std::string& object_path() const { return object_path_; } | 67 const std::string& object_path() const { return object_path_; } |
65 | 68 |
| 69 void set_nacl_bound( |
| 70 bool nacl_bound, |
| 71 std::unique_ptr<content::PepperVpnProviderResourceHostProxy> |
| 72 pepper_vpn_provider_proxy) { |
| 73 nacl_bound_ = nacl_bound; |
| 74 pepper_vpn_provider_proxy_ = std::move(pepper_vpn_provider_proxy); |
| 75 } |
| 76 |
66 // ShillThirdPartyVpnObserver: | 77 // ShillThirdPartyVpnObserver: |
67 void OnPacketReceived(const std::vector<char>& data) override; | 78 void OnPacketReceived(const std::vector<char>& data) override; |
68 void OnPlatformMessage(uint32_t message) override; | 79 void OnPlatformMessage(uint32_t message) override; |
69 | 80 |
70 private: | 81 private: |
71 const std::string extension_id_; | 82 const std::string extension_id_; |
72 const std::string configuration_name_; | 83 const std::string configuration_name_; |
73 const std::string key_; | 84 const std::string key_; |
74 const std::string object_path_; | 85 const std::string object_path_; |
75 | 86 |
| 87 bool nacl_bound_; |
| 88 std::unique_ptr<content::PepperVpnProviderResourceHostProxy> |
| 89 pepper_vpn_provider_proxy_; |
| 90 |
76 std::string service_path_; | 91 std::string service_path_; |
77 | 92 |
78 base::WeakPtr<VpnService> vpn_service_; | 93 base::WeakPtr<VpnService> vpn_service_; |
79 | 94 |
80 DISALLOW_COPY_AND_ASSIGN(VpnConfiguration); | 95 DISALLOW_COPY_AND_ASSIGN(VpnConfiguration); |
81 }; | 96 }; |
82 | 97 |
83 VpnService::VpnConfiguration::VpnConfiguration( | 98 VpnService::VpnConfiguration::VpnConfiguration( |
84 const std::string& extension_id, | 99 const std::string& extension_id, |
85 const std::string& configuration_name, | 100 const std::string& configuration_name, |
86 const std::string& key, | 101 const std::string& key, |
87 base::WeakPtr<VpnService> vpn_service) | 102 base::WeakPtr<VpnService> vpn_service) |
88 : extension_id_(extension_id), | 103 : extension_id_(extension_id), |
89 configuration_name_(configuration_name), | 104 configuration_name_(configuration_name), |
90 key_(key), | 105 key_(key), |
91 object_path_(shill::kObjectPathBase + key_), | 106 object_path_(shill::kObjectPathBase + key_), |
92 vpn_service_(vpn_service) { | 107 nacl_bound_(false), |
93 } | 108 vpn_service_(vpn_service) {} |
94 | 109 |
95 VpnService::VpnConfiguration::~VpnConfiguration() { | 110 VpnService::VpnConfiguration::~VpnConfiguration() { |
96 } | 111 } |
97 | 112 |
98 void VpnService::VpnConfiguration::OnPacketReceived( | 113 void VpnService::VpnConfiguration::OnPacketReceived( |
99 const std::vector<char>& data) { | 114 const std::vector<char>& data) { |
100 if (!vpn_service_) { | 115 if (!vpn_service_) { |
101 return; | 116 return; |
102 } | 117 } |
103 std::unique_ptr<base::ListValue> event_args = | 118 // If the configuration was added via a PPAPI plugin |
104 api_vpn::OnPacketReceived::Create(data); | 119 if (nacl_bound_) { |
105 vpn_service_->SendSignalToExtension( | 120 if (pepper_vpn_provider_proxy_) |
106 extension_id_, extensions::events::VPN_PROVIDER_ON_PACKET_RECEIVED, | 121 pepper_vpn_provider_proxy_->SendOnPacketReceived(data); |
107 api_vpn::OnPacketReceived::kEventName, std::move(event_args)); | 122 } else { |
| 123 std::unique_ptr<base::ListValue> event_args = |
| 124 api_vpn::OnPacketReceived::Create(data); |
| 125 vpn_service_->SendSignalToExtension( |
| 126 extension_id_, extensions::events::VPN_PROVIDER_ON_PACKET_RECEIVED, |
| 127 api_vpn::OnPacketReceived::kEventName, std::move(event_args)); |
| 128 } |
108 } | 129 } |
109 | 130 |
110 void VpnService::VpnConfiguration::OnPlatformMessage(uint32_t message) { | 131 void VpnService::VpnConfiguration::OnPlatformMessage(uint32_t message) { |
111 if (!vpn_service_) { | 132 if (!vpn_service_) { |
112 return; | 133 return; |
113 } | 134 } |
114 DCHECK_GE(api_vpn::PLATFORM_MESSAGE_LAST, message); | 135 DCHECK_GE(api_vpn::PLATFORM_MESSAGE_LAST, message); |
115 | 136 |
116 api_vpn::PlatformMessage platform_message = | 137 api_vpn::PlatformMessage platform_message = |
117 static_cast<api_vpn::PlatformMessage>(message); | 138 static_cast<api_vpn::PlatformMessage>(message); |
118 | 139 |
119 if (platform_message == api_vpn::PLATFORM_MESSAGE_CONNECTED) { | 140 if (platform_message == api_vpn::PLATFORM_MESSAGE_CONNECTED) { |
120 vpn_service_->SetActiveConfiguration(this); | 141 vpn_service_->SetActiveConfiguration(this); |
121 } else if (platform_message == api_vpn::PLATFORM_MESSAGE_DISCONNECTED || | 142 } else if (platform_message == api_vpn::PLATFORM_MESSAGE_DISCONNECTED || |
122 platform_message == api_vpn::PLATFORM_MESSAGE_ERROR) { | 143 platform_message == api_vpn::PLATFORM_MESSAGE_ERROR) { |
123 vpn_service_->SetActiveConfiguration(nullptr); | 144 vpn_service_->SetActiveConfiguration(nullptr); |
| 145 |
| 146 // Disconnect NaCl-bound configuration |
| 147 if (nacl_bound_) { |
| 148 nacl_bound_ = false; |
| 149 if (pepper_vpn_provider_proxy_) |
| 150 pepper_vpn_provider_proxy_->SendOnUnbind(); |
| 151 pepper_vpn_provider_proxy_.reset(); |
| 152 } |
124 } | 153 } |
125 | 154 |
126 // TODO(kaliamoorthi): Update the lower layers to get the error message and | 155 // TODO(kaliamoorthi): Update the lower layers to get the error message and |
127 // pass in the error instead of std::string(). | 156 // pass in the error instead of std::string(). |
128 std::unique_ptr<base::ListValue> event_args = | 157 std::unique_ptr<base::ListValue> event_args = |
129 api_vpn::OnPlatformMessage::Create(configuration_name_, platform_message, | 158 api_vpn::OnPlatformMessage::Create(configuration_name_, platform_message, |
130 std::string()); | 159 std::string()); |
131 | 160 |
132 vpn_service_->SendSignalToExtension( | 161 vpn_service_->SendSignalToExtension( |
133 extension_id_, extensions::events::VPN_PROVIDER_ON_PLATFORM_MESSAGE, | 162 extension_id_, extensions::events::VPN_PROVIDER_ON_PLATFORM_MESSAGE, |
134 api_vpn::OnPlatformMessage::kEventName, std::move(event_args)); | 163 api_vpn::OnPlatformMessage::kEventName, std::move(event_args)); |
135 } | 164 } |
136 | 165 |
| 166 class VpnService::VpnServiceProxyImpl : public content::VpnServiceProxy { |
| 167 public: |
| 168 VpnServiceProxyImpl(base::WeakPtr<VpnService> vpn_service); |
| 169 ~VpnServiceProxyImpl() override; |
| 170 |
| 171 void Bind(const std::string& extension_id, |
| 172 const std::string& configuration_id, |
| 173 const std::string& configuration_name, |
| 174 const SuccessCallback& success, |
| 175 const FailureCallback& failure, |
| 176 std::unique_ptr<content::PepperVpnProviderResourceHostProxy> |
| 177 pepper_vpn_provider_proxy) override; |
| 178 void SendPacket(const std::string& extension_id, |
| 179 const std::vector<char>& data, |
| 180 const SuccessCallback& success, |
| 181 const FailureCallback& failure) override; |
| 182 |
| 183 private: |
| 184 base::WeakPtr<VpnService> vpn_service_; |
| 185 |
| 186 DISALLOW_COPY_AND_ASSIGN(VpnServiceProxyImpl); |
| 187 }; |
| 188 |
| 189 VpnService::VpnServiceProxyImpl::VpnServiceProxyImpl( |
| 190 base::WeakPtr<VpnService> vpn_service) |
| 191 : vpn_service_(vpn_service) {} |
| 192 |
| 193 VpnService::VpnServiceProxyImpl::~VpnServiceProxyImpl() {} |
| 194 |
| 195 void VpnService::VpnServiceProxyImpl::Bind( |
| 196 const std::string& extension_id, |
| 197 const std::string& configuration_id, |
| 198 const std::string& configuration_name, |
| 199 const SuccessCallback& success, |
| 200 const FailureCallback& failure, |
| 201 std::unique_ptr<content::PepperVpnProviderResourceHostProxy> |
| 202 pepper_vpn_provider_proxy) { |
| 203 if (!vpn_service_) { |
| 204 NOTREACHED(); |
| 205 return; |
| 206 } |
| 207 |
| 208 vpn_service_->Bind(extension_id, configuration_id, configuration_name, |
| 209 success, failure, std::move(pepper_vpn_provider_proxy)); |
| 210 } |
| 211 |
| 212 void VpnService::VpnServiceProxyImpl::SendPacket( |
| 213 const std::string& extension_id, |
| 214 const std::vector<char>& data, |
| 215 const SuccessCallback& success, |
| 216 const FailureCallback& failure) { |
| 217 if (!vpn_service_) { |
| 218 NOTREACHED(); |
| 219 return; |
| 220 } |
| 221 |
| 222 vpn_service_->SendPacket(extension_id, data, success, failure); |
| 223 } |
| 224 |
137 VpnService::VpnService( | 225 VpnService::VpnService( |
138 content::BrowserContext* browser_context, | 226 content::BrowserContext* browser_context, |
139 const std::string& userid_hash, | 227 const std::string& userid_hash, |
140 extensions::ExtensionRegistry* extension_registry, | 228 extensions::ExtensionRegistry* extension_registry, |
141 extensions::EventRouter* event_router, | 229 extensions::EventRouter* event_router, |
142 ShillThirdPartyVpnDriverClient* shill_client, | 230 ShillThirdPartyVpnDriverClient* shill_client, |
143 NetworkConfigurationHandler* network_configuration_handler, | 231 NetworkConfigurationHandler* network_configuration_handler, |
144 NetworkProfileHandler* network_profile_handler, | 232 NetworkProfileHandler* network_profile_handler, |
145 NetworkStateHandler* network_state_handler) | 233 NetworkStateHandler* network_state_handler) |
146 : browser_context_(browser_context), | 234 : browser_context_(browser_context), |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 } | 657 } |
570 delete configuration; | 658 delete configuration; |
571 } | 659 } |
572 | 660 |
573 bool VpnService::DoesActiveConfigurationExistAndIsAccessAuthorized( | 661 bool VpnService::DoesActiveConfigurationExistAndIsAccessAuthorized( |
574 const std::string& extension_id) { | 662 const std::string& extension_id) { |
575 return active_configuration_ && | 663 return active_configuration_ && |
576 active_configuration_->extension_id() == extension_id; | 664 active_configuration_->extension_id() == extension_id; |
577 } | 665 } |
578 | 666 |
| 667 void VpnService::Bind( |
| 668 const std::string& extension_id, |
| 669 const std::string& configuration_id, |
| 670 const std::string& configuration_name, |
| 671 const SuccessCallback& success, |
| 672 const FailureCallback& failure, |
| 673 std::unique_ptr<content::PepperVpnProviderResourceHostProxy> |
| 674 pepper_vpn_provider_proxy) { |
| 675 // The ID is the configuration name for now. This may change in the future. |
| 676 const std::string key = GetKey(extension_id, configuration_id); |
| 677 if (!ContainsKey(key_to_configuration_map_, key)) { |
| 678 failure.Run(std::string(), std::string("Unauthorized access 1.")); |
| 679 return; |
| 680 } |
| 681 |
| 682 VpnConfiguration* configuration = key_to_configuration_map_[key]; |
| 683 if (active_configuration_ != configuration) { |
| 684 failure.Run(std::string(), std::string("Unauthorized access 2.")); |
| 685 return; |
| 686 } |
| 687 |
| 688 if (configuration->extension_id() != extension_id || |
| 689 configuration->configuration_name() != configuration_name) { |
| 690 failure.Run(std::string(), std::string("Unauthorized access 3.")); |
| 691 return; |
| 692 } |
| 693 |
| 694 const std::string service_path = configuration->service_path(); |
| 695 if (service_path.empty()) { |
| 696 failure.Run(std::string(), std::string("Pending create.")); |
| 697 return; |
| 698 } |
| 699 |
| 700 // Connection authorized. All packets will be routed through NaCl. |
| 701 configuration->set_nacl_bound(true, std::move(pepper_vpn_provider_proxy)); |
| 702 |
| 703 success.Run(); |
| 704 } |
| 705 |
| 706 std::unique_ptr<content::VpnServiceProxy> VpnService::GetVpnServiceProxy() { |
| 707 return base::WrapUnique(new VpnServiceProxyImpl(weak_factory_.GetWeakPtr())); |
| 708 } |
| 709 |
579 } // namespace chromeos | 710 } // namespace chromeos |
OLD | NEW |