Index: components/wifi/wifi_service_win.cc |
diff --git a/components/wifi/wifi_service_win.cc b/components/wifi/wifi_service_win.cc |
index 4fe0724bf50726b24c1fef14e574ea14e1aabedf..053e328e4a0c8caf7ae90773c602c5fcdd3ec62c 100644 |
--- a/components/wifi/wifi_service_win.cc |
+++ b/components/wifi/wifi_service_win.cc |
@@ -25,6 +25,8 @@ |
namespace { |
const char kWiFiServiceError[] = "Error.WiFiService"; |
+const char kWiFiServiceErrorNotImplemented[] = |
+ "Error.WiFiService.NotImplemented"; |
const wchar_t kNwCategoryWizardRegKey[] = |
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Network\\" |
L"NwCategoryWizard"; |
@@ -208,6 +210,11 @@ class WiFiServiceImpl : 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, |
@@ -360,7 +367,11 @@ class WiFiServiceImpl : public WiFiService { |
DWORD SaveTempProfile(const std::string& network_guid); |
// Get previously stored |profile_xml| for |network_guid|. |
- DWORD GetProfile(const std::string& network_guid, std::string* profile_xml); |
+ // If |get_plaintext_key| is true, and process has sufficient privileges, then |
+ // <sharedKey> data in |profile_xml| will be unprotected. |
+ DWORD GetProfile(const std::string& network_guid, |
+ bool get_plaintext_key, |
+ std::string* profile_xml); |
// Return true if there is previously stored profile xml for |network_guid|. |
bool HaveProfile(const std::string& network_guid); |
@@ -637,6 +648,55 @@ void WiFiServiceImpl::StartDisconnect(const std::string& network_guid, |
CheckError(error_code, kWiFiServiceError, error); |
} |
+void WiFiServiceImpl::GetKeyFromSystem(const std::string& network_guid, |
+ bool get_plaintext_key, |
+ std::string* key_data, |
+ std::string* error) { |
afontan
2014/02/12 09:17:28
I assume that the caller will have a way to pass t
mef
2014/02/12 16:29:38
Yes, see https://codereview.chromium.org/102993002
|
+ DWORD error_code = EnsureInitialized(); |
+ if (CheckError(error_code, kWiFiServiceError, error)) |
+ return; |
+ |
+ std::string profile_xml; |
+ error_code = GetProfile(network_guid, get_plaintext_key, &profile_xml); |
+ if (CheckError(error_code, kWiFiServiceError, error)) |
+ return; |
+ |
+ const char kSharedKeyElement[] = "sharedKey"; |
+ const char kProtectedElement[] = "protected"; |
+ const char kKeyMaterialElement[] = "keyMaterial"; |
+ |
+ // Quick check to verify presence of <sharedKey> element. |
+ if (profile_xml.find(kSharedKeyElement) == std::string::npos) { |
+ *error = kWiFiServiceError; |
+ return; |
+ } |
+ |
+ XmlReader reader; |
+ if (reader.Load(profile_xml)) { |
+ while(reader.Read()) { |
+ reader.SkipToElement(); |
+ if (reader.NodeName() == kSharedKeyElement) { |
+ while(reader.Read()) { |
+ reader.SkipToElement(); |
+ if (reader.NodeName() == kKeyMaterialElement) { |
+ reader.ReadElementContent(key_data); |
afontan
2014/02/12 09:29:28
if !get_plaintext_key we are done, we could break.
mef
2014/02/12 16:29:38
Done.
|
+ } |
+ if (reader.NodeName() == kProtectedElement) { |
afontan
2014/02/12 09:17:28
else if?
mef
2014/02/12 16:29:38
Done.
|
+ std::string protected_data; |
+ reader.ReadElementContent(&protected_data); |
+ if (get_plaintext_key && protected_data != "false") |
+ *error = kWiFiServiceError; |
afontan
2014/02/12 09:29:28
Can this ever happen? Do we need to protect agains
mef
2014/02/12 16:29:38
In my testing without UAC privilege escalation cal
|
+ } |
+ } |
+ return; |
+ } |
+ } |
+ } |
+ |
+ // Did not find passphrase in the profile. |
+ *error = kWiFiServiceError; |
+} |
+ |
void WiFiServiceImpl::SetEventObservers( |
scoped_refptr<base::MessageLoopProxy> message_loop_proxy, |
const NetworkGuidListCallback& networks_changed_observer, |
@@ -755,7 +815,7 @@ DWORD WiFiServiceImpl::SaveCurrentConnectedNetwork( |
if (error == ERROR_SUCCESS) { |
SaveTempProfile(*connected_network_guid); |
std::string profile_xml; |
- error = GetProfile(*connected_network_guid, &profile_xml); |
+ error = GetProfile(*connected_network_guid, false, &profile_xml); |
if (error == ERROR_SUCCESS) { |
saved_profiles_xml_[*connected_network_guid] = profile_xml; |
} |
@@ -1442,6 +1502,7 @@ DWORD WiFiServiceImpl::SaveTempProfile(const std::string& network_guid) { |
} |
DWORD WiFiServiceImpl::GetProfile(const std::string& network_guid, |
+ bool get_plaintext_key, |
std::string* profile_xml) { |
if (client_ == NULL) { |
NOTREACHED(); |
@@ -1450,13 +1511,14 @@ DWORD WiFiServiceImpl::GetProfile(const std::string& network_guid, |
DWORD error = ERROR_SUCCESS; |
base::string16 profile_name = ProfileNameFromGUID(network_guid); |
+ DWORD flags = get_plaintext_key ? WLAN_PROFILE_GET_PLAINTEXT_KEY : 0; |
LPWSTR str_profile_xml = NULL; |
error = WlanGetProfile_function_(client_, |
&interface_guid_, |
profile_name.c_str(), |
NULL, |
&str_profile_xml, |
- NULL, |
+ &flags, |
NULL); |
if (error == ERROR_SUCCESS && str_profile_xml != NULL) { |
@@ -1473,7 +1535,7 @@ DWORD WiFiServiceImpl::GetProfile(const std::string& network_guid, |
bool WiFiServiceImpl::HaveProfile(const std::string& network_guid) { |
DWORD error = ERROR_SUCCESS; |
std::string profile_xml; |
- return GetProfile(network_guid, &profile_xml) == ERROR_SUCCESS; |
+ return GetProfile(network_guid, false, &profile_xml) == ERROR_SUCCESS; |
} |
bool WiFiServiceImpl::AuthEncryptionFromSecurity( |