From 8577e7cbc306e19ba8fc8f493426193ea5b1ff35 Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Sun, 6 Sep 2026 21:08:42 -0700 Subject: [PATCH] Parsing OpenSSH extensions (#823) * Agent extension parsing * Temporarily disable binding * Fix test * TODO Cleanup * TODO Cleanup * Put back assertion --- .../OpenSSHPublicKeyWriter.swift | 2 +- .../SSHProtocolKit/OpenSSHReader.swift | 13 ++ .../OpenSSHSignatureWriter.swift | 2 +- .../SSHProtocolKit/SSHAgentInputParser.swift | 149 +++++++++++++++++- .../SSHProtocolKit/SSHAgentProtocol.swift | 76 ++++++++- .../SSHProtocolExtensions.swift | 76 +++++++++ .../Sources/SecretAgentKit/Agent.swift | 56 ++++++- .../Types/SigningRequestTarget.swift | 52 ++++++ .../SecretAgentKitTests/AgentTests.swift | 2 +- Sources/SecretAgent/SecretAgent.entitlements | 4 +- Sources/Secretive.xcodeproj/project.pbxproj | 28 +++- .../xcshareddata/xcschemes/Secretive.xcscheme | 3 + 12 files changed, 444 insertions(+), 19 deletions(-) create mode 100644 Sources/Packages/Sources/SSHProtocolKit/SSHProtocolExtensions.swift create mode 100644 Sources/Packages/Sources/SecretKit/Types/SigningRequestTarget.swift diff --git a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHPublicKeyWriter.swift b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHPublicKeyWriter.swift index 16854a3..cbc105b 100644 --- a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHPublicKeyWriter.swift +++ b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHPublicKeyWriter.swift @@ -19,7 +19,7 @@ public struct OpenSSHPublicKeyWriter: Sendable { ("nistp" + String(describing: secret.keyType.size)).lengthAndData + secret.publicKey.lengthAndData case .mldsa: - // https://www.ietf.org/archive/id/draft-sfluhrer-ssh-mldsa-04.txt + // https://datatracker.ietf.org/doc/html/draft-sfluhrer-ssh-mldsa-05 openSSHIdentifier(for: secret.keyType).lengthAndData + secret.publicKey.lengthAndData case .rsa: diff --git a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHReader.swift b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHReader.swift index e33d738..bdcc1a9 100644 --- a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHReader.swift +++ b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHReader.swift @@ -42,6 +42,18 @@ public final class OpenSSHReader { return convertEndianness ? T(value.bigEndian) : T(value) } + public func readNextByteAsBool() throws(OpenSSHReaderError) -> Bool { + let size = MemoryLayout.size + guard remaining.count >= size else { throw .beyondBounds } + let lengthRange = 0.. String { try String(decoding: readNextChunk(convertEndianness: convertEndianness), as: UTF8.self) } @@ -53,5 +65,6 @@ public final class OpenSSHReader { } public enum OpenSSHReaderError: Error, Codable { + case incorrectFormat case beyondBounds } diff --git a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHSignatureWriter.swift b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHSignatureWriter.swift index 25397db..8bdb939 100644 --- a/Sources/Packages/Sources/SSHProtocolKit/OpenSSHSignatureWriter.swift +++ b/Sources/Packages/Sources/SSHProtocolKit/OpenSSHSignatureWriter.swift @@ -17,7 +17,7 @@ public struct OpenSSHSignatureWriter: Sendable { // https://datatracker.ietf.org/doc/html/rfc5656#section-3.1 ecdsaSignature(signature, keyType: secret.keyType) case .mldsa: - // https://datatracker.ietf.org/doc/html/draft-sfluhrer-ssh-mldsa-00#name-public-key-algorithms + // https://datatracker.ietf.org/doc/html/draft-sfluhrer-ssh-mldsa-05 mldsaSignature(signature, keyType: secret.keyType) case .rsa: // https://datatracker.ietf.org/doc/html/rfc4253#section-6.6 diff --git a/Sources/Packages/Sources/SSHProtocolKit/SSHAgentInputParser.swift b/Sources/Packages/Sources/SSHProtocolKit/SSHAgentInputParser.swift index d219a35..c547aaa 100644 --- a/Sources/Packages/Sources/SSHProtocolKit/SSHAgentInputParser.swift +++ b/Sources/Packages/Sources/SSHProtocolKit/SSHAgentInputParser.swift @@ -3,6 +3,8 @@ import OSLog import SecretKit import CertificateKit +import CryptoKit + public protocol SSHAgentInputParserProtocol { func parse(data: Data) async throws -> SSHAgent.Request @@ -53,8 +55,8 @@ public struct SSHAgentInputParser: SSHAgentInputParserProtocol { return .unlock case SSHAgent.Request.addSmartcardKeyConstrained.protocolID: return .addSmartcardKeyConstrained - case SSHAgent.Request.protocolExtension.protocolID: - return .protocolExtension + case SSHAgent.Request.protocolExtension(.empty).protocolID: + return .protocolExtension(try protocolExtension(from: body)) default: return .unknown(rawRequestInt) } @@ -64,12 +66,150 @@ public struct SSHAgentInputParser: SSHAgentInputParserProtocol { extension SSHAgentInputParser { + private enum Constants { + static let userAuthMagic: UInt8 = 50 // SSH2_MSG_USERAUTH_REQUEST + static let sshSigMagic = Data("SSHSIG".utf8) + } + func signatureRequestContext(from data: Data) throws(OpenSSHReaderError) -> SSHAgent.Request.SignatureRequestContext { let reader = OpenSSHReader(data: data) let rawKeyBlob = try reader.readNextChunk() let keyBlob = certificatePublicKeyBlob(from: rawKeyBlob) ?? rawKeyBlob - let dataToSign = try reader.readNextChunk() - return SSHAgent.Request.SignatureRequestContext(keyBlob: keyBlob, dataToSign: dataToSign) + let rawPayload = try reader.readNextChunk() + let payload: SSHAgent.Request.SignatureRequestContext.SignaturePayload + do { + if rawPayload.count > 6 && rawPayload[0..<6] == Constants.sshSigMagic { + payload = .init(raw: rawPayload, decoded: .sshSig(try sshSigPayload(from: rawPayload[6...]))) + } else { + payload = .init(raw: rawPayload, decoded: .sshConnection(try sshConnectionPayload(from: rawPayload))) + } + } catch { + payload = .init(raw: rawPayload, decoded: nil) + } + return SSHAgent.Request.SignatureRequestContext(keyBlob: keyBlob, dataToSign: payload) + } + + func sshSigPayload(from data: Data) throws(OpenSSHReaderError) -> SSHAgent.Request.SignatureRequestContext.SignaturePayload.DecodedPayload.SSHSigPayload { + // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig#L79 + let payloadReader = OpenSSHReader(data: data) + let namespace = try payloadReader.readNextChunkAsString() + _ = try payloadReader.readNextChunk() // reserved + let hashAlgorithm = try payloadReader.readNextChunkAsString() + let hash = try payloadReader.readNextChunk() + return .init( + namespace: namespace, + hashAlgorithm: hashAlgorithm, + hash: hash + ) + } + + func sshConnectionPayload(from data: Data) throws(OpenSSHReaderError) -> SSHAgent.Request.SignatureRequestContext.SignaturePayload.DecodedPayload.SSHConnectionPayload { + let payloadReader = OpenSSHReader(data: data) + _ = try payloadReader.readNextChunk() + let magic = try payloadReader.readNextBytes(as: UInt8.self, convertEndianness: false) + guard magic == Constants.userAuthMagic else { throw .incorrectFormat } + let username = try payloadReader.readNextChunkAsString() + _ = try payloadReader.readNextChunkAsString() // "ssh-connection" + _ = try payloadReader.readNextChunkAsString() // "publickey-hostbound-v00@openssh.com" + let hasSignature = try payloadReader.readNextByteAsBool() + let algorithm = try payloadReader.readNextChunkAsString() + let publicKeyReader = try payloadReader.readNextChunkAsSubReader() + _ = try publicKeyReader.readNextChunk() + _ = try publicKeyReader.readNextChunk() + let publicKey = try publicKeyReader.readNextChunk() + let hostKeyReader = try payloadReader.readNextChunkAsSubReader() + _ = try hostKeyReader.readNextChunk() + let hostKey = try hostKeyReader.readNextChunk() + return .init( + username: username, + hasSignature: hasSignature, + publicKeyAlgorithm: algorithm, + publicKey: publicKey, + hostKey: hostKey, + ) + } + + func protocolExtension(from data: Data) throws(AgentParsingError) -> SSHAgent.ProtocolExtension { + do { + let reader = OpenSSHReader(data: data) + let nameRaw = try reader.readNextChunkAsString() + let nameSplit = nameRaw.split(separator: "@") + guard nameSplit.count == 2 else { + throw AgentParsingError.invalidData + } + let (name, domain) = (nameSplit[0], nameSplit[1]) + switch domain { + case SSHAgent.ProtocolExtension.OpenSSHExtension.domain: + switch name { + case SSHAgent.ProtocolExtension.OpenSSHExtension.sessionBind(.empty).name: + let hostkeyBlob = try reader.readNextChunkAsSubReader() + let hostKeyType = try hostkeyBlob.readNextChunkAsString() + let hostKeyData = try hostkeyBlob.readNextChunk() + let sessionID = try reader.readNextChunk() + let signatureBlob = try reader.readNextChunkAsSubReader() + _ = try signatureBlob.readNextChunk() // key type again + let signature = try signatureBlob.readNextChunk() + let forwarding = try reader.readNextByteAsBool() + switch hostKeyType { + case "ssh-ed25519": + let hostKey = try CryptoKit.Curve25519.Signing.PublicKey(rawRepresentation: hostKeyData) + guard hostKey.isValidSignature(signature, for: sessionID) else { + throw AgentParsingError.incorrectSignature + } + case "ecdsa-sha2-nistp256": + let hostKey = try CryptoKit.P256.Signing.PublicKey(rawRepresentation: hostKeyData) + guard hostKey.isValidSignature(try .init(rawRepresentation: signature), for: sessionID) else { + throw AgentParsingError.incorrectSignature + } + case "ecdsa-sha2-nistp384": + let hostKey = try CryptoKit.P384.Signing.PublicKey(rawRepresentation: hostKeyData) + guard hostKey.isValidSignature(try .init(rawRepresentation: signature), for: sessionID) else { + throw AgentParsingError.incorrectSignature + } + case "ssh-mldsa-65": + if #available(macOS 26.0, *) { + let hostKey = try CryptoKit.MLDSA65.PublicKey(rawRepresentation: hostKeyData) + guard hostKey.isValidSignature(signature, for: sessionID) else { + throw AgentParsingError.incorrectSignature + } + } else { + throw AgentParsingError.unhandledRequest + } + case "ssh-mldsa-87": + if #available(macOS 26.0, *) { + let hostKey = try CryptoKit.MLDSA65.PublicKey(rawRepresentation: hostKeyData) + guard hostKey.isValidSignature(signature, for: sessionID) else { + throw AgentParsingError.incorrectSignature + } + } else { + throw AgentParsingError.unhandledRequest + } + case "ssh-rsa": + throw AgentParsingError.unhandledRequest + default: + throw AgentParsingError.unhandledRequest + } + let context = SSHAgent.ProtocolExtension.OpenSSHExtension.SessionBindContext( + hostKey: hostKeyData, + sessionID: sessionID, + signature: signature, + forwarding: forwarding + ) + return .openSSH(.sessionBind(context)) + default: + return .openSSH(.unknown(String(name))) + } + default: + return .unknown(nameRaw) + } + + } catch let error as OpenSSHReaderError { + throw .openSSHReader(error) + } catch let error as AgentParsingError { + throw error + } catch { + throw .unknownRequest + } } func certificatePublicKeyBlob(from hash: Data) -> Data? { @@ -99,6 +239,7 @@ extension SSHAgentInputParser { case unknownRequest case unhandledRequest case invalidData + case incorrectSignature case openSSHReader(OpenSSHReaderError) } diff --git a/Sources/Packages/Sources/SSHProtocolKit/SSHAgentProtocol.swift b/Sources/Packages/Sources/SSHProtocolKit/SSHAgentProtocol.swift index 0007989..1f1a36f 100644 --- a/Sources/Packages/Sources/SSHProtocolKit/SSHAgentProtocol.swift +++ b/Sources/Packages/Sources/SSHProtocolKit/SSHAgentProtocol.swift @@ -19,7 +19,7 @@ extension SSHAgent { case lock case unlock case addSmartcardKeyConstrained - case protocolExtension + case protocolExtension(ProtocolExtension) case unknown(UInt8) public var protocolID: UInt8 { @@ -60,18 +60,82 @@ extension SSHAgent { public struct SignatureRequestContext: Sendable, Codable { public let keyBlob: Data - public let dataToSign: Data + public let dataToSign: SignaturePayload - public init(keyBlob: Data, dataToSign: Data) { + public init(keyBlob: Data, dataToSign: SignaturePayload) { self.keyBlob = keyBlob self.dataToSign = dataToSign } public static var empty: SignatureRequestContext { - SignatureRequestContext(keyBlob: Data(), dataToSign: Data()) + SignatureRequestContext(keyBlob: Data(), dataToSign: SignaturePayload(raw: Data(), decoded: nil)) + } + + public struct SignaturePayload: Sendable, Codable { + + public let raw: Data + public let decoded: DecodedPayload? + + public init( + raw: Data, + decoded: DecodedPayload? + ) { + self.raw = raw + self.decoded = decoded + } + + public enum DecodedPayload: Sendable, Codable { + case sshConnection(SSHConnectionPayload) + case sshSig(SSHSigPayload) + + public struct SSHConnectionPayload: Sendable, Codable { + + public let username: String + public let hasSignature: Bool + public let publicKeyAlgorithm: String + public let publicKey: Data + public let hostKey: Data + + public init( + username: String, + hasSignature: Bool, + publicKeyAlgorithm: String, + publicKey: Data, + hostKey: Data + ) { + self.username = username + self.hasSignature = hasSignature + self.publicKeyAlgorithm = publicKeyAlgorithm + self.publicKey = publicKey + self.hostKey = hostKey + } + + } + + public struct SSHSigPayload: Sendable, Codable { + + public let namespace: String + public let hashAlgorithm: String + public let hash: Data + + public init( + namespace: String, + hashAlgorithm: String, + hash: Data, + ) { + self.namespace = namespace + self.hashAlgorithm = hashAlgorithm + self.hash = hash + } + + } + + } + } } + } /// The type of the SSH Agent Response, as described in https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent#section-5.1 @@ -88,8 +152,8 @@ extension SSHAgent { switch self { case .agentFailure: "SSH_AGENT_FAILURE" case .agentSuccess: "SSH_AGENT_SUCCESS" - case .agentIdentitiesAnswer: "SSH_AGENT_IDENTITIES_ANSWER" - case .agentSignResponse: "SSH_AGENT_SIGN_RESPONSE" + case .agentIdentitiesAnswer: "SSH2_AGENT_IDENTITIES_ANSWER" + case .agentSignResponse: "SSH2_AGENT_SIGN_RESPONSE" case .agentExtensionFailure: "SSH_AGENT_EXTENSION_FAILURE" case .agentExtensionResponse: "SSH_AGENT_EXTENSION_RESPONSE" } diff --git a/Sources/Packages/Sources/SSHProtocolKit/SSHProtocolExtensions.swift b/Sources/Packages/Sources/SSHProtocolKit/SSHProtocolExtensions.swift new file mode 100644 index 0000000..511926f --- /dev/null +++ b/Sources/Packages/Sources/SSHProtocolKit/SSHProtocolExtensions.swift @@ -0,0 +1,76 @@ +import Foundation + +// Extensions, as defined in https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.agent + +extension SSHAgent { + + public enum ProtocolExtension: CustomDebugStringConvertible, Codable, Sendable { + case openSSH(OpenSSHExtension) + case unknown(String) + + public var debugDescription: String { + switch self { + case let .openSSH(protocolExtension): + protocolExtension.debugDescription + case .unknown(let string): + "Unknown (\(string))" + } + } + + public static var empty: ProtocolExtension { + .unknown("empty") + } + + private struct ProtocolExtensionParsingError: Error {} + + } + +} + +extension SSHAgent.ProtocolExtension { + + public enum OpenSSHExtension: CustomDebugStringConvertible, Codable, Sendable { + case sessionBind(SessionBindContext) + case unknown(String) + + public static var domain: String { + "openssh.com" + } + + public var name: String { + switch self { + case .sessionBind: + "session-bind" + case .unknown(let name): + name + } + } + + public var debugDescription: String { + "\(name)@\(OpenSSHExtension.domain)" + } + } + +} + +extension SSHAgent.ProtocolExtension.OpenSSHExtension { + + public struct SessionBindContext: Codable, Sendable { + + public let hostKey: Data + public let sessionID: Data + public let signature: Data + public let forwarding: Bool + + public init(hostKey: Data, sessionID: Data, signature: Data, forwarding: Bool) { + self.hostKey = hostKey + self.sessionID = sessionID + self.signature = signature + self.forwarding = forwarding + } + + public static let empty = SessionBindContext(hostKey: Data(), sessionID: Data(), signature: Data(), forwarding: false) + + } + +} diff --git a/Sources/Packages/Sources/SecretAgentKit/Agent.swift b/Sources/Packages/Sources/SecretAgentKit/Agent.swift index d3445ef..6700370 100644 --- a/Sources/Packages/Sources/SecretAgentKit/Agent.swift +++ b/Sources/Packages/Sources/SecretAgentKit/Agent.swift @@ -16,6 +16,8 @@ public final class Agent: Sendable { private let signatureWriter = OpenSSHSignatureWriter() private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "Agent") + @MainActor private var sessionID: SSHAgent.ProtocolExtension.OpenSSHExtension.SessionBindContext? + /// Initializes an agent with a store list and a witness. /// - Parameters: /// - storeList: The `SecretStoreList` to make available. @@ -31,7 +33,11 @@ public final class Agent: Sendable { extension Agent { - public func handle(request: SSHAgent.Request, provenance: SigningRequestProvenance) async -> Data { + public func handle( + request: SSHAgent.Request, + provenance: SigningRequestProvenance + ) async -> Data { + logger.debug("Agent received request of type \(request.debugDescription)") // Depending on the launch context (such as after macOS update), the agent may need to reload secrets before acting await reloadSecretsIfNeccessary() var response = Data() @@ -42,9 +48,54 @@ extension Agent { response.append(await identities()) logger.debug("Agent returned \(SSHAgent.Response.agentIdentitiesAnswer.debugDescription)") case .signRequest(let context): + let target: SigningRequestTarget? + switch context.dataToSign.decoded { + case .sshConnection(let payload): + target = .connection( + .init( + username: payload.username, + hasSignature: payload.hasSignature, + publicKeyAlgorithm: payload.publicKeyAlgorithm, + publicKey: payload.publicKey, + hostKey: payload.hostKey + ) + ) + if let boundSession = await sessionID { + guard payload.hostKey == boundSession.hostKey else { + logger.error("Agent received bind request, but host key does not match signature request host key.") + throw BindingFailure() + } + } + case .sshSig(let payload): + target = .signature( + .init( + namespace: payload.namespace, + hashAlgorithm: payload.hashAlgorithm, + hash: payload.hash + ) + ) + default: + target = nil + } + _ = target response.append(SSHAgent.Response.agentSignResponse.data) - response.append(try await sign(data: context.dataToSign, keyBlob: context.keyBlob, provenance: provenance)) + response.append(try await sign(data: context.dataToSign.raw, keyBlob: context.keyBlob, provenance: provenance)) logger.debug("Agent returned \(SSHAgent.Response.agentSignResponse.debugDescription)") + case .protocolExtension(.openSSH(.sessionBind(let bind))): + // This is disabled until forward enforcement is handled. + _ = bind + response = try await MainActor.run { + logger.debug("Agent received bind request but not currently supported.") + throw UnhandledRequestError() +// guard sessionID == nil else { +// logger.error("Agent received bind request, but already bound.") +// throw BindingFailure() +// } +// logger.debug("Agent bound") +// sessionID = bind +// return SSHAgent.Response.agentSuccess.data + } + logger.debug("Agent returned \(SSHAgent.Response.agentSuccess.debugDescription)") case .unknown(let value): logger.error("Agent received unknown request of type \(value).") throw UnhandledRequestError() @@ -142,6 +193,7 @@ extension Agent { struct NoMatchingKeyError: Error {} struct UnhandledRequestError: Error {} + struct BindingFailure: Error {} } diff --git a/Sources/Packages/Sources/SecretKit/Types/SigningRequestTarget.swift b/Sources/Packages/Sources/SecretKit/Types/SigningRequestTarget.swift new file mode 100644 index 0000000..351a67d --- /dev/null +++ b/Sources/Packages/Sources/SecretKit/Types/SigningRequestTarget.swift @@ -0,0 +1,52 @@ +import Foundation +import AppKit + +/// Describes the target of the signature operation. +public enum SigningRequestTarget: Sendable { + + case connection(ConnectionPayload) + case signature(SignaturePayload) + + public struct ConnectionPayload: Sendable, Codable{ + + public let username: String + public let hasSignature: Bool + public let publicKeyAlgorithm: String + public let publicKey: Data + public let hostKey: Data + + public init( + username: String, + hasSignature: Bool, + publicKeyAlgorithm: String, + publicKey: Data, + hostKey: Data, + ) { + self.username = username + self.hasSignature = hasSignature + self.publicKeyAlgorithm = publicKeyAlgorithm + self.publicKey = publicKey + self.hostKey = hostKey + } + + } + + public struct SignaturePayload: Sendable, Codable { + + public let namespace: String + public let hashAlgorithm: String + public let hash: Data + + public init( + namespace: String, + hashAlgorithm: String, + hash: Data, + ) { + self.namespace = namespace + self.hashAlgorithm = hashAlgorithm + self.hash = hash + } + + } + +} diff --git a/Sources/Packages/Tests/SecretAgentKitTests/AgentTests.swift b/Sources/Packages/Tests/SecretAgentKitTests/AgentTests.swift index b8bd9c5..8942fb6 100644 --- a/Sources/Packages/Tests/SecretAgentKitTests/AgentTests.swift +++ b/Sources/Packages/Tests/SecretAgentKitTests/AgentTests.swift @@ -68,7 +68,7 @@ import CertificateKit let signature = try P256.Signing.ECDSASignature(rawRepresentation: rs) // Correct signature #expect(try P256.Signing.PublicKey(x963Representation: Constants.Secrets.ecdsa256Secret.publicKey) - .isValidSignature(signature, for: context.dataToSign)) + .isValidSignature(signature, for: context.dataToSign.raw)) } // MARK: Witness protocol diff --git a/Sources/SecretAgent/SecretAgent.entitlements b/Sources/SecretAgent/SecretAgent.entitlements index 35188de..28f4467 100644 --- a/Sources/SecretAgent/SecretAgent.entitlements +++ b/Sources/SecretAgent/SecretAgent.entitlements @@ -16,10 +16,10 @@ 1 com.apple.security.hardened-process.hardened-heap - com.apple.security.smartcard - com.apple.security.hardened-process.platform-restrictions-string 2 + com.apple.security.smartcard + keychain-access-groups $(AppIdentifierPrefix)com.maxgoedjen.Secretive diff --git a/Sources/Secretive.xcodeproj/project.pbxproj b/Sources/Secretive.xcodeproj/project.pbxproj index 54f5f08..2b6e30b 100644 --- a/Sources/Secretive.xcodeproj/project.pbxproj +++ b/Sources/Secretive.xcodeproj/project.pbxproj @@ -699,7 +699,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 2650; + LastSwiftUpdateCheck = 2700; LastUpgradeCheck = 2640; ORGANIZATIONNAME = "Max Goedjen"; TargetAttributes = { @@ -744,8 +744,8 @@ 50617D7E23FCE48D0099B055 /* Secretive */, 50A3B78924026B7500D209EA /* SecretAgent */, 50692D112E6FDB880043C7BB /* SecretiveUpdater */, - 50692E4F2E6FF9D20043C7BB /* SecretAgentInputParser */, 50E205132FAAB81C00402380 /* SecretiveCertificateParser */, + 50692E4F2E6FF9D20043C7BB /* SecretAgentInputParser */, ); }; /* End PBXProject section */ @@ -1515,6 +1515,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + AUTOMATION_APPLE_EVENTS = NO; CODE_SIGN_ENTITLEMENTS = SecretAgent/SecretAgent.entitlements; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; @@ -1533,6 +1534,7 @@ ENABLE_RESOURCE_ACCESS_CAMERA = NO; ENABLE_RESOURCE_ACCESS_CONTACTS = NO; ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO; ENABLE_RESOURCE_ACCESS_PRINTING = NO; ENABLE_RESOURCE_ACCESS_USB = NO; INFOPLIST_FILE = SecretAgent/Info.plist; @@ -1544,6 +1546,12 @@ MARKETING_VERSION = 1; PRODUCT_BUNDLE_IDENTIFIER = "$(SECRETIVE_BASE_BUNDLE_ID).SecretAgent"; PRODUCT_NAME = "$(TARGET_NAME)"; + RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO; + RUNTIME_EXCEPTION_ALLOW_JIT = NO; + RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO; + RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO; + RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO; + RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO; }; name = Test; }; @@ -1551,6 +1559,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + AUTOMATION_APPLE_EVENTS = NO; CODE_SIGN_ENTITLEMENTS = SecretAgent/SecretAgent.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; @@ -1570,6 +1579,7 @@ ENABLE_RESOURCE_ACCESS_CAMERA = NO; ENABLE_RESOURCE_ACCESS_CONTACTS = NO; ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO; ENABLE_RESOURCE_ACCESS_PRINTING = NO; ENABLE_RESOURCE_ACCESS_USB = NO; INFOPLIST_FILE = SecretAgent/Info.plist; @@ -1581,6 +1591,12 @@ MARKETING_VERSION = 1; PRODUCT_BUNDLE_IDENTIFIER = "$(SECRETIVE_BASE_BUNDLE_ID).SecretAgent"; PRODUCT_NAME = "$(TARGET_NAME)"; + RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO; + RUNTIME_EXCEPTION_ALLOW_JIT = NO; + RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO; + RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO; + RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO; + RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO; }; name = Debug; }; @@ -1588,6 +1604,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + AUTOMATION_APPLE_EVENTS = NO; CODE_SIGN_ENTITLEMENTS = SecretAgent/SecretAgent.entitlements; CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; @@ -1608,6 +1625,7 @@ ENABLE_RESOURCE_ACCESS_CAMERA = NO; ENABLE_RESOURCE_ACCESS_CONTACTS = NO; ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PHOTO_LIBRARY = NO; ENABLE_RESOURCE_ACCESS_PRINTING = NO; ENABLE_RESOURCE_ACCESS_USB = NO; INFOPLIST_FILE = SecretAgent/Info.plist; @@ -1620,6 +1638,12 @@ PRODUCT_BUNDLE_IDENTIFIER = "$(SECRETIVE_BASE_BUNDLE_ID).SecretAgent"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "Secretive - Secret Agent"; + RUNTIME_EXCEPTION_ALLOW_DYLD_ENVIRONMENT_VARIABLES = NO; + RUNTIME_EXCEPTION_ALLOW_JIT = NO; + RUNTIME_EXCEPTION_ALLOW_UNSIGNED_EXECUTABLE_MEMORY = NO; + RUNTIME_EXCEPTION_DEBUGGING_TOOL = NO; + RUNTIME_EXCEPTION_DISABLE_EXECUTABLE_PAGE_PROTECTION = NO; + RUNTIME_EXCEPTION_DISABLE_LIBRARY_VALIDATION = NO; }; name = Release; }; diff --git a/Sources/Secretive.xcodeproj/xcshareddata/xcschemes/Secretive.xcscheme b/Sources/Secretive.xcodeproj/xcshareddata/xcschemes/Secretive.xcscheme index b7eccb7..77ddc38 100644 --- a/Sources/Secretive.xcodeproj/xcshareddata/xcschemes/Secretive.xcscheme +++ b/Sources/Secretive.xcodeproj/xcshareddata/xcschemes/Secretive.xcscheme @@ -87,6 +87,9 @@ ReferencedContainer = "container:Secretive.xcodeproj"> + +