Fixed MeshCMD AMT Script Exception

This commit is contained in:
Ylian Saint-Hilaire 2019-04-09 15:51:05 -07:00
parent 6d828aa895
commit a0ab8ddeed
14 changed files with 137 additions and 69 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -109,10 +109,10 @@ module.exports.setup = function(binary, startvars) {
var argcount = ReadShort(obj.script, obj.ip + 4); var argcount = ReadShort(obj.script, obj.ip + 4);
var argptr = obj.ip + 6; var argptr = obj.ip + 6;
var args = []; var args = [];
// Clear all temp variables (This is optional) // Clear all temp variables (This is optional)
for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } } for (var i in obj.variables) { if (i.startsWith('__')) { delete obj.variables[i]; } }
// Loop on each argument, moving forward by the argument length each time // Loop on each argument, moving forward by the argument length each time
for (var i = 0; i < argcount; i++) { for (var i = 0; i < argcount; i++) {
var arglen = ReadShort(obj.script, argptr); var arglen = ReadShort(obj.script, argptr);
@ -122,7 +122,7 @@ module.exports.setup = function(binary, startvars) {
if (argtyp < 2) { if (argtyp < 2) {
// Get the value and replace all {var} with variable values // Get the value and replace all {var} with variable values
argval = argval.toString(); argval = argval.toString();
while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); } if (argval != null) { while (argval.split("{").length > 1) { var t = argval.split("{").pop().split("}").shift(); argval = argval.replace('{' + t + '}', obj.getVar(t)); } }
if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable. if (argtyp == 1) { obj.variables['__' + i] = decodeURI(argval); argval = '__' + i; } // If argtyp is 1, this is a literal. Store in temp variable.
args.push(argval); args.push(argval);
} }
@ -132,7 +132,7 @@ module.exports.setup = function(binary, startvars) {
} }
argptr += (2 + arglen); argptr += (2 + arglen);
} }
// Move instruction pointer forward by command size // Move instruction pointer forward by command size
obj.ip += cmdlen; obj.ip += cmdlen;

File diff suppressed because one or more lines are too long

View File

@ -46,38 +46,41 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if (arg == 2) { try { ws._socket._parent.end(); if (obj.nodeid != null) { parent.parent.debug(1, 'Hard disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); } } catch (e) { console.log(e); } } // Hard close, close the TCP socket if (arg == 2) { try { ws._socket._parent.end(); if (obj.nodeid != null) { parent.parent.debug(1, 'Hard disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); } } catch (e) { console.log(e); } } // Hard close, close the TCP socket
// If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent). // If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent).
// Remove this agent from the webserver list // If this is a recovery agent, don't bother with all this clean up.
if (parent.wsagents[obj.dbNodeKey] == obj) { if ((obj.agentInfo.capabilities & 0x40) == 0) {
delete parent.wsagents[obj.dbNodeKey]; // Remove this agent from the webserver list
parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1); if (parent.wsagents[obj.dbNodeKey] == obj) {
} delete parent.wsagents[obj.dbNodeKey];
parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
// Get the current mesh }
const mesh = parent.meshes[obj.dbMeshKey];
// Get the current mesh
// If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery) const mesh = parent.meshes[obj.dbMeshKey];
if (((obj.agentInfo) && (obj.agentInfo.capabilities) && ((obj.agentInfo.capabilities & 0x20) || (obj.agentInfo.capabilities & 0x40))) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
// Delete this node including network interface information and events // If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery)
db.Remove(obj.dbNodeKey); // Remove node with that id if (((obj.agentInfo) && (obj.agentInfo.capabilities) && (obj.agentInfo.capabilities & 0x20)) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
db.Remove('if' + obj.dbNodeKey); // Remove interface information // Delete this node including network interface information and events
db.Remove('nt' + obj.dbNodeKey); // Remove notes db.Remove(obj.dbNodeKey); // Remove node with that id
db.Remove('lc' + obj.dbNodeKey); // Remove last connect time db.Remove('if' + obj.dbNodeKey); // Remove interface information
db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data db.Remove('nt' + obj.dbNodeKey); // Remove notes
db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node db.Remove('lc' + obj.dbNodeKey); // Remove last connect time
db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node db.RemoveSMBIOS(obj.dbNodeKey); // Remove SMBios data
db.RemoveAllNodeEvents(obj.dbNodeKey); // Remove all events for this node
// Event node deletion db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
// Event node deletion
// Disconnect all connections if needed parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
if ((state != null) && (state.connectivity != null)) { // Disconnect all connections if needed
if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection if ((state != null) && (state.connectivity != null)) {
if ((state.connectivity & 1) != 0) { parent.wsagents[obj.dbNodeKey].close(); } // Disconnect mesh agent
if ((state.connectivity & 2) != 0) { parent.parent.mpsserver.close(parent.parent.mpsserver.ciraConnections[obj.dbNodeKey]); } // Disconnect CIRA connection
}
} else {
// Update the last connect time
if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
} }
} else {
// Update the last connect time
if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
} }
// If we where updating the agent, clean that up. // If we where updating the agent, clean that up.
@ -522,6 +525,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection || (obj.agentInfo == null)) { return; } if ((obj.authenticated != 1) || (obj.meshid == null) || obj.pendingCompleteAgentConnection || (obj.agentInfo == null)) { return; }
obj.pendingCompleteAgentConnection = true; obj.pendingCompleteAgentConnection = true;
if (obj.agentInfo.capabilities & 0x40) {
// This is a recovery agent
obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash.
return;
}
// Check if we have too many agent sessions // Check if we have too many agent sessions
if (typeof domain.limits.maxagentsessions == 'number') { if (typeof domain.limits.maxagentsessions == 'number') {
// Count the number of agent sessions for this domain // Count the number of agent sessions for this domain
@ -700,40 +709,25 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Not sure why, but in rare cases, obj.agentInfo is undefined here. // Not sure why, but in rare cases, obj.agentInfo is undefined here.
if ((obj.agentInfo == null) || (typeof obj.agentInfo.capabilities != 'number')) { return; } // This is an odd case. if ((obj.agentInfo == null) || (typeof obj.agentInfo.capabilities != 'number')) { return; } // This is an odd case.
if ((obj.agentInfo.capabilities & 64) != 0) { // Check if we need to make an native update check
// This is a recovery agent obj.agentExeInfo = parent.parent.meshAgentBinaries[obj.agentInfo.agentId];
obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash. const corename = parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core;
} else { if (corename == null) { obj.send(common.ShortToStr(10) + common.ShortToStr(0)); } // MeshCommand_CoreModule, ask mesh agent to clear the core
// Check if we need to make an native update check
obj.agentExeInfo = parent.parent.meshAgentBinaries[obj.agentInfo.agentId];
const corename = parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core;
if (corename == null) { obj.send(common.ShortToStr(10) + common.ShortToStr(0)); } // MeshCommand_CoreModule, ask mesh agent to clear the core
if ((obj.agentExeInfo != null) && (obj.agentExeInfo.update == true)) { if ((obj.agentExeInfo != null) && (obj.agentExeInfo.update == true)) {
// Ask the agent for it's executable binary hash // Ask the agent for it's executable binary hash
obj.send(common.ShortToStr(12) + common.ShortToStr(0)); obj.send(common.ShortToStr(12) + common.ShortToStr(0));
} else {
// Check the mesh core, if the agent is capable of running one
if (((obj.agentInfo.capabilities & 16) != 0) && (corename != null)) {
obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash.
} else { } else {
// Check the mesh core, if the agent is capable of running one agentCoreIsStable(); // No updates needed, agent is ready to go.
if (((obj.agentInfo.capabilities & 16) != 0) && (corename != null)) {
obj.send(common.ShortToStr(11) + common.ShortToStr(0)); // Command 11, ask for mesh core hash.
} else {
agentCoreIsStable(); // No updates needed, agent is ready to go.
}
} }
} }
}); });
} }
function recoveryAgentCoreIsStable() {
// Recovery agent is doing ok, lets perform main agent checking.
// TODO
console.log('recoveryAgentCoreIsStable()');
// Close the recovery agent connection when done.
//obj.close(1);
}
// Take a basic Intel AMT policy and add all server information to it, making it ready to send to this agent. // Take a basic Intel AMT policy and add all server information to it, making it ready to send to this agent.
function completeIntelAmtPolicy(amtPolicy) { function completeIntelAmtPolicy(amtPolicy) {
if (amtPolicy == null) return null; if (amtPolicy == null) return null;
@ -764,6 +758,21 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
} }
} }
function recoveryAgentCoreIsStable(mesh) {
// Recovery agent is doing ok, lets perform main agent checking.
//console.log('recoveryAgentCoreIsStable()');
// Fetch the the real agent nodeid
db.Get('da' + obj.dbNodeKey, function (err, nodes) {
if (nodes.length == 1) {
obj.realNodeKey = nodes[0].raid;
obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: obj.realNodeKey } }));
} else {
obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: null } }));
}
});
}
function agentCoreIsStable() { function agentCoreIsStable() {
// Check that the mesh exists // Check that the mesh exists
const mesh = parent.meshes[obj.dbMeshKey]; const mesh = parent.meshes[obj.dbMeshKey];
@ -772,6 +781,17 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
return; // Probably not worth doing anything else. Hold this agent. return; // Probably not worth doing anything else. Hold this agent.
} }
// Fetch the the real agent nodeid
db.Get('ra' + obj.dbNodeKey, function (err, nodes) {
if (nodes.length == 1) {
obj.diagnosticNodeKey = nodes[0].daid;
obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: obj.diagnosticNodeKey } }));
}
});
// Check if this is a recovery agent
if (obj.agentInfo.capabilities & 0x40) { recoveryAgentCoreIsStable(mesh); return; }
// Send Intel AMT policy // Send Intel AMT policy
if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT. if (obj.agentExeInfo && (obj.agentExeInfo.amt == true) && (mesh.amt != null)) { // Only send Intel AMT policy to agents what could have AMT.
try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { } try { obj.send(JSON.stringify({ action: 'amtPolicy', amtPolicy: completeIntelAmtPolicy(common.Clone(mesh.amt)) })); } catch (ex) { }
@ -1066,6 +1086,48 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
} }
break; break;
} }
case 'diagnostic':
{
if (typeof command.value == 'object') {
switch (command.value.command) {
case 'register': {
// Only main agent can do this
if (((obj.agentInfo.capabilities & 0x40) == 0) && (typeof command.value.command.value == 'string') && (command.value.command.value.length == 64)) {
// Store links to diagnostic agent id
var daNodeKey = 'node/' + domain.id + '/' + command.value.command.value;
db.Set({ _id: 'da' + daNodeKey, domain: domain.id, time: obj.connectTime, raid: obj.dbNodeKey }); // DiagnosticAgent --> Agent
db.Set({ _id: 'ra' + obj.dbNodeKey, domain: domain.id, time: obj.connectTime, daid: daNodeKey }); // Agent --> DiagnosticAgent
}
break;
}
case 'query': {
// Only the diagnostic agent can do
if ((obj.agentInfo.capabilities & 0x40) != 0) {
// Return nodeid of main agent + connection status
db.Get('da' + obj.dbNodeKey, function (err, nodes) {
if (nodes.length == 1) {
obj.realNodeKey = nodes[0].raid;
obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: obj.realNodeKey } }));
} else {
obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: null } }));
}
});
}
break;
}
case 'log': {
// Only the diagnostic agent can do
if (((obj.agentInfo.capabilities & 0x40) != 0) && (typeof command.value.command.value == 'string') && (command.value.command.value.length < 256)) {
// Log a value in the event log of the main again
var event = { etype: 'node', action: 'diagnostic', nodeid: obj.dbNodeKey, domain: domain.id, msg: command.value.command.value };
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, event);
}
break;
}
}
}
break;
}
default: { default: {
console.log('Unknown agent action (' + obj.remoteaddrport + '): ' + command.action + '.'); console.log('Unknown agent action (' + obj.remoteaddrport + '): ' + command.action + '.');
break; break;
@ -1076,6 +1138,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Change the current core information string and event it // Change the current core information string and event it
function ChangeAgentCoreInfo(command) { function ChangeAgentCoreInfo(command) {
if (obj.agentInfo.capabilities & 0x40) return;
if ((command == null) || (command == null)) return; // Safety, should never happen. if ((command == null) || (command == null)) return; // Safety, should never happen.
// Check that the mesh exists // Check that the mesh exists
@ -1137,6 +1200,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Change the current core information string and event it // Change the current core information string and event it
function ChangeAgentLocationInfo(command) { function ChangeAgentLocationInfo(command) {
if (obj.agentInfo.capabilities & 0x40) return;
if ((command == null) || (command == null)) { return; } // Safety, should never happen. if ((command == null) || (command == null)) { return; } // Safety, should never happen.
// Check that the mesh exists // Check that the mesh exists
@ -1172,6 +1236,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Update the mesh agent tab in the database // Update the mesh agent tab in the database
function ChangeAgentTag(tag) { function ChangeAgentTag(tag) {
if (obj.agentInfo.capabilities & 0x40) return;
if (tag.length == 0) { tag = null; } if (tag.length == 0) { tag = null; }
// Get the node and change it if needed // Get the node and change it if needed
db.Get(obj.dbNodeKey, function (err, nodes) { db.Get(obj.dbNodeKey, function (err, nodes) {

View File

@ -1396,6 +1396,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
db.RemoveSMBIOS(node._id); // Remove SMBios data db.RemoveSMBIOS(node._id); // Remove SMBios data
db.RemoveAllNodeEvents(node._id); // Remove all events for this node db.RemoveAllNodeEvents(node._id); // Remove all events for this node
db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node
db.Get('ra' + obj.dbNodeKey, function (err, nodes) {
if (nodes.length == 1) { db.Remove('da' + nodes[0].daid); } // Remove diagnostic agent to real agent link
db.Remove('ra' + node._id); // Remove real agent to diagnostic agent link
});
// Event node deletion // Event node deletion
parent.parent.DispatchEvent(['*', node.meshid], obj, { etype: 'node', username: user.name, action: 'removenode', nodeid: node._id, msg: 'Removed device ' + node.name + ' from group ' + mesh.name, domain: domain.id }); parent.parent.DispatchEvent(['*', node.meshid], obj, { etype: 'node', username: user.name, action: 'removenode', nodeid: node._id, msg: 'Removed device ' + node.name + ' from group ' + mesh.name, domain: domain.id });

View File

@ -92,7 +92,7 @@
} }
#page_content { #page_content {
max-height: calc(100vh - 108px); /*max-height: calc(100vh - 108px);*/
} }
.fullscreen #page_content { .fullscreen #page_content {
position: absolute; position: absolute;

File diff suppressed because one or more lines are too long

View File

@ -1043,7 +1043,6 @@
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); } if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
var hide = 0; var hide = 0;
if (args.hide) { hide = parseInt(args.hide); } if (args.hide) { hide = parseInt(args.hide); }
console.log("-----------hide:", hide)
if (webPageFullScreen == false) { if (webPageFullScreen == false) {
QC('body').remove("fullscreen"); QC('body').remove("fullscreen");
QC('body').remove("arg_hide"); QC('body').remove("arg_hide");

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
<div id=topbar class="noselect style3"> <div id=topbar class="noselect style3">
<div id=toggle title="Toggle full width" onclick="toggleFullScreen(1)">&harr;</div> <div id=toggle title="Toggle full width" onclick="toggleFullScreen(1)">&harr;</div>
</div> </div>
<div id=column_l> <div id=column_l style="height:calc(100vh - 111px)">
<h1>Welcome</h1> <h1>Welcome</h1>
<div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using <a href="http://www.meshcommander.com/meshcentral2">MeshCentral</a>, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the &quot;My Devices&quot; section of this web site and you will be able to monitor them and take control of them.</div> <div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using <a href="http://www.meshcommander.com/meshcentral2">MeshCentral</a>, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the &quot;My Devices&quot; section of this web site and you will be able to monitor them and take control of them.</div>
<table id="centralTable" style=""> <table id="centralTable" style="">

File diff suppressed because one or more lines are too long