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