[Sandbox Broker] Bypass entitled paths
Include entitlement granted user folders in the permission check, so that if the file or folder is nested under one of them, it allocates a static permission object, rather than querying the list of configured paths every time. This also prevents the player from popping open the path grant / suggester dialog every time a default path is in the file set listed, which should provide some relief to most users. Signed-off-by: Christopher Snowhill <kode54@gmail.com>lastfm
parent
824648321c
commit
cacdc13d15
|
@ -17,12 +17,47 @@
|
||||||
|
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
|
|
||||||
|
static NSURL *_containerDirectory = nil;
|
||||||
|
static NSURL *_defaultMusicDirectory = nil;
|
||||||
|
static NSURL *_defaultDownloadsDirectory = nil;
|
||||||
|
static NSURL *_defaultMoviesDirectory = nil;
|
||||||
|
|
||||||
|
static NSURL *containerDirectory(void) {
|
||||||
|
NSString *path = [@"~" stringByExpandingTildeInPath];
|
||||||
|
return [NSURL fileURLWithPath:path];
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX this is only for comparison, not "escaping the sandbox"
|
||||||
|
static NSURL *pathEscape(NSString *path) {
|
||||||
|
NSString *componentsToRemove = [NSString stringWithFormat:@"Library/Containers/%@/Data/", [[NSBundle mainBundle] bundleIdentifier]];
|
||||||
|
NSRange rangeOfMatch = [path rangeOfString:componentsToRemove];
|
||||||
|
if(rangeOfMatch.location != NSNotFound)
|
||||||
|
path = [path stringByReplacingCharactersInRange:rangeOfMatch withString:@""];
|
||||||
|
return [NSURL fileURLWithPath:path];
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSURL *defaultMusicDirectory(void) {
|
||||||
|
NSString *path = [NSSearchPathForDirectoriesInDomains(NSMusicDirectory, NSUserDomainMask, YES) lastObject];
|
||||||
|
return pathEscape(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSURL *defaultDownloadsDirectory(void) {
|
||||||
|
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES) lastObject];
|
||||||
|
return pathEscape(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSURL *defaultMoviesDirectory(void) {
|
||||||
|
NSString *path = [NSSearchPathForDirectoriesInDomains(NSMoviesDirectory, NSUserDomainMask, YES) lastObject];
|
||||||
|
return pathEscape(path);
|
||||||
|
}
|
||||||
|
|
||||||
static SandboxBroker *kSharedSandboxBroker = nil;
|
static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
|
|
||||||
@interface SandboxEntry : NSObject {
|
@interface SandboxEntry : NSObject {
|
||||||
SandboxToken *_token;
|
SandboxToken *_token;
|
||||||
NSInteger _refCount;
|
NSInteger _refCount;
|
||||||
NSURL *_secureUrl;
|
NSURL *_secureUrl;
|
||||||
|
NSString *_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
@property(readonly) SandboxToken *token;
|
@property(readonly) SandboxToken *token;
|
||||||
|
@ -34,6 +69,7 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
@property NSInteger refCount;
|
@property NSInteger refCount;
|
||||||
|
|
||||||
- (id)initWithToken:(SandboxToken *)token;
|
- (id)initWithToken:(SandboxToken *)token;
|
||||||
|
- (id)initWithStaticURL:(NSURL *)url;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SandboxEntry
|
@implementation SandboxEntry
|
||||||
|
@ -43,6 +79,18 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
obj->_refCount = 1;
|
obj->_refCount = 1;
|
||||||
obj->_secureUrl = nil;
|
obj->_secureUrl = nil;
|
||||||
obj->_token = token;
|
obj->_token = token;
|
||||||
|
obj->_path = token.path;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithStaticURL:(NSURL *)url {
|
||||||
|
SandboxEntry *obj = [super init];
|
||||||
|
if(obj) {
|
||||||
|
obj->_refCount = 1;
|
||||||
|
obj->_secureUrl = nil;
|
||||||
|
obj->_token = nil;
|
||||||
|
obj->_path = [url path];
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +116,7 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)path {
|
- (NSString *)path {
|
||||||
return _token.path;
|
return _path;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -145,6 +193,22 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
- (SandboxEntry *)recursivePathTest:(NSURL *)url {
|
- (SandboxEntry *)recursivePathTest:(NSURL *)url {
|
||||||
SandboxEntry *ret = nil;
|
SandboxEntry *ret = nil;
|
||||||
|
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
_containerDirectory = containerDirectory();
|
||||||
|
_defaultMusicDirectory = defaultMusicDirectory();
|
||||||
|
_defaultDownloadsDirectory = defaultDownloadsDirectory();
|
||||||
|
_defaultMoviesDirectory = defaultMoviesDirectory();
|
||||||
|
});
|
||||||
|
|
||||||
|
NSArray *urls = @[_containerDirectory, _defaultMusicDirectory, _defaultDownloadsDirectory, _defaultMoviesDirectory];
|
||||||
|
|
||||||
|
for(NSURL *checkUrl in urls) {
|
||||||
|
if([SandboxBroker isPath:url aSubdirectoryOf:checkUrl]) {
|
||||||
|
return [[SandboxEntry alloc] initWithStaticURL:checkUrl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
|
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
|
||||||
|
|
||||||
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:NO];
|
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:NO];
|
||||||
|
@ -207,7 +271,9 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
if(_entry) {
|
if(_entry) {
|
||||||
[storage addObject:_entry];
|
[storage addObject:_entry];
|
||||||
|
|
||||||
|
if(_entry.secureUrl) {
|
||||||
[_entry.secureUrl startAccessingSecurityScopedResource];
|
[_entry.secureUrl startAccessingSecurityScopedResource];
|
||||||
|
}
|
||||||
|
|
||||||
return CFBridgingRetain(_entry);
|
return CFBridgingRetain(_entry);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue