mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Partial diagnostics relay implementation
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
name = "idevice"
|
||||
description = "A Rust library to interact with services on iOS devices."
|
||||
authors = ["Jackson Coxson"]
|
||||
version = "0.1.36"
|
||||
version = "0.1.37"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
documentation = "https://docs.rs/idevice"
|
||||
@@ -62,6 +62,7 @@ core_device = ["xpc", "dep:uuid"]
|
||||
core_device_proxy = ["dep:serde_json", "dep:json", "dep:byteorder"]
|
||||
crashreportcopymobile = ["afc"]
|
||||
debug_proxy = []
|
||||
diagnostics_relay = []
|
||||
dvt = ["dep:byteorder", "dep:ns-keyed-archive"]
|
||||
heartbeat = ["tokio/macros", "tokio/time"]
|
||||
house_arrest = ["afc"]
|
||||
@@ -88,6 +89,7 @@ full = [
|
||||
"core_device_proxy",
|
||||
"crashreportcopymobile",
|
||||
"debug_proxy",
|
||||
"diagnostics_relay",
|
||||
"dvt",
|
||||
"heartbeat",
|
||||
"house_arrest",
|
||||
|
||||
113
idevice/src/services/diagnostics_relay.rs
Normal file
113
idevice/src/services/diagnostics_relay.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
//! Diagnostics Relay
|
||||
|
||||
use crate::{lockdown::LockdownClient, obf, Idevice, IdeviceError, IdeviceService};
|
||||
|
||||
/// Client for interacting with the Diagnostics Relay
|
||||
pub struct DiagnosticsRelayClient {
|
||||
/// The underlying device connection with established service
|
||||
pub idevice: Idevice,
|
||||
}
|
||||
|
||||
impl IdeviceService for DiagnosticsRelayClient {
|
||||
/// Returns the service name as registered with lockdownd
|
||||
fn service_name() -> std::borrow::Cow<'static, str> {
|
||||
obf!("com.apple.mobile.diagnostics_relay")
|
||||
}
|
||||
|
||||
/// Establishes a connection to the service
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `provider` - Device connection provider
|
||||
///
|
||||
/// # Returns
|
||||
/// A connected `DiagnosticsRelayClient` instance
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns `IdeviceError` if any step of the connection process fails
|
||||
///
|
||||
/// # Process
|
||||
/// 1. Connects to lockdownd service
|
||||
/// 2. Starts a lockdown session
|
||||
/// 3. Requests the service port
|
||||
/// 4. Establishes connection to the port
|
||||
/// 5. Optionally starts TLS if required by service
|
||||
async fn connect(
|
||||
provider: &dyn crate::provider::IdeviceProvider,
|
||||
) -> Result<Self, IdeviceError> {
|
||||
let mut lockdown = LockdownClient::connect(provider).await?;
|
||||
lockdown
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.await?;
|
||||
|
||||
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||
|
||||
let mut idevice = provider.connect(port).await?;
|
||||
if ssl {
|
||||
idevice
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(Self { idevice })
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticsRelayClient {
|
||||
/// Creates a new client from an existing device connection
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `idevice` - Pre-established device connection
|
||||
pub fn new(idevice: Idevice) -> Self {
|
||||
Self { idevice }
|
||||
}
|
||||
|
||||
/// Requests data from the IO registry
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `current_plane` - The plane to request the tree as
|
||||
/// * `entry_name` - The entry to get
|
||||
/// * `entry_class` - The class to filter by
|
||||
///
|
||||
/// # Returns
|
||||
/// A plist of the tree on success
|
||||
pub async fn ioregistry(
|
||||
&mut self,
|
||||
current_plane: Option<impl Into<String>>,
|
||||
entry_name: Option<impl Into<String>>,
|
||||
entry_class: Option<impl Into<String>>,
|
||||
) -> Result<Option<plist::Dictionary>, IdeviceError> {
|
||||
let mut req = plist::Dictionary::new();
|
||||
if let Some(plane) = current_plane {
|
||||
let plane = plane.into();
|
||||
req.insert("CurrentPlane".into(), plane.into());
|
||||
}
|
||||
if let Some(name) = entry_name {
|
||||
let name = name.into();
|
||||
req.insert("EntryName".into(), name.into());
|
||||
}
|
||||
if let Some(class) = entry_class {
|
||||
let class = class.into();
|
||||
req.insert("EntryClass".into(), class.into());
|
||||
}
|
||||
req.insert("Request".into(), "IORegistry".into());
|
||||
self.idevice
|
||||
.send_plist(plist::Value::Dictionary(req))
|
||||
.await?;
|
||||
let mut res = self.idevice.read_plist().await?;
|
||||
|
||||
match res.get("Status").and_then(|x| x.as_string()) {
|
||||
Some("Success") => {}
|
||||
_ => {
|
||||
return Err(IdeviceError::UnexpectedResponse);
|
||||
}
|
||||
}
|
||||
|
||||
let res = res
|
||||
.remove("Diagnostics")
|
||||
.and_then(|x| x.into_dictionary())
|
||||
.and_then(|mut x| x.remove("IORegistry"))
|
||||
.and_then(|x| x.into_dictionary());
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ pub mod core_device_proxy;
|
||||
pub mod crashreportcopymobile;
|
||||
#[cfg(feature = "debug_proxy")]
|
||||
pub mod debug_proxy;
|
||||
#[cfg(feature = "diagnostics_relay")]
|
||||
pub mod diagnostics_relay;
|
||||
#[cfg(feature = "dvt")]
|
||||
pub mod dvt;
|
||||
#[cfg(feature = "heartbeat")]
|
||||
|
||||
Reference in New Issue
Block a user