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

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: a Created 3 years, 11 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, Profile* profile) {
139 // If we are being carpet bombed, block the request. 140 // If we are being carpet bombed, block the request.
140 if (!g_accept_requests) 141 if (!g_accept_requests)
141 return BLOCK; 142 return BLOCK;
142 143
143 if (scheme.length() == 1) { 144 if (scheme.length() == 1) {
144 // We have a URL that looks something like: 145 // We have a URL that looks something like:
145 // C:/WINDOWS/system32/notepad.exe 146 // C:/WINDOWS/system32/notepad.exe
146 // ShellExecuting this URL will cause the specified program to be executed. 147 // ShellExecuting this URL will cause the specified program to be executed.
147 return BLOCK; 148 return BLOCK;
148 } 149 }
149 150
150 // Check the stored prefs. 151 // 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 152 // and migrate the prefs to the profile.
152 // profile, not in the local state. http://crbug.com/457254 153 // TODO(ramyasharma) remove the migration in M61.
153 PrefService* pref = g_browser_process->local_state(); 154 PrefService* local_prefs = g_browser_process->local_state();
154 if (pref) { // May be NULL during testing. 155 PrefService* profile_prefs = profile->GetPrefs();
155 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 156 if (local_prefs && profile_prefs) { // May be NULL during testing.
157 DictionaryPrefUpdate local_state_schemas(
158 local_prefs, prefs::kExcludedSchemes);
159 DictionaryPrefUpdate update_excluded_schemas_profile(
160 profile_prefs, prefs::kExcludedSchemes);
161 if (update_excluded_schemas_profile->empty()) {
162 // Copy local state to profile state.
163 for (base::DictionaryValue::Iterator it(*local_state_schemas);
164 !it.IsAtEnd(); it.Advance()) {
165 bool is_blocked;
166 // Discard local state if set to blocked, to reset all users
167 // stuck in 'Do Nothing' + 'Do Not Open' state back to the default
168 // prompt state.
169 if (it.value().GetAsBoolean(&is_blocked) && !is_blocked)
170 update_excluded_schemas_profile->SetBoolean(it.key(), is_blocked);
171 }
172 // TODO(ramyasharma): Clear only if required.
173 local_prefs->ClearPref(prefs::kExcludedSchemes);
174 }
156 175
157 // Warm up the dictionary if needed. 176 // Prepopulate the default states each time.
158 PrepopulateDictionary(update_excluded_schemas.Get()); 177 PrepopulateDictionary(update_excluded_schemas_profile.Get());
159 178
160 bool should_block; 179 bool should_block;
161 if (update_excluded_schemas->GetBoolean(scheme, &should_block)) 180 if (update_excluded_schemas_profile->GetBoolean(scheme, &should_block))
162 return should_block ? BLOCK : DONT_BLOCK; 181 return should_block ? BLOCK : DONT_BLOCK;
163 } 182 }
164 183
165 return UNKNOWN; 184 return UNKNOWN;
166 } 185 }
167 186
168 // static 187 // static
169 void ExternalProtocolHandler::SetBlockState(const std::string& scheme, 188 void ExternalProtocolHandler::SetBlockState(const std::string& scheme,
170 BlockState state) { 189 BlockState state,
190 Profile* profile) {
171 // Set in the stored prefs. 191 // Set in the stored prefs.
172 // TODO(pkasting): This kind of thing should go in the preferences on the 192 PrefService* profile_prefs = profile->GetPrefs();
173 // profile, not in the local state. http://crbug.com/457254 193 if (profile_prefs) { // May be NULL during testing.
174 PrefService* pref = g_browser_process->local_state(); 194 DictionaryPrefUpdate update_excluded_schemas_profile(
175 if (pref) { // May be NULL during testing. 195 profile_prefs, prefs::kExcludedSchemes);
176 DictionaryPrefUpdate update_excluded_schemas(pref, prefs::kExcludedSchemes); 196 if (!update_excluded_schemas_profile->empty()) {
177 197 if (state == UNKNOWN)
178 if (state == UNKNOWN) { 198 update_excluded_schemas_profile->Remove(scheme, nullptr);
179 update_excluded_schemas->Remove(scheme, NULL); 199 else
180 } else { 200 update_excluded_schemas_profile->SetBoolean(scheme, (state == BLOCK));
181 update_excluded_schemas->SetBoolean(scheme, (state == BLOCK));
182 } 201 }
183 } 202 }
184 } 203 }
185 204
186 // static 205 // static
187 void ExternalProtocolHandler::LaunchUrlWithDelegate( 206 void ExternalProtocolHandler::LaunchUrlWithDelegate(
188 const GURL& url, 207 const GURL& url,
189 int render_process_host_id, 208 int render_process_host_id,
190 int render_view_routing_id, 209 int render_view_routing_id,
191 ui::PageTransition page_transition, 210 ui::PageTransition page_transition,
192 bool has_user_gesture, 211 bool has_user_gesture,
193 Delegate* delegate) { 212 Delegate* delegate) {
194 DCHECK(base::MessageLoopForUI::IsCurrent()); 213 DCHECK(base::MessageLoopForUI::IsCurrent());
195 214
196 // Escape the input scheme to be sure that the command does not 215 // Escape the input scheme to be sure that the command does not
197 // have parameters unexpected by the external program. 216 // have parameters unexpected by the external program.
198 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec()); 217 std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec());
199 GURL escaped_url(escaped_url_string); 218 GURL escaped_url(escaped_url_string);
219
220 content::WebContents* web_contents = tab_util::GetWebContentsByID(
221 render_process_host_id, render_view_routing_id);
222 Profile* profile = nullptr;
223 if (web_contents) // Maybe NULL during testing.
224 profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
200 BlockState block_state = 225 BlockState block_state =
201 GetBlockStateWithDelegate(escaped_url.scheme(), delegate); 226 GetBlockStateWithDelegate(escaped_url.scheme(), delegate, profile);
202 if (block_state == BLOCK) { 227 if (block_state == BLOCK) {
203 if (delegate) 228 if (delegate)
204 delegate->BlockRequest(); 229 delegate->BlockRequest();
205 return; 230 return;
206 } 231 }
207 232
208 g_accept_requests = false; 233 g_accept_requests = false;
209 234
210 // The worker creates tasks with references to itself and puts them into 235 // The worker creates tasks with references to itself and puts them into
211 // message loops. 236 // message loops.
(...skipping 24 matching lines...) Expand all
236 261
237 // static 262 // static
238 void ExternalProtocolHandler::PermitLaunchUrl() { 263 void ExternalProtocolHandler::PermitLaunchUrl() {
239 DCHECK(base::MessageLoopForUI::IsCurrent()); 264 DCHECK(base::MessageLoopForUI::IsCurrent());
240 g_accept_requests = true; 265 g_accept_requests = true;
241 } 266 }
242 267
243 // static 268 // static
244 void ExternalProtocolHandler::PrepopulateDictionary( 269 void ExternalProtocolHandler::PrepopulateDictionary(
245 base::DictionaryValue* win_pref) { 270 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[] = { 271 static const char* const denied_schemes[] = {
252 "afp", 272 "afp",
253 "data", 273 "data",
254 "disk", 274 "disk",
255 "disks", 275 "disks",
256 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply 276 // ShellExecuting file:///C:/WINDOWS/system32/notepad.exe will simply
257 // execute the file specified! Hopefully we won't see any "file" schemes 277 // 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 278 // 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. 279 // than to let an attacker format the user's hard drive.
260 "file", 280 "file",
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 312 }
293 313
294 // static 314 // static
295 void ExternalProtocolHandler::RecordMetrics(bool selected) { 315 void ExternalProtocolHandler::RecordMetrics(bool selected) {
296 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox", 316 UMA_HISTOGRAM_BOOLEAN("BrowserDialogs.ExternalProtocol.RememberCheckbox",
297 selected); 317 selected);
298 } 318 }
299 319
300 // static 320 // static
301 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { 321 void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) {
302 registry->RegisterDictionaryPref(prefs::kExcludedSchemes); 322 registry->RegisterDictionaryPref(prefs::kExcludedSchemes);
303 } 323 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698