1 // Copyright (c) 2011 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 "base/command_line.h" // TODO(jamescook): Remove.
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/chromeos/cros/cros_library.h"
11 #include "chrome/browser/chromeos/login/user_manager.h"
12 #include "chrome/browser/chromeos/options/wifi_config_model.h"
13 #include "chrome/common/chrome_switches.h" // TODO(jamescook): Remove.
14 #include "grit/chromium_strings.h"
15 #include "grit/generated_resources.h"
16 #include "grit/locale_settings.h"
17 #include "grit/theme_resources.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "views/controls/button/checkbox.h"
21 #include "views/controls/button/image_button.h"
22 #include "views/controls/button/native_button.h"
23 #include "views/controls/label.h"
24 #include "views/controls/textfield/textfield.h"
25 #include "views/layout/grid_layout.h"
26 #include "views/layout/layout_constants.h"
27 #include "views/window/window.h"
28
29 namespace chromeos {
30
31 namespace {
32
33 enum SecurityComboboxIndex {
34 SECURITY_INDEX_NONE = 0,
35 SECURITY_INDEX_WEP = 1,
36 SECURITY_INDEX_WPA = 2,
37 SECURITY_INDEX_RSN = 3,
38 SECURITY_INDEX_COUNT = 4
39 };
40
41 class SecurityComboboxModel : public ui::ComboboxModel {
42 public:
SecurityComboboxModel()43 SecurityComboboxModel() {}
~SecurityComboboxModel()44 virtual ~SecurityComboboxModel() {}
GetItemCount()45 virtual int GetItemCount() {
46 return SECURITY_INDEX_COUNT;
47 }
GetItemAt(int index)48 virtual string16 GetItemAt(int index) {
49 if (index == SECURITY_INDEX_NONE)
50 return l10n_util::GetStringUTF16(
51 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_NONE);
52 else if (index == SECURITY_INDEX_WEP)
53 return l10n_util::GetStringUTF16(
54 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WEP);
55 else if (index == SECURITY_INDEX_WPA)
56 return l10n_util::GetStringUTF16(
57 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WPA);
58 else if (index == SECURITY_INDEX_RSN)
59 return l10n_util::GetStringUTF16(
60 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_RSN);
61 NOTREACHED();
62 return string16();
63 }
64 private:
65 DISALLOW_COPY_AND_ASSIGN(SecurityComboboxModel);
66 };
67
68 // TODO(jamescook): For M12 we only expose PEAP and EAP-TTLS. Later, when
69 // when we support all methods by default, order this list to be alphabetical.
70 enum EAPMethodComboboxIndex {
71 EAP_METHOD_INDEX_NONE = 0,
72 EAP_METHOD_INDEX_PEAP = 1,
73 EAP_METHOD_INDEX_TTLS = 2, // By default we support up to here.
74 EAP_METHOD_INDEX_TLS = 3,
75 EAP_METHOD_INDEX_LEAP = 4, // Flag "--enable-all-eap" allows up to here.
76 EAP_METHOD_INDEX_COUNT = 5
77 };
78
79 class EAPMethodComboboxModel : public ui::ComboboxModel {
80 public:
EAPMethodComboboxModel()81 EAPMethodComboboxModel() {}
~EAPMethodComboboxModel()82 virtual ~EAPMethodComboboxModel() {}
GetItemCount()83 virtual int GetItemCount() {
84 // TODO(jamescook): For M12 we only expose PEAP and EAP-TTLS by default.
85 // Remove this switch when all methods are supported.
86 if (!CommandLine::ForCurrentProcess()->HasSwitch(
87 switches::kEnableExperimentalEap))
88 return EAP_METHOD_INDEX_TTLS + 1;
89 return EAP_METHOD_INDEX_COUNT;
90 }
GetItemAt(int index)91 virtual string16 GetItemAt(int index) {
92 if (index == EAP_METHOD_INDEX_NONE)
93 return l10n_util::GetStringUTF16(
94 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_NONE);
95 else if (index == EAP_METHOD_INDEX_PEAP)
96 return l10n_util::GetStringUTF16(
97 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_PEAP);
98 else if (index == EAP_METHOD_INDEX_TLS)
99 return l10n_util::GetStringUTF16(
100 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TLS);
101 else if (index == EAP_METHOD_INDEX_TTLS)
102 return l10n_util::GetStringUTF16(
103 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TTLS);
104 else if (index == EAP_METHOD_INDEX_LEAP)
105 return l10n_util::GetStringUTF16(
106 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_LEAP);
107 NOTREACHED();
108 return string16();
109 }
110 private:
111 DISALLOW_COPY_AND_ASSIGN(EAPMethodComboboxModel);
112 };
113
114 enum Phase2AuthComboboxIndex {
115 PHASE_2_AUTH_INDEX_AUTO = 0, // LEAP, EAP-TLS have only this auth.
116 PHASE_2_AUTH_INDEX_MD5 = 1,
117 PHASE_2_AUTH_INDEX_MSCHAPV2 = 2, // PEAP has up to this auth.
118 PHASE_2_AUTH_INDEX_MSCHAP = 3,
119 PHASE_2_AUTH_INDEX_PAP = 4,
120 PHASE_2_AUTH_INDEX_CHAP = 5, // EAP-TTLS has up to this auth.
121 PHASE_2_AUTH_INDEX_COUNT = 6
122 };
123
124 class Phase2AuthComboboxModel : public ui::ComboboxModel {
125 public:
Phase2AuthComboboxModel(views::Combobox * eap_method_combobox)126 explicit Phase2AuthComboboxModel(views::Combobox* eap_method_combobox)
127 : eap_method_combobox_(eap_method_combobox) {}
~Phase2AuthComboboxModel()128 virtual ~Phase2AuthComboboxModel() {}
GetItemCount()129 virtual int GetItemCount() {
130 switch (eap_method_combobox_->selected_item()) {
131 case EAP_METHOD_INDEX_NONE:
132 case EAP_METHOD_INDEX_TLS:
133 case EAP_METHOD_INDEX_LEAP:
134 return PHASE_2_AUTH_INDEX_AUTO + 1;
135 case EAP_METHOD_INDEX_PEAP:
136 return PHASE_2_AUTH_INDEX_MSCHAPV2 + 1;
137 case EAP_METHOD_INDEX_TTLS:
138 return PHASE_2_AUTH_INDEX_CHAP + 1;
139 }
140 NOTREACHED();
141 return 0;
142 }
GetItemAt(int index)143 virtual string16 GetItemAt(int index) {
144 if (index == PHASE_2_AUTH_INDEX_AUTO)
145 return l10n_util::GetStringUTF16(
146 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_AUTO);
147 else if (index == PHASE_2_AUTH_INDEX_MD5)
148 return l10n_util::GetStringUTF16(
149 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MD5);
150 else if (index == PHASE_2_AUTH_INDEX_MSCHAPV2)
151 return l10n_util::GetStringUTF16(
152 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAPV2);
153 else if (index == PHASE_2_AUTH_INDEX_MSCHAP)
154 return l10n_util::GetStringUTF16(
155 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAP);
156 else if (index == PHASE_2_AUTH_INDEX_PAP)
157 return l10n_util::GetStringUTF16(
158 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_PAP);
159 else if (index == PHASE_2_AUTH_INDEX_CHAP)
160 return l10n_util::GetStringUTF16(
161 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_CHAP);
162 NOTREACHED();
163 return string16();
164 }
165 private:
166 views::Combobox* eap_method_combobox_;
167 DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel);
168 };
169
170 // Combobox that supports a preferred width. Used by Server CA combobox
171 // because the strings inside it are too wide.
172 class ComboboxWithWidth : public views::Combobox {
173 public:
ComboboxWithWidth(ui::ComboboxModel * model,int width)174 ComboboxWithWidth(ui::ComboboxModel* model, int width)
175 : Combobox(model),
176 width_(width) {
177 }
~ComboboxWithWidth()178 virtual ~ComboboxWithWidth() {}
GetPreferredSize()179 virtual gfx::Size GetPreferredSize() OVERRIDE {
180 gfx::Size size = Combobox::GetPreferredSize();
181 size.set_width(width_);
182 return size;
183 }
184 private:
185 int width_;
186 DISALLOW_COPY_AND_ASSIGN(ComboboxWithWidth);
187 };
188
189 class ServerCACertComboboxModel : public ui::ComboboxModel {
190 public:
ServerCACertComboboxModel(WifiConfigModel * wifi_config_model)191 explicit ServerCACertComboboxModel(WifiConfigModel* wifi_config_model)
192 : wifi_config_model_(wifi_config_model) {
193 }
~ServerCACertComboboxModel()194 virtual ~ServerCACertComboboxModel() {}
GetItemCount()195 virtual int GetItemCount() {
196 // First "Default", then the certs, then "Do not check".
197 return wifi_config_model_->GetServerCaCertCount() + 2;
198 }
GetItemAt(int combo_index)199 virtual string16 GetItemAt(int combo_index) {
200 if (combo_index == 0)
201 return l10n_util::GetStringUTF16(
202 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
203 if (combo_index == GetItemCount() - 1)
204 return l10n_util::GetStringUTF16(
205 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK);
206 int cert_index = combo_index - 1;
207 return wifi_config_model_->GetServerCaCertName(cert_index);
208 }
209 private:
210 WifiConfigModel* wifi_config_model_;
211 DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
212 };
213
214 class ClientCertComboboxModel : public ui::ComboboxModel {
215 public:
ClientCertComboboxModel(WifiConfigModel * wifi_config_model)216 explicit ClientCertComboboxModel(WifiConfigModel* wifi_config_model)
217 : wifi_config_model_(wifi_config_model) {
218 }
~ClientCertComboboxModel()219 virtual ~ClientCertComboboxModel() {}
GetItemCount()220 virtual int GetItemCount() {
221 // One initial item "None", then the certs.
222 return 1 + wifi_config_model_->GetUserCertCount();
223 }
GetItemAt(int combo_index)224 virtual string16 GetItemAt(int combo_index) {
225 if (combo_index == 0)
226 return l10n_util::GetStringUTF16(
227 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_NONE);
228 int cert_index = combo_index - 1;
229 return wifi_config_model_->GetUserCertName(cert_index);
230 }
231 private:
232 WifiConfigModel* wifi_config_model_;
233 DISALLOW_COPY_AND_ASSIGN(ClientCertComboboxModel);
234 };
235
236 } // namespace
237
WifiConfigView(NetworkConfigView * parent,WifiNetwork * wifi)238 WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
239 : ChildNetworkConfigView(parent, wifi),
240 wifi_config_model_(new WifiConfigModel()),
241 is_8021x_(false),
242 ssid_textfield_(NULL),
243 eap_method_combobox_(NULL),
244 phase_2_auth_label_(NULL),
245 phase_2_auth_combobox_(NULL),
246 client_cert_label_(NULL),
247 client_cert_combobox_(NULL),
248 server_ca_cert_label_(NULL),
249 server_ca_cert_combobox_(NULL),
250 identity_label_(NULL),
251 identity_textfield_(NULL),
252 identity_anonymous_label_(NULL),
253 identity_anonymous_textfield_(NULL),
254 save_credentials_checkbox_(NULL),
255 security_combobox_(NULL),
256 passphrase_label_(NULL),
257 passphrase_textfield_(NULL),
258 passphrase_visible_button_(NULL),
259 error_label_(NULL) {
260 Init(wifi);
261 }
262
WifiConfigView(NetworkConfigView * parent)263 WifiConfigView::WifiConfigView(NetworkConfigView* parent)
264 : ChildNetworkConfigView(parent),
265 wifi_config_model_(new WifiConfigModel()),
266 is_8021x_(false),
267 ssid_textfield_(NULL),
268 eap_method_combobox_(NULL),
269 phase_2_auth_label_(NULL),
270 phase_2_auth_combobox_(NULL),
271 client_cert_label_(NULL),
272 client_cert_combobox_(NULL),
273 server_ca_cert_label_(NULL),
274 server_ca_cert_combobox_(NULL),
275 identity_label_(NULL),
276 identity_textfield_(NULL),
277 identity_anonymous_label_(NULL),
278 identity_anonymous_textfield_(NULL),
279 save_credentials_checkbox_(NULL),
280 security_combobox_(NULL),
281 passphrase_label_(NULL),
282 passphrase_textfield_(NULL),
283 passphrase_visible_button_(NULL),
284 error_label_(NULL) {
285 Init(NULL);
286 }
287
~WifiConfigView()288 WifiConfigView::~WifiConfigView() {
289 }
290
GetTitle()291 string16 WifiConfigView::GetTitle() {
292 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS);
293 }
294
CanLogin()295 bool WifiConfigView::CanLogin() {
296 static const size_t kMinWirelessPasswordLen = 5;
297
298 if (service_path_.empty()) {
299 // Enforce ssid is non empty.
300 if (GetSSID().empty())
301 return false;
302
303 // If security is not none, also enforce passphrase is non empty.
304 if (security_combobox_->selected_item() != SECURITY_INDEX_NONE &&
305 passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
306 return false;
307 } else {
308 if (is_8021x_) {
309 // Make sure the EAP method is set
310 if (eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_NONE)
311 return false;
312 } else {
313 // if the network requires a passphrase, make sure it is the right length.
314 if (passphrase_textfield_ != NULL &&
315 passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
316 return false;
317 }
318 }
319 return true;
320 }
321
UpdateDialogButtons()322 void WifiConfigView::UpdateDialogButtons() {
323 parent_->GetDialogClientView()->UpdateDialogButtons();
324 }
325
RefreshEAPFields()326 void WifiConfigView::RefreshEAPFields() {
327 int selected = eap_method_combobox_->selected_item();
328
329 // If EAP method changes, the phase 2 auth choices may have changed also.
330 phase_2_auth_combobox_->ModelChanged();
331 phase_2_auth_combobox_->SetSelectedItem(0);
332 phase_2_auth_combobox_->SetEnabled(
333 phase_2_auth_combobox_->model()->GetItemCount() > 1);
334 phase_2_auth_label_->SetEnabled(phase_2_auth_combobox_->IsEnabled());
335
336 // No password for EAP-TLS
337 passphrase_textfield_->SetEnabled(selected != EAP_METHOD_INDEX_NONE &&
338 selected != EAP_METHOD_INDEX_TLS);
339 passphrase_label_->SetEnabled(passphrase_textfield_->IsEnabled());
340 if (!passphrase_textfield_->IsEnabled())
341 passphrase_textfield_->SetText(string16());
342
343 // Client certs only for EAP-TLS
344 if (client_cert_combobox_) {
345 client_cert_combobox_->SetEnabled(selected == EAP_METHOD_INDEX_TLS);
346 client_cert_label_->SetEnabled(client_cert_combobox_->IsEnabled());
347 }
348
349 // No server CA certs for LEAP
350 server_ca_cert_combobox_->SetEnabled(selected != EAP_METHOD_INDEX_NONE &&
351 selected != EAP_METHOD_INDEX_LEAP);
352 server_ca_cert_label_->SetEnabled(server_ca_cert_combobox_->IsEnabled());
353
354 // No anonymous identity if no phase 2 auth.
355 identity_anonymous_textfield_->SetEnabled(
356 phase_2_auth_combobox_->IsEnabled());
357 identity_anonymous_label_->SetEnabled(
358 identity_anonymous_textfield_->IsEnabled());
359 if (!identity_anonymous_textfield_->IsEnabled())
360 identity_anonymous_textfield_->SetText(string16());
361 }
362
UpdateErrorLabel()363 void WifiConfigView::UpdateErrorLabel() {
364 std::string error_msg;
365 if (!service_path_.empty()) {
366 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
367 const WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
368 if (wifi && wifi->failed()) {
369 bool passphrase_empty = wifi->GetPassphrase().empty();
370 switch (wifi->error()) {
371 case ERROR_BAD_PASSPHRASE:
372 if (!passphrase_empty) {
373 error_msg = l10n_util::GetStringUTF8(
374 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
375 }
376 break;
377 case ERROR_BAD_WEPKEY:
378 if (!passphrase_empty) {
379 error_msg = l10n_util::GetStringUTF8(
380 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_WEPKEY);
381 }
382 break;
383 default:
384 error_msg = wifi->GetErrorString();
385 break;
386 }
387 }
388 }
389 if (!error_msg.empty()) {
390 error_label_->SetText(UTF8ToWide(error_msg));
391 error_label_->SetVisible(true);
392 } else {
393 error_label_->SetVisible(false);
394 }
395 }
396
ContentsChanged(views::Textfield * sender,const string16 & new_contents)397 void WifiConfigView::ContentsChanged(views::Textfield* sender,
398 const string16& new_contents) {
399 UpdateDialogButtons();
400 }
401
HandleKeyEvent(views::Textfield * sender,const views::KeyEvent & key_event)402 bool WifiConfigView::HandleKeyEvent(views::Textfield* sender,
403 const views::KeyEvent& key_event) {
404 if (sender == passphrase_textfield_ &&
405 key_event.key_code() == ui::VKEY_RETURN) {
406 parent_->GetDialogClientView()->AcceptWindow();
407 }
408 return false;
409 }
410
ButtonPressed(views::Button * sender,const views::Event & event)411 void WifiConfigView::ButtonPressed(views::Button* sender,
412 const views::Event& event) {
413 if (sender == passphrase_visible_button_) {
414 if (passphrase_textfield_)
415 passphrase_textfield_->SetPassword(!passphrase_textfield_->IsPassword());
416 } else {
417 NOTREACHED();
418 }
419 }
420
ItemChanged(views::Combobox * combo_box,int prev_index,int new_index)421 void WifiConfigView::ItemChanged(views::Combobox* combo_box,
422 int prev_index, int new_index) {
423 if (new_index == prev_index)
424 return;
425 if (combo_box == security_combobox_) {
426 // If changed to no security, then disable combobox and clear it.
427 // Otherwise, enable it. Also, update can login.
428 if (new_index == SECURITY_INDEX_NONE) {
429 passphrase_label_->SetEnabled(false);
430 passphrase_textfield_->SetEnabled(false);
431 passphrase_textfield_->SetText(string16());
432 } else {
433 passphrase_label_->SetEnabled(true);
434 passphrase_textfield_->SetEnabled(true);
435 }
436 } else if (combo_box == eap_method_combobox_) {
437 RefreshEAPFields();
438 }
439 UpdateDialogButtons();
440 }
441
Login()442 bool WifiConfigView::Login() {
443 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
444 if (service_path_.empty()) {
445 ConnectionSecurity sec = SECURITY_UNKNOWN;
446 switch (security_combobox_->selected_item()) {
447 case SECURITY_INDEX_NONE:
448 sec = SECURITY_NONE;
449 break;
450 case SECURITY_INDEX_WEP:
451 sec = SECURITY_WEP;
452 break;
453 case SECURITY_INDEX_WPA:
454 sec = SECURITY_WPA;
455 break;
456 case SECURITY_INDEX_RSN:
457 sec = SECURITY_RSN;
458 break;
459 }
460 cros->ConnectToWifiNetwork(
461 sec, GetSSID(), GetPassphrase(), std::string(), std::string());
462 } else {
463 WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
464 if (!wifi) {
465 // Flimflam no longer knows about this wifi network (edge case).
466 // TODO(stevenjb): Add a notification (chromium-os13225).
467 LOG(WARNING) << "Wifi network: " << service_path_ << " no longer exists.";
468 return true;
469 }
470 if (is_8021x_) {
471 // EAP method
472 EAPMethod method = EAP_METHOD_UNKNOWN;
473 switch (eap_method_combobox_->selected_item()) {
474 case EAP_METHOD_INDEX_PEAP:
475 method = EAP_METHOD_PEAP;
476 break;
477 case EAP_METHOD_INDEX_TLS:
478 method = EAP_METHOD_TLS;
479 break;
480 case EAP_METHOD_INDEX_TTLS:
481 method = EAP_METHOD_TTLS;
482 break;
483 case EAP_METHOD_INDEX_LEAP:
484 method = EAP_METHOD_LEAP;
485 break;
486 }
487 DCHECK(method != EAP_METHOD_UNKNOWN);
488 wifi->SetEAPMethod(method);
489
490 // Phase 2 authentication
491 if (phase_2_auth_combobox_->IsEnabled()) {
492 EAPPhase2Auth auth = EAP_PHASE_2_AUTH_AUTO;
493 switch (phase_2_auth_combobox_->selected_item()) {
494 case PHASE_2_AUTH_INDEX_MD5:
495 auth = EAP_PHASE_2_AUTH_MD5;
496 break;
497 case PHASE_2_AUTH_INDEX_MSCHAPV2:
498 auth = EAP_PHASE_2_AUTH_MSCHAPV2;
499 break;
500 case PHASE_2_AUTH_INDEX_MSCHAP:
501 auth = EAP_PHASE_2_AUTH_MSCHAP;
502 break;
503 case PHASE_2_AUTH_INDEX_PAP:
504 auth = EAP_PHASE_2_AUTH_PAP;
505 break;
506 case PHASE_2_AUTH_INDEX_CHAP:
507 auth = EAP_PHASE_2_AUTH_CHAP;
508 break;
509 }
510 wifi->SetEAPPhase2Auth(auth);
511 }
512
513 // Server CA certificate
514 if (server_ca_cert_combobox_->IsEnabled()) {
515 int selected = server_ca_cert_combobox_->selected_item();
516 if (selected == 0) {
517 // First item is "Default".
518 wifi->SetEAPServerCaCertNssNickname(std::string());
519 wifi->SetEAPUseSystemCAs(true);
520 } else if (selected ==
521 server_ca_cert_combobox_->model()->GetItemCount() - 1) {
522 // Last item is "Do not check".
523 wifi->SetEAPServerCaCertNssNickname(std::string());
524 wifi->SetEAPUseSystemCAs(false);
525 } else {
526 int cert_index = selected - 1;
527 std::string nss_nickname =
528 wifi_config_model_->GetServerCaCertNssNickname(cert_index);
529 wifi->SetEAPServerCaCertNssNickname(nss_nickname);
530 }
531 }
532
533 // Client certificate
534 if (client_cert_combobox_ && client_cert_combobox_->IsEnabled()) {
535 int selected = client_cert_combobox_->selected_item();
536 if (selected == 0) {
537 // First item is "None".
538 wifi->SetEAPClientCertPkcs11Id(std::string());
539 } else {
540 // Send cert ID to flimflam.
541 int cert_index = selected - 1;
542 std::string cert_pkcs11_id =
543 wifi_config_model_->GetUserCertPkcs11Id(cert_index);
544 wifi->SetEAPClientCertPkcs11Id(cert_pkcs11_id);
545 }
546 }
547
548 // Identity
549 if (identity_textfield_->IsEnabled()) {
550 wifi->SetEAPIdentity(UTF16ToUTF8(identity_textfield_->text()));
551 }
552
553 // Anonymous identity
554 if (identity_anonymous_textfield_->IsEnabled()) {
555 wifi->SetEAPAnonymousIdentity(
556 UTF16ToUTF8(identity_anonymous_textfield_->text()));
557 }
558
559 // Passphrase
560 if (passphrase_textfield_->IsEnabled()) {
561 wifi->SetEAPPassphrase(UTF16ToUTF8(passphrase_textfield_->text()));
562 }
563
564 // Save credentials
565 wifi->SetSaveCredentials(save_credentials_checkbox_->checked());
566 } else {
567 const std::string passphrase = GetPassphrase();
568 if (passphrase != wifi->passphrase())
569 wifi->SetPassphrase(passphrase);
570 }
571
572 cros->ConnectToWifiNetwork(wifi);
573 // Connection failures are responsible for updating the UI, including
574 // reopening dialogs.
575 }
576 return true; // dialog will be closed
577 }
578
Cancel()579 void WifiConfigView::Cancel() {
580 }
581
GetSSID() const582 std::string WifiConfigView::GetSSID() const {
583 std::string result;
584 if (ssid_textfield_ != NULL) {
585 std::string untrimmed = UTF16ToUTF8(ssid_textfield_->text());
586 TrimWhitespaceASCII(untrimmed, TRIM_ALL, &result);
587 }
588 return result;
589 }
590
GetPassphrase() const591 std::string WifiConfigView::GetPassphrase() const {
592 std::string result;
593 if (passphrase_textfield_ != NULL)
594 result = UTF16ToUTF8(passphrase_textfield_->text());
595 return result;
596 }
597
598 // This will initialize the view depending on if we have a wifi network or not.
599 // And if we are doing simple password encyption or the more complicated
600 // 802.1x encryption.
601 // If we are creating the "Join other network..." dialog, we will allow user
602 // to enter the data. And if they select the 802.1x encryption, we will show
603 // the 802.1x fields.
Init(WifiNetwork * wifi)604 void WifiConfigView::Init(WifiNetwork* wifi) {
605 views::GridLayout* layout = views::GridLayout::CreatePanel(this);
606 SetLayoutManager(layout);
607
608 int column_view_set_id = 0;
609 views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
610 // Label
611 column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
612 views::GridLayout::USE_PREF, 0, 0);
613 // Textfield
614 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
615 views::GridLayout::USE_PREF, 0,
616 ChildNetworkConfigView::kPassphraseWidth);
617 // Password visible button
618 column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
619 views::GridLayout::USE_PREF, 0, 0);
620
621 // SSID input
622 layout->StartRow(0, column_view_set_id);
623 layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
624 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID))));
625 if (!wifi) {
626 ssid_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
627 ssid_textfield_->SetController(this);
628 ssid_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
629 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID));
630 layout->AddView(ssid_textfield_);
631 } else {
632 views::Label* label = new views::Label(UTF8ToWide(wifi->name()));
633 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
634 layout->AddView(label);
635 }
636 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
637
638 // Security select
639 if (!wifi) {
640 layout->StartRow(0, column_view_set_id);
641 layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
642 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY))));
643 security_combobox_ = new views::Combobox(new SecurityComboboxModel());
644 security_combobox_->set_listener(this);
645 layout->AddView(security_combobox_);
646 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
647 }
648
649 is_8021x_ = wifi && wifi->encrypted() &&
650 wifi->encryption() == SECURITY_8021X;
651 if (is_8021x_) {
652 // Only enumerate certificates in the data model for 802.1X networks.
653 wifi_config_model_->UpdateCertificates();
654
655 // EAP method
656 layout->StartRow(0, column_view_set_id);
657 layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
658 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD))));
659 eap_method_combobox_ = new views::Combobox(new EAPMethodComboboxModel());
660 eap_method_combobox_->set_listener(this);
661 layout->AddView(eap_method_combobox_);
662 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
663
664 // Phase 2 authentication
665 layout->StartRow(0, column_view_set_id);
666 phase_2_auth_label_ =
667 new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
668 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH)));
669 layout->AddView(phase_2_auth_label_);
670 phase_2_auth_combobox_ = new views::Combobox(
671 new Phase2AuthComboboxModel(eap_method_combobox_));
672 phase_2_auth_label_->SetEnabled(false);
673 phase_2_auth_combobox_->SetEnabled(false);
674 phase_2_auth_combobox_->set_listener(this);
675 layout->AddView(phase_2_auth_combobox_);
676 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
677
678 // Server CA certificate
679 layout->StartRow(0, column_view_set_id);
680 server_ca_cert_label_ =
681 new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
682 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)));
683 layout->AddView(server_ca_cert_label_);
684 server_ca_cert_combobox_ = new ComboboxWithWidth(
685 new ServerCACertComboboxModel(wifi_config_model_.get()),
686 ChildNetworkConfigView::kPassphraseWidth);
687 server_ca_cert_label_->SetEnabled(false);
688 server_ca_cert_combobox_->SetEnabled(false);
689 server_ca_cert_combobox_->set_listener(this);
690 layout->AddView(server_ca_cert_combobox_);
691 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
692
693 // TODO(jamescook): Add back client certificate combobox when we support
694 // EAP-TLS by default.
695 if (CommandLine::ForCurrentProcess()->HasSwitch(
696 switches::kEnableExperimentalEap)) {
697 // Client certificate
698 layout->StartRow(0, column_view_set_id);
699 client_cert_label_ = new views::Label(
700 UTF16ToWide(l10n_util::GetStringUTF16(
701 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT)));
702 layout->AddView(client_cert_label_);
703 client_cert_combobox_ = new views::Combobox(
704 new ClientCertComboboxModel(wifi_config_model_.get()));
705 client_cert_label_->SetEnabled(false);
706 client_cert_combobox_->SetEnabled(false);
707 client_cert_combobox_->set_listener(this);
708 layout->AddView(client_cert_combobox_);
709 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
710 }
711
712 // Identity
713 layout->StartRow(0, column_view_set_id);
714 identity_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
715 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY)));
716 layout->AddView(identity_label_);
717 identity_textfield_ = new views::Textfield(
718 views::Textfield::STYLE_DEFAULT);
719 identity_textfield_->SetController(this);
720 if (!wifi->identity().empty())
721 identity_textfield_->SetText(UTF8ToUTF16(wifi->identity()));
722 layout->AddView(identity_textfield_);
723 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
724 }
725
726 // Passphrase input
727 layout->StartRow(0, column_view_set_id);
728 int label_text_id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE;
729 passphrase_label_ = new views::Label(
730 UTF16ToWide(l10n_util::GetStringUTF16(label_text_id)));
731 layout->AddView(passphrase_label_);
732 passphrase_textfield_ = new views::Textfield(
733 views::Textfield::STYLE_PASSWORD);
734 passphrase_textfield_->SetController(this);
735 if (wifi && !wifi->GetPassphrase().empty())
736 passphrase_textfield_->SetText(UTF8ToUTF16(wifi->GetPassphrase()));
737 // Disable passphrase input initially for other network.
738 if (!wifi) {
739 passphrase_label_->SetEnabled(false);
740 passphrase_textfield_->SetEnabled(false);
741 }
742 passphrase_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
743 label_text_id));
744 layout->AddView(passphrase_textfield_);
745 // Password visible button.
746 passphrase_visible_button_ = new views::ImageButton(this);
747 passphrase_visible_button_->SetImage(
748 views::ImageButton::BS_NORMAL,
749 ResourceBundle::GetSharedInstance().
750 GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE));
751 passphrase_visible_button_->SetImageAlignment(
752 views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
753 layout->AddView(passphrase_visible_button_);
754 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
755
756 if (is_8021x_) {
757 // Anonymous identity
758 layout->StartRow(0, column_view_set_id);
759 identity_anonymous_label_ =
760 new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
761 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS)));
762 layout->AddView(identity_anonymous_label_);
763 identity_anonymous_textfield_ = new views::Textfield(
764 views::Textfield::STYLE_DEFAULT);
765 identity_anonymous_label_->SetEnabled(false);
766 identity_anonymous_textfield_->SetEnabled(false);
767 identity_anonymous_textfield_->SetController(this);
768 layout->AddView(identity_anonymous_textfield_);
769 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
770
771 // Save credentials
772 layout->StartRow(0, column_view_set_id);
773 save_credentials_checkbox_ = new views::Checkbox(
774 UTF16ToWide(l10n_util::GetStringUTF16(
775 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS)));
776 layout->SkipColumns(1);
777 layout->AddView(save_credentials_checkbox_);
778 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
779 }
780
781 // After creating the fields, we set the values. Fields need to be created
782 // first because RefreshEAPFields() will enable/disable them as appropriate.
783 if (is_8021x_) {
784 // EAP Method
785 switch (wifi->eap_method()) {
786 case EAP_METHOD_PEAP:
787 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_PEAP);
788 break;
789 case EAP_METHOD_TTLS:
790 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TTLS);
791 break;
792 case EAP_METHOD_TLS:
793 if (CommandLine::ForCurrentProcess()->HasSwitch(
794 switches::kEnableExperimentalEap))
795 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TLS);
796 else // Clean up from previous run with the switch set.
797 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_NONE);
798 break;
799 case EAP_METHOD_LEAP:
800 if (CommandLine::ForCurrentProcess()->HasSwitch(
801 switches::kEnableExperimentalEap))
802 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_LEAP);
803 else // Clean up from previous run with the switch set.
804 eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_NONE);
805 break;
806 default:
807 break;
808 }
809 RefreshEAPFields();
810
811 // Phase 2 authentication
812 if (phase_2_auth_combobox_->IsEnabled()) {
813 switch (wifi->eap_phase_2_auth()) {
814 case EAP_PHASE_2_AUTH_MD5:
815 phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MD5);
816 break;
817 case EAP_PHASE_2_AUTH_MSCHAPV2:
818 phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAPV2);
819 break;
820 case EAP_PHASE_2_AUTH_MSCHAP:
821 phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAP);
822 break;
823 case EAP_PHASE_2_AUTH_PAP:
824 phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_PAP);
825 break;
826 case EAP_PHASE_2_AUTH_CHAP:
827 phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_CHAP);
828 break;
829 default:
830 break;
831 }
832 }
833
834 // Server CA certificate
835 if (server_ca_cert_combobox_->IsEnabled()) {
836 const std::string& nss_nickname = wifi->eap_server_ca_cert_nss_nickname();
837 if (nss_nickname.empty()) {
838 if (wifi->eap_use_system_cas()) {
839 // "Default"
840 server_ca_cert_combobox_->SetSelectedItem(0);
841 } else {
842 // "Do not check"
843 server_ca_cert_combobox_->SetSelectedItem(
844 server_ca_cert_combobox_->model()->GetItemCount() - 1);
845 }
846 } else {
847 // select the certificate if available
848 int cert_index = wifi_config_model_->GetServerCaCertIndex(nss_nickname);
849 if (cert_index >= 0) {
850 // Skip item for "Default"
851 server_ca_cert_combobox_->SetSelectedItem(1 + cert_index);
852 }
853 }
854 }
855
856 // Client certificate
857 if (client_cert_combobox_ && client_cert_combobox_->IsEnabled()) {
858 const std::string& pkcs11_id = wifi->eap_client_cert_pkcs11_id();
859 if (pkcs11_id.empty()) {
860 // First item is "None".
861 client_cert_combobox_->SetSelectedItem(0);
862 } else {
863 int cert_index = wifi_config_model_->GetUserCertIndex(pkcs11_id);
864 if (cert_index >= 0) {
865 // Skip item for "None"
866 client_cert_combobox_->SetSelectedItem(1 + cert_index);
867 }
868 }
869 }
870
871 // Identity
872 if (identity_textfield_->IsEnabled())
873 identity_textfield_->SetText(UTF8ToUTF16(wifi->eap_identity()));
874
875 // Anonymous identity
876 if (identity_anonymous_textfield_->IsEnabled())
877 identity_anonymous_textfield_->SetText(
878 UTF8ToUTF16(wifi->eap_anonymous_identity()));
879
880 // Passphrase
881 if (passphrase_textfield_->IsEnabled())
882 passphrase_textfield_->SetText(UTF8ToUTF16(wifi->eap_passphrase()));
883
884 // Save credentials
885 bool save_credentials = (wifi ? wifi->save_credentials() : false);
886 save_credentials_checkbox_->SetChecked(save_credentials);
887 }
888
889 // Create an error label.
890 layout->StartRow(0, column_view_set_id);
891 layout->SkipColumns(1);
892 error_label_ = new views::Label();
893 error_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
894 error_label_->SetColor(SK_ColorRED);
895 layout->AddView(error_label_);
896
897 // Set or hide the error text.
898 UpdateErrorLabel();
899 }
900
InitFocus()901 void WifiConfigView::InitFocus() {
902 // Set focus to a reasonable widget, depending on what we're showing.
903 if (ssid_textfield_)
904 ssid_textfield_->RequestFocus();
905 else if (eap_method_combobox_)
906 eap_method_combobox_->RequestFocus();
907 else if (passphrase_textfield_ && passphrase_textfield_->IsEnabled())
908 passphrase_textfield_->RequestFocus();
909 }
910
911 } // namespace chromeos
912