-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat(apple-tv): add tunnel service for verified connections #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds Apple TV tunnel service functionality with pair verification protocol support for already-paired devices. The implementation extends the pairing storage system with device loading/listing capabilities, introduces a new CLI script for establishing Apple TV tunnel connections, migrates logging from @appium/support to an internal logger, and removes unused code.
- Implements pair verification protocol for secure tunnel establishment with previously-paired Apple TV devices
- Adds X25519 key exchange and ChaCha20-Poly1305 encryption for tunnel security
- Extends pairing storage with
load()andgetAvailableDeviceIds()methods
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| src/services/ios/mobile-config/index.ts | Replaces unused error variable with catch-all and improves logging level for profile removal |
| src/services/ios/afc/stream-utils.ts | Removes unused totalRead tracking variable |
| src/services/ios/afc/index.ts | Removes unused imports buildReadPayload and nextReadChunkSize |
| src/lib/tunnel/packet-stream-server.ts | Removes unused SerializedPacketMessage interface |
| src/lib/tunnel/index.ts | Removes unused TunnelResult interface |
| src/lib/plist/length-based-splitter.ts | Removes dead code for XML/binary plist detection that was never used |
| src/lib/lockdown/index.ts | Removes unused StartSessionRequest interface |
| src/lib/bonjour/bonjour-discovery.ts | Adjusts logging levels to reduce verbosity of discovery operations |
| src/lib/apple-tv/tunnel/types.ts | Defines TcpListenerInfo interface for tunnel service responses |
| src/lib/apple-tv/tunnel/tunnel-service.ts | Implements TLS-PSK tunnel connection and encrypted TCP listener creation |
| src/lib/apple-tv/tunnel/index.ts | Exports tunnel service components |
| src/lib/apple-tv/storage/types.ts | Adds PairRecord interface and extends storage interface with load/list methods |
| src/lib/apple-tv/storage/pairing-storage.ts | Implements pair record loading, device ID enumeration, and migrates to internal logger |
| src/lib/apple-tv/storage/index.ts | Exports PairRecord type |
| src/lib/apple-tv/pairing/user-input-service.ts | Migrates from @appium/support logger to internal logger |
| src/lib/apple-tv/pairing-protocol/pairing-protocol.ts | Migrates to internal logger |
| src/lib/apple-tv/pairing-protocol/pair-verification-protocol.ts | Implements 4-step pair verification protocol with X25519 key exchange |
| src/lib/apple-tv/pairing-protocol/index.ts | Exports pair verification protocol components |
| src/lib/apple-tv/pairing-protocol/constants.ts | Adds constants for pair verification, encryption messages, and states |
| src/lib/apple-tv/network/network-client.ts | Migrates to internal logger |
| src/lib/apple-tv/index.ts | Exports tunnel service module |
| src/lib/apple-tv/encryption/x25519.ts | Implements X25519 key pair generation and Diffie-Hellman exchange |
| src/lib/apple-tv/encryption/index.ts | Exports X25519 encryption utilities |
| src/lib/apple-tv/discovery/device-discovery.ts | Migrates to internal logger |
| scripts/start-appletv-tunnel.ts | CLI script for establishing Apple TV tunnels with pair verification and registry server |
| scripts/pair-appletv.ts | Migrates to internal logger |
| package.json | Adds start-appletv-tunnel npm script |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/lib/apple-tv/pairing-protocol/pair-verification-protocol.ts
Outdated
Show resolved
Hide resolved
| const PACKET_STREAM_PORT = 50100; | ||
|
|
||
| class AppleTVTunnelService { | ||
| private logger = getLogger('AppleTVTunnelService'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if it make sense to make the logger to an instance variable. We do not want different class instances to have different loggers. Consider moving it to module level/making static
| private logger = getLogger('AppleTVTunnelService'); | ||
| private networkClient: NetworkClient; | ||
| private storage: PairingStorage; | ||
| private sequenceNumber = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
number?
| const devices = await this.discoverDevices(); | ||
|
|
||
| this.logger.debug('Step 1: Device Discovery success'); | ||
| this.logger.debug(`Found ${devices.length} device(s) via Bonjour`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider using util.pluralize helper from @appium/support
| @@ -0,0 +1,416 @@ | |||
| #!/usr/bin/env tsx | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider refactoring this script and move appropriate APIs to their (potentially reusable) libraries. The script itself should only contain the client code.
|
|
||
| constructor( | ||
| private readonly networkClient: NetworkClientInterface, | ||
| sequenceNumber: number, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sequenceNumber might also be defined here
| pairRecord: PairRecord, | ||
| deviceId: string, | ||
| ): Promise<VerificationKeys> { | ||
| PairVerificationProtocol.log.debug( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having class name as a prefix is redundant. Consider moving the logger instance to the module root
| const errorCode = state4TLV[PairingDataComponentType.ERROR] as Buffer; | ||
| const errorDecimal = errorCode[0]; | ||
|
|
||
| const errorDescriptions: Record<number, string> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be a global constant?
| }, | ||
| ]); | ||
|
|
||
| const payload: PairingRequest = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see some unnecessary duplication while building this payload
| let item = this.box.getItem(itemName); | ||
|
|
||
| if (!item) { | ||
| item = await this.box.createItem(itemName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be simplified to const item = this.box.getItem(itemName) ?? await this.box.createItem(itemName)
| ); | ||
| return deviceIds; | ||
| } catch (error) { | ||
| this.log.error('Error getting available device IDs:', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any reason to mute this error?
Creates a tunnel for paired appletv connections. The code uses pair-record from strongbox -> validates (uses pair verification protocol) and creates the tunnel