Move app name + iconurl to tracer. (#149)
This commit is contained in:
parent
3328ada3bf
commit
dc5c21c568
|
@ -26,9 +26,9 @@ class Notifier {
|
||||||
func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) {
|
func notify(accessTo secret: AnySecret, by provenance: SigningRequestProvenance) {
|
||||||
let notificationCenter = UNUserNotificationCenter.current()
|
let notificationCenter = UNUserNotificationCenter.current()
|
||||||
let notificationContent = UNMutableNotificationContent()
|
let notificationContent = UNMutableNotificationContent()
|
||||||
notificationContent.title = "Signed Request from \(provenance.origin.name)"
|
notificationContent.title = "Signed Request from \(provenance.origin.displayName)"
|
||||||
notificationContent.subtitle = "Using secret \"\(secret.name)\""
|
notificationContent.subtitle = "Using secret \"\(secret.name)\""
|
||||||
if let iconURL = iconURL(for: provenance), let attachment = try? UNNotificationAttachment(identifier: "icon", url: iconURL, options: nil) {
|
if let iconURL = provenance.origin.iconURL, let attachment = try? UNNotificationAttachment(identifier: "icon", url: iconURL, options: nil) {
|
||||||
notificationContent.attachments = [attachment]
|
notificationContent.attachments = [attachment]
|
||||||
}
|
}
|
||||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)
|
let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil)
|
||||||
|
@ -54,23 +54,6 @@ class Notifier {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Notifier {
|
|
||||||
|
|
||||||
func iconURL(for provenance: SigningRequestProvenance) -> URL? {
|
|
||||||
do {
|
|
||||||
if let app = NSRunningApplication(processIdentifier: provenance.origin.pid), let icon = app.icon?.tiffRepresentation {
|
|
||||||
let temporaryURL = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("\(UUID().uuidString).png"))
|
|
||||||
let bitmap = NSBitmapImageRep(data: icon)
|
|
||||||
try bitmap?.representation(using: .png, properties: [:])?.write(to: temporaryURL)
|
|
||||||
return temporaryURL
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Notifier: SigningWitness {
|
extension Notifier: SigningWitness {
|
||||||
|
|
||||||
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
|
func speakNowOrForeverHoldYourPeace(forAccessTo secret: AnySecret, by provenance: SigningRequestProvenance) throws {
|
||||||
|
|
|
@ -4,6 +4,9 @@ import Security
|
||||||
import SecretKit
|
import SecretKit
|
||||||
|
|
||||||
struct SigningRequestTracer {
|
struct SigningRequestTracer {
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SigningRequestTracer {
|
||||||
|
|
||||||
func provenance(from fileHandleReader: FileHandleReader) -> SigningRequestProvenance {
|
func provenance(from fileHandleReader: FileHandleReader) -> SigningRequestProvenance {
|
||||||
let firstInfo = process(from: fileHandleReader.pidOfConnectedProcess)
|
let firstInfo = process(from: fileHandleReader.pidOfConnectedProcess)
|
||||||
|
@ -34,7 +37,24 @@ struct SigningRequestTracer {
|
||||||
let flags: SecCSFlags = [.considerExpiration, .enforceRevocationChecks]
|
let flags: SecCSFlags = [.considerExpiration, .enforceRevocationChecks]
|
||||||
SecCodeCreateWithPID(pid, SecCSFlags(), &secCode)
|
SecCodeCreateWithPID(pid, SecCSFlags(), &secCode)
|
||||||
let valid = SecCodeCheckValidity(secCode.takeRetainedValue(), flags, nil) == errSecSuccess
|
let valid = SecCodeCheckValidity(secCode.takeRetainedValue(), flags, nil) == errSecSuccess
|
||||||
return SigningRequestProvenance.Process(pid: pid, name: procName, path: path, validSignature: valid, parentPID: ppid)
|
return SigningRequestProvenance.Process(pid: pid, processName: procName, appName: appName(for: pid), iconURL: iconURL(for: pid), path: path, validSignature: valid, parentPID: ppid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func iconURL(for pid: Int32) -> URL? {
|
||||||
|
do {
|
||||||
|
if let app = NSRunningApplication(processIdentifier: pid), let icon = app.icon?.tiffRepresentation {
|
||||||
|
let temporaryURL = URL(fileURLWithPath: (NSTemporaryDirectory() as NSString).appendingPathComponent("\(UUID().uuidString).png"))
|
||||||
|
let bitmap = NSBitmapImageRep(data: icon)
|
||||||
|
try bitmap?.representation(using: .png, properties: [:])?.write(to: temporaryURL)
|
||||||
|
return temporaryURL
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func appName(for pid: Int32) -> String? {
|
||||||
|
NSRunningApplication(processIdentifier: pid)?.localizedName
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ class AgentTests: XCTestCase {
|
||||||
let agent = Agent(storeList: list, witness: witness)
|
let agent = Agent(storeList: list, witness: witness)
|
||||||
agent.handle(reader: stubReader, writer: stubWriter)
|
agent.handle(reader: stubReader, writer: stubWriter)
|
||||||
XCTAssertEqual(witnessTrace, speakNowTrace)
|
XCTAssertEqual(witnessTrace, speakNowTrace)
|
||||||
XCTAssertEqual(witnessTrace.origin.name, "Finder")
|
XCTAssertEqual(witnessTrace.origin.displayName, "Finder")
|
||||||
XCTAssertEqual(witnessTrace.origin.validSignature, true)
|
XCTAssertEqual(witnessTrace.origin.validSignature, true)
|
||||||
XCTAssertEqual(witnessTrace.origin.parentPID, 1)
|
XCTAssertEqual(witnessTrace.origin.parentPID, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,19 +27,27 @@ extension SigningRequestProvenance {
|
||||||
public struct Process: Equatable {
|
public struct Process: Equatable {
|
||||||
|
|
||||||
public let pid: Int32
|
public let pid: Int32
|
||||||
public let name: String
|
public let processName: String
|
||||||
|
public let appName: String?
|
||||||
|
public let iconURL: URL?
|
||||||
public let path: String
|
public let path: String
|
||||||
public let validSignature: Bool
|
public let validSignature: Bool
|
||||||
public let parentPID: Int32?
|
public let parentPID: Int32?
|
||||||
|
|
||||||
public init(pid: Int32, name: String, path: String, validSignature: Bool, parentPID: Int32?) {
|
public init(pid: Int32, processName: String, appName: String?, iconURL: URL?, path: String, validSignature: Bool, parentPID: Int32?) {
|
||||||
self.pid = pid
|
self.pid = pid
|
||||||
self.name = name
|
self.processName = processName
|
||||||
|
self.appName = appName
|
||||||
|
self.iconURL = iconURL
|
||||||
self.path = path
|
self.path = path
|
||||||
self.validSignature = validSignature
|
self.validSignature = validSignature
|
||||||
self.parentPID = parentPID
|
self.parentPID = parentPID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var displayName: String {
|
||||||
|
appName ?? processName
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ extension SecureEnclave {
|
||||||
|
|
||||||
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
|
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
|
||||||
let context = LAContext()
|
let context = LAContext()
|
||||||
context.localizedReason = "sign a request from \"\(provenance.origin.name)\" using secret \"\(secret.name)\""
|
context.localizedReason = "sign a request from \"\(provenance.origin.displayName)\" using secret \"\(secret.name)\""
|
||||||
context.localizedCancelTitle = "Deny"
|
context.localizedCancelTitle = "Deny"
|
||||||
let attributes = [
|
let attributes = [
|
||||||
kSecClass: kSecClassKey,
|
kSecClass: kSecClassKey,
|
||||||
|
|
|
@ -47,7 +47,7 @@ extension SmartCard {
|
||||||
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
|
public func sign(data: Data, with secret: SecretType, for provenance: SigningRequestProvenance) throws -> Data {
|
||||||
guard let tokenID = tokenID else { fatalError() }
|
guard let tokenID = tokenID else { fatalError() }
|
||||||
let context = LAContext()
|
let context = LAContext()
|
||||||
context.localizedReason = "sign a request from \"\(provenance.origin.name)\" using secret \"\(secret.name)\""
|
context.localizedReason = "sign a request from \"\(provenance.origin.displayName)\" using secret \"\(secret.name)\""
|
||||||
context.localizedCancelTitle = "Deny"
|
context.localizedCancelTitle = "Deny"
|
||||||
let attributes = [
|
let attributes = [
|
||||||
kSecClass: kSecClassKey,
|
kSecClass: kSecClassKey,
|
||||||
|
|
Loading…
Reference in New Issue