Home | History | Annotate | Download | only in networking_private
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/extensions/api/networking_private/networking_private_chromeos.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/callback.h"
     10 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     11 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
     12 #include "chrome/common/extensions/api/networking_private.h"
     13 #include "chrome/common/extensions/api/networking_private.h"
     14 #include "chromeos/dbus/dbus_thread_manager.h"
     15 #include "chromeos/dbus/shill_manager_client.h"
     16 #include "chromeos/login/login_state.h"
     17 #include "chromeos/network/managed_network_configuration_handler.h"
     18 #include "chromeos/network/network_connection_handler.h"
     19 #include "chromeos/network/network_device_handler.h"
     20 #include "chromeos/network/network_event_log.h"
     21 #include "chromeos/network/network_state.h"
     22 #include "chromeos/network/network_state_handler.h"
     23 #include "chromeos/network/network_util.h"
     24 #include "chromeos/network/onc/onc_signature.h"
     25 #include "chromeos/network/onc/onc_translator.h"
     26 #include "chromeos/network/onc/onc_utils.h"
     27 #include "chromeos/network/portal_detector/network_portal_detector.h"
     28 #include "components/onc/onc_constants.h"
     29 #include "content/public/browser/browser_context.h"
     30 
     31 using chromeos::NetworkHandler;
     32 using chromeos::NetworkTypePattern;
     33 using chromeos::ShillManagerClient;
     34 using extensions::NetworkingPrivateDelegate;
     35 
     36 namespace {
     37 
     38 chromeos::ShillManagerClient* GetShillManagerClient() {
     39   return chromeos::DBusThreadManager::Get()->GetShillManagerClient();
     40 }
     41 
     42 chromeos::NetworkStateHandler* GetStateHandler() {
     43   return NetworkHandler::Get()->network_state_handler();
     44 }
     45 
     46 chromeos::ManagedNetworkConfigurationHandler* GetManagedConfigurationHandler() {
     47   return NetworkHandler::Get()->managed_network_configuration_handler();
     48 }
     49 
     50 ShillManagerClient::VerificationProperties ConvertVerificationProperties(
     51     const extensions::api::networking_private::VerificationProperties& input) {
     52   ShillManagerClient::VerificationProperties output;
     53   output.certificate = input.certificate;
     54   output.public_key = input.public_key;
     55   output.nonce = input.nonce;
     56   output.signed_data = input.signed_data;
     57   output.device_serial = input.device_serial;
     58   output.device_ssid = input.device_ssid;
     59   output.device_bssid = input.device_bssid;
     60   return output;
     61 }
     62 
     63 bool GetServicePathFromGuid(const std::string& guid,
     64                             std::string* service_path,
     65                             std::string* error) {
     66   const chromeos::NetworkState* network =
     67       GetStateHandler()->GetNetworkStateFromGuid(guid);
     68   if (!network) {
     69     *error = extensions::networking_private::kErrorInvalidNetworkGuid;
     70     return false;
     71   }
     72   *service_path = network->path();
     73   return true;
     74 }
     75 
     76 bool GetUserIdHash(content::BrowserContext* browser_context,
     77                    std::string* user_hash,
     78                    std::string* error) {
     79   std::string profile_user_hash =
     80       chromeos::ProfileHelper::GetUserIdHashFromProfile(
     81           static_cast<Profile*>(browser_context));
     82 
     83   // Currently Chrome OS only configures networks for the primary user.
     84   // Configuration attempts from other browser contexts should fail.
     85   // TODO(stevenjb): use an ExtensionsBrowserClient method to access
     86   // ProfileHelper when moving this to src/extensions.
     87   if (profile_user_hash != chromeos::LoginState::Get()->primary_user_hash()) {
     88     // Disallow class requiring a user id hash from a non-primary user context
     89     // to avoid complexities with the policy code.
     90     LOG(ERROR) << "networkingPrivate API call from non primary user: "
     91                << profile_user_hash;
     92     *error = "Error.NonPrimaryUser";
     93     return false;
     94   }
     95   *user_hash = profile_user_hash;
     96   return true;
     97 }
     98 
     99 void NetworkHandlerDictionaryCallback(
    100     const NetworkingPrivateDelegate::DictionaryCallback& callback,
    101     const std::string& service_path,
    102     const base::DictionaryValue& dictionary) {
    103   scoped_ptr<base::DictionaryValue> dictionary_copy(dictionary.DeepCopy());
    104   callback.Run(dictionary_copy.Pass());
    105 }
    106 
    107 void NetworkHandlerFailureCallback(
    108     const NetworkingPrivateDelegate::FailureCallback& callback,
    109     const std::string& error_name,
    110     scoped_ptr<base::DictionaryValue> error_data) {
    111   callback.Run(error_name);
    112 }
    113 
    114 void ShillFailureCallback(
    115     const NetworkingPrivateDelegate::FailureCallback& callback,
    116     const std::string& error_name,
    117     const std::string& error_message) {
    118   callback.Run(error_name);
    119 }
    120 
    121 }  // namespace
    122 
    123 ////////////////////////////////////////////////////////////////////////////////
    124 
    125 namespace extensions {
    126 
    127 NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
    128     content::BrowserContext* browser_context)
    129     : browser_context_(browser_context) {
    130 }
    131 
    132 NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {}
    133 
    134 void NetworkingPrivateChromeOS::GetProperties(
    135     const std::string& guid,
    136     const DictionaryCallback& success_callback,
    137     const FailureCallback& failure_callback) {
    138   std::string service_path, error;
    139   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    140     failure_callback.Run(error);
    141     return;
    142   }
    143 
    144   GetManagedConfigurationHandler()->GetProperties(
    145       service_path,
    146       base::Bind(&NetworkHandlerDictionaryCallback, success_callback),
    147       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    148 }
    149 
    150 void NetworkingPrivateChromeOS::GetManagedProperties(
    151     const std::string& guid,
    152     const DictionaryCallback& success_callback,
    153     const FailureCallback& failure_callback) {
    154   std::string service_path, error;
    155   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    156     failure_callback.Run(error);
    157     return;
    158   }
    159 
    160   std::string user_id_hash;
    161   if (!GetUserIdHash(browser_context_, &user_id_hash, &error)) {
    162     failure_callback.Run(error);
    163     return;
    164   }
    165 
    166   GetManagedConfigurationHandler()->GetManagedProperties(
    167       user_id_hash,
    168       service_path,
    169       base::Bind(&NetworkHandlerDictionaryCallback, success_callback),
    170       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    171 }
    172 
    173 void NetworkingPrivateChromeOS::GetState(
    174     const std::string& guid,
    175     const DictionaryCallback& success_callback,
    176     const FailureCallback& failure_callback) {
    177   std::string service_path, error;
    178   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    179     failure_callback.Run(error);
    180     return;
    181   }
    182 
    183   const chromeos::NetworkState* network_state =
    184       GetStateHandler()->GetNetworkStateFromServicePath(
    185           service_path, false /* configured_only */);
    186   if (!network_state) {
    187     failure_callback.Run(networking_private::kErrorNetworkUnavailable);
    188     return;
    189   }
    190 
    191   scoped_ptr<base::DictionaryValue> network_properties =
    192       chromeos::network_util::TranslateNetworkStateToONC(network_state);
    193 
    194   success_callback.Run(network_properties.Pass());
    195 }
    196 
    197 void NetworkingPrivateChromeOS::SetProperties(
    198     const std::string& guid,
    199     scoped_ptr<base::DictionaryValue> properties,
    200     const VoidCallback& success_callback,
    201     const FailureCallback& failure_callback) {
    202   std::string service_path, error;
    203   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    204     failure_callback.Run(error);
    205     return;
    206   }
    207 
    208   GetManagedConfigurationHandler()->SetProperties(
    209       service_path,
    210       *properties,
    211       success_callback,
    212       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    213 }
    214 
    215 void NetworkingPrivateChromeOS::CreateNetwork(
    216     bool shared,
    217     scoped_ptr<base::DictionaryValue> properties,
    218     const StringCallback& success_callback,
    219     const FailureCallback& failure_callback) {
    220   std::string user_id_hash, error;
    221   // Do not allow configuring a non-shared network from a non-primary user.
    222   if (!shared && !GetUserIdHash(browser_context_, &user_id_hash, &error)) {
    223     failure_callback.Run(error);
    224     return;
    225   }
    226 
    227   GetManagedConfigurationHandler()->CreateConfiguration(
    228       user_id_hash,
    229       *properties,
    230       success_callback,
    231       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    232 }
    233 
    234 void NetworkingPrivateChromeOS::GetNetworks(
    235     const std::string& network_type,
    236     bool configured_only,
    237     bool visible_only,
    238     int limit,
    239     const NetworkListCallback& success_callback,
    240     const FailureCallback& failure_callback) {
    241   NetworkTypePattern pattern =
    242       chromeos::onc::NetworkTypePatternFromOncType(network_type);
    243   scoped_ptr<base::ListValue> network_properties_list =
    244       chromeos::network_util::TranslateNetworkListToONC(
    245           pattern, configured_only, visible_only, limit, false /* debugging */);
    246   success_callback.Run(network_properties_list.Pass());
    247 }
    248 
    249 void NetworkingPrivateChromeOS::StartConnect(
    250     const std::string& guid,
    251     const VoidCallback& success_callback,
    252     const FailureCallback& failure_callback) {
    253   std::string service_path, error;
    254   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    255     failure_callback.Run(error);
    256     return;
    257   }
    258 
    259   const bool check_error_state = false;
    260   NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
    261       service_path,
    262       success_callback,
    263       base::Bind(&NetworkHandlerFailureCallback, failure_callback),
    264       check_error_state);
    265 }
    266 
    267 void NetworkingPrivateChromeOS::StartDisconnect(
    268     const std::string& guid,
    269     const VoidCallback& success_callback,
    270     const FailureCallback& failure_callback) {
    271   std::string service_path, error;
    272   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    273     failure_callback.Run(error);
    274     return;
    275   }
    276 
    277   NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
    278       service_path,
    279       success_callback,
    280       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    281 }
    282 
    283 void NetworkingPrivateChromeOS::VerifyDestination(
    284     const VerificationProperties& verification_properties,
    285     const BoolCallback& success_callback,
    286     const FailureCallback& failure_callback) {
    287   ShillManagerClient::VerificationProperties verification_property_struct =
    288       ConvertVerificationProperties(verification_properties);
    289 
    290   GetShillManagerClient()->VerifyDestination(
    291       verification_property_struct,
    292       success_callback,
    293       base::Bind(&ShillFailureCallback, failure_callback));
    294 }
    295 
    296 void NetworkingPrivateChromeOS::VerifyAndEncryptCredentials(
    297     const std::string& guid,
    298     const VerificationProperties& verification_properties,
    299     const StringCallback& success_callback,
    300     const FailureCallback& failure_callback) {
    301   std::string service_path, error;
    302   if (!GetServicePathFromGuid(guid, &service_path, &error)) {
    303     failure_callback.Run(error);
    304     return;
    305   }
    306 
    307   ShillManagerClient::VerificationProperties verification_property_struct =
    308       ConvertVerificationProperties(verification_properties);
    309 
    310   GetShillManagerClient()->VerifyAndEncryptCredentials(
    311       verification_property_struct,
    312       service_path,
    313       success_callback,
    314       base::Bind(&ShillFailureCallback, failure_callback));
    315 }
    316 
    317 void NetworkingPrivateChromeOS::VerifyAndEncryptData(
    318     const VerificationProperties& verification_properties,
    319     const std::string& data,
    320     const StringCallback& success_callback,
    321     const FailureCallback& failure_callback) {
    322   ShillManagerClient::VerificationProperties verification_property_struct =
    323       ConvertVerificationProperties(verification_properties);
    324 
    325   GetShillManagerClient()->VerifyAndEncryptData(
    326       verification_property_struct,
    327       data,
    328       success_callback,
    329       base::Bind(&ShillFailureCallback, failure_callback));
    330 }
    331 
    332 void NetworkingPrivateChromeOS::SetWifiTDLSEnabledState(
    333     const std::string& ip_or_mac_address,
    334     bool enabled,
    335     const StringCallback& success_callback,
    336     const FailureCallback& failure_callback) {
    337   NetworkHandler::Get()->network_device_handler()->SetWifiTDLSEnabled(
    338       ip_or_mac_address,
    339       enabled,
    340       success_callback,
    341       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    342 }
    343 
    344 void NetworkingPrivateChromeOS::GetWifiTDLSStatus(
    345     const std::string& ip_or_mac_address,
    346     const StringCallback& success_callback,
    347     const FailureCallback& failure_callback) {
    348   NetworkHandler::Get()->network_device_handler()->GetWifiTDLSStatus(
    349       ip_or_mac_address,
    350       success_callback,
    351       base::Bind(&NetworkHandlerFailureCallback, failure_callback));
    352 }
    353 
    354 void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
    355     const std::string& guid,
    356     const StringCallback& success_callback,
    357     const FailureCallback& failure_callback) {
    358   chromeos::NetworkPortalDetector* detector =
    359       chromeos::NetworkPortalDetector::Get();
    360   if (!detector) {
    361     failure_callback.Run(networking_private::kErrorNotReady);
    362     return;
    363   }
    364 
    365   chromeos::NetworkPortalDetector::CaptivePortalState state =
    366       detector->GetCaptivePortalState(guid);
    367   success_callback.Run(
    368       chromeos::NetworkPortalDetector::CaptivePortalStatusString(state.status));
    369 }
    370 
    371 scoped_ptr<base::ListValue>
    372 NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
    373   chromeos::NetworkStateHandler* state_handler = GetStateHandler();
    374 
    375   scoped_ptr<base::ListValue> network_list(new base::ListValue);
    376 
    377   if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
    378     network_list->AppendString(::onc::network_type::kEthernet);
    379   if (state_handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
    380     network_list->AppendString(::onc::network_type::kWiFi);
    381   if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Wimax()))
    382     network_list->AppendString(::onc::network_type::kWimax);
    383   if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
    384     network_list->AppendString(::onc::network_type::kCellular);
    385 
    386   return network_list.Pass();
    387 }
    388 
    389 bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string& type) {
    390   NetworkTypePattern pattern =
    391       chromeos::onc::NetworkTypePatternFromOncType(type);
    392 
    393   GetStateHandler()->SetTechnologyEnabled(
    394       pattern, true, chromeos::network_handler::ErrorCallback());
    395 
    396   return true;
    397 }
    398 
    399 bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string& type) {
    400   NetworkTypePattern pattern =
    401       chromeos::onc::NetworkTypePatternFromOncType(type);
    402 
    403   GetStateHandler()->SetTechnologyEnabled(
    404       pattern, false, chromeos::network_handler::ErrorCallback());
    405 
    406   return true;
    407 }
    408 
    409 bool NetworkingPrivateChromeOS::RequestScan() {
    410   GetStateHandler()->RequestScan();
    411   return true;
    412 }
    413 
    414 }  // namespace extensions
    415