express-ws update.

This commit is contained in:
Ylian Saint-Hilaire 2021-06-08 10:45:00 -07:00
commit 386c6a002e
2 changed files with 121 additions and 54 deletions

View File

@ -46,9 +46,11 @@ var MESHRIGHT_CHATNOTIFY = 16384;
var MESHRIGHT_UNINSTALL = 32768; var MESHRIGHT_UNINSTALL = 32768;
var MESHRIGHT_NODESKTOP = 65536; var MESHRIGHT_NODESKTOP = 65536;
if (require('MeshAgent').ARCHID == null) { if (require('MeshAgent').ARCHID == null)
{
var id = null; var id = null;
switch (process.platform) { switch (process.platform)
{
case 'win32': case 'win32':
id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4; id = require('_GenericMarshal').PointerSize == 4 ? 3 : 4;
break; break;
@ -56,21 +58,22 @@ if (require('MeshAgent').ARCHID == null) {
id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30; id = require('_GenericMarshal').PointerSize == 4 ? 31 : 30;
break; break;
case 'darwin': case 'darwin':
try { try
{
id = require('os').arch() == 'x64' ? 16 : 29; id = require('os').arch() == 'x64' ? 16 : 29;
} }
catch (xx) { catch (xx)
{
id = 16; id = 16;
} }
break; break;
} }
if (id != null) { Object.defineProperty(require('MeshAgent'), 'ARCHID', { value: id }); } if (id != null) { Object.defineProperty(require('MeshAgent'), 'ARCHID', { value: id }); }
} }
var obj = {}; var obj = {};
var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server. var agentFileHttpRequests = {}; // Currently active agent HTTPS GET requests from the server.
var agentFileHttpPendingRequests = []; // Pending HTTPS GET requests from the server. var agentFileHttpPendingRequests = []; // Pending HTTPS GET requests from the server.
var debugConsole = (_MSH().debugConsole == 1); var debugConsole = (global._MSH && (_MSH().debugConsole == 1));
if (process.platform == 'win32' && require('user-sessions').isRoot()) { if (process.platform == 'win32' && require('user-sessions').isRoot()) {
// Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value // Check the Agent Uninstall MetaData for correctness, as the installer may have written an incorrect value
@ -277,8 +280,16 @@ obj.DAIPC.on('connection', function (c) {
}); });
// Send current sessions to registered apps // Send current sessions to registered apps
function broadcastSessionsToRegisteredApps(x) { function broadcastSessionsToRegisteredApps(x)
{
var p = {}, i;
for (i = 0; i < sendAgentMessage.messages.length; ++i)
{
p[i] = sendAgentMessage.messages[i];
}
tunnelUserCount.msg = p;
broadcastToRegisteredApps({ cmd: 'sessions', sessions: tunnelUserCount }); broadcastToRegisteredApps({ cmd: 'sessions', sessions: tunnelUserCount });
tunnelUserCount.msg = {};
} }
// Send this object to all registered local applications // Send this object to all registered local applications
@ -838,7 +849,8 @@ function handleServerCommand(data) {
// Perform manual server TLS certificate checking based on the certificate hash given by the server. // Perform manual server TLS certificate checking based on the certificate hash given by the server.
woptions.rejectUnauthorized = 0; woptions.rejectUnauthorized = 0;
woptions.checkServerIdentity = function checkServerIdentity(certs) { woptions.checkServerIdentity = function checkServerIdentity(certs)
{
/* /*
try { sendConsoleText("certs[0].digest: " + certs[0].digest); } catch (ex) { sendConsoleText(ex); } try { sendConsoleText("certs[0].digest: " + certs[0].digest); } catch (ex) { sendConsoleText(ex); }
try { sendConsoleText("certs[0].fingerprint: " + certs[0].fingerprint); } catch (ex) { sendConsoleText(ex); } try { sendConsoleText("certs[0].fingerprint: " + certs[0].fingerprint); } catch (ex) { sendConsoleText(ex); }
@ -847,8 +859,15 @@ function handleServerCommand(data) {
*/ */
// If the tunnel certificate matches the control channel certificate, accept the connection // If the tunnel certificate matches the control channel certificate, accept the connection
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { } var noErrors = true;
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { } try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.digest == certs[0].digest) return; } catch (ex) { noErrors = false; }
try { if (require('MeshAgent').ServerInfo.ControlChannelCertificate.fingerprint == certs[0].fingerprint) return; } catch (ex) { noErrors = false; }
if (certs[0].digest == null || noErrors == true)
{
sendAgentMessage("This agent is using insecure tunnels, consider updating.", 3, 119, true);
return;
}
// Check that the certificate is the one expected by the server, fail if not. // Check that the certificate is the one expected by the server, fail if not.
if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) { throw new Error('BadCert') } if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) { throw new Error('BadCert') }
} }
@ -2942,31 +2961,32 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
break; break;
} }
case 'agentmsg': { case 'agentmsg': {
if (args['_'].length == 0) { if (args['_'].length == 0)
{
response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage
} else { } else
if ((args['_'][0] == 'add') && (args['_'].length > 1)) { {
var msgIndex = 1, iconIndex = 0; if ((args['_'][0] == 'add') && (args['_'].length > 1))
while (tunnelUserCount.msg[msgIndex] != null) { msgIndex++; } {
var msgID, iconIndex = 0;
if (args['_'].length >= 3) { try { iconIndex = parseInt(args['_'][2]); } catch (e) { } } if (args['_'].length >= 3) { try { iconIndex = parseInt(args['_'][2]); } catch (e) { } }
if (typeof iconIndex != 'number') { iconIndex = 0; } if (typeof iconIndex != 'number') { iconIndex = 0; }
tunnelUserCount.msg[msgIndex] = { msg: args['_'][1], icon: iconIndex }; msgID = sendAgentMessage(args['_'][1], iconIndex);
response = 'Agent message ' + msgIndex + ' added.'; response = 'Agent message: ' + msgID + ' added.';
} else if ((args['_'][0] == 'remove') && (args['_'].length > 1)) { } else if ((args['_'][0] == 'remove') && (args['_'].length > 1))
var msgIndex = 0; {
try { msgIndex = parseInt(args['_'][1]); } catch (x) { } var r = removeAgentMessage(args['_'][1]);
if (tunnelUserCount.msg[msgIndex] == null) { response = "Message not found."; } else { delete tunnelUserCount.msg[msgIndex]; response = "Message removed."; } response = 'Message ' + (r ? 'removed' : 'NOT FOUND');
} else if (args['_'][0] == 'list') { } else if (args['_'][0] == 'list')
response = JSON.stringify(tunnelUserCount.msg, null, 2); {
response = JSON.stringify(sendAgentMessage(), null, 2);
} }
try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (x) { }
broadcastSessionsToRegisteredApps(); broadcastSessionsToRegisteredApps();
} }
break; break;
} }
case 'clearagentmsg': { case 'clearagentmsg': {
tunnelUserCount.msg = {}; removeAgentMessage();
try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (x) { }
broadcastSessionsToRegisteredApps(); broadcastSessionsToRegisteredApps();
break; break;
} }
@ -3985,14 +4005,58 @@ function sendConsoleText(text, sessionid) {
if (sessionid != 'pipe') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: text, sessionid: sessionid }); } if (sessionid != 'pipe') { require('MeshAgent').SendCommand({ action: 'msg', type: 'console', value: text, sessionid: sessionid }); }
} }
// Send a mesh agent message to server, placing a bubble/badge on the agent device function removeAgentMessage(msgid)
function sendAgentMessage(msg, icon) { {
if (sendAgentMessage.messages == null) { var ret = false;
sendAgentMessage.messages = {}; if (msgid == null)
sendAgentMessage.nextid = 1; {
// Delete all messages
sendAgentMessage.messages = [];
ret = true;
} }
sendAgentMessage.messages[sendAgentMessage.nextid++] = { msg: msg, icon: icon }; else
require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: sendAgentMessage.messages }); {
var i = sendAgentMessage.messages.findIndex(function (v) { return (v.id == msgid); });
if (i >= 0)
{
sendAgentMessage.messages.splice(i, 1);
ret = true;
}
}
if (ret) { sendAgentMessage(); }
return (ret);
}
// Send a mesh agent message to server, placing a bubble/badge on the agent device
function sendAgentMessage(msg, icon, serverid, first)
{
if (sendAgentMessage.messages == null)
{
sendAgentMessage.messages = [];
}
if (arguments.length > 0)
{
if (first == null || (serverid && first && sendAgentMessage.messages.findIndex(function (v) { return (v.msgid == serverid); }) < 0))
{
sendAgentMessage.messages.push({ msg: msg, icon: icon, msgid: serverid });
sendAgentMessage.messages.peek().id = sendAgentMessage.messages.peek()._hashCode();
}
}
var p = {}, i;
for (i = 0; i < sendAgentMessage.messages.length; ++i)
{
p[i] = sendAgentMessage.messages[i];
}
try
{
require('MeshAgent').SendCommand({ action: 'sessions', type: 'msg', value: p });
}
catch(ex)
{
}
return (arguments.length > 0 ? sendAgentMessage.messages.peek().id : sendAgentMessage.messages);
} }
function getOpenDescriptors() { function getOpenDescriptors() {
switch (process.platform) { switch (process.platform) {
@ -4390,14 +4454,27 @@ function agentUpdate_Start(updateurl, updateoptions) {
//process.exit = function (code) { console.log("Exit with code: " + code.toString()); } //process.exit = function (code) { console.log("Exit with code: " + code.toString()); }
// Called when the server connection state changes // Called when the server connection state changes
function handleServerConnection(state) { function handleServerConnection(state)
{
meshServerConnectionState = state; meshServerConnectionState = state;
if (meshServerConnectionState == 0) { if (meshServerConnectionState == 0)
{
// Server disconnected // Server disconnected
if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; } if (selfInfoUpdateTimer != null) { clearInterval(selfInfoUpdateTimer); selfInfoUpdateTimer = null; }
lastSelfInfo = null; lastSelfInfo = null;
} else { } else
{
// Server connected, send mesh core information // Server connected, send mesh core information
if (require('MeshAgent').ServerInfo == null || require('MeshAgent').ServerInfo.ControlChannelCertificate == null)
{
// Outdated Agent, will have insecure tunnels
sendAgentMessage("This agent has an outdated certificate validation mechanism, consider updating.", 3, 118);
}
else if (global._MSH == null)
{
sendAgentMessage("This agent is outdated, consider updating.", 3, 120);
}
var oldNodeId = db.Get('OldNodeId'); var oldNodeId = db.Get('OldNodeId');
if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); } if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
@ -4407,14 +4484,16 @@ function handleServerConnection(state) {
// Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings // Update the server on with basic info, logged in users and more advanced stuff, like Intel ME and Network Settings
meInfoStr = null; meInfoStr = null;
sendPeriodicServerUpdate(null, true); sendPeriodicServerUpdate(null, true);
if (selfInfoUpdateTimer == null) { if (selfInfoUpdateTimer == null)
{
selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); // 20 minutes selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); // 20 minutes
selfInfoUpdateTimer.metadata = 'meshcore (InfoUpdate Timer)'; selfInfoUpdateTimer.metadata = 'meshcore (InfoUpdate Timer)';
} }
// Send any state messages // Send any state messages
if (Object.keys(tunnelUserCount.msg).length > 0) { if (Object.keys(tunnelUserCount.msg).length > 0)
try { mesh.SendCommand({ action: 'sessions', type: 'msg', value: tunnelUserCount.msg }); } catch (e) { } {
sendAgentMessage();
broadcastSessionsToRegisteredApps(); broadcastSessionsToRegisteredApps();
} }

View File

@ -36,33 +36,21 @@
"sample-config-advanced.json" "sample-config-advanced.json"
], ],
"dependencies": { "dependencies": {
"archiver": "^4.0.2",
"archiver-zip-encrypted": "^1.0.9",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"cbor": "~5.2.0", "cbor": "~5.2.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"cookie-session": "^2.0.0-beta.3", "cookie-session": "^2.0.0-beta.3",
"express": "^4.17.0", "express": "^4.17.0",
"express-handlebars": "^3.1.0", "express-handlebars": "^3.1.0",
"express-ws": "^4.0.0", "express-ws": "^5.0.1",
"image-size": "^1.0.0",
"ipcheck": "^0.1.0", "ipcheck": "^0.1.0",
"loadavg-windows": "^1.1.1", "minimist": "^1.2.0",
"minimist": "^1.2.5",
"mongodb": "^3.6.9",
"multiparty": "^4.2.2", "multiparty": "^4.2.2",
"nedb": "^1.8.0", "nedb": "^1.8.0",
"node-forge": "^0.10.0", "node-forge": "^0.10.0",
"node-rdpjs-2": "^0.3.5",
"node-windows": "^1.0.0-beta.5",
"otplib": "^10.2.3",
"saslprep": "^1.0.3",
"ssh2": "^1.1.0",
"web-push": "^3.4.4",
"ws": "^7.4.6", "ws": "^7.4.6",
"xmldom": "^0.5.0", "xmldom": "^0.5.0",
"yauzl": "^2.10.0", "yauzl": "^2.10.0"
"yubikeyotp": "^0.2.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",