| OLD | NEW |
| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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())) { |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |