shill: Clear PMKSA cached credentials on unload

When an 802.1x WiFi service Unload()s, ask wpa_supplicant to clear
all cached credentials.  This is a workaround for dropping PMKSA
cache entries in wpa_supplicant when the user logs ouut.  Newer
versions of wpa_supplicant will support dropping cache entries
automatically when netblocks are changed.  This will allow more
granular key clearing.

BUG=chromium-os:23367
TEST=New unit test

Change-Id: I94d69b6943d69c7f5f31ed7846d908b38ce8e6c8
Reviewed-on: https://gerrit.chromium.org/gerrit/15163
Commit-Ready: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/wifi_unittest.cc b/wifi_unittest.cc
index f4902d2..d8595c6 100644
--- a/wifi_unittest.cc
+++ b/wifi_unittest.cc
@@ -269,6 +269,9 @@
                  const string &bssid,
                  int16_t signal_strength,
                  const char *mode);
+  void ClearCachedCredentials() {
+    wifi_->ClearCachedCredentials();
+  }
   void ReportIPConfigComplete() {
     wifi_->IPConfigUpdatedCallback(dhcp_config_, true);
   }
@@ -1382,4 +1385,37 @@
   ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
 }
 
+TEST_F(WiFiMainTest, ClearCachedCredentials) {
+  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
+      *supplicant_interface_proxy_;
+
+  StartWiFi();
+
+  // Ensure call to the proxy is deferred.
+  EXPECT_CALL(supplicant_interface_proxy, ClearCachedCredentials())
+      .Times(0);
+  ClearCachedCredentials();
+
+  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);
+
+  EXPECT_CALL(supplicant_interface_proxy, ClearCachedCredentials())
+      .Times(1);
+  dispatcher_.DispatchPendingEvents();
+
+  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);
+
+  EXPECT_CALL(supplicant_interface_proxy, ClearCachedCredentials())
+      .Times(0);
+  ClearCachedCredentials();
+  ClearCachedCredentials();
+
+  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);
+
+  // Ensure multiple calls to ClearCachedCredentials() results in only
+  // one call to the proxy.
+  EXPECT_CALL(supplicant_interface_proxy, ClearCachedCredentials())
+      .Times(1);
+  dispatcher_.DispatchPendingEvents();
+}
+
 }  // namespace shill