[AltServer] Adds ALTServerConnectionError to wrap libimobiledevice errors

This commit is contained in:
Riley Testut
2021-05-20 11:46:38 -07:00
parent bc2dae1b21
commit c97acfc76c
6 changed files with 242 additions and 2 deletions

View File

@@ -0,0 +1,25 @@
//
// NSError+libimobiledevice.h
// AltServer
//
// Created by Riley Testut on 3/23/21.
// Copyright © 2021 Riley Testut. All rights reserved.
//
#import <libimobiledevice/mobile_image_mounter.h>
#import <libimobiledevice/debugserver.h>
#import <libimobiledevice/installation_proxy.h>
#import <AltSign/ALTDevice.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSError (libimobiledevice)
+ (nullable instancetype)errorWithMobileImageMounterError:(mobile_image_mounter_error_t)error device:(nullable ALTDevice *)device;
+ (nullable instancetype)errorWithDebugServerError:(debugserver_error_t)error device:(nullable ALTDevice *)device;
+ (nullable instancetype)errorWithInstallationProxyError:(instproxy_error_t)error device:(nullable ALTDevice *)device;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,86 @@
//
// NSError+libimobiledevice.m
// AltServer
//
// Created by Riley Testut on 3/23/21.
// Copyright © 2021 Riley Testut. All rights reserved.
//
#import "NSError+libimobiledevice.h"
#import "NSError+ALTServerError.h"
@implementation NSError (libimobiledevice)
+ (nullable instancetype)errorWithMobileImageMounterError:(mobile_image_mounter_error_t)error device:(nullable ALTDevice *)device
{
NSMutableDictionary *userInfo = [@{
ALTUnderlyingErrorDomainErrorKey: @"Mobile Image Mounter",
ALTUnderlyingErrorCodeErrorKey: [@(error) description],
} mutableCopy];
if (device)
{
userInfo[ALTDeviceNameErrorKey] = device.name;
}
switch (error)
{
case MOBILE_IMAGE_MOUNTER_E_SUCCESS: return nil;
case MOBILE_IMAGE_MOUNTER_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo];
case MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo];
case MOBILE_IMAGE_MOUNTER_E_CONN_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo];
case MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo];
case MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorDeviceLocked userInfo:userInfo];
case MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo];
}
}
+ (nullable instancetype)errorWithDebugServerError:(debugserver_error_t)error device:(nullable ALTDevice *)device
{
NSMutableDictionary *userInfo = [@{
ALTUnderlyingErrorDomainErrorKey: @"Debug Server",
ALTUnderlyingErrorCodeErrorKey: [@(error) description],
} mutableCopy];
if (device)
{
userInfo[ALTDeviceNameErrorKey] = device.name;
}
switch (error)
{
case DEBUGSERVER_E_SUCCESS: return nil;
case DEBUGSERVER_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo];
case DEBUGSERVER_E_MUX_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo];
case DEBUGSERVER_E_SSL_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorSSL userInfo:userInfo];
case DEBUGSERVER_E_RESPONSE_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo];
case DEBUGSERVER_E_TIMEOUT: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorTimedOut userInfo:userInfo];
case DEBUGSERVER_E_UNKNOWN_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo];
}
}
+ (nullable instancetype)errorWithInstallationProxyError:(instproxy_error_t)error device:(nullable ALTDevice *)device
{
NSMutableDictionary *userInfo = [@{
ALTUnderlyingErrorDomainErrorKey: @"Installation Proxy",
ALTUnderlyingErrorCodeErrorKey: [@(error) description],
} mutableCopy];
if (device)
{
userInfo[ALTDeviceNameErrorKey] = device.name;
}
switch (error)
{
case INSTPROXY_E_SUCCESS: return nil;
case INSTPROXY_E_INVALID_ARG: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidRequest userInfo:userInfo];
case INSTPROXY_E_PLIST_ERROR: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorInvalidResponse userInfo:userInfo];
case INSTPROXY_E_CONN_FAILED: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUsbmuxd userInfo:userInfo];
case INSTPROXY_E_RECEIVE_TIMEOUT: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorTimedOut userInfo:userInfo];
// case INSTPROXY_E_DEVICE_OS_VERSION_TOO_LOW: return [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorUnsupportediOSVersion userInfo:nil]; // Error message assumes we're installing AltStore
default: return [NSError errorWithDomain:AltServerConnectionErrorDomain code:ALTServerConnectionErrorUnknown userInfo:userInfo];
}
}
@end

View File

@@ -304,6 +304,7 @@
BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */; }; BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */; };
BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE6325922A83BEB00F30809 /* Authentication.storyboard */; }; BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE6325922A83BEB00F30809 /* Authentication.storyboard */; };
BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */; }; BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */; };
BFE972E3260A8B2700D0BDAC /* NSError+libimobiledevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */; };
BFECAC7F24FD950B0077C41F /* CodableServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD44605241188C300EAB90A /* CodableServerError.swift */; }; BFECAC7F24FD950B0077C41F /* CodableServerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD44605241188C300EAB90A /* CodableServerError.swift */; };
BFECAC8024FD950B0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; }; BFECAC8024FD950B0077C41F /* ConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18BFF22485828200DD5981 /* ConnectionManager.swift */; };
BFECAC8124FD950B0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; }; BFECAC8124FD950B0077C41F /* ALTServerError+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF767CB2489AB5C0097E58C /* ALTServerError+Conveniences.swift */; };
@@ -761,6 +762,8 @@
BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = "<group>"; }; BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = "<group>"; };
BFE6325922A83BEB00F30809 /* Authentication.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Authentication.storyboard; sourceTree = "<group>"; }; BFE6325922A83BEB00F30809 /* Authentication.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Authentication.storyboard; sourceTree = "<group>"; };
BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationOperation.swift; sourceTree = "<group>"; }; BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationOperation.swift; sourceTree = "<group>"; };
BFE972E1260A8B2700D0BDAC /* NSError+libimobiledevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+libimobiledevice.h"; sourceTree = "<group>"; };
BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSError+libimobiledevice.mm"; sourceTree = "<group>"; };
BFF00D2F2501BD7D00746320 /* Intents.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = "<group>"; }; BFF00D2F2501BD7D00746320 /* Intents.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = "<group>"; };
BFF00D312501BDA100746320 /* BackgroundRefreshAppsOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundRefreshAppsOperation.swift; sourceTree = "<group>"; }; BFF00D312501BDA100746320 /* BackgroundRefreshAppsOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundRefreshAppsOperation.swift; sourceTree = "<group>"; };
BFF00D332501BDCF00746320 /* IntentHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = "<group>"; }; BFF00D332501BDCF00746320 /* IntentHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = "<group>"; };
@@ -965,6 +968,7 @@
BF703195229F36FF006E110F /* Devices */, BF703195229F36FF006E110F /* Devices */,
BFD52BDC22A0A659000B7ED1 /* Connections */, BFD52BDC22A0A659000B7ED1 /* Connections */,
BF055B4A233B528B0086DEA9 /* Extensions */, BF055B4A233B528B0086DEA9 /* Extensions */,
BFE972E0260A8B0700D0BDAC /* Categories */,
BF703194229F36F6006E110F /* Resources */, BF703194229F36F6006E110F /* Resources */,
BF703196229F370F006E110F /* Supporting Files */, BF703196229F370F006E110F /* Supporting Files */,
); );
@@ -1616,6 +1620,15 @@
path = Authentication; path = Authentication;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
BFE972E0260A8B0700D0BDAC /* Categories */ = {
isa = PBXGroup;
children = (
BFE972E1260A8B2700D0BDAC /* NSError+libimobiledevice.h */,
BFE972E2260A8B2700D0BDAC /* NSError+libimobiledevice.mm */,
);
path = Categories;
sourceTree = "<group>";
};
BFF00D2E2501BD4B00746320 /* Intents */ = { BFF00D2E2501BD4B00746320 /* Intents */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -2276,6 +2289,7 @@
BFECAC9424FD98BA0077C41F /* NSError+ALTServerError.m in Sources */, BFECAC9424FD98BA0077C41F /* NSError+ALTServerError.m in Sources */,
BFECAC9324FD98BA0077C41F /* CFNotificationName+AltStore.m in Sources */, BFECAC9324FD98BA0077C41F /* CFNotificationName+AltStore.m in Sources */,
BFE48975238007CE003239E0 /* AnisetteDataManager.swift in Sources */, BFE48975238007CE003239E0 /* AnisetteDataManager.swift in Sources */,
BFE972E3260A8B2700D0BDAC /* NSError+libimobiledevice.mm in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -10,9 +10,13 @@
extern NSErrorDomain const AltServerErrorDomain; extern NSErrorDomain const AltServerErrorDomain;
extern NSErrorDomain const AltServerInstallationErrorDomain; extern NSErrorDomain const AltServerInstallationErrorDomain;
extern NSErrorDomain const AltServerConnectionErrorDomain;
extern NSErrorUserInfoKey const ALTUnderlyingErrorDomainErrorKey;
extern NSErrorUserInfoKey const ALTUnderlyingErrorCodeErrorKey; extern NSErrorUserInfoKey const ALTUnderlyingErrorCodeErrorKey;
extern NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey; extern NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey;
extern NSErrorUserInfoKey const ALTAppNameErrorKey;
extern NSErrorUserInfoKey const ALTDeviceNameErrorKey;
typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError) typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError)
{ {
@@ -44,6 +48,17 @@ typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError)
ALTServerErrorAppDeletionFailed = 16, ALTServerErrorAppDeletionFailed = 16,
}; };
typedef NS_ERROR_ENUM(AltServerConnectionErrorDomain, ALTServerConnectionError)
{
ALTServerConnectionErrorUnknown,
ALTServerConnectionErrorDeviceLocked,
ALTServerConnectionErrorInvalidRequest,
ALTServerConnectionErrorInvalidResponse,
ALTServerConnectionErrorUsbmuxd,
ALTServerConnectionErrorSSL,
ALTServerConnectionErrorTimedOut,
};
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface NSError (ALTServerError) @interface NSError (ALTServerError)

View File

@@ -10,9 +10,13 @@
NSErrorDomain const AltServerErrorDomain = @"com.rileytestut.AltServer"; NSErrorDomain const AltServerErrorDomain = @"com.rileytestut.AltServer";
NSErrorDomain const AltServerInstallationErrorDomain = @"com.rileytestut.AltServer.Installation"; NSErrorDomain const AltServerInstallationErrorDomain = @"com.rileytestut.AltServer.Installation";
NSErrorDomain const AltServerConnectionErrorDomain = @"com.rileytestut.AltServer.Connection";
NSErrorUserInfoKey const ALTUnderlyingErrorDomainErrorKey = @"underlyingErrorDomain";
NSErrorUserInfoKey const ALTUnderlyingErrorCodeErrorKey = @"underlyingErrorCode"; NSErrorUserInfoKey const ALTUnderlyingErrorCodeErrorKey = @"underlyingErrorCode";
NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey = @"bundleIdentifier"; NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey = @"bundleIdentifier";
NSErrorUserInfoKey const ALTAppNameErrorKey = @"appName";
NSErrorUserInfoKey const ALTDeviceNameErrorKey = @"deviceName";
@implementation NSError (ALTServerError) @implementation NSError (ALTServerError)
@@ -23,14 +27,26 @@ NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey = @"bundleIdenti
{ {
return [error altserver_localizedFailureReason]; return [error altserver_localizedFailureReason];
} }
else if ([userInfoKey isEqualToString:NSLocalizedRecoverySuggestionErrorKey])
if ([userInfoKey isEqualToString:NSLocalizedRecoverySuggestionErrorKey])
{ {
return [error altserver_localizedRecoverySuggestion]; return [error altserver_localizedRecoverySuggestion];
} }
return nil; return nil;
}]; }];
[NSError setUserInfoValueProviderForDomain:AltServerConnectionErrorDomain provider:^id _Nullable(NSError * _Nonnull error, NSErrorUserInfoKey _Nonnull userInfoKey) {
if ([userInfoKey isEqualToString:NSLocalizedDescriptionKey])
{
return [error altserver_connection_localizedDescription];
}
else if ([userInfoKey isEqualToString:NSLocalizedRecoverySuggestionErrorKey])
{
return [error altserver_connection_localizedRecoverySuggestion];
}
return nil;
}];
} }
- (nullable NSString *)altserver_localizedFailureReason - (nullable NSString *)altserver_localizedFailureReason
@@ -146,5 +162,88 @@ NSErrorUserInfoKey const ALTProvisioningProfileBundleIDErrorKey = @"bundleIdenti
return localizedDescription; return localizedDescription;
} }
#pragma mark - AltServerConnectionErrorDomain -
- (nullable NSString *)altserver_connection_localizedDescription
{
switch ((ALTServerConnectionError)self.code)
{
case ALTServerConnectionErrorUnknown:
{
NSString *underlyingErrorDomain = self.userInfo[ALTUnderlyingErrorDomainErrorKey];
NSString *underlyingErrorCode = self.userInfo[ALTUnderlyingErrorCodeErrorKey];
if (underlyingErrorDomain != nil && underlyingErrorCode != nil)
{
return [NSString stringWithFormat:NSLocalizedString(@"%@ error %@.", @""), underlyingErrorDomain, underlyingErrorCode];
}
else if (underlyingErrorCode != nil)
{
return [NSString stringWithFormat:NSLocalizedString(@"Connection error code: %@", @""), underlyingErrorCode];
}
return nil;
}
case ALTServerConnectionErrorDeviceLocked:
{
NSString *deviceName = self.userInfo[ALTDeviceNameErrorKey] ?: NSLocalizedString(@"The device", @"");
return [NSString stringWithFormat:NSLocalizedString(@"%@ is currently locked.", @""), deviceName];
}
case ALTServerConnectionErrorInvalidRequest:
{
NSString *deviceName = self.userInfo[ALTDeviceNameErrorKey] ?: NSLocalizedString(@"The device", @"");
return [NSString stringWithFormat:NSLocalizedString(@"%@ received an invalid request from AltServer.", @""), deviceName];
}
case ALTServerConnectionErrorInvalidResponse:
{
NSString *deviceName = self.userInfo[ALTDeviceNameErrorKey] ?: NSLocalizedString(@"the device", @"");
return [NSString stringWithFormat:NSLocalizedString(@"AltServer received an invalid response from %@.", @""), deviceName];
}
case ALTServerConnectionErrorUsbmuxd:
{
return NSLocalizedString(@"There was an issue communicating with the usbmuxd daemon.", @"");
}
case ALTServerConnectionErrorSSL:
{
NSString *deviceName = self.userInfo[ALTDeviceNameErrorKey] ?: NSLocalizedString(@"the device", @"");
return [NSString stringWithFormat:NSLocalizedString(@"AltServer could not establish a secure connection to %@.", @""), deviceName];
}
case ALTServerConnectionErrorTimedOut:
{
NSString *deviceName = self.userInfo[ALTDeviceNameErrorKey] ?: NSLocalizedString(@"the device", @"");
return [NSString stringWithFormat:NSLocalizedString(@"AltServer's connection to %@ timed out.", @""), deviceName];
}
}
return nil;
}
- (nullable NSString *)altserver_connection_localizedRecoverySuggestion
{
switch ((ALTServerConnectionError)self.code)
{
case ALTServerConnectionErrorDeviceLocked:
{
return NSLocalizedString(@"Please unlock the device with your passcode and try again.", @"");
}
case ALTServerConnectionErrorUnknown:
case ALTServerConnectionErrorInvalidRequest:
case ALTServerConnectionErrorInvalidResponse:
case ALTServerConnectionErrorUsbmuxd:
case ALTServerConnectionErrorSSL:
case ALTServerConnectionErrorTimedOut:
{
return nil;
}
}
}
@end @end

View File

@@ -15,6 +15,7 @@ public extension ALTServerError
switch error switch error
{ {
case let error as ALTServerError: self = error case let error as ALTServerError: self = error
case let error as ALTServerConnectionError: self = ALTServerError(.connectionFailed, underlyingError: error)
case is DecodingError: self = ALTServerError(.invalidRequest, underlyingError: error) case is DecodingError: self = ALTServerError(.invalidRequest, underlyingError: error)
case is EncodingError: self = ALTServerError(.invalidResponse, underlyingError: error) case is EncodingError: self = ALTServerError(.invalidResponse, underlyingError: error)
case let error as NSError: case let error as NSError: