Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: chrome/browser/external_protocol/external_protocol_handler.cc

Issue 2623033006: [Re-landing] Migrate external protocol prefs from local state to profiles (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/external_protocol/external_protocol_handler.h" 5 #include "chrome/browser/external_protocol/external_protocol_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 const std::string& protocol, 45 const std::string& protocol,
46 ExternalProtocolHandler::Delegate* delegate) { 46 ExternalProtocolHandler::Delegate* delegate) {
47 if (delegate) 47 if (delegate)
48 return delegate->CreateShellWorker(callback, protocol); 48 return delegate->CreateShellWorker(callback, protocol);
49 49
50 return new shell_integration::DefaultProtocolClientWorker(callback, protocol); 50 return new shell_integration::DefaultProtocolClientWorker(callback, protocol);
51 } 51 }
52 52
53 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate( 53 ExternalProtocolHandler::BlockState GetBlockStateWithDelegate(
54 const std::string& scheme, 54 const std::string& scheme,
55 ExternalProtocolHandler::Delegate* delegate) { 55 ExternalProtocolHandler::Delegate* delegate,
56 Profile* profile) {
56 if (!delegate) 57 if (!delegate)
57 return ExternalProtocolHandler::GetBlockState(scheme); 58 return ExternalProtocolHandler::GetBlockState(scheme, profile);
58 59
59 return delegate->GetBlockState(scheme); 60 return delegate->GetBlockState(scheme, profile);
60 } 61 }
61 62
62 void RunExternalProtocolDialogWithDelegate( 63 void RunExternalProtocolDialogWithDelegate(
63 const GURL& url, 64 const GURL& url,
64 int render_process_host_id, 65 int render_process_host_id,
65 int routing_id, 66 int routing_id,
66 ui::PageTransition page_transition, 67 ui::PageTransition page_transition,
67 bool has_user_gesture, 68 bool has_user_gesture,
68 ExternalProtocolHandler::Delegate* delegate) { 69 ExternalProtocolHandler::Delegate* delegate) {
69 if (!delegate) { 70 if (!delegate) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 129 }
129 130
130 LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, render_process_host_id, 131 LaunchUrlWithoutSecurityCheckWithDelegate(escaped_url, render_process_host_id,
131 render_view_routing_id, delegate); 132 render_view_routing_id, delegate);
132 } 133 }
133 134
134 } // namespace 135 } // namespace
135 136
136 // static 137 // static
137 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( 138 ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState(
138 const std::string& scheme) { 139 const std::string& scheme,
140 Profile* profile) {
139 // If we are being carpet bombed, block the request. 141 // If we are being carpet bombed, block the request.
140 if (!g_accept_requests) 142 if (!g_accept_requests)
141 return BLOCK; 143 return BLOCK;
142 144
143 if (scheme.length() == 1) { 145 if (scheme.length() == 1) {
144 // We have a URL that looks something like: 146 // We have a URL that looks something like:
145 // C:/WINDOWS/system32/notepad.exe 147 // C:/WINDOWS/system32/notepad.exe
146 // ShellExecuting this URL will cause the specified program to be executed. 148 // ShellExecuting this URL will cause the specified program to be executed.
147 return BLOCK; 149 return BLOCK;
148 } 150 }
149 151
150 // Check the stored prefs. 152 // Check if there are any prefs in the local state. If there are, wipe them,
151 // TODO(pkasting): This kind of thing should go in the preferences on the 153 // and migrate the prefs to the profile.
152 // profile, not in the local state. http://crbug.com/457254 154 // TODO(ramyasharma) remove the migration in M61.
153 PrefService* pref = g_browser_process->local_state(); 155 PrefService* local_prefs = g_browser_process->local_state();
154 if (pref) { // May be NULL during testing. 156 PrefService* profile_prefs = profile->GetPrefs();
155 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 157 if (local_prefs && profile_prefs) { // May be NULL during testing.
158 DictionaryPrefUpdate local_state_schemas(local_prefs,
159 prefs::kExcludedSchemes);
160 DictionaryPrefUpdate update_excluded_schemas_profile(
161 profile_prefs, prefs::kExcludedSchemes);
162 if (update_excluded_schemas_profile->empty()) {
163 // Copy local state to profile state.
164 for (base::DictionaryValue::Iterator it(*local_state_schemas);
165 !it.IsAtEnd(); it.Advance()) {
166 bool is_blocked;
167 // Discard local state if set to blocked, to reset all users
168 // stuck in 'Do Nothing' + 'Do Not Open' state back to the default
169 // prompt state.
170 if (it.value().GetAsBoolean(&is_blocked) && !is_blocked)
171 update_excluded_schemas_profile->SetBoolean(it.key(), is_blocked);
172 }
173 // TODO(ramyasharma): Clear only if required.
174 local_prefs->ClearPref(prefs::kExcludedSchemes);
175 }
156 176
157 // Warm up the dictionary if needed. 177 // Prepopulate the default states each time.
158 PrepopulateDictionary(update_excluded_schemas.Get()); 178 PrepopulateDictionary(update_excluded_schemas_profile.Get());
159 179
160 bool should_block; 180 bool should_block;
161 if (update_excluded_schemas->GetBoolean(scheme, &should_block)) 181 if (update_excluded_schemas_profile->GetBoolean(scheme, &should_block))
162 return should_block ? BLOCK : DONT_BLOCK; 182 return should_block ? BLOCK : DONT_BLOCK;
163 } 183 }
164 184
165 return UNKNOWN; 185 return UNKNOWN;
166 } 186 }
167 187
168 // static 188 // static
169 void ExternalProtocolHandler::SetBlockState(const std::string& scheme, 189 void ExternalProtocolHandler::SetBlockState(const std::string& scheme,
170 BlockState state) { 190 BlockState state,
191 Profile* profile) {
171 // Set in the stored prefs. 192 // Set in the stored prefs.
172 // TODO(pkasting): This kind of thing should go in the preferences on the 193 PrefService* profile_prefs = profile->GetPrefs();
173 // profile, not in the local state. http://crbug.com/457254 194 if (profile_prefs) { // May be NULL during testing.
174 PrefService* pref = g_browser_process->local_state(); 195 DictionaryPrefUpdate update_excluded_schemas_profile(
175 if (pref) { // May be NULL during testing. 196 profile_prefs, prefs::kExcludedSchemes);
176 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 197 if (!update_excluded_schemas_profile->empty()) {
177 198 if (state == UNKNOWN)
178 if (state == UNKNOWN) { 199 update_excluded_schemas_profile->Remove(scheme, nullptr);
179 update_excluded_schemas->Remove(scheme, NULL); 200 else
180 } else { 201 update_excluded_schemas_profile->SetBoolean(scheme, (state == BLOCK));
181 update_excluded_schemas->SetBoolean(scheme, (state == BLOCK));
182 } 202 }
183 } 203 }
184 } 204 }
185 205
186 // static 206 // static
187 void ExternalProtocolHandler::LaunchUrlWithDelegate( 207 void ExternalProtocolHandler::LaunchUrlWithDelegate(
188 const GURL& url, 208 const GURL& url,
189 int render_process_host_id, 209 int render_process_host_id,
190 int render_view_routing_id, 210 int render_view_routing_id,
191 ui::PageTransition page_transition, 211 ui::PageTransition page_transition,
192 bool has_user_gesture, 212 bool has_user_gesture,
193 Delegate* delegate) { 213 Delegate* delegate) {
194 DCHECK(base::MessageLoopForUI::IsCurrent()); 214 DCHECK(base::MessageLoopForUI::IsCurrent());
195 215
196 // Escape the input scheme to be sure that the command does not 216 // Escape the input scheme to be sure that the command does not
197 // have parameters unexpected by the external program. 217 // have parameters unexpected by the external program.
198 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec()); 218 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec());
199 GURL escaped_url(escaped_url_string); 219 GURL escaped_url(escaped_url_string);
220
221 content::WebContents* web_contents = tab_util::GetWebContentsByID(
222 render_process_host_id, render_view_routing_id);
223 Profile* profile = nullptr;
224 if (web_contents) // Maybe NULL during testing.
225 profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
200 BlockState block_state = 226 BlockState block_state =
201 GetBlockStateWithDelegate(escaped_url.scheme(), delegate); 227 GetBlockStateWithDelegate(escaped_url.scheme(), delegate, profile);
202 if (block_state == BLOCK) { 228 if (block_state == BLOCK) {
203 if (delegate) 229 if (delegate)
204 delegate->BlockRequest(); 230 delegate->BlockRequest();
205 return; 231 return;
206 } 232 }
207 233
208 g_accept_requests = false; 234 g_accept_requests = false;
209 235
210 // The worker creates tasks with references to itself and puts them into 236 // The worker creates tasks with references to itself and puts them into
211 // message loops. 237 // message loops.
(...skipping 24 matching lines...) Expand all
236 262
237 // static 263 // static
238 void ExternalProtocolHandler::PermitLaunchUrl() { 264 void ExternalProtocolHandler::PermitLaunchUrl() {
239 DCHECK(base::MessageLoopForUI::IsCurrent()); 265 DCHECK(base::MessageLoopForUI::IsCurrent());
240 g_accept_requests = true; 266 g_accept_requests = true;
241 } 267 }
242 268
243 // static 269 // static
244 void ExternalProtocolHandler::PrepopulateDictionary( 270 void ExternalProtocolHandler::PrepopulateDictionary(
245 base::DictionaryValue* win_pref) { 271 base::DictionaryValue* win_pref) {
246 static bool is_warm = false;
247 if (is_warm)
248 return;
249 is_warm = true;
250
251 static const char* const denied_schemes[] = { 272 static const char* const denied_schemes[] = {
252 "afp", 273 "afp",
253 "data", 274 "data",
254 "disk", 275 "disk",
255 "disks", 276 "disks",
256 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply 277 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply
257 // execute the file specified! Hopefully we won't see any "file" schemes 278 // execute the file specified! Hopefully we won't see any "file" schemes
258 // because we think of file:// URLs as handled URLs, but better to be safe 279 // because we think of file:// URLs as handled URLs, but better to be safe
259 // than to let an attacker format the user's hard drive. 280 // than to let an attacker format the user's hard drive.
260 "file", 281 "file",
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // static 315 // static
295 void ExternalProtocolHandler::RecordMetrics(bool selected) { 316 void ExternalProtocolHandler::RecordMetrics(bool selected) {
296 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox", 317 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox",
297 selected); 318 selected);
298 } 319 }
299 320
300 // static 321 // static
301 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { 322 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) {
302 registry->RegisterDictionaryPref(prefs::kExcludedSchemes); 323 registry->RegisterDictionaryPref(prefs::kExcludedSchemes);
303 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698