Skip to content

Commit c1bf50e

Browse files
committed
fix: more reliable FDA check
Closes #43
1 parent fb4b005 commit c1bf50e

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

permissions.mm

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@
2323
const std::string kNotDetermined{"not determined"};
2424
const std::string kLimited{"limited"};
2525

26+
std::string CheckFileAccessLevel(NSString *path) {
27+
int fd = open([path cStringUsingEncoding:kCFStringEncodingUTF8], O_RDONLY);
28+
if (fd != -1) {
29+
close(fd);
30+
return kAuthorized;
31+
}
32+
33+
if (errno == ENOENT)
34+
return kNotDetermined;
35+
36+
if (errno == EPERM || errno == EACCES)
37+
return kDenied;
38+
39+
return kNotDetermined;
40+
}
41+
2642
PHAccessLevel GetPHAccessLevel(const std::string &type)
2743
API_AVAILABLE(macosx(10.16)) {
2844
return type == "read-write" ? PHAccessLevelReadWrite : PHAccessLevelAddOnly;
@@ -247,25 +263,27 @@ bool HasOpenSystemPreferencesDialog() {
247263

248264
// Returns a status indicating whether the user has Full Disk Access.
249265
std::string FDAAuthStatus() {
250-
std::string auth_status = kNotDetermined;
251-
NSString *path;
252266
NSString *home_folder = GetUserHomeFolderPath();
267+
NSMutableArray<NSString *> *files = [[NSMutableArray alloc]
268+
initWithObjects:[home_folder stringByAppendingPathComponent:
269+
@"Library/Safari/Bookmarks.plist"],
270+
@"/Library/Application Support/com.apple.TCC/TCC.db",
271+
@"/Library/Preferences/com.apple.TimeMachine.plist", nil];
253272

254273
if (@available(macOS 10.15, *)) {
255-
path = [home_folder
256-
stringByAppendingPathComponent:@"Library/Safari/CloudTabs.db"];
257-
} else {
258-
path = [home_folder
259-
stringByAppendingPathComponent:@"Library/Safari/Bookmarks.plist"];
274+
[files addObject:[home_folder stringByAppendingPathComponent:
275+
@"Library/Safari/CloudTabs.db"]];
260276
}
261277

262-
NSFileManager *manager = [NSFileManager defaultManager];
263-
BOOL file_exists = [manager fileExistsAtPath:path];
264-
NSData *data = [NSData dataWithContentsOfFile:path];
265-
if (data == nil && file_exists) {
266-
auth_status = kDenied;
267-
} else if (file_exists) {
268-
auth_status = kAuthorized;
278+
std::string auth_status = kNotDetermined;
279+
for (NSString *file in files) {
280+
const std::string can_read = CheckFileAccessLevel(file);
281+
if (can_read == kAuthorized) {
282+
break;
283+
auth_status = kAuthorized;
284+
} else if (can_read == kDenied) {
285+
auth_status = kDenied;
286+
}
269287
}
270288

271289
return auth_status;

0 commit comments

Comments
 (0)