Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbf0b756

Browse files
committed
retry
1 parent492cb38 commitbf0b756

File tree

7 files changed

+78
-18
lines changed

7 files changed

+78
-18
lines changed

‎Coder Desktop/Coder Desktop/Coder_Desktop.entitlements

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,9 @@
88
</array>
99
<key>com.apple.developer.system-extension.install</key>
1010
<true/>
11-
<key>com.apple.security.app-sandbox</key>
12-
<true/>
1311
<key>com.apple.security.application-groups</key>
1412
<array>
1513
<string>$(TeamIdentifierPrefix)com.coder.Coder-Desktop</string>
1614
</array>
17-
<key>com.apple.security.files.user-selected.read-only</key>
18-
<true/>
19-
<key>com.apple.security.network.client</key>
20-
<true/>
2115
</dict>
2216
</plist>

‎Coder Desktop/Coder Desktop/NetworkExtension.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ enum NetworkExtensionState: Equatable {
2424
/// An actor that handles configuring, enabling, and disabling the VPN tunnel via the
2525
/// NetworkExtension APIs.
2626
extensionCoderVPNService{
27-
funchasNetworkExtensionConfig()async->Bool{
27+
funcloadNetworkExtensionConfig()async{
2828
do{
29-
_=tryawaitgetTunnelManager()
30-
returntrue
29+
lettm=tryawaitgetTunnelManager()
30+
neState=.disabled
31+
serverAddress= tm.protocolConfiguration?.serverAddress
3132
}catch{
32-
returnfalse
33+
neState=.unconfigured
3334
}
3435
}
3536

‎Coder Desktop/Coder Desktop/VPNService.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,13 @@ final class CoderVPNService: NSObject, VPNService {
6363
// only stores a weak reference to the delegate.
6464
varsystemExtnDelegate:SystemExtensionDelegate<CoderVPNService>?
6565

66+
varserverAddress:String?
67+
6668
overrideinit(){
6769
super.init()
6870
installSystemExtension()
6971
Task{
70-
neState=ifawaithasNetworkExtensionConfig(){
71-
.disabled
72-
}else{
73-
.unconfigured
74-
}
72+
awaitloadNetworkExtensionConfig()
7573
}
7674
xpc.connect()
7775
xpc.getPeerState()
@@ -115,6 +113,7 @@ final class CoderVPNService: NSObject, VPNService {
115113
func configureTunnelProviderProtocol(proto:NETunnelProviderProtocol?){
116114
Task{
117115
iflet proto{
116+
serverAddress= proto.serverAddress
118117
awaitconfigureNetworkExtension(proto: proto)
119118
// this just configures the VPN, it doesn't enable it
120119
tunnelState=.disabled

‎Coder Desktop/Coder Desktop/XPCInterface.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,37 @@ import VPNLib
6464
svc.onExtensionPeerUpdate(data)
6565
}
6666
}
67+
68+
// The NE has verified the dylib and knows better than mac's Gatekeeper
69+
func removeQuarantine(path:String, reply:@escaping(Bool)->Void){
70+
letreply=CallbackWrapper(reply)
71+
Task{@MainActorin
72+
letprompt="""
73+
Coder Desktop wants to execute code downloaded from\
74+
\(svc.serverAddress??"the Coder deployment"). The code has been\
75+
verified to be signed by Coder.
76+
"""
77+
letsource="""
78+
do shell script"xattr -d com.apple.quarantine\(path)"\
79+
with prompt"\(prompt)"\
80+
with administrator privileges
81+
"""
82+
do{
83+
tryawaitwithCheckedThrowingContinuation{ continuationin
84+
guardlet script=NSAppleScript(source: source)else{
85+
return
86+
}
87+
// Run on a background thread
88+
Task.detached{
89+
varerror:NSDictionary?
90+
script.executeAndReturnError(&error)
91+
continuation.resume()
92+
}
93+
}
94+
reply(true)
95+
}catch{
96+
reply(false)
97+
}
98+
}
99+
}
67100
}

‎Coder Desktop/VPN/Manager.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ actor Manager {
4646
}catch{
4747
throw.validation(error)
4848
}
49+
50+
// HACK: The downloaded dylib may be quarantined, but we've validated it's signature
51+
// so it's safe to execute. However, the SE must be sandboxed, so we defer to the app.
52+
tryawaitremoveQuarantine(dest)
53+
4954
do{
5055
try tunnelHandle=TunnelHandle(dylibPath: dest)
5156
}catch{
@@ -228,6 +233,8 @@ enum ManagerError: Error {
228233
case serverInfo(String)
229234
case errorResponse(msg:String)
230235
case noTunnelFileDescriptor
236+
case noApp
237+
case permissionDenied
231238

232239
vardescription:String{
233240
switchself{
@@ -249,6 +256,10 @@ enum ManagerError: Error {
249256
msg
250257
case.noTunnelFileDescriptor:
251258
"Could not find a tunnel file descriptor"
259+
case.noApp:
260+
"The VPN must be started with the app open to perform first-time setup"
261+
case.permissionDenied:
262+
"Permission was not granted to run the CoderVPN dylib"
252263
}
253264
}
254265
}
@@ -273,3 +284,24 @@ func writeVpnLog(_ log: Vpn_Log) {
273284
letfields= log.fields.map{"\($0.name):\($0.value)"}.joined(separator:",")
274285
logger.log(level: level,"\(log.message, privacy:.public):\(fields, privacy:.public)")
275286
}
287+
288+
privatefunc removeQuarantine(_ dest:URL)asyncthrows(ManagerError){
289+
varflag:AnyObject?
290+
letfile=NSURL(fileURLWithPath: dest.path)
291+
try? file.getResourceValue(&flag, forKey: kCFURLQuarantinePropertiesKeyasURLResourceKey)
292+
if flag!=nil{
293+
guardlet conn= globalXPCListenerDelegate.connelse{
294+
throw.noApp
295+
}
296+
// Wait for unsandboxed app to accept our file
297+
do{
298+
tryawaitwithCheckedThrowingContinuation{[dest] continuationin
299+
conn.removeQuarantine(path: dest.path){ _in
300+
continuation.resume()
301+
}
302+
}
303+
}catch{
304+
throw.permissionDenied
305+
}
306+
}
307+
}

‎Coder Desktop/VPNLib/Util.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
publicstructCallbackWrapper<T, U>:@uncheckedSendable{
2-
privateletblock:(T?)->U
2+
privateletblock:(T)->U
33

4-
publicinit(_ block:@escaping(T?)->U){
4+
publicinit(_ block:@escaping(T)->U){
55
self.block= block
66
}
77

8-
publicfunc callAsFunction(_ error:T?)->U{
8+
publicfunc callAsFunction(_ error:T)->U{
99
block(error)
1010
}
1111
}

‎Coder Desktop/VPNLib/XPC.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ import Foundation
1010
@objcpublicprotocolVPNXPCClientCallbackProtocol{
1111
// data is a serialized `Vpn_PeerUpdate`
1212
func onPeerUpdate(_ data:Data)
13+
func removeQuarantine(path:String, reply:@escaping(Bool)->Void)
1314
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp