-
-
Notifications
You must be signed in to change notification settings - Fork 182
/
connect.go
executable file
·147 lines (132 loc) · 5.09 KB
/
connect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package ios
import (
"fmt"
)
type connectMessage struct {
BundleID string
ClientVersionString string
MessageType string
ProgName string
LibUSBMuxVersion uint32 `plist:"kLibUSBMuxVersion"`
DeviceID uint32
PortNumber uint16
}
func newConnectMessage(deviceID int, portNumber uint16) connectMessage {
data := connectMessage{
BundleID: "go.ios.control",
ClientVersionString: "go-usbmux-0.0.1",
MessageType: "Connect",
ProgName: "go-usbmux",
LibUSBMuxVersion: 3,
DeviceID: uint32(deviceID),
PortNumber: portNumber,
}
return data
}
//Connect issues a Connect Message to UsbMuxd for the given deviceID on the given port
//enabling the newCodec for it.
//It returns an error containing the UsbMux error code should the connect fail.
func (muxConn *UsbMuxConnection) Connect(deviceID int, port uint16) error {
msg := newConnectMessage(deviceID, Ntohs(port))
muxConn.Send(msg)
resp, err := muxConn.ReadMessage()
if err != nil {
return err
}
response := MuxResponsefromBytes(resp.Payload)
if response.IsSuccessFull() {
return nil
}
return fmt.Errorf("Failed connecting to service, error code:%d", response.Number)
}
//serviceConfigurations stores info about which DTX based services only execute a SSL Handshake
//and then go back to sending unencrypted data right after the handshake.
var serviceConfigurations = map[string]bool{
"com.apple.instruments.remoteserver": true,
"com.apple.accessibility.axAuditDaemon.remoteserver": true,
"com.apple.testmanagerd.lockdown": true,
"com.apple.debugserver": true,
}
//ConnectLockdown connects this Usbmux connection to the LockDown service that
// always runs on the device on the same port. The connect call needs the deviceID which can be
// retrieved from a DeviceList using the ListDevices function. After this function
// is done, the UsbMuxConnection cannot be used anymore because the same underlying
// network connection is used for talking to Lockdown. Sending usbmux commands would break it.
// It returns a new LockDownConnection.
func (muxConn *UsbMuxConnection) ConnectLockdown(deviceID int) (*LockDownConnection, error) {
msg := newConnectMessage(deviceID, Lockdownport)
err := muxConn.Send(msg)
if err != nil {
return &LockDownConnection{}, err
}
resp, err := muxConn.ReadMessage()
if err != nil {
return &LockDownConnection{}, err
}
response := MuxResponsefromBytes(resp.Payload)
if response.IsSuccessFull() {
return &LockDownConnection{muxConn.deviceConn, "", NewPlistCodec()}, nil
}
return nil, fmt.Errorf("Failed connecting to Lockdown with error code:%d", response.Number)
}
//ConnectToService connects to a service on the phone and returns the ready to use DeviceConnectionInterface
func ConnectToService(device DeviceEntry, serviceName string) (DeviceConnectionInterface, error) {
startServiceResponse, err := StartService(device, serviceName)
if err != nil {
return nil, err
}
pairRecord, err := ReadPairRecord(device.Properties.SerialNumber)
if err != nil {
return nil, err
}
muxConn, err := NewUsbMuxConnectionSimple()
if err != nil {
return nil, fmt.Errorf("Could not connect to usbmuxd socket, is it running? %w", err)
}
err = muxConn.connectWithStartServiceResponse(device.DeviceID, startServiceResponse, pairRecord)
if err != nil {
return nil, err
}
return muxConn.ReleaseDeviceConnection(), nil
}
//connectWithStartServiceResponse issues a Connect Message to UsbMuxd for the given deviceID on the given port
//enabling the newCodec for it. It also enables SSL on the new service connection if requested by StartServiceResponse.
//It returns an error containing the UsbMux error code should the connect fail.
func (muxConn *UsbMuxConnection) connectWithStartServiceResponse(deviceID int, startServiceResponse StartServiceResponse, pairRecord PairRecord) error {
err := muxConn.Connect(deviceID, startServiceResponse.Port)
if err != nil {
return err
}
var sslerr error
if startServiceResponse.EnableServiceSSL {
if _, ok := serviceConfigurations[startServiceResponse.Service]; ok {
sslerr = muxConn.deviceConn.EnableSessionSslHandshakeOnly(pairRecord)
} else {
sslerr = muxConn.deviceConn.EnableSessionSsl(pairRecord)
}
if sslerr != nil {
return sslerr
}
}
return nil
}
func ConnectLockdownWithSession(device DeviceEntry) (*LockDownConnection, error) {
muxConnection, err := NewUsbMuxConnectionSimple()
if err != nil {
return nil, fmt.Errorf("USBMuxConnection failed with: %v", err)
}
defer muxConnection.ReleaseDeviceConnection()
pairRecord, err := muxConnection.ReadPair(device.Properties.SerialNumber)
if err != nil {
return nil, fmt.Errorf("could not retrieve PairRecord with error: %v", err)
}
lockdownConnection, err := muxConnection.ConnectLockdown(device.DeviceID)
if err != nil {
return nil, fmt.Errorf("Lockdown connection failed with: %v", err)
}
resp, err := lockdownConnection.StartSession(pairRecord)
if err != nil {
return nil, fmt.Errorf("StartSession failed: %+v error: %v", resp, err)
}
return lockdownConnection, nil
}