This commit is contained in:
parent
d365da11cd
commit
64225af0c1
|
@ -1,47 +1,45 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import OSLog
|
||||||
import SecretKit
|
import SecretKit
|
||||||
|
|
||||||
public class PublicKeyStandinFileStoreController {
|
/// Controller responsible for writing public keys to disk, so that they're easily accessible by scripts.
|
||||||
|
public class PublicKeyFileStoreController {
|
||||||
|
|
||||||
var files: [PublicKeyStandinFileController] = []
|
private let logger = Logger()
|
||||||
|
private let directory = NSHomeDirectory().appending("/PublicKeys")
|
||||||
|
|
||||||
public init(secrets: [AnySecret]) {
|
/// Initializes a PublicKeyFileStoreController
|
||||||
let directory = NSHomeDirectory().appending("/PublicKeys")
|
public init() {
|
||||||
try? FileManager.default.removeItem(at: URL(fileURLWithPath: directory))
|
|
||||||
try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directory), withIntermediateDirectories: false, attributes: nil)
|
|
||||||
// TODO: TEST
|
|
||||||
files = secrets.filter({ $0.name == "Git Signature"})
|
|
||||||
/*files = secrets*/.map { PublicKeyStandinFileController(secret: $0, path: directory.appending("/").appending("test") )}
|
|
||||||
print("Done")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Constants {
|
/// Removes and recreates the directory used to store keys.
|
||||||
static var standinExtension = "secretive-public-key"
|
public func clear() throws {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/// Writes out the keys specified to disk.
|
||||||
|
/// - Parameter secrets: The Secrets to generate keys for.
|
||||||
public class PublicKeyStandinFileController {
|
/// - Parameter clear: Whether or not the directory should be erased before writing keys.
|
||||||
|
public func generatePublicKeys(for secrets: [AnySecret], clear: Bool = false) throws {
|
||||||
private var fileHandle: FileHandle?
|
logger.log("Writing public keys to disk")
|
||||||
private let secret: AnySecret
|
if clear {
|
||||||
private let keyWriter = OpenSSHKeyWriter()
|
try? FileManager.default.removeItem(at: URL(fileURLWithPath: directory))
|
||||||
|
|
||||||
public init(secret: AnySecret, path: String) {
|
|
||||||
self.secret = secret
|
|
||||||
resetHandle(path: path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resetHandle(path: String) {
|
|
||||||
try? FileManager.default.removeItem(atPath: path)
|
|
||||||
let fifo = mkfifo(UnsafePointer(Array(path.utf8CString)), S_IRWXU)
|
|
||||||
assert(fifo == 0)
|
|
||||||
fileHandle = nil
|
|
||||||
fileHandle = FileHandle(forWritingAtPath: path)
|
|
||||||
fileHandle?.writeabilityHandler = { [self] handle in
|
|
||||||
try! handle.write(contentsOf: keyWriter.openSSHString(secret: secret).data(using: .utf8)!)
|
|
||||||
try! fileHandle?.close()
|
|
||||||
// self.resetHandle(path: path)
|
|
||||||
}
|
}
|
||||||
|
try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directory), withIntermediateDirectories: false, attributes: nil)
|
||||||
|
let keyWriter = OpenSSHKeyWriter()
|
||||||
|
for secret in secrets {
|
||||||
|
let path = path(for: secret)
|
||||||
|
guard let data = keyWriter.openSSHString(secret: secret).data(using: .utf8) else { continue }
|
||||||
|
FileManager.default.createFile(atPath: path, contents: data, attributes: nil)
|
||||||
|
}
|
||||||
|
logger.log("Finished writing public keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The path for a Secret's public key.
|
||||||
|
/// - Parameter secret: The Secret to return the path for.
|
||||||
|
/// - 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.
|
||||||
|
func path(for secret: AnySecret) -> String {
|
||||||
|
directory.appending("/").appending("\(secret.name.replacingOccurrences(of: " ", with: "-")).pub")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import CryptoTokenKit
|
||||||
import LocalAuthentication
|
import LocalAuthentication
|
||||||
import SecretKit
|
import SecretKit
|
||||||
|
|
||||||
// TODO: Might need to split this up into "sub-stores?"
|
|
||||||
// ie, each token has its own Store.
|
|
||||||
extension SmartCard {
|
extension SmartCard {
|
||||||
|
|
||||||
/// An implementation of Store backed by a Smart Card.
|
/// An implementation of Store backed by a Smart Card.
|
||||||
|
|
|
@ -18,6 +18,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}()
|
}()
|
||||||
private let updater = Updater(checkOnLaunch: false)
|
private let updater = Updater(checkOnLaunch: false)
|
||||||
private let notifier = Notifier()
|
private let notifier = Notifier()
|
||||||
|
private let publicKeyFileStoreController = PublicKeyFileStoreController()
|
||||||
private lazy var agent: Agent = {
|
private lazy var agent: Agent = {
|
||||||
Agent(storeList: storeList, witness: notifier)
|
Agent(storeList: storeList, witness: notifier)
|
||||||
}()
|
}()
|
||||||
|
@ -25,10 +26,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String
|
let path = (NSHomeDirectory() as NSString).appendingPathComponent("socket.ssh") as String
|
||||||
return SocketController(path: path)
|
return SocketController(path: path)
|
||||||
}()
|
}()
|
||||||
// TODO: CLEANUP
|
|
||||||
private lazy var fakeFile: PublicKeyStandinFileStoreController = {
|
|
||||||
PublicKeyStandinFileStoreController(secrets: storeList.stores.flatMap({ $0.secrets }))
|
|
||||||
}()
|
|
||||||
private var updateSink: AnyCancellable?
|
private var updateSink: AnyCancellable?
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
|
@ -41,12 +38,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
guard let update = update else { return }
|
guard let update = update else { return }
|
||||||
self.notifier.notify(update: update, ignore: self.updater.ignore(release:))
|
self.notifier.notify(update: update, ignore: self.updater.ignore(release:))
|
||||||
}
|
}
|
||||||
// TODO: CLEANUP
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
print(self.fakeFile)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reloadKeys() {
|
||||||
|
// TODO: This
|
||||||
|
// storeList.reloadAll()
|
||||||
|
try? publicKeyFileStoreController.clear()
|
||||||
|
try? publicKeyFileStoreController.generatePublicKeys(for: storeList.stores.flatMap({ $0.secrets }))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,10 @@ struct SecretDetailView<SecretType: Secret>: View {
|
||||||
CopyableView(title: "MD5 Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHMD5Fingerprint(secret: secret))
|
CopyableView(title: "MD5 Fingerprint", image: Image(systemName: "touchid"), text: keyWriter.openSSHMD5Fingerprint(secret: secret))
|
||||||
Spacer()
|
Spacer()
|
||||||
.frame(height: 20)
|
.frame(height: 20)
|
||||||
CopyableView(title: "Public Key", image: Image(systemName: "key"), text: keyString)
|
CopyableView(title: "Public Key Contents", image: Image(systemName: "key"), text: keyString)
|
||||||
|
Spacer()
|
||||||
|
.frame(height: 20)
|
||||||
|
CopyableView(title: "Public Key Path", image: Image(systemName: "lock.doc"), text: "/Users/max/whatever")
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,12 +43,7 @@ struct SecretDetailView<SecretType: Secret>: View {
|
||||||
var keyString: String {
|
var keyString: String {
|
||||||
keyWriter.openSSHString(secret: secret, comment: "\(dashedKeyName)@\(dashedHostName)")
|
keyWriter.openSSHString(secret: secret, comment: "\(dashedKeyName)@\(dashedHostName)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func copy() {
|
|
||||||
NSPasteboard.general.declareTypes([.string], owner: nil)
|
|
||||||
NSPasteboard.general.setString(keyString, forType: .string)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
Loading…
Reference in New Issue