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 = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[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(
|
||||
idevice: *mut IdeviceHandle,
|
||||
pairing_file: *const IdevicePairingFile,
|
||||
legacy: bool,
|
||||
) -> *mut IdeviceFfiError {
|
||||
if idevice.is_null() || pairing_file.is_null() {
|
||||
return ffi_err!(IdeviceError::FfiInvalidArg);
|
||||
@@ -350,7 +351,7 @@ pub unsafe extern "C" fn idevice_start_session(
|
||||
let pf = unsafe { &(*pairing_file).0 };
|
||||
|
||||
// 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 {
|
||||
Ok(_) => null_mut(),
|
||||
|
||||
@@ -76,6 +76,18 @@ pub trait IdeviceService: Sized {
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
||||
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
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.await?;
|
||||
@@ -90,7 +102,7 @@ pub trait IdeviceService: Sized {
|
||||
let mut idevice = provider.connect(port).await?;
|
||||
if ssl {
|
||||
idevice
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||
.await?;
|
||||
}
|
||||
|
||||
@@ -464,6 +476,7 @@ impl Idevice {
|
||||
pub async fn start_session(
|
||||
&mut self,
|
||||
pairing_file: &pairing_file::PairingFile,
|
||||
legacy: bool,
|
||||
) -> Result<(), IdeviceError> {
|
||||
#[cfg(feature = "rustls")]
|
||||
{
|
||||
@@ -523,15 +536,16 @@ impl Idevice {
|
||||
}
|
||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||
{
|
||||
let connector =
|
||||
openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls()).unwrap();
|
||||
let mut connector =
|
||||
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
|
||||
.build()
|
||||
.configure()
|
||||
.unwrap()
|
||||
.into_ssl("ur mom")
|
||||
.unwrap();
|
||||
let mut connector = connector.build().configure()?.into_ssl("ur mom")?;
|
||||
|
||||
connector.set_certificate(&pairing_file.host_certificate)?;
|
||||
connector.set_private_key(&pairing_file.host_private_key)?;
|
||||
@@ -553,18 +567,18 @@ impl Idevice {
|
||||
pub enum IdeviceError {
|
||||
#[error("device socket io failed")]
|
||||
Socket(#[from] io::Error) = -1,
|
||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
||||
#[cfg(feature = "rustls")]
|
||||
#[error("PEM parse failed")]
|
||||
PemParseFailed(#[from] rustls::pki_types::pem::Error) = -2,
|
||||
|
||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
||||
#[cfg(feature = "rustls")]
|
||||
#[error("TLS error")]
|
||||
Rustls(#[from] rustls::Error) = -3,
|
||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||
#[error("TLS error")]
|
||||
Rustls(#[from] openssl::ssl::Error) = -3,
|
||||
|
||||
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
|
||||
#[cfg(feature = "rustls")]
|
||||
#[error("TLS verifiction build failed")]
|
||||
TlsBuilderFailed(#[from] rustls::server::VerifierBuilderError) = -4,
|
||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||
@@ -817,6 +831,7 @@ impl IdeviceError {
|
||||
pub fn code(&self) -> i32 {
|
||||
match self {
|
||||
IdeviceError::Socket(_) => -1,
|
||||
#[cfg(feature = "rustls")]
|
||||
IdeviceError::PemParseFailed(_) => -2,
|
||||
IdeviceError::Rustls(_) => -3,
|
||||
IdeviceError::TlsBuilderFailed(_) => -4,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
|
||||
use openssl::{
|
||||
pkey::{PKey, Private},
|
||||
x509::X509,
|
||||
@@ -237,6 +237,7 @@ impl TryFrom<RawPairingFile> for PairingFile {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
impl From<PairingFile> for RawPairingFile {
|
||||
/// Converts a structured pairing file into a raw pairing file for serialization
|
||||
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
|
||||
/// If the data already has headers, it returns it as is
|
||||
/// If not, it adds the appropriate BEGIN and END headers
|
||||
|
||||
@@ -124,6 +124,18 @@ pub async fn flush_reports(
|
||||
provider: &dyn crate::provider::IdeviceProvider,
|
||||
) -> Result<(), IdeviceError> {
|
||||
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
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.await?;
|
||||
@@ -135,7 +147,7 @@ pub async fn flush_reports(
|
||||
let mut idevice = provider.connect(port).await?;
|
||||
if ssl {
|
||||
idevice
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,18 @@ impl crate::IdeviceService for remote_server::RemoteServerClient<Box<dyn ReadWri
|
||||
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
|
||||
// Establish Lockdown session
|
||||
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
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.await?;
|
||||
@@ -56,7 +68,7 @@ impl crate::IdeviceService for remote_server::RemoteServerClient<Box<dyn ReadWri
|
||||
let mut idevice = provider.connect(port).await?;
|
||||
if ssl {
|
||||
idevice
|
||||
.start_session(&provider.get_pairing_file().await?)
|
||||
.start_session(&provider.get_pairing_file().await?, legacy)
|
||||
.await?;
|
||||
}
|
||||
// Convert to transport and build client
|
||||
|
||||
@@ -157,6 +157,17 @@ impl LockdownClient {
|
||||
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!({
|
||||
"Label": self.idevice.label.clone(),
|
||||
"Request": "StartSession",
|
||||
@@ -178,7 +189,7 @@ impl LockdownClient {
|
||||
}
|
||||
}
|
||||
|
||||
self.idevice.start_session(pairing_file).await?;
|
||||
self.idevice.start_session(pairing_file, legacy).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user