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

Commitea87f52

Browse files
committed
fix: add code signing requirements to xpc connections
1 parentc7dbde8 commitea87f52

File tree

5 files changed

+132
-124
lines changed

5 files changed

+132
-124
lines changed

‎Coder-Desktop/Coder-Desktop/XPCInterface.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import VPNLib
3636
_=self.connect()
3737
}
3838
logger.info("connecting to\(helperAppMachServiceName)")
39+
connection.setCodeSigningRequirement(SignatureValidator.peerRequirement)
3940
connection.resume()
4041
self.connection= connection
4142
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 HelperNEXPCListener: NSObject, NSXPCListenerDelegate, HelperNEXPCInterface
3232
conns.removeAll{ $0== newConnection}
3333
logger.debug("connection interrupted")
3434
}
35+
newConnection.setCodeSigningRequirement(SignatureValidator.peerRequirement)
3536
newConnection.resume()
3637
conns.append(newConnection)
3738
returntrue
@@ -149,6 +150,7 @@ class HelperAppXPCListener: NSObject, NSXPCListenerDelegate, HelperAppXPCInterfa
149150
conns.removeAll{ $0== newConnection}
150151
logger.debug("app connection invalidated")
151152
}
153+
newConnection.setCodeSigningRequirement(SignatureValidator.peerRequirement)
152154
newConnection.resume()
153155
conns.append(newConnection)
154156
returntrue

‎Coder-Desktop/VPN/HelperXPCSpeaker.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ final class HelperXPCSpeaker: NEXPCInterface, @unchecked Sendable {
2929
connection.interruptionHandler={[weak self]in
3030
self?.connection=nil
3131
}
32+
connection.setCodeSigningRequirement(SignatureValidator.peerRequirement)
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\(SignatureValidator.minimumCoderVersion)
36-
or higher to use Coder Desktop.
37-
"""
38-
}
39-
}
40-
41-
publicvarlocalizedDescription:String{ description}
42-
}
43-
44-
publicclassSignatureValidator{
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\(SignatureValidator.minimumCoderVersion)
35+
or higher to use Coder Desktop.
36+
"""
37+
}
38+
}
39+
40+
publicvarlocalizedDescription:String{ description}
41+
}
42+
43+
publicclassSignatureValidator{
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+
publicstaticletpeerRequirement="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