mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-20 12:13:26 +01:00
[AltServer] Fixes installing more than 3 apps on 13.3 and below
This commit is contained in:
@@ -445,12 +445,10 @@ private extension ConnectionManager
|
|||||||
|
|
||||||
func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: ClientConnection)
|
func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: ClientConnection)
|
||||||
{
|
{
|
||||||
let removeInactiveProfiles = (request.activeProfiles != nil)
|
ALTDeviceManager.shared.installProvisioningProfiles(request.provisioningProfiles, toDeviceWithUDID: request.udid, activeProvisioningProfiles: request.activeProfiles) { (success, error) in
|
||||||
ALTDeviceManager.shared.installProvisioningProfiles(request.provisioningProfiles, toDeviceWithUDID: request.udid, activeProvisioningProfiles: request.activeProfiles, removeInactiveProvisioningProfiles: removeInactiveProfiles) { (errors) in
|
if let error = error, !success
|
||||||
|
|
||||||
if let error = errors.values.first
|
|
||||||
{
|
{
|
||||||
print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", errors)
|
print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", error)
|
||||||
|
|
||||||
let errorResponse = ErrorResponse(error: ALTServerError(error))
|
let errorResponse = ErrorResponse(error: ALTServerError(error))
|
||||||
connection.send(errorResponse, shouldDisconnect: true) { (result) in
|
connection.send(errorResponse, shouldDisconnect: true) { (result) in
|
||||||
@@ -471,10 +469,10 @@ private extension ConnectionManager
|
|||||||
|
|
||||||
func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: ClientConnection)
|
func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: ClientConnection)
|
||||||
{
|
{
|
||||||
ALTDeviceManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers, fromDeviceWithUDID: request.udid) { (errors) in
|
ALTDeviceManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers, fromDeviceWithUDID: request.udid) { (success, error) in
|
||||||
if let error = errors.values.first
|
if let error = error, !success
|
||||||
{
|
{
|
||||||
print("Failed to remove profiles \(request.bundleIdentifiers):", errors)
|
print("Failed to remove profiles \(request.bundleIdentifiers):", error)
|
||||||
|
|
||||||
let errorResponse = ErrorResponse(error: ALTServerError(error))
|
let errorResponse = ErrorResponse(error: ALTServerError(error))
|
||||||
connection.send(errorResponse, shouldDisconnect: true) { (result) in
|
connection.send(errorResponse, shouldDisconnect: true) { (result) in
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ extern NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification
|
|||||||
/* App Installation */
|
/* App Installation */
|
||||||
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
- (NSProgress *)installAppAtURL:(NSURL *)fileURL toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
||||||
|
|
||||||
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles removeInactiveProvisioningProfiles:(BOOL)removeInactiveProvisioningProfiles completionHandler:(void (^)(NSDictionary<ALTProvisioningProfile *, NSError *> *errors))completionHandler;
|
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
||||||
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(NSDictionary<NSString *, NSError *> *errors))completionHandler;
|
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *_Nullable error))completionHandler;
|
||||||
|
|
||||||
/* Connections */
|
/* Connections */
|
||||||
- (void)startWiredConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTWiredConnection *_Nullable connection, NSError *_Nullable error))completionHandler;
|
- (void)startWiredConnectionToDevice:(ALTDevice *)device completionHandler:(void (^)(ALTWiredConnection *_Nullable connection, NSError *_Nullable error))completionHandler;
|
||||||
|
|||||||
@@ -176,6 +176,20 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
|||||||
return finish([NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: fileURL}]);
|
return finish([NSError errorWithDomain:NSCocoaErrorDomain code:NSFileReadCorruptFileError userInfo:@{NSURLErrorKey: fileURL}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL];
|
||||||
|
if (application.provisioningProfile)
|
||||||
|
{
|
||||||
|
[installedProfiles addObject:application.provisioningProfile];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ALTApplication *appExtension in application.appExtensions)
|
||||||
|
{
|
||||||
|
if (appExtension.provisioningProfile)
|
||||||
|
{
|
||||||
|
[installedProfiles addObject:appExtension.provisioningProfile];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find Device */
|
/* Find Device */
|
||||||
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -279,75 +293,38 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
|||||||
service = NULL;
|
service = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL];
|
BOOL shouldManageProfiles = (activeProvisioningProfiles != nil || [application.provisioningProfile isFreeProvisioningProfile]);
|
||||||
if (application.provisioningProfile)
|
if (shouldManageProfiles)
|
||||||
{
|
{
|
||||||
[installedProfiles addObject:application.provisioningProfile];
|
// Free developer account was used to sign this app, so we need to remove all
|
||||||
}
|
// provisioning profiles in order to remain under sideloaded app limit.
|
||||||
|
|
||||||
for (ALTApplication *appExtension in application.appExtensions)
|
|
||||||
{
|
|
||||||
if (appExtension.provisioningProfile)
|
|
||||||
{
|
|
||||||
[installedProfiles addObject:appExtension.provisioningProfile];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Provisioning Profiles */
|
|
||||||
if (activeProvisioningProfiles != nil)
|
|
||||||
{
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error];
|
NSDictionary<NSString *, ALTProvisioningProfile *> *removedProfiles = [self removeAllFreeProfilesExcludingBundleIdentifiers:nil misagent:mis error:&error];
|
||||||
if (provisioningProfiles == nil)
|
if (removedProfiles == nil)
|
||||||
{
|
{
|
||||||
return finish(error);
|
return finish(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
[removedProfiles enumerateKeysAndObjectsUsingBlock:^(NSString *bundleID, ALTProvisioningProfile *profile, BOOL * _Nonnull stop) {
|
||||||
|
if (activeProvisioningProfiles != nil)
|
||||||
{
|
{
|
||||||
if (![provisioningProfile isFreeProvisioningProfile])
|
if ([activeProvisioningProfiles containsObject:bundleID])
|
||||||
{
|
{
|
||||||
continue;
|
// Only cache active profiles to reinstall afterwards.
|
||||||
}
|
cachedProfiles[bundleID] = profile;
|
||||||
|
|
||||||
BOOL installingProfile = NO;
|
|
||||||
for (ALTProvisioningProfile *installedProfile in installedProfiles)
|
|
||||||
{
|
|
||||||
if ([installedProfile.bundleIdentifier isEqualToString:provisioningProfile.bundleIdentifier])
|
|
||||||
{
|
|
||||||
installingProfile = YES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([activeProvisioningProfiles containsObject:provisioningProfile.bundleIdentifier] && !installingProfile)
|
|
||||||
{
|
|
||||||
// We're not installing this provisioning profile, but it is active,
|
|
||||||
// so we'll cache it to install it again after installing this app.
|
|
||||||
|
|
||||||
ALTProvisioningProfile *preferredProfile = cachedProfiles[provisioningProfile.bundleIdentifier];
|
|
||||||
if (preferredProfile != nil)
|
|
||||||
{
|
|
||||||
if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending)
|
|
||||||
{
|
|
||||||
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
// Cache all profiles to reinstall afterwards if we didn't provide activeProvisioningProfiles.
|
||||||
}
|
cachedProfiles[bundleID] = profile;
|
||||||
}
|
|
||||||
|
|
||||||
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
|
|
||||||
{
|
|
||||||
return finish(error);
|
|
||||||
}
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
lockdownd_client_free(client);
|
lockdownd_client_free(client);
|
||||||
client = NULL;
|
client = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||||
|
|
||||||
@@ -514,7 +491,7 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
|||||||
|
|
||||||
#pragma mark - Provisioning Profiles -
|
#pragma mark - Provisioning Profiles -
|
||||||
|
|
||||||
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(NSSet<NSString *> *)activeProvisioningProfiles removeInactiveProvisioningProfiles:(BOOL)removeInactiveProvisioningProfiles completionHandler:(void (^)(NSDictionary<ALTProvisioningProfile *, NSError *> *errors))completionHandler;
|
- (void)installProvisioningProfiles:(NSSet<ALTProvisioningProfile *> *)provisioningProfiles toDeviceWithUDID:(NSString *)udid activeProvisioningProfiles:(nullable NSSet<NSString *> *)activeProvisioningProfiles completionHandler:(void (^)(BOOL success, NSError *error))completionHandler
|
||||||
{
|
{
|
||||||
dispatch_async(self.installationQueue, ^{
|
dispatch_async(self.installationQueue, ^{
|
||||||
__block idevice_t device = NULL;
|
__block idevice_t device = NULL;
|
||||||
@@ -523,109 +500,86 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
|||||||
__block misagent_client_t mis = NULL;
|
__block misagent_client_t mis = NULL;
|
||||||
__block lockdownd_service_descriptor_t service = NULL;
|
__block lockdownd_service_descriptor_t service = NULL;
|
||||||
|
|
||||||
void (^finish)(NSDictionary<ALTProvisioningProfile *, NSError *> *, NSError *) = ^(NSDictionary *installationErrors, NSError *error) {
|
void (^finish)(NSError *_Nullable) = ^(NSError *error) {
|
||||||
lockdownd_service_descriptor_free(service);
|
lockdownd_service_descriptor_free(service);
|
||||||
misagent_client_free(mis);
|
misagent_client_free(mis);
|
||||||
afc_client_free(afc);
|
afc_client_free(afc);
|
||||||
lockdownd_client_free(client);
|
lockdownd_client_free(client);
|
||||||
idevice_free(device);
|
idevice_free(device);
|
||||||
|
|
||||||
if (installationErrors)
|
completionHandler(error == nil, error);
|
||||||
{
|
|
||||||
completionHandler(installationErrors);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSMutableDictionary *installationErrors = [NSMutableDictionary dictionary];
|
|
||||||
for (ALTProvisioningProfile *profile in provisioningProfiles)
|
|
||||||
{
|
|
||||||
installationErrors[profile] = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
completionHandler(installationErrors);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Find Device */
|
/* Find Device */
|
||||||
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to Device */
|
/* Connect to Device */
|
||||||
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
|
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to Misagent */
|
/* Connect to Misagent */
|
||||||
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
|
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
|
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray<ALTProvisioningProfile *> *installedProvisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error];
|
|
||||||
if (provisioningProfiles == nil)
|
if (activeProvisioningProfiles != nil)
|
||||||
{
|
{
|
||||||
return finish(nil, error);
|
// Remove all non-active free provisioning profiles.
|
||||||
|
|
||||||
|
NSMutableSet *excludedBundleIdentifiers = [activeProvisioningProfiles mutableCopy];
|
||||||
|
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
||||||
|
{
|
||||||
|
// Ensure we DO remove old versions of profiles we're about to install, even if they are active.
|
||||||
|
[excludedBundleIdentifiers removeObject:provisioningProfile.bundleIdentifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALTProvisioningProfile *provisioningProfile in installedProvisioningProfiles)
|
if (![self removeAllFreeProfilesExcludingBundleIdentifiers:excludedBundleIdentifiers misagent:mis error:&error])
|
||||||
{
|
{
|
||||||
if (![provisioningProfile isFreeProvisioningProfile])
|
return finish(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
continue;
|
// Remove only older versions of provisioning profiles we're about to install.
|
||||||
|
|
||||||
|
NSMutableSet *bundleIdentifiers = [NSMutableSet set];
|
||||||
|
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
||||||
|
{
|
||||||
|
[bundleIdentifiers addObject:provisioningProfile.bundleIdentifier];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL removeProfile = NO;
|
if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error])
|
||||||
|
|
||||||
for (ALTProvisioningProfile *profile in provisioningProfiles)
|
|
||||||
{
|
{
|
||||||
if ([profile.bundleIdentifier isEqualToString:provisioningProfile.bundleIdentifier])
|
return finish(error);
|
||||||
{
|
|
||||||
// Remove previous provisioning profile before installing new one.
|
|
||||||
removeProfile = YES;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (removeInactiveProvisioningProfiles && ![activeProvisioningProfiles containsObject:provisioningProfile.bundleIdentifier])
|
|
||||||
{
|
|
||||||
// Remove all non-active provisioning profiles to remain under 3 app limit for free developer accounts.
|
|
||||||
removeProfile = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeProfile)
|
|
||||||
{
|
|
||||||
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
|
|
||||||
{
|
|
||||||
return finish(nil, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NSMutableDictionary<ALTProvisioningProfile *, NSError *> *profileErrors = [NSMutableDictionary dictionary];
|
|
||||||
|
|
||||||
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
||||||
{
|
{
|
||||||
NSError *error = nil;
|
|
||||||
if (![self installProvisioningProfile:provisioningProfile misagent:mis error:&error])
|
if (![self installProvisioningProfile:provisioningProfile misagent:mis error:&error])
|
||||||
{
|
{
|
||||||
profileErrors[provisioningProfile] = error;
|
return finish(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish(profileErrors, nil);
|
finish(nil);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(NSDictionary<NSString *, NSError *> *errors))completionHandler
|
- (void)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers fromDeviceWithUDID:(NSString *)udid completionHandler:(void (^)(BOOL success, NSError *error))completionHandler
|
||||||
{
|
{
|
||||||
dispatch_async(self.installationQueue, ^{
|
dispatch_async(self.installationQueue, ^{
|
||||||
__block idevice_t device = NULL;
|
__block idevice_t device = NULL;
|
||||||
@@ -634,77 +588,110 @@ NSNotificationName const ALTDeviceManagerDeviceDidDisconnectNotification = @"ALT
|
|||||||
__block misagent_client_t mis = NULL;
|
__block misagent_client_t mis = NULL;
|
||||||
__block lockdownd_service_descriptor_t service = NULL;
|
__block lockdownd_service_descriptor_t service = NULL;
|
||||||
|
|
||||||
void (^finish)(NSDictionary<NSString *, NSError *> *, NSError *) = ^(NSDictionary *installationErrors, NSError *error) {
|
void (^finish)(NSError *_Nullable) = ^(NSError *error) {
|
||||||
lockdownd_service_descriptor_free(service);
|
lockdownd_service_descriptor_free(service);
|
||||||
misagent_client_free(mis);
|
misagent_client_free(mis);
|
||||||
afc_client_free(afc);
|
afc_client_free(afc);
|
||||||
lockdownd_client_free(client);
|
lockdownd_client_free(client);
|
||||||
idevice_free(device);
|
idevice_free(device);
|
||||||
|
|
||||||
if (installationErrors)
|
completionHandler(error == nil, error);
|
||||||
{
|
|
||||||
completionHandler(installationErrors);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSMutableDictionary *installationErrors = [NSMutableDictionary dictionary];
|
|
||||||
for (NSString *bundleID in bundleIdentifiers)
|
|
||||||
{
|
|
||||||
installationErrors[bundleID] = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
completionHandler(installationErrors);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Find Device */
|
/* Find Device */
|
||||||
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
if (idevice_new(&device, udid.UTF8String) != IDEVICE_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorDeviceNotFound userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to Device */
|
/* Connect to Device */
|
||||||
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
|
if (lockdownd_client_new_with_handshake(device, &client, "altserver") != LOCKDOWN_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to Misagent */
|
/* Connect to Misagent */
|
||||||
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
|
if (lockdownd_start_service(client, "com.apple.misagent", &service) != LOCKDOWN_E_SUCCESS || service == NULL)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
|
if (misagent_client_new(device, service, &mis) != MISAGENT_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:&error];
|
if (![self removeProvisioningProfilesForBundleIdentifiers:bundleIdentifiers misagent:mis error:&error])
|
||||||
if (provisioningProfiles == nil)
|
|
||||||
{
|
{
|
||||||
return finish(nil, error);
|
return finish(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableDictionary<NSString *, NSError *> *profileErrors = [NSMutableDictionary dictionary];
|
finish(nil);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeProvisioningProfilesForBundleIdentifiers:(NSSet<NSString *> *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error
|
||||||
|
{
|
||||||
|
return [self removeAllProfilesForBundleIdentifiers:bundleIdentifiers excludingBundleIdentifiers:nil limitedToFreeProfiles:NO misagent:mis error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeAllFreeProfilesExcludingBundleIdentifiers:(nullable NSSet<NSString *> *)bundleIdentifiers misagent:(misagent_client_t)mis error:(NSError **)error
|
||||||
|
{
|
||||||
|
return [self removeAllProfilesForBundleIdentifiers:nil excludingBundleIdentifiers:bundleIdentifiers limitedToFreeProfiles:YES misagent:mis error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary<NSString *, ALTProvisioningProfile *> *)removeAllProfilesForBundleIdentifiers:(nullable NSSet<NSString *> *)includedBundleIdentifiers
|
||||||
|
excludingBundleIdentifiers:(nullable NSSet<NSString *> *)excludedBundleIdentifiers
|
||||||
|
limitedToFreeProfiles:(BOOL)limitedToFreeProfiles
|
||||||
|
misagent:(misagent_client_t)mis
|
||||||
|
error:(NSError **)error
|
||||||
|
{
|
||||||
|
NSMutableDictionary<NSString *, ALTProvisioningProfile *> *cachedProfiles = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
|
NSArray<ALTProvisioningProfile *> *provisioningProfiles = [self copyProvisioningProfilesWithClient:mis error:error];
|
||||||
|
if (provisioningProfiles == nil)
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove provisioning profiles */
|
|
||||||
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
for (ALTProvisioningProfile *provisioningProfile in provisioningProfiles)
|
||||||
{
|
{
|
||||||
if (![bundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
|
if (limitedToFreeProfiles && ![provisioningProfile isFreeProvisioningProfile])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:&error])
|
if (includedBundleIdentifiers != nil && ![includedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
|
||||||
{
|
{
|
||||||
profileErrors[provisioningProfile.bundleIdentifier] = error;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludedBundleIdentifiers != nil && [excludedBundleIdentifiers containsObject:provisioningProfile.bundleIdentifier])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALTProvisioningProfile *preferredProfile = cachedProfiles[provisioningProfile.bundleIdentifier];
|
||||||
|
if (preferredProfile != nil)
|
||||||
|
{
|
||||||
|
if ([provisioningProfile.expirationDate compare:preferredProfile.expirationDate] == NSOrderedDescending)
|
||||||
|
{
|
||||||
|
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cachedProfiles[provisioningProfile.bundleIdentifier] = provisioningProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (![self removeProvisioningProfile:provisioningProfile misagent:mis error:error])
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish(profileErrors, nil);
|
return cachedProfiles;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)installProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error
|
- (BOOL)installProvisioningProfile:(ALTProvisioningProfile *)provisioningProfile misagent:(misagent_client_t)mis error:(NSError **)error
|
||||||
|
|||||||
Reference in New Issue
Block a user