diff options
-rw-r--r-- | chrome/browser/chromeos/cros/mock_network_library.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.cc | 30 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.h | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/vpn_config_view.cc | 119 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/vpn_config_view.h | 3 |
5 files changed, 140 insertions, 18 deletions
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h index 5922bd5..a71dfc9 100644 --- a/chrome/browser/chromeos/cros/mock_network_library.h +++ b/chrome/browser/chromeos/cros/mock_network_library.h @@ -114,7 +114,8 @@ class MockNetworkLibrary : public NetworkLibrary { const std::string&, const std::string&, const std::string&)); - MOCK_METHOD5(ConnectToVirtualNetworkCert, void(const std::string&, + MOCK_METHOD6(ConnectToVirtualNetworkCert, void(const std::string&, + const std::string&, const std::string&, const std::string&, const std::string&, diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 4988813..fb57f3a 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -2994,10 +2994,10 @@ class NetworkLibraryImpl : public NetworkLibrary { connect_data_.service_name = ssid; connect_data_.eap_method = eap_method; connect_data_.eap_auth = eap_auth; - connect_data_.eap_server_ca_cert_nss_nickname = + connect_data_.server_ca_cert_nss_nickname = eap_server_ca_cert_nss_nickname; connect_data_.eap_use_system_cas = eap_use_system_cas; - connect_data_.eap_client_cert_pkcs11_id = eap_client_cert_pkcs11_id; + connect_data_.client_cert_pkcs11_id = eap_client_cert_pkcs11_id; connect_data_.eap_identity = eap_identity; connect_data_.eap_anonymous_identity = eap_anonymous_identity; connect_data_.passphrase = passphrase; @@ -3037,9 +3037,9 @@ class NetworkLibraryImpl : public NetworkLibrary { // Enterprise 802.1X EAP network. wifi->SetEAPMethod(data.eap_method); wifi->SetEAPPhase2Auth(data.eap_auth); - wifi->SetEAPServerCaCertNssNickname(data.eap_server_ca_cert_nss_nickname); + wifi->SetEAPServerCaCertNssNickname(data.server_ca_cert_nss_nickname); wifi->SetEAPUseSystemCAs(data.eap_use_system_cas); - wifi->SetEAPClientCertPkcs11Id(data.eap_client_cert_pkcs11_id); + wifi->SetEAPClientCertPkcs11Id(data.client_cert_pkcs11_id); wifi->SetEAPIdentity(data.eap_identity); wifi->SetEAPAnonymousIdentity(data.eap_anonymous_identity); wifi->SetEAPPassphrase(data.passphrase); @@ -3099,7 +3099,8 @@ class NetworkLibraryImpl : public NetworkLibrary { virtual void ConnectToVirtualNetworkCert( const std::string& service_name, const std::string& server_hostname, - const std::string& client_cert_id, + const std::string& server_ca_cert_nss_nickname, + const std::string& client_cert_pkcs11_id, const std::string& username, const std::string& user_passphrase) { if (!EnsureCrosLoaded()) @@ -3107,7 +3108,8 @@ class NetworkLibraryImpl : public NetworkLibrary { // Store the connection data to be used by the callback. connect_data_.service_name = service_name; connect_data_.server_hostname = server_hostname; - connect_data_.vpn_client_cert_pkcs11_id = client_cert_id; + connect_data_.server_ca_cert_nss_nickname = server_ca_cert_nss_nickname; + connect_data_.client_cert_pkcs11_id = client_cert_pkcs11_id; connect_data_.psk_username = username; connect_data_.passphrase = user_passphrase; RequestVirtualNetwork(service_name.c_str(), @@ -3148,8 +3150,8 @@ class NetworkLibraryImpl : public NetworkLibrary { vpn->set_added(true); if (!data.server_hostname.empty()) vpn->set_server_hostname(data.server_hostname); - vpn->SetCACertNSS(""); - vpn->SetClientCertID(data.vpn_client_cert_pkcs11_id); + vpn->SetCACertNSS(data.server_ca_cert_nss_nickname); + vpn->SetClientCertID(data.client_cert_pkcs11_id); vpn->SetPSKPassphrase(data.psk_key); vpn->SetUsername(data.psk_username); vpn->SetUserPassphrase(data.passphrase); @@ -4877,18 +4879,17 @@ class NetworkLibraryImpl : public NetworkLibrary { ConnectionSecurity security; std::string service_name; // For example, SSID. std::string passphrase; + std::string server_hostname; + std::string server_ca_cert_nss_nickname; + std::string client_cert_pkcs11_id; EAPMethod eap_method; EAPPhase2Auth eap_auth; - std::string eap_server_ca_cert_nss_nickname; bool eap_use_system_cas; - std::string eap_client_cert_pkcs11_id; std::string eap_identity; std::string eap_anonymous_identity; - bool save_credentials; std::string psk_key; std::string psk_username; - std::string server_hostname; - std::string vpn_client_cert_pkcs11_id; + bool save_credentials; }; ConnectData connect_data_; @@ -5041,7 +5042,8 @@ class NetworkLibraryStubImpl : public NetworkLibrary { virtual void ConnectToVirtualNetworkCert( const std::string& service_name, const std::string& server_hostname, - const std::string& client_cert_id, + const std::string& server_ca_cert_nss_nickname, + const std::string& client_cert_pkcs11_id, const std::string& username, const std::string& user_passphrase) {} virtual void SignalCellularPlanPayment() {} diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index 76d1a35..6e484f9 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -1164,7 +1164,8 @@ class NetworkLibrary { virtual void ConnectToVirtualNetworkCert( const std::string& service_name, const std::string& server_hostname, - const std::string& client_cert_id, + const std::string& server_ca_cert_nss_nickname, + const std::string& client_cert_pkcs11_id, const std::string& username, const std::string& user_passphrase) = 0; diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc index c89e83e..77faee5 100644 --- a/chrome/browser/chromeos/options/vpn_config_view.cc +++ b/chrome/browser/chromeos/options/vpn_config_view.cc @@ -26,6 +26,9 @@ namespace { +// Root CA certificates that are built into Chrome use this token name. +const char* const kRootCertificateTokenName = "Builtin Object Token"; + string16 ProviderTypeToString(chromeos::VirtualNetwork::ProviderType type) { switch (type) { case chromeos::VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK: @@ -66,6 +69,66 @@ class ProviderTypeComboboxModel : public ui::ComboboxModel { DISALLOW_COPY_AND_ASSIGN(ProviderTypeComboboxModel); }; +// TODO(stevenjb): Integrate with changes from chromium-os:15829. +class ServerCACertComboboxModel : public ui::ComboboxModel { + public: + ServerCACertComboboxModel() { + net::CertDatabase cert_db; + net::CertificateList cert_list; + cert_db.ListCerts(&cert_list); + // Find all the CA certificates. + for (net::CertificateList::const_iterator it = cert_list.begin(); + it != cert_list.end(); ++it) { + net::X509Certificate* cert = it->get(); + net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); + net::CertType type = x509_certificate_model::GetType(cert_handle); + if (type == net::CA_CERT) { + // Exclude root CA certificates that are built into Chrome. + std::string token_name = + x509_certificate_model::GetTokenName(cert_handle); + if (token_name != kRootCertificateTokenName) + ca_certs_.push_back(*it); + } + } + } + virtual ~ServerCACertComboboxModel() {} + + virtual int GetItemCount() { + return static_cast<int>(ca_certs_.size() + 1); // "Default" + certs + } + + virtual string16 GetItemAt(int index) { + if (index == 0) + return l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT); + int cert_index = index - 1; + if (cert_index >= 0 && cert_index < static_cast<int>(ca_certs_.size())) { + net::X509Certificate* cert = ca_certs_[cert_index].get(); + std::string name = + x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle()); + return UTF8ToUTF16(name); + } + return string16(); + } + + int GetCertCount() { + return static_cast<int>(ca_certs_.size()); + } + + std::string GetCertNssNickname(int cert_index) { + if (0 <= cert_index && cert_index < static_cast<int>(ca_certs_.size())) { + net::X509Certificate* cert = ca_certs_[cert_index].get(); + return x509_certificate_model::GetNickname(cert->os_cert_handle()); + } + return std::string(); + } + + private: + net::CertificateList ca_certs_; + DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel); +}; + +// TODO(stevenjb): Integrate with changes from chromium-os:15829. class UserCertComboboxModel : public ui::ComboboxModel { public: UserCertComboboxModel() { @@ -236,6 +299,8 @@ void VPNConfigView::ItemChanged(views::Combobox* combo_box, UpdateErrorLabel(); } else if (combo_box == user_cert_combobox_) { // Nothing to do for now. + } else if (combo_box == server_ca_cert_combobox_) { + // Nothing to do for now. } else { NOTREACHED(); } @@ -256,6 +321,7 @@ bool VPNConfigView::Login() { case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: { cros->ConnectToVirtualNetworkCert(GetService(), GetServer(), + GetServerCACertNssNickname(), GetUserCertID(), GetUsername(), GetUserPassphrase()); @@ -315,6 +381,8 @@ void VPNConfigView::InitFocus() { psk_passphrase_textfield_->RequestFocus(); else if (user_cert_combobox_ && user_cert_combobox_->IsEnabled()) user_cert_combobox_->RequestFocus(); + else if (server_ca_cert_combobox_ && server_ca_cert_combobox_->IsEnabled()) + server_ca_cert_combobox_->RequestFocus(); } const std::string VPNConfigView::GetTextFromField( @@ -354,6 +422,19 @@ const std::string VPNConfigView::GetUserPassphrase() const { return GetTextFromField(user_passphrase_textfield_, false); } +const std::string VPNConfigView::GetServerCACertNssNickname() const { + int selected = server_ca_cert_combobox_->selected_item(); + if (selected == 0) { + // First item is "Default". + return std::string(); + } else { + int cert_index = selected - 1; + ServerCACertComboboxModel* model = static_cast<ServerCACertComboboxModel*>( + server_ca_cert_combobox_->model()); + return model->GetCertNssNickname(cert_index); + } +} + const std::string VPNConfigView::GetUserCertID() const { int selected = user_cert_combobox_->selected_item(); UserCertComboboxModel* model = static_cast<UserCertComboboxModel*>( @@ -453,6 +534,29 @@ void VPNConfigView::Init(VirtualNetwork* vpn) { layout->AddView(psk_passphrase_textfield_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + // Server CA certificate + layout->StartRow(0, column_view_set_id); + server_ca_cert_label_ = + new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA))); + layout->AddView(server_ca_cert_label_); + ServerCACertComboboxModel* server_ca_cert_model = + new ServerCACertComboboxModel(); + server_ca_cert_combobox_ = new views::Combobox(server_ca_cert_model); + if (vpn && !vpn->ca_cert_nss().empty()) { + // Select the current server CA certificate in the combobox. + for (int i = 0; i < server_ca_cert_model->GetCertCount(); ++i) { + std::string cert_name = server_ca_cert_model->GetCertNssNickname(i); + if (cert_name == vpn->ca_cert_nss()) { + int item_index = i + 1; // First item is "Default" + server_ca_cert_combobox_->SetSelectedItem(item_index); + break; + } + } + } + layout->AddView(server_ca_cert_combobox_); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + // User certificate label and input. layout->StartRow(0, column_view_set_id); user_cert_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( @@ -518,18 +622,29 @@ void VPNConfigView::EnableControls() { case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK: psk_passphrase_label_->SetEnabled(true); psk_passphrase_textfield_->SetEnabled(true); + server_ca_cert_label_->SetEnabled(false); + server_ca_cert_combobox_->SetEnabled(false); user_cert_label_->SetEnabled(false); user_cert_combobox_->SetEnabled(false); break; case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: - case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN: { psk_passphrase_label_->SetEnabled(false); psk_passphrase_textfield_->SetEnabled(false); + server_ca_cert_label_->SetEnabled(true); + server_ca_cert_combobox_->SetEnabled(true); + user_cert_label_->SetEnabled(true); + // Only enable the combobox if the user actually has a cert to select. + user_cert_combobox_->SetEnabled(HaveUserCerts()); + break; + case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN: + psk_passphrase_label_->SetEnabled(false); + psk_passphrase_textfield_->SetEnabled(false); + server_ca_cert_label_->SetEnabled(false); + server_ca_cert_combobox_->SetEnabled(false); user_cert_label_->SetEnabled(true); // Only enable the combobox if the user actually has a cert to select. user_cert_combobox_->SetEnabled(HaveUserCerts()); break; - } default: NOTREACHED(); break; diff --git a/chrome/browser/chromeos/options/vpn_config_view.h b/chrome/browser/chromeos/options/vpn_config_view.h index 6a0c828..a2c6c5c 100644 --- a/chrome/browser/chromeos/options/vpn_config_view.h +++ b/chrome/browser/chromeos/options/vpn_config_view.h @@ -81,6 +81,7 @@ class VPNConfigView : public ChildNetworkConfigView, const std::string GetPSKPassphrase() const; const std::string GetUsername() const; const std::string GetUserPassphrase() const; + const std::string GetServerCACertNssNickname() const; const std::string GetUserCertID() const; std::string server_hostname_; @@ -98,6 +99,8 @@ class VPNConfigView : public ChildNetworkConfigView, views::Textfield* psk_passphrase_textfield_; views::Label* user_cert_label_; views::Combobox* user_cert_combobox_; + views::Label* server_ca_cert_label_; + views::Combobox* server_ca_cert_combobox_; views::Textfield* username_textfield_; views::Textfield* user_passphrase_textfield_; views::Label* error_label_; |