mirror of
				https://github.com/maxgoedjen/secretive.git
				synced 2025-11-04 01:10:56 +00:00 
			
		
		
		
	Add agent support
This commit is contained in:
		
							parent
							
								
									286e2dc558
								
							
						
					
					
						commit
						a0bd55d1bf
					
				@ -4,14 +4,14 @@ import OSLog
 | 
			
		||||
import SecretKit
 | 
			
		||||
import SecretAgentKit
 | 
			
		||||
 | 
			
		||||
class Agent<StoreType: SecretStore> {
 | 
			
		||||
class Agent {
 | 
			
		||||
 | 
			
		||||
    fileprivate let store: StoreType
 | 
			
		||||
    fileprivate let storeList: SecretStoreList
 | 
			
		||||
    fileprivate let notifier: Notifier
 | 
			
		||||
 | 
			
		||||
    public init(store: StoreType, notifier: Notifier) {
 | 
			
		||||
    public init(storeList: SecretStoreList, notifier: Notifier) {
 | 
			
		||||
        os_log(.debug, "Agent is running")
 | 
			
		||||
        self.store = store
 | 
			
		||||
        self.storeList = storeList
 | 
			
		||||
        self.notifier = notifier
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -57,17 +57,18 @@ extension Agent {
 | 
			
		||||
extension Agent {
 | 
			
		||||
 | 
			
		||||
    func identities() throws -> Data {
 | 
			
		||||
        var count = UInt32(store.secrets.count).bigEndian
 | 
			
		||||
        let secrets = storeList.stores.flatMap(\.secrets)
 | 
			
		||||
        var count = UInt32(secrets.count).bigEndian
 | 
			
		||||
        let countData = Data(bytes: &count, count: UInt32.bitWidth/8)
 | 
			
		||||
        var keyData = Data()
 | 
			
		||||
        let writer = OpenSSHKeyWriter()
 | 
			
		||||
        for secret in store.secrets {
 | 
			
		||||
        for secret in secrets {
 | 
			
		||||
            let keyBlob = writer.data(secret: secret)
 | 
			
		||||
            keyData.append(writer.lengthAndData(of: keyBlob))
 | 
			
		||||
            let curveData = OpenSSHKeyWriter.Constants.curveType.data(using: .utf8)!
 | 
			
		||||
            keyData.append(writer.lengthAndData(of: curveData))
 | 
			
		||||
        }
 | 
			
		||||
        os_log(.debug, "Agent enumerated %@ identities", store.secrets.count as NSNumber)
 | 
			
		||||
        os_log(.debug, "Agent enumerated %@ identities", secrets.count as NSNumber)
 | 
			
		||||
        return countData + keyData
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -75,10 +76,16 @@ extension Agent {
 | 
			
		||||
        let reader = OpenSSHReader(data: data)
 | 
			
		||||
        let writer = OpenSSHKeyWriter()
 | 
			
		||||
        let hash = try reader.readNextChunk()
 | 
			
		||||
        let matching = store.secrets.filter { secret in
 | 
			
		||||
        let matching = storeList.stores.compactMap { store -> (AnySecretStore, AnySecret)? in
 | 
			
		||||
            let allMatching = store.secrets.filter { secret in
 | 
			
		||||
                hash == writer.data(secret: secret)
 | 
			
		||||
            }
 | 
			
		||||
        guard let secret = matching.first else {
 | 
			
		||||
            if let matching = allMatching.first {
 | 
			
		||||
                return (store, matching)
 | 
			
		||||
            }
 | 
			
		||||
            return nil
 | 
			
		||||
        }
 | 
			
		||||
        guard let (store, secret) = matching.first else {
 | 
			
		||||
            throw AgentError.noMatchingKey
 | 
			
		||||
        }
 | 
			
		||||
        let dataToSign = try reader.readNextChunk()
 | 
			
		||||
 | 
			
		||||
@ -5,10 +5,15 @@ import OSLog
 | 
			
		||||
@NSApplicationMain
 | 
			
		||||
class AppDelegate: NSObject, NSApplicationDelegate {
 | 
			
		||||
 | 
			
		||||
    let store = SecureEnclave.Store()
 | 
			
		||||
    let storeList: SecretStoreList = {
 | 
			
		||||
        let list = SecretStoreList()
 | 
			
		||||
        list.add(store: SecureEnclave.Store())
 | 
			
		||||
        list.add(store: SmartCard.Store())
 | 
			
		||||
        return list
 | 
			
		||||
    }()
 | 
			
		||||
    let notifier = Notifier()
 | 
			
		||||
    lazy var agent: Agent = {
 | 
			
		||||
        Agent(store: store, notifier: notifier)
 | 
			
		||||
        Agent(storeList: storeList, notifier: notifier)
 | 
			
		||||
    }()
 | 
			
		||||
    lazy var socketController: SocketController = {
 | 
			
		||||
        let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ public class AnySecretStore: SecretStore {
 | 
			
		||||
        _name = { secretStore.name }
 | 
			
		||||
        _id = { secretStore.id }
 | 
			
		||||
        _secrets = { secretStore.secrets.map { AnySecret($0) } }
 | 
			
		||||
        _sign = { try secretStore.sign(data: $0, with: $1 as! SecretStoreType.SecretType) }
 | 
			
		||||
        _sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType) }
 | 
			
		||||
        sink = secretStore.objectWillChange.sink { _ in
 | 
			
		||||
            self.objectWillChange.send()
 | 
			
		||||
        }
 | 
			
		||||
@ -65,5 +65,3 @@ public class AnySecretStoreModifiable: AnySecretStore, SecretStoreModifiable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,11 @@ public class SecretStoreList: ObservableObject {
 | 
			
		||||
        addInternal(store: modifiable)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public func addInternal(store: AnySecretStore) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extension SecretStoreList {
 | 
			
		||||
 | 
			
		||||
    fileprivate func addInternal(store: AnySecretStore) {
 | 
			
		||||
        stores.append(store)
 | 
			
		||||
        let sink = store.objectWillChange.sink {
 | 
			
		||||
            self.objectWillChange.send()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user