@@ -22,19 +22,25 @@ class HelperToolDelegate: NSObject, NSXPCListenerDelegate, HelperXPCProtocol {
22
22
return true
23
23
}
24
24
25
- func runCommand( command: String , withReply reply: @escaping ( Int32 , String ) -> Void ) {
25
+ func removeQuarantine( path: String , withReply reply: @escaping ( Int32 , String ) -> Void ) {
26
+ guard isCoderDesktopDylib ( at: path) else {
27
+ reply ( 1 , " Path is not to a Coder Desktop dylib: \( path) " )
28
+ return
29
+ }
30
+
26
31
let task = Process ( )
27
32
let pipe = Pipe ( )
28
33
29
34
task. standardOutput = pipe
30
35
task. standardError = pipe
31
- task. arguments = [ " -c " , command ]
36
+ task. arguments = [ " -c " , " xattr -d com.apple.quarantine ' \( path ) ' " ]
32
37
task. executableURL = URL ( fileURLWithPath: " /bin/bash " )
33
38
34
39
do {
35
40
try task. run ( )
36
41
} catch {
37
42
reply ( 1 , " Failed to start command: \( error) " )
43
+ return
38
44
}
39
45
40
46
let data = pipe. fileHandleForReading. readDataToEndOfFile ( )
@@ -45,6 +51,20 @@ class HelperToolDelegate: NSObject, NSXPCListenerDelegate, HelperXPCProtocol {
45
51
}
46
52
}
47
53
54
+ func isCoderDesktopDylib( at rawPath: String ) -> Bool {
55
+ let url = URL ( fileURLWithPath: rawPath)
56
+ . standardizedFileURL
57
+ . resolvingSymlinksInPath ( )
58
+
59
+ // *Must* be within the Coder Desktop System Extension sandbox
60
+ let requiredPrefix = [ " / " , " var " , " root " , " Library " , " Containers " ,
61
+ " com.coder.Coder-Desktop.VPN " ]
62
+ guard url. pathComponents. starts ( with: requiredPrefix) else { return false }
63
+ guard url. pathExtension. lowercased ( ) == " dylib " else { return false }
64
+ guard FileManager . default. fileExists ( atPath: url. path) else { return false }
65
+ return true
66
+ }
67
+
48
68
let delegate = HelperToolDelegate ( )
49
69
let listener = NSXPCListener ( machServiceName: " 4399GN35BJ.com.coder.Coder-Desktop.Helper " )
50
70
listener. delegate = delegate
0 commit comments