diff options
author | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 11:38:12 +0000 |
---|---|---|
committer | joaodasilva@chromium.org <joaodasilva@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 11:38:12 +0000 |
commit | a5a0ab36f31f06c69ef17240caaf3f899b161be7 (patch) | |
tree | 26992f5c35f422012f199f81958c1ba4444d2694 | |
parent | aa5f888a50689569f458c096fa63dba7a9d24a97 (diff) | |
download | chromium_src-a5a0ab36f31f06c69ef17240caaf3f899b161be7.zip chromium_src-a5a0ab36f31f06c69ef17240caaf3f899b161be7.tar.gz chromium_src-a5a0ab36f31f06c69ef17240caaf3f899b161be7.tar.bz2 |
Use the IAttachmentExecute service to set the Zone.Identifier stream,
when available. This is used to mark files as untrusted, because they were downloaded from the internet.
The DownloadTest.CheckInternetZone browser test was failing previously because
the Zone.Identifier stream created by the IAttachmentExecute service uses \r\n
for newlines, and the test was checking for \n.
See also http://codereview.chromium.org/590001, which this should close.
BUG=5719
TEST=DownloadTest.CheckInternetZone
Review URL: http://codereview.chromium.org/6880236
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83502 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/test/test_file_util_win.cc | 29 | ||||
-rw-r--r-- | chrome/browser/download/base_file.cc | 4 | ||||
-rw-r--r-- | chrome/common/win_safe_util.cc | 89 | ||||
-rw-r--r-- | chrome/common/win_safe_util.h | 12 |
4 files changed, 93 insertions, 41 deletions
diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc index 0159d2e..cec2f51 100644 --- a/base/test/test_file_util_win.cc +++ b/base/test/test_file_util_win.cc @@ -12,6 +12,7 @@ #include "base/file_path.h" #include "base/file_util.h" #include "base/logging.h" +#include "base/string_split.h" #include "base/win/scoped_handle.h" #include "base/threading/platform_thread.h" @@ -202,19 +203,21 @@ bool HasInternetZoneIdentifier(const FilePath& full_path) { if (!file_util::ReadFileToString(zone_path, &zone_path_contents)) return false; - static const char kInternetIdentifier[] = "[ZoneTransfer]\nZoneId=3"; - static const size_t kInternetIdentifierSize = - // Don't include null byte in size of identifier. - arraysize(kInternetIdentifier) - 1; - - // Our test is that the initial characters match the above, and that - // the character after the end of the string is eof, null, or newline; any - // of those three will invoke the Window Finder cautionary dialog. - return ((zone_path_contents.compare(0, kInternetIdentifierSize, - kInternetIdentifier) == 0) && - (kInternetIdentifierSize == zone_path_contents.length() || - zone_path_contents[kInternetIdentifierSize] == '\0' || - zone_path_contents[kInternetIdentifierSize] == '\n')); + std::vector<std::string> lines; + // This call also trims whitespaces, including carriage-returns (\r). + base::SplitString(zone_path_contents, '\n', &lines); + + switch (lines.size()) { + case 3: + // optional empty line at end of file: + if (lines[2] != "") + return false; + // fall through: + case 2: + return lines[0] == "[ZoneTransfer]" && lines[1] == "ZoneId=3"; + default: + return false; + } } std::wstring FilePathAsWString(const FilePath& path) { diff --git a/chrome/browser/download/base_file.cc b/chrome/browser/download/base_file.cc index d135191..7ea96b5 100644 --- a/chrome/browser/download/base_file.cc +++ b/chrome/browser/download/base_file.cc @@ -8,6 +8,7 @@ #include "base/format_macros.h" #include "base/logging.h" #include "base/stringprintf.h" +#include "base/utf_string_conversions.h" #include "crypto/secure_hash.h" #include "net/base/file_stream.h" #include "net/base/net_errors.h" @@ -184,7 +185,8 @@ void BaseFile::AnnotateWithSourceInformation() { #if defined(OS_WIN) // Sets the Zone to tell Windows that this file comes from the internet. // We ignore the return value because a failure is not fatal. - win_util::SetInternetZoneIdentifier(full_path_); + win_util::SetInternetZoneIdentifier(full_path_, + UTF8ToWide(source_url_.spec())); #elif defined(OS_MACOSX) file_metadata::AddQuarantineMetadataToFile(full_path_, source_url_, referrer_url_); diff --git a/chrome/common/win_safe_util.cc b/chrome/common/win_safe_util.cc index 6e4ff14..ff65a7e 100644 --- a/chrome/common/win_safe_util.cc +++ b/chrome/common/win_safe_util.cc @@ -14,6 +14,43 @@ #include "base/string_util.h" #include "base/win/scoped_comptr.h" +namespace { + +// This GUID is associated with any 'don't ask me again' settings that the +// user can select for different file types. +// {2676A9A2-D919-4fee-9187-152100393AB2} +static const GUID kClientID = { 0x2676a9a2, 0xd919, 0x4fee, + { 0x91, 0x87, 0x15, 0x21, 0x0, 0x39, 0x3a, 0xb2 } }; + +// Directly writes the ZoneIdentifier stream, without using the +// IAttachmentExecute service. +bool SetInternetZoneIdentifierDirectly(const FilePath& full_path) { + const DWORD kShare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + std::wstring path = full_path.value() + L":Zone.Identifier"; + HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, kShare, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == file) + return false; + + static const char kIdentifier[] = "[ZoneTransfer]\r\nZoneId=3\r\n"; + // Don't include trailing null in data written. + static const DWORD kIdentifierSize = arraysize(kIdentifier) - 1; + DWORD written = 0; + BOOL result = WriteFile(file, kIdentifier, kIdentifierSize, &written, + NULL); + BOOL flush_result = FlushFileBuffers(file); + CloseHandle(file); + + if (!result || !flush_result || written != kIdentifierSize) { + NOTREACHED(); + return false; + } + + return true; +} + +} + namespace win_util { // This function implementation is based on the attachment execution @@ -36,12 +73,6 @@ bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, return app::win::OpenItemViaShell(full_path); } - // This GUID is associated with any 'don't ask me again' settings that the - // user can select for different file types. - // {2676A9A2-D919-4fee-9187-152100393AB2} - static const GUID kClientID = { 0x2676a9a2, 0xd919, 0x4fee, - { 0x91, 0x87, 0x15, 0x21, 0x0, 0x39, 0x3a, 0xb2 } }; - attachment_services->SetClientGuid(kClientID); if (!window_title.empty()) @@ -84,27 +115,39 @@ bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, return app::win::OpenItemViaShellNoZoneCheck(full_path); } -bool SetInternetZoneIdentifier(const FilePath& full_path) { - const DWORD kShare = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - std::wstring path = full_path.value() + L":Zone.Identifier"; - HANDLE file = CreateFile(path.c_str(), GENERIC_WRITE, kShare, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == file) +bool SetInternetZoneIdentifier(const FilePath& full_path, + const std::wstring& source_url) { + base::win::ScopedComPtr<IAttachmentExecute> attachment_services; + HRESULT hr = attachment_services.CreateInstance(CLSID_AttachmentServices); + + if (FAILED(hr)) { + // We don't have Attachment Execution Services, it must be a pre-XP.SP2 + // Windows installation, or the thread does not have COM initialized. + if (hr == CO_E_NOTINITIALIZED) { + NOTREACHED(); + return false; + } + + // Write the ZoneIdentifier file directly. + return SetInternetZoneIdentifierDirectly(full_path); + } + + hr = attachment_services->SetClientGuid(kClientID); + if (FAILED(hr)) return false; - static const char kIdentifier[] = "[ZoneTransfer]\nZoneId=3"; - // Don't include trailing null in data written. - static const DWORD kIdentifierSize = arraysize(kIdentifier) - 1; - DWORD written = 0; - BOOL result = WriteFile(file, kIdentifier, kIdentifierSize, &written, - NULL); - BOOL flush_result = FlushFileBuffers(file); - CloseHandle(file); + hr = attachment_services->SetLocalPath(full_path.value().c_str()); + if (FAILED(hr)) + return false; - if (!result || !flush_result || written != kIdentifierSize) { - NOTREACHED(); + // Source is necessary for files ending in ".tmp" to avoid error 0x800c000e. + hr = attachment_services->SetSource(source_url.c_str()); + if (FAILED(hr)) + return false; + + hr = attachment_services->Save(); + if (FAILED(hr)) return false; - } return true; } diff --git a/chrome/common/win_safe_util.h b/chrome/common/win_safe_util.h index dee073d..424e8f8 100644 --- a/chrome/common/win_safe_util.h +++ b/chrome/common/win_safe_util.h @@ -1,9 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_COMMON_WIN_SAFE_UTIL_H__ -#define CHROME_COMMON_WIN_SAFE_UTIL_H__ +#ifndef CHROME_COMMON_WIN_SAFE_UTIL_H_ +#define CHROME_COMMON_WIN_SAFE_UTIL_H_ #pragma once #include <string> @@ -45,7 +45,11 @@ bool SaferOpenItemViaShell(HWND hwnd, const std::wstring& window_title, // function succeeds, false otherwise. A failure is expected on system where // the Zone Identifier is not supported, like a machine with a FAT32 filesystem. // It should not be considered fatal. -bool SetInternetZoneIdentifier(const FilePath& full_path); +// +// |full_path| is the path to save the file to, and +// |source_url| is the URL where the file was downloaded from. +bool SetInternetZoneIdentifier(const FilePath& full_path, + const std::wstring& source_url); } // namespace win_util |