Many bug fixes: Login screen, hw keys, relay domain and more.
This commit is contained in:
parent
084a6bab57
commit
bbd7a96c7b
20
meshagent.js
20
meshagent.js
|
@ -597,14 +597,14 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
// Check that the node exists
|
||||
db.Get(obj.dbNodeKey, function (err, nodes) {
|
||||
if (obj.agentInfo == null) { return; }
|
||||
var device;
|
||||
var device, mesh;
|
||||
|
||||
// See if this node exists in the database
|
||||
if ((nodes == null) || (nodes.length == 0)) {
|
||||
// This device does not exist, use the meshid given by the device
|
||||
|
||||
// See if this mesh exists, if it does not we may want to create it.
|
||||
const mesh = getMeshAutoCreate();
|
||||
mesh = getMeshAutoCreate();
|
||||
|
||||
// Check if the mesh exists
|
||||
if (mesh == null) {
|
||||
|
@ -647,7 +647,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
}
|
||||
|
||||
// See if this mesh exists, if it does not we may want to create it.
|
||||
const mesh = getMeshAutoCreate();
|
||||
mesh = getMeshAutoCreate();
|
||||
|
||||
// Check if the mesh exists
|
||||
if (mesh == null) {
|
||||
|
@ -705,6 +705,20 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
const dupAgent = parent.wsagents[obj.dbNodeKey];
|
||||
parent.wsagents[obj.dbNodeKey] = obj;
|
||||
if (dupAgent) {
|
||||
// Record duplicate agents
|
||||
if (parent.duplicateAgentsLog[obj.dbNodeKey] == null) {
|
||||
if (dupAgent.remoteaddr == obj.remoteaddr) {
|
||||
parent.duplicateAgentsLog[obj.dbNodeKey] = { name: device.name, group: mesh.name, ip: [obj.remoteaddr], count: 1 };
|
||||
} else {
|
||||
parent.duplicateAgentsLog[obj.dbNodeKey] = { name: device.name, group: mesh.name, ip: [obj.remoteaddr, dupAgent.remoteaddr], count: 1 };
|
||||
}
|
||||
} else {
|
||||
parent.duplicateAgentsLog[obj.dbNodeKey].name = device.name;
|
||||
parent.duplicateAgentsLog[obj.dbNodeKey].group = mesh.name;
|
||||
parent.duplicateAgentsLog[obj.dbNodeKey].count++;
|
||||
if (parent.duplicateAgentsLog[obj.dbNodeKey].ip.indexOf(obj.remoteaddr) == -1) { parent.duplicateAgentsLog[obj.dbNodeKey].ip.push(obj.remoteaddr); }
|
||||
}
|
||||
|
||||
// Close the duplicate agent
|
||||
parent.agentStats.duplicateAgentCount++;
|
||||
if (obj.nodeid != null) { parent.parent.debug(1, 'Duplicate agent ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); }
|
||||
|
|
14
meshuser.js
14
meshuser.js
|
@ -548,7 +548,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
case 'help': {
|
||||
r = 'Available commands: help, info, versions, args, resetserver, showconfig, usersessions, tasklimiter, setmaxtasks, cores,\r\n'
|
||||
r += 'migrationagents, agentstats, webstats, mpsstats, swarmstats, acceleratorsstats, updatecheck, serverupdate, nodeconfig,\r\n';
|
||||
r += 'heapdump, relays, autobackup.';
|
||||
r += 'heapdump, relays, autobackup, dupagents.';
|
||||
break;
|
||||
}
|
||||
case 'dupagents': {
|
||||
for (var i in parent.duplicateAgentsLog) { r += JSON.stringify(parent.duplicateAgentsLog[i]) + '\r\n'; }
|
||||
if (r == '') { r = 'No duplicate agents in log.'; }
|
||||
break;
|
||||
}
|
||||
case 'agentstats': {
|
||||
|
@ -1217,10 +1222,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// Change a user's password
|
||||
if (user.siteadmin != 0xFFFFFFFF) break;
|
||||
if (common.validateString(command.userid, 1, 256) == false) break;
|
||||
if (common.validateString(command.pass, 1, 256) == false) break;
|
||||
if (common.validateString(command.pass, 0, 256) == false) break;
|
||||
if ((command.hint != null) && (common.validateString(command.hint, 0, 256) == false)) break;
|
||||
if (typeof command.removeMultiFactor != 'boolean') break;
|
||||
if (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
||||
if ((command.pass != '') && (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false)) break; // Password does not meet requirements
|
||||
|
||||
var chguser = parent.users[command.userid];
|
||||
if (chguser) {
|
||||
|
@ -1230,8 +1235,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// Compute the password hash & save it
|
||||
require('./pass').hash(command.pass, function (err, salt, hash, tag) {
|
||||
if (!err) {
|
||||
chguser.salt = salt;
|
||||
chguser.hash = hash;
|
||||
if (command.pass != '') { chguser.salt = salt; chguser.hash = hash; }
|
||||
if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (command.hint != null)) {
|
||||
var hint = command.hint;
|
||||
if (hint.length > 250) { hint = hint.substring(0, 250); }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.3.4-y",
|
||||
"version": "0.3.4-z",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -28,13 +28,12 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"archiver": "^3.0.0",
|
||||
"archiver-zip-encrypted": "^1.0.3",
|
||||
"body-parser": "^1.19.0",
|
||||
"cbor": "^4.1.5",
|
||||
"compression": "^1.7.4",
|
||||
"connect-redis": "^3.4.1",
|
||||
"cookie-session": "^2.0.0-beta.3",
|
||||
"express": "^4.16.4",
|
||||
"express": "^4.17.0",
|
||||
"express-handlebars": "^3.1.0",
|
||||
"express-ws": "^4.0.0",
|
||||
"ipcheck": "^0.1.0",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
// Construct a MeshServer agent direction object
|
||||
var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, authCookie) {
|
||||
var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, authCookie, domainUrl) {
|
||||
var obj = {};
|
||||
obj.m = module; // This is the inner module (Terminal or Desktop)
|
||||
module.parent = obj;
|
||||
|
@ -25,6 +25,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
|
|||
obj.webchannel = null;
|
||||
obj.webrtc = null;
|
||||
obj.debugmode = 0;
|
||||
if (domainUrl == null) { domainUrl = '/'; }
|
||||
|
||||
// Console Message
|
||||
obj.consoleMessage = null;
|
||||
|
@ -47,7 +48,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
|
|||
obj.socket.onclose = obj.xxOnSocketClosed;
|
||||
obj.xxStateChange(1);
|
||||
//obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });
|
||||
obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*/meshrelay.ashx?id=" + obj.tunnelid, usage: obj.protocol });
|
||||
obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*" + domainUrl + "meshrelay.ashx?id=" + obj.tunnelid, usage: obj.protocol });
|
||||
//obj.debug("Agent Redir Start: " + url);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -2167,7 +2167,7 @@
|
|||
desktop.contype = 2;
|
||||
} else {
|
||||
// Setup the Mesh Agent remote desktop
|
||||
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie);
|
||||
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, domainUrl);
|
||||
desktop.debugmode = debugmode;
|
||||
desktop.m.debugmode = debugmode;
|
||||
desktop.attemptWebRTC = attemptWebRTC;
|
||||
|
@ -2468,7 +2468,7 @@
|
|||
function connectFiles(e) {
|
||||
if (!files) {
|
||||
// Setup a mesh agent files
|
||||
files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie);
|
||||
files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie, domainUrl);
|
||||
files.attemptWebRTC = attemptWebRTC;
|
||||
files.onStateChanged = onFilesStateChange;
|
||||
files.Start(filesNode._id);
|
||||
|
@ -2693,7 +2693,7 @@
|
|||
// Called by the html page to start a download, arguments are: path, file name and file size.
|
||||
function p13downloadfile(x, y, z) {
|
||||
if (xxdialogMode) return;
|
||||
downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort, authCookie); // Create our websocket file transport
|
||||
downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort, authCookie, domainUrl); // Create our websocket file transport
|
||||
downloadFile.ctrlMsgAllowed = false;
|
||||
downloadFile.onStateChanged = onFileDownloadStateChange;
|
||||
downloadFile.xpath = decodeURIComponent(x);
|
||||
|
@ -2780,7 +2780,7 @@
|
|||
|
||||
// Connect again
|
||||
function p13uploadReconnect() {
|
||||
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie);
|
||||
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie, domainUrl);
|
||||
uploadFile.ws.attemptWebRTC = false;
|
||||
uploadFile.ws.ctrlMsgAllowed = false;
|
||||
uploadFile.ws.onStateChanged = onFileUploadStateChange;
|
||||
|
|
|
@ -2485,7 +2485,7 @@
|
|||
multiDesktop[nodeid] = desk;
|
||||
} else if (contype == 1) {
|
||||
// Setup the Mesh Agent remote desktop
|
||||
desk = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('kvmid_' + shortid), serverPublicNamePort, authCookie);
|
||||
desk = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('kvmid_' + shortid), serverPublicNamePort, authCookie, domainUrl);
|
||||
desk.shortid = shortid;
|
||||
desk.attemptWebRTC = attemptWebRTC;
|
||||
desk.onStateChanged = onMultiDesktopStateChange;
|
||||
|
@ -4464,7 +4464,7 @@
|
|||
desktop.contype = 2;
|
||||
} else {
|
||||
// Setup the Mesh Agent remote desktop
|
||||
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie);
|
||||
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, domainUrl);
|
||||
desktop.debugmode = debugmode;
|
||||
desktop.m.debugmode = debugmode;
|
||||
desktop.attemptWebRTC = attemptWebRTC;
|
||||
|
@ -4963,7 +4963,7 @@
|
|||
Q('id_ttypebutton').value = terminalEmulations[terminal.m.terminalEmulation];
|
||||
} else {
|
||||
// Setup a mesh agent terminal
|
||||
terminal = CreateAgentRedirect(meshserver, CreateAmtRemoteTerminal('Term'), serverPublicNamePort, authCookie);
|
||||
terminal = CreateAgentRedirect(meshserver, CreateAmtRemoteTerminal('Term'), serverPublicNamePort, authCookie, domainUrl);
|
||||
terminal.debugmode = debugmode;
|
||||
terminal.m.debugmode = debugmode;
|
||||
terminal.m.lineFeed = ([1, 2, 3, 4, 21, 22].indexOf(currentNode.agent.id) >= 0) ? '\r\n' : '\r'; // On windows, send \r\n, on Linux only \r
|
||||
|
@ -5093,7 +5093,7 @@
|
|||
function connectFiles(e) {
|
||||
if (!files) {
|
||||
// Setup a mesh agent files
|
||||
files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie);
|
||||
files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie, domainUrl);
|
||||
files.attemptWebRTC = attemptWebRTC;
|
||||
files.onStateChanged = onFilesStateChange;
|
||||
files.onConsoleMessageChange = function () {
|
||||
|
@ -5354,7 +5354,7 @@
|
|||
// Called by the html page to start a download, arguments are: path, file name and file size.
|
||||
function p13downloadfile(x, y, z) {
|
||||
if (xxdialogMode) return;
|
||||
downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort, authCookie); // Create our websocket file transport
|
||||
downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort, authCookie, domainUrl); // Create our websocket file transport
|
||||
downloadFile.ctrlMsgAllowed = false;
|
||||
downloadFile.onStateChanged = onFileDownloadStateChange;
|
||||
downloadFile.xpath = decodeURIComponent(x);
|
||||
|
@ -5441,7 +5441,7 @@
|
|||
|
||||
// Connect again
|
||||
function p13uploadReconnect() {
|
||||
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie);
|
||||
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie, domainUrl);
|
||||
uploadFile.ws.attemptWebRTC = false;
|
||||
uploadFile.ws.ctrlMsgAllowed = false;
|
||||
uploadFile.ws.onStateChanged = onFileUploadStateChange;
|
||||
|
@ -7235,8 +7235,8 @@
|
|||
function p30showUserChangePassDialog(multiFactor) {
|
||||
if (xxdialogMode) return;
|
||||
var x = '';
|
||||
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
||||
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=showCreateNewAccountDialogValidate(1)></input>');
|
||||
x += addHtmlValue('Password', '<input id=p4pass1 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=p30showUserChangePassDialogValidate(1)></input>');
|
||||
x += addHtmlValue('Password', '<input id=p4pass2 type=password style=width:230px maxlength=256 onchange=showCreateNewAccountDialogValidate(1) onkeyup=p30showUserChangePassDialogValidate(1)></input>');
|
||||
if (features & 0x00010000) { x += addHtmlValue('Password hint', '<input id=p4hint type=text style=width:230px maxlength=256></input>'); }
|
||||
|
||||
if (passRequirements) {
|
||||
|
@ -7248,8 +7248,19 @@
|
|||
x += '<div><input id=p4resetNextLogin type=checkbox />Force password reset on next login.</div>';
|
||||
if (multiFactor == 1) { x += '<div><input id=p4twoFactorRemove type=checkbox />Remove all 2nd factor authentication.</div>'; }
|
||||
setDialogMode(2, "Change Password for " + EscapeHtml(currentUser.name), 3, p30showUserChangePassDialogEx, x, multiFactor);
|
||||
showCreateNewAccountDialogValidate(1);
|
||||
p30showUserChangePassDialogValidate();
|
||||
Q('p4pass1').focus();
|
||||
if (currentUser.passchange == -1) { Q('p4resetNextLogin').checked = true; }
|
||||
}
|
||||
|
||||
function p30showUserChangePassDialogValidate() {
|
||||
var ok = true;
|
||||
if ((Q('p4pass1').value != '') || (Q('p4pass2').value != '')) {
|
||||
if (Q('p4pass1').value != Q('p4pass2').value) { ok = false; } else {
|
||||
if (passRequirements) { if (checkPasswordRequirements(Q('p4pass1').value, passRequirements) == false) { ok = false; } }
|
||||
}
|
||||
}
|
||||
QE('idx_dlgOkButton', ok);
|
||||
}
|
||||
|
||||
function p30showUserChangePassDialogEx(b, tag) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -73,8 +73,8 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id=createpanel style="position:relative;display:none">
|
||||
<div style="background-color: #979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both">
|
||||
<div id=createpanel style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form action=createaccount method=post>
|
||||
<div id=message2>
|
||||
{{{message}}}
|
||||
|
@ -188,7 +188,7 @@
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<div id=resetpasswordpanel style="position:relative;background-color: #979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<div id=resetpasswordpanel style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form action=resetpassword method=post>
|
||||
<div id=message6>
|
||||
{{{message}}}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id=createpanel style="display:none">
|
||||
<div id=createpanel style="display:none;position:relative">
|
||||
<form action=createaccount method=post>
|
||||
<div id=message2>
|
||||
{{{message}}}
|
||||
|
@ -78,7 +78,7 @@
|
|||
<div>
|
||||
<b>Account Creation</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none;"></div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td id="nuUser" align=right width=100>Username:</td>
|
||||
|
@ -181,12 +181,12 @@
|
|||
<hr /><a onclick=xgo(1) style=cursor:pointer>Back to login</a>
|
||||
</form>
|
||||
</div>
|
||||
<div id=resetpasswordpanel style="display:none">
|
||||
<div id=resetpasswordpanel style="display:none;position:relative">
|
||||
<form action=resetpassword method=post>
|
||||
<div id=message6>
|
||||
{{{message}}}
|
||||
</div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none;"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td id="rnuPass1" width=100 align=right>Password:</td>
|
||||
|
|
|
@ -157,6 +157,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
obj.wsagents = {}; // NodeId --> Agent
|
||||
obj.wsagentsDisconnections = {};
|
||||
obj.wsagentsDisconnectionsTimer = null;
|
||||
obj.duplicateAgentsLog = {};
|
||||
obj.wssessions = {}; // UserId --> Array Of Sessions
|
||||
obj.wssessions2 = {}; // "UserId + SessionRnd" --> Session (Note that the SessionId is the UserId + / + SessionRnd)
|
||||
obj.wsPeerSessions = {}; // ServerId --> Array Of "UserId + SessionRnd"
|
||||
|
@ -599,10 +600,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
for (var i = 0; i < webAuthnKeys.length; i++) { authnOptions.keyIds.push(webAuthnKeys[i].keyId); }
|
||||
req.session.u2fchallenge = authnOptions.challenge;
|
||||
func(JSON.stringify(authnOptions));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
func('');
|
||||
}
|
||||
func('');
|
||||
}
|
||||
|
||||
function handleLoginRequest(req, res) {
|
||||
|
|
Loading…
Reference in New Issue