Chromium Code Reviews| 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( |