shill: Add support for connecting to PSK networks

BUG=chromium-os:21293
TEST=unittest + 2 new autotests to network_WiFiSecMat (021WPAasPSK and 022RSNasPSK)

Change-Id: Id727ca761f4457b134504fd05d5692915ab3c9eb
Reviewed-on: https://gerrit.chromium.org/gerrit/11030
Commit-Ready: Gaurav Shah <gauravsh@chromium.org>
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Tested-by: Gaurav Shah <gauravsh@chromium.org>
diff --git a/wifi.cc b/wifi.cc
index 9d88939..ec10b80 100644
--- a/wifi.cc
+++ b/wifi.cc
@@ -303,7 +303,7 @@
   std::map<string, DBus::Variant> scan_args;
   scan_args[wpa_supplicant::kPropertyScanType].writer().
       append_string(wpa_supplicant::kScanTypeActive);
-  // TODO(quiche) indicate scanning in UI
+  // TODO(quiche): Indicate scanning in UI. crosbug.com/14887
   supplicant_interface_proxy_->Scan(scan_args);
   scan_pending_ = true;
 }
diff --git a/wifi_service.cc b/wifi_service.cc
index 6b6f095..618f40a 100644
--- a/wifi_service.cc
+++ b/wifi_service.cc
@@ -200,7 +200,13 @@
   if (security_ == flimflam::kSecurity8021x) {
     NOTIMPLEMENTED();
   } else if (security_ == flimflam::kSecurityPsk) {
-    NOTIMPLEMENTED();
+    const string psk_proto = StringPrintf("%s %s",
+                                          wpa_supplicant::kSecurityModeWPA,
+                                          wpa_supplicant::kSecurityModeRSN);
+    params[wpa_supplicant::kPropertySecurityProtocol].writer().
+        append_string(psk_proto.c_str());
+    params[wpa_supplicant::kPropertyPreSharedKey].writer().
+        append_string(passphrase_.c_str());
   } else if (security_ == flimflam::kSecurityRsn) {
     params[wpa_supplicant::kPropertySecurityProtocol].writer().
         append_string(wpa_supplicant::kSecurityModeRSN);
@@ -214,9 +220,9 @@
   } else if (security_ == flimflam::kSecurityWep) {
     NOTIMPLEMENTED();
   } else if (security_ == flimflam::kSecurityNone) {
-    // nothing special to do here
+    // Nothing special to do here.
   } else {
-    LOG(ERROR) << "can't connect. unsupported security method " << security_;
+    LOG(ERROR) << "Can't connect. Unsupported security method " << security_;
   }
 
   params[wpa_supplicant::kPropertyKeyManagement].writer().
diff --git a/wifi_service.h b/wifi_service.h
index 080ae57..9fb2e60 100644
--- a/wifi_service.h
+++ b/wifi_service.h
@@ -56,6 +56,7 @@
   friend class WiFiServiceSecurityTest;
   FRIEND_TEST(WiFiServiceTest, ConnectTaskRSN);
   FRIEND_TEST(WiFiServiceTest, ConnectTaskWPA);
+  FRIEND_TEST(WiFiServiceTest, ConnectTaskPSK);
   FRIEND_TEST(WiFiServiceTest, LoadHidden);
 
   static const char kStorageHiddenSSID[];
diff --git a/wifi_service_unittest.cc b/wifi_service_unittest.cc
index 6533fa1..5c8e32e 100644
--- a/wifi_service_unittest.cc
+++ b/wifi_service_unittest.cc
@@ -196,6 +196,20 @@
   wifi_service->ConnectTask();
 }
 
+TEST_F(WiFiServiceTest, ConnectTaskPSK) {
+  vector<uint8_t> ssid(5, 0);
+  WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
+                                                   dispatcher(),
+                                                   manager(),
+                                                   wifi(),
+                                                   ssid,
+                                                   flimflam::kModeManaged,
+                                                   flimflam::kSecurityPsk);
+  EXPECT_CALL(*wifi(),
+              ConnectTo(wifi_service.get(), WPASecurityArgs()));
+  wifi_service->ConnectTask();
+}
+
 TEST_F(WiFiServiceTest, LoadHidden) {
   vector<uint8_t> ssid(5, 0);
   ssid.push_back(0xff);