mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Improved file transfers, added file downloads over WebRTC.
This commit is contained in:
parent
2a835d25cd
commit
0c3c0973bc
28 changed files with 579 additions and 230 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -391,7 +391,7 @@ function startLms(func) {
|
|||
//var xx = AllWsman[4];
|
||||
//console.log(xx);
|
||||
//osamtstack.Get(AllWsmanRequests.shift(), startLmsWsmanResponse, null, true);
|
||||
osamtstack.Get('IPS_SecIOService', startLmsWsmanResponse, null, true);
|
||||
//osamtstack.Get('IPS_SecIOService', startLmsWsmanResponse, null, true);
|
||||
//osamtstack.BatchEnum(null, ['IPS_KVMRedirectionSettingData', 'CIM_SoftwareIdentity'], startLmsWsmanResponse, null, true);
|
||||
//osamtstack.BatchEnum(null, AllWsman, startLmsWsmanResponse, null, true);
|
||||
});
|
||||
|
|
|
@ -31,7 +31,7 @@ function createMeshCore(agent) {
|
|||
var fs = require('fs');
|
||||
var rtc = require('ILibWebRTC');
|
||||
var amtMei = null, amtLms = null, amtLmsState = 0;
|
||||
var amtMeiConnected = 0, amtMeiState = null, amtMeiTmpState = null;
|
||||
var amtMeiConnected = 0, amtMeiTmpState = null;
|
||||
var wifiScannerLib = null;
|
||||
var wifiScanner = null;
|
||||
var networkMonitor = null;
|
||||
|
@ -77,7 +77,7 @@ function createMeshCore(agent) {
|
|||
amtMeiConnected = 1;
|
||||
amtMei = new amtMeiLib();
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; sendPeriodicServerUpdate(); });
|
||||
amtMei.on('connect', function () { amtMeiConnected = 2; getAmtInfo(); });
|
||||
amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
|
||||
} catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
|
||||
// Try to load up the WIFI scanner
|
||||
|
@ -403,7 +403,7 @@ function createMeshCore(agent) {
|
|||
// List all the drives in the root, or the root itself
|
||||
var results = null;
|
||||
try { results = fs.readDrivesSync(); } catch (e) { } // TODO: Anyway to get drive total size and free space? Could draw a progress bar.
|
||||
//console.log('a', objToString(results, 0, '.'));
|
||||
//console.log('a', objToString(results, 0, ' '));
|
||||
if (results != null) {
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
var drive = { n: results[i].name, t: 1 };
|
||||
|
@ -515,6 +515,7 @@ function createMeshCore(agent) {
|
|||
this.write(new Buffer(JSON.stringify({ action: 'uploadack', reqid: this.httprequest.uploadFileid }))); // Ask for more data
|
||||
return;
|
||||
}
|
||||
/*
|
||||
// If this is a download, send more of the file
|
||||
if (this.httprequest.downloadFile) {
|
||||
var buf = new Buffer(4096);
|
||||
|
@ -523,14 +524,15 @@ function createMeshCore(agent) {
|
|||
if (len > 0) { this.write(buf.slice(0, len)); } else { fs.closeSync(this.httprequest.downloadFile); this.httprequest.downloadFile = undefined; this.end(); }
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
if (this.httprequest.state == 0) {
|
||||
// Check if this is a relay connection
|
||||
if (data == 'c') { this.httprequest.state = 1; sendConsoleText("Tunnel #" + this.httprequest.index + " now active", this.httprequest.sessionid); }
|
||||
} else {
|
||||
// Handle tunnel data
|
||||
if (this.httprequest.protocol == 0) { // 1 = SOL, 2 = KVM, 3 = IDER, 4 = Files, 5 = FileTransfer
|
||||
// Take a look at the protocolab
|
||||
// Take a look at the protocol
|
||||
this.httprequest.protocol = parseInt(data);
|
||||
if (typeof this.httprequest.protocol != 'number') { this.httprequest.protocol = 0; }
|
||||
if (this.httprequest.protocol == 1) {
|
||||
|
@ -550,8 +552,7 @@ function createMeshCore(agent) {
|
|||
this.on('data', onTunnelControlData);
|
||||
//this.write('MeshCore Terminal Hello');
|
||||
if (process.platform != 'win32') { this.httprequest.process.stdin.write("stty erase ^H\nalias ls='ls --color=auto'\nclear\n"); }
|
||||
}
|
||||
if (this.httprequest.protocol == 2) {
|
||||
} else if (this.httprequest.protocol == 2) {
|
||||
// Remote desktop using native pipes
|
||||
this.httprequest.desktop = { state: 0, kvm: mesh.getRemoteDesktopStream(), tunnel: this };
|
||||
this.httprequest.desktop.kvm.parent = this.httprequest.desktop;
|
||||
|
@ -568,8 +569,7 @@ function createMeshCore(agent) {
|
|||
this.removeAllListeners('data');
|
||||
this.on('data', onTunnelControlData);
|
||||
//this.write('MeshCore KVM Hello!1');
|
||||
}
|
||||
else if (this.httprequest.protocol == 5) {
|
||||
} else if (this.httprequest.protocol == 5) {
|
||||
// Setup files
|
||||
// NOP
|
||||
}
|
||||
|
@ -579,7 +579,6 @@ function createMeshCore(agent) {
|
|||
this.httprequest.process.write(data);
|
||||
} else if (this.httprequest.protocol == 2) {
|
||||
// Send data into remote desktop
|
||||
// TODO ADD REMOTE DESKTOP (This is test code)
|
||||
if (this.httprequest.desktop.state == 0) {
|
||||
this.write(new Buffer(String.fromCharCode(0x11, 0xFE, 0x00, 0x00, 0x4D, 0x45, 0x53, 0x48, 0x00, 0x00, 0x00, 0x00, 0x02)));
|
||||
this.httprequest.desktop.state = 1;
|
||||
|
@ -590,9 +589,13 @@ function createMeshCore(agent) {
|
|||
// Process files commands
|
||||
var cmd = null;
|
||||
try { cmd = JSON.parse(data); } catch (e) { };
|
||||
if ((cmd == null) || (cmd.action == undefined)) { return; }
|
||||
if (cmd == null) { return; }
|
||||
if ((cmd.ctrlChannel == '102938') || ((cmd.type == 'offer') && (cmd.sdp != null))) { onTunnelControlData(cmd, this); return; } // If this is control data, handle it now.
|
||||
if (cmd.action == undefined) { return; }
|
||||
//sendConsoleText('CMD: ' + JSON.stringify(cmd));
|
||||
|
||||
if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows
|
||||
//console.log(objToString(cmd, 0, '.'));
|
||||
//console.log(objToString(cmd, 0, ' '));
|
||||
switch (cmd.action) {
|
||||
case 'ls': {
|
||||
/*
|
||||
|
@ -642,6 +645,36 @@ function createMeshCore(agent) {
|
|||
try { fs.renameSync(oldfullpath, newfullpath); } catch (e) { console.log(e); }
|
||||
break;
|
||||
}
|
||||
case 'download': {
|
||||
// Download a file
|
||||
var sendNextBlock = 0;
|
||||
if (cmd.sub == 'start') { // Setup the download
|
||||
if (this.filedownload != null) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
this.filedownload = { id: cmd.id, path: cmd.path, ptr: 0 }
|
||||
try { this.filedownload.f = fs.openSync(this.filedownload.path, 'rbN'); } catch (e) { this.write({ action: 'download', sub: 'cancel', id: this.filedownload.id }); delete this.filedownload; }
|
||||
if (this.filedownload) { this.write({ action: 'download', sub: 'start', id: cmd.id }); }
|
||||
} else if ((this.filedownload != null) && (cmd.id == this.filedownload.id)) { // Download commands
|
||||
if (cmd.sub == 'startack') { sendNextBlock = 8; } else if (cmd.sub == 'stop') { delete this.filedownload; } else if (cmd.sub == 'ack') { sendNextBlock = 1; }
|
||||
}
|
||||
// Send the next download block(s)
|
||||
while (sendNextBlock > 0) {
|
||||
sendNextBlock--;
|
||||
var buf = new Buffer(4096);
|
||||
buf.writeInt32BE(0x01020304, 0);
|
||||
var len = fs.readSync(this.filedownload.f, buf, 4, 4092, null);
|
||||
this.filedownload.ptr += len;
|
||||
if (len > 0) {
|
||||
this.write(buf.slice(0, len + 4)); // Write as binary
|
||||
} else {
|
||||
fs.closeSync(this.filedownload.f);
|
||||
this.write({ action: 'download', sub: 'done', id: this.filedownload.id });
|
||||
delete this.filedownload;
|
||||
sendNextBlock = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case 'download': {
|
||||
// Packet download of a file, agent to browser
|
||||
if (cmd.path == undefined) break;
|
||||
|
@ -662,6 +695,7 @@ function createMeshCore(agent) {
|
|||
this.httprequest.downloadFile.end = function () { }
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case 'upload': {
|
||||
// Upload a file, browser to agent
|
||||
if (this.httprequest.uploadFile != undefined) { fs.closeSync(this.httprequest.uploadFile); this.httprequest.uploadFile = undefined; }
|
||||
|
@ -691,65 +725,61 @@ function createMeshCore(agent) {
|
|||
}
|
||||
|
||||
// Called when receiving control data on websocket
|
||||
function onTunnelControlData(data) {
|
||||
if (typeof data != 'string') return;
|
||||
//sendConsoleText('onTunnelControlData: ' + data);
|
||||
//console.log('onTunnelControlData: ' + data);
|
||||
|
||||
function onTunnelControlData(data, ws) {
|
||||
var obj;
|
||||
try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; }
|
||||
if (ws == null) { ws = this; }
|
||||
if (typeof data == 'string') { try { obj = JSON.parse(data); } catch (e) { sendConsoleText('Invalid control JSON'); return; } }
|
||||
else if (typeof data == 'object') { obj = data; } else { return; }
|
||||
//sendConsoleText('onTunnelControlData(' + ws.httprequest.protocol + '): ' + JSON.stringify(data));
|
||||
//console.log('onTunnelControlData: ' + JSON.stringify(data));
|
||||
|
||||
if (obj.type == 'close') {
|
||||
// We received the close on the websocket
|
||||
//sendConsoleText('Tunnel #' + this.tunnel.index + ' WebSocket control close');
|
||||
try { this.close(); } catch (e) { }
|
||||
//sendConsoleText('Tunnel #' + ws.tunnel.index + ' WebSocket control close');
|
||||
try { ws.close(); } catch (e) { }
|
||||
} else if (obj.type == 'webrtc0') { // Browser indicates we can start WebRTC switch-over.
|
||||
if (this.websocket.httprequest.protocol == 1) { // Terminal
|
||||
if (ws.httprequest.protocol == 1) { // Terminal
|
||||
// This is a terminal data stream, unpipe the terminal now and indicate to the other side that terminal data will no longer be received over WebSocket
|
||||
this.websocket.httprequest.process.stdout.unpipe(this.websocket);
|
||||
this.websocket.httprequest.process.stderr.unpipe(this.websocket);
|
||||
this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
|
||||
} else if (this.websocket.httprequest.protocol == 2) { // Desktop
|
||||
ws.httprequest.process.stdout.unpipe(ws);
|
||||
ws.httprequest.process.stderr.unpipe(ws);
|
||||
} else if (ws.httprequest.protocol == 2) { // Desktop
|
||||
// This is a KVM data stream, unpipe the KVM now and indicate to the other side that KVM data will no longer be received over WebSocket
|
||||
this.websocket.httprequest.desktop.kvm.unpipe(this.websocket);
|
||||
this.websocket.write("{\"type\":\"webrtc1\"}"); // End of data marker
|
||||
ws.httprequest.desktop.kvm.unpipe(ws);
|
||||
} else {
|
||||
// Switch things around so all WebRTC data goes to onTunnelData().
|
||||
ws.rtcchannel.httprequest = ws.httprequest;
|
||||
ws.rtcchannel.removeAllListeners('data');
|
||||
ws.rtcchannel.on('data', onTunnelData);
|
||||
}
|
||||
/*
|
||||
else {
|
||||
// Debug, just display on agent console
|
||||
rtcchannel.on('data', function (buffer) { sendConsoleText("RTCReceived: " + buffer.length + " bytes"); });
|
||||
rtcchannel.on('end', function () { sendConsoleText("RTCChannel: " + this.name + " was closed"); });
|
||||
channel.write('WebRTC HELLO!');
|
||||
}
|
||||
*/
|
||||
ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc1\"}"); // End of data marker
|
||||
} else if (obj.type == 'webrtc1') {
|
||||
if (this.httprequest.protocol == 1) { // Terminal
|
||||
if (ws.httprequest.protocol == 1) { // Terminal
|
||||
// Switch the user input from websocket to webrtc at this point.
|
||||
this.unpipe(this.httprequest.process.stdin);
|
||||
this.rtcchannel.pipe(this.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
|
||||
this.resume(); // Resume the websocket to keep receiving control data
|
||||
} else if (this.httprequest.protocol == 2) { // Desktop
|
||||
ws.unpipe(ws.httprequest.process.stdin);
|
||||
ws.rtcchannel.pipe(ws.httprequest.process.stdin, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
|
||||
ws.resume(); // Resume the websocket to keep receiving control data
|
||||
} else if (ws.httprequest.protocol == 2) { // Desktop
|
||||
// Switch the user input from websocket to webrtc at this point.
|
||||
this.unpipe(this.httprequest.desktop.kvm);
|
||||
try { this.webrtc.rtcchannel.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1 }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
|
||||
this.resume(); // Resume the websocket to keep receiving control data
|
||||
ws.unpipe(ws.httprequest.desktop.kvm);
|
||||
try { ws.webrtc.rtcchannel.pipe(ws.httprequest.desktop.kvm, { dataTypeSkip: 1 }); } catch (e) { sendConsoleText('EX2'); } // 0 = Binary, 1 = Text.
|
||||
ws.resume(); // Resume the websocket to keep receiving control data
|
||||
}
|
||||
this.write("{\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
|
||||
ws.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc2\"}"); // Indicates we will no longer get any data on websocket, switching to WebRTC at this point.
|
||||
} else if (obj.type == 'webrtc2') {
|
||||
// Other side received websocket end of data marker, start sending data on WebRTC channel
|
||||
if (this.httprequest.protocol == 1) { // Terminal
|
||||
this.httprequest.process.stdout.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
|
||||
this.httprequest.process.stderr.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
|
||||
} else if (this.httprequest.protocol == 2) { // Desktop
|
||||
this.httprequest.desktop.kvm.pipe(this.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
|
||||
if (ws.httprequest.protocol == 1) { // Terminal
|
||||
ws.httprequest.process.stdout.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
|
||||
ws.httprequest.process.stderr.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text.
|
||||
} else if (ws.httprequest.protocol == 2) { // Desktop
|
||||
ws.httprequest.desktop.kvm.pipe(ws.webrtc.rtcchannel, { dataTypeSkip: 1 }); // 0 = Binary, 1 = Text.
|
||||
}
|
||||
} else if (obj.type == 'offer') {
|
||||
// This is a WebRTC offer.
|
||||
this.webrtc = rtc.createConnection();
|
||||
this.webrtc.websocket = this;
|
||||
this.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
|
||||
this.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
|
||||
this.webrtc.on('dataChannel', function (rtcchannel) {
|
||||
ws.webrtc = rtc.createConnection();
|
||||
ws.webrtc.websocket = ws;
|
||||
ws.webrtc.on('connected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC connected');*/ });
|
||||
ws.webrtc.on('disconnected', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC disconnected');*/ });
|
||||
ws.webrtc.on('dataChannel', function (rtcchannel) {
|
||||
//sendConsoleText('WebRTC Datachannel open, protocol: ' + this.websocket.httprequest.protocol);
|
||||
rtcchannel.xrtc = this;
|
||||
rtcchannel.websocket = this.websocket;
|
||||
|
@ -757,9 +787,9 @@ function createMeshCore(agent) {
|
|||
this.websocket.rtcchannel = rtcchannel;
|
||||
this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
|
||||
this.websocket.rtcchannel.on('end', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');*/ });
|
||||
this.websocket.write("{\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
|
||||
this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
|
||||
});
|
||||
this.write({ type: "answer", sdp: this.webrtc.setOffer(obj.sdp) });
|
||||
ws.write({ type: 'answer', ctrlChannel: '102938', sdp: ws.webrtc.setOffer(obj.sdp) });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,19 +834,19 @@ function createMeshCore(agent) {
|
|||
case 'info': { // Return information about the agent and agent core module
|
||||
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
|
||||
if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
|
||||
response += '\r\nModules: ' + JSON.stringify(addedModules) + '';
|
||||
response += '\r\nServerConnected: ' + mesh.isControlChannelConnected + '';
|
||||
response += '\r\nModules: ' + addedModules.join(', ');
|
||||
response += '\r\nServerConnected: ' + mesh.isControlChannelConnected;
|
||||
var oldNodeId = db.Get('OldNodeId');
|
||||
if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
|
||||
response += '\r\ServerState: ' + meshServerConnectionState + '.';
|
||||
break;
|
||||
}
|
||||
case 'selfinfo': { // Return self information block
|
||||
response = JSON.stringify(buildSelfInfo());
|
||||
buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' '), sessionid); });
|
||||
break;
|
||||
}
|
||||
case 'args': { // Displays parsed command arguments
|
||||
response = 'args ' + objToString(args, 0, '.');
|
||||
response = 'args ' + objToString(args, 0, ' ');
|
||||
break;
|
||||
}
|
||||
case 'print': { // Print a message on the mesh agent console, does nothing when running in the background
|
||||
|
@ -986,17 +1016,17 @@ function createMeshCore(agent) {
|
|||
break;
|
||||
}
|
||||
case 'amt': { // Show Intel AMT status
|
||||
if (amtMeiState != null) {
|
||||
response = objToString(amtMeiState, 0, '.');
|
||||
} else {
|
||||
response = 'This mesh agent does not support Intel AMT.';
|
||||
}
|
||||
getAmtInfo(function (state) {
|
||||
var resp = 'Intel AMT not detected.';
|
||||
if (state != null) { resp = objToString(state, 0, ' '); }
|
||||
sendConsoleText(resp, sessionid);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'netinfo': { // Show network interface information
|
||||
//response = objToString(mesh.NetInfo, 0, '.');
|
||||
//response = objToString(mesh.NetInfo, 0, ' ');
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
response = objToString(interfaces, 0, '.');
|
||||
response = objToString(interfaces, 0, ' ');
|
||||
break;
|
||||
}
|
||||
case 'wakeonlan': { // Send wake-on-lan
|
||||
|
@ -1027,7 +1057,7 @@ function createMeshCore(agent) {
|
|||
}
|
||||
case 'location': {
|
||||
getIpLocationData(function (location) {
|
||||
sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, '.'));
|
||||
sendConsoleText(objToString({ "action": "iplocation", "type": "publicip", "value": location }, 0, ' '));
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -1108,20 +1138,19 @@ function createMeshCore(agent) {
|
|||
|
||||
// Build a bunch a self information data that will be sent to the server
|
||||
// We need to do this periodically and if anything changes, send the update to the server.
|
||||
function buildSelfInfo() {
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
if (mesh.hasHECI == 1) {
|
||||
var meinfo = amtMeiState;
|
||||
var amtPresent = false, intelamt = {};
|
||||
function buildSelfInfo(func) {
|
||||
getAmtInfo(function (meinfo) {
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
if (meinfo != null) {
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; amtPresent = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; amtPresent = true; }
|
||||
if (meinfo.flags) { intelamt.flags = meinfo.Flags; amtPresent = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; amtPresent = true; }
|
||||
if (amtPresent == true) { r.intelamt = intelamt }
|
||||
var intelamt = {}, p = false;
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (p == true) { r.intelamt = intelamt }
|
||||
}
|
||||
}
|
||||
return JSON.stringify(r);
|
||||
func(r);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the server with the latest network interface information
|
||||
|
@ -1141,8 +1170,10 @@ function createMeshCore(agent) {
|
|||
function sendPeriodicServerUpdate(force) {
|
||||
if ((amtMeiConnected != 1) || (force == true)) { // If we are pending MEI connection, hold off on updating the server on self-info
|
||||
// Update the self information data
|
||||
var selfInfo = buildSelfInfo(), selfInfoStr = JSON.stringify(selfInfo);
|
||||
if ((force == true) || (selfInfoStr != lastSelfInfo)) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
|
||||
buildSelfInfo(function (selfInfo) {
|
||||
selfInfoStr = JSON.stringify(selfInfo);
|
||||
if ((force == true) || (selfInfoStr != lastSelfInfo)) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
|
||||
});
|
||||
}
|
||||
|
||||
// Update network information
|
||||
|
@ -1160,7 +1191,7 @@ function createMeshCore(agent) {
|
|||
amtMei.getEHBCState(function (result) { if (result.EHBC == true) { amtMeiTmpState.Flags += 1; } });
|
||||
amtMei.getControlMode(function (result) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } });
|
||||
//amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; });
|
||||
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } amtMeiState = amtMeiTmpState; sendPeriodicServerUpdate(); if (func != null) { func(amtMeiState); } });
|
||||
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
|
||||
}
|
||||
|
||||
// Called on MicroLMS Intel AMT user notification
|
||||
|
|
78
agents/meshinstall-initd.sh
Normal file
78
agents/meshinstall-initd.sh
Normal file
|
@ -0,0 +1,78 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: <NAME>
|
||||
# Required-Start: $local_fs $network $named $time $syslog
|
||||
# Required-Stop: $local_fs $network $named $time $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Description: <DESCRIPTION>
|
||||
### END INIT INFO
|
||||
|
||||
SCRIPT=/usr/local/mesh/meshagent
|
||||
RUNAS=root
|
||||
|
||||
PIDFILE=/var/run/meshagent.pid
|
||||
LOGFILE=/var/log/meshagent.log
|
||||
|
||||
start() {
|
||||
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then
|
||||
echo 'Service already running' >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Starting service…' >&2
|
||||
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
|
||||
su -c "$CMD" $RUNAS > "$PIDFILE"
|
||||
echo 'Service started' >&2
|
||||
}
|
||||
|
||||
stop() {
|
||||
if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
|
||||
echo 'Service not running' >&2
|
||||
return 1
|
||||
fi
|
||||
echo 'Stopping service…' >&2
|
||||
kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
|
||||
echo 'Service stopped' >&2
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
|
||||
local SURE
|
||||
read SURE
|
||||
if [ "$SURE" = "yes" ]; then
|
||||
stop
|
||||
rm -f "$PIDFILE"
|
||||
echo "Notice: log file will not be removed: '$LOGFILE'" >&2
|
||||
update-rc.d -f <NAME> remove
|
||||
rm -fv "$0"
|
||||
fi
|
||||
}
|
||||
|
||||
forceuninstall() {
|
||||
stop
|
||||
rm -f "$PIDFILE"
|
||||
rm -f "$LOGFILE"
|
||||
update-rc.d -f <NAME> remove
|
||||
rm -fv "$0"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
uninstall)
|
||||
uninstall
|
||||
;;
|
||||
forceuninstall)
|
||||
uninstall
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|uninstall}"
|
||||
esac
|
164
agents/meshinstall-linux-old.sh
Normal file
164
agents/meshinstall-linux-old.sh
Normal file
|
@ -0,0 +1,164 @@
|
|||
#!/bin/bash
|
||||
|
||||
CheckStartupType() {
|
||||
# echo "Checking process autostart system..."
|
||||
if [[ `systemctl` =~ -\.mount ]]; then return 1; # systemd;
|
||||
elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
|
||||
elif [[ -f /etc/init.d/cron && ! -h /etc/init.d/cron ]]; then return 3; # sysv-init;
|
||||
fi
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Add "StartupType=(type)" to .msh file
|
||||
UpdateMshFile() {
|
||||
# Remove all lines that start with "StartupType="
|
||||
sed '/^StartupType=/ d' < /usr/local/mesh/meshagent.msh >> /usr/local/mesh/meshagent2.msh
|
||||
# Add the startup type to the file
|
||||
echo "StartupType=$starttype" >> /usr/local/mesh/meshagent2.msh
|
||||
mv /usr/local/mesh/meshagent2.msh /usr/local/mesh/meshagent.msh
|
||||
}
|
||||
|
||||
CheckInstallAgent() {
|
||||
# echo "Checking mesh identifier..."
|
||||
if [ -e "/usr/local" ]
|
||||
then
|
||||
installpath="/usr/local/mesh"
|
||||
else
|
||||
installpath="/usr/mesh"
|
||||
fi
|
||||
if [ $# -eq 2 ]
|
||||
then
|
||||
url=$1
|
||||
meshid=$2
|
||||
meshidlen=${#meshid}
|
||||
if [ $meshidlen -eq 64 ]
|
||||
then
|
||||
# echo "Detecting computer type..."
|
||||
machinetype=$( uname -m )
|
||||
machineid=0
|
||||
if [ $machinetype == 'x86_64' ]
|
||||
then
|
||||
# Linux x86, 64 bit
|
||||
machineid=6
|
||||
fi
|
||||
if [ $machinetype == 'x86' ]
|
||||
then
|
||||
# Linux x86, 32 bit
|
||||
machineid=5
|
||||
fi
|
||||
if [ $machinetype == 'armv6l' ] || [ $machinetype == 'armv7l' ]
|
||||
then
|
||||
# RaspberryPi 1 (armv6l) or RaspberryPi 2/3 (armv7l)
|
||||
machineid=25
|
||||
fi
|
||||
# TODO: Add more machine types, detect KVM support, etc.
|
||||
if [ $machineid -eq 0 ]
|
||||
then
|
||||
echo "Unsupported machine type: $machinetype, check with server administrator."
|
||||
else
|
||||
DownloadAgent $url $meshid $machineid
|
||||
fi
|
||||
else
|
||||
echo "MeshID is not correct, must be 64 characters long."
|
||||
fi
|
||||
else
|
||||
echo "URI and/or MeshID have not been specified, must be passed in as arguments."
|
||||
return 0;
|
||||
fi
|
||||
}
|
||||
|
||||
DownloadAgent() {
|
||||
url=$1
|
||||
meshid=$2
|
||||
machineid=$3
|
||||
# Create folder
|
||||
mkdir -p /usr/local/mesh
|
||||
cd /usr/local/mesh
|
||||
# echo "Downloading mesh agent..."
|
||||
wget $url/meshagents?id=$machineid -q --no-check-certificate -O /usr/local/mesh/meshagent
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "Mesh agent downloaded."
|
||||
# TODO: We could check the meshagent sha256 hash, but best to authenticate the server.
|
||||
chmod 755 /usr/local/mesh/meshagent
|
||||
wget $url/meshsettings?id=$meshid -q --no-check-certificate -O /usr/local/mesh/meshagent.msh
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
UpdateMshFile
|
||||
if [ $starttype -eq 1 ]
|
||||
then
|
||||
echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /lib/systemd/system/meshagent.service
|
||||
systemctl enable meshagent
|
||||
systemctl start meshagent
|
||||
else
|
||||
./meshagent start
|
||||
ln -s /usr/local/mesh/meshagent /sbin/meshcmd
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
|
||||
fi
|
||||
echo "Mesh agent started."
|
||||
else
|
||||
echo "Unable to download mesh settings at: $url/meshsettings?id=$meshid."
|
||||
fi
|
||||
else
|
||||
echo "Unable to download mesh agent at: $url/meshagents?id=$machineid."
|
||||
fi
|
||||
}
|
||||
|
||||
UninstallAgent() {
|
||||
# Uninstall agent
|
||||
if [ -e "/usr/local" ]
|
||||
then
|
||||
installpath="/usr/local/mesh"
|
||||
else
|
||||
installpath="/usr/mesh"
|
||||
fi
|
||||
|
||||
if [ $starttype -eq 1 ]
|
||||
then
|
||||
rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service
|
||||
systemctl disable meshagent
|
||||
systemctl stop meshagent
|
||||
else
|
||||
rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
|
||||
fi
|
||||
|
||||
if [ -e $installpath ]
|
||||
then
|
||||
cd $installpath
|
||||
if [ -e "$installpath/meshagent" ]
|
||||
then
|
||||
./meshagent stop
|
||||
fi
|
||||
rm -rf $installpath/*
|
||||
rmdir $installpath
|
||||
fi
|
||||
echo "Agent uninstalled."
|
||||
}
|
||||
|
||||
|
||||
CheckStartupType
|
||||
starttype=$?
|
||||
#echo "Type: $starttype"
|
||||
|
||||
currentuser=$( whoami )
|
||||
if [ $currentuser == 'root' ]
|
||||
then
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo -e "This script will install or uninstall a mesh agent, usage:\n $0 [serverurl] [meshid]\n $0 uninstall"
|
||||
else
|
||||
if [ $# -eq 1 ]
|
||||
then
|
||||
if [ $1 == 'uninstall' ] || [ $1 == 'UNINSTALL' ]
|
||||
then
|
||||
UninstallAgent
|
||||
fi
|
||||
else
|
||||
CheckInstallAgent $1 $2
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Must be root to install or uninstall mesh agent."
|
||||
fi
|
|
@ -1,6 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
CheckStartupType() {
|
||||
# echo "Checking process autostart system..."
|
||||
starttype=`ps -p 1 | awk '/1/ {print $4}'`
|
||||
if [[ $starttype == 'systemd' ]]; then return 1; # systemd;
|
||||
elif [[ $starttype == 'init' ]]; then return 3; # sysv-init;
|
||||
elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
|
||||
fi
|
||||
return 0;
|
||||
}
|
||||
|
||||
CheckStartupTypeOld() {
|
||||
# echo "Checking process autostart system..."
|
||||
if [[ `systemctl` =~ -\.mount ]]; then return 1; # systemd;
|
||||
elif [[ `/sbin/init --version` =~ upstart ]]; then return 2; # upstart;
|
||||
|
@ -87,15 +97,26 @@ DownloadAgent() {
|
|||
UpdateMshFile
|
||||
if [ $starttype -eq 1 ]
|
||||
then
|
||||
# systemd
|
||||
echo -e "[Unit]\nDescription=MeshCentral Agent\n[Service]\nExecStart=/usr/local/mesh/meshagent\nStandardOutput=null\nRestart=always\nRestartSec=3\n[Install]\nWantedBy=multi-user.target\nAlias=meshagent.service\n" > /lib/systemd/system/meshagent.service
|
||||
systemctl enable meshagent
|
||||
systemctl start meshagent
|
||||
else
|
||||
./meshagent start
|
||||
ln -s /usr/local/mesh/meshagent /sbin/meshcmd
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
|
||||
if [ $starttype -eq 3 ]
|
||||
then
|
||||
# initd
|
||||
wget $url/meshagents?script=2 -q --no-check-certificate -O /etc/init.d/meshagent
|
||||
chmod +x /etc/init.d/meshagent
|
||||
update-rc.d meshagent default # creates symlinks for rc.d
|
||||
service meshagent start
|
||||
else
|
||||
# upstart / others (???)
|
||||
./meshagent start
|
||||
ln -s /usr/local/mesh/meshagent /sbin/meshcmd
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc2.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc3.d/S20mesh
|
||||
ln -s /usr/local/mesh/meshagent /etc/rc5.d/S20mesh
|
||||
fi
|
||||
fi
|
||||
echo "Mesh agent started."
|
||||
else
|
||||
|
@ -117,11 +138,20 @@ UninstallAgent() {
|
|||
|
||||
if [ $starttype -eq 1 ]
|
||||
then
|
||||
# systemd
|
||||
rm -f /sbin/meshcmd /lib/systemd/system/meshagent.service
|
||||
systemctl disable meshagent
|
||||
systemctl stop meshagent
|
||||
else
|
||||
rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
|
||||
if [ $starttype -eq 3 ]
|
||||
then
|
||||
# initd
|
||||
service meshagent forceuninstall
|
||||
rm -f /sbin/meshcmd /etc/init.d/meshagent
|
||||
else
|
||||
# upstart / others (???)
|
||||
rm -f /sbin/meshcmd /etc/rc2.d/S20mesh /etc/rc3.d/S20mesh /etc/rc5.d/S20mesh
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e $installpath ]
|
||||
|
|
|
@ -357,6 +357,7 @@ function AmtStackCreateService(wsmanStack) {
|
|||
obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
|
||||
obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
|
||||
obj.IPS_KVMRedirectionSettingData_DataChannelRead = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelRead", {}, callback_func); }
|
||||
obj.IPS_KVMRedirectionSettingData_DataChannelWrite = function (Data, callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "DataChannelWrite", { "DataMessage": Data }, callback_func); }
|
||||
obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
|
||||
obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
|
||||
obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue