mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 06:26:15 +01:00
Change to tokio for io
This commit is contained in:
185
Cargo.lock
generated
185
Cargo.lock
generated
@@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler2"
|
name = "adler2"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -66,6 +75,27 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
@@ -87,6 +117,12 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.5"
|
version = "1.2.5"
|
||||||
@@ -250,6 +286,12 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.2"
|
version = "0.15.2"
|
||||||
@@ -382,7 +424,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idevice"
|
name = "idevice"
|
||||||
version = "0.1.5"
|
version = "0.1.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
@@ -391,6 +433,8 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-openssl",
|
||||||
"ureq",
|
"ureq",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -449,6 +493,16 @@ version = "0.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.22"
|
version = "0.4.22"
|
||||||
@@ -470,12 +524,32 @@ dependencies = [
|
|||||||
"adler2",
|
"adler2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.36.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.2"
|
version = "1.20.2"
|
||||||
@@ -520,12 +594,41 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@@ -578,6 +681,15 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
@@ -622,6 +734,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.21"
|
version = "0.23.21"
|
||||||
@@ -654,6 +772,12 @@ dependencies = [
|
|||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.216"
|
version = "1.0.216"
|
||||||
@@ -691,12 +815,31 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.9.8"
|
version = "0.9.8"
|
||||||
@@ -798,6 +941,46 @@ dependencies = [
|
|||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.43.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"bytes",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-openssl"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59df6849caa43bb7567f9a36f863c447d95a11d5903c9cc334ba32576a27eadd"
|
||||||
|
dependencies = [
|
||||||
|
"openssl",
|
||||||
|
"openssl-sys",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "idevice"
|
name = "idevice"
|
||||||
description = "A Rust library to interact with services on iOS devices."
|
description = "A Rust library to interact with services on iOS devices."
|
||||||
authors = ["Jackson Coxson"]
|
authors = ["Jackson Coxson"]
|
||||||
version = "0.1.5"
|
version = "0.1.6"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
documentation = "https://docs.rs/idevice"
|
documentation = "https://docs.rs/idevice"
|
||||||
@@ -12,6 +12,7 @@ keywords = ["lockdownd", "ios"]
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ideviceinfo"
|
name = "ideviceinfo"
|
||||||
path = "src/tools/ideviceinfo.rs"
|
path = "src/tools/ideviceinfo.rs"
|
||||||
|
required-features = ["bin"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "heartbeat_client"
|
name = "heartbeat_client"
|
||||||
@@ -27,6 +28,8 @@ path = "src/tools/mounter.rs"
|
|||||||
required-features = ["sha2", "ureq"]
|
required-features = ["sha2", "ureq"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
tokio = { version = "1.43", features = ["io-util"] }
|
||||||
|
tokio-openssl = { version = "0.6" }
|
||||||
plist = { version = "1.7" }
|
plist = { version = "1.7" }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
thiserror = { version = "2" }
|
thiserror = { version = "2" }
|
||||||
@@ -39,4 +42,4 @@ sha2 = { version = "0.10", optional = true }
|
|||||||
ureq = { version = "2.12", optional = true }
|
ureq = { version = "2.12", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std-tcp = []
|
bin = ["tokio/full", "sha2", "ureq"]
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ on an iOS device that a Mac normally would.
|
|||||||
|
|
||||||
## State
|
## State
|
||||||
|
|
||||||
|
**IMPORTANT**: Breaking changes will happen at each point release until 0.2.0.
|
||||||
|
The library is still in the development and brainstorming stage.
|
||||||
|
Pin your `Cargo.toml` to a specific version to avoid breakage.
|
||||||
|
|
||||||
This library is in development and research stage.
|
This library is in development and research stage.
|
||||||
Releases are being published to crates.io for use in other projects,
|
Releases are being published to crates.io for use in other projects,
|
||||||
but the API and feature-set are far from final or even planned.
|
but the API and feature-set are far from final or even planned.
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ impl HeartbeatClient {
|
|||||||
Self { idevice }
|
Self { idevice }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_marco(&mut self) -> Result<u64, IdeviceError> {
|
pub async fn get_marco(&mut self) -> Result<u64, IdeviceError> {
|
||||||
let rec = self.idevice.read_plist()?;
|
let rec = self.idevice.read_plist().await?;
|
||||||
match rec.get("Interval") {
|
match rec.get("Interval") {
|
||||||
Some(plist::Value::Integer(interval)) => {
|
Some(plist::Value::Integer(interval)) => {
|
||||||
if let Some(interval) = interval.as_unsigned() {
|
if let Some(interval) = interval.as_unsigned() {
|
||||||
@@ -35,12 +35,12 @@ impl HeartbeatClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_polo(&mut self) -> Result<(), IdeviceError> {
|
pub async fn send_polo(&mut self) -> Result<(), IdeviceError> {
|
||||||
let mut req = plist::Dictionary::new();
|
let mut req = plist::Dictionary::new();
|
||||||
req.insert("Command".into(), "Polo".into());
|
req.insert("Command".into(), "Polo".into());
|
||||||
self.idevice
|
self.idevice
|
||||||
.send_plist(plist::Value::Dictionary(req.clone()))
|
.send_plist(plist::Value::Dictionary(req.clone()))
|
||||||
.unwrap();
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ impl InstallationProxyClient {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// `application_type` - The application type to filter by
|
/// `application_type` - The application type to filter by
|
||||||
/// `bundle_identifiers` - The identifiers to filter by
|
/// `bundle_identifiers` - The identifiers to filter by
|
||||||
pub fn get_apps(
|
pub async fn get_apps(
|
||||||
&mut self,
|
&mut self,
|
||||||
application_type: Option<String>,
|
application_type: Option<String>,
|
||||||
bundle_identifiers: Option<Vec<String>>,
|
bundle_identifiers: Option<Vec<String>>,
|
||||||
@@ -37,9 +37,11 @@ impl InstallationProxyClient {
|
|||||||
let mut req = plist::Dictionary::new();
|
let mut req = plist::Dictionary::new();
|
||||||
req.insert("Command".into(), "Lookup".into());
|
req.insert("Command".into(), "Lookup".into());
|
||||||
// req.insert("ClientOptions".into(), plist::Value::Dictionary(options));
|
// req.insert("ClientOptions".into(), plist::Value::Dictionary(options));
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut res = self.idevice.read_plist()?;
|
let mut res = self.idevice.read_plist().await?;
|
||||||
match res.remove("LookupResult") {
|
match res.remove("LookupResult") {
|
||||||
Some(plist::Value::Dictionary(res)) => {
|
Some(plist::Value::Dictionary(res)) => {
|
||||||
Ok(res.into_iter().collect::<HashMap<String, plist::Value>>())
|
Ok(res.into_iter().collect::<HashMap<String, plist::Value>>())
|
||||||
|
|||||||
59
src/lib.rs
59
src/lib.rs
@@ -8,11 +8,12 @@ pub mod pairing_file;
|
|||||||
|
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
|
||||||
use std::io::{self, BufWriter, Read, Write};
|
use std::io::{self, BufWriter};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
|
|
||||||
pub trait ReadWrite: Read + Write + Send + Sync + std::fmt::Debug {}
|
pub trait ReadWrite: AsyncRead + AsyncWrite + Unpin + Send + Sync + std::fmt::Debug {}
|
||||||
impl<T: Read + Write + Send + Sync + std::fmt::Debug> ReadWrite for T {}
|
impl<T: AsyncRead + AsyncWrite + Unpin + Send + Sync + std::fmt::Debug> ReadWrite for T {}
|
||||||
|
|
||||||
pub struct Idevice {
|
pub struct Idevice {
|
||||||
socket: Option<Box<dyn ReadWrite>>, // in a box for now to use the ReadWrite trait for further uses
|
socket: Option<Box<dyn ReadWrite>>, // in a box for now to use the ReadWrite trait for further uses
|
||||||
@@ -27,26 +28,13 @@ impl Idevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std-tcp")]
|
pub async fn get_type(&mut self) -> Result<String, IdeviceError> {
|
||||||
pub fn connect_tcp(
|
|
||||||
addr: std::net::SocketAddr,
|
|
||||||
label: impl Into<String>,
|
|
||||||
) -> Result<Self, std::io::Error> {
|
|
||||||
let socket = std::net::TcpStream::connect(addr)?;
|
|
||||||
let label = label.into();
|
|
||||||
Ok(Self {
|
|
||||||
socket: Some(Box::new(socket)),
|
|
||||||
label,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_type(&mut self) -> Result<String, IdeviceError> {
|
|
||||||
let mut req = plist::Dictionary::new();
|
let mut req = plist::Dictionary::new();
|
||||||
req.insert("Label".into(), self.label.clone().into());
|
req.insert("Label".into(), self.label.clone().into());
|
||||||
req.insert("Request".into(), "QueryType".into());
|
req.insert("Request".into(), "QueryType".into());
|
||||||
let message = plist::to_value(&req)?;
|
let message = plist::to_value(&req)?;
|
||||||
self.send_plist(message)?;
|
self.send_plist(message).await?;
|
||||||
let message: plist::Dictionary = self.read_plist()?;
|
let message: plist::Dictionary = self.read_plist().await?;
|
||||||
match message.get("Type") {
|
match message.get("Type") {
|
||||||
Some(m) => Ok(plist::from_value(m)?),
|
Some(m) => Ok(plist::from_value(m)?),
|
||||||
None => Err(IdeviceError::UnexpectedResponse),
|
None => Err(IdeviceError::UnexpectedResponse),
|
||||||
@@ -54,7 +42,7 @@ impl Idevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a plist to the socket
|
/// Sends a plist to the socket
|
||||||
fn send_plist(&mut self, message: plist::Value) -> Result<(), IdeviceError> {
|
async fn send_plist(&mut self, message: plist::Value) -> Result<(), IdeviceError> {
|
||||||
if let Some(socket) = &mut self.socket {
|
if let Some(socket) = &mut self.socket {
|
||||||
let buf = Vec::new();
|
let buf = Vec::new();
|
||||||
let mut writer = BufWriter::new(buf);
|
let mut writer = BufWriter::new(buf);
|
||||||
@@ -62,8 +50,8 @@ impl Idevice {
|
|||||||
let message = writer.into_inner().unwrap();
|
let message = writer.into_inner().unwrap();
|
||||||
let message = String::from_utf8(message)?;
|
let message = String::from_utf8(message)?;
|
||||||
let len = message.len() as u32;
|
let len = message.len() as u32;
|
||||||
socket.write_all(&len.to_be_bytes())?;
|
socket.write_all(&len.to_be_bytes()).await?;
|
||||||
socket.write_all(message.as_bytes())?;
|
socket.write_all(message.as_bytes()).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(IdeviceError::NoEstablishedConnection)
|
Err(IdeviceError::NoEstablishedConnection)
|
||||||
@@ -71,23 +59,23 @@ impl Idevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends raw bytes to the socket
|
/// Sends raw bytes to the socket
|
||||||
fn send_raw(&mut self, message: &[u8]) -> Result<(), IdeviceError> {
|
async fn send_raw(&mut self, message: &[u8]) -> Result<(), IdeviceError> {
|
||||||
if let Some(socket) = &mut self.socket {
|
if let Some(socket) = &mut self.socket {
|
||||||
Ok(socket.write_all(message)?)
|
Ok(socket.write_all(message).await?)
|
||||||
} else {
|
} else {
|
||||||
Err(IdeviceError::NoEstablishedConnection)
|
Err(IdeviceError::NoEstablishedConnection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a plist from the socket
|
/// Read a plist from the socket
|
||||||
fn read_plist(&mut self) -> Result<plist::Dictionary, IdeviceError> {
|
async fn read_plist(&mut self) -> Result<plist::Dictionary, IdeviceError> {
|
||||||
if let Some(socket) = &mut self.socket {
|
if let Some(socket) = &mut self.socket {
|
||||||
debug!("Reading response size");
|
debug!("Reading response size");
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
socket.read_exact(&mut buf)?;
|
socket.read_exact(&mut buf).await?;
|
||||||
let len = u32::from_be_bytes(buf);
|
let len = u32::from_be_bytes(buf);
|
||||||
let mut buf = vec![0; len as usize];
|
let mut buf = vec![0; len as usize];
|
||||||
socket.read_exact(&mut buf)?;
|
socket.read_exact(&mut buf).await?;
|
||||||
let res: plist::Dictionary = plist::from_bytes(&buf)?;
|
let res: plist::Dictionary = plist::from_bytes(&buf)?;
|
||||||
debug!("Received plist: {res:#?}");
|
debug!("Received plist: {res:#?}");
|
||||||
|
|
||||||
@@ -106,11 +94,19 @@ impl Idevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps current connection in TLS
|
/// Wraps current connection in TLS
|
||||||
pub fn start_session(
|
pub async fn start_session(
|
||||||
&mut self,
|
&mut self,
|
||||||
pairing_file: &pairing_file::PairingFile,
|
pairing_file: &pairing_file::PairingFile,
|
||||||
) -> Result<(), IdeviceError> {
|
) -> Result<(), IdeviceError> {
|
||||||
let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();
|
let connector = SslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
|
|
||||||
|
let mut connector = connector
|
||||||
|
.build()
|
||||||
|
.configure()
|
||||||
|
.unwrap()
|
||||||
|
.into_ssl("ur mom")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
connector
|
connector
|
||||||
.set_certificate(&pairing_file.host_certificate)
|
.set_certificate(&pairing_file.host_certificate)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -119,9 +115,10 @@ impl Idevice {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
connector.set_verify(SslVerifyMode::empty());
|
connector.set_verify(SslVerifyMode::empty());
|
||||||
|
|
||||||
let connector = connector.build();
|
|
||||||
let socket = self.socket.take().unwrap();
|
let socket = self.socket.take().unwrap();
|
||||||
let ssl_stream = connector.connect("ur mom", socket).unwrap();
|
|
||||||
|
let mut ssl_stream = tokio_openssl::SslStream::new(connector, socket).unwrap();
|
||||||
|
std::pin::Pin::new(&mut ssl_stream).connect().await.unwrap();
|
||||||
self.socket = Some(Box::new(ssl_stream));
|
self.socket = Some(Box::new(ssl_stream));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -24,30 +24,30 @@ impl LockdowndClient {
|
|||||||
pub fn new(idevice: Idevice) -> Self {
|
pub fn new(idevice: Idevice) -> Self {
|
||||||
Self { idevice }
|
Self { idevice }
|
||||||
}
|
}
|
||||||
pub fn get_value(&mut self, value: impl Into<String>) -> Result<String, IdeviceError> {
|
pub async fn get_value(&mut self, value: impl Into<String>) -> Result<String, IdeviceError> {
|
||||||
let req = LockdowndRequest {
|
let req = LockdowndRequest {
|
||||||
label: self.idevice.label.clone(),
|
label: self.idevice.label.clone(),
|
||||||
key: Some(value.into()),
|
key: Some(value.into()),
|
||||||
request: "GetValue".to_string(),
|
request: "GetValue".to_string(),
|
||||||
};
|
};
|
||||||
let message = plist::to_value(&req)?;
|
let message = plist::to_value(&req)?;
|
||||||
self.idevice.send_plist(message)?;
|
self.idevice.send_plist(message).await?;
|
||||||
let message: plist::Dictionary = self.idevice.read_plist()?;
|
let message: plist::Dictionary = self.idevice.read_plist().await?;
|
||||||
match message.get("Value") {
|
match message.get("Value") {
|
||||||
Some(m) => Ok(plist::from_value(m)?),
|
Some(m) => Ok(plist::from_value(m)?),
|
||||||
None => Err(IdeviceError::UnexpectedResponse),
|
None => Err(IdeviceError::UnexpectedResponse),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_values(&mut self) -> Result<plist::Dictionary, IdeviceError> {
|
pub async fn get_all_values(&mut self) -> Result<plist::Dictionary, IdeviceError> {
|
||||||
let req = LockdowndRequest {
|
let req = LockdowndRequest {
|
||||||
label: self.idevice.label.clone(),
|
label: self.idevice.label.clone(),
|
||||||
key: None,
|
key: None,
|
||||||
request: "GetValue".to_string(),
|
request: "GetValue".to_string(),
|
||||||
};
|
};
|
||||||
let message = plist::to_value(&req)?;
|
let message = plist::to_value(&req)?;
|
||||||
self.idevice.send_plist(message)?;
|
self.idevice.send_plist(message).await?;
|
||||||
let message: plist::Dictionary = self.idevice.read_plist()?;
|
let message: plist::Dictionary = self.idevice.read_plist().await?;
|
||||||
match message.get("Value") {
|
match message.get("Value") {
|
||||||
Some(m) => Ok(plist::from_value(m)?),
|
Some(m) => Ok(plist::from_value(m)?),
|
||||||
None => Err(IdeviceError::UnexpectedResponse),
|
None => Err(IdeviceError::UnexpectedResponse),
|
||||||
@@ -55,7 +55,7 @@ impl LockdowndClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a TLS session with the client
|
/// Starts a TLS session with the client
|
||||||
pub fn start_session(
|
pub async fn start_session(
|
||||||
&mut self,
|
&mut self,
|
||||||
pairing_file: &pairing_file::PairingFile,
|
pairing_file: &pairing_file::PairingFile,
|
||||||
) -> Result<(), IdeviceError> {
|
) -> Result<(), IdeviceError> {
|
||||||
@@ -82,9 +82,11 @@ impl LockdowndClient {
|
|||||||
plist::Value::String(pairing_file.system_buid.clone()),
|
plist::Value::String(pairing_file.system_buid.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(request))?;
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(request))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let response = self.idevice.read_plist()?;
|
let response = self.idevice.read_plist().await?;
|
||||||
match response.get("EnableSessionSSL") {
|
match response.get("EnableSessionSSL") {
|
||||||
Some(plist::Value::Boolean(enable)) => {
|
Some(plist::Value::Boolean(enable)) => {
|
||||||
if !enable {
|
if !enable {
|
||||||
@@ -96,7 +98,7 @@ impl LockdowndClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.idevice.start_session(pairing_file)?;
|
self.idevice.start_session(pairing_file).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +107,7 @@ impl LockdowndClient {
|
|||||||
/// `identifier` - The identifier for the service you want to start
|
/// `identifier` - The identifier for the service you want to start
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// The port number and whether to enable SSL on success, `IdeviceError` on failure
|
/// The port number and whether to enable SSL on success, `IdeviceError` on failure
|
||||||
pub fn start_service(
|
pub async fn start_service(
|
||||||
&mut self,
|
&mut self,
|
||||||
identifier: impl Into<String>,
|
identifier: impl Into<String>,
|
||||||
) -> Result<(u16, bool), IdeviceError> {
|
) -> Result<(u16, bool), IdeviceError> {
|
||||||
@@ -113,8 +115,10 @@ impl LockdowndClient {
|
|||||||
let mut req = plist::Dictionary::new();
|
let mut req = plist::Dictionary::new();
|
||||||
req.insert("Request".into(), "StartService".into());
|
req.insert("Request".into(), "StartService".into());
|
||||||
req.insert("Service".into(), identifier.into());
|
req.insert("Service".into(), identifier.into());
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
let response = self.idevice.read_plist()?;
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
let response = self.idevice.read_plist().await?;
|
||||||
match response.get("EnableServiceSSL") {
|
match response.get("EnableServiceSSL") {
|
||||||
Some(plist::Value::Boolean(ssl)) => match response.get("Port") {
|
Some(plist::Value::Boolean(ssl)) => match response.get("Port") {
|
||||||
Some(plist::Value::Integer(port)) => {
|
Some(plist::Value::Integer(port)) => {
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ impl ImageMounter {
|
|||||||
Self { idevice }
|
Self { idevice }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_devices(&mut self) -> Result<Vec<plist::Value>, IdeviceError> {
|
pub async fn copy_devices(&mut self) -> Result<Vec<plist::Value>, IdeviceError> {
|
||||||
let mut req = plist::Dictionary::new();
|
let mut req = plist::Dictionary::new();
|
||||||
req.insert("Command".into(), "CopyDevices".into());
|
req.insert("Command".into(), "CopyDevices".into());
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
let mut res = self.idevice.read_plist()?;
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
let mut res = self.idevice.read_plist().await?;
|
||||||
|
|
||||||
match res.remove("EntryList") {
|
match res.remove("EntryList") {
|
||||||
Some(plist::Value::Array(i)) => Ok(i),
|
Some(plist::Value::Array(i)) => Ok(i),
|
||||||
@@ -23,7 +25,7 @@ impl ImageMounter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload_image(
|
pub async fn upload_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
image_type: impl Into<String>,
|
image_type: impl Into<String>,
|
||||||
image: &[u8],
|
image: &[u8],
|
||||||
@@ -36,9 +38,11 @@ impl ImageMounter {
|
|||||||
req.insert("ImageType".into(), image_type.into());
|
req.insert("ImageType".into(), image_type.into());
|
||||||
req.insert("ImageSize".into(), (image.len() as u64).into());
|
req.insert("ImageSize".into(), (image.len() as u64).into());
|
||||||
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let res = self.idevice.read_plist()?;
|
let res = self.idevice.read_plist().await?;
|
||||||
match res.get("Status") {
|
match res.get("Status") {
|
||||||
Some(plist::Value::String(s)) => {
|
Some(plist::Value::String(s)) => {
|
||||||
if s.as_str() != "ReceiveBytesAck" {
|
if s.as_str() != "ReceiveBytesAck" {
|
||||||
@@ -49,9 +53,9 @@ impl ImageMounter {
|
|||||||
_ => return Err(IdeviceError::UnexpectedResponse),
|
_ => return Err(IdeviceError::UnexpectedResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.idevice.send_raw(image)?;
|
self.idevice.send_raw(image).await?;
|
||||||
|
|
||||||
let res = self.idevice.read_plist()?;
|
let res = self.idevice.read_plist().await?;
|
||||||
match res.get("Status") {
|
match res.get("Status") {
|
||||||
Some(plist::Value::String(s)) => {
|
Some(plist::Value::String(s)) => {
|
||||||
if s.as_str() != "Success" {
|
if s.as_str() != "Success" {
|
||||||
@@ -65,7 +69,7 @@ impl ImageMounter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mount_image(
|
pub async fn mount_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
image_type: impl Into<String>,
|
image_type: impl Into<String>,
|
||||||
signature: Vec<u8>,
|
signature: Vec<u8>,
|
||||||
@@ -80,9 +84,11 @@ impl ImageMounter {
|
|||||||
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
||||||
req.insert("ImageTrustCache".into(), plist::Value::Data(trust_cache));
|
req.insert("ImageTrustCache".into(), plist::Value::Data(trust_cache));
|
||||||
req.insert("ImageInfoPlist".into(), info_plist);
|
req.insert("ImageInfoPlist".into(), info_plist);
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let res = self.idevice.read_plist()?;
|
let res = self.idevice.read_plist().await?;
|
||||||
|
|
||||||
match res.get("Status") {
|
match res.get("Status") {
|
||||||
Some(plist::Value::String(s)) => {
|
Some(plist::Value::String(s)) => {
|
||||||
@@ -99,7 +105,7 @@ impl ImageMounter {
|
|||||||
|
|
||||||
/// Queries the personalization manifest from the device.
|
/// Queries the personalization manifest from the device.
|
||||||
/// On failure, the socket must be closed and reestablished.
|
/// On failure, the socket must be closed and reestablished.
|
||||||
pub fn query_personalization_manifest(
|
pub async fn query_personalization_manifest(
|
||||||
&mut self,
|
&mut self,
|
||||||
image_type: impl Into<String>,
|
image_type: impl Into<String>,
|
||||||
signature: Vec<u8>,
|
signature: Vec<u8>,
|
||||||
@@ -111,9 +117,11 @@ impl ImageMounter {
|
|||||||
req.insert("PersonalizedImageType".into(), image_type.clone().into());
|
req.insert("PersonalizedImageType".into(), image_type.clone().into());
|
||||||
req.insert("ImageType".into(), image_type.into());
|
req.insert("ImageType".into(), image_type.into());
|
||||||
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
req.insert("ImageSignature".into(), plist::Value::Data(signature));
|
||||||
self.idevice.send_plist(plist::Value::Dictionary(req))?;
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut res = self.idevice.read_plist()?;
|
let mut res = self.idevice.read_plist().await?;
|
||||||
match res.remove("ImageSignature") {
|
match res.remove("ImageSignature") {
|
||||||
Some(plist::Value::Data(i)) => Ok(i),
|
Some(plist::Value::Data(i)) => Ok(i),
|
||||||
_ => Err(IdeviceError::NotFound),
|
_ => Err(IdeviceError::NotFound),
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ use std::{
|
|||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut host = None;
|
let mut host = None;
|
||||||
let mut pairing_file = None;
|
let mut pairing_file = None;
|
||||||
@@ -62,32 +63,33 @@ fn main() {
|
|||||||
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
||||||
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
||||||
|
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let idevice = Idevice::new(socket, "heartbeat_client");
|
let idevice = Idevice::new(socket, "heartbeat_client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
||||||
|
|
||||||
let mut lockdown_client = LockdowndClient { idevice };
|
let mut lockdown_client = LockdowndClient { idevice };
|
||||||
lockdown_client.start_session(&p).unwrap();
|
lockdown_client.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let (port, _) = lockdown_client
|
let (port, _) = lockdown_client
|
||||||
.start_service("com.apple.mobile.heartbeat")
|
.start_service("com.apple.mobile.heartbeat")
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let socket = SocketAddrV4::new(ip, port);
|
let socket = SocketAddrV4::new(ip, port);
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let mut idevice = Idevice::new(socket, "heartbeat_client");
|
let mut idevice = Idevice::new(socket, "heartbeat_client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
||||||
|
|
||||||
idevice.start_session(&p).unwrap();
|
idevice.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let mut heartbeat_client = HeartbeatClient { idevice };
|
let mut heartbeat_client = HeartbeatClient { idevice };
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
heartbeat_client.get_marco().unwrap();
|
heartbeat_client.get_marco().await.unwrap();
|
||||||
heartbeat_client.send_polo().unwrap();
|
heartbeat_client.send_polo().await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ use idevice::{
|
|||||||
Idevice,
|
Idevice,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut host = None;
|
let mut host = None;
|
||||||
let mut pairing_file = None;
|
let mut pairing_file = None;
|
||||||
@@ -61,15 +62,15 @@ fn main() {
|
|||||||
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
||||||
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
||||||
|
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let idevice = Idevice::new(socket, "ideviceinfo-jkcoxson");
|
let idevice = Idevice::new(socket, "ideviceinfo-jkcoxson");
|
||||||
|
|
||||||
let mut lockdown_client = LockdowndClient::new(idevice);
|
let mut lockdown_client = LockdowndClient::new(idevice);
|
||||||
println!("{:?}", lockdown_client.get_value("ProductVersion"));
|
println!("{:?}", lockdown_client.get_value("ProductVersion").await);
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
||||||
println!("{:?}", lockdown_client.start_session(&p));
|
println!("{:?}", lockdown_client.start_session(&p).await);
|
||||||
println!("{:?}", lockdown_client.idevice.get_type().unwrap());
|
println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());
|
||||||
println!("{:#?}", lockdown_client.get_all_values());
|
println!("{:#?}", lockdown_client.get_all_values().await);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ use std::{
|
|||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut host = None;
|
let mut host = None;
|
||||||
let mut pairing_file = None;
|
let mut pairing_file = None;
|
||||||
@@ -62,30 +63,31 @@ fn main() {
|
|||||||
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
||||||
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
||||||
|
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let idevice = Idevice::new(socket, "heartbeat_client");
|
let idevice = Idevice::new(socket, "heartbeat_client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
||||||
|
|
||||||
let mut lockdown_client = LockdowndClient { idevice };
|
let mut lockdown_client = LockdowndClient { idevice };
|
||||||
lockdown_client.start_session(&p).unwrap();
|
lockdown_client.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let (port, _) = lockdown_client
|
let (port, _) = lockdown_client
|
||||||
.start_service("com.apple.mobile.installation_proxy")
|
.start_service("com.apple.mobile.installation_proxy")
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let socket = SocketAddrV4::new(ip, port);
|
let socket = SocketAddrV4::new(ip, port);
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let mut idevice = Idevice::new(socket, "instproxy-client");
|
let mut idevice = Idevice::new(socket, "instproxy-client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
||||||
|
|
||||||
idevice.start_session(&p).unwrap();
|
idevice.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let mut instproxy_client = InstallationProxyClient::new(idevice);
|
let mut instproxy_client = InstallationProxyClient::new(idevice);
|
||||||
let apps = instproxy_client.get_apps(None, None).unwrap();
|
let apps = instproxy_client.get_apps(None, None).await.unwrap();
|
||||||
for app in apps.keys() {
|
for app in apps.keys() {
|
||||||
println!("{app}");
|
println!("{app}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ use std::{
|
|||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut host = None;
|
let mut host = None;
|
||||||
let mut pairing_file = None;
|
let mut pairing_file = None;
|
||||||
@@ -64,30 +65,31 @@ fn main() {
|
|||||||
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
let ip = Ipv4Addr::from_str(host.unwrap().as_str()).unwrap();
|
||||||
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
let socket = SocketAddrV4::new(ip, lockdownd::LOCKDOWND_PORT);
|
||||||
|
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let idevice = Idevice::new(socket, "mounter_client");
|
let idevice = Idevice::new(socket, "mounter_client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.as_ref().unwrap()).unwrap();
|
||||||
|
|
||||||
let mut lockdown_client = LockdowndClient { idevice };
|
let mut lockdown_client = LockdowndClient { idevice };
|
||||||
lockdown_client.start_session(&p).unwrap();
|
lockdown_client.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let (port, _) = lockdown_client
|
let (port, _) = lockdown_client
|
||||||
.start_service("com.apple.mobile.mobile_image_mounter")
|
.start_service("com.apple.mobile.mobile_image_mounter")
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let socket = SocketAddrV4::new(ip, port);
|
let socket = SocketAddrV4::new(ip, port);
|
||||||
let socket = std::net::TcpStream::connect(socket).unwrap();
|
let socket = tokio::net::TcpStream::connect(socket).await.unwrap();
|
||||||
let socket = Box::new(socket);
|
let socket = Box::new(socket);
|
||||||
let mut idevice = Idevice::new(socket, "mounter_client");
|
let mut idevice = Idevice::new(socket, "mounter_client");
|
||||||
|
|
||||||
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
let p = PairingFile::read_from_file(pairing_file.unwrap()).unwrap();
|
||||||
|
|
||||||
idevice.start_session(&p).unwrap();
|
idevice.start_session(&p).await.unwrap();
|
||||||
|
|
||||||
let mut mounter_client = ImageMounter::new(idevice);
|
let mut mounter_client = ImageMounter::new(idevice);
|
||||||
let images = mounter_client.copy_devices().unwrap();
|
let images = mounter_client.copy_devices().await.unwrap();
|
||||||
println!("Images: {images:#?}");
|
println!("Images: {images:#?}");
|
||||||
|
|
||||||
let image = std::fs::read("Image.dmg").unwrap();
|
let image = std::fs::read("Image.dmg").unwrap();
|
||||||
@@ -97,6 +99,7 @@ fn main() {
|
|||||||
|
|
||||||
let manifest = mounter_client
|
let manifest = mounter_client
|
||||||
.query_personalization_manifest("DeveloperDiskImage", hash.to_vec())
|
.query_personalization_manifest("DeveloperDiskImage", hash.to_vec())
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!("len: {}", manifest.len());
|
println!("len: {}", manifest.len());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user