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->GetDangerType() != DownloadStateInfo::NOT_DANGEROUS) { |
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 #if defined(ENABLE_SAFE_BROWSING) |
| 299 DownloadProtectionService* |
| 300 ChromeDownloadManagerDelegate::GetDownloadProtectionService() { |
| 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 return NULL; |
| 307 } |
| 308 #endif |
| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 !download_manager_->LastDownloadPath().empty()) { | 417 !download_manager_->LastDownloadPath().empty()) { |
409 state.suggested_path = download_manager_->LastDownloadPath(); | 418 state.suggested_path = download_manager_->LastDownloadPath(); |
410 } else { | 419 } else { |
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 && |
419 state.is_dangerous_file = | 428 state.force_file_name.empty() && |
420 IsDangerousFile(*download, state, visited_referrer_before); | 429 IsDangerousFile(*download, state, visited_referrer_before)) { |
| 430 state.danger = DownloadStateInfo::DANGEROUS_FILE; |
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 // TODO(noelutz): if the user changes the extension name in the UI to |
| 440 // something like .exe SafeBrowsing will currently *not* check if the |
| 441 // download is malicious. |
| 442 state.danger = DownloadStateInfo::MAYBE_DANGEROUS_CONTENT; |
| 443 } |
| 444 #endif |
| 445 |
423 // We need to move over to the download thread because we don't want to stat | 446 // We need to move over to the download thread because we don't want to stat |
424 // the suggested path on the UI thread. | 447 // the suggested path on the UI thread. |
425 // We can only access preferences on the UI thread, so check the download path | 448 // We can only access preferences on the UI thread, so check the download path |
426 // now and pass the value to the FILE thread. | 449 // now and pass the value to the FILE thread. |
427 BrowserThread::PostTask( | 450 BrowserThread::PostTask( |
428 BrowserThread::FILE, FROM_HERE, | 451 BrowserThread::FILE, FROM_HERE, |
429 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists, | 452 base::Bind(&ChromeDownloadManagerDelegate::CheckIfSuggestedPathExists, |
430 this, download->id(), state, | 453 this, download->id(), state, |
431 download_prefs_->download_path())); | 454 download_prefs_->download_path())); |
432 } | 455 } |
(...skipping 13 matching lines...) Expand all Loading... |
446 // to the user's "My Documents" directory. We'll prompt them in this case. | 469 // to the user's "My Documents" directory. We'll prompt them in this case. |
447 FilePath dir = state.suggested_path.DirName(); | 470 FilePath dir = state.suggested_path.DirName(); |
448 FilePath filename = state.suggested_path.BaseName(); | 471 FilePath filename = state.suggested_path.BaseName(); |
449 if (!file_util::PathIsWritable(dir)) { | 472 if (!file_util::PathIsWritable(dir)) { |
450 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; | 473 VLOG(1) << "Unable to write to directory \"" << dir.value() << "\""; |
451 state.prompt_user_for_save_location = true; | 474 state.prompt_user_for_save_location = true; |
452 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); | 475 PathService::Get(chrome::DIR_USER_DOCUMENTS, &state.suggested_path); |
453 state.suggested_path = state.suggested_path.Append(filename); | 476 state.suggested_path = state.suggested_path.Append(filename); |
454 } | 477 } |
455 | 478 |
456 // If the download is deemed dangerous, we'll use a temporary name for it. | 479 // If the download is possibly dangerous, we'll use a temporary name for it. |
457 if (state.IsDangerous()) { | 480 if (state.danger != DownloadStateInfo::NOT_DANGEROUS) { |
458 state.target_name = FilePath(state.suggested_path).BaseName(); | 481 state.target_name = FilePath(state.suggested_path).BaseName(); |
459 // Create a temporary file to hold the file until the user approves its | 482 // Create a temporary file to hold the file until the user approves its |
460 // download. | 483 // download. |
461 FilePath::StringType file_name; | 484 FilePath::StringType file_name; |
462 FilePath path; | 485 FilePath path; |
463 #if defined(OS_WIN) | 486 #if defined(OS_WIN) |
464 string16 unconfirmed_prefix = | 487 string16 unconfirmed_prefix = |
465 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); | 488 l10n_util::GetStringUTF16(IDS_DOWNLOAD_UNCONFIRMED_PREFIX); |
466 #else | 489 #else |
467 std::string unconfirmed_prefix = | 490 std::string unconfirmed_prefix = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 << state.suggested_path.value() << "\""; | 522 << state.suggested_path.value() << "\""; |
500 state.prompt_user_for_save_location = true; | 523 state.prompt_user_for_save_location = true; |
501 } | 524 } |
502 } | 525 } |
503 | 526 |
504 // Create an empty file at the suggested path so that we don't allocate the | 527 // Create an empty file at the suggested path so that we don't allocate the |
505 // same "non-existant" path to multiple downloads. | 528 // same "non-existant" path to multiple downloads. |
506 // See: http://code.google.com/p/chromium/issues/detail?id=3662 | 529 // See: http://code.google.com/p/chromium/issues/detail?id=3662 |
507 if (!state.prompt_user_for_save_location && | 530 if (!state.prompt_user_for_save_location && |
508 state.force_file_name.empty()) { | 531 state.force_file_name.empty()) { |
509 if (state.IsDangerous()) | 532 if (state.danger != DownloadStateInfo::NOT_DANGEROUS) |
510 file_util::WriteFile(state.suggested_path, "", 0); | 533 file_util::WriteFile(state.suggested_path, "", 0); |
511 else | 534 else |
512 file_util::WriteFile(download_util::GetCrDownloadPath( | 535 file_util::WriteFile(download_util::GetCrDownloadPath( |
513 state.suggested_path), "", 0); | 536 state.suggested_path), "", 0); |
514 } | 537 } |
515 | 538 |
516 BrowserThread::PostTask( | 539 BrowserThread::PostTask( |
517 BrowserThread::UI, FROM_HERE, | 540 BrowserThread::UI, FROM_HERE, |
518 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable, | 541 base::Bind(&ChromeDownloadManagerDelegate::OnPathExistenceAvailable, |
519 this, download_id, state)); | 542 this, download_id, state)); |
(...skipping 14 matching lines...) Expand all Loading... |
534 bool ChromeDownloadManagerDelegate::IsDangerousFile( | 557 bool ChromeDownloadManagerDelegate::IsDangerousFile( |
535 const DownloadItem& download, | 558 const DownloadItem& download, |
536 const DownloadStateInfo& state, | 559 const DownloadStateInfo& state, |
537 bool visited_referrer_before) { | 560 bool visited_referrer_before) { |
538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
539 | 562 |
540 // Anything loaded directly from the address bar is OK. | 563 // Anything loaded directly from the address bar is OK. |
541 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR) | 564 if (state.transition_type & content::PAGE_TRANSITION_FROM_ADDRESS_BAR) |
542 return false; | 565 return false; |
543 | 566 |
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. | 567 // Extensions that are not from the gallery are considered dangerous. |
549 if (IsExtensionDownload(&download)) { | 568 if (IsExtensionDownload(&download)) { |
550 ExtensionService* service = profile_->GetExtensionService(); | 569 ExtensionService* service = profile_->GetExtensionService(); |
551 if (!service || !service->IsDownloadFromGallery(download.GetURL(), | 570 if (!service || !service->IsDownloadFromGallery(download.GetURL(), |
552 download.referrer_url())) | 571 download.referrer_url())) |
553 return true; | 572 return true; |
554 } | 573 } |
555 | 574 |
556 // Anything the user has marked auto-open is OK if it's user-initiated. | 575 // Anything the user has marked auto-open is OK if it's user-initiated. |
557 if (ShouldOpenFileBasedOnExtension(state.suggested_path) && | 576 if (ShouldOpenFileBasedOnExtension(state.suggested_path) && |
(...skipping 14 matching lines...) Expand all Loading... |
572 int32 download_id, int64 db_handle) { | 591 int32 download_id, int64 db_handle) { |
573 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 592 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
574 // call this function with an invalid |db_handle|. For instance, this can | 593 // call this function with an invalid |db_handle|. For instance, this can |
575 // happen when the history database is offline. We cannot have multiple | 594 // 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 | 595 // DownloadItems with the same invalid db_handle, so we need to assign a |
577 // unique |db_handle| here. | 596 // unique |db_handle| here. |
578 if (db_handle == DownloadItem::kUninitializedHandle) | 597 if (db_handle == DownloadItem::kUninitializedHandle) |
579 db_handle = download_history_->GetNextFakeDbHandle(); | 598 db_handle = download_history_->GetNextFakeDbHandle(); |
580 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); | 599 download_manager_->OnItemAddedToPersistentStore(download_id, db_handle); |
581 } | 600 } |
OLD | NEW |