diff --git a/SMC/Helper/Info.plist b/SMC/Helper/Info.plist
index 7265bf1e..e64e4b39 100644
--- a/SMC/Helper/Info.plist
+++ b/SMC/Helper/Info.plist
@@ -7,11 +7,11 @@
CFBundleName
eu.exelban.Stats.SMC.Helper
CFBundleShortVersionString
- 1.0.0
+ 1.0.1
CFBundleVersion
- 1
- CFBundleInfoDictionaryVersion
- 6.0
+ 2
+ CFBundleInfoDictionaryVersion
+ 6.0
SMAuthorizedClients
anchor apple generic and identifier "eu.exelban.Stats" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = RP2S87B72W)
diff --git a/SMC/Helper/main.swift b/SMC/Helper/main.swift
index d90dfdcf..d94fdef2 100644
--- a/SMC/Helper/main.swift
+++ b/SMC/Helper/main.swift
@@ -48,11 +48,22 @@ class Helper: NSObject, NSXPCListenerDelegate, HelperProtocol {
}
}
- func listener(_ listener: NSXPCListener, shouldAcceptNewConnection connection: NSXPCConnection) -> Bool {
- connection.exportedInterface = NSXPCInterface(with: HelperProtocol.self)
- connection.exportedObject = self
- connection.invalidationHandler = {
- if let connectionIndex = self.connections.firstIndex(of: connection) {
+ func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
+ do {
+ let isValid = try CodesignCheck.codeSigningMatches(pid: newConnection.processIdentifier)
+ if !isValid {
+ NSLog("invalid connection, dropping")
+ return false
+ }
+ } catch {
+ NSLog("error checking code signing: \(error)")
+ return false
+ }
+
+ newConnection.exportedInterface = NSXPCInterface(with: HelperProtocol.self)
+ newConnection.exportedObject = self
+ newConnection.invalidationHandler = {
+ if let connectionIndex = self.connections.firstIndex(of: newConnection) {
self.connections.remove(at: connectionIndex)
}
if self.connections.isEmpty {
@@ -60,8 +71,8 @@ class Helper: NSObject, NSXPCListenerDelegate, HelperProtocol {
}
}
- self.connections.append(connection)
- connection.resume()
+ self.connections.append(newConnection)
+ newConnection.resume()
return true
}
@@ -185,3 +196,81 @@ extension Helper {
exit(0)
}
}
+
+// https://github.com/duanefields/VirtualKVM/blob/master/VirtualKVM/CodesignCheck.swift
+let kSecCSDefaultFlags = 0
+
+enum CodesignCheckError: Error {
+ case message(String)
+}
+
+struct CodesignCheck {
+ public static func codeSigningMatches(pid: pid_t) throws -> Bool {
+ return try self.codeSigningCertificatesForSelf() == self.codeSigningCertificates(forPID: pid)
+ }
+
+ private static func codeSigningCertificatesForSelf() throws -> [SecCertificate] {
+ guard let secStaticCode = try secStaticCodeSelf() else { return [] }
+ return try codeSigningCertificates(forStaticCode: secStaticCode)
+ }
+
+ private static func codeSigningCertificates(forPID pid: pid_t) throws -> [SecCertificate] {
+ guard let secStaticCode = try secStaticCode(forPID: pid) else { return [] }
+ return try codeSigningCertificates(forStaticCode: secStaticCode)
+ }
+
+ private static func executeSecFunction(_ secFunction: () -> (OSStatus) ) throws {
+ let osStatus = secFunction()
+ guard osStatus == errSecSuccess else {
+ throw CodesignCheckError.message(String(describing: SecCopyErrorMessageString(osStatus, nil)))
+ }
+ }
+
+ private static func secStaticCodeSelf() throws -> SecStaticCode? {
+ var secCodeSelf: SecCode?
+ try executeSecFunction { SecCodeCopySelf(SecCSFlags(rawValue: 0), &secCodeSelf) }
+ guard let secCode = secCodeSelf else {
+ throw CodesignCheckError.message("SecCode returned empty from SecCodeCopySelf")
+ }
+ return try secStaticCode(forSecCode: secCode)
+ }
+
+ private static func secStaticCode(forPID pid: pid_t) throws -> SecStaticCode? {
+ var secCodePID: SecCode?
+ try executeSecFunction { SecCodeCopyGuestWithAttributes(nil, [kSecGuestAttributePid: pid] as CFDictionary, [], &secCodePID) }
+ guard let secCode = secCodePID else {
+ throw CodesignCheckError.message("SecCode returned empty from SecCodeCopyGuestWithAttributes")
+ }
+ return try secStaticCode(forSecCode: secCode)
+ }
+
+ private static func secStaticCode(forSecCode secCode: SecCode) throws -> SecStaticCode? {
+ var secStaticCodeCopy: SecStaticCode?
+ try executeSecFunction { SecCodeCopyStaticCode(secCode, [], &secStaticCodeCopy) }
+ guard let secStaticCode = secStaticCodeCopy else {
+ throw CodesignCheckError.message("SecStaticCode returned empty from SecCodeCopyStaticCode")
+ }
+ return secStaticCode
+ }
+
+ private static func isValid(secStaticCode: SecStaticCode) throws {
+ try executeSecFunction { SecStaticCodeCheckValidity(secStaticCode, SecCSFlags(rawValue: kSecCSDoNotValidateResources | kSecCSCheckNestedCode), nil) }
+ }
+
+ private static func secCodeInfo(forStaticCode secStaticCode: SecStaticCode) throws -> [String: Any]? {
+ try isValid(secStaticCode: secStaticCode)
+ var secCodeInfoCFDict: CFDictionary?
+ try executeSecFunction { SecCodeCopySigningInformation(secStaticCode, SecCSFlags(rawValue: kSecCSSigningInformation), &secCodeInfoCFDict) }
+ guard let secCodeInfo = secCodeInfoCFDict as? [String: Any] else {
+ throw CodesignCheckError.message("CFDictionary returned empty from SecCodeCopySigningInformation")
+ }
+ return secCodeInfo
+ }
+
+ private static func codeSigningCertificates(forStaticCode secStaticCode: SecStaticCode) throws -> [SecCertificate] {
+ guard
+ let secCodeInfo = try secCodeInfo(forStaticCode: secStaticCode),
+ let secCertificates = secCodeInfo[kSecCodeInfoCertificates as String] as? [SecCertificate] else { return [] }
+ return secCertificates
+ }
+}
diff --git a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme
index acf91b28..8fb3609a 100644
--- a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme
+++ b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme
@@ -1,6 +1,6 @@
CFBundleShortVersionString
$(MARKETING_VERSION)
CFBundleVersion
- 639
+ 640
Description
Simple macOS system monitor in your menu bar
LSApplicationCategoryType
diff --git a/Widgets/Supporting Files/Info.plist b/Widgets/Supporting Files/Info.plist
index e01c1cd8..2f0de2ec 100644
--- a/Widgets/Supporting Files/Info.plist
+++ b/Widgets/Supporting Files/Info.plist
@@ -13,7 +13,7 @@
CFBundleShortVersionString
2.11.20
CFBundleVersion
- 639
+ 640
NSExtension
NSExtensionPointIdentifier