• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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