mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-04-10 17:47:19 +00:00
Merge branch 'main' into popovers
This commit is contained in:
commit
763b6ea57d
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -6,7 +6,7 @@ on:
|
||||
- '*'
|
||||
jobs:
|
||||
test:
|
||||
runs-on: macOS-latest
|
||||
runs-on: macos-11.0
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
@ -18,7 +18,7 @@ jobs:
|
||||
AGENT_PROFILE_DATA: ${{ secrets.AGENT_PROFILE_DATA }}
|
||||
run: ./.github/scripts/signing.sh
|
||||
- name: Set Environment
|
||||
run: sudo xcrun xcode-select -s /Applications/Xcode_12_beta.app
|
||||
run: sudo xcrun xcode-select -s /Applications/Xcode_12.2.app
|
||||
- name: Test
|
||||
run: xcrun xcodebuild test -project Secretive.xcodeproj -scheme Secretive
|
||||
build:
|
||||
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@ -3,11 +3,11 @@ name: Test
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: macOS-latest
|
||||
runs-on: macos-11.0
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set Environment
|
||||
run: sudo xcrun xcode-select -s /Applications/Xcode_12_beta.app
|
||||
run: sudo xcrun xcode-select -s /Applications/Xcode_12.2.app
|
||||
- name: Test
|
||||
run: xcrun xcodebuild test -project Secretive.xcodeproj -scheme Secretive
|
||||
|
33
APP_CONFIG.md
Normal file
33
APP_CONFIG.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Setting up Third Party Apps FAQ
|
||||
|
||||
## Tower
|
||||
|
||||
Tower provides [instructions](https://www.git-tower.com/help/mac/integration/environment).
|
||||
|
||||
## GitHub Desktop
|
||||
|
||||
Should just work, no configuration needed
|
||||
|
||||
## Fork
|
||||
|
||||
Add this to your `~/.ssh/config` (the path should match the socket path from the setup flow).
|
||||
|
||||
```
|
||||
Host *
|
||||
IdentityAgent /Users/$YOUR_USERNAME/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
|
||||
```
|
||||
|
||||
## VS Code
|
||||
|
||||
Add this to your `~/.ssh/config` (the path should match the socket path from the setup flow).
|
||||
|
||||
```
|
||||
Host *
|
||||
IdentityAgent /Users/$YOUR_USERNAME/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh
|
||||
```
|
||||
|
||||
|
||||
# The app I use isn't listed here!
|
||||
|
||||
If you know how to get it set up, please open a PR for this page and add it! Contributions are very welcome.
|
||||
If you're not able to get it working, please file a [GitHub issue](https://github.com/maxgoedjen/secretive/issues/new) for it. No guarantees we'll be able to get it working, but chances are someone else in the community might be able to.
|
8
FAQ.md
8
FAQ.md
@ -4,13 +4,9 @@
|
||||
|
||||
The secure enclave doesn't allow import or export of private keys. For any new computer, you should just create a new set of keys. If you're using a smart card, you _might_ be able to export your private key from the vendor's software.
|
||||
|
||||
### Secretive doesn't work with my git client
|
||||
### Secretive doesn't work with my git client/app
|
||||
|
||||
Secretive relies on the `SSH_AUTH_SOCK` environment variable being respected. The `git` and `ssh` command line tools natively respect this, but third party apps may require some configuration to work. A non-exhaustive list of clients is provided here:
|
||||
|
||||
Tower - [Instructions](https://www.git-tower.com/help/mac/integration/environment)
|
||||
|
||||
GitHub Desktop: Should just work, no configuration needed
|
||||
Secretive relies on the `SSH_AUTH_SOCK` environment variable being respected. The `git` and `ssh` command line tools natively respect this, but third party apps may require some configuration to work. A non-exhaustive list of setup steps is provided in the [App Config FAQ](APP_CONFIG.md).
|
||||
|
||||
### Secretive isn't working for me
|
||||
|
||||
|
BIN
Icon.sketch
Normal file
BIN
Icon.sketch
Normal file
Binary file not shown.
@ -26,7 +26,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
private var updateSink: AnyCancellable?
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
os_log(.debug, "SecretAgent finished launching")
|
||||
Logger().debug("SecretAgent finished launching")
|
||||
DispatchQueue.main.async {
|
||||
self.socketController.handler = self.agent.handle(reader:writer:)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ public class Agent {
|
||||
private let requestTracer = SigningRequestTracer()
|
||||
|
||||
public init(storeList: SecretStoreList, witness: SigningWitness? = nil) {
|
||||
os_log(.debug, "Agent is running")
|
||||
Logger().debug("Agent is running")
|
||||
self.storeList = storeList
|
||||
self.witness = witness
|
||||
}
|
||||
@ -22,16 +22,16 @@ public class Agent {
|
||||
extension Agent {
|
||||
|
||||
public func handle(reader: FileHandleReader, writer: FileHandleWriter) {
|
||||
os_log(.debug, "Agent handling new data")
|
||||
Logger().debug("Agent handling new data")
|
||||
let data = reader.availableData
|
||||
guard !data.isEmpty else { return }
|
||||
let requestTypeInt = data[4]
|
||||
guard let requestType = SSHAgent.RequestType(rawValue: requestTypeInt) else {
|
||||
writer.write(OpenSSHKeyWriter().lengthAndData(of: SSHAgent.ResponseType.agentFailure.data))
|
||||
os_log(.debug, "Agent returned %@", SSHAgent.ResponseType.agentFailure.debugDescription)
|
||||
Logger().debug("Agent returned \(SSHAgent.ResponseType.agentFailure.debugDescription)")
|
||||
return
|
||||
}
|
||||
os_log(.debug, "Agent handling request of type %@", requestType.debugDescription)
|
||||
Logger().debug("Agent handling request of type \(requestType.debugDescription)")
|
||||
let subData = Data(data[5...])
|
||||
let response = handle(requestType: requestType, data: subData, reader: reader)
|
||||
writer.write(response)
|
||||
@ -44,17 +44,17 @@ extension Agent {
|
||||
case .requestIdentities:
|
||||
response.append(SSHAgent.ResponseType.agentIdentitiesAnswer.data)
|
||||
response.append(identities())
|
||||
os_log(.debug, "Agent returned %@", SSHAgent.ResponseType.agentIdentitiesAnswer.debugDescription)
|
||||
Logger().debug("Agent returned \(SSHAgent.ResponseType.agentIdentitiesAnswer.debugDescription)")
|
||||
case .signRequest:
|
||||
let provenance = requestTracer.provenance(from: reader)
|
||||
response.append(SSHAgent.ResponseType.agentSignResponse.data)
|
||||
response.append(try sign(data: data, provenance: provenance))
|
||||
os_log(.debug, "Agent returned %@", SSHAgent.ResponseType.agentSignResponse.debugDescription)
|
||||
Logger().debug("Agent returned \(SSHAgent.ResponseType.agentSignResponse.debugDescription)")
|
||||
}
|
||||
} catch {
|
||||
response.removeAll()
|
||||
response.append(SSHAgent.ResponseType.agentFailure.data)
|
||||
os_log(.debug, "Agent returned %@", SSHAgent.ResponseType.agentFailure.debugDescription)
|
||||
Logger().debug("Agent returned \(SSHAgent.ResponseType.agentFailure.debugDescription)")
|
||||
}
|
||||
let full = OpenSSHKeyWriter().lengthAndData(of: response)
|
||||
return full
|
||||
@ -76,7 +76,7 @@ extension Agent {
|
||||
let curveData = writer.curveType(for: secret.algorithm, length: secret.keySize).data(using: .utf8)!
|
||||
keyData.append(writer.lengthAndData(of: curveData))
|
||||
}
|
||||
os_log(.debug, "Agent enumerated %@ identities", secrets.count as NSNumber)
|
||||
Logger().debug("Agent enumerated \(secrets.count) identities")
|
||||
return countData + keyData
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ extension Agent {
|
||||
let reader = OpenSSHReader(data: data)
|
||||
let hash = reader.readNextChunk()
|
||||
guard let (store, secret) = secret(matching: hash) else {
|
||||
os_log(.debug, "Agent did not have a key matching %@", hash as NSData)
|
||||
Logger().debug("Agent did not have a key matching \(hash as NSData)")
|
||||
throw AgentError.noMatchingKey
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ extension Agent {
|
||||
try witness.witness(accessTo: secret, by: provenance)
|
||||
}
|
||||
|
||||
os_log(.debug, "Agent signed request")
|
||||
Logger().debug("Agent signed request")
|
||||
|
||||
return signedData
|
||||
}
|
||||
|
@ -8,16 +8,16 @@ public class SocketController {
|
||||
public var handler: ((FileHandleReader, FileHandleWriter) -> Void)?
|
||||
|
||||
public init(path: String) {
|
||||
os_log(.debug, "Socket controller setting up at %@", path)
|
||||
Logger().debug("Socket controller setting up at \(path)")
|
||||
if let _ = try? FileManager.default.removeItem(atPath: path) {
|
||||
os_log(.debug, "Socket controller removed existing socket")
|
||||
Logger().debug("Socket controller removed existing socket")
|
||||
}
|
||||
let exists = FileManager.default.fileExists(atPath: path)
|
||||
assert(!exists)
|
||||
os_log(.debug, "Socket controller path is clear")
|
||||
Logger().debug("Socket controller path is clear")
|
||||
port = socketPort(at: path)
|
||||
configureSocket(at: path)
|
||||
os_log(.debug, "Socket listening at %@", path)
|
||||
Logger().debug("Socket listening at \(path)")
|
||||
}
|
||||
|
||||
func configureSocket(at path: String) {
|
||||
@ -50,7 +50,7 @@ public class SocketController {
|
||||
}
|
||||
|
||||
@objc func handleConnectionAccept(notification: Notification) {
|
||||
os_log(.debug, "Socket controller accepted connection")
|
||||
Logger().debug("Socket controller accepted connection")
|
||||
guard let new = notification.userInfo?[NSFileHandleNotificationFileHandleItem] as? FileHandle else { return }
|
||||
handler?(new, new)
|
||||
new.waitForDataInBackgroundAndNotify()
|
||||
@ -58,9 +58,9 @@ public class SocketController {
|
||||
}
|
||||
|
||||
@objc func handleConnectionDataAvailable(notification: Notification) {
|
||||
os_log(.debug, "Socket controller has new data available")
|
||||
Logger().debug("Socket controller has new data available")
|
||||
guard let new = notification.object as? FileHandle else { return }
|
||||
os_log(.debug, "Socket controller received new file handle")
|
||||
Logger().debug("Socket controller received new file handle")
|
||||
handler?(new, new)
|
||||
}
|
||||
|
||||
|
@ -1401,7 +1401,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1432,7 +1431,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1455,7 +1453,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -1475,7 +1472,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -1502,7 +1498,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1532,7 +1527,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1563,7 +1557,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Brief;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1719,7 +1712,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.Secretive.SecretKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1743,7 +1735,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -1770,7 +1761,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1794,7 +1784,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@ -1880,7 +1869,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1911,7 +1899,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
@ -1934,7 +1921,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -1954,7 +1940,6 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.maxgoedjen.SecretAgentKitTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -31,13 +31,13 @@
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon 2@1x.png",
|
||||
"filename" : "Mac Icon.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon 2@2x.png",
|
||||
"filename" : "Mac Icon@0.25x.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 66 KiB |
BIN
Secretive/Assets.xcassets/AppIcon.appiconset/Mac Icon.png
Normal file
BIN
Secretive/Assets.xcassets/AppIcon.appiconset/Mac Icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
Secretive/Assets.xcassets/AppIcon.appiconset/Mac Icon@0.25x.png
Normal file
BIN
Secretive/Assets.xcassets/AppIcon.appiconset/Mac Icon@0.25x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -23,7 +23,7 @@ struct CreateSecretView<StoreType: SecretStoreModifiable>: View {
|
||||
}
|
||||
HStack {
|
||||
Text("Name:")
|
||||
TextField("Shhhhh", text: $name)
|
||||
TextField("Shhhhh", text: $name).focusable()
|
||||
}
|
||||
HStack {
|
||||
Toggle(isOn: $requiresAuthentication) {
|
||||
|
@ -176,6 +176,7 @@ struct SSHAgentSetupView: View {
|
||||
bodyText: "Add this line to your shell config telling SSH to talk to Secret Agent when it wants to authenticate. Secretive can either do this for you automatically, or you can copy and paste this into your config file.",
|
||||
buttonTitle: "I Added it Manually",
|
||||
buttonAction: buttonAction) {
|
||||
Link("If you're trying to set up a third party app, check out the FAQ.", destination: URL(string: "https://github.com/maxgoedjen/secretive/APP_CONFIG.md")!)
|
||||
Picker(selection: $selectedShellInstruction, label: EmptyView()) {
|
||||
ForEach(SSHAgentSetupView.controller.shellInstructions) { instruction in
|
||||
Text(instruction.shell)
|
||||
|
Loading…
Reference in New Issue
Block a user