1 // Copyright (c) 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 "chromeos/network/network_connection_handler.h"
8 #include "base/command_line.h"
9 #include "base/json/json_reader.h"
10 #include "base/location.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "chromeos/cert_loader.h"
13 #include "chromeos/chromeos_switches.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/dbus/shill_manager_client.h"
16 #include "chromeos/dbus/shill_service_client.h"
17 #include "chromeos/network/client_cert_util.h"
18 #include "chromeos/network/network_configuration_handler.h"
19 #include "chromeos/network/network_event_log.h"
20 #include "chromeos/network/network_handler_callbacks.h"
21 #include "chromeos/network/network_profile_handler.h"
22 #include "chromeos/network/network_state.h"
23 #include "chromeos/network/network_state_handler.h"
24 #include "chromeos/network/network_ui_data.h"
25 #include "chromeos/network/shill_property_util.h"
26 #include "chromeos/tpm_token_loader.h"
27 #include "dbus/object_path.h"
28 #include "net/cert/x509_certificate.h"
29 #include "third_party/cros_system_api/dbus/service_constants.h"
35 void InvokeErrorCallback(const std::string
& service_path
,
36 const network_handler::ErrorCallback
& error_callback
,
37 const std::string
& error_name
) {
38 std::string error_msg
= "Connect Error: " + error_name
;
39 NET_LOG_ERROR(error_msg
, service_path
);
40 network_handler::RunErrorCallback(
41 error_callback
, service_path
, error_name
, error_msg
);
44 bool IsAuthenticationError(const std::string
& error
) {
45 return (error
== shill::kErrorBadWEPKey
||
46 error
== shill::kErrorPppAuthFailed
||
47 error
== shill::kErrorEapLocalTlsFailed
||
48 error
== shill::kErrorEapRemoteTlsFailed
||
49 error
== shill::kErrorEapAuthenticationFailed
);
52 bool VPNRequiresCredentials(const std::string
& service_path
,
53 const std::string
& provider_type
,
54 const base::DictionaryValue
& provider_properties
) {
55 if (provider_type
== shill::kProviderOpenVpn
) {
57 provider_properties
.GetStringWithoutPathExpansion(
58 shill::kOpenVPNUserProperty
, &username
);
59 if (username
.empty()) {
60 NET_LOG_EVENT("OpenVPN: No username", service_path
);
63 bool passphrase_required
= false;
64 provider_properties
.GetBooleanWithoutPathExpansion(
65 shill::kPassphraseRequiredProperty
, &passphrase_required
);
66 if (passphrase_required
) {
67 NET_LOG_EVENT("OpenVPN: Passphrase Required", service_path
);
70 NET_LOG_EVENT("OpenVPN Is Configured", service_path
);
72 bool passphrase_required
= false;
73 provider_properties
.GetBooleanWithoutPathExpansion(
74 shill::kL2tpIpsecPskRequiredProperty
, &passphrase_required
);
75 if (passphrase_required
) {
76 NET_LOG_EVENT("VPN: PSK Required", service_path
);
79 provider_properties
.GetBooleanWithoutPathExpansion(
80 shill::kPassphraseRequiredProperty
, &passphrase_required
);
81 if (passphrase_required
) {
82 NET_LOG_EVENT("VPN: Passphrase Required", service_path
);
85 NET_LOG_EVENT("VPN Is Configured", service_path
);
90 std::string
GetDefaultUserProfilePath(const NetworkState
* network
) {
91 if (!NetworkHandler::IsInitialized() ||
92 !LoginState::Get()->IsUserAuthenticated() ||
93 (network
&& network
->type() == shill::kTypeWifi
&&
94 network
->security() == shill::kSecurityNone
)) {
95 return NetworkProfileHandler::kSharedProfilePath
;
97 const NetworkProfile
* profile
=
98 NetworkHandler::Get()->network_profile_handler()->GetDefaultUserProfile();
99 return profile
? profile
->path
: NetworkProfileHandler::kSharedProfilePath
;
104 const char NetworkConnectionHandler::kErrorNotFound
[] = "not-found";
105 const char NetworkConnectionHandler::kErrorConnected
[] = "connected";
106 const char NetworkConnectionHandler::kErrorConnecting
[] = "connecting";
107 const char NetworkConnectionHandler::kErrorNotConnected
[] = "not-connected";
108 const char NetworkConnectionHandler::kErrorPassphraseRequired
[] =
109 "passphrase-required";
110 const char NetworkConnectionHandler::kErrorActivationRequired
[] =
111 "activation-required";
112 const char NetworkConnectionHandler::kErrorCertificateRequired
[] =
113 "certificate-required";
114 const char NetworkConnectionHandler::kErrorConfigurationRequired
[] =
115 "configuration-required";
116 const char NetworkConnectionHandler::kErrorAuthenticationRequired
[] =
117 "authentication-required";
118 const char NetworkConnectionHandler::kErrorShillError
[] = "shill-error";
119 const char NetworkConnectionHandler::kErrorConfigureFailed
[] =
121 const char NetworkConnectionHandler::kErrorConnectCanceled
[] =
124 struct NetworkConnectionHandler::ConnectRequest
{
125 ConnectRequest(const std::string
& service_path
,
126 const std::string
& profile_path
,
127 const base::Closure
& success
,
128 const network_handler::ErrorCallback
& error
)
129 : service_path(service_path
),
130 profile_path(profile_path
),
131 connect_state(CONNECT_REQUESTED
),
132 success_callback(success
),
133 error_callback(error
) {
136 CONNECT_REQUESTED
= 0,
138 CONNECT_CONNECTING
= 2
140 std::string service_path
;
141 std::string profile_path
;
142 ConnectState connect_state
;
143 base::Closure success_callback
;
144 network_handler::ErrorCallback error_callback
;
147 NetworkConnectionHandler::NetworkConnectionHandler()
148 : cert_loader_(NULL
),
149 network_state_handler_(NULL
),
150 network_configuration_handler_(NULL
),
152 certificates_loaded_(false) {
155 NetworkConnectionHandler::~NetworkConnectionHandler() {
156 if (network_state_handler_
)
157 network_state_handler_
->RemoveObserver(this, FROM_HERE
);
159 cert_loader_
->RemoveObserver(this);
160 if (LoginState::IsInitialized())
161 LoginState::Get()->RemoveObserver(this);
164 void NetworkConnectionHandler::Init(
165 NetworkStateHandler
* network_state_handler
,
166 NetworkConfigurationHandler
* network_configuration_handler
) {
167 if (LoginState::IsInitialized()) {
168 LoginState::Get()->AddObserver(this);
169 logged_in_
= LoginState::Get()->IsUserLoggedIn();
172 if (CertLoader::IsInitialized()) {
173 cert_loader_
= CertLoader::Get();
174 cert_loader_
->AddObserver(this);
175 certificates_loaded_
= cert_loader_
->certificates_loaded();
177 // TODO(tbarzic): Require a mock or stub cert_loader in tests.
178 certificates_loaded_
= true;
181 if (network_state_handler
) {
182 network_state_handler_
= network_state_handler
;
183 network_state_handler_
->AddObserver(this, FROM_HERE
);
185 network_configuration_handler_
= network_configuration_handler
;
188 void NetworkConnectionHandler::LoggedInStateChanged() {
189 if (LoginState::Get()->IsUserLoggedIn()) {
191 NET_LOG_EVENT("Logged In", "");
195 void NetworkConnectionHandler::OnCertificatesLoaded(
196 const net::CertificateList
& cert_list
,
198 certificates_loaded_
= true;
199 NET_LOG_EVENT("Certificates Loaded", "");
200 if (queued_connect_
) {
201 NET_LOG_EVENT("Connecting to Queued Network",
202 queued_connect_
->service_path
);
204 // Make a copy of |queued_connect_| parameters, because |queued_connect_|
205 // will get reset at the beginning of |ConnectToNetwork|.
206 std::string service_path
= queued_connect_
->service_path
;
207 base::Closure success_callback
= queued_connect_
->success_callback
;
208 network_handler::ErrorCallback error_callback
=
209 queued_connect_
->error_callback
;
211 ConnectToNetwork(service_path
, success_callback
, error_callback
,
212 false /* check_error_state */);
213 } else if (initial_load
) {
214 // Once certificates have loaded, connect to the "best" available network.
215 network_state_handler_
->ConnectToBestWifiNetwork();
219 void NetworkConnectionHandler::ConnectToNetwork(
220 const std::string
& service_path
,
221 const base::Closure
& success_callback
,
222 const network_handler::ErrorCallback
& error_callback
,
223 bool check_error_state
) {
224 NET_LOG_USER("ConnectToNetwork", service_path
);
225 // Clear any existing queued connect request.
226 queued_connect_
.reset();
227 if (HasConnectingNetwork(service_path
)) {
228 NET_LOG_USER("Connect Request While Pending", service_path
);
229 InvokeErrorCallback(service_path
, error_callback
, kErrorConnecting
);
233 // Check cached network state for connected, connecting, or unactivated
234 // networks. These states will not be affected by a recent configuration.
235 // Note: NetworkState may not exist for a network that was recently
236 // configured, in which case these checks do not apply anyway.
237 const NetworkState
* network
=
238 network_state_handler_
->GetNetworkState(service_path
);
241 // For existing networks, perform some immediate consistency checks.
242 if (network
->IsConnectedState()) {
243 InvokeErrorCallback(service_path
, error_callback
, kErrorConnected
);
246 if (network
->IsConnectingState()) {
247 InvokeErrorCallback(service_path
, error_callback
, kErrorConnecting
);
250 if (network
->RequiresActivation()) {
251 InvokeErrorCallback(service_path
, error_callback
,
252 kErrorActivationRequired
);
256 if (check_error_state
) {
257 const std::string
& error
= network
->error();
258 if (error
== shill::kErrorBadPassphrase
) {
259 InvokeErrorCallback(service_path
, error_callback
, error
);
262 if (IsAuthenticationError(error
)) {
264 service_path
, error_callback
, kErrorAuthenticationRequired
);
270 // If the network does not have a profile path, specify the correct default
271 // profile here and set it once connected. Otherwise leave it empty to
272 // indicate that it does not need to be set.
273 std::string profile_path
;
274 if (!network
|| network
->profile_path().empty())
275 profile_path
= GetDefaultUserProfilePath(network
);
277 // All synchronous checks passed, add |service_path| to connecting list.
278 pending_requests_
.insert(std::make_pair(
280 ConnectRequest(service_path
, profile_path
,
281 success_callback
, error_callback
)));
283 // Connect immediately to 'connectable' networks.
284 // TODO(stevenjb): Shill needs to properly set Connectable for VPN.
285 if (network
&& network
->connectable() && network
->type() != shill::kTypeVPN
) {
286 CallShillConnect(service_path
);
290 // Request additional properties to check. VerifyConfiguredAndConnect will
291 // use only these properties, not cached properties, to ensure that they
292 // are up to date after any recent configuration.
293 network_configuration_handler_
->GetProperties(
295 base::Bind(&NetworkConnectionHandler::VerifyConfiguredAndConnect
,
296 AsWeakPtr(), check_error_state
),
297 base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure
,
298 AsWeakPtr(), service_path
));
301 void NetworkConnectionHandler::DisconnectNetwork(
302 const std::string
& service_path
,
303 const base::Closure
& success_callback
,
304 const network_handler::ErrorCallback
& error_callback
) {
305 NET_LOG_USER("DisconnectNetwork", service_path
);
306 const NetworkState
* network
=
307 network_state_handler_
->GetNetworkState(service_path
);
309 InvokeErrorCallback(service_path
, error_callback
, kErrorNotFound
);
312 if (!network
->IsConnectedState()) {
313 InvokeErrorCallback(service_path
, error_callback
, kErrorNotConnected
);
316 CallShillDisconnect(service_path
, success_callback
, error_callback
);
319 bool NetworkConnectionHandler::HasConnectingNetwork(
320 const std::string
& service_path
) {
321 return pending_requests_
.count(service_path
) != 0;
324 bool NetworkConnectionHandler::HasPendingConnectRequest() {
325 return pending_requests_
.size() > 0;
328 void NetworkConnectionHandler::NetworkListChanged() {
329 CheckAllPendingRequests();
332 void NetworkConnectionHandler::NetworkPropertiesUpdated(
333 const NetworkState
* network
) {
334 if (HasConnectingNetwork(network
->path()))
335 CheckPendingRequest(network
->path());
338 NetworkConnectionHandler::ConnectRequest
*
339 NetworkConnectionHandler::GetPendingRequest(const std::string
& service_path
) {
340 std::map
<std::string
, ConnectRequest
>::iterator iter
=
341 pending_requests_
.find(service_path
);
342 return iter
!= pending_requests_
.end() ? &(iter
->second
) : NULL
;
345 // ConnectToNetwork implementation
347 void NetworkConnectionHandler::VerifyConfiguredAndConnect(
348 bool check_error_state
,
349 const std::string
& service_path
,
350 const base::DictionaryValue
& service_properties
) {
351 NET_LOG_EVENT("VerifyConfiguredAndConnect", service_path
);
353 // If 'passphrase_required' is still true, then the 'Passphrase' property
354 // has not been set to a minimum length value.
355 bool passphrase_required
= false;
356 service_properties
.GetBooleanWithoutPathExpansion(
357 shill::kPassphraseRequiredProperty
, &passphrase_required
);
358 if (passphrase_required
) {
359 ErrorCallbackForPendingRequest(service_path
, kErrorPassphraseRequired
);
363 std::string type
, security
;
364 service_properties
.GetStringWithoutPathExpansion(shill::kTypeProperty
, &type
);
365 service_properties
.GetStringWithoutPathExpansion(
366 shill::kSecurityProperty
, &security
);
367 bool connectable
= false;
368 service_properties
.GetBooleanWithoutPathExpansion(
369 shill::kConnectableProperty
, &connectable
);
371 // In case NetworkState was not available in ConnectToNetwork (e.g. it had
372 // been recently configured), we need to check Connectable again.
373 if (connectable
&& type
!= shill::kTypeVPN
) {
374 // TODO(stevenjb): Shill needs to properly set Connectable for VPN.
375 CallShillConnect(service_path
);
379 // Get VPN provider type and host (required for configuration) and ensure
380 // that required VPN non-cert properties are set.
381 const base::DictionaryValue
* provider_properties
= NULL
;
382 std::string vpn_provider_type
, vpn_provider_host
, vpn_client_cert_id
;
383 if (type
== shill::kTypeVPN
) {
384 // VPN Provider values are read from the "Provider" dictionary, not the
385 // "Provider.Type", etc keys (which are used only to set the values).
386 if (service_properties
.GetDictionaryWithoutPathExpansion(
387 shill::kProviderProperty
, &provider_properties
)) {
388 provider_properties
->GetStringWithoutPathExpansion(
389 shill::kTypeProperty
, &vpn_provider_type
);
390 provider_properties
->GetStringWithoutPathExpansion(
391 shill::kHostProperty
, &vpn_provider_host
);
392 provider_properties
->GetStringWithoutPathExpansion(
393 shill::kL2tpIpsecClientCertIdProperty
, &vpn_client_cert_id
);
395 if (vpn_provider_type
.empty() || vpn_provider_host
.empty()) {
396 ErrorCallbackForPendingRequest(service_path
, kErrorConfigurationRequired
);
401 scoped_ptr
<NetworkUIData
> ui_data
=
402 shill_property_util::GetUIDataFromProperties(service_properties
);
404 client_cert::ConfigType client_cert_type
= client_cert::CONFIG_TYPE_NONE
;
405 if (type
== shill::kTypeVPN
) {
406 if (vpn_provider_type
== shill::kProviderOpenVpn
) {
407 client_cert_type
= client_cert::CONFIG_TYPE_OPENVPN
;
409 // L2TP/IPSec only requires a certificate if one is specified in ONC
410 // or one was configured by the UI. Otherwise it is L2TP/IPSec with
411 // PSK and doesn't require a certificate.
413 // TODO(benchan): Modify shill to specify the authentication type via
414 // the kL2tpIpsecAuthenticationType property, so that Chrome doesn't need
415 // to deduce the authentication type based on the
416 // kL2tpIpsecClientCertIdProperty here (and also in VPNConfigView).
417 if (!vpn_client_cert_id
.empty() ||
418 (ui_data
&& ui_data
->certificate_type() != CLIENT_CERT_TYPE_NONE
))
419 client_cert_type
= client_cert::CONFIG_TYPE_IPSEC
;
421 } else if (type
== shill::kTypeWifi
&& security
== shill::kSecurity8021x
) {
422 client_cert_type
= client_cert::CONFIG_TYPE_EAP
;
425 base::DictionaryValue config_properties
;
426 if (client_cert_type
!= client_cert::CONFIG_TYPE_NONE
) {
427 // If the client certificate must be configured, this will be set to a
429 std::string pkcs11_id
;
431 // Check certificate properties in kUIDataProperty if configured.
432 // Note: Wifi/VPNConfigView set these properties explicitly, in which case
433 // only the TPM must be configured.
434 if (ui_data
&& ui_data
->certificate_type() == CLIENT_CERT_TYPE_PATTERN
) {
435 // User must be logged in to connect to a network requiring a certificate.
436 if (!logged_in_
|| !cert_loader_
) {
437 ErrorCallbackForPendingRequest(service_path
, kErrorCertificateRequired
);
441 // If certificates have not been loaded yet, queue the connect request.
442 if (!certificates_loaded_
) {
443 NET_LOG_EVENT("Certificates not loaded", "");
444 ConnectRequest
* request
= GetPendingRequest(service_path
);
446 NET_LOG_ERROR("No pending request to queue", service_path
);
449 NET_LOG_EVENT("Connect Request Queued", service_path
);
450 queued_connect_
.reset(new ConnectRequest(
451 service_path
, request
->profile_path
,
452 request
->success_callback
, request
->error_callback
));
453 pending_requests_
.erase(service_path
);
457 pkcs11_id
= CertificateIsConfigured(ui_data
.get());
458 // Ensure the certificate is available and configured.
459 if (!cert_loader_
->IsHardwareBacked() || pkcs11_id
.empty()) {
460 ErrorCallbackForPendingRequest(service_path
, kErrorCertificateRequired
);
463 } else if (check_error_state
&&
464 !client_cert::IsCertificateConfigured(client_cert_type
,
465 service_properties
)) {
466 // Network may not be configured.
467 ErrorCallbackForPendingRequest(service_path
, kErrorConfigurationRequired
);
471 // The network may not be 'Connectable' because the TPM properties are not
472 // set up, so configure tpm slot/pin before connecting.
473 if (cert_loader_
&& cert_loader_
->IsHardwareBacked()) {
474 // Pass NULL if pkcs11_id is empty, so that it doesn't clear any
475 // previously configured client cert.
476 client_cert::SetShillProperties(
478 base::IntToString(cert_loader_
->TPMTokenSlotID()),
479 TPMTokenLoader::Get()->tpm_user_pin(),
480 pkcs11_id
.empty() ? NULL
: &pkcs11_id
,
485 if (type
== shill::kTypeVPN
) {
486 // VPN may require a username, and/or passphrase to be set. (Check after
487 // ensuring that any required certificates are configured).
488 DCHECK(provider_properties
);
489 if (VPNRequiresCredentials(
490 service_path
, vpn_provider_type
, *provider_properties
)) {
491 NET_LOG_USER("VPN Requires Credentials", service_path
);
492 ErrorCallbackForPendingRequest(service_path
, kErrorConfigurationRequired
);
496 // If it's L2TP/IPsec PSK, there is no properties to configure, so proceed
498 if (client_cert_type
== client_cert::CONFIG_TYPE_NONE
) {
499 CallShillConnect(service_path
);
504 if (!config_properties
.empty()) {
505 NET_LOG_EVENT("Configuring Network", service_path
);
506 network_configuration_handler_
->SetProperties(
509 base::Bind(&NetworkConnectionHandler::CallShillConnect
,
512 base::Bind(&NetworkConnectionHandler::HandleConfigurationFailure
,
518 // Otherwise, we probably still need to configure the network since
519 // 'Connectable' is false. If |check_error_state| is true, signal an
520 // error, otherwise attempt to connect to possibly gain additional error
521 // state from Shill (or in case 'Connectable' is improperly unset).
522 if (check_error_state
)
523 ErrorCallbackForPendingRequest(service_path
, kErrorConfigurationRequired
);
525 CallShillConnect(service_path
);
528 void NetworkConnectionHandler::CallShillConnect(
529 const std::string
& service_path
) {
530 NET_LOG_EVENT("Sending Connect Request to Shill", service_path
);
531 DBusThreadManager::Get()->GetShillServiceClient()->Connect(
532 dbus::ObjectPath(service_path
),
533 base::Bind(&NetworkConnectionHandler::HandleShillConnectSuccess
,
534 AsWeakPtr(), service_path
),
535 base::Bind(&NetworkConnectionHandler::HandleShillConnectFailure
,
536 AsWeakPtr(), service_path
));
539 void NetworkConnectionHandler::HandleConfigurationFailure(
540 const std::string
& service_path
,
541 const std::string
& error_name
,
542 scoped_ptr
<base::DictionaryValue
> error_data
) {
543 ConnectRequest
* request
= GetPendingRequest(service_path
);
545 NET_LOG_ERROR("HandleConfigurationFailure called with no pending request.",
549 network_handler::ErrorCallback error_callback
= request
->error_callback
;
550 pending_requests_
.erase(service_path
);
551 if (!error_callback
.is_null())
552 error_callback
.Run(kErrorConfigureFailed
, error_data
.Pass());
555 void NetworkConnectionHandler::HandleShillConnectSuccess(
556 const std::string
& service_path
) {
557 ConnectRequest
* request
= GetPendingRequest(service_path
);
559 NET_LOG_ERROR("HandleShillConnectSuccess called with no pending request.",
563 request
->connect_state
= ConnectRequest::CONNECT_STARTED
;
564 NET_LOG_EVENT("Connect Request Acknowledged", service_path
);
565 // Do not call success_callback here, wait for one of the following
567 // * State transitions to a non connecting state indicating succes or failure
568 // * Network is no longer in the visible list, indicating failure
569 CheckPendingRequest(service_path
);
572 void NetworkConnectionHandler::HandleShillConnectFailure(
573 const std::string
& service_path
,
574 const std::string
& dbus_error_name
,
575 const std::string
& dbus_error_message
) {
576 ConnectRequest
* request
= GetPendingRequest(service_path
);
578 NET_LOG_ERROR("HandleShillConnectFailure called with no pending request.",
582 network_handler::ErrorCallback error_callback
= request
->error_callback
;
583 pending_requests_
.erase(service_path
);
584 network_handler::ShillErrorCallbackFunction(
585 shill::kErrorConnectFailed
, service_path
, error_callback
,
586 dbus_error_name
, dbus_error_message
);
589 void NetworkConnectionHandler::CheckPendingRequest(
590 const std::string service_path
) {
591 ConnectRequest
* request
= GetPendingRequest(service_path
);
593 if (request
->connect_state
== ConnectRequest::CONNECT_REQUESTED
)
594 return; // Request has not started, ignore update
595 const NetworkState
* network
=
596 network_state_handler_
->GetNetworkState(service_path
);
598 return; // NetworkState may not be be updated yet.
600 if (network
->IsConnectingState()) {
601 request
->connect_state
= ConnectRequest::CONNECT_CONNECTING
;
604 if (network
->IsConnectedState()) {
605 NET_LOG_EVENT("Connect Request Succeeded", service_path
);
606 if (!request
->profile_path
.empty()) {
607 // If a profile path was specified, set it on a successful connection.
608 network_configuration_handler_
->SetNetworkProfile(
609 service_path
, request
->profile_path
,
610 base::Bind(&base::DoNothing
),
611 chromeos::network_handler::ErrorCallback());
613 if (!request
->success_callback
.is_null())
614 request
->success_callback
.Run();
615 pending_requests_
.erase(service_path
);
618 if (network
->connection_state() == shill::kStateIdle
&&
619 request
->connect_state
!= ConnectRequest::CONNECT_CONNECTING
) {
620 // Connection hasn't started yet, keep waiting.
624 // Network is neither connecting or connected; an error occurred.
625 std::string error_name
; // 'Canceled' or 'Failed'
626 // If network->error() is empty here, we will look it up later, but we
627 // need to preserve it in case Shill clears it before then. crbug.com/302020.
628 std::string shill_error
= network
->error();
629 if (network
->connection_state() == shill::kStateIdle
&&
630 pending_requests_
.size() > 1) {
631 // Another connect request canceled this one.
632 error_name
= kErrorConnectCanceled
;
634 error_name
= shill::kErrorConnectFailed
;
635 if (network
->connection_state() != shill::kStateFailure
) {
636 NET_LOG_ERROR("Unexpected State: " + network
->connection_state(),
640 std::string error_msg
= error_name
;
641 if (!shill_error
.empty())
642 error_msg
+= ": " + shill_error
;
643 NET_LOG_ERROR(error_msg
, service_path
);
645 network_handler::ErrorCallback error_callback
= request
->error_callback
;
646 pending_requests_
.erase(service_path
);
647 if (error_callback
.is_null())
649 network_handler::RunErrorCallback(
650 error_callback
, service_path
, error_name
, shill_error
);
653 void NetworkConnectionHandler::CheckAllPendingRequests() {
654 for (std::map
<std::string
, ConnectRequest
>::iterator iter
=
655 pending_requests_
.begin(); iter
!= pending_requests_
.end(); ++iter
) {
656 CheckPendingRequest(iter
->first
);
660 std::string
NetworkConnectionHandler::CertificateIsConfigured(
661 NetworkUIData
* ui_data
) {
662 if (ui_data
->certificate_pattern().Empty())
663 return std::string();
664 // Find the matching certificate.
665 scoped_refptr
<net::X509Certificate
> matching_cert
=
666 client_cert::GetCertificateMatch(ui_data
->certificate_pattern(),
667 cert_loader_
->cert_list());
668 if (!matching_cert
.get())
669 return std::string();
670 return CertLoader::GetPkcs11IdForCert(*matching_cert
.get());
673 void NetworkConnectionHandler::ErrorCallbackForPendingRequest(
674 const std::string
& service_path
,
675 const std::string
& error_name
) {
676 ConnectRequest
* request
= GetPendingRequest(service_path
);
678 NET_LOG_ERROR("ErrorCallbackForPendingRequest with no pending request.",
682 // Remove the entry before invoking the callback in case it triggers a retry.
683 network_handler::ErrorCallback error_callback
= request
->error_callback
;
684 pending_requests_
.erase(service_path
);
685 InvokeErrorCallback(service_path
, error_callback
, error_name
);
690 void NetworkConnectionHandler::CallShillDisconnect(
691 const std::string
& service_path
,
692 const base::Closure
& success_callback
,
693 const network_handler::ErrorCallback
& error_callback
) {
694 NET_LOG_USER("Disconnect Request", service_path
);
695 DBusThreadManager::Get()->GetShillServiceClient()->Disconnect(
696 dbus::ObjectPath(service_path
),
697 base::Bind(&NetworkConnectionHandler::HandleShillDisconnectSuccess
,
698 AsWeakPtr(), service_path
, success_callback
),
699 base::Bind(&network_handler::ShillErrorCallbackFunction
,
700 kErrorShillError
, service_path
, error_callback
));
703 void NetworkConnectionHandler::HandleShillDisconnectSuccess(
704 const std::string
& service_path
,
705 const base::Closure
& success_callback
) {
706 NET_LOG_EVENT("Disconnect Request Sent", service_path
);
707 if (!success_callback
.is_null())
708 success_callback
.Run();
711 } // namespace chromeos