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 base::DictionaryValue* properties_ptr = properties.get();
178 task_runner_->PostTaskAndReply(
180 base::Bind(&WiFiService::GetProperties,
181 base::Unretained(wifi_service_.get()),
185 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
186 weak_factory_.GetWeakPtr(),
187 service_callbacks->id,
189 base::Passed(&properties),
190 base::Owned(error)));
193 void NetworkingPrivateServiceClient::GetManagedProperties(
194 const std::string& guid,
195 const DictionaryCallback& success_callback,
196 const FailureCallback& failure_callback) {
197 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
198 service_callbacks->failure_callback = failure_callback;
199 service_callbacks->get_properties_callback = success_callback;
201 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
202 std::string* error = new std::string;
204 base::DictionaryValue* properties_ptr = properties.get();
205 task_runner_->PostTaskAndReply(
207 base::Bind(&WiFiService::GetManagedProperties,
208 base::Unretained(wifi_service_.get()),
212 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
213 weak_factory_.GetWeakPtr(),
214 service_callbacks->id,
216 base::Passed(&properties),
217 base::Owned(error)));
220 void NetworkingPrivateServiceClient::GetState(
221 const std::string& guid,
222 const DictionaryCallback& success_callback,
223 const FailureCallback& failure_callback) {
224 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
225 service_callbacks->failure_callback = failure_callback;
226 service_callbacks->get_properties_callback = success_callback;
228 scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue);
229 std::string* error = new std::string;
231 base::DictionaryValue* properties_ptr = properties.get();
232 task_runner_->PostTaskAndReply(
234 base::Bind(&WiFiService::GetState,
235 base::Unretained(wifi_service_.get()),
239 base::Bind(&NetworkingPrivateServiceClient::AfterGetProperties,
240 weak_factory_.GetWeakPtr(),
241 service_callbacks->id,
243 base::Passed(&properties),
244 base::Owned(error)));
247 void NetworkingPrivateServiceClient::SetProperties(
248 const std::string& guid,
249 scoped_ptr<base::DictionaryValue> properties,
250 const VoidCallback& success_callback,
251 const FailureCallback& failure_callback) {
252 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
253 service_callbacks->failure_callback = failure_callback;
254 service_callbacks->set_properties_callback = success_callback;
256 std::string* error = new std::string;
258 task_runner_->PostTaskAndReply(
260 base::Bind(&WiFiService::SetProperties,
261 base::Unretained(wifi_service_.get()),
263 base::Passed(&properties),
265 base::Bind(&NetworkingPrivateServiceClient::AfterSetProperties,
266 weak_factory_.GetWeakPtr(),
267 service_callbacks->id,
268 base::Owned(error)));
271 void NetworkingPrivateServiceClient::CreateNetwork(
273 scoped_ptr<base::DictionaryValue> properties,
274 const StringCallback& success_callback,
275 const FailureCallback& failure_callback) {
276 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
277 service_callbacks->failure_callback = failure_callback;
278 service_callbacks->create_network_callback = success_callback;
280 std::string* network_guid = new std::string;
281 std::string* error = new std::string;
283 task_runner_->PostTaskAndReply(
285 base::Bind(&WiFiService::CreateNetwork,
286 base::Unretained(wifi_service_.get()),
288 base::Passed(&properties),
291 base::Bind(&NetworkingPrivateServiceClient::AfterCreateNetwork,
292 weak_factory_.GetWeakPtr(),
293 service_callbacks->id,
294 base::Owned(network_guid),
295 base::Owned(error)));
298 void NetworkingPrivateServiceClient::GetNetworks(
299 const std::string& network_type,
300 bool configured_only,
303 const NetworkListCallback& success_callback,
304 const FailureCallback& failure_callback) {
305 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
306 service_callbacks->failure_callback = failure_callback;
307 service_callbacks->get_visible_networks_callback = success_callback;
309 scoped_ptr<base::ListValue> networks(new base::ListValue);
311 // TODO(stevenjb/mef): Apply filters (configured, visible, limit).
313 base::ListValue* networks_ptr = networks.get();
314 task_runner_->PostTaskAndReply(
316 base::Bind(&WiFiService::GetVisibleNetworks,
317 base::Unretained(wifi_service_.get()),
321 base::Bind(&NetworkingPrivateServiceClient::AfterGetVisibleNetworks,
322 weak_factory_.GetWeakPtr(),
323 service_callbacks->id,
324 base::Passed(&networks)));
327 void NetworkingPrivateServiceClient::StartConnect(
328 const std::string& guid,
329 const VoidCallback& success_callback,
330 const FailureCallback& failure_callback) {
331 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
332 service_callbacks->failure_callback = failure_callback;
333 service_callbacks->start_connect_callback = success_callback;
335 std::string* error = new std::string;
337 task_runner_->PostTaskAndReply(
339 base::Bind(&WiFiService::StartConnect,
340 base::Unretained(wifi_service_.get()),
343 base::Bind(&NetworkingPrivateServiceClient::AfterStartConnect,
344 weak_factory_.GetWeakPtr(),
345 service_callbacks->id,
346 base::Owned(error)));
349 void NetworkingPrivateServiceClient::StartDisconnect(
350 const std::string& guid,
351 const VoidCallback& success_callback,
352 const FailureCallback& failure_callback) {
353 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
354 service_callbacks->failure_callback = failure_callback;
355 service_callbacks->start_disconnect_callback = success_callback;
357 std::string* error = new std::string;
359 task_runner_->PostTaskAndReply(
361 base::Bind(&WiFiService::StartDisconnect,
362 base::Unretained(wifi_service_.get()),
365 base::Bind(&NetworkingPrivateServiceClient::AfterStartDisconnect,
366 weak_factory_.GetWeakPtr(),
367 service_callbacks->id,
368 base::Owned(error)));
371 void NetworkingPrivateServiceClient::VerifyDestination(
372 const VerificationProperties& verification_properties,
373 const BoolCallback& success_callback,
374 const FailureCallback& failure_callback) {
375 if (!crypto_verify_) {
376 failure_callback.Run(networking_private::kErrorNotSupported);
380 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
381 service_callbacks->failure_callback = failure_callback;
382 service_callbacks->verify_destination_callback = success_callback;
384 CryptoVerify::Credentials credentials;
385 if (!GetVerificationCredentials(verification_properties, &credentials)) {
386 failure_callback.Run(networking_private::kErrorEncryptionError);
390 bool* result = new bool;
391 std::string* error = new std::string;
393 task_runner_->PostTaskAndReply(
395 base::Bind(&CryptoVerify::VerifyDestination,
396 base::Unretained(crypto_verify_.get()),
400 base::Bind(&NetworkingPrivateServiceClient::AfterVerifyDestination,
401 weak_factory_.GetWeakPtr(),
402 service_callbacks->id,
404 base::Owned(error)));
407 void NetworkingPrivateServiceClient::VerifyAndEncryptCredentials(
408 const std::string& guid,
409 const VerificationProperties& verification_properties,
410 const StringCallback& success_callback,
411 const FailureCallback& failure_callback) {
412 if (!crypto_verify_) {
413 failure_callback.Run(networking_private::kErrorNotSupported);
417 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
418 service_callbacks->failure_callback = failure_callback;
419 service_callbacks->verify_and_encrypt_credentials_callback = success_callback;
421 CryptoVerify::Credentials credentials;
422 if (!GetVerificationCredentials(verification_properties, &credentials)) {
423 failure_callback.Run(networking_private::kErrorEncryptionError);
427 CryptoVerify::VerifyAndEncryptCredentialsCallback callback_relay(base::Bind(
428 &AfterVerifyAndEncryptCredentialsRelay,
430 &NetworkingPrivateServiceClient::AfterVerifyAndEncryptCredentials,
431 weak_factory_.GetWeakPtr(),
432 service_callbacks->id),
433 base::MessageLoopProxy::current()));
435 task_runner_->PostTask(FROM_HERE,
436 base::Bind(&CryptoVerify::VerifyAndEncryptCredentials,
437 base::Unretained(crypto_verify_.get()),
443 void NetworkingPrivateServiceClient::VerifyAndEncryptData(
444 const VerificationProperties& verification_properties,
445 const std::string& data,
446 const StringCallback& success_callback,
447 const FailureCallback& failure_callback) {
448 if (!crypto_verify_) {
449 failure_callback.Run(networking_private::kErrorNotSupported);
453 ServiceCallbacks* service_callbacks = AddServiceCallbacks();
454 service_callbacks->failure_callback = failure_callback;
455 service_callbacks->verify_and_encrypt_data_callback = success_callback;
457 CryptoVerify::Credentials credentials;
458 if (!GetVerificationCredentials(verification_properties, &credentials)) {
459 failure_callback.Run(networking_private::kErrorEncryptionError);
463 std::string* result = new std::string;
464 std::string* error = new std::string;
466 task_runner_->PostTaskAndReply(
468 base::Bind(&CryptoVerify::VerifyAndEncryptData,
469 base::Unretained(crypto_verify_.get()),
474 base::Bind(&NetworkingPrivateServiceClient::AfterVerifyAndEncryptData,
475 weak_factory_.GetWeakPtr(),
476 service_callbacks->id,
478 base::Owned(error)));
481 void NetworkingPrivateServiceClient::SetWifiTDLSEnabledState(
482 const std::string& ip_or_mac_address,
484 const StringCallback& success_callback,
485 const FailureCallback& failure_callback) {
486 failure_callback.Run(networking_private::kErrorNotSupported);
489 void NetworkingPrivateServiceClient::GetWifiTDLSStatus(
490 const std::string& ip_or_mac_address,
491 const StringCallback& success_callback,
492 const FailureCallback& failure_callback) {
493 failure_callback.Run(networking_private::kErrorNotSupported);
496 void NetworkingPrivateServiceClient::GetCaptivePortalStatus(
497 const std::string& guid,
498 const StringCallback& success_callback,
499 const FailureCallback& failure_callback) {
500 failure_callback.Run(networking_private::kErrorNotSupported);
503 scoped_ptr<base::ListValue>
504 NetworkingPrivateServiceClient::GetEnabledNetworkTypes() {
505 scoped_ptr<base::ListValue> network_list;
506 return network_list.Pass();
509 bool NetworkingPrivateServiceClient::EnableNetworkType(
510 const std::string& type) {
514 bool NetworkingPrivateServiceClient::DisableNetworkType(
515 const std::string& type) {
519 bool NetworkingPrivateServiceClient::RequestScan() {
520 task_runner_->PostTask(
522 base::Bind(&WiFiService::RequestNetworkScan,
523 base::Unretained(wifi_service_.get())));
527 ////////////////////////////////////////////////////////////////////////////////
529 void NetworkingPrivateServiceClient::AfterGetProperties(
530 ServiceCallbacksID callback_id,
531 const std::string& network_guid,
532 scoped_ptr<base::DictionaryValue> properties,
533 const std::string* error) {
534 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
535 DCHECK(service_callbacks);
536 if (!error->empty()) {
537 DCHECK(!service_callbacks->failure_callback.is_null());
538 service_callbacks->failure_callback.Run(*error);
540 DCHECK(!service_callbacks->get_properties_callback.is_null());
541 service_callbacks->get_properties_callback.Run(properties.Pass());
543 RemoveServiceCallbacks(callback_id);
546 void NetworkingPrivateServiceClient::AfterGetVisibleNetworks(
547 ServiceCallbacksID callback_id,
548 scoped_ptr<base::ListValue> networks) {
549 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
550 DCHECK(service_callbacks);
551 DCHECK(!service_callbacks->get_visible_networks_callback.is_null());
552 service_callbacks->get_visible_networks_callback.Run(networks.Pass());
553 RemoveServiceCallbacks(callback_id);
556 void NetworkingPrivateServiceClient::AfterSetProperties(
557 ServiceCallbacksID callback_id,
558 const std::string* error) {
559 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
560 DCHECK(service_callbacks);
561 if (!error->empty()) {
562 DCHECK(!service_callbacks->failure_callback.is_null());
563 service_callbacks->failure_callback.Run(*error);
565 DCHECK(!service_callbacks->set_properties_callback.is_null());
566 service_callbacks->set_properties_callback.Run();
568 RemoveServiceCallbacks(callback_id);
571 void NetworkingPrivateServiceClient::AfterCreateNetwork(
572 ServiceCallbacksID callback_id,
573 const std::string* network_guid,
574 const std::string* error) {
575 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
576 DCHECK(service_callbacks);
577 if (!error->empty()) {
578 DCHECK(!service_callbacks->failure_callback.is_null());
579 service_callbacks->failure_callback.Run(*error);
581 DCHECK(!service_callbacks->create_network_callback.is_null());
582 service_callbacks->create_network_callback.Run(*network_guid);
584 RemoveServiceCallbacks(callback_id);
587 void NetworkingPrivateServiceClient::AfterStartConnect(
588 ServiceCallbacksID callback_id,
589 const std::string* error) {
590 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
591 DCHECK(service_callbacks);
592 if (!error->empty()) {
593 DCHECK(!service_callbacks->failure_callback.is_null());
594 service_callbacks->failure_callback.Run(*error);
596 DCHECK(!service_callbacks->start_connect_callback.is_null());
597 service_callbacks->start_connect_callback.Run();
599 RemoveServiceCallbacks(callback_id);
602 void NetworkingPrivateServiceClient::AfterStartDisconnect(
603 ServiceCallbacksID callback_id,
604 const std::string* error) {
605 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
606 DCHECK(service_callbacks);
607 if (!error->empty()) {
608 DCHECK(!service_callbacks->failure_callback.is_null());
609 service_callbacks->failure_callback.Run(*error);
611 DCHECK(!service_callbacks->start_disconnect_callback.is_null());
612 service_callbacks->start_disconnect_callback.Run();
614 RemoveServiceCallbacks(callback_id);
617 void NetworkingPrivateServiceClient::AfterVerifyDestination(
618 ServiceCallbacksID callback_id,
620 const std::string* error) {
621 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
622 DCHECK(service_callbacks);
623 if (!error->empty()) {
624 DCHECK(!service_callbacks->failure_callback.is_null());
625 service_callbacks->failure_callback.Run(*error);
627 DCHECK(!service_callbacks->verify_destination_callback.is_null());
628 service_callbacks->verify_destination_callback.Run(*result);
630 RemoveServiceCallbacks(callback_id);
633 void NetworkingPrivateServiceClient::AfterVerifyAndEncryptCredentials(
634 ServiceCallbacksID callback_id,
635 const std::string& encrypted_data,
636 const std::string& error) {
637 DCHECK_CURRENTLY_ON(BrowserThread::UI);
638 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
639 DCHECK(service_callbacks);
640 if (!error.empty()) {
641 DCHECK(!service_callbacks->failure_callback.is_null());
642 service_callbacks->failure_callback.Run(error);
645 !service_callbacks->verify_and_encrypt_credentials_callback.is_null());
646 service_callbacks->verify_and_encrypt_credentials_callback.Run(
649 RemoveServiceCallbacks(callback_id);
652 void NetworkingPrivateServiceClient::AfterVerifyAndEncryptData(
653 ServiceCallbacksID callback_id,
654 const std::string* result,
655 const std::string* error) {
656 ServiceCallbacks* service_callbacks = callbacks_map_.Lookup(callback_id);
657 DCHECK(service_callbacks);
658 if (!error->empty()) {
659 DCHECK(!service_callbacks->failure_callback.is_null());
660 service_callbacks->failure_callback.Run(*error);
662 DCHECK(!service_callbacks->verify_and_encrypt_data_callback.is_null());
663 service_callbacks->verify_and_encrypt_data_callback.Run(*result);
665 RemoveServiceCallbacks(callback_id);
668 void NetworkingPrivateServiceClient::OnNetworksChangedEventOnUIThread(
669 const std::vector<std::string>& network_guids) {
670 DCHECK_CURRENTLY_ON(BrowserThread::UI);
671 FOR_EACH_OBSERVER(Observer,
672 network_events_observers_,
673 OnNetworksChangedEvent(network_guids));
676 void NetworkingPrivateServiceClient::OnNetworkListChangedEventOnUIThread(
677 const std::vector<std::string>& network_guids) {
678 DCHECK_CURRENTLY_ON(BrowserThread::UI);
679 FOR_EACH_OBSERVER(Observer,
680 network_events_observers_,
681 OnNetworkListChangedEvent(network_guids));
684 } // namespace extensions