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