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 = download_protection_service(); |
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 = download_protection_service(); |
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::download_protection_service() { | |
asanka
2011/11/16 03:23:48
Nit: This is not a trivial accessor.
noelutz
2011/11/16 03:50:26
Done.
| |
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 // TODO(noelutz): ensure that URL warning was not already shown. |
asanka
2011/11/16 03:23:48
Shall we, instead, ensure that the DownloadItem is
noelutz
2011/11/16 03:50:26
Much easier. Done.
| |
334 // 1) display a warning if the result is DANGEROUS. | 342 if (result == DownloadProtectionService::DANGEROUS) |
335 // 2) make sure we haven't already displayed a warning for the URL. | 343 item->MarkContentDangerous(); |
336 // 3) disable the existing dangerous file warning for executables. | |
337 | 344 |
338 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id()); | 345 SafeBrowsingStateMap::iterator it = safe_browsing_state_.find(item->id()); |
339 DCHECK(it != safe_browsing_state_.end() && it->second.pending); | 346 DCHECK(it != safe_browsing_state_.end() && it->second.pending); |
340 if (it != safe_browsing_state_.end()) { | 347 if (it != safe_browsing_state_.end()) { |
341 it->second.pending = false; | 348 it->second.pending = false; |
342 it->second.verdict = result; | 349 it->second.verdict = result; |
343 } | 350 } |
344 download_manager_->MaybeCompleteDownload(item); | 351 download_manager_->MaybeCompleteDownload(item); |
345 } | 352 } |
346 | 353 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 state.suggested_path = download_prefs_->download_path(); | 418 state.suggested_path = download_prefs_->download_path(); |
412 } | 419 } |
413 state.suggested_path = state.suggested_path.Append(generated_name); | 420 state.suggested_path = state.suggested_path.Append(generated_name); |
414 } else { | 421 } else { |
415 state.suggested_path = state.force_file_name; | 422 state.suggested_path = state.force_file_name; |
416 } | 423 } |
417 | 424 |
418 if (!state.prompt_user_for_save_location && state.force_file_name.empty()) { | 425 if (!state.prompt_user_for_save_location && state.force_file_name.empty()) { |
419 state.is_dangerous_file = | 426 state.is_dangerous_file = |
420 IsDangerousFile(*download, state, visited_referrer_before); | 427 IsDangerousFile(*download, state, visited_referrer_before); |
428 state.needs_quarantine_file = true; | |
421 } | 429 } |
422 | 430 |
431 #if defined(ENABLE_SAFE_BROWSING) | |
432 DownloadProtectionService* service = download_protection_service(); | |
433 // Return false if this type of files is handled by the enhanced SafeBrowsing | |
434 // download protection. | |
435 if (service && service->enabled() && | |
436 service->IsSupportedFileType(state.suggested_path.BaseName())) { | |
437 state.is_dangerous_file = false; | |
438 state.needs_quarantine_file = true; | |
439 } | |
440 #endif | |
441 | |
423 // We need to move over to the download thread because we don't want to stat | 442 // We need to move over to the download thread because we don't want to stat |
424 // the suggested path on the UI thread. | 443 // the suggested path on the UI thread. |
425 // We can only access preferences on the UI thread, so check the download path | 444 // We can only access preferences on the UI thread, so check the download path |
426 // now and pass the value to the FILE thread. | 445 // now and pass the value to the FILE thread. |
427 BrowserThread::PostTask( | 446 BrowserThread::PostTask( |
428 BrowserThread::FILE, FROM_HERE, | 447 BrowserThread::FILE, FROM_HERE, |
429 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists, | 448 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists, |
430 this, download->id(), state, | 449 this, download->id(), state, |
431 download_prefs_->download_path())); | 450 download_prefs_->download_path())); |
432 } | 451 } |
(...skipping 14 matching lines...) Expand all Loading... | |
447 FilePath dir = state.suggested_path.DirName(); | 466 FilePath dir = state.suggested_path.DirName(); |
448 FilePath filename = state.suggested_path.BaseName(); | 467 FilePath filename = state.suggested_path.BaseName(); |
449 if (!file_util::PathIsWritable(dir)) { | 468 if (!file_util::PathIsWritable(dir)) { |
450 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; | 469 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; |
451 state.prompt_user_for_save_location = true; | 470 state.prompt_user_for_save_location = true; |
452 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); | 471 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); |
453 state.suggested_path = state.suggested_path.Append(filename); | 472 state.suggested_path = state.suggested_path.Append(filename); |
454 } | 473 } |
455 | 474 |
456 // If the download is deemed dangerous, we'll use a temporary name for it. | 475 // If the download is deemed dangerous, we'll use a temporary name for it. |
457 if (state.IsDangerous()) { | 476 if (state.needs_quarantine_file) { |
458 state.target_name = FilePath(state.suggested_path).BaseName(); | 477 state.target_name = FilePath(state.suggested_path).BaseName(); |
459 // Create a temporary file to hold the file until the user approves its | 478 // Create a temporary file to hold the file until the user approves its |
460 // download. | 479 // download. |
461 FilePath::StringType file_name; | 480 FilePath::StringType file_name; |
462 FilePath path; | 481 FilePath path; |
463 #if defined(OS_WIN) | 482 #if defined(OS_WIN) |
464 string16 unconfirmed_prefix = | 483 string16 unconfirmed_prefix = |
465 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 484 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
466 #else | 485 #else |
467 std::string unconfirmed_prefix = | 486 std::string unconfirmed_prefix = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 << state.suggested_path.value() << "\""; | 518 << state.suggested_path.value() << "\""; |
500 state.prompt_user_for_save_location = true; | 519 state.prompt_user_for_save_location = true; |
501 } | 520 } |
502 } | 521 } |
503 | 522 |
504 // Create an empty file at the suggested path so that we don't allocate the | 523 // Create an empty file at the suggested path so that we don't allocate the |
505 // same "non-existant" path to multiple downloads. | 524 // same "non-existant" path to multiple downloads. |
506 // See: http://code.google.com/p/chromium/issues/detail?id=3662 | 525 // See: http://code.google.com/p/chromium/issues/detail?id=3662 |
507 if (!state.prompt_user_for_save_location && | 526 if (!state.prompt_user_for_save_location && |
508 state.force_file_name.empty()) { | 527 state.force_file_name.empty()) { |
509 if (state.IsDangerous()) | 528 if (state.needs_quarantine_file) |
510 file_util::WriteFile(state.suggested_path, "", 0); | 529 file_util::WriteFile(state.suggested_path, "", 0); |
511 else | 530 else |
512 file_util::WriteFile(download_util::GetCrDownloadPath( | 531 file_util::WriteFile(download_util::GetCrDownloadPath( |
513 state.suggested_path), "", 0); | 532 state.suggested_path), "", 0); |
514 } | 533 } |
515 | 534 |
516 BrowserThread::PostTask( | 535 BrowserThread::PostTask( |
517 BrowserThread::UI, FROM_HERE, | 536 BrowserThread::UI, FROM_HERE, |
518 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable, | 537 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable, |
519 this, download_id, state)); | 538 this, download_id, state)); |
(...skipping 14 matching lines...) Expand all Loading... | |
534 bool ChromeDownloadManagerDelegate::IsDangerousFile( | 553 bool ChromeDownloadManagerDelegate::IsDangerousFile( |
535 const DownloadItem& download, | 554 const DownloadItem& download, |
536 const DownloadStateInfo& state, | 555 const DownloadStateInfo& state, |
537 bool visited_referrer_before) { | 556 bool visited_referrer_before) { |
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
539 | 558 |
540 // Anything loaded directly from the address bar is OK. | 559 // Anything loaded directly from the address bar is OK. |
541 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR) | 560 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR) |
542 return false; | 561 return false; |
543 | 562 |
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. | 563 // Extensions that are not from the gallery are considered dangerous. |
549 if (IsExtensionDownload(&download)) { | 564 if (IsExtensionDownload(&download)) { |
550 ExtensionService* service = profile_->GetExtensionService(); | 565 ExtensionService* service = profile_->GetExtensionService(); |
551 if (!service || !service->IsDownloadFromGallery(download.GetURL(), | 566 if (!service || !service->IsDownloadFromGallery(download.GetURL(), |
552 download.referrer_url())) | 567 download.referrer_url())) |
553 return true; | 568 return true; |
554 } | 569 } |
555 | 570 |
556 // Anything the user has marked auto-open is OK if it's user-initiated. | 571 // Anything the user has marked auto-open is OK if it's user-initiated. |
557 if (ShouldOpenFileBasedOnExtension(state.suggested_path) && | 572 if (ShouldOpenFileBasedOnExtension(state.suggested_path) && |
(...skipping 14 matching lines...) Expand all Loading... | |
572 int32 download_id, int64 db_handle) { | 587 int32 download_id, int64 db_handle) { |
573 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 588 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
574 // call this function with an invalid |db_handle|. For instance, this can | 589 // call this function with an invalid |db_handle|. For instance, this can |
575 // happen when the history database is offline. We cannot have multiple | 590 // 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 | 591 // DownloadItems with the same invalid db_handle, so we need to assign a |
577 // unique |db_handle| here. | 592 // unique |db_handle| here. |
578 if (db_handle == DownloadItem::kUninitializedHandle) | 593 if (db_handle == DownloadItem::kUninitializedHandle) |
579 db_handle = download_history_->GetNextFakeDbHandle(); | 594 db_handle = download_history_->GetNextFakeDbHandle(); |
580 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 595 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
581 } | 596 } |
OLD | NEW |