Add local pairing bridge for web-based iOS signers - #28
Closed
Mora140 wants to merge 4 commits into
Closed
Conversation
…device's pairing record over 127.0.0.1, gated behind explicit in-app approval + a per-session bearer token
…r into its own Foundation-only file so the wire format can be tested without Network
|
lolol, pairing file is heart of access to device coz at this point the device blindly trusts the other side, why would one want it over http lol, and that to thru App Store hosted VPN that needs to be legally compliant and not be malicious. anyways am not sure abt intent, but this could be seen bad if exploited. |
Owner
|
For the sake of not wanting to poke the Apple bear, I'm going to say no to anything like this. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a loopback-only HTTP bridge so a web-based iOS signer running in Safari can ask LocalDevVPN to run the device pairing flow and hand back the resulting pairing record — the native piece a web app can't provide for itself.
The app already had two ways in (
localdevvpn://enable/disableand the App Intent), but both are one-shot commands with no way to return data. This extends the URL scheme with apairverb as the entry point from a website, and adds the missing return path as a127.0.0.1-only HTTP server. The packet tunnel is untouched — loopback traffic never enters it, so pairing works whether or not the VPN is connected.Authorization, not an anonymous read
GET /v1/pairing-recordnever answers a page that just probes localhost:Origin(which a page can't forge) plus a six-digit code the requesting page must display, so the user confirms the tab in front of them rather than a hidden one.Hostmust be the literal loopback authority, which blocks DNS rebinding.The bridge is off by default and only listens while the app is in the foreground, with a short background assertion so a page that was just handed a token can still fetch the record after Safari comes forward.
On the pairing flow itself
No public iOS API lets an app mint a lockdown pairing record for the device it runs on — iOS ≤16 needs a trusted host driving lockdownd, iOS 17+ uses
remotepairingdbehind an Apple-internal entitlement, andDeviceDiscoveryUIyields anNWEndpoint, not a pairing record. So the system-flow provider reports its availability honestly instead of reaching for private API, and the shipped path falls back to a user-driven pairing-file import through the document picker. APairingFlowProviderseam behind-D LOCALDEVVPN_NATIVE_PAIRINGlets an entitled build drop in a real PIN flow later without changing the API, the states, or the UI.No new entitlements, no
.pbxprojchanges (the project uses synchronized folder groups).Files
LocalDevVPN/Pairing/PairingRecord.swiftLocalDevVPN/Pairing/DevicePairingService.swiftLocalDevVPN/Pairing/PairingBridge.swiftLocalDevVPN/Pairing/PairingHTTPServer.swiftLocalDevVPN/Pairing/PairingHTTPMessages.swiftLocalDevVPN/Pairing/PairingBridgeViews.swiftPlus
docs/pairing-bridge.md(API reference, security model, iOS limitations) anddocs/pairing-bridge-demo.html(a self-contained test client).Test plan
19842–19844docs/pairing-bridge-demo.htmland run both flows end to end: thelocaldevvpn://pairdeep link and the polling/verification-code flowGET /v1/pairing-recordreturns 401 with no token, and only succeeds after approving in the appdocs/pairing-bridge.mdcovers the iOS API, entitlement, App Store, background-execution, Safari/CORS and networking limitations worth knowing about before reviewing.