mirror of
https://github.com/maxgoedjen/secretive.git
synced 2026-04-10 03:07:22 +02:00
Compare commits
10 Commits
newsetup_l
...
codeql_wor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8826726bc3 | ||
|
|
bf78879310 | ||
|
|
ca495f4b7f | ||
|
|
6dc93806a8 | ||
|
|
99a6d48e53 | ||
|
|
935ac32ea2 | ||
|
|
a0a632f245 | ||
|
|
51fed9e593 | ||
|
|
f652d1d961 | ||
|
|
8aacd428b1 |
46
.github/workflows/codeql.yml
vendored
Normal file
46
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: "CodeQL Advanced"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
schedule:
|
||||||
|
- cron: '26 15 * * 3'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze (${{ matrix.language }})
|
||||||
|
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
packages: read
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- language: actions
|
||||||
|
build-mode: none
|
||||||
|
- language: swift
|
||||||
|
build-mode: manual
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
build-mode: ${{ matrix.build-mode }}
|
||||||
|
- if: matrix.build-mode == 'manual'
|
||||||
|
name: "Select Xcode"
|
||||||
|
run: sudo xcrun xcode-select -s /Applications/Xcode_26.0.app
|
||||||
|
- if: matrix.build-mode == 'manual'
|
||||||
|
name: "Build"
|
||||||
|
run: xcrun xcodebuild -project Sources/Secretive.xcodeproj -scheme Secretive -configuration Release build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
||||||
@@ -61,4 +61,4 @@ Because secrets in the Secure Enclave are not exportable, they are not able to b
|
|||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
If you discover any vulnerabilities in this project, please notify [max.goedjen@gmail.com](mailto:max.goedjen@gmail.com) with the subject containing "SECRETIVE SECURITY."
|
Secretive's security policy is detailed in [SECURITY.md](SECURITY.md). To report security issues, please use [GitHub's private reporting feature.](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability)
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ The latest version on the [Releases page](https://github.com/maxgoedjen/secretiv
|
|||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
If you discover any vulnerabilities in this project, please notify max.goedjen@gmail.com with the subject containing "SECRETIVE SECURITY."
|
To report security issues, please use [GitHub's private reporting feature.](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability)
|
||||||
|
|||||||
@@ -89,9 +89,8 @@ extension Agent {
|
|||||||
|
|
||||||
for secret in secrets {
|
for secret in secrets {
|
||||||
let keyBlob = publicKeyWriter.data(secret: secret)
|
let keyBlob = publicKeyWriter.data(secret: secret)
|
||||||
let curveData = publicKeyWriter.openSSHIdentifier(for: secret.keyType)
|
|
||||||
keyData.append(keyBlob.lengthAndData)
|
keyData.append(keyBlob.lengthAndData)
|
||||||
keyData.append(curveData.lengthAndData)
|
keyData.append(publicKeyWriter.comment(secret: secret).lengthAndData)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if let (certificateData, name) = try? await certificateHandler.keyBlobAndName(for: secret) {
|
if let (certificateData, name) = try? await certificateHandler.keyBlobAndName(for: secret) {
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ extension SocketController {
|
|||||||
provenance = SigningRequestTracer().provenance(from: fileHandle)
|
provenance = SigningRequestTracer().provenance(from: fileHandle)
|
||||||
(messages, messagesContinuation) = AsyncStream.makeStream()
|
(messages, messagesContinuation) = AsyncStream.makeStream()
|
||||||
Task { [messagesContinuation, logger] in
|
Task { [messagesContinuation, logger] in
|
||||||
await fileHandle.waitForDataInBackgroundAndNotifyOnMainActor()
|
|
||||||
for await _ in NotificationCenter.default.notifications(named: .NSFileHandleDataAvailable, object: fileHandle) {
|
for await _ in NotificationCenter.default.notifications(named: .NSFileHandleDataAvailable, object: fileHandle) {
|
||||||
let data = fileHandle.availableData
|
let data = fileHandle.availableData
|
||||||
guard !data.isEmpty else {
|
guard !data.isEmpty else {
|
||||||
@@ -91,6 +90,9 @@ extension SocketController {
|
|||||||
logger.debug("Socket controller yielded data.")
|
logger.debug("Socket controller yielded data.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Task {
|
||||||
|
await fileHandle.waitForDataInBackgroundAndNotifyOnMainActor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes new data to the socket.
|
/// Writes new data to the socket.
|
||||||
|
|||||||
@@ -31,18 +31,7 @@ public struct OpenSSHPublicKeyWriter: Sendable {
|
|||||||
/// Generates an OpenSSH string representation of the secret.
|
/// Generates an OpenSSH string representation of the secret.
|
||||||
/// - Returns: OpenSSH string representation of the secret.
|
/// - Returns: OpenSSH string representation of the secret.
|
||||||
public func openSSHString<SecretType: Secret>(secret: SecretType) -> String {
|
public func openSSHString<SecretType: Secret>(secret: SecretType) -> String {
|
||||||
let resolvedComment: String
|
return [openSSHIdentifier(for: secret.keyType), data(secret: secret).base64EncodedString(), comment(secret: secret)]
|
||||||
if let comment = secret.publicKeyAttribution {
|
|
||||||
resolvedComment = comment
|
|
||||||
} else {
|
|
||||||
let dashedKeyName = secret.name.replacingOccurrences(of: " ", with: "-")
|
|
||||||
let dashedHostName = ["secretive", Host.current().localizedName, "local"]
|
|
||||||
.compactMap { $0 }
|
|
||||||
.joined(separator: ".")
|
|
||||||
.replacingOccurrences(of: " ", with: "-")
|
|
||||||
resolvedComment = "\(dashedKeyName)@\(dashedHostName)"
|
|
||||||
}
|
|
||||||
return [openSSHIdentifier(for: secret.keyType), data(secret: secret).base64EncodedString(), resolvedComment]
|
|
||||||
.compactMap { $0 }
|
.compactMap { $0 }
|
||||||
.joined(separator: " ")
|
.joined(separator: " ")
|
||||||
}
|
}
|
||||||
@@ -65,6 +54,19 @@ public struct OpenSSHPublicKeyWriter: Sendable {
|
|||||||
.joined(separator: ":")
|
.joined(separator: ":")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func comment<SecretType: Secret>(secret: SecretType) -> String {
|
||||||
|
if let comment = secret.publicKeyAttribution {
|
||||||
|
return comment
|
||||||
|
} else {
|
||||||
|
let dashedKeyName = secret.name.replacingOccurrences(of: " ", with: "-")
|
||||||
|
let dashedHostName = ["secretive", Host.current().localizedName, "local"]
|
||||||
|
.compactMap { $0 }
|
||||||
|
.joined(separator: ".")
|
||||||
|
.replacingOccurrences(of: " ", with: "-")
|
||||||
|
return "\(dashedKeyName)@\(dashedHostName)"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension OpenSSHPublicKeyWriter {
|
extension OpenSSHPublicKeyWriter {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ extension SecureEnclave {
|
|||||||
var accessError: SecurityError?
|
var accessError: SecurityError?
|
||||||
let flags: SecAccessControlCreateFlags = switch attributes.authentication {
|
let flags: SecAccessControlCreateFlags = switch attributes.authentication {
|
||||||
case .notRequired:
|
case .notRequired:
|
||||||
[]
|
[.privateKeyUsage]
|
||||||
case .presenceRequired:
|
case .presenceRequired:
|
||||||
[.userPresence, .privateKeyUsage]
|
[.userPresence, .privateKeyUsage]
|
||||||
case .biometryCurrent:
|
case .biometryCurrent:
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ struct EditSecretView<StoreType: SecretStoreModifiable>: View {
|
|||||||
|
|
||||||
func rename() {
|
func rename() {
|
||||||
var attributes = secret.attributes
|
var attributes = secret.attributes
|
||||||
if !publicKeyAttribution.isEmpty {
|
attributes.publicKeyAttribution = publicKeyAttribution.isEmpty ? nil : publicKeyAttribution
|
||||||
attributes.publicKeyAttribution = publicKeyAttribution
|
|
||||||
}
|
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
try await store.update(secret: secret, name: name, attributes: attributes)
|
try await store.update(secret: secret, name: name, attributes: attributes)
|
||||||
|
|||||||
Reference in New Issue
Block a user