Chromium Code Reviews| Index: extensions/browser/api/vpn_provider/vpn_service.cc |
| diff --git a/extensions/browser/api/vpn_provider/vpn_service.cc b/extensions/browser/api/vpn_provider/vpn_service.cc |
| index 1f1b95bb2511535ca2c297bb15239ae0a85a4ee1..45c1e55e7f83e2a9eb71904423e72b29f6b2ecb6 100644 |
| --- a/extensions/browser/api/vpn_provider/vpn_service.cc |
| +++ b/extensions/browser/api/vpn_provider/vpn_service.cc |
| @@ -14,6 +14,7 @@ |
| #include "base/location.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/stl_util.h" |
| #include "base/strings/string_number_conversions.h" |
| @@ -27,6 +28,7 @@ |
| #include "chromeos/network/network_state.h" |
| #include "chromeos/network/network_state_handler.h" |
| #include "chromeos/network/network_type_pattern.h" |
| +#include "content/public/browser/pepper_vpn_provider_service_helper.h" |
| #include "crypto/sha2.h" |
| #include "extensions/browser/event_router.h" |
| #include "extensions/browser/extension_registry.h" |
| @@ -62,6 +64,8 @@ class VpnService::VpnConfiguration : public ShillThirdPartyVpnObserver { |
| } |
| const std::string& object_path() const { return object_path_; } |
| + void set_nacl_bound(bool nacl_bound) { nacl_bound_ = nacl_bound; } |
| + |
| // ShillThirdPartyVpnObserver: |
| void OnPacketReceived(const std::vector<char>& data) override; |
| void OnPlatformMessage(uint32_t message) override; |
| @@ -72,6 +76,8 @@ class VpnService::VpnConfiguration : public ShillThirdPartyVpnObserver { |
| const std::string key_; |
| const std::string object_path_; |
| + bool nacl_bound_; |
| + |
| std::string service_path_; |
| base::WeakPtr<VpnService> vpn_service_; |
| @@ -88,8 +94,8 @@ VpnService::VpnConfiguration::VpnConfiguration( |
| configuration_name_(configuration_name), |
| key_(key), |
| object_path_(shill::kObjectPathBase + key_), |
| - vpn_service_(vpn_service) { |
| -} |
| + nacl_bound_(false), |
| + vpn_service_(vpn_service) {} |
| VpnService::VpnConfiguration::~VpnConfiguration() { |
| } |
| @@ -99,11 +105,17 @@ void VpnService::VpnConfiguration::OnPacketReceived( |
| if (!vpn_service_) { |
| return; |
| } |
| - std::unique_ptr<base::ListValue> event_args = |
| - api_vpn::OnPacketReceived::Create(data); |
| - vpn_service_->SendSignalToExtension( |
| - extension_id_, extensions::events::VPN_PROVIDER_ON_PACKET_RECEIVED, |
| - api_vpn::OnPacketReceived::kEventName, std::move(event_args)); |
| + // If the configrataion was added via a PPAPI plugin |
|
ncarter (slow)
2016/05/17 17:15:40
"configuration"
adrian.belgun
2016/05/17 17:18:55
Done.
|
| + if (nacl_bound_) { |
| + content::VpnProviderServiceHelper::GetInstance()->OnPacketReceived( |
| + extension_id_, data); |
| + } else { |
| + std::unique_ptr<base::ListValue> event_args = |
| + api_vpn::OnPacketReceived::Create(data); |
| + vpn_service_->SendSignalToExtension( |
| + extension_id_, extensions::events::VPN_PROVIDER_ON_PACKET_RECEIVED, |
| + api_vpn::OnPacketReceived::kEventName, std::move(event_args)); |
| + } |
| } |
| void VpnService::VpnConfiguration::OnPlatformMessage(uint32_t message) { |
| @@ -120,6 +132,12 @@ void VpnService::VpnConfiguration::OnPlatformMessage(uint32_t message) { |
| } else if (platform_message == api_vpn::PLATFORM_MESSAGE_DISCONNECTED || |
| platform_message == api_vpn::PLATFORM_MESSAGE_ERROR) { |
| vpn_service_->SetActiveConfiguration(nullptr); |
| + |
| + // Disconnect NaCl-bound configuration |
| + if (nacl_bound_) { |
| + nacl_bound_ = false; |
| + content::VpnProviderServiceHelper::GetInstance()->OnUnbind(extension_id_); |
| + } |
| } |
| // TODO(kaliamoorthi): Update the lower layers to get the error message and |
| @@ -133,6 +151,61 @@ void VpnService::VpnConfiguration::OnPlatformMessage(uint32_t message) { |
| api_vpn::OnPlatformMessage::kEventName, std::move(event_args)); |
| } |
| +class VpnService::VpnServiceDelegateImpl : public content::VpnServiceDelegate { |
| + public: |
| + VpnServiceDelegateImpl(base::WeakPtr<VpnService> vpn_service); |
| + ~VpnServiceDelegateImpl() override; |
| + |
| + void Bind(const std::string& extension_id, |
| + const std::string& configuration_id, |
| + const std::string& configuration_name, |
| + const SuccessCallback& success, |
| + const FailureCallback& failure) override; |
| + void SendPacket(const std::string& extension_id, |
| + const std::vector<char>& data, |
| + const SuccessCallback& success, |
| + const FailureCallback& failure) override; |
| + |
| + private: |
| + base::WeakPtr<VpnService> vpn_service_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(VpnServiceDelegateImpl); |
| +}; |
| + |
| +VpnService::VpnServiceDelegateImpl::VpnServiceDelegateImpl( |
| + base::WeakPtr<VpnService> vpn_service) |
| + : vpn_service_(vpn_service) {} |
| + |
| +VpnService::VpnServiceDelegateImpl::~VpnServiceDelegateImpl() {} |
| + |
| +void VpnService::VpnServiceDelegateImpl::Bind( |
| + const std::string& extension_id, |
| + const std::string& configuration_id, |
| + const std::string& configuration_name, |
| + const SuccessCallback& success, |
| + const FailureCallback& failure) { |
| + if (!vpn_service_) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + vpn_service_->Bind(extension_id, configuration_id, configuration_name, |
| + success, failure); |
| +} |
| + |
| +void VpnService::VpnServiceDelegateImpl::SendPacket( |
| + const std::string& extension_id, |
| + const std::vector<char>& data, |
| + const SuccessCallback& success, |
| + const FailureCallback& failure) { |
| + if (!vpn_service_) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + vpn_service_->SendPacket(extension_id, data, success, failure); |
| +} |
| + |
| VpnService::VpnService( |
| content::BrowserContext* browser_context, |
| const std::string& userid_hash, |
| @@ -158,6 +231,9 @@ VpnService::VpnService( |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&VpnService::NetworkListChanged, weak_factory_.GetWeakPtr())); |
| + content::VpnProviderServiceHelper::GetInstance()->RegisterDelegate( |
| + browser_context, |
| + base::WrapUnique(new VpnServiceDelegateImpl(weak_factory_.GetWeakPtr()))); |
| } |
| VpnService::~VpnService() { |
| @@ -575,4 +651,40 @@ bool VpnService::DoesActiveConfigurationExistAndIsAccessAuthorized( |
| active_configuration_->extension_id() == extension_id; |
| } |
| +void VpnService::Bind(const std::string& extension_id, |
| + const std::string& configuration_id, |
| + const std::string& configuration_name, |
| + const SuccessCallback& success, |
| + const FailureCallback& failure) { |
| + // The ID is the configuration name for now. This may change in the future. |
| + const std::string key = GetKey(extension_id, configuration_id); |
| + if (!ContainsKey(key_to_configuration_map_, key)) { |
| + failure.Run(std::string(), std::string("Unauthorized access 1.")); |
| + return; |
| + } |
| + |
| + VpnConfiguration* configuration = key_to_configuration_map_[key]; |
| + if (active_configuration_ != configuration) { |
| + failure.Run(std::string(), std::string("Unauthorized access 2.")); |
| + return; |
| + } |
| + |
| + if (configuration->extension_id() != extension_id || |
| + configuration->configuration_name() != configuration_name) { |
| + failure.Run(std::string(), std::string("Unauthorized access 3.")); |
| + return; |
| + } |
| + |
| + const std::string service_path = configuration->service_path(); |
| + if (service_path.empty()) { |
| + failure.Run(std::string(), std::string("Pending create.")); |
| + return; |
| + } |
| + |
| + // Connection authorized. All packets will be routed through NaCl. |
| + configuration->set_nacl_bound(true); |
| + |
| + success.Run(); |
| +} |
| + |
| } // namespace chromeos |