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.
5 #include "chrome/browser/extensions/api/networking_private/networking_private_service_client.h"
7 #include "base/base64.h"
9 #include "base/sequenced_task_runner.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "base/threading/worker_pool.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/extensions/api/networking_private/networking_private_api.h"
15 #include "chrome/common/extensions/api/networking_private.h"
16 #include "content/public/browser/browser_thread.h"
18 using content::BrowserThread;
20 namespace extensions {
24 const char kNetworkingPrivateSequenceTokenName[] = "NetworkingPrivate";
26 bool GetVerificationCredentials(
27 const NetworkingPrivateDelegate::VerificationProperties& properties,
28 NetworkingPrivateServiceClient::CryptoVerify::Credentials* credentials) {
29 std::vector<std::string> data_parts;
30 data_parts.push_back(properties.device_ssid);
31 data_parts.push_back(properties.device_serial);
32 data_parts.push_back(properties.device_bssid);
33 data_parts.push_back(properties.public_key);
34 data_parts.push_back(properties.nonce);
35 credentials->unsigned_data = JoinString(data_parts, ",");
36 if (!base::Base64Decode(properties.signed_data, &credentials->signed_data)) {
37 LOG(ERROR) << "Failed to decode signed data: " << properties.signed_data;
40 credentials->certificate = properties.certificate;
41 credentials->device_bssid = properties.device_bssid;
42 if (!base::Base64Decode(properties.public_key, &credentials->public_key)) {
43 LOG(ERROR) << "Failed to decode public key";
49 // Deletes WiFiService and CryptoVerify objects on worker thread.
50 void ShutdownServicesOnWorkerThread(
51 scoped_ptr<wifi::WiFiService> wifi_service,
52 scoped_ptr<NetworkingPrivateServiceClient::CryptoVerify> crypto_verify) {
53 DCHECK(wifi_service.get());
54 DCHECK(crypto_verify.get());
57 // Forwards call back from VerifyAndEncryptCredentials on random thread to
58 // |callback| on correct |callback_loop_proxy|.
59 void AfterVerifyAndEncryptCredentialsRelay(
60 const NetworkingPrivateServiceClient::CryptoVerify::
61 VerifyAndEncryptCredentialsCallback& callback,
62 scoped_refptr<base::MessageLoopProxy> callback_loop_proxy,
63 const std::string& key_data,
64 const std::string& error) {
65 callback_loop_proxy->PostTask(FROM_HERE,
66 base::Bind(callback, key_data, error));
71 NetworkingPrivateServiceClient::CryptoVerify::CryptoVerify() {}
72 NetworkingPrivateServiceClient::CryptoVerify::~CryptoVerify() {}
74 NetworkingPrivateServiceClient::CryptoVerify::Credentials::Credentials() {}
75 NetworkingPrivateServiceClient::CryptoVerify::Credentials::~Credentials() {}
77 NetworkingPrivateServiceClient::NetworkingPrivateServiceClient(
78 wifi::WiFiService* wifi_service,
79 CryptoVerify* crypto_verify)
80 : crypto_verify_(crypto_verify),
81 wifi_service_(wifi_service),
83 sequence_token_ = BrowserThread::GetBlockingPool()->
84 GetNamedSequenceToken(kNetworkingPrivateSequenceTokenName);
85 task_runner_ = BrowserThread::GetBlockingPool()->
86 GetSequencedTaskRunnerWithShutdownBehavior(
88 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
89 task_runner_->PostTask(
92 &WiFiService::Initialize,
93 base::Unretained(wifi_service_.get()),
95 task_runner_->PostTask(
98 &WiFiService::SetEventObservers,
99 base::Unretained(wifi_service_.get()),
100 base::MessageLoopProxy::current(),
102 &NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread,
103 weak_factory_.GetWeakPtr()),
105 &NetworkingPrivateServiceClient::
106 OnNetworkListChangedEventOnUIThread,
107 weak_factory_.GetWeakPtr())));
108 net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
111 NetworkingPrivateServiceClient::~NetworkingPrivateServiceClient() {
112 // Verify that these objects were passed to ShutdownServicesOnWorkerThread to
113 // be deleted after completion of all posted tasks.
114 DCHECK(!wifi_service_.get());
115 DCHECK(!crypto_verify_.get());
118 NetworkingPrivateServiceClient::ServiceCallbacks::ServiceCallbacks() {}
120 NetworkingPrivateServiceClient::ServiceCallbacks::~ServiceCallbacks() {}
122 void NetworkingPrivateServiceClient::Shutdown() {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
125 // Clear callbacks map to release callbacks from UI thread.
126 callbacks_map_.Clear();
127 // Post ShutdownServicesOnWorkerThread task to delete services when all posted
129 task_runner_->PostTask(
131 base::Bind(&ShutdownServicesOnWorkerThread,
132 base::Passed(&wifi_service_),
133 base::Passed(&crypto_verify_)));
136 void NetworkingPrivateServiceClient::AddObserver(Observer* observer) {
137 network_events_observers_.AddObserver(observer);
140 void NetworkingPrivateServiceClient::RemoveObserver(Observer* observer) {
141 network_events_observers_.RemoveObserver(observer);
144 void NetworkingPrivateServiceClient::OnNetworkChanged(
145 net::NetworkChangeNotifier::ConnectionType type) {
146 task_runner_->PostTask(
148 base::Bind(&WiFiService::RequestConnectedNetworkUpdate,
149 base::Unretained(wifi_service_.get())));
152 NetworkingPrivateServiceClient::ServiceCallbacks*
153 NetworkingPrivateServiceClient::AddServiceCallbacks() {
154 ServiceCallbacks* service_callbacks = new ServiceCallbacks();
155 service_callbacks->id = callbacks_map_.Add(service_callbacks);
156 return service_callbacks;
159 void NetworkingPrivateServiceClient::RemoveServiceCallbacks(
160 ServiceCallbacksID callback_id) {
161 callbacks_map_.Remove(callback_id);
164 // NetworkingPrivateServiceClient implementation
166 void NetworkingPrivateServiceClient::GetProperties(
167 const std::string& guid,
168 const DictionaryCallback& success_callback,
169 const FailureCallback& failure_callback) {
170 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
171 service_callbacks->failure_callback = failure_callback;
172 service_callbacks->get_properties_callback = success_callback;
174 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
175 std::string* error = new std::string;
177 task_runner_->PostTaskAndReply(
179 base::Bind(&WiFiService::GetProperties,
180 base::Unretained(wifi_service_.get()),
184 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
185 weak_factory_.GetWeakPtr(),
186 service_callbacks->id,
188 base::Passed(&properties),
189 base::Owned(error)));
192 void NetworkingPrivateServiceClient::GetManagedProperties(
193 const std::string& guid,
194 const DictionaryCallback& success_callback,
195 const FailureCallback& failure_callback) {
196 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
197 service_callbacks->failure_callback = failure_callback;
198 service_callbacks->get_properties_callback = success_callback;
200 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
201 std::string* error = new std::string;
203 task_runner_->PostTaskAndReply(
205 base::Bind(&WiFiService::GetManagedProperties,
206 base::Unretained(wifi_service_.get()),
210 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
211 weak_factory_.GetWeakPtr(),
212 service_callbacks->id,
214 base::Passed(&properties),
215 base::Owned(error)));
218 void NetworkingPrivateServiceClient::GetState(
219 const std::string& guid,
220 const DictionaryCallback& success_callback,
221 const FailureCallback& failure_callback) {
222 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
223 service_callbacks->failure_callback = failure_callback;
224 service_callbacks->get_properties_callback = success_callback;
226 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
227 std::string* error = new std::string;
229 task_runner_->PostTaskAndReply(
231 base::Bind(&WiFiService::GetState,
232 base::Unretained(wifi_service_.get()),
236 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
237 weak_factory_.GetWeakPtr(),
238 service_callbacks->id,
240 base::Passed(&properties),
241 base::Owned(error)));
244 void NetworkingPrivateServiceClient::SetProperties(
245 const std::string& guid,
246 scoped_ptr<base::DictionaryValue> properties,
247 const VoidCallback& success_callback,
248 const FailureCallback& failure_callback) {
249 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
250 service_callbacks->failure_callback = failure_callback;
251 service_callbacks->set_properties_callback = success_callback;
253 std::string* error = new std::string;
255 task_runner_->PostTaskAndReply(
257 base::Bind(&WiFiService::SetProperties,
258 base::Unretained(wifi_service_.get()),
260 base::Passed(&properties),
262 base::Bind(&NetworkingPrivateServiceClient::AfterSetProperties,
263 weak_factory_.GetWeakPtr(),
264 service_callbacks->id,
265 base::Owned(error)));
268 void NetworkingPrivateServiceClient::CreateNetwork(
270 scoped_ptr<base::DictionaryValue> properties,
271 const StringCallback& success_callback,
272 const FailureCallback& failure_callback) {
273 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
274 service_callbacks->failure_callback = failure_callback;
275 service_callbacks->create_network_callback = success_callback;
277 std::string* network_guid = new std::string;
278 std::string* error = new std::string;
280 task_runner_->PostTaskAndReply(
282 base::Bind(&WiFiService::CreateNetwork,
283 base::Unretained(wifi_service_.get()),
285 base::Passed(&properties),
288 base::Bind(&NetworkingPrivateServiceClient::AfterCreateNetwork,
289 weak_factory_.GetWeakPtr(),
290 service_callbacks->id,
291 base::Owned(network_guid),
292 base::Owned(error)));
295 void NetworkingPrivateServiceClient::GetNetworks(
296 const std::string& network_type,
297 bool configured_only,
300 const NetworkListCallback& success_callback,
301 const FailureCallback& failure_callback) {
302 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
303 service_callbacks->failure_callback = failure_callback;
304 service_callbacks->get_visible_networks_callback = success_callback;
306 scoped_ptr<base::ListValue> networks(new base::ListValue);
308 // TODO(stevenjb/mef): Apply filters (configured, visible, limit).
310 task_runner_->PostTaskAndReply(
312 base::Bind(&WiFiService::GetVisibleNetworks,
313 base::Unretained(wifi_service_.get()),
317 base::Bind(&NetworkingPrivateServiceClient::AfterGetVisibleNetworks,
318 weak_factory_.GetWeakPtr(),
319 service_callbacks->id,
320 base::Passed(&networks)));
323 void NetworkingPrivateServiceClient::StartConnect(
324 const std::string& guid,
325 const VoidCallback& success_callback,
326 const FailureCallback& failure_callback) {
327 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
328 service_callbacks->failure_callback = failure_callback;
329 service_callbacks->start_connect_callback = success_callback;
331 std::string* error = new std::string;
333 task_runner_->PostTaskAndReply(
335 base::Bind(&WiFiService::StartConnect,
336 base::Unretained(wifi_service_.get()),
339 base::Bind(&NetworkingPrivateServiceClient::AfterStartConnect,
340 weak_factory_.GetWeakPtr(),
341 service_callbacks->id,
342 base::Owned(error)));
345 void NetworkingPrivateServiceClient::StartDisconnect(
346 const std::string& guid,
347 const VoidCallback& success_callback,
348 const FailureCallback& failure_callback) {
349 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
350 service_callbacks->failure_callback = failure_callback;
351 service_callbacks->start_disconnect_callback = success_callback;
353 std::string* error = new std::string;
355 task_runner_->PostTaskAndReply(
357 base::Bind(&WiFiService::StartDisconnect,
358 base::Unretained(wifi_service_.get()),
361 base::Bind(&NetworkingPrivateServiceClient::AfterStartDisconnect,
362 weak_factory_.GetWeakPtr(),
363 service_callbacks->id,
364 base::Owned(error)));
367 void NetworkingPrivateServiceClient::VerifyDestination(
368 const VerificationProperties& verification_properties,
369 const BoolCallback& success_callback,
370 const FailureCallback& failure_callback) {
371 if (!crypto_verify_) {
372 failure_callback.Run(networking_private::kErrorNotSupported);
376 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
377 service_callbacks->failure_callback = failure_callback;
378 service_callbacks->verify_destination_callback = success_callback;
380 CryptoVerify::Credentials credentials;
381 if (!GetVerificationCredentials(verification_properties, &credentials)) {
382 failure_callback.Run(networking_private::kErrorEncryptionError);
386 bool* result = new bool;
387 std::string* error = new std::string;
389 task_runner_->PostTaskAndReply(
391 base::Bind(&CryptoVerify::VerifyDestination,
392 base::Unretained(crypto_verify_.get()),
396 base::Bind(&NetworkingPrivateServiceClient::AfterVerifyDestination,
397 weak_factory_.GetWeakPtr(),
398 service_callbacks->id,
400 base::Owned(error)));
403 void NetworkingPrivateServiceClient::VerifyAndEncryptCredentials(
404 const std::string& guid,
405 const VerificationProperties& verification_properties,
406 const StringCallback& success_callback,
407 const FailureCallback& failure_callback) {
408 if (!crypto_verify_) {
409 failure_callback.Run(networking_private::kErrorNotSupported);
413 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
414 service_callbacks->failure_callback = failure_callback;
415 service_callbacks->verify_and_encrypt_credentials_callback = success_callback;
417 CryptoVerify::Credentials credentials;
418 if (!GetVerificationCredentials(verification_properties, &credentials)) {
419 failure_callback.Run(networking_private::kErrorEncryptionError);
423 CryptoVerify::VerifyAndEncryptCredentialsCallback callback_relay(base::Bind(
424 &AfterVerifyAndEncryptCredentialsRelay,
426 &NetworkingPrivateServiceClient::AfterVerifyAndEncryptCredentials,
427 weak_factory_.GetWeakPtr(),
428 service_callbacks->id),
429 base::MessageLoopProxy::current()));
431 task_runner_->PostTask(FROM_HERE,
432 base::Bind(&CryptoVerify::VerifyAndEncryptCredentials,
433 base::Unretained(crypto_verify_.get()),
439 void NetworkingPrivateServiceClient::VerifyAndEncryptData(
440 const VerificationProperties& verification_properties,
441 const std::string& data,
442 const StringCallback& success_callback,
443 const FailureCallback& failure_callback) {
444 if (!crypto_verify_) {
445 failure_callback.Run(networking_private::kErrorNotSupported);
449 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
450 service_callbacks->failure_callback = failure_callback;
451 service_callbacks->verify_and_encrypt_data_callback = success_callback;
453 CryptoVerify::Credentials credentials;
454 if (!GetVerificationCredentials(verification_properties, &credentials)) {
455 failure_callback.Run(networking_private::kErrorEncryptionError);
459 std::string* result = new std::string;
460 std::string* error = new std::string;
462 task_runner_->PostTaskAndReply(
464 base::Bind(&CryptoVerify::VerifyAndEncryptData,
465 base::Unretained(crypto_verify_.get()),
470 base::Bind(&NetworkingPrivateServiceClient::AfterVerifyAndEncryptData,
471 weak_factory_.GetWeakPtr(),
472 service_callbacks->id,
474 base::Owned(error)));
477 void NetworkingPrivateServiceClient::SetWifiTDLSEnabledState(
478 const std::string& ip_or_mac_address,
480 const StringCallback& success_callback,
481 const FailureCallback& failure_callback) {
482 failure_callback.Run(networking_private::kErrorNotSupported);
485 void NetworkingPrivateServiceClient::GetWifiTDLSStatus(
486 const std::string& ip_or_mac_address,
487 const StringCallback& success_callback,
488 const FailureCallback& failure_callback) {
489 failure_callback.Run(networking_private::kErrorNotSupported);
492 void NetworkingPrivateServiceClient::GetCaptivePortalStatus(
493 const std::string& guid,
494 const StringCallback& success_callback,
495 const FailureCallback& failure_callback) {
496 failure_callback.Run(networking_private::kErrorNotSupported);
499 scoped_ptr<base::ListValue>
500 NetworkingPrivateServiceClient::GetEnabledNetworkTypes() {
501 scoped_ptr<base::ListValue> network_list;
502 return network_list.Pass();
505 bool NetworkingPrivateServiceClient::EnableNetworkType(
506 const std::string& type) {
510 bool NetworkingPrivateServiceClient::DisableNetworkType(
511 const std::string& type) {
515 bool NetworkingPrivateServiceClient::RequestScan() {
516 task_runner_->PostTask(
518 base::Bind(&WiFiService::RequestNetworkScan,
519 base::Unretained(wifi_service_.get())));
523 ////////////////////////////////////////////////////////////////////////////////
525 void NetworkingPrivateServiceClient::AfterGetProperties(
526 ServiceCallbacksID callback_id,
527 const std::string& network_guid,
528 scoped_ptr<base::DictionaryValue> properties,
529 const std::string* error) {
530 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
531 DCHECK(service_callbacks);
532 if (!error->empty()) {
533 DCHECK(!service_callbacks->failure_callback.is_null());
534 service_callbacks->failure_callback.Run(*error);
536 DCHECK(!service_callbacks->get_properties_callback.is_null());
537 service_callbacks->get_properties_callback.Run(properties.Pass());
539 RemoveServiceCallbacks(callback_id);
542 void NetworkingPrivateServiceClient::AfterGetVisibleNetworks(
543 ServiceCallbacksID callback_id,
544 scoped_ptr<base::ListValue> networks) {
545 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
546 DCHECK(service_callbacks);
547 DCHECK(!service_callbacks->get_visible_networks_callback.is_null());
548 service_callbacks->get_visible_networks_callback.Run(networks.Pass());
549 RemoveServiceCallbacks(callback_id);
552 void NetworkingPrivateServiceClient::AfterSetProperties(
553 ServiceCallbacksID callback_id,
554 const std::string* error) {
555 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
556 DCHECK(service_callbacks);
557 if (!error->empty()) {
558 DCHECK(!service_callbacks->failure_callback.is_null());
559 service_callbacks->failure_callback.Run(*error);
561 DCHECK(!service_callbacks->set_properties_callback.is_null());
562 service_callbacks->set_properties_callback.Run();
564 RemoveServiceCallbacks(callback_id);
567 void NetworkingPrivateServiceClient::AfterCreateNetwork(
568 ServiceCallbacksID callback_id,
569 const std::string* network_guid,
570 const std::string* error) {
571 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
572 DCHECK(service_callbacks);
573 if (!error->empty()) {
574 DCHECK(!service_callbacks->failure_callback.is_null());
575 service_callbacks->failure_callback.Run(*error);
577 DCHECK(!service_callbacks->create_network_callback.is_null());
578 service_callbacks->create_network_callback.Run(*network_guid);
580 RemoveServiceCallbacks(callback_id);
583 void NetworkingPrivateServiceClient::AfterStartConnect(
584 ServiceCallbacksID callback_id,
585 const std::string* error) {
586 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
587 DCHECK(service_callbacks);
588 if (!error->empty()) {
589 DCHECK(!service_callbacks->failure_callback.is_null());
590 service_callbacks->failure_callback.Run(*error);
592 DCHECK(!service_callbacks->start_connect_callback.is_null());
593 service_callbacks->start_connect_callback.Run();
595 RemoveServiceCallbacks(callback_id);
598 void NetworkingPrivateServiceClient::AfterStartDisconnect(
599 ServiceCallbacksID callback_id,
600 const std::string* error) {
601 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
602 DCHECK(service_callbacks);
603 if (!error->empty()) {
604 DCHECK(!service_callbacks->failure_callback.is_null());
605 service_callbacks->failure_callback.Run(*error);
607 DCHECK(!service_callbacks->start_disconnect_callback.is_null());
608 service_callbacks->start_disconnect_callback.Run();
610 RemoveServiceCallbacks(callback_id);
613 void NetworkingPrivateServiceClient::AfterVerifyDestination(
614 ServiceCallbacksID callback_id,
616 const std::string* error) {
617 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
618 DCHECK(service_callbacks);
619 if (!error->empty()) {
620 DCHECK(!service_callbacks->failure_callback.is_null());
621 service_callbacks->failure_callback.Run(*error);
623 DCHECK(!service_callbacks->verify_destination_callback.is_null());
624 service_callbacks->verify_destination_callback.Run(*result);
626 RemoveServiceCallbacks(callback_id);
629 void NetworkingPrivateServiceClient::AfterVerifyAndEncryptCredentials(
630 ServiceCallbacksID callback_id,
631 const std::string& encrypted_data,
632 const std::string& error) {
633 DCHECK_CURRENTLY_ON(BrowserThread::UI);
634 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
635 DCHECK(service_callbacks);
636 if (!error.empty()) {
637 DCHECK(!service_callbacks->failure_callback.is_null());
638 service_callbacks->failure_callback.Run(error);
641 !service_callbacks->verify_and_encrypt_credentials_callback.is_null());
642 service_callbacks->verify_and_encrypt_credentials_callback.Run(
645 RemoveServiceCallbacks(callback_id);
648 void NetworkingPrivateServiceClient::AfterVerifyAndEncryptData(
649 ServiceCallbacksID callback_id,
650 const std::string* result,
651 const std::string* error) {
652 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
653 DCHECK(service_callbacks);
654 if (!error->empty()) {
655 DCHECK(!service_callbacks->failure_callback.is_null());
656 service_callbacks->failure_callback.Run(*error);
658 DCHECK(!service_callbacks->verify_and_encrypt_data_callback.is_null());
659 service_callbacks->verify_and_encrypt_data_callback.Run(*result);
661 RemoveServiceCallbacks(callback_id);
664 void NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread(
665 const std::vector<std::string>& network_guids) {
666 DCHECK_CURRENTLY_ON(BrowserThread::UI);
667 FOR_EACH_OBSERVER(Observer,
668 network_events_observers_,
669 OnNetworksChangedEvent(network_guids));
672 void NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread(
673 const std::vector<std::string>& network_guids) {
674 DCHECK_CURRENTLY_ON(BrowserThread::UI);
675 FOR_EACH_OBSERVER(Observer,
676 network_events_observers_,
677 OnNetworkListChangedEvent(network_guids));
680 } // namespace extensions