@@ -22,19 +22,25 @@ class HelperToolDelegate: NSObject, NSXPCListenerDelegate, HelperXPCProtocol {
2222 return true
2323 }
2424
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+
2631 let task = Process ( )
2732 let pipe = Pipe ( )
2833
2934 task. standardOutput = pipe
3035 task. standardError = pipe
31- task. arguments = [ " -c " , command ]
36+ task. arguments = [ " -c " , " xattr -d com.apple.quarantine ' \( path ) ' " ]
3237 task. executableURL = URL ( fileURLWithPath: " /bin/bash " )
3338
3439 do {
3540 try task. run ( )
3641 } catch {
3742 reply ( 1 , " Failed to start command: \( error) " )
43+ return
3844 }
3945
4046 let data = pipe. fileHandleForReading. readDataToEndOfFile ( )
@@ -45,6 +51,20 @@ class HelperToolDelegate: NSObject, NSXPCListenerDelegate, HelperXPCProtocol {
4551 }
4652}
4753
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+
4868let delegate = HelperToolDelegate ( )
4969let listener = NSXPCListener ( machServiceName: " 4399GN35BJ.com.coder.Coder-Desktop.Helper " )
5070listener. delegate = delegate
0 commit comments