111 lines
4 KiB
JavaScript
111 lines
4 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.LockdowndClient = void 0;
|
|
const Debug = require("debug");
|
|
const tls = require("tls");
|
|
const lockdown_1 = require("../protocol/lockdown");
|
|
const client_1 = require("./client");
|
|
const debug = Debug('native-run:ios:lib:client:lockdownd');
|
|
function isLockdowndServiceResponse(resp) {
|
|
return resp.Request === 'StartService' && resp.Service !== undefined && resp.Port !== undefined;
|
|
}
|
|
function isLockdowndSessionResponse(resp) {
|
|
return resp.Request === 'StartSession';
|
|
}
|
|
function isLockdowndAllValuesResponse(resp) {
|
|
return resp.Request === 'GetValue' && resp.Value !== undefined;
|
|
}
|
|
function isLockdowndValueResponse(resp) {
|
|
return resp.Request === 'GetValue' && resp.Key !== undefined && typeof resp.Value === 'string';
|
|
}
|
|
function isLockdowndQueryTypeResponse(resp) {
|
|
return resp.Request === 'QueryType' && resp.Type !== undefined;
|
|
}
|
|
class LockdowndClient extends client_1.ServiceClient {
|
|
constructor(socket) {
|
|
super(socket, new lockdown_1.LockdownProtocolClient(socket));
|
|
this.socket = socket;
|
|
}
|
|
async startService(name) {
|
|
debug(`startService: ${name}`);
|
|
const resp = await this.protocolClient.sendMessage({
|
|
Request: 'StartService',
|
|
Service: name,
|
|
});
|
|
if (isLockdowndServiceResponse(resp)) {
|
|
return { port: resp.Port, enableServiceSSL: !!resp.EnableServiceSSL };
|
|
}
|
|
else {
|
|
throw new client_1.ResponseError(`Error starting service ${name}`, resp);
|
|
}
|
|
}
|
|
async startSession(pairRecord) {
|
|
debug(`startSession: ${pairRecord}`);
|
|
const resp = await this.protocolClient.sendMessage({
|
|
Request: 'StartSession',
|
|
HostID: pairRecord.HostID,
|
|
SystemBUID: pairRecord.SystemBUID,
|
|
});
|
|
if (isLockdowndSessionResponse(resp)) {
|
|
if (resp.EnableSessionSSL) {
|
|
this.protocolClient.socket = new tls.TLSSocket(this.protocolClient.socket, {
|
|
secureContext: tls.createSecureContext({
|
|
secureProtocol: 'TLSv1_2_method',
|
|
cert: pairRecord.RootCertificate,
|
|
key: pairRecord.RootPrivateKey,
|
|
}),
|
|
});
|
|
debug(`Socket upgraded to TLS connection`);
|
|
}
|
|
// TODO: save sessionID for StopSession?
|
|
}
|
|
else {
|
|
throw new client_1.ResponseError('Error starting session', resp);
|
|
}
|
|
}
|
|
async getAllValues() {
|
|
debug(`getAllValues`);
|
|
const resp = await this.protocolClient.sendMessage({ Request: 'GetValue' });
|
|
if (isLockdowndAllValuesResponse(resp)) {
|
|
return resp.Value;
|
|
}
|
|
else {
|
|
throw new client_1.ResponseError('Error getting lockdown value', resp);
|
|
}
|
|
}
|
|
async getValue(val) {
|
|
debug(`getValue: ${val}`);
|
|
const resp = await this.protocolClient.sendMessage({
|
|
Request: 'GetValue',
|
|
Key: val,
|
|
});
|
|
if (isLockdowndValueResponse(resp)) {
|
|
return resp.Value;
|
|
}
|
|
else {
|
|
throw new client_1.ResponseError('Error getting lockdown value', resp);
|
|
}
|
|
}
|
|
async queryType() {
|
|
debug('queryType');
|
|
const resp = await this.protocolClient.sendMessage({
|
|
Request: 'QueryType',
|
|
});
|
|
if (isLockdowndQueryTypeResponse(resp)) {
|
|
return resp.Type;
|
|
}
|
|
else {
|
|
throw new client_1.ResponseError('Error getting lockdown query type', resp);
|
|
}
|
|
}
|
|
async doHandshake(pairRecord) {
|
|
debug('doHandshake');
|
|
// if (await this.lockdownQueryType() !== 'com.apple.mobile.lockdown') {
|
|
// throw new Error('Invalid type received from lockdown handshake');
|
|
// }
|
|
// await this.getLockdownValue('ProductVersion');
|
|
// TODO: validate pair and pair
|
|
await this.startSession(pairRecord);
|
|
}
|
|
}
|
|
exports.LockdowndClient = LockdowndClient;
|