| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/network_connection_handler.h" | 5 #include "chromeos/network/network_connection_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "chromeos/chromeos_switches.h" | 10 #include "chromeos/chromeos_switches.h" |
| 11 #include "chromeos/dbus/dbus_thread_manager.h" | 11 #include "chromeos/dbus/dbus_thread_manager.h" |
| 12 #include "chromeos/dbus/shill_manager_client.h" | 12 #include "chromeos/dbus/shill_manager_client.h" |
| 13 #include "chromeos/dbus/shill_service_client.h" | 13 #include "chromeos/dbus/shill_service_client.h" |
| 14 #include "chromeos/network/certificate_pattern_matcher.h" | 14 #include "chromeos/network/client_cert_util.h" |
| 15 #include "chromeos/network/managed_network_configuration_handler.h" | 15 #include "chromeos/network/managed_network_configuration_handler.h" |
| 16 #include "chromeos/network/network_configuration_handler.h" | 16 #include "chromeos/network/network_configuration_handler.h" |
| 17 #include "chromeos/network/network_event_log.h" | 17 #include "chromeos/network/network_event_log.h" |
| 18 #include "chromeos/network/network_handler_callbacks.h" | 18 #include "chromeos/network/network_handler_callbacks.h" |
| 19 #include "chromeos/network/network_state.h" | 19 #include "chromeos/network/network_state.h" |
| 20 #include "chromeos/network/network_state_handler.h" | 20 #include "chromeos/network/network_state_handler.h" |
| 21 #include "chromeos/network/network_ui_data.h" | 21 #include "chromeos/network/network_ui_data.h" |
| 22 #include "dbus/object_path.h" | 22 #include "dbus/object_path.h" |
| 23 #include "net/cert/x509_certificate.h" | 23 #include "net/cert/x509_certificate.h" |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | 24 #include "third_party/cros_system_api/dbus/service_constants.h" |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } | 394 } |
| 395 // VPN requires a host and username to be set. | 395 // VPN requires a host and username to be set. |
| 396 if (!VPNIsConfigured( | 396 if (!VPNIsConfigured( |
| 397 service_path, vpn_provider_type, *provider_properties)) { | 397 service_path, vpn_provider_type, *provider_properties)) { |
| 398 NET_LOG_ERROR("VPN Not Configured", service_path); | 398 NET_LOG_ERROR("VPN Not Configured", service_path); |
| 399 ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); | 399 ErrorCallbackForPendingRequest(service_path, kErrorConfigurationRequired); |
| 400 return; | 400 return; |
| 401 } | 401 } |
| 402 } | 402 } |
| 403 | 403 |
| 404 // These will be set if they need to be configured, otherwise they will | 404 client_cert::ConfigType client_cert_type = client_cert::CONFIG_TYPE_NONE; |
| 405 // be left empty and the properties will not be set. | 405 if (type == flimflam::kTypeVPN) { |
| 406 std::string pkcs11_id, tpm_slot, tpm_pin; | 406 if (vpn_provider_type == flimflam::kProviderOpenVpn) |
| 407 client_cert_type = client_cert::CONFIG_TYPE_OPENVPN; |
| 408 else |
| 409 client_cert_type = client_cert::CONFIG_TYPE_IPSEC; |
| 410 } else if (type == flimflam::kTypeWifi) { |
| 411 client_cert_type = client_cert::CONFIG_TYPE_EAP; |
| 412 } |
| 407 | 413 |
| 408 // Check certificate properties in kUIDataProperty if configured. | 414 base::DictionaryValue config_properties; |
| 409 // Note: Wifi/VPNConfigView set these properties explicitly. | 415 if (client_cert_type != client_cert::CONFIG_TYPE_NONE) { |
| 410 scoped_ptr<NetworkUIData> ui_data = | 416 // If the client certificate must be configured, this will be set to a |
| 411 ManagedNetworkConfigurationHandler::GetUIData(service_properties); | 417 // non-empty string. |
| 412 if (ui_data && ui_data->certificate_type() == CLIENT_CERT_TYPE_PATTERN) { | 418 std::string pkcs11_id; |
| 413 // User must be logged in to connect to a network requiring a certificate. | 419 |
| 414 if (!logged_in_ || !cert_loader_) { | 420 // Check certificate properties in kUIDataProperty if configured. |
| 415 ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); | 421 // Note: Wifi/VPNConfigView set these properties explicitly, in which case |
| 416 return; | 422 // only the TPM must be configured. |
| 423 scoped_ptr<NetworkUIData> ui_data = |
| 424 ManagedNetworkConfigurationHandler::GetUIData(service_properties); |
| 425 if (ui_data && ui_data->certificate_type() == CLIENT_CERT_TYPE_PATTERN) { |
| 426 // User must be logged in to connect to a network requiring a certificate. |
| 427 if (!logged_in_ || !cert_loader_) { |
| 428 ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); |
| 429 return; |
| 430 } |
| 431 |
| 432 // If certificates have not been loaded yet, queue the connect request. |
| 433 if (!certificates_loaded_) { |
| 434 ConnectRequest* request = pending_request(service_path); |
| 435 DCHECK(request); |
| 436 NET_LOG_EVENT("Connect Request Queued", service_path); |
| 437 queued_connect_.reset(new ConnectRequest( |
| 438 service_path, request->success_callback, request->error_callback)); |
| 439 pending_requests_.erase(service_path); |
| 440 return; |
| 441 } |
| 442 |
| 443 pkcs11_id = CertificateIsConfigured(ui_data.get()); |
| 444 // Ensure the certificate is available and configured. |
| 445 if (!cert_loader_->IsHardwareBacked() || pkcs11_id.empty()) { |
| 446 ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); |
| 447 return; |
| 448 } |
| 417 } | 449 } |
| 418 | 450 |
| 419 // If certificates have not been loaded yet, queue the connect request. | 451 // The network may not be 'Connectable' because the TPM properties are not |
| 420 if (!certificates_loaded_) { | 452 // set up, so configure tpm slot/pin before connecting. |
| 421 ConnectRequest* request = pending_request(service_path); | 453 if (cert_loader_ && cert_loader_->IsHardwareBacked()) { |
| 422 DCHECK(request); | 454 // Pass NULL if pkcs11_id is empty, so that it doesn't clear any |
| 423 NET_LOG_EVENT("Connect Request Queued", service_path); | 455 // previously configured client cert. |
| 424 queued_connect_.reset(new ConnectRequest( | 456 client_cert::SetShillProperties(client_cert_type, |
| 425 service_path, request->success_callback, request->error_callback)); | 457 cert_loader_->tpm_token_slot(), |
| 426 pending_requests_.erase(service_path); | 458 cert_loader_->tpm_user_pin(), |
| 427 return; | 459 pkcs11_id.empty() ? NULL : &pkcs11_id, |
| 428 } | 460 &config_properties); |
| 429 | |
| 430 // Ensure the certificate is available and configured. | |
| 431 if (!CertificateIsConfigured(ui_data.get(), &pkcs11_id)) { | |
| 432 ErrorCallbackForPendingRequest(service_path, kErrorCertificateRequired); | |
| 433 return; | |
| 434 } | 461 } |
| 435 } | 462 } |
| 436 | 463 |
| 437 // The network may not be 'Connectable' because the TPM properties are | |
| 438 // not set up, so configure tpm slot/pin before connecting. | |
| 439 if (cert_loader_) { | |
| 440 tpm_slot = cert_loader_->tpm_token_slot(); | |
| 441 tpm_pin = cert_loader_->tpm_user_pin(); | |
| 442 } | |
| 443 | |
| 444 base::DictionaryValue config_properties; | |
| 445 | |
| 446 if (type == flimflam::kTypeVPN) { | |
| 447 if (vpn_provider_type == flimflam::kProviderOpenVpn) { | |
| 448 if (!pkcs11_id.empty()) { | |
| 449 config_properties.SetStringWithoutPathExpansion( | |
| 450 flimflam::kOpenVPNClientCertIdProperty, pkcs11_id); | |
| 451 } | |
| 452 if (!tpm_pin.empty()) { | |
| 453 config_properties.SetStringWithoutPathExpansion( | |
| 454 flimflam::kOpenVPNPinProperty, tpm_pin); | |
| 455 } | |
| 456 } else { | |
| 457 if (!pkcs11_id.empty()) { | |
| 458 config_properties.SetStringWithoutPathExpansion( | |
| 459 flimflam::kL2tpIpsecClientCertIdProperty, pkcs11_id); | |
| 460 } | |
| 461 if (!tpm_slot.empty()) { | |
| 462 config_properties.SetStringWithoutPathExpansion( | |
| 463 flimflam::kL2tpIpsecClientCertSlotProperty, tpm_slot); | |
| 464 } | |
| 465 if (!tpm_pin.empty()) { | |
| 466 config_properties.SetStringWithoutPathExpansion( | |
| 467 flimflam::kL2tpIpsecPinProperty, tpm_pin); | |
| 468 } | |
| 469 } | |
| 470 } else if (type == flimflam::kTypeWifi) { | |
| 471 if (!pkcs11_id.empty()) { | |
| 472 config_properties.SetStringWithoutPathExpansion( | |
| 473 flimflam::kEapCertIdProperty, pkcs11_id); | |
| 474 config_properties.SetStringWithoutPathExpansion( | |
| 475 flimflam::kEapKeyIdProperty, pkcs11_id); | |
| 476 } | |
| 477 if (!tpm_pin.empty()) { | |
| 478 config_properties.SetStringWithoutPathExpansion( | |
| 479 flimflam::kEapPinProperty, tpm_pin); | |
| 480 } | |
| 481 } | |
| 482 | |
| 483 if (!config_properties.empty()) { | 464 if (!config_properties.empty()) { |
| 484 NET_LOG_EVENT("Configuring Network", service_path); | 465 NET_LOG_EVENT("Configuring Network", service_path); |
| 485 | 466 |
| 486 // Set configuration properties required by Shill to identify the network. | 467 // Set configuration properties required by Shill to identify the network. |
| 487 config_properties.SetStringWithoutPathExpansion( | 468 config_properties.SetStringWithoutPathExpansion( |
| 488 flimflam::kTypeProperty, type); | 469 flimflam::kTypeProperty, type); |
| 489 CopyStringFromDictionary(service_properties, flimflam::kNameProperty, | 470 CopyStringFromDictionary(service_properties, flimflam::kNameProperty, |
| 490 &config_properties); | 471 &config_properties); |
| 491 CopyStringFromDictionary(service_properties, flimflam::kGuidProperty, | 472 CopyStringFromDictionary(service_properties, flimflam::kGuidProperty, |
| 492 &config_properties); | 473 &config_properties); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 error_callback.Run(error_name, error_data.Pass()); | 600 error_callback.Run(error_name, error_data.Pass()); |
| 620 } | 601 } |
| 621 | 602 |
| 622 void NetworkConnectionHandler::CheckAllPendingRequests() { | 603 void NetworkConnectionHandler::CheckAllPendingRequests() { |
| 623 for (std::map<std::string, ConnectRequest>::iterator iter = | 604 for (std::map<std::string, ConnectRequest>::iterator iter = |
| 624 pending_requests_.begin(); iter != pending_requests_.end(); ++iter) { | 605 pending_requests_.begin(); iter != pending_requests_.end(); ++iter) { |
| 625 CheckPendingRequest(iter->first); | 606 CheckPendingRequest(iter->first); |
| 626 } | 607 } |
| 627 } | 608 } |
| 628 | 609 |
| 629 bool NetworkConnectionHandler::CertificateIsConfigured(NetworkUIData* ui_data, | 610 std::string NetworkConnectionHandler::CertificateIsConfigured( |
| 630 std::string* pkcs11_id) { | 611 NetworkUIData* ui_data) { |
| 631 if (ui_data->certificate_pattern().Empty()) | 612 if (ui_data->certificate_pattern().Empty()) |
| 632 return false; | 613 return std::string(); |
| 633 | |
| 634 // Find the matching certificate. | 614 // Find the matching certificate. |
| 635 scoped_refptr<net::X509Certificate> matching_cert = | 615 scoped_refptr<net::X509Certificate> matching_cert = |
| 636 certificate_pattern::GetCertificateMatch(ui_data->certificate_pattern()); | 616 client_cert::GetCertificateMatch(ui_data->certificate_pattern()); |
| 637 if (!matching_cert.get()) | 617 if (!matching_cert.get()) |
| 638 return false; | 618 return std::string(); |
| 639 *pkcs11_id = cert_loader_->GetPkcs11IdForCert(*matching_cert.get()); | 619 return CertLoader::GetPkcs11IdForCert(*matching_cert.get()); |
| 640 return true; | |
| 641 } | 620 } |
| 642 | 621 |
| 643 void NetworkConnectionHandler::ErrorCallbackForPendingRequest( | 622 void NetworkConnectionHandler::ErrorCallbackForPendingRequest( |
| 644 const std::string& service_path, | 623 const std::string& service_path, |
| 645 const std::string& error_name) { | 624 const std::string& error_name) { |
| 646 ConnectRequest* request = pending_request(service_path); | 625 ConnectRequest* request = pending_request(service_path); |
| 647 DCHECK(request); | 626 DCHECK(request); |
| 648 // Remove the entry before invoking the callback in case it triggers a retry. | 627 // Remove the entry before invoking the callback in case it triggers a retry. |
| 649 network_handler::ErrorCallback error_callback = request->error_callback; | 628 network_handler::ErrorCallback error_callback = request->error_callback; |
| 650 pending_requests_.erase(service_path); | 629 pending_requests_.erase(service_path); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 672 |
| 694 void NetworkConnectionHandler::HandleShillActivateSuccess( | 673 void NetworkConnectionHandler::HandleShillActivateSuccess( |
| 695 const std::string& service_path, | 674 const std::string& service_path, |
| 696 const base::Closure& success_callback) { | 675 const base::Closure& success_callback) { |
| 697 NET_LOG_EVENT("Activate Request Sent", service_path); | 676 NET_LOG_EVENT("Activate Request Sent", service_path); |
| 698 if (!success_callback.is_null()) | 677 if (!success_callback.is_null()) |
| 699 success_callback.Run(); | 678 success_callback.Run(); |
| 700 } | 679 } |
| 701 | 680 |
| 702 } // namespace chromeos | 681 } // namespace chromeos |
| OLD | NEW |