mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Added Intel AMT tunneling configuration support.
This commit is contained in:
parent
b555fcbe43
commit
fd8265313d
8 changed files with 709 additions and 109 deletions
|
@ -35,6 +35,9 @@ function CreateAPFClient(parent, args) {
|
|||
obj.pfwd_idx = 0;
|
||||
obj.timer = null; // Keep alive timer
|
||||
|
||||
// obj.onChannelClosed
|
||||
// obj.onJsonControl
|
||||
|
||||
// Function copied from common.js
|
||||
function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }; // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
|
||||
function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); };
|
||||
|
@ -139,16 +142,14 @@ function CreateAPFClient(parent, args) {
|
|||
}
|
||||
|
||||
obj.onSecureConnect = function onSecureConnect(resp, ws, head) {
|
||||
//Debug("APF Secure WebSocket connected.");
|
||||
Debug("APF Secure WebSocket connected.");
|
||||
//console.log(JSON.stringify(resp));
|
||||
obj.forwardClient.tag = { accumulator: [] };
|
||||
obj.forwardClient.ws = ws;
|
||||
obj.forwardClient.ws.on('end', function () {
|
||||
//Debug("APF: Connection is closing.");
|
||||
if (obj.timer != null) {
|
||||
clearInterval(obj.timer);
|
||||
obj.timer = null;
|
||||
}
|
||||
Debug("APF: Connection is closing.");
|
||||
if (obj.timer != null) { clearInterval(obj.timer); obj.timer = null; }
|
||||
if (obj.onChannelClosed) { obj.onChannelClosed(obj); }
|
||||
});
|
||||
|
||||
obj.forwardClient.ws.on('data', function (data) {
|
||||
|
@ -159,21 +160,16 @@ function CreateAPFClient(parent, args) {
|
|||
len = ProcessData(obj.forwardClient);
|
||||
if (len > 0) { obj.forwardClient.tag.accumulator = obj.forwardClient.tag.accumulator.slice(len); }
|
||||
if (obj.cirastate == CIRASTATE.FAILED) {
|
||||
//Debug("APF: in a failed state, destroying socket.");
|
||||
Debug("APF: in a failed state, destroying socket.");
|
||||
obj.forwardClient.ws.end();
|
||||
}
|
||||
} while (len > 0);
|
||||
} catch (e) {
|
||||
Debug(e);
|
||||
}
|
||||
} catch (ex) { Debug(ex); }
|
||||
});
|
||||
|
||||
obj.forwardClient.ws.on('error', function (e) {
|
||||
//Debug("APF: Connection error, ending connecting.");
|
||||
if (obj.timer != null) {
|
||||
clearInterval(obj.timer);
|
||||
obj.timer = null;
|
||||
}
|
||||
Debug("APF: Connection error, ending connecting.");
|
||||
if (obj.timer != null) { clearInterval(obj.timer); obj.timer = null; }
|
||||
});
|
||||
|
||||
obj.state = CIRASTATE.INITIAL;
|
||||
|
@ -185,20 +181,20 @@ function CreateAPFClient(parent, args) {
|
|||
function SendJsonControl(socket, o) {
|
||||
var data = JSON.stringify(o)
|
||||
socket.write(String.fromCharCode(APFProtocol.JSON_CONTROL) + IntToStr(data.length) + data);
|
||||
//Debug("APF: Send JSON control: " + data);
|
||||
Debug("APF: Send JSON control: " + data);
|
||||
}
|
||||
|
||||
function SendProtocolVersion(socket, uuid) {
|
||||
var data = String.fromCharCode(APFProtocol.PROTOCOLVERSION) + IntToStr(1) + IntToStr(0) + IntToStr(0) + hex2rstr(strToGuid(uuid)) + binzerostring(64);
|
||||
socket.write(data);
|
||||
//Debug("APF: Send protocol version 1 0 " + uuid);
|
||||
Debug("APF: Send protocol version 1 0 " + uuid);
|
||||
obj.cirastate = CIRASTATE.PROTOCOL_VERSION_SENT;
|
||||
}
|
||||
|
||||
function SendServiceRequest(socket, service) {
|
||||
var data = String.fromCharCode(APFProtocol.SERVICE_REQUEST) + IntToStr(service.length) + service;
|
||||
socket.write(data);
|
||||
//Debug("APF: Send service request " + service);
|
||||
Debug("APF: Send service request " + service);
|
||||
if (service == 'auth@amt.intel.com') {
|
||||
obj.cirastate = CIRASTATE.AUTH_SERVICE_REQUEST_SENT;
|
||||
} else if (service == 'pfwd@amt.intel.com') {
|
||||
|
@ -213,7 +209,7 @@ function CreateAPFClient(parent, args) {
|
|||
data += IntToStr(8) + 'password';
|
||||
data += binzerostring(1) + IntToStr(pass.length) + pass;
|
||||
socket.write(data);
|
||||
//Debug("APF: Send username password authentication to MPS");
|
||||
Debug("APF: Send username password authentication to MPS");
|
||||
obj.cirastate = CIRASTATE.AUTH_REQUEST_SENT;
|
||||
}
|
||||
|
||||
|
@ -222,18 +218,18 @@ function CreateAPFClient(parent, args) {
|
|||
var data = String.fromCharCode(APFProtocol.GLOBAL_REQUEST) + IntToStr(tcpipfwd.length) + tcpipfwd + binzerostring(1, 1);
|
||||
data += IntToStr(amthostname.length) + amthostname + IntToStr(amtport);
|
||||
socket.write(data);
|
||||
//Debug("APF: Send tcpip-forward " + amthostname + ":" + amtport);
|
||||
Debug("APF: Send tcpip-forward " + amthostname + ":" + amtport);
|
||||
obj.cirastate = CIRASTATE.GLOBAL_REQUEST_SENT;
|
||||
}
|
||||
|
||||
function SendKeepAliveRequest(socket) {
|
||||
socket.write(String.fromCharCode(APFProtocol.KEEPALIVE_REQUEST) + IntToStr(255));
|
||||
//Debug("APF: Send keepalive request");
|
||||
Debug("APF: Send keepalive request");
|
||||
}
|
||||
|
||||
function SendKeepAliveReply(socket, cookie) {
|
||||
socket.write(String.fromCharCode(APFProtocol.KEEPALIVE_REPLY) + IntToStr(cookie));
|
||||
//Debug("APF: Send keepalive reply");
|
||||
Debug("APF: Send keepalive reply");
|
||||
}
|
||||
|
||||
function ProcessData(socket) {
|
||||
|
@ -246,7 +242,7 @@ function CreateAPFClient(parent, args) {
|
|||
switch (cmd) {
|
||||
case APFProtocol.SERVICE_ACCEPT: {
|
||||
var slen = ReadInt(data, 1), service = data.substring(5, 6 + slen);
|
||||
//Debug("APF: Service request to " + service + " accepted.");
|
||||
Debug("APF: Service request to " + service + " accepted.");
|
||||
if (service == 'auth@amt.intel.com') {
|
||||
if (obj.cirastate >= CIRASTATE.AUTH_SERVICE_REQUEST_SENT) {
|
||||
SendUserAuthRequest(socket.ws, obj.args.mpsuser, obj.args.mpspass);
|
||||
|
@ -261,47 +257,47 @@ function CreateAPFClient(parent, args) {
|
|||
case APFProtocol.REQUEST_SUCCESS: {
|
||||
if (len >= 5) {
|
||||
var port = ReadInt(data, 1);
|
||||
//Debug("APF: Request to port forward " + port + " successful.");
|
||||
Debug("APF: Request to port forward " + port + " successful.");
|
||||
// iterate to pending port forward request
|
||||
if (obj.pfwd_idx < pfwd_ports.length) {
|
||||
SendGlobalRequestPfwd(socket.ws, obj.args.clientname, pfwd_ports[obj.pfwd_idx++]);
|
||||
} else {
|
||||
// no more port forward, now setup timer to send keep alive
|
||||
//Debug("APF: Start keep alive for every " + obj.args.mpskeepalive + " ms.");
|
||||
Debug("APF: Start keep alive for every " + obj.args.mpskeepalive + " ms.");
|
||||
obj.timer = setInterval(function () {
|
||||
SendKeepAliveRequest(obj.forwardClient.ws);
|
||||
}, obj.args.mpskeepalive);//
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
//Debug("APF: Request successful.");
|
||||
Debug("APF: Request successful.");
|
||||
return 1;
|
||||
}
|
||||
case APFProtocol.USERAUTH_SUCCESS: {
|
||||
//Debug("APF: User Authentication successful");
|
||||
Debug("APF: User Authentication successful");
|
||||
// Send Pfwd service request
|
||||
SendServiceRequest(socket.ws, 'pfwd@amt.intel.com');
|
||||
return 1;
|
||||
}
|
||||
case APFProtocol.USERAUTH_FAILURE: {
|
||||
//Debug("APF: User Authentication failed");
|
||||
Debug("APF: User Authentication failed");
|
||||
obj.cirastate = CIRASTATE.FAILED;
|
||||
return 14;
|
||||
}
|
||||
case APFProtocol.KEEPALIVE_REQUEST: {
|
||||
//Debug("APF: Keep Alive Request with cookie: " + ReadInt(data, 1));
|
||||
Debug("APF: Keep Alive Request with cookie: " + ReadInt(data, 1));
|
||||
SendKeepAliveReply(socket.ws, ReadInt(data, 1));
|
||||
return 5;
|
||||
}
|
||||
case APFProtocol.KEEPALIVE_REPLY: {
|
||||
//Debug("APF: Keep Alive Reply with cookie: " + ReadInt(data, 1));
|
||||
Debug("APF: Keep Alive Reply with cookie: " + ReadInt(data, 1));
|
||||
return 5;
|
||||
}
|
||||
// Channel management
|
||||
case APFProtocol.CHANNEL_OPEN: {
|
||||
// Parse CHANNEL OPEN request
|
||||
var p_res = parseChannelOpen(data);
|
||||
//Debug("APF: CHANNEL_OPEN request: " + JSON.stringify(p_res));
|
||||
Debug("APF: CHANNEL_OPEN request: " + JSON.stringify(p_res));
|
||||
// Check if target port is in pfwd_ports
|
||||
if (pfwd_ports.indexOf(p_res.target_port) >= 0) {
|
||||
// Connect socket to that port
|
||||
|
@ -322,21 +318,15 @@ function CreateAPFClient(parent, args) {
|
|||
});
|
||||
|
||||
chan.on('error', function (e) {
|
||||
//Debug("Downlink connection error: " + e);
|
||||
Debug("Downlink connection error: " + e);
|
||||
});
|
||||
|
||||
chan.on('end', function () {
|
||||
var chan = obj.downlinks[p_res.sender_chan];
|
||||
if (chan != null) {
|
||||
try {
|
||||
//Debug("Socket ends.");
|
||||
SendChannelClose(socket.ws, p_res.sender_chan);
|
||||
chan.xclosed = 1;
|
||||
// Add some delay before removing... otherwise race condition
|
||||
setTimeout(function () { delete obj.downlinks[p_res.sender_chan]; }, 100);
|
||||
} catch (e) {
|
||||
//Debug("Downlink connection exception: " + e);
|
||||
}
|
||||
Debug("Socket ends.");
|
||||
try { SendChannelClose(socket.ws, p_res.sender_chan); } catch (ex) { }
|
||||
delete obj.downlinks[p_res.sender_chan];
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -348,22 +338,17 @@ function CreateAPFClient(parent, args) {
|
|||
return p_res.len;
|
||||
}
|
||||
case APFProtocol.CHANNEL_OPEN_CONFIRMATION: {
|
||||
//Debug("APF: CHANNEL_OPEN_CONFIRMATION");
|
||||
Debug("APF: CHANNEL_OPEN_CONFIRMATION");
|
||||
return 17;
|
||||
}
|
||||
case APFProtocol.CHANNEL_CLOSE: {
|
||||
var rcpt_chan = ReadInt(data, 1);
|
||||
//Debug("APF: CHANNEL_CLOSE: " + rcpt_chan);
|
||||
var chan = obj.downlinks[rcpt_chan];
|
||||
if ((chan != null) && (chan.xclosed !== 1)) {
|
||||
SendChannelClose(socket.ws, rcpt_chan);
|
||||
try { obj.downlinks[rcpt_chan].end(); } catch (e) { }
|
||||
delete obj.downlinks[rcpt_chan];
|
||||
}
|
||||
Debug("APF: CHANNEL_CLOSE: " + rcpt_chan);
|
||||
try { obj.downlinks[rcpt_chan].end(); } catch (ex) { }
|
||||
return 5;
|
||||
}
|
||||
case APFProtocol.CHANNEL_DATA: {
|
||||
//Debug("APF: CHANNEL_DATA: " + JSON.stringify(rstr2hex(data)));
|
||||
Debug("APF: CHANNEL_DATA: " + JSON.stringify(rstr2hex(data)));
|
||||
var rcpt_chan = ReadInt(data, 1);
|
||||
var chan_data_len = ReadInt(data, 5);
|
||||
var chan_data = data.substring(9, 9 + chan_data_len);
|
||||
|
@ -372,22 +357,26 @@ function CreateAPFClient(parent, args) {
|
|||
chan.curInWindow += chan_data_len;
|
||||
try {
|
||||
chan.write(Buffer.from(chan_data, 'binary'), function () {
|
||||
//Debug("Write completed.");
|
||||
Debug("Write completed.");
|
||||
// If the incoming window is over half used, send an adjust.
|
||||
if (this.curInWindow > (this.maxInWindow / 2)) { SendChannelWindowAdjust(socket.ws, rcpt_chan, this.curInWindow); this.curInWindow = 0; }
|
||||
});
|
||||
} catch (e) {
|
||||
//Debug("Cannot forward data to downlink socket.");
|
||||
}
|
||||
} catch (ex) { Debug("Cannot forward data to downlink socket."); }
|
||||
}
|
||||
return 9 + chan_data_len;
|
||||
}
|
||||
case APFProtocol.CHANNEL_WINDOW_ADJUST: {
|
||||
//Debug("APF: CHANNEL_WINDOW_ADJUST ");
|
||||
Debug("APF: CHANNEL_WINDOW_ADJUST");
|
||||
return 9;
|
||||
}
|
||||
case APFProtocol.JSON_CONTROL: {
|
||||
Debug("APF: JSON_CONTROL");
|
||||
var len = ReadInt(data, 1);
|
||||
if (obj.onJsonControl) { var o = null; try { o = JSON.parse(data.substring(5, 5 + len)); } catch (ex) { } if (o != null) { obj.onJsonControl(o); } }
|
||||
return 5 + len;
|
||||
}
|
||||
default: {
|
||||
//Debug("CMD: " + cmd + " is not implemented.");
|
||||
Debug("CMD: " + cmd + " is not implemented.");
|
||||
obj.cirastate = CIRASTATE.FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
@ -412,36 +401,32 @@ function CreateAPFClient(parent, args) {
|
|||
|
||||
function SendChannelOpenFailure(socket, chan_data) {
|
||||
socket.write(String.fromCharCode(APFProtocol.CHANNEL_OPEN_FAILURE) + IntToStr(chan_data.sender_chan) + IntToStr(2) + IntToStr(0) + IntToStr(0));
|
||||
//Debug("APF: Send ChannelOpenFailure");
|
||||
Debug("APF: Send ChannelOpenFailure");
|
||||
}
|
||||
|
||||
function SendChannelOpenConfirm(socket, chan_data) {
|
||||
socket.write(String.fromCharCode(APFProtocol.CHANNEL_OPEN_CONFIRMATION) + IntToStr(chan_data.sender_chan) + IntToStr(chan_data.sender_chan) + IntToStr(chan_data.window_size) + IntToStr(0xFFFFFFFF));
|
||||
//Debug("APF: Send ChannelOpenConfirmation");
|
||||
Debug("APF: Send ChannelOpenConfirmation");
|
||||
}
|
||||
|
||||
function SendChannelWindowAdjust(socket, chan, size) {
|
||||
socket.write(String.fromCharCode(APFProtocol.CHANNEL_WINDOW_ADJUST) + IntToStr(chan) + IntToStr(size));
|
||||
//Debug("APF: Send ChannelWindowAdjust: " + rstr2hex(data));
|
||||
Debug("APF: Send ChannelWindowAdjust, channel: " + chan + ", size: " + size);
|
||||
}
|
||||
|
||||
function SendChannelData(socket, chan, data) {
|
||||
socket.write(Buffer.concat([Buffer.from(String.fromCharCode(APFProtocol.CHANNEL_DATA) + IntToStr(chan) + IntToStr(data.length), 'binary'), data]));
|
||||
//Debug("APF: Send ChannelData: " + rstr2hex(buf));
|
||||
Debug("APF: Send ChannelData: " + data.toString('hex'));
|
||||
}
|
||||
|
||||
function SendChannelClose(socket, chan) {
|
||||
socket.write(String.fromCharCode(APFProtocol.CHANNEL_CLOSE) + IntToStr(chan));
|
||||
//Debug("APF: Send ChannelClose ");
|
||||
Debug("APF: Send ChannelClose ");
|
||||
}
|
||||
|
||||
obj.connect = function () {
|
||||
if (obj.forwardClient != null) {
|
||||
try {
|
||||
obj.forwardClient.ws.end();
|
||||
} catch (e) {
|
||||
Debug(e);
|
||||
}
|
||||
try { obj.forwardClient.ws.end(); } catch (ex) { Debug(ex); }
|
||||
//obj.forwardClient = null;
|
||||
}
|
||||
obj.cirastate = CIRASTATE.INITIAL;
|
||||
|
@ -457,7 +442,7 @@ function CreateAPFClient(parent, args) {
|
|||
obj.forwardClient.end(); // end request, trigger completion of HTTP request
|
||||
}
|
||||
|
||||
obj.disconnect = function () { try { obj.forwardClient.ws.end(); } catch (e) { Debug(e); } }
|
||||
obj.disconnect = function () { try { obj.forwardClient.ws.end(); } catch (ex) { Debug(ex); } }
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue