Home | History | Annotate | Download | only in options
      1 // Copyright (c) 2012 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.
      4 
      5 #include "chrome/browser/chromeos/options/wifi_config_view.h"
      6 
      7 #include "ash/system/chromeos/network/network_connect.h"
      8 #include "base/bind.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
     13 #include "chrome/browser/chromeos/net/onc_utils.h"
     14 #include "chrome/browser/chromeos/options/passphrase_textfield.h"
     15 #include "chrome/browser/profiles/profile_manager.h"
     16 #include "chromeos/login/login_state.h"
     17 #include "chromeos/network/network_configuration_handler.h"
     18 #include "chromeos/network/network_event_log.h"
     19 #include "chromeos/network/network_handler.h"
     20 #include "chromeos/network/network_state.h"
     21 #include "chromeos/network/network_state_handler.h"
     22 #include "chromeos/network/network_ui_data.h"
     23 #include "chromeos/network/shill_property_util.h"
     24 #include "chromeos/tpm_token_loader.h"
     25 #include "components/onc/onc_constants.h"
     26 #include "grit/chromium_strings.h"
     27 #include "grit/generated_resources.h"
     28 #include "grit/locale_settings.h"
     29 #include "grit/theme_resources.h"
     30 #include "third_party/cros_system_api/dbus/service_constants.h"
     31 #include "ui/base/l10n/l10n_util.h"
     32 #include "ui/base/resource/resource_bundle.h"
     33 #include "ui/events/event.h"
     34 #include "ui/views/controls/button/checkbox.h"
     35 #include "ui/views/controls/button/image_button.h"
     36 #include "ui/views/controls/combobox/combobox.h"
     37 #include "ui/views/controls/label.h"
     38 #include "ui/views/controls/textfield/textfield.h"
     39 #include "ui/views/layout/grid_layout.h"
     40 #include "ui/views/layout/layout_constants.h"
     41 #include "ui/views/widget/widget.h"
     42 #include "ui/views/window/dialog_client_view.h"
     43 
     44 namespace chromeos {
     45 
     46 namespace {
     47 
     48 // Combobox that supports a preferred width.  Used by Server CA combobox
     49 // because the strings inside it are too wide.
     50 class ComboboxWithWidth : public views::Combobox {
     51  public:
     52   ComboboxWithWidth(ui::ComboboxModel* model, int width)
     53       : Combobox(model),
     54         width_(width) {
     55   }
     56   virtual ~ComboboxWithWidth() {}
     57   virtual gfx::Size GetPreferredSize() const OVERRIDE {
     58     gfx::Size size = Combobox::GetPreferredSize();
     59     size.set_width(width_);
     60     return size;
     61   }
     62  private:
     63   int width_;
     64   DISALLOW_COPY_AND_ASSIGN(ComboboxWithWidth);
     65 };
     66 
     67 enum SecurityComboboxIndex {
     68   SECURITY_INDEX_NONE  = 0,
     69   SECURITY_INDEX_WEP   = 1,
     70   SECURITY_INDEX_PSK   = 2,
     71   SECURITY_INDEX_COUNT = 3
     72 };
     73 
     74 // Methods in alphabetical order.
     75 enum EAPMethodComboboxIndex {
     76   EAP_METHOD_INDEX_NONE  = 0,
     77   EAP_METHOD_INDEX_LEAP  = 1,
     78   EAP_METHOD_INDEX_PEAP  = 2,
     79   EAP_METHOD_INDEX_TLS   = 3,
     80   EAP_METHOD_INDEX_TTLS  = 4,
     81   EAP_METHOD_INDEX_COUNT = 5
     82 };
     83 
     84 enum Phase2AuthComboboxIndex {
     85   PHASE_2_AUTH_INDEX_AUTO     = 0,  // LEAP, EAP-TLS have only this auth.
     86   PHASE_2_AUTH_INDEX_MD5      = 1,
     87   PHASE_2_AUTH_INDEX_MSCHAPV2 = 2,  // PEAP has up to this auth.
     88   PHASE_2_AUTH_INDEX_MSCHAP   = 3,
     89   PHASE_2_AUTH_INDEX_PAP      = 4,
     90   PHASE_2_AUTH_INDEX_CHAP     = 5,  // EAP-TTLS has up to this auth.
     91   PHASE_2_AUTH_INDEX_COUNT    = 6
     92 };
     93 
     94 void ShillError(const std::string& function,
     95                 const std::string& error_name,
     96                 scoped_ptr<base::DictionaryValue> error_data) {
     97   NET_LOG_ERROR("Shill Error from WifiConfigView: " + error_name, function);
     98 }
     99 
    100 }  // namespace
    101 
    102 namespace internal {
    103 
    104 class SecurityComboboxModel : public ui::ComboboxModel {
    105  public:
    106   SecurityComboboxModel();
    107   virtual ~SecurityComboboxModel();
    108 
    109   // Overridden from ui::ComboboxModel:
    110   virtual int GetItemCount() const OVERRIDE;
    111   virtual base::string16 GetItemAt(int index) OVERRIDE;
    112 
    113  private:
    114   DISALLOW_COPY_AND_ASSIGN(SecurityComboboxModel);
    115 };
    116 
    117 class EAPMethodComboboxModel : public ui::ComboboxModel {
    118  public:
    119   EAPMethodComboboxModel();
    120   virtual ~EAPMethodComboboxModel();
    121 
    122   // Overridden from ui::ComboboxModel:
    123   virtual int GetItemCount() const OVERRIDE;
    124   virtual base::string16 GetItemAt(int index) OVERRIDE;
    125 
    126  private:
    127   DISALLOW_COPY_AND_ASSIGN(EAPMethodComboboxModel);
    128 };
    129 
    130 class Phase2AuthComboboxModel : public ui::ComboboxModel {
    131  public:
    132   explicit Phase2AuthComboboxModel(views::Combobox* eap_method_combobox);
    133   virtual ~Phase2AuthComboboxModel();
    134 
    135   // Overridden from ui::ComboboxModel:
    136   virtual int GetItemCount() const OVERRIDE;
    137   virtual base::string16 GetItemAt(int index) OVERRIDE;
    138 
    139  private:
    140   views::Combobox* eap_method_combobox_;
    141 
    142   DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel);
    143 };
    144 
    145 class ServerCACertComboboxModel : public ui::ComboboxModel {
    146  public:
    147   ServerCACertComboboxModel();
    148   virtual ~ServerCACertComboboxModel();
    149 
    150   // Overridden from ui::ComboboxModel:
    151   virtual int GetItemCount() const OVERRIDE;
    152   virtual base::string16 GetItemAt(int index) OVERRIDE;
    153 
    154  private:
    155   DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
    156 };
    157 
    158 class UserCertComboboxModel : public ui::ComboboxModel {
    159  public:
    160   explicit UserCertComboboxModel(WifiConfigView* owner);
    161   virtual ~UserCertComboboxModel();
    162 
    163   // Overridden from ui::ComboboxModel:
    164   virtual int GetItemCount() const OVERRIDE;
    165   virtual base::string16 GetItemAt(int index) OVERRIDE;
    166 
    167  private:
    168   WifiConfigView* owner_;
    169 
    170   DISALLOW_COPY_AND_ASSIGN(UserCertComboboxModel);
    171 };
    172 
    173 // SecurityComboboxModel -------------------------------------------------------
    174 
    175 SecurityComboboxModel::SecurityComboboxModel() {
    176 }
    177 
    178 SecurityComboboxModel::~SecurityComboboxModel() {
    179 }
    180 
    181 int SecurityComboboxModel::GetItemCount() const {
    182     return SECURITY_INDEX_COUNT;
    183   }
    184 base::string16 SecurityComboboxModel::GetItemAt(int index) {
    185   if (index == SECURITY_INDEX_NONE)
    186     return l10n_util::GetStringUTF16(
    187         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_NONE);
    188   else if (index == SECURITY_INDEX_WEP)
    189     return l10n_util::GetStringUTF16(
    190         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WEP);
    191   else if (index == SECURITY_INDEX_PSK)
    192     return l10n_util::GetStringUTF16(
    193         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_PSK);
    194   NOTREACHED();
    195   return base::string16();
    196 }
    197 
    198 // EAPMethodComboboxModel ------------------------------------------------------
    199 
    200 EAPMethodComboboxModel::EAPMethodComboboxModel() {
    201 }
    202 
    203 EAPMethodComboboxModel::~EAPMethodComboboxModel() {
    204 }
    205 
    206 int EAPMethodComboboxModel::GetItemCount() const {
    207   return EAP_METHOD_INDEX_COUNT;
    208 }
    209 base::string16 EAPMethodComboboxModel::GetItemAt(int index) {
    210   if (index == EAP_METHOD_INDEX_NONE)
    211     return l10n_util::GetStringUTF16(
    212         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_NONE);
    213   else if (index == EAP_METHOD_INDEX_LEAP)
    214     return l10n_util::GetStringUTF16(
    215         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_LEAP);
    216   else if (index == EAP_METHOD_INDEX_PEAP)
    217     return l10n_util::GetStringUTF16(
    218         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_PEAP);
    219   else if (index == EAP_METHOD_INDEX_TLS)
    220     return l10n_util::GetStringUTF16(
    221         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TLS);
    222   else if (index == EAP_METHOD_INDEX_TTLS)
    223     return l10n_util::GetStringUTF16(
    224         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TTLS);
    225   NOTREACHED();
    226   return base::string16();
    227 }
    228 
    229 // Phase2AuthComboboxModel -----------------------------------------------------
    230 
    231 Phase2AuthComboboxModel::Phase2AuthComboboxModel(
    232     views::Combobox* eap_method_combobox)
    233     : eap_method_combobox_(eap_method_combobox) {
    234 }
    235 
    236 Phase2AuthComboboxModel::~Phase2AuthComboboxModel() {
    237 }
    238 
    239 int Phase2AuthComboboxModel::GetItemCount() const {
    240   switch (eap_method_combobox_->selected_index()) {
    241     case EAP_METHOD_INDEX_NONE:
    242     case EAP_METHOD_INDEX_TLS:
    243     case EAP_METHOD_INDEX_LEAP:
    244       return PHASE_2_AUTH_INDEX_AUTO + 1;
    245     case EAP_METHOD_INDEX_PEAP:
    246       return PHASE_2_AUTH_INDEX_MSCHAPV2 + 1;
    247     case EAP_METHOD_INDEX_TTLS:
    248       return PHASE_2_AUTH_INDEX_CHAP + 1;
    249   }
    250   NOTREACHED();
    251   return 0;
    252 }
    253 
    254 base::string16 Phase2AuthComboboxModel::GetItemAt(int index) {
    255   if (index == PHASE_2_AUTH_INDEX_AUTO)
    256     return l10n_util::GetStringUTF16(
    257         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_AUTO);
    258   else if (index == PHASE_2_AUTH_INDEX_MD5)
    259     return l10n_util::GetStringUTF16(
    260         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MD5);
    261   else if (index == PHASE_2_AUTH_INDEX_MSCHAPV2)
    262     return l10n_util::GetStringUTF16(
    263         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAPV2);
    264   else if (index == PHASE_2_AUTH_INDEX_MSCHAP)
    265     return l10n_util::GetStringUTF16(
    266         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAP);
    267   else if (index == PHASE_2_AUTH_INDEX_PAP)
    268     return l10n_util::GetStringUTF16(
    269         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_PAP);
    270   else if (index == PHASE_2_AUTH_INDEX_CHAP)
    271     return l10n_util::GetStringUTF16(
    272         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_CHAP);
    273   NOTREACHED();
    274   return base::string16();
    275 }
    276 
    277 // ServerCACertComboboxModel ---------------------------------------------------
    278 
    279 ServerCACertComboboxModel::ServerCACertComboboxModel() {
    280 }
    281 
    282 ServerCACertComboboxModel::~ServerCACertComboboxModel() {
    283 }
    284 
    285 int ServerCACertComboboxModel::GetItemCount() const {
    286   if (CertLibrary::Get()->CertificatesLoading())
    287     return 1;  // "Loading"
    288   // First "Default", then the certs, then "Do not check".
    289   return CertLibrary::Get()->NumCertificates(
    290       CertLibrary::CERT_TYPE_SERVER_CA) + 2;
    291 }
    292 
    293 base::string16 ServerCACertComboboxModel::GetItemAt(int index) {
    294   if (CertLibrary::Get()->CertificatesLoading())
    295     return l10n_util::GetStringUTF16(
    296         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
    297   if (index == 0)
    298     return l10n_util::GetStringUTF16(
    299         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
    300   if (index == GetItemCount() - 1)
    301     return l10n_util::GetStringUTF16(
    302         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK);
    303   int cert_index = index - 1;
    304   return CertLibrary::Get()->GetCertDisplayStringAt(
    305       CertLibrary::CERT_TYPE_SERVER_CA, cert_index);
    306 }
    307 
    308 // UserCertComboboxModel -------------------------------------------------------
    309 
    310 UserCertComboboxModel::UserCertComboboxModel(WifiConfigView* owner)
    311     : owner_(owner) {
    312 }
    313 
    314 UserCertComboboxModel::~UserCertComboboxModel() {
    315 }
    316 
    317 int UserCertComboboxModel::GetItemCount() const {
    318   if (!owner_->UserCertActive())
    319     return 1;  // "None installed" (combobox must have at least 1 entry)
    320   if (CertLibrary::Get()->CertificatesLoading())
    321     return 1;  // "Loading"
    322   int num_certs =
    323       CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER);
    324   if (num_certs == 0)
    325     return 1;  // "None installed"
    326   return num_certs;
    327 }
    328 
    329 base::string16 UserCertComboboxModel::GetItemAt(int index) {
    330   if (!owner_->UserCertActive())
    331     return l10n_util::GetStringUTF16(
    332         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
    333   if (CertLibrary::Get()->CertificatesLoading())
    334     return l10n_util::GetStringUTF16(
    335         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
    336   if (CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) == 0)
    337     return l10n_util::GetStringUTF16(
    338         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
    339   return CertLibrary::Get()->GetCertDisplayStringAt(
    340       CertLibrary::CERT_TYPE_USER, index);
    341 }
    342 
    343 }  // namespace internal
    344 
    345 WifiConfigView::WifiConfigView(NetworkConfigView* parent,
    346                                const std::string& service_path,
    347                                bool show_8021x)
    348     : ChildNetworkConfigView(parent, service_path),
    349       ssid_textfield_(NULL),
    350       eap_method_combobox_(NULL),
    351       phase_2_auth_label_(NULL),
    352       phase_2_auth_combobox_(NULL),
    353       user_cert_label_(NULL),
    354       user_cert_combobox_(NULL),
    355       server_ca_cert_label_(NULL),
    356       server_ca_cert_combobox_(NULL),
    357       subject_match_label_(NULL),
    358       subject_match_textfield_(NULL),
    359       identity_label_(NULL),
    360       identity_textfield_(NULL),
    361       identity_anonymous_label_(NULL),
    362       identity_anonymous_textfield_(NULL),
    363       save_credentials_checkbox_(NULL),
    364       share_network_checkbox_(NULL),
    365       shared_network_label_(NULL),
    366       security_combobox_(NULL),
    367       passphrase_label_(NULL),
    368       passphrase_textfield_(NULL),
    369       passphrase_visible_button_(NULL),
    370       error_label_(NULL),
    371       weak_ptr_factory_(this) {
    372   Init(show_8021x);
    373   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
    374 }
    375 
    376 WifiConfigView::~WifiConfigView() {
    377   RemoveAllChildViews(true);  // Destroy children before models
    378   if (NetworkHandler::IsInitialized()) {
    379     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
    380         this, FROM_HERE);
    381   }
    382   CertLibrary::Get()->RemoveObserver(this);
    383 }
    384 
    385 base::string16 WifiConfigView::GetTitle() const {
    386   const NetworkState* network = GetNetworkState();
    387   if (network && network->type() == shill::kTypeEthernet)
    388     return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONFIGURE_ETHERNET);
    389   return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS);
    390 }
    391 
    392 views::View* WifiConfigView::GetInitiallyFocusedView() {
    393   // Return a reasonable widget for initial focus,
    394   // depending on what we're showing.
    395   if (ssid_textfield_)
    396     return ssid_textfield_;
    397   else if (eap_method_combobox_)
    398     return eap_method_combobox_;
    399   else if (passphrase_textfield_ && passphrase_textfield_->enabled())
    400     return passphrase_textfield_;
    401   else
    402     return NULL;
    403 }
    404 
    405 bool WifiConfigView::CanLogin() {
    406   static const size_t kMinWirelessPasswordLen = 5;
    407 
    408   // We either have an existing network or the user entered an SSID.
    409   if (service_path_.empty() && GetSsid().empty())
    410     return false;
    411 
    412   // If the network requires a passphrase, make sure it is the right length.
    413   if (passphrase_textfield_ != NULL &&
    414       passphrase_textfield_->enabled() &&
    415       !passphrase_textfield_->show_fake() &&
    416       passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
    417     return false;
    418 
    419   // If we're using EAP, we must have a method.
    420   if (eap_method_combobox_ &&
    421       eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_NONE)
    422     return false;
    423 
    424   // Block login if certs are required but user has none.
    425   if (UserCertRequired() && (!HaveUserCerts() || !IsUserCertValid()))
    426       return false;
    427 
    428   return true;
    429 }
    430 
    431 bool WifiConfigView::UserCertRequired() const {
    432   return UserCertActive();
    433 }
    434 
    435 bool WifiConfigView::HaveUserCerts() const {
    436   return CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) > 0;
    437 }
    438 
    439 bool WifiConfigView::IsUserCertValid() const {
    440   if (!UserCertActive())
    441     return false;
    442   int index = user_cert_combobox_->selected_index();
    443   if (index < 0)
    444     return false;
    445   // Currently only hardware-backed user certificates are valid.
    446   if (CertLibrary::Get()->IsHardwareBacked() &&
    447       !CertLibrary::Get()->IsCertHardwareBackedAt(
    448           CertLibrary::CERT_TYPE_USER, index))
    449     return false;
    450   return true;
    451 }
    452 
    453 bool WifiConfigView::Phase2AuthActive() const {
    454   if (phase_2_auth_combobox_)
    455     return phase_2_auth_combobox_->model()->GetItemCount() > 1;
    456   return false;
    457 }
    458 
    459 bool WifiConfigView::PassphraseActive() const {
    460   if (eap_method_combobox_) {
    461     // No password for EAP-TLS.
    462     int index = eap_method_combobox_->selected_index();
    463     return index != EAP_METHOD_INDEX_NONE && index != EAP_METHOD_INDEX_TLS;
    464   } else if (security_combobox_) {
    465     return security_combobox_->selected_index() != SECURITY_INDEX_NONE;
    466   }
    467   return false;
    468 }
    469 
    470 bool WifiConfigView::UserCertActive() const {
    471   // User certs only for EAP-TLS.
    472   if (eap_method_combobox_)
    473     return eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_TLS;
    474 
    475   return false;
    476 }
    477 
    478 bool WifiConfigView::CaCertActive() const {
    479   // No server CA certs for LEAP.
    480   if (eap_method_combobox_) {
    481     int index = eap_method_combobox_->selected_index();
    482     return index != EAP_METHOD_INDEX_NONE && index != EAP_METHOD_INDEX_LEAP;
    483   }
    484   return false;
    485 }
    486 
    487 void WifiConfigView::UpdateDialogButtons() {
    488   parent_->GetDialogClientView()->UpdateDialogButtons();
    489 }
    490 
    491 void WifiConfigView::RefreshEapFields() {
    492   // If EAP method changes, the phase 2 auth choices may have changed also.
    493   phase_2_auth_combobox_->ModelChanged();
    494   phase_2_auth_combobox_->SetSelectedIndex(0);
    495   bool phase_2_auth_enabled = Phase2AuthActive();
    496   phase_2_auth_combobox_->SetEnabled(phase_2_auth_enabled &&
    497                                      phase_2_auth_ui_data_.IsEditable());
    498   phase_2_auth_label_->SetEnabled(phase_2_auth_enabled);
    499 
    500   // Passphrase.
    501   bool passphrase_enabled = PassphraseActive();
    502   passphrase_textfield_->SetEnabled(passphrase_enabled &&
    503                                     passphrase_ui_data_.IsEditable());
    504   passphrase_label_->SetEnabled(passphrase_enabled);
    505   if (!passphrase_enabled)
    506     passphrase_textfield_->SetText(base::string16());
    507 
    508   // User cert.
    509   bool certs_loading = CertLibrary::Get()->CertificatesLoading();
    510   bool user_cert_enabled = UserCertActive();
    511   user_cert_label_->SetEnabled(user_cert_enabled);
    512   bool have_user_certs = !certs_loading && HaveUserCerts();
    513   user_cert_combobox_->SetEnabled(user_cert_enabled &&
    514                                   have_user_certs &&
    515                                   user_cert_ui_data_.IsEditable());
    516   user_cert_combobox_->ModelChanged();
    517   user_cert_combobox_->SetSelectedIndex(0);
    518 
    519   // Server CA.
    520   bool ca_cert_enabled = CaCertActive();
    521   server_ca_cert_label_->SetEnabled(ca_cert_enabled);
    522   server_ca_cert_combobox_->SetEnabled(ca_cert_enabled &&
    523                                        !certs_loading &&
    524                                        server_ca_cert_ui_data_.IsEditable());
    525   server_ca_cert_combobox_->ModelChanged();
    526   server_ca_cert_combobox_->SetSelectedIndex(0);
    527 
    528   // Subject Match
    529   bool subject_match_enabled =
    530       ca_cert_enabled && eap_method_combobox_ &&
    531       eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_TLS;
    532   subject_match_label_->SetEnabled(subject_match_enabled);
    533   subject_match_textfield_->SetEnabled(subject_match_enabled);
    534   if (!subject_match_enabled)
    535     subject_match_textfield_->SetText(base::string16());
    536 
    537   // No anonymous identity if no phase 2 auth.
    538   bool identity_anonymous_enabled = phase_2_auth_enabled;
    539   identity_anonymous_textfield_->SetEnabled(
    540       identity_anonymous_enabled && identity_anonymous_ui_data_.IsEditable());
    541   identity_anonymous_label_->SetEnabled(identity_anonymous_enabled);
    542   if (!identity_anonymous_enabled)
    543     identity_anonymous_textfield_->SetText(base::string16());
    544 
    545   RefreshShareCheckbox();
    546 }
    547 
    548 void WifiConfigView::RefreshShareCheckbox() {
    549   if (!share_network_checkbox_)
    550     return;
    551 
    552   if (security_combobox_ &&
    553       security_combobox_->selected_index() == SECURITY_INDEX_NONE) {
    554     share_network_checkbox_->SetEnabled(false);
    555     share_network_checkbox_->SetChecked(true);
    556   } else if (eap_method_combobox_ &&
    557              (eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_TLS ||
    558               user_cert_combobox_->selected_index() != 0)) {
    559     // Can not share TLS network (requires certificate), or any network where
    560     // user certificates are enabled.
    561     share_network_checkbox_->SetEnabled(false);
    562     share_network_checkbox_->SetChecked(false);
    563   } else {
    564     bool value = false;
    565     bool enabled = false;
    566     ChildNetworkConfigView::GetShareStateForLoginState(&value, &enabled);
    567 
    568     share_network_checkbox_->SetChecked(value);
    569     share_network_checkbox_->SetEnabled(enabled);
    570   }
    571 }
    572 
    573 void WifiConfigView::UpdateErrorLabel() {
    574   base::string16 error_msg;
    575   if (UserCertRequired() && CertLibrary::Get()->CertificatesLoaded()) {
    576     if (!HaveUserCerts()) {
    577       if (!LoginState::Get()->IsUserLoggedIn() ||
    578           LoginState::Get()->IsGuestUser()) {
    579         error_msg = l10n_util::GetStringUTF16(
    580             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_LOGIN_FOR_USER_CERT);
    581       } else {
    582         error_msg = l10n_util::GetStringUTF16(
    583             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
    584       }
    585     } else if (!IsUserCertValid()) {
    586       error_msg = l10n_util::GetStringUTF16(
    587           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_REQUIRE_HARDWARE_BACKED);
    588     }
    589   }
    590   if (error_msg.empty() && !service_path_.empty()) {
    591     const NetworkState* network = GetNetworkState();
    592     if (network && network->connection_state() == shill::kStateFailure) {
    593       error_msg = ash::network_connect::ErrorString(
    594           network->last_error(), network->path());
    595     }
    596   }
    597   if (!error_msg.empty()) {
    598     error_label_->SetText(error_msg);
    599     error_label_->SetVisible(true);
    600   } else {
    601     error_label_->SetVisible(false);
    602   }
    603 }
    604 
    605 void WifiConfigView::ContentsChanged(views::Textfield* sender,
    606                                      const base::string16& new_contents) {
    607   UpdateDialogButtons();
    608 }
    609 
    610 bool WifiConfigView::HandleKeyEvent(views::Textfield* sender,
    611                                     const ui::KeyEvent& key_event) {
    612   if (sender == passphrase_textfield_ &&
    613       key_event.key_code() == ui::VKEY_RETURN) {
    614     parent_->GetDialogClientView()->AcceptWindow();
    615   }
    616   return false;
    617 }
    618 
    619 void WifiConfigView::ButtonPressed(views::Button* sender,
    620                                    const ui::Event& event) {
    621   if (sender == passphrase_visible_button_ && passphrase_textfield_) {
    622     if (passphrase_textfield_->GetTextInputType() == ui::TEXT_INPUT_TYPE_TEXT) {
    623       passphrase_textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
    624       passphrase_visible_button_->SetToggled(false);
    625     } else {
    626       passphrase_textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
    627       passphrase_visible_button_->SetToggled(true);
    628     }
    629   } else {
    630     NOTREACHED();
    631   }
    632 }
    633 
    634 void WifiConfigView::OnPerformAction(views::Combobox* combobox) {
    635   if (combobox == security_combobox_) {
    636     bool passphrase_enabled = PassphraseActive();
    637     passphrase_label_->SetEnabled(passphrase_enabled);
    638     passphrase_textfield_->SetEnabled(passphrase_enabled &&
    639                                       passphrase_ui_data_.IsEditable());
    640     if (!passphrase_enabled)
    641       passphrase_textfield_->SetText(base::string16());
    642     RefreshShareCheckbox();
    643   } else if (combobox == user_cert_combobox_) {
    644     RefreshShareCheckbox();
    645   } else if (combobox == eap_method_combobox_) {
    646     RefreshEapFields();
    647   }
    648   UpdateDialogButtons();
    649   UpdateErrorLabel();
    650 }
    651 
    652 void WifiConfigView::OnCertificatesLoaded(bool initial_load) {
    653   RefreshEapFields();
    654   UpdateDialogButtons();
    655   UpdateErrorLabel();
    656 }
    657 
    658 bool WifiConfigView::Login() {
    659   const NetworkState* network = GetNetworkState();
    660 
    661   // Set configuration properties.
    662   base::DictionaryValue properties;
    663 
    664   // Default shared state for non-private networks is true.
    665   const bool share_default = !network || !network->IsPrivate();
    666   bool share_network = GetShareNetwork(share_default);
    667   bool only_policy_autoconnect =
    668       onc::PolicyAllowsOnlyPolicyNetworksToAutoconnect(!share_network);
    669   if (only_policy_autoconnect) {
    670     properties.SetBooleanWithoutPathExpansion(shill::kAutoConnectProperty,
    671                                               false);
    672   }
    673 
    674   if (service_path_.empty()) {
    675     // TODO(stevenjb): Support modifying existing EAP configurations.
    676     // Will probably wait to do this in WebUI instead.
    677     properties.SetStringWithoutPathExpansion(
    678         shill::kTypeProperty, shill::kTypeWifi);
    679     shill_property_util::SetSSID(GetSsid(), &properties);
    680     properties.SetStringWithoutPathExpansion(
    681         shill::kModeProperty, shill::kModeManaged);
    682     properties.SetBooleanWithoutPathExpansion(
    683         shill::kSaveCredentialsProperty, GetSaveCredentials());
    684     std::string security = shill::kSecurityNone;
    685     if (!eap_method_combobox_) {
    686       switch (security_combobox_->selected_index()) {
    687         case SECURITY_INDEX_NONE:
    688           security = shill::kSecurityNone;
    689           break;
    690         case SECURITY_INDEX_WEP:
    691           security = shill::kSecurityWep;
    692           break;
    693         case SECURITY_INDEX_PSK:
    694           security = shill::kSecurityPsk;
    695           break;
    696       }
    697       std::string passphrase = GetPassphrase();
    698       if (!passphrase.empty()) {
    699         properties.SetStringWithoutPathExpansion(
    700             shill::kPassphraseProperty, GetPassphrase());
    701       }
    702     } else {
    703       security = shill::kSecurity8021x;
    704       SetEapProperties(&properties);
    705     }
    706     properties.SetStringWithoutPathExpansion(
    707         shill::kSecurityProperty, security);
    708 
    709     // Configure and connect to network.
    710     ash::network_connect::CreateConfigurationAndConnect(&properties,
    711                                                         share_network);
    712   } else {
    713     if (!network) {
    714       // Shill no longer knows about this network (edge case).
    715       // TODO(stevenjb): Add notification for this.
    716       NET_LOG_ERROR("Network not found", service_path_);
    717       return true;  // Close dialog
    718     }
    719     if (eap_method_combobox_) {
    720       SetEapProperties(&properties);
    721       properties.SetBooleanWithoutPathExpansion(
    722           shill::kSaveCredentialsProperty, GetSaveCredentials());
    723     } else {
    724       const std::string passphrase = GetPassphrase();
    725       if (!passphrase.empty()) {
    726         properties.SetStringWithoutPathExpansion(
    727             shill::kPassphraseProperty, passphrase);
    728       }
    729     }
    730     if (network->type() == shill::kTypeEthernet) {
    731       // When configuring an ethernet service, we actually configure the
    732       // EthernetEap service, which exists in the Profile only.
    733       // See crbug.com/126870 for more info.
    734       properties.SetStringWithoutPathExpansion(shill::kTypeProperty,
    735                                                shill::kTypeEthernetEap);
    736       share_network = false;
    737       // Set the TPM PIN.
    738       properties.SetStringWithoutPathExpansion(
    739           shill::kEapPinProperty, TPMTokenLoader::Get()->tpm_user_pin());
    740       ash::network_connect::CreateConfiguration(&properties, share_network);
    741     } else {
    742       ash::network_connect::ConfigureNetworkAndConnect(
    743           service_path_, properties, share_network);
    744     }
    745   }
    746   return true;  // dialog will be closed
    747 }
    748 
    749 std::string WifiConfigView::GetSsid() const {
    750   std::string result;
    751   if (ssid_textfield_ != NULL) {
    752     std::string untrimmed = base::UTF16ToUTF8(ssid_textfield_->text());
    753     base::TrimWhitespaceASCII(untrimmed, base::TRIM_ALL, &result);
    754   }
    755   return result;
    756 }
    757 
    758 std::string WifiConfigView::GetPassphrase() const {
    759   std::string result;
    760   if (passphrase_textfield_ != NULL)
    761     result = base::UTF16ToUTF8(passphrase_textfield_->text());
    762   return result;
    763 }
    764 
    765 bool WifiConfigView::GetSaveCredentials() const {
    766   if (!save_credentials_checkbox_)
    767     return true;  // share networks by default (e.g. non 8021x).
    768   return save_credentials_checkbox_->checked();
    769 }
    770 
    771 bool WifiConfigView::GetShareNetwork(bool share_default) const {
    772   if (!share_network_checkbox_)
    773     return share_default;
    774   return share_network_checkbox_->checked();
    775 }
    776 
    777 std::string WifiConfigView::GetEapMethod() const {
    778   DCHECK(eap_method_combobox_);
    779   switch (eap_method_combobox_->selected_index()) {
    780     case EAP_METHOD_INDEX_PEAP:
    781       return shill::kEapMethodPEAP;
    782     case EAP_METHOD_INDEX_TLS:
    783       return shill::kEapMethodTLS;
    784     case EAP_METHOD_INDEX_TTLS:
    785       return shill::kEapMethodTTLS;
    786     case EAP_METHOD_INDEX_LEAP:
    787       return shill::kEapMethodLEAP;
    788     case EAP_METHOD_INDEX_NONE:
    789     default:
    790       return "";
    791   }
    792 }
    793 
    794 std::string WifiConfigView::GetEapPhase2Auth() const {
    795   DCHECK(phase_2_auth_combobox_);
    796   bool is_peap = (GetEapMethod() == shill::kEapMethodPEAP);
    797   switch (phase_2_auth_combobox_->selected_index()) {
    798     case PHASE_2_AUTH_INDEX_MD5:
    799       return is_peap ? shill::kEapPhase2AuthPEAPMD5
    800           : shill::kEapPhase2AuthTTLSMD5;
    801     case PHASE_2_AUTH_INDEX_MSCHAPV2:
    802       return is_peap ? shill::kEapPhase2AuthPEAPMSCHAPV2
    803           : shill::kEapPhase2AuthTTLSMSCHAPV2;
    804     case PHASE_2_AUTH_INDEX_MSCHAP:
    805       return shill::kEapPhase2AuthTTLSMSCHAP;
    806     case PHASE_2_AUTH_INDEX_PAP:
    807       return shill::kEapPhase2AuthTTLSPAP;
    808     case PHASE_2_AUTH_INDEX_CHAP:
    809       return shill::kEapPhase2AuthTTLSCHAP;
    810     case PHASE_2_AUTH_INDEX_AUTO:
    811     default:
    812       return "";
    813   }
    814 }
    815 
    816 std::string WifiConfigView::GetEapServerCaCertPEM() const {
    817   DCHECK(server_ca_cert_combobox_);
    818   int index = server_ca_cert_combobox_->selected_index();
    819   if (index == 0) {
    820     // First item is "Default".
    821     return std::string();
    822   } else if (index == server_ca_cert_combobox_->model()->GetItemCount() - 1) {
    823     // Last item is "Do not check".
    824     return std::string();
    825   } else {
    826     int cert_index = index - 1;
    827     return CertLibrary::Get()->GetServerCACertPEMAt(cert_index);
    828   }
    829 }
    830 
    831 bool WifiConfigView::GetEapUseSystemCas() const {
    832   DCHECK(server_ca_cert_combobox_);
    833   // Only use system CAs if the first item ("Default") is selected.
    834   return server_ca_cert_combobox_->selected_index() == 0;
    835 }
    836 
    837 std::string WifiConfigView::GetEapSubjectMatch() const {
    838   DCHECK(subject_match_textfield_);
    839   return base::UTF16ToUTF8(subject_match_textfield_->text());
    840 }
    841 
    842 std::string WifiConfigView::GetEapClientCertPkcs11Id() const {
    843   DCHECK(user_cert_combobox_);
    844   if (!HaveUserCerts() || !UserCertActive()) {
    845     return std::string();  // No certificate selected or not required.
    846   } else {
    847     // Certificates are listed in the order they appear in the model.
    848     int index = user_cert_combobox_->selected_index();
    849     return CertLibrary::Get()->GetUserCertPkcs11IdAt(index);
    850   }
    851 }
    852 
    853 std::string WifiConfigView::GetEapIdentity() const {
    854   DCHECK(identity_textfield_);
    855   return base::UTF16ToUTF8(identity_textfield_->text());
    856 }
    857 
    858 std::string WifiConfigView::GetEapAnonymousIdentity() const {
    859   DCHECK(identity_anonymous_textfield_);
    860   return base::UTF16ToUTF8(identity_anonymous_textfield_->text());
    861 }
    862 
    863 void WifiConfigView::SetEapProperties(base::DictionaryValue* properties) {
    864   properties->SetStringWithoutPathExpansion(
    865       shill::kEapIdentityProperty, GetEapIdentity());
    866   properties->SetStringWithoutPathExpansion(
    867       shill::kEapMethodProperty, GetEapMethod());
    868   properties->SetStringWithoutPathExpansion(
    869       shill::kEapPhase2AuthProperty, GetEapPhase2Auth());
    870   properties->SetStringWithoutPathExpansion(
    871       shill::kEapAnonymousIdentityProperty, GetEapAnonymousIdentity());
    872   properties->SetStringWithoutPathExpansion(
    873       shill::kEapSubjectMatchProperty, GetEapSubjectMatch());
    874 
    875   // shill requires both CertID and KeyID for TLS connections, despite
    876   // the fact that by convention they are the same ID.
    877   properties->SetStringWithoutPathExpansion(
    878       shill::kEapCertIdProperty, GetEapClientCertPkcs11Id());
    879   properties->SetStringWithoutPathExpansion(
    880       shill::kEapKeyIdProperty, GetEapClientCertPkcs11Id());
    881 
    882   properties->SetBooleanWithoutPathExpansion(
    883       shill::kEapUseSystemCasProperty, GetEapUseSystemCas());
    884   properties->SetStringWithoutPathExpansion(
    885       shill::kEapPasswordProperty, GetPassphrase());
    886 
    887   base::ListValue* pem_list = new base::ListValue;
    888   pem_list->AppendString(GetEapServerCaCertPEM());
    889   properties->SetWithoutPathExpansion(
    890       shill::kEapCaCertPemProperty, pem_list);
    891 }
    892 
    893 void WifiConfigView::Cancel() {
    894 }
    895 
    896 void WifiConfigView::Init(bool show_8021x) {
    897   const NetworkState* network = GetNetworkState();
    898   if (network) {
    899     if (network->type() == shill::kTypeWifi) {
    900       if (network->security() == shill::kSecurity8021x)
    901         show_8021x = true;
    902     } else if (network->type() == shill::kTypeEthernet) {
    903       show_8021x = true;
    904     } else {
    905       NOTREACHED() << "Unexpected network type for WifiConfigView: "
    906                    << network->type() << " Path: " << service_path_;
    907     }
    908     ParseEAPUIProperty(&eap_method_ui_data_, network, ::onc::eap::kOuter);
    909     ParseEAPUIProperty(&phase_2_auth_ui_data_, network, ::onc::eap::kInner);
    910     ParseEAPUIProperty(
    911         &user_cert_ui_data_, network, ::onc::eap::kClientCertRef);
    912     ParseEAPUIProperty(
    913         &server_ca_cert_ui_data_, network, ::onc::eap::kServerCARef);
    914     if (server_ca_cert_ui_data_.IsManaged()) {
    915       ParseEAPUIProperty(
    916           &server_ca_cert_ui_data_, network, ::onc::eap::kUseSystemCAs);
    917     }
    918     ParseEAPUIProperty(&identity_ui_data_, network, ::onc::eap::kIdentity);
    919     ParseEAPUIProperty(
    920         &identity_anonymous_ui_data_, network, ::onc::eap::kAnonymousIdentity);
    921     ParseEAPUIProperty(
    922         &save_credentials_ui_data_, network, ::onc::eap::kSaveCredentials);
    923     if (show_8021x)
    924       ParseEAPUIProperty(&passphrase_ui_data_, network, ::onc::eap::kPassword);
    925     else
    926       ParseUIProperty(&passphrase_ui_data_, network, ::onc::wifi::kPassphrase);
    927   }
    928 
    929   views::GridLayout* layout = views::GridLayout::CreatePanel(this);
    930   SetLayoutManager(layout);
    931 
    932   const int column_view_set_id = 0;
    933   views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
    934   const int kPasswordVisibleWidth = 20;
    935   // Label
    936   column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
    937                         views::GridLayout::USE_PREF, 0, 0);
    938   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    939   // Textfield, combobox.
    940   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
    941                         views::GridLayout::USE_PREF, 0,
    942                         ChildNetworkConfigView::kInputFieldMinWidth);
    943   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    944   // Password visible button / policy indicator.
    945   column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
    946                         views::GridLayout::USE_PREF, 0, kPasswordVisibleWidth);
    947 
    948   // SSID input
    949   if (!network || network->type() != shill::kTypeEthernet) {
    950     layout->StartRow(0, column_view_set_id);
    951     layout->AddView(new views::Label(l10n_util::GetStringUTF16(
    952         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID)));
    953     if (!network) {
    954       ssid_textfield_ = new views::Textfield();
    955       ssid_textfield_->set_controller(this);
    956       ssid_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
    957           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID));
    958       layout->AddView(ssid_textfield_);
    959     } else {
    960       views::Label* label =
    961           new views::Label(base::UTF8ToUTF16(network->name()));
    962       label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    963       layout->AddView(label);
    964     }
    965     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    966   }
    967 
    968   // Security select
    969   if (!network && !show_8021x) {
    970     layout->StartRow(0, column_view_set_id);
    971     base::string16 label_text = l10n_util::GetStringUTF16(
    972         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY);
    973     layout->AddView(new views::Label(label_text));
    974     security_combobox_model_.reset(new internal::SecurityComboboxModel);
    975     security_combobox_ = new views::Combobox(security_combobox_model_.get());
    976     security_combobox_->SetAccessibleName(label_text);
    977     security_combobox_->set_listener(this);
    978     layout->AddView(security_combobox_);
    979     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    980   }
    981 
    982   // Only enumerate certificates in the data model for 802.1X networks.
    983   if (show_8021x) {
    984     // Observer any changes to the certificate list.
    985     CertLibrary::Get()->AddObserver(this);
    986 
    987     // EAP method
    988     layout->StartRow(0, column_view_set_id);
    989     base::string16 eap_label_text = l10n_util::GetStringUTF16(
    990         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD);
    991     layout->AddView(new views::Label(eap_label_text));
    992     eap_method_combobox_model_.reset(new internal::EAPMethodComboboxModel);
    993     eap_method_combobox_ = new views::Combobox(
    994         eap_method_combobox_model_.get());
    995     eap_method_combobox_->SetAccessibleName(eap_label_text);
    996     eap_method_combobox_->set_listener(this);
    997     eap_method_combobox_->SetEnabled(eap_method_ui_data_.IsEditable());
    998     layout->AddView(eap_method_combobox_);
    999     layout->AddView(new ControlledSettingIndicatorView(eap_method_ui_data_));
   1000     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1001 
   1002     // Phase 2 authentication
   1003     layout->StartRow(0, column_view_set_id);
   1004     base::string16 phase_2_label_text = l10n_util::GetStringUTF16(
   1005         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH);
   1006     phase_2_auth_label_ = new views::Label(phase_2_label_text);
   1007     layout->AddView(phase_2_auth_label_);
   1008     phase_2_auth_combobox_model_.reset(
   1009         new internal::Phase2AuthComboboxModel(eap_method_combobox_));
   1010     phase_2_auth_combobox_ = new views::Combobox(
   1011         phase_2_auth_combobox_model_.get());
   1012     phase_2_auth_combobox_->SetAccessibleName(phase_2_label_text);
   1013     phase_2_auth_label_->SetEnabled(false);
   1014     phase_2_auth_combobox_->SetEnabled(false);
   1015     phase_2_auth_combobox_->set_listener(this);
   1016     layout->AddView(phase_2_auth_combobox_);
   1017     layout->AddView(new ControlledSettingIndicatorView(phase_2_auth_ui_data_));
   1018     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1019 
   1020     // Server CA certificate
   1021     layout->StartRow(0, column_view_set_id);
   1022     base::string16 server_ca_cert_label_text = l10n_util::GetStringUTF16(
   1023         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA);
   1024     server_ca_cert_label_ = new views::Label(server_ca_cert_label_text);
   1025     layout->AddView(server_ca_cert_label_);
   1026     server_ca_cert_combobox_model_.reset(
   1027         new internal::ServerCACertComboboxModel());
   1028     server_ca_cert_combobox_ = new ComboboxWithWidth(
   1029         server_ca_cert_combobox_model_.get(),
   1030         ChildNetworkConfigView::kInputFieldMinWidth);
   1031     server_ca_cert_combobox_->SetAccessibleName(server_ca_cert_label_text);
   1032     server_ca_cert_label_->SetEnabled(false);
   1033     server_ca_cert_combobox_->SetEnabled(false);
   1034     server_ca_cert_combobox_->set_listener(this);
   1035     layout->AddView(server_ca_cert_combobox_);
   1036     layout->AddView(
   1037         new ControlledSettingIndicatorView(server_ca_cert_ui_data_));
   1038     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1039 
   1040     // Subject Match
   1041     layout->StartRow(0, column_view_set_id);
   1042     base::string16 subject_match_label_text = l10n_util::GetStringUTF16(
   1043         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_SUBJECT_MATCH);
   1044     subject_match_label_ = new views::Label(subject_match_label_text);
   1045     layout->AddView(subject_match_label_);
   1046     subject_match_textfield_ = new views::Textfield();
   1047     subject_match_textfield_->SetAccessibleName(subject_match_label_text);
   1048     subject_match_textfield_->set_controller(this);
   1049     layout->AddView(subject_match_textfield_);
   1050     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1051 
   1052     // User certificate
   1053     layout->StartRow(0, column_view_set_id);
   1054     base::string16 user_cert_label_text = l10n_util::GetStringUTF16(
   1055         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT);
   1056     user_cert_label_ = new views::Label(user_cert_label_text);
   1057     layout->AddView(user_cert_label_);
   1058     user_cert_combobox_model_.reset(new internal::UserCertComboboxModel(this));
   1059     user_cert_combobox_ = new views::Combobox(user_cert_combobox_model_.get());
   1060     user_cert_combobox_->SetAccessibleName(user_cert_label_text);
   1061     user_cert_label_->SetEnabled(false);
   1062     user_cert_combobox_->SetEnabled(false);
   1063     user_cert_combobox_->set_listener(this);
   1064     layout->AddView(user_cert_combobox_);
   1065     layout->AddView(new ControlledSettingIndicatorView(user_cert_ui_data_));
   1066     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1067 
   1068     // Identity
   1069     layout->StartRow(0, column_view_set_id);
   1070     base::string16 identity_label_text = l10n_util::GetStringUTF16(
   1071         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY);
   1072     identity_label_ = new views::Label(identity_label_text);
   1073     layout->AddView(identity_label_);
   1074     identity_textfield_ = new views::Textfield();
   1075     identity_textfield_->SetAccessibleName(identity_label_text);
   1076     identity_textfield_->set_controller(this);
   1077     identity_textfield_->SetEnabled(identity_ui_data_.IsEditable());
   1078     layout->AddView(identity_textfield_);
   1079     layout->AddView(new ControlledSettingIndicatorView(identity_ui_data_));
   1080     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1081   }
   1082 
   1083   // Passphrase input
   1084   layout->StartRow(0, column_view_set_id);
   1085   int label_text_id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE;
   1086   base::string16 passphrase_label_text =
   1087       l10n_util::GetStringUTF16(label_text_id);
   1088   passphrase_label_ = new views::Label(passphrase_label_text);
   1089   layout->AddView(passphrase_label_);
   1090   passphrase_textfield_ = new PassphraseTextfield();
   1091   passphrase_textfield_->set_controller(this);
   1092   // Disable passphrase input initially for other network.
   1093   passphrase_label_->SetEnabled(network);
   1094   passphrase_textfield_->SetEnabled(network &&
   1095                                     passphrase_ui_data_.IsEditable());
   1096   passphrase_textfield_->SetAccessibleName(passphrase_label_text);
   1097   layout->AddView(passphrase_textfield_);
   1098 
   1099   if (passphrase_ui_data_.IsManaged()) {
   1100     layout->AddView(new ControlledSettingIndicatorView(passphrase_ui_data_));
   1101   } else {
   1102     // Password visible button.
   1103     passphrase_visible_button_ = new views::ToggleImageButton(this);
   1104     passphrase_visible_button_->SetFocusable(true);
   1105     passphrase_visible_button_->SetTooltipText(
   1106         l10n_util::GetStringUTF16(
   1107             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_SHOW));
   1108     passphrase_visible_button_->SetToggledTooltipText(
   1109         l10n_util::GetStringUTF16(
   1110             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_HIDE));
   1111     passphrase_visible_button_->SetImage(
   1112         views::ImageButton::STATE_NORMAL,
   1113         ResourceBundle::GetSharedInstance().
   1114         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD));
   1115     passphrase_visible_button_->SetImage(
   1116         views::ImageButton::STATE_HOVERED,
   1117         ResourceBundle::GetSharedInstance().
   1118         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD_HOVER));
   1119     passphrase_visible_button_->SetToggledImage(
   1120         views::ImageButton::STATE_NORMAL,
   1121         ResourceBundle::GetSharedInstance().
   1122         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD));
   1123     passphrase_visible_button_->SetToggledImage(
   1124         views::ImageButton::STATE_HOVERED,
   1125         ResourceBundle::GetSharedInstance().
   1126         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD_HOVER));
   1127     passphrase_visible_button_->SetImageAlignment(
   1128         views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
   1129     layout->AddView(passphrase_visible_button_);
   1130   }
   1131 
   1132   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1133 
   1134   if (show_8021x) {
   1135     // Anonymous identity
   1136     layout->StartRow(0, column_view_set_id);
   1137     identity_anonymous_label_ =
   1138         new views::Label(l10n_util::GetStringUTF16(
   1139             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS));
   1140     layout->AddView(identity_anonymous_label_);
   1141     identity_anonymous_textfield_ = new views::Textfield();
   1142     identity_anonymous_label_->SetEnabled(false);
   1143     identity_anonymous_textfield_->SetEnabled(false);
   1144     identity_anonymous_textfield_->set_controller(this);
   1145     layout->AddView(identity_anonymous_textfield_);
   1146     layout->AddView(
   1147         new ControlledSettingIndicatorView(identity_anonymous_ui_data_));
   1148     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1149   }
   1150 
   1151   // Checkboxes.
   1152 
   1153   // Save credentials
   1154   if (show_8021x) {
   1155     layout->StartRow(0, column_view_set_id);
   1156     save_credentials_checkbox_ = new views::Checkbox(
   1157         l10n_util::GetStringUTF16(
   1158             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS));
   1159     save_credentials_checkbox_->SetEnabled(
   1160         save_credentials_ui_data_.IsEditable());
   1161     layout->SkipColumns(1);
   1162     layout->AddView(save_credentials_checkbox_);
   1163     layout->AddView(
   1164         new ControlledSettingIndicatorView(save_credentials_ui_data_));
   1165   }
   1166 
   1167   // Share network
   1168   if (!network || network->profile_path().empty()) {
   1169     layout->StartRow(0, column_view_set_id);
   1170     share_network_checkbox_ = new views::Checkbox(
   1171         l10n_util::GetStringUTF16(
   1172             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SHARE_NETWORK));
   1173     layout->SkipColumns(1);
   1174     layout->AddView(share_network_checkbox_);
   1175   }
   1176   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1177 
   1178   // Create an error label.
   1179   layout->StartRow(0, column_view_set_id);
   1180   layout->SkipColumns(1);
   1181   error_label_ = new views::Label();
   1182   error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   1183   error_label_->SetEnabledColor(SK_ColorRED);
   1184   layout->AddView(error_label_);
   1185 
   1186   // Initialize the field and checkbox values.
   1187 
   1188   if (!network && show_8021x)
   1189     RefreshEapFields();
   1190 
   1191   RefreshShareCheckbox();
   1192   UpdateErrorLabel();
   1193 
   1194   if (network) {
   1195     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1196         service_path_,
   1197         base::Bind(&WifiConfigView::InitFromProperties,
   1198                    weak_ptr_factory_.GetWeakPtr(),
   1199                    show_8021x),
   1200         base::Bind(&ShillError, "GetProperties"));
   1201   }
   1202 }
   1203 
   1204 void WifiConfigView::InitFromProperties(
   1205     bool show_8021x,
   1206     const std::string& service_path,
   1207     const base::DictionaryValue& properties) {
   1208   if (!show_8021x) {
   1209     std::string passphrase;
   1210     properties.GetStringWithoutPathExpansion(
   1211         shill::kPassphraseProperty, &passphrase);
   1212     passphrase_textfield_->SetText(base::UTF8ToUTF16(passphrase));
   1213     return;
   1214   }
   1215 
   1216   // EAP Method
   1217   std::string eap_method;
   1218   properties.GetStringWithoutPathExpansion(
   1219       shill::kEapMethodProperty, &eap_method);
   1220   if (eap_method == shill::kEapMethodPEAP)
   1221     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_PEAP);
   1222   else if (eap_method == shill::kEapMethodTTLS)
   1223     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TTLS);
   1224   else if (eap_method == shill::kEapMethodTLS)
   1225     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TLS);
   1226   else if (eap_method == shill::kEapMethodLEAP)
   1227     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_LEAP);
   1228   RefreshEapFields();
   1229 
   1230   // Phase 2 authentication and anonymous identity.
   1231   if (Phase2AuthActive()) {
   1232     std::string eap_phase_2_auth;
   1233     properties.GetStringWithoutPathExpansion(
   1234         shill::kEapPhase2AuthProperty, &eap_phase_2_auth);
   1235     if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMD5)
   1236       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MD5);
   1237     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMSCHAPV2)
   1238       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAPV2);
   1239     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMSCHAP)
   1240       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAP);
   1241     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSPAP)
   1242       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_PAP);
   1243     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSCHAP)
   1244       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_CHAP);
   1245 
   1246     std::string eap_anonymous_identity;
   1247     properties.GetStringWithoutPathExpansion(
   1248         shill::kEapAnonymousIdentityProperty, &eap_anonymous_identity);
   1249     identity_anonymous_textfield_->SetText(
   1250         base::UTF8ToUTF16(eap_anonymous_identity));
   1251   }
   1252 
   1253   // Subject match
   1254   std::string subject_match;
   1255   properties.GetStringWithoutPathExpansion(
   1256       shill::kEapSubjectMatchProperty, &subject_match);
   1257   subject_match_textfield_->SetText(base::UTF8ToUTF16(subject_match));
   1258 
   1259   // Server CA certificate.
   1260   if (CaCertActive()) {
   1261     std::string eap_ca_cert_pem;
   1262     const base::ListValue* pems = NULL;
   1263     if (properties.GetListWithoutPathExpansion(
   1264             shill::kEapCaCertPemProperty, &pems))
   1265       pems->GetString(0, &eap_ca_cert_pem);
   1266     if (eap_ca_cert_pem.empty()) {
   1267       bool eap_use_system_cas = false;
   1268       properties.GetBooleanWithoutPathExpansion(
   1269           shill::kEapUseSystemCasProperty, &eap_use_system_cas);
   1270       if (eap_use_system_cas) {
   1271         // "Default"
   1272         server_ca_cert_combobox_->SetSelectedIndex(0);
   1273       } else {
   1274         // "Do not check".
   1275         server_ca_cert_combobox_->SetSelectedIndex(
   1276             server_ca_cert_combobox_->model()->GetItemCount() - 1);
   1277       }
   1278     } else {
   1279       // Select the certificate if available.
   1280       int cert_index =
   1281           CertLibrary::Get()->GetServerCACertIndexByPEM(eap_ca_cert_pem);
   1282       if (cert_index >= 0) {
   1283         // Skip item for "Default".
   1284         server_ca_cert_combobox_->SetSelectedIndex(1 + cert_index);
   1285       } else {
   1286         // "Default"
   1287         server_ca_cert_combobox_->SetSelectedIndex(0);
   1288       }
   1289     }
   1290   }
   1291 
   1292   // User certificate.
   1293   if (UserCertActive()) {
   1294     std::string eap_cert_id;
   1295     properties.GetStringWithoutPathExpansion(
   1296         shill::kEapCertIdProperty, &eap_cert_id);
   1297     if (!eap_cert_id.empty()) {
   1298       int cert_index =
   1299           CertLibrary::Get()->GetUserCertIndexByPkcs11Id(eap_cert_id);
   1300       if (cert_index >= 0)
   1301         user_cert_combobox_->SetSelectedIndex(cert_index);
   1302     }
   1303   }
   1304 
   1305   // Identity is always active.
   1306   std::string eap_identity;
   1307   properties.GetStringWithoutPathExpansion(
   1308       shill::kEapIdentityProperty, &eap_identity);
   1309   identity_textfield_->SetText(base::UTF8ToUTF16(eap_identity));
   1310 
   1311   // Passphrase
   1312   if (PassphraseActive()) {
   1313     std::string eap_password;
   1314     properties.GetStringWithoutPathExpansion(
   1315         shill::kEapPasswordProperty, &eap_password);
   1316     passphrase_textfield_->SetText(base::UTF8ToUTF16(eap_password));
   1317     // If 'Connectable' is True, show a fake passphrase to indicate that it
   1318     // has already been set.
   1319     bool connectable = false;
   1320     properties.GetBooleanWithoutPathExpansion(
   1321         shill::kConnectableProperty, &connectable);
   1322     passphrase_textfield_->SetShowFake(connectable);
   1323   }
   1324 
   1325   // Save credentials
   1326   bool save_credentials = false;
   1327   properties.GetBooleanWithoutPathExpansion(
   1328       shill::kSaveCredentialsProperty, &save_credentials);
   1329   save_credentials_checkbox_->SetChecked(save_credentials);
   1330 
   1331   UpdateDialogButtons();
   1332   RefreshShareCheckbox();
   1333   UpdateErrorLabel();
   1334 }
   1335 
   1336 void WifiConfigView::InitFocus() {
   1337   views::View* view_to_focus = GetInitiallyFocusedView();
   1338   if (view_to_focus)
   1339     view_to_focus->RequestFocus();
   1340 }
   1341 
   1342 bool WifiConfigView::IsConfigureDialog() {
   1343   const NetworkState* network = GetNetworkState();
   1344   return network && network->type() == shill::kTypeEthernet;
   1345 }
   1346 
   1347 void WifiConfigView::NetworkPropertiesUpdated(const NetworkState* network) {
   1348   if (network->path() != service_path_)
   1349     return;
   1350   UpdateErrorLabel();
   1351 }
   1352 
   1353 const NetworkState* WifiConfigView::GetNetworkState() const {
   1354   if (service_path_.empty())
   1355     return NULL;
   1356   return NetworkHandler::Get()->network_state_handler()->GetNetworkState(
   1357       service_path_);
   1358 }
   1359 
   1360 // static
   1361 void WifiConfigView::ParseUIProperty(NetworkPropertyUIData* property_ui_data,
   1362                                      const NetworkState* network,
   1363                                      const std::string& key) {
   1364   ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
   1365   const base::DictionaryValue* onc =
   1366       onc::FindPolicyForActiveUser(network->guid(), &onc_source);
   1367   std::string onc_tag = network->type() == shill::kTypeEthernet
   1368                             ? ::onc::network_config::kEthernet
   1369                             : ::onc::network_config::kWiFi;
   1370   property_ui_data->ParseOncProperty(onc_source, onc, onc_tag + '.' + key);
   1371 }
   1372 
   1373 // static
   1374 void WifiConfigView::ParseEAPUIProperty(NetworkPropertyUIData* property_ui_data,
   1375                                         const NetworkState* network,
   1376                                         const std::string& key) {
   1377   std::string onc_tag = network->type() == shill::kTypeEthernet
   1378                             ? ::onc::ethernet::kEAP
   1379                             : ::onc::wifi::kEAP;
   1380   ParseUIProperty(property_ui_data, network, onc_tag + '.' + key);
   1381 }
   1382 
   1383 }  // namespace chromeos
   1384