1// Copyright 2013 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_api.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/callback.h"
10#include "base/command_line.h"
11#include "chrome/browser/browser_process.h"
12#include "chrome/browser/browser_process_platform_part_chromeos.h"
13#include "chrome/browser/chromeos/profiles/profile_helper.h"
14#include "chrome/browser/extensions/extension_function_registry.h"
15#include "chrome/common/chrome_switches.h"
16#include "chrome/common/extensions/api/networking_private.h"
17#include "chromeos/dbus/dbus_thread_manager.h"
18#include "chromeos/dbus/shill_manager_client.h"
19#include "chromeos/network/managed_network_configuration_handler.h"
20#include "chromeos/network/network_connection_handler.h"
21#include "chromeos/network/network_state.h"
22#include "chromeos/network/network_state_handler.h"
23#include "chromeos/network/onc/onc_signature.h"
24#include "chromeos/network/onc/onc_translator.h"
25#include "chromeos/network/shill_property_util.h"
26#include "components/onc/onc_constants.h"
27
28namespace api = extensions::api::networking_private;
29
30using chromeos::DBusThreadManager;
31using chromeos::ManagedNetworkConfigurationHandler;
32using chromeos::NetworkHandler;
33using chromeos::NetworkState;
34using chromeos::NetworkStateHandler;
35using chromeos::NetworkTypePattern;
36using chromeos::ShillManagerClient;
37
38namespace {
39
40// Helper function that converts between the two types of verification
41// properties. They should always have the same fields, but we do this here to
42// prevent ShillManagerClient from depending directly on the extension API.
43ShillManagerClient::VerificationProperties ConvertVerificationProperties(
44    const api::VerificationProperties& input) {
45  ShillManagerClient::VerificationProperties output;
46  COMPILE_ASSERT(sizeof(api::VerificationProperties) ==
47                     sizeof(ShillManagerClient::VerificationProperties),
48                 verification_properties_no_longer_match);
49
50  output.certificate = input.certificate;
51  output.public_key = input.public_key;
52  output.nonce = input.nonce;
53  output.signed_data = input.signed_data;
54  output.device_serial = input.device_serial;
55  output.device_ssid = input.device_ssid;
56  output.device_bssid = input.device_bssid;
57  return output;
58}
59
60std::string GetUserIdHash(Profile* profile) {
61  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) {
62    return g_browser_process->platform_part()->
63        profile_helper()->GetUserIdHashFromProfile(profile);
64  } else {
65    return g_browser_process->platform_part()->
66        profile_helper()->active_user_id_hash();
67  }
68}
69
70}  // namespace
71
72////////////////////////////////////////////////////////////////////////////////
73// NetworkingPrivateGetPropertiesFunction
74
75NetworkingPrivateGetPropertiesFunction::
76  ~NetworkingPrivateGetPropertiesFunction() {
77}
78
79bool NetworkingPrivateGetPropertiesFunction::RunImpl() {
80  scoped_ptr<api::GetProperties::Params> params =
81      api::GetProperties::Params::Create(*args_);
82  EXTENSION_FUNCTION_VALIDATE(params);
83
84  NetworkHandler::Get()->managed_network_configuration_handler()->GetProperties(
85      params->network_guid,  // service path
86      base::Bind(&NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess,
87                 this),
88      base::Bind(&NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed,
89                 this));
90  return true;
91}
92
93void NetworkingPrivateGetPropertiesFunction::GetPropertiesSuccess(
94    const std::string& service_path,
95    const base::DictionaryValue& dictionary) {
96  base::DictionaryValue* network_properties = dictionary.DeepCopy();
97  network_properties->SetStringWithoutPathExpansion(onc::network_config::kGUID,
98                                                    service_path);
99  SetResult(network_properties);
100  SendResponse(true);
101}
102
103void NetworkingPrivateGetPropertiesFunction::GetPropertiesFailed(
104    const std::string& error_name,
105    scoped_ptr<base::DictionaryValue> error_data) {
106  error_ = error_name;
107  SendResponse(false);
108}
109
110////////////////////////////////////////////////////////////////////////////////
111// NetworkingPrivateGetManagedPropertiesFunction
112
113NetworkingPrivateGetManagedPropertiesFunction::
114  ~NetworkingPrivateGetManagedPropertiesFunction() {
115}
116
117bool NetworkingPrivateGetManagedPropertiesFunction::RunImpl() {
118  scoped_ptr<api::GetManagedProperties::Params> params =
119      api::GetManagedProperties::Params::Create(*args_);
120  EXTENSION_FUNCTION_VALIDATE(params);
121
122  std::string user_id_hash;
123  GetUserIdHash(GetProfile());
124  NetworkHandler::Get()->managed_network_configuration_handler()->
125      GetManagedProperties(
126          user_id_hash,
127          params->network_guid,  // service path
128          base::Bind(&NetworkingPrivateGetManagedPropertiesFunction::Success,
129                     this),
130          base::Bind(&NetworkingPrivateGetManagedPropertiesFunction::Failure,
131                     this));
132  return true;
133}
134
135void NetworkingPrivateGetManagedPropertiesFunction::Success(
136    const std::string& service_path,
137    const base::DictionaryValue& dictionary) {
138  base::DictionaryValue* network_properties = dictionary.DeepCopy();
139  network_properties->SetStringWithoutPathExpansion(onc::network_config::kGUID,
140                                                    service_path);
141  SetResult(network_properties);
142  SendResponse(true);
143}
144
145void NetworkingPrivateGetManagedPropertiesFunction::Failure(
146    const std::string& error_name,
147    scoped_ptr<base::DictionaryValue> error_data) {
148  error_ = error_name;
149  SendResponse(false);
150}
151
152////////////////////////////////////////////////////////////////////////////////
153// NetworkingPrivateGetStateFunction
154
155NetworkingPrivateGetStateFunction::
156  ~NetworkingPrivateGetStateFunction() {
157}
158
159bool NetworkingPrivateGetStateFunction::RunImpl() {
160  scoped_ptr<api::GetState::Params> params =
161      api::GetState::Params::Create(*args_);
162  EXTENSION_FUNCTION_VALIDATE(params);
163  // The |network_guid| parameter is storing the service path.
164  std::string service_path = params->network_guid;
165
166  const NetworkState* state = NetworkHandler::Get()->network_state_handler()->
167      GetNetworkState(service_path);
168  if (!state) {
169    error_ = "Error.InvalidParameter";
170    return false;
171  }
172
173  scoped_ptr<base::DictionaryValue> result_dict(new base::DictionaryValue);
174  state->GetProperties(result_dict.get());
175  scoped_ptr<base::DictionaryValue> onc_network_part =
176      chromeos::onc::TranslateShillServiceToONCPart(*result_dict,
177          &chromeos::onc::kNetworkWithStateSignature);
178  SetResult(onc_network_part.release());
179  SendResponse(true);
180
181  return true;
182}
183
184////////////////////////////////////////////////////////////////////////////////
185// NetworkingPrivateSetPropertiesFunction
186
187NetworkingPrivateSetPropertiesFunction::
188~NetworkingPrivateSetPropertiesFunction() {
189}
190
191bool NetworkingPrivateSetPropertiesFunction::RunImpl() {
192  scoped_ptr<api::SetProperties::Params> params =
193      api::SetProperties::Params::Create(*args_);
194  EXTENSION_FUNCTION_VALIDATE(params);
195
196  scoped_ptr<base::DictionaryValue> properties_dict(
197      params->properties.ToValue());
198
199  NetworkHandler::Get()->managed_network_configuration_handler()->SetProperties(
200      params->network_guid,  // service path
201      *properties_dict,
202      base::Bind(&NetworkingPrivateSetPropertiesFunction::ResultCallback,
203                 this),
204      base::Bind(&NetworkingPrivateSetPropertiesFunction::ErrorCallback,
205                 this));
206  return true;
207}
208
209void NetworkingPrivateSetPropertiesFunction::ErrorCallback(
210    const std::string& error_name,
211    const scoped_ptr<base::DictionaryValue> error_data) {
212  error_ = error_name;
213  SendResponse(false);
214}
215
216void NetworkingPrivateSetPropertiesFunction::ResultCallback() {
217  SendResponse(true);
218}
219
220////////////////////////////////////////////////////////////////////////////////
221// NetworkingPrivateCreateNetworkFunction
222
223NetworkingPrivateCreateNetworkFunction::
224~NetworkingPrivateCreateNetworkFunction() {
225}
226
227bool NetworkingPrivateCreateNetworkFunction::RunImpl() {
228  scoped_ptr<api::CreateNetwork::Params> params =
229      api::CreateNetwork::Params::Create(*args_);
230  EXTENSION_FUNCTION_VALIDATE(params);
231
232  std::string user_id_hash;
233  if (!params->shared)
234    user_id_hash = GetUserIdHash(GetProfile());
235
236  scoped_ptr<base::DictionaryValue> properties_dict(
237      params->properties.ToValue());
238
239  NetworkHandler::Get()->managed_network_configuration_handler()->
240      CreateConfiguration(
241          user_id_hash,
242          *properties_dict,
243          base::Bind(&NetworkingPrivateCreateNetworkFunction::ResultCallback,
244                     this),
245          base::Bind(&NetworkingPrivateCreateNetworkFunction::ErrorCallback,
246                     this));
247  return true;
248}
249
250void NetworkingPrivateCreateNetworkFunction::ErrorCallback(
251    const std::string& error_name,
252    const scoped_ptr<base::DictionaryValue> error_data) {
253  error_ = error_name;
254  SendResponse(false);
255}
256
257void NetworkingPrivateCreateNetworkFunction::ResultCallback(
258    const std::string& guid) {
259  results_ = api::CreateNetwork::Results::Create(guid);
260  SendResponse(true);
261}
262
263////////////////////////////////////////////////////////////////////////////////
264// NetworkingPrivateGetVisibleNetworksFunction
265
266NetworkingPrivateGetVisibleNetworksFunction::
267~NetworkingPrivateGetVisibleNetworksFunction() {
268}
269
270bool NetworkingPrivateGetVisibleNetworksFunction::RunImpl() {
271  scoped_ptr<api::GetVisibleNetworks::Params> params =
272      api::GetVisibleNetworks::Params::Create(*args_);
273  EXTENSION_FUNCTION_VALIDATE(params);
274  std::string type_filter =
275      api::GetVisibleNetworks::Params::ToString(params->type);
276
277  NetworkStateHandler::NetworkStateList network_states;
278  NetworkHandler::Get()->network_state_handler()->GetNetworkList(
279      &network_states);
280
281  base::ListValue* network_properties_list = new base::ListValue;
282  for (NetworkStateHandler::NetworkStateList::iterator it =
283           network_states.begin();
284       it != network_states.end(); ++it) {
285    const std::string& service_path = (*it)->path();
286    base::DictionaryValue shill_dictionary;
287    (*it)->GetProperties(&shill_dictionary);
288
289    scoped_ptr<base::DictionaryValue> onc_network_part =
290        chromeos::onc::TranslateShillServiceToONCPart(shill_dictionary,
291            &chromeos::onc::kNetworkWithStateSignature);
292
293    std::string onc_type;
294    onc_network_part->GetStringWithoutPathExpansion(onc::network_config::kType,
295                                                    &onc_type);
296    if (type_filter == onc::network_type::kAllTypes ||
297        onc_type == type_filter) {
298      onc_network_part->SetStringWithoutPathExpansion(
299          onc::network_config::kGUID,
300          service_path);
301      network_properties_list->Append(onc_network_part.release());
302    }
303  }
304
305  SetResult(network_properties_list);
306  SendResponse(true);
307  return true;
308}
309
310////////////////////////////////////////////////////////////////////////////////
311// NetworkingPrivateGetEnabledNetworkTypesFunction
312
313NetworkingPrivateGetEnabledNetworkTypesFunction::
314~NetworkingPrivateGetEnabledNetworkTypesFunction() {
315}
316
317bool NetworkingPrivateGetEnabledNetworkTypesFunction::RunImpl() {
318  NetworkStateHandler* state_handler =
319      NetworkHandler::Get()->network_state_handler();
320
321  base::ListValue* network_list = new base::ListValue;
322
323  if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
324    network_list->AppendString("Ethernet");
325  if (state_handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
326    network_list->AppendString("WiFi");
327  if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
328    network_list->AppendString("Cellular");
329
330  SetResult(network_list);
331  return true;
332}
333
334////////////////////////////////////////////////////////////////////////////////
335// NetworkingPrivateEnableNetworkTypeFunction
336
337NetworkingPrivateEnableNetworkTypeFunction::
338~NetworkingPrivateEnableNetworkTypeFunction() {
339}
340
341bool NetworkingPrivateEnableNetworkTypeFunction::RunImpl() {
342  scoped_ptr<api::EnableNetworkType::Params> params =
343      api::EnableNetworkType::Params::Create(*args_);
344  EXTENSION_FUNCTION_VALIDATE(params);
345  NetworkStateHandler* state_handler =
346      NetworkHandler::Get()->network_state_handler();
347
348  switch (params->network_type) {
349    case api::NETWORK_TYPE_ETHERNET:
350      state_handler->SetTechnologyEnabled(
351          NetworkTypePattern::Ethernet(), true,
352          chromeos::network_handler::ErrorCallback());
353      break;
354
355    case api::NETWORK_TYPE_WIFI:
356      state_handler->SetTechnologyEnabled(
357          NetworkTypePattern::WiFi(), true,
358          chromeos::network_handler::ErrorCallback());
359      break;
360
361    case api::NETWORK_TYPE_CELLULAR:
362      state_handler->SetTechnologyEnabled(
363          NetworkTypePattern::Cellular(), true,
364          chromeos::network_handler::ErrorCallback());
365      break;
366
367    default:
368      break;
369  }
370  return true;
371}
372
373////////////////////////////////////////////////////////////////////////////////
374// NetworkingPrivateDisableNetworkTypeFunction
375
376NetworkingPrivateDisableNetworkTypeFunction::
377~NetworkingPrivateDisableNetworkTypeFunction() {
378}
379
380bool NetworkingPrivateDisableNetworkTypeFunction::RunImpl() {
381  scoped_ptr<api::DisableNetworkType::Params> params =
382      api::DisableNetworkType::Params::Create(*args_);
383  NetworkStateHandler* state_handler =
384      NetworkHandler::Get()->network_state_handler();
385
386  switch (params->network_type) {
387    case api::NETWORK_TYPE_ETHERNET:
388      state_handler->SetTechnologyEnabled(
389          NetworkTypePattern::Ethernet(), false,
390          chromeos::network_handler::ErrorCallback());
391      break;
392
393    case api::NETWORK_TYPE_WIFI:
394      state_handler->SetTechnologyEnabled(
395          NetworkTypePattern::WiFi(), false,
396          chromeos::network_handler::ErrorCallback());
397      break;
398
399    case api::NETWORK_TYPE_CELLULAR:
400      state_handler->SetTechnologyEnabled(
401          NetworkTypePattern::Cellular(), false,
402          chromeos::network_handler::ErrorCallback());
403      break;
404
405    default:
406      break;
407  }
408
409  return true;
410}
411
412////////////////////////////////////////////////////////////////////////////////
413// NetworkingPrivateRequestNetworkScanFunction
414
415NetworkingPrivateRequestNetworkScanFunction::
416~NetworkingPrivateRequestNetworkScanFunction() {
417}
418
419bool NetworkingPrivateRequestNetworkScanFunction::RunImpl() {
420  NetworkHandler::Get()->network_state_handler()->RequestScan();
421  return true;
422}
423
424////////////////////////////////////////////////////////////////////////////////
425// NetworkingPrivateStartConnectFunction
426
427NetworkingPrivateStartConnectFunction::
428  ~NetworkingPrivateStartConnectFunction() {
429}
430
431void  NetworkingPrivateStartConnectFunction::ConnectionStartSuccess() {
432  SendResponse(true);
433}
434
435void NetworkingPrivateStartConnectFunction::ConnectionStartFailed(
436    const std::string& error_name,
437    const scoped_ptr<base::DictionaryValue> error_data) {
438  error_ = error_name;
439  SendResponse(false);
440}
441
442bool NetworkingPrivateStartConnectFunction::RunImpl() {
443  scoped_ptr<api::StartConnect::Params> params =
444      api::StartConnect::Params::Create(*args_);
445  EXTENSION_FUNCTION_VALIDATE(params);
446
447  const bool check_error_state = false;
448  NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
449      params->network_guid,  // service path
450      base::Bind(
451          &NetworkingPrivateStartConnectFunction::ConnectionStartSuccess,
452          this),
453      base::Bind(
454          &NetworkingPrivateStartConnectFunction::ConnectionStartFailed,
455          this),
456      check_error_state);
457  return true;
458}
459
460////////////////////////////////////////////////////////////////////////////////
461// NetworkingPrivateStartDisconnectFunction
462
463NetworkingPrivateStartDisconnectFunction::
464  ~NetworkingPrivateStartDisconnectFunction() {
465}
466
467void  NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess() {
468  SendResponse(true);
469}
470
471void NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed(
472    const std::string& error_name,
473    const scoped_ptr<base::DictionaryValue> error_data) {
474  error_ = error_name;
475  SendResponse(false);
476}
477
478bool NetworkingPrivateStartDisconnectFunction::RunImpl() {
479  scoped_ptr<api::StartDisconnect::Params> params =
480      api::StartDisconnect::Params::Create(*args_);
481  EXTENSION_FUNCTION_VALIDATE(params);
482
483  NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
484      params->network_guid,  // service path
485      base::Bind(
486          &NetworkingPrivateStartDisconnectFunction::DisconnectionStartSuccess,
487          this),
488      base::Bind(
489          &NetworkingPrivateStartDisconnectFunction::DisconnectionStartFailed,
490          this));
491  return true;
492}
493
494////////////////////////////////////////////////////////////////////////////////
495// NetworkingPrivateVerifyDestinationFunction
496
497NetworkingPrivateVerifyDestinationFunction::
498  ~NetworkingPrivateVerifyDestinationFunction() {
499}
500
501bool NetworkingPrivateVerifyDestinationFunction::RunImpl() {
502  scoped_ptr<api::VerifyDestination::Params> params =
503      api::VerifyDestination::Params::Create(*args_);
504  EXTENSION_FUNCTION_VALIDATE(params);
505
506  ShillManagerClient::VerificationProperties verification_properties =
507      ConvertVerificationProperties(params->properties);
508
509  DBusThreadManager::Get()->GetShillManagerClient()->VerifyDestination(
510      verification_properties,
511      base::Bind(
512          &NetworkingPrivateVerifyDestinationFunction::ResultCallback,
513          this),
514      base::Bind(
515          &NetworkingPrivateVerifyDestinationFunction::ErrorCallback,
516          this));
517  return true;
518}
519
520void NetworkingPrivateVerifyDestinationFunction::ResultCallback(
521    bool result) {
522  results_ = api::VerifyDestination::Results::Create(result);
523  SendResponse(true);
524}
525
526void NetworkingPrivateVerifyDestinationFunction::ErrorCallback(
527    const std::string& error_name, const std::string& error) {
528  error_ = error_name;
529  SendResponse(false);
530}
531
532////////////////////////////////////////////////////////////////////////////////
533// NetworkingPrivateVerifyAndEncryptCredentialsFunction
534
535NetworkingPrivateVerifyAndEncryptCredentialsFunction::
536  ~NetworkingPrivateVerifyAndEncryptCredentialsFunction() {
537}
538
539bool NetworkingPrivateVerifyAndEncryptCredentialsFunction::RunImpl() {
540  scoped_ptr<api::VerifyAndEncryptCredentials::Params> params =
541      api::VerifyAndEncryptCredentials::Params::Create(*args_);
542  EXTENSION_FUNCTION_VALIDATE(params);
543  ShillManagerClient* shill_manager_client =
544      DBusThreadManager::Get()->GetShillManagerClient();
545
546  ShillManagerClient::VerificationProperties verification_properties =
547      ConvertVerificationProperties(params->properties);
548
549  shill_manager_client->VerifyAndEncryptCredentials(
550      verification_properties,
551      params->guid,
552      base::Bind(
553          &NetworkingPrivateVerifyAndEncryptCredentialsFunction::ResultCallback,
554          this),
555      base::Bind(
556          &NetworkingPrivateVerifyAndEncryptCredentialsFunction::ErrorCallback,
557          this));
558  return true;
559}
560
561void NetworkingPrivateVerifyAndEncryptCredentialsFunction::ResultCallback(
562    const std::string& result) {
563  results_ = api::VerifyAndEncryptCredentials::Results::Create(result);
564  SendResponse(true);
565}
566
567void NetworkingPrivateVerifyAndEncryptCredentialsFunction::ErrorCallback(
568    const std::string& error_name, const std::string& error) {
569  error_ = error_name;
570  SendResponse(false);
571}
572
573////////////////////////////////////////////////////////////////////////////////
574// NetworkingPrivateVerifyAndEncryptDataFunction
575
576NetworkingPrivateVerifyAndEncryptDataFunction::
577  ~NetworkingPrivateVerifyAndEncryptDataFunction() {
578}
579
580bool NetworkingPrivateVerifyAndEncryptDataFunction::RunImpl() {
581  scoped_ptr<api::VerifyAndEncryptData::Params> params =
582      api::VerifyAndEncryptData::Params::Create(*args_);
583  EXTENSION_FUNCTION_VALIDATE(params);
584
585  ShillManagerClient::VerificationProperties verification_properties =
586      ConvertVerificationProperties(params->properties);
587
588  DBusThreadManager::Get()->GetShillManagerClient()->VerifyAndEncryptData(
589      verification_properties,
590      params->data,
591      base::Bind(
592          &NetworkingPrivateVerifyAndEncryptDataFunction::ResultCallback,
593          this),
594      base::Bind(
595          &NetworkingPrivateVerifyAndEncryptDataFunction::ErrorCallback,
596          this));
597  return true;
598}
599
600void NetworkingPrivateVerifyAndEncryptDataFunction::ResultCallback(
601    const std::string& result) {
602  results_ = api::VerifyAndEncryptData::Results::Create(result);
603  SendResponse(true);
604}
605
606void NetworkingPrivateVerifyAndEncryptDataFunction::ErrorCallback(
607    const std::string& error_name, const std::string& error) {
608  error_ = error_name;
609  SendResponse(false);
610}
611