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

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate.cc

Issue 8468020: Propagate the SafeBrowsing download protection verdict to the DownloadItem. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Address Ben's comment. Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/download/chrome_download_manager_delegate.h" 5 #include "chrome/browser/download/chrome_download_manager_delegate.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // history service thread is still reading the persistent state, we do not 79 // history service thread is still reading the persistent state, we do not
80 // insert the new DownloadItem into 'history_downloads_' or inform our 80 // insert the new DownloadItem into 'history_downloads_' or inform our
81 // observers at this point. OnCreateDownloadEntryComplete() handles that 81 // observers at this point. OnCreateDownloadEntryComplete() handles that
82 // finalization of the the download creation as a callback from the history 82 // finalization of the the download creation as a callback from the history
83 // thread. 83 // thread.
84 DownloadItem* download = 84 DownloadItem* download =
85 download_manager_->GetActiveDownloadItem(download_id); 85 download_manager_->GetActiveDownloadItem(download_id);
86 if (!download) 86 if (!download)
87 return false; 87 return false;
88 88
89 #if defined(ENABLE_SAFE_BROWSING) 89 #if defined(ENABLE_SAFE_BROWSING)
Randy Smith (Not in Mondays) 2011/11/16 18:04:04 GetDownloadProtectionService() isn't inside of an
noelutz 2011/11/16 23:15:07 I think it's needed. changed.
Randy Smith (Not in Mondays) 2011/11/17 16:49:31 Hmmm. So it would seem to me that we could also a
noelutz 2011/11/17 17:05:44 Agreed. If that's OK I would like to do that in a
90 SafeBrowsingService* sb_service = 90 DownloadProtectionService* service = GetDownloadProtectionService();
91 g_browser_process->safe_browsing_service(); 91 if (service) {
92 if (sb_service && sb_service->download_protection_service() &&
93 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
94 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = " 92 VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = "
95 << download->DebugString(false); 93 << download->DebugString(false);
96 sb_service->download_protection_service()->CheckDownloadUrl( 94 service->CheckDownloadUrl(
97 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download), 95 DownloadProtectionService::DownloadInfo::FromDownloadItem(*download),
98 base::Bind( 96 base::Bind(
99 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone, 97 &ChromeDownloadManagerDelegate::CheckDownloadUrlDone,
100 this, 98 this,
101 download->id())); 99 download->id()));
102 return false; 100 return false;
103 } 101 }
104 #endif 102 #endif
105 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE); 103 CheckDownloadUrlDone(download_id, DownloadProtectionService::SAFE);
106 return false; 104 return false;
107 } 105 }
108 106
109 void ChromeDownloadManagerDelegate::ChooseDownloadPath( 107 void ChromeDownloadManagerDelegate::ChooseDownloadPath(
110 TabContents* tab_contents, 108 TabContents* tab_contents,
111 const FilePath& suggested_path, 109 const FilePath& suggested_path,
112 void* data) { 110 void* data) {
113 // Deletes itself. 111 // Deletes itself.
114 new DownloadFilePicker( 112 new DownloadFilePicker(
115 download_manager_, tab_contents, suggested_path, data); 113 download_manager_, tab_contents, suggested_path, data);
116 } 114 }
117 115
118 bool ChromeDownloadManagerDelegate::OverrideIntermediatePath( 116 bool ChromeDownloadManagerDelegate::OverrideIntermediatePath(
119 DownloadItem* item, 117 DownloadItem* item,
120 FilePath* intermediate_path) { 118 FilePath* intermediate_path) {
121 if (item->IsDangerous()) { 119 if (item->needs_quarantine_file()) {
122 // The download is not safe. It's name is already set to an intermediate 120 // The download might not be safe. It's name is already set to an
123 // name, so no need to override. 121 // intermediate name, so no need to override.
124 return false; 122 return false;
125 } 123 }
126 124
127 // The download is a safe download. We need to rename it to its intermediate 125 // The download is a safe download. We need to rename it to its intermediate
128 // '.crdownload' path. The final name after user confirmation will be set 126 // '.crdownload' path. The final name after user confirmation will be set
129 // from DownloadItem::OnDownloadCompleting. 127 // from DownloadItem::OnDownloadCompleting.
130 *intermediate_path = download_util::GetCrDownloadPath(item->full_path()); 128 *intermediate_path = download_util::GetCrDownloadPath(item->full_path());
131 return true; 129 return true;
132 } 130 }
133 131
(...skipping 23 matching lines...) Expand all
157 // See if there is already a pending SafeBrowsing check for that download. 155 // See if there is already a pending SafeBrowsing check for that download.
158 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id()); 156 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id());
159 if (it != safe_browsing_state_.end()) { 157 if (it != safe_browsing_state_.end()) {
160 SafeBrowsingState state = it->second; 158 SafeBrowsingState state = it->second;
161 if (!state.pending) { 159 if (!state.pending) {
162 safe_browsing_state_.erase(it); 160 safe_browsing_state_.erase(it);
163 } 161 }
164 return !state.pending; 162 return !state.pending;
165 } 163 }
166 // Begin the safe browsing download protection check. 164 // Begin the safe browsing download protection check.
167 SafeBrowsingService* sb_service = 165 DownloadProtectionService* service = GetDownloadProtectionService();
168 g_browser_process->safe_browsing_service(); 166 if (service) {
169 if (sb_service && sb_service->download_protection_service() &&
170 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
171 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = " 167 VLOG(2) << __FUNCTION__ << "() Start SB download check for download = "
172 << item->DebugString(false); 168 << item->DebugString(false);
173 sb_service->download_protection_service()->CheckClientDownload( 169 service->CheckClientDownload(
174 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item), 170 DownloadProtectionService::DownloadInfo::FromDownloadItem(*item),
175 base::Bind( 171 base::Bind(
176 &ChromeDownloadManagerDelegate::CheckClientDownloadDone, 172 &ChromeDownloadManagerDelegate::CheckClientDownloadDone,
177 this, 173 this,
178 item->id())); 174 item->id()));
179 SafeBrowsingState state; 175 SafeBrowsingState state;
180 state.pending = true; 176 state.pending = true;
181 state.verdict = DownloadProtectionService::SAFE; 177 state.verdict = DownloadProtectionService::SAFE;
182 safe_browsing_state_[item->id()] = state; 178 safe_browsing_state_[item->id()] = state;
183 return false; 179 return false;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 288
293 float progress = 0; 289 float progress = 0;
294 int download_count = 0; 290 int download_count = 0;
295 bool progress_known = 291 bool progress_known =
296 g_browser_process->download_status_updater()->GetProgress( 292 g_browser_process->download_status_updater()->GetProgress(
297 &progress, &download_count); 293 &progress, &download_count);
298 download_util::UpdateAppIconDownloadProgress( 294 download_util::UpdateAppIconDownloadProgress(
299 download_count, progress_known, progress); 295 download_count, progress_known, progress);
300 } 296 }
301 297
298 DownloadProtectionService*
299 ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
300 #if defined(ENABLE_SAFE_BROWSING)
301 SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
302 if (sb_service && sb_service->download_protection_service() &&
303 profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
304 return sb_service->download_protection_service();
305 }
306 #endif
307 return NULL;
308 }
309
302 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone( 310 void ChromeDownloadManagerDelegate::CheckDownloadUrlDone(
303 int32 download_id, 311 int32 download_id,
304 DownloadProtectionService::DownloadCheckResult result) { 312 DownloadProtectionService::DownloadCheckResult result) {
305 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
306 DownloadItem* download = 314 DownloadItem* download =
307 download_manager_->GetActiveDownloadItem(download_id); 315 download_manager_->GetActiveDownloadItem(download_id);
308 if (!download) 316 if (!download)
309 return; 317 return;
310 318
311 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false) 319 VLOG(2) << __FUNCTION__ << "() download = " << download->DebugString(false)
(...skipping 11 matching lines...) Expand all
323 int32 download_id, 331 int32 download_id,
324 DownloadProtectionService::DownloadCheckResult result) { 332 DownloadProtectionService::DownloadCheckResult result) {
325 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id); 333 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id);
326 if (!item) { 334 if (!item) {
327 safe_browsing_state_.erase(download_id); // Just in case. 335 safe_browsing_state_.erase(download_id); // Just in case.
328 return; 336 return;
329 } 337 }
330 338
331 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false) 339 VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false)
332 << " verdict = " << result; 340 << " verdict = " << result;
333 // TODO(noelutz): 341 // We only mark the content as being dangerous if the download's safety state
334 // 1) display a warning if the result is DANGEROUS. 342 // has not been set to DANGEROUS yet. We don't want to show two warnings.
335 // 2) make sure we haven't already displayed a warning for the URL. 343 if (result == DownloadProtectionService::DANGEROUS &&
336 // 3) disable the existing dangerous file warning for executables. 344 item->safety_state() == DownloadItem::SAFE)
345 item->MarkContentDangerous();
337 346
338 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id()); 347 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id());
339 DCHECK(it != safe_browsing_state_.end() && it->second.pending); 348 DCHECK(it != safe_browsing_state_.end() && it->second.pending);
340 if (it != safe_browsing_state_.end()) { 349 if (it != safe_browsing_state_.end()) {
341 it->second.pending = false; 350 it->second.pending = false;
342 it->second.verdict = result; 351 it->second.verdict = result;
343 } 352 }
344 download_manager_->MaybeCompleteDownload(item); 353 download_manager_->MaybeCompleteDownload(item);
345 } 354 }
346 355
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 state.suggested_path = download_prefs_->download_path(); 420 state.suggested_path = download_prefs_->download_path();
412 } 421 }
413 state.suggested_path = state.suggested_path.Append(generated_name); 422 state.suggested_path = state.suggested_path.Append(generated_name);
414 } else { 423 } else {
415 state.suggested_path = state.force_file_name; 424 state.suggested_path = state.force_file_name;
416 } 425 }
417 426
418 if (!state.prompt_user_for_save_location && state.force_file_name.empty()) { 427 if (!state.prompt_user_for_save_location && state.force_file_name.empty()) {
419 state.is_dangerous_file = 428 state.is_dangerous_file =
420 IsDangerousFile(*download, state, visited_referrer_before); 429 IsDangerousFile(*download, state, visited_referrer_before);
430 state.needs_quarantine_file = true;
421 } 431 }
422 432
433 #if defined(ENABLE_SAFE_BROWSING)
434 DownloadProtectionService* service = GetDownloadProtectionService();
435 // Return false if this type of files is handled by the enhanced SafeBrowsing
436 // download protection.
437 if (service && service->enabled() &&
438 service->IsSupportedFileType(state.suggested_path.BaseName())) {
Randy Smith (Not in Mondays) 2011/11/16 17:52:41 Asanka: I just wanted to explicitly check with you
asanka 2011/11/16 18:34:05 Good question. At this point state.suggested_path
noelutz 2011/11/16 23:15:07 I don't think so. I think that's good enough for
439 state.is_dangerous_file = false;
440 state.needs_quarantine_file = true;
441 }
442 #endif
443
423 // We need to move over to the download thread because we don't want to stat 444 // We need to move over to the download thread because we don't want to stat
424 // the suggested path on the UI thread. 445 // the suggested path on the UI thread.
425 // We can only access preferences on the UI thread, so check the download path 446 // We can only access preferences on the UI thread, so check the download path
426 // now and pass the value to the FILE thread. 447 // now and pass the value to the FILE thread.
427 BrowserThread::PostTask( 448 BrowserThread::PostTask(
428 BrowserThread::FILE, FROM_HERE, 449 BrowserThread::FILE, FROM_HERE,
429 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists, 450 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists,
430 this, download->id(), state, 451 this, download->id(), state,
431 download_prefs_->download_path())); 452 download_prefs_->download_path()));
432 } 453 }
(...skipping 14 matching lines...) Expand all
447 FilePath dir = state.suggested_path.DirName(); 468 FilePath dir = state.suggested_path.DirName();
448 FilePath filename = state.suggested_path.BaseName(); 469 FilePath filename = state.suggested_path.BaseName();
449 if (!file_util::PathIsWritable(dir)) { 470 if (!file_util::PathIsWritable(dir)) {
450 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; 471 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\"";
451 state.prompt_user_for_save_location = true; 472 state.prompt_user_for_save_location = true;
452 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); 473 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path);
453 state.suggested_path = state.suggested_path.Append(filename); 474 state.suggested_path = state.suggested_path.Append(filename);
454 } 475 }
455 476
456 // If the download is deemed dangerous, we'll use a temporary name for it. 477 // If the download is deemed dangerous, we'll use a temporary name for it.
457 if (state.IsDangerous()) { 478 if (state.needs_quarantine_file) {
458 state.target_name = FilePath(state.suggested_path).BaseName(); 479 state.target_name = FilePath(state.suggested_path).BaseName();
459 // Create a temporary file to hold the file until the user approves its 480 // Create a temporary file to hold the file until the user approves its
460 // download. 481 // download.
461 FilePath::StringType file_name; 482 FilePath::StringType file_name;
462 FilePath path; 483 FilePath path;
463 #if defined(OS_WIN) 484 #if defined(OS_WIN)
464 string16 unconfirmed_prefix = 485 string16 unconfirmed_prefix =
465 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); 486 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX);
466 #else 487 #else
467 std::string unconfirmed_prefix = 488 std::string unconfirmed_prefix =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 << state.suggested_path.value() << "\""; 520 << state.suggested_path.value() << "\"";
500 state.prompt_user_for_save_location = true; 521 state.prompt_user_for_save_location = true;
501 } 522 }
502 } 523 }
503 524
504 // Create an empty file at the suggested path so that we don't allocate the 525 // Create an empty file at the suggested path so that we don't allocate the
505 // same "non-existant" path to multiple downloads. 526 // same "non-existant" path to multiple downloads.
506 // See: http://code.google.com/p/chromium/issues/detail?id=3662 527 // See: http://code.google.com/p/chromium/issues/detail?id=3662
507 if (!state.prompt_user_for_save_location && 528 if (!state.prompt_user_for_save_location &&
508 state.force_file_name.empty()) { 529 state.force_file_name.empty()) {
509 if (state.IsDangerous()) 530 if (state.needs_quarantine_file)
510 file_util::WriteFile(state.suggested_path, "", 0); 531 file_util::WriteFile(state.suggested_path, "", 0);
511 else 532 else
512 file_util::WriteFile(download_util::GetCrDownloadPath( 533 file_util::WriteFile(download_util::GetCrDownloadPath(
513 state.suggested_path), "", 0); 534 state.suggested_path), "", 0);
514 } 535 }
515 536
516 BrowserThread::PostTask( 537 BrowserThread::PostTask(
517 BrowserThread::UI, FROM_HERE, 538 BrowserThread::UI, FROM_HERE,
518 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable, 539 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable,
519 this, download_id, state)); 540 this, download_id, state));
(...skipping 14 matching lines...) Expand all
534 bool ChromeDownloadManagerDelegate::IsDangerousFile( 555 bool ChromeDownloadManagerDelegate::IsDangerousFile(
535 const DownloadItem& download, 556 const DownloadItem& download,
536 const DownloadStateInfo& state, 557 const DownloadStateInfo& state,
537 bool visited_referrer_before) { 558 bool visited_referrer_before) {
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
539 560
540 // Anything loaded directly from the address bar is OK. 561 // Anything loaded directly from the address bar is OK.
541 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR) 562 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR)
542 return false; 563 return false;
543 564
544 // Return false if this type of files is handled by the enhanced SafeBrowsing
545 // download protection.
546 // TODO(noelutz): implement that check.
547
548 // Extensions that are not from the gallery are considered dangerous. 565 // Extensions that are not from the gallery are considered dangerous.
549 if (IsExtensionDownload(&download)) { 566 if (IsExtensionDownload(&download)) {
550 ExtensionService* service = profile_->GetExtensionService(); 567 ExtensionService* service = profile_->GetExtensionService();
551 if (!service || !service->IsDownloadFromGallery(download.GetURL(), 568 if (!service || !service->IsDownloadFromGallery(download.GetURL(),
552 download.referrer_url())) 569 download.referrer_url()))
553 return true; 570 return true;
554 } 571 }
555 572
556 // Anything the user has marked auto-open is OK if it's user-initiated. 573 // Anything the user has marked auto-open is OK if it's user-initiated.
557 if (ShouldOpenFileBasedOnExtension(state.suggested_path) && 574 if (ShouldOpenFileBasedOnExtension(state.suggested_path) &&
(...skipping 14 matching lines...) Expand all
572 int32 download_id, int64 db_handle) { 589 int32 download_id, int64 db_handle) {
573 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 590 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
574 // call this function with an invalid |db_handle|. For instance, this can 591 // call this function with an invalid |db_handle|. For instance, this can
575 // happen when the history database is offline. We cannot have multiple 592 // happen when the history database is offline. We cannot have multiple
576 // DownloadItems with the same invalid db_handle, so we need to assign a 593 // DownloadItems with the same invalid db_handle, so we need to assign a
577 // unique |db_handle| here. 594 // unique |db_handle| here.
578 if (db_handle == DownloadItem::kUninitializedHandle) 595 if (db_handle == DownloadItem::kUninitializedHandle)
579 db_handle = download_history_->GetNextFakeDbHandle(); 596 db_handle = download_history_->GetNextFakeDbHandle();
580 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); 597 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle);
581 } 598 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698