Compare commits

...

4 Commits
xpc ... v2.2.0

5 changed files with 15 additions and 9 deletions

View File

@ -6,6 +6,7 @@ public class PublicKeyFileStoreController {
private let logger = Logger() private let logger = Logger()
private let directory: String private let directory: String
private let keyWriter = OpenSSHKeyWriter()
/// Initializes a PublicKeyFileStoreController. /// Initializes a PublicKeyFileStoreController.
public init(homeDirectory: String) { public init(homeDirectory: String) {
@ -21,7 +22,6 @@ public class PublicKeyFileStoreController {
try? FileManager.default.removeItem(at: URL(fileURLWithPath: directory)) try? FileManager.default.removeItem(at: URL(fileURLWithPath: directory))
} }
try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directory), withIntermediateDirectories: false, attributes: nil) try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directory), withIntermediateDirectories: false, attributes: nil)
let keyWriter = OpenSSHKeyWriter()
for secret in secrets { for secret in secrets {
let path = path(for: secret) let path = path(for: secret)
guard let data = keyWriter.openSSHString(secret: secret).data(using: .utf8) else { continue } guard let data = keyWriter.openSSHString(secret: secret).data(using: .utf8) else { continue }
@ -35,7 +35,8 @@ public class PublicKeyFileStoreController {
/// - Returns: The path to the Secret's public key. /// - Returns: The path to the Secret's public key.
/// - Warning: This method returning a path does not imply that a key has been written to disk already. This method only describes where it will be written to. /// - Warning: This method returning a path does not imply that a key has been written to disk already. This method only describes where it will be written to.
public func path<SecretType: Secret>(for secret: SecretType) -> String { public func path<SecretType: Secret>(for secret: SecretType) -> String {
directory.appending("/").appending("\(secret.name.replacingOccurrences(of: " ", with: "-")).pub") let minimalHex = keyWriter.openSSHMD5Fingerprint(secret: secret).replacingOccurrences(of: ":", with: "")
return directory.appending("/").appending("\(minimalHex).pub")
} }
} }

View File

@ -56,6 +56,9 @@ public protocol SecretStoreModifiable: SecretStore {
extension NSNotification.Name { extension NSNotification.Name {
// Distributed notification that keys were modified out of process (ie, that the management tool added/removed secrets)
public static let secretStoreUpdated = NSNotification.Name("com.maxgoedjen.Secretive.secretStore.updated") public static let secretStoreUpdated = NSNotification.Name("com.maxgoedjen.Secretive.secretStore.updated")
// Internal notification that keys were reloaded from the backing store.
public static let secretStoreReloaded = NSNotification.Name("com.maxgoedjen.Secretive.secretStore.reloaded")
} }

View File

@ -24,7 +24,7 @@ extension SecureEnclave {
/// Initializes a Store. /// Initializes a Store.
public init() { public init() {
DistributedNotificationCenter.default().addObserver(forName: .secretStoreUpdated, object: nil, queue: .main) { _ in DistributedNotificationCenter.default().addObserver(forName: .secretStoreUpdated, object: nil, queue: .main) { _ in
self.reloadSecrets(notify: false) self.reloadSecrets(notifyAgent: false)
} }
loadSecrets() loadSecrets()
} }
@ -171,12 +171,13 @@ extension SecureEnclave {
extension SecureEnclave.Store { extension SecureEnclave.Store {
/// Reloads all secrets from the store. /// Reloads all secrets from the store.
/// - Parameter notify: A boolean indicating whether a distributed notification should be posted, notifying other processes (ie, the SecretAgent) to reload their stores as well. /// - Parameter notifyAgent: A boolean indicating whether a distributed notification should be posted, notifying other processes (ie, the SecretAgent) to reload their stores as well.
private func reloadSecrets(notify: Bool = true) { private func reloadSecrets(notifyAgent: Bool = true) {
secrets.removeAll() secrets.removeAll()
loadSecrets() loadSecrets()
if notify { NotificationCenter.default.post(name: .secretStoreReloaded, object: self)
DistributedNotificationCenter.default().post(name: .secretStoreUpdated, object: nil) if notifyAgent {
DistributedNotificationCenter.default().postNotificationName(.secretStoreUpdated, object: nil, deliverImmediately: true)
} }
} }

View File

@ -33,7 +33,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
DispatchQueue.main.async { DispatchQueue.main.async {
self.socketController.handler = self.agent.handle(reader:writer:) self.socketController.handler = self.agent.handle(reader:writer:)
} }
DistributedNotificationCenter.default().addObserver(forName: .secretStoreUpdated, object: nil, queue: .main) { [self] _ in NotificationCenter.default.addObserver(forName: .secretStoreReloaded, object: nil, queue: .main) { [self] _ in
try? publicKeyFileStoreController.generatePublicKeys(for: storeList.stores.flatMap({ $0.secrets }), clear: true) try? publicKeyFileStoreController.generatePublicKeys(for: storeList.stores.flatMap({ $0.secrets }), clear: true)
} }
try? publicKeyFileStoreController.generatePublicKeys(for: storeList.stores.flatMap({ $0.secrets }), clear: true) try? publicKeyFileStoreController.generatePublicKeys(for: storeList.stores.flatMap({ $0.secrets }), clear: true)

View File

@ -18,7 +18,8 @@ class Notifier {
let rawDurations = [ let rawDurations = [
Measurement(value: 1, unit: UnitDuration.minutes), Measurement(value: 1, unit: UnitDuration.minutes),
Measurement(value: 5, unit: UnitDuration.minutes), Measurement(value: 5, unit: UnitDuration.minutes),
Measurement(value: 1, unit: UnitDuration.hours) Measurement(value: 1, unit: UnitDuration.hours),
Measurement(value: 24, unit: UnitDuration.hours)
] ]
let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: "Do Not Unlock", options: []) let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: "Do Not Unlock", options: [])