Skip to content

Commit

Permalink
fruity: Support networked lockdown for CoreDevice
Browse files Browse the repository at this point in the history
Where we need to provide the remote unlock host key as part of the
RSDCheckin.

Kudos to @as0ler and @mrmacete for reporting and helping get to the
bottom of this one.
  • Loading branch information
oleavr committed Jan 23, 2025
1 parent af9c36c commit d1df792
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 18 deletions.
20 changes: 18 additions & 2 deletions src/fruity/device-monitor-macos.vala
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ namespace Frida.Fruity {
private ConnectionType _connection_type;
private string _udid;
private string _name;
private Bytes? _remote_unlock_host_key;

private Promise<Tunnel>? tunnel_request;

Expand All @@ -153,6 +154,13 @@ namespace Frida.Fruity {
var reader = new XpcObjectReader (device_info);
_name = reader.read_member ("name").get_string_value ();
reader.end_member ();

if (reader.has_member ("remoteUnlockHostKey")) {
_remote_unlock_host_key = new Bytes (reader.read_member ("remoteUnlockHostKey").get_data_value ());
reader.end_member ();
} else {
_remote_unlock_host_key = null;
}
}

private void on_state_changed (Object obj, ParamSpec pspec) {
Expand Down Expand Up @@ -224,7 +232,7 @@ namespace Frida.Fruity {
tunnel_request = new Promise<Tunnel> ();

try {
var tunnel = new MacOSTunnel (pairing_device);
var tunnel = new MacOSTunnel (pairing_device, _remote_unlock_host_key);
yield tunnel.attach (cancellable);

tunnel_request.resolve (tunnel);
Expand Down Expand Up @@ -252,20 +260,28 @@ namespace Frida.Fruity {
}
}

public Bytes? remote_unlock_host_key {
get {
return _remote_unlock_host_key;
}
}

public Darwin.Xpc.Uuid? assertion_identifier {
get {
return _assertion_identifier;
}
}

private XpcClient pairing_device;
private Bytes? _remote_unlock_host_key;
private Darwin.Xpc.Uuid? _assertion_identifier;
private InetAddress? tunnel_device_address;
private DiscoveryService? _discovery;
private int64 _opened_at = -1;

public MacOSTunnel (XpcClient pairing_device) {
public MacOSTunnel (XpcClient pairing_device, Bytes? remote_unlock_host_key) {
this.pairing_device = pairing_device;
_remote_unlock_host_key = remote_unlock_host_key;
}

public async void close (Cancellable? cancellable) throws IOError {
Expand Down
24 changes: 23 additions & 1 deletion src/fruity/device-monitor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ namespace Frida.Fruity {
checkin.set_string ("Request", "RSDCheckin");
checkin.set_string ("Label", "Xcode");
checkin.set_string ("ProtocolVersion", "2");
unowned Bytes? key = tunnel.remote_unlock_host_key;
if (key != null)
checkin.set_bytes ("EscrowBag", key);

try {
yield service.query (checkin, cancellable);
Expand Down Expand Up @@ -496,6 +499,10 @@ namespace Frida.Fruity {
get;
}

public abstract Bytes? remote_unlock_host_key {
get;
}

public abstract async void close (Cancellable? cancellable) throws IOError;
public abstract async IOStream open_tcp_connection (uint16 port, Cancellable? cancellable) throws Error, IOError;
}
Expand Down Expand Up @@ -1675,10 +1682,17 @@ namespace Frida.Fruity {
}
}

public Bytes? remote_unlock_host_key {
get {
return _remote_unlock_host_key;
}
}

private UsbNcmDriver? ncm;
private TunnelConnection? tunnel_connection;
private DiscoveryService? _discovery_service;
private int64 _opened_at = -1;
private Bytes? _remote_unlock_host_key;

public PortableUsbTunnel (UsbDevice device, NcmPeer peer, PairingStore store) {
Object (
Expand Down Expand Up @@ -1707,11 +1721,11 @@ namespace Frida.Fruity {
);
var pairing_transport = new XpcPairingTransport (yield netstack.open_tcp_connection (tunnel_endpoint, cancellable));
var pairing_service = yield PairingService.open (pairing_transport, pairing_store, cancellable);

TunnelConnection tc = yield pairing_service.open_tunnel (ncm_peer.ip, netstack, cancellable);
tc.closed.connect (on_tunnel_connection_close);

_opened_at = get_monotonic_time ();
_remote_unlock_host_key = pairing_service.established_peer.remote_unlock_host_key;

var rsd_endpoint = (InetSocketAddress) Object.new (typeof (InetSocketAddress),
address: tc.remote_address,
Expand Down Expand Up @@ -1880,9 +1894,16 @@ namespace Frida.Fruity {
}
}

public Bytes? remote_unlock_host_key {
get {
return _remote_unlock_host_key;
}
}

private TunnelConnection? tunnel_connection;
private DiscoveryService? _discovery_service;
private int64 _opened_at = -1;
private Bytes? _remote_unlock_host_key;

private const uint PAIRING_CONNECTION_TIMEOUT = 2000;

Expand All @@ -1905,6 +1926,7 @@ namespace Frida.Fruity {
TunnelConnection tc = yield pairing_service.open_tunnel (endpoint.get_address (), netstack, cancellable);

_opened_at = get_monotonic_time ();
_remote_unlock_host_key = pairing_service.established_peer.remote_unlock_host_key;

var rsd_endpoint = (InetSocketAddress) Object.new (typeof (InetSocketAddress),
address: tc.remote_address,
Expand Down
Loading

0 comments on commit d1df792

Please sign in to comment.