From a62ce2863dd513a4b801a0ffb3588b6ff0de3715 Mon Sep 17 00:00:00 2001 From: nab138 Date: Sat, 14 Feb 2026 15:19:59 -0500 Subject: [PATCH] Improve logging and small refactor --- isideload/src/sideload/application.rs | 1 + isideload/src/sideload/mod.rs | 1 + isideload/src/sideload/sideloader.rs | 112 +++++-------------------- isideload/src/sideload/sign.rs | 114 ++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 93 deletions(-) create mode 100644 isideload/src/sideload/sign.rs diff --git a/isideload/src/sideload/application.rs b/isideload/src/sideload/application.rs index 8cf531c..4a33ecb 100644 --- a/isideload/src/sideload/application.rs +++ b/isideload/src/sideload/application.rs @@ -208,6 +208,7 @@ impl Application { }) .collect(); + info!("Registered app IDs"); Ok(app_ids) } diff --git a/isideload/src/sideload/mod.rs b/isideload/src/sideload/mod.rs index d0258ed..5e59ac5 100644 --- a/isideload/src/sideload/mod.rs +++ b/isideload/src/sideload/mod.rs @@ -5,4 +5,5 @@ pub mod cert_identity; #[cfg(feature = "install")] pub mod install; pub mod sideloader; +pub mod sign; pub use builder::{SideloaderBuilder, TeamSelection}; diff --git a/isideload/src/sideload/sideloader.rs b/isideload/src/sideload/sideloader.rs index 5501e38..a1a0272 100644 --- a/isideload/src/sideload/sideloader.rs +++ b/isideload/src/sideload/sideloader.rs @@ -11,17 +11,15 @@ use crate::{ application::{Application, SpecialApp}, builder::MaxCertsBehavior, cert_identity::CertificateIdentity, + sign, }, - util::{device::IdeviceInfo, plist::PlistDataExtract, storage::SideloadingStorage}, + util::{device::IdeviceInfo, storage::SideloadingStorage}, }; use std::path::PathBuf; -use apple_codesign::{SigningSettings, UnifiedSigner}; use idevice::provider::IdeviceProvider; -use plist::Dictionary; -use plist_macro::plist_to_xml_string; -use rootcause::{option_ext::OptionExt, prelude::*}; +use rootcause::prelude::*; use tracing::info; pub struct Sideloader { @@ -65,7 +63,7 @@ impl Sideloader { team: Option, // this will be replaced with proper entitlement handling later increased_memory_limit: bool, - ) -> Result { + ) -> Result<(PathBuf, Option), Report> { let team = match team { Some(t) => t, None => self.get_team().await?, @@ -138,6 +136,8 @@ impl Sideloader { } } + info!("App IDs configured"); + app.apply_special_app_behavior(&special, &group_identifier, &cert_identity) .await .context("Failed to modify app bundle")?; @@ -147,6 +147,8 @@ impl Sideloader { .download_team_provisioning_profile(&team, &main_app_id, None) .await?; + info!("Acquired provisioning profile"); + app.bundle.write_info()?; for ext in app.bundle.app_extensions_mut() { ext.write_info()?; @@ -161,34 +163,18 @@ impl Sideloader { ) .await?; - let mut settings = Self::signing_settings(&cert_identity)?; - let entitlements: Dictionary = Self::entitlements_from_prov( - provisioning_profile.encoded_profile.as_ref(), + sign::sign( + &mut app, + &cert_identity, + &provisioning_profile, &special, &team, - )?; - - settings - .set_entitlements_xml( - apple_codesign::SettingsScope::Main, - plist_to_xml_string(&entitlements), - ) - .context("Failed to set entitlements XML")?; - let signer = UnifiedSigner::new(settings); - - for bundle in app.bundle.collect_bundles_sorted() { - info!("Signing bundle {}", bundle.bundle_dir.display()); - signer - .sign_path_in_place(&bundle.bundle_dir) - .context(format!( - "Failed to sign bundle: {}", - bundle.bundle_dir.display() - ))?; - } + ) + .context("Failed to sign app")?; info!("App signed!"); - Ok(app.bundle.bundle_dir.clone()) + Ok((app.bundle.bundle_dir.clone(), special)) } #[cfg(feature = "install")] @@ -197,7 +183,7 @@ impl Sideloader { device_provider: &impl IdeviceProvider, app_path: PathBuf, increased_memory_limit: bool, - ) -> Result<(), Report> { + ) -> Result, Report> { let device_info = IdeviceInfo::from_device(device_provider).await?; let team = self.get_team().await?; @@ -205,11 +191,11 @@ impl Sideloader { .ensure_device_registered(&team, &device_info.name, &device_info.udid, None) .await?; - let signed_app_path = self + let (signed_app_path, special_app) = self .sign_app(app_path, Some(team), increased_memory_limit) .await?; - info!("Installing..."); + info!("Transferring App..."); crate::sideload::install::install_app(device_provider, &signed_app_path, |progress| { info!("Installing: {}%", progress); @@ -217,7 +203,7 @@ impl Sideloader { .await .context("Failed to install app on device")?; - Ok(()) + Ok(special_app) } /// Get the developer team according to the configured team selection behavior pub async fn get_team(&mut self) -> Result { @@ -246,64 +232,4 @@ impl Sideloader { } }) } - - pub fn signing_settings<'a>( - cert: &'a CertificateIdentity, - ) -> Result, Report> { - let mut settings = SigningSettings::default(); - - cert.setup_signing_settings(&mut settings)?; - settings.set_for_notarization(false); - settings.set_shallow(true); - - Ok(settings) - } - - fn entitlements_from_prov( - data: &[u8], - special: &Option, - team: &DeveloperTeam, - ) -> Result { - let start = data - .windows(6) - .position(|w| w == b"") - .ok_or_report()? - + 8; - let plist_data = &data[start..end]; - let plist = plist::Value::from_reader_xml(plist_data)?; - - let mut entitlements = plist - .as_dictionary() - .ok_or_report()? - .get_dict("Entitlements")? - .clone(); - - if matches!( - special, - Some(SpecialApp::SideStoreLc) | Some(SpecialApp::LiveContainer) - ) { - let mut keychain_access = vec![plist::Value::String(format!( - "{}.com.kdt.livecontainer.shared", - team.team_id - ))]; - - for number in 1..128 { - keychain_access.push(plist::Value::String(format!( - "{}.com.kdt.livecontainer.shared.{}", - team.team_id, number - ))); - } - - entitlements.insert( - "keychain-access-groups".to_string(), - plist::Value::Array(keychain_access), - ); - } - - Ok(entitlements) - } } diff --git a/isideload/src/sideload/sign.rs b/isideload/src/sideload/sign.rs new file mode 100644 index 0000000..837116e --- /dev/null +++ b/isideload/src/sideload/sign.rs @@ -0,0 +1,114 @@ +use apple_codesign::{SigningSettings, UnifiedSigner}; +use plist::Dictionary; +use plist_macro::plist_to_xml_string; +use rootcause::{option_ext::OptionExt, prelude::*}; +use tracing::info; + +use crate::{ + dev::{app_ids::Profile, teams::DeveloperTeam}, + sideload::{ + application::{Application, SpecialApp}, + cert_identity::CertificateIdentity, + }, + util::plist::PlistDataExtract, +}; + +pub fn sign( + app: &mut Application, + cert_identity: &CertificateIdentity, + provisioning_profile: &Profile, + special: &Option, + team: &DeveloperTeam, +) -> Result<(), Report> { + let mut settings = signing_settings(cert_identity)?; + let entitlements: Dictionary = entitlements_from_prov( + provisioning_profile.encoded_profile.as_ref(), + &special, + &team, + )?; + + settings + .set_entitlements_xml( + apple_codesign::SettingsScope::Main, + plist_to_xml_string(&entitlements), + ) + .context("Failed to set entitlements XML")?; + let signer = UnifiedSigner::new(settings); + + for bundle in app.bundle.collect_bundles_sorted() { + info!( + "Signing {}", + bundle + .bundle_dir + .file_name() + .unwrap_or(bundle.bundle_dir.as_os_str()) + .to_string_lossy() + ); + signer + .sign_path_in_place(&bundle.bundle_dir) + .context(format!( + "Failed to sign bundle: {}", + bundle.bundle_dir.display() + ))?; + } + + Ok(()) +} + +pub fn signing_settings<'a>(cert: &'a CertificateIdentity) -> Result, Report> { + let mut settings = SigningSettings::default(); + + cert.setup_signing_settings(&mut settings)?; + settings.set_for_notarization(false); + settings.set_shallow(true); + + Ok(settings) +} + +fn entitlements_from_prov( + data: &[u8], + special: &Option, + team: &DeveloperTeam, +) -> Result { + let start = data + .windows(6) + .position(|w| w == b"") + .ok_or_report()? + + 8; + let plist_data = &data[start..end]; + let plist = plist::Value::from_reader_xml(plist_data)?; + + let mut entitlements = plist + .as_dictionary() + .ok_or_report()? + .get_dict("Entitlements")? + .clone(); + + if matches!( + special, + Some(SpecialApp::SideStoreLc) | Some(SpecialApp::LiveContainer) + ) { + let mut keychain_access = vec![plist::Value::String(format!( + "{}.com.kdt.livecontainer.shared", + team.team_id + ))]; + + for number in 1..128 { + keychain_access.push(plist::Value::String(format!( + "{}.com.kdt.livecontainer.shared.{}", + team.team_id, number + ))); + } + + entitlements.insert( + "keychain-access-groups".to_string(), + plist::Value::Array(keychain_access), + ); + } + + Ok(entitlements) +}