shill: add support for connecting to WPA-PSK networks
BUG=chromium-os:20897
TEST=unittests, some autotests (see below)
the following autotests now pass, at least in the wifi_vm_config:
- network_WiFiManager.000_SSID_Length_Limit
- network_WiFiSecMat.010CheckWPA_TKIP
- network_WiFiSecMat.011CheckWPA_AES
- network_WiFiSecMat.012CheckWPA_Multi
- network_WiFiSecMat.018CheckWPA_CounterMeasures
Change-Id: Ie7499fd87f661ceef3ef0aae348a08bd43c305f4
Reviewed-on: http://gerrit.chromium.org/gerrit/8586
Tested-by: mukesh agrawal <quiche@google.com>
Reviewed-by: Paul Stewart <pstew@chromium.org>
diff --git a/wifi_endpoint.cc b/wifi_endpoint.cc
index 300c258..3791bdc 100644
--- a/wifi_endpoint.cc
+++ b/wifi_endpoint.cc
@@ -5,41 +5,35 @@
#include "shill/wifi_endpoint.h"
#include <base/logging.h>
+#include <base/stl_util-inl.h>
#include <base/stringprintf.h>
#include <base/string_number_conversions.h>
+#include <base/string_util.h>
#include <chromeos/dbus/service_constants.h>
+#include "shill/wpa_supplicant.h"
+
+using std::map;
+using std::set;
using std::string;
+using std::vector;
namespace shill {
-const char WiFiEndpoint::kSupplicantPropertySSID[] = "SSID";
-const char WiFiEndpoint::kSupplicantPropertyBSSID[] = "BSSID";
-const char WiFiEndpoint::kSupplicantPropertySignal[] = "Signal";
-const char WiFiEndpoint::kSupplicantPropertyMode[] = "Mode";
-
-const char WiFiEndpoint::kSupplicantNetworkModeInfrastructure[] =
- "infrastructure";
-const char WiFiEndpoint::kSupplicantNetworkModeAdHoc[] = "ad-hoc";
-const char WiFiEndpoint::kSupplicantNetworkModeAccessPoint[] = "ap";
-
-const uint32_t WiFiEndpoint::kSupplicantNetworkModeInfrastructureInt = 0;
-const uint32_t WiFiEndpoint::kSupplicantNetworkModeAdHocInt = 1;
-const uint32_t WiFiEndpoint::kSupplicantNetworkModeAccessPointInt = 2;
-
WiFiEndpoint::WiFiEndpoint(
- const std::map<string, ::DBus::Variant> &properties) {
+ const map<string, ::DBus::Variant> &properties) {
// XXX will segfault on missing properties
ssid_ =
- properties.find(kSupplicantPropertySSID)->second.
+ properties.find(wpa_supplicant::kBSSPropertySSID)->second.
operator std::vector<uint8_t>();
bssid_ =
- properties.find(kSupplicantPropertyBSSID)->second.
+ properties.find(wpa_supplicant::kBSSPropertyBSSID)->second.
operator std::vector<uint8_t>();
signal_strength_ =
- properties.find(kSupplicantPropertySignal)->second;
+ properties.find(wpa_supplicant::kBSSPropertySignal)->second;
network_mode_ = ParseMode(
- properties.find(kSupplicantPropertyMode)->second);
+ properties.find(wpa_supplicant::kBSSPropertyMode)->second);
+ security_mode_ = ParseSecurity(properties);
if (network_mode_.empty()) {
// XXX log error?
@@ -58,16 +52,16 @@
// static
uint32_t WiFiEndpoint::ModeStringToUint(const std::string &mode_string) {
if (mode_string == flimflam::kModeManaged)
- return kSupplicantNetworkModeInfrastructureInt;
+ return wpa_supplicant::kNetworkModeInfrastructureInt;
else if (mode_string == flimflam::kModeAdhoc)
- return kSupplicantNetworkModeAdHocInt;
+ return wpa_supplicant::kNetworkModeAdHocInt;
else
NOTIMPLEMENTED() << "Shill dos not support " << mode_string
<< " mode at this time.";
return 0;
}
-const std::vector<uint8_t> &WiFiEndpoint::ssid() const {
+const vector<uint8_t> &WiFiEndpoint::ssid() const {
return ssid_;
}
@@ -92,16 +86,20 @@
}
const string &WiFiEndpoint::network_mode() const {
- return network_mode_;
+ return network_mode_;
+}
+
+const string &WiFiEndpoint::security_mode() const {
+ return security_mode_;
}
// static
-const char *WiFiEndpoint::ParseMode(const std::string &mode_string) {
- if (mode_string == kSupplicantNetworkModeInfrastructure) {
+const char *WiFiEndpoint::ParseMode(const string &mode_string) {
+ if (mode_string == wpa_supplicant::kNetworkModeInfrastructure) {
return flimflam::kModeManaged;
- } else if (mode_string == kSupplicantNetworkModeAdHoc) {
+ } else if (mode_string == wpa_supplicant::kNetworkModeAdHoc) {
return flimflam::kModeAdhoc;
- } else if (mode_string == kSupplicantNetworkModeAccessPoint) {
+ } else if (mode_string == wpa_supplicant::kNetworkModeAccessPoint) {
NOTREACHED() << "Shill does not support AP mode at this time.";
return NULL;
} else {
@@ -110,4 +108,71 @@
}
}
+// static
+const char *WiFiEndpoint::ParseSecurity(
+ const map<string, ::DBus::Variant> &properties) {
+ set<KeyManagement> rsn_key_management_methods;
+ if (ContainsKey(properties, wpa_supplicant::kPropertyRSN)) {
+ // TODO(quiche): check type before casting
+ const map<string, ::DBus::Variant> rsn_properties(
+ properties.find(wpa_supplicant::kPropertyRSN)->second.
+ operator map<string, ::DBus::Variant>());
+ ParseKeyManagementMethods(rsn_properties, &rsn_key_management_methods);
+ }
+
+ set<KeyManagement> wpa_key_management_methods;
+ if (ContainsKey(properties, wpa_supplicant::kPropertyWPA)) {
+ // TODO(qucihe): check type before casting
+ const map<string, ::DBus::Variant> rsn_properties(
+ properties.find(wpa_supplicant::kPropertyWPA)->second.
+ operator map<string, ::DBus::Variant>());
+ ParseKeyManagementMethods(rsn_properties, &wpa_key_management_methods);
+ }
+
+ bool wep_privacy = false;
+ if (ContainsKey(properties, wpa_supplicant::kPropertyPrivacy)) {
+ wep_privacy = properties.find(wpa_supplicant::kPropertyPrivacy)->second.
+ reader().get_bool();
+ }
+
+ if (ContainsKey(rsn_key_management_methods, kKeyManagement802_1x) ||
+ ContainsKey(wpa_key_management_methods, kKeyManagement802_1x)) {
+ return flimflam::kSecurity8021x;
+ } else if (ContainsKey(rsn_key_management_methods, kKeyManagementPSK)) {
+ return flimflam::kSecurityRsn;
+ } else if (ContainsKey(wpa_key_management_methods, kKeyManagementPSK)) {
+ return flimflam::kSecurityWpa;
+ } else if (wep_privacy) {
+ return flimflam::kSecurityWep;
+ } else {
+ return flimflam::kSecurityNone;
+ }
+}
+
+// static
+void WiFiEndpoint::ParseKeyManagementMethods(
+ const map<string, ::DBus::Variant> &security_method_properties,
+ set<KeyManagement> *key_management_methods) {
+ if (!ContainsKey(security_method_properties,
+ wpa_supplicant::kSecurityMethodPropertyKeyManagement)) {
+ return;
+ }
+
+ // TODO(quiche): check type before cast
+ const vector<string> key_management_vec =
+ security_method_properties.
+ find(wpa_supplicant::kSecurityMethodPropertyKeyManagement)->second.
+ operator vector<string>();
+ for (vector<string>::const_iterator it = key_management_vec.begin();
+ it != key_management_vec.end();
+ ++it) {
+ if (EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixEAP, true)) {
+ key_management_methods->insert(kKeyManagement802_1x);
+ } else if (
+ EndsWith(*it, wpa_supplicant::kKeyManagementMethodSuffixPSK, true)) {
+ key_management_methods->insert(kKeyManagementPSK);
+ }
+ }
+}
+
} // namespace shill