Skip to content

Commit fa1331f

Browse files
clarationhugeBlack
andauthored
refactor: options, signer, include team id picker (#4)
* some moving around * fix: clear entitlements before setting * fix: Correctly sign lc & sidestore (#3) - embeds altcertificate to lc+ss - can now add multiple appgroups, previously only accepted one due to poor api design - extra handling for sidestore ALTAppGroups * major refactor (super unfinished) * bring back some stuff * improve registering speed by 90% * team id picker --------- Co-authored-by: Huge_Black <60165378+hugeBlack@users.noreply.github.com>
1 parent 5768562 commit fa1331f

24 files changed

Lines changed: 888 additions & 698 deletions

File tree

.github/workflows/build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ on:
33
push:
44
branches:
55
- main
6+
paths:
7+
- 'crates/**'
8+
- 'Cargo.toml'
9+
- 'Cargo.lock'
10+
- 'apps/**'
11+
- 'package/**'
12+
- '.github/workflows/build.yml'
613
workflow_dispatch:
714

815
env:

Cargo.lock

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ resolver = "3"
33
members = [
44
"apps/plumeimpactor",
55
"apps/plumesign",
6-
"crates/grand_slam"
6+
"crates/grand_slam",
7+
"crates/utils"
78
]
89

910
[workspace.package]
@@ -30,7 +31,7 @@ incremental = true # Improves re-compile times
3031
tokio = { version = "1.43", features = ["macros", "rt-multi-thread"] }
3132

3233
# Application
33-
idevice = { git = "https://github.com/jkcoxson/idevice", rev = "ea61459", features = ["afc", "installation_proxy", "debug_proxy", "rsd", "tunnel_tcp_stack", "heartbeat", "usbmuxd"] }
34+
idevice = { git = "https://github.com/jkcoxson/idevice", rev = "ea61459", features = ["afc", "installation_proxy", "debug_proxy", "rsd", "tunnel_tcp_stack", "heartbeat", "usbmuxd", "house_arrest"] }
3435
zip = { version = "4.3", default-features = false, features = ["deflate"] }
3536
plist = "1.8.0"
3637
omnisette = { git = "https://github.com/PlumeImpactor/omnisette", rev = "ce1e5cc", package = "omnisette", features = ["remote-anisette-v3"] }
@@ -47,6 +48,7 @@ apple-codesign = { version = "0.29.0", default-features = false }
4748
uuid = "1.18.1"
4849
reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"] }
4950
serde_json = { version = "1" }
51+
futures = "0.3.31"
5052

5153
[patch.crates-io]
5254
srp = { path="./target/patch/srp-0.6.0" }

apps/plumeimpactor/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ repository.workspace = true
99

1010
[dependencies]
1111
idevice.workspace = true
12-
zip.workspace = true
1312
tokio.workspace = true
1413
thiserror.workspace = true
1514
uuid.workspace = true
1615
plist.workspace = true
16+
futures.workspace = true
1717
grand_slam = { path = "../../crates/grand_slam", features = ["vendored-botan"] }
18+
utils = { path = "../../crates/utils" }
1819

1920
wxdragon = "0.9.2"
20-
futures = "0.3.31"
2121
rustls = { version = "0.23.32", features = ["ring"] }
2222

2323
keyring = { version = "3.6.3", default-features = false, features = ["windows-native", "apple-native", "linux-native"] }
2424

2525
[target.'cfg(target_os = "windows")'.build-dependencies]
2626
embed-manifest = "1.4"
27-
winres = "0.1"
27+
winres = "0.1"

apps/plumeimpactor/src/frame.rs

Lines changed: 84 additions & 221 deletions
Large diffs are not rendered by default.

apps/plumeimpactor/src/handlers.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
use wxdragon::prelude::*;
2-
3-
use tokio::sync::mpsc;
4-
use tokio::sync::mpsc::error::TryRecvError;
2+
use tokio::sync::{
3+
mpsc,
4+
mpsc::error::TryRecvError
5+
};
56
use std::sync::mpsc as std_mpsc;
6-
77
use grand_slam::auth::Account;
8-
use grand_slam::utils::{PlistInfoTrait, SignerSettings};
9-
8+
use utils::{
9+
SignerOptions,
10+
Package,
11+
PlistInfoTrait,
12+
Device
13+
};
1014
use crate::frame::PlumeFrame;
1115
use crate::keychain::AccountCredentials;
12-
use crate::utils::{Device, Package};
1316

1417
#[derive(Debug)]
1518
pub enum PlumeFrameMessage {
@@ -20,6 +23,7 @@ pub enum PlumeFrameMessage {
2023
AccountLogin(Account),
2124
AccountDeleted,
2225
AwaitingTwoFactorCode(std_mpsc::Sender<Result<String, String>>),
26+
RequestTeamSelection(Vec<String>, std_mpsc::Sender<Result<i32, String>>),
2327
InstallProgress(i32, Option<String>),
2428
Error(String),
2529
}
@@ -36,15 +40,15 @@ pub struct PlumeFrameMessageHandler {
3640
// --- account ---
3741
pub account_credentials: Option<Account>,
3842
// --- signer settings ---
39-
pub signer_settings: SignerSettings,
43+
pub signer_settings: SignerOptions,
4044
}
4145

4246
impl PlumeFrameMessageHandler {
4347
pub fn new(
4448
receiver: mpsc::UnboundedReceiver<PlumeFrameMessage>,
4549
plume_frame: PlumeFrame,
4650
) -> Self {
47-
let signer_settings = SignerSettings::default();
51+
let signer_settings = SignerOptions::default();
4852
Self {
4953
receiver,
5054
plume_frame,
@@ -119,7 +123,7 @@ impl PlumeFrameMessageHandler {
119123
return;
120124
}
121125

122-
package.load_into_signer_settings(&mut self.signer_settings);
126+
package.load_into_signer_options(&mut self.signer_settings);
123127

124128
self.package_selected = Some(package);
125129
self.plume_frame.install_page.set_settings(&self.signer_settings, Some(self.package_selected.as_ref().unwrap()));
@@ -139,7 +143,7 @@ impl PlumeFrameMessageHandler {
139143
self.plume_frame.install_page.panel.hide();
140144
self.plume_frame.default_page.panel.show(true);
141145
self.plume_frame.frame.layout();
142-
self.signer_settings = SignerSettings::default();
146+
self.signer_settings = SignerOptions::default();
143147
self.plume_frame.install_page.set_settings(&self.signer_settings, None);
144148
self.plume_frame.add_ipa_button.enable(true);
145149
}
@@ -182,6 +186,17 @@ impl PlumeFrameMessageHandler {
182186
self.handle_message(PlumeFrameMessage::Error(format!("Failed to send two-factor code response: {}", e)));
183187
}
184188
}
189+
PlumeFrameMessage::RequestTeamSelection(teams, tx) => {
190+
let result = self.plume_frame.create_text_selection_dialog(
191+
"Select a Team",
192+
"Please select a team from the list:",
193+
teams,
194+
);
195+
196+
if let Err(e) = tx.send(result) {
197+
self.handle_message(PlumeFrameMessage::Error(format!("Failed to send team selection response: {}", e)));
198+
}
199+
}
185200
PlumeFrameMessage::InstallProgress(progress, message_opt) => {
186201
println!("Progress: {} - {:?}", progress, message_opt);
187202
let Some(selected_package) = &self.package_selected else {

apps/plumeimpactor/src/main.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ mod frame;
44
mod keychain;
55
mod pages;
66
mod handlers;
7-
mod utils;
87

98
use std::{
109
env,
@@ -25,18 +24,16 @@ use thiserror::Error as ThisError;
2524

2625
#[derive(Debug, ThisError)]
2726
pub enum Error {
28-
#[error("Info.plist not found")]
29-
PackageInfoPlistMissing,
3027
#[error("I/O error: {0}")]
3128
Io(#[from] std::io::Error),
3229
#[error("Plist error: {0}")]
3330
Plist(#[from] plist::Error),
34-
#[error("Zip error: {0}")]
35-
Zip(#[from] zip::result::ZipError),
3631
#[error("Idevice error: {0}")]
3732
Idevice(#[from] idevice::IdeviceError),
3833
#[error("GrandSlam error: {0}")]
3934
GrandSlam(#[from] grand_slam::Error),
35+
#[error("Utils error: {0}")]
36+
Utils(#[from] utils::Error),
4037
}
4138

4239
pub fn get_data_path() -> PathBuf {
@@ -51,4 +48,4 @@ pub fn get_data_path() -> PathBuf {
5148
fs::create_dir_all(&dir).ok();
5249

5350
dir
54-
}
51+
}

apps/plumeimpactor/src/pages/install.rs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use grand_slam::utils::{PlistInfoTrait, SignerSettings};
1+
use utils::{PlistInfoTrait, SignerOptions, Package};
22
use wxdragon::prelude::*;
33

4-
use crate::utils::Package;
5-
64
#[derive(Clone)]
75
pub struct InstallPage {
86
pub panel: Panel,
@@ -17,7 +15,6 @@ pub struct InstallPage {
1715
ipad_fullscreen_checkbox: CheckBox,
1816
game_mode_checkbox: CheckBox,
1917
pro_motion_checkbox: CheckBox,
20-
should_embed_pairing_checkbox: CheckBox,
2118
skip_registering_extensions_checkbox: CheckBox,
2219

2320
original_name: Option<String>,
@@ -80,10 +77,6 @@ pub fn create_install_page(frame: &Frame) -> InstallPage {
8077
let advanced_label = StaticText::builder(&panel)
8178
.with_label("Advanced:")
8279
.build();
83-
let should_embed_pairing_checkbox = CheckBox::builder(&panel)
84-
.with_label("Embed Pairing File")
85-
.build();
86-
should_embed_pairing_checkbox.enable(false);
8780
let skip_registering_extensions_checkbox = CheckBox::builder(&panel)
8881
.with_label("Only Register Main Bundle")
8982
.build();
@@ -94,8 +87,7 @@ pub fn create_install_page(frame: &Frame) -> InstallPage {
9487
checkbox_sizer.add(&game_mode_checkbox, 0, SizerFlag::Expand | SizerFlag::Top | SizerFlag::Left, 8);
9588
checkbox_sizer.add(&pro_motion_checkbox, 0, SizerFlag::Expand | SizerFlag::Top | SizerFlag::Left | SizerFlag::Bottom, 8);
9689
checkbox_sizer.add(&advanced_label, 0, SizerFlag::Top | SizerFlag::Bottom, 6);
97-
checkbox_sizer.add(&should_embed_pairing_checkbox, 0, SizerFlag::Expand | SizerFlag::Left, 8);
98-
checkbox_sizer.add(&skip_registering_extensions_checkbox, 0, SizerFlag::Expand | SizerFlag::Top | SizerFlag::Left, 8);
90+
checkbox_sizer.add(&skip_registering_extensions_checkbox, 0, SizerFlag::Expand | SizerFlag::Left, 8);
9991

10092
settings_sizer.add_sizer(&textfields_sizer, 1, SizerFlag::Expand | SizerFlag::Right, 13);
10193
settings_sizer.add_sizer(&checkbox_sizer, 1, SizerFlag::Expand, 13);
@@ -140,7 +132,6 @@ pub fn create_install_page(frame: &Frame) -> InstallPage {
140132
ipad_fullscreen_checkbox,
141133
game_mode_checkbox,
142134
pro_motion_checkbox,
143-
should_embed_pairing_checkbox,
144135
skip_registering_extensions_checkbox,
145136

146137
original_name: None,
@@ -151,14 +142,13 @@ pub fn create_install_page(frame: &Frame) -> InstallPage {
151142

152143

153144
impl InstallPage {
154-
pub fn set_settings(&mut self, settings: &SignerSettings, package: Option<&Package>) {
155-
self.support_older_versions_checkbox.set_value(settings.support_minimum_os_version);
156-
self.support_file_sharing_checkbox.set_value(settings.support_file_sharing);
157-
self.ipad_fullscreen_checkbox.set_value(settings.support_ipad_fullscreen);
158-
self.game_mode_checkbox.set_value(settings.support_game_mode);
159-
self.pro_motion_checkbox.set_value(settings.support_pro_motion);
160-
self.should_embed_pairing_checkbox.set_value(settings.should_embed_pairing);
161-
self.skip_registering_extensions_checkbox.set_value(settings.should_only_use_main_provisioning);
145+
pub fn set_settings(&mut self, settings: &SignerOptions, package: Option<&Package>) {
146+
self.support_older_versions_checkbox.set_value(settings.features.support_minimum_os_version);
147+
self.support_file_sharing_checkbox.set_value(settings.features.support_file_sharing);
148+
self.ipad_fullscreen_checkbox.set_value(settings.features.support_ipad_fullscreen);
149+
self.game_mode_checkbox.set_value(settings.features.support_game_mode);
150+
self.pro_motion_checkbox.set_value(settings.features.support_pro_motion);
151+
self.skip_registering_extensions_checkbox.set_value(settings.embedding.single_profile);
162152

163153
if let Some(package) = package {
164154
if let Some(ref name) = package.get_name() {
@@ -194,15 +184,14 @@ impl InstallPage {
194184
}
195185
}
196186

197-
pub fn update_fields(&self, settings: &mut SignerSettings) {
198-
settings.support_minimum_os_version = self.support_older_versions_checkbox.get_value();
199-
settings.support_file_sharing = self.support_file_sharing_checkbox.get_value();
200-
settings.support_ipad_fullscreen = self.ipad_fullscreen_checkbox.get_value();
201-
settings.support_game_mode = self.game_mode_checkbox.get_value();
202-
settings.support_pro_motion = self.pro_motion_checkbox.get_value();
203-
settings.should_embed_pairing = self.should_embed_pairing_checkbox.get_value();
204-
settings.should_only_use_main_provisioning = self.skip_registering_extensions_checkbox.get_value();
205-
187+
pub fn update_fields(&self, settings: &mut SignerOptions) {
188+
settings.features.support_minimum_os_version = self.support_older_versions_checkbox.get_value();
189+
settings.features.support_file_sharing = self.support_file_sharing_checkbox.get_value();
190+
settings.features.support_ipad_fullscreen = self.ipad_fullscreen_checkbox.get_value();
191+
settings.features.support_game_mode = self.game_mode_checkbox.get_value();
192+
settings.features.support_pro_motion = self.pro_motion_checkbox.get_value();
193+
settings.embedding.single_profile = self.skip_registering_extensions_checkbox.get_value();
194+
206195
if let Some(ref original_name) = self.original_name {
207196
let current_name = self.custom_name_textfield.get_value();
208197
if &current_name != original_name {

apps/plumeimpactor/src/pages/settings.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,6 @@ pub fn create_settings_dialog(parent: &Window) -> SettingsDialog {
111111

112112
sizer.add(&StaticLine::builder(&dialog).build(), 0, SizerFlag::Expand | SizerFlag::All, 13);
113113

114-
let cert_button_sizer = BoxSizer::builder(Orientation::Horizontal).build();
115-
let import_cert_button = Button::builder(&dialog).with_label("Import P12").build();
116-
import_cert_button.enable(false);
117-
let export_cert_button = Button::builder(&dialog).with_label("Export P12").build();
118-
export_cert_button.enable(false);
119-
cert_button_sizer.add(&import_cert_button, 1, SizerFlag::Expand, 0);
120-
cert_button_sizer.add_spacer(13);
121-
cert_button_sizer.add(&export_cert_button, 1, SizerFlag::Expand, 0);
122-
123-
sizer.add_sizer(&cert_button_sizer, 0, SizerFlag::Right | SizerFlag::Left, 13);
124-
125114
dialog.set_sizer(sizer, true);
126115

127116
SettingsDialog {
@@ -206,3 +195,21 @@ impl PlumeFrame {
206195
result
207196
}
208197
}
198+
199+
// MARK: - Text Selection Dialog
200+
impl PlumeFrame {
201+
pub fn create_text_selection_dialog(
202+
&self, title: &str,
203+
label: &str,
204+
choices: Vec<String>,
205+
) -> Result<i32, String> {
206+
let choice_refs: Vec<&str> = choices.iter().map(|s| s.as_str()).collect();
207+
let dialog = SingleChoiceDialog::builder(&self.frame, label, title, &choice_refs).build();
208+
let rc = dialog.show_modal();
209+
if rc == ID_OK as i32 {
210+
Ok(dialog.get_selection())
211+
} else {
212+
Err("Dialog cancelled".to_string())
213+
}
214+
}
215+
}

0 commit comments

Comments
 (0)