Merge branch 'main' into popovers

This commit is contained in:
Max Goedjen 2020-11-11 15:35:25 -08:00
commit 763b6ea57d
No known key found for this signature in database
GPG Key ID: E58C21DD77B9B8E8
16 changed files with 61 additions and 46 deletions

View File

@ -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:

View File

@ -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
View 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
View File

@ -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

Binary file not shown.

View File

@ -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:)
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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;

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -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) {

View File

@ -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)