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