diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 22:31:51 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 22:31:51 +0000 |
commit | 388e4d376be45063c5ba65b4d089f245665b7917 (patch) | |
tree | 70b32b48a0f7b4a9a9dd20d44f79bfa3b72732c0 /chrome/browser/chromeos | |
parent | ccc66057ce11a5217c730cee82900bc21644a6fd (diff) | |
download | chromium_src-388e4d376be45063c5ba65b4d089f245665b7917.zip chromium_src-388e4d376be45063c5ba65b4d089f245665b7917.tar.gz chromium_src-388e4d376be45063c5ba65b4d089f245665b7917.tar.bz2 |
Join Wi-Fi network dialog lists user and server-CA certificates.
- Fixed width of server CA combobox, as it can be very wide.
- Introduced WifiConfigModel to hold cert info for WifiConfigView.
- Send user cert to flimflam by PKCS#11 ID
- Send server CA cert to flimflam by nickname
BUG=chromium-os:11412
TEST=Make successful connection to 802.1x network.
Review URL: http://codereview.chromium.org/6693083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81498 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos')
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.cc | 54 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.h | 15 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/network_config_view.cc | 5 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/wifi_config_model.cc | 172 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/wifi_config_model.h | 70 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/wifi_config_view.cc | 138 | ||||
-rw-r--r-- | chrome/browser/chromeos/options/wifi_config_view.h | 4 |
7 files changed, 377 insertions, 81 deletions
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 65d6df1..f42aee6 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -162,17 +162,20 @@ const char* kSecurity8021x = "802_1x"; const char* kSecurityNone = "none"; // Flimflam EAP property names. +// See src/third_party/flimflam/doc/service-api.txt. const char* kEapIdentityProperty = "EAP.Identity"; const char* kEapMethodProperty = "EAP.EAP"; const char* kEapPhase2AuthProperty = "EAP.InnerEAP"; const char* kEapAnonymousIdentityProperty = "EAP.AnonymousIdentity"; -const char* kEapClientCertProperty = "EAP.ClientCert"; -const char* kEapCertIDProperty = "EAP.CertID"; +const char* kEapClientCertProperty = "EAP.ClientCert"; // path +const char* kEapCertIDProperty = "EAP.CertID"; // PKCS#11 ID +const char* kEapClientCertNssProperty = "EAP.ClientCertNSS"; // NSS nickname const char* kEapPrivateKeyProperty = "EAP.PrivateKey"; const char* kEapPrivateKeyPasswordProperty = "EAP.PrivateKeyPassword"; const char* kEapKeyIDProperty = "EAP.KeyID"; -const char* kEapCACertProperty = "EAP.CACert"; -const char* kEapCACertIDProperty = "EAP.CACertID"; +const char* kEapCaCertProperty = "EAP.CACert"; // server CA cert path +const char* kEapCaCertIDProperty = "EAP.CACertID"; // server CA PKCS#11 ID +const char* kEapCaCertNssProperty = "EAP.CACertNSS"; // server CA NSS nickname const char* kEapUseSystemCAsProperty = "EAP.UseSystemCAs"; const char* kEapPinProperty = "EAP.PIN"; const char* kEapPasswordProperty = "EAP.Password"; @@ -346,11 +349,13 @@ enum PropertyIndex { PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY, PROPERTY_INDEX_EAP_CLIENT_CERT, PROPERTY_INDEX_EAP_CERT_ID, + PROPERTY_INDEX_EAP_CLIENT_CERT_NSS, PROPERTY_INDEX_EAP_PRIVATE_KEY, PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD, PROPERTY_INDEX_EAP_KEY_ID, PROPERTY_INDEX_EAP_CA_CERT, PROPERTY_INDEX_EAP_CA_CERT_ID, + PROPERTY_INDEX_EAP_CA_CERT_NSS, PROPERTY_INDEX_EAP_USE_SYSTEM_CAS, PROPERTY_INDEX_EAP_PIN, PROPERTY_INDEX_EAP_PASSWORD, @@ -416,11 +421,13 @@ StringToEnum<PropertyIndex>::Pair property_index_table[] = { { kEapAnonymousIdentityProperty, PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY }, { kEapClientCertProperty, PROPERTY_INDEX_EAP_CLIENT_CERT }, { kEapCertIDProperty, PROPERTY_INDEX_EAP_CERT_ID }, + { kEapClientCertNssProperty, PROPERTY_INDEX_EAP_CLIENT_CERT_NSS }, { kEapPrivateKeyProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY }, { kEapPrivateKeyPasswordProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD }, { kEapKeyIDProperty, PROPERTY_INDEX_EAP_KEY_ID }, - { kEapCACertProperty, PROPERTY_INDEX_EAP_CA_CERT }, - { kEapCACertIDProperty, PROPERTY_INDEX_EAP_CA_CERT_ID }, + { kEapCaCertProperty, PROPERTY_INDEX_EAP_CA_CERT }, + { kEapCaCertIDProperty, PROPERTY_INDEX_EAP_CA_CERT_ID }, + { kEapCaCertNssProperty, PROPERTY_INDEX_EAP_CA_CERT_NSS }, { kEapUseSystemCAsProperty, PROPERTY_INDEX_EAP_USE_SYSTEM_CAS }, { kEapPinProperty, PROPERTY_INDEX_EAP_PIN }, { kEapPasswordProperty, PROPERTY_INDEX_EAP_PASSWORD }, @@ -1393,6 +1400,8 @@ bool WifiNetwork::ParseValue(int index, const Value* value) { return value->GetAsString(&identity_); case PROPERTY_INDEX_CERT_PATH: return value->GetAsString(&cert_path_); + case PROPERTY_INDEX_EAP_IDENTITY: + return value->GetAsString(&eap_identity_); case PROPERTY_INDEX_EAP_METHOD: { std::string method; if (value->GetAsString(&method)) { @@ -1409,22 +1418,22 @@ bool WifiNetwork::ParseValue(int index, const Value* value) { } break; } - case PROPERTY_INDEX_EAP_IDENTITY: - return value->GetAsString(&eap_identity_); case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: return value->GetAsString(&eap_anonymous_identity_); - case PROPERTY_INDEX_EAP_CLIENT_CERT: - return value->GetAsString(&eap_client_cert_path_); - case PROPERTY_INDEX_EAP_CA_CERT: - return value->GetAsString(&eap_server_ca_cert_path_); - case PROPERTY_INDEX_EAP_PASSWORD: - return value->GetAsString(&eap_passphrase_); + case PROPERTY_INDEX_EAP_CERT_ID: + return value->GetAsString(&eap_client_cert_pkcs11_id_); + case PROPERTY_INDEX_EAP_CA_CERT_NSS: + return value->GetAsString(&eap_server_ca_cert_nss_nickname_); case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: return value->GetAsBoolean(&eap_use_system_cas_); - case PROPERTY_INDEX_EAP_CERT_ID: + case PROPERTY_INDEX_EAP_PASSWORD: + return value->GetAsString(&eap_passphrase_); + case PROPERTY_INDEX_EAP_CLIENT_CERT: + case PROPERTY_INDEX_EAP_CLIENT_CERT_NSS: case PROPERTY_INDEX_EAP_PRIVATE_KEY: case PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD: case PROPERTY_INDEX_EAP_KEY_ID: + case PROPERTY_INDEX_EAP_CA_CERT: case PROPERTY_INDEX_EAP_CA_CERT_ID: case PROPERTY_INDEX_EAP_PIN: case PROPERTY_INDEX_EAP_KEY_MGMT: @@ -1515,14 +1524,17 @@ void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) { } } -void WifiNetwork::SetEAPServerCACert(const std::string& cert_path) { - eap_server_ca_cert_path_ = cert_path; - SetOrClearStringProperty(kEapCACertProperty, cert_path); +void WifiNetwork::SetEAPServerCaCertNssNickname( + const std::string& nss_nickname) { + VLOG(1) << "SetEAPServerCaCertNssNickname " << nss_nickname; + eap_server_ca_cert_nss_nickname_ = nss_nickname; + SetOrClearStringProperty(kEapCaCertNssProperty, nss_nickname); } -void WifiNetwork::SetEAPClientCert(const std::string& cert_path) { - eap_client_cert_path_ = cert_path; - SetOrClearStringProperty(kEapClientCertProperty, cert_path); +void WifiNetwork::SetEAPClientCertPkcs11Id(const std::string& pkcs11_id) { + VLOG(1) << "SetEAPClientCertPkcs11Id " << pkcs11_id; + eap_client_cert_pkcs11_id_ = pkcs11_id; + SetOrClearStringProperty(kEapCertIDProperty, pkcs11_id); } void WifiNetwork::SetEAPUseSystemCAs(bool use_system_cas) { diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index 6420686..0029577 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -494,9 +494,10 @@ class WifiNetwork : public WirelessNetwork { EAPMethod eap_method() const { return eap_method_; } EAPPhase2Auth eap_phase_2_auth() const { return eap_phase_2_auth_; } - const std::string& eap_server_ca_cert() const { - return eap_server_ca_cert_path_; } - const std::string& eap_client_cert() const { return eap_client_cert_path_; } + const std::string& eap_server_ca_cert_nss_nickname() const { + return eap_server_ca_cert_nss_nickname_; } + const std::string& eap_client_cert_pkcs11_id() const { + return eap_client_cert_pkcs11_id_; } const bool eap_use_system_cas() const { return eap_use_system_cas_; } const std::string& eap_identity() const { return eap_identity_; } const std::string& eap_anonymous_identity() const { @@ -512,8 +513,8 @@ class WifiNetwork : public WirelessNetwork { // 802.1x properties void SetEAPMethod(EAPMethod method); void SetEAPPhase2Auth(EAPPhase2Auth auth); - void SetEAPServerCACert(const std::string& cert_path); - void SetEAPClientCert(const std::string& cert_path); + void SetEAPServerCaCertNssNickname(const std::string& nss_nickname); + void SetEAPClientCertPkcs11Id(const std::string& pkcs11_id); void SetEAPUseSystemCAs(bool use_system_cas); void SetEAPIdentity(const std::string& identity); void SetEAPAnonymousIdentity(const std::string& identity); @@ -558,8 +559,8 @@ class WifiNetwork : public WirelessNetwork { EAPMethod eap_method_; EAPPhase2Auth eap_phase_2_auth_; - std::string eap_server_ca_cert_path_; - std::string eap_client_cert_path_; + std::string eap_server_ca_cert_nss_nickname_; + std::string eap_client_cert_pkcs11_id_; bool eap_use_system_cas_; std::string eap_identity_; std::string eap_anonymous_identity_; diff --git a/chrome/browser/chromeos/options/network_config_view.cc b/chrome/browser/chromeos/options/network_config_view.cc index c858dce..30172e6 100644 --- a/chrome/browser/chromeos/options/network_config_view.cc +++ b/chrome/browser/chromeos/options/network_config_view.cc @@ -88,10 +88,9 @@ void NetworkConfigView::Layout() { } gfx::Size NetworkConfigView::GetPreferredSize() { - // TODO(chocobo): Once UI is finalized, create locale settings. gfx::Size result(views::Window::GetLocalizedContentsSize( - IDS_ABOUT_DIALOG_WIDTH_CHARS, - IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES)); + IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS, + IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES)); result.set_height(wificonfig_view_->GetPreferredSize().height()); return result; } diff --git a/chrome/browser/chromeos/options/wifi_config_model.cc b/chrome/browser/chromeos/options/wifi_config_model.cc new file mode 100644 index 0000000..5dc2f52 --- /dev/null +++ b/chrome/browser/chromeos/options/wifi_config_model.cc @@ -0,0 +1,172 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/options/wifi_config_model.h" + +#include <algorithm> + +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" // g_browser_process +#include "chrome/common/net/x509_certificate_model.h" +#include "net/base/cert_database.h" +#include "net/base/x509_certificate.h" +#include "ui/base/l10n/l10n_util_collator.h" // CompareString16WithCollator +#include "unicode/coll.h" // icu::Collator + +namespace chromeos { + +namespace { + +typedef scoped_refptr<net::X509Certificate> X509CertificateRefPtr; + +// Root CA certificates that are built into Chrome use this token name. +const char* const kRootCertificateTokenName = "Builtin Object Token"; + +// Returns a user-visible name for a given certificate. +string16 GetCertDisplayString(const net::X509Certificate* cert) { + DCHECK(cert); + std::string name_or_nick = + x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle()); + return UTF8ToUTF16(name_or_nick); +} + +// Comparison functor for locale-sensitive sorting of certificates by name. +class CertNameComparator { + public: + explicit CertNameComparator(icu::Collator* collator) + : collator_(collator) { + } + + bool operator()(const X509CertificateRefPtr& lhs, + const X509CertificateRefPtr& rhs) const { + string16 lhs_name = GetCertDisplayString(lhs); + string16 rhs_name = GetCertDisplayString(rhs); + if (collator_ == NULL) + return lhs_name < rhs_name; + return l10n_util::CompareString16WithCollator( + collator_, lhs_name, rhs_name) == UCOL_LESS; + } + + private: + icu::Collator* collator_; +}; + +} // namespace + +WifiConfigModel::WifiConfigModel() { +} + +WifiConfigModel::~WifiConfigModel() { +} + +void WifiConfigModel::UpdateCertificates() { + // CertDatabase and its wrappers do not have random access to certificates, + // so build filtered lists once. + net::CertificateList cert_list; + cert_db_.ListCerts(&cert_list); + 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); + switch (type) { + case net::USER_CERT: + user_certs_.push_back(*it); + break; + case 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) + server_ca_certs_.push_back(*it); + break; + } + default: + // We only care about those two types. + break; + } + } + + // Perform locale-sensitive sorting by certificate name. + scoped_ptr<icu::Collator> collator; + UErrorCode error = U_ZERO_ERROR; + collator.reset( + icu::Collator::createInstance( + icu::Locale(g_browser_process->GetApplicationLocale().c_str()), + error)); + if (U_FAILURE(error)) + collator.reset(NULL); + CertNameComparator cert_name_comparator(collator.get()); + std::sort(user_certs_.begin(), user_certs_.end(), cert_name_comparator); + std::sort(server_ca_certs_.begin(), server_ca_certs_.end(), + cert_name_comparator); +} + +int WifiConfigModel::GetUserCertCount() const { + return static_cast<int>(user_certs_.size()); +} + +string16 WifiConfigModel::GetUserCertName(int cert_index) const { + DCHECK(cert_index >= 0); + DCHECK(cert_index < static_cast<int>(user_certs_.size())); + net::X509Certificate* cert = user_certs_[cert_index].get(); + return GetCertDisplayString(cert); +} + +std::string WifiConfigModel::GetUserCertPkcs11Id(int cert_index) const { + DCHECK(cert_index >= 0); + DCHECK(cert_index < static_cast<int>(user_certs_.size())); + net::X509Certificate* cert = user_certs_[cert_index].get(); + net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); + return x509_certificate_model::GetPkcs11Id(cert_handle); +} + +int WifiConfigModel::GetUserCertIndex(const std::string& pkcs11_id) const { + // The list of user certs is small, so just test each one. + for (int index = 0; index < static_cast<int>(user_certs_.size()); ++index) { + net::X509Certificate* cert = user_certs_[index].get(); + net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); + std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); + if (id == pkcs11_id) + return index; + } + // Not found. + return -1; +} + +int WifiConfigModel::GetServerCaCertCount() const { + return static_cast<int>(server_ca_certs_.size()); +} + +string16 WifiConfigModel::GetServerCaCertName(int cert_index) const { + DCHECK(cert_index >= 0); + DCHECK(cert_index < static_cast<int>(server_ca_certs_.size())); + net::X509Certificate* cert = server_ca_certs_[cert_index].get(); + return GetCertDisplayString(cert); +} + +std::string WifiConfigModel::GetServerCaCertNssNickname(int cert_index) const { + DCHECK(cert_index >= 0); + DCHECK(cert_index < static_cast<int>(server_ca_certs_.size())); + net::X509Certificate* cert = server_ca_certs_[cert_index].get(); + net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); + return x509_certificate_model::GetNickname(cert_handle); +} + +int WifiConfigModel::GetServerCaCertIndex( + const std::string& nss_nickname) const { + // List of server certs is small, so just test each one. + for (int i = 0; i < static_cast<int>(server_ca_certs_.size()); ++i) { + net::X509Certificate* cert = server_ca_certs_[i].get(); + net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); + std::string nickname = x509_certificate_model::GetNickname(cert_handle); + if (nickname == nss_nickname) + return i; + } + // Not found. + return -1; +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/options/wifi_config_model.h b/chrome/browser/chromeos/options/wifi_config_model.h new file mode 100644 index 0000000..b56822b --- /dev/null +++ b/chrome/browser/chromeos/options/wifi_config_model.h @@ -0,0 +1,70 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_ +#define CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_ +#pragma once + +#include <string> + +#include "base/string16.h" +#include "net/base/cert_database.h" + +namespace chromeos { + +// Data model for Wi-Fi connection configuration dialog. Mostly concerned +// with certificate management for Extensible Authentication Protocol (EAP) +// enterprise networks. +class WifiConfigModel { + public: + // Constructs a model with empty lists of certificates. If you are + // configuring a 802.1X network, call UpdateCertificates() to build the + // internal cache of certificate names and IDs. + WifiConfigModel(); + ~WifiConfigModel(); + + // Updates the cached certificate lists. + void UpdateCertificates(); + + // Returns the number of user certificates. + int GetUserCertCount() const; + + // Returns a user-visible name for a given user certificate. + string16 GetUserCertName(int cert_index) const; + + // Returns the PKCS#11 ID for a given user certificate. + std::string GetUserCertPkcs11Id(int cert_index) const; + + // Returns the cert_index for a given PKCS#11 user certificate ID, + // or -1 if no certificate with that ID exists. + int GetUserCertIndex(const std::string& pkcs11_id) const; + + // Returns the number of server CA certificates. + int GetServerCaCertCount() const; + + // Returns a user-visible name for a given server CA certificate. + string16 GetServerCaCertName(int cert_index) const; + + // Returns the NSS nickname for a given server CA certificate. + std::string GetServerCaCertNssNickname(int cert_index) const; + + // Returns the cert_index for a given server CA certificate NSS nickname, + // or -1 if no certificate with that ID exists. + int GetServerCaCertIndex(const std::string& nss_nickname) const; + + private: + net::CertDatabase cert_db_; + + // List of user certificates, sorted by name. + net::CertificateList user_certs_; + + // List of server CA certificates, sorted by name. + net::CertificateList server_ca_certs_; + + DISALLOW_COPY_AND_ASSIGN(WifiConfigModel); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_ diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc index 458a5f4..0ba7231 100644 --- a/chrome/browser/chromeos/options/wifi_config_view.cc +++ b/chrome/browser/chromeos/options/wifi_config_view.cc @@ -9,6 +9,7 @@ #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/options/network_config_view.h" +#include "chrome/browser/chromeos/options/wifi_config_model.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -160,40 +161,69 @@ class Phase2AuthComboboxModel : public ui::ComboboxModel { DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel); }; -// TODO(chocobo): Added logic for getting server CA certs combobox populated. +// Combobox that supports a preferred width. Used by Server CA combobox +// because the strings inside it are too wide. +class ComboboxWithWidth : public views::Combobox { + public: + ComboboxWithWidth(ui::ComboboxModel* model, int width) + : Combobox(model), + width_(width) { + } + virtual ~ComboboxWithWidth() {} + virtual gfx::Size GetPreferredSize() OVERRIDE { + gfx::Size size = Combobox::GetPreferredSize(); + size.set_width(width_); + return size; + } + private: + int width_; + DISALLOW_COPY_AND_ASSIGN(ComboboxWithWidth); +}; + class ServerCACertComboboxModel : public ui::ComboboxModel { public: - ServerCACertComboboxModel() {} + explicit ServerCACertComboboxModel(WifiConfigModel* wifi_config_model) + : wifi_config_model_(wifi_config_model) { + } virtual ~ServerCACertComboboxModel() {} virtual int GetItemCount() { - return 3; + // First "Default", then the certs, then "Do not check". + return wifi_config_model_->GetServerCaCertCount() + 2; } - virtual string16 GetItemAt(int index) { - if (index == 0) + virtual string16 GetItemAt(int combo_index) { + if (combo_index == 0) return l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT); - if (index == GetItemCount()-1) + if (combo_index == GetItemCount() - 1) return l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK); - return UTF8ToUTF16("/tmp/ca-cert.pem"); + int cert_index = combo_index - 1; + return wifi_config_model_->GetServerCaCertName(cert_index); } private: + WifiConfigModel* wifi_config_model_; DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel); }; -// TODO(chocobo): Added logic for getting client certs combobox populated. class ClientCertComboboxModel : public ui::ComboboxModel { public: - ClientCertComboboxModel() {} + explicit ClientCertComboboxModel(WifiConfigModel* wifi_config_model) + : wifi_config_model_(wifi_config_model) { + } virtual ~ClientCertComboboxModel() {} virtual int GetItemCount() { - return 1; + // One initial item "None", then the certs. + return 1 + wifi_config_model_->GetUserCertCount(); } - virtual string16 GetItemAt(int index) { - return l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_NONE); + virtual string16 GetItemAt(int combo_index) { + if (combo_index == 0) + return l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_NONE); + int cert_index = combo_index - 1; + return wifi_config_model_->GetUserCertName(cert_index); } private: + WifiConfigModel* wifi_config_model_; DISALLOW_COPY_AND_ASSIGN(ClientCertComboboxModel); }; @@ -201,6 +231,7 @@ class ClientCertComboboxModel : public ui::ComboboxModel { WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi) : parent_(parent), + wifi_config_model_(new WifiConfigModel()), is_8021x_(false), service_path_(wifi->service_path()), ssid_textfield_(NULL), @@ -225,6 +256,7 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi) WifiConfigView::WifiConfigView(NetworkConfigView* parent) : parent_(parent), + wifi_config_model_(new WifiConfigModel()), is_8021x_(false), ssid_textfield_(NULL), eap_method_combobox_(NULL), @@ -462,15 +494,19 @@ bool WifiConfigView::Login() { if (server_ca_cert_combobox_->IsEnabled()) { int selected = server_ca_cert_combobox_->selected_item(); if (selected == 0) { - wifi->SetEAPServerCACert(std::string()); + // First item is "Default". + wifi->SetEAPServerCaCertNssNickname(std::string()); wifi->SetEAPUseSystemCAs(true); } else if (selected == - server_ca_cert_combobox_->model()->GetItemCount()-1) { - wifi->SetEAPServerCACert(std::string()); + server_ca_cert_combobox_->model()->GetItemCount() - 1) { + // Last item is "Do not check". + wifi->SetEAPServerCaCertNssNickname(std::string()); wifi->SetEAPUseSystemCAs(false); } else { - wifi->SetEAPServerCACert(UTF16ToUTF8( - server_ca_cert_combobox_->model()->GetItemAt(selected))); + int cert_index = selected - 1; + std::string nss_nickname = + wifi_config_model_->GetServerCaCertNssNickname(cert_index); + wifi->SetEAPServerCaCertNssNickname(nss_nickname); } } @@ -478,10 +514,14 @@ bool WifiConfigView::Login() { if (client_cert_combobox_->IsEnabled()) { int selected = client_cert_combobox_->selected_item(); if (selected == 0) { - wifi->SetEAPClientCert(std::string()); + // First item is "None". + wifi->SetEAPClientCertPkcs11Id(std::string()); } else { - wifi->SetEAPClientCert( - UTF16ToUTF8(client_cert_combobox_->model()->GetItemAt(selected))); + // Send cert ID to flimflam. + int cert_index = selected - 1; + std::string cert_pkcs11_id = + wifi_config_model_->GetUserCertPkcs11Id(cert_index); + wifi->SetEAPClientCertPkcs11Id(cert_pkcs11_id); } } @@ -585,6 +625,9 @@ void WifiConfigView::Init(WifiNetwork* wifi) { is_8021x_ = wifi && wifi->encrypted() && wifi->encryption() == SECURITY_8021X; if (is_8021x_) { + // Only enumerate certificates in the data model for 802.1X networks. + wifi_config_model_->UpdateCertificates(); + // EAP method layout->StartRow(0, column_view_set_id); layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( @@ -614,8 +657,9 @@ void WifiConfigView::Init(WifiNetwork* wifi) { new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA))); layout->AddView(server_ca_cert_label_); - server_ca_cert_combobox_ = new views::Combobox( - new ServerCACertComboboxModel()); + server_ca_cert_combobox_ = new ComboboxWithWidth( + new ServerCACertComboboxModel( + wifi_config_model_.get()), kPasswordWidth); server_ca_cert_label_->SetEnabled(false); server_ca_cert_combobox_->SetEnabled(false); server_ca_cert_combobox_->set_listener(this); @@ -628,7 +672,7 @@ void WifiConfigView::Init(WifiNetwork* wifi) { IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT))); layout->AddView(client_cert_label_); client_cert_combobox_ = new views::Combobox( - new ClientCertComboboxModel()); + new ClientCertComboboxModel(wifi_config_model_.get())); client_cert_label_->SetEnabled(false); client_cert_combobox_->SetEnabled(false); client_cert_combobox_->set_listener(this); @@ -742,43 +786,37 @@ void WifiConfigView::Init(WifiNetwork* wifi) { // Server CA certificate if (server_ca_cert_combobox_->IsEnabled()) { - const std::string& cert = wifi->eap_server_ca_cert(); - if (cert.empty()) { - if (wifi->eap_use_system_cas()) + const std::string& nss_nickname = wifi->eap_server_ca_cert_nss_nickname(); + if (nss_nickname.empty()) { + if (wifi->eap_use_system_cas()) { + // "Default" server_ca_cert_combobox_->SetSelectedItem(0); - else // select last item for "Do Not Check" + } else { + // "Do not check" server_ca_cert_combobox_->SetSelectedItem( - server_ca_cert_combobox_->model()->GetItemCount()-1); + server_ca_cert_combobox_->model()->GetItemCount() - 1); + } } else { - // select the certificate path if available - // Note: the last item is "Do Not Check" so no need to compare that. - for (int i = 1; - i < server_ca_cert_combobox_->model()->GetItemCount()-1; - i++) { - if (cert == - UTF16ToUTF8(server_ca_cert_combobox_->model()->GetItemAt(i))) { - server_ca_cert_combobox_->SetSelectedItem(i); - break; - } + // select the certificate if available + int cert_index = wifi_config_model_->GetServerCaCertIndex(nss_nickname); + if (cert_index >= 0) { + // Skip item for "Default" + server_ca_cert_combobox_->SetSelectedItem(1 + cert_index); } } } // Client certificate if (client_cert_combobox_->IsEnabled()) { - const std::string& cert = wifi->eap_client_cert(); - if (cert.empty()) { + const std::string& pkcs11_id = wifi->eap_client_cert_pkcs11_id(); + if (pkcs11_id.empty()) { + // First item is "None". client_cert_combobox_->SetSelectedItem(0); } else { - // select the certificate path if available - for (int i = 1; - i < client_cert_combobox_->model()->GetItemCount(); - i++) { - if (cert == - UTF16ToUTF8(client_cert_combobox_->model()->GetItemAt(i))) { - client_cert_combobox_->SetSelectedItem(i); - break; - } + int cert_index = wifi_config_model_->GetUserCertIndex(pkcs11_id); + if (cert_index >= 0) { + // Skip item for "None" + client_cert_combobox_->SetSelectedItem(1 + cert_index); } } } diff --git a/chrome/browser/chromeos/options/wifi_config_view.h b/chrome/browser/chromeos/options/wifi_config_view.h index b3995a1..4f857fe9 100644 --- a/chrome/browser/chromeos/options/wifi_config_view.h +++ b/chrome/browser/chromeos/options/wifi_config_view.h @@ -9,6 +9,7 @@ #include <string> #include "base/gtest_prod_util.h" +#include "base/memory/scoped_ptr.h" #include "base/string16.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/ui/shell_dialogs.h" @@ -26,6 +27,7 @@ class FilePath; namespace chromeos { class NetworkConfigView; +class WifiConfigModel; // A dialog box for showing a password textfield. class WifiConfigView : public views::View, @@ -82,6 +84,8 @@ class WifiConfigView : public views::View, NetworkConfigView* parent_; + scoped_ptr<WifiConfigModel> wifi_config_model_; + // Whether or not it is an 802.1x network. bool is_8021x_; |