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