mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Enable SSL on iOS < 5
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1582,7 +1582,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.106",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ pub unsafe extern "C" fn idevice_rsd_checkin(idevice: *mut IdeviceHandle) -> *mu
|
|||||||
pub unsafe extern "C" fn idevice_start_session(
|
pub unsafe extern "C" fn idevice_start_session(
|
||||||
idevice: *mut IdeviceHandle,
|
idevice: *mut IdeviceHandle,
|
||||||
pairing_file: *const IdevicePairingFile,
|
pairing_file: *const IdevicePairingFile,
|
||||||
|
legacy: bool,
|
||||||
) -> *mut IdeviceFfiError {
|
) -> *mut IdeviceFfiError {
|
||||||
if idevice.is_null() || pairing_file.is_null() {
|
if idevice.is_null() || pairing_file.is_null() {
|
||||||
return ffi_err!(IdeviceError::FfiInvalidArg);
|
return ffi_err!(IdeviceError::FfiInvalidArg);
|
||||||
@@ -350,7 +351,7 @@ pub unsafe extern "C" fn idevice_start_session(
|
|||||||
let pf = unsafe { &(*pairing_file).0 };
|
let pf = unsafe { &(*pairing_file).0 };
|
||||||
|
|
||||||
// Run the start_session method in the runtime
|
// Run the start_session method in the runtime
|
||||||
let result = run_sync(async { dev.start_session(pf).await });
|
let result = run_sync(async move { dev.start_session(pf, legacy).await });
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => null_mut(),
|
Ok(_) => null_mut(),
|
||||||
|
|||||||
@@ -76,6 +76,18 @@ pub trait IdeviceService: Sized {
|
|||||||
#[allow(async_fn_in_trait)]
|
#[allow(async_fn_in_trait)]
|
||||||
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
||||||
let mut lockdown = LockdownClient::connect(provider).await?;
|
let mut lockdown = LockdownClient::connect(provider).await?;
|
||||||
|
|
||||||
|
let legacy = lockdown
|
||||||
|
.get_value(Some("ProductVersion"), None)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.as_string())
|
||||||
|
.and_then(|x| x.split(".").next())
|
||||||
|
.and_then(|x| x.parse::<u8>().ok())
|
||||||
|
.map(|x| x < 5)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
lockdown
|
lockdown
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -90,7 +102,7 @@ pub trait IdeviceService: Sized {
|
|||||||
let mut idevice = provider.connect(port).await?;
|
let mut idevice = provider.connect(port).await?;
|
||||||
if ssl {
|
if ssl {
|
||||||
idevice
|
idevice
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +476,7 @@ impl Idevice {
|
|||||||
pub async fn start_session(
|
pub async fn start_session(
|
||||||
&mut self,
|
&mut self,
|
||||||
pairing_file: &pairing_file::PairingFile,
|
pairing_file: &pairing_file::PairingFile,
|
||||||
|
legacy: bool,
|
||||||
) -> Result<(), IdeviceError> {
|
) -> Result<(), IdeviceError> {
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
{
|
{
|
||||||
@@ -523,15 +536,16 @@ impl Idevice {
|
|||||||
}
|
}
|
||||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||||
{
|
{
|
||||||
let connector =
|
let mut connector =
|
||||||
openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls()).unwrap();
|
openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls())?;
|
||||||
|
if legacy {
|
||||||
|
connector.set_min_proto_version(Some(openssl::ssl::SslVersion::SSL3))?;
|
||||||
|
connector.set_max_proto_version(Some(openssl::ssl::SslVersion::TLS1))?;
|
||||||
|
connector.set_cipher_list("ALL:!aNULL:!eNULL:@SECLEVEL=0")?;
|
||||||
|
connector.set_options(openssl::ssl::SslOptions::ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
|
||||||
|
}
|
||||||
|
|
||||||
let mut connector = connector
|
let mut connector = connector.build().configure()?.into_ssl("ur mom")?;
|
||||||
.build()
|
|
||||||
.configure()
|
|
||||||
.unwrap()
|
|
||||||
.into_ssl("ur mom")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
connector.set_certificate(&pairing_file.host_certificate)?;
|
connector.set_certificate(&pairing_file.host_certificate)?;
|
||||||
connector.set_private_key(&pairing_file.host_private_key)?;
|
connector.set_private_key(&pairing_file.host_private_key)?;
|
||||||
@@ -553,18 +567,18 @@ impl Idevice {
|
|||||||
pub enum IdeviceError {
|
pub enum IdeviceError {
|
||||||
#[error("device socket io failed")]
|
#[error("device socket io failed")]
|
||||||
Socket(#[from] io::Error) = -1,
|
Socket(#[from] io::Error) = -1,
|
||||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
#[cfg(feature = "rustls")]
|
||||||
#[error("PEM parse failed")]
|
#[error("PEM parse failed")]
|
||||||
PemParseFailed(#[from] rustls::pki_types::pem::Error) = -2,
|
PemParseFailed(#[from] rustls::pki_types::pem::Error) = -2,
|
||||||
|
|
||||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
#[cfg(feature = "rustls")]
|
||||||
#[error("TLS error")]
|
#[error("TLS error")]
|
||||||
Rustls(#[from] rustls::Error) = -3,
|
Rustls(#[from] rustls::Error) = -3,
|
||||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||||
#[error("TLS error")]
|
#[error("TLS error")]
|
||||||
Rustls(#[from] openssl::ssl::Error) = -3,
|
Rustls(#[from] openssl::ssl::Error) = -3,
|
||||||
|
|
||||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
#[cfg(feature = "rustls")]
|
||||||
#[error("TLS verifiction build failed")]
|
#[error("TLS verifiction build failed")]
|
||||||
TlsBuilderFailed(#[from] rustls::server::VerifierBuilderError) = -4,
|
TlsBuilderFailed(#[from] rustls::server::VerifierBuilderError) = -4,
|
||||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||||
@@ -817,6 +831,7 @@ impl IdeviceError {
|
|||||||
pub fn code(&self) -> i32 {
|
pub fn code(&self) -> i32 {
|
||||||
match self {
|
match self {
|
||||||
IdeviceError::Socket(_) => -1,
|
IdeviceError::Socket(_) => -1,
|
||||||
|
#[cfg(feature = "rustls")]
|
||||||
IdeviceError::PemParseFailed(_) => -2,
|
IdeviceError::PemParseFailed(_) => -2,
|
||||||
IdeviceError::Rustls(_) => -3,
|
IdeviceError::Rustls(_) => -3,
|
||||||
IdeviceError::TlsBuilderFailed(_) => -4,
|
IdeviceError::TlsBuilderFailed(_) => -4,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||||
use openssl::{
|
use openssl::{
|
||||||
pkey::{PKey, Private},
|
pkey::{PKey, Private},
|
||||||
x509::X509,
|
x509::X509,
|
||||||
@@ -237,6 +237,7 @@ impl TryFrom<RawPairingFile> for PairingFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rustls")]
|
||||||
impl From<PairingFile> for RawPairingFile {
|
impl From<PairingFile> for RawPairingFile {
|
||||||
/// Converts a structured pairing file into a raw pairing file for serialization
|
/// Converts a structured pairing file into a raw pairing file for serialization
|
||||||
fn from(value: PairingFile) -> Self {
|
fn from(value: PairingFile) -> Self {
|
||||||
@@ -264,6 +265,26 @@ impl From<PairingFile> for RawPairingFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||||
|
impl TryFrom<PairingFile> for RawPairingFile {
|
||||||
|
type Error = openssl::error::ErrorStack;
|
||||||
|
|
||||||
|
fn try_from(value: PairingFile) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self {
|
||||||
|
device_certificate: Data::new(value.device_certificate.to_pem()?),
|
||||||
|
host_private_key: Data::new(value.host_private_key.private_key_to_pem_pkcs8()?),
|
||||||
|
host_certificate: Data::new(value.host_certificate.to_pem()?),
|
||||||
|
root_private_key: Data::new(value.root_private_key.private_key_to_pem_pkcs8()?),
|
||||||
|
root_certificate: Data::new(value.root_certificate.to_pem()?),
|
||||||
|
system_buid: value.system_buid,
|
||||||
|
host_id: value.host_id.clone(),
|
||||||
|
escrow_bag: Data::new(value.escrow_bag),
|
||||||
|
wifi_mac_address: value.wifi_mac_address,
|
||||||
|
udid: value.udid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper function to ensure data has proper PEM headers
|
/// Helper function to ensure data has proper PEM headers
|
||||||
/// If the data already has headers, it returns it as is
|
/// If the data already has headers, it returns it as is
|
||||||
/// If not, it adds the appropriate BEGIN and END headers
|
/// If not, it adds the appropriate BEGIN and END headers
|
||||||
|
|||||||
@@ -124,6 +124,18 @@ pub async fn flush_reports(
|
|||||||
provider: &dyn crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<(), IdeviceError> {
|
) -> Result<(), IdeviceError> {
|
||||||
let mut lockdown = LockdownClient::connect(provider).await?;
|
let mut lockdown = LockdownClient::connect(provider).await?;
|
||||||
|
|
||||||
|
let legacy = lockdown
|
||||||
|
.get_value(Some("ProductVersion"), None)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.as_string())
|
||||||
|
.and_then(|x| x.split(".").next())
|
||||||
|
.and_then(|x| x.parse::<u8>().ok())
|
||||||
|
.map(|x| x < 5)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
lockdown
|
lockdown
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -135,7 +147,7 @@ pub async fn flush_reports(
|
|||||||
let mut idevice = provider.connect(port).await?;
|
let mut idevice = provider.connect(port).await?;
|
||||||
if ssl {
|
if ssl {
|
||||||
idevice
|
idevice
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,18 @@ impl crate::IdeviceService for remote_server::RemoteServerClient<Box<dyn ReadWri
|
|||||||
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
||||||
// Establish Lockdown session
|
// Establish Lockdown session
|
||||||
let mut lockdown = LockdownClient::connect(provider).await?;
|
let mut lockdown = LockdownClient::connect(provider).await?;
|
||||||
|
|
||||||
|
let legacy = lockdown
|
||||||
|
.get_value(Some("ProductVersion"), None)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.as_string())
|
||||||
|
.and_then(|x| x.split(".").next())
|
||||||
|
.and_then(|x| x.parse::<u8>().ok())
|
||||||
|
.map(|x| x < 5)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
lockdown
|
lockdown
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -56,7 +68,7 @@ impl crate::IdeviceService for remote_server::RemoteServerClient<Box<dyn ReadWri
|
|||||||
let mut idevice = provider.connect(port).await?;
|
let mut idevice = provider.connect(port).await?;
|
||||||
if ssl {
|
if ssl {
|
||||||
idevice
|
idevice
|
||||||
.start_session(&provider.get_pairing_file().await?)
|
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
// Convert to transport and build client
|
// Convert to transport and build client
|
||||||
|
|||||||
@@ -157,6 +157,17 @@ impl LockdownClient {
|
|||||||
return Err(IdeviceError::NoEstablishedConnection);
|
return Err(IdeviceError::NoEstablishedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let legacy = self
|
||||||
|
.get_value(Some("ProductVersion"), None)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|x| x.as_string())
|
||||||
|
.and_then(|x| x.split(".").next())
|
||||||
|
.and_then(|x| x.parse::<u8>().ok())
|
||||||
|
.map(|x| x < 5)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
let request = crate::plist!({
|
let request = crate::plist!({
|
||||||
"Label": self.idevice.label.clone(),
|
"Label": self.idevice.label.clone(),
|
||||||
"Request": "StartSession",
|
"Request": "StartSession",
|
||||||
@@ -178,7 +189,7 @@ impl LockdownClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.idevice.start_session(pairing_file).await?;
|
self.idevice.start_session(pairing_file, legacy).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user