Added user authentication option.
This commit is contained in:
parent
170088fa3f
commit
12305fab90
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -342,9 +342,9 @@ function run(argv) {
|
|||
var amtMeiModule = require('amt-mei');
|
||||
var amtMei = new amtMeiModule();
|
||||
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||||
amtMei.getVersion(function (val) { for (var version in val.Versions) { if (val.Versions[version].Description == 'AMT') { mestate.ver = val.Versions[version].Version; } } });
|
||||
amtMei.getProvisioningState(function (result) { mestate.ProvisioningState = result; });
|
||||
amtMei.getProvisioningMode(function (result) { mestate.ProvisioningMode = result; });
|
||||
amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } });
|
||||
amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } });
|
||||
amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } });
|
||||
amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } });
|
||||
amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } });
|
||||
amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } });
|
||||
|
@ -352,7 +352,8 @@ function run(argv) {
|
|||
amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } });
|
||||
amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
|
||||
amtMei.getDnsSuffix(function (result) {
|
||||
mestate.dns = result;
|
||||
if (result) { mestate.dns = result; }
|
||||
if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) {
|
||||
var str = 'Intel AMT v' + mestate.ver;
|
||||
if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; }
|
||||
else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; }
|
||||
|
@ -370,6 +371,9 @@ function run(argv) {
|
|||
if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); }
|
||||
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); }
|
||||
console.log(str + '.');
|
||||
} else {
|
||||
console.log('Intel(R) AMT not supported.');
|
||||
}
|
||||
exit(1);
|
||||
});
|
||||
} else if (settings.action == 'amtinfodebug') {
|
||||
|
|
|
@ -25,7 +25,7 @@ function dbus(address, uid)
|
|||
.createEvent('signal');
|
||||
Object.defineProperty(this, "uid", { value: uid });
|
||||
this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid });
|
||||
this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while true; do read X; echo "$X"; done )\n');
|
||||
this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while read X; do echo "$X"; done )\n');
|
||||
this._child.stdout.dbus = this;
|
||||
this._child.stdout.on('data', function (chunk)
|
||||
{
|
||||
|
|
17
meshuser.js
17
meshuser.js
|
@ -86,7 +86,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
req.session.currentNode = '';
|
||||
} else {
|
||||
// Close the websocket connection
|
||||
try { obj.ws.close(); } catch (e) { } return;
|
||||
console.log('NOAUTH1');
|
||||
ws.send(JSON.stringify({ action: 'close', cause: 'noauth' }));
|
||||
try { obj.ws.close(); } catch (e) { }
|
||||
return;
|
||||
}
|
||||
}
|
||||
req.session.ws = obj.ws; // Associate this websocket session with the web session
|
||||
|
@ -121,7 +124,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
};
|
||||
|
||||
user.subscriptions = obj.parent.subscribe(user._id, ws); // Subscribe to events
|
||||
obj.ws._socket.setKeepAlive(true, 240000); // Set TCP keep alive
|
||||
try { obj.ws._socket.setKeepAlive(true, 240000); } catch (ex) { } // Set TCP keep alive
|
||||
|
||||
// Send current server statistics
|
||||
obj.SendServerStats = function () {
|
||||
|
@ -329,7 +332,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
command.sessionid = ws.sessionId; // Set the session id, required for responses.
|
||||
command.rights = rights.rights; // Add user rights flags to the message
|
||||
delete command.nodeid; // Remove the nodeid since it's implyed.
|
||||
agent.send(JSON.stringify(command));
|
||||
try { agent.send(JSON.stringify(command)); } catch (ex) { }
|
||||
}
|
||||
} else {
|
||||
// Check if a peer server is connected to this agent
|
||||
|
@ -601,7 +604,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
|
||||
// Get the list of sessions for this user
|
||||
var sessions = obj.parent.wssessions[command.userid];
|
||||
if (sessions != null) { for (i in sessions) { sessions[i].send(JSON.stringify(notification)); } }
|
||||
if (sessions != null) { for (i in sessions) { try { sessions[i].send(JSON.stringify(notification)); } catch (ex) { } } }
|
||||
|
||||
if (obj.parent.parent.multiServer != null) {
|
||||
// TODO: Add multi-server support
|
||||
|
@ -925,7 +928,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
var agent = obj.parent.wsagents[i];
|
||||
if ((targetMeshes.indexOf(agent.dbMeshKey) >= 0) && (agent.authenticated == 2)) {
|
||||
//console.log('Asking agent ' + agent.dbNodeKey + ' to wake ' + macs.join(','));
|
||||
agent.send(JSON.stringify({ action: 'wakeonlan', macs: macs }));
|
||||
try { agent.send(JSON.stringify({ action: 'wakeonlan', macs: macs })); } catch (ex) { }
|
||||
wakeActions++;
|
||||
}
|
||||
}
|
||||
|
@ -966,7 +969,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
var agent = obj.parent.wsagents[node._id];
|
||||
if (agent != null) {
|
||||
// Send the power command
|
||||
agent.send(JSON.stringify({ action: 'poweraction', actiontype: command.actiontype }));
|
||||
try { agent.send(JSON.stringify({ action: 'poweraction', actiontype: command.actiontype })); } catch (ex) { }
|
||||
powerActions++;
|
||||
}
|
||||
}
|
||||
|
@ -1004,7 +1007,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
|||
var agent = obj.parent.wsagents[node._id];
|
||||
if (agent != null) {
|
||||
// Send the power command
|
||||
agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg }));
|
||||
try { agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg })); } catch (ex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -679,7 +679,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
|||
};
|
||||
|
||||
function ChangeHostname(socket, host) {
|
||||
if (socket.tag.host == host) return; // Nothing to change
|
||||
if (socket.tag.host === host) return; // Nothing to change
|
||||
socket.tag.host = host;
|
||||
|
||||
// Change the device
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.2.2-c",
|
||||
"version": "0.2.2-d",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
|
|
@ -155,28 +155,27 @@
|
|||
<div id=devViewButton3 class=viewSelector onclick=onDeviceViewChange(3) title="Desktops"><div class="viewSelector3"></div></div>
|
||||
<div id=devViewButton4 class=viewSelector onclick=onDeviceViewChange(4) title="Map"><div class="viewSelector4"></div></div>
|
||||
</div><div><h1>My Devices</h1></div>
|
||||
<div style=width:100%;height:24px;background-color:#d3d9d6>
|
||||
<div class=h1 style=height:100%;float:left> </div>
|
||||
<div id=devListToolbar class=style14 style="height:100%;float:left;vertical-align:middle">
|
||||
<table style=width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0>
|
||||
<tr>
|
||||
<td class=h1></td>
|
||||
<td id=devListToolbar class=style14>
|
||||
<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />
|
||||
<input type=button id=GroupActionButton disabled="disabled" value="Group Action" onclick=groupActionFunction() />
|
||||
<input id=SearchInput type=text style=width:120px placeholder=Search onchange=onSearchInputChanged() onkeyup=onSearchInputChanged() autocomplete=off onfocus=onSearchFocus(1) onblur=onSearchFocus(0) />
|
||||
<input type=checkbox id=RealNameCheckBox onclick=onRealNameCheckBox() /><span title="Show devices operating system name">OS Name</span>
|
||||
</div>
|
||||
<div id=kvmListToolbar class=style14 style=height:100%;float:left>
|
||||
</td>
|
||||
<td id=kvmListToolbar class=style14 style=height:100%>
|
||||
<input type="button" onclick="connectAllKvmFunction()" value="Connect All" />
|
||||
<input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All" />
|
||||
<input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect" />Auto
|
||||
<input type="button" onclick="showMultiDesktopSettings()" value="Settings" />
|
||||
</div>
|
||||
<div id=devMapToolbar class=style14 style=height:100%;float:left>
|
||||
</td>
|
||||
<td id=devMapToolbar class=style14 style=height:100%>
|
||||
<input type=text id=mapSearchLocation placeholder="Search Location" onfocus=onMapSearchFocus(1) onblur=onMapSearchFocus(0) />
|
||||
<input type=button value=Search title="Search for location" onclick=getSearchLocation() />
|
||||
<input type=button id=refreshmap title="Reset map view" value=Reset style=margin-left:5px onclick=refreshMap(false,true) />
|
||||
</div>
|
||||
<div class="auto-style1" style=height:100%;float:right>
|
||||
<div style="height:100%;width:4px;float:right;background-color:#ffffff"></div>
|
||||
<div class=h2 style="height:100%;float:right"> </div>
|
||||
</td>
|
||||
<td class="auto-style1" style=height:100%>
|
||||
<div style="float:right;display:none" id=devListToolbarView>
|
||||
View
|
||||
<select id=viewselect onchange=onDeviceViewChange()>
|
||||
|
@ -205,8 +204,10 @@
|
|||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class=h2></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id=NoMeshesPanel style=display:none>
|
||||
<table style="width:100%;padding:20px">
|
||||
<tr>
|
||||
|
@ -253,11 +254,11 @@
|
|||
</div>
|
||||
<div id=p3 style=display:none>
|
||||
<h1>My Events</h1>
|
||||
<div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
|
||||
<div class=style7 style=width:16px;height:100%;float:left> </div>
|
||||
<div class=h1 style=height:100%;float:left> </div>
|
||||
<div class=style14 style=height:100%;float:left> <input id=p2deleteall type=button onclick=showDeleteAllEventsDialog() style=display:none value="Delete All..." /> </div>
|
||||
<div class="auto-style1" style="height:100%;float:right">
|
||||
<table style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0>
|
||||
<tr>
|
||||
<td class=h1></td>
|
||||
<td> <input id=p2deleteall type=button onclick=showDeleteAllEventsDialog() style=display:none value="Delete All..." /></td>
|
||||
<td class=auto-style1>
|
||||
Show
|
||||
<select id=p3limitdropdown onchange=refreshEvents()>
|
||||
<option value=60>Last 60</option>
|
||||
|
@ -266,27 +267,25 @@
|
|||
<option value=500>Last 500</option>
|
||||
<option value=1000>Last 1000</option>
|
||||
</select>
|
||||
<div style="height:100%;width:20px;float:right;background-color:#ffffff"></div>
|
||||
<div class="h2" style="height:100%;float:right;"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class=h2></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id=p3events style="height:calc(100vh - 243px);overflow-y:scroll"></div>
|
||||
</div>
|
||||
<div id=p4 style=display:none>
|
||||
<h1>My Users</h1>
|
||||
<div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
|
||||
<div class=style7 style=width:16px;height:100%;float:left> </div>
|
||||
<div class=h1 style=height:100%;float:left> </div>
|
||||
<div class=style14 style=height:100%;float:left>
|
||||
|
||||
<table style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0>
|
||||
<tr>
|
||||
<td class=h1></td>
|
||||
<td class=style14>
|
||||
|
||||
<input type=button onclick=showCreateNewAccountDialog() value="New Account..." />
|
||||
<input id=UserSearchInput type=text style=width:120px placeholder=Search onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) />
|
||||
</div>
|
||||
<div class=auto-style1 style="height:100%;float:right">
|
||||
<div style="height:100%;width:20px;float:right;background-color:#ffffff"></div>
|
||||
<div class=h2 style="height:100%;float:right"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class=h2></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="p3users" style="max-height:calc(100vh - 243px);overflow-y:auto"></div>
|
||||
</div>
|
||||
<div id=p5 style=display:none>
|
||||
|
@ -1235,7 +1234,7 @@
|
|||
x += addHtmlValue2('Current Version', '<b>' + EscapeHtml(message.current) + '</b>');
|
||||
x += addHtmlValue2('Latest Version', '<b>' + EscapeHtml(message.latest) + '</b>');
|
||||
x += '</div>';
|
||||
if ((message.current == message.latest) || ((features & 2048) == 0)) {
|
||||
if ((message.latest.indexOf('.') == -1) || (message.current == message.latest) || ((features & 2048) == 0)) {
|
||||
setDialogMode(2, "MeshCentral Version", 1, null, x);
|
||||
} else {
|
||||
setDialogMode(2, "MeshCentral Version", 3, server_showVersionDlgEx, x + '<br /><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to start server self-update.');
|
||||
|
@ -2595,6 +2594,7 @@
|
|||
} catch (ex) {
|
||||
console.log(ex);
|
||||
QV('viewselectmapoption', false);
|
||||
QV('devViewButton4', false);
|
||||
xxmap = null;
|
||||
}
|
||||
}
|
||||
|
@ -6176,9 +6176,7 @@
|
|||
for (var i in message.values) {
|
||||
x += '<div class=userTableHeader style=margin-bottom:4px;width:200px>' + i + '</div>';
|
||||
for (var j in message.values[i]) {
|
||||
x += '<div style=width:300px;display:inline-block><div class=bar style=height:24px;width:100%;font-size:medium>';
|
||||
x += '<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>';
|
||||
x += '<div><span>' + j + '</span><span style=float:right>' + message.values[i][j] + '</span></div></div></div>';
|
||||
x += '<div style=display:inline-block><table style=width:300px;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0><tr><td class=h1></td><td><span>' + j + '</span><span style=float:right>' + message.values[i][j] + '</span></td><td class=h2></td></tr></table></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
54
webserver.js
54
webserver.js
|
@ -214,7 +214,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
if (!module.parent) console.log('authenticating %s:%s:%s', domain.id, name, pass);
|
||||
var user = obj.users['user/' + domain.id + '/' + name.toLowerCase()];
|
||||
// Query the db for the given username
|
||||
if (!user) return fn(new Error('cannot find user'));
|
||||
if (!user) { fn(new Error('cannot find user')); return; }
|
||||
// Apply the same algorithm to the POSTed password, applying the hash against the pass / salt, if there is a match we found the user
|
||||
if (user.salt == null) {
|
||||
fn(new Error('invalid password'));
|
||||
|
@ -1803,7 +1803,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
obj.app.post(url + 'amtevents.ashx', obj.handleAmtEventRequest);
|
||||
obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
|
||||
obj.app.ws(url + 'webrelay.ashx', handleRelayWebSocket);
|
||||
obj.app.ws(url + 'control.ashx', function (ws, req) { try { var domain = checkUserIpAddress(ws, req); if (domain != null) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); } } catch (e) { console.log(e); } });
|
||||
obj.app.get(url + 'meshagents', obj.handleMeshAgentRequest);
|
||||
obj.app.get(url + 'meshosxagent', obj.handleMeshOsxAgentRequest);
|
||||
obj.app.get(url + 'meshsettings', obj.handleMeshSettingsRequest);
|
||||
|
@ -1814,6 +1813,57 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
|
||||
obj.app.ws(url + 'meshrelay.ashx', function (ws, req) { try { obj.meshRelayHandler.CreateMeshRelay(obj, ws, req, getDomain(req)); } catch (e) { console.log(e); } });
|
||||
|
||||
// User login
|
||||
obj.app.ws(url + 'control.ashx', function (ws, req) {
|
||||
try {
|
||||
var domain = checkUserIpAddress(ws, req);
|
||||
if (domain != null) {
|
||||
var loginok = false;
|
||||
// Check if the user is logged in
|
||||
if ((!req.session) || (!req.session.userid) || (req.session.domainid != domain.id)) {
|
||||
// If a default user is active, setup the session here.
|
||||
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
|
||||
if (req.session && req.session.loginmode) { delete req.session.loginmode; }
|
||||
req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase();
|
||||
req.session.domainid = domain.id;
|
||||
req.session.currentNode = '';
|
||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
||||
loginok = true;
|
||||
} else {
|
||||
// See the the user/pass is provided in URL arguments
|
||||
if ((req.query.user != null) && (req.query.pass != null)) {
|
||||
loginok = true;
|
||||
obj.authenticate(req.query.user, req.query.pass, domain, function (err, userid) {
|
||||
var loginok2 = false;
|
||||
if (err == null) {
|
||||
var user = obj.users[userid];
|
||||
if (user) {
|
||||
req.session.userid = userid;
|
||||
req.session.domainid = domain.id;
|
||||
req.session.currentNode = '';
|
||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
||||
loginok2 = true;
|
||||
}
|
||||
}
|
||||
if (loginok2 == false) {
|
||||
// Close the websocket connection
|
||||
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
|
||||
loginok = true;
|
||||
}
|
||||
if (loginok == false) {
|
||||
// Close the websocket connection
|
||||
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
|
||||
}
|
||||
}
|
||||
} catch (e) { console.log(e); }
|
||||
});
|
||||
|
||||
// Server picture
|
||||
obj.app.get(url + 'serverpic.ashx', function (req, res) {
|
||||
// Check if we have "server.png" in the data folder, if so, use that.
|
||||
|
|
Loading…
Reference in New Issue