shill: move passphrase validation from WiFi to WiFiService

this paves the way for actually parsing passphrase info into
fields of a WiFiService, rather than just validating it. also,
we need this code for calls to WiFiService.SetProperty.

BUG=None
TEST=unittests

Change-Id: I8467b36e07588b99f12cc5a4ecb7cf2deb7cf068
Reviewed-on: http://gerrit.chromium.org/gerrit/8821
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
diff --git a/key_value_store.cc b/key_value_store.cc
index bc0f55b..d905467 100644
--- a/key_value_store.cc
+++ b/key_value_store.cc
@@ -24,13 +24,13 @@
 
 bool KeyValueStore::GetBool(const string &name) const {
   map<string, bool>::const_iterator it(bool_properties_.find(name));
-  CHECK(it != bool_properties_.end());
+  CHECK(it != bool_properties_.end()) << "for bool property " << name;
   return it->second;
 }
 
 const string &KeyValueStore::GetString(const string &name) const {
   map<string, string>::const_iterator it(string_properties_.find(name));
-  CHECK(it != string_properties_.end());
+  CHECK(it != string_properties_.end()) << "for string property " << name;
   return it->second;
 }
 
diff --git a/wifi.cc b/wifi.cc
index d12d271..9d6ef2d 100644
--- a/wifi.cc
+++ b/wifi.cc
@@ -370,134 +370,37 @@
     return NULL;
   }
 
-  if (security_method == flimflam::kSecurityWep) {
-    string passphrase = args.GetString(flimflam::kPassphraseProperty);
-    passphrase = ParseWEPPassphrase(passphrase, error);
-    if (error->IsFailure()) {
-      return NULL;
-    }
-  } else if (security_method == flimflam::kSecurityPsk ||
-             security_method == flimflam::kSecurityWpa ||
-             security_method == flimflam::kSecurityRsn) {
-    string passphrase = args.GetString(flimflam::kPassphraseProperty);
-    passphrase = ParseWPAPassphrase(passphrase, error);
-    if (error->IsFailure()) {
-      return NULL;
-    }
-  }
-
   WiFiService *service = NULL;
 
   // TODO(quiche): search for existing service
 
   if (service == NULL) {
-    // TODO(quiche): construct a new service
+    service = new WiFiService(control_interface(),
+                              dispatcher(),
+                              manager(),
+                              this,
+                              vector<uint8_t>(ssid.begin(), ssid.end()),
+                              flimflam::kModeManaged,
+                              security_method);
+    services()->push_back(service);
+    // TODO(quiche): add to service_by_private_id_?
+    // TODO(quiche): register service with manager
   }
 
-  // TODO(quiche): apply configuration parameters
+  if (security_method == flimflam::kSecurityWep ||
+      security_method == flimflam::kSecurityPsk ||
+      security_method == flimflam::kSecurityWpa ||
+      security_method == flimflam::kSecurityRsn) {
+    service->SetPassphrase(args.GetString(flimflam::kPassphraseProperty),
+                           error);
+    if (error->IsFailure()) {
+      return NULL;
+    }
+  }
+
+  // TODO(quiche): apply any other configuration parameters
 
   return service;
 }
 
-// static
-string WiFi::ParseWEPPassphrase(const string &passphrase, Error *error) {
-  unsigned int length = passphrase.length();
-
-  switch (length) {
-    case IEEE_80211::kWEP40AsciiLen:
-    case IEEE_80211::kWEP104AsciiLen:
-      break;
-    case IEEE_80211::kWEP40AsciiLen + 2:
-    case IEEE_80211::kWEP104AsciiLen + 2:
-      CheckWEPKeyIndex(passphrase, error);
-      break;
-    case IEEE_80211::kWEP40HexLen:
-    case IEEE_80211::kWEP104HexLen:
-      CheckWEPIsHex(passphrase, error);
-      break;
-    case IEEE_80211::kWEP40HexLen + 2:
-    case IEEE_80211::kWEP104HexLen + 2:
-      (CheckWEPKeyIndex(passphrase, error) ||
-       CheckWEPPrefix(passphrase, error)) &&
-          CheckWEPIsHex(passphrase.substr(2), error);
-      break;
-    case IEEE_80211::kWEP40HexLen + 4:
-    case IEEE_80211::kWEP104HexLen + 4:
-      CheckWEPKeyIndex(passphrase, error) &&
-          CheckWEPPrefix(passphrase.substr(2), error) &&
-          CheckWEPIsHex(passphrase.substr(4), error);
-      break;
-    default:
-      error->Populate(Error::kInvalidPassphrase);
-      break;
-  }
-
-  // TODO(quiche): may need to normalize passphrase format
-  if (error->IsSuccess()) {
-    return passphrase;
-  } else {
-    return "";
-  }
-}
-
-// static
-string WiFi::ParseWPAPassphrase(const string &passphrase, Error *error) {
-  unsigned int length = passphrase.length();
-  vector<uint8> passphrase_bytes;
-
-  if (base::HexStringToBytes(passphrase, &passphrase_bytes)) {
-    if (length != IEEE_80211::kWPAHexLen &&
-        (length < IEEE_80211::kWPAAsciiMinLen ||
-         length > IEEE_80211::kWPAAsciiMaxLen)) {
-      error->Populate(Error::kInvalidPassphrase);
-    }
-  } else {
-    if (length < IEEE_80211::kWPAAsciiMinLen ||
-        length > IEEE_80211::kWPAAsciiMaxLen) {
-      error->Populate(Error::kInvalidPassphrase);
-    }
-  }
-
-  // TODO(quiche): may need to normalize passphrase format
-  if (error->IsSuccess()) {
-    return passphrase;
-  } else {
-    return "";
-  }
-}
-
-// static
-bool WiFi::CheckWEPIsHex(const string &passphrase, Error *error) {
-  vector<uint8> passphrase_bytes;
-  if (base::HexStringToBytes(passphrase, &passphrase_bytes)) {
-    return true;
-  } else {
-    error->Populate(Error::kInvalidPassphrase);
-    return false;
-  }
-}
-
-// static
-bool WiFi::CheckWEPKeyIndex(const string &passphrase, Error *error) {
-  if (StartsWithASCII(passphrase, "0:", false) ||
-      StartsWithASCII(passphrase, "1:", false) ||
-      StartsWithASCII(passphrase, "2:", false) ||
-      StartsWithASCII(passphrase, "3:", false)) {
-    return true;
-  } else {
-    error->Populate(Error::kInvalidPassphrase);
-    return false;
-  }
-}
-
-// static
-bool WiFi::CheckWEPPrefix(const string &passphrase, Error *error) {
-  if (StartsWithASCII(passphrase, "0x", false)) {
-    return true;
-  } else {
-    error->Populate(Error::kInvalidPassphrase);
-    return false;
-  }
-}
-
 }  // namespace shill
diff --git a/wifi.h b/wifi.h
index d395c87..4fd8eca 100644
--- a/wifi.h
+++ b/wifi.h
@@ -70,14 +70,6 @@
   void ScanDoneTask();
   void ScanTask();
 
-  static std::string ParseWEPPassphrase(const std::string &passphrase,
-                                        Error *error);
-  static std::string ParseWPAPassphrase(const std::string &passphrase,
-                                        Error *error);
-  static bool CheckWEPIsHex(const std::string &passphrase, Error *error);
-  static bool CheckWEPKeyIndex(const std::string &passphrase, Error *error);
-  static bool CheckWEPPrefix(const std::string &passphrase, Error *error);
-
   ScopedRunnableMethodFactory<WiFi> task_factory_;
   scoped_ptr<SupplicantProcessProxyInterface> supplicant_process_proxy_;
   scoped_ptr<SupplicantInterfaceProxyInterface> supplicant_interface_proxy_;
diff --git a/wifi_service.cc b/wifi_service.cc
index daeb80f..c9713ef 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -15,12 +15,15 @@
 
 #include "shill/control_interface.h"
 #include "shill/device.h"
+#include "shill/error.h"
+#include "shill/ieee80211.h"
 #include "shill/shill_event.h"
 #include "shill/wifi.h"
 #include "shill/wifi_endpoint.h"
 #include "shill/wpa_supplicant.h"
 
 using std::string;
+using std::vector;
 
 namespace shill {
 
@@ -126,6 +129,16 @@
   return ssid_;
 }
 
+void WiFiService::SetPassphrase(const string &passphrase, Error *error) {
+  if (security_ == flimflam::kSecurityWep) {
+    passphrase_ = ParseWEPPassphrase(passphrase, error);
+  } else if (security_ == flimflam::kSecurityPsk ||
+             security_ == flimflam::kSecurityWpa ||
+             security_ == flimflam::kSecurityRsn) {
+    passphrase_ = ParseWPAPassphrase(passphrase, error);
+  }
+}
+
 // private methods
 void WiFiService::ConnectTask() {
   std::map<string, DBus::Variant> params;
@@ -170,4 +183,105 @@
   return wifi_->GetRpcIdentifier();
 }
 
+// static
+string WiFiService::ParseWEPPassphrase(const string &passphrase, Error *error) {
+  unsigned int length = passphrase.length();
+
+  switch (length) {
+    case IEEE_80211::kWEP40AsciiLen:
+    case IEEE_80211::kWEP104AsciiLen:
+      break;
+    case IEEE_80211::kWEP40AsciiLen + 2:
+    case IEEE_80211::kWEP104AsciiLen + 2:
+      CheckWEPKeyIndex(passphrase, error);
+      break;
+    case IEEE_80211::kWEP40HexLen:
+    case IEEE_80211::kWEP104HexLen:
+      CheckWEPIsHex(passphrase, error);
+      break;
+    case IEEE_80211::kWEP40HexLen + 2:
+    case IEEE_80211::kWEP104HexLen + 2:
+      (CheckWEPKeyIndex(passphrase, error) ||
+       CheckWEPPrefix(passphrase, error)) &&
+          CheckWEPIsHex(passphrase.substr(2), error);
+      break;
+    case IEEE_80211::kWEP40HexLen + 4:
+    case IEEE_80211::kWEP104HexLen + 4:
+      CheckWEPKeyIndex(passphrase, error) &&
+          CheckWEPPrefix(passphrase.substr(2), error) &&
+          CheckWEPIsHex(passphrase.substr(4), error);
+      break;
+    default:
+      error->Populate(Error::kInvalidPassphrase);
+      break;
+  }
+
+  // TODO(quiche): may need to normalize passphrase format
+  if (error->IsSuccess()) {
+    return passphrase;
+  } else {
+    return "";
+  }
+}
+
+// static
+string WiFiService::ParseWPAPassphrase(const string &passphrase, Error *error) {
+  unsigned int length = passphrase.length();
+  vector<uint8> passphrase_bytes;
+
+  if (base::HexStringToBytes(passphrase, &passphrase_bytes)) {
+    if (length != IEEE_80211::kWPAHexLen &&
+        (length < IEEE_80211::kWPAAsciiMinLen ||
+         length > IEEE_80211::kWPAAsciiMaxLen)) {
+      error->Populate(Error::kInvalidPassphrase);
+    }
+  } else {
+    if (length < IEEE_80211::kWPAAsciiMinLen ||
+        length > IEEE_80211::kWPAAsciiMaxLen) {
+      error->Populate(Error::kInvalidPassphrase);
+    }
+  }
+
+  // TODO(quiche): may need to normalize passphrase format
+  if (error->IsSuccess()) {
+    return passphrase;
+  } else {
+    return "";
+  }
+}
+
+// static
+bool WiFiService::CheckWEPIsHex(const string &passphrase, Error *error) {
+  vector<uint8> passphrase_bytes;
+  if (base::HexStringToBytes(passphrase, &passphrase_bytes)) {
+    return true;
+  } else {
+    error->Populate(Error::kInvalidPassphrase);
+    return false;
+  }
+}
+
+// static
+bool WiFiService::CheckWEPKeyIndex(const string &passphrase, Error *error) {
+  if (StartsWithASCII(passphrase, "0:", false) ||
+      StartsWithASCII(passphrase, "1:", false) ||
+      StartsWithASCII(passphrase, "2:", false) ||
+      StartsWithASCII(passphrase, "3:", false)) {
+    return true;
+  } else {
+    error->Populate(Error::kInvalidPassphrase);
+    return false;
+  }
+}
+
+// static
+bool WiFiService::CheckWEPPrefix(const string &passphrase, Error *error) {
+  if (StartsWithASCII(passphrase, "0x", false)) {
+    return true;
+  } else {
+    error->Populate(Error::kInvalidPassphrase);
+    return false;
+  }
+}
+
 }  // namespace shill
diff --git a/wifi_service.h b/wifi_service.h
index a68d3b7..9f2a8ef 100644
--- a/wifi_service.h
+++ b/wifi_service.h
@@ -17,6 +17,7 @@
 
 class ControlInterface;
 class EventDispatcher;
+class Error;
 class Manager;
 
 class WiFiService : public Service {
@@ -43,6 +44,8 @@
   const std::string &key_management() const;
   const std::vector<uint8_t> &ssid() const;
 
+  void SetPassphrase(const std::string &passphrase, Error *error);
+
  private:
   FRIEND_TEST(WiFiServiceTest, ConnectTaskRSN);
   FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA);
@@ -51,6 +54,14 @@
 
   std::string GetDeviceRpcId();
 
+  static std::string ParseWEPPassphrase(const std::string &passphrase,
+                                        Error *error);
+  static std::string ParseWPAPassphrase(const std::string &passphrase,
+                                        Error *error);
+  static bool CheckWEPIsHex(const std::string &passphrase, Error *error);
+  static bool CheckWEPKeyIndex(const std::string &passphrase, Error *error);
+  static bool CheckWEPPrefix(const std::string &passphrase, Error *error);
+
   // Properties
   std::string passphrase_;
   bool need_passphrase_;