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

Side by Side Diff: content/common/quarantine/quarantine_mac.mm

Issue 2124373002: [PPAPI] Quarantine files that are writeable by a Pepper plugin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@consolidate-file-metadata
Patch Set: Address comments. Created 4 years 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "content/browser/download/quarantine.h" 5 #include "content/public/common/quarantine.h"
6 6
7 #import <ApplicationServices/ApplicationServices.h> 7 #import <ApplicationServices/ApplicationServices.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/mac/foundation_util.h" 13 #include "base/mac/foundation_util.h"
13 #include "base/mac/mac_logging.h" 14 #include "base/mac/mac_logging.h"
14 #include "base/mac/mac_util.h" 15 #include "base/mac/mac_util.h"
15 #include "base/mac/scoped_cftyperef.h" 16 #include "base/mac/scoped_cftyperef.h"
16 #include "base/mac/scoped_nsobject.h" 17 #include "base/mac/scoped_nsobject.h"
17 #include "base/strings/sys_string_conversions.h" 18 #include "base/strings/sys_string_conversions.h"
18 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
19 #include "url/gurl.h" 20 #include "url/gurl.h"
20 21
21 namespace { 22 namespace {
22 23
23 // Once Chrome no longer supports macOS 10.9, this code will no longer be 24 // Once Chrome no longer supports macOS 10.9, this code will no longer be
24 // necessary. Note that LSCopyItemAttribute was deprecated in macOS 10.8, but 25 // necessary. Note that LSCopyItemAttribute was deprecated in macOS 10.8, but
25 // the replacement to kLSItemQuarantineProperties did not exist until macOS 26 // the replacement to kLSItemQuarantineProperties did not exist until macOS
26 // 10.10. 27 // 10.10.
27 #if !defined(MAC_OS_X_VERSION_10_10) || \ 28 #if !defined(MAC_OS_X_VERSION_10_10) || \
28 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10 29 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
29 #pragma clang diagnostic push 30 #pragma clang diagnostic push
30 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 31 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
31 bool GetQuarantinePropertiesDeprecated( 32 bool GetQuarantinePropertiesDeprecated(
32 const base::FilePath& file, 33 const base::FilePath& file,
33 base::scoped_nsobject<NSMutableDictionary>* properties) { 34 base::scoped_nsobject<NSMutableDictionary>* properties) {
34 const UInt8* path = reinterpret_cast<const UInt8*>(file.value().c_str()); 35 const UInt8* path = reinterpret_cast<const UInt8*>(file.value().c_str());
35 FSRef file_ref; 36 FSRef file_ref;
36 if (FSPathMakeRef(path, &file_ref, nullptr) != noErr) 37 if (FSPathMakeRef(path, &file_ref, nullptr) != noErr)
37 return false; 38 return false;
38 39
39 base::ScopedCFTypeRef<CFTypeRef> quarantine_properties; 40 base::ScopedCFTypeRef<CFTypeRef> quarantine_properties;
40 OSStatus status = LSCopyItemAttribute(&file_ref, kLSRolesAll, 41 OSStatus status =
41 kLSItemQuarantineProperties, quarantine_properties.InitializeInto()); 42 LSCopyItemAttribute(&file_ref, kLSRolesAll, kLSItemQuarantineProperties,
43 quarantine_properties.InitializeInto());
42 if (status != noErr) 44 if (status != noErr)
43 return true; 45 return true;
44 46
45 CFDictionaryRef quarantine_properties_dict = 47 CFDictionaryRef quarantine_properties_dict =
46 base::mac::CFCast<CFDictionaryRef>(quarantine_properties.get()); 48 base::mac::CFCast<CFDictionaryRef>(quarantine_properties.get());
47 if (!quarantine_properties_dict) { 49 if (!quarantine_properties_dict) {
48 LOG(WARNING) << "kLSItemQuarantineProperties is not a dictionary on file " 50 LOG(WARNING) << "kLSItemQuarantineProperties is not a dictionary on file "
49 << file.value(); 51 << file.value();
50 return false; 52 return false;
51 } 53 }
52 54
53 properties->reset( 55 properties->reset(
54 [base::mac::CFToNSCast(quarantine_properties_dict) mutableCopy]); 56 [base::mac::CFToNSCast(quarantine_properties_dict) mutableCopy]);
55 return true; 57 return true;
56 } 58 }
57 59
58 bool SetQuarantinePropertiesDeprecated(const base::FilePath& file, 60 bool SetQuarantinePropertiesDeprecated(const base::FilePath& file,
59 NSDictionary* properties) { 61 NSDictionary* properties) {
60 const UInt8* path = reinterpret_cast<const UInt8*>(file.value().c_str()); 62 const UInt8* path = reinterpret_cast<const UInt8*>(file.value().c_str());
61 FSRef file_ref; 63 FSRef file_ref;
62 if (FSPathMakeRef(path, &file_ref, nullptr) != noErr) 64 if (FSPathMakeRef(path, &file_ref, nullptr) != noErr)
63 return false; 65 return false;
66
64 OSStatus os_error = LSSetItemAttribute( 67 OSStatus os_error = LSSetItemAttribute(
65 &file_ref, kLSRolesAll, kLSItemQuarantineProperties, properties); 68 &file_ref, kLSRolesAll, kLSItemQuarantineProperties, properties);
66 if (os_error != noErr) { 69 if (os_error != noErr) {
67 OSSTATUS_LOG(WARNING, os_error) 70 OSSTATUS_LOG(WARNING, os_error)
68 << "Unable to set quarantine attributes on file " << file.value(); 71 << "Unable to set quarantine attributes on file " << file.value();
69 return false; 72 return false;
70 } 73 }
71 return true; 74 return true;
72 } 75 }
73 #pragma clang diagnostic pop 76 #pragma clang diagnostic pop
(...skipping 23 matching lines...) Expand all
97 return false; 100 return false;
98 } 101 }
99 102
100 if (!quarantine_properties) 103 if (!quarantine_properties)
101 return true; 104 return true;
102 105
103 NSDictionary* quarantine_properties_dict = 106 NSDictionary* quarantine_properties_dict =
104 base::mac::ObjCCast<NSDictionary>(quarantine_properties); 107 base::mac::ObjCCast<NSDictionary>(quarantine_properties);
105 if (!quarantine_properties_dict) { 108 if (!quarantine_properties_dict) {
106 LOG(WARNING) << "Quarantine properties have wrong class: " 109 LOG(WARNING) << "Quarantine properties have wrong class: "
107 << [[[quarantine_properties class] description] UTF8String]; 110 << base::SysNSStringToUTF8(
111 [[quarantine_properties class] description]);
108 return false; 112 return false;
109 } 113 }
110 114
111 properties->reset([quarantine_properties_dict mutableCopy]); 115 properties->reset([quarantine_properties_dict mutableCopy]);
112 return true; 116 return true;
113 } 117 }
114 118
115 bool SetQuarantineProperties(const base::FilePath& file, 119 bool SetQuarantineProperties(const base::FilePath& file,
116 NSDictionary* properties) { 120 NSDictionary* properties) {
117 base::scoped_nsobject<NSURL> file_url([[NSURL alloc] 121 base::scoped_nsobject<NSURL> file_url([[NSURL alloc]
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 196 }
193 if (!md_item_set_attribute_func) 197 if (!md_item_set_attribute_func)
194 return false; 198 return false;
195 199
196 NSString* file_path = [NSString stringWithUTF8String:file.value().c_str()]; 200 NSString* file_path = [NSString stringWithUTF8String:file.value().c_str()];
197 if (!file_path) 201 if (!file_path)
198 return false; 202 return false;
199 203
200 base::ScopedCFTypeRef<MDItemRef> md_item( 204 base::ScopedCFTypeRef<MDItemRef> md_item(
201 MDItemCreate(NULL, base::mac::NSToCFCast(file_path))); 205 MDItemCreate(NULL, base::mac::NSToCFCast(file_path)));
202 if (!md_item) 206 if (!md_item) {
207 LOG(WARNING) << "MDItemCreate failed for path " << file.value();
203 return false; 208 return false;
209 }
204 210
205 // We won't put any more than 2 items into the attribute. 211 // We won't put any more than 2 items into the attribute.
206 NSMutableArray* list = [NSMutableArray arrayWithCapacity:2]; 212 NSMutableArray* list = [NSMutableArray arrayWithCapacity:2];
207 213
208 // Follow Safari's lead: the first item in the list is the source URL of 214 // Follow Safari's lead: the first item in the list is the source URL of
209 // the downloaded file. If the referrer is known, store that, too. 215 // the downloaded file. If the referrer is known, store that, too.
210 NSString* origin_url = [NSString stringWithUTF8String:source.spec().c_str()]; 216 NSString* origin_url = [NSString stringWithUTF8String:source.spec().c_str()];
211 if (origin_url) 217 if (origin_url)
212 [list addObject:origin_url]; 218 [list addObject:origin_url];
213 NSString* referrer_url = 219 NSString* referrer_url =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // be quarantined against the user's wishes. 257 // be quarantined against the user's wishes.
252 return true; 258 return true;
253 } 259 }
254 260
255 // kLSQuarantineAgentNameKey, kLSQuarantineAgentBundleIdentifierKey, and 261 // kLSQuarantineAgentNameKey, kLSQuarantineAgentBundleIdentifierKey, and
256 // kLSQuarantineTimeStampKey are set for us (see LSQuarantine.h), so we only 262 // kLSQuarantineTimeStampKey are set for us (see LSQuarantine.h), so we only
257 // need to set the values that the OS can't infer. 263 // need to set the values that the OS can't infer.
258 264
259 if (![properties valueForKey:(NSString*)kLSQuarantineTypeKey]) { 265 if (![properties valueForKey:(NSString*)kLSQuarantineTypeKey]) {
260 CFStringRef type = source.SchemeIsHTTPOrHTTPS() 266 CFStringRef type = source.SchemeIsHTTPOrHTTPS()
261 ? kLSQuarantineTypeWebDownload 267 ? kLSQuarantineTypeWebDownload
262 : kLSQuarantineTypeOtherDownload; 268 : kLSQuarantineTypeOtherDownload;
263 [properties setValue:(NSString*)type 269 [properties setValue:(NSString*)type
264 forKey:(NSString*)kLSQuarantineTypeKey]; 270 forKey:(NSString*)kLSQuarantineTypeKey];
265 } 271 }
266 272
267 if (![properties valueForKey:(NSString*)kLSQuarantineOriginURLKey] && 273 if (![properties valueForKey:(NSString*)kLSQuarantineOriginURLKey] &&
268 referrer.is_valid()) { 274 referrer.is_valid()) {
269 NSString* referrer_url = 275 NSString* referrer_url =
270 [NSString stringWithUTF8String:referrer.spec().c_str()]; 276 [NSString stringWithUTF8String:referrer.spec().c_str()];
271 [properties setValue:referrer_url 277 [properties setValue:referrer_url
272 forKey:(NSString*)kLSQuarantineOriginURLKey]; 278 forKey:(NSString*)kLSQuarantineOriginURLKey];
(...skipping 12 matching lines...) Expand all
285 return SetQuarantinePropertiesDeprecated(file, properties); 291 return SetQuarantinePropertiesDeprecated(file, properties);
286 } 292 }
287 } 293 }
288 294
289 } // namespace 295 } // namespace
290 296
291 QuarantineFileResult QuarantineFile(const base::FilePath& file, 297 QuarantineFileResult QuarantineFile(const base::FilePath& file,
292 const GURL& source_url, 298 const GURL& source_url,
293 const GURL& referrer_url, 299 const GURL& referrer_url,
294 const std::string& client_guid) { 300 const std::string& client_guid) {
301 if (!base::PathExists(file))
302 return QuarantineFileResult::FILE_MISSING;
303
304 // Don't consider it an error if we fail to add origin metadata.
305 AddOriginMetadataToFile(file, source_url, referrer_url);
295 bool quarantine_succeeded = 306 bool quarantine_succeeded =
296 AddQuarantineMetadataToFile(file, source_url, referrer_url); 307 AddQuarantineMetadataToFile(file, source_url, referrer_url);
297 bool origin_succeeded = 308 return quarantine_succeeded ? QuarantineFileResult::OK
298 AddOriginMetadataToFile(file, source_url, referrer_url); 309 : QuarantineFileResult::ANNOTATION_FAILED;
299 return quarantine_succeeded && origin_succeeded 310 }
300 ? QuarantineFileResult::OK 311
301 : QuarantineFileResult::ANNOTATION_FAILED; 312 bool IsFileQuarantined(const base::FilePath& file,
313 const GURL& expected_source_url,
314 const GURL& referrer_url) {
315 base::ThreadRestrictions::AssertIOAllowed();
316
317 if (!base::PathExists(file))
318 return false;
319
320 base::scoped_nsobject<NSMutableDictionary> properties;
321 bool success = false;
322 if (base::mac::IsAtLeastOS10_10()) {
323 success = GetQuarantineProperties(file, &properties);
324 } else {
325 success = GetQuarantinePropertiesDeprecated(file, &properties);
326 }
327
328 if (!success || !properties)
329 return false;
330
331 NSString* source_url =
332 [[properties valueForKey:(NSString*)kLSQuarantineDataURLKey] description];
333
334 if (!expected_source_url.is_valid())
335 return [source_url length] > 0;
336
337 if (![source_url
338 isEqualToString:base::SysUTF8ToNSString(expected_source_url.spec())])
339 return false;
340
341 return !referrer_url.is_valid() ||
342 [[[properties valueForKey:(NSString*)kLSQuarantineOriginURLKey]
343 description]
344 isEqualToString:base::SysUTF8ToNSString(referrer_url.spec())];
302 } 345 }
303 346
304 } // namespace content 347 } // namespace content
OLDNEW
« no previous file with comments | « content/common/quarantine/quarantine_linux_unittest.cc ('k') | content/common/quarantine/quarantine_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698