mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-16 18:23:53 +01:00
[AltDaemon] Replaces local socket communication with XPC
Allows AltDaemon to be launched on demand + reject any connections not made from AltStore.
This commit is contained in:
@@ -10,6 +10,23 @@
|
|||||||
#import "NSError+ALTServerError.h"
|
#import "NSError+ALTServerError.h"
|
||||||
#import "CFNotificationName+AltStore.h"
|
#import "CFNotificationName+AltStore.h"
|
||||||
|
|
||||||
|
// libproc
|
||||||
|
int proc_pidpath(int pid, void * buffer, uint32_t buffersize);
|
||||||
|
|
||||||
|
// Security.framework
|
||||||
|
CF_ENUM(uint32_t) {
|
||||||
|
kSecCSInternalInformation = 1 << 0,
|
||||||
|
kSecCSSigningInformation = 1 << 1,
|
||||||
|
kSecCSRequirementInformation = 1 << 2,
|
||||||
|
kSecCSDynamicInformation = 1 << 3,
|
||||||
|
kSecCSContentInformation = 1 << 4,
|
||||||
|
kSecCSSkipResourceDirectory = 1 << 5,
|
||||||
|
kSecCSCalculateCMSDigest = 1 << 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
OSStatus SecStaticCodeCreateWithPath(CFURLRef path, uint32_t flags, void ** __nonnull CF_RETURNS_RETAINED staticCode);
|
||||||
|
OSStatus SecCodeCopySigningInformation(void *code, uint32_t flags, CFDictionaryRef * __nonnull CF_RETURNS_RETAINED information);
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface AKDevice : NSObject
|
@interface AKDevice : NSObject
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ struct AppManager
|
|||||||
// Remove all inactive profiles (if active profiles are provided), and the previous profiles.
|
// Remove all inactive profiles (if active profiles are provided), and the previous profiles.
|
||||||
for fileURL in profileURLs
|
for fileURL in profileURLs
|
||||||
{
|
{
|
||||||
guard let profile = ALTProvisioningProfile(url: fileURL) else { continue }
|
// Use memory mapping to reduce peak memory usage and stay within limit.
|
||||||
|
guard let profile = try? ALTProvisioningProfile(url: fileURL, options: [.mappedIfSafe]) else { continue }
|
||||||
|
|
||||||
if installingBundleIDs.contains(profile.bundleIdentifier) || (activeProfiles?.contains(profile.bundleIdentifier) == false && profile.isFreeProvisioningProfile)
|
if installingBundleIDs.contains(profile.bundleIdentifier) || (activeProfiles?.contains(profile.bundleIdentifier) == false && profile.isFreeProvisioningProfile)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ConnectionManager.swift
|
// DaemonRequestHandler.swift
|
||||||
// AltServer
|
// AltDaemon
|
||||||
//
|
//
|
||||||
// Created by Riley Testut on 6/1/20.
|
// Created by Riley Testut on 6/1/20.
|
||||||
// Copyright © 2019 Riley Testut. All rights reserved.
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
||||||
@@ -11,7 +11,7 @@ import Foundation
|
|||||||
typealias DaemonConnectionManager = ConnectionManager<DaemonRequestHandler>
|
typealias DaemonConnectionManager = ConnectionManager<DaemonRequestHandler>
|
||||||
|
|
||||||
private let connectionManager = ConnectionManager(requestHandler: DaemonRequestHandler(),
|
private let connectionManager = ConnectionManager(requestHandler: DaemonRequestHandler(),
|
||||||
connectionHandlers: [LocalConnectionHandler()])
|
connectionHandlers: [XPCConnectionHandler()])
|
||||||
|
|
||||||
extension DaemonConnectionManager
|
extension DaemonConnectionManager
|
||||||
{
|
{
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
//
|
|
||||||
// LocalConnectionHandler.swift
|
|
||||||
// AltDaemon
|
|
||||||
//
|
|
||||||
// Created by Riley Testut on 6/2/20.
|
|
||||||
// Copyright © 2020 Riley Testut. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import Network
|
|
||||||
|
|
||||||
private let ReceivedLocalServerConnectionRequest: @convention(c) (CFNotificationCenter?, UnsafeMutableRawPointer?, CFNotificationName?, UnsafeRawPointer?, CFDictionary?) -> Void =
|
|
||||||
{ (center, observer, name, object, userInfo) in
|
|
||||||
guard let name = name, let observer = observer else { return }
|
|
||||||
|
|
||||||
let connection = unsafeBitCast(observer, to: LocalConnectionHandler.self)
|
|
||||||
connection.handle(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
class LocalConnectionHandler: ConnectionHandler
|
|
||||||
{
|
|
||||||
var connectionHandler: ((Connection) -> Void)?
|
|
||||||
var disconnectionHandler: ((Connection) -> Void)?
|
|
||||||
|
|
||||||
private let dispatchQueue = DispatchQueue(label: "io.altstore.LocalConnectionListener", qos: .utility)
|
|
||||||
|
|
||||||
deinit
|
|
||||||
{
|
|
||||||
self.stopListening()
|
|
||||||
}
|
|
||||||
|
|
||||||
func startListening()
|
|
||||||
{
|
|
||||||
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
|
|
||||||
let observer = Unmanaged.passUnretained(self).toOpaque()
|
|
||||||
|
|
||||||
CFNotificationCenterAddObserver(notificationCenter, observer, ReceivedLocalServerConnectionRequest, CFNotificationName.localServerConnectionAvailableRequest.rawValue, nil, .deliverImmediately)
|
|
||||||
CFNotificationCenterAddObserver(notificationCenter, observer, ReceivedLocalServerConnectionRequest, CFNotificationName.localServerConnectionStartRequest.rawValue, nil, .deliverImmediately)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopListening()
|
|
||||||
{
|
|
||||||
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
|
|
||||||
let observer = Unmanaged.passUnretained(self).toOpaque()
|
|
||||||
|
|
||||||
CFNotificationCenterRemoveObserver(notificationCenter, observer, .localServerConnectionAvailableRequest, nil)
|
|
||||||
CFNotificationCenterRemoveObserver(notificationCenter, observer, .localServerConnectionStartRequest, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate func handle(_ notification: CFNotificationName)
|
|
||||||
{
|
|
||||||
switch notification
|
|
||||||
{
|
|
||||||
case .localServerConnectionAvailableRequest:
|
|
||||||
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
|
|
||||||
CFNotificationCenterPostNotification(notificationCenter, .localServerConnectionAvailableResponse, nil, nil, true)
|
|
||||||
|
|
||||||
case .localServerConnectionStartRequest:
|
|
||||||
let connection = NWConnection(host: "localhost", port: NWEndpoint.Port(rawValue: ALTDeviceListeningSocket)!, using: .tcp)
|
|
||||||
self.start(connection)
|
|
||||||
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension LocalConnectionHandler
|
|
||||||
{
|
|
||||||
func start(_ nwConnection: NWConnection)
|
|
||||||
{
|
|
||||||
print("Starting connection to:", nwConnection)
|
|
||||||
|
|
||||||
// Use same instance for all callbacks.
|
|
||||||
let connection = NetworkConnection(nwConnection)
|
|
||||||
|
|
||||||
nwConnection.stateUpdateHandler = { [weak self] (state) in
|
|
||||||
switch state
|
|
||||||
{
|
|
||||||
case .setup, .preparing: break
|
|
||||||
|
|
||||||
case .ready:
|
|
||||||
print("Connected to client:", nwConnection.endpoint)
|
|
||||||
self?.connectionHandler?(connection)
|
|
||||||
|
|
||||||
case .waiting:
|
|
||||||
print("Waiting for connection...")
|
|
||||||
|
|
||||||
case .failed(let error):
|
|
||||||
print("Failed to connect to service \(nwConnection.endpoint).", error)
|
|
||||||
self?.disconnect(connection)
|
|
||||||
|
|
||||||
case .cancelled:
|
|
||||||
self?.disconnect(connection)
|
|
||||||
|
|
||||||
@unknown default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nwConnection.start(queue: self.dispatchQueue)
|
|
||||||
}
|
|
||||||
|
|
||||||
func disconnect(_ connection: Connection)
|
|
||||||
{
|
|
||||||
connection.disconnect()
|
|
||||||
|
|
||||||
self.disconnectionHandler?(connection)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
90
AltDaemon/XPCConnectionHandler.swift
Normal file
90
AltDaemon/XPCConnectionHandler.swift
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// XPCConnectionHandler.swift
|
||||||
|
// AltDaemon
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/14/20.
|
||||||
|
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Security
|
||||||
|
|
||||||
|
class XPCConnectionHandler: NSObject, ConnectionHandler
|
||||||
|
{
|
||||||
|
var connectionHandler: ((Connection) -> Void)?
|
||||||
|
var disconnectionHandler: ((Connection) -> Void)?
|
||||||
|
|
||||||
|
private let dispatchQueue = DispatchQueue(label: "io.altstore.XPCConnectionListener", qos: .utility)
|
||||||
|
private let listener = NSXPCListener.makeListener(machServiceName: XPCConnection.machServiceName)
|
||||||
|
|
||||||
|
deinit
|
||||||
|
{
|
||||||
|
self.stopListening()
|
||||||
|
}
|
||||||
|
|
||||||
|
func startListening()
|
||||||
|
{
|
||||||
|
self.listener.delegate = self
|
||||||
|
self.listener.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopListening()
|
||||||
|
{
|
||||||
|
self.listener.suspend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension XPCConnectionHandler
|
||||||
|
{
|
||||||
|
func disconnect(_ connection: Connection)
|
||||||
|
{
|
||||||
|
connection.disconnect()
|
||||||
|
|
||||||
|
self.disconnectionHandler?(connection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension XPCConnectionHandler: NSXPCListenerDelegate
|
||||||
|
{
|
||||||
|
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool
|
||||||
|
{
|
||||||
|
let maximumPathLength = 4 * UInt32(MAXPATHLEN)
|
||||||
|
|
||||||
|
let pathBuffer = UnsafeMutablePointer<CChar>.allocate(capacity: Int(maximumPathLength))
|
||||||
|
defer { pathBuffer.deallocate() }
|
||||||
|
|
||||||
|
proc_pidpath(newConnection.processIdentifier, pathBuffer, maximumPathLength)
|
||||||
|
|
||||||
|
let path = String(cString: pathBuffer)
|
||||||
|
let fileURL = URL(fileURLWithPath: path)
|
||||||
|
|
||||||
|
var code: UnsafeMutableRawPointer?
|
||||||
|
defer { code.map { Unmanaged<AnyObject>.fromOpaque($0).release() } }
|
||||||
|
|
||||||
|
var status = SecStaticCodeCreateWithPath(fileURL as CFURL, 0, &code)
|
||||||
|
guard status == 0 else { return false }
|
||||||
|
|
||||||
|
var signingInfo: CFDictionary?
|
||||||
|
defer { signingInfo.map { Unmanaged<AnyObject>.passUnretained($0).release() } }
|
||||||
|
|
||||||
|
status = SecCodeCopySigningInformation(code, kSecCSInternalInformation | kSecCSSigningInformation, &signingInfo)
|
||||||
|
guard status == 0 else { return false }
|
||||||
|
|
||||||
|
// Only accept connections from AltStore.
|
||||||
|
guard
|
||||||
|
let codeSigningInfo = signingInfo as? [String: Any],
|
||||||
|
let bundleIdentifier = codeSigningInfo["identifier"] as? String,
|
||||||
|
bundleIdentifier.contains("com.rileytestut.AltStore")
|
||||||
|
else { return false }
|
||||||
|
|
||||||
|
let connection = XPCConnection(newConnection)
|
||||||
|
newConnection.invalidationHandler = { [weak self, weak connection] in
|
||||||
|
guard let self = self, let connection = connection else { return }
|
||||||
|
self.disconnect(connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.connectionHandler?(connection)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,8 +14,13 @@
|
|||||||
<key>UserName</key>
|
<key>UserName</key>
|
||||||
<string>mobile</string>
|
<string>mobile</string>
|
||||||
<key>KeepAlive</key>
|
<key>KeepAlive</key>
|
||||||
<true/>
|
<false/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<false/>
|
||||||
|
<key>MachServices</key>
|
||||||
|
<dict>
|
||||||
|
<key>cy:io.altstore.altdaemon</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18B0F022E25DF9005C4CF5 /* ToastView.swift */; };
|
BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18B0F022E25DF9005C4CF5 /* ToastView.swift */; };
|
||||||
BF18BFFD2485A1E400DD5981 /* WiredConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFFC2485A1E400DD5981 /* WiredConnectionHandler.swift */; };
|
BF18BFFD2485A1E400DD5981 /* WiredConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFFC2485A1E400DD5981 /* WiredConnectionHandler.swift */; };
|
||||||
BF1E312B229F474900370A3C /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3129229F474900370A3C /* RequestHandler.swift */; };
|
BF1E312B229F474900370A3C /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3129229F474900370A3C /* RequestHandler.swift */; };
|
||||||
|
BF1FE358251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */; };
|
||||||
|
BF1FE359251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */; };
|
||||||
BF29012F2318F6B100D88A45 /* AppBannerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF29012E2318F6B100D88A45 /* AppBannerView.xib */; };
|
BF29012F2318F6B100D88A45 /* AppBannerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF29012E2318F6B100D88A45 /* AppBannerView.xib */; };
|
||||||
BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2901302318F7A800D88A45 /* AppBannerView.swift */; };
|
BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2901302318F7A800D88A45 /* AppBannerView.swift */; };
|
||||||
BF340E9A250AD39500A192CB /* ViewApp.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = BF989191250AAE86002ACF50 /* ViewApp.intentdefinition */; };
|
BF340E9A250AD39500A192CB /* ViewApp.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = BF989191250AAE86002ACF50 /* ViewApp.intentdefinition */; };
|
||||||
@@ -190,7 +192,7 @@
|
|||||||
BF8B17EB250AC40000F8157F /* FileManager+SharedDirectories.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6A531F246DC1B0004F59C8 /* FileManager+SharedDirectories.swift */; };
|
BF8B17EB250AC40000F8157F /* FileManager+SharedDirectories.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF6A531F246DC1B0004F59C8 /* FileManager+SharedDirectories.swift */; };
|
||||||
BF8CAE452489E772004D6CCE /* AnisetteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */; };
|
BF8CAE452489E772004D6CCE /* AnisetteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */; };
|
||||||
BF8CAE462489E772004D6CCE /* AppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE432489E772004D6CCE /* AppManager.swift */; };
|
BF8CAE462489E772004D6CCE /* AppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE432489E772004D6CCE /* AppManager.swift */; };
|
||||||
BF8CAE472489E772004D6CCE /* RequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE442489E772004D6CCE /* RequestHandler.swift */; };
|
BF8CAE472489E772004D6CCE /* DaemonRequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE442489E772004D6CCE /* DaemonRequestHandler.swift */; };
|
||||||
BF8CAE4C2489F637004D6CCE /* AltDaemon.deb in Resources */ = {isa = PBXBuildFile; fileRef = BF8CAE4A2489F5A0004D6CCE /* AltDaemon.deb */; };
|
BF8CAE4C2489F637004D6CCE /* AltDaemon.deb in Resources */ = {isa = PBXBuildFile; fileRef = BF8CAE4A2489F5A0004D6CCE /* AltDaemon.deb */; };
|
||||||
BF8CAE4E248AEABA004D6CCE /* UIDevice+Jailbreak.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */; };
|
BF8CAE4E248AEABA004D6CCE /* UIDevice+Jailbreak.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */; };
|
||||||
BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C122E659F700049BA1 /* AppContentViewController.swift */; };
|
BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8F69C122E659F700049BA1 /* AppContentViewController.swift */; };
|
||||||
@@ -235,6 +237,9 @@
|
|||||||
BFC57A652416C72400EB891E /* DeactivateAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */; };
|
BFC57A652416C72400EB891E /* DeactivateAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */; };
|
||||||
BFC57A6E2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */; };
|
BFC57A6E2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */; };
|
||||||
BFC57A702416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */; };
|
BFC57A702416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */; };
|
||||||
|
BFC712C32512D5F100AB5EBE /* XPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C12512D5F100AB5EBE /* XPCConnection.swift */; };
|
||||||
|
BFC712C42512D5F100AB5EBE /* XPCConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C12512D5F100AB5EBE /* XPCConnection.swift */; };
|
||||||
|
BFC712C52512D5F100AB5EBE /* XPCConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC712C22512D5F100AB5EBE /* XPCConnectionHandler.swift */; };
|
||||||
BFC84A4D2421A19100853474 /* SourcesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC84A4C2421A19100853474 /* SourcesViewController.swift */; };
|
BFC84A4D2421A19100853474 /* SourcesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC84A4C2421A19100853474 /* SourcesViewController.swift */; };
|
||||||
BFCB9207250AB2120057B44E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BFCB9206250AB2120057B44E /* Colors.xcassets */; };
|
BFCB9207250AB2120057B44E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BFCB9206250AB2120057B44E /* Colors.xcassets */; };
|
||||||
BFCCB51A245E3401001853EA /* VerifyAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCB519245E3401001853EA /* VerifyAppOperation.swift */; };
|
BFCCB51A245E3401001853EA /* VerifyAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCB519245E3401001853EA /* VerifyAppOperation.swift */; };
|
||||||
@@ -307,7 +312,6 @@
|
|||||||
BFECAC8924FD950E0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; };
|
BFECAC8924FD950E0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; };
|
||||||
BFECAC8A24FD950E0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; };
|
BFECAC8A24FD950E0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; };
|
||||||
BFECAC8B24FD950E0077C41F /* ServerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3128229F474900370A3C /* ServerProtocol.swift */; };
|
BFECAC8B24FD950E0077C41F /* ServerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E3128229F474900370A3C /* ServerProtocol.swift */; };
|
||||||
BFECAC8C24FD950E0077C41F /* NetworkConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CD2489ABE90097E58C /* NetworkConnection.swift */; };
|
|
||||||
BFECAC8D24FD950E0077C41F /* ALTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = BF718BD723C93DB700A89F2D /* ALTConstants.m */; };
|
BFECAC8D24FD950E0077C41F /* ALTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = BF718BD723C93DB700A89F2D /* ALTConstants.m */; };
|
||||||
BFECAC8E24FD950E0077C41F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF624858BDE00DD5981 /* Connection.swift */; };
|
BFECAC8E24FD950E0077C41F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF624858BDE00DD5981 /* Connection.swift */; };
|
||||||
BFECAC8F24FD950E0077C41F /* Result+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBAC8852295C90300587369 /* Result+Conveniences.swift */; };
|
BFECAC8F24FD950E0077C41F /* Result+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBAC8852295C90300587369 /* Result+Conveniences.swift */; };
|
||||||
@@ -328,7 +332,6 @@
|
|||||||
BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */; };
|
BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */; };
|
||||||
BFF615A82510042B00484D3B /* AltStoreCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; };
|
BFF615A82510042B00484D3B /* AltStoreCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; };
|
||||||
BFF767C82489A74E0097E58C /* WirelessConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767C72489A74E0097E58C /* WirelessConnectionHandler.swift */; };
|
BFF767C82489A74E0097E58C /* WirelessConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767C72489A74E0097E58C /* WirelessConnectionHandler.swift */; };
|
||||||
BFFCFA582488648D0077BFCE /* LocalConnectionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF10EB3124870B3F0055E6DB /* LocalConnectionHandler.swift */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -432,7 +435,6 @@
|
|||||||
BF088D322501A4FF008082D9 /* OpenSSL.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = Dependencies/AltSign/Dependencies/OpenSSL/Frameworks/OpenSSL.xcframework; sourceTree = "<group>"; };
|
BF088D322501A4FF008082D9 /* OpenSSL.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = OpenSSL.xcframework; path = Dependencies/AltSign/Dependencies/OpenSSL/Frameworks/OpenSSL.xcframework; sourceTree = "<group>"; };
|
||||||
BF0C4EBC22A1BD8B009A2DD7 /* AppManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = "<group>"; };
|
BF0C4EBC22A1BD8B009A2DD7 /* AppManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = "<group>"; };
|
||||||
BF0DCA652433BDF500E3A595 /* AnalyticsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsManager.swift; sourceTree = "<group>"; };
|
BF0DCA652433BDF500E3A595 /* AnalyticsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsManager.swift; sourceTree = "<group>"; };
|
||||||
BF10EB3124870B3F0055E6DB /* LocalConnectionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalConnectionHandler.swift; sourceTree = "<group>"; };
|
|
||||||
BF10EB33248730750055E6DB /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
BF10EB33248730750055E6DB /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
BF18B0F022E25DF9005C4CF5 /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
|
BF18B0F022E25DF9005C4CF5 /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
|
||||||
BF18BFE724857D7900DD5981 /* AltDaemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AltDaemon; sourceTree = BUILT_PRODUCTS_DIR; };
|
BF18BFE724857D7900DD5981 /* AltDaemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AltDaemon; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -447,6 +449,7 @@
|
|||||||
BF1E314722A060F300370A3C /* AltStore-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltStore-Bridging-Header.h"; sourceTree = "<group>"; };
|
BF1E314722A060F300370A3C /* AltStore-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AltStore-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
BF1E314822A060F400370A3C /* NSError+ALTServerError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+ALTServerError.h"; sourceTree = "<group>"; };
|
BF1E314822A060F400370A3C /* NSError+ALTServerError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+ALTServerError.h"; sourceTree = "<group>"; };
|
||||||
BF1E314922A060F400370A3C /* NSError+ALTServerError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+ALTServerError.m"; sourceTree = "<group>"; };
|
BF1E314922A060F400370A3C /* NSError+ALTServerError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+ALTServerError.m"; sourceTree = "<group>"; };
|
||||||
|
BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSXPCConnection+MachServices.swift"; sourceTree = "<group>"; };
|
||||||
BF219A7E22CAC431007676A6 /* AltStore.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltStore.entitlements; sourceTree = "<group>"; };
|
BF219A7E22CAC431007676A6 /* AltStore.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltStore.entitlements; sourceTree = "<group>"; };
|
||||||
BF29012E2318F6B100D88A45 /* AppBannerView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AppBannerView.xib; sourceTree = "<group>"; };
|
BF29012E2318F6B100D88A45 /* AppBannerView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AppBannerView.xib; sourceTree = "<group>"; };
|
||||||
BF2901302318F7A800D88A45 /* AppBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppBannerView.swift; sourceTree = "<group>"; };
|
BF2901302318F7A800D88A45 /* AppBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppBannerView.swift; sourceTree = "<group>"; };
|
||||||
@@ -630,7 +633,7 @@
|
|||||||
BF8B17F0250AC62400F8157F /* AltWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltWidgetExtension.entitlements; sourceTree = "<group>"; };
|
BF8B17F0250AC62400F8157F /* AltWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AltWidgetExtension.entitlements; sourceTree = "<group>"; };
|
||||||
BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnisetteDataManager.swift; sourceTree = "<group>"; };
|
BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnisetteDataManager.swift; sourceTree = "<group>"; };
|
||||||
BF8CAE432489E772004D6CCE /* AppManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = "<group>"; };
|
BF8CAE432489E772004D6CCE /* AppManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = "<group>"; };
|
||||||
BF8CAE442489E772004D6CCE /* RequestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestHandler.swift; sourceTree = "<group>"; };
|
BF8CAE442489E772004D6CCE /* DaemonRequestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DaemonRequestHandler.swift; sourceTree = "<group>"; };
|
||||||
BF8CAE4A2489F5A0004D6CCE /* AltDaemon.deb */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = AltDaemon.deb; sourceTree = "<group>"; };
|
BF8CAE4A2489F5A0004D6CCE /* AltDaemon.deb */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = AltDaemon.deb; sourceTree = "<group>"; };
|
||||||
BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Jailbreak.swift"; sourceTree = "<group>"; };
|
BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Jailbreak.swift"; sourceTree = "<group>"; };
|
||||||
BF8F69C122E659F700049BA1 /* AppContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppContentViewController.swift; sourceTree = "<group>"; };
|
BF8F69C122E659F700049BA1 /* AppContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppContentViewController.swift; sourceTree = "<group>"; };
|
||||||
@@ -662,6 +665,8 @@
|
|||||||
BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeactivateAppOperation.swift; sourceTree = "<group>"; };
|
BFC57A642416C72400EB891E /* DeactivateAppOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeactivateAppOperation.swift; sourceTree = "<group>"; };
|
||||||
BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledAppsCollectionHeaderView.swift; sourceTree = "<group>"; };
|
BFC57A6D2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledAppsCollectionHeaderView.swift; sourceTree = "<group>"; };
|
||||||
BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InstalledAppsCollectionHeaderView.xib; sourceTree = "<group>"; };
|
BFC57A6F2416FC7600EB891E /* InstalledAppsCollectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InstalledAppsCollectionHeaderView.xib; sourceTree = "<group>"; };
|
||||||
|
BFC712C12512D5F100AB5EBE /* XPCConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XPCConnection.swift; sourceTree = "<group>"; };
|
||||||
|
BFC712C22512D5F100AB5EBE /* XPCConnectionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XPCConnectionHandler.swift; sourceTree = "<group>"; };
|
||||||
BFC84A4C2421A19100853474 /* SourcesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourcesViewController.swift; sourceTree = "<group>"; };
|
BFC84A4C2421A19100853474 /* SourcesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourcesViewController.swift; sourceTree = "<group>"; };
|
||||||
BFCB9206250AB2120057B44E /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
BFCB9206250AB2120057B44E /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
||||||
BFCCB519245E3401001853EA /* VerifyAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAppOperation.swift; sourceTree = "<group>"; };
|
BFCCB519245E3401001853EA /* VerifyAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAppOperation.swift; sourceTree = "<group>"; };
|
||||||
@@ -858,8 +863,8 @@
|
|||||||
children = (
|
children = (
|
||||||
BFFCFA45248835530077BFCE /* AltDaemon.entitlements */,
|
BFFCFA45248835530077BFCE /* AltDaemon.entitlements */,
|
||||||
BF10EB33248730750055E6DB /* main.swift */,
|
BF10EB33248730750055E6DB /* main.swift */,
|
||||||
BF8CAE442489E772004D6CCE /* RequestHandler.swift */,
|
BFC712C22512D5F100AB5EBE /* XPCConnectionHandler.swift */,
|
||||||
BF10EB3124870B3F0055E6DB /* LocalConnectionHandler.swift */,
|
BF8CAE442489E772004D6CCE /* DaemonRequestHandler.swift */,
|
||||||
BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */,
|
BF8CAE422489E772004D6CCE /* AnisetteDataManager.swift */,
|
||||||
BF8CAE432489E772004D6CCE /* AppManager.swift */,
|
BF8CAE432489E772004D6CCE /* AppManager.swift */,
|
||||||
BF18C0032485B4DE00DD5981 /* AltDaemon-Bridging-Header.h */,
|
BF18C0032485B4DE00DD5981 /* AltDaemon-Bridging-Header.h */,
|
||||||
@@ -1580,6 +1585,7 @@
|
|||||||
BFBAC8852295C90300587369 /* Result+Conveniences.swift */,
|
BFBAC8852295C90300587369 /* Result+Conveniences.swift */,
|
||||||
BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */,
|
BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */,
|
||||||
BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */,
|
BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */,
|
||||||
|
BF1FE357251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1602,6 +1608,7 @@
|
|||||||
BF18BFFE2485A42800DD5981 /* ALTConnection.h */,
|
BF18BFFE2485A42800DD5981 /* ALTConnection.h */,
|
||||||
BF18BFF624858BDE00DD5981 /* Connection.swift */,
|
BF18BFF624858BDE00DD5981 /* Connection.swift */,
|
||||||
BFF767CD2489ABE90097E58C /* NetworkConnection.swift */,
|
BFF767CD2489ABE90097E58C /* NetworkConnection.swift */,
|
||||||
|
BFC712C12512D5F100AB5EBE /* XPCConnection.swift */,
|
||||||
);
|
);
|
||||||
path = Connections;
|
path = Connections;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2126,10 +2133,12 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
BF8CAE452489E772004D6CCE /* AnisetteDataManager.swift in Sources */,
|
BF8CAE452489E772004D6CCE /* AnisetteDataManager.swift in Sources */,
|
||||||
|
BF1FE358251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */,
|
||||||
BFECAC8F24FD950E0077C41F /* Result+Conveniences.swift in Sources */,
|
BFECAC8F24FD950E0077C41F /* Result+Conveniences.swift in Sources */,
|
||||||
BF8CAE472489E772004D6CCE /* RequestHandler.swift in Sources */,
|
BF8CAE472489E772004D6CCE /* DaemonRequestHandler.swift in Sources */,
|
||||||
BFECAC8C24FD950E0077C41F /* NetworkConnection.swift in Sources */,
|
|
||||||
BFECAC8824FD950E0077C41F /* CodableServerError.swift in Sources */,
|
BFECAC8824FD950E0077C41F /* CodableServerError.swift in Sources */,
|
||||||
|
BFC712C32512D5F100AB5EBE /* XPCConnection.swift in Sources */,
|
||||||
|
BFC712C52512D5F100AB5EBE /* XPCConnectionHandler.swift in Sources */,
|
||||||
BFECAC8A24FD950E0077C41F /* ALTServerError+Conveniences.swift in Sources */,
|
BFECAC8A24FD950E0077C41F /* ALTServerError+Conveniences.swift in Sources */,
|
||||||
BFECAC8D24FD950E0077C41F /* ALTConstants.m in Sources */,
|
BFECAC8D24FD950E0077C41F /* ALTConstants.m in Sources */,
|
||||||
BFECAC8924FD950E0077C41F /* ConnectionManager.swift in Sources */,
|
BFECAC8924FD950E0077C41F /* ConnectionManager.swift in Sources */,
|
||||||
@@ -2138,7 +2147,6 @@
|
|||||||
BFECAC8B24FD950E0077C41F /* ServerProtocol.swift in Sources */,
|
BFECAC8B24FD950E0077C41F /* ServerProtocol.swift in Sources */,
|
||||||
BFECAC9624FD98BB0077C41F /* NSError+ALTServerError.m in Sources */,
|
BFECAC9624FD98BB0077C41F /* NSError+ALTServerError.m in Sources */,
|
||||||
BF10EB34248730750055E6DB /* main.swift in Sources */,
|
BF10EB34248730750055E6DB /* main.swift in Sources */,
|
||||||
BFFCFA582488648D0077BFCE /* LocalConnectionHandler.swift in Sources */,
|
|
||||||
BF8CAE462489E772004D6CCE /* AppManager.swift in Sources */,
|
BF8CAE462489E772004D6CCE /* AppManager.swift in Sources */,
|
||||||
BFECAC9024FD950E0077C41F /* Bundle+AltStore.swift in Sources */,
|
BFECAC9024FD950E0077C41F /* Bundle+AltStore.swift in Sources */,
|
||||||
);
|
);
|
||||||
@@ -2271,6 +2279,7 @@
|
|||||||
BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */,
|
BFAECC532501B0A400528F27 /* ServerProtocol.swift in Sources */,
|
||||||
BFAECC572501B0A400528F27 /* ConnectionManager.swift in Sources */,
|
BFAECC572501B0A400528F27 /* ConnectionManager.swift in Sources */,
|
||||||
BF66EE9D2501AEC1007EE018 /* AppProtocol.swift in Sources */,
|
BF66EE9D2501AEC1007EE018 /* AppProtocol.swift in Sources */,
|
||||||
|
BFC712C42512D5F100AB5EBE /* XPCConnection.swift in Sources */,
|
||||||
BF66EE8C2501AEB2007EE018 /* Keychain.swift in Sources */,
|
BF66EE8C2501AEB2007EE018 /* Keychain.swift in Sources */,
|
||||||
BF66EED42501AECA007EE018 /* AltStore5ToAltStore6.xcmappingmodel in Sources */,
|
BF66EED42501AECA007EE018 /* AltStore5ToAltStore6.xcmappingmodel in Sources */,
|
||||||
BF66EE972501AEBC007EE018 /* ALTAppPermission.m in Sources */,
|
BF66EE972501AEBC007EE018 /* ALTAppPermission.m in Sources */,
|
||||||
@@ -2303,6 +2312,7 @@
|
|||||||
BF66EECC2501AECA007EE018 /* Source.swift in Sources */,
|
BF66EECC2501AECA007EE018 /* Source.swift in Sources */,
|
||||||
BF66EED72501AECA007EE018 /* InstalledApp.swift in Sources */,
|
BF66EED72501AECA007EE018 /* InstalledApp.swift in Sources */,
|
||||||
BF66EECE2501AECA007EE018 /* InstalledAppPolicy.swift in Sources */,
|
BF66EECE2501AECA007EE018 /* InstalledAppPolicy.swift in Sources */,
|
||||||
|
BF1FE359251A9FB000C3CE09 /* NSXPCConnection+MachServices.swift in Sources */,
|
||||||
BF66EEA62501AEC5007EE018 /* PatreonAPI.swift in Sources */,
|
BF66EEA62501AEC5007EE018 /* PatreonAPI.swift in Sources */,
|
||||||
BF66EED02501AECA007EE018 /* AltStore6ToAltStore7.xcmappingmodel in Sources */,
|
BF66EED02501AECA007EE018 /* AltStore6ToAltStore7.xcmappingmodel in Sources */,
|
||||||
BF66EEDC2501AECA007EE018 /* MergePolicy.swift in Sources */,
|
BF66EEDC2501AECA007EE018 /* MergePolicy.swift in Sources */,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import AltStoreCore
|
||||||
import Roxas
|
import Roxas
|
||||||
|
|
||||||
private let ReceivedServerConnectionResponse: @convention(c) (CFNotificationCenter?, UnsafeMutableRawPointer?, CFNotificationName?, UnsafeRawPointer?, CFDictionary?) -> Void =
|
private let ReceivedServerConnectionResponse: @convention(c) (CFNotificationCenter?, UnsafeMutableRawPointer?, CFNotificationName?, UnsafeRawPointer?, CFDictionary?) -> Void =
|
||||||
@@ -52,11 +53,11 @@ class FindServerOperation: ResultOperation<Server>
|
|||||||
|
|
||||||
// Prepare observers to receive callback from wired connection or background daemon (if available).
|
// Prepare observers to receive callback from wired connection or background daemon (if available).
|
||||||
CFNotificationCenterAddObserver(notificationCenter, observer, ReceivedServerConnectionResponse, CFNotificationName.wiredServerConnectionAvailableResponse.rawValue, nil, .deliverImmediately)
|
CFNotificationCenterAddObserver(notificationCenter, observer, ReceivedServerConnectionResponse, CFNotificationName.wiredServerConnectionAvailableResponse.rawValue, nil, .deliverImmediately)
|
||||||
CFNotificationCenterAddObserver(notificationCenter, observer, ReceivedServerConnectionResponse, CFNotificationName.localServerConnectionAvailableResponse.rawValue, nil, .deliverImmediately)
|
|
||||||
|
|
||||||
// Post notifications.
|
// Post notifications.
|
||||||
CFNotificationCenterPostNotification(notificationCenter, .wiredServerConnectionAvailableRequest, nil, nil, true)
|
CFNotificationCenterPostNotification(notificationCenter, .wiredServerConnectionAvailableRequest, nil, nil, true)
|
||||||
CFNotificationCenterPostNotification(notificationCenter, .localServerConnectionAvailableRequest, nil, nil, true)
|
|
||||||
|
self.discoverLocalServer()
|
||||||
|
|
||||||
// Wait for either callback or timeout.
|
// Wait for either callback or timeout.
|
||||||
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
|
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
|
||||||
@@ -97,18 +98,28 @@ class FindServerOperation: ResultOperation<Server>
|
|||||||
let observer = Unmanaged.passUnretained(self).toOpaque()
|
let observer = Unmanaged.passUnretained(self).toOpaque()
|
||||||
|
|
||||||
CFNotificationCenterRemoveObserver(notificationCenter, observer, .wiredServerConnectionAvailableResponse, nil)
|
CFNotificationCenterRemoveObserver(notificationCenter, observer, .wiredServerConnectionAvailableResponse, nil)
|
||||||
CFNotificationCenterRemoveObserver(notificationCenter, observer, .localServerConnectionAvailableResponse, nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate extension FindServerOperation
|
fileprivate extension FindServerOperation
|
||||||
{
|
{
|
||||||
|
func discoverLocalServer()
|
||||||
|
{
|
||||||
|
let connection = XPCConnection()
|
||||||
|
connection.connect { (result) in
|
||||||
|
switch result
|
||||||
|
{
|
||||||
|
case .failure(let error): print("Could not connect to AltDaemon XPC service.", error)
|
||||||
|
case .success: self.isLocalServerConnectionAvailable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handle(_ notification: CFNotificationName)
|
func handle(_ notification: CFNotificationName)
|
||||||
{
|
{
|
||||||
switch notification
|
switch notification
|
||||||
{
|
{
|
||||||
case .wiredServerConnectionAvailableResponse: self.isWiredServerConnectionAvailable = true
|
case .wiredServerConnectionAvailableResponse: self.isWiredServerConnectionAvailable = true
|
||||||
case .localServerConnectionAvailableResponse: self.isLocalServerConnectionAvailable = true
|
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ import AltStoreCore
|
|||||||
class ServerConnection
|
class ServerConnection
|
||||||
{
|
{
|
||||||
var server: Server
|
var server: Server
|
||||||
var connection: NWConnection
|
var connection: Connection
|
||||||
|
|
||||||
init(server: Server, connection: NWConnection)
|
init(server: Server, connection: Connection)
|
||||||
{
|
{
|
||||||
self.server = server
|
self.server = server
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
@@ -37,17 +37,15 @@ class ServerConnection
|
|||||||
data = try JSONEncoder().encode(payload)
|
data = try JSONEncoder().encode(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
func process(_ error: Error?) -> Bool
|
func process<T>(_ result: Result<T, ALTServerError>) -> Bool
|
||||||
{
|
{
|
||||||
if error != nil
|
switch result
|
||||||
{
|
{
|
||||||
completionHandler(.failure(ConnectionError.connectionDropped))
|
case .success: return true
|
||||||
|
case .failure(let error):
|
||||||
|
completionHandler(.failure(error))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if prependSize
|
if prependSize
|
||||||
@@ -55,22 +53,21 @@ class ServerConnection
|
|||||||
let requestSize = Int32(data.count)
|
let requestSize = Int32(data.count)
|
||||||
let requestSizeData = withUnsafeBytes(of: requestSize) { Data($0) }
|
let requestSizeData = withUnsafeBytes(of: requestSize) { Data($0) }
|
||||||
|
|
||||||
self.connection.send(content: requestSizeData, completion: .contentProcessed { (error) in
|
self.connection.send(requestSizeData) { (result) in
|
||||||
guard process(error) else { return }
|
guard process(result) else { return }
|
||||||
|
|
||||||
self.connection.send(content: data, completion: .contentProcessed { (error) in
|
self.connection.send(data) { (result) in
|
||||||
guard process(error) else { return }
|
guard process(result) else { return }
|
||||||
completionHandler(.success(()))
|
completionHandler(.success(()))
|
||||||
})
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connection.send(content: data, completion: .contentProcessed { (error) in
|
self.connection.send(data) { (result) in
|
||||||
guard process(error) else { return }
|
guard process(result) else { return }
|
||||||
completionHandler(.success(()))
|
completionHandler(.success(()))
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -84,16 +81,16 @@ class ServerConnection
|
|||||||
{
|
{
|
||||||
let size = MemoryLayout<Int32>.size
|
let size = MemoryLayout<Int32>.size
|
||||||
|
|
||||||
self.connection.receive(minimumIncompleteLength: size, maximumLength: size) { (data, _, _, error) in
|
self.connection.receiveData(expectedSize: size) { (result) in
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
let data = try self.process(data: data, error: error)
|
let data = try result.get()
|
||||||
|
|
||||||
let expectedBytes = Int(data.withUnsafeBytes { $0.load(as: Int32.self) })
|
let expectedBytes = Int(data.withUnsafeBytes { $0.load(as: Int32.self) })
|
||||||
self.connection.receive(minimumIncompleteLength: expectedBytes, maximumLength: expectedBytes) { (data, _, _, error) in
|
self.connection.receiveData(expectedSize: expectedBytes) { (result) in
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
let data = try self.process(data: data, error: error)
|
let data = try result.get()
|
||||||
|
|
||||||
let response = try AltStoreCore.JSONDecoder().decode(ServerResponse.self, from: data)
|
let response = try AltStoreCore.JSONDecoder().decode(ServerResponse.self, from: data)
|
||||||
completionHandler(.success(response))
|
completionHandler(.success(response))
|
||||||
@@ -111,36 +108,3 @@ class ServerConnection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension ServerConnection
|
|
||||||
{
|
|
||||||
func process(data: Data?, error: NWError?) throws -> Data
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
guard let data = data else { throw error ?? ALTServerError(.unknown) }
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
catch let error as NWError
|
|
||||||
{
|
|
||||||
print("Error receiving data from connection \(connection)", error)
|
|
||||||
|
|
||||||
throw ALTServerError(.lostConnection)
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch let error as ALTServerError
|
|
||||||
{
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
preconditionFailure("A non-ALTServerError should never be thrown from this method.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -63,39 +63,23 @@ extension ServerManager
|
|||||||
func connect(to server: Server, completion: @escaping (Result<ServerConnection, Error>) -> Void)
|
func connect(to server: Server, completion: @escaping (Result<ServerConnection, Error>) -> Void)
|
||||||
{
|
{
|
||||||
DispatchQueue.global().async {
|
DispatchQueue.global().async {
|
||||||
func finish(_ result: Result<ServerConnection, Error>)
|
func finish(_ result: Result<Connection, Error>)
|
||||||
{
|
{
|
||||||
completion(result)
|
switch result
|
||||||
}
|
{
|
||||||
|
case .failure(let error): completion(.failure(error))
|
||||||
func start(_ connection: NWConnection)
|
case .success(let connection):
|
||||||
{
|
let serverConnection = ServerConnection(server: server, connection: connection)
|
||||||
connection.stateUpdateHandler = { [unowned connection] (state) in
|
completion(.success(serverConnection))
|
||||||
switch state
|
|
||||||
{
|
|
||||||
case .failed(let error):
|
|
||||||
print("Failed to connect to service \(server.service?.name ?? "").", error)
|
|
||||||
finish(.failure(ConnectionError.connectionFailed))
|
|
||||||
|
|
||||||
case .cancelled:
|
|
||||||
finish(.failure(OperationError.cancelled))
|
|
||||||
|
|
||||||
case .ready:
|
|
||||||
let connection = ServerConnection(server: server, connection: connection)
|
|
||||||
finish(.success(connection))
|
|
||||||
|
|
||||||
case .waiting: break
|
|
||||||
case .setup: break
|
|
||||||
case .preparing: break
|
|
||||||
@unknown default: break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.start(queue: self.dispatchQueue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let incomingConnectionsSemaphore = self.incomingConnectionsSemaphore, server.connectionType != .wireless
|
switch server.connectionType
|
||||||
{
|
{
|
||||||
|
case .local: self.connectToLocalServer(completion: finish(_:))
|
||||||
|
case .wired:
|
||||||
|
guard let incomingConnectionsSemaphore = self.incomingConnectionsSemaphore else { return finish(.failure(ALTServerError(.connectionFailed))) }
|
||||||
|
|
||||||
print("Waiting for incoming connection...")
|
print("Waiting for incoming connection...")
|
||||||
|
|
||||||
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
|
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
|
||||||
@@ -103,39 +87,27 @@ extension ServerManager
|
|||||||
switch server.connectionType
|
switch server.connectionType
|
||||||
{
|
{
|
||||||
case .wired: CFNotificationCenterPostNotification(notificationCenter, .wiredServerConnectionStartRequest, nil, nil, true)
|
case .wired: CFNotificationCenterPostNotification(notificationCenter, .wiredServerConnectionStartRequest, nil, nil, true)
|
||||||
case .local: CFNotificationCenterPostNotification(notificationCenter, .localServerConnectionStartRequest, nil, nil, true)
|
case .local, .wireless: break
|
||||||
case .wireless: break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = incomingConnectionsSemaphore.wait(timeout: .now() + 10.0)
|
_ = incomingConnectionsSemaphore.wait(timeout: .now() + 10.0)
|
||||||
|
|
||||||
if let connection = self.incomingConnections?.popLast()
|
if let connection = self.incomingConnections?.popLast()
|
||||||
{
|
{
|
||||||
start(connection)
|
self.connectToRemoteServer(server, connection: connection, completion: finish(_:))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
finish(.failure(ALTServerError(.connectionFailed)))
|
finish(.failure(ALTServerError(.connectionFailed)))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if let service = server.service
|
case .wireless:
|
||||||
{
|
guard let service = server.service else { return finish(.failure(ALTServerError(.connectionFailed))) }
|
||||||
|
|
||||||
print("Connecting to service:", service)
|
print("Connecting to service:", service)
|
||||||
|
|
||||||
let parameters = NWParameters.tcp
|
let connection = NWConnection(to: .service(name: service.name, type: service.type, domain: service.domain, interface: nil), using: .tcp)
|
||||||
|
self.connectToRemoteServer(server, connection: connection, completion: finish(_:))
|
||||||
if server.connectionType == .local
|
|
||||||
{
|
|
||||||
// Prevent AltStore from initiating connections over multiple interfaces simultaneously 🤷♂️
|
|
||||||
parameters.requiredInterfaceType = .loopback
|
|
||||||
}
|
|
||||||
|
|
||||||
let connection = NWConnection(to: .service(name: service.name, type: service.type, domain: service.domain, interface: nil), using: parameters)
|
|
||||||
start(connection)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
finish(.failure(ALTServerError(.connectionFailed)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,6 +163,47 @@ private extension ServerManager
|
|||||||
self.incomingConnections = nil
|
self.incomingConnections = nil
|
||||||
self.incomingConnectionsSemaphore = nil
|
self.incomingConnectionsSemaphore = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func connectToRemoteServer(_ server: Server, connection: NWConnection, completion: @escaping (Result<Connection, Error>) -> Void)
|
||||||
|
{
|
||||||
|
connection.stateUpdateHandler = { [unowned connection] (state) in
|
||||||
|
switch state
|
||||||
|
{
|
||||||
|
case .failed(let error):
|
||||||
|
print("Failed to connect to service \(server.service?.name ?? "").", error)
|
||||||
|
completion(.failure(ConnectionError.connectionFailed))
|
||||||
|
|
||||||
|
case .cancelled:
|
||||||
|
completion(.failure(OperationError.cancelled))
|
||||||
|
|
||||||
|
case .ready:
|
||||||
|
let connection = NetworkConnection(connection)
|
||||||
|
completion(.success(connection))
|
||||||
|
|
||||||
|
case .waiting: break
|
||||||
|
case .setup: break
|
||||||
|
case .preparing: break
|
||||||
|
@unknown default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.start(queue: self.dispatchQueue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func connectToLocalServer(completion: @escaping (Result<Connection, Error>) -> Void)
|
||||||
|
{
|
||||||
|
let connection = XPCConnection()
|
||||||
|
connection.connect { (result) in
|
||||||
|
switch result
|
||||||
|
{
|
||||||
|
case .failure(let error):
|
||||||
|
print("Could not connect to AltDaemon XPC service.", error)
|
||||||
|
completion(.failure(error))
|
||||||
|
|
||||||
|
case .success: completion(.success(connection))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ServerManager: NetServiceBrowserDelegate
|
extension ServerManager: NetServiceBrowserDelegate
|
||||||
|
|||||||
2
Dependencies/AltSign
vendored
2
Dependencies/AltSign
vendored
Submodule Dependencies/AltSign updated: 508abc4cdf...229e7d5751
@@ -14,8 +14,4 @@ extern CFNotificationName const ALTWiredServerConnectionAvailableRequest NS_SWIF
|
|||||||
extern CFNotificationName const ALTWiredServerConnectionAvailableResponse NS_SWIFT_NAME(wiredServerConnectionAvailableResponse);
|
extern CFNotificationName const ALTWiredServerConnectionAvailableResponse NS_SWIFT_NAME(wiredServerConnectionAvailableResponse);
|
||||||
extern CFNotificationName const ALTWiredServerConnectionStartRequest NS_SWIFT_NAME(wiredServerConnectionStartRequest);
|
extern CFNotificationName const ALTWiredServerConnectionStartRequest NS_SWIFT_NAME(wiredServerConnectionStartRequest);
|
||||||
|
|
||||||
extern CFNotificationName const ALTLocalServerConnectionAvailableRequest NS_SWIFT_NAME(localServerConnectionAvailableRequest);
|
|
||||||
extern CFNotificationName const ALTLocalServerConnectionAvailableResponse NS_SWIFT_NAME(localServerConnectionAvailableResponse);
|
|
||||||
extern CFNotificationName const ALTLocalServerConnectionStartRequest NS_SWIFT_NAME(localServerConnectionStartRequest);
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -11,7 +11,3 @@
|
|||||||
CFNotificationName const ALTWiredServerConnectionAvailableRequest = CFSTR("io.altstore.Request.WiredServerConnectionAvailable");
|
CFNotificationName const ALTWiredServerConnectionAvailableRequest = CFSTR("io.altstore.Request.WiredServerConnectionAvailable");
|
||||||
CFNotificationName const ALTWiredServerConnectionAvailableResponse = CFSTR("io.altstore.Response.WiredServerConnectionAvailable");
|
CFNotificationName const ALTWiredServerConnectionAvailableResponse = CFSTR("io.altstore.Response.WiredServerConnectionAvailable");
|
||||||
CFNotificationName const ALTWiredServerConnectionStartRequest = CFSTR("io.altstore.Request.WiredServerConnectionStart");
|
CFNotificationName const ALTWiredServerConnectionStartRequest = CFSTR("io.altstore.Request.WiredServerConnectionStart");
|
||||||
|
|
||||||
CFNotificationName const ALTLocalServerConnectionAvailableRequest = CFSTR("io.altstore.Request.LocalServerConnectionAvailable");
|
|
||||||
CFNotificationName const ALTLocalServerConnectionAvailableResponse = CFSTR("io.altstore.Response.LocalServerConnectionAvailable");
|
|
||||||
CFNotificationName const ALTLocalServerConnectionStartRequest = CFSTR("io.altstore.Request.LocalServerConnectionStart");
|
|
||||||
|
|||||||
150
Shared/Connections/XPCConnection.swift
Normal file
150
Shared/Connections/XPCConnection.swift
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
//
|
||||||
|
// XPCConnection.swift
|
||||||
|
// AltKit
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 6/15/20.
|
||||||
|
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc private protocol XPCConnectionProxy
|
||||||
|
{
|
||||||
|
func ping(completionHandler: @escaping () -> Void)
|
||||||
|
func receive(_ data: Data, completionHandler: @escaping (Bool, Error?) -> Void)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension XPCConnection
|
||||||
|
{
|
||||||
|
public static let machServiceName = "cy:io.altstore.altdaemon"
|
||||||
|
}
|
||||||
|
|
||||||
|
public class XPCConnection: NSObject, Connection
|
||||||
|
{
|
||||||
|
public let xpcConnection: NSXPCConnection
|
||||||
|
|
||||||
|
private let queue = DispatchQueue(label: "io.altstore.XPCConnection")
|
||||||
|
private let dispatchGroup = DispatchGroup()
|
||||||
|
private var semaphore: DispatchSemaphore?
|
||||||
|
private var buffer = Data(capacity: 1024)
|
||||||
|
|
||||||
|
private var error: Error?
|
||||||
|
|
||||||
|
public init(_ xpcConnection: NSXPCConnection = .makeConnection(machServiceName: XPCConnection.machServiceName))
|
||||||
|
{
|
||||||
|
let proxyInterface = NSXPCInterface(with: XPCConnectionProxy.self)
|
||||||
|
xpcConnection.remoteObjectInterface = proxyInterface
|
||||||
|
xpcConnection.exportedInterface = proxyInterface
|
||||||
|
|
||||||
|
self.xpcConnection = xpcConnection
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
xpcConnection.interruptionHandler = {
|
||||||
|
self.error = ALTServerError(.lostConnection)
|
||||||
|
}
|
||||||
|
|
||||||
|
xpcConnection.exportedObject = self
|
||||||
|
xpcConnection.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit
|
||||||
|
{
|
||||||
|
self.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension XPCConnection
|
||||||
|
{
|
||||||
|
func makeProxy(errorHandler: @escaping (Error) -> Void) -> XPCConnectionProxy
|
||||||
|
{
|
||||||
|
let proxy = self.xpcConnection.remoteObjectProxyWithErrorHandler { (error) in
|
||||||
|
print("Error messaging remote object proxy:", error)
|
||||||
|
self.error = error
|
||||||
|
errorHandler(error)
|
||||||
|
} as! XPCConnectionProxy
|
||||||
|
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension XPCConnection
|
||||||
|
{
|
||||||
|
func connect(completionHandler: @escaping (Result<Void, Error>) -> Void)
|
||||||
|
{
|
||||||
|
let proxy = self.makeProxy { (error) in
|
||||||
|
completionHandler(.failure(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.ping {
|
||||||
|
completionHandler(.success(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func disconnect()
|
||||||
|
{
|
||||||
|
self.xpcConnection.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func __send(_ data: Data, completionHandler: @escaping (Bool, Error?) -> Void)
|
||||||
|
{
|
||||||
|
guard self.error == nil else { return completionHandler(false, self.error) }
|
||||||
|
|
||||||
|
let proxy = self.makeProxy { (error) in
|
||||||
|
completionHandler(false, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy.receive(data) { (success, error) in
|
||||||
|
completionHandler(success, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func __receiveData(expectedSize: Int, completionHandler: @escaping (Data?, Error?) -> Void)
|
||||||
|
{
|
||||||
|
guard self.error == nil else { return completionHandler(nil, self.error) }
|
||||||
|
|
||||||
|
self.queue.async {
|
||||||
|
let copiedBuffer = self.buffer // Copy buffer to prevent runtime crashes.
|
||||||
|
guard copiedBuffer.count >= expectedSize else {
|
||||||
|
self.semaphore = DispatchSemaphore(value: 0)
|
||||||
|
DispatchQueue.global().async {
|
||||||
|
_ = self.semaphore?.wait(timeout: .now() + 1.0)
|
||||||
|
self.__receiveData(expectedSize: expectedSize, completionHandler: completionHandler)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = copiedBuffer.prefix(expectedSize)
|
||||||
|
self.buffer = copiedBuffer.dropFirst(expectedSize)
|
||||||
|
|
||||||
|
completionHandler(data, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension XPCConnection
|
||||||
|
{
|
||||||
|
override public var description: String {
|
||||||
|
return "\(self.xpcConnection.endpoint) (XPC)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension XPCConnection: XPCConnectionProxy
|
||||||
|
{
|
||||||
|
fileprivate func ping(completionHandler: @escaping () -> Void)
|
||||||
|
{
|
||||||
|
completionHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func receive(_ data: Data, completionHandler: @escaping (Bool, Error?) -> Void)
|
||||||
|
{
|
||||||
|
self.queue.async {
|
||||||
|
self.buffer.append(data)
|
||||||
|
|
||||||
|
self.semaphore?.signal()
|
||||||
|
self.semaphore = nil
|
||||||
|
|
||||||
|
completionHandler(true, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Shared/Extensions/NSXPCConnection+MachServices.swift
Normal file
33
Shared/Extensions/NSXPCConnection+MachServices.swift
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// NSXPCConnection+MachServices.swift
|
||||||
|
// AltStore
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 9/22/20.
|
||||||
|
// Copyright © 2020 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objc private protocol XPCPrivateAPI
|
||||||
|
{
|
||||||
|
init(machServiceName: String)
|
||||||
|
init(machServiceName: String, options: NSXPCConnection.Options)
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension NSXPCConnection
|
||||||
|
{
|
||||||
|
class func makeConnection(machServiceName: String) -> NSXPCConnection
|
||||||
|
{
|
||||||
|
let connection = unsafeBitCast(self, to: XPCPrivateAPI.Type.self).init(machServiceName: machServiceName, options: .privileged)
|
||||||
|
return unsafeBitCast(connection, to: NSXPCConnection.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension NSXPCListener
|
||||||
|
{
|
||||||
|
class func makeListener(machServiceName: String) -> NSXPCListener
|
||||||
|
{
|
||||||
|
let listener = unsafeBitCast(self, to: XPCPrivateAPI.Type.self).init(machServiceName: machServiceName)
|
||||||
|
return unsafeBitCast(listener, to: NSXPCListener.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user