"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;