1use crate::{Idevice, IdeviceError, IdeviceService, obf};
4
5pub struct AmfiClient {
7 pub idevice: Idevice,
9}
10
11impl IdeviceService for AmfiClient {
12 fn service_name() -> std::borrow::Cow<'static, str> {
14 obf!("com.apple.amfi.lockdown")
15 }
16
17 async fn from_stream(idevice: Idevice) -> Result<Self, crate::IdeviceError> {
18 Ok(Self::new(idevice))
19 }
20}
21
22impl AmfiClient {
23 pub fn new(idevice: Idevice) -> Self {
28 Self { idevice }
29 }
30
31 pub async fn reveal_developer_mode_option_in_ui(&mut self) -> Result<(), IdeviceError> {
34 let request = crate::plist!({
35 "action": 0,
36 });
37 self.idevice.send_plist(request).await?;
38
39 let res = self.idevice.read_plist().await?;
40 if res.get("success").is_some() {
41 Ok(())
42 } else {
43 Err(IdeviceError::UnexpectedResponse)
44 }
45 }
46
47 pub async fn enable_developer_mode(&mut self) -> Result<(), IdeviceError> {
49 let request = crate::plist!({
50 "action": 1,
51 });
52 self.idevice.send_plist(request).await?;
53
54 let res = self.idevice.read_plist().await?;
55 if res.get("success").is_some() {
56 Ok(())
57 } else {
58 Err(IdeviceError::UnexpectedResponse)
59 }
60 }
61
62 pub async fn accept_developer_mode(&mut self) -> Result<(), IdeviceError> {
64 let request = crate::plist!({
65 "action": 2,
66 });
67 self.idevice.send_plist(request).await?;
68
69 let res = self.idevice.read_plist().await?;
70 if res.get("success").is_some() {
71 Ok(())
72 } else {
73 Err(IdeviceError::UnexpectedResponse)
74 }
75 }
76
77 pub async fn get_developer_mode_status(&mut self) -> Result<bool, IdeviceError> {
79 let request = crate::plist!({
80 "action": 3,
81 });
82 self.idevice.send_plist(request).await?;
83
84 let res = self.idevice.read_plist().await?;
85 match res.get("success").and_then(|x| x.as_boolean()) {
86 Some(true) => (),
87 _ => return Err(IdeviceError::UnexpectedResponse),
88 }
89
90 match res.get("status").and_then(|x| x.as_boolean()) {
91 Some(b) => Ok(b),
92 _ => Err(IdeviceError::UnexpectedResponse),
93 }
94 }
95
96 pub async fn trust_app_signer(
98 &mut self,
99 uuid: impl Into<String>,
100 ) -> Result<bool, IdeviceError> {
101 let request = crate::plist!({
102 "action": 4,
103 "input_profile_uuid": uuid.into(),
104 });
105
106 self.idevice.send_plist(request).await?;
107
108 let res = self.idevice.read_plist().await?;
109 match res.get("success").and_then(|x| x.as_boolean()) {
110 Some(true) => (),
111 _ => return Err(IdeviceError::UnexpectedResponse),
112 }
113
114 match res.get("status").and_then(|x| x.as_boolean()) {
115 Some(b) => Ok(b),
116 _ => Err(IdeviceError::UnexpectedResponse),
117 }
118 }
119}