diff options
author | chocobo@chromium.org <chocobo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-22 08:20:26 +0000 |
---|---|---|
committer | chocobo@chromium.org <chocobo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-22 08:20:26 +0000 |
commit | 9100a36587fe017c6243b80834e83ce30864cfb9 (patch) | |
tree | 4faa1a25284ab77c3fb65701b1e1130d296417a1 /chrome/browser | |
parent | df40d9804740ded32c2a28fb197ca835870ce5e4 (diff) | |
download | chromium_src-9100a36587fe017c6243b80834e83ce30864cfb9.zip chromium_src-9100a36587fe017c6243b80834e83ce30864cfb9.tar.gz chromium_src-9100a36587fe017c6243b80834e83ce30864cfb9.tar.bz2 |
Finish initial 802.1x implementation
BUG=chromium-os:11412
TEST=make successful connection to 802.1x network.
Review URL: http://codereview.chromium.org/6713028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78971 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
7 files changed, 589 insertions, 105 deletions
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index e97b838..27611ac 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -152,6 +152,38 @@ const char* kSecurityRsn = "rsn"; const char* kSecurity8021x = "802_1x"; const char* kSecurityNone = "none"; +// Flimflam EAP property names. +const char* kEapIdentityProperty = "EAP.Identity"; +const char* kEapMethodProperty = "EAP.EAP"; +const char* kEapPhase2AuthProperty = "EAP.InnerEAP"; +const char* kEapAnonymousIdentityProperty = "EAP.AnonymousIdentity"; +const char* kEapClientCertProperty = "EAP.ClientCert"; +const char* kEapCertIDProperty = "EAP.CertID"; +const char* kEapPrivateKeyProperty = "EAP.PrivateKey"; +const char* kEapPrivateKeyPasswordProperty = "EAP.PrivateKeyPassword"; +const char* kEapKeyIDProperty = "EAP.KeyID"; +const char* kEapCACertProperty = "EAP.CACert"; +const char* kEapCACertIDProperty = "EAP.CACertID"; +const char* kEapUseSystemCAsProperty = "EAP.UseSystemCAs"; +const char* kEapPinProperty = "EAP.PIN"; +const char* kEapPasswordProperty = "EAP.Password"; +const char* kEapKeyMgmtProperty = "EAP.KeyMgmt"; + +// Flimflam EAP method options. +const std::string& kEapMethodPEAP = "PEAP"; +const std::string& kEapMethodTLS = "TLS"; +const std::string& kEapMethodTTLS = "TTLS"; +const std::string& kEapMethodLEAP = "LEAP"; + +// Flimflam EAP phase 2 auth options. +const std::string& kEapPhase2AuthPEAPMD5 = "auth=MD5"; +const std::string& kEapPhase2AuthPEAPMSCHAPV2 = "auth=MSCHAPV2"; +const std::string& kEapPhase2AuthTTLSMD5 = "autheap=MD5"; +const std::string& kEapPhase2AuthTTLSMSCHAPV2 = "autheap=MSCHAPV2"; +const std::string& kEapPhase2AuthTTLSMSCHAP = "autheap=MSCHAP"; +const std::string& kEapPhase2AuthTTLSPAP = "autheap=PAP"; +const std::string& kEapPhase2AuthTTLSCHAP = "autheap=CHAP"; + // Flimflam state options. const char* kStateIdle = "idle"; const char* kStateCarrier = "carrier"; @@ -297,6 +329,21 @@ enum PropertyIndex { PROPERTY_INDEX_DEFAULT_TECHNOLOGY, PROPERTY_INDEX_DEVICE, PROPERTY_INDEX_DEVICES, + PROPERTY_INDEX_EAP_IDENTITY, + PROPERTY_INDEX_EAP_METHOD, + PROPERTY_INDEX_EAP_PHASE_2_AUTH, + PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY, + PROPERTY_INDEX_EAP_CLIENT_CERT, + PROPERTY_INDEX_EAP_CERT_ID, + PROPERTY_INDEX_EAP_PRIVATE_KEY, + PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD, + PROPERTY_INDEX_EAP_KEY_ID, + PROPERTY_INDEX_EAP_CA_CERT, + PROPERTY_INDEX_EAP_CA_CERT_ID, + PROPERTY_INDEX_EAP_USE_SYSTEM_CAS, + PROPERTY_INDEX_EAP_PIN, + PROPERTY_INDEX_EAP_PASSWORD, + PROPERTY_INDEX_EAP_KEY_MGMT, PROPERTY_INDEX_ENABLED_TECHNOLOGIES, PROPERTY_INDEX_ERROR, PROPERTY_INDEX_ESN, @@ -349,6 +396,21 @@ StringToEnum<PropertyIndex>::Pair property_index_table[] = { { kDefaultTechnologyProperty, PROPERTY_INDEX_DEFAULT_TECHNOLOGY }, { kDeviceProperty, PROPERTY_INDEX_DEVICE }, { kDevicesProperty, PROPERTY_INDEX_DEVICES }, + { kEapIdentityProperty, PROPERTY_INDEX_EAP_IDENTITY }, + { kEapMethodProperty, PROPERTY_INDEX_EAP_METHOD }, + { kEapPhase2AuthProperty, PROPERTY_INDEX_EAP_PHASE_2_AUTH }, + { kEapAnonymousIdentityProperty, PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY }, + { kEapClientCertProperty, PROPERTY_INDEX_EAP_CLIENT_CERT }, + { kEapCertIDProperty, PROPERTY_INDEX_EAP_CERT_ID }, + { kEapPrivateKeyProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY }, + { kEapPrivateKeyPasswordProperty, PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD }, + { kEapKeyIDProperty, PROPERTY_INDEX_EAP_KEY_ID }, + { kEapCACertProperty, PROPERTY_INDEX_EAP_CA_CERT }, + { kEapCACertIDProperty, PROPERTY_INDEX_EAP_CA_CERT_ID }, + { kEapUseSystemCAsProperty, PROPERTY_INDEX_EAP_USE_SYSTEM_CAS }, + { kEapPinProperty, PROPERTY_INDEX_EAP_PIN }, + { kEapPasswordProperty, PROPERTY_INDEX_EAP_PASSWORD }, + { kEapKeyMgmtProperty, PROPERTY_INDEX_EAP_KEY_MGMT }, { kEnabledTechnologiesProperty, PROPERTY_INDEX_ENABLED_TECHNOLOGIES }, { kErrorProperty, PROPERTY_INDEX_ERROR }, { kEsnProperty, PROPERTY_INDEX_ESN }, @@ -530,6 +592,33 @@ static ConnectionSecurity ParseSecurity(const std::string& security) { return parser.Get(security); } +static EAPMethod ParseEAPMethod(const std::string& method) { + static StringToEnum<EAPMethod>::Pair table[] = { + { kEapMethodPEAP.c_str(), EAP_METHOD_PEAP }, + { kEapMethodTLS.c_str(), EAP_METHOD_TLS }, + { kEapMethodTTLS.c_str(), EAP_METHOD_TTLS }, + { kEapMethodLEAP.c_str(), EAP_METHOD_LEAP }, + }; + static StringToEnum<EAPMethod> parser( + table, arraysize(table), EAP_METHOD_UNKNOWN); + return parser.Get(method); +} + +static EAPPhase2Auth ParseEAPPhase2Auth(const std::string& auth) { + static StringToEnum<EAPPhase2Auth>::Pair table[] = { + { kEapPhase2AuthPEAPMD5.c_str(), EAP_PHASE_2_AUTH_MD5 }, + { kEapPhase2AuthPEAPMSCHAPV2.c_str(), EAP_PHASE_2_AUTH_MSCHAPV2 }, + { kEapPhase2AuthTTLSMD5.c_str(), EAP_PHASE_2_AUTH_MD5 }, + { kEapPhase2AuthTTLSMSCHAPV2.c_str(), EAP_PHASE_2_AUTH_MSCHAPV2 }, + { kEapPhase2AuthTTLSMSCHAP.c_str(), EAP_PHASE_2_AUTH_MSCHAP }, + { kEapPhase2AuthTTLSPAP.c_str(), EAP_PHASE_2_AUTH_PAP }, + { kEapPhase2AuthTTLSCHAP.c_str(), EAP_PHASE_2_AUTH_CHAP }, + }; + static StringToEnum<EAPPhase2Auth> parser( + table, arraysize(table), EAP_PHASE_2_AUTH_AUTO); + return parser.Get(auth); +} + //////////////////////////////////////////////////////////////////////////// // Html output helper functions @@ -1229,6 +1318,43 @@ bool WifiNetwork::ParseValue(int index, const Value* value) { return value->GetAsString(&identity_); case PROPERTY_INDEX_CERT_PATH: return value->GetAsString(&cert_path_); + case PROPERTY_INDEX_EAP_METHOD: { + std::string method; + if (value->GetAsString(&method)) { + eap_method_ = ParseEAPMethod(method); + return true; + } + break; + } + case PROPERTY_INDEX_EAP_PHASE_2_AUTH: { + std::string auth; + if (value->GetAsString(&auth)) { + eap_phase_2_auth_ = ParseEAPPhase2Auth(auth); + return true; + } + break; + } + case PROPERTY_INDEX_EAP_IDENTITY: + return value->GetAsString(&eap_identity_); + case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: + return value->GetAsString(&eap_anonymous_identity_); + case PROPERTY_INDEX_EAP_CLIENT_CERT: + return value->GetAsString(&eap_client_cert_path_); + case PROPERTY_INDEX_EAP_CA_CERT: + return value->GetAsString(&eap_server_ca_cert_path_); + case PROPERTY_INDEX_EAP_PASSWORD: + return value->GetAsString(&eap_passphrase_); + case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: + return value->GetAsBoolean(&eap_use_system_cas_); + case PROPERTY_INDEX_EAP_CERT_ID: + case PROPERTY_INDEX_EAP_PRIVATE_KEY: + case PROPERTY_INDEX_EAP_PRIVATE_KEY_PASSWORD: + case PROPERTY_INDEX_EAP_KEY_ID: + case PROPERTY_INDEX_EAP_CA_CERT_ID: + case PROPERTY_INDEX_EAP_PIN: + case PROPERTY_INDEX_EAP_KEY_MGMT: + // These properties are currently not used in the UI. + return true; default: return WirelessNetwork::ParseValue(index, value); } @@ -1264,6 +1390,86 @@ void WifiNetwork::SetCertPath(const std::string& cert_path) { SetStringProperty(kCertPathProperty, cert_path); } +void WifiNetwork::SetEAPMethod(EAPMethod method) { + eap_method_ = method; + switch (method) { + case EAP_METHOD_PEAP: + SetStringProperty(kEapMethodProperty, kEapMethodPEAP); + break; + case EAP_METHOD_TLS: + SetStringProperty(kEapMethodProperty, kEapMethodTLS); + break; + case EAP_METHOD_TTLS: + SetStringProperty(kEapMethodProperty, kEapMethodTTLS); + break; + case EAP_METHOD_LEAP: + SetStringProperty(kEapMethodProperty, kEapMethodLEAP); + break; + default: + SetStringProperty(kEapMethodProperty, std::string()); + break; + } +} + +void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) { + eap_phase_2_auth_ = auth; + bool is_peap = (eap_method_ == EAP_METHOD_PEAP); + switch (auth) { + case EAP_PHASE_2_AUTH_AUTO: + SetStringProperty(kEapPhase2AuthProperty, std::string()); + break; + case EAP_PHASE_2_AUTH_MD5: + SetStringProperty(kEapPhase2AuthProperty, + is_peap ? kEapPhase2AuthPEAPMD5 + : kEapPhase2AuthTTLSMD5); + break; + case EAP_PHASE_2_AUTH_MSCHAPV2: + SetStringProperty(kEapPhase2AuthProperty, + is_peap ? kEapPhase2AuthPEAPMSCHAPV2 + : kEapPhase2AuthTTLSMSCHAPV2); + break; + case EAP_PHASE_2_AUTH_MSCHAP: + SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSMSCHAP); + break; + case EAP_PHASE_2_AUTH_PAP: + SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSPAP); + break; + case EAP_PHASE_2_AUTH_CHAP: + SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSCHAP); + break; + } +} + +void WifiNetwork::SetEAPServerCACert(const std::string& cert_path) { + eap_server_ca_cert_path_ = cert_path; + SetStringProperty(kEapCACertProperty, cert_path); +} + +void WifiNetwork::SetEAPClientCert(const std::string& cert_path) { + eap_client_cert_path_ = cert_path; + SetStringProperty(kEapClientCertProperty, cert_path); +} + +void WifiNetwork::SetEAPUseSystemCAs(bool use_system_cas) { + eap_use_system_cas_ = use_system_cas; + SetBooleanProperty(kEapUseSystemCAsProperty, use_system_cas); +} + +void WifiNetwork::SetEAPIdentity(const std::string& identity) { + eap_identity_ = identity; + SetStringProperty(kEapIdentityProperty, identity); +} + +void WifiNetwork::SetEAPAnonymousIdentity(const std::string& identity) { + eap_anonymous_identity_ = identity; + SetStringProperty(kEapAnonymousIdentityProperty, identity); +} + +void WifiNetwork::SetEAPPassphrase(const std::string& passphrase) { + eap_passphrase_ = passphrase; + SetStringProperty(kEapPasswordProperty, passphrase); +} + std::string WifiNetwork::GetEncryptionString() { switch (encryption_) { case SECURITY_UNKNOWN: @@ -1287,6 +1493,9 @@ bool WifiNetwork::IsPassphraseRequired() const { // (http://crosbug.com/10135). if (error_ == ERROR_BAD_PASSPHRASE || error_ == ERROR_BAD_WEPKEY) return true; + // For 802.1x networks, configuration is required if connectable is false. + if (encryption_ == SECURITY_8021X) + return !connectable_; return passphrase_required_; } @@ -2864,13 +3073,13 @@ class NetworkLibraryImpl : public NetworkLibrary { AddNetwork(wifi3); WifiNetwork* wifi4 = new WifiNetwork("fw4"); - wifi3->set_name("Fake Wifi 802.1x"); - wifi3->set_strength(50); - wifi3->set_connected(false); - wifi3->set_encryption(SECURITY_8021X); - wifi3->set_identity("nobody@google.com"); - wifi3->set_cert_path("SETTINGS:key_id=3,cert_id=3,pin=111111"); - wifi3->set_passphrase_required(true); + wifi4->set_name("Fake Wifi 802.1x"); + wifi4->set_strength(50); + wifi4->set_connected(false); + wifi4->set_connectable(false); + wifi4->set_encryption(SECURITY_8021X); + wifi4->set_identity("nobody@google.com"); + wifi4->set_cert_path("SETTINGS:key_id=3,cert_id=3,pin=111111"); AddNetwork(wifi4); active_wifi_ = wifi1; diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index afc5e0f..e57d6b7 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -111,6 +111,25 @@ enum ConnectionError { ERROR_AAA_FAILED = 11, }; +// We are currently only supporting setting a single EAP Method. +enum EAPMethod { + EAP_METHOD_UNKNOWN = 0, + EAP_METHOD_PEAP = 1, + EAP_METHOD_TLS = 2, + EAP_METHOD_TTLS = 3, + EAP_METHOD_LEAP = 4 +}; + +// We are currently only supporting setting a single EAP phase 2 authentication. +enum EAPPhase2Auth { + EAP_PHASE_2_AUTH_AUTO = 0, + EAP_PHASE_2_AUTH_MD5 = 1, + EAP_PHASE_2_AUTH_MSCHAPV2 = 2, + EAP_PHASE_2_AUTH_MSCHAP = 3, + EAP_PHASE_2_AUTH_PAP = 4, + EAP_PHASE_2_AUTH_CHAP = 5 +}; + // Cellular network is considered low data when less than 60 minues. static const int kCellularDataLowSecs = 60 * 60; @@ -199,8 +218,8 @@ class Network { } ConnectionError error() const { return error_; } ConnectionState state() const { return state_; } - // Is this network connectable. Some networks are not yet ready to be - // connected. For example, an 8021X network without certificates. + // Is this network connectable. Currently, this is mainly used by 802.1x + // networks to specify that the network is not configured yet. bool connectable() const { return connectable_; } // Is this the active network, i.e, the one through which // network traffic is being routed? A network can be connected, @@ -429,7 +448,10 @@ class WifiNetwork : public WirelessNetwork { explicit WifiNetwork(const std::string& service_path) : WirelessNetwork(service_path, TYPE_WIFI), encryption_(SECURITY_NONE), - passphrase_required_(false) { + passphrase_required_(false), + eap_method_(EAP_METHOD_UNKNOWN), + eap_phase_2_auth_(EAP_PHASE_2_AUTH_AUTO), + eap_use_system_cas_(true) { } bool encrypted() const { return encryption_ != SECURITY_NONE; } @@ -438,12 +460,33 @@ class WifiNetwork : public WirelessNetwork { const std::string& identity() const { return identity_; } const std::string& cert_path() const { return cert_path_; } + EAPMethod eap_method() const { return eap_method_; } + EAPPhase2Auth eap_phase_2_auth() const { return eap_phase_2_auth_; } + const std::string& eap_server_ca_cert() const { + return eap_server_ca_cert_path_; } + const std::string& eap_client_cert() const { return eap_client_cert_path_; } + const bool eap_use_system_cas() const { return eap_use_system_cas_; } + const std::string& eap_identity() const { return eap_identity_; } + const std::string& eap_anonymous_identity() const { + return eap_anonymous_identity_; } + const std::string& eap_passphrase() const { return eap_passphrase_; } + const std::string& GetPassphrase() const; void SetPassphrase(const std::string& passphrase); void SetIdentity(const std::string& identity); void SetCertPath(const std::string& cert_path); + // 802.1x properties + void SetEAPMethod(EAPMethod method); + void SetEAPPhase2Auth(EAPPhase2Auth auth); + void SetEAPServerCACert(const std::string& cert_path); + void SetEAPClientCert(const std::string& cert_path); + void SetEAPUseSystemCAs(bool use_system_cas); + void SetEAPIdentity(const std::string& identity); + void SetEAPAnonymousIdentity(const std::string& identity); + void SetEAPPassphrase(const std::string& passphrase); + // Return a string representation of the encryption code. // This not translated and should be only used for debugging purposes. std::string GetEncryptionString(); @@ -481,6 +524,15 @@ class WifiNetwork : public WirelessNetwork { std::string identity_; std::string cert_path_; + EAPMethod eap_method_; + EAPPhase2Auth eap_phase_2_auth_; + std::string eap_server_ca_cert_path_; + std::string eap_client_cert_path_; + bool eap_use_system_cas_; + std::string eap_identity_; + std::string eap_anonymous_identity_; + std::string eap_passphrase_; + // Internal state (not stored in flimflam). // Passphrase set by user (stored for UI). std::string user_passphrase_; diff --git a/chrome/browser/chromeos/options/network_config_view.cc b/chrome/browser/chromeos/options/network_config_view.cc index 3012a05..80eea6a 100644 --- a/chrome/browser/chromeos/options/network_config_view.cc +++ b/chrome/browser/chromeos/options/network_config_view.cc @@ -89,8 +89,8 @@ void NetworkConfigView::Layout() { gfx::Size NetworkConfigView::GetPreferredSize() { // TODO(chocobo): Once UI is finalized, create locale settings. gfx::Size result(views::Window::GetLocalizedContentsSize( - IDS_IMPORT_DIALOG_WIDTH_CHARS, - IDS_IMPORT_DIALOG_HEIGHT_LINES)); + IDS_ABOUT_DIALOG_WIDTH_CHARS, + IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES)); result.set_height(wificonfig_view_->GetPreferredSize().height()); return result; } diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc index 4a92ccb..01f09e3 100644 --- a/chrome/browser/chromeos/options/wifi_config_view.cc +++ b/chrome/browser/chromeos/options/wifi_config_view.cc @@ -160,6 +160,43 @@ class Phase2AuthComboboxModel : public ui::ComboboxModel { DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel); }; +// TODO(chocobo): Added logic for getting server CA certs combobox populated. +class ServerCACertComboboxModel : public ui::ComboboxModel { + public: + ServerCACertComboboxModel() {} + virtual ~ServerCACertComboboxModel() {} + virtual int GetItemCount() { + return 3; + } + virtual string16 GetItemAt(int index) { + if (index == 0) + return l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_USE_SYSTEM); + if (index == GetItemCount()-1) + return l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_DO_NOT_CHECK); + return UTF8ToUTF16("/tmp/ca-cert.pem"); + } + private: + DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel); +}; + +// TODO(chocobo): Added logic for getting client certs combobox populated. +class ClientCertComboboxModel : public ui::ComboboxModel { + public: + ClientCertComboboxModel() {} + virtual ~ClientCertComboboxModel() {} + virtual int GetItemCount() { + return 1; + } + virtual string16 GetItemAt(int index) { + return l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_NONE); + } + private: + DISALLOW_COPY_AND_ASSIGN(ClientCertComboboxModel); +}; + } // namespace WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi) @@ -169,6 +206,8 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi) ssid_textfield_(NULL), eap_method_combobox_(NULL), phase_2_auth_combobox_(NULL), + client_cert_combobox_(NULL), + server_ca_cert_combobox_(NULL), identity_textfield_(NULL), identity_anonymous_textfield_(NULL), certificate_browse_button_(NULL), @@ -186,6 +225,8 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent) ssid_textfield_(NULL), eap_method_combobox_(NULL), phase_2_auth_combobox_(NULL), + client_cert_combobox_(NULL), + server_ca_cert_combobox_(NULL), identity_textfield_(NULL), identity_anonymous_textfield_(NULL), certificate_browse_button_(NULL), @@ -217,18 +258,12 @@ bool WifiConfigView::CanLogin() { // Make sure the EAP method is set if (eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_NONE) return false; - - // If we have an identity field, we can login if we have a non empty - // identity and a certificate path - if (identity_textfield_ != NULL && - (identity_textfield_->text().empty() || certificate_path_.empty())) + } else { + // if the network requires a passphrase, make sure it is the right length. + if (passphrase_textfield_ != NULL && + passphrase_textfield_->text().length() < kMinWirelessPasswordLen) return false; } - - // if the network requires a passphrase, make sure it is the right length. - if (passphrase_textfield_ != NULL && - passphrase_textfield_->text().length() < kMinWirelessPasswordLen) - return false; } return true; } @@ -237,6 +272,35 @@ void WifiConfigView::UpdateDialogButtons() { parent_->GetDialogClientView()->UpdateDialogButtons(); } +void WifiConfigView::RefreshEAPFields() { + int selected = eap_method_combobox_->selected_item(); + + // If EAP method changes, the phase 2 auth choices may have changed also. + phase_2_auth_combobox_->ModelChanged(); + phase_2_auth_combobox_->SetSelectedItem(0); + phase_2_auth_combobox_->SetEnabled( + phase_2_auth_combobox_->model()->GetItemCount() > 1); + + // No password for EAP-TLS + passphrase_textfield_->SetEnabled(selected != EAP_METHOD_INDEX_NONE && + selected != EAP_METHOD_INDEX_TLS); + if (!passphrase_textfield_->IsEnabled()) + passphrase_textfield_->SetText(string16()); + + // Client certs only for EAP-TLS + client_cert_combobox_->SetEnabled(selected == EAP_METHOD_INDEX_TLS); + + // No server CA certs for LEAP + server_ca_cert_combobox_->SetEnabled(selected != EAP_METHOD_INDEX_NONE && + selected != EAP_METHOD_INDEX_LEAP); + + // No anonymous identity if no phase 2 auth. + identity_anonymous_textfield_->SetEnabled( + phase_2_auth_combobox_->IsEnabled()); + if (!identity_anonymous_textfield_->IsEnabled()) + identity_anonymous_textfield_->SetText(string16()); +} + void WifiConfigView::UpdateErrorLabel(bool failed) { static const int kNoError = -1; int id = kNoError; @@ -312,31 +376,7 @@ void WifiConfigView::ItemChanged(views::Combobox* combo_box, passphrase_textfield_->SetEnabled(true); } } else if (combo_box == eap_method_combobox_) { - // If EAP method changes, the phase 2 auth choices may have changed also. - phase_2_auth_combobox_->ModelChanged(); - phase_2_auth_combobox_->SetSelectedItem(0); - phase_2_auth_combobox_->SetEnabled( - phase_2_auth_combobox_->model()->GetItemCount() > 1); - - // No password for EAP-TLS - if (eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_TLS) { - passphrase_textfield_->SetEnabled(false); - passphrase_textfield_->SetText(string16()); - } else { - passphrase_textfield_->SetEnabled(true); - } - - // No client certs for EAP-TTLS, PEAP, or LEAP - - // No server certs for LEAP - - // No anonymous identity if no phase 2 auth. - if (phase_2_auth_combobox_->model()->GetItemCount() > 1) { - identity_anonymous_textfield_->SetEnabled(true); - } else { - identity_anonymous_textfield_->SetEnabled(false); - identity_anonymous_textfield_->SetText(string16()); - } + RefreshEAPFields(); } UpdateDialogButtons(); } @@ -352,22 +392,27 @@ void WifiConfigView::FileSelected(const FilePath& path, } bool WifiConfigView::Login() { - std::string identity_string; - if (identity_textfield_ != NULL) { - identity_string = UTF16ToUTF8(identity_textfield_->text()); - } NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); if (service_path_.empty()) { + std::string identity_string; + if (identity_textfield_ != NULL) { + identity_string = UTF16ToUTF8(identity_textfield_->text()); + } ConnectionSecurity sec = SECURITY_UNKNOWN; - int index = security_combobox_->selected_item(); - if (index == SECURITY_INDEX_NONE) - sec = SECURITY_NONE; - else if (index == SECURITY_INDEX_WEP) - sec = SECURITY_WEP; - else if (index == SECURITY_INDEX_WPA) - sec = SECURITY_WPA; - else if (index == SECURITY_INDEX_RSN) - sec = SECURITY_RSN; + switch (security_combobox_->selected_item()) { + case SECURITY_INDEX_NONE: + sec = SECURITY_NONE; + break; + case SECURITY_INDEX_WEP: + sec = SECURITY_WEP; + break; + case SECURITY_INDEX_WPA: + sec = SECURITY_WPA; + break; + case SECURITY_INDEX_RSN: + sec = SECURITY_RSN; + break; + } cros->ConnectToWifiNetwork( sec, GetSSID(), GetPassphrase(), identity_string, certificate_path_, true); @@ -380,9 +425,96 @@ bool WifiConfigView::Login() { return true; } if (is_8021x_) { - // TODO(chocobo): Set 802.1x properties + // EAP method + EAPMethod method = EAP_METHOD_UNKNOWN; + switch (eap_method_combobox_->selected_item()) { + case EAP_METHOD_INDEX_PEAP: + method = EAP_METHOD_PEAP; + break; + case EAP_METHOD_INDEX_TLS: + method = EAP_METHOD_TLS; + break; + case EAP_METHOD_INDEX_TTLS: + method = EAP_METHOD_TTLS; + break; + case EAP_METHOD_INDEX_LEAP: + method = EAP_METHOD_LEAP; + break; + } + DCHECK(method != EAP_METHOD_UNKNOWN); + wifi->SetEAPMethod(method); + + // Phase 2 authentication + if (phase_2_auth_combobox_->IsEnabled()) { + EAPPhase2Auth auth = EAP_PHASE_2_AUTH_AUTO; + switch (phase_2_auth_combobox_->selected_item()) { + case PHASE_2_AUTH_INDEX_MD5: + auth = EAP_PHASE_2_AUTH_MD5; + break; + case PHASE_2_AUTH_INDEX_MSCHAPV2: + auth = EAP_PHASE_2_AUTH_MSCHAPV2; + break; + case PHASE_2_AUTH_INDEX_MSCHAP: + auth = EAP_PHASE_2_AUTH_MSCHAP; + break; + case PHASE_2_AUTH_INDEX_PAP: + auth = EAP_PHASE_2_AUTH_PAP; + break; + case PHASE_2_AUTH_INDEX_CHAP: + auth = EAP_PHASE_2_AUTH_CHAP; + break; + } + wifi->SetEAPPhase2Auth(auth); + } + + // Server CA certificate + if (server_ca_cert_combobox_->IsEnabled()) { + int selected = server_ca_cert_combobox_->selected_item(); + if (selected == 0) { + wifi->SetEAPServerCACert(std::string()); + wifi->SetEAPUseSystemCAs(true); + } else if (selected == + server_ca_cert_combobox_->model()->GetItemCount()-1) { + wifi->SetEAPServerCACert(std::string()); + wifi->SetEAPUseSystemCAs(false); + } else { + wifi->SetEAPServerCACert(UTF16ToUTF8( + server_ca_cert_combobox_->model()->GetItemAt(selected))); + } + } + + // Client certificate + if (client_cert_combobox_->IsEnabled()) { + int selected = client_cert_combobox_->selected_item(); + if (selected == 0) { + wifi->SetEAPClientCert(std::string()); + } else { + wifi->SetEAPClientCert( + UTF16ToUTF8(client_cert_combobox_->model()->GetItemAt(selected))); + } + } + + // Identity + if (identity_textfield_->IsEnabled()) { + wifi->SetEAPIdentity(UTF16ToUTF8(identity_textfield_->text())); + } + + // Anonymous identity + if (identity_anonymous_textfield_->IsEnabled()) { + wifi->SetEAPAnonymousIdentity( + UTF16ToUTF8(identity_anonymous_textfield_->text())); + } + + // Passphrase + if (passphrase_textfield_->IsEnabled()) { + wifi->SetEAPPassphrase(UTF16ToUTF8(passphrase_textfield_->text())); + } + } else { + const std::string passphrase = GetPassphrase(); + if (passphrase != wifi->passphrase()) + wifi->SetPassphrase(passphrase); } - wifi->SetPassphrase(GetPassphrase()); + cros->ConnectToWifiNetwork(wifi); // Connection failures are responsible for updating the UI, including // reopening dialogs. @@ -459,20 +591,10 @@ void WifiConfigView::Init(WifiNetwork* wifi) { layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); } - // Certificate input - // Loaded certificates (i.e. stored in a pkcs11 device) do not require - // a passphrase. - bool certificate_loaded = false; - - // Add ID and cert password if we're using 802.1x - // XXX we're cheating and assuming 802.1x means EAP-TLS - not true - // in general, but very common. WPA Supplicant doesn't report the - // EAP type because it's unknown until the process begins, and we'd - // need some kind of callback. is_8021x_ = wifi && wifi->encrypted() && wifi->encryption() == SECURITY_8021X; if (is_8021x_) { - // EAP Method + // EAP method layout->StartRow(0, column_view_set_id); layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD)))); @@ -481,7 +603,7 @@ void WifiConfigView::Init(WifiNetwork* wifi) { layout->AddView(eap_method_combobox_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); - // Phase 2 Authentication + // Phase 2 authentication layout->StartRow(0, column_view_set_id); layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH)))); @@ -492,30 +614,26 @@ void WifiConfigView::Init(WifiNetwork* wifi) { layout->AddView(phase_2_auth_combobox_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); - // Certificate + // Server CA certificate + layout->StartRow(0, column_view_set_id); + layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( + IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)))); + server_ca_cert_combobox_ = new views::Combobox( + new ServerCACertComboboxModel()); + server_ca_cert_combobox_->SetEnabled(false); + server_ca_cert_combobox_->set_listener(this); + layout->AddView(server_ca_cert_combobox_); + layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + + // Client certificate layout->StartRow(0, column_view_set_id); layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT)))); - if (!wifi->cert_path().empty()) { - certificate_path_ = wifi->cert_path(); - certificate_loaded = wifi->IsCertificateLoaded(); - } - if (certificate_loaded) { - std::wstring label = UTF16ToWide(l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_INSTALLED)); - views::Label* cert_text = new views::Label(label); - cert_text->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - layout->AddView(cert_text); - } else { - std::wstring label; - if (!certificate_path_.empty()) - label = UTF8ToWide(certificate_path_); - else - label = UTF16ToWide(l10n_util::GetStringUTF16( - IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_BUTTON)); - certificate_browse_button_ = new views::NativeButton(this, label); - layout->AddView(certificate_browse_button_); - } + client_cert_combobox_ = new views::Combobox( + new ClientCertComboboxModel()); + client_cert_combobox_->SetEnabled(false); + client_cert_combobox_->set_listener(this); + layout->AddView(client_cert_combobox_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); // Identity @@ -530,7 +648,7 @@ void WifiConfigView::Init(WifiNetwork* wifi) { layout->AddView(identity_textfield_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); - // Anonymous Identity + // Anonymous identity layout->StartRow(0, column_view_set_id); layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16( IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS)))); @@ -573,6 +691,108 @@ void WifiConfigView::Init(WifiNetwork* wifi) { layout->AddView(passphrase_visible_button_); layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); + // After creating the fields, we set the values. Fields need to be created + // first because RefreshEAPFields() will enable/disable them as appropriate. + if (is_8021x_) { + // EAP Method + switch (wifi->eap_method()) { + case EAP_METHOD_PEAP: + eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_PEAP); + break; + case EAP_METHOD_TLS: + eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TLS); + break; + case EAP_METHOD_TTLS: + eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TTLS); + break; + case EAP_METHOD_LEAP: + eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_LEAP); + break; + default: + break; + } + RefreshEAPFields(); + + // Phase 2 authentication + if (phase_2_auth_combobox_->IsEnabled()) { + switch (wifi->eap_phase_2_auth()) { + case EAP_PHASE_2_AUTH_MD5: + phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MD5); + break; + case EAP_PHASE_2_AUTH_MSCHAPV2: + phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAPV2); + break; + case EAP_PHASE_2_AUTH_MSCHAP: + phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAP); + break; + case EAP_PHASE_2_AUTH_PAP: + phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_PAP); + break; + case EAP_PHASE_2_AUTH_CHAP: + phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_CHAP); + break; + default: + break; + } + } + + // Server CA certificate + if (server_ca_cert_combobox_->IsEnabled()) { + const std::string& cert = wifi->eap_server_ca_cert(); + if (cert.empty()) { + if (wifi->eap_use_system_cas()) + server_ca_cert_combobox_->SetSelectedItem(0); + else // select last item for "Do Not Check" + server_ca_cert_combobox_->SetSelectedItem( + server_ca_cert_combobox_->model()->GetItemCount()-1); + } else { + // select the certificate path if available + // Note: the last item is "Do Not Check" so no need to compare that. + for (int i = 1; + i < server_ca_cert_combobox_->model()->GetItemCount()-1; + i++) { + if (cert == + UTF16ToUTF8(server_ca_cert_combobox_->model()->GetItemAt(i))) { + server_ca_cert_combobox_->SetSelectedItem(i); + break; + } + } + } + } + + // Client certificate + if (client_cert_combobox_->IsEnabled()) { + const std::string& cert = wifi->eap_client_cert(); + if (cert.empty()) { + client_cert_combobox_->SetSelectedItem(0); + } else { + // select the certificate path if available + for (int i = 1; + i < client_cert_combobox_->model()->GetItemCount(); + i++) { + if (cert == + UTF16ToUTF8(client_cert_combobox_->model()->GetItemAt(i))) { + client_cert_combobox_->SetSelectedItem(i); + break; + } + } + } + } + + // Identity + if (identity_textfield_->IsEnabled()) + identity_textfield_->SetText(UTF8ToUTF16(wifi->eap_identity())); + + // Anonymous identity + if (identity_anonymous_textfield_->IsEnabled()) + identity_anonymous_textfield_->SetText( + UTF8ToUTF16(wifi->eap_anonymous_identity())); + + // Passphrase + if (passphrase_textfield_->IsEnabled()) + passphrase_textfield_->SetText(UTF8ToUTF16(wifi->eap_passphrase())); + } + // Create an error label. layout->StartRow(0, column_view_set_id); layout->SkipColumns(1); diff --git a/chrome/browser/chromeos/options/wifi_config_view.h b/chrome/browser/chromeos/options/wifi_config_view.h index 3aa52a8..b2d37b2 100644 --- a/chrome/browser/chromeos/options/wifi_config_view.h +++ b/chrome/browser/chromeos/options/wifi_config_view.h @@ -78,6 +78,9 @@ class WifiConfigView : public views::View, // Updates state of the Login button. void UpdateDialogButtons(); + // Enable/Disable EAP fields as appropriate based on selected EAP method. + void RefreshEAPFields(); + // Updates the error text label. void UpdateErrorLabel(bool failed); @@ -91,6 +94,8 @@ class WifiConfigView : public views::View, views::Textfield* ssid_textfield_; views::Combobox* eap_method_combobox_; views::Combobox* phase_2_auth_combobox_; + views::Combobox* client_cert_combobox_; + views::Combobox* server_ca_cert_combobox_; views::Textfield* identity_textfield_; views::Textfield* identity_anonymous_textfield_; views::NativeButton* certificate_browse_button_; diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc index 157afb4..2415490 100644 --- a/chrome/browser/chromeos/status/network_menu.cc +++ b/chrome/browser/chromeos/status/network_menu.cc @@ -612,7 +612,9 @@ void NetworkMenu::InitMenuItems() { const SkBitmap* badge = wifi_networks[i]->encrypted() ? rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : NULL; int flag = FLAG_WIFI; - if (!wifi_networks[i]->connectable()) + // If a network is not connectable from login/oobe, we disable it. + // We do not allow configuring a network (e.g. 802.1x) from login/oobe. + if (!IsBrowserMode() && !wifi_networks[i]->connectable()) flag |= FLAG_DISABLED; if (active_wifi && wifi_networks[i]->service_path() == active_wifi->service_path()) @@ -672,8 +674,6 @@ void NetworkMenu::InitMenuItems() { const SkBitmap* badge = BadgeForNetworkTechnology(cell_networks[i]); const SkBitmap* roaming_badge = BadgeForRoamingStatus(cell_networks[i]); int flag = FLAG_CELLULAR; - if (!cell_networks[i]->connectable()) - flag |= FLAG_DISABLED; bool isActive = active_cellular && cell_networks[i]->service_path() == active_cellular->service_path() && (cell_networks[i]->connecting() || cell_networks[i]->connected()); diff --git a/chrome/browser/resources/options/chromeos_internet_network_element.js b/chrome/browser/resources/options/chromeos_internet_network_element.js index 5d9da41..d68be67 100644 --- a/chrome/browser/resources/options/chromeos_internet_network_element.js +++ b/chrome/browser/resources/options/chromeos_internet_network_element.js @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -81,7 +81,7 @@ cr.define('options.internet', function() { while (item && !item.data) { item = item.parentNode; } - if (item.connecting || !item.connectable) + if (item.connecting) return; if (item) { @@ -226,10 +226,8 @@ cr.define('options.internet', function() { 'disconnect']); })); } - if (!this.data.connected && !this.data.connecting && - this.data.connectable) { - // connect button (if not ethernet and not showing activate button - // and connectable) + if (!this.data.connected && !this.data.connecting) { + // connect button (if not ethernet and not showing activate button) if (this.data.networkType != Constants.TYPE_ETHERNET && !show_activate && !no_plan) { buttonsDiv.appendChild( |