diff --git a/Cargo.lock b/Cargo.lock index 27fb430..a64e1c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -981,7 +981,7 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "isideload" -version = "0.1.21" +version = "0.1.22" dependencies = [ "hex", "idevice", @@ -2839,9 +2839,9 @@ dependencies = [ [[package]] name = "zsign-rust" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e6f7303e79779f24807ebb43de1816334c6bbbfb1982785d21189bc1cb47f79" +checksum = "f246eecd6b89f0ba582563ec68049f1b6f3498c455d78940355d0cfb09b38379" dependencies = [ "bindgen", "cc", diff --git a/isideload/Cargo.toml b/isideload/Cargo.toml index 20b2d38..a07fd07 100644 --- a/isideload/Cargo.toml +++ b/isideload/Cargo.toml @@ -3,7 +3,7 @@ name = "isideload" description = "Sideload iOS/iPadOS applications" license = "MPL-2.0" authors = ["Nicholas Sharp "] -version = "0.1.21" +version = "0.1.22" edition = "2024" repository = "https://github.com/nab138/isideload" documentation = "https://docs.rs/isideload" @@ -24,5 +24,5 @@ hex = "0.4" sha1 = "0.10" idevice = { version = "0.1.46", features = ["afc", "installation_proxy", "ring"], default-features = false } openssl = "0.10" -zsign-rust = "0.1.6" +zsign-rust = "0.1.7" thiserror = "2" diff --git a/isideload/src/bundle.rs b/isideload/src/bundle.rs index 117acfd..579f27a 100644 --- a/isideload/src/bundle.rs +++ b/isideload/src/bundle.rs @@ -7,12 +7,13 @@ use std::{ path::{Path, PathBuf}, }; +#[derive(Debug)] pub struct Bundle { pub app_info: Dictionary, pub bundle_dir: PathBuf, app_extensions: Vec, - _frameworks: Vec, + frameworks: Vec, _libraries: Vec, } @@ -81,7 +82,7 @@ impl Bundle { app_info, bundle_dir: bundle_path, app_extensions, - _frameworks: frameworks, + frameworks, _libraries: libraries, }) } @@ -113,6 +114,14 @@ impl Bundle { &mut self.app_extensions } + pub fn frameworks(&self) -> &[Bundle] { + &self.frameworks + } + + pub fn frameworks_mut(&mut self) -> &mut [Bundle] { + &mut self.frameworks + } + pub fn write_info(&self) -> Result<(), Error> { let info_plist_path = self.bundle_dir.join("Info.plist"); let result = plist::to_file_binary(&info_plist_path, &self.app_info); diff --git a/isideload/src/lib.rs b/isideload/src/lib.rs index 698bd75..b127f9d 100644 --- a/isideload/src/lib.rs +++ b/isideload/src/lib.rs @@ -63,8 +63,6 @@ pub struct SideloadConfiguration<'a> { pub store_dir: std::path::PathBuf, /// Whether or not to revoke the certificate immediately after installation pub revoke_cert: bool, - /// Whether or not to force SideStore App Group (fixes LiveContainer+SideStore issues) - pub force_sidestore_app_group: bool, } impl Default for SideloadConfiguration<'_> { @@ -80,7 +78,6 @@ impl<'a> SideloadConfiguration<'a> { logger: &DefaultLogger, store_dir: std::env::current_dir().unwrap(), revoke_cert: false, - force_sidestore_app_group: false, } } @@ -103,9 +100,4 @@ impl<'a> SideloadConfiguration<'a> { self.revoke_cert = revoke_cert; self } - - pub fn set_force_sidestore_app_group(mut self, force: bool) -> Self { - self.force_sidestore_app_group = force; - self - } } diff --git a/isideload/src/sideload.rs b/isideload/src/sideload.rs index 39b51dc..b9e742d 100644 --- a/isideload/src/sideload.rs +++ b/isideload/src/sideload.rs @@ -105,7 +105,14 @@ pub async fn sideload_app( }; let mut app = Application::new(app_path)?; + let is_sidestore = app.bundle.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore"; + let is_lc_and_sidestore = app + .bundle + .frameworks() + .iter() + .any(|f| f.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore"); + let main_app_bundle_id = match app.bundle.bundle_identifier() { Some(id) => id.to_string(), None => { @@ -254,35 +261,44 @@ pub async fn sideload_app( let group_identifier = format!( "group.{}", - if config.force_sidestore_app_group { + if is_lc_and_sidestore { format!("com.SideStore.SideStore.{}", team.team_id) } else { main_app_id_str.clone() } ); - if is_sidestore { + if is_sidestore || is_lc_and_sidestore { app.bundle.app_info.insert( "ALTAppGroups".to_string(), plist::Value::Array(vec![plist::Value::String(group_identifier.clone())]), ); - app.bundle.app_info.insert( - "ALTCertificateID".to_string(), - plist::Value::String(cert.get_serial_number().unwrap()), - ); + let target_bundle = if is_lc_and_sidestore { + app.bundle + .frameworks_mut() + .iter_mut() + .find(|fw| fw.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore") + } else { + Some(&mut app.bundle) + }; - match cert.to_pkcs12(&cert.machine_id) { - Ok(p12_bytes) => { - let alt_cert_path = app.bundle.bundle_dir.join("ALTCertificate.p12"); - if alt_cert_path.exists() { - std::fs::remove_file(&alt_cert_path).map_err(Error::Filesystem)?; + if let Some(target_bundle) = target_bundle { + target_bundle.app_info.insert( + "ALTCertificateID".to_string(), + plist::Value::String(cert.get_serial_number().unwrap()), + ); + + match cert.to_pkcs12(&cert.machine_id) { + Ok(p12_bytes) => { + let alt_cert_path = target_bundle.bundle_dir.join("ALTCertificate.p12"); + + let mut file = + std::fs::File::create(&alt_cert_path).map_err(Error::Filesystem)?; + file.write_all(&p12_bytes).map_err(Error::Filesystem)?; } - - let mut file = std::fs::File::create(&alt_cert_path).map_err(Error::Filesystem)?; - file.write_all(&p12_bytes).map_err(Error::Filesystem)?; + Err(e) => return error_and_return(logger, e), } - Err(e) => return error_and_return(logger, e), } } @@ -384,11 +400,16 @@ pub async fn sideload_app( for ext in app.bundle.app_extensions_mut() { ext.write_info()?; } + for ext in app.bundle.frameworks_mut() { + ext.write_info()?; + } match ZSignOptions::new(app.bundle.bundle_dir.to_str().unwrap()) .with_cert_file(cert.get_certificate_file_path().to_str().unwrap()) .with_pkey_file(cert.get_private_key_file_path().to_str().unwrap()) .with_prov_file(profile_path.to_str().unwrap()) + .with_force() + .with_disable_cache() .sign() { Ok(_) => {}