Index: components/wifi/wifi_service_mac.mm |
diff --git a/components/wifi/wifi_service_mac.mm b/components/wifi/wifi_service_mac.mm |
index ffe3846d8306de6ae7f35f424ccf8f45d2871016..4e1821ecbe9347be3d69f16bd7a23286e1acb27d 100644 |
--- a/components/wifi/wifi_service_mac.mm |
+++ b/components/wifi/wifi_service_mac.mm |
@@ -9,6 +9,7 @@ |
#import <SystemConfiguration/SystemConfiguration.h> |
#include "base/bind.h" |
+#include "base/mac/foundation_util.h" |
#include "base/mac/scoped_cftyperef.h" |
#include "base/mac/scoped_nsobject.h" |
#include "base/message_loop/message_loop.h" |
@@ -97,6 +98,11 @@ class WiFiServiceMac : public WiFiService { |
virtual void StartDisconnect(const std::string& network_guid, |
std::string* error) OVERRIDE; |
+ virtual void GetKeyFromSystem(const std::string& network_guid, |
+ bool get_plaintext_key, |
+ std::string* key_data, |
+ std::string* error) OVERRIDE; |
+ |
virtual void SetEventObservers( |
scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
const NetworkGuidListCallback& networks_changed_observer, |
@@ -367,6 +373,49 @@ void WiFiServiceMac::StartDisconnect(const std::string& network_guid, |
} |
} |
+void WiFiServiceMac::GetKeyFromSystem(const std::string& network_guid, |
+ bool get_plaintext_key, |
+ std::string* key_data, |
+ std::string* error) { |
+ static const char kAirPortServiceName[] = "AirPort"; |
+ |
+ UInt32 password_length = 0; |
+ void *password_data = NULL; |
+ OSStatus status = noErr; |
+ if (get_plaintext_key) { |
+ status = SecKeychainFindGenericPassword(NULL, |
+ strlen(kAirPortServiceName), |
+ kAirPortServiceName, |
+ network_guid.length(), |
+ network_guid.c_str(), |
+ &password_length, |
+ &password_data, |
+ NULL); |
+ } else { |
+ NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: |
+ (id)kSecClassGenericPassword, kSecClass, |
+ SSIDFromGUID(network_guid), kSecAttrAccount, |
+ kCFBooleanTrue, kSecReturnRef, |
+ nil]; |
+ |
+ CFDataRef data = NULL; |
+ status = SecItemCopyMatching(base::mac::NSToCFCast(query), |
+ reinterpret_cast<CFTypeRef *>(&data)); |
+ base::ScopedCFTypeRef<CFDataRef> scoped_data(data); |
+ } |
+ |
+ if (status != errSecSuccess) { |
+ *error = kErrorNotFound; |
+ return; |
+ } |
+ |
+ if (password_data) { |
+ *key_data = std::string(reinterpret_cast<char*>(password_data), |
+ password_length); |
+ SecKeychainItemFreeContent(NULL, password_data); |
+ } |
+} |
+ |
void WiFiServiceMac::SetEventObservers( |
scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
const NetworkGuidListCallback& networks_changed_observer, |