summaryrefslogtreecommitdiffstats
path: root/components/wifi_sync
diff options
context:
space:
mode:
authorquiche <quiche@chromium.org>2015-01-09 17:21:47 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-10 01:22:45 +0000
commit80674e39108f7c132716a5c8c9a9056ec4716d1e (patch)
tree355a8fc977cabb66d619376f31cf62fa59b30219 /components/wifi_sync
parent8c03af4290db10990cb4a0bb37cd2dbd4ea41605 (diff)
downloadchromium_src-80674e39108f7c132716a5c8c9a9056ec4716d1e.zip
chromium_src-80674e39108f7c132716a5c8c9a9056ec4716d1e.tar.gz
chromium_src-80674e39108f7c132716a5c8c9a9056ec4716d1e.tar.bz2
wifi_sync: add ability to convert WifiCredential to onc properties
There will be a couple of places where we need to convert from a WifiCredential, to a DictionaryValue of ONC properties. So let's put the conversion code someplace where it can be re-used. The two places we'll need to convert a WifiCredential to ONC properties will be WifiConfigDelegate and sync integration tests. Both will need ONC properties to create a network in the platform-specific network configuration for ChromeOS. BUG=chromium:431435 TEST=components_unittests --gtest_filter="Wifi*" Review URL: https://codereview.chromium.org/809803005 Cr-Commit-Position: refs/heads/master@{#310930}
Diffstat (limited to 'components/wifi_sync')
-rw-r--r--components/wifi_sync/BUILD.gn1
-rw-r--r--components/wifi_sync/network_state_helper_chromeos.cc10
-rw-r--r--components/wifi_sync/wifi_credential.cc80
-rw-r--r--components/wifi_sync/wifi_credential.h44
-rw-r--r--components/wifi_sync/wifi_credential_unittest.cc140
5 files changed, 256 insertions, 19 deletions
diff --git a/components/wifi_sync/BUILD.gn b/components/wifi_sync/BUILD.gn
index 38626ba..9ca41db 100644
--- a/components/wifi_sync/BUILD.gn
+++ b/components/wifi_sync/BUILD.gn
@@ -34,6 +34,7 @@ source_set("unit_tests") {
]
sources = [
+ "wifi_credential_unittest.cc",
"wifi_security_class_chromeos_unittest.cc",
"wifi_security_class_unittest.cc",
]
diff --git a/components/wifi_sync/network_state_helper_chromeos.cc b/components/wifi_sync/network_state_helper_chromeos.cc
index 5cf6f18..f7afa73 100644
--- a/components/wifi_sync/network_state_helper_chromeos.cc
+++ b/components/wifi_sync/network_state_helper_chromeos.cc
@@ -33,11 +33,15 @@ WifiCredential::CredentialSet GetWifiCredentialsForShillProfile(
// TODO(quiche): Fill in the actual passphrase via an asynchronous
// call to a chromeos::NetworkConfigurationHandler instance's
// GetProperties method.
- credentials.insert(
- WifiCredential(
+ scoped_ptr<WifiCredential> credential =
+ WifiCredential::Create(
network->raw_ssid(),
WifiSecurityClassFromShillSecurity(network->security_class()),
- "" /* empty passphrase */));
+ "" /* empty passphrase */);
+ if (!credential)
+ LOG(ERROR) << "Failed to create credential";
+ else
+ credentials.insert(*credential);
}
return credentials;
}
diff --git a/components/wifi_sync/wifi_credential.cc b/components/wifi_sync/wifi_credential.cc
index 73fbaf2..490cd7b 100644
--- a/components/wifi_sync/wifi_credential.cc
+++ b/components/wifi_sync/wifi_credential.cc
@@ -4,25 +4,68 @@
#include "components/wifi_sync/wifi_credential.h"
-#include <limits>
-#include <string>
-
+#include "base/i18n/streaming_utf8_validator.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "components/onc/onc_constants.h"
namespace wifi_sync {
-WifiCredential::WifiCredential(
- const std::vector<unsigned char>& ssid,
+WifiCredential::~WifiCredential() {
+}
+
+// static
+scoped_ptr<WifiCredential> WifiCredential::Create(
+ const SsidBytes& ssid,
WifiSecurityClass security_class,
- const std::string& passphrase)
- : ssid_(ssid),
- security_class_(security_class),
- passphrase_(passphrase) {
+ const std::string& passphrase) {
+ if (security_class == SECURITY_CLASS_INVALID) {
+ LOG(ERROR) << "SecurityClass is invalid.";
+ return nullptr;
+ }
+
+ if (!base::StreamingUtf8Validator::Validate(passphrase)) {
+ LOG(ERROR) << "Passphrase is not valid UTF-8";
+ return nullptr;
+ }
+
+ return make_scoped_ptr(new WifiCredential(ssid, security_class, passphrase));
}
-WifiCredential::~WifiCredential() {
+scoped_ptr<base::DictionaryValue> WifiCredential::ToOncProperties() const {
+ const std::string ssid_utf8(ssid().begin(), ssid().end());
+ // TODO(quiche): Remove this test, once ONC suports non-UTF-8 SSIDs.
+ // crbug.com/432546.
+ if (!base::StreamingUtf8Validator::Validate(ssid_utf8)) {
+ LOG(ERROR) << "SSID is not valid UTF-8";
+ return nullptr;
+ }
+
+ std::string onc_security;
+ if (!WifiSecurityClassToOncSecurityString(security_class(), &onc_security)) {
+ NOTREACHED() << "Failed to convert SecurityClass with value "
+ << security_class();
+ return make_scoped_ptr(new base::DictionaryValue());
+ }
+
+ scoped_ptr<base::DictionaryValue> onc_properties(
+ new base::DictionaryValue());
+ onc_properties->Set(onc::toplevel_config::kType,
+ new base::StringValue(onc::network_type::kWiFi));
+ // TODO(quiche): Switch to the HexSSID property, once ONC fully supports it.
+ // crbug.com/432546.
+ onc_properties->Set(onc::network_config::WifiProperty(onc::wifi::kSSID),
+ new base::StringValue(ssid_utf8));
+ onc_properties->Set(onc::network_config::WifiProperty(onc::wifi::kSecurity),
+ new base::StringValue(onc_security));
+ if (WifiSecurityClassSupportsPassphrases(security_class())) {
+ onc_properties->Set(
+ onc::network_config::WifiProperty(onc::wifi::kPassphrase),
+ new base::StringValue(passphrase()));
+ }
+ return onc_properties;
}
std::string WifiCredential::ToString() const {
@@ -45,4 +88,21 @@ WifiCredential::CredentialSet WifiCredential::MakeSet() {
return CredentialSet(WifiCredential::IsLessThan);
}
+// static
+WifiCredential::SsidBytes WifiCredential::MakeSsidBytesForTest(
+ const std::string& ssid) {
+ return SsidBytes(ssid.begin(), ssid.end());
+}
+
+// Private methods.
+
+WifiCredential::WifiCredential(
+ const std::vector<unsigned char>& ssid,
+ WifiSecurityClass security_class,
+ const std::string& passphrase)
+ : ssid_(ssid),
+ security_class_(security_class),
+ passphrase_(passphrase) {
+}
+
} // namespace wifi_sync
diff --git a/components/wifi_sync/wifi_credential.h b/components/wifi_sync/wifi_credential.h
index 7c0342a..da36426 100644
--- a/components/wifi_sync/wifi_credential.h
+++ b/components/wifi_sync/wifi_credential.h
@@ -11,31 +11,52 @@
#include <string>
#include <vector>
+#include "base/memory/scoped_ptr.h"
#include "components/wifi_sync/wifi_security_class.h"
+namespace base {
+class DictionaryValue;
+}
+
namespace wifi_sync {
// A container to hold the information required to locate and connect
// to a WiFi network.
class WifiCredential final { // final because the class is copyable
public:
+ // Per IEEE 802.11-2012 (Sec 8.4.2.2), the only requirement on SSIDs
+ // is that they are between 0 and 32 bytes in length
+ // (inclusive). There are no restrictions on the values of those
+ // bytes. The SSID is not, e.g., required to be encoded as UTF-8.
using SsidBytes = std::vector<uint8_t>;
using CredentialSet = std::set<
WifiCredential,
bool(*)(const WifiCredential&a, const WifiCredential& b)>;
- // Constructs a credential with the given |ssid|, |security_class|,
- // and |passphrase|. No assumptions are made about the input
- // encoding of |ssid|. The passphrase must be valid UTF-8.
- WifiCredential(const SsidBytes& ssid,
- WifiSecurityClass security_class,
- const std::string& passphrase);
~WifiCredential();
+ // Creates a WifiCredential with the given |ssid|, |security_class|,
+ // and |passphrase|. No assumptions are made about the input
+ // encoding of |ssid|. |passphrase|, however, must be valid
+ // UTF-8. Returns NULL if the parameters are invalid.
+ static scoped_ptr<WifiCredential> Create(
+ const SsidBytes& ssid,
+ WifiSecurityClass security_class,
+ const std::string& passphrase);
+
const SsidBytes& ssid() const { return ssid_; }
WifiSecurityClass security_class() const { return security_class_; }
const std::string& passphrase() const { return passphrase_; }
+ // Returns a dictionary which represents this WifiCredential as ONC
+ // properties. The resulting dictionary can be used, e.g, to
+ // configure a new network using
+ // chromeos::NetworkConfigurationHandler::CreateConfiguration. Due
+ // to limitations in ONC, this operation fails if ssid() is not
+ // valid UTF-8. In case of failure, returns a scoped_ptr with value
+ // nullptr.
+ scoped_ptr<base::DictionaryValue> ToOncProperties() const;
+
// Returns a string representation of the credential, for debugging
// purposes. The string will not include the credential's passphrase.
std::string ToString() const;
@@ -47,7 +68,18 @@ class WifiCredential final { // final because the class is copyable
// ordering function plumbed in.
static CredentialSet MakeSet();
+ // Returns |ssid| as an SsidBytes instance. This convenience
+ // function simplifies some tests, which need to instantiate
+ // SsidBytes from string literals.
+ static SsidBytes MakeSsidBytesForTest(const std::string& ssid);
+
private:
+ // Constructs a credential with the given |ssid|, |security_class|,
+ // and |passphrase|.
+ WifiCredential(const SsidBytes& ssid,
+ WifiSecurityClass security_class,
+ const std::string& passphrase);
+
// The WiFi network's SSID.
const SsidBytes ssid_;
// The WiFi network's security class (e.g. WEP, PSK).
diff --git a/components/wifi_sync/wifi_credential_unittest.cc b/components/wifi_sync/wifi_credential_unittest.cc
new file mode 100644
index 0000000..b737217
--- /dev/null
+++ b/components/wifi_sync/wifi_credential_unittest.cc
@@ -0,0 +1,140 @@
+// Copyright 2015 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.
+
+#include "components/wifi_sync/wifi_credential.h"
+
+#include "base/logging.h"
+#include "base/values.h"
+#include "components/onc/onc_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace wifi_sync {
+
+namespace {
+
+const char kSsid[] = "fake-ssid";
+const char kSsidNonUtf8[] = "\xc0";
+const char kPassphraseWep[] = "abcde";
+const char kPassphraseWepNonUtf8[] = "\xc0\xc0\xc0\xc0\xc0";
+const char kPassphrasePsk[] = "fake-psk-passphrase";
+const char kPassphrase8021X[] = "fake-8021X-passphrase";
+
+WifiCredential MakeCredential(const std::string& ssid,
+ WifiSecurityClass security_class,
+ const std::string& passphrase) {
+ scoped_ptr<WifiCredential> credential =
+ WifiCredential::Create(
+ WifiCredential::MakeSsidBytesForTest(ssid),
+ security_class,
+ passphrase);
+ CHECK(credential);
+ return *credential;
+}
+
+bool TypeIsWifi(const base::DictionaryValue& onc_properties) {
+ std::string network_type;
+ EXPECT_TRUE(onc_properties.GetString(
+ onc::toplevel_config::kType, &network_type));
+ return network_type == onc::network_type::kWiFi;
+}
+
+std::string GetSsid(const base::DictionaryValue& onc_properties) {
+ std::string ssid;
+ EXPECT_TRUE(onc_properties.GetString(
+ onc::network_config::WifiProperty(onc::wifi::kSSID), &ssid));
+ return ssid;
+}
+
+std::string GetOncSecurity(const base::DictionaryValue& onc_properties) {
+ std::string onc_security;
+ EXPECT_TRUE(onc_properties.GetString(
+ onc::network_config::WifiProperty(onc::wifi::kSecurity), &onc_security));
+ return onc_security;
+}
+
+std::string GetPassphrase(const base::DictionaryValue& onc_properties) {
+ std::string passphrase;
+ EXPECT_TRUE(onc_properties.GetString(
+ onc::network_config::WifiProperty(onc::wifi::kPassphrase), &passphrase));
+ return passphrase;
+}
+
+} // namespace
+
+TEST(WifiCredentialTest, CreateWithSecurityClassInvalid) {
+ scoped_ptr<WifiCredential> credential =
+ WifiCredential::Create(
+ WifiCredential::MakeSsidBytesForTest(kSsid),
+ SECURITY_CLASS_INVALID,
+ "");
+ EXPECT_FALSE(credential);
+}
+
+TEST(WifiCredentialTest, CreateWithPassphraseNonUtf8) {
+ scoped_ptr<WifiCredential> credential =
+ WifiCredential::Create(
+ WifiCredential::MakeSsidBytesForTest(kSsid),
+ SECURITY_CLASS_WEP,
+ kPassphraseWepNonUtf8);
+ EXPECT_FALSE(credential);
+}
+
+TEST(WifiCredentialTest, ToOncPropertiesSecurityNone) {
+ const WifiCredential credential(
+ MakeCredential(kSsid, SECURITY_CLASS_NONE, ""));
+ scoped_ptr<base::DictionaryValue> onc_properties =
+ credential.ToOncProperties();
+ ASSERT_TRUE(onc_properties);
+ EXPECT_TRUE(TypeIsWifi(*onc_properties));
+ EXPECT_EQ(kSsid, GetSsid(*onc_properties));
+ EXPECT_EQ(onc::wifi::kSecurityNone, GetOncSecurity(*onc_properties));
+}
+
+TEST(WifiCredentialTest, ToOncPropertiesSecurityWep) {
+ const WifiCredential credential(
+ MakeCredential(kSsid, SECURITY_CLASS_WEP, kPassphraseWep));
+ scoped_ptr<base::DictionaryValue> onc_properties =
+ credential.ToOncProperties();
+ ASSERT_TRUE(onc_properties);
+ EXPECT_TRUE(TypeIsWifi(*onc_properties));
+ EXPECT_EQ(kSsid, GetSsid(*onc_properties));
+ EXPECT_EQ(onc::wifi::kWEP_PSK, GetOncSecurity(*onc_properties));
+ EXPECT_EQ(kPassphraseWep, GetPassphrase(*onc_properties));
+}
+
+TEST(WifiCredentialTest, ToOncPropertiesSecurityPsk) {
+ const WifiCredential credential(
+ MakeCredential(kSsid, SECURITY_CLASS_PSK, kPassphrasePsk));
+ scoped_ptr<base::DictionaryValue> onc_properties =
+ credential.ToOncProperties();
+ ASSERT_TRUE(onc_properties);
+ EXPECT_TRUE(TypeIsWifi(*onc_properties));
+ EXPECT_EQ(kSsid, GetSsid(*onc_properties));
+ EXPECT_EQ(onc::wifi::kWPA_PSK, GetOncSecurity(*onc_properties));
+ EXPECT_EQ(kPassphrasePsk, GetPassphrase(*onc_properties));
+}
+
+TEST(WifiCredentialTest, ToOncPropertiesSecurity8021X) {
+ const WifiCredential credential(
+ MakeCredential(kSsid, SECURITY_CLASS_802_1X, kPassphrase8021X));
+ scoped_ptr<base::DictionaryValue> onc_properties =
+ credential.ToOncProperties();
+ ASSERT_TRUE(onc_properties);
+ EXPECT_TRUE(TypeIsWifi(*onc_properties));
+ EXPECT_EQ(kSsid, GetSsid(*onc_properties));
+ EXPECT_EQ(onc::wifi::kWPA_EAP, GetOncSecurity(*onc_properties));
+ EXPECT_EQ(kPassphrase8021X, GetPassphrase(*onc_properties));
+}
+
+// TODO(quiche): Update this test, once ONC suports non-UTF-8 SSIDs.
+// crbug.com/432546.
+TEST(WifiCredentialTest, ToOncPropertiesSsidNonUtf8) {
+ const WifiCredential credential(
+ MakeCredential(kSsidNonUtf8, SECURITY_CLASS_NONE, ""));
+ scoped_ptr<base::DictionaryValue> onc_properties =
+ credential.ToOncProperties();
+ EXPECT_FALSE(onc_properties);
+}
+
+} // namespace wifi_sync