From 07d9a9f2c3d0a50cda4918e5304a33a6c1687ed4 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Sun, 13 Nov 2022 21:58:28 -0700 Subject: [PATCH 01/17] Set anisette URL from plist value --- AltStore/LaunchViewController.swift | 9 +++++++++ AltStore/Operations/FetchAnisetteDataOperation.swift | 1 + 2 files changed, 10 insertions(+) diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 34bcd927..22ce6229 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -47,6 +47,7 @@ class LaunchViewController: RSTLaunchViewController override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) start_em_proxy(bind_addr: Consts.Proxy.serverURL) + setAnisetteServer() guard let pf = fetchPairingFile() else { displayError("Device pairing file not found.") @@ -83,6 +84,14 @@ class LaunchViewController: RSTLaunchViewController } } + func setAnisetteServer() { + if let anisetteUrl = Bundle.main.object(forInfoDictionaryKey: "customAnisetteURL") as? String { + UserDefaults.standard.set(anisetteUrl, forKey: "customAnisetteURL") + } else { + UserDefaults.standard.set("https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx", forKey: "customAnisetteURL") + } + } + func displayError(_ msg: String) { print(msg) // Create a new alert diff --git a/AltStore/Operations/FetchAnisetteDataOperation.swift b/AltStore/Operations/FetchAnisetteDataOperation.swift index edd69e4f..0cf60fb0 100644 --- a/AltStore/Operations/FetchAnisetteDataOperation.swift +++ b/AltStore/Operations/FetchAnisetteDataOperation.swift @@ -33,6 +33,7 @@ class FetchAnisetteDataOperation: ResultOperation } let urlString = UserDefaults.standard.string(forKey: "customAnisetteURL") ?? "https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx" + print("Anisette URL: " + urlString) guard let url = URL(string: urlString) else { return } let task = URLSession.shared.dataTask(with: url) { data, response, error in From 9b671cb1a9358c95c45df4137a7921f79dd6c3b2 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Sun, 13 Nov 2022 22:32:58 -0700 Subject: [PATCH 02/17] Add default fields for custom anisette --- AltStore/Info.plist | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 999afdd3..9a536432 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -125,6 +125,13 @@ UILaunchStoryboardName LaunchScreen + customAnisetteURL + https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + UIMainStoryboardFile Main UIRequiredDeviceCapabilities From 161d3a795d982202ad02d2631e2888d9259439e6 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Tue, 15 Nov 2022 22:59:39 -0700 Subject: [PATCH 03/17] Add settings bundle --- AltStore.xcodeproj/project.pbxproj | 4 ++++ AltStore/LaunchViewController.swift | 2 -- .../FetchAnisetteDataOperation.swift | 2 +- AltStore/Settings.bundle/Root.plist | 21 ++++++++++++++++++ .../Settings.bundle/en.lproj/Root.strings | Bin 0 -> 546 bytes 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 AltStore/Settings.bundle/Root.plist create mode 100644 AltStore/Settings.bundle/en.lproj/Root.strings diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 81fc54f6..e3d5d824 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 191E607D290B2EA5001A3B7C /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FD0290A651D001A3B7C /* jsmn.c */; }; 191E607E290B2EA7001A3B7C /* jplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FCF290A651D001A3B7C /* jplist.c */; }; 191E6087290C7B50001A3B7C /* libminimuxer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191E5FB5290A5E1F001A3B7C /* libminimuxer.a */; }; + 1920B04F2924AC8300744F60 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1920B04E2924AC8300744F60 /* Settings.bundle */; }; 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; }; 4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; }; @@ -560,6 +561,7 @@ 191E6065290B2D6B001A3B7C /* termcolors.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = termcolors.c; path = "../Dependencies/libimobiledevice-glue/src/termcolors.c"; sourceTree = ""; }; 191E6073290B2E02001A3B7C /* companion_proxy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = companion_proxy.c; path = ../Dependencies/libimobiledevice/src/companion_proxy.c; sourceTree = ""; }; 191E6074290B2E02001A3B7C /* preboard.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = preboard.c; path = ../Dependencies/libimobiledevice/src/preboard.c; sourceTree = ""; }; + 1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = ""; }; B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Roxas.xcodeproj; path = Dependencies/Roxas/Roxas.xcodeproj; sourceTree = ""; }; B39575F4284F29E20080B4FF /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1717,6 +1719,7 @@ BFD247962284D7C100981D42 /* Resources */, BF6C8FA8242935CA00125131 /* Dependencies */, BFD247972284D7D800981D42 /* Supporting Files */, + 1920B04E2924AC8300744F60 /* Settings.bundle */, ); path = AltStore; sourceTree = ""; @@ -2433,6 +2436,7 @@ BF44EEF3246B3A17002A52F2 /* AltBackup.ipa in Resources */, BF770E6922BD57DD002A40FE /* Silence.m4a in Resources */, BFD247772284B9A700981D42 /* Assets.xcassets in Resources */, + 1920B04F2924AC8300744F60 /* Settings.bundle in Resources */, BFF0B6922321A305007A79E1 /* AboutPatreonHeaderView.xib in Resources */, BFB6B22423187A3D0022A802 /* NewsCollectionViewCell.xib in Resources */, BFD247752284B9A500981D42 /* Main.storyboard in Resources */, diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 22ce6229..4fde0ef4 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -87,8 +87,6 @@ class LaunchViewController: RSTLaunchViewController func setAnisetteServer() { if let anisetteUrl = Bundle.main.object(forInfoDictionaryKey: "customAnisetteURL") as? String { UserDefaults.standard.set(anisetteUrl, forKey: "customAnisetteURL") - } else { - UserDefaults.standard.set("https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx", forKey: "customAnisetteURL") } } diff --git a/AltStore/Operations/FetchAnisetteDataOperation.swift b/AltStore/Operations/FetchAnisetteDataOperation.swift index 0cf60fb0..cf7c3bce 100644 --- a/AltStore/Operations/FetchAnisetteDataOperation.swift +++ b/AltStore/Operations/FetchAnisetteDataOperation.swift @@ -32,7 +32,7 @@ class FetchAnisetteDataOperation: ResultOperation return } - let urlString = UserDefaults.standard.string(forKey: "customAnisetteURL") ?? "https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx" + let urlString = UserDefaults.standard.string(forKey: "customAnisetteURL")! print("Anisette URL: " + urlString) guard let url = URL(string: urlString) else { return } diff --git a/AltStore/Settings.bundle/Root.plist b/AltStore/Settings.bundle/Root.plist new file mode 100644 index 00000000..5e78f1b0 --- /dev/null +++ b/AltStore/Settings.bundle/Root.plist @@ -0,0 +1,21 @@ + + + + + StringsTable + Root + PreferenceSpecifiers + + + Type + PSTextFieldSpecifier + Title + Anisette URL + Key + customAnisetteURL + DefaultValue + https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx + + + + diff --git a/AltStore/Settings.bundle/en.lproj/Root.strings b/AltStore/Settings.bundle/en.lproj/Root.strings new file mode 100644 index 0000000000000000000000000000000000000000..8cd87b9d6b20c1fbf87bd4db3db267fca5ad4df9 GIT binary patch literal 546 zcmaixOHRW;5JYRuDMndFh#Ua1V1d}N;sVAV2TO?uC3a9aJn*VxFrY}tnon0(S66#J z-d9>G>6W!ur(SDqlp`9nn~*(m%iWnv?yq`Qfp6XbK1?+om~~#r)ZnhkYQU_VbfjuT zHNn`CX<0sd*m1A}>&5sU$akD=GTXJ1e literal 0 HcmV?d00001 From 2aaef99a5491fc5cf858874902c97297aaa48a8e Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Wed, 16 Nov 2022 13:14:04 -0700 Subject: [PATCH 04/17] Choose a pairing file at runtime --- AltStore/LaunchViewController.swift | 74 ++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 4fde0ef4..081b5401 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -12,8 +12,9 @@ import EmotionalDamage import minimuxer import AltStoreCore +import UniformTypeIdentifiers -class LaunchViewController: RSTLaunchViewController +class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate { private var didFinishLaunching = false @@ -53,12 +54,7 @@ class LaunchViewController: RSTLaunchViewController displayError("Device pairing file not found.") return } - set_usbmuxd_socket() - let res = start_minimuxer(pairing_file: pf) - if res != 0 { - displayError("minimuxer failed to start. Incorrect arguments were passed.") - } - auto_mount_dev_image() + start_minimuxer_threads(pf) } func fetchPairingFile() -> String? { @@ -80,6 +76,26 @@ class LaunchViewController: RSTLaunchViewController print("Loaded ALTPairingFile from Info.plist") return plistString } else { + // Show an alert explaining the pairing file + // Create new Alert + var dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://youtu.be/dQw4w9WgXcQ", preferredStyle: .alert) + + // Create OK button with action handler + let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in + // Try to load it from a file picker + var types = UTType.types(tag: "plist", tagClass: UTTagClass.filenameExtension, conformingTo: nil) + types.append(contentsOf: UTType.types(tag: "mobiledevicepairing", tagClass: UTTagClass.filenameExtension, conformingTo: nil)) + let documentPickerController = UIDocumentPickerViewController(forOpeningContentTypes: types) + documentPickerController.delegate = self + self.present(documentPickerController, animated: true, completion: nil) + }) + + //Add OK button to a dialog message + dialogMessage.addAction(ok) + + // Present Alert to + self.present(dialogMessage, animated: true, completion: nil) + return nil } } @@ -98,6 +114,50 @@ class LaunchViewController: RSTLaunchViewController // Present alert to user self.present(dialogMessage, animated: true, completion: nil) } + + func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { + let url = urls[0] + let isSecuredURL = url.startAccessingSecurityScopedResource() == true + + do { + // Read to a string + let data1 = try Data(contentsOf: urls[0]) + let pairing_string = String(bytes: data1, encoding: .utf8) + if pairing_string == nil { + displayError("Unable to read pairing file") + } + + // Save to a file for next launch + let filename = "ALTPairingFile.mobiledevicepairing" + let fm = FileManager.default + let documentsPath = fm.documentsDirectory.appendingPathComponent("/\(filename)") + try pairing_string?.write(to: documentsPath, atomically: true, encoding: String.Encoding.utf8) + + // Start minimuxer now that we have a file + start_minimuxer_threads(pairing_string!) + + } catch { + displayError("Unable to read pairing file") + } + + if (isSecuredURL) { + url.stopAccessingSecurityScopedResource() + } + controller.dismiss(animated: true, completion: nil) + } + + func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { + displayError("Choosing a pairing file was cancelled") + } + + func start_minimuxer_threads(_ pairing_file: String) { + set_usbmuxd_socket() + let res = start_minimuxer(pairing_file: pairing_file) + if res != 0 { + displayError("minimuxer failed to start. Incorrect arguments were passed.") + } + auto_mount_dev_image() + } } extension LaunchViewController From 5e4a21087e067c81dce541ad830b4242ac5e443f Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Wed, 16 Nov 2022 13:58:14 -0700 Subject: [PATCH 05/17] Remove customAnisetteURL from default Info.plist --- AltStore/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 9a536432..8e3f521f 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -125,8 +125,6 @@ UILaunchStoryboardName LaunchScreen - customAnisetteURL - https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx NSAppTransportSecurity NSAllowsArbitraryLoads From 1257e4efac9ae7a66c46f8e273810c8a1f3f6c87 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 16:41:02 -0500 Subject: [PATCH 06/17] Anisette URL convenience methods and logging Signed-off-by: Joseph Mattello --- AltStore.xcodeproj/project.pbxproj | 4 ++ AltStore/Extensions/OSLog+SideStore.swift | 65 +++++++++++++++++++ AltStore/Info.plist | 2 + AltStore/LaunchViewController.swift | 38 ++++++++--- AltStore/Settings.bundle/Root.plist | 2 +- .../Extensions/UserDefaults+AltStore.swift | 2 +- 6 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 AltStore/Extensions/OSLog+SideStore.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index e3d5d824..4fe695c9 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 4879A9622861049C00FC1BBD /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A9612861049C00FC1BBD /* OpenSSL */; }; B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; }; B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + B376FE3E29258C8900E18883 /* OSLog+SideStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B376FE3D29258C8900E18883 /* OSLog+SideStore.swift */; }; B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B39575F4284F29E20080B4FF /* Roxas.framework */; }; B39F16132918D7C5002E9404 /* Consts.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39F16122918D7C5002E9404 /* Consts.swift */; }; B39F16152918D7DA002E9404 /* Consts+Proxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B39F16142918D7DA002E9404 /* Consts+Proxy.swift */; }; @@ -564,6 +565,7 @@ 1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = ""; }; B3146EC6284F580500BBC3FD /* Roxas.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Roxas.xcodeproj; path = Dependencies/Roxas/Roxas.xcodeproj; sourceTree = ""; }; + B376FE3D29258C8900E18883 /* OSLog+SideStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OSLog+SideStore.swift"; sourceTree = ""; }; B39575F4284F29E20080B4FF /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B39F16122918D7C5002E9404 /* Consts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Consts.swift; sourceTree = ""; }; B39F16142918D7DA002E9404 /* Consts+Proxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Consts+Proxy.swift"; sourceTree = ""; }; @@ -1795,6 +1797,7 @@ BF8CAE4D248AEABA004D6CCE /* UIDevice+Jailbreak.swift */, BFE00A1F2503097F00EB4D0C /* INInteraction+AltStore.swift */, D57F2C9326E01BC700B9FA39 /* UIDevice+Vibration.swift */, + B376FE3D29258C8900E18883 /* OSLog+SideStore.swift */, ); path = Extensions; sourceTree = ""; @@ -2764,6 +2767,7 @@ BF18B0F122E25DF9005C4CF5 /* ToastView.swift in Sources */, BF3D649F22E7B24C00E9056B /* CollapsingTextView.swift in Sources */, BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */, + B376FE3E29258C8900E18883 /* OSLog+SideStore.swift in Sources */, BF08858322DE795100DE9F1E /* MyAppsViewController.swift in Sources */, BFC84A4D2421A19100853474 /* SourcesViewController.swift in Sources */, BFF0B696232242D3007A79E1 /* LicensesViewController.swift in Sources */, diff --git a/AltStore/Extensions/OSLog+SideStore.swift b/AltStore/Extensions/OSLog+SideStore.swift new file mode 100644 index 00000000..9f01098b --- /dev/null +++ b/AltStore/Extensions/OSLog+SideStore.swift @@ -0,0 +1,65 @@ +// +// OSLog+SideStore.swift +// SideStore +// +// Created by Joseph Mattiello on 11/16/22. +// Copyright © 2022 Riley Testut. All rights reserved. +// + +import Foundation +import OSLog + +let customLog = OSLog(subsystem: "org.sidestore.sidestore", + category: "ios") + + +public extension OSLog { + /// Error logger extension + /// - Parameters: + /// - message: String or format string + /// - args: optional args for format string + static func error(_ message: StaticString, _ args: CVarArg...) { + os_log(message, log: customLog, type: .error, args) + } + + /// Info logger extension + /// - Parameters: + /// - message: String or format string + /// - args: optional args for format string + static func info(_ message: StaticString, _ args: CVarArg...) { + os_log(message, log: customLog, type: .info, args) + } + + /// Debug logger extension + /// - Parameters: + /// - message: String or format string + /// - args: optional args for format string + static func debug(_ message: StaticString, _ args: CVarArg...) { + os_log(message, log: customLog, type: .debug, args) + } +} + +/// Error logger convenience method for SideStore logging +/// - Parameters: +/// - message: String or format string +/// - args: optional args for format string +public func ELOG(_ message: StaticString, _ args: CVarArg...) { + OSLog.error(message, args) +} + +/// Info logger convenience method for SideStore logging +/// - Parameters: +/// - message: String or format string +/// - args: optional args for format string +public func ILOG(_ message: StaticString, _ args: CVarArg...) { + OSLog.info(message, args) +} + + +/// Debug logger convenience method for SideStore logging +/// - Parameters: +/// - message: String or format string +/// - args: optional args for format string +public func DLOG(_ message: StaticString, _ args: CVarArg...) { + OSLog.debug(message, args) +} diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 8e3f521f..2348b0e1 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -13,6 +13,8 @@ 1F7D5B55-79CE-4546-A029-D4DDC4AF3B6D ALTPairingFile <insert pairing file here> + ALTAnisetteURL + https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDocumentTypes diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 081b5401..1dab2c20 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -13,6 +13,33 @@ import minimuxer import AltStoreCore import UniformTypeIdentifiers +import OSLog + +public struct AnisetteManager { + + /// User defined URL from Settings/UserDefaults + static var userURL: String? { + guard let urlString = UserDefaults.shared.customAnisetteURL else { return nil } + // Test it's a valid URL + guard URL(string: urlString) != nil else { + ELOG("UserDefaults has invalid `customAnisetteURL`") + assertionFailure("UserDefaults has invalid `customAnisetteURL`") + return nil + } + return urlString + } + static var defaultURL: String { + guard let url = Bundle.main.object(forInfoDictionaryKey: "ALTAnisetteURL") as? String else { + assertionFailure("Info.plist has invalid `ALTAnisetteURL`") + } + return url + } + static var currentURLString: String { userURL ?? defaultURL } + // Force unwrap is safe here since we check validity before hand -- @JoeMatt + + /// User url or default from plist if none specified + static var currentURL: URL { URL(string: currentURLString)! } +} class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate { @@ -48,7 +75,6 @@ class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) start_em_proxy(bind_addr: Consts.Proxy.serverURL) - setAnisetteServer() guard let pf = fetchPairingFile() else { displayError("Device pairing file not found.") @@ -78,7 +104,7 @@ class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate } else { // Show an alert explaining the pairing file // Create new Alert - var dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://youtu.be/dQw4w9WgXcQ", preferredStyle: .alert) + let dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://youtu.be/dQw4w9WgXcQ", preferredStyle: .alert) // Create OK button with action handler let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in @@ -99,13 +125,7 @@ class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate return nil } } - - func setAnisetteServer() { - if let anisetteUrl = Bundle.main.object(forInfoDictionaryKey: "customAnisetteURL") as? String { - UserDefaults.standard.set(anisetteUrl, forKey: "customAnisetteURL") - } - } - + func displayError(_ msg: String) { print(msg) // Create a new alert diff --git a/AltStore/Settings.bundle/Root.plist b/AltStore/Settings.bundle/Root.plist index 5e78f1b0..779d72e0 100644 --- a/AltStore/Settings.bundle/Root.plist +++ b/AltStore/Settings.bundle/Root.plist @@ -14,7 +14,7 @@ Key customAnisetteURL DefaultValue - https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx + diff --git a/AltStoreCore/Extensions/UserDefaults+AltStore.swift b/AltStoreCore/Extensions/UserDefaults+AltStore.swift index 75b5a041..5b331092 100644 --- a/AltStoreCore/Extensions/UserDefaults+AltStore.swift +++ b/AltStoreCore/Extensions/UserDefaults+AltStore.swift @@ -3,7 +3,7 @@ // AltStore // // Created by Riley Testut on 6/4/19. -// Copyright © 2019 Riley Testut. All rights reserved. +// Copyright © 2019 SideStore. All rights reserved. // import Foundation From 2c615682df904de94e613b1767ad83380d004495 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 16:52:36 -0500 Subject: [PATCH 07/17] OSLog+SideStore update copyright Signed-off-by: Joseph Mattello --- AltStore/Extensions/OSLog+SideStore.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/Extensions/OSLog+SideStore.swift b/AltStore/Extensions/OSLog+SideStore.swift index 9f01098b..73559248 100644 --- a/AltStore/Extensions/OSLog+SideStore.swift +++ b/AltStore/Extensions/OSLog+SideStore.swift @@ -3,7 +3,7 @@ // SideStore // // Created by Joseph Mattiello on 11/16/22. -// Copyright © 2022 Riley Testut. All rights reserved. +// Copyright © 2022 SideStore. All rights reserved. // import Foundation From 39805bc103d5e7d5d09c034a770f7dd8d2407392 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 17:04:18 -0500 Subject: [PATCH 08/17] Anisette URL fix missing abort Signed-off-by: Joseph Mattello --- AltStore/LaunchViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 1dab2c20..78667f74 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -31,6 +31,7 @@ public struct AnisetteManager { static var defaultURL: String { guard let url = Bundle.main.object(forInfoDictionaryKey: "ALTAnisetteURL") as? String else { assertionFailure("Info.plist has invalid `ALTAnisetteURL`") + abort() } return url } From c8fc4ea5006aaf649906d247d9f1a4f0526865d5 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 17:07:54 -0500 Subject: [PATCH 09/17] AltStore scheme XCode auto edits Signed-off-by: Joseph Mattello --- .../xcshareddata/xcschemes/AltStore.xcscheme | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AltStore.xcodeproj/xcshareddata/xcschemes/AltStore.xcscheme b/AltStore.xcodeproj/xcshareddata/xcschemes/AltStore.xcscheme index cdc3f471..2c21e935 100644 --- a/AltStore.xcodeproj/xcshareddata/xcschemes/AltStore.xcscheme +++ b/AltStore.xcodeproj/xcshareddata/xcschemes/AltStore.xcscheme @@ -15,8 +15,8 @@ @@ -45,8 +45,8 @@ @@ -68,8 +68,8 @@ From f1a8334f59a88ec9344a37203e54b2b8e7bf950b Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 17:50:57 -0500 Subject: [PATCH 10/17] OSLog+SideStore fix staticstring Signed-off-by: Joseph Mattello --- AltStore/Extensions/OSLog+SideStore.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/AltStore/Extensions/OSLog+SideStore.swift b/AltStore/Extensions/OSLog+SideStore.swift index 73559248..73fb7c0e 100644 --- a/AltStore/Extensions/OSLog+SideStore.swift +++ b/AltStore/Extensions/OSLog+SideStore.swift @@ -10,7 +10,7 @@ import Foundation import OSLog let customLog = OSLog(subsystem: "org.sidestore.sidestore", - category: "ios") + category: "ios") public extension OSLog { @@ -39,11 +39,13 @@ public extension OSLog { } } +// TODO: Add file,line,function to messages? -- @JoeMatt + /// Error logger convenience method for SideStore logging /// - Parameters: /// - message: String or format string /// - args: optional args for format string -public func ELOG(_ message: StaticString, _ args: CVarArg...) { +public func ELOG(_ message: StaticString, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, _ args: CVarArg...) { OSLog.error(message, args) } @@ -51,15 +53,17 @@ public func ELOG(_ message: StaticString, _ args: CVarArg...) { /// - Parameters: /// - message: String or format string /// - args: optional args for format string -public func ILOG(_ message: StaticString, _ args: CVarArg...) { +public func ILOG(_ message: StaticString, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, _ args: CVarArg...) { OSLog.info(message, args) } - /// Debug logger convenience method for SideStore logging /// - Parameters: /// - message: String or format string /// - args: optional args for format string -public func DLOG(_ message: StaticString, _ args: CVarArg...) { +@inlinable +public func DLOG(_ message: StaticString, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, _ args: CVarArg...) { OSLog.debug(message, args) } + +// mark: Helpers From c34245ff211e9a29eb5d23bdb337e5974ccea5a7 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 17:51:13 -0500 Subject: [PATCH 11/17] FetchAnisetteDataOperation.swift fix url reading Signed-off-by: Joseph Mattello --- .../FetchAnisetteDataOperation.swift | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/AltStore/Operations/FetchAnisetteDataOperation.swift b/AltStore/Operations/FetchAnisetteDataOperation.swift index cf7c3bce..298a8fe2 100644 --- a/AltStore/Operations/FetchAnisetteDataOperation.swift +++ b/AltStore/Operations/FetchAnisetteDataOperation.swift @@ -32,34 +32,31 @@ class FetchAnisetteDataOperation: ResultOperation return } - let urlString = UserDefaults.standard.string(forKey: "customAnisetteURL")! - print("Anisette URL: " + urlString) - guard let url = URL(string: urlString) else { return } - - let task = URLSession.shared.dataTask(with: url) { data, response, error in - - guard let data = data, error == nil else { return } - - do { - // make sure this JSON is in the format we expect - // convert data to json - if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String] { - // try to read out a dictionary - //for some reason serial number isn't needed but it doesn't work unless it has a value - let formattedJSON: [String: String] = ["machineID": json["X-Apple-I-MD-M"]!, "oneTimePassword": json["X-Apple-I-MD"]!, "localUserID": json["X-Apple-I-MD-LU"]!, "routingInfo": json["X-Apple-I-MD-RINFO"]!, "deviceUniqueIdentifier": json["X-Mme-Device-Id"]!, "deviceDescription": json["X-MMe-Client-Info"]!, "date": json["X-Apple-I-Client-Time"]!, "locale": json["X-Apple-Locale"]!, "timeZone": json["X-Apple-I-TimeZone"]!, "deviceSerialNumber": "1"] - - if let anisette = ALTAnisetteData(json: formattedJSON) { - self.finish(.success(anisette)) - } - } - } catch let error as NSError { - print("Failed to load: \(error.localizedDescription)") - self.finish(.failure(error)) - } - - } - - task.resume() - + let url = AnisetteManager.currentURL + DLOG("Anisette URL: %@", url.absoluteString) + + let task = URLSession.shared.dataTask(with: url) { data, response, error in + guard let data = data, error == nil else { return } + + do { + // make sure this JSON is in the format we expect + // convert data to json + if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String] { + // try to read out a dictionary + //for some reason serial number isn't needed but it doesn't work unless it has a value + let formattedJSON: [String: String] = ["machineID": json["X-Apple-I-MD-M"]!, "oneTimePassword": json["X-Apple-I-MD"]!, "localUserID": json["X-Apple-I-MD-LU"]!, "routingInfo": json["X-Apple-I-MD-RINFO"]!, "deviceUniqueIdentifier": json["X-Mme-Device-Id"]!, "deviceDescription": json["X-MMe-Client-Info"]!, "date": json["X-Apple-I-Client-Time"]!, "locale": json["X-Apple-Locale"]!, "timeZone": json["X-Apple-I-TimeZone"]!, "deviceSerialNumber": "1"] + + if let anisette = ALTAnisetteData(json: formattedJSON) { + self.finish(.success(anisette)) + } + } + } catch let error as NSError { + print("Failed to load: \(error.localizedDescription)") + self.finish(.failure(error)) + } + + } + + task.resume() } } From 50e0e88cc283f0eda38f5a4ee77b3199d8b73032 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 17:51:30 -0500 Subject: [PATCH 12/17] ORGANIZATIONNAME to SideStore Signed-off-by: Joseph Mattello --- AltStore.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 4fe695c9..e850693a 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -2257,7 +2257,7 @@ attributes = { LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 1020; - ORGANIZATIONNAME = "Riley Testut"; + ORGANIZATIONNAME = SideStore; TargetAttributes = { 19104DB12909C06C00C49C7B = { CreatedOnToolsVersion = 14.0; From 02b837c54b748b835250e864f0f785d9714ade3e Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 18:26:54 -0500 Subject: [PATCH 13/17] Settings.bundle group and text type URL Signed-off-by: Joseph Mattello --- AltStore/Settings.bundle/Root.plist | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/AltStore/Settings.bundle/Root.plist b/AltStore/Settings.bundle/Root.plist index 779d72e0..651bd264 100644 --- a/AltStore/Settings.bundle/Root.plist +++ b/AltStore/Settings.bundle/Root.plist @@ -4,6 +4,8 @@ StringsTable Root + ApplicationGroupContainerIdentifier + group.$(APP_GROUP_IDENTIFIER) PreferenceSpecifiers @@ -15,6 +17,14 @@ customAnisetteURL DefaultValue + IsSecure + Alphabet + AutocapitalizationType + None + AutocorrectionType + No + KeyboardType + URL From c7d4b722d0e3a4bbde7017ae10014dfb5ad4b559 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 22:39:20 -0500 Subject: [PATCH 14/17] refactor anisette manager to own file Signed-off-by: Joseph Mattello --- AltStore.xcodeproj/project.pbxproj | 4 +++ AltStore/LaunchViewController.swift | 28 ------------------- AltStore/Settings/AnisetteManager.swift | 36 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 AltStore/Settings/AnisetteManager.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index e850693a..7c9c859e 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -45,6 +45,7 @@ B3C395F9284F362400DA9E2F /* AppCenterCrashes in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395F8284F362400DA9E2F /* AppCenterCrashes */; }; B3C395FC284F3B2400DA9E2F /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395FB284F3B2400DA9E2F /* Sparkle */; }; B3C395FF284F3C0900DA9E2F /* STPrivilegedTask in Frameworks */ = {isa = PBXBuildFile; productRef = B3C395FE284F3C0900DA9E2F /* STPrivilegedTask */; }; + B3EE16B62925E27D00B3B1F5 /* AnisetteManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EE16B52925E27D00B3B1F5 /* AnisetteManager.swift */; }; BF02419622F2199300129732 /* RefreshAttemptsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02419522F2199300129732 /* RefreshAttemptsViewController.swift */; }; BF0241AA22F29CCD00129732 /* UserDefaults+AltServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0241A922F29CCD00129732 /* UserDefaults+AltServer.swift */; }; BF08858322DE795100DE9F1E /* MyAppsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF08858222DE795100DE9F1E /* MyAppsViewController.swift */; }; @@ -578,6 +579,7 @@ B3C3960D284F4E4B00DA9E2F /* AltWidgetExtension.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltWidgetExtension.xcconfig; sourceTree = ""; }; B3C3960E284F4F9100DA9E2F /* AltStoreCore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltStoreCore.xcconfig; sourceTree = ""; }; B3C3960F284F53E900DA9E2F /* AltBackup.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AltBackup.xcconfig; sourceTree = ""; }; + B3EE16B52925E27D00B3B1F5 /* AnisetteManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnisetteManager.swift; sourceTree = ""; }; BF02419522F2199300129732 /* RefreshAttemptsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshAttemptsViewController.swift; sourceTree = ""; }; BF0241A922F29CCD00129732 /* UserDefaults+AltServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+AltServer.swift"; sourceTree = ""; }; BF08858222DE795100DE9F1E /* MyAppsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppsViewController.swift; sourceTree = ""; }; @@ -1834,6 +1836,7 @@ BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */, BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */, BFF0B695232242D3007A79E1 /* LicensesViewController.swift */, + B3EE16B52925E27D00B3B1F5 /* AnisetteManager.swift */, ); path = Settings; sourceTree = ""; @@ -2746,6 +2749,7 @@ BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */, BF3D64B022E8D4B800E9056B /* AppContentViewControllerCells.swift in Sources */, BFC57A6E2416FC5D00EB891E /* InstalledAppsCollectionHeaderView.swift in Sources */, + B3EE16B62925E27D00B3B1F5 /* AnisetteManager.swift in Sources */, BF88F97224F8727D00BB75DF /* AppManagerErrors.swift in Sources */, B39F16152918D7DA002E9404 /* Consts+Proxy.swift in Sources */, BF6C8FAE2429597900125131 /* BannerCollectionViewCell.swift in Sources */, diff --git a/AltStore/LaunchViewController.swift b/AltStore/LaunchViewController.swift index 78667f74..8f9e590b 100644 --- a/AltStore/LaunchViewController.swift +++ b/AltStore/LaunchViewController.swift @@ -13,34 +13,6 @@ import minimuxer import AltStoreCore import UniformTypeIdentifiers -import OSLog - -public struct AnisetteManager { - - /// User defined URL from Settings/UserDefaults - static var userURL: String? { - guard let urlString = UserDefaults.shared.customAnisetteURL else { return nil } - // Test it's a valid URL - guard URL(string: urlString) != nil else { - ELOG("UserDefaults has invalid `customAnisetteURL`") - assertionFailure("UserDefaults has invalid `customAnisetteURL`") - return nil - } - return urlString - } - static var defaultURL: String { - guard let url = Bundle.main.object(forInfoDictionaryKey: "ALTAnisetteURL") as? String else { - assertionFailure("Info.plist has invalid `ALTAnisetteURL`") - abort() - } - return url - } - static var currentURLString: String { userURL ?? defaultURL } - // Force unwrap is safe here since we check validity before hand -- @JoeMatt - - /// User url or default from plist if none specified - static var currentURL: URL { URL(string: currentURLString)! } -} class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDelegate { diff --git a/AltStore/Settings/AnisetteManager.swift b/AltStore/Settings/AnisetteManager.swift new file mode 100644 index 00000000..19861d0c --- /dev/null +++ b/AltStore/Settings/AnisetteManager.swift @@ -0,0 +1,36 @@ +// +// AnisetteManager.swift +// SideStore +// +// Created by Joseph Mattiello on 11/16/22. +// Copyright © 2022 SideStore. All rights reserved. +// + +import Foundation + +public struct AnisetteManager { + + /// User defined URL from Settings/UserDefaults + static var userURL: String? { + guard let urlString = UserDefaults.shared.customAnisetteURL, !urlString.isEmpty else { return nil } + // Test it's a valid URL + guard URL(string: urlString) != nil else { + ELOG("UserDefaults has invalid `customAnisetteURL`") + assertionFailure("UserDefaults has invalid `customAnisetteURL`") + return nil + } + return urlString + } + static var defaultURL: String { + guard let url = Bundle.main.object(forInfoDictionaryKey: "ALTAnisetteURL") as? String else { + assertionFailure("Info.plist has invalid `ALTAnisetteURL`") + abort() + } + return url + } + static var currentURLString: String { userURL ?? defaultURL } + // Force unwrap is safe here since we check validity before hand -- @JoeMatt + + /// User url or default from plist if none specified + static var currentURL: URL { URL(string: currentURLString)! } +} From de05579d1f928a602ed274c921fd9df8b4503bae Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Wed, 16 Nov 2022 22:39:45 -0500 Subject: [PATCH 15/17] Remove customAnisetteURL empty string default Signed-off-by: Joseph Mattello --- AltStore/Settings.bundle/Root.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/AltStore/Settings.bundle/Root.plist b/AltStore/Settings.bundle/Root.plist index 651bd264..dc88137f 100644 --- a/AltStore/Settings.bundle/Root.plist +++ b/AltStore/Settings.bundle/Root.plist @@ -15,8 +15,6 @@ Anisette URL Key customAnisetteURL - DefaultValue - IsSecure Alphabet AutocapitalizationType From 77cf00e8e4eb9e2daa440719ded6038e98c38ff3 Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Mon, 21 Nov 2022 20:54:27 -0500 Subject: [PATCH 16/17] info.plst add mobiledevicepairing imported type Signed-off-by: Joseph Mattello --- AltStore/Info.plist | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 2348b0e1..85306265 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -178,6 +178,25 @@ ipa + + UTTypeConformsTo + + com.apple.plist + + UTTypeDescription + Mobile Device Pairing + UTTypeIconFiles + + UTTypeIdentifier + org.sidestore.mobiledevicepairing + UTTypeTagSpecification + + public.filename-extension + + mobiledevicepairing + + + From 70a258aae2c99f6478be8d97f7a7adc24992a47e Mon Sep 17 00:00:00 2001 From: Joseph Mattello Date: Mon, 21 Nov 2022 21:24:40 -0500 Subject: [PATCH 17/17] AnisetteManager UserDefaults.standard from .shared Signed-off-by: Joseph Mattello --- AltStore/Settings/AnisetteManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AltStore/Settings/AnisetteManager.swift b/AltStore/Settings/AnisetteManager.swift index 19861d0c..9db5157a 100644 --- a/AltStore/Settings/AnisetteManager.swift +++ b/AltStore/Settings/AnisetteManager.swift @@ -12,7 +12,7 @@ public struct AnisetteManager { /// User defined URL from Settings/UserDefaults static var userURL: String? { - guard let urlString = UserDefaults.shared.customAnisetteURL, !urlString.isEmpty else { return nil } + guard let urlString = UserDefaults.standard.customAnisetteURL, !urlString.isEmpty else { return nil } // Test it's a valid URL guard URL(string: urlString) != nil else { ELOG("UserDefaults has invalid `customAnisetteURL`")