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

Commita5d5337

Browse files
committed
fix: add code signing requirements to xpc connections
1 parent1453e77 commita5d5337

File tree

5 files changed

+132
-124
lines changed

5 files changed

+132
-124
lines changed

‎Coder-Desktop/Coder-Desktop/AppHelperXPCClient.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import VPNLib
3737
_=self.connect()
3838
}
3939
logger.info("connecting to\(helperAppMachServiceName)")
40+
connection.setCodeSigningRequirement(Validator.xpcPeerRequirement)
4041
connection.resume()
4142
self.connection= connection
4243
return connection

‎Coder-Desktop/Coder-DesktopHelper/HelperXPCListeners.swift‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class HelperNEXPCServer: NSObject, NSXPCListenerDelegate, @unchecked Sendable {
3232
conns.removeAll{ $0== newConnection}
3333
logger.debug("connection interrupted")
3434
}
35+
newConnection.setCodeSigningRequirement(Validator.xpcPeerRequirement)
3536
newConnection.resume()
3637
conns.append(newConnection)
3738
returntrue
@@ -145,6 +146,7 @@ class HelperAppXPCServer: NSObject, NSXPCListenerDelegate, @unchecked Sendable {
145146
conns.removeAll{ $0== newConnection}
146147
logger.debug("app connection invalidated")
147148
}
149+
newConnection.setCodeSigningRequirement(Validator.xpcPeerRequirement)
148150
newConnection.resume()
149151
conns.append(newConnection)
150152
returntrue

‎Coder-Desktop/VPN/NEHelperXPCClient.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ final class HelperXPCClient: @unchecked Sendable {
2929
connection.interruptionHandler={[weak self]in
3030
self?.connection=nil
3131
}
32+
connection.setCodeSigningRequirement(Validator.xpcPeerRequirement)
3233
connection.resume()
3334
self.connection= connection
3435
return connection

‎Coder-Desktop/VPNLib/Download.swift‎

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,6 @@
11
import CryptoKit
22
import Foundation
33

4-
publicenumValidationError:Error{
5-
case fileNotFound
6-
case unableToCreateStaticCode
7-
case invalidSignature
8-
case unableToRetrieveInfo
9-
case invalidIdentifier(identifier:String?)
10-
case invalidTeamIdentifier(identifier:String?)
11-
case missingInfoPList
12-
case invalidVersion(version:String?)
13-
case belowMinimumCoderVersion
14-
15-
publicvardescription:String{
16-
switchself{
17-
case.fileNotFound:
18-
"The file does not exist."
19-
case.unableToCreateStaticCode:
20-
"Unable to create a static code object."
21-
case.invalidSignature:
22-
"The file's signature is invalid."
23-
case.unableToRetrieveInfo:
24-
"Unable to retrieve signing information."
25-
caselet.invalidIdentifier(identifier):
26-
"Invalid identifier:\(identifier??"unknown")."
27-
caselet.invalidVersion(version):
28-
"Invalid runtime version:\(version??"unknown")."
29-
caselet.invalidTeamIdentifier(identifier):
30-
"Invalid team identifier:\(identifier??"unknown")."
31-
case.missingInfoPList:
32-
"Info.plist is not embedded within the dylib."
33-
case.belowMinimumCoderVersion:
34-
"""
35-
The Coder deployment must be version\(Validator.minimumCoderVersion)
36-
or higher to use Coder Desktop.
37-
"""
38-
}
39-
}
40-
41-
publicvarlocalizedDescription:String{ description}
42-
}
43-
44-
publicclassValidator{
45-
// Whilst older dylibs exist, this app assumes v2.20 or later.
46-
publicstaticletminimumCoderVersion="2.20.0"
47-
48-
privatestaticletexpectedName="CoderVPN"
49-
privatestaticletexpectedIdentifier="com.coder.Coder-Desktop.VPN.dylib"
50-
privatestaticletexpectedTeamIdentifier="4399GN35BJ"
51-
52-
privatestaticletinfoIdentifierKey="CFBundleIdentifier"
53-
privatestaticletinfoNameKey="CFBundleName"
54-
privatestaticletinfoShortVersionKey="CFBundleShortVersionString"
55-
56-
privatestaticletsignInfoFlags:SecCSFlags=.init(rawValue: kSecCSSigningInformation)
57-
58-
// `expectedVersion` must be of the form `[0-9]+.[0-9]+.[0-9]+`
59-
publicstaticfunc validate(path:URL, expectedVersion:String)throws(ValidationError){
60-
guardFileManager.default.fileExists(atPath: path.path)else{
61-
throw.fileNotFound
62-
}
63-
64-
varstaticCode:SecStaticCode?
65-
letstatus=SecStaticCodeCreateWithPath(pathasCFURL,SecCSFlags(),&staticCode)
66-
guard status== errSecSuccess,let code= staticCodeelse{
67-
throw.unableToCreateStaticCode
68-
}
69-
70-
letvalidateStatus=SecStaticCodeCheckValidity(code,SecCSFlags(),nil)
71-
guard validateStatus== errSecSuccesselse{
72-
throw.invalidSignature
73-
}
74-
75-
varinformation:CFDictionary?
76-
letinfoStatus=SecCodeCopySigningInformation(code, signInfoFlags,&information)
77-
guard infoStatus== errSecSuccess,let info= informationas?[String:Any]else{
78-
throw.unableToRetrieveInfo
79-
}
80-
81-
guardlet identifier=info[kSecCodeInfoIdentifierasString]as?String,
82-
identifier== expectedIdentifier
83-
else{
84-
throw.invalidIdentifier(identifier:info[kSecCodeInfoIdentifierasString]as?String)
85-
}
86-
87-
guardlet teamIdentifier=info[kSecCodeInfoTeamIdentifierasString]as?String,
88-
teamIdentifier== expectedTeamIdentifier
89-
else{
90-
throw.invalidTeamIdentifier(
91-
identifier:info[kSecCodeInfoTeamIdentifierasString]as?String
92-
)
93-
}
94-
95-
guardlet infoPlist=info[kSecCodeInfoPListasString]as?[String:AnyObject]else{
96-
throw.missingInfoPList
97-
}
98-
99-
tryvalidateInfo(infoPlist: infoPlist, expectedVersion: expectedVersion)
100-
}
101-
102-
privatestaticfunc validateInfo(infoPlist:[String:AnyObject], expectedVersion:String)throws(ValidationError){
103-
guardlet plistIdent=infoPlist[infoIdentifierKey]as?String, plistIdent== expectedIdentifierelse{
104-
throw.invalidIdentifier(identifier:infoPlist[infoIdentifierKey]as?String)
105-
}
106-
107-
guardlet plistName=infoPlist[infoNameKey]as?String, plistName== expectedNameelse{
108-
throw.invalidIdentifier(identifier:infoPlist[infoNameKey]as?String)
109-
}
110-
111-
// Downloaded dylib must match the version of the server
112-
guardlet dylibVersion=infoPlist[infoShortVersionKey]as?String,
113-
expectedVersion== dylibVersion
114-
else{
115-
throw.invalidVersion(version:infoPlist[infoShortVersionKey]as?String)
116-
}
117-
118-
// Downloaded dylib must be at least the minimum Coder server version
119-
guardlet dylibVersion=infoPlist[infoShortVersionKey]as?String,
120-
// x.compare(y) is .orderedDescending if x > y
121-
minimumCoderVersion.compare(dylibVersion, options:.numeric)!=.orderedDescending
122-
else{
123-
throw.belowMinimumCoderVersion
124-
}
125-
}
126-
}
127-
1284
publicfunc download(
1295
src:URL,
1306
dest:URL,
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import Foundation
2+
3+
publicenumValidationError:Error{
4+
case fileNotFound
5+
case unableToCreateStaticCode
6+
case invalidSignature
7+
case unableToRetrieveInfo
8+
case invalidIdentifier(identifier:String?)
9+
case invalidTeamIdentifier(identifier:String?)
10+
case missingInfoPList
11+
case invalidVersion(version:String?)
12+
case belowMinimumCoderVersion
13+
14+
publicvardescription:String{
15+
switchself{
16+
case.fileNotFound:
17+
"The file does not exist."
18+
case.unableToCreateStaticCode:
19+
"Unable to create a static code object."
20+
case.invalidSignature:
21+
"The file's signature is invalid."
22+
case.unableToRetrieveInfo:
23+
"Unable to retrieve signing information."
24+
caselet.invalidIdentifier(identifier):
25+
"Invalid identifier:\(identifier??"unknown")."
26+
caselet.invalidVersion(version):
27+
"Invalid runtime version:\(version??"unknown")."
28+
caselet.invalidTeamIdentifier(identifier):
29+
"Invalid team identifier:\(identifier??"unknown")."
30+
case.missingInfoPList:
31+
"Info.plist is not embedded within the dylib."
32+
case.belowMinimumCoderVersion:
33+
"""
34+
The Coder deployment must be version\(Validator.minimumCoderVersion)
35+
or higher to use Coder Desktop.
36+
"""
37+
}
38+
}
39+
40+
publicvarlocalizedDescription:String{ description}
41+
}
42+
43+
publicclassValidator{
44+
// Whilst older dylibs exist, this app assumes v2.20 or later.
45+
publicstaticletminimumCoderVersion="2.20.0"
46+
47+
privatestaticletexpectedName="CoderVPN"
48+
privatestaticletexpectedIdentifier="com.coder.Coder-Desktop.VPN.dylib"
49+
privatestaticletexpectedTeamIdentifier="4399GN35BJ"
50+
51+
privatestaticletinfoIdentifierKey="CFBundleIdentifier"
52+
privatestaticletinfoNameKey="CFBundleName"
53+
privatestaticletinfoShortVersionKey="CFBundleShortVersionString"
54+
55+
privatestaticletsignInfoFlags:SecCSFlags=.init(rawValue: kSecCSSigningInformation)
56+
57+
// `expectedVersion` must be of the form `[0-9]+.[0-9]+.[0-9]+`
58+
publicstaticfunc validate(path:URL, expectedVersion:String)throws(ValidationError){
59+
guardFileManager.default.fileExists(atPath: path.path)else{
60+
throw.fileNotFound
61+
}
62+
63+
varstaticCode:SecStaticCode?
64+
letstatus=SecStaticCodeCreateWithPath(pathasCFURL,SecCSFlags(),&staticCode)
65+
guard status== errSecSuccess,let code= staticCodeelse{
66+
throw.unableToCreateStaticCode
67+
}
68+
69+
letvalidateStatus=SecStaticCodeCheckValidity(code,SecCSFlags(),nil)
70+
guard validateStatus== errSecSuccesselse{
71+
throw.invalidSignature
72+
}
73+
74+
varinformation:CFDictionary?
75+
letinfoStatus=SecCodeCopySigningInformation(code, signInfoFlags,&information)
76+
guard infoStatus== errSecSuccess,let info= informationas?[String:Any]else{
77+
throw.unableToRetrieveInfo
78+
}
79+
80+
guardlet identifier=info[kSecCodeInfoIdentifierasString]as?String,
81+
identifier== expectedIdentifier
82+
else{
83+
throw.invalidIdentifier(identifier:info[kSecCodeInfoIdentifierasString]as?String)
84+
}
85+
86+
guardlet teamIdentifier=info[kSecCodeInfoTeamIdentifierasString]as?String,
87+
teamIdentifier== expectedTeamIdentifier
88+
else{
89+
throw.invalidTeamIdentifier(
90+
identifier:info[kSecCodeInfoTeamIdentifierasString]as?String
91+
)
92+
}
93+
94+
guardlet infoPlist=info[kSecCodeInfoPListasString]as?[String:AnyObject]else{
95+
throw.missingInfoPList
96+
}
97+
98+
tryvalidateInfo(infoPlist: infoPlist, expectedVersion: expectedVersion)
99+
}
100+
101+
publicstaticletxpcPeerRequirement="anchor apple generic"+ // Apple-issued certificate chain
102+
" and certificate leaf[subject.OU] =\""+ expectedTeamIdentifier+"\"" // Signed by the Coder team
103+
104+
privatestaticfunc validateInfo(infoPlist:[String:AnyObject], expectedVersion:String)throws(ValidationError){
105+
guardlet plistIdent=infoPlist[infoIdentifierKey]as?String, plistIdent== expectedIdentifierelse{
106+
throw.invalidIdentifier(identifier:infoPlist[infoIdentifierKey]as?String)
107+
}
108+
109+
guardlet plistName=infoPlist[infoNameKey]as?String, plistName== expectedNameelse{
110+
throw.invalidIdentifier(identifier:infoPlist[infoNameKey]as?String)
111+
}
112+
113+
// Downloaded dylib must match the version of the server
114+
guardlet dylibVersion=infoPlist[infoShortVersionKey]as?String,
115+
expectedVersion== dylibVersion
116+
else{
117+
throw.invalidVersion(version:infoPlist[infoShortVersionKey]as?String)
118+
}
119+
120+
// Downloaded dylib must be at least the minimum Coder server version
121+
guardlet dylibVersion=infoPlist[infoShortVersionKey]as?String,
122+
// x.compare(y) is .orderedDescending if x > y
123+
minimumCoderVersion.compare(dylibVersion, options:.numeric)!=.orderedDescending
124+
else{
125+
throw.belowMinimumCoderVersion
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp